diff --git a/Myshipping.Application/EDI/ZhongYuanSoApiHelper.cs b/Myshipping.Application/EDI/ZhongYuanSoApiHelper.cs index c5fe180e..57201c18 100644 --- a/Myshipping.Application/EDI/ZhongYuanSoApiHelper.cs +++ b/Myshipping.Application/EDI/ZhongYuanSoApiHelper.cs @@ -115,15 +115,22 @@ namespace Myshipping.Application.EDI postModel.saveName = template.TemplateName; var mapPortLoad = mappingPortLoad.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.PORTLOADCODE); - var mapPort = mappingPort.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.PORTDISCHARGECODE); + //var mapPort = mappingPort.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.PORTDISCHARGECODE); if (mapPortLoad == null) { return new KeyValuePair(false, $"未找到起运港映射信息:{custOrder.PORTLOADCODE}"); } + //if (mapPort == null) + //{ + // return new KeyValuePair(false, $"未找到目的港映射信息:{custOrder.PORTDISCHARGECODE}"); + //} + + //2024年5月9日,衣国豪:改用目的地,而不是卸货港 + var mapPort = mappingPort.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.DESTINATIONCODE); if (mapPort == null) { - return new KeyValuePair(false, $"未找到目的港映射信息:{custOrder.PORTDISCHARGECODE}"); + return new KeyValuePair(false, $"未找到目的地映射信息:{custOrder.DESTINATIONCODE}"); } //运输条款 diff --git a/Myshipping.Application/Enum/TaskShareLinkStatusEnum.cs b/Myshipping.Application/Enum/TaskShareLinkStatusEnum.cs index d894f1f7..5281ef12 100644 --- a/Myshipping.Application/Enum/TaskShareLinkStatusEnum.cs +++ b/Myshipping.Application/Enum/TaskShareLinkStatusEnum.cs @@ -34,6 +34,12 @@ namespace Myshipping.Application /// 重复KEY被取消 /// [Description("重复KEY被取消")] - REPEAT_KEY + REPEAT_KEY, + + /// + /// 已完结 + /// + [Description("已完结")] + COMPLETE, } } diff --git a/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs b/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs index 740c79a4..f31684f4 100644 --- a/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs +++ b/Myshipping.Application/Service/BookingCustomerOrder/BookingCustomerOrderService.cs @@ -908,10 +908,10 @@ namespace Myshipping.Application throw Oops.Bah("未找到数据"); } - if (model.BSSTATUS != "已提交") - { - throw Oops.Bah("当前状态不能接受审核回推"); - } + //if (model.BSSTATUS != "已提交") + //{ + // throw Oops.Bah("当前状态不能接受审核回推"); + //} if (recModel.Accept) { @@ -1669,6 +1669,8 @@ namespace Myshipping.Application SaveAuditLog($"待审核", order.Id); } + _logger.LogInformation($"rtnList:{rtnList.ToJsonString()}"); + //全部成功后,才能自动订舱和审核 if (rtnList.Count(x => x.Success == false) == 0) { @@ -1686,12 +1688,12 @@ namespace Myshipping.Application { foreach (var ordId in ordIdList) { + var succ = false; try { _logger.LogInformation($"自动订舱:{ordId}"); await PostApiSO(ordId); - _logger.LogInformation($"自动审核:{ordId}"); - await AuditBooking(ordId, true, "系统自动审核"); + succ = true; } catch (Exception ex) { @@ -1699,6 +1701,12 @@ namespace Myshipping.Application await AuditBooking(ordId, false, ex.Message, notFeedback: true); throw ex; } + + if (succ) + { + _logger.LogInformation($"自动审核:{ordId}"); + await AuditBooking(ordId, true, "系统自动审核"); + } } } } @@ -2079,6 +2087,8 @@ namespace Myshipping.Application // throw Oops.Bah("目的港代码和名称不能为空"); //} + + //起运港校验 if (string.IsNullOrEmpty(input.PORTLOADCODE)) { throw Oops.Bah("起运港代码不能为空"); @@ -2090,6 +2100,8 @@ namespace Myshipping.Application throw Oops.Bah($"未找到匹配的起运港:{input.PORTLOADCODE}"); } + + //目的港校验 if (string.IsNullOrEmpty(input.PORTDISCHARGECODE)) { throw Oops.Bah("目的港代码不能为空"); @@ -2101,6 +2113,19 @@ namespace Myshipping.Application throw Oops.Bah($"未找到匹配的目的港:{input.PORTDISCHARGECODE}"); } + + //目的地校验 + if (string.IsNullOrEmpty(input.DESTINATIONCODE)) + { + throw Oops.Bah("目的地代码不能为空"); + } + + var destination = portDestList.FirstOrDefault(x => x.Code == input.DESTINATIONCODE); + if (destination == null) + { + throw Oops.Bah($"未找到匹配的目的地:{input.DESTINATIONCODE}"); + } + if (string.IsNullOrEmpty(input.SERVICECODE)) { throw Oops.Bah("运输条款代码不能为空"); @@ -2219,7 +2244,6 @@ namespace Myshipping.Application } - var destination = portDestList.FirstOrDefault(x => x.Code == input.DESTINATIONCODE); //赋值根据唯一代码匹配后的代码、名称等信息 custOrder.CARRIER = carr.EnName; @@ -2228,8 +2252,8 @@ namespace Myshipping.Application custOrder.PORTDISCHARGE = portDest.EnName; custOrder.PORTDISCHARGEID = portDest.EdiCode; custOrder.SERVICE = service.Name; - custOrder.DESTINATION = destination?.EnName; - custOrder.DESTINATIONID = destination?.EdiCode; + custOrder.DESTINATION = destination.EnName; + custOrder.DESTINATIONID = destination.EdiCode; custOrder.BLFRT = frt.EnName; //2024年4月19日,将分拆的收发通拼接到大文本的收发通中 diff --git a/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs b/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs index 78f5d27a..7061ee79 100644 --- a/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs +++ b/Myshipping.Application/Service/BookingSlot/BookingSlotService.cs @@ -1565,7 +1565,7 @@ namespace Myshipping.Application { BookingSlotWithOrderDto dto = null; - var slotInfo = await _repBase.AsQueryable().Filter(null,true).FirstAsync(a => a.SLOT_BOOKING_NO == slotBookingNo && a.TenantId == tenantId); + var slotInfo = await _repBase.AsQueryable().Filter(null,true).FirstAsync(a => a.SLOT_BOOKING_NO == slotBookingNo && a.TenantId == tenantId && a.IsDeleted == false); if (slotInfo == null) { @@ -1574,7 +1574,7 @@ namespace Myshipping.Application return dto; } - var list = _repAllocation.AsQueryable().Filter(null, true).Where(a => a.BOOKING_SLOT_ID == slotInfo.Id && a.TenantId == tenantId).ToList(); + var list = _repAllocation.AsQueryable().Filter(null, true).Where(a => a.BOOKING_SLOT_ID == slotInfo.Id && a.TenantId == tenantId && a.IsDeleted == false).ToList(); dto = new BookingSlotWithOrderDto { diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/Nomination/TaskRollingNominationShowDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/Nomination/TaskRollingNominationShowDto.cs index 3af02262..90c73437 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/Nomination/TaskRollingNominationShowDto.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/Nomination/TaskRollingNominationShowDto.cs @@ -51,12 +51,17 @@ namespace Myshipping.Application /// /// 原船记录 /// - public TaskRollingNominationShipDto From { get; set; } + public List From { get; set; } /// /// 换船记录 /// - public TaskRollingNominationShipDto To { get; set; } + public List To { get; set; } + + /// + /// 预甩的FROM TO对应列表 + /// + public List FromToList { get; set; } /// /// 单票汇总列表 @@ -216,6 +221,11 @@ namespace Myshipping.Application /// public string CtnNote { get; set; } + + /// + /// 箱号 + /// + public string EquipmentNumber { get; set; } } /// @@ -328,4 +338,20 @@ namespace Myshipping.Application /// public string PKId { get; set; } } + + /// + /// 预甩的FROM TO对应列表 + /// + public class TaskRollingNominationShipFromToDto + { + /// + /// 原船记录 + /// + public TaskRollingNominationShipDto FromShip { get; set; } + + /// + /// 换船记录列表 + /// + public List ToShipList { get; set; } + } } diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/ShareLink/PushShareLinkFeedBackDto.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/ShareLink/PushShareLinkFeedBackDto.cs index a2f4217d..61db3150 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/ShareLink/PushShareLinkFeedBackDto.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/ShareLink/PushShareLinkFeedBackDto.cs @@ -25,5 +25,10 @@ namespace Myshipping.Application /// 用户意见内容 /// public string userOpinionTxt { get; set; } + + /// + /// 是否人工触发(默认true) true-人工触发 false-定时触发 + /// + public bool isManual { get; set; } = true; } } diff --git a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageMapper.cs b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageMapper.cs index 113e3947..c3388a4d 100644 --- a/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageMapper.cs +++ b/Myshipping.Application/Service/TaskManagePlat/Dtos/TaskManageMapper.cs @@ -941,6 +941,7 @@ namespace Myshipping.Application .Map(dest => dest.CtnCode, src => src.CTNCODE) .Map(dest => dest.CtnAll, src => src.CTNALL) .Map(dest => dest.CtnNum, src => src.CTNNUM) + .Map(dest => dest.EquipmentNumber, src => src.EQUIPMENT_NUMBER) .Map(dest => dest.PKId, src => src.PK_ID); config.ForType() diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageRollingNominationService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageRollingNominationService.cs index 29605999..ecb9673b 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageRollingNominationService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageRollingNominationService.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Myshipping.Application @@ -168,24 +169,71 @@ namespace Myshipping.Application }; var shipList = _taskRollingNominationShipInfoRepository.AsQueryable() - .Where(a => a.NOM_ID == rollModel.PK_ID && a.GROUP_INDX == 1 && !a.IsDeleted).ToList(); + .Where(a => a.NOM_ID == rollModel.PK_ID && a.IsDeleted == false).ToList(); - if(shipList.Count == 0) - shipList = _taskRollingNominationShipInfoRepository.AsQueryable() - .Where(a => a.NOM_ID == rollModel.PK_ID && a.GROUP_INDX == 0 && !a.IsDeleted).ToList(); + var fromEntity = shipList.Where(a => + a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList(); - var fromEntity = shipList.FirstOrDefault(a => - a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)); + if (fromEntity.Count > 0) + model.From = fromEntity.Select(p=>p.Adapt()).ToList(); - if (fromEntity != null) - model.From = fromEntity.Adapt(); + var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE,"To(\\s+[0-9]+)?" + , RegexOptions.IgnoreCase)).ToList(); - var toEntity = shipList.FirstOrDefault(a => - a.SHIP_TYPE.Equals("To", StringComparison.OrdinalIgnoreCase)); + if (toEntity.Count > 0) + model.To = toEntity.Select(p => p.Adapt()).ToList(); - if (toEntity != null) - model.To = toEntity.Adapt(); + //优先PORT关联FROM和TO,也有PORT为空的情况,这种就需要用Terminal来关联 + if (model.From.Any(t => string.IsNullOrWhiteSpace(t.Port))) + { + //这里为了前端原船和换船做了根据Terminal对应 + model.FromToList = model.From.GroupJoin(model.To, l => l.Terminal?.Trim(), r => r.Terminal?.Trim(), (l, r) => + { + TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto(); + + dto.FromShip = l; + + var currArg = r.ToList(); + + if (currArg.Count > 0) + { + dto.ToShipList = currArg.Select((p, idx) => + { + if (Regex.IsMatch(p.ShipType, "[0-9]+")) + return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p }; + + return new { SortNo = idx + 1, Obj = p }; + }).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList(); + } + + return dto; + }).ToList(); + } + else + { + //这里为了前端原船和换船做了根据PORT对应 + model.FromToList = model.From.GroupJoin(model.To, l => l.Port?.Trim(), r => r.Port?.Trim(), (l, r) => + { + TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto(); + + dto.FromShip = l; + + var currArg = r.ToList(); + + if (currArg.Count > 0) + { + dto.ToShipList = currArg.Select((p, idx) => + { + if (Regex.IsMatch(p.ShipType, "[0-9]+")) + return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p }; + + return new { SortNo = idx + 1, Obj = p }; + }).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList(); + } + return dto; + }).ToList(); + } var withDispatchList = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true) .LeftJoin((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID) @@ -307,7 +355,8 @@ namespace Myshipping.Application BatchId = preBillDispatch?.BATCH_ID, BookingId = preBillDetail.BOOKING_ID, GroupName = $"SHIPMENT_{idx + 1}", - CtnNote = ctnNote + CtnNote = ctnNote, + EquipmentNumber = preBillDetail.EQUIPMENT_NUMBER }; return preBillInfo; diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageSISubmittedService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageSISubmittedService.cs index ae205d43..b86c61a8 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageSISubmittedService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageSISubmittedService.cs @@ -299,15 +299,15 @@ namespace Myshipping.Application var siCtnList = _taskSISubmittedCtnRepository.AsQueryable().Filter(null, true).Where(a => a.P_PKID == siSubmitted.PK_ID && a.TenantId == UserManager.TENANT_ID).ToList(); + var orderInfo = _bookingOrderRepository.AsQueryable().Filter(null, true) + .First(a => a.MBLNO == siSubmitted.MBL_NO && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID && a.ParentId == 0); + if (paramConfig != null && paramConfig.ParaValue.Equals("ENABLE",StringComparison.OrdinalIgnoreCase)) { siSubmitted.IS_SET_AUTO_UPD_BOOKING = true; _logger.LogInformation($"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 配置了自动更新订舱详情"); - var orderInfo = _bookingOrderRepository.AsQueryable().Filter(null, true) - .First(a => a.MBLNO == siSubmitted.MBL_NO && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID && a.ParentId == 0); - if(orderInfo != null) { _logger.LogInformation($"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 获取了订舱详情完成 bookingid={orderInfo.Id}"); @@ -391,7 +391,7 @@ namespace Myshipping.Application //bkModel.ISSUETYPE = "telex"; bkModel.ISSUETYPE = "Telex"; } - else if (siSubmitted.ISSUETYPE.Equals("seaway", StringComparison.OrdinalIgnoreCase)) + else if (siSubmitted.ISSUETYPE.Equals("original", StringComparison.OrdinalIgnoreCase)) { //bkModel.ISSUETYPE = "original"; bkModel.ISSUETYPE = "Original"; @@ -822,6 +822,153 @@ namespace Myshipping.Application result.msg = "当前租户没开通自动(SI回执是否自动更新订舱)"; siSubmitted.IS_SET_AUTO_UPD_BOOKING = false; + + //将文件同步到订舱的附件 + if (orderInfo != null) + { + //推送截单货物状态 + var pushModel = new ModifyServiceProjectStatusDto + { + BookingId = orderInfo.Id, + SourceType = TrackingSourceTypeEnum.AUTO, + StatusCodes = new List { + new ModifyServiceProjectStatusDetailDto { StatusCode = "JD" } } + }; + + if (siSubmitted.NOTICE_DATE.HasValue) + { + pushModel.StatusCodes[0].SetActDate = siSubmitted.NOTICE_DATE.Value; + } + + var saveStatusRlt = await _bookingValueAddedService.SaveServiceStatus(pushModel); + + _logger.LogInformation($"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 推送截单状态完成 结果={JSON.Serialize(saveStatusRlt)}"); + + siSubmitted.PROCESS_STATUS = "SUCC"; + siSubmitted.PROCESS_DATE = DateTime.Now; + siSubmitted.IS_UPDATE_BOOKING = true; + siSubmitted.UPDATE_BOOKING_DATE = DateTime.Now; + + //直接完成SI的回执任务 + if (taskBase.IS_PUBLIC == 1) + { + //更新任务的状态 + taskBase.IS_PUBLIC = 0; + taskBase.IS_COMPLETE = 1; + taskBase.COMPLETE_DEAL = "AUTO"; + taskBase.COMPLETE_DEAL_NAME = "自动"; + taskBase.COMPLETE_DATE = DateTime.Now; + + if (!string.IsNullOrWhiteSpace(orderInfo.OP)) + { + taskBase.RealUserId = long.Parse(orderInfo.OPID); + taskBase.RealUserName = orderInfo.OP; + taskBase.UpdatedTime = DateTime.Now; + taskBase.UpdatedUserId = long.Parse(orderInfo.OPID); + taskBase.UpdatedUserName = orderInfo.OP; + } + else + { + taskBase.RealUserId = orderInfo.CreatedUserId.Value; + taskBase.RealUserName = orderInfo.CreatedUserName; + taskBase.UpdatedTime = DateTime.Now; + taskBase.UpdatedUserId = orderInfo.CreatedUserId.Value; + taskBase.UpdatedUserName = orderInfo.CreatedUserName; + } + + //更新任务台,将当前任务变更为个人任务 + await _taskBaseRepository.AsUpdateable(taskBase).UpdateColumns(it => new { + it.IS_PUBLIC, + it.RealUserId, + it.RealUserName, + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName + + }).ExecuteCommandAsync(); + } + else + { + taskBase.IS_COMPLETE = 1; + taskBase.COMPLETE_DEAL = "AUTO"; + taskBase.COMPLETE_DEAL_NAME = "自动"; + taskBase.COMPLETE_DATE = DateTime.Now; + + if (!string.IsNullOrWhiteSpace(orderInfo.OP)) + { + taskBase.RealUserId = long.Parse(orderInfo.OPID); + taskBase.RealUserName = orderInfo.OP; + taskBase.UpdatedTime = DateTime.Now; + taskBase.UpdatedUserId = long.Parse(orderInfo.OPID); + taskBase.UpdatedUserName = orderInfo.OP; + } + else + { + taskBase.RealUserId = orderInfo.CreatedUserId.Value; + taskBase.RealUserName = orderInfo.CreatedUserName; + taskBase.UpdatedTime = DateTime.Now; + taskBase.UpdatedUserId = orderInfo.CreatedUserId.Value; + taskBase.UpdatedUserName = orderInfo.CreatedUserName; + } + + //更新任务台,将当前任务变更为个人任务 + await _taskBaseRepository.AsUpdateable(taskBase).UpdateColumns(it => new { + it.IS_PUBLIC, + it.RealUserId, + it.RealUserName, + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName + + }).ExecuteCommandAsync(); + } + + + //处理附件 + var opt = App.GetOptions(); + var dirAbs = opt.basePath; + if (string.IsNullOrEmpty(dirAbs)) + { + dirAbs = App.WebHostEnvironment.WebRootPath; + } + + string batchNo = IDGen.NextID().ToString(); + + var fileList = _taskFileRepository.AsQueryable().Filter(null, true).Where(a => a.TASK_PKID == taskPkId && a.TenantId == taskBase.TenantId.Value).ToList(); + + fileList.ForEach(file => + { + if (file.FILE_CATEGORY == TaskFileCategoryEnum.SI_SUBMITTED.ToString()) + { + var fileFullPath = Path.Combine(dirAbs, file.FILE_PATH); + + if (File.Exists(fileFullPath)) + { + //如果确认文件读取成功 + var bookFilePath = FileAttachHelper.MoveFile(orderInfo.Id.ToString(), fileFullPath, batchNo + , false, null, true).GetAwaiter().GetResult(); + + //将格式单附件写入订舱的附件 + SaveEDIFile(orderInfo.Id, bookFilePath, new System.IO.FileInfo(bookFilePath).Name, taskBase.TenantId.Value).GetAwaiter(); + } + } + }); + + + _logger.LogInformation($"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 上传订舱数据附件完成"); + + result.succ = true; + result.msg = "处理成功"; + + _logger.LogInformation($"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 更新完成"); + } + else + { + result.succ = false; + result.msg = $"提单号{siSubmitted.MBL_NO} 检索订舱数据失败"; + + _logger.LogInformation($"taskPkId={taskPkId} 提单号{siSubmitted.MBL_NO} 检索订舱数据失败"); + } } } catch (Exception ex) diff --git a/Myshipping.Application/Service/TaskManagePlat/TaskManageShareLinkService.cs b/Myshipping.Application/Service/TaskManagePlat/TaskManageShareLinkService.cs index 84bfa62a..5780c965 100644 --- a/Myshipping.Application/Service/TaskManagePlat/TaskManageShareLinkService.cs +++ b/Myshipping.Application/Service/TaskManagePlat/TaskManageShareLinkService.cs @@ -7,11 +7,13 @@ using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.StaticFiles.Infrastructure; using Microsoft.Extensions.Logging; using Myshipping.Application.ConfigOption; using Myshipping.Application.Entity; using Myshipping.Core; using Myshipping.Core.Service; +using NPOI.Util; using StackExchange.Profiling.Internal; using System; using System.Collections.Generic; @@ -503,29 +505,200 @@ namespace Myshipping.Application.Service.TaskManagePlat }; var shipList = _taskRollingNominationShipInfoRepository.AsQueryable().Filter(null, true) - .Where(a => a.NOM_ID == rollModel.PK_ID && a.GROUP_INDX == 1 && !a.IsDeleted).ToList(); + .Where(a => a.NOM_ID == rollModel.PK_ID && a.IsDeleted == false).ToList(); - var fromEntity = shipList.FirstOrDefault(a => - a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)); + var fromEntity = shipList.Where(a => + a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList(); - if (fromEntity != null) - model.From = fromEntity.Adapt(); + if (fromEntity.Count > 0) + model.From = fromEntity.Select(p => p.Adapt()).ToList(); - var toEntity = shipList.FirstOrDefault(a => - a.SHIP_TYPE.Equals("To", StringComparison.OrdinalIgnoreCase)); + var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE, "To(\\s+[0-9]+)?" + , RegexOptions.IgnoreCase)).ToList(); - if (toEntity != null) - model.To = toEntity.Adapt(); + if (toEntity.Count > 0) + model.To = toEntity.Select(p => p.Adapt()).ToList(); + + List fromToList = new List(); + + //优先PORT关联FROM和TO,也有PORT为空的情况,这种就需要用Terminal来关联 + if (model.From.Any(t => string.IsNullOrWhiteSpace(t.Port))) + { + //这里为了前端原船和换船做了根据Terminal对应 + fromToList = model.From.GroupJoin(model.To, l => l.Terminal?.Trim(), r => r.Terminal?.Trim(), (l, r) => + { + TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto(); + + dto.FromShip = l; + + var currArg = r.ToList(); + + if (currArg.Count > 0) + { + dto.ToShipList = currArg.Select((p, idx) => + { + if (Regex.IsMatch(p.ShipType, "[0-9]+")) + return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p }; + + return new { SortNo = idx + 1, Obj = p }; + }).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList(); + } + + return dto; + }).ToList(); + } + else + { + //这里为了前端原船和换船做了根据PORT对应 + fromToList = model.From.GroupJoin(model.To, l => l.Port?.Trim(), r => r.Port?.Trim(), (l, r) => + { + TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto(); + + dto.FromShip = l; + + var currArg = r.ToList(); + + if (currArg.Count > 0) + { + dto.ToShipList = currArg.Select((p, idx) => + { + if (Regex.IsMatch(p.ShipType, "[0-9]+")) + return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p }; + + return new { SortNo = idx + 1, Obj = p }; + }).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList(); + } + + return dto; + }).ToList(); + } List> tuples = new List>(); model.LoadDetailList = list.Select(a => a.Detail.Adapt()).ToList(); + model.FromToList = new List(); + if (model.LoadDetailList.Count > 0) { model.TotalLoadCtnStat = string.Join(",", model.LoadDetailList.GroupBy(x => x.CtnAll) .Select(x => $"{x.Key}*{x.Sum(t => t.CtnNum)}").ToArray()); + + string rollRegex = "Roll\\s+to\\s+\\w+\\s+\\w{3,}\\/\\w+,\\s?if\\s+cannot\\s+catch\\s?,\\s+roll\\s+to\\s+\\w{3,}\\s+next\\s+sailing"; + string rollontoRegex = "Roll\\s+onto\\s+\\w{3,}\\s+\\w+,\\s+[0-9]+\\s+days\\s+delay\\."; + + bool isSelectRoll = false; + bool isRoll = false; + bool isRollOnto = false; + + model.LoadDetailList.ForEach(p => + { + string vslCode = string.Empty; + string voyNo = string.Empty; + string strCode = string.Empty; + string strCode2 = string.Empty; + + if (Regex.IsMatch(p.Status, rollRegex, RegexOptions.IgnoreCase)) + { + string currS = Regex.Match(p.Status, "(?<=Roll\\sto\\s\\w+\\s)\\w{3,}\\/\\w+(?=,)").Value; + vslCode = Regex.Split(currS, "\\/")[0]?.Trim(); + voyNo = Regex.Split(currS, "\\/")[1]?.Trim(); + + strCode = Regex.Match(p.Status, "(?<=if\\scannot\\scatch\\s?,\\sroll\\sto\\s)\\w{3,}(?=\\s+next\\s+sailing)").Value?.Trim(); + + isSelectRoll = true; + } + else if (p.Status.Trim().Equals("roll", StringComparison.OrdinalIgnoreCase)) + { + isRoll = true; + } + else if(Regex.IsMatch(p.Status, rollontoRegex, RegexOptions.IgnoreCase)) + { + vslCode = Regex.Match(p.Status, "(?<=Roll\\sonto\\s)\\w{3,}(?=\\s+\\w+,)").Value?.Trim(); + + isRollOnto = true; + } + + for (int i = 0; i < fromToList.Count; i++) + { + if(!string.IsNullOrWhiteSpace(fromToList[i].FromShip.Port)) + { + if (fromToList[i].FromShip.Port.Equals(p.PlaceOfReceipt, StringComparison.OrdinalIgnoreCase)) + { + var fromInfo = fromToList[i].FromShip.Adapt(); + + List toShipList = new List(); + + if (isSelectRoll) + { + for (int j = 0; j < fromToList[i].ToShipList.Count; j++) + { + if (fromToList[i].ToShipList[j].VslCode.Equals(vslCode, StringComparison.OrdinalIgnoreCase)) + { + toShipList.Add(fromToList[i].ToShipList[j].Adapt()); + } + else if (fromToList[i].ToShipList[j].ShipString.Equals(strCode, StringComparison.OrdinalIgnoreCase)) + { + toShipList.Add(fromToList[i].ToShipList[j].Adapt()); + } + } + } + else if (isRoll) + { + for (int j = 0; j < fromToList[i].ToShipList.Count; j++) + { + if (fromToList[i].ToShipList[j].Port.Equals(p.PlaceOfDelivery?.Trim(), StringComparison.OrdinalIgnoreCase)) + { + toShipList.Add(fromToList[i].ToShipList[j].Adapt()); + } + } + } + + if (toShipList.Count == 0) + { + if (fromToList[i].ToShipList.Count == 1) + { + toShipList.Add(fromToList[i].ToShipList.FirstOrDefault().Adapt()); + } + } + + model.FromToList.Add(new TaskRollingNominationShipFromToDto + { + FromShip = fromInfo, + ToShipList = toShipList + }); + } + } + else + { + if (fromToList[i].FromShip.Terminal.Contains(p.PlaceOfReceipt, StringComparison.OrdinalIgnoreCase)) + { + var fromInfo = fromToList[i].FromShip.Adapt(); + + List toShipList = new List(); + + if (isRollOnto) + { + for (int j = 0; j < fromToList[i].ToShipList.Count; j++) + { + if (fromToList[i].ToShipList[j].VslCode.Equals(vslCode, StringComparison.OrdinalIgnoreCase)) + { + toShipList.Add(fromToList[i].ToShipList[j].Adapt()); + } + } + } + + model.FromToList.Add(new TaskRollingNominationShipFromToDto + { + FromShip = fromInfo, + ToShipList = toShipList + }); + } + } + + } + }); } } catch (Exception ex) @@ -551,6 +724,7 @@ namespace Myshipping.Application.Service.TaskManagePlat /* 1、验证shareKey是否有效。 2、查看分享记录找到对应的预甩调度详情。 + 3、用户已经提交过意见的不能再发起 3、更新用户反馈意见。 4、返回成功 */ @@ -568,9 +742,18 @@ namespace Myshipping.Application.Service.TaskManagePlat if (shareEntity == null) throw Oops.Oh($"链接分享不存在"); + if(shareEntity.STATUS != TaskShareLinkStatusEnum.ACTIVE.ToString()) + { + if(shareEntity.STATUS != TaskShareLinkStatusEnum.COMPLETE.ToString()) + throw Oops.Oh($"预甩通知用户已反馈,不能重复提交"); + + throw Oops.Oh($"分享链接已失效,请咨询操作重新获取"); + } + shareEntity.USER_OPINION = model.userOpinion; shareEntity.USER_OPINION_TXT = model.userOpinionTxt; shareEntity.CONFIRM_DATE = DateTime.Now; + shareEntity.IS_MANUAL = model.isManual; await _taskShareLinkInfoRepository.AsUpdateable(shareEntity) .UpdateColumns(it => new @@ -578,8 +761,11 @@ namespace Myshipping.Application.Service.TaskManagePlat it.USER_OPINION, it.USER_OPINION_TXT, it.CONFIRM_DATE, + it.IS_MANUAL, }).ExecuteCommandAsync(); + //需要回写预甩任务的 + result.succ = true; result.msg = "成功"; } diff --git a/Myshipping.Application/Service/TrackingSystem/ServiceWorkFlowManageService.cs b/Myshipping.Application/Service/TrackingSystem/ServiceWorkFlowManageService.cs index ff85ca6a..6a37b5c7 100644 --- a/Myshipping.Application/Service/TrackingSystem/ServiceWorkFlowManageService.cs +++ b/Myshipping.Application/Service/TrackingSystem/ServiceWorkFlowManageService.cs @@ -1625,63 +1625,68 @@ namespace Myshipping.Application var activitiesRunInfo = _serviceWorkFlowRunActivitiesInfoRepository .AsQueryable().First(b => b.PK_ID == detail.Detail.PK_ID); - var beforeObj = new + _logger.LogInformation("批次={no} 取消状态前记录 出问题的地方 info={info} msg={msg}", batchNo,JSON.Serialize(info), JSON.Serialize(activitiesRunInfo)); + + if(activitiesRunInfo != null) { - ACT_VAL = activitiesRunInfo.ACT_VAL, - ACT_REMARK = activitiesRunInfo.ACT_REMARK, - ACT_DATE = activitiesRunInfo.ACT_DATE, - IS_YIELD = activitiesRunInfo.IS_YIELD - }; + var beforeObj = new + { + ACT_VAL = activitiesRunInfo.ACT_VAL, + ACT_REMARK = activitiesRunInfo.ACT_REMARK, + ACT_DATE = activitiesRunInfo.ACT_DATE, + IS_YIELD = activitiesRunInfo.IS_YIELD + }; - _logger.LogInformation("批次={no} 取消状态前记录 msg={msg}", batchNo,JSON.Serialize(beforeObj)); + _logger.LogInformation("批次={no} 取消状态前记录 msg={msg}", batchNo, JSON.Serialize(beforeObj)); - activitiesRunInfo.ACT_VAL = null; - activitiesRunInfo.ACT_REMARK = null; - activitiesRunInfo.ACT_DATE = null; - activitiesRunInfo.IS_YIELD = 0; + activitiesRunInfo.ACT_VAL = null; + activitiesRunInfo.ACT_REMARK = null; + activitiesRunInfo.ACT_DATE = null; + activitiesRunInfo.IS_YIELD = 0; - activitiesRunInfo.UpdatedTime = nowDate; - activitiesRunInfo.UpdatedUserId = long.Parse(info.Main.OperUserId); - activitiesRunInfo.UpdatedUserName = info.Main.OperUserName; + activitiesRunInfo.UpdatedTime = nowDate; + activitiesRunInfo.UpdatedUserId = long.Parse(info.Main.OperUserId); + activitiesRunInfo.UpdatedUserName = info.Main.OperUserName; - await _serviceWorkFlowRunActivitiesInfoRepository.AsUpdateable(activitiesRunInfo) - .UpdateColumns(it => new - { - it.ACT_DATE, - it.IS_YIELD, - it.ACT_REMARK, - it.ACT_VAL, - it.UpdatedTime, - it.UpdatedUserId, - it.UpdatedUserName - }).ExecuteCommandAsync(); + await _serviceWorkFlowRunActivitiesInfoRepository.AsUpdateable(activitiesRunInfo) + .UpdateColumns(it => new + { + it.ACT_DATE, + it.IS_YIELD, + it.ACT_REMARK, + it.ACT_VAL, + it.UpdatedTime, + it.UpdatedUserId, + it.UpdatedUserName + }).ExecuteCommandAsync(); - #region 写入运行日志 - var runLog = activitiesRunInfo.Adapt(); - runLog.PK_ID = IDGen.NextID().ToString(); - runLog.RUN_ID = activitiesRunInfo.RUN_ID; - runLog.RUN_DETAIL_ID = activitiesRunInfo.PK_ID; - runLog.BATCH_NO = batchNo; - runLog.OPER_TYPE = TrackingRunOperTypeEnum.CANCEL_STATUS.ToString(); - runLog.EXEC_RESULT = "SUCC"; - runLog.EXEC_NOTE = "Update"; - runLog.MBL_NO = info.Main?.MBlNo.ToUpper(); - runLog.VESSEL_VOYNO = info.Main?.VesselVoyno.ToUpper(); - runLog.ORDER_NO = info.Main?.OrderNo; - runLog.RELEASE_VERSION = detail.Main.RELEASE_VERSION; - runLog.BUSI_SYSTEM_CODE = info.Main.BusiSystemCode.ToUpper(); - runLog.BUSI_ID = info.Main.BusiId.ToUpper(); - runLog.SERVICE_WF_ID = detail.Main.SERVICE_WF_ID.ToUpper(); - runLog.SERVICE_PROJECT_CODE = detail.Main.SERVICE_PROJECT_CODE.ToUpper(); - runLog.SERVICE_PROJECT_NAME = detail.Main.SERVICE_PROJECT_NAME.ToUpper(); - runLog.ACT_VAL = beforeObj.ACT_VAL; - runLog.ACT_DATE = beforeObj.ACT_DATE; - runLog.ACT_REMARK = beforeObj.ACT_REMARK; - runLog.IS_YIELD = beforeObj.IS_YIELD; - runLog.SOURCE_TYPE = info.Main.SourceType.ToString(); + #region 写入运行日志 + var runLog = activitiesRunInfo.Adapt(); + runLog.PK_ID = IDGen.NextID().ToString(); + runLog.RUN_ID = activitiesRunInfo.RUN_ID; + runLog.RUN_DETAIL_ID = activitiesRunInfo.PK_ID; + runLog.BATCH_NO = batchNo; + runLog.OPER_TYPE = TrackingRunOperTypeEnum.CANCEL_STATUS.ToString(); + runLog.EXEC_RESULT = "SUCC"; + runLog.EXEC_NOTE = "Update"; + runLog.MBL_NO = info.Main?.MBlNo.ToUpper(); + runLog.VESSEL_VOYNO = info.Main?.VesselVoyno.ToUpper(); + runLog.ORDER_NO = info.Main?.OrderNo; + runLog.RELEASE_VERSION = detail.Main.RELEASE_VERSION; + runLog.BUSI_SYSTEM_CODE = info.Main.BusiSystemCode.ToUpper(); + runLog.BUSI_ID = info.Main.BusiId.ToUpper(); + runLog.SERVICE_WF_ID = detail.Main.SERVICE_WF_ID.ToUpper(); + runLog.SERVICE_PROJECT_CODE = detail.Main.SERVICE_PROJECT_CODE.ToUpper(); + runLog.SERVICE_PROJECT_NAME = detail.Main.SERVICE_PROJECT_NAME.ToUpper(); + runLog.ACT_VAL = beforeObj.ACT_VAL; + runLog.ACT_DATE = beforeObj.ACT_DATE; + runLog.ACT_REMARK = beforeObj.ACT_REMARK; + runLog.IS_YIELD = beforeObj.IS_YIELD; + runLog.SOURCE_TYPE = info.Main.SourceType.ToString(); - await _serviceWorkFlowRunLogInfoRepository.InsertAsync(runLog); - #endregion + await _serviceWorkFlowRunLogInfoRepository.InsertAsync(runLog); + #endregion + } } }); });