|
|
using Amazon.Runtime.Internal.Util;
|
|
|
using AngleSharp.Dom;
|
|
|
using DS.Module.Core;
|
|
|
using DS.Module.Core.Data;
|
|
|
using DS.Module.Core.Extensions;
|
|
|
using DS.Module.Core.Helpers;
|
|
|
using DS.Module.SqlSugar;
|
|
|
using DS.Module.UserModule;
|
|
|
using DS.WMS.Core.Code.Entity;
|
|
|
using DS.WMS.Core.Fee.Entity;
|
|
|
using DS.WMS.Core.Info.Entity;
|
|
|
using DS.WMS.Core.Map.Entity;
|
|
|
using DS.WMS.Core.Op.Dtos;
|
|
|
using DS.WMS.Core.Op.Entity;
|
|
|
using DS.WMS.Core.Op.Interface;
|
|
|
using DS.WMS.Core.Sys.Entity;
|
|
|
using DS.WMS.Core.Sys.Interface;
|
|
|
using LanguageExt;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using Newtonsoft.Json;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using NLog;
|
|
|
using SqlSugar;
|
|
|
using System.Collections.Specialized;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using Logger = NLog.Logger;
|
|
|
using NPOI.HSSF.UserModel;
|
|
|
using NPOI.SS.UserModel;
|
|
|
using Org.BouncyCastle.Ocsp;
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using DS.WMS.Core.Op.EDI;
|
|
|
using DS.Module.PrintModule;
|
|
|
|
|
|
namespace DS.WMS.Core.Op.Method;
|
|
|
|
|
|
public class SeaExportService : ISeaExportService
|
|
|
{
|
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
private readonly ISqlSugarClient db;
|
|
|
private readonly IUser user;
|
|
|
private readonly ISaasDbService saasService;
|
|
|
private readonly ICommonService commonService;
|
|
|
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
|
|
private readonly ISeaExportCommonService seaComService;
|
|
|
private readonly IWebHostEnvironment _environment;
|
|
|
//private readonly IPrintService _printService;
|
|
|
|
|
|
const string CONST_MAPPING_MODULE = "BOOK_OR_CLOSING";
|
|
|
const string CONST_MAPPING_MODULE_ROUTE = "BOOK_OR_CLOSING_RT";
|
|
|
const string CONST_MAPPING_MODULE_VOLTA = "BOOK_CLOSING_VOLTA";
|
|
|
const string CONST_MAPPING_MODULE_INTTRA = "INTTRA_EDI";
|
|
|
|
|
|
private const string PrintRecentListTypeKey = "booking_print_recent_list";
|
|
|
|
|
|
const string CONST_TSL_EDI_URL = "tsl_edi_declare_url";
|
|
|
const string CONST_TSL_TYPE_CODE = "TslWeb";
|
|
|
const string CONST_ONE_SOFILE_CATE_CODE = "one_so_file_template";
|
|
|
const string PRINT_DATASOURCE_KEY = "booking_order";
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="serviceProvider"></param>
|
|
|
public SeaExportService(IServiceProvider serviceProvider)
|
|
|
{
|
|
|
_serviceProvider = serviceProvider;
|
|
|
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
|
|
|
user = _serviceProvider.GetRequiredService<IUser>();
|
|
|
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
|
|
|
commonService = _serviceProvider.GetRequiredService<ICommonService>();
|
|
|
seaComService = _serviceProvider.GetRequiredService<ISeaExportCommonService>();
|
|
|
_environment = _serviceProvider.GetRequiredService<IWebHostEnvironment>();
|
|
|
//_printService = _serviceProvider.GetRequiredService<IPrintService>();
|
|
|
|
|
|
#region 设置对象映射
|
|
|
TypeAdapterConfig<SeaExportEdi, SeaExportEDIBaseModel>
|
|
|
.NewConfig()
|
|
|
.Map(dto => dto.WEITUO, poco => poco.CustomerName)
|
|
|
.Map(dto => dto.OpEName, poco => poco.OpEName)
|
|
|
.Map(dto => dto.OpTel, poco => poco.OpTel)
|
|
|
.Map(dto => dto.OpEmail, poco => poco.OpEmail)
|
|
|
.Map(dto => dto.EDIATTN, poco => poco.EDIAttn)
|
|
|
.Map(dto => dto.EDIATTNTEL, poco => poco.EDIAttnTel)
|
|
|
.Map(dto => dto.EDIATTNEMAIL, poco => poco.EDIAttnMail)
|
|
|
.Map(dto => dto.AMSCONSIGNEE, poco => poco.AMSConsignee)
|
|
|
.Map(dto => dto.AMSNOTIFYPARTY, poco => poco.AMSNotifyParty)
|
|
|
.Map(dto => dto.MasterBOLIndicator, poco => poco.MasterBolIndicator)
|
|
|
.Map(dto => dto.KINGTAREWEIGHT, poco => poco.KingTareweight)
|
|
|
.Map(dto => dto.ConsigneeEdiCode, poco => poco.ConsigneeEdiCode)
|
|
|
.Map(dto => dto.ShipperEdiCode, poco => poco.ShipperEdiCode)
|
|
|
.Map(dto => dto.SalesRepCode, poco => poco.SalerCode)
|
|
|
.Map(dto => dto.ACIHBL, poco => poco.ACIHBL)
|
|
|
.Map(dto => dto.S0CC0C, poco => poco.S0CC0C)
|
|
|
.Map(dto => dto.cKHI, poco => poco.CKHI)
|
|
|
.Map(dto => dto.cNCM, poco => poco.CNCM)
|
|
|
.Map(dto => dto.wNCM, poco => poco.WNCM)
|
|
|
.Map(dto => dto.CNPTNo, poco => poco.CNPTNo)
|
|
|
.Map(dto => dto.ORDERREMARK, poco => poco.OrderRemark)
|
|
|
//.Map(dto => dto.ERNCODE, poco => poco.)
|
|
|
//.Map(dto => dto.TACCODE, poco => poco.)
|
|
|
//.Map(dto => dto.VAECODE, poco => poco.)
|
|
|
//.Map(dto => dto.FECCODE, poco => poco.)
|
|
|
;
|
|
|
|
|
|
TypeAdapterConfig<SeaExport, SeaExportEDIBaseModel>
|
|
|
.NewConfig()
|
|
|
.Map(dto => dto.ORDERNO, poco => poco.OrderNo)
|
|
|
.Map(dto => dto.YARD, poco => poco.Yard)
|
|
|
.Map(dto => dto.MBLNO, poco => poco.MBLNO)
|
|
|
.Map(dto => dto.BLFRT, poco => poco.MBLFrt)
|
|
|
.Map(dto => dto.VESSEL, poco => poco.Vessel)
|
|
|
.Map(dto => dto.VOYNO, poco => poco.Voyno)
|
|
|
.Map(dto => dto.NVOYNO, poco => poco.InnerVoyno)
|
|
|
.Map(dto => dto.ETD, poco => poco.ETD)
|
|
|
.Map(dto => dto.ETA, poco => poco.ETA)
|
|
|
.Map(dto => dto.CLOSINGDATE, poco => poco.ClosingDate)
|
|
|
.Map(dto => dto.EDIREMARK, poco => poco.EdiRemark)
|
|
|
//.Map(dto => dto.SIREMARK, poco => poco.)
|
|
|
//.Map(dto => dto.BYCOUNTRY, poco => poco.)
|
|
|
.Map(dto => dto.CARRIER, poco => poco.Carrier)
|
|
|
.Map(dto => dto.CARRIERID, poco => poco.Carrier)
|
|
|
.Map(dto => dto.SHIPPER, poco => poco.Shipper)
|
|
|
.Map(dto => dto.CONSIGNEE, poco => poco.Consignee)
|
|
|
.Map(dto => dto.NOTIFYPARTY, poco => poco.NotifyParty)
|
|
|
.Map(dto => dto.NOTIFYPARTY2, poco => poco.SecondNotifyParty)
|
|
|
.Map(dto => dto.HSCODE, poco => poco.HSCode)
|
|
|
.Map(dto => dto.GOODSNAME, poco => poco.GoodsName)
|
|
|
.Map(dto => dto.MARKS, poco => poco.Marks)
|
|
|
.Map(dto => dto.PLACERECEIPTID, poco => poco.ReceiptPlace)
|
|
|
.Map(dto => dto.PLACERECEIPT, poco => poco.ReceiptPlace)
|
|
|
.Map(dto => dto.PORTLOADID, poco => poco.LoadPort)
|
|
|
.Map(dto => dto.PORTLOAD, poco => poco.LoadPort)
|
|
|
.Map(dto => dto.PORTDISCHARGEID, poco => poco.DischargePort)
|
|
|
.Map(dto => dto.PORTDISCHARGE, poco => poco.DischargePort)
|
|
|
.Map(dto => dto.TRANSPORTID, poco => poco.TransportCode)
|
|
|
.Map(dto => dto.TRANSPORT, poco => poco.Transport)
|
|
|
.Map(dto => dto.PLACEDELIVERYID, poco => poco.DeliveryPlace)
|
|
|
.Map(dto => dto.PLACEDELIVERY, poco => poco.DeliveryPlace)
|
|
|
.Map(dto => dto.DESTINATIONID, poco => poco.Destination)
|
|
|
.Map(dto => dto.DESTINATION, poco => poco.Destination)
|
|
|
.Map(dto => dto.PKGS, poco => poco.PKGS)
|
|
|
.Map(dto => dto.KINDPKGS, poco => poco.KindPkgs)
|
|
|
.Map(dto => dto.CBM, poco => poco.CBM)
|
|
|
.Map(dto => dto.CARGOID, poco => poco.CargoId)
|
|
|
.Map(dto => dto.DCLASS, poco => poco.DangerClass)
|
|
|
.Map(dto => dto.DUNNO, poco => poco.DangerNo)
|
|
|
.Map(dto => dto.DPAGE, poco => poco.DangerPage)
|
|
|
.Map(dto => dto.DLABEL, poco => poco.DangerLabel)
|
|
|
.Map(dto => dto.TEMPSET, poco => poco.TemperatureSet)
|
|
|
.Map(dto => dto.TEMPMIN, poco => poco.TemperatureMin)
|
|
|
.Map(dto => dto.TEMPMAX, poco => poco.TemperatureMax)
|
|
|
.Map(dto => dto.REEFERF, poco => poco.ReeferQuantity)
|
|
|
.Map(dto => dto.HUMIDITY, poco => poco.Humidity)
|
|
|
.Map(dto => dto.PREPARDAT, poco => poco.PrepareAt)
|
|
|
.Map(dto => dto.PREPARDATID, poco => poco.PrepareAt)
|
|
|
.Map(dto => dto.PAYABLEAT, poco => poco.PayableAt)
|
|
|
.Map(dto => dto.PAYABLEATID, poco => poco.PayableAt)
|
|
|
.Map(dto => dto.NOBILL, poco => poco.NoBill)
|
|
|
.Map(dto => dto.ISSUEPLACE, poco => poco.IssuePlace)
|
|
|
.Map(dto => dto.ISSUEDATE, poco => poco.IssueDate)
|
|
|
.Map(dto => dto.ISSUEPLACEID, poco => poco.IssuePlace)
|
|
|
.Map(dto => dto.SERVICE, poco => poco.Service)
|
|
|
.Map(dto => dto.CONTRACTNO, poco => poco.ContractNo)
|
|
|
.Map(dto => dto.SERVICECONTRACTNO, poco => poco.ServiceContractNo)
|
|
|
//.Map(dto => dto.CONSIGNEEPOSTCODE, poco => poco.)
|
|
|
//.Map(dto => dto.CONSIGNEECOUNTRY, poco => poco.)
|
|
|
//.Map(dto => dto.CONSIGNEETAXNO, poco => poco.)
|
|
|
//.Map(dto => dto.NOTIFYPARTYPOSTCODE, poco => poco.)
|
|
|
//.Map(dto => dto.NOTIFYPARTYCOUNTRY, poco => poco.)
|
|
|
//.Map(dto => dto.NOTIFYPARTYTAXNO, poco => poco.)
|
|
|
//.Map(dto => dto.CONSIGNEEDOORADDR, poco => poco.)
|
|
|
//.Map(dto => dto.SHIPPERDOORADDR, poco => poco.)
|
|
|
//.Map(dto => dto.SCACCODE, poco => poco.)
|
|
|
//.Map(dto => dto.ITNCODE, poco => poco.)
|
|
|
//.Map(dto => dto.FREIGHTPAYER, poco => poco.)
|
|
|
//.Map(dto => dto.AMSCODE, poco => poco.)
|
|
|
.Map(dto => dto.ISCONTAINERSOC, poco => poco.IsContainerSoc)
|
|
|
//.Map(dto => dto.GOODSCODE, poco => poco.GoodsName)
|
|
|
//.Map(dto => dto.SERVICEEDICODE, poco => poco.)
|
|
|
|
|
|
;
|
|
|
|
|
|
TypeAdapterConfig<OpCtn, SeaExportCtnEDIBaseModel>
|
|
|
.NewConfig()
|
|
|
.Map(dto => dto.CNTRNO, poco => poco.CntrNo)
|
|
|
.Map(dto => dto.TEU, poco => poco.TEU)
|
|
|
.Map(dto => dto.CTNNUM, poco => poco.CtnNum)
|
|
|
.Map(dto => dto.CTNSTATUS, poco => poco.CtnStatus)
|
|
|
.Map(dto => dto.SEALNO, poco => poco.SealNo)
|
|
|
.Map(dto => dto.PKGS, poco => poco.PKGS)
|
|
|
.Map(dto => dto.KINDPKGS, poco => poco.KindPkgs)
|
|
|
.Map(dto => dto.KGS, poco => poco.KGS)
|
|
|
.Map(dto => dto.CBM, poco => poco.CBM)
|
|
|
.Map(dto => dto.TAREWEIGHT, poco => poco.TareWeight)
|
|
|
.Map(dto => dto.WEIGHKGS, poco => poco.WeightKGS)
|
|
|
.Map(dto => dto.WEIGHTYPE, poco => poco.WeightType)
|
|
|
.Map(dto => dto.WEIGHSIGN, poco => poco.WeightSign)
|
|
|
;
|
|
|
|
|
|
TypeAdapterConfig<OpCtnDetail, SeaExportCtnDetailEDIBaseModel>
|
|
|
.NewConfig()
|
|
|
.Map(dto => dto.HSCODE, poco => poco.HSCode)
|
|
|
.Map(dto => dto.MARKS, poco => poco.Marks)
|
|
|
.Map(dto => dto.DESCRIPTION, poco => poco.Description)
|
|
|
.Map(dto => dto.PKGS, poco => poco.PKGS)
|
|
|
.Map(dto => dto.KINDPKGS, poco => poco.KindPkgs)
|
|
|
.Map(dto => dto.KGS, poco => poco.KGS)
|
|
|
.Map(dto => dto.CBM, poco => poco.CBM);
|
|
|
//.IgnoreNonMapped(true);//只映射Map指定的属性,其他属性都排除;
|
|
|
#endregion 设置对象映射
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 列表
|
|
|
/// </summary>
|
|
|
/// <param name="request"></param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult<List<SeaExportRes>> GetListByPage(PageRequest request)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
//序列化查询条件
|
|
|
var whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition);
|
|
|
var data = tenantDb.Queryable<SeaExport>()
|
|
|
.Where(whereList)
|
|
|
.Select<SeaExportRes>()
|
|
|
.Mapper(it =>
|
|
|
{
|
|
|
it.SourceDetailName = tenantDb.Queryable<CodeSourceDetail>().Where(x => x.Id == it.SourceDetailId).Select(n => n.DetailName).First();
|
|
|
}
|
|
|
).ToQueryPage(request.PageCondition);
|
|
|
return data;
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 编辑
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult EditSeaExport(SeaExportReq req)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
if (req.Id == 0)
|
|
|
{
|
|
|
if (req.BLType != "拼箱分票" && tenantDb.Queryable<SeaExport>().Where(x => x.MBLNO == req.MBLNO.Trim()).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息主提单号已存在!", MultiLanguageConst.SeaExportMBLNOExist);
|
|
|
}
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => x.HBLNO == req.HBLNO.Trim()).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息分提单号已存在!", MultiLanguageConst.SeaExportHBLNOExist);
|
|
|
}
|
|
|
//TODO 会计期间不允许小于已结转期间
|
|
|
if (req.CloseDocDate.IsNotNull() && req.CloseDocDate < req.ETD)
|
|
|
{
|
|
|
return DataResult.Failed("截单日期不允许小于开船日期!", MultiLanguageConst.SeaExportCloseDocDateLimit);
|
|
|
}
|
|
|
if (req.ClosingDate.IsNotNull() && req.ClosingDate < req.ETD)
|
|
|
{
|
|
|
return DataResult.Failed("截港日期不允许小于开船日期!", MultiLanguageConst.SeaExportCloseDateLimit);
|
|
|
}
|
|
|
var sequence = commonService.GetSequenceNext<SeaExport>();
|
|
|
if (!sequence.Succeeded)
|
|
|
{
|
|
|
return DataResult.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
|
|
|
}
|
|
|
var data = req.Adapt<SeaExport>();
|
|
|
data.CustomerNo = sequence.Data;
|
|
|
|
|
|
var entity = tenantDb.Insertable(data).ExecuteReturnEntity();
|
|
|
|
|
|
if (req.CtnInfo.Count > 0)
|
|
|
{
|
|
|
|
|
|
foreach (var item in req.CtnInfo)
|
|
|
{
|
|
|
var ctn = item.Adapt<OpCtn>();
|
|
|
ctn.BSNO = entity.Id.ToString();
|
|
|
tenantDb.Insertable(ctn).ExecuteCommand();
|
|
|
}
|
|
|
}
|
|
|
if (req.EdiInfo.IsNotNull())
|
|
|
{
|
|
|
var edi = req.EdiInfo.Adapt<SeaExportEdi>();
|
|
|
edi.BusinessId = entity.Id;
|
|
|
tenantDb.Insertable(edi).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
return DataResult.Successed("添加成功!", entity.Id, MultiLanguageConst.DataCreateSuccess);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == req.Id).First();
|
|
|
|
|
|
|
|
|
if ((bool)info.IsBusinessLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息业务已锁定!", MultiLanguageConst.SeaExportBusinessLock);
|
|
|
}
|
|
|
info = req.Adapt(info);
|
|
|
//TODO 会计期间不允许小于已结转期间
|
|
|
if (info.CloseDocDate.IsNotNull() && info.CloseDocDate < info.ETD)
|
|
|
{
|
|
|
return DataResult.Failed("截单日期不允许小于开船日期!", MultiLanguageConst.SeaExportCloseDocDateLimit);
|
|
|
}
|
|
|
if (info.ClosingDate.IsNotNull() && info.ClosingDate < info.ETD)
|
|
|
{
|
|
|
return DataResult.Failed("截港日期不允许小于开船日期!", MultiLanguageConst.SeaExportCloseDateLimit);
|
|
|
}
|
|
|
tenantDb.Updateable(info).IgnoreColumns(ignoreAllNullColumns: true).EnableDiffLogEvent().ExecuteCommand();
|
|
|
|
|
|
|
|
|
if (req.CtnInfo.Count > 0)
|
|
|
{
|
|
|
var ctnList = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == req.Id.ToString()).ToList();
|
|
|
foreach (var item in req.CtnInfo)
|
|
|
{
|
|
|
if (item.Id == 0)
|
|
|
{
|
|
|
var ctn = item.Adapt<OpCtn>();
|
|
|
ctn.BSNO = info.Id.ToString();
|
|
|
tenantDb.Insertable(ctn).ExecuteCommand();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var ctn = ctnList.First(x => x.Id == item.Id);
|
|
|
ctn = item.Adapt(ctn);
|
|
|
tenantDb.Updateable(ctn).ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
if (req.EdiInfo.IsNotNull())
|
|
|
{
|
|
|
var edi = tenantDb.Queryable<SeaExportEdi>().Where(x => x.BusinessId == req.Id).ToList();
|
|
|
var ediInfo = req.EdiInfo.Adapt(edi);
|
|
|
tenantDb.Updateable(ediInfo).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 详情
|
|
|
/// </summary>
|
|
|
/// <param name="id"></param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult<SeaExportRes> GetSeaExportInfo(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var data = tenantDb.Queryable<SeaExport>()
|
|
|
.Where(a => a.Id == long.Parse(id))
|
|
|
.Select<SeaExportRes>()
|
|
|
.Mapper(it =>
|
|
|
{
|
|
|
it.EdiInfo = tenantDb.Queryable<SeaExportEdi>().Where(x => x.BusinessId == it.Id).Select<SeaExportEdiRes>().First();
|
|
|
}
|
|
|
)
|
|
|
.First();
|
|
|
return DataResult<SeaExportRes>.Success(data, MultiLanguageConst.DataQuerySuccess);
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 批量更新
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportBatchEdit(SeaExportBatchEditReq req)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
if (req.Ids.Count == 0)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口批量编辑未勾选!", MultiLanguageConst.SeaExportBatchEditNoSelect);
|
|
|
}
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => !req.Ids.Contains(x.Id)).Any().IsNull())
|
|
|
{
|
|
|
return DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist);
|
|
|
}
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id) && x.IsBusinessLocking == true).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息业务已锁定!", MultiLanguageConst.SeaExportBusinessLock);
|
|
|
}
|
|
|
|
|
|
if (req.AccountDate.IsNotNull())
|
|
|
{
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id) && x.IsFeeLocking == true).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息费用已锁定!", MultiLanguageConst.SeaExportFeeLock);
|
|
|
}
|
|
|
}
|
|
|
var orderList = tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id)).ToList();
|
|
|
|
|
|
var dic = req.GetPropertiesArray();
|
|
|
|
|
|
foreach (var item in orderList)
|
|
|
{
|
|
|
var info = req.Adapt(item);
|
|
|
tenantDb.Updateable(info).UpdateColumns(dic).EnableDiffLogEvent().ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 业务单据单票复制
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportCopy(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
if (info.IsNullOrEmpty())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist);
|
|
|
}
|
|
|
//获取表单复制模板
|
|
|
var template = tenantDb.Queryable<CodeFormCopy>().Where(x => x.PermissionId == 1772509201441099776).First();
|
|
|
var sequence = commonService.GetSequenceNext<SeaExport>();
|
|
|
if (!sequence.Succeeded)
|
|
|
{
|
|
|
return DataResult.Failed(sequence.Message, MultiLanguageConst.SequenceSetNotExist);
|
|
|
}
|
|
|
|
|
|
var data = new SeaExport();
|
|
|
if (template.IsNullOrEmpty())
|
|
|
{
|
|
|
data = info.Adapt(data);
|
|
|
data.Id = 0;
|
|
|
data.ParentId = 0;
|
|
|
data.IsBusinessLocking = false;
|
|
|
data.IsFeeLocking = false;
|
|
|
data.CustomerNo = sequence.Data;
|
|
|
var entity = tenantDb.Insertable(data).ExecuteReturnEntity();
|
|
|
return DataResult.Successed("复制成功!", entity.Id, MultiLanguageConst.DataCopySuccess);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
data = info.Adapt(data);
|
|
|
data.Id = 0;
|
|
|
data.ParentId = 0;
|
|
|
data.IsBusinessLocking = false;
|
|
|
data.IsFeeLocking = false;
|
|
|
data.CustomerNo = sequence.Data;
|
|
|
|
|
|
var list0 = template.CopyFields.Split(",");
|
|
|
var list1 = new List<string>();
|
|
|
foreach (var item in list0)
|
|
|
{
|
|
|
list1.Add(item.ToUpperCamelCase());
|
|
|
}
|
|
|
list1.Add("IsBusinessLocking");
|
|
|
list1.Add("IsFeeLocking");
|
|
|
list1.Add("CustomerNo");
|
|
|
var insertColumns = list1.ToArray();
|
|
|
//insertColumns.AddRange(["Id", "ParentId", "IsBusinessLocking", "IsFeeLocking", "CustomerNo"]);
|
|
|
var entity = tenantDb.Insertable(data).InsertColumns(insertColumns).ExecuteReturnEntity();
|
|
|
|
|
|
return DataResult.Successed("复制成功!", entity.Id, MultiLanguageConst.DataCopySuccess);
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
#region 删除
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 业务单据删除
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportDel(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
if (info.IsNullOrEmpty())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist);
|
|
|
}
|
|
|
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => x.ParentId == long.Parse(id)).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口存在分票信息,不能删除!", MultiLanguageConst.SeaExportPartExist);
|
|
|
}
|
|
|
if (tenantDb.Queryable<FeeRecord>().Where(x => x.BusinessId == long.Parse(id)).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口存在费用信息,不能删除!", MultiLanguageConst.SeaExportFeeExist);
|
|
|
}
|
|
|
|
|
|
if ((bool)info.IsBusinessLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息业务已锁定!", MultiLanguageConst.SeaExportBusinessLock);
|
|
|
}
|
|
|
|
|
|
if ((bool)info.IsFeeLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息费用已锁定!", MultiLanguageConst.SeaExportFeeLock);
|
|
|
}
|
|
|
|
|
|
info.Deleted = true;
|
|
|
info.DeleteTime = DateTime.Now;
|
|
|
info.DeleteBy = long.Parse(user.UserId);
|
|
|
tenantDb.Updateable(info).ExecuteCommand();
|
|
|
//tenantDb.Deleteable(info).IsLogic().ExecuteCommand("Deleted");
|
|
|
|
|
|
return DataResult.Successed("删除成功!", MultiLanguageConst.DataDelSuccess);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 业务单据删除
|
|
|
/// </summary>
|
|
|
/// <param name="req">业务Ids</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportBatchDel(IdModel req)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
if (req.Ids.Length == 0)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口批量操作未勾选!", MultiLanguageConst.SeaExportBatchOpNoSelect);
|
|
|
}
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id)).Any().IsNull())
|
|
|
{
|
|
|
return DataResult.Failed("不存在的海运出口信息!", MultiLanguageConst.SeaExportExist);
|
|
|
}
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id) && x.IsBusinessLocking == true).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息业务已锁定!", MultiLanguageConst.SeaExportBusinessLock);
|
|
|
}
|
|
|
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id) && x.IsFeeLocking == true).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息费用已锁定!", MultiLanguageConst.SeaExportFeeLock);
|
|
|
}
|
|
|
|
|
|
if (tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.ParentId)).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口存在分票信息,不能删除!", MultiLanguageConst.SeaExportPartExist);
|
|
|
}
|
|
|
if (tenantDb.Queryable<FeeRecord>().Where(x => req.Ids.Contains(x.BusinessId)).Any())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口存在费用信息,不能删除!", MultiLanguageConst.SeaExportFeeExist);
|
|
|
}
|
|
|
|
|
|
var list = tenantDb.Queryable<SeaExport>().Where(x => req.Ids.Contains(x.Id)).ToList();
|
|
|
|
|
|
//tenantDb.Deleteable(list).IsLogic().ExecuteCommand("Deleted");
|
|
|
//tenantDb.Deleteable<SeaExport>(list).IsLogic().ExecuteCommand("Deleted");
|
|
|
foreach (var item in list)
|
|
|
{
|
|
|
item.Deleted = true;
|
|
|
item.DeleteTime = DateTime.Now;
|
|
|
item.DeleteBy = long.Parse(user.UserId);
|
|
|
tenantDb.Updateable(item).ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
return DataResult.Successed("删除成功!", MultiLanguageConst.DataDelSuccess);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 费用锁定 业务锁定
|
|
|
/// <summary>
|
|
|
/// 业务锁定
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportBusinessLook(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
if (info.IsNullOrEmpty())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist);
|
|
|
}
|
|
|
if ((bool)info.IsBusinessLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息业务已锁定!", MultiLanguageConst.SeaExportBusinessLock);
|
|
|
}
|
|
|
|
|
|
info.IsBusinessLocking = true;
|
|
|
tenantDb.Updateable(info).ExecuteCommand();
|
|
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 费用锁定
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportFeeLook(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
if (info.IsNullOrEmpty())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist);
|
|
|
}
|
|
|
if ((bool)info.IsFeeLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息费用已锁定!", MultiLanguageConst.SeaExportFeeLock);
|
|
|
}
|
|
|
|
|
|
info.IsFeeLocking = true;
|
|
|
tenantDb.Updateable(info).ExecuteCommand();
|
|
|
|
|
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 业务解锁
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportBusinessUnLook(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
if (info.IsNullOrEmpty())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist);
|
|
|
}
|
|
|
if (!(bool)info.IsBusinessLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息业务锁定已解锁!", MultiLanguageConst.SeaExportBusinessUnLock);
|
|
|
}
|
|
|
|
|
|
info.IsBusinessLocking = false;
|
|
|
tenantDb.Updateable(info).ExecuteCommand();
|
|
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 费用解锁
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public DataResult SeaExportFeeUnLook(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
if (info.IsNullOrEmpty())
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist);
|
|
|
}
|
|
|
if (!(bool)info.IsFeeLocking)
|
|
|
{
|
|
|
return DataResult.Failed("海运出口信息费用锁定已解锁!", MultiLanguageConst.SeaExportFeeUnLock);
|
|
|
}
|
|
|
|
|
|
info.IsFeeLocking = false;
|
|
|
tenantDb.Updateable(info).ExecuteCommand();
|
|
|
|
|
|
|
|
|
return DataResult.Successed("更新成功!", MultiLanguageConst.DataUpdateSuccess);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取场站数据
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <param name="isWeb"></param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> GetYardData(string id, bool isWeb = false)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var info = tenantDb.Queryable<SeaExport>().Where(x => x.Id == long.Parse(id)).First();
|
|
|
|
|
|
if (info.IsNull())
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist));
|
|
|
}
|
|
|
if (string.IsNullOrEmpty(info.YardId.ToString()))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("请先选择场站!", MultiLanguageConst.SeaExportNotExist));
|
|
|
}
|
|
|
|
|
|
var data = GetYardDataAndMappingSystem(info, isWeb);
|
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Success(""));
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 从爬虫获取场站数据,并映射为系统中的箱型
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private async Task<DataResult<List<YardCtnImportRes>>> GetYardDataAndMappingSystem(SeaExport order, bool isWeb = false)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var req = new YardDataReq
|
|
|
{
|
|
|
YardId = order.YardId,
|
|
|
MBLNO = order.MBLNO,
|
|
|
IsWeb = isWeb
|
|
|
};
|
|
|
|
|
|
var rtn = await GetYardData(req);
|
|
|
//if (!rtn.Key)
|
|
|
//{
|
|
|
// throw Oops.Bah(rtn.Value);
|
|
|
//}
|
|
|
//场站引入的数据,转换为订舱箱型,且带上箱型代码
|
|
|
var ctnList = tenantDb.Queryable<CodeCtn>().Where(x => x.Status == StatusEnum.Enable).ToList();
|
|
|
var mapCtn = tenantDb.Queryable<MappingCtn>().Where(x => x.Status == StatusEnum.Enable).ToList();
|
|
|
|
|
|
var listRtn = JsonConvert.DeserializeObject<List<YardCtnImportRes>>(rtn.Data);
|
|
|
|
|
|
foreach (var item in listRtn)
|
|
|
{
|
|
|
var ctnall = item.CTNALL;
|
|
|
var findMap = mapCtn.FirstOrDefault(x => x.Module == "YardData" && x.MapCode == ctnall);
|
|
|
var findCtn = ctnList.FirstOrDefault(x => x.CtnName == ctnall);
|
|
|
if (findMap != null)
|
|
|
{
|
|
|
item.CtnCode = findMap.Code;
|
|
|
|
|
|
findCtn = ctnList.First(c => c.EdiCode == findMap.Code);
|
|
|
item.CTNALL = findCtn.CtnName; //名称显示维护的箱型
|
|
|
}
|
|
|
else if (findCtn != null)
|
|
|
{
|
|
|
item.CtnCode = findCtn.EdiCode;
|
|
|
item.CTNALL = findCtn.CtnName; //名称显示维护的箱型
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<List<YardCtnImportRes>>.Failed($"未找到箱型{ctnall}的场站引入配置"));
|
|
|
}
|
|
|
}
|
|
|
return await Task.FromResult(DataResult<List<YardCtnImportRes>>.Success(listRtn));
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 异步调取出口运踪场站详情(按箱明细显示)
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> GetYardData(YardDataReq req)
|
|
|
{
|
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var account = tenantDb.Queryable<CodeThirdParty>().Where(x => x.CustomerId == req.YardId && x.AccountType == "BillTrace").First();
|
|
|
|
|
|
var userKey = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "spiderUserKeyBilltrace" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userSecret = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "spiderUserSecretBilltrace" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var spiderServerUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "spiderServerUrlBillTraceNew" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var tenantName = db.Queryable<SysTenant>().Filter(null, true).Where(x => x.Id == long.Parse(user.TenantId)).First().Name;
|
|
|
if (account.IsNull())
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未配置出口运踪场站第三方账号信息!"));
|
|
|
}
|
|
|
|
|
|
var yardMap = tenantDb.Queryable<MappingYard>().Where(x => x.LinkId == req.YardId && x.Module == "BillTrace").First();
|
|
|
if (yardMap.IsNull())
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"场站代号配置未找到:{req.YardId}"));
|
|
|
}
|
|
|
var objSend = new
|
|
|
{
|
|
|
user_key = userKey,
|
|
|
user_secret = userSecret,
|
|
|
customer_id = user.TenantId,
|
|
|
customer_name = tenantName,
|
|
|
web_code = yardMap.MapCode,
|
|
|
bno = req.MBLNO,
|
|
|
req_type = req.IsWeb ? "1" : "0",
|
|
|
web_user = account.AppKey,
|
|
|
web_psw = account.AppSecret,
|
|
|
};
|
|
|
var urlYard = spiderServerUrl;
|
|
|
if (!urlYard.EndsWith("/"))
|
|
|
{
|
|
|
urlYard += "/";
|
|
|
}
|
|
|
|
|
|
urlYard += "real/query";
|
|
|
|
|
|
var res = RequestHelper.Post(JsonConvert.SerializeObject(objSend), urlYard);
|
|
|
var rtnObj = JObject.Parse(res);
|
|
|
if (rtnObj.GetIntValue("code") != 200)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("$\"获取场站数据失败:{rtnObj.GetStringValue(\"msg\")}\"!"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var rtnData = rtnObj.GetStringValue("data");
|
|
|
if (req.IsWeb)
|
|
|
{
|
|
|
var viewstatehtml = GetDataHtmlList(rtnData, "__VIEWSTATE", "/>");
|
|
|
if (viewstatehtml != "")
|
|
|
{
|
|
|
rtnData = rtnData.Replace(viewstatehtml, "");
|
|
|
}
|
|
|
}
|
|
|
return await Task.FromResult(DataResult<string>.Success(rtnData));
|
|
|
}
|
|
|
}
|
|
|
public static string GetDataHtmlList(string html, string startstr, string endstr)
|
|
|
{
|
|
|
var subhtml = html;
|
|
|
var htmllength = subhtml.Length;
|
|
|
var startindex = subhtml.IndexOf(startstr);
|
|
|
//if (startindex == -1 || startindex == 0) return "";
|
|
|
if (startindex == -1) return "";
|
|
|
subhtml = subhtml.Substring(startindex + startstr.Length, htmllength - startindex - startstr.Length);
|
|
|
var endindex = subhtml.IndexOf(endstr);
|
|
|
if (endindex != -1 && endindex != 0)
|
|
|
subhtml = subhtml.Substring(0, endindex);
|
|
|
|
|
|
return subhtml;
|
|
|
|
|
|
}
|
|
|
|
|
|
#region 运踪相关
|
|
|
/// <summary>
|
|
|
/// 发起运踪订阅或者更新提单号
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> SendOrUpdateTrace(List<BillTraceReq> req)
|
|
|
{
|
|
|
if (req.Count == 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未传入正确参数!"));
|
|
|
}
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var userKey = db.Queryable<SysConfig>().Filter(null,true).Where(x => x.Code == "seae_billtraceurl_userKey" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userPwd = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "seae_billtraceurl_userPwd" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userId = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "seae_billtraceurl_userId" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var reqUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "request_seae_billtraceurl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var resUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "response_seae_billtraceurl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
|
BillTraceMain billdto = new BillTraceMain();
|
|
|
List<BillTraceReq> billTraceList = new List<BillTraceReq>();
|
|
|
foreach (var item in req)
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(item.CARRIERID))
|
|
|
{
|
|
|
var et = await tenantDb.Queryable<BookingStatus>().Where(x => x.StatusCode == "status_mudigang" && x.BusinessId == Convert.ToInt64(item.BusinessId)).FirstAsync();
|
|
|
if (et != null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("\"提单号\" + item.MBLNO + \"已订阅!"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(item.YardCode))
|
|
|
{
|
|
|
var et = await tenantDb.Queryable<BookingStatus>().Where(x => x.StatusCode == "status_qiyungang" && x.BusinessId == Convert.ToInt64(item.BusinessId)).FirstAsync();
|
|
|
if (et != null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("\"提单号\" + item.MBLNO + \"已订阅!"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (item.isBook && (string.IsNullOrWhiteSpace(item.CARRIERID) || string.IsNullOrWhiteSpace(item.CARRIER) || string.IsNullOrWhiteSpace(item.MBLNO)))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("订阅目的港船公司或提单号不能为空!"));
|
|
|
}
|
|
|
if (!item.isBook && (string.IsNullOrWhiteSpace(item.YARD) || string.IsNullOrWhiteSpace(item.YardCode) || string.IsNullOrWhiteSpace(item.MBLNO)))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("订阅港前数据提单号或场站不能为空!"));
|
|
|
}
|
|
|
var yardMap = tenantDb.Queryable<MappingYard>().Where(x => x.Code == item.YardCode && x.Module == "BillTrace").First();
|
|
|
if (yardMap.IsNull())
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"场站代号配置未找到:{item.YardCode}"));
|
|
|
}
|
|
|
billTraceList.Add(new BillTraceReq
|
|
|
{
|
|
|
BusinessId = item.BusinessId,
|
|
|
MBLNO = item.MBLNO,
|
|
|
YARD = item.YARD == "" ? null : item.YARD,
|
|
|
YardCode = yardMap.MapCode == "" ? null : yardMap.MapCode,
|
|
|
CARRIER = item.CARRIER == "" ? null : item.CARRIER,
|
|
|
CARRIERID = item.CARRIERID == "" ? null : item.CARRIERID,
|
|
|
isBook = item.isBook
|
|
|
});
|
|
|
var status = string.Empty;
|
|
|
var IsBookingYZ = String.Empty;
|
|
|
if (!string.IsNullOrWhiteSpace(item.YardCode) && !string.IsNullOrWhiteSpace(item.CARRIERID))
|
|
|
{
|
|
|
status = "订阅起运港,目的港";
|
|
|
IsBookingYZ = "3";
|
|
|
}
|
|
|
else if (string.IsNullOrWhiteSpace(item.YardCode) && !string.IsNullOrWhiteSpace(item.CARRIERID))
|
|
|
{
|
|
|
status = "订阅目的港";
|
|
|
IsBookingYZ = "2";
|
|
|
}
|
|
|
else if (!string.IsNullOrWhiteSpace(item.YardCode) && string.IsNullOrWhiteSpace(item.CARRIERID))
|
|
|
{
|
|
|
status = "订阅起运港";
|
|
|
IsBookingYZ = "1";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
IsBookingYZ = "0";
|
|
|
}
|
|
|
//TODO 添加booking日志
|
|
|
//更新运踪标识
|
|
|
var info = tenantDb.Queryable<SeaExport>().First(x => x.Id == Convert.ToInt64(item.BusinessId));
|
|
|
info.IsBookingYZ = IsBookingYZ;
|
|
|
|
|
|
await tenantDb.Updateable(info).ExecuteCommandAsync();
|
|
|
}
|
|
|
|
|
|
billdto.Children = billTraceList;
|
|
|
billdto.Key = userKey;
|
|
|
billdto.PWD = userPwd;
|
|
|
billdto.url = resUrl;
|
|
|
billdto.Gid = userId;
|
|
|
var json = billdto.ToJsonString();
|
|
|
|
|
|
if (!reqUrl.EndsWith("/"))
|
|
|
{
|
|
|
reqUrl += "/";
|
|
|
}
|
|
|
|
|
|
reqUrl += "BillTrace/UpdateMblno";
|
|
|
|
|
|
var result = RequestHelper.Post(json, reqUrl);
|
|
|
|
|
|
var res = JsonConvert.DeserializeObject<BillTraceRes>(result);
|
|
|
|
|
|
if (!res.Success)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"发起运踪订阅或者更新提单号失败:{res.Message}"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Success(res.Data));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 运踪退订
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> UnsubscribeBillTrace(List<BillTraceUnsubscribeList> req)
|
|
|
{
|
|
|
if (req.Count == 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未传入正确参数!"));
|
|
|
}
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var userKey = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "seae_billtraceurl_userKey" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userPwd = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "seae_billtraceurl_userPwd" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userId = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "seae_billtraceurl_userId" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var reqUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "request_seae_billtraceurl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var resUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "response_seae_billtraceurl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
|
BillTraceUnsubscribeDto reqDto = new BillTraceUnsubscribeDto()
|
|
|
{
|
|
|
Children = new List<BillTraceUnsubscribeList>(),
|
|
|
Key = userKey,
|
|
|
PWD = userPwd,
|
|
|
Gid = userId
|
|
|
};
|
|
|
foreach (var item in req)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(item.BusinessId))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("订舱记录主键不能为空!!"));
|
|
|
}
|
|
|
reqDto.Children.Add(new BillTraceUnsubscribeList(item.BusinessId, item.MBLNO));
|
|
|
|
|
|
//TODO 添加booking日志
|
|
|
//更新运踪标识
|
|
|
var info = tenantDb.Queryable<SeaExport>().First(x => x.Id == Convert.ToInt64(item.BusinessId));
|
|
|
info.IsBookingYZ = "0";
|
|
|
|
|
|
await tenantDb.Updateable(info).ExecuteCommandAsync();
|
|
|
}
|
|
|
var json = reqDto.ToJsonString();
|
|
|
if (!reqUrl.EndsWith("/"))
|
|
|
{
|
|
|
reqUrl += "/";
|
|
|
}
|
|
|
|
|
|
reqUrl += "BillTrace/UnsubscribeBillTrace";
|
|
|
|
|
|
var result = RequestHelper.Post(json, reqUrl);
|
|
|
|
|
|
var res = JsonConvert.DeserializeObject<BillTraceRes>(result);
|
|
|
|
|
|
if (!res.Success)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"运踪退订失败:{res.Message}"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Success(res.Data));
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region VGM及VMG链接
|
|
|
/// <summary>
|
|
|
/// 获取VGM、VGM SI链接
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string[]>> VgmLink(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
var bookingId = long.Parse(id);
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == bookingId);
|
|
|
if (order == null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist));
|
|
|
}
|
|
|
|
|
|
var orderUrl = tenantDb.Queryable<BookingOrderUrl>().First(x => x.BusinessId == bookingId);
|
|
|
if (orderUrl == null)
|
|
|
{
|
|
|
orderUrl = new BookingOrderUrl()
|
|
|
{
|
|
|
BusinessId = bookingId
|
|
|
};
|
|
|
await tenantDb.Insertable(orderUrl).ExecuteCommandAsync();
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrEmpty(orderUrl.UrlVgm))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Success(new string[] { orderUrl.UrlVgm, orderUrl.UrlVgmSi }));
|
|
|
}
|
|
|
|
|
|
//校验船公司
|
|
|
if (string.IsNullOrEmpty(order.Carrier))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("船公司未正确填写!"));
|
|
|
}
|
|
|
|
|
|
var ctns = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == id).ToList();
|
|
|
//判断船公司是否支持
|
|
|
var allowCarrier = db.Queryable<SysDictData>().Where(x => x.TypeId == 1790194688729419776).Select(x => x.Value).ToList();
|
|
|
if (!allowCarrier.Contains(order.Carrier))
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("不支持的船公司"));
|
|
|
|
|
|
//船公司网站账号
|
|
|
var webacc = tenantDb.Queryable<CodeThirdParty>().Where(x => x.CustomerId == order.CarrierId && x.AccountType == "VgmSet").First(); ;
|
|
|
if (webacc == null)
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("船公司网站账号未配置"));
|
|
|
|
|
|
//场站转换
|
|
|
var yardset = tenantDb.Queryable<MappingYard>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingVgm" && x.LinkId == order.YardId).First();
|
|
|
if (yardset == null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed(String.Format("场站EDI配置未找到:{0}", $"{order.Yard}(VGM)")));
|
|
|
}
|
|
|
|
|
|
//校验箱子数据录入
|
|
|
if (ctns.Where(c => string.IsNullOrEmpty(c.CtnAll) || !c.CtnNum.HasValue).Count() > 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("所有箱型箱量必须录入完整!"));
|
|
|
}
|
|
|
|
|
|
//箱型映射
|
|
|
var ctnMapping = tenantDb.Queryable<MappingCtn>().Where(x => x.Module == "BookingVgm").ToList();
|
|
|
//if (ctnMapping.Count == 0)
|
|
|
//{
|
|
|
// throw Oops.Bah(BookingErrorCode.BOOK122);
|
|
|
//}
|
|
|
|
|
|
var expCode = ctns.Select(x => x.CtnCode).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList();
|
|
|
if (expCode.Count > 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed(String.Format("箱型EDI配置未找到:{0}", $"{string.Join(',', expCode)}(VGM)")));
|
|
|
}
|
|
|
|
|
|
//接收反馈地址
|
|
|
var dicUrlVgmResp = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "vgm_si_post_reponse" && x.TenantId == 1288018625843826688).First();
|
|
|
var dicUrlSiResp = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "si_post_response" && x.TenantId == 1288018625843826688).First();
|
|
|
|
|
|
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == long.Parse(user.UserId));
|
|
|
var tenant = db.Queryable<SysTenant>().Filter(null, true).First(x => x.Id == long.Parse(user.TenantId));
|
|
|
//调用vgm链接服务
|
|
|
var postUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "vgm_link_service" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var postObj = new
|
|
|
{
|
|
|
SystemCode = "djy_hechuan",
|
|
|
billOrderId = order.Id.ToString(),
|
|
|
sendOrderCode = order.MBLNO,
|
|
|
customerName = $"{tenant.Name}+{userInfo.UserName}", //公司名称+用户姓名
|
|
|
customerId = order.CustomerId.ToString(),
|
|
|
agentName = string.IsNullOrEmpty(order.Forwarder) ? tenant.Name : order.Forwarder,
|
|
|
carrierCode = order.Carrier,
|
|
|
userName = webacc.AppKey,
|
|
|
userPassword = webacc.AppSecret,
|
|
|
depotCode = yardset.MapCode,
|
|
|
depotName = yardset.MapName,
|
|
|
linkName = userInfo.UserName,
|
|
|
linkMobile = userInfo.Phone,
|
|
|
linkEmail = userInfo.Email,
|
|
|
userId = userInfo.DjyUserId,
|
|
|
signatory = userInfo.NickName,
|
|
|
returnUrl = dicUrlVgmResp?.Value,
|
|
|
shipName = order.Vessel,
|
|
|
voyNo = order.Voyno,
|
|
|
etdstr = order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
potrSend = order.LoadPort,
|
|
|
potrGoal = order.DischargePort,
|
|
|
boxinfoStr = order.CntrTotal.Replace("'", ""),
|
|
|
vgmEndTimeStr = order.CloseVgmDate.HasValue ? order.CloseVgmDate.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
returnOkUrl = "",
|
|
|
SiReturnUrl = dicUrlSiResp?.Value,
|
|
|
DataInfoJson = new
|
|
|
{
|
|
|
order.Shipper,
|
|
|
order.Consignee,
|
|
|
order.NotifyParty,
|
|
|
order.Marks,
|
|
|
order.Description,
|
|
|
order.MBLFrt,
|
|
|
order.Service,
|
|
|
order.IssueType,
|
|
|
order.Transport,
|
|
|
order.TransportCode,
|
|
|
order.Destination,
|
|
|
order.DestinationId,
|
|
|
order.KindPkgs,
|
|
|
order.ThirdPayAt,
|
|
|
order.LoadPort,
|
|
|
order.LoadPortId,
|
|
|
order.DischargePort,
|
|
|
order.DischargePortId
|
|
|
}
|
|
|
};
|
|
|
|
|
|
string strPostObj = postObj.ToJsonString();
|
|
|
_logger.Info($"调用VGM链接接口 {postUrl} 传递数据:{strPostObj}");
|
|
|
var result = RequestHelper.Post(strPostObj, postUrl);
|
|
|
_logger.Info($"调用VGM链接接口返回:{result}");
|
|
|
|
|
|
var jobjResp = JObject.Parse(result);
|
|
|
int respCode = jobjResp.GetIntValue("code");
|
|
|
if (respCode != 200)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed(jobjResp.GetStringValue("message")));
|
|
|
}
|
|
|
|
|
|
|
|
|
//保存url
|
|
|
var memoData = jobjResp.GetJObjectValue("memoData");
|
|
|
orderUrl.UrlVgm = memoData.GetStringValue("vgmUrl");
|
|
|
orderUrl.UrlVgmSi = memoData.GetStringValue("vgmAndSiUrl");
|
|
|
await tenantDb.Updateable(orderUrl).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
//货运动态
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
{
|
|
|
BusinessId = bookingId,
|
|
|
Status = $"生成VGM链接",
|
|
|
Group = "ship",
|
|
|
OpTime = DateTime.Now,
|
|
|
MBLNO = order.MBLNO
|
|
|
};
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Success(new string[]{ orderUrl.UrlVgm, orderUrl.UrlVgmSi }));
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 发送VGM
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> VgmSend(string id) {
|
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
var bookingId = long.Parse(id);
|
|
|
|
|
|
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == bookingId);
|
|
|
var ctns = tenantDb.Queryable<OpCtn>().Where(x => x. BSNO == id).ToList();
|
|
|
|
|
|
//船公司
|
|
|
if (order.CarrierId == 0 || order.CarrierId.ToString().IsNull())
|
|
|
return await Task.FromResult(DataResult<string>.Failed("船公司未正确填写!"));
|
|
|
|
|
|
//提单号不能为空
|
|
|
if (string.IsNullOrEmpty(order.MBLNO))
|
|
|
return await Task.FromResult(DataResult<string>.Failed("主提单号不能为空!"));
|
|
|
|
|
|
var config = db.Queryable<SysConfig>().Where(x => x.Code == "VgmDirectSendCarrierCode").First();
|
|
|
if (config == null)
|
|
|
return await Task.FromResult(DataResult<string>.Failed("请配置租户的VGM直发船司参数!"));
|
|
|
|
|
|
var arrCarr = config.Value.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
|
|
if (!arrCarr.Contains(order.Carrier)) //使用大简云发送vgm
|
|
|
{
|
|
|
//ETD不能为空
|
|
|
if (!order.ETD.HasValue)
|
|
|
return await Task.FromResult(DataResult<string>.Failed("ETD不能为空!"));
|
|
|
|
|
|
//重量不能为空
|
|
|
if (!order.KGS.HasValue)
|
|
|
return await Task.FromResult(DataResult<string>.Failed("重量不能为空!"));
|
|
|
|
|
|
var urlConfig = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "DjyVgmApiMyshppingUrl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userKey = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "DjyVgmApiMyshppingUserKey" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var userPwd = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "DjyVgmApiMyshppingUserPwd" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
|
if (userKey.IsNull() || userPwd.IsNull())
|
|
|
return await Task.FromResult(DataResult<string>.Failed("请在网站账号中维护VGM接口的用户id和秘钥!"));
|
|
|
|
|
|
var objMdata = new
|
|
|
{
|
|
|
MBLNO = order.MBLNO,
|
|
|
CARRIER = order.Carrier,
|
|
|
ChuanMing = order.Vessel,
|
|
|
HangCi = order.VoucherNo,
|
|
|
ETD = order.ETD.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
|
|
ZongZhongLiang = order.KGS.ToString(),
|
|
|
BeiZhu = "",
|
|
|
ORDERNO = order.CustomerNo,
|
|
|
VGMCLOSETIME = order.CloseVgmDate.HasValue ? order.CloseVgmDate.Value.ToString("yyyy-MM-dd HH:mm:ss") : ""
|
|
|
};
|
|
|
|
|
|
var listCtn = new List<dynamic>();
|
|
|
foreach (var ctn in ctns)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(ctn.CtnAll)
|
|
|
|| string.IsNullOrEmpty(ctn.CntrNo)
|
|
|
|| string.IsNullOrEmpty(ctn.SealNo)
|
|
|
|| !ctn.WeightKGS.HasValue
|
|
|
|| string.IsNullOrEmpty(ctn.WeightDate))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("所有箱子的箱型、箱号、封号、称重重量和称重时间都不能为空!"));
|
|
|
}
|
|
|
|
|
|
listCtn.Add(new
|
|
|
{
|
|
|
ChengZhongZhongLiang = ctn.WeightKGS.Value.ToString(),
|
|
|
ChengZhongShiJian = ctn.WeightDate,
|
|
|
CTNALL = ctn.CtnAll.Replace("'", ""),
|
|
|
CNTRNO = ctn.CntrNo,
|
|
|
SEALNO = ctn.SealNo
|
|
|
});
|
|
|
}
|
|
|
|
|
|
var dictParam = new Dictionary<string, string> {
|
|
|
{ "ac", "vgm" },
|
|
|
{ "uid", userKey },
|
|
|
{ "skey", userPwd },
|
|
|
{ "optype", "9"},
|
|
|
{ "mdata", JsonConvert.SerializeObject(objMdata)},
|
|
|
{ "ctndata", JsonConvert.SerializeObject(listCtn)}
|
|
|
};
|
|
|
|
|
|
_logger.Info($"调用vgm发送接口:{ urlConfig },参数:{JsonConvert.SerializeObject(dictParam)}");
|
|
|
|
|
|
|
|
|
|
|
|
var result = RequestHelper.Post(JsonConvert.SerializeObject(dictParam), urlConfig);
|
|
|
|
|
|
_logger.Info($"调用vgm发送接口:{ urlConfig },返回:{result}");
|
|
|
|
|
|
var jobjRtn = JObject.Parse(result);
|
|
|
if (jobjRtn.GetBooleanValue("Success"))
|
|
|
{
|
|
|
//货运动态
|
|
|
var bookingStatus = new BookingStatusLog() {
|
|
|
BusinessId = bookingId,
|
|
|
Status = $"发送VGM",
|
|
|
Group = "ship",
|
|
|
MBLNO = order.MBLNO
|
|
|
};
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed(jobjRtn.GetStringValue("Message")));
|
|
|
}
|
|
|
}
|
|
|
else //直接调用vgm接口直发
|
|
|
{
|
|
|
//判断船公司是否支持
|
|
|
var allowCarrier = db.Queryable<SysDictData>().Where(x => x.TypeId == 1790194688729419776).Select(x => x.Value).ToList();
|
|
|
if (!allowCarrier.Contains(order.Carrier))
|
|
|
return await Task.FromResult(DataResult<string>.Failed("不支持的船公司"));
|
|
|
|
|
|
////船公司网站账号
|
|
|
//var carrWebAccMap = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "carrier_web_account_mapping" && x.Code == order.Carrier);
|
|
|
//if (carrWebAccMap == null)
|
|
|
// return await Task.FromResult(DataResult<string>.Failed("不支持的船公司或账号映射未配置"));
|
|
|
|
|
|
var webacc = tenantDb.Queryable<CodeThirdParty>().Where(x => x.CustomerId == order.CarrierId && x.AccountType == "VgmSet").First(); ;
|
|
|
if (webacc == null)
|
|
|
return await Task.FromResult(DataResult<string>.Failed("船公司网站账号未配置"));
|
|
|
|
|
|
#region 箱信息校验,2022-7-1修改:【累加】的必须有重量、皮重和称重重量;【总重】的只需要称重重量不为空
|
|
|
if (ctns.Where(c => c.WeightType== "累加" &&
|
|
|
(
|
|
|
string.IsNullOrEmpty(c.CntrNo)
|
|
|
|| !c.WeightKGS.HasValue
|
|
|
|| c.WeightKGS == 0
|
|
|
|| !c.TareWeight.HasValue
|
|
|
|| c.TareWeight == 0
|
|
|
|| !c.KGS.HasValue
|
|
|
|| c.KGS == 0)
|
|
|
).Count() > 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("称重方式为累加时,箱号、重量、箱皮重以及称重重量都不能为空"));
|
|
|
}
|
|
|
|
|
|
if (ctns.Where(c => c.WeightType == "总重" &&
|
|
|
(
|
|
|
string.IsNullOrEmpty(c.CntrNo)
|
|
|
|| !c.WeightKGS.HasValue
|
|
|
|| c.WeightKGS == 0)
|
|
|
).Count() > 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("称重方式为总重时,箱号和称重重量都不能为空"));
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(order.Yard) || string.IsNullOrEmpty(order.YardId.ToString()))
|
|
|
return await Task.FromResult(DataResult<string>.Failed("场站未正确选择!"));
|
|
|
// 场站映射
|
|
|
string mappingYard, mappingYardId;
|
|
|
var yardMapList = tenantDb.Queryable<MappingYard>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingVgm" && x.LinkId == order.YardId && (x.CarrierId == 0 || x.CarrierId == order.CarrierId))?.ToList();
|
|
|
if (yardMapList?.Any() == true)
|
|
|
{
|
|
|
var yardset = yardMapList.FirstOrDefault(x => x.CarrierId == order.CarrierId)
|
|
|
?? yardMapList.FirstOrDefault(x => x.CarrierId == 0 || x.CarrierId.ToString() == "");
|
|
|
|
|
|
mappingYard = yardset.MapName;
|
|
|
mappingYardId = yardset.MapCode;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var yard = tenantDb.Queryable<InfoClient>().First(x => x.Id == order.YardId);
|
|
|
mappingYard = yard.ShortName;
|
|
|
mappingYardId = yard.CodeName;
|
|
|
}
|
|
|
|
|
|
// 船司映射
|
|
|
var carrMap = tenantDb.Queryable<MappingCarrier>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingVgm" && x.LinkId == order.CarrierId).First();
|
|
|
string mappingCarrierCode = carrMap != null ? carrMap.MapCode : order.Carrier;
|
|
|
|
|
|
var userInfo = await db.Queryable<SysUser>().Filter(null,true).FirstAsync(x => x.Id == long.Parse(user.UserId));
|
|
|
|
|
|
var tenant = db.Queryable<SysTenant>().Filter(null,true).First(x=>x.Id == long.Parse(user.TenantId));
|
|
|
int idx = 1;
|
|
|
//调用接口
|
|
|
var postUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "vgm_service_single" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
//var dicUrl = _cache.GetAllDictData().Result.First(x => x.TypeCode == "url_set" && x.Code == "vgm_service_single");
|
|
|
var sendObj = new
|
|
|
{
|
|
|
SystemCode = "djy_hechuan",
|
|
|
billOrderId = order.Id.ToString(),
|
|
|
sendOrderCode = order.MBLNO,
|
|
|
customerName = $"{tenant.Name}+{ userInfo.UserName }", //公司名称+用户姓名
|
|
|
customerId = order.CustomerId.ToString(),
|
|
|
agentName = string.IsNullOrEmpty(order.Forwarder) ? tenant.Name : order.Forwarder,
|
|
|
carrierCode = mappingCarrierCode,
|
|
|
userName = webacc.AppKey,
|
|
|
userPassword = webacc.AppSecret,
|
|
|
depotCode = mappingYardId,
|
|
|
depotName = mappingYard,
|
|
|
linkName = userInfo.UserName,
|
|
|
linkMobile = userInfo.Phone,
|
|
|
linkEmail = userInfo.Email,
|
|
|
userId = userInfo.DjyUserId,
|
|
|
signatory = userInfo.NickName, //2023年8月28日,董怡含:把用户昵称当做vgm上传人
|
|
|
returnUrl = "",
|
|
|
shipName = order.Vessel,
|
|
|
voyNo = order.Voyno,
|
|
|
etdstr = order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
potrSend = order.LoadPort,
|
|
|
potrGoal = order.DischargePort,
|
|
|
boxinfoStr = order.CntrTotal.Replace("'", ""),
|
|
|
vgmEndTimeStr = order.CloseVgmDate.HasValue ? order.CloseVgmDate.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
BoxInfo = ctns.Select(c => new
|
|
|
{
|
|
|
index = idx++,
|
|
|
boxType = c.CtnAll.Replace("'", ""),
|
|
|
boxcount = c.CtnNum.HasValue ? c.CtnNum.Value : 0,
|
|
|
code = c.CntrNo,
|
|
|
sealCode = c.SealNo,
|
|
|
weigth = c.KGS,
|
|
|
weigthTare = c.TareWeight,
|
|
|
weigthTotal = c.WeightKGS,
|
|
|
weigthType = c.WeightType == "累加" ? "SM2" : "SM1"
|
|
|
}).ToList(),
|
|
|
returnOkUrl = ""
|
|
|
};
|
|
|
|
|
|
string strPostObj = sendObj.ToJsonString();
|
|
|
_logger.Info($"调用VGM直发接口 {postUrl} 传递数据:{strPostObj}");
|
|
|
var result = RequestHelper.Post(strPostObj, postUrl);
|
|
|
|
|
|
_logger.Info($"调用VGM直发接口返回:{result}");
|
|
|
|
|
|
var jobjResp = JObject.Parse(result);
|
|
|
int respCode = jobjResp.GetIntValue("code");
|
|
|
if (respCode != 200)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed(jobjResp.GetStringValue("message")));
|
|
|
}
|
|
|
//货运动态
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
{
|
|
|
BusinessId = bookingId,
|
|
|
Status = $"直发VGM",
|
|
|
Group = "ship",
|
|
|
OpTime = DateTime.Now,
|
|
|
MBLNO = order.MBLNO
|
|
|
};
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
}
|
|
|
|
|
|
////设置货物状态:已发VGM,并回传东胜
|
|
|
await seaComService.SetGoodsStatus("YFVGM", bookingId);
|
|
|
//await SendBookingOrder(new long[] { bookingId });
|
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Success("Vgm发送成功!"));
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 批量获取vgm
|
|
|
/// </summary>
|
|
|
/// <param name="ids">业务id 逗号拼接</param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<List<BatchVGM>>> GetVmgDataList(string ids)
|
|
|
{
|
|
|
var arr = ids.Split(',');
|
|
|
if (arr.Length == 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<List<BatchVGM>>.Failed("请传入正确数据!"));
|
|
|
}
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
var main = await tenantDb.Queryable<SeaExport>().Where(x => x.ParentId == 0).ToListAsync();
|
|
|
List<BatchVGM> batchVGMs = new List<BatchVGM>();
|
|
|
foreach (var item in arr)
|
|
|
{
|
|
|
BatchVGM batchVGM = new BatchVGM();
|
|
|
batchVGM.Id = Convert.ToInt64(item);
|
|
|
batchVGM.MBLNO = main.Where(x => x.Id == batchVGM.Id).Select(x => x.MBLNO).FirstOrDefault();
|
|
|
batchVGM.ctnlist = await tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == item).Select(x => new BatchVGMList
|
|
|
{
|
|
|
Id = x.Id,
|
|
|
CtnCode = x.CtnCode,
|
|
|
CtnAll = x.CtnAll,
|
|
|
CntrNo = x.CntrNo,
|
|
|
KGS = x.KGS,
|
|
|
TareWeight = x.TareWeight,
|
|
|
WeightType = x.WeightType,
|
|
|
WeightKGS = x.WeightKGS
|
|
|
}).ToListAsync();
|
|
|
|
|
|
batchVGMs.Add(batchVGM);
|
|
|
}
|
|
|
return await Task.FromResult(DataResult<List<BatchVGM>>.Success(batchVGMs));
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 批量保存vgm
|
|
|
/// </summary>
|
|
|
/// <param name="dto"></param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> SaveBatchVgm(List<BatchVGMList> dto)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
if (dto == null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未提交数据!"));
|
|
|
}
|
|
|
|
|
|
|
|
|
foreach (var item in dto)
|
|
|
{
|
|
|
var dic = item.GetPropertiesArray();
|
|
|
var info = tenantDb.Queryable<OpCtn>().Where(x=>x.Id == item.Id).First();
|
|
|
info = item.Adapt(info);
|
|
|
|
|
|
tenantDb.Updateable(info).UpdateColumns(dic).ExecuteCommand();
|
|
|
}
|
|
|
return await Task.FromResult(DataResult<string>.Success("更新成功!", MultiLanguageConst.DataUpdateSuccess));
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 小票链接
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取提箱小票链接
|
|
|
/// </summary>
|
|
|
/// <param name="id">业务Id</param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<DataResult<string>> TxxpLink(string id)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
var bookingId = long.Parse(id);
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == bookingId);
|
|
|
if (order == null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist));
|
|
|
}
|
|
|
|
|
|
var orderUrl = tenantDb.Queryable<BookingOrderUrl>().First(x => x.BusinessId == bookingId);
|
|
|
if (orderUrl == null)
|
|
|
{
|
|
|
orderUrl = new BookingOrderUrl()
|
|
|
{
|
|
|
BusinessId = bookingId
|
|
|
};
|
|
|
await tenantDb.Insertable(orderUrl).ExecuteCommandAsync();
|
|
|
}
|
|
|
|
|
|
//校验船公司
|
|
|
if (string.IsNullOrEmpty(order.Carrier))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("船公司未正确填写!"));
|
|
|
}
|
|
|
|
|
|
//判断船公司是否支持 1790295446942519296
|
|
|
var allowCarrier = db.Queryable<SysDictData>()
|
|
|
.InnerJoin<SysDictType>((a,b)=>a.TypeId == b.Id).Where((a,b) => b.Code == "txxp_carrier_list").Select((a,b) => a.Value).ToList();
|
|
|
if (!allowCarrier.Contains(order.Carrier))
|
|
|
return await Task.FromResult(DataResult<string>.Failed("不支持的船公司"));
|
|
|
|
|
|
var carrCode = order.Carrier;
|
|
|
var carrMap = tenantDb.Queryable<MappingCarrier>().Where(y => y.Code == order.Carrier && y.Module == "BookingTxxp").First();
|
|
|
if (carrMap != null)
|
|
|
{
|
|
|
carrCode = carrMap.MapCode;
|
|
|
}
|
|
|
|
|
|
//根据订舱代理获取账号类型
|
|
|
var ytMapList = db.Queryable<SysDictData>()
|
|
|
.InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id).Where((a, b) => b.Code == "txxp_yitong_forwarder_map")
|
|
|
.Select((a,b)=>new { Value = a.Value, Name = a.Name }).ToList();
|
|
|
|
|
|
var ytmap = ytMapList.FirstOrDefault(x => x.Value == order.Forwarder);
|
|
|
if (ytmap == null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"订舱代理 {order.Forwarder} 对应的网站账号类型未配置"));
|
|
|
}
|
|
|
|
|
|
//亿通账号
|
|
|
var ytAcc = tenantDb.Queryable<CodeThirdParty>().Where(x => x.CustomerId == order.ForwarderId && x.AccountType == "YitongWeb").First(); ;
|
|
|
if (ytAcc == null)
|
|
|
return await Task.FromResult(DataResult<string>.Failed("亿通账号未配置"));
|
|
|
|
|
|
//场站转换
|
|
|
var yardsetList = tenantDb.Queryable<MappingYard>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingTxxp" && x.LinkId == order.YardId && (x.CarrierId == 0 || x.CarrierId == order.CarrierId)).ToList();
|
|
|
if (yardsetList.Count == 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed(String.Format("场站EDI配置未找到:{0}", $"{order.Yard} {order.Carrier}(提箱小票)")));
|
|
|
}
|
|
|
|
|
|
|
|
|
var yardset = yardsetList.FirstOrDefault(x => x.Code == order.Carrier);
|
|
|
if (yardset == null)
|
|
|
{
|
|
|
yardset = yardsetList.FirstOrDefault(x => x.Code == null || x.Code == "");
|
|
|
}
|
|
|
|
|
|
var ctns = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == id).ToList();
|
|
|
//校验箱子数据录入
|
|
|
if (ctns.Where(c => string.IsNullOrEmpty(c.CtnAll) || !c.CtnNum.HasValue).Count() > 0)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("所有箱型箱量必须录入完整!"));
|
|
|
}
|
|
|
|
|
|
//箱型映射
|
|
|
var ctnMapping = tenantDb.Queryable<MappingCtn>().Where(x => x.Module == "BookingTxxp").ToList();
|
|
|
|
|
|
var expCode = ctns.Select(x => x.CtnCode).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList();
|
|
|
if (expCode.Count > 0)
|
|
|
{
|
|
|
var expName = ctns.Where(x => expCode.Contains(x.CtnCode)).Select(x => x.CtnAll).Distinct().ToList();
|
|
|
return await Task.FromResult(DataResult<string>.Failed(String.Format("箱型EDI配置未找到:{0}", $"{string.Join(',', expCode)}(提箱小票)")));
|
|
|
}
|
|
|
|
|
|
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == long.Parse(user.UserId));
|
|
|
var tenant = db.Queryable<SysTenant>().Filter(null, true).First(x => x.Id == long.Parse(user.TenantId));
|
|
|
|
|
|
//调用小票服务
|
|
|
var postUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "txxp_service" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
var postObj = new
|
|
|
{
|
|
|
SystemCode = "djy_hechuan",
|
|
|
CarrierCode = carrCode,
|
|
|
billOrderId = order.Id.ToString(),
|
|
|
sendOrderCode = order.MBLNO,
|
|
|
userId = userInfo.DjyUserId,
|
|
|
customerId = order.CustomerId.ToString(),
|
|
|
// userName = currUser.CODENAME,
|
|
|
//userPassword = currUser.PASSWORD,
|
|
|
operatorName = userInfo.UserName,
|
|
|
depotCode = yardset.MapCode,
|
|
|
depotName = yardset.MapName,
|
|
|
AgentName = tenant.Name,
|
|
|
linkName = userInfo.UserName,
|
|
|
linkMobile = userInfo.Phone,
|
|
|
CustomerName = $"{tenant.Name}+{userInfo.UserName}", //公司名称+用户姓名
|
|
|
memo = string.Empty,
|
|
|
boxInfo = ctns.Select(c =>
|
|
|
{
|
|
|
var mapCtn = ctnMapping.First(x => x.Code == c.CtnCode);
|
|
|
return new
|
|
|
{
|
|
|
boxType = mapCtn == null ? c.CtnAll : mapCtn.MapCode,
|
|
|
boxCount = c.CtnNum.Value
|
|
|
};
|
|
|
}),
|
|
|
sysLoginName = ytAcc.AppKey,
|
|
|
sysPsssword = ytAcc.AppSecret
|
|
|
};
|
|
|
|
|
|
|
|
|
string strPostObj = postObj.ToJsonString();
|
|
|
_logger.Info($"调用提箱小票接口传递数据:{strPostObj}");
|
|
|
var result = RequestHelper.Post(strPostObj, postUrl);
|
|
|
_logger.Info($"调用提箱小票接口返回:{result}");
|
|
|
|
|
|
var jobjResp = JObject.Parse(result);
|
|
|
int respCode = jobjResp.GetIntValue("code");
|
|
|
if (respCode != 200)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed(jobjResp.GetStringValue("message")));
|
|
|
}
|
|
|
|
|
|
var addUrlFlag = string.IsNullOrEmpty(orderUrl.UrlTxxp) ? true : false; //新生成还是更新链接
|
|
|
//保存url
|
|
|
|
|
|
//保存url
|
|
|
var txxpUrl = jobjResp.GetStringValue("data");
|
|
|
orderUrl.UrlTxxp = txxpUrl;
|
|
|
await tenantDb.Updateable(orderUrl).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
//货运动态
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
{
|
|
|
BusinessId = bookingId,
|
|
|
Status = $"{(addUrlFlag ? "生成" : "更新")}提箱小票链接",
|
|
|
Group = "ship",
|
|
|
OpTime = DateTime.Now,
|
|
|
MBLNO = order.MBLNO
|
|
|
};
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
return await Task.FromResult(DataResult<string>.Success(txxpUrl));
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 检查是否VOLTA并返回初始数据
|
|
|
/// <summary>
|
|
|
/// 检查是否VOLTA并返回初始数据
|
|
|
/// </summary>
|
|
|
/// <param name="req">请求参数</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
public DataResult<VOLTAEDIBaseModel> CheckAndInitVOLTAEdi(BookingOrClosingEDIOrderReq req)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
/*
|
|
|
判断当前单子是否满足执行VOLTA截单流程
|
|
|
1、是截单请求
|
|
|
2、船公司是VOL。
|
|
|
3、提单号开头是(VOL、FCS、REL)
|
|
|
*/
|
|
|
string batchNo = GuidHelper.NewGuidFormatN();
|
|
|
|
|
|
_logger.Info("批次={no}获取请求VOLTA截单详情 {msg}", batchNo, JsonConvert.SerializeObject(req));
|
|
|
|
|
|
if (!req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase))
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"只接受发送类型截单(E)");
|
|
|
|
|
|
if (req.Id == 0)
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"订单Id不能为空");
|
|
|
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == req.Id);
|
|
|
|
|
|
if (order == null)
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"获取订单信息失败");
|
|
|
|
|
|
if (order.ParentId== 0)
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"获取当前订单为分单不能生成EDI信息");
|
|
|
|
|
|
_logger.Info("批次={no}提取订单信息完成", batchNo);
|
|
|
|
|
|
if (!order.Carrier.Equals("VOL", StringComparison.OrdinalIgnoreCase) && !order.Carrier.Equals("FCS", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"当前订单的船公司不是VOL(沃尔塔航运)不能发送VOLTA截单EDI");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(order.MBLNO))
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"提单号不能为空");
|
|
|
|
|
|
if (!order.MBLNO.StartsWith("VOL") && !order.MBLNO.StartsWith("FCS") && !order.MBLNO.StartsWith("REL"))
|
|
|
{
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed($"只支持提单号开头是(VOL、FCS、REL)发送截单");
|
|
|
}
|
|
|
|
|
|
//箱信息
|
|
|
var ctns = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == order.Id.ToString()).ToList();
|
|
|
|
|
|
//VOLTAEDIBaseModel voltaModel = order.Adapt<VOLTAEDIBaseModel>();
|
|
|
var voltaModel = new VOLTAEDIBaseModel() {
|
|
|
BookingId = order.MBLNO,
|
|
|
id = order.Id,
|
|
|
ShpperName = order.ShipperContent,
|
|
|
ConsigneeName = order.ConsigneeContent,
|
|
|
NotifyName = order.NotifyPartyContent,
|
|
|
LoadPort = order.LoadPort,
|
|
|
DischargePort = order.DischargePort,
|
|
|
FinalDestination = order.Destination,
|
|
|
PlaceOfDelivery =order.DeliveryPlace,
|
|
|
CargoDescription = order.Description,
|
|
|
Marks = order.Marks,
|
|
|
Vessel = order.Vessel,
|
|
|
VoyNo = order.Voyno
|
|
|
};
|
|
|
#region 拆分收、发、通(名称、地址拆分)
|
|
|
if (!string.IsNullOrWhiteSpace(voltaModel.ShpperName))
|
|
|
{
|
|
|
string name = voltaModel.ShpperName;
|
|
|
voltaModel.ShpperName = GetShipCneeNotifyDetail(name);
|
|
|
voltaModel.ShpperAddr = GetShipCneeNotifyDetail(name, "addr");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(voltaModel.ConsigneeName))
|
|
|
{
|
|
|
string name = voltaModel.ConsigneeName;
|
|
|
voltaModel.ConsigneeName = GetShipCneeNotifyDetail(name);
|
|
|
voltaModel.ConsigneeAddr = GetShipCneeNotifyDetail(name, "addr");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(voltaModel.NotifyName))
|
|
|
{
|
|
|
string name = voltaModel.NotifyName;
|
|
|
voltaModel.NotifyName = GetShipCneeNotifyDetail(name);
|
|
|
voltaModel.NotifyAddr = GetShipCneeNotifyDetail(name, "addr");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
if (voltaModel.CargoDescription.EndsWith("\n"))
|
|
|
voltaModel.CargoDescription = voltaModel.CargoDescription.Substring(0, voltaModel.CargoDescription.Length - 1);
|
|
|
|
|
|
if (voltaModel != null) {
|
|
|
var list = new List<VOLTAEDIContaModel>();
|
|
|
foreach (var item in ctns)
|
|
|
{
|
|
|
list.Add(new VOLTAEDIContaModel() {
|
|
|
ContaNo = item.CntrNo,
|
|
|
SealNo =item.SealNo,
|
|
|
GWt = item.KGS,
|
|
|
NWt = item.TareWeight,
|
|
|
Qty = item.PKGS,
|
|
|
CBM = item.CBM,
|
|
|
Pkgs =item.KindPkgs
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
//voltaModel.ContaList = ctns.Adapt<List<VOLTAEDIContaModel>>();
|
|
|
|
|
|
StringBuilder pkgsBuilder = new StringBuilder();
|
|
|
//还需要翻译箱明细的包装
|
|
|
if (voltaModel.ContaList != null && voltaModel.ContaList.Count > 0)
|
|
|
{
|
|
|
List<string> origPkgsList = voltaModel.ContaList.Select(x => x.Pkgs).Distinct().ToList();
|
|
|
|
|
|
//包装基础数据
|
|
|
var basePkgsList = tenantDb.Queryable<CodePackage>().ToList();
|
|
|
|
|
|
var ediPkgsList = tenantDb.Queryable<MappingPackage>().Where(t => t.Module == "BOOK_CLOSING_VOLTA"
|
|
|
&& t.CarrierId.HasValue && t.CarrierId ==order.CarrierId)
|
|
|
.ToList();
|
|
|
|
|
|
int startNo = 1;
|
|
|
voltaModel.ContaList.ForEach(x =>
|
|
|
{
|
|
|
x.SNo = startNo;
|
|
|
var curBasePkgs = basePkgsList.FirstOrDefault(p => p.PackageName.Equals(x.Pkgs, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (curBasePkgs == null)
|
|
|
pkgsBuilder.Append($"包装{x.Pkgs}的基础数据代码未找到");
|
|
|
|
|
|
if (curBasePkgs != null)
|
|
|
{
|
|
|
var ediPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(curBasePkgs.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (ediPkgs == null || string.IsNullOrWhiteSpace(ediPkgs.MapCode))
|
|
|
pkgsBuilder.AppendLine($"包装{x.Pkgs}的EDI代码未找到");
|
|
|
|
|
|
if (ediPkgs != null)
|
|
|
{
|
|
|
x.EdiPkgs = ediPkgs.MapCode?.Trim();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(x.EdiPkgs))
|
|
|
x.EdiPkgs = string.Empty;
|
|
|
|
|
|
startNo++;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (pkgsBuilder.Length > 0)
|
|
|
{
|
|
|
_logger.Info("批次={no}获取请求VOLTA截单详情有错误 {msg}", batchNo, JsonConvert.SerializeObject(req));
|
|
|
return DataResult<VOLTAEDIBaseModel>.Failed("获取请求VOLTA截单详情有错误:"+ JsonConvert.SerializeObject(req));
|
|
|
}
|
|
|
|
|
|
return DataResult<VOLTAEDIBaseModel>.Success(voltaModel);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 提取收、发、通详情
|
|
|
/// <summary>
|
|
|
/// 提取收、发、通详情
|
|
|
/// </summary>
|
|
|
/// <param name="name">收、发、通信息</param>
|
|
|
/// <param name="location">内容定位(name-名称;addr-地址)</param>
|
|
|
/// <returns>返回截取字符</returns>
|
|
|
private string GetShipCneeNotifyDetail(string name, string location = "name")
|
|
|
{
|
|
|
string result = string.Empty;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (location == "name")
|
|
|
{
|
|
|
result = Regex.Match(name, ".*(?=\\n)").Value;
|
|
|
}
|
|
|
else if (location == "addr")
|
|
|
{
|
|
|
string s = Regex.Match(name, ".*(?=\\n)").Value;
|
|
|
|
|
|
result = name.Replace(s, "");
|
|
|
|
|
|
if (Regex.IsMatch(result, "^\\n"))
|
|
|
{
|
|
|
result = Regex.Replace(result, "^\\n", "");
|
|
|
}
|
|
|
|
|
|
//result = Regex.Match(name, $"(?<={s}).*").Value;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Info($"{nameof(GetShipCneeNotifyDetail)} 提取收、发、通详情异常,原因:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 订舱、截单EDI
|
|
|
/// <summary>
|
|
|
/// 发送订舱、截单EDI
|
|
|
/// </summary>
|
|
|
/// <param name="req">订舱、截单EDI请求</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
public async Task<DataResult<string>> SendBookingOrClosingEDI(BookingOrClosingEDIOrderReq req)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var dictValue= db.Queryable<SysDictData>()
|
|
|
.InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id).Where((a, b) => b.Code == "XiangManCang")
|
|
|
.Select((a, b) => new { Value = a.Value, Name = a.Name }).First();
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == req.Id);
|
|
|
var Forwarder = order.Forwarder;
|
|
|
if (!string.IsNullOrEmpty(Forwarder) && dictValue.Value == Forwarder)
|
|
|
{
|
|
|
return await XMCEXCEL(req.Id);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await InnerBookingOrClosingEDI(req);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
/// <summary>
|
|
|
/// 箱满仓生成excel文件
|
|
|
/// </summary>
|
|
|
/// <param name="Id"></param>
|
|
|
/// <param name="flag"></param>
|
|
|
/// <returns></returns>
|
|
|
public async Task<dynamic> XMCEXCEL(long Id, bool flag = false)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == Id);
|
|
|
|
|
|
var edi = tenantDb.Queryable<SeaExportEdi>().First(x => x.BusinessId == Id);
|
|
|
var ctn = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == order.Id.ToString()).ToList();
|
|
|
|
|
|
#region 箱满仓生成excel文件
|
|
|
string fileName = String.Empty;
|
|
|
//var opt = App.GetOptions<PrintTemplateOptions>();
|
|
|
var dirAbs = AppSetting.app(new string[] { "PrintTemplate", "BasePath" });
|
|
|
var relativePath = AppSetting.app(new string[] { "PrintTemplate", "RelativePath" });
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
{
|
|
|
dirAbs = _environment.WebRootPath;
|
|
|
}
|
|
|
var fPath = "upload/printtemplate/箱满舱上传Excel模板.xls";
|
|
|
var fileAbsPath = Path.Combine(dirAbs, fPath);
|
|
|
_logger.Info($"准备调用EXCEL");
|
|
|
var file = new FileStream(fileAbsPath, FileMode.Open);
|
|
|
var excelwork = new HSSFWorkbook(file);
|
|
|
var sheet = excelwork.GetSheetAt(0);
|
|
|
for (int i = 0; i < sheet.LastRowNum; i++)
|
|
|
{
|
|
|
////获取行
|
|
|
var row = sheet.GetRow(i);
|
|
|
if (i == 0)
|
|
|
{
|
|
|
//委托编号
|
|
|
ICell cell = row.GetCell(5);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[5].SetCellValue(order.CustomerNo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(order.CustomerNo);
|
|
|
}
|
|
|
}
|
|
|
if (i == 1)
|
|
|
{
|
|
|
//场站
|
|
|
var yardid = order.Yard;
|
|
|
if (!string.IsNullOrEmpty(yardid))
|
|
|
{
|
|
|
ICell cell = row.GetCell(5);
|
|
|
var yard = tenantDb.Queryable<MappingYard>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.Module == "XiangManCangEDI" && x.Code == yardid)
|
|
|
.Select(x => x.MapCode).First();
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[5].SetCellValue(yard);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(yard);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
if (i == 2)
|
|
|
{
|
|
|
//指定业务员
|
|
|
ICell cell = row.GetCell(5);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[5].SetCellValue(edi.XMCYWY);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(edi.XMCYWY);
|
|
|
}
|
|
|
}
|
|
|
if (i == 3)
|
|
|
{
|
|
|
//提单号
|
|
|
ICell cell = row.GetCell(5);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(order.MBLNO))
|
|
|
{
|
|
|
|
|
|
row.Cells[5].SetCellValue(order.CustomerNo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
row.Cells[5].SetCellValue(order.MBLNO);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(order.MBLNO))
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(order.CustomerNo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(order.MBLNO);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (i == 8)
|
|
|
{
|
|
|
//发货人
|
|
|
ICell cell = row.GetCell(1);
|
|
|
var shipper = tenantDb.Queryable<InfoClient>()
|
|
|
.Where(x => x.Status == 0 && x.Id == order.ShipperId).First();
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(shipper.ShortName);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(shipper.ShortName);
|
|
|
}
|
|
|
}
|
|
|
if (i == 10)
|
|
|
{
|
|
|
//发货人代码
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.Shipper);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.Shipper);
|
|
|
}
|
|
|
}
|
|
|
if (i == 11)
|
|
|
{
|
|
|
//收货人
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.Consignee);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.Consignee);
|
|
|
}
|
|
|
}
|
|
|
if (i == 14)
|
|
|
{
|
|
|
//通知人
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.NotifyParty);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.NotifyParty);
|
|
|
}
|
|
|
}
|
|
|
if (i == 17)
|
|
|
{
|
|
|
//第二通知人
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.SecondNotifyParty);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.SecondNotifyParty);
|
|
|
}
|
|
|
}
|
|
|
if (i == 18)
|
|
|
{
|
|
|
//起运港国际五字代码
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.LoadPort);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.LoadPort);
|
|
|
}
|
|
|
|
|
|
var service = order.Service;
|
|
|
//运输方式
|
|
|
ICell cell5 = row.GetCell(5);
|
|
|
var serviceMap = tenantDb.Queryable<MappingService>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.Module == "XiangManCangEDI" && x.Code == service).Select(x => x.MapCode).First();
|
|
|
|
|
|
if (cell5 != null)
|
|
|
{
|
|
|
row.Cells[5].SetCellValue(serviceMap);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(serviceMap);
|
|
|
}
|
|
|
}
|
|
|
if (i == 19)
|
|
|
{
|
|
|
//卸货港国际五字代码
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.DischargePort);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.DischargePort);
|
|
|
}
|
|
|
}
|
|
|
if (i == 20)
|
|
|
{
|
|
|
//交货地国际五字代码
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.Destination);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.Destination);
|
|
|
}
|
|
|
}
|
|
|
if (i == 21)
|
|
|
{
|
|
|
//ETD
|
|
|
|
|
|
if (order.ETD != null)
|
|
|
{
|
|
|
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(Convert.ToDateTime(order.ETD).ToString("yyyy-MM-dd"));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(Convert.ToDateTime(order.ETD).ToString("yyyy-MM-dd"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//船名
|
|
|
ICell cell4 = row.GetCell(4);
|
|
|
if (cell4 != null)
|
|
|
{
|
|
|
row.Cells[4].SetCellValue(order.Vessel);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(4).SetCellValue(order.Vessel);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
if (i == 22)
|
|
|
{
|
|
|
//客户协约号
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.ContractNo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.ContractNo);
|
|
|
}
|
|
|
}
|
|
|
if (i == 23)
|
|
|
{
|
|
|
//航次
|
|
|
ICell cell = row.GetCell(4);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[4].SetCellValue(order.InnerVoyno);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(4).SetCellValue(order.InnerVoyno);
|
|
|
}
|
|
|
}
|
|
|
if (i == 26)
|
|
|
{
|
|
|
//唛头
|
|
|
ICell cell = row.GetCell(0);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[0].SetCellValue(order.Marks);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(0).SetCellValue(order.Marks);
|
|
|
}
|
|
|
|
|
|
if (order.PKGS != null)
|
|
|
{
|
|
|
//件数
|
|
|
ICell cell1 = row.GetCell(1);
|
|
|
if (cell1 != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.PKGS.ToString());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.PKGS.ToString());
|
|
|
}
|
|
|
|
|
|
}
|
|
|
//包装
|
|
|
ICell cell2 = row.GetCell(2);
|
|
|
if (cell2 != null)
|
|
|
{
|
|
|
row.Cells[2].SetCellValue(order.KindPkgs);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(2).SetCellValue(order.KindPkgs);
|
|
|
}
|
|
|
//品名
|
|
|
ICell cell3 = row.GetCell(3);
|
|
|
if (cell3 != null)
|
|
|
{
|
|
|
row.Cells[3].SetCellValue(order.Description);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(3).SetCellValue(order.Description);
|
|
|
}
|
|
|
if (order.KGS != null)
|
|
|
{
|
|
|
//重量
|
|
|
ICell cell4 = row.GetCell(4);
|
|
|
if (cell3 != null)
|
|
|
{
|
|
|
row.Cells[4].SetCellValue(order.KGS.ToString());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(4).SetCellValue(order.KGS.ToString());
|
|
|
}
|
|
|
}
|
|
|
if (order.CBM != null)
|
|
|
{
|
|
|
//尺码
|
|
|
ICell cell5 = row.GetCell(5);
|
|
|
if (cell5 != null)
|
|
|
{
|
|
|
row.Cells[5].SetCellValue(order.CBM.ToString());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(5).SetCellValue(order.CBM.ToString());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (i == 39)
|
|
|
{
|
|
|
var c = ctn.DistinctBy(x => x.CtnAll).ToList();
|
|
|
var ctnAll = string.Empty;
|
|
|
foreach (var item in c)
|
|
|
{
|
|
|
var ctnMap = tenantDb.Queryable<MappingService>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.Module == "XiangManCangEDI" && x.Code == item.CtnCode).Select(x => x.MapCode).First();
|
|
|
|
|
|
ctnAll += $"{ctn.Where(x => x.CtnAll == item.CtnAll).Count()}*{ctnMap}+";
|
|
|
}
|
|
|
ctnAll = ctnAll.Substring(0, ctnAll.Length - 1);
|
|
|
//箱型箱量
|
|
|
ICell cell = row.GetCell(0);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[0].SetCellValue(ctnAll);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(0).SetCellValue(ctnAll);
|
|
|
}
|
|
|
}
|
|
|
if (i == 42)
|
|
|
{
|
|
|
//运费支付方式
|
|
|
|
|
|
var BLFRTCode = tenantDb.Queryable<CodeFrt>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.FrtName == order.MBLFrt).Select(x => x.EdiCode).First();
|
|
|
var bl = string.Empty;
|
|
|
if (!string.IsNullOrEmpty(BLFRTCode))
|
|
|
{
|
|
|
bl = tenantDb.Queryable<MappingService>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.Module == "XiangManCangEDI" && x.Code == BLFRTCode).Select(x => x.MapCode).First();
|
|
|
|
|
|
}
|
|
|
ICell cell = row.GetCell(0);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[0].SetCellValue(bl);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(0).SetCellValue(bl);
|
|
|
}
|
|
|
}
|
|
|
if (i == 43)
|
|
|
{
|
|
|
//hscode
|
|
|
ICell cell = row.GetCell(3);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[3].SetCellValue(order.HSCode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(3).SetCellValue(order.HSCode);
|
|
|
}
|
|
|
}
|
|
|
if (i == 44)
|
|
|
{
|
|
|
var BLFRTCode = tenantDb.Queryable<CodeFrt>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.FrtName == order.MBLFrt).Select(x => x.EdiCode).First();
|
|
|
var bl = string.Empty;
|
|
|
if (!string.IsNullOrEmpty(BLFRTCode))
|
|
|
{
|
|
|
bl = tenantDb.Queryable<MappingService>()
|
|
|
.Where(x => x.Status == StatusEnum.Enable && x.Module == "XiangManCangEDI" && x.Code == BLFRTCode).Select(x => x.MapCode).First();
|
|
|
|
|
|
}
|
|
|
if (bl == "预付")
|
|
|
{
|
|
|
//预付地点
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.PrepareAt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.PrepareAt);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if ((bl == "到付"))
|
|
|
{
|
|
|
|
|
|
//预付地点
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.PayableAt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.PayableAt);
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
if (i == 45)
|
|
|
{
|
|
|
//Name accout
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(edi.EmcNameAccount);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(edi.EmcNameAccount);
|
|
|
}
|
|
|
ICell _cell = row.GetCell(4);
|
|
|
if (_cell != null)
|
|
|
{
|
|
|
row.Cells[4].SetCellValue(edi.EmcNameAccount);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(4).SetCellValue(edi.EmcNameAccount);
|
|
|
}
|
|
|
}
|
|
|
if (i == 47)
|
|
|
{
|
|
|
//Name accout
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.TemperatureSet);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.TemperatureSet);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//温度
|
|
|
ICell cell2 = row.GetCell(2);
|
|
|
if (cell2 != null)
|
|
|
{
|
|
|
row.Cells[2].SetCellValue(order.ReeferQuantity);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(2).SetCellValue(order.ReeferQuantity);
|
|
|
}
|
|
|
|
|
|
|
|
|
//湿度
|
|
|
ICell cell3 = row.GetCell(3);
|
|
|
if (cell2 != null)
|
|
|
{
|
|
|
row.Cells[3].SetCellValue(order.Humidity);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(3).SetCellValue(order.Humidity);
|
|
|
}
|
|
|
}
|
|
|
if (i == 49)
|
|
|
{
|
|
|
//危险品编号
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.DangerNo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.DangerNo);
|
|
|
}
|
|
|
}
|
|
|
if (i == 50)
|
|
|
{
|
|
|
//订舱备注
|
|
|
ICell cell = row.GetCell(1);
|
|
|
if (cell != null)
|
|
|
{
|
|
|
row.Cells[1].SetCellValue(order.BookingRemark);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
row.CreateCell(1).SetCellValue(order.BookingRemark);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var fileFullPath = Path.Combine(_environment.WebRootPath, AppSetting.app(new string[] { "TempFile", "Path" }));//服务器路径
|
|
|
if (!Directory.Exists(fileFullPath))
|
|
|
{
|
|
|
Directory.CreateDirectory(fileFullPath);
|
|
|
}
|
|
|
|
|
|
//2023-4-3,根据合川操作要求,文件名只带提单号
|
|
|
if (!string.IsNullOrEmpty(order.MBLNO))
|
|
|
{
|
|
|
fileName = $"{DateTime.Now.Ticks}_{order.MBLNO}.xls";//名称
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
fileName = $"{DateTime.Now.Ticks}_{order.MBLNO}.xls";//名称
|
|
|
}
|
|
|
_logger.Info("导出excel:" + Path.Combine(fileFullPath, fileName));
|
|
|
var filestream = new FileStream(Path.Combine(fileFullPath, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
|
|
excelwork.Write(filestream);
|
|
|
|
|
|
#endregion
|
|
|
if (flag)
|
|
|
{
|
|
|
filestream.Close();
|
|
|
filestream.Dispose();
|
|
|
var fpath = Path.Combine(fileFullPath, fileName);
|
|
|
var fInfo = new FileInfo(fpath);
|
|
|
_logger.Info("箱满仓文件地址:" + fpath + " " + fInfo);
|
|
|
return new FileStreamResult(new FileStream(fpath, FileMode.Open), "application/octet-stream") { FileDownloadName = fInfo.Name };
|
|
|
}
|
|
|
|
|
|
#region 调用爬虫接口
|
|
|
|
|
|
var url = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "xiangManCangPostUrl" && x.TenantId == 1288018625843826688).Select(x => x.Value).First();
|
|
|
if (string.IsNullOrEmpty(url))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未配置箱满仓请求地址,请联系管理员!"));
|
|
|
}
|
|
|
var account = tenantDb.Queryable<CodeThirdParty>().First(x => x.CustomerId == order.CarrierId && x.AccountType == "XiangManCang");
|
|
|
if (account == null)
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未配置箱满仓账号!"));
|
|
|
}
|
|
|
|
|
|
var key = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "billTraceNewUserKey" && x.TenantId == 1288018625843826688).Select(x => x.Value).First();
|
|
|
|
|
|
if (string.IsNullOrEmpty(key))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未获取到相关KEY,请联系管理员!"));
|
|
|
}
|
|
|
|
|
|
var secret = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "billTraceNewUserSecret" && x.TenantId == 1288018625843826688).Select(x => x.Value).First();
|
|
|
if (string.IsNullOrEmpty(secret))
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未获取到相关SECRET,请联系管理员!"));
|
|
|
}
|
|
|
////使用HttpClient方式上传文件
|
|
|
var carrier_code = db.Queryable<MappingCarrier>().Where(x => x.Module == "HeChuan" && x.MapCode == order.Carrier).Select(x => x.Code).First();
|
|
|
string fn = string.Empty;
|
|
|
using (var httpClient = new HttpClient())
|
|
|
{
|
|
|
using (var request = new HttpRequestMessage(new HttpMethod("Post"), url))
|
|
|
{
|
|
|
//request.Headers.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
|
|
|
var multipartContent = new MultipartFormDataContent();
|
|
|
multipartContent.Add(new StringContent("user_key"), key);
|
|
|
multipartContent.Add(new StringContent("user_secret"), secret);
|
|
|
multipartContent.Add(new StringContent("web_user"), account.AppKey);
|
|
|
multipartContent.Add(new StringContent("web_psw"), account.AppSecret);
|
|
|
multipartContent.Add(new StringContent("carrier_code"), carrier_code);
|
|
|
multipartContent.Add(new StreamContent(filestream, (int)filestream.Length), "file", fileName);
|
|
|
request.Content = multipartContent;
|
|
|
var response = await httpClient.SendAsync(request);
|
|
|
if (response.IsSuccessStatusCode)
|
|
|
{
|
|
|
var strRtn = response.Content.ReadAsStringAsync().Result;
|
|
|
var jobj = strRtn.ToJObject();
|
|
|
if (jobj.GetIntValue("code") == 200)
|
|
|
{
|
|
|
fn = jobj.GetStringValue("msg");
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await Task.FromResult(DataResult<string>.Failed(jobj.GetStringValue("msg")));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//return fn;
|
|
|
return await Task.FromResult(DataResult<string>.Success(fn));
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
#region 根据船公司ID获取EDI的路由枚举
|
|
|
/// <summary>
|
|
|
/// 根据船公司ID获取EDI的路由枚举
|
|
|
/// </summary>
|
|
|
/// <param name="carrierId">船公司ID</param>
|
|
|
/// <param name="ediRouteCfg"></param>
|
|
|
/// <returns>返回适用的路由枚举</returns>
|
|
|
private EDIRouteEnum GetEDIRoute(string carrierId, MappingCarrier ediRouteCfg)
|
|
|
{
|
|
|
EDIRouteEnum routeEnum = EDIRouteEnum.NULL;
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
//var ediRouteCfg = _cache.GetAllMappingCarrier().GetAwaiter().GetResult()
|
|
|
// .FirstOrDefault(t => t.Module.Equals("BOOK_OR_CLOSING_RT", StringComparison.OrdinalIgnoreCase)
|
|
|
// && t.Code.Equals(carrierId, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (ediRouteCfg != null && !string.IsNullOrWhiteSpace(ediRouteCfg.MapCode))
|
|
|
routeEnum = (EDIRouteEnum)System.Enum.Parse(typeof(EDIRouteEnum), ediRouteCfg.MapCode);
|
|
|
|
|
|
//switch (carrierId.ToUpper())
|
|
|
//{
|
|
|
// case "PIL":
|
|
|
// routeEnum = EDIRouteEnum.PIL;
|
|
|
// break;
|
|
|
// case "ONE":
|
|
|
// routeEnum = EDIRouteEnum.YT;
|
|
|
// break;
|
|
|
// case "TSL":
|
|
|
// routeEnum = EDIRouteEnum.TSL;
|
|
|
// break;
|
|
|
// case "YML":
|
|
|
// routeEnum = EDIRouteEnum.YML;
|
|
|
// break;
|
|
|
// case "WY":
|
|
|
// routeEnum = EDIRouteEnum.WY;
|
|
|
// break;
|
|
|
//}
|
|
|
|
|
|
return routeEnum;
|
|
|
}
|
|
|
#endregion
|
|
|
public async Task<DataResult<string>> InnerBookingOrClosingEDI(BookingOrClosingEDIOrderReq req)
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
string batchNo = GuidHelper.NewGuidFormatN();
|
|
|
|
|
|
_logger.Info("批次={no}获取请求订舱、截单EDI {msg}", batchNo, JsonConvert.SerializeObject(req));
|
|
|
/*
|
|
|
发送订舱和截单EDI的流程
|
|
|
1、通过订单号获取订单信息。
|
|
|
2、检查订单的必填信息。
|
|
|
3、根据船公司ID获取对应的路由枚举。
|
|
|
4、获取EDI转换参数。(集装箱型号、包装方式)
|
|
|
5、读取EDI的配置信息,获取船公司相关的EDI配置。
|
|
|
6、检查详细信息。
|
|
|
7、生成订舱或者截单EDI报文,并返回文件保存绝对路径。
|
|
|
*/
|
|
|
if (req.Id == 0)
|
|
|
return DataResult<string>.Failed($"订单Id不能为空");
|
|
|
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == req.Id);
|
|
|
if (order == null)
|
|
|
return DataResult<string>.Failed($"获取订单信息失败");
|
|
|
if (order.ParentId == 0)
|
|
|
return DataResult<string>.Failed($"获取当前订单为分单不能生成EDI信息");
|
|
|
|
|
|
var orderEDI = tenantDb.Queryable<SeaExportEdi>().First(x => x.BusinessId == req.Id);
|
|
|
_logger.Info("批次={no}提取订单信息完成", batchNo);
|
|
|
|
|
|
var ediExtModel = tenantDb.Queryable<SeaExportEdi>().First(x => x.BusinessId == req.Id);
|
|
|
|
|
|
if (ediExtModel == null)
|
|
|
return DataResult<string>.Failed($"获取EDI信息失败");
|
|
|
|
|
|
_logger.Info("批次={no}提取订单EDI信息完成", batchNo);
|
|
|
|
|
|
//箱信息
|
|
|
var contaList = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == order.Id.ToString()).ToList();
|
|
|
|
|
|
|
|
|
var check= CheckBookingOrClosingEDI(order, contaList);
|
|
|
if (!check.Succeeded)
|
|
|
{
|
|
|
return DataResult<string>.Failed(check.Message);
|
|
|
}
|
|
|
var carrMap= tenantDb.Queryable<MappingCarrier>().Where(t => t.Module.Equals("BOOK_OR_CLOSING_RT", StringComparison.OrdinalIgnoreCase)
|
|
|
&& t.LinkId == order.CarrierId)
|
|
|
.First();
|
|
|
|
|
|
EDIRouteEnum ediRouteEnum = GetEDIRoute(order.Carrier, carrMap);
|
|
|
|
|
|
if (ediRouteEnum == EDIRouteEnum.YT)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(order.NoBill))
|
|
|
{
|
|
|
return DataResult<string>.Failed($"当前船公司{order.Carrier} EDI={ediRouteEnum.ToString()} 提单份数必填");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//部分船公司EDI需要填写操作英文名称,这里预先预警,其他船公司如果也需要可以再此追加
|
|
|
if (ediRouteEnum == EDIRouteEnum.TSL)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(ediExtModel.OpEName))
|
|
|
return DataResult<string>.Failed($"未填写(EDI并补充信息)操作英文名称");
|
|
|
}
|
|
|
|
|
|
_logger.Info("批次={no} 获取EDI路由完成 路由={route}", batchNo, ediRouteEnum.ToString());
|
|
|
|
|
|
if (ediRouteEnum == EDIRouteEnum.NULL)
|
|
|
return DataResult<string>.Failed($"当前船公司没有对应的请求路由配置");
|
|
|
|
|
|
//这里船公司VOL的单子不能走此通道发送
|
|
|
if (ediRouteEnum == EDIRouteEnum.VOL)
|
|
|
return DataResult<string>.Failed($"当前船公司VOL不能执行标准发送");
|
|
|
|
|
|
//集装箱型
|
|
|
var ediCtnList = tenantDb.Queryable<MappingCtn>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
|
|
|
&& t.CarrierId == order.CarrierId).ToList();
|
|
|
|
|
|
//包装
|
|
|
var ediPkgsList = tenantDb.Queryable<MappingPackage>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
|
|
|
&& t.CarrierId == order.CarrierId).ToList();
|
|
|
|
|
|
//包装基础数据
|
|
|
var basePkgsList = tenantDb.Queryable<CodePackage>().Where(x=>x.Status == StatusEnum.Enable).ToList();
|
|
|
|
|
|
//EDI SO\SI代码
|
|
|
var ediSOSICfg = tenantDb.Queryable<MappingCarrier>().First(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
|
|
|
&& t.LinkId == order.CarrierId);
|
|
|
|
|
|
if (ediSOSICfg == null || string.IsNullOrWhiteSpace(ediSOSICfg.MapCode))
|
|
|
return DataResult<string>.Failed($"CARRIERID={order.Carrier} 发送SO(SI)的船公司EDI代码未找到");
|
|
|
|
|
|
string postSpiderUrl = string.Empty;
|
|
|
CodeThirdParty userWebAccountConfig = null;
|
|
|
|
|
|
if (ediRouteEnum == EDIRouteEnum.TSL && req.Send)
|
|
|
{
|
|
|
if (req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase))
|
|
|
return DataResult<string>.Failed($"暂未提供TSL的截单发送");
|
|
|
|
|
|
postSpiderUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == CONST_TSL_EDI_URL && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(postSpiderUrl))
|
|
|
return DataResult<string>.Failed($"字典未配置 url_set->{CONST_TSL_EDI_URL} 请联系管理员");
|
|
|
|
|
|
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置
|
|
|
userWebAccountConfig = await tenantDb.Queryable<CodeThirdParty>().FirstAsync(x => x.AccountType == CONST_TSL_TYPE_CODE);
|
|
|
|
|
|
|
|
|
_logger.Info("批次={no} 获取获取网站的账户完成,result={Num}", batchNo,JsonConvert.SerializeObject(userWebAccountConfig));
|
|
|
|
|
|
if (userWebAccountConfig == null)
|
|
|
return DataResult<string>.Failed($"未配置个人或公司网站账户,网站{CONST_TSL_TYPE_CODE}");
|
|
|
}
|
|
|
|
|
|
|
|
|
var ediModel = new EDIBaseModel();
|
|
|
|
|
|
//2023-03-06 修改读取EDI配置方法,所有提取配置必须是已启用的EnableFlag=true,并且要根据SendType匹配发送类型,SendType=""表示使用订舱和截单,SO-订舱 SI-截单
|
|
|
var ftpSet = tenantDb.Queryable<CodeEdiSet>()
|
|
|
.First(a => a.EdiTypeCode.Equals(ediRouteEnum.ToString(), StringComparison.OrdinalIgnoreCase) && a.CarrierId == order.CarrierId
|
|
|
&& a.Status == StatusEnum.Enable
|
|
|
&& (string.IsNullOrWhiteSpace(a.SendType) ||
|
|
|
(!string.IsNullOrWhiteSpace(a.SendType) && ((req.SendType == "B" && a.SendType == "SO") || (req.SendType == "E" && a.SendType == "SI")))));
|
|
|
|
|
|
if (ftpSet == null)
|
|
|
return DataResult<string>.Failed($"获取EDICODE={ediRouteEnum.ToString()}的EDI参数设置失败");
|
|
|
|
|
|
_logger.Info("批次={no} 获取EDI配置完成 路由={set}", batchNo, JsonConvert.SerializeObject(ftpSet));
|
|
|
|
|
|
ediModel.SENDCODE = ftpSet.SendCode;
|
|
|
ediModel.SENDNAME = ftpSet.SendName;
|
|
|
ediModel.RECEIVECODE = ftpSet.ReceiveCode;
|
|
|
ediModel.SENDCOMPANYCODE = ftpSet.SendCompanyCode;
|
|
|
ediModel.SENDSUBCOMPANYCODE = ftpSet.SendCompanyCode;
|
|
|
ediModel.ALIASSENDCODE = ftpSet.AliasSendCode;
|
|
|
ediModel.SENDSHIPPERCODE = ftpSet.SendShipperCode;
|
|
|
|
|
|
ediModel.filetype = req.SendType; //订舱
|
|
|
ediModel.filerole = req.FileRole;
|
|
|
|
|
|
//读取文件配置
|
|
|
//var fileCfg = App.GetOptions<BookingAttachOptions>();
|
|
|
var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" });
|
|
|
string filePath = String.Empty;
|
|
|
string relativePath = string.Empty;
|
|
|
|
|
|
if (!req.Send)
|
|
|
{
|
|
|
var opt = AppSetting.app(new string[] { "TempFile", "Path" });
|
|
|
|
|
|
filePath = $"{Path.Combine(_environment.WebRootPath, opt)}\\{order.CustomerNo}";//服务器路径
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var cfgPath = AppSetting.app(new string[] { "FileSettings", "RelativePath" });
|
|
|
relativePath = $"{cfgPath}\\edifiles\\{order.CustomerNo}";
|
|
|
|
|
|
filePath = $"{(!string.IsNullOrWhiteSpace(basePath) ? basePath : _environment.WebRootPath)}\\{relativePath}";
|
|
|
}
|
|
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
|
{
|
|
|
relativePath = relativePath.Replace("\\", "/");
|
|
|
filePath = filePath.Replace("\\", "/");
|
|
|
}
|
|
|
|
|
|
|
|
|
_logger.Info("批次={no} 生成文件保存路径完成 路由={filePath} 服务器系统={system}", batchNo, filePath, RuntimeInformation.OSDescription);
|
|
|
//预先创建目录
|
|
|
if (!Directory.Exists(filePath))
|
|
|
{
|
|
|
Directory.CreateDirectory(filePath);
|
|
|
}
|
|
|
|
|
|
ediModel.filerpath = filePath;
|
|
|
|
|
|
/*
|
|
|
* 2023-03-08 这里根据最新的要求,不通过前台读取了,直接从配置读取
|
|
|
ediModel.UseForWarderCode = model.useForwarderCode;
|
|
|
ediModel.ForWarderCode = model.forwarderCode;
|
|
|
ediModel.ForWarderName = model.forwarderName;
|
|
|
*/
|
|
|
ediModel.ForWarderCode = ftpSet.SendCode;
|
|
|
ediModel.ForWarderName = ftpSet.SendName;
|
|
|
|
|
|
ediModel.BSLIST = new List<SeaExportEDIBaseModel>();
|
|
|
|
|
|
//TODO 数据映射
|
|
|
var primaryModel = order.Adapt<SeaExportEDIBaseModel>();
|
|
|
primaryModel = orderEDI.Adapt<SeaExportEDIBaseModel>();
|
|
|
|
|
|
//航次取内部航次号 2023-04-03 合川操作确认这样调整
|
|
|
primaryModel.VOYNO = order.InnerVoyno;
|
|
|
|
|
|
//航线信息直接取的航司航线(ESL用)
|
|
|
primaryModel.ESLLINECODE = order.Lane;
|
|
|
|
|
|
//起始港映射
|
|
|
var ediLoadPortList = tenantDb.Queryable<MappingPort>()
|
|
|
.Where(a => a.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && a.CarrierId == order.CarrierId).ToList();
|
|
|
|
|
|
//收货地
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.PLACERECEIPTID))
|
|
|
{
|
|
|
var currPortInfo = ediLoadPortList.FirstOrDefault(a =>
|
|
|
a.Code.Equals(primaryModel.PLACERECEIPTID, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"收货地{primaryModel.PLACERECEIPTID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.PLACERECEIPTID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//装货港
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.PORTLOADID))
|
|
|
{
|
|
|
var currPortInfo = ediLoadPortList.FirstOrDefault(a =>
|
|
|
a.Code.Equals(primaryModel.PORTLOADID, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"装货港{primaryModel.PORTLOADID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.PORTLOADID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//签单地点
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.ISSUEPLACEID))
|
|
|
{
|
|
|
var currPortInfo = ediLoadPortList.FirstOrDefault(a =>
|
|
|
a.Code.Equals(primaryModel.ISSUEPLACEID, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"签单地点{primaryModel.ISSUEPLACEID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.ISSUEPLACEID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//预付地点
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.PREPARDATID))
|
|
|
{
|
|
|
var currPortInfo = ediLoadPortList.FirstOrDefault(a =>
|
|
|
a.Code.Equals(primaryModel.PREPARDATID, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"预付地点{primaryModel.PREPARDATID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.PREPARDATID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//目的港基础
|
|
|
var portList = tenantDb.Queryable<CodePort>().Where(x=>x.Status == StatusEnum.Enable).ToList();
|
|
|
|
|
|
//目的港映射
|
|
|
var ediPortList = tenantDb.Queryable<MappingPort>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && t.CarrierId == order.CarrierId).ToList();
|
|
|
|
|
|
//卸货港
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.PORTDISCHARGEID))
|
|
|
{
|
|
|
var sameList = portList.Where(a =>
|
|
|
!string.IsNullOrWhiteSpace(a.EdiCode)
|
|
|
&& a.EdiCode.Equals(primaryModel.PORTDISCHARGEID, StringComparison.OrdinalIgnoreCase))
|
|
|
.Select(a => a.PortName).ToList();
|
|
|
|
|
|
if (sameList == null || sameList.Count == 0)
|
|
|
return DataResult<string>.Failed($"卸货港{primaryModel.PORTDISCHARGEID}基础港口代码未找到");
|
|
|
|
|
|
var currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code) && a.CarrierId == order.CarrierId);
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
{
|
|
|
currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code));
|
|
|
}
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"卸货港{primaryModel.PORTDISCHARGEID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.PORTDISCHARGEID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//中转港
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.TRANSPORTID))
|
|
|
{
|
|
|
var sameList = portList.Where(a =>
|
|
|
!string.IsNullOrWhiteSpace(a.EdiCode)
|
|
|
&& a.EdiCode.Equals(primaryModel.TRANSPORTID, StringComparison.OrdinalIgnoreCase))
|
|
|
.Select(a => a.PortName).ToList();
|
|
|
|
|
|
if (sameList == null || sameList.Count == 0)
|
|
|
return DataResult<string>.Failed($"中转港{primaryModel.TRANSPORTID}基础港口代码未找到");
|
|
|
|
|
|
var currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code) && a.CarrierId == order.CarrierId);
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
{
|
|
|
currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code));
|
|
|
}
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"中转港{primaryModel.TRANSPORTID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.TRANSPORTID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//目的地
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.DESTINATIONID))
|
|
|
{
|
|
|
var sameList = portList.Where(a =>
|
|
|
!string.IsNullOrWhiteSpace(a.EdiCode)
|
|
|
&& a.EdiCode.Equals(primaryModel.DESTINATIONID, StringComparison.OrdinalIgnoreCase))
|
|
|
.Select(a => a.PortName?.Trim()).ToList();
|
|
|
|
|
|
if (sameList == null || sameList.Count == 0)
|
|
|
return DataResult<string>.Failed($"目的地{primaryModel.DESTINATIONID}基础港口代码未找到");
|
|
|
|
|
|
var currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code) && a.CarrierId == order.CarrierId);
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
{
|
|
|
currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code));
|
|
|
}
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"目的地{primaryModel.DESTINATIONID}的EDI代码未找到");
|
|
|
primaryModel.DESTINATIONID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//交货地
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.PLACEDELIVERYID))
|
|
|
{
|
|
|
var sameList = portList.Where(a =>
|
|
|
!string.IsNullOrWhiteSpace(a.EdiCode)
|
|
|
&& a.EdiCode.Equals(primaryModel.PLACEDELIVERYID, StringComparison.OrdinalIgnoreCase))
|
|
|
.Select(a => a.PortName).ToList();
|
|
|
|
|
|
if (sameList == null || sameList.Count == 0)
|
|
|
return DataResult<string>.Failed($"交货地{primaryModel.PLACEDELIVERYID}基础港口代码未找到");
|
|
|
|
|
|
var currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code) && a.CarrierId == order.CarrierId);
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
{
|
|
|
currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code));
|
|
|
}
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"交货地{primaryModel.PLACEDELIVERYID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.PLACEDELIVERYID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//到付地点
|
|
|
if (!string.IsNullOrWhiteSpace(primaryModel.PAYABLEATID))
|
|
|
{
|
|
|
var sameList = portList.Where(a =>
|
|
|
!string.IsNullOrWhiteSpace(a.EdiCode)
|
|
|
&& a.EdiCode.Equals(primaryModel.PAYABLEATID, StringComparison.OrdinalIgnoreCase))
|
|
|
.Select(a => a.PortName).ToList();
|
|
|
|
|
|
if (sameList == null || sameList.Count == 0)
|
|
|
return DataResult<string>.Failed($"到付地点{primaryModel.PAYABLEATID}基础港口代码未找到");
|
|
|
|
|
|
var currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code) && a.CarrierId == order.CarrierId);
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
{
|
|
|
currPortInfo = ediPortList.FirstOrDefault(a =>
|
|
|
sameList.Contains(a.Code));
|
|
|
}
|
|
|
|
|
|
if (currPortInfo == null)
|
|
|
return DataResult<string>.Failed($"到付地点{primaryModel.PAYABLEATID}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.PAYABLEATID = currPortInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
//起运港是CNTAO并且船公司是太平需要判断场站EDI
|
|
|
if (ediRouteEnum == EDIRouteEnum.WY)
|
|
|
{
|
|
|
//场站
|
|
|
var ediYardList = tenantDb.Queryable<MappingYard>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(order.Yard))
|
|
|
{
|
|
|
var currYardInfo = ediYardList.FirstOrDefault(t => t.Code.Equals(order.Yard, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currYardInfo == null)
|
|
|
return DataResult<string>.Failed($"场站{order.Yard}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.YARDEDICODE = currYardInfo.MapCode?.Trim();
|
|
|
primaryModel.YARD = currYardInfo.MapName?.Trim();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//ESL、PIL、WY、YML、YT 需要付费方式映射EDI代码
|
|
|
if (ediRouteEnum == EDIRouteEnum.ESL || ediRouteEnum == EDIRouteEnum.PIL || ediRouteEnum == EDIRouteEnum.WY
|
|
|
|| ediRouteEnum == EDIRouteEnum.YML || ediRouteEnum == EDIRouteEnum.YT || ediRouteEnum == EDIRouteEnum.INTTRA)
|
|
|
{
|
|
|
//付费方式基础数据
|
|
|
var baseFrtList = tenantDb.Queryable<CodeFrt>().Where(x=>x.Status == StatusEnum.Enable).ToList();
|
|
|
|
|
|
var baseFrtInfo = baseFrtList.FirstOrDefault(t =>
|
|
|
t.EdiCode.Equals(order.MBLFrt, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (baseFrtInfo == null)
|
|
|
return DataResult<string>.Failed($"付费方式{order.MBLFrt}的基础代码未找到");
|
|
|
|
|
|
//付费方式映射
|
|
|
var ediFrtList = tenantDb.Queryable<MappingFrt>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && t.CarrierId == order.CarrierId).ToList();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(order.MBLFrt))
|
|
|
{
|
|
|
var currFrtInfo = ediFrtList.FirstOrDefault(t => t.Code.Equals(baseFrtInfo.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currFrtInfo == null)
|
|
|
return DataResult<string>.Failed($"付费方式{order.MBLFrt}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.BLFRTEDICODE = currFrtInfo.MapCode?.Trim();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(order.Service))
|
|
|
{
|
|
|
//运输条款EDI
|
|
|
var baseServiceList = tenantDb.Queryable<CodeService>().Where(x => x.Status == StatusEnum.Enable).ToList();
|
|
|
|
|
|
var baseServiceInfo = baseServiceList.FirstOrDefault(t =>
|
|
|
t.EdiCode.Equals(order.Service, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (baseServiceInfo == null)
|
|
|
return DataResult<string>.Failed($"运输条款{order.Service}的基础代码未找到");
|
|
|
|
|
|
//运输条款映射
|
|
|
var ediServiceList = tenantDb.Queryable<MappingService>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && t.CarrierId == order.CarrierId).ToList();
|
|
|
|
|
|
var currServiceInfo = ediServiceList.FirstOrDefault(t => t.Code.Equals(baseServiceInfo.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currServiceInfo == null)
|
|
|
return DataResult<string>.Failed($"运输条款{order.Service}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.SERVICEEDICODE = currServiceInfo.MapCode?.Trim();
|
|
|
}
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(order.IssueType))
|
|
|
{
|
|
|
//签单方式EDI
|
|
|
var baseIssueTypeList = tenantDb.Queryable<CodeIssueType>().Where(x => x.Status == StatusEnum.Enable).ToList();
|
|
|
|
|
|
var baseIssueTypeInfo = baseIssueTypeList.FirstOrDefault(t =>
|
|
|
t.EnName.Equals(order.IssueType, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (baseIssueTypeInfo == null)
|
|
|
return DataResult<string>.Failed($"签单方式{order.IssueType}的基础代码未找到");
|
|
|
|
|
|
//签单方式映射
|
|
|
var ediIssueTypeList = tenantDb.Queryable<MappingIssueType>()
|
|
|
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
|
|
|
).ToList();
|
|
|
|
|
|
var currIssueTypeInfo = ediIssueTypeList.FirstOrDefault(t => t.CarrierId == order.CarrierId
|
|
|
&& t.Code.Equals(baseIssueTypeInfo.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currIssueTypeInfo == null)
|
|
|
{
|
|
|
//如果没有对应的船司记录,则取默认的第一个代码对应的记录
|
|
|
currIssueTypeInfo = ediIssueTypeList.FirstOrDefault(t => t.Code.Equals(baseIssueTypeInfo.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
}
|
|
|
|
|
|
if (currIssueTypeInfo == null)
|
|
|
return DataResult<string>.Failed($"签单方式{order.IssueType}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.ISSUETYPE = currIssueTypeInfo.MapCode?.Trim().ToUpper();
|
|
|
}
|
|
|
|
|
|
primaryModel.CARRIEREDICODE = ediSOSICfg.MapCode;
|
|
|
|
|
|
//这里除了TSL,订舱编号默认都对应到业务编号(订舱保存时自动生成)
|
|
|
if (ediRouteEnum == EDIRouteEnum.TSL)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(order.CustomerNo))
|
|
|
return DataResult<string>.Failed($"船公司是{order.CustomerNo} 订舱编号不能为空");
|
|
|
primaryModel.ORDERNO = order.CustomerNo;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
primaryModel.ORDERNO = order.BookingNo;
|
|
|
}
|
|
|
|
|
|
//2023-06-15 按照沟通要求,如果主提单号为空,并且订舱编号不为空,可以去订舱编号填入主提单号
|
|
|
if (string.IsNullOrWhiteSpace(primaryModel.MBLNO))
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(order.CustomerNo))
|
|
|
{
|
|
|
_logger.Info("批次={no} 主题单号为空 MBLNO={mblno} 取订舱编号补到主提单号 custno={custno}", batchNo, primaryModel.MBLNO, order.CustomerNo);
|
|
|
|
|
|
if (req.SendType.Equals("B", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
primaryModel.MBLNO = order.CustomerNo;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var curBasePkgs = basePkgsList.FirstOrDefault(p => p.PackageName.Equals(order.KindPkgs, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (curBasePkgs == null)
|
|
|
return DataResult<string>.Failed($"包装{order.KindPkgs}的基础数据代码未找到");
|
|
|
|
|
|
var ediPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(curBasePkgs.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (ediPkgs == null || string.IsNullOrWhiteSpace(ediPkgs.MapCode))
|
|
|
return DataResult<string>.Failed($"包装{order.KindPkgs}的EDI代码未找到");
|
|
|
|
|
|
primaryModel.KINDPKGS_EDI_CODE = ediPkgs.MapCode?.Trim();
|
|
|
|
|
|
//这里是订舱时,默认取SOREMARK赋值到EDIREMARK
|
|
|
if (req.SendType == "B")
|
|
|
{
|
|
|
primaryModel.EDIREMARK = order.EdiRemark;
|
|
|
}
|
|
|
|
|
|
primaryModel.S0CC0C = ediExtModel.S0CC0C;
|
|
|
primaryModel.ACIHBL = ediExtModel.ACIHBL;
|
|
|
|
|
|
primaryModel.MasterBOLIndicator = ediExtModel.MasterBolIndicator;
|
|
|
primaryModel.ConsigneeEdiCode = ediExtModel.ConsigneeEdiCode;
|
|
|
primaryModel.ShipperEdiCode = ediExtModel.ShipperEdiCode;
|
|
|
primaryModel.SalesRepCode = ediExtModel.SalerCode;
|
|
|
primaryModel.CNPTNo = ediExtModel.CNPTNo;
|
|
|
|
|
|
//优先取订舱的EDI附属信息,为空取FTP配置
|
|
|
primaryModel.EDIATTN = ediExtModel.EDIAttn;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(primaryModel.EDIATTN))
|
|
|
{
|
|
|
primaryModel.EDIATTN = ftpSet.SendAttn;
|
|
|
}
|
|
|
primaryModel.EDIATTNTEL = ediExtModel.EDIAttnTel;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(primaryModel.EDIATTNTEL))
|
|
|
{
|
|
|
primaryModel.EDIATTNTEL = ftpSet.SendTel;
|
|
|
}
|
|
|
|
|
|
primaryModel.EDIATTNEMAIL = ediExtModel.EDIAttnMail;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(primaryModel.EDIATTNEMAIL))
|
|
|
{
|
|
|
primaryModel.EDIATTNEMAIL = ftpSet.SendEmail;
|
|
|
}
|
|
|
|
|
|
primaryModel.AMSCONSIGNEE = ediExtModel.AMSConsignee;
|
|
|
primaryModel.AMSNOTIFYPARTY = ediExtModel.AMSNotifyParty;
|
|
|
|
|
|
primaryModel.OpEName = ediExtModel.OpEName;
|
|
|
primaryModel.OpTel = ediExtModel.OpTel;
|
|
|
primaryModel.OpEmail = ediExtModel.OpEmail;
|
|
|
|
|
|
/*
|
|
|
2023-04-14 确认东胜流程后,这里调整商品名称取值,不从EDI扩展信息取,改为从主表的GOODS_CODE取代码经过品名翻译英文填写
|
|
|
注:仅限PIL
|
|
|
//primaryModel.GOODSNAME = ediExtModel.GoodsName;
|
|
|
*/
|
|
|
|
|
|
if (ediRouteEnum == EDIRouteEnum.PIL)
|
|
|
{
|
|
|
if (req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(order.GoodsName))
|
|
|
{
|
|
|
if (order.GoodsId == 0)
|
|
|
{
|
|
|
return DataResult<string>.Failed($"海运出口商品Id未回填!");
|
|
|
}
|
|
|
var pGoods = tenantDb.Queryable<CodeGoods>().First(x => x.Id == order.GoodsId);
|
|
|
if (pGoods == null)
|
|
|
{
|
|
|
_logger.Info("批次={no} 提取商品名称失败 GoodsName={code}", batchNo, order.GoodsName);
|
|
|
|
|
|
return DataResult<string>.Failed($"商品Id对应商品名称未找到!");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
primaryModel.GOODSNAME = pGoods.EnName;
|
|
|
|
|
|
_logger.Info("批次={no} 提取商品名称失败 name={name}", batchNo, pGoods.GoodName);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (req.SendType.Equals("B", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
//2023-05-17 PIL订舱时不提供GOODSNAME,这里默认赋空
|
|
|
primaryModel.GOODSNAME = string.Empty;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
primaryModel.cKHI = ediExtModel.CKHI;
|
|
|
primaryModel.cNCM = ediExtModel.CNCM;
|
|
|
primaryModel.wNCM = ediExtModel.WNCM;
|
|
|
primaryModel.ORDERREMARK = ediExtModel.OrderRemark;
|
|
|
|
|
|
//2023-05-10 (PIL)订舱的预抵日期不提供输入框,按照和川操作要求取开船日期填写到预抵日期
|
|
|
if (string.IsNullOrWhiteSpace(primaryModel.ETA) && !string.IsNullOrWhiteSpace(primaryModel.ETD) &&
|
|
|
ediRouteEnum == EDIRouteEnum.PIL)
|
|
|
{
|
|
|
primaryModel.ETA = primaryModel.ETD;
|
|
|
}
|
|
|
|
|
|
primaryModel.KINGTAREWEIGHT = ediExtModel.KingTareweight.HasValue ? ediExtModel.KingTareweight.Value : 0;
|
|
|
|
|
|
_logger.Info("批次={no} 提取箱完成 数量={total}", batchNo, contaList.Count);
|
|
|
|
|
|
primaryModel.CTNLIST = new List<SeaExportCtnEDIBaseModel>();
|
|
|
|
|
|
|
|
|
//集装箱
|
|
|
foreach (var conta in contaList)
|
|
|
{
|
|
|
//TODO 转换
|
|
|
var contaModel = conta.Adapt<SeaExportCtnEDIBaseModel>();
|
|
|
|
|
|
//EDI箱型
|
|
|
var currConta = ediCtnList.FirstOrDefault(x => x.Code.Equals(conta.CtnCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currConta == null)
|
|
|
return DataResult<string>.Failed($"箱型{conta.CtnCode}的EDI代码未找到!");
|
|
|
|
|
|
contaModel.CTNALLCODE = currConta.MapCode;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(conta.KindPkgs))
|
|
|
return DataResult<string>.Failed($"集装箱包装不能为空!");
|
|
|
|
|
|
var curContaBasePkgs = basePkgsList.FirstOrDefault(p => p.PackageName.Equals(conta.KindPkgs, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (curContaBasePkgs == null)
|
|
|
return DataResult<string>.Failed($"包装{conta.KindPkgs}的基础数据代码未找到!");
|
|
|
|
|
|
//EDI包装
|
|
|
var ediContaPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(curContaBasePkgs.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (currConta == null)
|
|
|
return DataResult<string>.Failed($"包装{conta.KindPkgs}的EDI代码未找到!");
|
|
|
|
|
|
contaModel.KINDPKGS_EDI_CODE = ediContaPkgs.MapCode?.Trim();
|
|
|
|
|
|
primaryModel.CTNLIST.Add(contaModel);
|
|
|
}
|
|
|
|
|
|
//多品名
|
|
|
var cargoList = tenantDb.Queryable<OpCtnDetail>().Where(t => contaList.Select(a => a.Id).ToArray().Contains(t.CtnId)).ToList();
|
|
|
|
|
|
_logger.Info("批次={no} 提取多品名完成 数量={total}", batchNo, cargoList.Count);
|
|
|
|
|
|
primaryModel.CTNGOODSLIST = new List<SeaExportCtnDetailEDIBaseModel>();
|
|
|
|
|
|
foreach (var cargo in cargoList)
|
|
|
{
|
|
|
//TODO 映射
|
|
|
var cargoModel = cargo.Adapt<SeaExportCtnDetailEDIBaseModel>();
|
|
|
|
|
|
cargoModel.CNTRNO = contaList.FirstOrDefault(a => a.Id == cargo.CtnId).CntrNo;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(cargo.KindPkgs))
|
|
|
return DataResult<string>.Failed($"多品名包装不能为空!");
|
|
|
|
|
|
var curCargoBasePkgs = basePkgsList.FirstOrDefault(p => p.PackageName.Equals(cargo.KindPkgs, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (curCargoBasePkgs == null)
|
|
|
return DataResult<string>.Failed($"包装{cargo.KindPkgs}的基础数据代码未找到");
|
|
|
|
|
|
var ediDetailPkgs = ediPkgsList.FirstOrDefault(x => x.Code.Equals(curCargoBasePkgs.EdiCode, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (ediDetailPkgs == null)
|
|
|
return DataResult<string>.Failed($"货明细的包装{cargo.KindPkgs}的EDI代码未找到");
|
|
|
|
|
|
cargoModel.KINDPKGS_EDI_CODE = ediDetailPkgs.MapCode?.Trim();
|
|
|
|
|
|
primaryModel.CTNGOODSLIST.Add(cargoModel);
|
|
|
}
|
|
|
|
|
|
ediModel.BSLIST.Add(primaryModel);
|
|
|
|
|
|
var result = await InnerSendBookingOrClosingEDI(req, ediModel, ediRouteEnum);
|
|
|
|
|
|
_logger.Info("批次={no} 生成EDI文件完成 结果={result}", batchNo, JsonConvert.SerializeObject(result));
|
|
|
|
|
|
if (!result.Succeeded)
|
|
|
{
|
|
|
return DataResult<string>.Failed(result.Message);
|
|
|
}
|
|
|
|
|
|
if (order.Carrier.Equals("ONE", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
//await PrintCarrierOneSOFileAsync(order);
|
|
|
}
|
|
|
|
|
|
if (req.Send)
|
|
|
{
|
|
|
/*
|
|
|
2023-05-24 这里新增TSL的判断,如果是走TSL则默认走吴广的外挂,需要提供个人账户
|
|
|
*/
|
|
|
|
|
|
string currFilePath = string.Empty;
|
|
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
|
{
|
|
|
currFilePath = System.Text.RegularExpressions.Regex.Match(result.ExtraData1.ToString(), relativePath.Replace("/", "\\/") + ".*").Value;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
currFilePath = System.Text.RegularExpressions.Regex.Match(result.ExtraData1.ToString(), relativePath.Replace("\\", "\\\\") + ".*").Value;
|
|
|
}
|
|
|
|
|
|
string fileTypeCode = "edi";
|
|
|
string fileTypeName = "EDI文件";
|
|
|
|
|
|
if (req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
fileTypeCode = "esi";
|
|
|
fileTypeName = "ESI文件";
|
|
|
}
|
|
|
|
|
|
//这里先写入附件表
|
|
|
await SaveEDIFile(req.Id, currFilePath, new System.IO.FileInfo(currFilePath).Name, fileTypeCode, fileTypeName);
|
|
|
|
|
|
_logger.Info("批次={no} 直接发送FTP 文件访问地址={filepath}", batchNo, result.ExtraData1.ToString());
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
//是否发送邮件,EDI这里主要分2种通道发送 默认是FTP,如果配置里指定了接收接收邮箱,就需要推送邮件
|
|
|
bool isSendEmail = false;
|
|
|
|
|
|
//上传FTP
|
|
|
EdiDataResult sendStatus = null;
|
|
|
|
|
|
//TSL单独走接口
|
|
|
if (ediRouteEnum == EDIRouteEnum.TSL)
|
|
|
{
|
|
|
sendStatus = await InnerSendBookingOrClosingEDIToPOST(result.ExtraData1.ToString(), postSpiderUrl, userWebAccountConfig);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//是订舱并且FTP配置了订舱接收邮箱则触发邮箱发送
|
|
|
if (ftpSet.SendType.Equals("SO", StringComparison.OrdinalIgnoreCase)
|
|
|
&& req.SendType.Equals("B", StringComparison.OrdinalIgnoreCase)
|
|
|
&& !string.IsNullOrWhiteSpace(ftpSet.ReceiveEmail))
|
|
|
{
|
|
|
isSendEmail = true;
|
|
|
}
|
|
|
else if (ftpSet.SendType.Equals("SI", StringComparison.OrdinalIgnoreCase)
|
|
|
&& req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase)
|
|
|
&& !string.IsNullOrWhiteSpace(ftpSet.ReceiveEmail))
|
|
|
{
|
|
|
isSendEmail = true;
|
|
|
}
|
|
|
else if (string.IsNullOrWhiteSpace(ftpSet.SendType)
|
|
|
&& !string.IsNullOrWhiteSpace(ftpSet.ReceiveEmail))
|
|
|
{
|
|
|
isSendEmail = true;
|
|
|
}
|
|
|
|
|
|
if (isSendEmail)
|
|
|
{
|
|
|
//推送订舱邮件
|
|
|
sendStatus = await InnerSendBookingOrClosingEDIToEmail(order, result.ExtraData1.ToString(), req.SendType, result.ExtraData2.ToString(), ftpSet);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sendStatus = await InnerSendBookingOrClosingEDIToFTP(result.ExtraData1.ToString(), ftpSet);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.Info("批次={no} 发送完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, sendStatus.Succeeded ? "成功" : "失败");
|
|
|
|
|
|
//var logId = await _bookinglog.InsertReturnSnowflakeIdAsync(new BookingLog
|
|
|
//{
|
|
|
// Type = "Trace",
|
|
|
// BookingId = model.Id,
|
|
|
// TenantId = Convert.ToInt64(UserManager.TENANT_ID),
|
|
|
// CreatedTime = DateTime.Now,
|
|
|
// CreatedUserId = UserManager.UserId,
|
|
|
// CreatedUserName = UserManager.Name
|
|
|
//});
|
|
|
|
|
|
string sendTypeName = "FTP";
|
|
|
|
|
|
if (isSendEmail)
|
|
|
{
|
|
|
sendTypeName = "邮件";
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.TSL)
|
|
|
{
|
|
|
sendTypeName = "POST";
|
|
|
}
|
|
|
|
|
|
//await _bookinglogdetail.InsertReturnSnowflakeIdAsync(new BookingLogDetail
|
|
|
//{
|
|
|
// PId = logId,
|
|
|
// Field = String.Empty,
|
|
|
// OldValue = String.Empty,
|
|
|
// NewValue = $"发送 {order.CARRIERID} EDI 类型={model.sendType} 通过{sendTypeName} {(sendStatus.succ ? "成功" : "失败")}",
|
|
|
//});
|
|
|
|
|
|
if (!sendStatus.Succeeded)
|
|
|
{
|
|
|
return DataResult<string>.Failed($"发送失败,原因:{sendStatus.Message}");
|
|
|
}
|
|
|
|
|
|
//截单
|
|
|
if (req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
//如果是截单需最后推送货物状态
|
|
|
await seaComService.SetGoodsStatus("JD", req.Id);
|
|
|
//await SendBookingOrder(new long[] { req.Id });
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Success(result.ExtraData1.ToString()));
|
|
|
//return result.ExtraData1.ToString();
|
|
|
}
|
|
|
|
|
|
|
|
|
private async Task SaveEDIFile(long boookId, string FilePath, string fileName, string fileTypeCode = "edi", string fileTypeName = "EDI文件")
|
|
|
{
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
/*
|
|
|
直接将附件信息写入附件表
|
|
|
*/
|
|
|
//EDI文件
|
|
|
var bookFile = new OpFile
|
|
|
{
|
|
|
FileName = fileName,
|
|
|
FilePath = FilePath,
|
|
|
TypeCode = fileTypeCode,
|
|
|
TypeName = fileTypeName,
|
|
|
LinkId = boookId,
|
|
|
};
|
|
|
|
|
|
await tenantDb.Insertable(bookFile).ExecuteCommandAsync();
|
|
|
}
|
|
|
|
|
|
#region 检查订舱、截单EDI订单信息
|
|
|
/// <summary>
|
|
|
/// 检查订舱、截单EDI订单信息
|
|
|
/// </summary>
|
|
|
/// <param name="order"></param>
|
|
|
/// <param name="ctnList"></param>
|
|
|
private DataResult<string> CheckBookingOrClosingEDI(SeaExport order, List<OpCtn> ctnList)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(order.Carrier))
|
|
|
return DataResult<string>.Failed("船公司必须填写!");
|
|
|
|
|
|
//if (string.IsNullOrWhiteSpace(order.OPID))
|
|
|
// throw Oops.Bah("未填写操作人");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(order.KindPkgs))
|
|
|
return DataResult<string>.Failed("包装种类未填写!");
|
|
|
|
|
|
//增加箱包装和主信息的包装是否一致校验
|
|
|
if (ctnList.Any(a => a.KindPkgs != order.KindPkgs))
|
|
|
{
|
|
|
return DataResult<string>.Failed("集装箱包装和订舱包装不一致,请修改!");
|
|
|
}
|
|
|
|
|
|
//如果合同协议号不为空需要判断是否字符前、后有空格,不允许字符前后有空格,需要提示修改
|
|
|
if (!string.IsNullOrWhiteSpace(order.ContractNo))
|
|
|
{
|
|
|
if (order.ContractNo.StartsWith(" "))
|
|
|
return DataResult<string>.Failed("运费协议号前含有空格,请修改!");
|
|
|
|
|
|
if (order.ContractNo.EndsWith(" "))
|
|
|
return DataResult<string>.Failed("运费协议号后含有空格,请修改!");
|
|
|
}
|
|
|
|
|
|
//增加件、重、尺比对
|
|
|
if (ctnList != null && ctnList.Count > 0)
|
|
|
{
|
|
|
if (ctnList.Sum(a => a.PKGS.HasValue ? a.PKGS.Value : 0) != (order.PKGS.HasValue ? order.PKGS.Value : 0))
|
|
|
{
|
|
|
return DataResult<string>.Failed("集装箱件数合计和订舱件数不一致,请修改!");
|
|
|
}
|
|
|
|
|
|
if (ctnList.Sum(a => a.KGS.HasValue ? a.KGS.Value : 0) != (order.KGS.HasValue ? order.KGS.Value : 0))
|
|
|
{
|
|
|
return DataResult<string>.Failed("集装箱重量合计和订舱重量不一致,请修改!");
|
|
|
}
|
|
|
|
|
|
if (ctnList.Sum(a => a.CBM.HasValue ? a.CBM.Value : 0) != (order.CBM.HasValue ? order.CBM.Value : 0))
|
|
|
{
|
|
|
return DataResult<string>.Failed("集装箱尺码合计和订舱尺码不一致,请修改!");
|
|
|
}
|
|
|
}
|
|
|
return DataResult<string>.Success("验证成功!");
|
|
|
}
|
|
|
#endregion
|
|
|
#region 上传邮件
|
|
|
/// <summary>
|
|
|
/// 上传邮件
|
|
|
/// </summary>
|
|
|
/// <param name="bookingOrder">订舱详情</param>
|
|
|
/// <param name="filePath">文件路径</param>
|
|
|
/// <param name="sendType">请求类型</param>
|
|
|
/// <param name="ediCfg">EDI配置</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<EdiDataResult> InnerSendBookingOrClosingEDIToEmail(SeaExport bookingOrder, string filePath,
|
|
|
string sendType, string emailTopic, CodeEdiSet ediCfg)
|
|
|
{
|
|
|
var result = new EdiDataResult { Succeeded = true };
|
|
|
|
|
|
var emailUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "email_api_url" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
//var emailUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
// .FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "email_api_url")?.Value;
|
|
|
|
|
|
if (emailUrl == null)
|
|
|
{
|
|
|
result.Succeeded = false;
|
|
|
result.Message = "系统参数配置email_api_url 请联系管理员";
|
|
|
return await Task.FromResult(result);
|
|
|
}
|
|
|
|
|
|
List<EmailApiDto> emailList = new List<EmailApiDto>();
|
|
|
|
|
|
EmailApiDto emailApiDto = new EmailApiDto
|
|
|
{
|
|
|
SendTo = ediCfg.ReceiveEmail,
|
|
|
Title = emailTopic,
|
|
|
Attaches = new List<AttachesInfo>(),
|
|
|
Body = emailTopic,
|
|
|
};
|
|
|
|
|
|
System.IO.FileStream file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|
|
int SplitSize = 5242880;//5M分片长度
|
|
|
int index = 1; //序号 第几片
|
|
|
long StartPosition = 5242880 * (index - 1);
|
|
|
long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
|
|
|
if (lastLens < 5242880)
|
|
|
{
|
|
|
SplitSize = (int)lastLens;
|
|
|
}
|
|
|
byte[] heByte = new byte[SplitSize];
|
|
|
file.Seek(StartPosition, SeekOrigin.Begin);
|
|
|
//第一个参数是 起始位置
|
|
|
file.Read(heByte, 0, SplitSize);
|
|
|
//第三个参数是 读取长度(剩余长度)
|
|
|
file.Close();
|
|
|
|
|
|
string base64Str = Convert.ToBase64String(heByte);
|
|
|
|
|
|
emailApiDto.Attaches.Add(new AttachesInfo
|
|
|
{
|
|
|
AttachName = Path.GetFileName(filePath),
|
|
|
AttachContent = base64Str
|
|
|
});
|
|
|
|
|
|
emailList.Add(emailApiDto);
|
|
|
|
|
|
string strJoin = System.IO.File.ReadAllText(filePath);
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
string res = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
res = RequestHelper.Post(JsonConvert.SerializeObject(emailList), emailUrl);
|
|
|
//res = await emailUrl.SetBody(emailList, "application/json").PostAsync();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.Info($"发送邮件异常:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.Info($"邮件上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,{strJoin}");
|
|
|
|
|
|
_logger.Info($"发送邮件返回:{JsonConvert.SerializeObject(res)}");
|
|
|
|
|
|
//if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
//{
|
|
|
// var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
// var respObj = JsonConvert.DeserializeAnonymousType(userResult, new
|
|
|
// {
|
|
|
// Success = false,
|
|
|
// Message = string.Empty,
|
|
|
// Code = -9999,
|
|
|
// });
|
|
|
|
|
|
// result.Succeeded = respObj.Success;
|
|
|
// result.Message = respObj.Message;
|
|
|
//}
|
|
|
if (res != null)
|
|
|
{
|
|
|
var respObj = JsonConvert.DeserializeAnonymousType(res, new
|
|
|
{
|
|
|
Success = false,
|
|
|
Message = string.Empty,
|
|
|
Code = -9999,
|
|
|
});
|
|
|
|
|
|
result.Succeeded = respObj.Success;
|
|
|
result.Message = respObj.Message;
|
|
|
}
|
|
|
return await Task.FromResult(result);
|
|
|
//return result;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 上传FTP
|
|
|
/// <summary>
|
|
|
/// 上传FTP
|
|
|
/// </summary>
|
|
|
/// <param name="filePath">EDI文件路径</param>
|
|
|
/// <param name="ediCfg">FTP配置</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<EdiDataResult> InnerSendBookingOrClosingEDIToFTP(string filePath, CodeEdiSet ediCfg)
|
|
|
{
|
|
|
EdiDataResult result = new EdiDataResult { Succeeded = true };
|
|
|
|
|
|
CancellationTokenSource cts = new CancellationTokenSource();
|
|
|
|
|
|
string host = string.Empty;
|
|
|
string port = string.Empty;
|
|
|
|
|
|
if (ediCfg.ServerIp.IndexOf(":") >= 0)
|
|
|
{
|
|
|
host = ediCfg.ServerIp.Split(new char[] { ':' }).FirstOrDefault().Trim();
|
|
|
port = ediCfg.ServerIp.Split(new char[] { ':' }).Last()?.Trim();
|
|
|
}
|
|
|
|
|
|
NameValueCollection par = new NameValueCollection();
|
|
|
par.Add("host", host);
|
|
|
//这里如果配置没有指定端口号默认是21端口
|
|
|
par.Add("port", string.IsNullOrWhiteSpace(port) ? "21" : port);
|
|
|
par.Add("username", ediCfg.UserName);
|
|
|
par.Add("pwd", ediCfg.Password);
|
|
|
par.Add("path", ediCfg.FolderName);
|
|
|
|
|
|
var ftpSpiderUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "booking_edi_ftp_server" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
if (ftpSpiderUrl == null)
|
|
|
return await Task.FromResult(EdiDataResult.Failed("系统未配置booking_edi_ftp_server 请联系管理员!"));
|
|
|
|
|
|
//var fileInfo = new FileInfo(filePath);
|
|
|
|
|
|
_logger.Info($"准备请求发送ftp:{ftpSpiderUrl} ,参数:{JsonConvert.SerializeObject(par)},文件:{filePath}");
|
|
|
|
|
|
|
|
|
System.IO.FileStream file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|
|
int SplitSize = 5242880;//5M分片长度
|
|
|
int index = 1; //序号 第几片
|
|
|
long StartPosition = 5242880 * (index - 1);
|
|
|
long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
|
|
|
if (lastLens < 5242880)
|
|
|
{
|
|
|
SplitSize = (int)lastLens;
|
|
|
}
|
|
|
byte[] heByte = new byte[SplitSize];
|
|
|
file.Seek(StartPosition, SeekOrigin.Begin);
|
|
|
//第一个参数是 起始位置
|
|
|
file.Read(heByte, 0, SplitSize);
|
|
|
//第三个参数是 读取长度(剩余长度)
|
|
|
file.Close();
|
|
|
|
|
|
string strJoin = System.IO.File.ReadAllText(filePath);
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
_logger.Info("FTP 开始上传");
|
|
|
|
|
|
var res = FTPHelper.TransmitFtpFile(ftpSpiderUrl, par, new
|
|
|
{
|
|
|
file = "file",
|
|
|
fileName = Path.GetFileName(filePath),
|
|
|
fileBytes = heByte
|
|
|
});
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.Info($"FTP 上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,{strJoin}");
|
|
|
|
|
|
_logger.Info($"发送ftp返回:{res}");
|
|
|
|
|
|
var jobjRetn = JObject.Parse(res);
|
|
|
|
|
|
if (jobjRetn.GetStringValue("status") != "1")
|
|
|
{
|
|
|
result.Succeeded = false;
|
|
|
result.Message = jobjRetn.GetStringValue("message");
|
|
|
}
|
|
|
return await Task.FromResult(result);
|
|
|
//return result;
|
|
|
}
|
|
|
#endregion
|
|
|
/// <summary>
|
|
|
/// EDI发送POST请求
|
|
|
/// </summary>
|
|
|
/// <param name="filePath">文件路径</param>
|
|
|
/// <param name="url">请求URL</param>
|
|
|
/// <param name="accountConfig">配置账户</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<EdiDataResult> InnerSendBookingOrClosingEDIToPOST(string filePath, string url, CodeThirdParty accountConfig)
|
|
|
{
|
|
|
|
|
|
CancellationTokenSource cts = new CancellationTokenSource();
|
|
|
var userKey = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "BCOrDraftUserKey" && x.TenantId == 1288018625843826688).First();
|
|
|
var userPwd = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "BCOrDraftUserSecret" && x.TenantId == 1288018625843826688).First();
|
|
|
if (userKey.IsNull())
|
|
|
{
|
|
|
return await Task.FromResult(EdiDataResult.Failed("请配置相关账号!"));
|
|
|
}
|
|
|
if (userPwd.IsNull())
|
|
|
{
|
|
|
return await Task.FromResult(EdiDataResult.Failed("请配置相关密钥!"));
|
|
|
}
|
|
|
NameValueCollection par = new NameValueCollection();
|
|
|
//par.Add("user_key", App.Configuration["BCOrDraftUserKey"]);
|
|
|
//par.Add("user_secret", App.Configuration["BCOrDraftUserSecret"]);
|
|
|
par.Add("user_key", userKey.Value);
|
|
|
par.Add("user_secret", userPwd.Value);
|
|
|
par.Add("web_user", accountConfig.AppKey?.Trim());
|
|
|
par.Add("web_psw", accountConfig.AppSecret?.Trim());
|
|
|
|
|
|
_logger.Info($"准备请求发送POST:{url} ,参数:{JsonConvert.SerializeObject(par)},文件:{filePath}");
|
|
|
|
|
|
System.IO.FileStream file = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|
|
int SplitSize = 5242880;//5M分片长度
|
|
|
int index = 1; //序号 第几片
|
|
|
long StartPosition = 5242880 * (index - 1);
|
|
|
long lastLens = file.Length - StartPosition;//真不知道怎么起命了,就这样吧
|
|
|
if (lastLens < 5242880)
|
|
|
{
|
|
|
SplitSize = (int)lastLens;
|
|
|
}
|
|
|
byte[] heByte = new byte[SplitSize];
|
|
|
file.Seek(StartPosition, SeekOrigin.Begin);
|
|
|
//第一个参数是 起始位置
|
|
|
file.Read(heByte, 0, SplitSize);
|
|
|
//第三个参数是 读取长度(剩余长度)
|
|
|
file.Close();
|
|
|
|
|
|
string strJoin = System.IO.File.ReadAllText(filePath);
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
_logger.Info("POST 开始上传");
|
|
|
|
|
|
var res = FTPHelper.TransmitFtpFile(url, par, new
|
|
|
{
|
|
|
file = "file",
|
|
|
fileName = Path.GetFileName(filePath),
|
|
|
fileBytes = heByte
|
|
|
});
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.Info($"请求POST 上传完成 上传文件大小:{heByte.Length} 用时:{timeDiff}ms.,{strJoin}");
|
|
|
|
|
|
_logger.Info($"发送POST返回:{res}");
|
|
|
|
|
|
var jobjRetn = JObject.Parse(res);
|
|
|
|
|
|
if (jobjRetn.GetStringValue("code") != "200")
|
|
|
{
|
|
|
return await Task.FromResult(EdiDataResult.Failed(jobjRetn.GetStringValue("msg")));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return await Task.FromResult(EdiDataResult.Failed("请求成功!"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 触发订舱
|
|
|
/// <summary>
|
|
|
/// 触发订舱
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <param name="ediModel"></param>
|
|
|
/// <param name="ediRouteEnum"></param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<EdiDataResult> InnerSendBookingOrClosingEDI(BookingOrClosingEDIOrderReq req, EDIBaseModel ediModel, EDIRouteEnum ediRouteEnum)
|
|
|
{
|
|
|
var result = new EdiDataResult();
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
try
|
|
|
{
|
|
|
if (ediRouteEnum == EDIRouteEnum.PIL)
|
|
|
{
|
|
|
#region PIL
|
|
|
string strCheck = PILEdiHelper.IsCreatePILEDI(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.PIL.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
|
|
|
var currRlt = PILEdiHelper.CreateEdiPIL(ediModel);
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
result.ExtraData2 = currRlt.Succeeded ? currRlt.ExtraData2.ToString() : "";
|
|
|
//return await Task.FromResult(currRlt);
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.TSL)
|
|
|
{
|
|
|
#region TSL
|
|
|
string strCheck = TSLEdiHelper.IsCreateTSL(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.TSL.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
var currRlt = new EdiDataResult();
|
|
|
|
|
|
if (req.SendType == "B")
|
|
|
{
|
|
|
currRlt = TSLEdiHelper.CreateEdiTSL(ediModel);
|
|
|
}
|
|
|
else if (req.SendType == "E")
|
|
|
{
|
|
|
currRlt = TSLEdiHelper.CreateEdiTSLSI(ediModel);
|
|
|
}
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.WY)
|
|
|
{
|
|
|
#region WY
|
|
|
string strCheck = WYEdiHelper.IsCreateWYEDI(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.WY.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
var currRlt = WYEdiHelper.CreateEdiWY(ediModel);
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.YML)
|
|
|
{
|
|
|
#region YML
|
|
|
string strCheck = YMLEdiHelper.IsCreateYMLEDI(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.YML.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
var currRlt = new EdiDataResult();
|
|
|
if (req.SendType == "B")
|
|
|
{
|
|
|
currRlt= YMLEdiHelper.CreateEdiYML(ediModel);
|
|
|
}
|
|
|
else if (req.SendType == "E")
|
|
|
{
|
|
|
currRlt = YMLEdiHelper.CreateEdiYMLSI(ediModel);
|
|
|
}
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.YT)
|
|
|
{
|
|
|
#region YT
|
|
|
string strCheck = YTEdiHelper.IsCreateYTEDI(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.YT.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
|
|
|
var currRlt = YTEdiHelper.CreateEdiYT(ediModel);
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.ESL)
|
|
|
{
|
|
|
#region ESL
|
|
|
string strCheck = ESLEdiHelper.IsCreateESLEDI(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.ESL.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
|
|
|
var currRlt = ESLEdiHelper.CreateEdiESL(ediModel);
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.MELL)
|
|
|
{
|
|
|
#region MELL
|
|
|
string strCheck = MellEdiHelper.IsCreatePILMELL(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.MELL.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
|
|
|
|
|
|
var currRlt = MellEdiHelper.CreateEdiPILMELL(ediModel);
|
|
|
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
result.ExtraData2 = currRlt.Succeeded ? currRlt.ExtraData2.ToString() : "";
|
|
|
}
|
|
|
else if (ediRouteEnum == EDIRouteEnum.INTTRA)
|
|
|
{
|
|
|
//这里INTTRA单独取了船公司
|
|
|
var ediSOSICfg = tenantDb.Queryable<MappingCarrier>().First(t => t.Module.Equals(CONST_MAPPING_MODULE_INTTRA, StringComparison.OrdinalIgnoreCase)
|
|
|
&& t.Code == ediModel.BSLIST.FirstOrDefault().CARRIERID);
|
|
|
|
|
|
if (ediSOSICfg == null || string.IsNullOrWhiteSpace(ediSOSICfg.MapCode))
|
|
|
throw new Exception($"CARRIERID={ediModel.BSLIST.FirstOrDefault().CARRIERID} INTTRA EDI订舱和截单 的船公司EDI代码未找到");
|
|
|
|
|
|
ediModel.BSLIST.FirstOrDefault().CARRIEREDICODE = ediSOSICfg.MapCode;
|
|
|
|
|
|
#region INTTRA
|
|
|
string strCheck = InttraEdiHelper.IsCreateINTTR(ediModel);
|
|
|
|
|
|
_logger.Info($"调用SO(SI),校验:{strCheck},数据对象:{JsonConvert.SerializeObject(ediModel)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(strCheck))
|
|
|
{
|
|
|
if (Regex.IsMatch(strCheck, "\\<br\\s{1,}/\\>"))
|
|
|
{
|
|
|
strCheck = Regex.Replace(strCheck, "\\<br\\s{1,}/\\>", "\n");
|
|
|
}
|
|
|
throw new Exception($"发送{EDIRouteEnum.INTTRA.ToString()}校验失败,{strCheck}");
|
|
|
}
|
|
|
var currRlt = new EdiDataResult();
|
|
|
if (req.SendType == "B")
|
|
|
{
|
|
|
currRlt = InttraEdiHelper.CreateEdiINTTR(ediModel);
|
|
|
}
|
|
|
else if (req.SendType == "E")
|
|
|
{
|
|
|
currRlt = InttraEdiHelper.CreateEdiINTTRSI(ediModel);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
result.Succeeded = currRlt.Succeeded;
|
|
|
result.ExtraData1 = currRlt.Succeeded ? currRlt.ExtraData1.ToString() : "";
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.Succeeded = false;
|
|
|
result.Message = ex.Message;
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
} |