using Admin.NET.Plugin.AiDOP.FinishedWarehouse.Dto;
namespace Admin.NET.Plugin.AiDOP.FinishedWarehouse;
///
/// S7 生产入库单列表 只读 list 服务。
///
/// 数据源(2026-07-30 起):DOP 数据中台标准层 mdp_std_production_receipt(扁平,一行=一条 NbrDetail 明细)。
/// 该 std 由 ProductionReceiptMdpSyncService 从 aidopdev.NbrMaster/NbrDetail Type='WOI'(生产入库)同步标准化而来,且已双源(dopdemorq)。
/// S7 成品入库与 S5 生产收货读同一批 WOI 数据(过滤逐字相同)→ CTO 拍板复用该 std、不另建管线/实体(S5-list 与 S7-list 展示同一 WOI 单据的两个视角)。
///
/// 口径映射(std 列 → 列表列):入库单号=nbr;行号=line;入库日期=receipt_date;状态=status;入库类型=remark;
/// 生产线=prod_line;工单号=work_ord;ERP工单号=erp_work_ord;物料编码=item_num;名称=item_name;规格=item_spec;
/// 入库库位=location_to;批次=lot_serial;入库数量=qty_rec;单位=um;相关单号=ord_nbr。
///
/// 本服务仅 SELECT:无新增/编辑/删除/入库写入/库存事务/状态流转。租户口径对齐 ProductionReceiptService:
/// 仅当 input.TenantId>0 才按 m.tenant_id 过滤(receipt std tenant 由同步入站上下文赋值,默认租户可能空态)。
///
[ApiDescriptionSettings(Order = 310, Description = "生产入库单列表")]
[Route("api/S7ProductionInbound")]
[NonUnify]
public class ProductionInboundService : IDynamicApiController, ITransient
{
/// 主/系统租户哨兵:超管未选择目标租户时其 JWT TenantId 即此值,拒绝作为业务租户。
private const long MainTenantId = 1300000000001L;
private readonly ISqlSugarClient _db;
private readonly UserManager _userManager;
public ProductionInboundService(ISqlSugarClient db, UserManager userManager)
{
_db = db;
_userManager = userManager;
}
/// 严格可信租户解析:只来自认证后 JWT;无 Token(<=0) 或超管未选主租户 → 拒绝;不读前端 tenantId、无默认回退。
private long ResolveTenantOrThrow()
{
var tid = _userManager.TenantId;
if (tid <= 0)
throw Oops.Oh("无法确定当前租户,请重新登录或选择目标租户");
if (_userManager.SuperAdmin && tid == MainTenantId)
throw Oops.Oh("超级管理员操作前必须选择目标租户");
return tid;
}
///
/// 生产入库单列表(只读分页查询,扁平:一行=一条明细;读数据中台标准层 mdp_std_production_receipt)。
///
[DisplayName("生产入库单列表")]
[HttpGet("list")]
public async Task