fix(生产管理): 修复工单数量类型及完善出货逻辑

将工单数量字段从可空类型改为非可空类型并添加默认值
添加成品入库数量字段并完善相关业务逻辑
修复出货失败时的错误响应
完善撤销入库/出库操作时的工单数量调整
增加出货数量与成品入库数量的校验
This commit is contained in:
2026-02-10 15:07:59 +08:00
parent 176f854aaa
commit 9793fdd42f
7 changed files with 107 additions and 72 deletions

View File

@@ -612,6 +612,10 @@ namespace DOAN.Admin.WebApi.Controllers
} }
var response = _ProWorkorderMaterialService.ShipProduct(request); var response = _ProWorkorderMaterialService.ShipProduct(request);
if (!response)
{
return ToResponse(new ApiResult(500, "出货失败!"));
}
return SUCCESS(response); return SUCCESS(response);
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -58,9 +58,10 @@ namespace DOAN.Model.MES.product.Dto
public string Unit { get; set; } public string Unit { get; set; }
public int? PlanNum { get; set; } = 0; public int PlanNum { get; set; } = 0;
public int? ShipmentNum { get; set; } = 0; public int ShipmentNum { get; set; } = 0;
public int? DefectNum { get; set; } = 0; public int ProductNum { get; set; } = 0;
public int DefectNum { get; set; } = 0;
public int? Sort { get; set; } public int? Sort { get; set; }
public DateTime? WorkorderDate { get; set; } public DateTime? WorkorderDate { get; set; }

View File

@@ -39,20 +39,26 @@ namespace DOAN.Model.MES.product
/// 计划数量 /// 计划数量
/// </summary> /// </summary>
[SugarColumn(ColumnName = "plan_num")] [SugarColumn(ColumnName = "plan_num")]
public int? PlanNum { get; set; } public int PlanNum { get; set; } = 0;
/// <summary> /// <summary>
/// 出货数量 /// 出货数量
/// </summary> /// </summary>
[SugarColumn(ColumnName = "shipment_num")] [SugarColumn(ColumnName = "shipment_num")]
public int? ShipmentNum { get; set; } public int ShipmentNum { get; set; } = 0;
/// <summary> /// <summary>
/// 缺陷数量 /// 缺陷数量
/// </summary> /// </summary>
[SugarColumn(ColumnName = "defect_num")] [SugarColumn(ColumnName = "defect_num")]
public int? DefectNum { get; set; } public int DefectNum { get; set; } = 0;
/// <summary>
/// 成品入库数量
/// </summary>
[SugarColumn(ColumnName = "product_num")]
public int ProductNum { get; set; } = 0;
/// <summary> /// <summary>
/// 序号 /// 序号

View File

