using Indotalent.ConfigBackEnd.Extensions; using Indotalent.Data.Entities; using Indotalent.Data.Enums; using Microsoft.EntityFrameworkCore; namespace Indotalent.Infrastructure.Database.Demo; public static class PaymentReceiveSeeder { public static async Task GenerateDataAsync(AppDbContext context) { if (await context.PaymentReceive.AnyAsync()) return; var random = new Random(); var entityName = nameof(PaymentReceive); var dateFinish = DateTime.Now; var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1); var confirmedInvoices = await context.Invoice .Include(i => i.SalesOrder) .Where(i => i.InvoiceStatus == InvoiceStatus.Confirmed && i.SalesOrder != null) .ToListAsync(); var paymentMethods = await context.PaymentMethod .Select(pm => pm.Id) .ToListAsync(); if (!paymentMethods.Any()) return; for (DateTime date = dateStart; date < dateFinish; date = date.AddMonths(1)) { DateTime[] paymentDates = GetRandomDays(date.Year, date.Month, 4); foreach (var paymentDate in paymentDates) { if (confirmedInvoices.Count == 0) break; var status = GetRandomStatus(random); var invoice = GetRandomAndRemove(confirmedInvoices, random); var paymentMethodId = GetRandomValue(paymentMethods, random); var autoNo = await context.GenerateAutoNumberAsync( entityName: entityName, prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/" ); var paymentReceive = new PaymentReceive { AutoNumber = autoNo, Description = $"Payment Received on {paymentDate:MMMM yyyy}", PaymentDate = paymentDate, PaymentMethodId = paymentMethodId, PaymentAmount = invoice?.SalesOrder?.AfterTaxAmount, Status = status, InvoiceId = invoice?.Id }; await context.PaymentReceive.AddAsync(paymentReceive); } } await context.SaveChangesAsync(); } private static PaymentReceiveStatus GetRandomStatus(Random random) { var statuses = new[] { PaymentReceiveStatus.Draft, PaymentReceiveStatus.Cancelled, PaymentReceiveStatus.Confirmed, PaymentReceiveStatus.Archived }; var weights = new[] { 1, 1, 4, 1 }; 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 PaymentReceiveStatus.Confirmed; } private static T GetRandomAndRemove(List list, Random random) { int index = random.Next(list.Count); T value = list[index]; list.RemoveAt(index); return value; } private static T GetRandomValue(List list, Random random) { return list[random.Next(list.Count)]; } 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(); } }