using Indotalent.ConfigBackEnd.Extensions; using Indotalent.Data.Entities; using Indotalent.Data.Enums; using Microsoft.EntityFrameworkCore; namespace Indotalent.Infrastructure.Database.Demo; public static class InvoiceSeeder { public static async Task GenerateDataAsync(AppDbContext context) { if (await context.Invoice.AnyAsync()) return; var random = new Random(); var entityName = nameof(Invoice); var dateFinish = DateTime.Now; var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1); var confirmedSalesOrders = await context.SalesOrder .Where(so => so.OrderStatus == SalesOrderStatus.Confirmed) .Select(so => so.Id) .ToListAsync(); if (!confirmedSalesOrders.Any()) return; for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1)) { DateTime[] invoiceDates = GetRandomDays(date.Year, date.Month, 5); foreach (var invoiceDate in invoiceDates) { if (confirmedSalesOrders.Count == 0) break; var status = GetRandomStatus(random); var salesOrderId = GetRandomAndRemove(confirmedSalesOrders, random); var autoNo = await context.GenerateAutoNumberAsync( entityName: entityName, prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/" ); var invoice = new Invoice { AutoNumber = autoNo, InvoiceDate = invoiceDate, InvoiceStatus = status, Description = $"Invoice for {invoiceDate:MMMM yyyy}", SalesOrderId = salesOrderId }; await context.Invoice.AddAsync(invoice); } } await context.SaveChangesAsync(); } private static InvoiceStatus GetRandomStatus(Random random) { var statuses = new[] { InvoiceStatus.Draft, InvoiceStatus.Cancelled, InvoiceStatus.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 InvoiceStatus.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(); } }