You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
8.0 KiB
C#

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<ProductionSummary>
{
Task<ProductionSummary> GetByDateAsync(DateTime date);
Task<IEnumerable<ProductionSummary>> GetByDateRangeAsync(DateTime startDate, DateTime endDate);
Task<ProductionSummary> GetByDeviceAndDateAsync(int deviceId, DateTime date);
Task<ProductionSummary> GetTodaySummaryAsync();
Task<ProductionSummary> GetYesterdaySummaryAsync();
Task<WeeklyProductionSummary> GetWeeklySummaryAsync(DateTime weekStart);
Task<MonthlyProductionSummary> GetMonthlySummaryAsync(int year, int month);
Task<ProductionSummary> GetBestPerformingDeviceAsync(DateTime date);
Task<ProductionSummary> GetWorstPerformingDeviceAsync(DateTime date);
Task ArchiveProductionSummariesAsync(int daysToKeep = 90);
}
public class ProductionSummaryRepository : Repository<ProductionSummary>, IProductionSummaryRepository
{
private readonly CNCDbContext _context;
public ProductionSummaryRepository(CNCDbContext context) : base(context)
{
_context = context;
}
public async Task<ProductionSummary> 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<IEnumerable<ProductionSummary>> 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<ProductionSummary> 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<ProductionSummary> GetTodaySummaryAsync()
{
return await GetByDateAsync(DateTime.Today);
}
public async Task<ProductionSummary> GetYesterdaySummaryAsync()
{
return await GetByDateAsync(DateTime.Today.AddDays(-1));
}
public async Task<WeeklyProductionSummary> 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<MonthlyProductionSummary> 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<WeeklyProductionSummary>()
};
// 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<ProductionSummary> 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<ProductionSummary> 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();
}
}
}
}