using DS.Module.Core; using DS.Module.Core.Constants; using DS.Module.DjyServiceStatus; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Code.Interface; using DS.WMS.Core.Info.Dtos; using DS.WMS.Core.Info.Interface; using DS.WMS.Core.Map.Dtos; using DS.WMS.Core.Map.Interface; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Op.Interface; using DS.WMS.Core.Op.Method; using DS.WMS.Core.Sys.Interface; using DS.WMS.Core.TaskPlat.Dtos; using DS.WMS.Core.TaskPlat.Entity; using DS.WMS.Core.TaskPlat.Interface; using Mapster; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using NPOI.XWPF.UserModel; using SqlSugar; namespace DS.WMS.Core.TaskPlat.Method { /// /// 任务台-BC子任务 /// public class TaskManageBCService : TaskManageBaseService, ITaskManageBCService { // 实例化时构建 private readonly IConfigService configService; private readonly IClientInfoService clientInfoService; private readonly IMappingCarrierService mappingCarrierService; private readonly IOpFileService opFileService; private readonly ICodeCtnService codeCtnService; // 按需构建 private Lazy bookingSlotService; private Lazy seaExportService; private Lazy djyServiceStatusService; public TaskManageBCService(IUser user, ILogger logger, ISaasDbService saasDbService, IServiceProvider serviceProvider, IWebHostEnvironment environment, IConfigService configService, IClientInfoService clientInfoService, IMappingCarrierService mappingCarrierService, IOpFileService opFileService, ICodeCtnService codeCtnService) : base(user, logger, saasDbService, serviceProvider, environment) { this.configService = configService; this.clientInfoService = clientInfoService; this.mappingCarrierService = mappingCarrierService; this.opFileService = opFileService; this.codeCtnService = codeCtnService; bookingSlotService = new Lazy(serviceProvider.GetRequiredService); seaExportService = new Lazy(serviceProvider.GetRequiredService); djyServiceStatusService = new Lazy(serviceProvider.GetRequiredService); } /// /// 通过任务信息(BC)生成订舱或舱位 /// /// 生成订舱或者舱位请求 /// 返回回执 public async Task> CreateBookingAndSlot(BookingOrSlotGenerateDto model) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); logger.LogInformation($"接收生成订舱或舱位请求,参数{JsonConvert.SerializeObject(model)}"); try { /* 1、GEN_BOOKING_SLOT-生成舱位和订舱 (1)生成舱位 (2)生成海运订舱 (3)更新舱位库存 (4)更新BC任务 2、GEN_BOOKING-只生成订舱 (1)生成海运订舱 (4)更新BC任务 3、GEN_SLOT-只生成舱位 (1)生成舱位 (4)更新BC任务 3、GEN_SLOT-只生成舱位 (1)查找订舱记录 (3)更新舱位库存 (4)更新BC任务 */ if (model.BCTaskId == 0) throw new Exception($"BC任务主键不能为空"); //生成方式(GEN_BOOKING_SLOT-生成舱位和订舱;GEN_BOOKING-只生成订舱;GEN_SLOT-只生成舱位;GEN_EXIST_BOOKING-匹配指定的订舱) if (string.IsNullOrWhiteSpace(model.GenerateMethod)) throw new Exception($"生成方式不能为空,需要指定一种生成方式"); var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); var bcTaskInfo = await tenantDb.Queryable().Where(u => u.Id == model.BCTaskId).FirstAsync(); if (bcTaskInfo == null) { throw new Exception($"任务主键{model.BCTaskId}无法获取业务信息"); } var bcOrder = await tenantDb.Queryable().Where(a => a.TASK_ID == bcTaskInfo.Id).FirstAsync(); if (bcOrder == null) throw new Exception($"任务主键{model.BCTaskId}无法获取BC业务信息"); var bcCtnList = await tenantDb.Queryable().Where(a => a.P_ID == bcOrder.Id).ToListAsync(); var fileList = await tenantDb.Queryable().Where(a => a.TASK_PKID == bcTaskInfo.Id).ToListAsync(); if (model.GenerateMethod != "UPD_BOOKING") { if (bcOrder.BOOKING_ORDER_ID.HasValue && bcOrder.BOOKING_ORDER_ID.Value > 0) { throw new Exception($"当前BC任务已生成订舱订单,不能重复生成"); } } if (model.GenerateMethod == "GEN_BOOKING_SLOT") { #region 推送舱位、推送订舱 //推送舱位 //long bookingSlotId = 0; BookingSlotBase? bookingSlot = null; if (bcOrder.BOOKING_SLOT_ID.HasValue && bcOrder.BOOKING_SLOT_ID.Value > 0) { //bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value; throw new Exception($"生成舱位失败,舱位已存在"); } //这里增加委托单位联系人的校验,重新从后台拉取了委托单位相关联系人,如果比对不一致跳出异常终止执行 ValidateContact(model); //触发生成舱位 bookingSlot = await GenerateBookingSlotByTaskBcInfo(bcOrder, bcCtnList, fileList); logger.LogInformation($"生成舱位完成,bookingSlotId={bookingSlot?.Id} taskid={bcOrder.TASK_ID}"); if (bookingSlot == null || bookingSlot.Id == 0) throw new Exception($"生成舱位失败"); var slotFileList = opFileService.GetOpFileList(bookingSlot.Id.ToString()).Data; //if (bookingSlotService == null) //{ // bookingSlotService = serviceProvider.GetRequiredService(); //} //推送订舱订单 var bookingOrderId = await bookingSlotService.Value.GenerateBookingOrder(bookingSlot, slotFileList, model, null); logger.LogInformation($"生成订舱订单完成,bookingOrderId={bookingOrderId} taskid={bcOrder.TASK_ID}"); if (bookingOrderId < 1) throw new Exception($"生成订舱订单失败"); List slots = new List(); //检索舱位信息 var slotInfo = (await bookingSlotService.Value.Detail(bookingSlot.Id)).Data; BookingSlotBaseWithCtnDto baseInfo = slotInfo.Adapt(); baseInfo.Id = bookingSlot.Id; baseInfo.CtnList = slotInfo.CtnList.Adapt>(); slots.Add(baseInfo); //对应订舱和舱位关系 ImportSlotsDto importSlotsDto = new() { bookingOrderId = bookingOrderId, slots = slots, isCheck = false }; var allocRlt = await bookingSlotService.Value.ImportSlots(importSlotsDto); logger.LogInformation($"生成订舱和舱位关系完成,allocRlt={JsonConvert.SerializeObject(allocRlt)} taskid={bcOrder.TASK_ID}"); if (!allocRlt.Succeeded) { throw new Exception($"生成订舱和舱位关系失败"); } var bcEntity = await tenantDb.Queryable().Where(a => a.Id == bcOrder.Id).FirstAsync(); if (bcEntity == null) { throw new Exception($"未获取有效任务BC失败,更新失败"); } bcEntity.BOOKING_ORDER_ID = bookingOrderId; bcEntity.BOOKING_SLOT_ID = slotInfo.Id; bcEntity.UpdateTime = DateTime.Now; bcEntity.UpdateBy = long.Parse(user.UserId); bcEntity.UpdateUserName = user.UserName; //更新任务BC await tenantDb.Updateable(bcEntity).UpdateColumns(it => new { it.BOOKING_ORDER_ID, it.BOOKING_SLOT_ID, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); var taskEntity = await tenantDb.Queryable().FirstAsync(u => u.Id == bcEntity.TASK_ID); if (taskEntity == null) { throw new Exception($"未获取有效任务记录,更新失败"); } #region 更新任务 //如果是公共任务,需要变成个人任务 RealUserId = 当前操作人 if (taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.RealUserId = long.Parse(user.UserId); taskEntity.RealUserName = user.UserName; taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = taskEntity.RealUserId; taskEntity.UpdateUserName = user.UserName; taskEntity.IS_COMPLETE = 1; taskEntity.COMPLETE_DATE = DateTime.Now; taskEntity.COMPLETE_DEAL = "MANUAL"; taskEntity.COMPLETE_DEAL = "手工"; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.RealUserId, it.RealUserName, it.IS_COMPLETE, it.COMPLETE_DATE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME }).ExecuteCommandAsync(); } else { taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = long.Parse(user.UserId); taskEntity.UpdateUserName = user.UserName; taskEntity.IS_COMPLETE = 1; taskEntity.COMPLETE_DATE = DateTime.Now; taskEntity.COMPLETE_DEAL = "MANUAL"; taskEntity.COMPLETE_DEAL = "手工"; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.IS_COMPLETE, it.COMPLETE_DATE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME }).ExecuteCommandAsync(); } #endregion //var currBCOrder = await tenantDb.Queryable().Where(a => a.Id == bcEntity.Id).FirstAsync(); //if (currBCOrder != null && model.IsDirectSend) //{ // //异步推送邮件 // var mailRlt = await GenerateSendEmail(currBCOrder, bcTaskInfo, model.usePersonalEmailSend); // if (!mailRlt.succ) // { // throw Oops.Oh($"邮件推送失败,原因:{mailRlt.msg},可以任务编辑页面重新发送邮件"); // } //} #endregion } else if (model.GenerateMethod == "GEN_BOOKING") { #region 推送订舱 //bookingSlot = null; if (bcOrder.BOOKING_ORDER_ID.HasValue && bcOrder.BOOKING_ORDER_ID.Value > 0) { //bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value; throw new Exception($"生成订舱订单失败,订舱订单已存在"); } if (!bcOrder.BOOKING_SLOT_ID.HasValue || bcOrder.BOOKING_SLOT_ID.Value < 1) { //bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value; throw new Exception($"生成订舱订单失败,舱位未生成不能直接生成订舱订单"); } long bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value; //这里增加委托单位联系人的校验,重新从后台拉取了委托单位相关联系人,如果比对不一致跳出异常终止执行 ValidateContact(model); BookingSlotBase? bookingSlot = await tenantDb.Queryable().Where(x => x.Id == bookingSlotId).FirstAsync(); if (bookingSlot == null) { throw new Exception($"生成订舱订单失败,舱位未生成不能直接生成订舱订单"); } var slotFileList = opFileService.GetOpFileList(bookingSlotId.ToString()).Data; //推送订舱订单 //if (bookingSlotService == null) //{ // bookingSlotService = serviceProvider.GetRequiredService(); //} var bookingOrderId = await bookingSlotService.Value.GenerateBookingOrder(bookingSlot, slotFileList, model, null); logger.LogInformation($"生成订舱订单完成,bookingOrderId={bookingOrderId} taskid={bcOrder.TASK_ID}"); if (bookingOrderId < 1) throw new Exception($"生成订舱订单失败"); List slots = new List(); //检索舱位信息 var slotInfo = (await bookingSlotService.Value.Detail(bookingSlot.Id)).Data; BookingSlotBaseWithCtnDto baseInfo = slotInfo.Adapt(); baseInfo.Id = bookingSlot.Id; baseInfo.CtnList = slotInfo.CtnList.Adapt>(); slots.Add(baseInfo); //对应订舱和舱位关系 ImportSlotsDto importSlotsDto = new() { bookingOrderId = bookingOrderId, slots = slots, isCheck = false }; var allocRlt = await bookingSlotService.Value.ImportSlots(importSlotsDto); logger.LogInformation($"生成订舱和舱位关系完成,allocRlt={JsonConvert.SerializeObject(allocRlt)} taskid={bcOrder.TASK_ID}"); if (!allocRlt.Succeeded) { throw new Exception($"生成订舱和舱位关系失败"); } var bcEntity = await tenantDb.Queryable().Where(a => a.Id == bcOrder.Id).FirstAsync(); if (bcEntity == null) { throw new Exception($"未获取有效任务BC失败,更新失败"); } bcEntity.BOOKING_ORDER_ID = bookingOrderId; bcEntity.BOOKING_SLOT_ID = slotInfo.Id; bcEntity.UpdateTime = DateTime.Now; bcEntity.UpdateBy = long.Parse(user.UserId); bcEntity.UpdateUserName = user.UserName; //更新任务BC await tenantDb.Updateable(bcEntity).UpdateColumns(it => new { it.BOOKING_ORDER_ID, it.BOOKING_SLOT_ID, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); var taskEntity = await tenantDb.Queryable().FirstAsync(u => u.Id == bcEntity.TASK_ID); if (taskEntity == null) { throw new Exception($"未获取有效任务记录,更新失败"); } #region 更新任务 //如果是公共任务,需要变成个人任务 RealUserId = 当前操作人 if (taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.RealUserId = long.Parse(user.UserId); taskEntity.RealUserName = user.UserName; taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = taskEntity.RealUserId; taskEntity.UpdateUserName = user.UserName; taskEntity.IS_COMPLETE = 1; taskEntity.COMPLETE_DATE = DateTime.Now; taskEntity.COMPLETE_DEAL = "MANUAL"; taskEntity.COMPLETE_DEAL = "手工"; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.RealUserId, it.RealUserName, it.IS_COMPLETE, it.COMPLETE_DATE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME }).ExecuteCommandAsync(); } else { taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = long.Parse(user.UserId); taskEntity.UpdateUserName = user.UserName; taskEntity.IS_COMPLETE = 1; taskEntity.COMPLETE_DATE = DateTime.Now; taskEntity.COMPLETE_DEAL = "MANUAL"; taskEntity.COMPLETE_DEAL = "手工"; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.IS_COMPLETE, it.COMPLETE_DATE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME }).ExecuteCommandAsync(); } #endregion //var currBCOrder = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcEntity.PK_ID); //if (currBCOrder != null && model.IsDirectSend) //{ // //异步推送邮件 // var mailRlt = await GenerateSendEmail(currBCOrder, bcTaskInfo, model.usePersonalEmailSend); // if (!mailRlt.succ) // { // throw Oops.Oh($"邮件推送失败,原因:{mailRlt.msg},可以任务编辑页面重新发送邮件"); // } //} #endregion } else if (model.GenerateMethod == "GEN_SLOT") { #region 推送舱位 BookingSlotBase? bookingSlot = null; if (bcOrder.BOOKING_SLOT_ID.HasValue && bcOrder.BOOKING_SLOT_ID.Value > 0) { //bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value; throw new Exception($"生成舱位失败,舱位已存在"); } //触发生成舱位 bookingSlot = await GenerateBookingSlotByTaskBcInfo(bcOrder, bcCtnList, fileList); logger.LogInformation($"生成舱位完成,bookingSlotId={bookingSlot?.Id} taskid={bcOrder.TASK_ID}"); if (bookingSlot == null || bookingSlot.Id == 0) throw new Exception($"生成舱位失败"); var bcEntity = await tenantDb.Queryable().Where(a => a.Id == bcOrder.Id).FirstAsync(); if (bcEntity == null) { throw new Exception($"未获取有效任务BC失败,更新失败"); } bcEntity.BOOKING_SLOT_ID = bookingSlot.Id; bcEntity.UpdateTime = DateTime.Now; bcEntity.UpdateBy = long.Parse(user.UserId); bcEntity.UpdateUserName = user.UserName; //更新任务BC await tenantDb.Updateable(bcEntity).UpdateColumns(it => new { it.BOOKING_SLOT_ID, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommandAsync(); var taskEntity = await tenantDb.Queryable().FirstAsync(u => u.Id == bcEntity.TASK_ID); if (taskEntity == null) { throw new Exception($"未获取有效任务记录,更新失败"); } #region 更新任务 //如果是公共任务,需要变成个人任务 RealUserId = 当前操作人 if (taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.RealUserId = long.Parse(user.UserId); taskEntity.RealUserName = user.UserName; taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = taskEntity.RealUserId; taskEntity.UpdateUserName = user.UserName; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.RealUserId, it.RealUserName, }).ExecuteCommandAsync(); } else { taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = long.Parse(user.UserId); taskEntity.UpdateUserName = user.UserName; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.UpdateTime, it.UpdateBy, it.UpdateUserName, }).ExecuteCommandAsync(); } #endregion #endregion } else if (model.GenerateMethod == "UPD_BOOKING") { #region 更新订舱 if (bcOrder.BOOKING_ORDER_ID == null || bcOrder.BOOKING_ORDER_ID.Value == 0) { throw new Exception($"更新订舱订单失败,舱位未关联到订单信息"); } //这里增加委托单位联系人的校验,重新从后台拉取了委托单位相关联系人,如果比对不一致跳出异常终止执行 ValidateContact(model); long bookingSlotId = bcOrder.BOOKING_SLOT_ID.Value; //这里增加委托单位联系人的校验,重新从后台拉取了委托单位相关联系人,如果比对不一致跳出异常终止执行 ValidateContact(model); BookingSlotBase? bookingSlot = await tenantDb.Queryable().Where(x => x.Id == bookingSlotId).FirstAsync(); if (bookingSlot == null) { throw new Exception($"更新订舱订单失败,未找到id为{bookingSlotId}的舱位信息"); } List bookingSlotCtnList = await tenantDb.Queryable().Where(x => x.Id == bookingSlotId).ToListAsync(); //推送订舱订单 var bookingOrderId = await UpdateBookingOrder((long)bcOrder.BOOKING_ORDER_ID, bookingSlot, bookingSlotCtnList, model, tenantDb); var taskEntity = await tenantDb.Queryable().FirstAsync(u => u.Id == bcOrder.TASK_ID); if (taskEntity == null) { throw new Exception($"未获取有效任务记录,更新失败"); } #region 更新任务 //如果是公共任务,需要变成个人任务 RealUserId = 当前操作人 if (taskEntity.IS_PUBLIC == 1) { taskEntity.IS_PUBLIC = 0; taskEntity.RealUserId = long.Parse(user.UserId); taskEntity.RealUserName = user.UserName; taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = taskEntity.RealUserId; taskEntity.UpdateUserName = user.UserName; taskEntity.IS_COMPLETE = 1; taskEntity.COMPLETE_DATE = DateTime.Now; taskEntity.COMPLETE_DEAL = "MANUAL"; taskEntity.COMPLETE_DEAL = "手工"; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.IS_PUBLIC, it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.RealUserId, it.RealUserName, it.IS_COMPLETE, it.COMPLETE_DATE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME }).ExecuteCommandAsync(); } else { taskEntity.UpdateTime = DateTime.Now; taskEntity.UpdateBy = long.Parse(user.UserId); taskEntity.UpdateUserName = user.UserName; taskEntity.IS_COMPLETE = 1; taskEntity.COMPLETE_DATE = DateTime.Now; taskEntity.COMPLETE_DEAL = "MANUAL"; taskEntity.COMPLETE_DEAL = "手工"; await tenantDb.Updateable(taskEntity).UpdateColumns(it => new { it.UpdateTime, it.UpdateBy, it.UpdateUserName, it.IS_COMPLETE, it.COMPLETE_DATE, it.COMPLETE_DEAL, it.COMPLETE_DEAL_NAME }).ExecuteCommandAsync(); } #endregion //var currBCOrder = await tenantDb.Queryable().Where(a => a.Id == bcEntity.Id).FirstAsync(); //if (currBCOrder != null && model.IsDirectSend) //{ // //异步推送邮件 // var mailRlt = await GenerateSendEmail(currBCOrder, bcTaskInfo, model.usePersonalEmailSend); // if (!mailRlt.succ) // { // throw Oops.Oh($"邮件推送失败,原因:{mailRlt.msg},可以任务编辑页面重新发送邮件"); // } //} #endregion } result.succ = true; result.msg = "成功"; return DataResult.Success(result); } catch (Exception ex) { result.succ = false; result.msg = $"生成订舱或舱位失败,原因:{ex.Message}"; return DataResult.FailedData(result); } } private void ValidateContact(BookingOrSlotGenerateDto model) { var paramConfig = configService.GetConfig(TenantParamCode.CONST_CREATE_BOOKING_NEED_CONTACT, long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value; if (model.CustomerContactList != null && model.CustomerContactList.Count > 0) { //取委托客户下面所有的联系人列表 var djyCustomerInfo = clientInfoService.GetClientInfoWithContact(new Info.Dtos.QueryClientInfo { ClientId = model.CustomerId.Value, IsController = true }).GetAwaiter().GetResult().Data; if (djyCustomerInfo == null) { logger.LogInformation($"委托单位{model.CustomerName} 获取失败,委托单位不存在或已作废 SlotId={model.SlotId.Value}"); //委托单位{0} 获取失败,委托单位不存在或已作废 throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotCreateContaNull)), model.CustomerName)); } if (djyCustomerInfo.ClientContactList == null && djyCustomerInfo.ClientContactList.Count < 1) { logger.LogInformation($"委托单位{model.CustomerName} 获取相关联系人失败,委托单位相关联系人为空 SlotId={model.SlotId.Value}"); //委托单位{0} 获取相关联系人失败,委托单位相关联系人为空 throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotCreateCustomerContractInfoNull)), model.CustomerName)); } model.CustomerContactList.ForEach(contact => { var djyCustomerContactMan = djyCustomerInfo.ClientContactList .FirstOrDefault(a => a.Id == contact.Id); if (djyCustomerContactMan == null) { logger.LogInformation($"委托单位{model.CustomerName} 联系人 {contact.Name}获取失败,联系人不存在或已作废 SlotId={model.SlotId}"); //委托单位 {0} 联系人 {1} 获取失败,联系人不存在或已作废 throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotCreateCustomerContractDeletedOrNoExists)), model.CustomerName, contact.Name)); } }); } else { if (paramConfig != null && paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase)) { //生成订舱时往来单位联系人必填,请修改 throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.BookingSlotCreateCustomerContractNotNull))); } } } /// /// 通过任务主键获取BC详情 /// /// BC任务主键 public async Task> GetInfoByTaskId(long taskId) { TaskManageOrderResultDto result = new TaskManageOrderResultDto(); try { var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); var taskBase = await tenantDb.Queryable().FirstAsync(a => a.Id == taskId); if (taskBase == null) throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseEmpty))); var bcOrder = await tenantDb.Queryable().FirstAsync(a => a.TASK_ID == taskId); if (bcOrder == null) throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBCInfoEmpty))); var bcCtnList = await tenantDb.Queryable().Where(a => a.P_ID == bcOrder.Id).ToListAsync(); TaskBCShowBaseDto model = bcOrder.Adapt(); if (bcCtnList.Count > 0) model.CtnList = bcCtnList.Adapt>(); var fileList = await tenantDb.Queryable().Where(a => a.TASK_PKID == bcOrder.TASK_ID).ToListAsync(); if (fileList.Count > 0) model.FileList = fileList.Adapt>(); model.taskStatus = taskBase.STATUS; #region 生成关键信息 model.Keywords = new List(); if (bcOrder.CARRIAGE_TYPE == "DIRECT_SHIP") { model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"承运方式:{bcOrder.CARRIAGE_TYPE_NAME}", Background = "#FFFF80", Icon = "icon-yunshu1" }); } else if (bcOrder.CARRIAGE_TYPE == "TRANSFER_SHIP") { model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"承运方式:{bcOrder.CARRIAGE_TYPE_NAME}", Background = "#CAF982", Icon = "icon-shuaxin" }); } if (bcOrder.BOOKING_SLOT_TYPE == "CONTRACT_ORDER") { model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"订舱方式:{bcOrder.BOOKING_SLOT_TYPE_NAME}", Background = "#81D3F8", Icon = "icon-touzijilu" }); } else if (bcOrder.BOOKING_SLOT_TYPE == "SPOT_ORDER") { model.Keywords.Add(new TaskBCShowBaseKeywordDto() { Name = $"订舱方式:{bcOrder.BOOKING_SLOT_TYPE_NAME}", Background = "#FACD91", Icon = "icon-beizhu1" }); } #endregion //await SetTaskStatus([taskId], x => x.IS_PUBLIC == 1, x => x.IS_EXCEPT == 0); //await SetTaskOwner([taskId], new List() //{ // new RecvUserInfo(111,"231312321"), // new RecvUserInfo(222,"affsdfdsf"), //}); result.succ = true; result.ext = model; //如果当前BC有对应记录,则读取订舱详情 //0726:经确认页面上没有用到订舱详情,所以暂时不返回 //if (bcOrder.BOOKING_ORDER_ID.HasValue) //{ // var bkOrder = await _bookingOrderRepository.AsQueryable(). // FirstAsync(a => a.Id == bcOrder.BOOKING_ORDER_ID.Value); // if (bkOrder != null) // { // var showBKOrder = bkOrder.Adapt(); // var ctnList = await _bookingCtnRepository.AsQueryable(). // Where(a => a.BILLID == bkOrder.Id).ToListAsync(); // if (ctnList.Count > 0) // showBKOrder.ctnInputs = ctnList.Adapt>(); // result.ext2 = showBKOrder; // } //} } catch (Exception ex) { result.succ = false; result.msg = $"获取BC详情异常,原因:{ex.Message}"; } return DataResult.Success(result); } #region 根据BC任务信息生成舱位 /// /// 根据BC任务信息,生成舱位(调用的) /// /// BC任务详情 /// BC任务集装箱列表 /// BC任务附件列表 /// 返回舱位ID private async Task GenerateBookingSlotByTaskBcInfo(TaskBCInfo taskBCInfo, List taskBCCtnList, List taskFileList, string opType = "add") { //long id = 0; try { var allMapCarrierList = await mappingCarrierService.GetAllList(); MappingCarrierRes? carrierInfo = null; if (allMapCarrierList.Succeeded) { carrierInfo = allMapCarrierList.Data.Where(t => t.MapCode.Equals(taskBCInfo.CARRIERID, StringComparison.OrdinalIgnoreCase) && t.Module == MappingModuleConst.CONST_MAPPING_CARRIER_MODULE).FirstOrDefault(); } BookingSlotBaseApiDto slotModel = new BookingSlotBaseApiDto { DataObj = new BookingSlotBaseApiSaveDto { CarrierId = carrierInfo?.LinkId, CarrierCode = carrierInfo?.MapCode, Carrier = carrierInfo?.MapName, SlotBookingNo = taskBCInfo.MBL_NO, BookingParty = taskBCInfo.BOOKING_PARTY, BookingSlotType = taskBCInfo.BOOKING_SLOT_TYPE, BookingSlotTypeName = taskBCInfo.BOOKING_SLOT_TYPE_NAME, Vessel = taskBCInfo.VESSEL, Voyno = taskBCInfo.VOYNO, VGMSubmissionCutDate = taskBCInfo.VGM_CUTOFF_TIME, //WeekAt = taskBCInfoDto.WEEK_AT, CarriageType = taskBCInfo.CARRIAGE_TYPE, CarriageTypeName = taskBCInfo.CARRIAGE_TYPE_NAME, ContractNo = taskBCInfo.CONTRACTNO, CtnStat = taskBCInfo.CTN_STAT, CYCutDate = taskBCInfo.CY_CUTOFF_TIME, DetensionFreeDays = taskBCInfo.DETENSION_FREE_DAYS, ETD = taskBCInfo.ETD, ETA = taskBCInfo.ETA, LaneCode = taskBCInfo.LANECODE, LaneName = taskBCInfo.LANENAME, ManifestCutDate = taskBCInfo.MANIFEST_CUT_DATE, MDGFCutDate = taskBCInfo.MDGF_CUT_DATE, PlaceDelivery = taskBCInfo.PLACEDELIVERY, PlaceReceipt = taskBCInfo.PLACERECEIPT, PortDischarge = taskBCInfo.PORTDISCHARGE, PortLoad = taskBCInfo.PORTLOAD, SICutDate = taskBCInfo.SI_CUT_DATE, CustomSICutDate = taskBCInfo.CUSTOM_SI_CUT_DATE, TransferPort1 = taskBCInfo.TRANSFER_PORT_1, TransferPort2 = taskBCInfo.TRANSFER_PORT_2, PriceCalculationDate = taskBCInfo.PRICE_CALCULATION_DATE, CtnList = new List() }, OpType = "add" }; if (int.TryParse(taskBCInfo.WEEK_AT, out int _weekat)) { slotModel.DataObj.WeekAt = _weekat; } var ctnCodeList = (await codeCtnService.GetAllList()).Data ?? new List(); if (taskBCCtnList.Count > 0) { taskBCCtnList.ForEach(t => { if (string.IsNullOrEmpty(t.CTNCODE) && !string.IsNullOrEmpty(t.CTNALL)) { var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.CtnName) && a.CtnName.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase)); t.CTNCODE = ctnCode != null ? $"{ctnCode.CtnSize}{ctnCode.CtnType}" : "(箱型未收录)"; } BookingSlotCtnSaveInput ctn = new BookingSlotCtnSaveInput { CtnCode = t.CTNCODE, CtnAll = t.CTNALL, CtnNum = t.CTNNUM.HasValue ? t.CTNNUM.Value : 1 }; slotModel.DataObj.CtnList.Add(ctn); }); } var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" }); DynameFileInfo dynameFile = null; DynameFileInfo dynameNoticeFile = null; if (taskFileList.Any(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString())) { var fileInfo = taskFileList.FirstOrDefault(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString()); string fileFullPath; if (string.IsNullOrEmpty(basePath)) { fileFullPath = Path.Combine(environment.WebRootPath ?? "", fileInfo.FILE_PATH); } else { fileFullPath = Path.Combine(basePath, fileInfo.FILE_PATH); } dynameFile = new DynameFileInfo { FileBytes = File.ReadAllBytes(fileFullPath), FileName = Path.GetFileName(fileFullPath) }; } if (taskFileList.Any(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC_NOTICE.ToString())) { var fileInfo = taskFileList.FirstOrDefault(t => t.FILE_CATEGORY == TaskFileCategoryEnum.BC.ToString()); string fileFullPath; if (string.IsNullOrEmpty(basePath)) { fileFullPath = Path.Combine(environment.WebRootPath ?? "", fileInfo.FILE_PATH); } else { fileFullPath = Path.Combine(basePath, fileInfo.FILE_PATH); } dynameNoticeFile = new DynameFileInfo { FileBytes = File.ReadAllBytes(fileFullPath), FileName = Path.GetFileName(fileFullPath) }; } var result = await bookingSlotService.Value.InnerApiReceive(slotModel, dynameFile, dynameNoticeFile); return result.Data; } catch (Exception ex) { logger.LogError($"任务BC MBLNO:{taskBCInfo.MBL_NO} 生成舱位异常,原因:{ex.Message}"); throw new Exception($"MBLNO:{taskBCInfo.MBL_NO} 生成舱位异常,原因:{ex.Message}"); } } #endregion #region 更新订舱 /// /// 更新订舱 /// /// 返回订舱ID private async Task UpdateBookingOrder( //TaskBCInfo taskBCInfo, //List taskBCCtnList, long bookingOrderId, BookingSlotBase bookingSlotBase, List bookingSlotCtnList, BookingOrSlotGenerateDto generateModel, SqlSugarScopeProvider? tenantDb = null) { long id = 0; if (tenantDb == null) { tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); } try { /* 1、新增订舱 2、推送服务项目 3、推送附件 */ var allMapCarrierList = await mappingCarrierService.GetAllList(); MappingCarrierRes carrierInfo = null; if (allMapCarrierList.Succeeded) { carrierInfo = allMapCarrierList.Data.FirstOrDefault(t => t.LinkId == bookingSlotBase.CarrierId.Value && t.Module == MappingModuleConst.CONST_MAPPING_CARRIER_MODULE); } SeaExportReq bkModel = new SeaExportReq { Id = bookingOrderId, CustomerId = generateModel.CustomerId.Value, CustomerName = generateModel.CustomerName, Carrier = carrierInfo?.MapName?.Trim(), CarrierId = bookingSlotBase.CarrierId.Value, BookingNo = bookingSlotBase.SlotBookingNo.Trim(), MBLNO = bookingSlotBase.SlotBookingNo.Trim(), ContractNo = !string.IsNullOrWhiteSpace(bookingSlotBase.ContractNo) ? bookingSlotBase.ContractNo : "", Vessel = bookingSlotBase.Vessel?.ToUpper()?.Trim(), Voyno = bookingSlotBase.Voyno?.ToUpper()?.Trim(), InnerVoyno = bookingSlotBase.Voyno?.ToUpper()?.Trim(), ETD = bookingSlotBase.ETD, ETA = bookingSlotBase.ETA, SaleId = generateModel.SaleId.HasValue ? generateModel.SaleId.Value : 0, Sale = generateModel.SaleName, OperatorId = generateModel.OpId.HasValue ? generateModel.OpId.Value : 0, OperatorName = generateModel.OpName, Doc = generateModel.DocId.HasValue ? generateModel.DocId.Value : 0, DocName = generateModel.DocName, //ROUTEID = generateModel.RouteID?.ToString(), //ROUTE = generateModel.Route, //CZRemark = generateModel.CZRemark, //ShenQingXiangShi = generateModel.ShenQingXiangShi, //LineManageID = generateModel.LineManageID?.ToString(), //LineName = generateModel.LineManage, VGMCloseDate = bookingSlotBase.VGMSubmissionCutDate, ClosingDate = bookingSlotBase.CYCutDate, CloseDocDate = bookingSlotBase.SICutDate, CustomerService = generateModel.CustServiceId.HasValue ? generateModel.CustServiceId.Value : 0, CustomerServiceName = generateModel.CustServiceName, LoadPort = bookingSlotBase.PortLoad, LoadPortId = bookingSlotBase.PortLoadId.HasValue ? bookingSlotBase.PortLoadId.Value : 0, DischargePortId = bookingSlotBase.PortDischargeId.HasValue ? bookingSlotBase.PortLoadId.Value : 0, DischargePort = bookingSlotBase.PortDischarge, ReceiptPlace = bookingSlotBase.PlaceReceipt, ReceiptPlaceId = bookingSlotBase.PlaceReceiptId.HasValue ? bookingSlotBase.PlaceReceiptId.Value : 0, DeliveryPlace = bookingSlotBase.PlaceDelivery, DeliveryPlaceId = bookingSlotBase.PlaceDeliveryId.HasValue ? bookingSlotBase.PlaceDeliveryId.Value : 0, BLType = "整箱", StlName = "票结", CtnInfo = new List() }; //var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList(); if (bookingSlotCtnList != null && bookingSlotCtnList.Count > 0) { bookingSlotCtnList.Select(t => { OpCtnReq ctn = new OpCtnReq { CtnCode = t.CtnCode, CtnAll = t.CtnAll, CtnNum = t.CtnNum }; return ctn; }); } var bkRlt = await seaExportService.Value.EditSeaExport(bkModel); id = long.Parse(bkRlt.Data.ToString()); string batchNo = Guid.NewGuid().ToString(); //var hisList = _bookingOrderContactRepository.AsQueryable().Where(a => a.BookingId == id && a.IsDeleted == false).ToList(); //if (hisList.Count > 0) //{ // //批量作废 // hisList.ForEach(async a => // { // a.IsDeleted = true; // a.UpdatedTime = DateTime.Now; // a.UpdatedUserId = UserManager.UserId; // a.UpdatedUserName = UserManager.Name; // await _bookingOrderContactRepository.UpdateAsync(a); // }); //} //这里如果指定了委托单位的邮件联系人,则推送订舱联系人 if (generateModel.CustomerContactList != null && generateModel.CustomerContactList.Count > 0) { var bookingContactList = await tenantDb.Queryable() .Where(a => a.BusinessId == id && a.Deleted == false).ToListAsync(); var djyCustomerInfo = clientInfoService.GetClientInfoWithContact(new Info.Dtos.QueryClientInfo { ClientId = generateModel.CustomerId.Value, IsController = true }) .GetAwaiter().GetResult().Data; generateModel.CustomerContactList.ForEach(contact => { ClientContactRes djyCustomerContactMan = null; if (djyCustomerInfo.ClientContactList != null && djyCustomerInfo.ClientContactList.Count > 0) { djyCustomerContactMan = djyCustomerInfo.ClientContactList.FirstOrDefault(a => a.Id == contact.Id); } if (djyCustomerContactMan != null) { var bookingContact = bookingContactList .FirstOrDefault(x => x.Email.Equals(djyCustomerContactMan.Email, StringComparison.OrdinalIgnoreCase)); if (bookingContact == null) { bookingContact = new BusinessOrderContact { Name = djyCustomerContactMan.ShortName, BusinessId = id, Email = djyCustomerContactMan.Email, Note = djyCustomerContactMan.Note, CreateTime = DateTime.Now, CreateBy = long.Parse(user.UserId), CreateUserName = user.UserName }; tenantDb.Insertable(bookingContact).ExecuteCommand(); //_bookingOrderContactRepository.Insert(bookingContact); } else { bookingContact.Name = djyCustomerContactMan.ShortName; bookingContact.Email = djyCustomerContactMan.Email; bookingContact.Note = djyCustomerContactMan.Note; bookingContact.UpdateTime = DateTime.Now; bookingContact.UpdateBy = long.Parse(user.UserId); bookingContact.UpdateUserName = user.UserName; tenantDb.Updateable(bookingContact).UpdateColumns(it => new { it.Name, it.Email, it.Note, it.UpdateTime, it.UpdateBy, it.UpdateUserName }).ExecuteCommand(); } } }); } if (generateModel.ProjectList != null && generateModel.ProjectList.Count > 0) { //写入服务项目 var prjRlt = djyServiceStatusService.Value.SaveServiceProject(new EmbedServiceProjectDto { BusinessId = id.ToString(), ProjectCodes = generateModel.ProjectList.Distinct().ToArray(), }); logger.LogInformation($"推送订舱的服务项目完成 id={id} rlt={JsonConvert.SerializeObject(prjRlt)}"); } logger.LogInformation($"任务BC MBLNO:{bookingSlotBase.SlotBookingNo} 生成订舱成功 id={id}"); } catch (Exception ex) { logger.LogError($"任务BC MBLNO:{bookingSlotBase.SlotBookingNo} 生成订舱异常,原因:{ex.Message}"); } return id; } #endregion #region 获取当前比对结果 /// /// 获取当前比对结果 /// /// BC任务主键 /// 返回回执 public async Task>> GetCompareResult(long taskId) { var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); var queryList = await tenantDb.Queryable() .InnerJoin((a, b) => a.Id == b.TASK_ID) .Where((a, b) => a.Id == taskId) .Select((a, b) => new { Base = a, BC = b }) .ToListAsync(); //任务主键{taskPkId}无法获取业务信息 if (queryList.Count == 0) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskId)); var taskBCInfo = queryList.FirstOrDefault().BC; if (taskBCInfo.BOOKING_SLOT_ID.HasValue) { return await bookingSlotService.Value.GetSlotCompareResult(taskBCInfo.BOOKING_SLOT_ID.Value, taskBCInfo.BATCH_NO); } else { return DataResult>.FailedData(new List()); } } #endregion } }