feat(物料管理): 新增物料库存相关功能及接口

- 在MmMaterial类中添加ParentMaterialCode字段支持物料层级关系
- 扩展MmRecordOutbound类增加供应商信息字段
- 重构FeedProcessReportwork方法支持原材料工单领料和库存ID指定
- 新增物料库存查询、领料、成品入库、出货等接口
- 完善库存操作逻辑,支持根据库存ID直接操作
- 添加相关DTO类支持新功能的数据传输
This commit is contained in:
2026-01-31 22:50:21 +08:00
parent cc1fe5f967
commit b018ebc687
10 changed files with 1160 additions and 120 deletions

View File

@@ -301,41 +301,83 @@ namespace DOAN.Service.BZFM
// 计算有符号变动量(蓝单为正,红单为负)
decimal delta = GetSignedQuantity(parm.ReceiptType, parm.Quantity);
var mmMaterial = Context
.Queryable<MmMaterial>()
.Where(it => it.MaterialCode == parm.MaterialCode)
.First();
if (mmMaterial == null)
return "物料不存在!";
var mmLocation = Context
.Queryable<MmLocation>()
.Where(it => it.WarehouseCode == parm.WarehouseCode)
.Where(it => it.LocationCode == parm.LocationCode)
.First();
if (mmLocation == null)
return "仓库编码或库位编码不存在!";
Context.Ado.BeginTran();
var mmInventory = Context
.Queryable<MmInventory>()
.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)
MmInventory mmInventory = null;
if (parm.InventoryId == -1)
{
if (parm.ReceiptType == 1)
var mmMaterial = Context
.Queryable<MmMaterial>()
.Where(it => it.MaterialCode == parm.MaterialCode)
.WhereIF(
!string.IsNullOrEmpty(parm.SupplierCode),
it => it.SupplierCode == parm.SupplierCode
)
.First();
if (mmMaterial == null)
return "物料不存在!";
var mmLocation = Context
.Queryable<MmLocation>()
.Where(it => it.WarehouseCode == parm.WarehouseCode)
.Where(it => it.LocationCode == parm.LocationCode)
.First();
if (mmLocation == null)
return "仓库编码或库位编码不存在!";
mmInventory = Context
.Queryable<MmInventory>()
.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)
{
//库存为0或者不存在不允许出库
Context.Ado.RollbackTran();
return "库存不存在,禁止出库!";
if (parm.ReceiptType == 1)
{
//库存为0或者不存在不允许出库
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 = parm.Unit,
LastUpdatedTime = null,
CreatedTime = nowDate,
};
Context.Insertable(newInventory).ExecuteCommand();
mmInventory = newInventory;
}
var newInventory = new MmInventory()
else
{
if (mmInventory.CurrentQty - delta < 0)
{
Context.Ado.RollbackTran();
return "库存不足,无法出库!";
}
mmInventory.CurrentQty -= delta;
Context
.Updateable(mmInventory)
.UpdateColumns(it => it.CurrentQty)
.ExecuteCommand();
}
var outboundNo = GenerateReceiptNo("CK");
MmRecordOutbound newRecord = new()
{
OutboundNo = outboundNo,
BatchNo = parm.BatchNo,
Operator = parm.Operator,
MaterialCode = mmMaterial.MaterialCode,
MaterialName = mmMaterial.MaterialName,
SupplierCode = mmMaterial.SupplierCode,
@@ -345,54 +387,100 @@ namespace DOAN.Service.BZFM
WarehouseCode = mmLocation.WarehouseCode,
WarehouseName = mmLocation.WarehouseName,
BatchNo = parm.BatchNo,
CurrentQty = -delta,
//TODO 待调整(可能涉及记录汇总)
Quantity = -delta,
Unit = parm.Unit,
LastUpdatedTime = null,
CreatedTime = nowDate,
TransactionType = parm.TransactionType,
Workorder = parm.Workorder,
WorkorderRaw = parm.WorkorderRaw,
OrderNo = parm.OrderNo,
Remarks = parm.Remarks,
};
Context.Insertable(newInventory).ExecuteCommand();
Context.Insertable(newRecord).ExecuteCommand();
Context.Ado.CommitTran();
return "ok";
}
else
{
if (mmInventory.CurrentQty - delta < 0)
mmInventory = Context
.Queryable<MmInventory>()
.Where(it => it.Id == parm.InventoryId)
.First();
if (mmInventory == null)
{
Context.Ado.RollbackTran();
return "库存不足,无法出库!";
if (parm.ReceiptType == 1)
{
//库存为0或者不存在不允许出库
Context.Ado.RollbackTran();
return "库存不存在,禁止出库!";
}
var newInventory = new MmInventory()
{
MaterialCode = mmInventory.MaterialCode,
MaterialName = mmInventory.MaterialName,
SupplierCode = mmInventory.SupplierCode,
SupplierName = mmInventory.SupplierName,
LocationCode = mmInventory.LocationCode,
LocationName = mmInventory.LocationName,
WarehouseCode = mmInventory.WarehouseCode,
WarehouseName = mmInventory.WarehouseName,
BatchNo = parm.BatchNo,
CurrentQty = -delta,
Unit = parm.Unit,
LastUpdatedTime = null,
CreatedTime = nowDate,
};
Context.Insertable(newInventory).ExecuteCommand();
mmInventory = newInventory;
}
mmInventory.CurrentQty -= delta;
Context
.Updateable(mmInventory)
.UpdateColumns(it => it.CurrentQty)
.ExecuteCommand();
else
{
if (mmInventory.CurrentQty - delta < 0)
{
Context.Ado.RollbackTran();
return "库存不足,无法出库!";
}
mmInventory.CurrentQty -= delta;
Context
.Updateable(mmInventory)
.UpdateColumns(it => it.CurrentQty)
.ExecuteCommand();
}
var outboundNo = GenerateReceiptNo("CK");
MmRecordOutbound newRecord = new()
{
OutboundNo = outboundNo,
BatchNo = parm.BatchNo,
Operator = parm.Operator,
MaterialCode = mmInventory.MaterialCode,
MaterialName = mmInventory.MaterialName,
SupplierCode = mmInventory.SupplierCode,
SupplierName = mmInventory.SupplierName,
LocationCode = mmInventory.LocationCode,
LocationName = mmInventory.LocationName,
WarehouseCode = mmInventory.WarehouseCode,
WarehouseName = mmInventory.WarehouseName,
//TODO 待调整(可能涉及记录汇总)
Quantity = -delta,
Unit = parm.Unit,
CreatedTime = nowDate,
TransactionType = parm.TransactionType,
Workorder = parm.Workorder,
WorkorderRaw = parm.WorkorderRaw,
OrderNo = parm.OrderNo,
Remarks = parm.Remarks,
};
Context.Insertable(newRecord).ExecuteCommand();
Context.Ado.CommitTran();
return "ok";
}
var outboundNo = GenerateReceiptNo("CK");
MmRecordOutbound newRecord = new()
{
OutboundNo = outboundNo,
BatchNo = parm.BatchNo,
Operator = parm.Operator,
MaterialCode = mmMaterial.MaterialCode,
MaterialName = mmMaterial.MaterialName,
LocationCode = mmLocation.LocationCode,
LocationName = mmLocation.LocationName,
WarehouseCode = mmLocation.WarehouseCode,
WarehouseName = mmLocation.WarehouseName,
//TODO 待调整(可能涉及记录汇总)
Quantity = -delta,
Unit = parm.Unit,
CreatedTime = nowDate,
TransactionType = parm.TransactionType,
Workorder = parm.Workorder,
WorkorderRaw = parm.WorkorderRaw,
OrderNo = parm.OrderNo,
Remarks = parm.Remarks,
};
Context.Insertable(newRecord).ExecuteCommand();
Context.Ado.CommitTran();
return "ok";
}
catch (Exception ex)
{
@@ -1047,7 +1135,10 @@ namespace DOAN.Service.BZFM
Context.Insertable(newRecord).ExecuteCommand();
// 更新工单和订单信息
if (!string.IsNullOrEmpty(parm.CustomerOrder) && !string.IsNullOrEmpty(parm.Workorder))
if (
!string.IsNullOrEmpty(parm.CustomerOrder)
&& !string.IsNullOrEmpty(parm.Workorder)
)
{
// 获取当前工单信息
var workorderInfo = Context
@@ -1081,10 +1172,12 @@ namespace DOAN.Service.BZFM
.First();
if (orderPurchase != null)
{
int newQuantity = Context
.Queryable<ProWorkorder>()
.Where(it => it.CustomerOrder == parm.CustomerOrder)
.Sum(it => it.ShipmentNum) ?? 0;
int newQuantity =
Context
.Queryable<ProWorkorder>()
.Where(it => it.CustomerOrder == parm.CustomerOrder)
.Sum(it => it.ShipmentNum)
?? 0;
orderPurchase.DeliveryQuantity = newQuantity;
if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity)