using AngleSharp.Dom; using DS.Module.Core; using DS.Module.Core.Data; using DS.Module.Core.Enums; using DS.Module.Core.Extensions; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Invoice.Dtos; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Dtos.TaskInteraction; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Op.Entity.TaskInteraction; using DS.WMS.Core.Op.Interface; using DS.WMS.Core.Op.Interface.TaskInteraction; using DS.WMS.Core.Op.Method.TaskInteraction; using DS.WMS.Core.Sys.Entity; 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 LanguageExt; using LanguageExt.Common; using LanguageExt.Pipes; using Mapster; using Masuit.Tools.Systems; using Microsoft.Extensions.DependencyInjection; using NPOI.SS.Formula.Functions; using Org.BouncyCastle.Ocsp; using SqlSugar; using System.Collections.Generic; using System.Drawing; using static AnyDiff.DifferenceLines; namespace DS.WMS.Core.Op.Method { /// /// 海运出口退舱接口 /// public class SeaExportRefundService: ISeaExportRefundService { private readonly IServiceProvider _serviceProvider; private readonly ISqlSugarClient db; private readonly IUser user; private readonly ISaasDbService saasService; private readonly ICommonService commonService; readonly ITaskService taskService; private readonly ISeaExportCommonService seaComService; private readonly IBookingSlotService bookSlotService; /// /// /// /// public SeaExportRefundService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; db = _serviceProvider.GetRequiredService(); user = _serviceProvider.GetRequiredService(); commonService = _serviceProvider.GetRequiredService(); saasService = _serviceProvider.GetRequiredService(); seaComService = _serviceProvider.GetRequiredService(); taskService = serviceProvider.GetRequiredService(); bookSlotService = serviceProvider.GetRequiredService(); } /// /// 列表 /// /// /// public async Task> GetListByPage(PageRequest request) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); //启用海运出口列表可视数据权限 (ISugarQueryable query, _) = await commonService.GetVisibleDataRuleFilter(tenantDb); var orgList = db.Queryable().Where(x => x.Status == StatusEnum.Enable); //序列化查询条件 var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition); //var result = tenantDb.Queryable() var statusList = tenantDb.Queryable().Select().ToList(); var result = query.Where(a=>(a.IsRefund == true || a.IsChangeETD == true) ) .InnerJoin((a, b) => a.Id == b.BusinessId) //.LeftJoin((a, b, c) => a.SaleOrgId == c.Id, "shippingweb8_dev.sys_org") //.LeftJoin((a, b, c) => a.SaleDeptId == c.Id, "shippingweb8_dev.sys_org") .Select((a, b) => new SeaExportRes() { //SaleDeptName = c.OrgName, }, true)//true表示 其余字段自动映射,根据字段名字 //.Select() .MergeTable() .Mapper(it => { it.BookingStatus = statusList.Where(x => x.BusinessId == it.Id).ToList(); //it.BookingStatus = tenantDb.Queryable().Where(x => x.BusinessId == it.Id).Select().ToList(); }) .Where(whereList); //.ToQueryPageAsync(request.PageCondition); var list = result.ToList(); var data = await result.ToQueryPageAsync(request.PageCondition); var totalData = new SeaExportDataTotalRes() { MainCount = list.Where(x => x.ParentId == 0).Count(), PartCount = list.Where(x => x.ParentId != 0).Count(), ReturnCount = 0, TEU = list.Sum(x => x.TEU), PKGS = list.Sum(x => x.PKGS), CBM = list.Sum(x => x.CBM), KGS = list.Sum(x => x.KGS), Cntr1 = list.Sum(x => x.Cntr1), Cntr2 = list.Sum(x => x.Cntr2), Cntr3 = list.Sum(x => x.Cntr3), Cntr4 = list.Sum(x => x.Cntr4), Cntr5 = list.Sum(x => x.Cntr5), Cntr6 = list.Sum(x => x.Cntr6), Cntr7 = list.Sum(x => x.Cntr7), Cntr8 = list.Sum(x => x.Cntr8), Cntr9 = list.Sum(x => x.Cntr9), Cntr10 = list.Sum(x => x.Cntr10), OtherCntr = list.Sum(x => x.OtherCntr), }; var res = new SeaExportListRes() { List = data.Data, TotalCount = list.Count(), DataTotal = totalData }; return await Task.FromResult(DataResult.Success(res, MultiLanguageConst.DataQuerySuccess)); } /// /// 详情 /// /// /// public async Task> GetSeaExportRefundInfo(string id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); tenantDb.QueryFilter.Clear(); var data = await tenantDb.Queryable() .Where(a => a.Id == long.Parse(id)) .Select() .Mapper(it => { var edi = tenantDb.Queryable().First(x => x.BusinessId == it.Id); if (edi != null) it.EdiInfo = edi.Adapt(); it.CtnInfo = tenantDb.Queryable().Where(x => x.BSNO == it.Id.ToString()).Select().ToList(); it.CtnPriceInfo = tenantDb.Queryable().Where(x => x.BusinessId == it.Id).Select().ToList(); it.BusinessLogList = tenantDb.Queryable().Where(x => x.BusinessId == it.Id) .Select() .Mapper(a => { a.Details = tenantDb.Queryable().Where(x => x.Pid == a.Id).ToList(); }) .ToList(); it.OrderContactList = tenantDb.Queryable().Where(x => x.BusinessId == it.Id).Select().ToList(); }) .FirstAsync(); return await Task.FromResult(DataResult.Success(data, MultiLanguageConst.DataQuerySuccess)); } #region 发起改配 /// /// 获取改配订单状态 /// /// /// public async Task> GetChangeOrderStatus(long id) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info = await tenantDb.Queryable().Where(x => x.Id == id).FirstAsync(); if (info.IsNull()) return await Task.FromResult(DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist)); var task = await tenantDb.Queryable().Where(x => x.BusinessId == id && x.TaskType == TaskBaseTypeEnum.WAIT_ORDER_AUDIT).FirstAsync(); if (task.IsNull()) { return await Task.FromResult(DataResult.Success("未审单")); } if (task.TaskStatus == TaskStatusEnum.Complete) { if (string.IsNullOrEmpty(info.MBLNO)) { return await Task.FromResult(DataResult.Success("已审未出号")); } else { if (info.IsBooking == true || info.IsVGM == true) { return await Task.FromResult(DataResult.Success("已申报")); } else { return await Task.FromResult(DataResult.Success("已出号未申报")); } } } else { return await Task.FromResult(DataResult.Success("未审单")); } } /// /// /// /// /// public async Task CreateChangeTaskAsync(ChangeTaskReq req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info = await tenantDb.Queryable().Where(x => x.Id == req.Id).FirstAsync(); if (info.IsNull()) return await Task.FromResult(DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist)); var task = await tenantDb.Queryable().Where(x => x.BusinessId == req.Id && x.TaskType == TaskBaseTypeEnum.WAIT_ORDER_AUDIT).FirstAsync(); if (task.IsNull()) { return await Task.FromResult(DataResult.Failed("此单未审,可直接编辑调整!")); } if (task.IsNotNull() && task.TaskStatus != TaskStatusEnum.Complete) { return await Task.FromResult(DataResult.Failed("此单未审,可直接编辑调整!")); } if (info.ETD.IsNotNull() && info.ETD < DateTime.Now) { return await Task.FromResult(DataResult.Failed("此单已开船,无法改配!")); } try { await tenantDb.Ado.BeginTranAsync(); #region 复制单据 var data = info.Adapt(); data.Id = 0; data.ParentId = 0; //data.CustomerNo = data.CustomerNo +"-GP"; data.BusinessStatus = "YSTC"; data.BusinessStatusName = "退舱已审"; var entity = await tenantDb.Insertable(data).ExecuteReturnEntityAsync(); var newKey = entity.Id; #region 初始化费用 var feeStatus = BusinessFeeStatus.Init(newKey); await tenantDb.Insertable(feeStatus).ExecuteCommandAsync(); #endregion var edi = await tenantDb.Queryable().FirstAsync(x => x.BusinessId == req.Id); if (edi.IsNotNull()) { var ediEntity = edi.Adapt(); ediEntity.Id = 0; ediEntity.BusinessId = newKey; await tenantDb.Insertable(ediEntity).ExecuteCommandAsync(); } var ctnList = await tenantDb.Queryable().Where(x => x.BSNO == req.Id.ToString()).ToListAsync(); if (ctnList.IsNotNull() && ctnList.Count>0) { var list = new List(); foreach (var item in ctnList) { var ctn = item.Adapt(); ctn.Id = 0; ctn.BSNO = newKey.ToString(); list.Add(ctn); } if (list.Count > 0) await tenantDb.Insertable(list).ExecuteCommandAsync(); } var priceList = await tenantDb.Queryable().Where(x => x.BusinessId == req.Id).ToListAsync(); if (priceList.IsNotNull() && priceList.Count > 0) { var list = new List(); foreach (var item in priceList) { var price = item.Adapt(); price.Id = 0; price.BusinessId = newKey; list.Add(price); } if (list.Count>0) await tenantDb.Insertable(list).ExecuteCommandAsync(); } var contactList = await tenantDb.Queryable().Where(x => x.BusinessId == req.Id).ToListAsync(); if (contactList.IsNotNull() && contactList.Count > 0) { var list = new List(); foreach (var item in contactList) { var contact = item.Adapt(); contact.Id = 0; contact.BusinessId = newKey; list.Add(contact); } if (list.Count > 0) await tenantDb.Insertable(list).ExecuteCommandAsync(); } //任务交互表 var taskList = await tenantDb.Queryable().Where(x => x.BusinessId == req.Id).ToListAsync(); if (taskList.IsNotNull() && taskList.Count > 0) { foreach (var item in taskList) { item.BusinessId = newKey; item.TaskStatus = TaskStatusEnum.Pending; } if (taskList.Count > 0) await tenantDb.Updateable(taskList).ExecuteCommandAsync(); } //任务台主表 var taskbaseList = await tenantDb.Queryable().Where(x => x.OUT_BS_NO == req.Id).ToListAsync(); if (taskbaseList.IsNotNull() && taskbaseList.Count > 0) { foreach (var item in taskbaseList) { item.OUT_BS_NO = newKey; } if (taskbaseList.Count > 0) await tenantDb.Updateable(taskbaseList).ExecuteCommandAsync(); } //任务台任务分配表 var taskAllocationList = await tenantDb.Queryable().Where(x => x.BusinessId == req.Id).ToListAsync(); if (taskAllocationList.IsNotNull() && taskAllocationList.Count > 0) { foreach (var item in taskAllocationList) { item.BusinessId = newKey; } if (taskAllocationList.Count > 0) await tenantDb.Updateable(taskAllocationList).ExecuteCommandAsync(); } #endregion //更新原单信息 info.CustomerNo = info.CustomerNo + "-GP"; info.IsBooking = false; info.IsCustoms = false; info.IsLand = false; info.IsVGM = false; info.BusinessStatus = ""; info.BusinessStatusName = ""; info.OrderProgress = "0"; await tenantDb.Updateable(info).UpdateColumns(x => new { x.CustomerNo,x.IsBooking,x.IsCustoms,x.IsLand,x.IsVGM,x.OrderProgress }).ExecuteCommandAsync(); var oldOrder = entity.Adapt(); entity.IsChangeETD = true; entity.ChangeReason = req.ChangeReason; entity.ChangeRemark = req.ChangeRemark; entity.ChangeOrderId = req.Id; entity.OrderProgress = req.OrderProgress; int rows = await tenantDb.Updateable(entity).UpdateColumns(x => new { x.IsChangeETD, x.ChangeReason, x.ChangeRemark, x.ChangeOrderId, x.OrderProgress, }).ExecuteCommandAsync(); await seaComService.SaveSeaExportLogAsync(new SeaExportSaveLog() { OperateType = "Update", OldOrder = oldOrder, NewOrder = entity, SourceCode = "CreateChangeTaskAsync", SourceName = "发起改配", }, tenantDb); #region 判断是否退舱 发起退舱 if (req.IsRefund) { var userList = new List(); if (req.OrderProgress =="2") //已出号未申报 发起退舱入池任务 推给当票商务 { userList.Add((long)entity.LanerId); var taskReq = new TaskCreationRequest() { BusinessId = newKey, BusinessType = BusinessType.OceanShippingExport, TaskTypeName = TaskBaseTypeEnum.RETURN_CABIN_POOL.ToString(), TaskTitle = $"【{TaskBaseTypeEnum.RETURN_CABIN_POOL.GetDescription()}】{entity?.CustomerNo}", TaskDescription = $"【{TaskBaseTypeEnum.RETURN_CABIN_POOL.GetDescription()}】{entity?.CustomerNo}", RecvUserIdList = userList.ToArray(), }; var result = await taskService.CreateTaskAsync(taskReq, false); if (!result.Succeeded) return await Task.FromResult(DataResult.Failed(result.Message)); } else //退舱确认任务 推给当票操作 { userList.Add(info.OperatorId); var taskReq = new TaskCreationRequest() { BusinessId = newKey, BusinessType = BusinessType.OceanShippingExport, TaskTypeName = TaskBaseTypeEnum.RETURN_CABIN.ToString(), TaskTitle = $"【{TaskBaseTypeEnum.RETURN_CABIN.GetDescription()}】{entity?.CustomerNo}", TaskDescription = $"【{TaskBaseTypeEnum.RETURN_CABIN.GetDescription()}】{entity?.CustomerNo}", RecvUserIdList = userList.ToArray() }; var result = await taskService.CreateTaskAsync(taskReq, false); if (!result.Succeeded) return await Task.FromResult(DataResult.Failed(result.Message)); } //await seaComService.SetGoodsStatus("YFTC", req.Id, tenantDb); } #endregion await tenantDb.Ado.CommitTranAsync(); return await Task.FromResult(DataResult.Successed("发起改配成功!")); } catch (Exception ex) { await tenantDb.Ado.RollbackTranAsync(); await ex.LogAsync(db); return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } } #endregion #region 发起退舱 public async Task CreateRefundAuditTaskAsync(RefundTaskReq req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info = await tenantDb.Queryable().Where(x => x.Id == req.Id).FirstAsync(); if (info.IsNull()) return await Task.FromResult(DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist)); if (!req.IsReserveFee && tenantDb.Queryable().Where(x => x.BusinessId == req.Id).Any()) { return await Task.FromResult(DataResult.Failed("存在业务相关费用,是否保留费用?")); } if (req.IsReserveFee && tenantDb.Queryable().Where(x => x.BusinessId == req.Id && x.FeeStatus == FeeStatus.Entering).Any()) { return await Task.FromResult(DataResult.Failed("存在录入状态的费用!")); } var taskReq = new TaskCreationRequest() { BusinessId = req.Id, BusinessType = BusinessType.OceanShippingExport, TaskTypeName = TaskBaseTypeEnum.RETURN_CABIN_AUDIT.ToString(), TaskTitle = $"【{TaskBaseTypeEnum.RETURN_CABIN_AUDIT.GetDescription()}】{info?.CustomerNo}", TaskDescription = $"【{TaskBaseTypeEnum.RETURN_CABIN_AUDIT.GetDescription()}】{info?.CustomerNo}", }; var result = await taskService.CreateTaskAsync(taskReq, false); if (!result.Succeeded) { return await Task.FromResult(DataResult.Failed(result.Message)); } else { var oldOrder = info.Adapt(); info.RefundTag = RefundTagEnum.Normal; info.RefundReason = req.RefundReason; info.RefundRemark = req.RefundRemark; info.OrderProgress = req.OrderProgress; int rows = await tenantDb.Updateable(info).UpdateColumns(x => new { x.RefundTag,x.RefundReason,x.RefundRemark,x.OrderProgress }).ExecuteCommandAsync(); await seaComService.SetGoodsStatus("YFTC", req.Id, tenantDb); await seaComService.SaveSeaExportLogAsync(new SeaExportSaveLog() { OperateType = "Update", OldOrder = oldOrder, NewOrder = info, SourceCode = "CreateRefundAuditTaskAsync", SourceName = "发起退仓审核", }, tenantDb); return await Task.FromResult(DataResult.Successed(result.Message)); } } #endregion /// /// 退舱审核完成回调 /// /// 回调信息 /// public async Task RefundAuditCallbackAsync(FlowCallback callback) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); if (callback.AuditType != TaskBaseTypeEnum.RETURN_CABIN_AUDIT) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems)); var info = await tenantDb.Queryable().Where(x => x.Id == callback.BusinessId).FirstAsync(); if (info.IsNull()) return await Task.FromResult(DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist)); if (callback.FlowStatus == FlowStatusEnum.Approve) { var userList = new List(); if (info.OrderProgress =="2")//已出号未申报 发起退舱入池任务 推给当票商务 { userList.Add((long)info.LaneId); var taskReq = new TaskCreationRequest() { BusinessId = info.Id, BusinessType = BusinessType.OceanShippingExport, TaskTypeName = TaskBaseTypeEnum.RETURN_CABIN_POOL.ToString(), TaskTitle = $"【{TaskBaseTypeEnum.RETURN_CABIN_POOL.GetDescription()}】{info?.CustomerNo}", TaskDescription = $"【{TaskBaseTypeEnum.RETURN_CABIN_POOL.GetDescription()}】{info?.CustomerNo}", RecvUserIdList = userList.ToArray() }; var result = await taskService.CreateTaskAsync(taskReq, false); if (!result.Succeeded) return await Task.FromResult(DataResult.Failed(result.Message)); } else //退舱确认任务 推给当票操作 { userList.Add(info.OperatorId); //发起退舱确认任务 var taskReq = new TaskCreationRequest() { BusinessId = info.Id, BusinessType = BusinessType.OceanShippingExport, TaskTypeName = TaskBaseTypeEnum.RETURN_CABIN.ToString(), TaskTitle = $"【{TaskBaseTypeEnum.RETURN_CABIN.GetDescription()}】{info?.CustomerNo}", TaskDescription = $"【{TaskBaseTypeEnum.RETURN_CABIN.GetDescription()}】{info?.CustomerNo}", RecvUserIdList = userList.ToArray() }; var result = await taskService.CreateTaskAsync(taskReq, false); if (!result.Succeeded) { return await Task.FromResult(DataResult.Failed(result.Message)); } } #region 更新退舱标识 await seaComService.SetGoodsStatus("YSTC", callback.BusinessId, tenantDb); var oldOrder = info.Adapt(); info.IsRefund = true; int rows = await tenantDb.Updateable(info).UpdateColumns(x => new { x.IsRefund, }).ExecuteCommandAsync(); await seaComService.SaveSeaExportLogAsync(new SeaExportSaveLog() { OperateType = "Update", OldOrder = oldOrder, NewOrder = info, SourceCode = "RefundAuditCallbackAsync", SourceName = "退仓审核通过", }, tenantDb); #endregion } else { await seaComService.SetGoodsStatus("TCBH", callback.BusinessId, tenantDb); } return DataResult.Success; //return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } /// /// 退舱入池 /// /// /// public async Task RefundPoolAsync(IdModel req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info = await tenantDb.Queryable().Where(x => x.Id == long.Parse(req.Id)).FirstAsync(); if (info.IsNull()) return await Task.FromResult(DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist)); //if (info.IsRefund == false) //{ // return await Task.FromResult(DataResult.Failed("订单状态必须为退舱标识!")); //} var task = await tenantDb.Queryable().Where(x => x.BusinessId == long.Parse(req.Id) && x.TaskType == TaskBaseTypeEnum.RETURN_CABIN_POOL).FirstAsync(); if (task.IsNotNull() && task.TaskStatus == TaskStatusEnum.Complete) { return await Task.FromResult(DataResult.Failed("退舱入池任务已完成!")); } var ctnList = await tenantDb.Queryable().Where(x => x.BSNO == req.Id).ToListAsync(); if (ctnList.Count == 0) return await Task.FromResult(DataResult.Failed("集装箱列表不能为空!")); var ctns = ctnList.Adapt>(); //调用退舱入池接口 var postData = new BookingSlotBaseApiDto() { OpType = "del", DataObj = new BookingSlotBaseApiSaveDto() { Id = info.ChangeOrderId.IsNotNull()? (long)info.ChangeOrderId : info.Id, SlotBookingNo = info.MBLNO, CtnList = ctns, } }; var res = await bookSlotService.InnerApiReceive(postData); if (!res.Succeeded) return await Task.FromResult(DataResult.Failed(res.Message)); return DataResult.Success; } /// /// 创建退舱确认任务 /// /// /// public async Task CreateRefundConfirmAsync(IdModel req) { var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var info = await tenantDb.Queryable().Where(x => x.Id == long.Parse(req.Id)).FirstAsync(); if (info.IsNull()) return await Task.FromResult(DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist)); //if (info.IsRefund == false) //{ // return await Task.FromResult(DataResult.Failed("订单状态必须为退舱标识!")); //} var task = await tenantDb.Queryable().Where(x => x.BusinessId == long.Parse(req.Id) && x.TaskType == TaskBaseTypeEnum.RETURN_CABIN).FirstAsync(); if (task.IsNotNull() && task.TaskStatus == TaskStatusEnum.Complete) { return await Task.FromResult(DataResult.Failed("退舱确认任务已完成!")); } var userList = new List(); userList.Add(info.OperatorId); //发起退舱确认任务 var taskReq = new TaskCreationRequest() { BusinessId = info.Id, BusinessType = BusinessType.OceanShippingExport, TaskTypeName = TaskBaseTypeEnum.RETURN_CABIN.ToString(), TaskTitle = $"【{TaskBaseTypeEnum.RETURN_CABIN.GetDescription()}】{info?.CustomerNo}", TaskDescription = $"【{TaskBaseTypeEnum.RETURN_CABIN.GetDescription()}】{info?.CustomerNo}", RecvUserIdList = userList.ToArray() }; var res = await taskService.CreateTaskAsync(taskReq, false); if (!res.Succeeded) return await Task.FromResult(DataResult.Failed(res.Message)); return DataResult.Success; } } }