|
|
using DS.Module.Core;
|
|
|
using DS.Module.Core.Data;
|
|
|
using DS.Module.Core.Helpers;
|
|
|
using DS.Module.SqlSugar;
|
|
|
using DS.Module.UserModule;
|
|
|
using DS.WMS.Core.Code.Entity;
|
|
|
using DS.WMS.Core.Map.Entity;
|
|
|
using DS.WMS.Core.Op.Dtos;
|
|
|
using DS.WMS.Core.Op.Dtos.Cargoo;
|
|
|
using DS.WMS.Core.Op.Entity;
|
|
|
using DS.WMS.Core.Op.Interface;
|
|
|
using DS.WMS.Core.Sys.Interface;
|
|
|
using DS.WMS.Core.Sys.Method;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using Newtonsoft.Json;
|
|
|
using SharpCompress.Common;
|
|
|
using SqlSugar;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
using NLog;
|
|
|
using DS.Module.Core.Constants;
|
|
|
using DS.WMS.Core.Map.Dtos;
|
|
|
using DS.WMS.Core.Map.Interface;
|
|
|
using Org.BouncyCastle.Ocsp;
|
|
|
using DS.WMS.Core.Invoice.Dtos;
|
|
|
using Org.BouncyCastle.Crypto;
|
|
|
using DS.WMS.Core.Info.Interface;
|
|
|
|
|
|
namespace DS.WMS.Core.Op.Method
|
|
|
{
|
|
|
public class CargooService : ICargooService
|
|
|
{
|
|
|
private readonly ISeaExportService _seaExportService;
|
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
private readonly ISqlSugarClient db;
|
|
|
private readonly IUser user;
|
|
|
private readonly ISaasDbService saasService;
|
|
|
private readonly ISeaExportCommonService seaComService;
|
|
|
private readonly IConfigService configService;
|
|
|
private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
|
|
|
private readonly IMappingCarrierService _mappingCarrierService;
|
|
|
private readonly IClientInfoService _clientInfoService;
|
|
|
|
|
|
const string CONST_MAPPING_MODULE = "CARGOO_DATA";
|
|
|
|
|
|
public CargooService(IServiceProvider serviceProvider)
|
|
|
{
|
|
|
_serviceProvider = serviceProvider;
|
|
|
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
|
|
|
user = _serviceProvider.GetRequiredService<IUser>();
|
|
|
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
|
|
|
|
|
|
seaComService = _serviceProvider.GetRequiredService<ISeaExportCommonService>();
|
|
|
configService = _serviceProvider.GetRequiredService<IConfigService>();
|
|
|
_mappingCarrierService = _serviceProvider.GetRequiredService<IMappingCarrierService>();
|
|
|
_clientInfoService = _serviceProvider.GetRequiredService<IClientInfoService>();
|
|
|
}
|
|
|
|
|
|
#region 发送Cargoo
|
|
|
/// <summary>
|
|
|
/// 发送Cargoo
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求详情</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
public async Task<DataResult<CargooShipmentResultDto>> SendCargoo(CargooShipmentReqDto model)
|
|
|
{
|
|
|
Logger.Log(NLog.LogLevel.Info, $"请求Cargoo API推送消息接收请求,{JsonConvert.SerializeObject(model)}");
|
|
|
|
|
|
if (model.bookingId <= 0)
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("订单ID不能为空");
|
|
|
|
|
|
//读取订单详情
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
//任务不考虑OrgId,这里去掉
|
|
|
tenantDb.QueryFilter.Clear<IOrgId>();
|
|
|
|
|
|
var bookingInfo = await tenantDb.Queryable<SeaExport>()
|
|
|
.FirstAsync(a => a.Id == model.bookingId);
|
|
|
|
|
|
if (bookingInfo == null)
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("订单信息获取失败,订单ID错误或数据已作废");
|
|
|
|
|
|
if (bookingInfo.ParentId != null && bookingInfo.ParentId > 0)
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("当前订单不是主单不能发送");
|
|
|
}
|
|
|
|
|
|
if (!(bookingInfo.SourceCode.Equals("FOB-WSL") || CheckContractNo(bookingInfo.ContractNo).GetAwaiter().GetResult().Succeeded))
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("Cargoo只支持业务来源是WSL指定货或合约号符合条件的订单");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(bookingInfo.MBLNO))
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("提单号不能为空");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(bookingInfo.CustomerNo))
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("委托编号不能为空");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(bookingInfo.ContractNo))
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("约号不能为空");
|
|
|
}
|
|
|
|
|
|
if (bookingInfo.LoadPortId <= 0)
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("装货港不能为空");
|
|
|
}
|
|
|
|
|
|
if (bookingInfo.DischargePortId <= 0)
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("卸货港不能为空");
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var ctnList = tenantDb.Queryable<OpCtn>().Where(a => a.BSNO == model.bookingId.ToString()).ToList();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
bool IsWSLFOB = false;
|
|
|
|
|
|
if (bookingInfo.SourceCode.Equals("FOB-WSL"))
|
|
|
IsWSLFOB = true;
|
|
|
|
|
|
//生成报文
|
|
|
var shipDtoRlt = GetCargooShipment(model.cargooStatusEnum, bookingInfo, ctnList, IsWSLFOB).GetAwaiter().GetResult();
|
|
|
|
|
|
if (!shipDtoRlt.Succeeded)
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.Failed($"生成Cargoo报文失败,原因:{shipDtoRlt.Message}");
|
|
|
}
|
|
|
|
|
|
var queryInfo = shipDtoRlt.Data;
|
|
|
|
|
|
//发送报文至API接口
|
|
|
var queryUrl = configService.GetConfig("CargooAPI", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
|
|
|
|
|
|
var cargooKey = configService.GetConfig("CarooAPIKey", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
|
|
|
|
|
|
CargooShipmentResultDto resultInfo = null;
|
|
|
|
|
|
var jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(queryInfo, Formatting.Indented, new JsonSerializerSettings
|
|
|
{
|
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
|
});
|
|
|
|
|
|
//var rlt = RequestHelper.Post(jsonBody, queryUrl);
|
|
|
|
|
|
var rlt = await RequestHelper.PostAsyncWithHeaders(queryUrl, jsonBody, new Dictionary<string, string> { { "Authorization", cargooKey } });
|
|
|
|
|
|
Logger.Log(NLog.LogLevel.Info, $"请求Cargoo API推送消息,{jsonBody}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rlt))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
Logger.Log(NLog.LogLevel.Info, $"请求Cargoo API推送消息结果,{rlt}");
|
|
|
|
|
|
resultInfo = JsonConvert.DeserializeObject<CargooShipmentResultDto>(rlt);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Logger.Log(NLog.LogLevel.Info, $"请求Cargoo API推送消息异常,原因:{ex.Message}");
|
|
|
|
|
|
throw new Exception($"请求Cargoo API推送消息异常,原因:{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (resultInfo != null)
|
|
|
{
|
|
|
if (resultInfo.data.FirstOrDefault().code == 200)
|
|
|
{
|
|
|
// 记录日志
|
|
|
await seaComService.SaveSeaExportLogAsync(new SeaExportSaveLog()
|
|
|
{
|
|
|
OperateType = "Update",
|
|
|
OldOrder = bookingInfo,
|
|
|
NewOrder = bookingInfo,
|
|
|
SourceCode = "SendCargoo",
|
|
|
SourceName = $"发送Cargoo {model.cargooStatusEnum.ToString()}",
|
|
|
}, tenantDb);
|
|
|
|
|
|
return DataResult<CargooShipmentResultDto>.Success("成功", resultInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentResultDto>.FailedData(resultInfo);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Logger.Log(NLog.LogLevel.Info, $"请求Cargoo API推送消息异常 ALL,原因:{ex.Message}");
|
|
|
|
|
|
return DataResult<CargooShipmentResultDto>.Failed($"发送失败,原因:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return DataResult<CargooShipmentResultDto>.Failed("发送失败");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 生成报文
|
|
|
/// <summary>
|
|
|
/// 生成报文
|
|
|
/// </summary>
|
|
|
/// <param name="order">订单详情</param>
|
|
|
/// <param name="ctnList">集装箱列表</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<DataResult<CargooShipmentDto>> GetCargooShipment(CargooStatusEnum cargooStatusEnum, SeaExport order, List<OpCtn> ctnList, bool IsWSLFOB)
|
|
|
{
|
|
|
/*
|
|
|
1、需要确认incoterm的填写
|
|
|
2、FCL_FCL、LCL_FCL
|
|
|
3、
|
|
|
*/
|
|
|
CargooShipmentDto dto = new CargooShipmentDto
|
|
|
{
|
|
|
bookingNumber = order.MBLNO,
|
|
|
blNumber = order.MBLNO,
|
|
|
incoterm = string.Empty,
|
|
|
movementType = string.Empty,
|
|
|
departureFrom = order.LoadPort,
|
|
|
departureTo = order.DischargePort,
|
|
|
carrierCode = order.Carrier,
|
|
|
|
|
|
containerTypes = new List<CargooShipmentContainerTypesDto>(),
|
|
|
items = new List<CargooShipmentItemDto>(),
|
|
|
parties = new List<CargooShipmentPartyDto>()
|
|
|
};
|
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
try
|
|
|
{
|
|
|
//ETD
|
|
|
if (order.ETD.HasValue)
|
|
|
{
|
|
|
if (order.ETD.Value != DateTime.MinValue)
|
|
|
{
|
|
|
dto.etd = order.ETD.Value.ToString("yyyy-MM-dd");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed("ETD格式错误");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed("ETD不能为空");
|
|
|
}
|
|
|
|
|
|
//ETA
|
|
|
if (order.ETA.HasValue)
|
|
|
{
|
|
|
if (order.ETA.Value != DateTime.MinValue)
|
|
|
{
|
|
|
dto.eta = order.ETA.Value.ToString("yyyy-MM-dd");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed("ETA格式错误");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//这里默认对应
|
|
|
if (!string.IsNullOrWhiteSpace(order.MBLFrt))
|
|
|
{
|
|
|
if (order.MBLFrt.IndexOf("COLLECT") >= 0)
|
|
|
{
|
|
|
dto.incoterm = "FOB";
|
|
|
}
|
|
|
else if (order.MBLFrt.IndexOf("PREPAID") >= 0)
|
|
|
{
|
|
|
dto.incoterm = "CIF";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//默认整箱
|
|
|
dto.movementType = "FCL_FCL";
|
|
|
|
|
|
//起始港映射
|
|
|
var mapPortList = new List<MappingPort>();
|
|
|
|
|
|
var portList = new List<CodePort>();
|
|
|
|
|
|
string loadPortCode = string.Empty;
|
|
|
string dischargePortCode = string.Empty;
|
|
|
|
|
|
#region 收货地
|
|
|
//收货地
|
|
|
if (order.ReceiptPlaceId > 0)
|
|
|
{
|
|
|
var portRlt = GetPortEDICode(order.ReceiptPlaceId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.ReceiptPlace, "收货地");
|
|
|
|
|
|
if (portRlt.Succeeded)
|
|
|
{
|
|
|
dto.por = new CargooShipmentPortDto
|
|
|
{
|
|
|
type = "1",
|
|
|
code = portRlt.Data
|
|
|
};
|
|
|
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 装货港
|
|
|
//装货港
|
|
|
if (order.LoadPortId > 0)
|
|
|
{
|
|
|
var portRlt = GetPortEDICode(order.LoadPortId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.ReceiptPlace, "装货港");
|
|
|
|
|
|
if (portRlt.Succeeded)
|
|
|
{
|
|
|
dto.pol = new CargooShipmentPortDto
|
|
|
{
|
|
|
type = "1",
|
|
|
code = portRlt.Data
|
|
|
};
|
|
|
|
|
|
|
|
|
loadPortCode = portRlt.Data;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 卸货港
|
|
|
//卸货港
|
|
|
if (order.DischargePortId > 0)
|
|
|
{
|
|
|
var portRlt = GetPortEDICode(order.DischargePortId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.ReceiptPlace, "卸货港");
|
|
|
|
|
|
if (portRlt.Succeeded)
|
|
|
{
|
|
|
dto.pod = new CargooShipmentPortDto
|
|
|
{
|
|
|
type = "1",
|
|
|
code = portRlt.Data
|
|
|
};
|
|
|
|
|
|
dto.fnd = new CargooShipmentPortDto
|
|
|
{
|
|
|
type = "1",
|
|
|
code = portRlt.Data
|
|
|
};
|
|
|
|
|
|
dischargePortCode = portRlt.Data;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
if (order.CarrierId > 0)
|
|
|
{
|
|
|
var carrierRlt = GetCarrierEDICode(order.CarrierId);
|
|
|
|
|
|
if (carrierRlt.Succeeded)
|
|
|
{
|
|
|
dto.carrierCode = carrierRlt.Data;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
List<CodeCtn> codeCtnList = new List<CodeCtn>();
|
|
|
List<MappingCtn> mapCtnList = new List<MappingCtn>();
|
|
|
|
|
|
List<CodePackage> codePackageList = new List<CodePackage>();
|
|
|
List<MappingPackage> mapPackageList = new List<MappingPackage>();
|
|
|
|
|
|
if (ctnList.Count > 0)
|
|
|
{
|
|
|
dto.containerTypes = ctnList.GroupBy(a => a.CtnCode).Select(a =>
|
|
|
{
|
|
|
return new CargooShipmentContainerTypesDto
|
|
|
{
|
|
|
count = a.Sum(b => b.CtnNum.HasValue ? b.CtnNum.Value : 1),
|
|
|
type = a.Key,
|
|
|
weight = a.Sum(b => b.KGS.HasValue ? b.KGS.Value : 0),
|
|
|
};
|
|
|
}).ToList();
|
|
|
|
|
|
foreach (var currCtn in dto.containerTypes)
|
|
|
{
|
|
|
var mapCtnRlt = GetCtnEDICode(currCtn.type, codeCtnList, mapCtnList, order.CarrierId, CONST_MAPPING_MODULE, "");
|
|
|
|
|
|
if (mapCtnRlt.Succeeded)
|
|
|
{
|
|
|
currCtn.type = mapCtnRlt.Data;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed($"箱型{currCtn.type} 的映射数据代码未找到");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
string kindPkgs = string.Empty;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(order.KindPkgs))
|
|
|
{
|
|
|
long packageId = long.Parse(order.KindPkgs);
|
|
|
|
|
|
var portRlt = GetPackageEDICode(packageId, codePackageList, mapPackageList, order.CarrierId, CONST_MAPPING_MODULE);
|
|
|
|
|
|
if (codePackageList.Any(b => b.Id == packageId))
|
|
|
kindPkgs = codePackageList.FirstOrDefault(b => b.Id == packageId).PackageName;
|
|
|
|
|
|
if (portRlt.Succeeded)
|
|
|
{
|
|
|
kindPkgs = portRlt.Data;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed($"包装{order.KindPkgs}的映射数据代码未找到");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed($"包装不能为空");
|
|
|
}
|
|
|
|
|
|
var shipCargo = new CargooShipmentItemDto
|
|
|
{
|
|
|
commodityCode = order.Description,
|
|
|
articleDescription = order.Description,
|
|
|
|
|
|
packageType = kindPkgs,
|
|
|
};
|
|
|
|
|
|
//件数
|
|
|
if (order.PKGS.HasValue && order.PKGS.Value > 0)
|
|
|
{
|
|
|
shipCargo.pieces = order.PKGS.Value;
|
|
|
}
|
|
|
|
|
|
if (order.PKGS.HasValue && order.PKGS.Value > 0)
|
|
|
{
|
|
|
shipCargo.packages = order.PKGS.Value;
|
|
|
}
|
|
|
|
|
|
//尺码
|
|
|
if (order.CBM.HasValue && order.CBM.Value > 0)
|
|
|
{
|
|
|
shipCargo.volume = order.CBM.Value;
|
|
|
}
|
|
|
|
|
|
//毛重
|
|
|
if (order.KGS.HasValue && order.KGS.Value > 0)
|
|
|
{
|
|
|
shipCargo.grossWeight = order.KGS.Value;
|
|
|
}
|
|
|
|
|
|
dto.items.Add(shipCargo);
|
|
|
|
|
|
dto.transportPlan = new CargooShipmentTransportPlanDto
|
|
|
{
|
|
|
mainCarriage = new List<CargooShipmentMainCarriageDto>()
|
|
|
};
|
|
|
|
|
|
dto.transportPlan.mainCarriage.Add(new CargooShipmentMainCarriageDto
|
|
|
{
|
|
|
from = new CargooShipmentCarriagePortDto {
|
|
|
code = loadPortCode
|
|
|
},
|
|
|
to = new CargooShipmentCarriagePortDto {
|
|
|
code = dischargePortCode
|
|
|
},
|
|
|
etd = order.ETD.Value.ToString("yyyy-MM-dd"),
|
|
|
transportMode = 50,
|
|
|
transportMean = new CargooShipmentTransportMeanDto {
|
|
|
name = order.Vessel
|
|
|
},
|
|
|
conveyanceReferenceNumber = $"{order.InnerVoyno}"
|
|
|
});
|
|
|
|
|
|
if (IsWSLFOB)
|
|
|
{
|
|
|
//var tmpList = tenantDb.Queryable<SeaExportShippingBillTemplate>()
|
|
|
// .WhereIF(order.ShipperId.HasValue && order.ShipperId.Value > 0, x => x.Id == order.ShipperId.Value)
|
|
|
// .WhereIF(order.ConsigneeId.HasValue && order.ConsigneeId.Value > 0, x => x.Id == order.ConsigneeId.Value)
|
|
|
// .WhereIF(order.NotifyPartyId.HasValue && order.NotifyPartyId.Value > 0, x => x.Id == order.NotifyPartyId.Value).ToList();
|
|
|
|
|
|
dto.parties.Add(new CargooShipmentPartyDto
|
|
|
{
|
|
|
type = "CZ",
|
|
|
name = "SUNNINESS LOGISTICS CO.,LTD."
|
|
|
});
|
|
|
|
|
|
//取委托客户下面所有的联系人列表
|
|
|
var djyCustomerInfo = _clientInfoService.GetClientInfoWithContact(new Info.Dtos.QueryClientInfo { ClientId = order.CustomerId, IsController = true }).GetAwaiter().GetResult().Data;
|
|
|
|
|
|
if (djyCustomerInfo == null)
|
|
|
{
|
|
|
Logger.Log(NLog.LogLevel.Info, $"委托单位{order.CustomerName} 获取失败,委托单位不存在或已作废 bookingId={order.Id}");
|
|
|
|
|
|
//委托单位{0} 获取失败,委托单位不存在或已作废
|
|
|
return DataResult<CargooShipmentDto>.Failed($"委托单位{order.CustomerName} 获取失败,委托单位不存在或已作废");
|
|
|
}
|
|
|
|
|
|
if(string.IsNullOrWhiteSpace(djyCustomerInfo.EnFullName))
|
|
|
return DataResult<CargooShipmentDto>.Failed($"委托单位{djyCustomerInfo.ShortName} 未维护客户英文全称");
|
|
|
|
|
|
dto.parties.Add(new CargooShipmentPartyDto
|
|
|
{
|
|
|
type = "CN",
|
|
|
name = djyCustomerInfo.EnFullName,
|
|
|
});
|
|
|
|
|
|
dto.parties.Add(new CargooShipmentPartyDto
|
|
|
{
|
|
|
type = "NI",
|
|
|
name = djyCustomerInfo.EnFullName,
|
|
|
});
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dto.parties.Add(new CargooShipmentPartyDto
|
|
|
{
|
|
|
type = "CZ",
|
|
|
name = "SUNNINESS LOGISTICS CO.,LTD."
|
|
|
});
|
|
|
|
|
|
dto.parties.Add(new CargooShipmentPartyDto
|
|
|
{
|
|
|
type = "NI",
|
|
|
name = "SUNNINESS LOGISTICS CO.,LTD."
|
|
|
});
|
|
|
|
|
|
dto.parties.Add(new CargooShipmentPartyDto
|
|
|
{
|
|
|
type = "CN",
|
|
|
name = "SUNNINESS LOGISTICS CO.,LTD."
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
dto.currentStatus = new CargooShipmentCurrentStatusDto
|
|
|
{
|
|
|
code = (int)cargooStatusEnum,
|
|
|
description = cargooStatusEnum.ToString()
|
|
|
};
|
|
|
|
|
|
dto.integrationId = order.CustomerNo;
|
|
|
dto.contractNumber = order.ContractNo;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
return DataResult<CargooShipmentDto>.Failed($"生成失败,原因:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return DataResult<CargooShipmentDto>.Success(dto);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检索港口的EDI代码
|
|
|
/// <summary>
|
|
|
/// 检索港口的EDI代码
|
|
|
/// </summary>
|
|
|
/// <param name="portId">港口ID</param>
|
|
|
/// <param name="codePortList">港口基础表</param>
|
|
|
/// <param name="mapPortList">港口映射表</param>
|
|
|
/// <param name="carrierId">船公司ID</param>
|
|
|
/// <param name="moduleName">模块代码</param>
|
|
|
/// <param name="portName">港口名称</param>
|
|
|
/// <param name="portCategory">港口分类(装货港、卸货港、交货地等)</param>
|
|
|
/// <param name="isNeedMapping">是否必需用映射</param>
|
|
|
/// <returns></returns>
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
private DataResult<string> GetPortEDICode(long portId, List<CodePort> codePortList, List<MappingPort> mapPortList, long carrierId, string moduleName,
|
|
|
string portName, string portCategory, string needMappingModule = "")
|
|
|
{
|
|
|
//如果历史港口映射有记录直接返回
|
|
|
if (mapPortList.Any(a => a.LinkId == portId))
|
|
|
{
|
|
|
var edi = mapPortList.FirstOrDefault(a => a.LinkId == portId).MapCode;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(edi))
|
|
|
return DataResult<string>.Success(edi);
|
|
|
|
|
|
return DataResult<string>.FailedData(edi);
|
|
|
}
|
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
string MappingModule = CONST_MAPPING_MODULE;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(needMappingModule))
|
|
|
{
|
|
|
MappingModule = needMappingModule;
|
|
|
}
|
|
|
|
|
|
var mapPortInfo = tenantDb.Queryable<MappingPort>()
|
|
|
.First(a => a.Module.Equals(MappingModule, StringComparison.OrdinalIgnoreCase) && a.CarrierId == carrierId && a.LinkId == portId);
|
|
|
|
|
|
if (mapPortInfo != null)
|
|
|
{
|
|
|
mapPortList.Add(mapPortInfo);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(mapPortInfo.MapCode))
|
|
|
return DataResult<string>.Success(mapPortInfo.MapCode);
|
|
|
|
|
|
return DataResult<string>.FailedData(mapPortInfo.MapCode);
|
|
|
}
|
|
|
//else
|
|
|
//{
|
|
|
// if (!string.IsNullOrWhiteSpace(needMappingModule))
|
|
|
// throw new Exception($"{portCategory} {portName} 未配置模块{needMappingModule} 映射");
|
|
|
//}
|
|
|
|
|
|
if (codePortList.Any(a => a.Id == portId))
|
|
|
{
|
|
|
var edi = codePortList.FirstOrDefault(a => a.Id == portId).EdiCode;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(edi))
|
|
|
return DataResult<string>.Success(edi);
|
|
|
|
|
|
return DataResult<string>.FailedData(edi);
|
|
|
}
|
|
|
|
|
|
var loadPortCodeRlt = seaComService.GetPortInfo(portId, tenantDb).GetAwaiter().GetResult();
|
|
|
|
|
|
if (!loadPortCodeRlt.Succeeded)
|
|
|
{
|
|
|
throw new Exception($"{portCategory} {portName}的港口基础代码未找到");
|
|
|
}
|
|
|
|
|
|
codePortList.Add(loadPortCodeRlt.Data);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(loadPortCodeRlt.Data?.EdiCode))
|
|
|
return DataResult<string>.Success(loadPortCodeRlt.Data?.EdiCode);
|
|
|
|
|
|
return DataResult<string>.FailedData(loadPortCodeRlt.Data?.EdiCode);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取船公司映射
|
|
|
/// <summary>
|
|
|
/// 获取船公司映射
|
|
|
/// </summary>
|
|
|
/// <param name="carrierId">船公司ID</param>
|
|
|
/// <returns></returns>
|
|
|
private DataResult<string> GetCarrierEDICode(long carrierId)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
var mapInfo = tenantDb.Queryable<MappingCarrier>()
|
|
|
.First(a => a.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && a.LinkId == carrierId);
|
|
|
|
|
|
if (mapInfo != null)
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(mapInfo.MapCode))
|
|
|
return DataResult<string>.Success(mapInfo.MapCode);
|
|
|
|
|
|
return DataResult<string>.FailedData(mapInfo.MapCode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var carrierRlt = seaComService.GetCarrierInfo(carrierId, tenantDb).GetAwaiter().GetResult();
|
|
|
|
|
|
if(carrierRlt.Succeeded)
|
|
|
{
|
|
|
return DataResult<string>.Success(carrierRlt.Data.EdiCode);
|
|
|
}
|
|
|
|
|
|
return DataResult<string>.FailedData("");
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检索集装箱型EDI代码
|
|
|
/// <summary>
|
|
|
/// 检索集装箱型EDI代码
|
|
|
/// </summary>
|
|
|
/// <param name="ctnCode">集装箱型ID</param>
|
|
|
/// <param name="codeCtnList">集装箱基础表</param>
|
|
|
/// <param name="mapCtnList">集装箱映射表</param>
|
|
|
/// <param name="carrierId">船公司ID</param>
|
|
|
/// <param name="moduleName">模块代码</param>
|
|
|
/// <param name="ctnName">集装箱名称</param>
|
|
|
/// <returns></returns>
|
|
|
private DataResult<string> GetCtnEDICode(string ctnCode, List<CodeCtn> codeCtnList, List<MappingCtn> mapCtnList, long carrierId, string moduleName
|
|
|
, string ctnName)
|
|
|
{
|
|
|
CodeCtn codeCtnInfo = null;
|
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
if (codeCtnList.Any(a => a.EdiCode == ctnCode))
|
|
|
{
|
|
|
codeCtnInfo = codeCtnList.FirstOrDefault(a => a.EdiCode == ctnCode);
|
|
|
}
|
|
|
|
|
|
if (codeCtnInfo == null)
|
|
|
{
|
|
|
codeCtnInfo = tenantDb.Queryable<CodeCtn>().First(a => a.EdiCode == ctnCode && a.Status == StatusEnum.Enable);
|
|
|
|
|
|
if (codeCtnInfo != null)
|
|
|
{
|
|
|
codeCtnList.Add(codeCtnInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new Exception($"集装箱 {ctnName} 基础代码未找到");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//如果历史港口映射有记录直接返回
|
|
|
if (mapCtnList.Any(a => a.LinkId == codeCtnInfo.Id))
|
|
|
{
|
|
|
var edi = mapCtnList.FirstOrDefault(a => a.LinkId == codeCtnInfo.Id).MapCode;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(edi))
|
|
|
return DataResult<string>.Success(edi);
|
|
|
|
|
|
return DataResult<string>.FailedData(edi);
|
|
|
}
|
|
|
|
|
|
MappingCtn mapCtnInfo = null;
|
|
|
|
|
|
mapCtnInfo = tenantDb.Queryable<MappingCtn>()
|
|
|
.First(a => a.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && a.LinkId == codeCtnInfo.Id);
|
|
|
|
|
|
if (mapCtnInfo != null)
|
|
|
{
|
|
|
mapCtnList.Add(mapCtnInfo);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(mapCtnInfo.MapCode))
|
|
|
return DataResult<string>.Success(mapCtnInfo.MapCode);
|
|
|
|
|
|
throw new Exception($"集装箱型 {ctnName}的映射代码未找到");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (codeCtnInfo != null && !string.IsNullOrWhiteSpace(codeCtnInfo.EdiCode))
|
|
|
{
|
|
|
return DataResult<string>.Success(codeCtnInfo.EdiCode);
|
|
|
}
|
|
|
|
|
|
throw new Exception($"集装箱型 {ctnName}基础代码EDI 错误");
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检索包装EDI代码
|
|
|
/// <summary>
|
|
|
/// 检索包装EDI代码
|
|
|
/// </summary>
|
|
|
/// <param name="packageCodeId">包装ID</param>
|
|
|
/// <param name="codePackageList">包装基础表</param>
|
|
|
/// <param name="mapPackageList">包装映射表</param>
|
|
|
/// <param name="carrierId">船公司ID</param>
|
|
|
/// <param name="moduleName">模块代码</param>
|
|
|
/// <param name="packageName">包装名称</param>
|
|
|
/// <returns></returns>
|
|
|
private DataResult<string> GetPackageEDICode(long packageCodeId, List<CodePackage> codePackageList, List<MappingPackage> mapPackageList, long carrierId, string moduleName)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
if (!codePackageList.Any(b => b.Id == packageCodeId))
|
|
|
{
|
|
|
var codePackage = tenantDb.Queryable<CodePackage>().First(a => a.Id == packageCodeId);
|
|
|
|
|
|
if (codePackage != null)
|
|
|
codePackageList.Add(codePackage);
|
|
|
}
|
|
|
|
|
|
//如果历史港口映射有记录直接返回
|
|
|
if (mapPackageList.Any(a => a.LinkId == packageCodeId))
|
|
|
{
|
|
|
var edi = mapPackageList.FirstOrDefault(a => a.LinkId == packageCodeId).MapCode;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(edi))
|
|
|
return DataResult<string>.Success(edi);
|
|
|
|
|
|
//return DataResult<string>.FailedData(edi);
|
|
|
}
|
|
|
|
|
|
//优先判断跟船公司设置包装映射,如果没有取默认映射
|
|
|
var mapPackageInfo = tenantDb.Queryable<MappingPackage>()
|
|
|
.First(a => a.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && a.CarrierId == carrierId && a.LinkId == packageCodeId);
|
|
|
|
|
|
if (mapPackageInfo != null)
|
|
|
{
|
|
|
mapPackageList.Add(mapPackageInfo);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(mapPackageInfo.MapCode))
|
|
|
return DataResult<string>.Success(mapPackageInfo.MapCode);
|
|
|
|
|
|
//return DataResult<string>.FailedData(mapPackageInfo.MapCode);
|
|
|
throw new Exception($"包装的映射代码未找到");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var codePackage = codePackageList.FirstOrDefault(b => b.Id == packageCodeId);
|
|
|
|
|
|
if (codePackage != null && !string.IsNullOrWhiteSpace(codePackage.EdiCode))
|
|
|
{
|
|
|
return DataResult<string>.Success(codePackage.EdiCode);
|
|
|
}
|
|
|
|
|
|
throw new Exception($"包装的基础信息EDI代码未找到");
|
|
|
}
|
|
|
|
|
|
//else
|
|
|
//{
|
|
|
//
|
|
|
//}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 发送Cargoo前验证
|
|
|
/// <summary>
|
|
|
/// 发送Cargoo前验证
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求详情</param>
|
|
|
/// <returns>succeeded-校验通过</returns>
|
|
|
public async Task<DataResult<string>> BeforeSendCargooCheck(CargooShipmentReqDto model)
|
|
|
{
|
|
|
//读取订单详情
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
//任务不考虑OrgId,这里去掉
|
|
|
tenantDb.QueryFilter.Clear<IOrgId>();
|
|
|
|
|
|
var bookingInfo = await tenantDb.Queryable<SeaExport>()
|
|
|
.FirstAsync(a => a.Id == model.bookingId);
|
|
|
|
|
|
if (bookingInfo == null)
|
|
|
return DataResult<string>.Failed("订单信息获取失败,订单ID错误或数据已作废");
|
|
|
|
|
|
if (bookingInfo.ParentId != null && bookingInfo.ParentId > 0)
|
|
|
{
|
|
|
return DataResult<string>.Failed("当前订单不是主单不能发送");
|
|
|
}
|
|
|
|
|
|
if (!(bookingInfo.SourceCode.Equals("FOB-WSL") || CheckContractNo(bookingInfo.ContractNo).GetAwaiter().GetResult().Succeeded))
|
|
|
{
|
|
|
return DataResult<string>.Failed("Cargoo只支持业务来源是WSL指定货或合约号符合条件的订单");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(bookingInfo.MBLNO))
|
|
|
{
|
|
|
return DataResult<string>.Failed("提单号不能为空");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(bookingInfo.CustomerNo))
|
|
|
{
|
|
|
return DataResult<string>.Failed("委托编号不能为空");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(bookingInfo.ContractNo))
|
|
|
{
|
|
|
return DataResult<string>.Failed("约号不能为空");
|
|
|
}
|
|
|
|
|
|
if (bookingInfo.LoadPortId <= 0)
|
|
|
{
|
|
|
return DataResult<string>.Failed("装货港不能为空");
|
|
|
}
|
|
|
|
|
|
if (bookingInfo.DischargePortId <= 0)
|
|
|
{
|
|
|
return DataResult<string>.Failed("卸货港不能为空");
|
|
|
}
|
|
|
|
|
|
return DataResult<string>.Success("校验通过");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检查合约号是否符合Cargoo要求
|
|
|
/// <summary>
|
|
|
/// 检查合约号是否符合Cargoo要求
|
|
|
/// </summary>
|
|
|
/// <param name="contractNo">合约号</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<DataResult<string>> CheckContractNo(string contractNo)
|
|
|
{
|
|
|
var carooAPIContractParty = configService.GetConfig("CarooAPIContractParty", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
|
|
|
|
|
|
if(string.IsNullOrWhiteSpace(contractNo))
|
|
|
return DataResult<string>.Failed("合约号不能为空");
|
|
|
|
|
|
//读取订单详情
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
//任务不考虑OrgId,这里去掉
|
|
|
tenantDb.QueryFilter.Clear<IOrgId>();
|
|
|
|
|
|
var model = await tenantDb.Queryable<BookingContractNoManage>().FirstAsync(t => t.ContractNo.Equals(contractNo,StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if(model == null)
|
|
|
return DataResult<string>.Failed($"合约号:{contractNo} 获取失败");
|
|
|
|
|
|
if(string.IsNullOrWhiteSpace(model.ContractPartyCode))
|
|
|
return DataResult<string>.Failed($"合约号:{contractNo} 获取合约方公司全称失败");
|
|
|
|
|
|
if (!model.ContractPartyCode.Equals(carooAPIContractParty))
|
|
|
{
|
|
|
return DataResult<string>.Failed($"合约号合约方公司全称{contractNo} 合约方公司全称:{model.ContractPartyCode} 不符合Cargoo发送");
|
|
|
}
|
|
|
|
|
|
return DataResult<string>.Success("合约号符合Cargoo");
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|