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 IProductionSummaryRepository : IRepository { Task GetByDateAsync(DateTime date); Task> GetByDateRangeAsync(DateTime startDate, DateTime endDate); Task GetByDeviceAndDateAsync(int deviceId, DateTime date); Task GetTodaySummaryAsync(); Task GetYesterdaySummaryAsync(); Task GetWeeklySummaryAsync(DateTime weekStart); Task GetMonthlySummaryAsync(int year, int month); Task GetBestPerformingDeviceAsync(DateTime date); Task GetWorstPerformingDeviceAsync(DateTime date); Task ArchiveProductionSummariesAsync(int daysToKeep = 90); } public class ProductionSummaryRepository : Repository, IProductionSummaryRepository { private readonly CNCDbContext _context; public ProductionSummaryRepository(CNCDbContext context) : base(context) { _context = context; } public async Task GetByDateAsync(DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); return await _context.ProductionSummaries .FirstOrDefaultAsync(s => s.ProductionDate >= startOfDay && s.ProductionDate < endOfDay); } public async Task> GetByDateRangeAsync(DateTime startDate, DateTime endDate) { return await _context.ProductionSummaries .Where(s => s.ProductionDate >= startDate && s.ProductionDate <= endDate) .OrderBy(s => s.ProductionDate) .ThenBy(s => s.DeviceName) .ToListAsync(); } public async Task GetByDeviceAndDateAsync(int deviceId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); return await _context.ProductionSummaries .FirstOrDefaultAsync(s => s.DeviceId == deviceId && s.ProductionDate >= startOfDay && s.ProductionDate < endOfDay); } public async Task GetTodaySummaryAsync() { return await GetByDateAsync(DateTime.Today); } public async Task GetYesterdaySummaryAsync() { return await GetByDateAsync(DateTime.Today.AddDays(-1)); } public async Task GetWeeklySummaryAsync(DateTime weekStart) { var weekEnd = weekStart.AddDays(7); var summaries = await _context.ProductionSummaries .Where(s => s.ProductionDate >= weekStart && s.ProductionDate < weekEnd) .ToListAsync(); var weeklySummary = new WeeklyProductionSummary { WeekStart = weekStart, WeekEnd = weekEnd, TotalDevices = summaries.Select(s => s.DeviceId).Distinct().Count(), TotalQuantity = summaries.Sum(s => s.TotalQuantity), AverageDailyQuantity = summaries.Any() ? summaries.Average(s => s.TotalQuantity) : 0, DailySummaries = summaries .GroupBy(s => s.ProductionDate) .Select(g => new DailyProductionSummary { Date = g.Key, TotalQuantity = g.Sum(s => s.TotalQuantity), DeviceCount = g.Select(s => s.DeviceId).Distinct().Count() }) .OrderBy(d => d.Date) .ToList() }; return weeklySummary; } public async Task GetMonthlySummaryAsync(int year, int month) { var monthStart = new DateTime(year, month, 1); var monthEnd = monthStart.AddMonths(1); var summaries = await _context.ProductionSummaries .Where(s => s.ProductionDate >= monthStart && s.ProductionDate < monthEnd) .ToListAsync(); var monthlySummary = new MonthlyProductionSummary { Year = year, Month = month, TotalDevices = summaries.Select(s => s.DeviceId).Distinct().Count(), TotalQuantity = summaries.Sum(s => s.TotalQuantity), AverageDailyQuantity = summaries.Any() ? summaries.Average(s => s.TotalQuantity) : 0, WeeklySummaries = new List() }; // Group by week var weeks = summaries .GroupBy(s => s.ProductionDate - TimeSpan.FromDays((int)s.ProductionDate.DayOfWeek)) .ToList(); foreach (var week in weeks) { var weeklySummary = new WeeklyProductionSummary { WeekStart = week.Key, WeekEnd = week.Key.AddDays(7), TotalQuantity = week.Sum(s => s.TotalQuantity), DailySummaries = week .GroupBy(s => s.ProductionDate) .Select(g => new DailyProductionSummary { Date = g.Key, TotalQuantity = g.Sum(s => s.TotalQuantity), DeviceCount = g.Select(s => s.DeviceId).Distinct().Count() }) .OrderBy(d => d.Date) .ToList() }; monthlySummary.WeeklySummaries.Add(weeklySummary); } return monthlySummary; } public async Task GetBestPerformingDeviceAsync(DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); var summaries = await _context.ProductionSummaries .Where(s => s.ProductionDate >= startOfDay && s.ProductionDate < endOfDay) .ToListAsync(); if (!summaries.Any()) return null; return summaries .OrderByDescending(s => s.TotalQuantity) .FirstOrDefault(); } public async Task GetWorstPerformingDeviceAsync(DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); var summaries = await _context.ProductionSummaries .Where(s => s.ProductionDate >= startOfDay && s.ProductionDate < endOfDay) .ToListAsync(); if (!summaries.Any()) return null; return summaries .OrderBy(s => s.TotalQuantity) .FirstOrDefault(); } public async Task ArchiveProductionSummariesAsync(int daysToKeep = 90) { var cutoffDate = DateTime.Today.AddDays(-daysToKeep); var summariesToArchive = await _context.ProductionSummaries .Where(s => s.ProductionDate < cutoffDate) .ToListAsync(); if (summariesToArchive.Any()) { // In a real implementation, you would move these to an archive table _context.ProductionSummaries.RemoveRange(summariesToArchive); await SaveAsync(); } } } }