@@ -907,7 +907,7 @@ namespace DOAN.Service.BZFM
{ {
return $"此记录已撤销过,不可重复撤销"; return $"此记录已撤销过,不可重复撤销";
} }
//做库红单 //做库红单
InboundReceiptDto revokeRecepitDto = new() InboundReceiptDto revokeRecepitDto = new()
{ {
ReceiptType = 2, ReceiptType = 2,
@@ -925,16 +925,36 @@ namespace DOAN.Service.BZFM
Remarks = $"撤销操作,入库单号:{recordInbound.InboundNo}", Remarks = $"撤销操作,入库单号:{recordInbound.InboundNo}",
}; };
string result = CreateInboundReceipt(revokeRecepitDto); string result = CreateInboundReceipt(revokeRecepitDto);
if (result == "ok") if (result != "ok")
{
recordInbound.Remarks = "已撤销";
Context.Updateable(recordInbound).ExecuteCommand();
return result;
}
else
{ {
return result; return result;
} }
// 如果是成品入库则还要减少工单记录数量
Context.Ado.BeginTran();
if (recordInbound.TransactionType == "生产入库")
{
var workorderInfo = Context
.Queryable<ProWorkorder>()
.Where(it => it.Workorder == recordInbound.Workorder)
.First();
if (workorderInfo == null)
{
Context.Ado.RollbackTran();
return "工单不存在";
}
// 数量调整
workorderInfo.ProductNum -= Math.Abs((int)recordInbound.Quantity);
if (workorderInfo.ProductNum < 0)
{
workorderInfo.ProductNum = 0;
}
Context.Updateable(workorderInfo).ExecuteCommand();
}
recordInbound.Remarks = "已撤销";
Context.Updateable(recordInbound).ExecuteCommand();
Context.Ado.CommitTran();
return result;
} }
else else
{ {
@@ -968,11 +988,11 @@ namespace DOAN.Service.BZFM
Remarks = $"撤销操作,出库单号:{recordOutbound.OutboundNo}", Remarks = $"撤销操作,出库单号:{recordOutbound.OutboundNo}",
}; };
string result = CreateOutboundReceipt(revokeRecepitDto); string result = CreateOutboundReceipt(revokeRecepitDto);
if(result != "ok") if (result != "ok")
{ {
return result; return result;
} }
// 如果是出货则还要减少出货单库存 // 如果是出货则还要减少出货单库存和工单出货数量
Context.Ado.BeginTran(); Context.Ado.BeginTran();
if (recordOutbound.TransactionType == "出货出库") if (recordOutbound.TransactionType == "出货出库")
{ {
@@ -995,19 +1015,19 @@ namespace DOAN.Service.BZFM
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
return "订单号不存在"; return "订单号不存在";
} }
Context // 数量调整
.Updateable<ProWorkorder>() workorderInfo.ShipmentNum -= Math.Abs((int)recordOutbound.Quantity);
.Where(it => it.Workorder == recordOutbound.Workorder) if (workorderInfo.ShipmentNum < 0)
.SetColumns(it => it.ShipmentNum == 0) {
.SetColumns(it => it.CustomerOrder == string.Empty) workorderInfo.ShipmentNum = 0;
.ExecuteCommand(); }
workorderInfo.CustomerOrder = string.Empty;
Context.Updateable(workorderInfo).ExecuteCommand();
// 修改采购订单是否完成 // 修改采购订单是否完成
int newQuantity = int newQuantity = Context
Context .Queryable<ProWorkorder>()
.Queryable<ProWorkorder>() .Where(it => it.CustomerOrder == orderPurchase.OrderNoMes)
.Where(it => it.CustomerOrder == orderPurchase.OrderNoMes) .Sum(it => it.ShipmentNum);
.Sum(it => it.ShipmentNum)
?? 0;
orderPurchase.DeliveryQuantity = newQuantity; orderPurchase.DeliveryQuantity = newQuantity;
if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity) if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity)
{ {
@@ -1198,7 +1218,7 @@ namespace DOAN.Service.BZFM
.First(); .First();
// 计算累计出货数量使用delta值考虑单据类型的影响 // 计算累计出货数量使用delta值考虑单据类型的影响
int currentShipmentNum = workorderInfo.ShipmentNum ?? 0; int currentShipmentNum = workorderInfo.ShipmentNum;
int newShipmentNum = currentShipmentNum + (int)delta; int newShipmentNum = currentShipmentNum + (int)delta;
// 验证出货数量有效性 // 验证出货数量有效性
@@ -1223,12 +1243,10 @@ namespace DOAN.Service.BZFM
.First(); .First();
if (orderPurchase != null) if (orderPurchase != null)
{ {
int newQuantity = int newQuantity = Context
Context .Queryable<ProWorkorder>()
.Queryable<ProWorkorder>() .Where(it => it.CustomerOrder == parm.CustomerOrder)
.Where(it => it.CustomerOrder == parm.CustomerOrder) .Sum(it => it.ShipmentNum);
.Sum(it => it.ShipmentNum)
?? 0;
orderPurchase.DeliveryQuantity = newQuantity; orderPurchase.DeliveryQuantity = newQuantity;
if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity) if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity)

View File

@@ -377,13 +377,33 @@ namespace DOAN.Service.MES.product
customerOrder, customerOrder,
worker worker
); );
if (result == 0)
{
throw new Exception("数据库操作失败");
}
if (result == 2)
{
throw new Exception("订单号不存在");
}
if (result == 3)
{
throw new Exception("订单超额");
}
if (result == 4)
{
throw new Exception("工单不存在");
}
if (result == 5)
{
throw new Exception("主体型号和订单物料不匹配");
}
return result == 1; return result == 1;
} }
catch (Exception ex) catch (Exception ex)
{ {
// 集成现有系统的日志记录 // 集成现有系统的日志记录
// Log.Error("出货操作失败", ex); // Log.Error("出货操作失败", ex);
throw; throw new Exception(ex.Message);
} }
} }
@@ -429,8 +449,8 @@ namespace DOAN.Service.MES.product
productionCode = mri.MaterialName, productionCode = mri.MaterialName,
MaterialCode = mri.MaterialCode, MaterialCode = mri.MaterialCode,
MaterialName = mri.MaterialName, MaterialName = mri.MaterialName,
ShipmentNum = pro.ShipmentNum ?? 0, ShipmentNum = pro.ShipmentNum,
PlanNum = pro.PlanNum ?? 0, PlanNum = pro.PlanNum,
Remark01 = mri.Remarks Remark01 = mri.Remarks
}, },
true true

View File

