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.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.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.Logging;
using Newtonsoft.Json;
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 IBookingSlotService bookingSlotService;
private readonly IOpFileService opFileService;
public TaskManageBCService(IUser user,
ILogger logger,
ISaasDbService saasDbService,
IServiceProvider serviceProvider,
IWebHostEnvironment environment,
IConfigService configService,
IClientInfoService clientInfoService,
IMappingCarrierService mappingCarrierService,
IOpFileService opFileService)
: base(user, logger, saasDbService, serviceProvider, environment)
{
this.configService = configService;
this.clientInfoService = clientInfoService;
this.mappingCarrierService = mappingCarrierService;
this.opFileService = opFileService;
}
///
/// 通过任务信息(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($"生成舱位失败,舱位已存在");
}
//这里增加委托单位联系人的校验,重新从后台拉取了委托单位相关联系人,如果比对不一致跳出异常终止执行
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.CustomerContactId);
if (djyCustomerContactMan == null)
{
logger.LogInformation($"委托单位{model.CustomerName} 联系人 {contact.Name}获取失败,联系人不存在或已作废 SlotId={model.SlotId.Value}");
//委托单位 {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)));
}
}
//触发生成舱位
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;
//推送订舱订单
var bookingOrderId = await bookingSlotService.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.Detail(bookingSlot.Id)).Data;
BookingSlotBaseWithCtnDto baseInfo = slotInfo.Adapt();
baseInfo.Id = bookingSlot.Id;
baseInfo.CtnList = slotInfo.CtnList.Adapt>();
slots.Add(baseInfo);
//对应订舱和舱位关系
//var allocRlt = await bookingSlotService.ImportSlots(slots, bookingOrderId, false);
//_logger.LogInformation($"生成订舱和舱位关系完成,allocRlt={JSON.Serialize(allocRlt)} taskid={bcOrder.TASK_ID}");
//if (!allocRlt.isSuccess)
//{
// throw Oops.Oh($"生成订舱和舱位关系失败");
//}
//var bcEntity = _taskBCInfoRepository.AsQueryable().First(a => a.PK_ID == bcOrder.PK_ID);
//if (bcEntity == null)
//{
// throw Oops.Oh($"未获取有效任务BC失败,更新失败");
//}
//bcEntity.BOOKING_ORDER_ID = bookingOrderId;
//bcEntity.BOOKING_SLOT_ID = bookingSlotId;
//bcEntity.UpdatedTime = DateTime.Now;
//bcEntity.UpdatedUserId = UserManager.UserId;
//bcEntity.UpdatedUserName = UserManager.Name;
////更新任务BC
//await _taskBCInfoRepository.AsUpdateable(bcEntity).UpdateColumns(it => new
//{
// it.BOOKING_ORDER_ID,
// it.BOOKING_SLOT_ID,
// it.UpdatedTime,
// it.UpdatedUserId,
// it.UpdatedUserName
//}).ExecuteCommandAsync();
//var taskEntity = _taskBaseRepository.AsQueryable().First(u => u.PK_ID == bcEntity.TASK_ID);
//if (taskEntity == null)
//{
// throw Oops.Oh($"未获取有效任务记录,更新失败");
//}
//#region 更新任务
////如果是公共任务,需要变成个人任务 RealUserId = 当前操作人
//if (taskEntity.IS_PUBLIC == 1)
//{
// taskEntity.IS_PUBLIC = 0;
// taskEntity.RealUserId = UserManager.UserId;
// taskEntity.RealUserName = UserManager.Name;
// taskEntity.UpdatedTime = DateTime.Now;
// taskEntity.UpdatedUserId = UserManager.UserId;
// taskEntity.UpdatedUserName = UserManager.Name;
// taskEntity.IS_COMPLETE = 1;
// taskEntity.COMPLETE_DATE = DateTime.Now;
// taskEntity.COMPLETE_DEAL = "MANUAL";
// taskEntity.COMPLETE_DEAL = "手工";
// await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
// {
// it.IS_PUBLIC,
// it.UpdatedTime,
// it.UpdatedUserId,
// it.UpdatedUserName,
// it.RealUserId,
// it.RealUserName,
// it.IS_COMPLETE,
// it.COMPLETE_DATE,
// it.COMPLETE_DEAL,
// it.COMPLETE_DEAL_NAME
// }).ExecuteCommandAsync();
//}
//else
//{
// taskEntity.UpdatedTime = DateTime.Now;
// taskEntity.UpdatedUserId = UserManager.UserId;
// taskEntity.UpdatedUserName = UserManager.Name;
// taskEntity.IS_COMPLETE = 1;
// taskEntity.COMPLETE_DATE = DateTime.Now;
// taskEntity.COMPLETE_DEAL = "MANUAL";
// taskEntity.COMPLETE_DEAL = "手工";
// await _taskBaseRepository.AsUpdateable(taskEntity).UpdateColumns(it => new
// {
// it.UpdatedTime,
// it.UpdatedUserId,
// it.UpdatedUserName,
// 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
}
return DataResult.Success(result);
}
catch (Exception ex)
{
result.succ = false;
result.msg = $"生成订舱或舱位失败,原因:{ex.Message}";
return DataResult.FailedData(result);
}
}
///
/// 通过任务主键获取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 = _cache.GetAllCodeCtn().GetAwaiter().GetResult().ToList();
if (taskBCCtnList.Count > 0)
{
taskBCCtnList.ForEach(t =>
{
//var ctnCode = ctnCodeList.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a.Name) &&
//a.Name.Equals(t.CTNALL, StringComparison.OrdinalIgnoreCase));
BookingSlotCtnSaveInput ctn = new BookingSlotCtnSaveInput
{
//CTNCODE = ctnCode?.Code,
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.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
//public virtual async Task<(bool canCompelete, string? msg)> CompleteAsync(long taskId)
//{
// return (true, null);
//}
}
}