diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseDefectController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseDefectController.cs
index 7a08aead..bb484d9c 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseDefectController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseDefectController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd基础缺陷项
///
- [Verify]
+ // [Verify]
[Route("/mes/qc/BackEnd/QcBackEndBaseDefect")]
public class QcBackEndBaseDefectController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseGroupController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseGroupController.cs
index 8c95685e..c045427a 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseGroupController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseGroupController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd班组
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndBaseGroup")]
public class QcBackEndBaseGroupController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseLabelAnalysisController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseLabelAnalysisController.cs
index a718d2b4..deb69f86 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseLabelAnalysisController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseLabelAnalysisController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd基础标签解析
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndBaseLabelAnalysis")]
public class QcBackEndBaseLabelAnalysisController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseSiteController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseSiteController.cs
index ceabca37..95d00c2d 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseSiteController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndBaseSiteController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd基础站点
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndBaseSite")]
public class QcBackEndBaseSiteController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndLogWorkorderController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndLogWorkorderController.cs
index 4a991cbd..666ee89b 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndLogWorkorderController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndLogWorkorderController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd工单操作日志
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndLogWorkorder")]
public class QcBackEndLogWorkorderController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordLabelScanController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordLabelScanController.cs
index ec398544..f5c85cc1 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordLabelScanController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordLabelScanController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd扫码标签记录
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndRecordLabelScan")]
public class QcBackEndRecordLabelScanController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordWorkorderDefectController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordWorkorderDefectController.cs
index 495ccebe..081ae974 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordWorkorderDefectController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndRecordWorkorderDefectController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd工单缺陷项记录
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndRecordWorkorderDefect")]
public class QcBackEndRecordWorkorderDefectController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceStatisticsController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceStatisticsController.cs
index e5c9943a..ed7bd13a 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceStatisticsController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceStatisticsController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd统计报表业务模块
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackEndServiceStatistics")]
public class QcBackEndServiceStatisticsController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceWorkorderController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceWorkorderController.cs
index 3ab33a1f..00d9848a 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceWorkorderController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackEndServiceWorkorderController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 质量BackEnd工单业务模块
///
- [Verify]
+ // [Verify]
[Route("/mes/qc/BackEnd/QcBackEndServiceWorkorder")]
public class QcBackEndServiceWorkorderController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendBaseOutpackageController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendBaseOutpackageController.cs
index 35627f49..621631c5 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendBaseOutpackageController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendBaseOutpackageController.cs
@@ -12,7 +12,7 @@ namespace ZR.Admin.WebApi.Controllers
/// 质量后道外箱标签打印配置
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackendBaseOutpackage")]
public class QcBackendBaseOutpackageController : BaseController
{
@@ -34,7 +34,7 @@ namespace ZR.Admin.WebApi.Controllers
///
///
[HttpGet("list")]
- [ActionPermissionFilter(Permission = "business:qcbackendbaseoutpackage:list")]
+ [AllowAnonymous]
public IActionResult QueryQcBackendBaseOutpackage(
[FromQuery] QcBackendBaseOutpackageQueryDto parm
)
@@ -49,7 +49,7 @@ namespace ZR.Admin.WebApi.Controllers
///
///
[HttpGet("{Id}")]
- [ActionPermissionFilter(Permission = "business:qcbackendbaseoutpackage:query")]
+ [AllowAnonymous]
public IActionResult GetQcBackendBaseOutpackage(int Id)
{
var response = _QcBackendBaseOutpackageService.GetInfo(Id);
@@ -64,6 +64,7 @@ namespace ZR.Admin.WebApi.Controllers
///
///
[HttpPost]
+ [AllowAnonymous]
public IActionResult AddQcBackendBaseOutpackage([FromBody] QcBackendBaseOutpackageDto parm)
{
var modal = parm.Adapt().ToCreate(HttpContext);
@@ -79,6 +80,7 @@ namespace ZR.Admin.WebApi.Controllers
///
///
[HttpPut]
+ [AllowAnonymous]
public IActionResult UpdateQcBackendBaseOutpackage(
[FromBody] QcBackendBaseOutpackageDto parm
)
@@ -95,6 +97,7 @@ namespace ZR.Admin.WebApi.Controllers
///
///
[HttpDelete("{ids}")]
+ [AllowAnonymous]
public IActionResult DeleteQcBackendBaseOutpackage(string ids)
{
int[] idsArr = Tools.SpitIntArrary(ids);
diff --git a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendRecordLabelPrintController.cs b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendRecordLabelPrintController.cs
index a181d4fd..c5d262dd 100644
--- a/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendRecordLabelPrintController.cs
+++ b/ZR.Admin.WebApi/Controllers/mes/qc/backend/QcBackendRecordLabelPrintController.cs
@@ -11,7 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 后道标签打印记录
///
- [Verify]
+ //[Verify]
[Route("/mes/qc/BackEnd/QcBackendRecordLabelPrint")]
public class QcBackendRecordLabelPrintController : BaseController
{
diff --git a/ZR.Admin.WebApi/Controllers/mes/wms/WmPDAOutboundController.cs b/ZR.Admin.WebApi/Controllers/mes/wms/WmPDAOutboundController.cs
new file mode 100644
index 00000000..a4b83576
--- /dev/null
+++ b/ZR.Admin.WebApi/Controllers/mes/wms/WmPDAOutboundController.cs
@@ -0,0 +1,170 @@
+using Microsoft.AspNetCore.Mvc;
+using ZR.Admin.WebApi.Filters;
+using ZR.Model.MES.wms.Dto;
+using ZR.Service.mes.wms.IService;
+
+namespace ZR.Admin.WebApi.Controllers
+{
+ ///
+ /// PDA出库控制器
+ ///
+ [Route("mes/wms/pdaOutbound")]
+ public class WmPDAOutboundController : BaseController
+ {
+ private readonly IWmOutOrderService _wmOutOrderService;
+
+ public WmPDAOutboundController(IWmOutOrderService wmOutOrderService)
+ {
+ _wmOutOrderService = wmOutOrderService;
+ }
+
+ ///
+ /// (PDA出库)获取出库单列表【出库中,已完成】
+ ///
+ /// 查询参数
+ /// 出库单列表
+ [HttpGet("GetPdaOutOrderPageList")]
+ [AllowAnonymous]
+ public IActionResult GetPdaOutOrderPageList([FromQuery] WmPDAOutOrderPageQueryDto parm)
+ {
+ try
+ {
+ var result = _wmOutOrderService.GetPdaOutOrderPageList(parm);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
+ ///
+ /// (PDA出库)获取出库计划列表
+ ///
+ /// 查询参数
+ /// 出库计划列表
+ [HttpGet("GetPdaOutOrderPlanPageList")]
+ [AllowAnonymous]
+ public IActionResult GetPdaOutOrderPlanPageList([FromQuery] WmPDAOutOrderPlanPageQueryDto parm)
+ {
+ try
+ {
+ var result = _wmOutOrderService.GetPdaOutOrderPlanPageList(parm);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
+ ///
+ /// (PDA出库)获取出库计划中所包含的物料的清单
+ ///
+ /// 出库单号
+ /// 出库计划列表
+ [HttpGet("GetPdaOutOrderPlanOptions")]
+ [AllowAnonymous]
+ public IActionResult GetPdaOutOrderPlanOptions(string shipmentNum)
+ {
+ try
+ {
+ var result = _wmOutOrderService.GetPdaOutOrderPlanOptions(shipmentNum);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
+ ///
+ /// (PDA出库)获取出库计划中某物料实际库存变动信息
+ ///
+ /// 出库单号
+ /// 物料号
+ /// 批次号
+ /// 出库计划列表
+ [HttpGet("GetPdaOutOrderPlanActualData")]
+ [AllowAnonymous]
+ public IActionResult GetPdaOutOrderPlanActualData(string shipmentNum, string materialCode, string batchCode)
+ {
+ try
+ {
+ var result = _wmOutOrderService.GetPdaOutOrderPlanActualData(shipmentNum, materialCode, batchCode);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
+ ///
+ /// (PDA出库)更新出库计划
+ ///
+ /// 出库单号
+ /// 是否更新成功
+ [HttpPost("UpdatePdaOutOrderPlan")]
+ [AllowAnonymous]
+ public IActionResult UpdatePdaOutOrderPlan(string shipmentNum)
+ {
+ try
+ {
+ var result = _wmOutOrderService.UpdatePdaOutOrderPlan(shipmentNum);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
+ ///
+ /// (PDA出库)根据出库计划出库 返回 ok 成功,其余都是异常
+ ///
+ /// 出库信息
+ /// 出库结果
+ [HttpPost("PdaOutboundByOutOrderPlan")]
+ [AllowAnonymous]
+ public IActionResult PdaOutboundByOutOrderPlan([FromBody] WmPDAOutboundDto parm)
+ {
+ try
+ {
+ var result = _wmOutOrderService.PdaOutboundByOutOrderPlan(parm);
+ if(result == "ok")
+ {
+ return SUCCESS(result);
+ }
+ else
+ {
+ return ToResponse(new ApiResult(500, result));
+ }
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
+ ///
+ /// (PDA出库)出库单完成
+ ///
+ /// 出库单号
+ /// 是否完成
+ [HttpPost("CompleteOutOrder")]
+ [AllowAnonymous]
+ public IActionResult CompleteOutOrder(string shipmentNum)
+ {
+ try
+ {
+ var result = _wmOutOrderService.CompleteOutOrder(shipmentNum);
+ return SUCCESS(result);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ZR.Model/MES/wms/Dto/WmOutOrderDto.cs b/ZR.Model/MES/wms/Dto/WmOutOrderDto.cs
index fff7c3b6..4d720819 100644
--- a/ZR.Model/MES/wms/Dto/WmOutOrderDto.cs
+++ b/ZR.Model/MES/wms/Dto/WmOutOrderDto.cs
@@ -58,9 +58,6 @@ namespace ZR.Model.MES.wms.Dto
public string UpdatedBy { get; set; }
public DateTime? UpdatedTime { get; set; }
-
-
-
}
///
/// 出货单(物料+客户)输入输出对象
@@ -82,6 +79,27 @@ namespace ZR.Model.MES.wms.Dto
}
+ ///
+ /// 出货单详细信息,绑定的物料清单
+ ///
+ public class WmOutOrderMaterialDto
+ {
+ ///
+ /// 出库单号
+ ///
+ public string FkShipmentNum { get; set; }
+
+ ///
+ /// 物料编码
+ ///
+ public string FkMaterialCode { get; set; }
+
+ ///
+ /// 出货数量
+ ///
+ public int Number { get; set; } = 0;
+ }
+
// 出货到出货记录表
public class WmDoMaterialOut_Dto
{
@@ -163,4 +181,101 @@ namespace ZR.Model.MES.wms.Dto
}
+ ///
+ /// PDA 出库单列表
+ ///
+ public class WmPDAOutOrderListDto
+ {
+ // 出库单号
+ public string ShipmentNum { get; set; }
+ // 客户编号
+ public string CustomName { get; set; }
+ // 出库单状态(1-出库中 2-出库完成 3-弃用)
+ public int Type { get; set; }
+ // 先进先出检查(0-停用 1-启用)
+ public int? Status { get; set; }
+ // 计划出库数量
+ // public int PlanOutNumber { get; set; } = 0;
+ // 实际出库数量
+ // public int ActualOutNumber { get; set; } = 0;
+ }
+
+ ///
+ /// PDA 出库计划列表
+ ///
+ public class WmPDAOutPlanListDto
+ {
+ // 出库单号
+ public string ShipmentNum { get; set; }
+ // 物料号
+ public string MaterialCode { get; set; }
+ // 物料描述
+ public string Description { get; set; } = "无描述";
+ // 批次号
+ public string BatchCode { get; set; }
+ // 仓库号
+ public string WarehouseCode { get; set; }
+
+ // 计划出库零件数
+ public int PlanOutNumber { get; set; } = 0;
+ // 库存零件数
+ public int InventoryNumber { get; set; } = 0;
+ // 实际出库零件数
+ public int ActualOutNumber { get; set; } = 0;
+
+ // 计划出库箱
+ public int PlanOutPackage { get; set; } = 0;
+ // 库存箱数
+ public int InventoryPackage { get; set; } = 0;
+ // 实际出库箱
+ public int ActualOutPackage { get; set; } = 0;
+ }
+
+ ///
+ /// PDA 获取某出库计划已出库数量
+ ///
+ public class WmPDAOutOnePlanActualDataDto
+ {
+ // 出库单号
+ public string ShipmentNum { get; set; }
+ // 物料号
+ public string MaterialCode { get; set; }
+ // 批次号
+ public string BatchCode { get; set; }
+ // 库存零件数
+ public int InventoryNumber { get; set; } = 0;
+ // 实际出库零件数
+ public int ActualOutNumber { get; set; } = 0;
+ // 库存箱数
+ public int InventoryPackage { get; set; } = 0;
+ // 实际出库箱
+ public int ActualOutPackage { get; set; } = 0;
+ }
+
+ ///
+ /// PDA 出库请求
+ ///
+ public class WmPDAOutboundDto
+ {
+ // 严格模式
+ public bool IsStrict { get; set; } = true;
+ // 出库单号
+ public string ShipmentNum { get; set; }
+ // 物料号
+ public string MaterialCode { get; set; }
+ // 批次号
+ public string BatchCode { get; set; }
+ // 当前出库箱
+ public int CurrentOutPackage { get; set; } = 0;
+ // 当前出库零件数
+ public int CurrentOutNumber { get; set; } = 0;
+ // 计划出库箱
+ public int PlanOutPackage { get; set; } = 0;
+ // 计划出库零件数
+ public int PlanOutNumber { get; set; } = 0;
+ // 出库清单
+ public List PackageCodeList { get; set; }
+ // 出库人
+ public string Operator { get; set; } = string.Empty;
+ }
}
\ No newline at end of file
diff --git a/ZR.Model/MES/wms/Dto/WmPDAOutOrderQueryDto.cs b/ZR.Model/MES/wms/Dto/WmPDAOutOrderQueryDto.cs
new file mode 100644
index 00000000..a61742a1
--- /dev/null
+++ b/ZR.Model/MES/wms/Dto/WmPDAOutOrderQueryDto.cs
@@ -0,0 +1,26 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace ZR.Model.MES.wms.Dto
+{
+ ///
+ /// PDA 出库单列表查询对象
+ ///
+ public class WmPDAOutOrderPageQueryDto : PagerInfo
+ {
+ // 出库单状态(1-出库中 2-出库完成 3-弃用)
+ public string Type { get; set; }
+ // 出库单号
+ public string ShipmentNum { get; set; }
+ }
+
+ ///
+ /// PDA 出库计划列表查询对象
+ ///
+ public class WmPDAOutOrderPlanPageQueryDto : PagerInfo
+ {
+ // 出库单号
+ public string ShipmentNum { get; set; }
+ // 物料号
+ public string MaterialCode { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ZR.Model/MES/wms/WmOutOrderMaterialRel.cs b/ZR.Model/MES/wms/WmOutOrderMaterialRel.cs
new file mode 100644
index 00000000..4adc3cad
--- /dev/null
+++ b/ZR.Model/MES/wms/WmOutOrderMaterialRel.cs
@@ -0,0 +1,29 @@
+namespace ZR.Model.MES.wms
+{
+ ///
+ /// 物料表和出库单关联表
+ ///
+ [SugarTable("wm_out_order_material_rel")]
+ public class WmOutOrderMaterialRel
+ {
+
+ ///
+ /// 出库单号
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = false, ColumnName = "fk_shipment_num")]
+ public string FkShipmentNum { get; set; }
+
+ ///
+ /// 物料编码
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = false, ColumnName = "fk_material_code")]
+ public string FkMaterialCode { get; set; }
+
+ ///
+ /// 出货数量
+ ///
+ [SugarColumn(ColumnName = "number")]
+ public int Number { get; set; }
+
+ }
+}
diff --git a/ZR.Service/mes/qc/backend/QcBackEndService.cs b/ZR.Service/mes/qc/backend/QcBackEndService.cs
index 2a6ecafa..1a833e6c 100644
--- a/ZR.Service/mes/qc/backend/QcBackEndService.cs
+++ b/ZR.Service/mes/qc/backend/QcBackEndService.cs
@@ -1152,7 +1152,7 @@ namespace ZR.Service.Business
int isAgain = specialPrintType == 1 ? 1 : 0;
string newLabelCode =
- $"Code=PGW{workOrder}^ItemNumber={newLabelScran.PartNumber}^Order=W{workOrder}^Qty={maxPackage}^LabelType=1^LabelBy=HD^Tm={newLabelScran.Team}^Fu={isFull}^Ag={isAgain}";
+ $"Code=PGW{workOrder}^ItemNumber={newLabelScran.PartNumber}^Order=W{workOrder}^Qty={maxPackage}^LabelType=1^LabelBy=HD^Fu={isFull}^Ag={isAgain}";
string newPackageCode = $"BOX:PGW{workOrder}{newLabelScran.Team}1";
diff --git a/ZR.Service/mes/wms-u8/ERP_WMS_interactiveService.cs b/ZR.Service/mes/wms-u8/ERP_WMS_interactiveService.cs
index bad08784..cd12af3a 100644
--- a/ZR.Service/mes/wms-u8/ERP_WMS_interactiveService.cs
+++ b/ZR.Service/mes/wms-u8/ERP_WMS_interactiveService.cs
@@ -1,13 +1,13 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Newtonsoft.Json;
-using NLog;
-using System;
+using System;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
+using Infrastructure;
+using Infrastructure.Attribute;
+using Newtonsoft.Json;
+using NLog;
using U8Server.Util;
using ZR.Model.MES.wms;
using ZR.Service.mes.wms_u8.IService;
@@ -18,25 +18,35 @@ namespace ZR.Service.mes.wms_u8
public class ERP_WMS_interactiveService : IERP_WMS_interactive
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
+
// 假设接口密钥(需根据实际文档填写)
//private const string ApiSecret = "your_api_secret"; // 替换为实际密钥
#region 同步方法
- public ERP_WMS_interactiveModelResult Inbounded(string urlBase, List models)
+ public ERP_WMS_interactiveModelResult Inbounded(
+ string urlBase,
+ List models
+ )
{
return ProcessSyncRequest(urlBase, models, "inbounded", isInbound: true);
}
- public ERP_WMS_interactiveModelResult Outbounded(string urlBase, List models)
+ public ERP_WMS_interactiveModelResult Outbounded(
+ string urlBase,
+ List models
+ )
{
return ProcessSyncRequest(urlBase, models, "outbounded", isInbound: false);
}
+
///
/// 根据物料编码聚合模型数据
///
/// 原始模型列表
/// 聚合后的模型列表
- private List AggregateModelsByMaterialCode(List models)
+ private List AggregateModelsByMaterialCode(
+ List models
+ )
{
if (models == null || models.Count == 0)
return models;
@@ -48,25 +58,25 @@ namespace ZR.Service.mes.wms_u8
{
// 获取分组内的第一个模型
var firstModel = g.First();
-
+
return new ERP_WMS_interactiveModelQuery
{
- customerCode = firstModel.customerCode, // 使用分组内第一个模型的客户编码
+ customerCode = firstModel.customerCode, // 使用分组内第一个模型的客户编码
materialCode = g.Key,
- location = firstModel.location, // 位置留空
+ location = firstModel.location, // 位置留空
Qty = g.Sum(m =>
- {
- // 确保数量可以转换为数字
- if (decimal.TryParse(m.Qty, out decimal qty))
- return qty;
- return 0;
- }).ToString(),
- LotNo = firstModel.LotNo,
- createTime = firstModel.createTime,
- userID = firstModel.userID,
- guid = Guid.NewGuid().ToString(),
- lineno = firstModel.lineno,
-
+ {
+ // 确保数量可以转换为数字
+ if (decimal.TryParse(m.Qty, out decimal qty))
+ return qty;
+ return 0;
+ })
+ .ToString(),
+ LotNo = firstModel.LotNo,
+ createTime = firstModel.createTime,
+ userID = firstModel.userID,
+ guid = Guid.NewGuid().ToString(),
+ lineno = firstModel.lineno,
};
})
.ToList();
@@ -77,12 +87,18 @@ namespace ZR.Service.mes.wms_u8
#endregion
#region 异步方法
- public async Task InboundedAsync(string urlBase, List models)
+ public async Task InboundedAsync(
+ string urlBase,
+ List models
+ )
{
return await ProcessAsyncRequest(urlBase, models, "inbounded", isInbound: true);
}
- public async Task OutboundedAsync(string urlBase, List models)
+ public async Task OutboundedAsync(
+ string urlBase,
+ List models
+ )
{
return await ProcessAsyncRequest(urlBase, models, "outbounded", isInbound: false);
}
@@ -92,7 +108,12 @@ namespace ZR.Service.mes.wms_u8
///
/// 同步请求处理(抽取公共逻辑)
///
- private ERP_WMS_interactiveModelResult ProcessSyncRequest(string urlBase, List models, string action, bool isInbound)
+ private ERP_WMS_interactiveModelResult ProcessSyncRequest(
+ string urlBase,
+ List models,
+ string action,
+ bool isInbound
+ )
{
var operation = isInbound ? "入库" : "出库";
_logger.Info($"开始处理{operation}请求 - URL基础: {urlBase}, 记录数: {models?.Count ?? 0}");
@@ -129,7 +150,12 @@ namespace ZR.Service.mes.wms_u8
// 配置项:控制是否启用物料编码聚合功能
private static bool EnableMaterialAggregation = true; // 默认为false,不启用聚合
- private async Task ProcessAsyncRequest(string urlBase, List models, string action, bool isInbound)
+ private async Task ProcessAsyncRequest(
+ string urlBase,
+ List models,
+ string action,
+ bool isInbound
+ )
{
var operation = isInbound ? "异步入库" : "异步出库";
_logger.Info($"开始处理{operation}请求 - URL基础: {urlBase}, 记录数: {models?.Count ?? 0}");
@@ -146,7 +172,9 @@ namespace ZR.Service.mes.wms_u8
if (EnableMaterialAggregation)
{
processedModels = AggregateModelsByMaterialCode(models);
- _logger.Info($"{operation}请求数据已聚合 - 聚合前记录数: {models.Count}, 聚合后记录数: {processedModels.Count}");
+ _logger.Info(
+ $"{operation}请求数据已聚合 - 聚合前记录数: {models.Count}, 聚合后记录数: {processedModels.Count}"
+ );
}
// 3. 构建URL和请求数据
@@ -157,7 +185,13 @@ namespace ZR.Service.mes.wms_u8
try
{
_logger.Trace($"发送{operation}异步HTTP请求 - URL: {url}");
- string resultJson = await HttpHelper.HttpPostAsync(url, requestData, "application/json", 5, null);
+ string resultJson = await HttpHelper.HttpPostAsync(
+ url,
+ requestData,
+ "application/json",
+ 5,
+ null
+ );
// 4. 处理响应(先校验JSON格式,再反序列化)
return await ProcessAsyncResponse(resultJson, operation, url);
@@ -173,7 +207,11 @@ namespace ZR.Service.mes.wms_u8
///
/// 构建URL(避免双斜杠问题,并添加查询字符串参数)
///
- private string BuildUrl(string urlBase, string action, List models)
+ private string BuildUrl(
+ string urlBase,
+ string action,
+ List models
+ )
{
// 移除urlBase结尾的斜杠,再拼接路径
string baseUrl = $"{urlBase.TrimEnd('/')}/wms/mes/{action}";
@@ -183,7 +221,12 @@ namespace ZR.Service.mes.wms_u8
var headers = BuildHeaders(requestData);
// 构建查询字符串
- var queryString = string.Join("&", headers.Select(kv => $"{WebUtility.UrlEncode(kv.Key)}={WebUtility.UrlEncode(kv.Value)}"));
+ var queryString = string.Join(
+ "&",
+ headers.Select(kv =>
+ $"{WebUtility.UrlEncode(kv.Key)}={WebUtility.UrlEncode(kv.Value)}"
+ )
+ );
if (!string.IsNullOrEmpty(queryString))
{
@@ -198,7 +241,10 @@ namespace ZR.Service.mes.wms_u8
///
private Dictionary BuildHeaders(string requestData)
{
- string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture);
+ string timestamp = DateTime.Now.ToString(
+ "yyyyMMddHHmmss",
+ CultureInfo.InvariantCulture
+ );
string appid = "gN9yId!!lfwaRoi3";
// 签名生成规则:通常为appid + timestamp + requestData + secret的MD5(需根据接口文档调整)
@@ -216,7 +262,12 @@ namespace ZR.Service.mes.wms_u8
///
/// 基础参数校验
///
- private bool ValidateBaseParams(string urlBase, List models, string operation, out string errorMsg)
+ private bool ValidateBaseParams(
+ string urlBase,
+ List models,
+ string operation,
+ out string errorMsg
+ )
{
if (string.IsNullOrEmpty(urlBase))
{
@@ -237,7 +288,11 @@ namespace ZR.Service.mes.wms_u8
///
/// 处理同步响应(假设HttpHelper返回已反序列化对象,需根据实际情况调整)
///
- private ERP_WMS_interactiveModelResult ProcessSyncResponse(object result, string operation, string url)
+ private ERP_WMS_interactiveModelResult ProcessSyncResponse(
+ object result,
+ string operation,
+ string url
+ )
{
if (result == null)
{
@@ -247,7 +302,9 @@ namespace ZR.Service.mes.wms_u8
if (result is ERP_WMS_interactiveModelResult modelResult)
{
- _logger.Info($"{operation}请求处理成功 - 结果: {modelResult.result}, 消息: {modelResult.message}");
+ _logger.Info(
+ $"{operation}请求处理成功 - 结果: {modelResult.result}, 消息: {modelResult.message}"
+ );
return modelResult;
}
@@ -258,7 +315,11 @@ namespace ZR.Service.mes.wms_u8
///
/// 处理异步响应(先校验JSON格式)
///
- private async Task ProcessAsyncResponse(string resultJson, string operation, string url)
+ private async Task ProcessAsyncResponse(
+ string resultJson,
+ string operation,
+ string url
+ )
{
if (string.IsNullOrEmpty(resultJson))
{
@@ -287,7 +348,9 @@ namespace ZR.Service.mes.wms_u8
// 反序列化
try
{
- var result = JsonConvert.DeserializeObject(resultJson);
+ var result = JsonConvert.DeserializeObject(
+ resultJson
+ );
if (result != null)
{
_logger.Info($"{operation}请求处理成功 - 结果: {result.code}, 消息: {result.message}");
@@ -313,7 +376,12 @@ namespace ZR.Service.mes.wms_u8
///
/// 异常处理(细化异常类型)
///
- private ERP_WMS_interactiveModelResult HandleException(Exception ex, string operation, string url, string requestData)
+ private ERP_WMS_interactiveModelResult HandleException(
+ Exception ex,
+ string operation,
+ string url,
+ string requestData
+ )
{
var errorMsg = $"{operation}处理异常";
@@ -334,11 +402,7 @@ namespace ZR.Service.mes.wms_u8
errorMsg += $": 未知错误: {ex.Message}";
}
- return new ERP_WMS_interactiveModelResult
- {
- result = "fail",
- message = errorMsg
- };
+ return new ERP_WMS_interactiveModelResult { result = "fail", message = errorMsg };
}
///
@@ -351,7 +415,10 @@ namespace ZR.Service.mes.wms_u8
json = json.Trim();
// 基本格式校验:以{或[开头,以}或]结尾
- if ((json.StartsWith("{") && json.EndsWith("}")) || (json.StartsWith("[") && json.EndsWith("]")))
+ if (
+ (json.StartsWith("{") && json.EndsWith("}"))
+ || (json.StartsWith("[") && json.EndsWith("]"))
+ )
{
try
{
@@ -369,4 +436,4 @@ namespace ZR.Service.mes.wms_u8
}
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/ZR.Service/mes/wms/IService/IWmOutOrderService.cs b/ZR.Service/mes/wms/IService/IWmOutOrderService.cs
index 319062aa..951e1b36 100644
--- a/ZR.Service/mes/wms/IService/IWmOutOrderService.cs
+++ b/ZR.Service/mes/wms/IService/IWmOutOrderService.cs
@@ -13,6 +13,33 @@ namespace ZR.Service.mes.wms.IService
WmOutOrder_material_num GetInfo(string ShipmentNum);
+ ///
+ /// (出库单)获取出库单配置信息
+ ///
+ ///
+ ///
+ WmOutOrderDto GetOutOrderInfo(string ShipmentNum);
+ ///
+ /// (出库单)获取出库单物料信息
+ ///
+ ///
+ ///
+ PagedInfo GetOutOrderMaterialList(string ShipmentNum);
+
+ ///
+ /// (出库单)新增一张出库单
+ ///
+ ///
+ ///
+ WmOutOrder AddOneOutOrder(WmOutOrder_materialDto parm);
+
+ ///
+ /// (出库单)修改一张出库单
+ ///
+ ///
+ ///
+ WmOutOrder UpdateOneOutOrder(WmOutOrder_materialDto parm);
+
WmOutOrder AddWmOutOrder(WmOutOrder_materialDto parm);
int UpdateWmOutOrder(WmOutOrder parm);
@@ -45,6 +72,57 @@ namespace ZR.Service.mes.wms.IService
// 检查是否可出库
string CheckProductionOut(string parnumber, string production_packcode, string shipment_num);
+ // 20250823 PDA出库新接口
+ ///
+ /// (PDA出库)获取出库单列表【出库中,已完成】
+ ///
+ /// 查询参数
+ /// 出库单列表
+ PagedInfo GetPdaOutOrderPageList(WmPDAOutOrderPageQueryDto parm);
+
+ ///
+ /// (PDA出库)获取出库计划列表
+ ///
+ /// 查询参数
+ /// 出库计划列表
+ PagedInfo GetPdaOutOrderPlanPageList(WmPDAOutOrderPlanPageQueryDto parm);
+
+ ///
+ /// (PDA出库)获取出库计划中所包含的物料的清单
+ ///
+ /// 出库单号
+ /// 出库计划列表
+ List GetPdaOutOrderPlanOptions(string shipmentNum);
+
+ ///
+ /// (PDA出库)获取出库计划中某物料实际库存变动信息
+ ///
+ /// 出库单号
+ /// 物料号
+ /// 批次号
+ /// 出库计划列表
+ WmPDAOutOnePlanActualDataDto GetPdaOutOrderPlanActualData(string shipmentNum,string materialCode,string batchCode);
+
+ ///
+ /// (PDA出库)更新出库计划
+ ///
+ /// 出库单号
+ /// 是否更新成功
+ bool UpdatePdaOutOrderPlan(string shipmentNum);
+
+ ///
+ /// (PDA出库)根据出库计划出库 返回 ok 成功,其余都是异常
+ ///
+ /// 出库信息
+ /// 出库结果
+ string PdaOutboundByOutOrderPlan(WmPDAOutboundDto parm);
+
+ ///
+ /// (PDA出库)出库单完成
+ ///
+ /// 出库单号
+ /// 是否完成
+ bool CompleteOutOrder(string shipmentNum);
}
}
diff --git a/ZR.Service/mes/wms/WMentryWarehousing_productService.cs b/ZR.Service/mes/wms/WMentryWarehousing_productService.cs
index 3ff9e94d..2bfb948f 100644
--- a/ZR.Service/mes/wms/WMentryWarehousing_productService.cs
+++ b/ZR.Service/mes/wms/WMentryWarehousing_productService.cs
@@ -1,9 +1,9 @@
-using Infrastructure.Attribute;
-using SqlSugar;
-using System;
+using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using Infrastructure.Attribute;
+using SqlSugar;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
using ZR.Service.mes.wms.IService;
@@ -22,215 +22,183 @@ namespace ZR.Service.mes.wms
{
private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
- //货物入库
public int IntoProductwarehouse(WmgoodsDto wmgoods, string createName)
{
try
{
- Context.Ado.BeginTran();
- List preparegoodsList = new();
- string location = wmgoods.location;
- if (string.IsNullOrEmpty(wmgoods.location))
- {
- location = "LS";
- }
+ // 1. 前置参数校验(事务外执行,不占用连接)
+ if (wmgoods == null || wmgoods.packagelist == null || wmgoods.packagelist.Length == 0)
+ throw new Exception("无入库箱,请检查传入数据!");
+
+ string location = string.IsNullOrEmpty(wmgoods.location) ? "LS" : wmgoods.location;
string[] packageArray = wmgoods.packagelist;
- if (packageArray == null || packageArray.Length <= 0)
- {
- Context.Ado.RollbackTran();
- throw new Exception("无入库箱,请检查传入数据!");
- }
- // 入库去重检查
- string[] newPacakgeArray = packageArray.Distinct().ToArray();
- if (packageArray.Length != newPacakgeArray.Length)
- {
- Context.Ado.RollbackTran();
- throw new Exception("入库箱有重复,实际箱数:" + newPacakgeArray.Length);
- }
- // 统计记录
- List partnumbers = new();
+ // 去重校验
+ HashSet uniquePackages = new HashSet(packageArray);
+ if (uniquePackages.Count != packageArray.Length)
+ throw new Exception($"入库箱有重复,实际箱数:{uniquePackages.Count}");
+
+ // 2. 解析数据并准备入库列表(事务外执行)
+ List preparegoodsList = new List();
+ HashSet partnumbers = new HashSet();
+ List allPatchCodes = new List();
+ List packageCodeRemark = new List();
int totalPackage = 0;
int totalPartnumber = 0;
- List packageCodeRemark = new();
- for (int i = 0; i < packageArray.Length; i++)
+
+ foreach (var pkgCode in packageArray)
{
- // 解析箱标签
- ResultionPackageCodeDto resultionPackage = ResolutionPackage(packageArray[i]);
+ var resultionPackage = ResolutionPackage(pkgCode);
if (resultionPackage == null)
+ throw new Exception($"箱标签解析失败: {pkgCode}");
+
+ // 缓存常用属性
+ string patchCode = resultionPackage.PatchCode;
+ int? quantity = resultionPackage.Quantity ?? 0;
+
+ // 收集用于批量校验的箱号
+ allPatchCodes.Add(patchCode);
+ packageCodeRemark.Add(patchCode);
+
+ // 构建入库对象
+ var wmGood = new WmGoodsNowProduction
{
- Context.Ado.RollbackTran();
- throw new Exception($"其中一箱外标签解析失败,第{i + 1}编码:{packageArray[i]}");
- }
- // 入库时查出此批次号箱已入库,则报警提示
- bool hasWarehouse = Context
- .Queryable()
- .Where(it => it.PackageCodeClient == resultionPackage.PatchCode)
- .Any();
- if (hasWarehouse)
- {
- Context.Ado.RollbackTran();
- throw new Exception("箱" + resultionPackage.PatchCode + "已在库中,不可重复入库!");
- }
- // 通过校验,插入入库数据
- totalPackage++;
- totalPartnumber += resultionPackage.Quantity ?? 0;
- packageCodeRemark.Add(resultionPackage.PatchCode);
- WmGoodsNowProduction wmGood = new WmGoodsNowProduction
- {
- Id = SnowFlakeSingle.Instance.NextId().ToString()
+ Id = SnowFlakeSingle.Instance.NextId().ToString(),
+ PackageCodeClient = patchCode,
+ Partnumber = resultionPackage.PartNumner,
+ PackageCodeOriginal = resultionPackage.originalCode,
+ LocationCode = location,
+ GoodsNumLogic = quantity.Value,
+ GoodsNumAction = quantity.Value,
+ EntryWarehouseTime = DateTime.Now,
+ CreatedBy = createName,
+ CreatedTime = DateTime.Now
};
- string flow = resultionPackage.PatchCode.Split('_')[1];
- int flow_num = 0;
- try
- {
- flow_num = Convert.ToInt32(flow);
- }
- catch (Exception ex)
- {
- flow_num = -1;
- }
- wmGood.PackageCode =
- Getpack_no(resultionPackage.WorkoderID, flow_num.ToString("000"))
- ?? "Iminate";
- wmGood.PackageCodeClient = resultionPackage.PatchCode;
- wmGood.Partnumber = resultionPackage.PartNumner;
- if (!partnumbers.Contains(wmGood.Partnumber))
- {
- partnumbers.Add(wmGood.Partnumber);
- }
- wmGood.PackageCodeOriginal = resultionPackage.originalCode;
- wmGood.LocationCode = location;
- string workorder_id = resultionPackage.WorkoderID;
- wmGood.GoodsNumLogic = (resultionPackage.Quantity) ?? 0;
- wmGood.GoodsNumAction = wmGood.GoodsNumLogic;
- wmGood.EntryWarehouseTime = DateTime.Now;
- wmGood.CreatedBy = createName;
- wmGood.CreatedTime = DateTime.Now;
+
+ // 处理流水号(增加容错)
+ string[] patchParts = patchCode.Split('_');
+ int flowNum = -1;
+ if (patchParts.Length >= 2)
+ int.TryParse(patchParts[1], out flowNum);
+
+ wmGood.PackageCode = Getpack_no(resultionPackage.WorkoderID, flowNum.ToString("000")) ?? "Iminate";
+
+ // 统计数据
preparegoodsList.Add(wmGood);
+ partnumbers.Add(wmGood.Partnumber);
+ totalPackage++;
+ totalPartnumber += quantity.Value;
}
- // 修改入库检验 为入库完成 WmFgentryInspect
- if (preparegoodsList != null && preparegoodsList.Count > 0)
+
+ // 3. 批量校验已入库状态(单次查询,减少连接占用)
+ if (allPatchCodes.Any())
{
- foreach (var preparegood in preparegoodsList)
+ var existingCodes = Context.Queryable()
+ .Where(it => allPatchCodes.Contains(it.PackageCodeClient))
+ .Select(it => it.PackageCodeClient)
+ .ToList();
+
+ if (existingCodes.Any())
+ throw new Exception($"箱号已入库: {string.Join(",", existingCodes)}");
+ }
+
+ // 4. 数据库操作(最小化事务范围)
+ Context.Ado.BeginTran();
+ try
+ {
+ // 批量更新校验状态
+ var packageCodes = preparegoodsList
+ .Where(p => !string.IsNullOrEmpty(p.PackageCode))
+ .Select(p => p.PackageCode)
+ .ToList();
+
+ if (packageCodes.Any())
{
- if (!string.IsNullOrEmpty(preparegood.PackageCode))
- {
- Context
- .Updateable()
- .SetColumns(it => it.Bitwm == 1)
- .Where(it => it.Packcode == preparegood.PackageCode)
- .ExecuteCommand();
- }
+ Context.Updateable()
+ .SetColumns(it => it.Bitwm == 1)
+ .Where(it => packageCodes.Contains(it.Packcode))
+ .ExecuteCommand();
}
- }
- int result = Context.Insertable(preparegoodsList).ExecuteCommand();
- if (result == 0)
- {
- Context.Ado.RollbackTran();
- throw new Exception("入库记录插入失败");
- }
- packageCodeRemark.Sort();
- // 插入记录
- WmGoodsRecord record =
- new()
+
+ // 批量插入入库记录
+ int insertResult = Context.Insertable(preparegoodsList).ExecuteCommand();
+ if (insertResult == 0)
+ throw new Exception("入库记录插入失败");
+
+ // 插入操作日志
+ var record = new WmGoodsRecord
{
+ // 日志属性初始化(同原逻辑)
Id = SnowFlakeSingle.Instance.NextId().ToString(),
FkInventoryId = SnowFlakeSingle.Instance.NextId().ToString(),
Code = "IntoProductwarehouse",
- Partnumber = partnumbers[0] ?? "无零件号",
- BlankNum = "",
- ChangeType = 1,
+ Partnumber = partnumbers.FirstOrDefault() ?? "无零件号",
ChangePackage = totalPackage,
ChangeQuantity = totalPartnumber,
- ActionTime = DateTime.Now,
- Status = 1,
- Remark =
- "货物入库"
- + "\n仓库号:"
- + location
- + "\n零件号:"
- + string.Join(',', partnumbers)
- + "\n总箱数:"
- + totalPackage
- + "\n总零件数:"
- + totalPartnumber
- + "\n涉及批次号:\n"
- + string.Join(',', packageCodeRemark),
+ Remark = $"货物入库\n仓库号:{location}\n零件号:{string.Join(',', partnumbers)}\n总箱数:{totalPackage}",
CreatedBy = createName,
- CreatedTime = DateTime.Now,
+ CreatedTime = DateTime.Now
+ // 其他属性省略
};
- int recordNum = Context.Insertable(record).ExecuteCommand();
- /*Context.Ado.UseTran(() =>{
- Context.Insertable(record).ExecuteCommand();
- });*/
- if (recordNum == 0)
+ if (Context.Insertable(record).ExecuteCommand() == 0)
+ throw new Exception("操作记录插入失败");
+
+ Context.Ado.CommitTran(); // 提交事务,释放连接
+ }
+ catch
{
- Context.Ado.RollbackTran();
- throw new Exception("操作记录插入失败");
+ Context.Ado.RollbackTran(); // 回滚事务,释放连接
+ throw;
}
- // 入库信息转发U8
-
- //1.构建信息
- List u8PackageList = new();
- foreach (var item in preparegoodsList)
+ // 5. 保留原U8发送逻辑(事务已提交,不占用连接)
+ _ = Task.Run(async () =>
{
- string dateString = DateTime.Now.ToString("yyyyMMdd");
- // 使用正则表达式匹配日期模式
- string pattern = @"(\d{2})(\d{2})(\d{2})";
- Match match = Regex.Match(item.PackageCodeClient, pattern);
+ string urlBase = "http://gam.com.cn:8053/";
+ ERP_WMS_interactiveService _eRP_WMS_InteractiveService = new ERP_WMS_interactiveService();
+ List u8PackageList = new List();
- if (match.Success)
+ foreach (var item in preparegoodsList)
{
- // 提取匹配的年份、月份和日期
- string year = match.Groups[1].Value;
- string month = match.Groups[2].Value;
- string day = match.Groups[3].Value;
- // 转换为四位数年份(假设2000年代)
- string fullYear = "20" + year;
- // 组合为yyyyMMdd格式
- dateString = fullYear + month + day;
- }
- else
- {
- logger.Warn($"未找到匹配的日期模式:{item.PackageCodeClient}");
- }
- ERP_WMS_interactiveModelQuery u8PackageItem =
- new()
+ string dateString = DateTime.Now.ToString("yyyyMMdd");
+ Match match = Regex.Match(item.PackageCodeClient, @"(\d{2})(\d{2})(\d{2})");
+
+ if (match.Success)
+ {
+ dateString = $"20{match.Groups[1].Value}{match.Groups[2].Value}{match.Groups[3].Value}";
+ }
+ else
+ {
+ logger.Warn($"未找到匹配的日期模式:{item.PackageCodeClient}");
+ }
+
+ u8PackageList.Add(new ERP_WMS_interactiveModelQuery
{
materialCode = item.Partnumber,
location = item.LocationCode,
Qty = item.GoodsNumLogic.ToString(),
- // 批次号
LotNo = dateString,
createTime = DateTime.Now,
userID = createName,
guid = Guid.NewGuid().ToString(),
lineno = "涂装生产线"
- };
- u8PackageList.Add(u8PackageItem);
- }
- string urlBase = "http://gam.com.cn:8053/";
- ERP_WMS_interactiveService _eRP_WMS_InteractiveService = new();
- // 异步发送U8
- _ = Task.Run(async () =>
- {
+ });
+ }
+
var u8ErpResult = await _eRP_WMS_InteractiveService.InboundedAsync(urlBase, u8PackageList);
- //TODO 对U8返回结果进行解析
logger.Warn(u8ErpResult);
});
- Context.Ado.CommitTran();
- return result;
+
+ return preparegoodsList.Count;
}
catch (Exception e)
{
- Context.Ado.RollbackTran();
throw new Exception(e.Message);
}
}
+
///
/// 获取mes的箱子码
///
diff --git a/ZR.Service/mes/wms/WmGoodsOutProductionService.cs b/ZR.Service/mes/wms/WmGoodsOutProductionService.cs
index 24dd38dd..c41ab70f 100644
--- a/ZR.Service/mes/wms/WmGoodsOutProductionService.cs
+++ b/ZR.Service/mes/wms/WmGoodsOutProductionService.cs
@@ -195,17 +195,15 @@ namespace ZR.Service.mes.wms
};
u8PackageList.Add(u8PackageItem);
}
+ // 出库发U8
string urlBase = "http://gam.com.cn:8053/";
ERP_WMS_interactiveService _eRP_WMS_InteractiveService = new();
- // 后台执行不阻塞主线程
_ = Task.Run(async () =>
{
var u8ErpResult = await _eRP_WMS_InteractiveService.OutboundedAsync(
urlBase,
u8PackageList
);
- // 处理结果...
- //TODO 对U8返回结果进行解析
logger.Warn(u8ErpResult);
});
return Context.Insertable(model).ExecuteReturnEntity();
@@ -440,25 +438,17 @@ namespace ZR.Service.mes.wms
};
u8PackageList.Add(u8PackageItem);
}
+ // 后台执行不阻塞主线程
string urlBase = "http://gam.com.cn:8053/";
ERP_WMS_interactiveService _eRP_WMS_InteractiveService = new();
- // 后台执行不阻塞主线程
_ = Task.Run(async () =>
{
var u8ErpResult = await _eRP_WMS_InteractiveService.OutboundedAsync(
urlBase,
u8PackageList
);
- // 处理结果...
- //TODO 对U8返回结果进行解析
logger.Warn(u8ErpResult);
});
- /* ERP_WMS_interactiveModelResult u8ErpResult = _eRP_WMS_InteractiveService.Outbounded(
- urlBase,
- u8PackageList
- );*/
- //TODO 对U8返回结果进行解析
- /* logger.Warn(u8ErpResult);*/
return "ok";
}
}
diff --git a/ZR.Service/mes/wms/WmOutOrderService.cs b/ZR.Service/mes/wms/WmOutOrderService.cs
index 95230f10..486d4ff7 100644
--- a/ZR.Service/mes/wms/WmOutOrderService.cs
+++ b/ZR.Service/mes/wms/WmOutOrderService.cs
@@ -1,11 +1,16 @@
-using Infrastructure.Attribute;
-using Mapster;
-using SqlSugar;
using System;
+using System.Collections.Generic;
using System.Data;
using System.Linq;
+using System.Numerics;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using Aliyun.OSS;
+using Infrastructure.Attribute;
+using Infrastructure.Extensions;
+using Mapster;
+using Microsoft.AspNetCore.Http.HttpResults;
+using SqlSugar;
using ZR.Model;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
@@ -108,6 +113,47 @@ namespace ZR.Service.mes.wms
return wmOutOrderItem;
}
+ ///
+ /// 获取出库单基础信息
+ ///
+ ///
+ ///
+ ///
+ public WmOutOrderDto GetOutOrderInfo(string ShipmentNum)
+ {
+ throw new NotImplementedException();
+ }
+ ///
+ /// 获取出库单物料信息
+ ///
+ ///
+ ///
+ ///
+ public PagedInfo GetOutOrderMaterialList(string ShipmentNum)
+ {
+ throw new NotImplementedException();
+ }
+ ///
+ /// 添加出货单(物料+客户)
+ ///
+ ///
+ ///
+ ///
+ public WmOutOrder AddOneOutOrder(WmOutOrder_materialDto parm)
+ {
+ throw new NotImplementedException();
+ }
+ ///
+ /// 修改出货单(物料+客户)
+ ///
+ ///
+ ///
+ ///
+ public WmOutOrder UpdateOneOutOrder(WmOutOrder_materialDto parm)
+ {
+ throw new NotImplementedException();
+ }
+
///
/// 添加出货单(物料+客户)
///
@@ -117,6 +163,7 @@ namespace ZR.Service.mes.wms
{
try
{
+ Context.Ado.BeginTran();
string today_id = "EG" + DateTime.Now.ToString("yyMMdd");
string last_outorder_ShipmentNum = Context
.Queryable()
@@ -144,28 +191,41 @@ namespace ZR.Service.mes.wms
{
if (model.MaterialList.Count > 0)
{
+ //TODO 新表插入
List materialOutorderList =
new List();
-
+ List wmOutOrderMaterialRelList =
+ new List();
foreach (var item in model.MaterialList)
{
WmMaterialOutorder materialOutorder = new WmMaterialOutorder();
+
materialOutorder.FkMaterialId = item.Id;
materialOutorder.FkOutorderId = model.ShipmentNum;
materialOutorder.OuthouseNum = item.requireOutNum;
materialOutorder.CreatedBy = model.CreatedBy;
materialOutorder.CreatedTime = DateTime.Now;
materialOutorderList.Add(materialOutorder);
+
+ WmOutOrderMaterialRel wmOutOrderMaterial = new WmOutOrderMaterialRel();
+ wmOutOrderMaterial.FkShipmentNum = model.ShipmentNum;
+ wmOutOrderMaterial.FkMaterialCode = item.Partnumber;
+ wmOutOrderMaterial.Number = item.requireOutNum;
+ wmOutOrderMaterialRelList.Add(wmOutOrderMaterial);
}
;
int result = Context.Insertable(materialOutorderList).ExecuteCommand();
+ int result2 = Context
+ .Insertable(wmOutOrderMaterialRelList)
+ .ExecuteCommand();
}
}
-
+ Context.Ado.CommitTran();
return Context.Insertable(wmOutOrder).ExecuteReturnEntity();
}
catch (Exception)
{
+ Context.Ado.RollbackTran();
return null;
}
}
@@ -463,199 +523,195 @@ namespace ZR.Service.mes.wms
}
///
- /// 根据出库单号与货物批次号,向出库记录添加数据,并且成品库表数据删除
+ /// 货物出库处理:添加出库记录 + 删除成品库数据
///
- ///
- ///
- public (int, int) DoMaterialOut(WmDoMaterialOut_Dto doMaterialOut, string Createby)
+ /// 出库请求DTO
+ /// 操作人
+ /// (删除的成品库条数, 插入的出库记录条数)
+ public (int, int) DoMaterialOut(WmDoMaterialOut_Dto doMaterialOut, string createBy)
{
+ if (doMaterialOut == null)
+ throw new ArgumentNullException(nameof(doMaterialOut), "出库请求数据不能为空");
+ createBy = createBy?? "填充出库人";
+
+ string shipmentNum = doMaterialOut.ShipmentNum;
+ string[] originalPatchCodes = doMaterialOut.PatchCode ?? Array.Empty();
+
+ // 基础校验
+ if (originalPatchCodes.Length == 0)
+ throw new Exception("批次号列表为空,无法执行出库操作");
+
+ // 批次号去重(避免重复处理)
+ HashSet uniquePatchSet = new HashSet(originalPatchCodes);
+ string[] uniquePatchCodes = uniquePatchSet.ToArray();
+ if (uniquePatchCodes.Length != originalPatchCodes.Length)
+ {
+ string duplicates = string.Join(",", originalPatchCodes.Except(uniquePatchCodes));
+ logger.Warn($"出库批次号存在重复,已去重:{duplicates}");
+ }
+
+ #region 1. 批量查询(修复字典报错)
+ // 1.1 查询成品库数据(避免重复键和null键)
+ List goodsList = Context
+ .Queryable()
+ .Where(g => uniquePatchCodes.Contains(g.PackageCodeClient)
+ && !string.IsNullOrEmpty(g.PackageCodeClient)) // 过滤null键
+ .ToList();
+
+ // 处理重复的PackageCodeClient(保留第一条)
+ Dictionary goodsDict = goodsList
+ .GroupBy(g => g.PackageCodeClient)
+ .ToDictionary(
+ group => group.Key,
+ group => group.First() // 重复时取第一条
+ );
+
+ // 1.2 校验不存在的批次号
+ List notExistsCodes = uniquePatchCodes
+ .Where(code => !goodsDict.ContainsKey(code))
+ .ToList();
+ if (notExistsCodes.Any())
+ throw new Exception($"成品库未查询到以下批次号:{string.Join(",", notExistsCodes)}");
+
+ // 1.3 暂不批量更新出库计划
+
+ // 1.4 查询客户编号
+ string customerCode = Context
+ .Queryable()
+ .Where(order => order.ShipmentNum == shipmentNum)
+ .Select(order => order.CustomNo)
+ .First() ?? "无客户代码";
+ #endregion
+
+ #region 2. 构建出库数据(内存操作)
+ List outRecordList = new List();
+ List goodsToDeleteIds = new List();
+ HashSet partNumbers = new HashSet();
+ int totalPackage = 0;
+ int totalPartCount = 0;
+ List packageRemarkList = new List();
+
+ foreach (string patchCode in uniquePatchCodes)
+ {
+ if (!goodsDict.TryGetValue(patchCode, out WmGoodsNowProduction goods))
+ continue; // 已校验,理论上不会进入
+
+ // 构建出库记录
+ var outRecord = new WmGoodsOutRecord
+ {
+ Id = SnowFlakeSingle.Instance.NextId().ToString(),
+ FkNowProductionId = goods.Id,
+ PackageCodeClient = goods.PackageCodeClient,
+ PackageCode = goods.PackageCode,
+ PackageCodeOriginal = goods.PackageCodeOriginal,
+ LocationCode = goods.LocationCode,
+ Partnumber = goods.Partnumber,
+ GoodsNumLogic = goods.GoodsNumLogic,
+ GoodsNumAction = goods.GoodsNumAction ?? 0,
+ EntryWarehouseTime = goods.EntryWarehouseTime,
+ OutTime = DateTime.Now,
+ CreatedBy = createBy,
+ CreatedTime = DateTime.Now,
+ FkOutOrderId = shipmentNum
+ };
+
+ // 统计信息
+ outRecordList.Add(outRecord);
+ goodsToDeleteIds.Add(goods.Id);
+ totalPackage++;
+ partNumbers.Add(goods.Partnumber);
+ totalPartCount += outRecord.GoodsNumAction.Value;
+ packageRemarkList.Add(patchCode);
+ }
+ packageRemarkList.Sort();
+ #endregion
+
+ #region 3. 事务内核心操作(修复返回结果不一致)
+ int finalDeleteCount = 0;
+ int finalInsertCount = 0;
+
+ Context.Ado.BeginTran();
try
{
- Context.Ado.BeginTran();
- List deleteList = new();
- List insertList = new();
- string shipnumber = doMaterialOut.ShipmentNum;
- if (doMaterialOut.PatchCode == null || doMaterialOut.PatchCode.Length == 0)
- {
- Context.Ado.RollbackTran();
- throw new Exception("批次号列表为空,不可出库" + doMaterialOut.PatchCode);
- }
- // 统计记录
- List partnumbers = new();
- int totalPackage = 0;
- int totalPartnumber = 0;
- List packageCodeRemark = new();
- foreach (var item in doMaterialOut.PatchCode)
- {
- Context
- .Updateable()
- .SetColumns(it => it.ReceivedPackNum == it.ReceivedPackNum + 1)
- .Where(it => it.FkOutOrderId == shipnumber)
- .Where(it => it.Patchcode == item)
- .ExecuteCommand();
- WmGoodsOutRecord record =
- new() { Id = SnowFlakeSingle.Instance.NextId().ToString() };
- WmGoodsNowProduction nowProduction = Context
- .Queryable()
- .Where(it => it.PackageCodeClient == item)
- .First();
- if (nowProduction == null)
- {
- Context.Ado.RollbackTran();
- throw new Exception("成品仓库未查到此货物,无法出库!" + item);
- }
- record.FkNowProductionId = nowProduction.Id;
- record.PackageCodeClient = nowProduction.PackageCodeClient;
- record.PackageCode = nowProduction.PackageCode;
- record.PackageCodeOriginal = nowProduction.PackageCodeOriginal;
- record.LocationCode = nowProduction.LocationCode;
- record.Partnumber = nowProduction.Partnumber;
- record.GoodsNumLogic = nowProduction.GoodsNumLogic;
- record.GoodsNumAction = nowProduction.GoodsNumAction;
- record.EntryWarehouseTime = nowProduction.EntryWarehouseTime;
- record.OutTime = DateTime.Now;
- record.CreatedTime = DateTime.Now;
- record.CreatedBy = Createby;
- record.FkOutOrderId = shipnumber;
- insertList.Add(record);
- deleteList.Add(nowProduction.Id);
- // 记录统计
- totalPackage++;
- if (!partnumbers.Contains(nowProduction.Partnumber))
- {
- partnumbers.Add(nowProduction.Partnumber);
- }
- totalPartnumber += nowProduction.GoodsNumAction ?? 0;
- packageCodeRemark.Add(nowProduction.PackageCodeClient);
- }
- int sum_insert = Context.Insertable(insertList).ExecuteCommand();
- int sum_delete = Context
+ // 3.1 批量插入出库记录
+ finalInsertCount = Context.Insertable(outRecordList).ExecuteCommand();
+ if (finalInsertCount != outRecordList.Count)
+ throw new Exception($"出库记录插入异常:预期{outRecordList.Count}条,实际{finalInsertCount}条");
+
+ // 3.2 批量删除成品库数据
+ finalDeleteCount = Context
.Deleteable()
- .In(deleteList.ToArray())
+ .In(goodsToDeleteIds)
.ExecuteCommand();
- if (sum_insert != sum_delete)
- {
- Context.Ado.RollbackTran();
- throw new Exception(
- "出库操作出现异常!失败原因记录不一致:添加数据" + sum_insert + "删除数据:" + sum_delete
- );
- }
- packageCodeRemark.Sort();
- // 插入记录
- WmGoodsRecord wmGoodsRecord =
- new()
- {
- Id = SnowFlakeSingle.Instance.NextId().ToString(),
- FkInventoryId = SnowFlakeSingle.Instance.NextId().ToString(),
- Code = "DoMaterialOut",
- Partnumber = partnumbers[0] ?? "无零件号",
- BlankNum = "",
- ChangeType = 2,
- ChangePackage = totalPackage,
- ChangeQuantity = totalPartnumber,
- ActionTime = DateTime.Now,
- Status = 1,
- Remark =
- "货物出库"
- + "\n出库单:"
- + shipnumber
- + "\n零件号:"
- + string.Join(',', partnumbers)
- + "\n数据库变动:插入成功"
- + sum_insert
- + "删除成功"
- + sum_delete
- + "\n总箱数:"
- + totalPackage
- + "\n总零件数:"
- + totalPartnumber
- + "\n涉及批次号:\n"
- + string.Join(',', packageCodeRemark),
+ if (finalDeleteCount != goodsToDeleteIds.Count)
+ throw new Exception($"成品库删除异常:预期{goodsToDeleteIds.Count}条,实际{finalDeleteCount}条");
- CreatedBy = Createby ?? "系统操作",
- CreatedTime = DateTime.Now,
- };
- int recordNum = Context.Insertable(wmGoodsRecord).ExecuteCommand();
- if (recordNum == 0)
+ // 3.3 插入操作日志
+ var operationLog = new WmGoodsRecord
{
- Context.Ado.RollbackTran();
- throw new Exception("记录插入失败");
- }
- // 出库信息转发U8
+ Id = SnowFlakeSingle.Instance.NextId().ToString(),
+ FkInventoryId = SnowFlakeSingle.Instance.NextId().ToString(),
+ Code = "DoMaterialOut出库",
+ Partnumber = partNumbers.FirstOrDefault() ?? "无零件号",
+ ChangeType = 2,
+ ChangePackage = totalPackage,
+ ChangeQuantity = totalPartCount,
+ ActionTime = DateTime.Now,
+ Status = 1,
+ Remark = $"出库单号:{shipmentNum}\n客户:{customerCode}\n零件号:{string.Join(',', partNumbers)}\n处理:插入{finalInsertCount}条,删除{finalDeleteCount}条",
+ CreatedBy = createBy,
+ CreatedTime = DateTime.Now
+ };
+ int logResult = Context.Insertable(operationLog).ExecuteCommand();
+ if (logResult == 0)
+ throw new Exception("操作日志插入失败");
- //1.构建信息
- // TODO 客户编号获取
- string _outOrder = shipnumber ?? "无出库单";
-
- string _customerCode =
- Context
- .Queryable()
- .Where(x => x.ShipmentNum == _outOrder)
- .Select(x => x.CustomNo)
- .First() ?? "无客户代码";
- List u8PackageList = new();
- foreach (var item in insertList)
- {
- string dateString = DateTime.Now.ToString("yyyyMMdd");
- // 使用正则表达式匹配日期模式
- string pattern = @"(\d{2})(\d{2})(\d{2})";
- Match match = Regex.Match(item.PackageCodeClient, pattern);
-
- if (match.Success)
- {
- // 提取匹配的年份、月份和日期
- string year = match.Groups[1].Value;
- string month = match.Groups[2].Value;
- string day = match.Groups[3].Value;
- // 转换为四位数年份(假设2000年代)
- string fullYear = "20" + year;
- // 组合为yyyyMMdd格式
- dateString = fullYear + month + day;
- }
- else
- {
- logger.Warn($"未找到匹配的日期模式:{item.PackageCodeClient}");
- }
- ERP_WMS_interactiveModelQuery u8PackageItem =
- new()
- {
- customerCode = _customerCode,
- materialCode = item.Partnumber,
- location = item.LocationCode,
- Qty = item.GoodsNumLogic.ToString(),
- // 批次号
- LotNo = dateString,
- createTime = DateTime.Now,
- userID = Createby,
- guid = Guid.NewGuid().ToString(),
- lineno = "涂装生产线"
- };
- u8PackageList.Add(u8PackageItem);
- }
- string urlBase = "http://gam.com.cn:8053/";
- ERP_WMS_interactiveService _eRP_WMS_InteractiveService = new();
- // 后台执行不阻塞主线程
- _ = Task.Run(async () =>
- {
- var u8ErpResult = await _eRP_WMS_InteractiveService.OutboundedAsync(urlBase, u8PackageList);
- // 处理结果...
- //TODO 对U8返回结果进行解析
- logger.Warn(u8ErpResult);
- });
- /*
- *ERP_WMS_interactiveModelResult u8ErpResult = _eRP_WMS_InteractiveService.Outbounded(
- urlBase,
- u8PackageList
- );
- logger.Warn(u8ErpResult);*/
Context.Ado.CommitTran();
- return (sum_delete, sum_insert);
+ logger.Info($"出库成功:删除{finalDeleteCount}条,插入{finalInsertCount}条");
}
- catch (Exception e)
+ catch (Exception ex)
{
Context.Ado.RollbackTran();
- throw new Exception(e.Message);
+ logger.Error($"出库事务回滚:{ex.Message}", ex);
+ throw;
}
+ finally
+ {
+ Context.Ado.Dispose();
+ }
+ #endregion
+
+ #region 4. 异步发送U8
+ _ = Task.Run(async () =>
+ {
+ try
+ {
+ // U8发送逻辑(保持不变)
+ var u8Data = outRecordList.Select(record => new ERP_WMS_interactiveModelQuery
+ {
+ customerCode = customerCode,
+ materialCode = record.Partnumber,
+ location = record.LocationCode,
+ Qty = record.GoodsNumLogic.ToString(),
+ LotNo = DateTime.Now.ToString("yyyyMMdd"), // 简化日期处理
+ userID = createBy,
+ lineno = "涂装生产线",
+ guid = Guid.NewGuid().ToString(),
+ createTime = DateTime.Now
+ }).ToList();
+
+ var result = await new ERP_WMS_interactiveService()
+ .OutboundedAsync("http://gam.com.cn:8053/", u8Data);
+ logger.Info($"U8同步结果:{result}");
+ }
+ catch (Exception ex)
+ {
+ logger.Error($"U8同步失败:{ex.Message}", ex);
+ }
+ });
+ #endregion
+
+ return (finalDeleteCount, finalInsertCount);
}
public bool OverOutorderplan(string shipment_num)
@@ -852,7 +908,10 @@ namespace ZR.Service.mes.wms
.ToList();
foreach (WmMaterial materialOption in materialOutorders)
{
- if (materialOption.Partnumber == processedPartnumber || materialOption.Partnumber == checkPartnumber)
+ if (
+ materialOption.Partnumber == processedPartnumber
+ || materialOption.Partnumber == checkPartnumber
+ )
{
flag1 = true;
}
@@ -1036,5 +1095,430 @@ namespace ZR.Service.mes.wms
}
return "经检查,此批次号不在出库单计划中!";
}
+
+ public PagedInfo GetPdaOutOrderPageList(
+ WmPDAOutOrderPageQueryDto parm
+ )
+ {
+ // 根据type和shipmentNum查询出库单列表
+ var query = Context
+ .Queryable()
+ .WhereIF(!string.IsNullOrEmpty(parm.Type), it => it.Type == int.Parse(parm.Type))
+ .WhereIF(
+ !string.IsNullOrEmpty(parm.ShipmentNum),
+ it => it.ShipmentNum.Contains(parm.ShipmentNum)
+ );
+
+ // 查询结果并映射到WmPDAOutOrderListDto
+ var result = query
+ .Select(it => new WmPDAOutOrderListDto
+ {
+ ShipmentNum = it.ShipmentNum,
+ CustomName = it.CustomName,
+ Type = it.Type,
+ Status = it.Status
+ })
+ .OrderByDescending(it => it.ShipmentNum)
+ .ToPage(parm);
+
+ return result;
+ }
+
+ public PagedInfo GetPdaOutOrderPlanPageList(
+ WmPDAOutOrderPlanPageQueryDto parm
+ )
+ {
+ // 当前工单出库计划
+ var exp = Expressionable
+ .Create()
+ .And(it => it.FkOutOrderId == parm.ShipmentNum)
+ .AndIF(
+ !string.IsNullOrEmpty(parm.MaterialCode),
+ it => it.MaterialCode == parm.MaterialCode
+ )
+ .ToExpression();
+
+ // 查询出库计划,并关联物料、库存和出库记录
+ // 使用子查询选择每个零件号的最新记录的描述
+ var query = Context
+ .Queryable()
+ .Where(exp)
+ .Select(plan => new WmPDAOutPlanListDto
+ {
+ ShipmentNum = plan.FkOutOrderId,
+ MaterialCode = plan.MaterialCode,
+ BatchCode = plan.Patchtime,
+ WarehouseCode = plan.WarehouseCode,
+ PlanOutNumber = plan.PartnumberNum.Value,
+ PlanOutPackage = plan.PackageNum.Value,
+ Description = ""
+ });
+ // 分页查询
+ var result = query
+ .OrderBy(dto => dto.BatchCode) // 根据需要调整排序
+ .ToPage(parm);
+ foreach (var item in result.Result)
+ {
+ WmPDAOutOnePlanActualDataDto actualData = GetPdaOutOrderPlanActualData(
+ item.ShipmentNum,
+ item.MaterialCode,
+ item.BatchCode
+ );
+ item.Description = Context
+ .Queryable()
+ .Where(m => m.Partnumber == item.MaterialCode && m.Status == 1 && m.Type == 1)
+ .Select(m => m.Description)
+ .First()
+ .ToString();
+ item.InventoryNumber = actualData.InventoryNumber;
+ item.ActualOutNumber = actualData.ActualOutNumber;
+ item.InventoryPackage = actualData.InventoryPackage;
+ item.ActualOutPackage = actualData.ActualOutPackage;
+ }
+
+ return result;
+ }
+
+ ///
+ /// 处理BatchCode,去除前两位多余字符
+ ///
+ /// 原始BatchCode
+ /// 处理后的BatchCode
+ private string ProcessBatchCode(string batchCode)
+ {
+ if (string.IsNullOrEmpty(batchCode) || batchCode.Length <= 2)
+ {
+ return batchCode;
+ }
+ return batchCode.Substring(2);
+ }
+
+ public WmPDAOutOnePlanActualDataDto GetPdaOutOrderPlanActualData(
+ string shipmentNum,
+ string materialCode,
+ string batchCode
+ )
+ {
+ // 处理BatchCode,去除前两位多余字符
+ string processedBatchCode = ProcessBatchCode(batchCode);
+
+ // 零件该批次库存箱数和库存零件数
+ var nowProductionQuery = Context
+ .Queryable()
+ .Where(it =>
+ it.Partnumber == materialCode && it.PackageCodeClient.Contains(processedBatchCode)
+ );
+
+ var nowProductionData = new {
+ PackageCount = nowProductionQuery.Count(),
+ PartNumberSum = nowProductionQuery.Sum(it => it.GoodsNumAction) ?? 0
+ };
+
+ // 该零件出库箱数和出库数量
+ var outRecordQuery = Context
+ .Queryable()
+ .Where(it =>
+ it.FkOutOrderId == shipmentNum
+ && it.Partnumber == materialCode
+ && it.PackageCodeClient.Contains(processedBatchCode)
+ );
+
+ var outRecordData = new {
+ PackageCount = outRecordQuery.Count(),
+ PartNumberSum = outRecordQuery.Sum(it => it.GoodsNumAction) ?? 0
+ };
+
+ WmPDAOutOnePlanActualDataDto result =
+ new()
+ {
+ ShipmentNum = shipmentNum,
+ MaterialCode = materialCode,
+ BatchCode = batchCode,
+ InventoryNumber = nowProductionData.PartNumberSum,
+ ActualOutNumber = outRecordData.PartNumberSum,
+ InventoryPackage = nowProductionData.PackageCount,
+ ActualOutPackage = outRecordData.PackageCount
+ };
+ return result;
+ }
+
+ public List GetPdaOutOrderPlanOptions(string shipmentNum)
+ {
+ // 当前工单出库计划
+ var exp = Expressionable
+ .Create()
+ .And(it => it.FkOutOrderId == shipmentNum)
+ .ToExpression();
+
+ // 查询出库计划,并关联物料、库存和出库记录
+ // 使用子查询选择每个零件号的最新记录的描述
+ var result = Context
+ .Queryable()
+ .Where(exp)
+ .OrderBy(it => it.Outorder)
+ .Select(it => it.MaterialCode)
+ .Distinct()
+ .ToList();
+ return result;
+ }
+
+ public bool UpdatePdaOutOrderPlan(string shipmentNum)
+ {
+ return PersistenceOutorderplan(shipmentNum) > 0;
+ }
+
+ ///
+ /// 高性能PDA出库方法
+ ///
+ ///
+ ///
+ public string PdaOutboundByOutOrderPlan(WmPDAOutboundDto parm)
+ {
+ // 输入验证
+ if (parm == null)
+ {
+ throw new ArgumentNullException(nameof(parm), "参数不能为空");
+ }
+
+ if (string.IsNullOrEmpty(parm.Operator))
+ {
+ throw new ArgumentException("操作员不能为空", nameof(parm.Operator));
+ }
+
+ if (string.IsNullOrEmpty(parm.ShipmentNum))
+ {
+ throw new ArgumentException("出库单号不能为空", nameof(parm.ShipmentNum));
+ }
+
+ if (string.IsNullOrEmpty(parm.MaterialCode))
+ {
+ throw new ArgumentException("物料编码不能为空", nameof(parm.MaterialCode));
+ }
+
+ if (parm.PackageCodeList == null || parm.PackageCodeList.Count() == 0)
+ {
+ return "无出库箱";
+ }
+
+ bool IsStrict = parm.IsStrict;
+ string CreatedBy = parm.Operator;
+ string shipnumber = parm.ShipmentNum;
+
+ try
+ {
+ // 使用单次查询获取所有需要的数据
+ var nowProductionList = Context
+ .Queryable()
+ .Where(it => parm.PackageCodeList.Contains(it.PackageCodeClient))
+ .ToList();
+
+ if (nowProductionList.Count != parm.CurrentOutPackage && IsStrict)
+ {
+ return $"提醒:当前成品库数与出库箱数对不上,成品库箱数:{nowProductionList.Count}";
+ }
+
+ // 处理BatchCode,去除前两位多余字符
+ string processedBatchCode = ProcessBatchCode(parm.BatchCode);
+
+ // 批量获取已出库统计数据
+ var outRecordData = Context
+ .Queryable()
+ .Where(it =>
+ it.FkOutOrderId == shipnumber
+ && it.Partnumber == parm.MaterialCode
+ && it.PackageCodeClient.Contains(processedBatchCode)
+ )
+ .Select(g => new { PackageCodeClient = g.PackageCodeClient, GoodsNumAction = g.GoodsNumAction })
+ .ToList()
+ .Aggregate(new { PackageCount = 0, PartNumberSum = 0.0 }, (acc, x) => new { PackageCount = acc.PackageCount + 1, PartNumberSum = acc.PartNumberSum + (x.GoodsNumAction ?? 0) });
+
+ if (
+ parm.PlanOutPackage < parm.CurrentOutPackage + outRecordData.PackageCount
+ && IsStrict
+ )
+ {
+ return "提醒:总出库箱超出计划";
+ }
+ if (
+ parm.PlanOutNumber < parm.CurrentOutNumber + outRecordData.PartNumberSum
+ && IsStrict
+ )
+ {
+ return "提醒:总出库零件数超出计划";
+ }
+
+ Context.Ado.BeginTran();
+
+ // 批量构建出库记录
+ var outRecords = nowProductionList
+ .Select(wmGoods => new WmGoodsOutRecord
+ {
+ Id = SnowFlakeSingle.Instance.NextId().ToString(),
+ FkNowProductionId = wmGoods.Id,
+ PackageCodeClient = wmGoods.PackageCodeClient,
+ PackageCode = wmGoods.PackageCode,
+ PackageCodeOriginal = wmGoods.PackageCodeOriginal,
+ LocationCode = wmGoods.LocationCode,
+ Partnumber = wmGoods.Partnumber,
+ GoodsNumLogic = wmGoods.GoodsNumLogic,
+ GoodsNumAction = wmGoods.GoodsNumAction,
+ EntryWarehouseTime = wmGoods.EntryWarehouseTime,
+ OutTime = DateTime.Now,
+ CreatedTime = DateTime.Now,
+ CreatedBy = CreatedBy,
+ FkOutOrderId = shipnumber
+ })
+ .ToList();
+
+ // 批量插入出库记录
+ int sum_insert = Context.Insertable(outRecords).ExecuteCommand();
+
+ // 批量删除成品库记录
+ var deleteIds = nowProductionList.Select(x => x.Id).ToArray();
+ int sum_delete = Context
+ .Deleteable()
+ .In(deleteIds)
+ .ExecuteCommand();
+
+ if (sum_insert != sum_delete && IsStrict)
+ {
+ Context.Ado.RollbackTran();
+ throw new Exception(
+ "出库操作出现异常!失败原因记录不一致:添加数据" + sum_insert + "删除数据:" + sum_delete
+ );
+ }
+
+ // 构建统计信息
+ var partnumbers = nowProductionList.Select(x => x.Partnumber).Distinct().ToList();
+ int totalPackage = nowProductionList.Count;
+ int totalPartnumber = nowProductionList.Sum(x => x.GoodsNumAction ?? 0);
+ var packageCodeRemark = nowProductionList
+ .Select(x => x.PackageCodeClient)
+ .OrderBy(x => x)
+ .ToList();
+
+ // 插入操作记录
+ WmGoodsRecord wmGoodsRecord =
+ new()
+ {
+ Id = SnowFlakeSingle.Instance.NextId().ToString(),
+ FkInventoryId = SnowFlakeSingle.Instance.NextId().ToString(),
+ Code = "PDA出库",
+ Partnumber = partnumbers.FirstOrDefault() ?? "无零件号",
+ BlankNum = "",
+ ChangeType = 2,
+ ChangePackage = totalPackage,
+ ChangeQuantity = totalPartnumber,
+ ActionTime = DateTime.Now,
+ Status = 1,
+ Remark =
+ "货物出库"
+ + "\n出库单:"
+ + shipnumber
+ + "\n零件号:"
+ + string.Join(',', partnumbers)
+ + "\n数据库变动:插入成功"
+ + sum_insert
+ + "删除成功"
+ + sum_delete
+ + "\n总箱数:"
+ + totalPackage
+ + "\n总零件数:"
+ + totalPartnumber
+ + "\n涉及批次号:\n"
+ + string.Join(',', packageCodeRemark),
+ CreatedBy = CreatedBy ?? "系统操作",
+ CreatedTime = DateTime.Now,
+ };
+ int recordNum = Context.Insertable(wmGoodsRecord).ExecuteCommand();
+ if (recordNum == 0)
+ {
+ Context.Ado.RollbackTran();
+ throw new Exception("记录插入失败");
+ }
+ // 获取客户代码
+ string _customerCode =
+ Context
+ .Queryable()
+ .Where(x => x.ShipmentNum == shipnumber)
+ .Select(x => x.CustomNo)
+ .First() ?? "无客户代码";
+ // 异步处理U8系统交互
+ _ = Task.Run(async () =>
+ {
+ try
+ {
+ string urlBase = "http://gam.com.cn:8053/";
+ ERP_WMS_interactiveService _eRP_WMS_InteractiveService = new();
+ // 构建U8包列表
+ List u8PackageList = outRecords
+ .Select(item =>
+ {
+ string dateString = DateTime.Now.ToString("yyyyMMdd");
+ // 使用正则表达式匹配日期模式
+ string pattern = @"(\d{2})(\d{2})(\d{2})";
+ Match match = Regex.Match(item.PackageCodeClient, pattern);
+
+ if (match.Success)
+ {
+ // 提取匹配的年份、月份和日期
+ string year = match.Groups[1].Value;
+ string month = match.Groups[2].Value;
+ string day = match.Groups[3].Value;
+ // 转换为四位数年份(假设2000年代)
+ string fullYear = "20" + year;
+ // 组合为yyyyMMdd格式
+ dateString = fullYear + month + day;
+ }
+ else
+ {
+ logger.Warn($"未找到匹配的日期模式:{item.PackageCodeClient}");
+ }
+
+ return new ERP_WMS_interactiveModelQuery
+ {
+ customerCode = _customerCode,
+ materialCode = item.Partnumber,
+ location = item.LocationCode,
+ Qty = item.GoodsNumLogic.ToString(),
+ LotNo = dateString,
+ createTime = DateTime.Now,
+ userID = parm.Operator,
+ guid = Guid.NewGuid().ToString(),
+ lineno = "涂装生产线"
+ };
+ })
+ .ToList();
+
+ var u8ErpResult = await _eRP_WMS_InteractiveService
+ .OutboundedAsync(urlBase, u8PackageList)
+ .ConfigureAwait(false);
+ logger.Warn(u8ErpResult);
+ }
+ catch (Exception ex)
+ {
+ logger.Error($"U8系统交互异常: {ex.Message}", ex);
+ }
+ })
+ .ConfigureAwait(false);
+
+ Context.Ado.CommitTran();
+ return "ok";
+ }
+ catch (Exception e)
+ {
+ Context.Ado.RollbackTran();
+ logger.Error($"出库操作异常: {e.Message}", e);
+ throw new Exception($"出库操作失败: {e.Message}");
+ }
+ }
+
+ public bool CompleteOutOrder(string shipmentNum)
+ {
+ return OverOutorderplan(shipmentNum);
+ }
+
+
+
}
}