using Indotalent.ConfigBackEnd.Extensions; using Indotalent.Data.Entities; using Indotalent.Data.Enums; using Microsoft.EntityFrameworkCore; namespace Indotalent.Infrastructure.Database.Demo; public static class PaymentDisburseSeeder { public static async Task GenerateDataAsync(AppDbContext context) { if (await context.PaymentDisburse.AnyAsync()) return; var random = new Random(); var entityName = nameof(PaymentDisburse); var dateFinish = DateTime.Now; var dateStart = new DateTime(dateFinish.AddMonths(-12).Year, dateFinish.AddMonths(-12).Month, 1); var confirmedBills = await context.Bill .Include(b => b.PurchaseOrder) .Where(b => b.BillStatus == BillStatus.Confirmed) .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 (confirmedBills.Count == 0) break; var status = GetRandomStatus(random); var bill = GetRandomAndRemove(confirmedBills, random); var paymentMethodId = GetRandomValue(paymentMethods, random); var autoNo = await context.GenerateAutoNumberAsync( entityName: entityName, prefixTemplate: $"{entityName.ToShortNameConsonant(3)}/{{Year}}/" ); var paymentDisburse = new PaymentDisburse { AutoNumber = autoNo, Description = $"Payment Disbursed on {paymentDate:MMMM yyyy}", PaymentDate = paymentDate, PaymentMethodId = paymentMethodId, PaymentAmount = bill.PurchaseOrder?.AfterTaxAmount, Status = status, BillId = bill.Id }; await context.PaymentDisburse.AddAsync(paymentDisburse); } } await context.SaveChangesAsync(); } private static PaymentDisburseStatus GetRandomStatus(Random random) { var statuses = new[] { PaymentDisburseStatus.Draft, PaymentDisburseStatus.Cancelled, PaymentDisburseStatus.Confirmed, PaymentDisburseStatus.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 PaymentDisburseStatus.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(); } }