diff --git a/Myshipping.Application/Entity/TaskManagePlat/TaskStoreMsgInfo.cs b/Myshipping.Application/Entity/TaskManagePlat/TaskStoreMsgInfo.cs new file mode 100644 index 00000000..f2311a21 --- /dev/null +++ b/Myshipping.Application/Entity/TaskManagePlat/TaskStoreMsgInfo.cs @@ -0,0 +1,34 @@ +using Myshipping.Application.Entity; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// 任务报文表 + /// + [SugarTable("task_store_msg")] + [Description(" 任务报文表")] + public class TaskStoreMsgInfo : TaskManageDbEntity + { + /// + /// 任务主键(父主键) + /// + public string TASK_PKID { get; set; } + + /// + /// 报文JSON + /// + public string MSG_JSON { get; set; } + + /// + /// 报文类型 BC_MSG-订舱确认报文 + /// + public string MSG_TYPE { get; set; } + } +} diff --git a/Myshipping.Application/Enum/TaskStoreMsgTypeEnum.cs b/Myshipping.Application/Enum/TaskStoreMsgTypeEnum.cs new file mode 100644 index 00000000..e76cc8a9 --- /dev/null +++ b/Myshipping.Application/Enum/TaskStoreMsgTypeEnum.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// 任务报文类型枚举 + /// + public enum TaskStoreMsgTypeEnum + { + /// + /// 订舱确认报文 + /// + [Description("订舱确认报文")] + BC_MSG, + } +} diff --git a/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs b/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs index bb516ad2..5242299f 100644 --- a/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs +++ b/Myshipping.Application/Service/BookingOrder/BookingOrderService.cs @@ -2850,6 +2850,7 @@ namespace Myshipping.Application } #endregion + [NonAction] public async Task InnerBookingOrClosingEDI(BookingOrClosingEDIOrderDto model) { string batchNo = IDGen.NextID().ToString(); @@ -3221,7 +3222,8 @@ namespace Myshipping.Application /// 订单主键 /// 订单号 /// 是否使用货代代码 - /// 货代代码 + /// 货代代码 + /// 货代称呼 /// 文件功能 (9原始,1 更新,5 退舱 ) /// 发送类型 B-订舱 E-截单 /// diff --git a/Myshipping.Application/Service/BookingOrder/IBookingOrderService.cs b/Myshipping.Application/Service/BookingOrder/IBookingOrderService.cs index adc38634..2f089214 100644 --- a/Myshipping.Application/Service/BookingOrder/IBookingOrderService.cs +++ b/Myshipping.Application/Service/BookingOrder/IBookingOrderService.cs @@ -43,5 +43,7 @@ namespace Myshipping.Application Task SendBookingOrClosingEDI (BookingOrClosingEDIOrderDto model); Task BachUpdate(BatchUpdate dto); + + Task InnerBookingOrClosingEDI(BookingOrClosingEDIOrderDto model); } } \ No newline at end of file diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/CalcLaraPageNumbersDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/CalcLaraPageNumbersDto.cs new file mode 100644 index 00000000..dee4d66d --- /dev/null +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/CalcLaraPageNumbersDto.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// + /// + public class CalcLaraPageNumbersDto + { + /// + /// 请求LARA纸列表 + /// + public List paperList { get; set; } + + /// + /// 当前任务主键 + /// + public string taskPkId { get; set; } + + /// + /// 移动方向 up-向上 down-向下 + /// + public string moveType { get; set; } = "down"; + + /// + /// 上次结束编号 + /// + public string numberTo { get; set; } + + /// + /// 原始序号 + /// + public Nullable origIndex { get; set; } + + /// + /// 现序号 + /// + public Nullable currIndex { get; set; } + } +} diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/LaraPaperRegistPostDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/LaraPaperRegistPostDto.cs index a9b4a101..1c054645 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/LaraPaperRegistPostDto.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/LaraPaperRegistPostDto.cs @@ -55,5 +55,20 @@ namespace Myshipping.Application /// /// public string ISSUETYPE { get; set; } + + /// + /// 排序值 + /// + public decimal SortNo { get; set; } + + /// + /// + /// + public int DraftNum { get; set; } + + /// + /// + /// + public int LastNumberTo { get; set; } } } diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskBCStoreResultInfo.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskBCStoreResultInfo.cs new file mode 100644 index 00000000..777d39a3 --- /dev/null +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskBCStoreResultInfo.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// 订舱确认结果 + /// + public class TaskBCStoreResultInfo + { + /// + /// 单号 + /// + [JsonPropertyName("bno")] + public string BNo { get; set; } + /// + /// 船名 + /// + [JsonPropertyName("CM")] + public string Vessel { get; set; } + + /// + /// 首程航次 + /// + [JsonPropertyName("HC1")] + public string Voyno { get; set; } + + /// + /// 二程航次 + /// + [JsonPropertyName("HC2")] + public string Voyno2 { get; set; } + + /// + /// 三程航次 + /// + [JsonPropertyName("HC3")] + public string Voyno3 { get; set; } + + /// + /// VGM时间 + /// + [JsonPropertyName("VGMTIME")] + public string VGMTime { get; set; } + + /// + /// ETD + /// + [JsonPropertyName("YJKHSJ")] + public string ETD { get; set; } + + /// + /// 装货截关时间 + /// + [JsonPropertyName("ZHQGSJ")] + public string ClosingDate { get; set; } + + /// + /// 湿度 + /// + [JsonPropertyName("humidity")] + public string Humidity { get; set; } + + /// + /// 最低温度 + /// + [JsonPropertyName("minimum_temperature")] + public string TempMin { get; set; } + + /// + /// 最高温度 + /// + [JsonPropertyName("maximum_temperature")] + public string TempMax { get; set; } + + /// + /// 中转温度 + /// + [JsonPropertyName("transport_temperature")] + public string TempTransport { get; set; } + + /// + /// 卸货港英文名称 + /// + [JsonPropertyName("XHG")] + public string PortDischargeEName { get; set; } + + /// + /// 集装箱 + /// + [JsonPropertyName("XXXL")] + public string CntrTotal { get; set; } + + /// + /// 报价号 + /// + [JsonPropertyName("BJH")] + public string BJH { get; set; } + + /// + /// 服务合同号 + /// + [JsonPropertyName("FWHT")] + public string FWHT { get; set; } + + /// + /// 通风立方米 + /// + [JsonPropertyName("ventilation_cubic_meter")] + public string VentilationCubicMeter { get; set; } + + /// + /// 客人参考号 + /// + [JsonPropertyName("guest_reference_number")] + public string GuestReferenceNumber { get; set; } + + /// + /// 最终交货地 + /// + [JsonPropertyName("ZZJHD")] + public string ZZJHD { get; set; } + } +} diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderExtMessageInfo.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderExtMessageInfo.cs new file mode 100644 index 00000000..6310f465 --- /dev/null +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderExtMessageInfo.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Myshipping.Application +{ + /// + /// 任务扩展报文 + /// + public class TaskManageOrderExtMessageInfo + { + /// + /// 序列化报文 + /// + public string SerialMsg { get; set; } + + /// + /// 序列化报文类型 JSON-JSON序列化 + /// + public string SerialType { get; set; } + + /// + /// 业务类型 + /// + public string BusiType { get; set; } + } +} diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs index 1d93e803..f9772e5a 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageOrderMessageMainInfo.cs @@ -112,5 +112,10 @@ namespace Myshipping.Application /// 单票账单 /// public TaskManageOrderPerBillInfo PerBillInfo { get; set; } + + /// + /// 序列化报文详情 + /// + public TaskManageOrderExtMessageInfo SerialMsgInfo { get; set; } } } diff --git a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageService.cs b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageService.cs index 701ff4ea..43c8f955 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Interface/ITaskManageService.cs @@ -219,5 +219,48 @@ namespace Myshipping.Application /// 返回结果 Task GetAbortChangeShipInfo(string taskPKId); + /// + /// 手工批量重新比对BC + /// + /// 任务主键数组 + /// 返回结果 + Task ManualReCompareBC(string[] PKIds); + + /// + /// 下载截单EDI + /// + /// 任务主键 + /// 订单号 + /// 是否使用货代代码 + /// 货代代码 + /// 货代称呼 + /// 文件功能 (9原始,1 更新,5 退舱 ) + /// 发送类型 B-订舱 E-截单 + /// + Task DownloadClosingEDI(string taskPKId, string orderNo, bool useForwarderCode, + string forwarderCode, string forwarderName, string fileRole, string sendType); + + + /// + /// 发送截单EDI + /// + /// 任务主键 + /// 订单号 + /// 是否使用货代代码 + /// 货代代码 + /// 货代称呼 + /// 文件功能 (9原始,1 更新,5 退舱 ) + /// 发送类型 E-截单 + /// 返回结果 + Task SendClosingEDI(string taskPKId, string orderNo, bool useForwarderCode, + string forwarderCode, string forwarderName, string fileRole, string sendType); + + + /// + /// 计算LARA纸计算页数 + /// + /// 请求LARA纸详情 + /// 返回结果 + Task> CalcLaraPageNumbers(CalcLaraPageNumbersDto model); } } diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs index 09360c33..125ad612 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageService.cs @@ -21,6 +21,7 @@ using Myshipping.Core.Entity; using Myshipping.Core.Helper; using Myshipping.Core.Service; using MySqlX.XDevAPI.Common; +using NetTaste; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Npoi.Mapper; @@ -34,7 +35,9 @@ using NPOI.SS.Formula.Functions; using NPOI.SS.UserModel; using NPOI.Util; using NPOI.XSSF.Model; +using Org.BouncyCastle.Asn1.Tsp; using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Asn1.X9; using SixLabors.ImageSharp.Processing.Processors.Transforms; using SqlSugar; using StackExchange.Profiling.Internal; @@ -76,6 +79,7 @@ namespace Myshipping.Application private readonly SqlSugarRepository _taskChargesHisInfoRepository; private readonly SqlSugarRepository _taskLARAPaperInfoRepository; private readonly SqlSugarRepository _taskPerBillBaseInfoRepository; + private readonly SqlSugarRepository _taskStoreMsgInfoRepository; private readonly SqlSugarRepository _bookingOrderRepository; private readonly SqlSugarRepository _bookingOrderContaRepository; @@ -88,6 +92,7 @@ namespace Myshipping.Application private readonly ISysCacheService _cache; private readonly ILogger _logger; + private readonly INamedServiceProvider _namedBookingOrderServiceProvider; const string CONST_WEB_ACCOUNT_TYPE = "CmaWeb"; const string CONST_BOOK_ORIGINAL_DOWN_URL_CODE = "bookOriginalDownUrl"; @@ -95,6 +100,11 @@ namespace Myshipping.Application const string CONST_WEB_LARA_ACCOUNT_TYPE = "LaraWeb"; const string CONST_LARA_DOWN_URL_CODE = "LaraPaperPostUrl"; + const string CONST_MAPPING_MODULE = "YunJia"; + + //LARA纸计算常量 + const int LARA_PARER_DRAFT_VAR = 3; + public TaskManageService(SqlSugarRepository taskBaseInfoRepository, SqlSugarRepository taskSIFeedBackInfoRepository, SqlSugarRepository taskSIFeedBackContaInfoRepository, @@ -113,6 +123,8 @@ namespace Myshipping.Application SqlSugarRepository bookingStatusRepository, SqlSugarRepository djyUserMailAccountRepository, SqlSugarRepository taskPerBillBaseInfoRepository, + SqlSugarRepository taskStoreMsgInfoRepository, + INamedServiceProvider namedBookingOrderServiceProvider, IDjyWebsiteAccountConfigService webAccountConfig, ISysCacheService cache, ILogger logger) @@ -135,6 +147,9 @@ namespace Myshipping.Application _bookingStatusRepository = bookingStatusRepository; _djyUserMailAccountRepository = djyUserMailAccountRepository; _taskPerBillBaseInfoRepository = taskPerBillBaseInfoRepository; + _taskStoreMsgInfoRepository = taskStoreMsgInfoRepository; + + _namedBookingOrderServiceProvider = namedBookingOrderServiceProvider; _webAccountConfig = webAccountConfig; _cache = cache; @@ -367,6 +382,21 @@ namespace Myshipping.Application }); } + if (info.Main.SerialMsgInfo != null) + { + var storeInfo = new TaskStoreMsgInfo + { + PK_ID = IDGen.NextID().ToString(), + TASK_PKID = taskInfo.PK_ID, + MSG_JSON = info.Main.SerialMsgInfo.SerialMsg, + MSG_TYPE = info.Main.SerialMsgInfo.SerialType, + CreatedTime = taskInfo.CreatedTime, + UpdatedTime = taskInfo.CreatedTime, + }; + + await _taskStoreMsgInfoRepository.InsertAsync(storeInfo); + } + result.succ = true; result.msg = "新增任务成功"; } @@ -3025,33 +3055,35 @@ namespace Myshipping.Application TaskVgmCompareDto md = l.Adapt(); + md.compareDiffList = new List(); + if (currInfo != null) { - if(!l.SEALNO.Equals(currInfo.SEAL_NO)) + if(l.SEALNO != currInfo.SEAL_NO) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.SealNo)); } - if (!l.CTNCODE.Equals(currInfo.CONTA_TYPE)) + if (l.CTNCODE != currInfo.CONTA_TYPE) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaType)); } - if (!l.CTNALL.Equals(currInfo.CONTA_TYPE_NAME)) + if (l.CTNALL != currInfo.CONTA_TYPE_NAME) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaTypeName)); } - if (!l.KGS.Equals(currInfo.KGS)) + if (l.KGS != currInfo.KGS) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.KGS)); } - if (!l.TAREWEIGHT.Equals(currInfo.TAREWEIGHT)) + if (l.TAREWEIGHT != currInfo.TAREWEIGHT) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.TareWeight)); } - if (!l.WEIGHKGS.Equals(currInfo.WEIGHKGS)) + if (l.WEIGHKGS != currInfo.WEIGHKGS) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighKGs)); } - if (!l.WEIGHTYPE.Equals(currInfo.WEIGHTYPE)) + if (l.WEIGHTYPE != currInfo.WEIGHTYPE) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighType)); } @@ -3079,33 +3111,35 @@ namespace Myshipping.Application TaskVgmCompareDto md = l.Adapt(); + md.compareDiffList = new List(); + if (currInfo != null) { - if (!l.SEAL_NO.Equals(currInfo.SEALNO)) + if (l.SEAL_NO != currInfo.SEALNO) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.SealNo)); } - if (!l.CONTA_TYPE.Equals(currInfo.CTNCODE)) + if (l.CONTA_TYPE != currInfo.CTNCODE) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaType)); } - if (!l.CONTA_TYPE_NAME.Equals(currInfo.CTNALL)) + if (l.CONTA_TYPE_NAME != currInfo.CTNALL) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.ContaTypeName)); } - if (!l.KGS.Equals(currInfo.KGS)) + if (l.KGS != currInfo.KGS) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.KGS)); } - if (!l.TAREWEIGHT.Equals(currInfo.TAREWEIGHT)) + if (l.TAREWEIGHT != currInfo.TAREWEIGHT) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.TareWeight)); } - if (!l.WEIGHKGS.Equals(currInfo.WEIGHKGS)) + if (l.WEIGHKGS != currInfo.WEIGHKGS) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighKGs)); } - if (!l.WEIGHTYPE.Equals(currInfo.WEIGHTYPE)) + if (l.WEIGHTYPE != currInfo.WEIGHTYPE) { md.compareDiffList.Add(nameof(TaskVgmCompareDto.WeighType)); } @@ -3404,6 +3438,683 @@ namespace Myshipping.Application return model; } #endregion + + #region 手工批量重新比对BC + /// + /// 手工批量重新比对BC + /// + /// 任务主键数组 + /// 返回结果 + [HttpPost("/TaskManage/ManualReCompareBC")] + public async Task ManualReCompareBC(string[] PKIds) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + string batchNo = IDGen.NextID().ToString(); + + _logger.LogInformation("批次={no} ids={ids} 手工批量重新比对BC开始", batchNo, string.Join(",", PKIds)); + + try + { + var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList(); + + _logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count); + + var list = new List(); + + taskList.ForEach(async tsk => + { + var rlt = await InnerSingleManualReCompareBC(tsk); + + list.Add(rlt); + }); + + + if (list.Any(t => !t.succ)) + { + result.msg = "失败"; + result.succ = false; + } + else + { + result.msg = "成功"; + result.succ = true; + } + } + catch (Exception ex) + { + throw Oops.Bah("手工批量重新比对BC异常,{0}", ex.Message); + } + + return result; + } + #endregion + + #region 手工单票重新比对BC + /// + /// 手工单票重新比对BC + /// + /// 任务详情 + /// 返回结果 + private async Task InnerSingleManualReCompareBC(TaskBaseInfo model) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto(); + + /* + 1、通过任务的报文表获取BC的报文。 + */ + try + { + var storeInfo = await _taskStoreMsgInfoRepository.AsQueryable() + .Where(t => t.TASK_PKID == model.PK_ID && t.MSG_TYPE == TaskStoreMsgTypeEnum.BC_MSG.ToString()).FirstAsync(); + + if(storeInfo == null) + throw Oops.Oh("MBL_NO={0},获取{1}报文失败", model.MBL_NO,TaskStoreMsgTypeEnum.BC_MSG.GetDescription()); + + var rtl = Newtonsoft.Json.JsonConvert.DeserializeObject(storeInfo.MSG_JSON); + + string msg = string.Empty; + //2023-02-02 测试过程中发现JSON数据格式有了变化,这里增加兼容 + if(rtl.mesage != null) + { + msg = JSON.Serialize(rtl.mesage); + } + else + { + msg = storeInfo.MSG_JSON; + } + + + if (string.IsNullOrWhiteSpace(msg)) + throw Oops.Oh("MBL_NO={0},解析{1}报文详情异常", model.MBL_NO, TaskStoreMsgTypeEnum.BC_MSG.GetDescription()); + + + var bookOrderList = _bookingOrderRepository.EntityContext.Queryable() + .InnerJoin((bk, ctn) => bk.Id == ctn.BILLID) + .Where((bk, ctn) => bk.Id == long.Parse(model.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID) + .Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList(); + + //获取订舱详情与BC进行比对 + var orderInfo = bookOrderList.FirstOrDefault().bk; + + List ctnList = new List(); + + if (bookOrderList.Any(t => t.ctn != null)) + ctnList = bookOrderList.Select(t => t.ctn).ToList(); + + if (orderInfo == null) + throw Oops.Oh("MBL_NO={0},获取订舱详情失败", model.MBL_NO); + + TaskBCStoreResultInfo bcStoreInfo = JSON.Deserialize(msg); + + //BC比较 + var compareResult = InnerCompareBC(bcStoreInfo,orderInfo, ctnList); + + if(!compareResult.succ) + { + //更新任务的反馈结果 + model.RESULT_NOTE = compareResult.msg; + model.UpdatedTime = DateTime.Now; + model.UpdatedUserId = UserManager.UserId; + model.UpdatedUserName = UserManager.Name; + + await _taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new + { + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName, + it.RESULT_NOTE, + + }).ExecuteCommandAsync(); + } + else + { + //置任务状态为完成 + model.STATUS = TaskStatusEnum.Complete.ToString(); + model.STATUS_NAME = TaskStatusEnum.Complete.GetDescription(); + model.COMPLETE_DATE = DateTime.Now; + model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString(); + model.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription(); + + model.UpdatedTime = DateTime.Now; + model.UpdatedUserId = UserManager.UserId; + model.UpdatedUserName = UserManager.Name; + + await _taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new + { + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName, + it.STATUS, + it.STATUS_NAME, + it.COMPLETE_DATE, + it.COMPLETE_DEAL, + it.COMPLETE_DEAL_NAME + }).ExecuteCommandAsync(); + + //更新订舱的ETD(记个日志) + if (!string.IsNullOrWhiteSpace(bcStoreInfo.ETD)) + { + DateTime etd = DateTime.MinValue; + + if(DateTime.TryParse(bcStoreInfo.ETD,out etd)) + { + orderInfo.ETD = etd; + orderInfo.UpdatedTime = DateTime.Now; + orderInfo.UpdatedUserId = UserManager.UserId; + orderInfo.UpdatedUserName = UserManager.Name; + + await _bookingOrderRepository.AsUpdateable(orderInfo).UpdateColumns(it => new + { + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName, + it.ETD + }).ExecuteCommandAsync(); + } + } + //【预留】异步推送后台任务(订舱自动放舱-BookingFangCang) + //【预留】异步推送后台任务(下货纸-Xiahuozhi) + } + + result.succ = true; + result.msg = "处理成功"; + } + catch (Exception ex) + { + result.succ = false; + result.msg = $"手工重新比对BC异常,{ex.Message}"; + + //throw Oops.Bah("手工重新比对BC异常,{0}", ex.Message); + } + + return result; + } + #endregion + + #region 单票比对BC + /// + /// 单票比对BC + /// + /// BC回执详情 + /// 订舱详情 + /// 订舱集装箱列表 + /// 返回结果 + private TaskManageOrderResultDto InnerCompareBC(TaskBCStoreResultInfo bcStoreInfo,BookingOrder orderInfo,List ctnList) + { + TaskManageOrderResultDto result = new TaskManageOrderResultDto { succ = true}; + + try + { + List> rltTupleList = new List>(); + + /* + 迁移过来的注释 + 2021-9-28,需求再变,BC需要再次比对约号 + 2021-7-19 需求修改:BC不需要再对比约号 + */ + + //约号 + if (!string.IsNullOrWhiteSpace(orderInfo.CONTRACTNO)) + { + if ((string.IsNullOrWhiteSpace(bcStoreInfo.BJH) || !Regex.IsMatch(orderInfo.CONTRACTNO, $"\\b{bcStoreInfo.BJH.Trim()}\\b")) + && (string.IsNullOrWhiteSpace(bcStoreInfo.FWHT) || !Regex.IsMatch(orderInfo.CONTRACTNO, $"\\b{bcStoreInfo.FWHT.Trim()}\\b"))) + { + rltTupleList.Add(new Tuple(false, "约号不一致")); + } + } + else + { + if (!string.IsNullOrWhiteSpace(bcStoreInfo.BJH) || !string.IsNullOrWhiteSpace(bcStoreInfo.FWHT)) + { + rltTupleList.Add(new Tuple(false, "约号不一致")); + } + } + + #region 集装箱 + //集装箱 + if (bcStoreInfo.CntrTotal != orderInfo.CNTRTOTAL) + { + //集装箱型 + var ediCtnList = _cache.GetAllMappingCtn().GetAwaiter().GetResult() + .Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) + && !string.IsNullOrWhiteSpace(t.CarrierCode) && t.CarrierCode.Equals(orderInfo.CARRIERID, StringComparison.OrdinalIgnoreCase)).ToList(); + + var storeCtnList = bcStoreInfo.CntrTotal.Split(new char[] { ';' }).Select(t => + { + var currArg = t.Split(new char[] { 'x' }); + + return new { Code = currArg[1]?.Trim(), Num = int.Parse(currArg[0]?.Trim()) }; + }).GroupBy(t => t.Code) + .Select(t => + { + return new { Code = t.Key, Num = t.Sum(x => x.Num) }; + }).ToList(); + + var orderCtnListctnList = ctnList.Select(t => + { + var mapCtn = ediCtnList.FirstOrDefault(x => x.Code.Equals(t.CTNCODE)); + + if (mapCtn != null && !string.IsNullOrWhiteSpace(mapCtn.MapCode)) + return new { Code = mapCtn.MapCode, Num = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1 }; + + return new { Code = t.CTNCODE, Num = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1 }; + }).GroupBy(t => t.Code) + .Select(t => + { + return new { Code = t.Key, Num = t.Sum(x => x.Num) }; + }).ToList(); + + if (storeCtnList.Count != orderCtnListctnList.Count) + { + rltTupleList.Add(new Tuple(false, "箱型箱量不一致")); + } + else + { + var totalList = storeCtnList.GroupJoin(orderCtnListctnList, l => l.Code, r => r.Code, (l, r) => + { + var rModel = r.FirstOrDefault(); + + if (rModel == null) + { + return false; + } + else + { + if (l.Num != rModel.Num) + return false; + } + + return true; + }).ToList(); + + if (totalList.Any(t => !t)) + { + rltTupleList.Add(new Tuple(false, "箱型箱量不一致")); + } + } + + } + #endregion + + //船名 + if (bcStoreInfo.Vessel != orderInfo.VESSEL?.Trim()) + { + rltTupleList.Add(new Tuple(false, "船名不一致")); + } + + //航次 + if (bcStoreInfo.Voyno?.Replace("1MA", "") != orderInfo.VOYNO?.Trim() + && bcStoreInfo.Voyno2 != orderInfo.VOYNO?.Trim() && bcStoreInfo.Voyno3 != orderInfo.VOYNO?.Trim()) + { + rltTupleList.Add(new Tuple(false, "航次不一致")); + } + + /* + //2021-10-12,增加最小、最大、运输温度,湿度,通风 的比较 + //2021-11-23,备注中含有NOR,不比较温度湿度等信息 + + 2023-02-02 这里补充了一下EDIREMARK的判断,用正则匹配NOR信息。NOR(冻代干集装箱) + */ + if (orderInfo.CARGOID == "R" && (string.IsNullOrWhiteSpace(orderInfo.SOREMARK) || !Regex.IsMatch(orderInfo.SOREMARK, "\\bNOR\\b"))) + { + //最低温度 + var compareReult = CompareTemperatureNum(orderInfo.TEMPMIN, bcStoreInfo.TempMin, "temp"); + + if (!compareReult.Item1) + rltTupleList.Add(compareReult); + + //最高温度 + compareReult = CompareTemperatureNum(orderInfo.TEMPMAX, bcStoreInfo.TempMax, "temp", "最高温度"); + + if (!compareReult.Item1) + rltTupleList.Add(compareReult); + + //运输温度 + compareReult = CompareTemperatureNum(orderInfo.TEMPSET, bcStoreInfo.TempTransport, "temp", "运输温度"); + + if (!compareReult.Item1) + rltTupleList.Add(compareReult); + + //湿度 + compareReult = CompareTemperatureNum(orderInfo.HUMIDITY, bcStoreInfo.Humidity, "humidity", "湿度"); + + if (!compareReult.Item1) + rltTupleList.Add(compareReult); + + //通风 + compareReult = CompareTemperatureNum(orderInfo.REEFERF, bcStoreInfo.VentilationCubicMeter, "vent", "通风"); + + if (!compareReult.Item1) + rltTupleList.Add(compareReult); + } + + + /* + * 2021-12-3,捷丰要求加卸货港和目的地校验,规则: + * A:大简云里卸货港字段‘,’之前的字符和BC里卸货港‘,’之前的字段。 + * 1.一致,自动发送下货纸 + * 2.不一致,生成待处理下货纸任务。 + * B:bc如果有最终交货地 那么要和系统目的港对比;最终交货地空白 就不用对比这个地方 + */ + string orderPortDischarge = orderInfo.PORTDISCHARGE.Split(new char[] { ',' }).FirstOrDefault()?.Trim(); + string storePortDischarge = bcStoreInfo.PortDischargeEName.Split(new char[] { ',' }).FirstOrDefault()?.Trim(); + + if (orderPortDischarge != storePortDischarge) + rltTupleList.Add(new Tuple(false, "卸货港不一致")); + + string orderDest = orderInfo.DESTINATION.Split(new char[] { ',' }).FirstOrDefault()?.Trim(); + string storeDest = bcStoreInfo.ZZJHD.Split(new char[] { ',' }).FirstOrDefault()?.Trim(); + + if (orderDest != storeDest) + rltTupleList.Add(new Tuple(false, "目的地不一致")); + + if (rltTupleList.Any(t => !t.Item1)) + { + result.succ = false; + result.msg = string.Join(";", rltTupleList.Select(t => t.Item2).ToArray()); + } + } + catch(Exception ex) + { + throw Oops.Bah("{0}单票比对BC异常,{1}",nameof(InnerCompareBC), ex.Message); + } + + return result; + } + #endregion + + #region 对比温度 + /// + /// 对比温度 + /// + /// 订舱数值 + /// 回执数值 + /// 操作类型 temp-温度 humidity-湿度 vent-通风 + /// 显示名称 + /// 返回结果 + private Tuple CompareTemperatureNum(string orderTemperature,string storeTemperature,string operType = "temp",string showName = "最低温度") + { + decimal orderTemp = int.MaxValue; + decimal storeTemp = int.MaxValue; + + decimal.TryParse(orderTemperature, out orderTemp); + + if (!string.IsNullOrWhiteSpace(storeTemperature)) + { + if (operType == "temp") + { + decimal.TryParse(Regex.Match(storeTemperature, "(\\-?([0-9]?|[0-9]+)\\.?[0-9]+)(?=C)").Value, out storeTemp); + } + else if (operType == "humidity") + { + decimal.TryParse(Regex.Match(storeTemperature, "\\[0-9]+").Value, out storeTemp); + } + else if (operType == "vent") + { + decimal.TryParse(storeTemperature, out storeTemp); + } + } + + if (storeTemp != int.MaxValue && orderTemp != int.MaxValue) + { + if (storeTemp != orderTemp) + return new Tuple(false, $"{showName}不一致"); + } + else + { + if (storeTemp != int.MaxValue || orderTemp != int.MaxValue) + return new Tuple(false, $"{showName}不一致"); + } + + return new Tuple(true, ""); + } + #endregion + + #region 下载截单EDI + /// + /// 下载截单EDI + /// + /// 任务主键 + /// 订单号 + /// 是否使用货代代码 + /// 货代代码 + /// 货代称呼 + /// 文件功能 (9原始,1 更新,5 退舱 ) + /// 发送类型 E-截单 + /// 返回结果 + [HttpGet("/TaskManage/DownloadClosingEDI")] + public async Task DownloadClosingEDI([FromQuery] string taskPKId, [FromQuery] string orderNo, [FromQuery] bool useForwarderCode, + [FromQuery] string forwarderCode, [FromQuery] string forwarderName, [FromQuery] string fileRole, [FromQuery] string sendType) + { + if (sendType?.ToUpper() != "E") + throw Oops.Oh($"sendType只接收E-截单"); + + var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId); + + if (taskInfo == null) + throw Oops.Oh($"任务信息获取失败"); + + if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO)) + throw Oops.Oh($"任务信息的订舱主键不存在"); + + if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString()) + throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}"); + + BookingOrder bookingOrder = null; + + if (!string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO)) + bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO)); + + if (bookingOrder == null) + throw Oops.Oh($"订舱信息获取失败,MBLNO={taskInfo.MBL_NO}"); + + var model = new BookingOrClosingEDIOrderDto + { + Id = bookingOrder.Id, + orderNo = orderNo, + useForwarderCode = useForwarderCode, + forwarderCode = forwarderCode, + forwarderName = forwarderName, + fileRole = fileRole, + send = false, + sendType = sendType + }; + + var bookingOrderService = _namedBookingOrderServiceProvider.GetService(nameof(BookingOrderService)); + + var filePath = await bookingOrderService.InnerBookingOrClosingEDI(model); + + var fileInfo = new FileInfo(filePath); + + var result = new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileInfo.Name }; + return result; + } + #endregion + + #region 发送截单EDI + /// + /// 发送截单EDI + /// + /// 任务主键 + /// 订单号 + /// 是否使用货代代码 + /// 货代代码 + /// 货代称呼 + /// 文件功能 (9原始,1 更新,5 退舱 ) + /// 发送类型 E-截单 + /// 返回结果 + [HttpGet("/TaskManage/SendClosingEDI")] + public async Task SendClosingEDI([FromQuery] string taskPKId, [FromQuery] string orderNo, [FromQuery] bool useForwarderCode, + [FromQuery] string forwarderCode, [FromQuery] string forwarderName, [FromQuery] string fileRole, [FromQuery] string sendType) + { + if (sendType?.ToUpper() != "E") + throw Oops.Oh($"sendType只接收E-截单"); + + var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId); + + if (taskInfo == null) + throw Oops.Oh($"任务信息获取失败"); + + if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO)) + throw Oops.Oh($"任务信息的订舱主键不存在"); + + if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString()) + throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}"); + + BookingOrder bookingOrder = null; + + if (!string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO)) + bookingOrder = _bookingOrderRepository.AsQueryable().First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO)); + + if (bookingOrder == null) + throw Oops.Oh($"订舱信息获取失败,MBLNO={taskInfo.MBL_NO}"); + + var model = new BookingOrClosingEDIOrderDto + { + Id = bookingOrder.Id, + orderNo = orderNo, + useForwarderCode = useForwarderCode, + forwarderCode = forwarderCode, + forwarderName = forwarderName, + fileRole = fileRole, + send = true, + sendType = sendType + }; + + var bookingOrderService = _namedBookingOrderServiceProvider.GetService(nameof(BookingOrderService)); + + return await bookingOrderService.InnerBookingOrClosingEDI(model); + } + #endregion + + #region 计算LARA纸计算页数 + /// + /// 计算LARA纸计算页数 + /// + /// 请求LARA纸详情 + /// 返回结果 + [HttpPost("/TaskManage/CalcLaraPageNumbers")] + public async Task> CalcLaraPageNumbers(CalcLaraPageNumbersDto model) + { + List list = new List(); + + /* + LARA计算方法 + + 1、判断是否为首次加载,model.moveType为空时表示首次加载,触发InitCalcLaraPageNumbers方法。 + 2、如果 model.moveType有值时,判断是调整行位置,根据指定的行位置重新计算编号。 + */ + try + { + if(string.IsNullOrWhiteSpace(model.moveType)) + { + list = InnerCalcLaraPageNumbers(model,true); + } + else + { + list = InnerCalcLaraPageNumbers(model); + } + } + catch (Exception ex) + { + throw Oops.Bah("计算LARA纸计算页数异常,{0}", ex.Message); + } + + return list; + } + #endregion + + #region 计算LARA纸 + /// + /// 计算LARA纸 + /// + /// 请求LARA纸详情 + /// 是否初始化 true-初始化 + /// + private List InnerCalcLaraPageNumbers(CalcLaraPageNumbersDto model,bool isInit = false) + { + List list = new List(); + + //如果判断不是首次加载,需要将移动的行从列表移动到指定位置后,重新计算。 + if(!isInit) + { + model.paperList = model.paperList.Select(t => + { + if (t.SortNo == model.origIndex.Value) + { + //up + if(model.currIndex < model.origIndex) + { + t.SortNo = (decimal)model.currIndex.Value - 0.1m; + } + else + { + t.SortNo = (decimal)model.currIndex.Value + 0.1m; + } + } + + return t; + }).OrderBy(t => t.SortNo) + .Select((t, idx) => + { + t.SortNo = (decimal)idx + 1; + return t; + + }).ToList(); + } + + var mNumberTo = int.Parse(model.numberTo.TrimStart('0')); + + if (mNumberTo > 0) + { + int lastNumberTo = 0; + int lastNumberFrom = 0; + + model.paperList.OrderBy(t => t.SortNo).ToList().ForEach(t => + { + LaraPaperRegistPostDto info = new LaraPaperRegistPostDto(); + + info.SortNo = t.SortNo; + info.DraftNum = t.DraftNum; + info.TaskId = t.TaskId; + info.ORDNO = t.ORDNO; + info.MBLNO = t.MBLNO; + info.ISSUETYPE = t.ISSUETYPE; + + if (t.SortNo == 1) + { + lastNumberFrom = mNumberTo + 1; + info.NumberFrom = (lastNumberFrom).ToString().PadLeft(9, '0'); + + var currNumberTo = (t.DraftNum * LARA_PARER_DRAFT_VAR) + mNumberTo; + + info.NumberTo = currNumberTo.ToString().PadLeft(9, '0'); + info.PageSum = currNumberTo - lastNumberFrom + 1; + + lastNumberTo = currNumberTo; + } + else + { + lastNumberFrom = lastNumberTo + 1; + info.NumberFrom = (lastNumberFrom).ToString().PadLeft(9, '0'); + + var currNumberTo = (t.DraftNum * LARA_PARER_DRAFT_VAR) + lastNumberTo; + + info.NumberTo = currNumberTo.ToString().PadLeft(9, '0'); + info.PageSum = currNumberTo - lastNumberFrom + 1; + + lastNumberTo = currNumberTo; + } + + + list.Add(info); + }); + } + + return list; + } + #endregion } #region 样本业务提取帮助类