using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Haoliang.Models.Production; using Haoliang.Data.Repositories; namespace Haoliang.Data.Repositories { public interface IProgramProductionSummaryRepository : IRepository { Task GetByDeviceAndDateAsync(int deviceId, DateTime date); Task> GetByDateAsync(DateTime date); Task> GetByDeviceAsync(int deviceId); Task> GetByProgramAsync(string programName); Task GetByDeviceAndProgramAsync(int deviceId, string programName); Task> GetByDateRangeAsync(DateTime startDate, DateTime endDate); Task GetTotalProductionAsync(DateTime date); Task UpdateProductionSummaryAsync(int deviceId, string programName, int quantity); Task ArchiveProductionSummariesAsync(int daysToKeep = 90); } public class ProgramProductionSummaryRepository : Repository, IProgramProductionSummaryRepository { private readonly CNCDbContext _context; public ProgramProductionSummaryRepository(CNCDbContext context) : base(context) { _context = context; } public async Task GetByDeviceAndDateAsync(int deviceId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); return await _context.ProgramProductionSummaries .FirstOrDefaultAsync(p => p.DeviceId == deviceId && p.ProductionDate >= startOfDay && p.ProductionDate < endOfDay); } public async Task> GetByDateAsync(DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); return await _context.ProgramProductionSummaries .Where(p => p.ProductionDate >= startOfDay && p.ProductionDate < endOfDay) .OrderBy(p => p.DeviceName) .ThenBy(p => p.ProgramName) .ToListAsync(); } public async Task> GetByDeviceAsync(int deviceId) { return await _context.ProgramProductionSummaries .Where(p => p.DeviceId == deviceId) .OrderByDescending(p => p.ProductionDate) .ThenBy(p => p.ProgramName) .ToListAsync(); } public async Task> GetByProgramAsync(string programName) { return await _context.ProgramProductionSummaries .Where(p => p.ProgramName == programName) .OrderByDescending(p => p.ProductionDate) .ThenBy(p => p.DeviceName) .ToListAsync(); } public async Task GetByDeviceAndProgramAsync(int deviceId, string programName) { var today = DateTime.Today; return await _context.ProgramProductionSummaries .FirstOrDefaultAsync(p => p.DeviceId == deviceId && p.ProgramName == programName && p.ProductionDate == today); } public async Task> GetByDateRangeAsync(DateTime startDate, DateTime endDate) { return await _context.ProgramProductionSummaries .Where(p => p.ProductionDate >= startDate && p.ProductionDate <= endDate) .OrderBy(p => p.ProductionDate) .ThenBy(p => p.DeviceName) .ThenBy(p => p.ProgramName) .ToListAsync(); } public async Task GetTotalProductionAsync(DateTime date) { var summaries = await GetByDateAsync(date); var totalSummary = new ProductionSummary { ProductionDate = date, TotalDevices = summaries.Select(s => s.DeviceId).Distinct().Count(), TotalPrograms = summaries.Count(), TotalQuantity = summaries.Sum(s => s.Quantity), AverageQuantity = summaries.Any() ? summaries.Average(s => s.Quantity) : 0, DeviceSummaries = summaries.GroupBy(s => s.DeviceId) .Select(g => new DeviceProductionSummary { DeviceId = g.Key, DeviceName = g.FirstOrDefault()?.DeviceName ?? "", TotalQuantity = g.Sum(s => s.Quantity), ProgramCount = g.Count(), Programs = g.Select(s => new ProgramSummary { ProgramName = s.ProgramName, Quantity = s.Quantity, Percentage = g.Sum(s => s.Quantity) > 0 ? (decimal)s.Quantity / g.Sum(s => s.Quantity) * 100 : 0 }).ToList() }).ToList() }; return totalSummary; } public async Task UpdateProductionSummaryAsync(int deviceId, string programName, int quantity) { var today = DateTime.Today; var summary = await GetByDeviceAndProgramAsync(deviceId, programName); if (summary != null) { // Update existing summary summary.Quantity += quantity; summary.UpdatedAt = DateTime.Now; _context.ProgramProductionSummaries.Update(summary); } else { // Create new summary var device = await _context.Devices.FindAsync(deviceId); summary = new ProgramProductionSummary { DeviceId = deviceId, DeviceName = device?.DeviceName ?? "", ProgramName = programName, Quantity = quantity, ProductionDate = today, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; _context.ProgramProductionSummaries.Add(summary); } await SaveAsync(); return true; } public async Task ArchiveProductionSummariesAsync(int daysToKeep = 90) { var cutoffDate = DateTime.Today.AddDays(-daysToKeep); var summariesToArchive = await _context.ProgramProductionSummaries .Where(p => p.ProductionDate < cutoffDate) .ToListAsync(); if (summariesToArchive.Any()) { // In a real implementation, you would move these to an archive table _context.ProgramProductionSummaries.RemoveRange(summariesToArchive); await SaveAsync(); } } } }