@@ -49,7 +49,7 @@ namespace DOAN.Service.MES.SmartScreen.Product
digital.ProductionPlanQuantity = Context digital.ProductionPlanQuantity = Context
.Queryable<ProWorkorder>() .Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == DateTime.Today) .Where(it => it.WorkorderDate == DateTime.Today)
.Sum(it => it.PlanNum ?? 0); .Sum(it => it.PlanNum);
//digital.ProductionFinishQuantity = Context.Queryable<ProReportwork01>().Where(it => it.JobDateTime >= DateTime.Today && it.JobDateTime < DateTime.Today.AddDays(1)) //digital.ProductionFinishQuantity = Context.Queryable<ProReportwork01>().Where(it => it.JobDateTime >= DateTime.Today && it.JobDateTime < DateTime.Today.AddDays(1))
// .Where(it => it.ProcessId == 90).Sum(it => it.FinishNum??0); // .Where(it => it.ProcessId == 90).Sum(it => it.FinishNum??0);

View File

@@ -171,7 +171,7 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
throw new Exception($"原材料工单无成品入库记录:{workorderRaw}"); throw new Exception($"原材料工单无成品入库记录:{workorderRaw}");
} }
int newShipmentNum = (proWorkorderRawInfo.ShipmentNum ?? 0) + finish_num; int newShipmentNum = (proWorkorderRawInfo.ShipmentNum) + finish_num;
if (newShipmentNum > inboundRecord.Quantity) if (newShipmentNum > inboundRecord.Quantity)
{ {
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
@@ -341,12 +341,6 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
} }
if (process == 70) if (process == 70)
{ {
MmRecordInbound inboundRecord = Context
.Queryable<MmRecordInbound>()
.Where(it => it.Workorder == workorder)
.Where(it => it.TransactionType == "生产入库")
.Where(it => it.Remarks != "已撤销")
.First();
MmMaterial mmMaterial = Context MmMaterial mmMaterial = Context
.Queryable<MmMaterial>() .Queryable<MmMaterial>()
.Where(it => it.MaterialCode == proWorkorder.productionCode) .Where(it => it.MaterialCode == proWorkorder.productionCode)
@@ -358,7 +352,9 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
$"物料档案不存在,无法成品入库:{proWorkorder.productionCode}" $"物料档案不存在,无法成品入库:{proWorkorder.productionCode}"
); );
} }
if (inboundRecord == null)
proWorkorder.ProductNum += finish_num;
if (proWorkorder.PlanNum >= proWorkorder.ProductNum)
{ {
//做生产入库单 //做生产入库单
// 暂时默认成品入库与出库批次号都为000 // 暂时默认成品入库与出库批次号都为000
@@ -387,11 +383,12 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
throw new Exception(createReceiptresult); throw new Exception(createReceiptresult);
} }
Context.Updateable(proWorkorder).ExecuteCommand();
} }
else else
{ {
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
throw new Exception("重新成品入库前请先撤销已有物料生产入库记录"); throw new Exception("成品入库数超出计划数");
} }
} }
Context.Ado.CommitTran(); Context.Ado.CommitTran();
@@ -503,13 +500,9 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
} }
// XXX 成品库出库 // XXX 成品库出库
MmRecordOutbound outboundDto = Context // 需要保证已入库数大于等于已出货数+现在要出货的数量
.Queryable<MmRecordOutbound>() workorderInfo.ShipmentNum += finish_num;
.Where(it => it.Workorder == workorder) if (workorderInfo.ProductNum >= workorderInfo.ShipmentNum)
.Where(it => it.TransactionType == "出货出库")
.Where(it => it.Remarks != "已撤销")
.First();
if (outboundDto == null)
{ {
// Todo找还有库存的成品库 // Todo找还有库存的成品库
@@ -541,23 +534,16 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
else else
{ {
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
throw new Exception("重新出货前请先撤销物料出货出库记录"); throw new Exception("出货数超出工单成品入库数!");
} }
workorderInfo.CustomerOrder = customer_order;
// 修改工单信息 // 修改工单信息
Context Context.Updateable(workorderInfo).ExecuteCommand();
.Updateable<ProWorkorder>()
.Where(it => it.Workorder == workorder)
.SetColumns(it => it.ShipmentNum == finish_num)
.SetColumns(it => it.CustomerOrder == customer_order)
.ExecuteCommand();
// 修改采购订单是否完成 // 修改采购订单是否完成
int newQuantity = int newQuantity = Context
Context .Queryable<ProWorkorder>()
.Queryable<ProWorkorder>() .Where(it => it.CustomerOrder == customer_order)
.Where(it => it.CustomerOrder == customer_order) .Sum(it => it.ShipmentNum);
.Sum(it => it.ShipmentNum)
?? 0;
orderPurchase.DeliveryQuantity = newQuantity; orderPurchase.DeliveryQuantity = newQuantity;
if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity) if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity)
{ {
@@ -577,10 +563,10 @@ public class ReportFlowService : BaseService<ProReportwork01>, IReportFlowServic
Context.Ado.CommitTran(); Context.Ado.CommitTran();
return result > 0 ? 1 : 0; return result > 0 ? 1 : 0;
} }
catch (Exception) catch (Exception ex)
{ {
Context.Ado.RollbackTran(); Context.Ado.RollbackTran();
throw; throw new Exception(ex.Message);
} }
} }