using DS.Module.Core; using DS.Module.RedisModule; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Code.Interface; using DS.WMS.Core.Code.Method; using DS.WMS.Core.Map.Interface; using DS.WMS.Core.Map.Method; using DS.WMS.Core.Sys.Interface; using DS.WMS.Core.Sys.Method; using DS.WMS.Core.TaskPlat.Dtos; using DS.WMS.Core.TaskPlat.Entity; using DS.WMS.Core.TaskPlat.Interface; using Microsoft.Extensions.DependencyInjection; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Mapster; using DS.Module.DjyServiceStatus; using Microsoft.AspNetCore.Identity; using DS.WMS.Core.Op.Interface; using Masuit.Tools; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Sys.Entity; using HtmlAgilityPack; using Microsoft.AspNetCore.Mvc; using Amazon.Runtime.Internal.Util; using Newtonsoft.Json; using NLog; using DS.Module.Core.Helpers; using System.Text.Json.Nodes; using LanguageExt.Pipes; using DS.WMS.Core.Op.Entity; using Org.BouncyCastle.Asn1.X9; using DS.WMS.Core.Op.EDI; using DS.WMS.Core.Sys.Dtos; using DS.WMS.Core.Code.Dtos; using DS.Module.Core.Data; using LanguageExt.Common; using DS.WMS.Core.Op.Method.TaskInteraction; using DS.WMS.Core.Op.Entity.TaskInteraction; using DS.WMS.Core.Op.Interface.TaskInteraction; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Logging; namespace DS.WMS.Core.TaskPlat.Method { public class TaskPOLContainerNotPickUpService : TaskManageBaseService, ITaskPOLContainerNotPickUpService { private readonly ISeaExportService _seaExportService; private readonly IConfigService _configService; private readonly IUserService _userService; private readonly ITaskLogService _logService; private readonly ITaskMailService _taskMailService; private readonly ITaskAllocationService _taskAllocationService; public TaskPOLContainerNotPickUpService(IUser user, ILogger logger, ISaasDbService saasDbService, IServiceProvider serviceProvider, IWebHostEnvironment environment) : base(user, logger, saasDbService, serviceProvider, environment) { //_serviceProvider = serviceProvider; //db = serviceProvider.GetRequiredService(); user = serviceProvider.GetRequiredService(); //saasService = serviceProvider.GetRequiredService(); _seaExportService = serviceProvider.GetRequiredService(); _configService = serviceProvider.GetRequiredService(); _userService = serviceProvider.GetRequiredService(); _taskMailService = serviceProvider.GetRequiredService(); _taskAllocationService = serviceProvider.GetRequiredService(); } #region 通过任务主键获取起运港未提箱详情 /// /// 通过任务主键获取起运港未提箱详情 /// /// 起运港未提箱任务主键 /// 返回回执 public async Task>> GetInfoByTaskId(long taskPKId) { //await SetTaskStatus(11, TaskBaseTypeEnum.CUT_MODIFY, TaskStatusEnum.Create, DateTime.Now, null); List list = new List(); var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); //任务不考虑OrgId,这里去掉 tenantDb.QueryFilter.Clear(); var queryList = await tenantDb.Queryable() .InnerJoin((a, b) => a.Id == b.TASK_ID) .Where((a, b) => a.Id == taskPKId) .Select((a, b) => new { Base = a, Pol = b }) .ToListAsync(); //任务主键{taskPkId}无法获取业务信息 if (queryList.Count == 0) throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId)); if (queryList.Count > 0) { list = queryList.Select(a => a.Pol.Adapt()).ToList(); } return DataResult>.Success(list); } #endregion #region 检索对应的订舱订单并保存订舱ID /// /// 检索对应的订舱订单并保存订舱ID /// /// 起运港未提箱任务主键 /// 返回回执 public async Task> SearchAndMarkBookingOrder(long taskPKId) { var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); var entity = tenantDb.Queryable().Filter(null, true).First(a => a.TASK_ID == taskPKId); return await _seaExportService.SearchOrderInfo(entity.MBL_NO); } #endregion #region 发送邮件通知给客户 /// /// 发送邮件通知给客户 /// /// 起运港未提箱主键 /// 邮件模板主键 /// 返回回执 public async Task> InnerSendEmailToCustomer(long taskPKId, long businessTaskMailId) { /* 1、先匹配订单。这里可能关联的是拆票订单,如果是拆票订单需要所有拆票记录都要发邮件通知) 2、有订单,调取任务规则补全相关人(如果当票已经有了人员表记录 task_base_allocation则不再处理人员) 3、调取发送模板。 4、填充模板数据。 5、发送邮件。 6、成功后置任务为完成状态。 */ var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); var entity = tenantDb.Queryable().Filter(null, true).First(a => a.TASK_ID == taskPKId); var baseInfo = tenantDb.Queryable().Filter(null, true).First(a => a.Id == taskPKId); var queryRlt = await _seaExportService.SearchOrderInfo(entity.MBL_NO); if (!queryRlt.Succeeded) { logger.LogInformation($"匹配订单信息失败 mblno={entity.MBL_NO},原因:{queryRlt.Message}"); return DataResult.Failed($"匹配订单信息失败 mblno={entity.MBL_NO},原因:{queryRlt.Message}"); } var taskInfo = entity.Adapt(); BusinessTaskMail? mailConfig = _taskMailService.GetAsync(businessTaskMailId).GetAwaiter().GetResult().Data; if (mailConfig == null) { await _logService.WriteLogAsync(new Op.Dtos.TaskInteraction.TaskUpdateRequest { BusinessId = taskPKId, BusinessType = BusinessType.OceanShippingExport, AutoCreateNext = true, TaskTypeName = TaskBaseTypeEnum.POL_CTN_NOT_PICKUP.ToString(), }, $"未能根据任务配置值获取邮件模板设置"); return DataResult.Failed("未能根据任务配置值获取邮件模板设置"); } var orderInfo = queryRlt.Data; logger.LogInformation($"获取订单详情成功 bookid={orderInfo.currOrder.Id}"); DateTime nowDate = DateTime.Now; List orderIdList = new List { orderInfo.currOrder.Id }; if (orderInfo.otherOrderList != null && orderInfo.otherOrderList.Count > 0) orderIdList.AddRange(orderInfo.otherOrderList.Select(t => t.Id).ToList()); //如果是拆票需要处理,处理所以分票记录 if (orderInfo.currOrder.SplitOrMergeFlag == 1) { bool isHasAlloc = false; foreach (var id in orderIdList) { var taskAllocList = tenantDb.Queryable().Where(a => a.TaskId == taskPKId).ToList(); var searchAllotUserRlt = _taskAllocationService.GetAllotUserBySeaExportId(TaskBaseTypeEnum.POL_CTN_NOT_PICKUP, id, new TaskFlowDataContext()).GetAwaiter().GetResult(); if (searchAllotUserRlt.Succeeded && searchAllotUserRlt.Data?.Count > 0) { isHasAlloc = true; var addUserList = searchAllotUserRlt.Data.GroupJoin(taskAllocList, l => l.RecvUserId, r => r.UserId, (l, r) => { if (r.ToList().Count == 0) return new { add = true, obl = l}; return new { add = false, obl = l }; }).Where(a=>a.add).Select(a=>a.obl).ToList(); if (addUserList.Count > 0) { //写入 addUserList.ForEach(b => { var alloc = new TaskBaseAllocation { Status = baseInfo.STATUS, StatusName = baseInfo.STATUS_NAME, TaskId = taskPKId, StatusTime = nowDate, UserId = b.RecvUserId, UserName = b.RecvUserName }; tenantDb.Insertable(alloc).ExecuteCommand(); }); } } } if (isHasAlloc && baseInfo.IS_PUBLIC == 1) { await tenantDb.Updateable(baseInfo).UpdateColumns(x => new { x.IS_PUBLIC }).ExecuteCommandAsync(); } } else { var taskAllocList = tenantDb.Queryable().Where(a => a.TaskId == taskPKId).ToList(); if (taskAllocList.Count == 0) { var searchAllotUserRlt = _taskAllocationService.GetAllotUserBySeaExportId(TaskBaseTypeEnum.POL_CTN_NOT_PICKUP, orderInfo.currOrder.Id,new TaskFlowDataContext()).GetAwaiter().GetResult(); if (searchAllotUserRlt.Succeeded && searchAllotUserRlt.Data?.Count > 0) { //写入 searchAllotUserRlt.Data.ForEach(b => { var alloc = new TaskBaseAllocation { Status = baseInfo.STATUS, StatusName = baseInfo.STATUS_NAME, TaskId = taskPKId, StatusTime = nowDate, UserId = b.RecvUserId, UserName = b.RecvUserName }; tenantDb.Insertable(alloc).ExecuteCommand(); }); if (baseInfo.IS_PUBLIC == 1) { baseInfo.IS_PUBLIC = 0; await tenantDb.Updateable(baseInfo).UpdateColumns(x => new { x.IS_PUBLIC }).ExecuteCommandAsync(); } } } } TaskTransferMsgDto resultDto = new TaskTransferMsgDto { ExcuteDate = nowDate, Detail = new List() }; Dictionary> dict = new Dictionary>(); foreach (var id in orderIdList) { TaskTransferMsgDataDto detail = new TaskTransferMsgDataDto { BusinessId = id, }; var model = new MailTemplateModel(taskInfo) { BusinessId = id, BusinessType = BusinessType.OceanShippingExport, }; MailService mailService = new MailService(serviceProvider); var result = await mailService.SendAsync(mailConfig, model); if (!result.Succeeded) { await _logService.WriteLogAsync(new Op.Dtos.TaskInteraction.TaskUpdateRequest { BusinessId = taskPKId, BusinessType = BusinessType.OceanShippingExport, AutoCreateNext = true, TaskTypeName = TaskBaseTypeEnum.POL_CTN_NOT_PICKUP.ToString(), }, result.Message); //return DataResult.Failed(result.Message); } detail.Status = result.Succeeded ? "SUCC" : "FAILURE"; detail.Message = result.Message; detail.MBlNo = entity.MBL_NO; resultDto.Detail.Add(detail); dict.Add(id, new Tuple(result.Succeeded, result.Message, entity.MBL_NO)); } //如果存在失败记录,不能置完成状态 if (!dict.Any(t => !t.Value.Item1)) { entity.IS_TRANSFER_USER = true; entity.LST_TRANSFER_USER_DATE = DateTime.Now; entity.LST_STATUS = "SUCC"; entity.LST_STATUS_NAME = "发送成功"; await tenantDb.Updateable(entity).UpdateColumns(x => new { x.IS_TRANSFER_USER, x.LST_TRANSFER_USER_DATE, x.LST_STATUS, x.LST_STATUS_NAME }).ExecuteCommandAsync(); //发送完邮件,自动标记任务状态为完成 await SetTaskStatus(taskPKId, TaskBaseTypeEnum.POL_CTN_NOT_PICKUP, TaskStatusEnum.Complete, DateTime.Now, null); } return DataResult.Success(resultDto); } #endregion #region 发送邮件通知给客户(任务自动机调取) /// /// 发送邮件通知给客户(任务自动机调取) /// /// 数据上下文 /// 返回回执 public async Task> SendEmailToCustomerTask(TaskFlowDataContext dataContext) { var taskPKId = dataContext.Get(TaskFlowDataNameConst.TaskPKId); if (taskPKId == 0) throw new ArgumentException($"缺少参数:{nameof(TaskFlowDataNameConst.TaskPKId)}"); var businessTaskMailId = dataContext.Get($"{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}"); if (businessTaskMailId == 0) throw new ArgumentException($"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}"); if (businessTaskMailId == 0) { await _logService.WriteLogAsync(new Op.Dtos.TaskInteraction.TaskUpdateRequest { BusinessId = taskPKId, BusinessType = BusinessType.OceanShippingExport, AutoCreateNext = true, TaskTypeName = TaskBaseTypeEnum.POL_CTN_NOT_PICKUP.ToString(), }, $"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}"); return DataResult.Failed($"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}"); } return await InnerSendEmailToCustomer(taskPKId, businessTaskMailId); } #endregion #region 手工发送邮件通知给客户 /// /// 手工发送邮件通知给客户 /// /// 起运港未提箱任务主键 /// 返回回执 public async Task> ManualSendEmailToCustomer(long taskPKId) { var paramConfig = _configService.GetConfig("POLContainerNotPickUpEmailTemplateID", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value; long businessTaskMailId = 0; if (!string.IsNullOrWhiteSpace(paramConfig)) { businessTaskMailId = long.Parse(paramConfig); } else { return DataResult.Failed($"缺少系统参数参数:起运港未提箱邮件模板ID-POLContainerNotPickUpEmailTemplateID"); } return await InnerSendEmailToCustomer(taskPKId, businessTaskMailId); } #endregion } }