You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookingHeChuan/Myshipping.Application/Service/TaskManagePlat/TaskManageRollingNomination...

1041 lines
47 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Myshipping.Application.Entity;
using Myshipping.Application.Service.TaskManagePlat;
using Myshipping.Core;
using Myshipping.Core.Service;
using MySqlX.XDevAPI.Common;
using NPOI.XWPF.UserModel;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Myshipping.Application
{
/// <summary>
/// 预甩货通知
/// </summary>
[ApiDescriptionSettings("Application", Name = "TaskManageRollingNomination", Order = 10)]
public class TaskManageRollingNominationService : ITaskManageRollingNominationService, IDynamicApiController, ITransient
{
private readonly ISysCacheService _cache;
private readonly ILogger<TaskManageRollingNominationService> _logger;
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
private readonly SqlSugarRepository<TaskRollingNominationInfo> _taskRollingNominationInfoRepository;
private readonly SqlSugarRepository<TaskRollingNominationShipInfo> _taskRollingNominationShipInfoRepository;
private readonly SqlSugarRepository<TaskRollingNominationDetailInfo> _taskRollingNominationDetailInfoRepository;
private readonly SqlSugarRepository<TaskRollingNominationDispatchInfo> _taskRollingNominationDispatchInfoRepository;
private readonly SqlSugarRepository<TaskShareLinkInfo> _taskShareLinkInfoRepository;
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
private readonly SqlSugarRepository<BookingCtn> _bookingCtnRepository;
private readonly INamedServiceProvider<ITaskManageShareLinkService> _namedServiceProvider;
public TaskManageRollingNominationService(SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
SqlSugarRepository<TaskRollingNominationInfo> taskRollingNominationInfoRepository,
SqlSugarRepository<TaskRollingNominationDetailInfo> taskRollingNominationDetailInfoRepository,
SqlSugarRepository<TaskRollingNominationDispatchInfo> taskRollingNominationDispatchInfoRepository,
SqlSugarRepository<TaskRollingNominationShipInfo> taskRollingNominationShipInfoRepository,
SqlSugarRepository<TaskShareLinkInfo> taskShareLinkInfoRepository,
SqlSugarRepository<BookingOrder> bookingOrderRepository,
INamedServiceProvider<ITaskManageShareLinkService> namedServiceProvider,
SqlSugarRepository<BookingCtn> bookingCtnRepository, ISysCacheService cache, ILogger<TaskManageRollingNominationService> logger)
{
_taskBaseRepository = taskBaseRepository;
_taskRollingNominationInfoRepository = taskRollingNominationInfoRepository;
_taskRollingNominationDetailInfoRepository = taskRollingNominationDetailInfoRepository;
_taskRollingNominationDispatchInfoRepository = taskRollingNominationDispatchInfoRepository;
_taskRollingNominationShipInfoRepository = taskRollingNominationShipInfoRepository;
_taskShareLinkInfoRepository = taskShareLinkInfoRepository;
_bookingOrderRepository = bookingOrderRepository;
_bookingCtnRepository = bookingCtnRepository;
_namedServiceProvider = namedServiceProvider;
_cache = cache;
_logger = logger;
}
#region 获取预甩详情
/// <summary>
/// 获取预甩详情
/// </summary>
/// <param name="pkId">预甩主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageRollingNomination/GetInfo")]
public async Task<TaskRollingNominationShowDto> GetInfo(string pkId)
{
TaskRollingNominationShowDto model = null;
try
{
var rollModel = _taskRollingNominationInfoRepository.AsQueryable()
.First(a => a.PK_ID == pkId && !a.IsDeleted);
if (rollModel == null)
throw Oops.Oh($"预甩货主键{pkId}无法获取业务信息");
model = await InnerGetInfo(rollModel);
}
catch (Exception ex)
{
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
throw ex;
}
return model;
}
#endregion
#region 通过任务主键获取预甩详情
/// <summary>
/// 通过任务主键获取预甩详情
/// </summary>
/// <param name="taskPkId">预甩任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageRollingNomination/GetInfoByTaskId")]
public async Task<TaskRollingNominationShowDto> GetInfoByTaskId(string taskPkId)
{
TaskRollingNominationShowDto model = null;
try
{
var taskBase = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskPkId && !a.IsDeleted);
if (taskBase == null)
throw Oops.Oh($"预甩货任务主键{taskPkId}无法获取任务信息");
var rollModel = _taskRollingNominationInfoRepository.AsQueryable()
.First(a => a.TASK_ID == taskBase.PK_ID && !a.IsDeleted);
if (rollModel == null)
throw Oops.Oh($"预甩货任务主键{taskBase.PK_ID}无法获取业务信息");
model = await InnerGetInfo(rollModel);
}
catch(Exception ex)
{
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
throw ex;
}
return model;
}
#endregion
#region 获取预甩详情
/// <summary>
/// 获取预甩详情
/// </summary>
/// <param name="rollModel">预甩货详情实体类</param>
/// <returns>返回详情</returns>
private async Task<TaskRollingNominationShowDto> InnerGetInfo(TaskRollingNominationInfo rollModel)
{
TaskRollingNominationShowDto model = null;
try
{
List<string> rollingPlanList = new List<string>();
if (!string.IsNullOrWhiteSpace(rollModel.PLAN_TXT))
{
rollingPlanList = rollModel.PLAN_TXT.Split("\\n").ToList();
}
model = new TaskRollingNominationShowDto
{
PlanType = rollModel.PLAN_TYPE,
CarrierId = rollModel.CARRIERID,
Carrier = rollModel.CARRIER,
ConfirmDeadLine = rollModel.CONFIRM_DEAD_LINE,
CreateTime = rollModel.READ_CREATE_TIME,
RollingTouchDoubleRollRemark = rollModel.ROLL_DOUBLE_REMARK,
LoadDetailList = new List<TaskRollingNominationShipDetailShowDto>(),
RollingPlanList = rollingPlanList,
PreBillList = new List<TaskRollingNominationShipPreBillShowDto>(),
NominationId = rollModel.PK_ID
};
var shipList = _taskRollingNominationShipInfoRepository.AsQueryable()
.Where(a => a.NOM_ID == rollModel.PK_ID && a.IsDeleted == false).ToList();
var fromEntity = shipList.Where(a =>
a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList();
if (fromEntity.Count > 0)
model.From = fromEntity.Select(p=>p.Adapt<TaskRollingNominationShipDto>()).ToList();
var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE,"To(\\s+[0-9]+)?"
, RegexOptions.IgnoreCase)).ToList();
if (toEntity.Count > 0)
model.To = toEntity.Select(p => p.Adapt<TaskRollingNominationShipDto>()).ToList();
//这里为了前端原船和换船做了根据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<TaskRollingNominationDispatchInfo>((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID)
.Where((detail, dispatch) => detail.NOM_ID == rollModel.PK_ID && detail.IsDeleted == false
&& (string.IsNullOrWhiteSpace(dispatch.PK_ID) || (!string.IsNullOrWhiteSpace(dispatch.PK_ID) && dispatch.IsDeleted == false)))
.Select((detail, dispatch) => new { Detail = detail, Dispatch = dispatch }).ToList();
List<Tuple<string,int>> tuples = new List<Tuple<string,int>>();
if (withDispatchList.Any(a =>
a.Detail.BOOKING_ID.HasValue && (a.Dispatch != null && !string.IsNullOrWhiteSpace(a.Dispatch.PK_ID))))
{
model.PreBillList = withDispatchList.Where(a =>
a.Detail.BOOKING_ID.HasValue && (a.Dispatch != null && !string.IsNullOrWhiteSpace(a.Dispatch.PK_ID)))
.GroupBy(a => a.Detail.CUSTOMERID)
.SelectMany((a, idx) => {
var cArg = a.ToList();
return a.GroupBy(b => b.Detail.SHIPMENT).Select(
b => {
var preBillArg = b.ToList();
var preBillDetail = preBillArg.FirstOrDefault().Detail;
var preBillDispatch = preBillArg.FirstOrDefault().Dispatch;
var cStaticlst = preBillArg.GroupBy(x => x.Detail.CTNALL)
.Select(x =>
new { Key = x.Key, Num = x.Sum(t => t.Detail.CTNNUM) }).ToList();
string ctnStat = string.Join(",", cStaticlst.Select(x =>
$"{x.Key}*{x.Num}").ToArray());
cStaticlst.ForEach(y => tuples.Add(new Tuple<string, int>(y.Key, y.Num)));
string ctnNote = preBillArg.FirstOrDefault(x =>
!string.IsNullOrWhiteSpace(x.Detail.CTNNOTE))?.Detail.CTNNOTE;
TaskRollingNominationShipPreBillShowDto preBillInfo = new TaskRollingNominationShipPreBillShowDto
{
Bookedby = preBillDetail.BOOKED_BY,
ConfirmDate = preBillDispatch?.CONFIRM_DATE,
ConfirmDeadLine = preBillDispatch?.CONFIRM_DEAD_LINE,
CtnStat = ctnStat,
CustomerId = preBillDetail.CUSTOMERID,
CustomerName = preBillDetail.CUSTOMERNAME,
ContractualName = preBillDetail.CONTRACTUAL_NAME,
CreateShareLinkDate = preBillDispatch?.CREATE_SHARE_LINK_DATE,
DischargePortName = preBillDetail.DISCHARGEPORT_NAME,
IsSend = preBillDispatch != null ? preBillDispatch.IS_SEND : false,
IsUserManual = preBillDispatch != null ? preBillDispatch.IS_USER_MANUAL : false,
LoadPortName = preBillDetail.LOADPORT_NAME,
PlaceOfDelivery = preBillDetail.PLACEOF_DELIVERY,
PlaceOfReceipt = preBillDetail.PLACEOF_RECEIPT,
Shipment = preBillDetail.SHIPMENT,
Status = preBillDispatch?.STATUS,
ShareLinkKey = preBillDispatch?.SHARE_LINK_KEY,
UserOpinion = preBillDispatch?.USER_OPINION,
UserOpinionTxt = preBillDispatch?.USER_OPINION_TXT,
BatchId = preBillDispatch?.BATCH_ID,
BookingId = preBillDetail.BOOKING_ID,
GroupName = preBillDetail.CUSTOMERID.HasValue ? $"CUST_{idx + 1}" : "",
CtnNote = ctnNote
};
return preBillInfo;
}).ToList();
}).ToList();
}
if (withDispatchList.Any(a =>
(a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID) || !a.Detail.BOOKING_ID.HasValue)
&& !a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase)))
{
model.PreBillList.AddRange(withDispatchList.Where(a =>
(a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID) || !a.Detail.BOOKING_ID.HasValue)
&& !a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))
.GroupBy(a => a.Detail.SHIPMENT)
.Select((b, idx) =>
{
var preBillArg = b.ToList();
var preBillDetail = preBillArg.FirstOrDefault().Detail;
var preBillDispatch = preBillArg.FirstOrDefault().Dispatch;
var cStaticlst = preBillArg.GroupBy(x => x.Detail.CTNALL)
.Select(x =>
new { Key = x.Key, Num = x.Sum(t => t.Detail.CTNNUM) }).ToList();
string ctnStat = string.Join(",", cStaticlst.Select(x =>
$"{x.Key}*{x.Num}").ToArray());
cStaticlst.ForEach(y => tuples.Add(new Tuple<string, int>(y.Key, y.Num)));
string ctnNote = preBillArg.FirstOrDefault(x =>
!string.IsNullOrWhiteSpace(x.Detail.CTNNOTE))?.Detail.CTNNOTE;
TaskRollingNominationShipPreBillShowDto preBillInfo = new TaskRollingNominationShipPreBillShowDto
{
Bookedby = preBillDetail.BOOKED_BY,
ConfirmDate = preBillDispatch?.CONFIRM_DATE,
ConfirmDeadLine = preBillDispatch?.CONFIRM_DEAD_LINE,
CtnStat = ctnStat,
CustomerId = preBillDetail.CUSTOMERID,
CustomerName = preBillDetail.CUSTOMERNAME,
ContractualName = preBillDetail.CONTRACTUAL_NAME,
CreateShareLinkDate = preBillDispatch?.CREATE_SHARE_LINK_DATE,
DischargePortName = preBillDetail.DISCHARGEPORT_NAME,
IsSend = preBillDispatch != null ? preBillDispatch.IS_SEND : false,
IsUserManual = preBillDispatch != null ? preBillDispatch.IS_USER_MANUAL : false,
LoadPortName = preBillDetail.LOADPORT_NAME,
PlaceOfDelivery = preBillDetail.PLACEOF_DELIVERY,
PlaceOfReceipt = preBillDetail.PLACEOF_RECEIPT,
Shipment = preBillDetail.SHIPMENT,
Status = preBillDispatch?.STATUS,
ShareLinkKey = preBillDispatch?.SHARE_LINK_KEY,
UserOpinion = preBillDispatch?.USER_OPINION,
UserOpinionTxt = preBillDispatch?.USER_OPINION_TXT,
BatchId = preBillDispatch?.BATCH_ID,
BookingId = preBillDetail.BOOKING_ID,
GroupName = $"SHIPMENT_{idx + 1}",
CtnNote = ctnNote,
EquipmentNumber = preBillDetail.EQUIPMENT_NUMBER
};
return preBillInfo;
}).ToList());
}
if (withDispatchList.Any(a=>(a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID))
&& a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase)))
{
model.LoadDetailList = withDispatchList.Where(a =>
(a.Dispatch == null || string.IsNullOrWhiteSpace(a.Dispatch.PK_ID))
&& a.Detail.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))
.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
}
if(tuples.Count > 0)
{
model.TotalPreBillCtnStat = string.Join(",", tuples.GroupBy(x => x.Item1)
.Select(x =>
$"{x.Key}*{x.Sum(t => t.Item2)}").ToArray());
}
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());
}
}
catch (Exception ex)
{
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
throw ex;
}
return model;
}
#endregion
#region 推送预甩货客户访问链接
/// <summary>
/// 推送预甩货客户访问链接
/// </summary>
/// <param name="nominationDispatchId">预甩货任务主键组</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageRollingNomination/PushShareLink")]
public async Task<TaskManageOrderResultDto> PushShareLink([FromBody] string[] nominationDispatchId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 生成预甩货调度
/// <summary>
/// 生成预甩货调度
/// </summary>
/// <param name="model">生成预甩货调度请求</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageRollingNomination/DispatchRollingNomination")]
public async Task<TaskManageOrderResultDto> DispatchRollingNomination([FromBody] RollingNominationDispatchRequestDto model)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
/*
1、如果调度ID不为空标识选择新的明细替换原有的调度。
1首先匹配所选的箱型箱量是否一致装货港、卸货港必需一致不满足不能进行生成调度。
2删除原调度生成新调度。
2、如果调度ID为空标识是新增调度。
3、没有订舱ID或委托单位ID的数据不能生成调度。
*/
DateTime nowDate = DateTime.Now;
if (!model.isAdd)
{
if(string.IsNullOrWhiteSpace(model.nominationBatchId))
{
throw Oops.Oh($"改配调度需要提供预甩货调度批次ID");
}
if (model.loadDetailIds == null || model.loadDetailIds.Length == 0)
{
throw Oops.Oh($"预甩货可Load明细信息不能为空");
}
var detailList = _taskRollingNominationDetailInfoRepository.AsQueryable()
.Where(a => model.loadDetailIds.Contains(a.PK_ID) && a.IsDeleted == false).ToList();
if (detailList.Count != model.loadDetailIds.Length)
{
throw Oops.Oh($"预甩货明细部分获取失败,请重新获取预甩货明细");
}
if (detailList.Any(a => !a.BOOKING_ID.HasValue || !a.CUSTOMERID.HasValue))
{
throw Oops.Oh($"预甩货明细存在未对应订舱的记录,不能生成调度");
}
var nomId = detailList.FirstOrDefault().NOM_ID;
var nomModel = _taskRollingNominationInfoRepository.AsQueryable()
.First(a => a.PK_ID == nomId);
var shipmentList = detailList.Select(a => a.SHIPMENT).Distinct().ToList();
Dictionary<string, string> batchDict = shipmentList.Select(a => new { Key = a, BatchId = IDGen.NextID().ToString() })
.ToDictionary(a => a.Key, b => b.BatchId);
List<TaskRollingNominationDispatchInfo> dispatchList = new List<TaskRollingNominationDispatchInfo>();
List<TaskRollingNominationDetailInfo> withDispatchDetailList = new List<TaskRollingNominationDetailInfo>();
var withDispatchList = _taskRollingNominationDetailInfoRepository.AsQueryable().Filter(null, true)
.InnerJoin<TaskRollingNominationDispatchInfo>((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID)
.Where((detail, dispatch) => detail.PK_ID == dispatch.DETAIL_ID && detail.IsDeleted == false
&& dispatch.IsDeleted == false && dispatch.BATCH_ID == model.nominationBatchId)
.Select((detail, dispatch) => new { Detail = detail, Dispatch = dispatch }).ToList();
if (withDispatchList.Count > 0)
{
withDispatchDetailList = withDispatchList.Select(a => a.Detail)
.ToList();
}
if (dispatchList.Count == 0)
{
throw Oops.Oh($"预甩货调度获取失败,无法改配");
}
//如果原调度对应的明细含有本次提交的明细,不允许改配调度
if (withDispatchDetailList.Any(a =>
model.loadDetailIds.Any(b => b == a.PK_ID)))
{
throw Oops.Oh($"预甩货调度获取失败,提交明细已生成调度,无法改配");
}
//需要匹配箱型箱量
var origCtnStat = string.Join(",", withDispatchDetailList
.GroupBy(a => a.CTNALL).OrderBy(a => a.Key)
.Select(a => $"{a.Key}*{a.Sum(b => b.CTNNUM)}").ToArray());
detailList = _taskRollingNominationDetailInfoRepository.AsQueryable()
.Where(a => shipmentList.Contains(a.SHIPMENT) && a.IsDeleted == false && a.NOM_ID == nomId).ToList();
var targetCtnStat = string.Join(",", detailList
.GroupBy(a => a.CTNALL).OrderBy(a => a.Key)
.Select(a => $"{a.Key}*{a.Sum(b => b.CTNNUM)}").ToArray());
//如果箱型箱量不一致不能改配
if (!origCtnStat.Equals(targetCtnStat))
{
throw Oops.Oh($"预甩货调度获取失败,提交明细箱型箱量于被改配调度不一致,无法改配");
}
var origShip = withDispatchDetailList.FirstOrDefault();
var targetShip = detailList.FirstOrDefault();
var origKey = $"{origShip.PLACEOF_RECEIPT}_{origShip.LOADPORT_NAME}_{origShip.DISCHARGEPORT_NAME}_{origShip.PLACEOF_DELIVERY}";
var targeKey = $"{targetShip.PLACEOF_RECEIPT}_{targetShip.LOADPORT_NAME}_{targetShip.DISCHARGEPORT_NAME}_{targetShip.PLACEOF_DELIVERY}";
//收货地、装货港、卸货港、交货地必需一致
if (!origKey.Equals(targeKey))
{
throw Oops.Oh($"预甩货调度获取失败,提交明细收货地、装货港、卸货港、交货地被改配调度不一致,无法改配");
}
//删除原调度
withDispatchList.ForEach(async a =>
{
a.Dispatch.IsDeleted = true;
a.Dispatch.UpdatedTime = nowDate;
a.Dispatch.UpdatedUserId = UserManager.UserId;
a.Dispatch.UpdatedUserName = UserManager.Name;
await _taskRollingNominationDispatchInfoRepository.AsUpdateable(a.Dispatch)
.UpdateColumns(it => new
{
it.IsDeleted,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
}).ExecuteCommandAsync();
});
//写入新调度
detailList.ForEach(a =>
{
TaskRollingNominationDispatchInfo dispatchInfo = new TaskRollingNominationDispatchInfo
{
PK_ID = IDGen.NextID().ToString(),
CreatedTime = nowDate,
UpdatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name,
DETAIL_ID = a.PK_ID,
NOM_ID = a.NOM_ID,
NOM_SHIP_ID = a.NOM_SHIP_ID,
IsDeleted = false,
STATUS = "WAIT",
TASK_ID = nomModel.TASK_ID,
TenantId = UserManager.TENANT_ID,
TenantName = UserManager.TENANT_NAME,
BATCH_ID = batchDict[a.SHIPMENT],
};
_taskRollingNominationDispatchInfoRepository.Insert(dispatchInfo);
});
}
else
{
var withDispatchList =
_taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
.InnerJoin<TaskRollingNominationDetailInfo>((nom, detail) => nom.PK_ID == detail.NOM_ID)
.LeftJoin<TaskRollingNominationDispatchInfo>((nom, detail, dispatch) =>
detail.PK_ID == dispatch.DETAIL_ID && dispatch.IsDeleted == false)
.Where((nom, detail, dispatch) =>
detail.IsDeleted == false
&& detail.NOM_ID == model.nominationId)
.Select((nom, detail, dispatch) =>
new { Nom = nom, Detail = detail, Dispatch = dispatch }).ToList();
if (withDispatchList.Any(p => p.Dispatch != null
&& !string.IsNullOrWhiteSpace(p.Dispatch.PK_ID)))
{
throw Oops.Oh($"预甩货明细已生成调度不能重复");
}
var nomiInfo = withDispatchList.FirstOrDefault().Nom;
var shipmentList = withDispatchList
.Select(a => a.Detail.SHIPMENT)
.Distinct().ToList();
Dictionary<string, string> batchDict = shipmentList.Select(a => new { Key = a, BatchId = IDGen.NextID().ToString() })
.ToDictionary(a => a.Key, b => b.BatchId);
DateTime deadLine = nomiInfo.CONFIRM_DEAD_LINE.Value.AddHours(2);
//开始写入调度
withDispatchList.ForEach(info =>
{
var a = info.Detail;
if (!a.NOM_STATUS_NOTE.Equals("Load", StringComparison.OrdinalIgnoreCase))
{
TaskRollingNominationDispatchInfo dispatchInfo = new TaskRollingNominationDispatchInfo
{
PK_ID = IDGen.NextID().ToString(),
CreatedTime = nowDate,
UpdatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name,
DETAIL_ID = a.PK_ID,
NOM_ID = a.NOM_ID,
NOM_SHIP_ID = a.NOM_SHIP_ID,
IsDeleted = false,
STATUS = RollingNominationDispatchStatusEnum.WAIT.ToString(),
TASK_ID = nomiInfo.TASK_ID,
TenantId = UserManager.TENANT_ID,
TenantName = UserManager.TENANT_NAME,
BATCH_ID = batchDict[a.SHIPMENT],
CONFIRM_DEAD_LINE = deadLine
};
_taskRollingNominationDispatchInfoRepository.Insert(dispatchInfo);
}
});
}
result.succ = true;
result.msg = "成功";
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"生成预甩货调度异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 刷新预甩货对应订舱
/// <summary>
/// 刷新预甩货对应订舱
/// </summary>
/// <param name="nominationId">预甩货主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageRollingNomination/RefreshBookingOrder")]
public async Task<TaskManageOrderResultDto> RefreshBookingOrder(string nominationId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
/*
获取所有当票预甩的所有没有BOOKING_ID的明细记录并用SHIPMENT(提单号),检索订舱数据,能匹配的更新
*/
var list = _taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
.InnerJoin<TaskRollingNominationDetailInfo>((nom, detail) => nom.PK_ID == detail.NOM_ID)
.Where((nom, detail) => nom.PK_ID == nominationId
&& detail.IsDeleted == false && !detail.BOOKING_ID.HasValue)
.Select((nom, detail) => detail).ToList();
if (list.Count > 0)
{
var mblNoArg = list.Select(a=>a.SHIPMENT).Distinct().ToList();
var orderList = _bookingOrderRepository.AsQueryable()
.Where(a => mblNoArg.Contains(a.MBLNO) && !a.ParentId.HasValue && a.IsDeleted == false).ToList();
DateTime nowDate = DateTime.Now;
if (orderList.Count > 0)
{
orderList.ForEach(ord =>
{
var dlist = list.Where(b => b.SHIPMENT.Equals(ord.MBLNO)).ToList();
if (dlist.Count > 0)
{
dlist.ForEach(dt =>
{
dt.BOOKING_ID = ord.Id;
dt.UpdatedTime = nowDate;
dt.UpdatedUserId = UserManager.UserId;
dt.UpdatedUserName = UserManager.Name;
_taskRollingNominationDetailInfoRepository.AsUpdateable(dt)
.UpdateColumns(it => new
{
it.BOOKING_ID,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
}).ExecuteCommand();
});
}
});
}
}
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"刷新预甩货对应订舱异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 查看分享链接
/// <summary>
/// 查看分享链接
/// </summary>
/// <param name="dispatchBatchId">预甩调度批次号</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageRollingNomination/GetUrl")]
public async Task<TaskManageOrderResultDto> GetUrl(string dispatchBatchId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
/*
用预甩调度的dispatchBatchId关联分享表的BUSI_ID获取分享KEY
*/
if (string.IsNullOrWhiteSpace(dispatchBatchId))
throw Oops.Oh($"预甩调度批次号不能为空");
var dispatchInfo = _taskRollingNominationDispatchInfoRepository.AsQueryable()
.First(a => a.BATCH_ID == dispatchBatchId);
if (dispatchInfo == null)
{
throw Oops.Oh($"获取预甩调度信息失败,不存在或已作废");
}
if(string.IsNullOrWhiteSpace(dispatchInfo.SHARE_LINK_KEY))
throw Oops.Oh($"链接访问KEY不存在请生成分享链接");
string[] statusArg = new string[] { RollingNominationDispatchStatusEnum.CANCEL.ToString(),
RollingNominationDispatchStatusEnum.EXPIRE.ToString() };
if (statusArg.Any(a => a.Equals(dispatchInfo.STATUS, StringComparison.OrdinalIgnoreCase)))
throw Oops.Oh($"链接访问KEY状态不可用");
result.succ = true;
result.ext = dispatchInfo.SHARE_LINK_KEY;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 获取Status是load的可配载的列表
/// <summary>
/// 获取Status是load的可配载的列表
/// </summary>
/// <param name="taskPkId">预甩货任务主键</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageRollingNomination/GetLoadStatusDetailList")]
public async Task<TaskManageOrderResultDto> GetLoadStatusDetailList(string taskPkId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var withDispatchList =
_taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
.InnerJoin<TaskRollingNominationDetailInfo>((nom,detail)=> nom.PK_ID == detail.NOM_ID)
.LeftJoin<TaskRollingNominationDispatchInfo>((nom,detail, dispatch) =>
detail.PK_ID == dispatch.DETAIL_ID && dispatch.IsDeleted == false)
.Where((nom,detail, dispatch) =>
nom.TASK_ID == taskPkId && detail.IsDeleted == false && string.IsNullOrWhiteSpace(dispatch.TASK_ID))
.Select((nom, detail, dispatch) => new { Detail = detail}).ToList();
if (withDispatchList.Count > 0)
{
result.ext = withDispatchList.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
}
result.succ = true;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"推送预甩货客户访问链接异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 获取提单号下预甩货的单票明细
/// <summary>
/// 获取提单号下预甩货的单票明细
/// </summary>
/// <param name="nominationId">预甩货主键</param>
/// <param name="shipmentNo">提单号</param>
/// <returns>返回回执</returns>
[HttpGet("/TaskManageRollingNomination/GetPreBillDetailList")]
public async Task<TaskManageOrderResultDto> GetPreBillDetailList([FromQuery] string nominationId, [FromQuery] string shipmentNo)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
var withDispatchList =
_taskRollingNominationInfoRepository.AsQueryable()
.InnerJoin<TaskRollingNominationDetailInfo>((nom, detail) => nom.PK_ID == detail.NOM_ID)
.Where((nom, detail) =>
nom.PK_ID == nominationId && detail.IsDeleted == false && detail.SHIPMENT == shipmentNo)
.Select((nom, detail) => new { Detail = detail }).ToList();
if (withDispatchList.Count > 0)
{
result.ext = withDispatchList.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
}
result.succ = true;
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"获取提单号下预甩货的单票明细异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 保存预甩货明细箱型信息
/// <summary>
/// 保存预甩货明细箱型信息(处理没有给箱型高度或者未能翻译的箱型,进行人工修正)
/// </summary>
/// <param name="model">保存预甩货明细箱型请求</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageRollingNomination/SaveDetailContainer")]
public async Task<TaskManageOrderResultDto> SaveDetailContainer(SaveDetailContainerDto model)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
if (string.IsNullOrWhiteSpace(model.ctnCode))
{
throw Oops.Oh($"请求的箱型代码不能为空");
}
var detailInfo = _taskRollingNominationDetailInfoRepository.AsQueryable()
.First(a => a.PK_ID == model.detailPKId && a.IsDeleted == false);
if (detailInfo == null)
throw Oops.Oh($"预甩货明细主键{model.detailPKId}无法获取业务信息");
var ctnCodeList = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
var ctnCodeModel = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
a.Code.Equals(model.ctnCode, StringComparison.OrdinalIgnoreCase));
if (ctnCodeModel == null)
throw Oops.Oh($"请求的箱型代码基础数据不存在,请修改");
detailInfo.CTNCODE = ctnCodeModel.Code;
detailInfo.CTNALL = ctnCodeModel.Name;
detailInfo.UpdatedTime = DateTime.Now;
detailInfo.UpdatedUserId = UserManager.UserId;
detailInfo.UpdatedUserName = UserManager.Name;
await _taskRollingNominationDetailInfoRepository.AsUpdateable(detailInfo).UpdateColumns(it => new
{
it.CTNCODE,
it.CTNALL,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
}).ExecuteCommandAsync();
result.succ = true;
result.msg = "成功";
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"保存预甩货明细箱型信息异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 生成访问链接
/// <summary>
/// 生成访问链接
/// </summary>
/// <param name="model">创建分享链接请求</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageRollingNomination/GenShareLink")]
public async Task<TaskManageOrderResultDto> GenShareLink(RollingNominationGenShareLinkDto model)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
if (string.IsNullOrWhiteSpace(model.dispatchBatchId))
{
throw Oops.Oh($"预甩调度批次ID不能为空");
}
var list = _taskRollingNominationDispatchInfoRepository.AsQueryable()
.Where(a => a.BATCH_ID == model.dispatchBatchId).ToList();
if(list.Count == 0)
throw Oops.Oh($"预甩调度批次ID无法获取业务信息");
var taskInfo = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == list.FirstOrDefault().TASK_ID);
ShareLinkRequestDto reqDto = new ShareLinkRequestDto {
businessId = model.dispatchBatchId,
businessType = "NOMI_DISPATCH",
expireDate = list.FirstOrDefault().CONFIRM_DEAD_LINE.Value.ToString("yyyy-MM-dd HH:mm:ss"),
isUserFeedBack = true,
taskType = taskInfo.TASK_BASE_TYPE,
isRenew = model.isRenew
};
var service = _namedServiceProvider.GetService(nameof(TaskManageShareLinkService));
result = await service.CreateShareLink(reqDto);
if(result.succ)
{
DateTime nowDate = DateTime.Now;
string shareKey = result.ext.ToString();
list.ForEach(p => {
p.SHARE_LINK_KEY = shareKey;
p.CREATE_SHARE_LINK_DATE = nowDate;
p.UpdatedTime = nowDate;
p.UpdatedUserId = UserManager.UserId;
p.UpdatedUserName = UserManager.Name;
_taskRollingNominationDispatchInfoRepository.AsUpdateable(p)
.UpdateColumns(it => new
{
it.SHARE_LINK_KEY,
it.CREATE_SHARE_LINK_DATE,
it.UpdatedTime,
it.UpdatedUserId,
it.UpdatedUserName
}).ExecuteCommandAsync();
});
}
}
catch(Exception ex)
{
result.succ = false;
result.msg = $"生成访问链接异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 取消访问链接
/// <summary>
/// 取消访问链接
/// </summary>
/// <param name="dispatchBatchId">预甩调度批次ID</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageRollingNomination/CancelShareLink")]
public async Task<TaskManageOrderResultDto> CancelShareLink(string dispatchBatchId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
if (string.IsNullOrWhiteSpace(dispatchBatchId))
{
throw Oops.Oh($"预甩调度批次ID不能为空");
}
var list = _taskRollingNominationDispatchInfoRepository.AsQueryable()
.Where(a => a.BATCH_ID == dispatchBatchId).ToList();
if (list.Count == 0)
throw Oops.Oh($"预甩调度批次ID无法获取业务信息");
var service = _namedServiceProvider.GetService(nameof(TaskManageShareLinkService));
result = await service.CancelShareLink(dispatchBatchId);
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"取消访问链接异常,原因:{ex.Message}";
}
return result;
}
#endregion
#region 获取用户反馈信息
/// <summary>
/// 获取用户反馈信息
/// </summary>
/// <param name="dispatchBatchId">预甩调度批次ID</param>
/// <returns>返回回执</returns>
[HttpPost("/TaskManageRollingNomination/GetUserFeedBack")]
public async Task<TaskManageOrderResultDto> GetUserFeedBack(string dispatchBatchId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
if (string.IsNullOrWhiteSpace(dispatchBatchId))
{
throw Oops.Oh($"预甩调度批次ID不能为空");
}
var list = _taskRollingNominationDispatchInfoRepository.AsQueryable()
.Where(a => a.BATCH_ID == dispatchBatchId).ToList();
if (list.Count == 0)
throw Oops.Oh($"预甩调度批次ID无法获取业务信息");
result.succ = true;
result.ext = new
{
userOpinion = list.FirstOrDefault().USER_OPINION,
userOpinionTxt = list.FirstOrDefault().USER_OPINION_TXT
};
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"获取用户反馈信息异常,原因:{ex.Message}";
}
return result;
}
#endregion
}
}