using Microsoft.EntityFrameworkCore; using PowderCoating.Core.Entities; using PowderCoating.Core.Enums; namespace PowderCoating.Infrastructure.Services; public partial class SeedDataService { /// /// Seeds maintenance records for all seeded equipment: historical completed records, /// upcoming scheduled records, and one overdue record for the Pressure Pot so the /// Equipment Maintenance report always has meaningful data. /// /// /// /// Each piece of equipment gets 2-3 completed historical maintenance records (up to /// 12 months back) plus one upcoming scheduled record. The Pressure Pot additionally /// has one overdue record (past due date, still Scheduled) to populate the overdue /// indicator on the Equipment page. /// /// /// Labor and parts costs are realistic for shop equipment maintenance, giving the /// Equipment Maintenance Cost report non-trivial totals from day one. /// /// /// Idempotency: bails early if any maintenance records already exist for this company's equipment. /// /// private async Task SeedMaintenanceRecordsAsync(Company company) { var equipmentIds = await _context.Set() .IgnoreQueryFilters() .Where(e => e.CompanyId == company.Id && !e.IsDeleted && SeededEquipmentSerials.Contains(e.SerialNumber)) .Select(e => e.Id) .ToListAsync(); if (equipmentIds.Count == 0) return 0; var existingCount = await _context.Set() .IgnoreQueryFilters() .CountAsync(m => equipmentIds.Contains(m.EquipmentId)); if (existingCount > 0) return 0; var equipment = await _context.Set() .IgnoreQueryFilters() .Where(e => equipmentIds.Contains(e.Id)) .ToListAsync(); // Try to grab a worker user to assign as performed-by var worker = await _userManager.Users .Where(u => u.CompanyId == company.Id && u.IsActive) .FirstOrDefaultAsync(); var now = DateTime.UtcNow; var records = new List(); // Per-equipment maintenance spec: (type, daysAgoFirst, intervalDays, laborCost, partsCost, notes) // Each equipment gets 2 completed records + 1 scheduled upcoming. // The Pressure Pot also gets 1 overdue record. static (string type, decimal labor, decimal parts, string desc, string work) MaintSpec(int i) => (i % 5) switch { 0 => ("Preventive", 120m, 45m, "Quarterly preventive maintenance", "Inspected elements, cleaned contacts, checked gaskets"), 1 => ("Inspection", 80m, 0m, "Monthly operational inspection", "Checked all systems, calibrated temperature probes"), 2 => ("Repair", 200m, 185m, "Filter and seal replacement", "Replaced intake filters and worn door seals"), 3 => ("Preventive", 140m, 60m, "Semi-annual preventive maintenance", "Lubricated moving parts, replaced wear items"), _ => ("Inspection", 60m, 0m, "Pre-season inspection and cleaning", "Full operational test, cleaned all surfaces"), }; int idx = 0; foreach (var eq in equipment) { var isPressurePot = eq.SerialNumber == "CLM101223456"; // Media Blast Room / Pressure Pot for (int r = 0; r < 2; r++) { var (mtype, labor, parts, desc, work) = MaintSpec(idx + r); var daysAgo = 180 - r * 60 - (idx % 4) * 15; var scheduled = now.AddDays(-daysAgo); var total = labor + parts; records.Add(new MaintenanceRecord { EquipmentId = eq.Id, MaintenanceType = mtype, Status = MaintenanceStatus.Completed, Priority = MaintenancePriority.Normal, ScheduledDate = scheduled, CompletedDate = scheduled.AddDays(1), PerformedById = worker?.Id, AssignedUserId = worker?.Id, Description = desc, WorkPerformed = work, LaborCost = labor, PartsCost = parts, TotalCost = total, DowntimeHours = 2m + r, CompanyId = company.Id, CreatedAt = scheduled.AddDays(-7) }); } // One upcoming scheduled record var upcomingDays = 15 + (idx % 30); records.Add(new MaintenanceRecord { EquipmentId = eq.Id, MaintenanceType = "Preventive", Status = MaintenanceStatus.Scheduled, Priority = MaintenancePriority.Normal, ScheduledDate = now.AddDays(upcomingDays), AssignedUserId = worker?.Id, Description = "Scheduled preventive maintenance", LaborCost = 0m, PartsCost = 0m, TotalCost = 0m, CompanyId = company.Id, CreatedAt = now.AddDays(-7) }); // Overdue record for the pressure pot only if (isPressurePot) { records.Add(new MaintenanceRecord { EquipmentId = eq.Id, MaintenanceType = "Repair", Status = MaintenanceStatus.Scheduled, Priority = MaintenancePriority.High, ScheduledDate = now.AddDays(-20), // overdue AssignedUserId = worker?.Id, Description = "Filter replacement — OVERDUE", Notes = "Media filter became clogged ahead of schedule. Shop is running reduced blast capacity until repaired.", LaborCost = 0m, PartsCost = 0m, TotalCost = 0m, CompanyId = company.Id, CreatedAt = now.AddDays(-30) }); } idx++; } await _context.Set().AddRangeAsync(records); await _context.SaveChangesAsync(); return records.Count; } }