using Admin.NET.Plugin.AiDOP.MaterialWarehouse.Dto;
namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
///
/// S5 库存查询 只读 list 服务。
///
/// 数据源:aidopdev.LocationMaster ⋈ LocationDetail(现存量),忠实复刻旧系统存储过程
/// pr_WMS_GetMissedLocationQty 主口径:Domain 过滤 + (AvailStatusQty+Assay+FreezeQty)>0,
/// 类型 LocType 由 LocationMaster.Typed 派生(VMI / Supp→O库),join ItemMaster(名称/单位)、
/// 富集 MissedPrint(货架/版本/供应商,Status not in U/P/C、Location 非空、Qty>0,按库位·物料·批次聚合)。
/// Domain 由 GeneralizedCodeMaster(SystemConfig/CompanyCode) 解析,默认 8010。
///
/// 忠实度说明:存储过程「多货架行拆分 + 按 MissedPrint 状态重算量」(原过程第 99-121 行) 仅在同一
/// 库位·物料·批次存在多货架时生效;当前 MissedPrint 为 0 行,其效果为零且无数据可验,本服务不复刻该拆分
/// (LocCount≤1 场景即 base + 富集,与现数据一致)。MissedPrint 回补后如需多货架拆分,另起批次复验。
///
/// 本服务仅 SELECT:无新增/编辑/删除/库存事务/状态流转;LocationDetail 无 tenant_id,不做租户过滤。
///
[ApiDescriptionSettings(Order = 300, Description = "库存查询")]
[Route("api/S5StockQuery")]
[AllowAnonymous]
[NonUnify]
public class StockQueryService : IDynamicApiController, ITransient
{
private readonly ISqlSugarClient _db;
public StockQueryService(ISqlSugarClient db)
{
_db = db;
}
private sealed class GrandTotals
{
public decimal QtyOnHand { get; set; }
public decimal Unrestricted { get; set; }
public decimal Qc { get; set; }
public decimal Frozen { get; set; }
}
/// 解析公司域(GeneralizedCodeMaster SystemConfig/CompanyCode,默认 8010)。
private async Task ResolveDomainAsync()
{
var list = await _db.Ado.SqlQueryAsync(
"SELECT Domain FROM GeneralizedCodeMaster WHERE FldName='SystemConfig' AND Val='CompanyCode' ORDER BY RecID LIMIT 1");
var domain = list.FirstOrDefault();
return string.IsNullOrWhiteSpace(domain) ? "8010" : domain;
}
// 派生 LocType 表达式(与存储过程一致)
private const string LocTypeExpr = "CASE WHEN t.typed='VMI' THEN 'VMI' WHEN t.typed='Supp' THEN 'O库' ELSE '' END";
///
/// 库存查询列表(只读分页查询)。
///
[DisplayName("库存查询列表")]
[HttpGet("list")]
public async Task