namespace Admin.NET.Plugin.AiDOP.Order;
/// 订单评审资源检查编排。
public class OrderResourceCheckService : ITransient
{
private readonly ISqlSugarClient _db;
private readonly MaterialRequirementCalculator _calculator;
private readonly ResourceCheckResultWriter _writer;
public OrderResourceCheckService(
ISqlSugarClient db,
MaterialRequirementCalculator calculator,
ResourceCheckResultWriter writer)
{
_db = db;
_calculator = calculator;
_writer = writer;
}
public async Task RunForEntryAsync(
OrderWorkOrderGenerationService.OrderHeader order,
OrderWorkOrderGenerationService.OrderEntryLine entry,
string workOrd,
string account,
List warnings)
{
var lines = await _calculator.BuildLinesAsync(order, entry, warnings);
var morderId = await ResolveMorderIdAsync(workOrd, entry.TenantId);
return await _writer.WriteAsync(order, entry, workOrd, morderId, lines, account, DateTime.Now);
}
/// 仅运行资源检查计算,不写库、不依赖工单。返回计算结果与 BOM 展开明细。
public async Task<(OrderResourceCheckResult Result, List Lines)> CheckOnlyAsync(
OrderWorkOrderGenerationService.OrderHeader order,
OrderWorkOrderGenerationService.OrderEntryLine entry,
List warnings)
{
var lines = await _calculator.BuildLinesAsync(order, entry, warnings);
var activeLines = lines.Where(x => x.IsUse == 1).ToList();
var needTime = entry.SysCapacityDate ?? entry.PlanDate ?? DateTime.Today;
var hasShortage = activeLines.Any(x => x.LackQty > 0);
var kittingTime = activeLines
.Where(x => x.LackQty > 0)
.Select(x => x.KittingTime)
.DefaultIfEmpty(needTime)
.Max();
var result = new OrderResourceCheckResult
{
LineCount = activeLines.Count,
HasShortage = hasShortage,
KittingTime = kittingTime,
};
return (result, lines);
}
/// 将已有计算结果写入 b_examine_result / b_bom_child_examine(需先创建工单)。
public async Task WriteResultAsync(
OrderWorkOrderGenerationService.OrderHeader order,
OrderWorkOrderGenerationService.OrderEntryLine entry,
string workOrd,
List lines,
string account)
{
var morderId = await ResolveMorderIdAsync(workOrd, entry.TenantId);
return await _writer.WriteAsync(order, entry, workOrd, morderId, lines, account, DateTime.Now);
}
private async Task ResolveMorderIdAsync(string workOrd, long tenantId)
{
var id = await _db.Ado.GetLongAsync(
"""
SELECT Id FROM mes_morder
WHERE morder_no = @WorkOrd AND tenant_id = @TenantId AND IsDeleted = 0
ORDER BY Id DESC LIMIT 1
""",
new List
{
new("@WorkOrd", workOrd),
new("@TenantId", tenantId)
});
return id > 0 ? id : null;
}
}