using Indotalent.ConfigBackEnd.Extensions; using Indotalent.Data.Entities; using Indotalent.Data.Enums; using Microsoft.EntityFrameworkCore; namespace Indotalent.Infrastructure.Database.Demo; public static class BillSeeder { public static async Task GenerateDataAsync(AppDbContext context) { if (await context.Bill.AnyAsync()) return; var random = new Random(); var entityName = nameof(Bill); var dateFinish = DateTime.Now; var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1); var confirmedPurchaseOrders = await context.PurchaseOrder .Where(po => po.OrderStatus == PurchaseOrderStatus.Confirmed) .Select(po => po.Id) .ToListAsync(); if (!confirmedPurchaseOrders.Any()) return; for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1)) { DateTime[] billDates = GetRandomDays(date.Year, date.Month, 5); foreach (var billDate in billDates) { if (confirmedPurchaseOrders.Count == 0) break; var status = GetRandomStatus(random); var purchaseOrderId = GetRandomAndRemove(confirmedPurchaseOrders, random); var autoNo = await context.GenerateAutoNumberAsync( entityName: entityName, prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/" ); var bill = new Bill { AutoNumber = autoNo, BillDate = billDate, BillStatus = status, Description = $"Bill for {billDate:MMMM yyyy}", PurchaseOrderId = purchaseOrderId }; await context.Bill.AddAsync(bill); } } await context.SaveChangesAsync(); } private static BillStatus GetRandomStatus(Random random) { var statuses = new[] { BillStatus.Draft, BillStatus.Cancelled, BillStatus.Confirmed }; var weights = new[] { 1, 1, 4 }; int totalWeight = weights.Sum(); int randomNumber = random.Next(0, totalWeight); for (int i = 0; i < statuses.Length; i++) { if (randomNumber < weights[i]) return statuses[i]; randomNumber -= weights[i]; } return BillStatus.Confirmed; } private static string GetRandomAndRemove(List list, Random random) { int index = random.Next(list.Count); string value = list[index]; list.RemoveAt(index); return value; } private static DateTime[] GetRandomDays(int year, int month, int count) { var random = new Random(); int daysInMonthCount = DateTime.DaysInMonth(year, month); var daysInMonth = Enumerable.Range(1, daysInMonthCount).ToList(); var selectedDays = new List(); for (int i = 0; i < count && daysInMonth.Count > 0; i++) { int day = daysInMonth[random.Next(daysInMonth.Count)]; selectedDays.Add(day); daysInMonth.Remove(day); } return selectedDays.Select(day => new DateTime(year, month, day)).ToArray(); } }