From 29bb07532fd500eafd78eb55f58bcd8185754cf8 Mon Sep 17 00:00:00 2001 From: git_rabbit Date: Mon, 29 Dec 2025 14:26:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=87=BA=E5=85=A5=E5=BA=93?= =?UTF-8?q?=E5=8D=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MES/Material/MmInventoryService.cs | 215 ++++++++++-------- 1 file changed, 122 insertions(+), 93 deletions(-) diff --git a/DOAN.Service/MES/Material/MmInventoryService.cs b/DOAN.Service/MES/Material/MmInventoryService.cs index 9a532f0..23d9dd0 100644 --- a/DOAN.Service/MES/Material/MmInventoryService.cs +++ b/DOAN.Service/MES/Material/MmInventoryService.cs @@ -134,8 +134,8 @@ namespace DOAN.Service.BZFM .Where(it => it.Status == "启用") .Select(it => new MmTransactionOption { - Label = it.TypeName, - Value = it.TypeCode + Label = it.TypeName, + Value = it.TypeCode }) .ToList(); } @@ -151,54 +151,35 @@ namespace DOAN.Service.BZFM try { DateTime nowDate = DateTime.Now; - // 验证信息 - // 校验蓝单红单 - int receiptType = parm.ReceiptType; - decimal CurrentQty = parm.Quantity; - if(receiptType == 1) - { - CurrentQty = Math.Abs(CurrentQty); - } - else - { - CurrentQty = - Math.Abs(CurrentQty); - } - MmMaterial mmMaterial = Context.Queryable() - .Where(it => it.MaterialCode == parm.MaterialCode) - .First(); - if(mmMaterial == null) - { - return "物料不存在!"; - } + // 计算有符号变动量(蓝单为正,红单为负) + decimal delta = GetSignedQuantity(parm.ReceiptType, parm.Quantity); - // 验证信息 - MmLocation mmLocation = Context.Queryable() + // 校验物料和库位 + var mmMaterial = Context.Queryable().Where(it => it.MaterialCode == parm.MaterialCode).First(); + if (mmMaterial == null) return "物料不存在!"; + + var mmLocation = Context.Queryable() .Where(it => it.WarehouseCode == parm.WarehouseCode) .Where(it => it.LocationCode == parm.LocationCode) .First(); - if (mmLocation == null) - { - return "仓库编码或库位编码不存在!"; - } - bool hasInventory = true; - MmInventory mmInventory = Context.Queryable() - .Where(it => it.MaterialCode == parm.MaterialCode) - .Where(it => it.BatchNo == parm.BatchNo) - .Where(it => it.LocationCode == parm.LocationCode) - .First(); - if(mmInventory == null) - { - hasInventory = false; - } + if (mmLocation == null) return "仓库编码或库位编码不存在!"; + // 启用事务 Context.Ado.BeginTran(); - if (!hasInventory) - { + // 获取现有库存(同物料、批次、库位) + var mmInventory = Context.Queryable() + .Where(it => it.MaterialCode == parm.MaterialCode) + .Where(it => it.BatchNo == parm.BatchNo) + .Where(it => it.WarehouseCode == parm.WarehouseCode) + .Where(it => it.LocationCode == parm.LocationCode) + .First(); - // 添加库存 - MmInventory newInventory = new MmInventory() + // 若不存在则新增;存在则更新 + if (mmInventory == null) + { + var newInventory = new MmInventory() { MaterialCode = mmMaterial.MaterialCode, LocationCode = mmLocation.LocationCode, @@ -206,7 +187,7 @@ namespace DOAN.Service.BZFM WarehouseCode = mmLocation.WarehouseCode, WarehouseName = mmLocation.WarehouseName, BatchNo = parm.BatchNo, - CurrentQty = parm.Quantity, + CurrentQty = delta, Unit = parm.Unit, ExpiryDate = parm.ExpiryDate, LastUpdatedTime = null, @@ -218,14 +199,15 @@ namespace DOAN.Service.BZFM else { Context.Updateable(mmInventory) - .SetColumns(it => it.CurrentQty == it.CurrentQty + CurrentQty) + .SetColumns(it => it.CurrentQty == it.CurrentQty + delta) .ExecuteCommand(); } - // 插入记录 - MmRecordInbound newRecord = new MmRecordInbound() + + // 插入入库记录,入库单号使用自动增长策略(同日期按序号) + var inboundNo = GenerateReceiptNo("RK"); + MmRecordInbound newRecord = new() { - // TODO处理入库单号自动累计增加 - InboundNo = "RK" + DateTime.Now.ToString("yyyyMMdd"), + InboundNo = inboundNo, BatchNo = parm.BatchNo, Operator = parm.Operator, MaterialCode = mmMaterial.MaterialCode, @@ -262,55 +244,31 @@ namespace DOAN.Service.BZFM try { DateTime nowDate = DateTime.Now; - // 验证信息 - // 校验蓝单红单 - int receiptType = parm.ReceiptType; - decimal CurrentQty = parm.Quantity; - if (receiptType == 1) - { - CurrentQty = Math.Abs(CurrentQty); - } - else - { - CurrentQty = -Math.Abs(CurrentQty); - } - MmMaterial mmMaterial = Context.Queryable() - .Where(it => it.MaterialCode == parm.MaterialCode) - .First(); - if (mmMaterial == null) - { - return "物料不存在!"; - } + // 计算有符号变动量(蓝单为正,红单为负) + decimal delta = GetSignedQuantity(parm.ReceiptType, parm.Quantity); - // 验证信息 + var mmMaterial = Context.Queryable().Where(it => it.MaterialCode == parm.MaterialCode).First(); + if (mmMaterial == null) return "物料不存在!"; - MmLocation mmLocation = Context.Queryable() + var mmLocation = Context.Queryable() .Where(it => it.WarehouseCode == parm.WarehouseCode) .Where(it => it.LocationCode == parm.LocationCode) .First(); - if (mmLocation == null) - { - return "仓库编码或库位编码不存在!"; - } - bool hasInventory = true; - MmInventory mmInventory = Context.Queryable() - .Where(it => it.MaterialCode == parm.MaterialCode) - .Where(it => it.BatchNo == parm.BatchNo) - .Where(it => it.LocationCode == parm.LocationCode) - .First(); - if (mmInventory == null) - { - hasInventory = false; - } - // 启用事务 + if (mmLocation == null) return "仓库编码或库位编码不存在!"; + Context.Ado.BeginTran(); - if (!hasInventory) - { + var mmInventory = Context.Queryable() + .Where(it => it.MaterialCode == parm.MaterialCode) + .Where(it => it.BatchNo == parm.BatchNo) + .Where(it => it.WarehouseCode == parm.WarehouseCode) + .Where(it => it.LocationCode == parm.LocationCode) + .First(); - // 添加库存 - MmInventory newInventory = new MmInventory() + if (mmInventory == null) + { + var newInventory = new MmInventory() { MaterialCode = mmMaterial.MaterialCode, LocationCode = mmLocation.LocationCode, @@ -318,7 +276,7 @@ namespace DOAN.Service.BZFM WarehouseCode = mmLocation.WarehouseCode, WarehouseName = mmLocation.WarehouseName, BatchNo = parm.BatchNo, - CurrentQty = - parm.Quantity, + CurrentQty = -delta, Unit = parm.Unit, LastUpdatedTime = null, CreatedTime = nowDate @@ -327,15 +285,21 @@ namespace DOAN.Service.BZFM } else { + if (mmInventory.CurrentQty - delta < 0) + { + Context.Ado.RollbackTran(); + return "库存不足,无法出库"; + } + Context.Updateable(mmInventory) - .SetColumns(it => it.CurrentQty == it.CurrentQty - CurrentQty) + .SetColumns(it => it.CurrentQty == it.CurrentQty - delta) .ExecuteCommand(); } - // 插入记录 - MmRecordOutbound newRecord = new MmRecordOutbound() + + var outboundNo = GenerateReceiptNo("CK"); + MmRecordOutbound newRecord = new() { - // TODO处理出库单号自动累计增加 - OutboundNo = "CK" + DateTime.Now.ToString("yyyyMMdd"), + OutboundNo = outboundNo, BatchNo = parm.BatchNo, Operator = parm.Operator, MaterialCode = mmMaterial.MaterialCode, @@ -362,5 +326,70 @@ namespace DOAN.Service.BZFM } } + /// + /// 根据单据类型与数量计算有符号变动量(蓝单为正,红单为负) + /// + /// 1 表示蓝单(正),其它为红单(负) + /// 1 表示蓝单(正),其它为红单(负) + private static decimal GetSignedQuantity(int receiptType, decimal quantity) + { + return receiptType == 1 ? Math.Abs(quantity) : -Math.Abs(quantity); + } + + /// + /// 生成单据编号,格式:{prefix}{yyyyMMdd}-{nnn} + /// 例如:RK20251225-001 + /// + private string GenerateReceiptNo(string prefix) + { + var datePart = DateTime.Now.ToString("yyyyMMdd"); + var baseNo = prefix + datePart + "-"; + + // 尝试从入库/出库表中获取当天最大的编号后缀 + try + { + if (prefix == "RK") + { + var last = Context.Queryable() + .Where(it => it.InboundNo.StartsWith(prefix + datePart)) + .OrderBy(it => it.InboundNo + " desc") + .Select(it => it.InboundNo) + .First(); + if (string.IsNullOrEmpty(last)) + { + return baseNo + "001"; + } + var suf = last.Substring((prefix + datePart).Length).TrimStart('-', '_'); + if (int.TryParse(suf, out var n)) + { + return baseNo + (n + 1).ToString("D3"); + } + return baseNo + "001"; + } + else + { + var last = Context.Queryable() + .Where(it => it.OutboundNo.StartsWith(prefix + datePart)) + .OrderBy(it => it.OutboundNo + " desc") + .Select(it => it.OutboundNo) + .First(); + if (string.IsNullOrEmpty(last)) + { + return baseNo + "001"; + } + var suf = last.Substring((prefix + datePart).Length).TrimStart('-', '_'); + if (int.TryParse(suf, out var n)) + { + return baseNo + (n + 1).ToString("D3"); + } + return baseNo + "001"; + } + } + catch + { + return baseNo + "001"; + } + } + } } \ No newline at end of file