using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos.Prod;
using F9WebAiTest.Domain.Common;
using F9WebAiTest.Domain.Entities.Prod;
namespace F9WebAiTest.Application.Services.Prod;
/// 丝片台帐:每日一条,记录浸丝 / 返丝 / 编丝 / 整理片数
public interface ISptzService
{
Task> GetPagedAsync(int pageIndex, int pageSize, DateTime dateFrom, DateTime dateTo);
Task GetForEditAsync(long id);
Task GetDefaultsAsync(DateTime date);
Task SaveAsync(SptzSaveDto dto);
Task DeleteAsync(long id);
}
public class SptzService : ISptzService
{
private readonly IRepository _sptzRepo;
private readonly IRepository _spjcRepo;
public SptzService(IRepository sptzRepo, IRepository spjcRepo)
{
_sptzRepo = sptzRepo;
_spjcRepo = spjcRepo;
}
public async Task> GetPagedAsync(int pageIndex, int pageSize, DateTime dateFrom, DateTime dateTo)
{
var all = await _sptzRepo.GetAllAsync();
var from = dateFrom.Date;
var to = dateTo.Date;
var q = all.AsQueryable().Where(x => x.Date.Date >= from && x.Date.Date <= to);
var total = q.LongCount();
var items = q.OrderBy(x => x.Date).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
return new PageResult
{
Items = items.Select(ToListDto).ToList(),
Total = total, PageIndex = pageIndex, PageSize = pageSize
};
}
public async Task GetForEditAsync(long id)
{
var e = await _sptzRepo.GetByIdAsync(id);
if (e == null) throw new ServiceException("丝片台帐不存在或已删除", 404);
return new SptzSaveDto
{
Id = e.Id,
Date = e.Date,
DateLast = e.DateLast,
JsShangcun = e.JsShangcun,
JsXiasi = e.JsXiasi,
JsJinsi = e.JsJinsi,
FsFsps = e.FsFsps,
BsBsps = e.BsBsps,
ZlZhengpin = e.ZlZhengpin,
ZlTichu = e.ZlTichu,
Memo = e.Memo
};
}
///
/// 新增默认值:上一本台账日期 + 其上存(= 上一日今存),并按当日「丝片检查」汇总出整理正品/剔除片数。
///
public async Task GetDefaultsAsync(DateTime date)
{
var target = date.Date;
var all = await _sptzRepo.GetAllAsync();
var latest = all.Where(x => x.Date.Date < target).OrderByDescending(x => x.Date).FirstOrDefault();
var latestAny = all.OrderByDescending(x => x.Date).FirstOrDefault();
var spjcs = (await _spjcRepo.GetAllAsync()).Where(x => x.Date.Date == target).ToList();
var tichu = spjcs.Sum(x => x.QsJiahua + x.QsYouwu + x.QsHeidian + x.QsShangsi
+ x.QsYetiao + x.QsXiaosipian + x.QsQita);
var zhengpin = spjcs.Sum(x => x.Pianshu + x.PianshuXuegong) - tichu;
return new SptzDefaultsDto
{
Date = target,
DateLast = latest?.Date,
JsShangcun = latest?.JsJincun ?? 0,
LatestDate = latestAny?.Date,
ZlTichu = tichu,
ZlZhengpin = zhengpin,
HasSpjc = spjcs.Count > 0
};
}
public async Task SaveAsync(SptzSaveDto dto)
{
var date = dto.Date.Date;
Sptz e;
if (dto.Id > 0)
{
e = await _sptzRepo.GetByIdAsync(dto.Id);
if (e == null) throw new ServiceException("丝片台帐不存在或已删除", 404);
var dup = await _sptzRepo.FirstOrDefaultAsync(x => x.Id != dto.Id && x.Date.Date == date);
if (dup != null) throw new ServiceException($"已存在 {date:yyyy-MM-dd} 的丝片台帐!");
}
else
{
var exists = await _sptzRepo.AnyAsync(x => x.Date.Date == date);
if (exists) throw new ServiceException($"已存在 {date:yyyy-MM-dd} 的丝片台帐!");
e = new Sptz();
await _sptzRepo.AddAsync(e);
}
e.Date = date;
e.DateLast = dto.DateLast == default ? date.AddDays(-1) : dto.DateLast.Date;
e.JsShangcun = dto.JsShangcun;
e.JsXiasi = dto.JsXiasi;
e.JsJinsi = dto.JsJinsi;
e.FsFsps = dto.FsFsps;
e.BsBsps = dto.BsBsps;
e.ZlZhengpin = dto.ZlZhengpin;
e.ZlTichu = dto.ZlTichu;
e.Memo = dto.Memo ?? "";
// 派生值由服务端重算(与 F9 一致):上日遗留/今日新增 = 上存 − 浸丝;今存 = 下丝 + 上日遗留/今日新增
e.JsSrylJrxz = e.JsShangcun - e.JsJinsi;
e.JsJincun = e.JsXiasi + e.JsSrylJrxz;
await _sptzRepo.UpdateAsync(e);
return e.Id;
}
public async Task DeleteAsync(long id)
{
var e = await _sptzRepo.GetByIdAsync(id);
if (e == null) throw new ServiceException("丝片台帐不存在或已删除", 404);
// 日期带唯一索引,物理删除避免「删除后重建」撞索引(与煮茧日报同一策略)
await _sptzRepo.HardDeleteAsync(e);
}
private static SptzListItemDto ToListDto(Sptz x) => new()
{
Id = x.Id,
Date = x.Date,
DateLast = x.DateLast,
JsShangcun = x.JsShangcun,
JsXiasi = x.JsXiasi,
JsJinsi = x.JsJinsi,
JsSrylJrxz = x.JsSrylJrxz,
JsJincun = x.JsJincun,
FsFsps = x.FsFsps,
BsBsps = x.BsBsps,
ZlZhengpin = x.ZlZhengpin,
ZlTichu = x.ZlTichu,
Memo = x.Memo
};
}