diff --git a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs
index e59b661..e10132c 100644
--- a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs
+++ b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs
@@ -288,5 +288,32 @@ namespace DOAN.Admin.WebApi.Controllers.BZFM
return SUCCESS(response);
}
+
+ ///
+ /// 出货操作
+ ///
+ ///
+ [HttpPost("Shipment")]
+ [AllowAnonymous]
+ [Log(Title = "出货操作", BusinessType = BusinessType.INSERT)]
+ public IActionResult Shipment([FromBody] ShipmentDto parm)
+ {
+ try
+ {
+ string response = _MmInventoryService.Shipment(parm);
+ if (response == "ok")
+ {
+ return ToResponse(new ApiResult(200, "ok"));
+ }
+ else
+ {
+ return ToResponse(new ApiResult(500, response));
+ }
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
}
}
diff --git a/DOAN.Model/MES/Material/Dto/ShipmentDto.cs b/DOAN.Model/MES/Material/Dto/ShipmentDto.cs
new file mode 100644
index 0000000..52335c6
--- /dev/null
+++ b/DOAN.Model/MES/Material/Dto/ShipmentDto.cs
@@ -0,0 +1,52 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace DOAN.Model.BZFM.Dto
+{
+ ///
+ /// 出货请求参数
+ ///
+ public class ShipmentDto
+ {
+ [Required(ErrorMessage = "物料编码不能为空")]
+ public string MaterialCode { get; set; }
+
+ [Required(ErrorMessage = "出货数量不能为空")]
+ public decimal Quantity { get; set; }
+
+ [Required(ErrorMessage = "仓库编码不能为空")]
+ public string WarehouseCode { get; set; }
+
+ [Required(ErrorMessage = "库位编码不能为空")]
+ public string LocationCode { get; set; }
+
+ public string BatchNo { get; set; }
+
+ [Required(ErrorMessage = "操作员不能为空")]
+ public string Operator { get; set; }
+
+ public string Workorder { get; set; }
+
+ public string WorkorderRaw { get; set; }
+
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "交易类型不能为空")]
+ public string TransactionType { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remarks { get; set; }
+
+ ///
+ /// 客户订单号
+ ///
+ [Required(ErrorMessage = "客户订单号不能为空")]
+ public string CustomerOrder { get; set; }
+
+ ///
+ /// 单据类型:1-蓝单正向,2-红单逆向
+ ///
+ public int ReceiptType { get; set; } = 1;
+ }
+}
\ No newline at end of file
diff --git a/DOAN.Service/MES/Material/IService/IMmInventoryService.cs b/DOAN.Service/MES/Material/IService/IMmInventoryService.cs
index e8b69fd..3ef9c7a 100644
--- a/DOAN.Service/MES/Material/IService/IMmInventoryService.cs
+++ b/DOAN.Service/MES/Material/IService/IMmInventoryService.cs
@@ -51,6 +51,12 @@ namespace DOAN.Service.BZFM.IBZFMService
///
///
string RevokeReceipt(MmInventoryRevokeDto parm);
+ ///
+ /// 出货操作 成功返回ok
+ ///
+ ///
+ ///
+ string Shipment(ShipmentDto parm);
///
/// 导入
diff --git a/DOAN.Service/MES/Material/MmInventoryService.cs b/DOAN.Service/MES/Material/MmInventoryService.cs
index 23783b6..6b1a335 100644
--- a/DOAN.Service/MES/Material/MmInventoryService.cs
+++ b/DOAN.Service/MES/Material/MmInventoryService.cs
@@ -1,7 +1,8 @@
using DOAN.Model;
using DOAN.Model.BZFM;
using DOAN.Model.BZFM.Dto;
-using DOAN.Model.Mobile.Dto;
+using DOAN.Model.MES.order;
+using DOAN.Model.MES.product;
using DOAN.Repository;
using DOAN.Service.BZFM.IBZFMService;
using Infrastructure.Attribute;
@@ -896,5 +897,221 @@ namespace DOAN.Service.BZFM
return e.Message;
}
}
+
+ ///
+ /// 出货操作 成功返回ok
+ ///
+ ///
+ ///
+ public string Shipment(ShipmentDto parm)
+ {
+ try
+ {
+ DateTime nowDate = DateTime.Now;
+
+ // 计算有符号变动量(蓝单为正,红单为负)
+ decimal delta = GetSignedQuantity(parm.ReceiptType, parm.Quantity);
+
+ // 校验物料和库位
+ 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 "仓库编码或库位编码不存在!";
+
+ // 启用事务
+ Context.Ado.BeginTran();
+
+ // 订单关联处理
+ if (!string.IsNullOrEmpty(parm.CustomerOrder))
+ {
+ // 判断订单号是否存在
+ var orderPurchase = Context
+ .Queryable()
+ .Where(o => o.OrderNoMes == parm.CustomerOrder)
+ .First();
+ if (orderPurchase == null)
+ {
+ Context.Ado.RollbackTran();
+ return "订单号不存在";
+ }
+
+ // 判断工单是否存在
+ if (!string.IsNullOrEmpty(parm.Workorder))
+ {
+ var workorderInfo = Context
+ .Queryable()
+ .Where(it => it.Workorder == parm.Workorder)
+ .First();
+ if (workorderInfo == null)
+ {
+ Context.Ado.RollbackTran();
+ return "工单不存在";
+ }
+
+ // 判断工单主体型号和订单物料号是否匹配
+ if (workorderInfo.productionCode != orderPurchase.MaterialCode)
+ {
+ Context.Ado.RollbackTran();
+ return "工单主体型号和订单物料号不匹配";
+ }
+ }
+ }
+
+ // 获取现有库存
+ 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();
+
+ // 库存检查
+ if (mmInventory == null)
+ {
+ if (parm.ReceiptType == 1)
+ {
+ Context.Ado.RollbackTran();
+ return "库存不存在,禁止出货!";
+ }
+ // 红单处理
+ var newInventory = new MmInventory()
+ {
+ MaterialCode = mmMaterial.MaterialCode,
+ MaterialName = mmMaterial.MaterialName,
+ SupplierCode = mmMaterial.SupplierCode,
+ SupplierName = mmMaterial.SupplierName,
+ LocationCode = mmLocation.LocationCode,
+ LocationName = mmLocation.LocationName,
+ WarehouseCode = mmLocation.WarehouseCode,
+ WarehouseName = mmLocation.WarehouseName,
+ BatchNo = parm.BatchNo,
+ CurrentQty = -delta,
+ Unit = mmMaterial.Unit,
+ LastUpdatedTime = null,
+ CreatedTime = nowDate,
+ };
+ Context.Insertable(newInventory).ExecuteCommand();
+ }
+ else
+ {
+ if (mmInventory.CurrentQty - delta < 0)
+ {
+ Context.Ado.RollbackTran();
+ return "库存不足,无法出货!";
+ }
+ // 更新库存
+ mmInventory.CurrentQty -= delta;
+ Context
+ .Updateable(mmInventory)
+ .UpdateColumns(it => it.CurrentQty)
+ .ExecuteCommand();
+ }
+
+ // 生成出货单号
+ var shipmentNo = GenerateReceiptNo("CH");
+
+ // 创建出货记录
+ MmRecordOutbound newRecord = new()
+ {
+ OutboundNo = shipmentNo,
+ BatchNo = parm.BatchNo,
+ Operator = parm.Operator,
+ MaterialCode = mmMaterial.MaterialCode,
+ MaterialName = mmMaterial.MaterialName,
+ LocationCode = mmLocation.LocationCode,
+ LocationName = mmLocation.LocationName,
+ WarehouseCode = mmLocation.WarehouseCode,
+ WarehouseName = mmLocation.WarehouseName,
+ Quantity = -delta,
+ Unit = mmMaterial.Unit,
+ CreatedTime = nowDate,
+ TransactionType = parm.TransactionType,
+ Workorder = parm.Workorder,
+ WorkorderRaw = parm.WorkorderRaw,
+ OrderNo = parm.CustomerOrder,
+ Remarks = parm.Remarks,
+ };
+ Context.Insertable(newRecord).ExecuteCommand();
+
+ // 更新工单和订单信息
+ if (!string.IsNullOrEmpty(parm.CustomerOrder) && !string.IsNullOrEmpty(parm.Workorder))
+ {
+ // 获取当前工单信息
+ var workorderInfo = Context
+ .Queryable()
+ .Where(it => it.Workorder == parm.Workorder)
+ .First();
+
+ // 计算累计出货数量(使用delta值,考虑单据类型的影响)
+ int currentShipmentNum = workorderInfo.ShipmentNum ?? 0;
+ int newShipmentNum = currentShipmentNum + (int)delta;
+
+ // 验证出货数量有效性
+ if (newShipmentNum < 0)
+ {
+ Context.Ado.RollbackTran();
+ return "累计出货数量不能为负数";
+ }
+
+ // 更新工单信息
+ Context
+ .Updateable()
+ .Where(it => it.Workorder == parm.Workorder)
+ .SetColumns(it => it.ShipmentNum == newShipmentNum)
+ .SetColumns(it => it.CustomerOrder == parm.CustomerOrder)
+ .ExecuteCommand();
+
+ // 修改采购订单信息
+ var orderPurchase = Context
+ .Queryable()
+ .Where(o => o.OrderNoMes == parm.CustomerOrder)
+ .First();
+ if (orderPurchase != null)
+ {
+ int newQuantity = Context
+ .Queryable()
+ .Where(it => it.CustomerOrder == parm.CustomerOrder)
+ .Sum(it => it.ShipmentNum) ?? 0;
+
+ orderPurchase.DeliveryQuantity = newQuantity;
+ if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity)
+ {
+ Context.Ado.RollbackTran();
+ return "交货数量超过订单需求数量";
+ }
+ if (orderPurchase.DeliveryQuantity == orderPurchase.DemandQuantity)
+ {
+ orderPurchase.Orderindicator = 1;
+ }
+ else
+ {
+ orderPurchase.Orderindicator = 0;
+ }
+ Context.Updateable(orderPurchase).ExecuteCommand();
+ }
+ }
+
+ // 提交事务
+ Context.Ado.CommitTran();
+ return "ok";
+ }
+ catch (Exception ex)
+ {
+ // 回滚操作
+ Context.Ado.RollbackTran();
+ return ex.Message;
+ }
+ }
}
}