You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ds8-solution-pro/ds-wms-service/DS.WMS.Core/Op/Method/SeaExportBookingOrClosingED...

3086 lines
130 KiB
C#

This file contains ambiguous Unicode characters!

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

using Amazon.Runtime.Internal.Util;
using Autofac.Core;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Extensions;
using DS.Module.Core.Helpers;
using DS.Module.DjyServiceStatus;
using DS.WMS.Core.Code.Entity;
using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Invoice.Dtos;
using DS.WMS.Core.Map.Entity;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.Op.EDI;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Sys.Entity;
using LanguageExt;
using LanguageExt.Common;
using Mapster;
using Masuit.Tools.Models;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.HSSF.UserModel;
using NPOI.OpenXmlFormats.Dml.Diagram;
using NPOI.SS.UserModel;
using Org.BouncyCastle.Ocsp;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
namespace DS.WMS.Core.Op.Method
{
/// <summary>
/// 海运出口提箱小票相关接口
/// </summary>
public partial class SeaExportService
{
const string CONST_AUTO_SYNC_DONGSHENG_BY_MQ = "AutoSyncBookingOrderToDongshengMQ";
/// <summary>
/// 打印保函
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<DataResult> PrintShippingOrderLetterPDF(string id)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var book = await tenantDb.Queryable<SeaExport>().ClearFilter<IOrgId>().FirstAsync(x => x.Id == long.Parse(id));
if (book == null)
{
return await Task.FromResult(DataResult.Failed("未找到订舱数据"));
}
var template = await db.Queryable<SysPrintTemplate>().FirstAsync(x => x.TemplateCode == "bill_of_letter" && x.CarrierId == book.CarrierId);
if (template == null)
{
return await Task.FromResult(DataResult.Failed("未找到当前船公司保函模板,模板代码:bill_of_letter"));
}
var url = AppSetting.Configuration["PrintService:LocalPrintUrl"];
if (url.IsNull())
return await Task.FromResult(DataResult.Failed("未配置本地打印地址"));
var req = new Module.PrintModule.OpenJsonPrintReq
{
TemplateId = template.Id,
PrintType = "1",
JsonDataStr = JsonConvert.SerializeObject(book)
};
var token = user.GetToken();
var res = await RequestHelper.PostJosnAsyncByToken(url, req.ToJson(), token);
//var result = JsonConvert.DeserializeObject<DataResult>(res);
var result = JObject.Parse(res);
if (result.GetBooleanValue("succeeded"))
{
return await Task.FromResult(DataResult.Successed("打印保函成功", result.GetStringValue("data"), MultiLanguageConst.DataQuerySuccess));
}
else
{
return await Task.FromResult(DataResult.Failed(result.GetStringValue("message")));
}
}
/// <summary>
/// 打印托书
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<DataResult> PrintShippingOrderPDF(string id)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var book = await tenantDb.Queryable<SeaExport>().ClearFilter<IOrgId>().FirstAsync(x => x.Id == long.Parse(id));
if (book == null)
{
return await Task.FromResult(DataResult.Failed("未找到订舱数据"));
}
var template = await db.Queryable<SysPrintTemplate>().FirstAsync(x => x.TemplateCode == "bill_of_lading");
if (template == null)
{
return await Task.FromResult(DataResult.Failed("未找到托书模板"));
}
var url = AppSetting.Configuration["PrintService:LocalPrintUrl"];
if (url.IsNull())
return await Task.FromResult(DataResult.Failed("未配置本地打印地址"));
var req = new Module.PrintModule.OpenJsonPrintReq
{
TemplateId = template.Id,
PrintType = "1",
JsonDataStr = JsonConvert.SerializeObject(book)
};
var token = user.GetToken();
var res = await RequestHelper.PostJosnAsyncByToken(url, req.ToJson(),token);
//var result = JsonConvert.DeserializeObject<DataResult>(res);
var result = JObject.Parse(res);
if (result.GetBooleanValue("succeeded"))
{
return await Task.FromResult(DataResult.Successed("打印托书成功",result.GetStringValue("data"),MultiLanguageConst.DataQuerySuccess));
}
else
{
return await Task.FromResult(DataResult.Failed(result.GetStringValue("message")));
}
}
/// <summary>
/// 发送托书
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<DataResult<string>> SendShippingOrderEmail(SendShippingOrderReq req) {
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var book = await tenantDb.Queryable<SeaExport>().ClearFilter<IOrgId>().FirstAsync(x => x.Id == req.BookingId);
if (book == null)
{
return await Task.FromResult(DataResult<string>.Failed("未找到订舱数据"));
}
var userMail = await tenantDb.Queryable<CodeUserEmail>().FirstAsync(x => x.CreateBy ==long.Parse(user.UserId));
if (userMail == null)
{
return await Task.FromResult(DataResult<string>.Failed("未配置发件邮箱"));
}
if (string.IsNullOrEmpty(userMail.SmtpServer) || userMail.SmtpPort == 25)
{
return await Task.FromResult(DataResult<string>.Failed("请正确配置发件邮箱且发件不能使用25端口"));
}
var emailUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "email_api_url" && x.TenantId == 1288018625843826688).First().Value;
if (emailUrl == null)
{
return await Task.FromResult(DataResult<string>.Failed("系统参数未配置email_api_url 请联系管理员"));
}
//处理附件
var attPostArr = new List<dynamic>();
foreach (var file in req.FileList)
{
var basePath = AppSetting.app(new string[] { "FileSettings", "BasePath" });
var relativePath = AppSetting.app(new string[] { "FileSettings", "RelativePath" });
var dirAbs = string.Empty;
var fileRelaPath = string.Empty;
var fileAbsPath = string.Empty;
if (string.IsNullOrEmpty(basePath))
{
dirAbs = Path.Combine(_environment.WebRootPath, relativePath);
}
else
{
dirAbs = Path.Combine(basePath, relativePath);
}
var fileFullName = Path.Combine(dirAbs, file);
//fileFullName = fileFullName.Replace(".OpApi", ".MainApi");
fileFullName = fileFullName.Replace("op-api", "main-api");
_logger.Info($"发送托书附件路径:{fileFullName}");
if (!File.Exists(fileFullName))
{
return await Task.FromResult(DataResult<string>.Failed("附件不存在,请检查"));
}
attPostArr.Add(new
{
AttachName = Path.GetFileName(file),
AttachContent = Convert.ToBase64String(File.ReadAllBytes(fileFullName))
});
}
var mailJson = new dynamic[]{
new
{
SendTo = req.SendTo,
Title = req.Title,
Body = req.Body,
CCTo= req.CCTo,
SmtpConfig = "",
Account=userMail.MailAccount,
Password=userMail.Password,
Server=userMail.SmtpServer,
Port=userMail.SmtpPort,
UseSSL=userMail.SmtpSSL,
Attaches=attPostArr
}
};
var mailStr = mailJson.ToJsonString();
_logger.Info($"准备发送托书邮件订舱ID{req.BookingId},邮箱:{userMail.MailAccount}");
var rtn = RequestHelper.Post(mailStr, emailUrl);
_logger.Info($"发送托书邮件返回:{rtn}。订舱ID{req.BookingId},邮箱:{userMail.MailAccount}");
var jRtn = JObject.Parse(rtn);
if (!jRtn.GetBooleanValue("Success"))
{
//throw Oops.Bah(jRtn.GetStringValue("Message"));
return await Task.FromResult(DataResult<string>.Failed(jRtn.GetStringValue("Message")));
}
return await Task.FromResult(DataResult<string>.Success(jRtn.GetStringValue("Message")));
//处理添加联系人邮箱
//var forwarder = await _djycustomer.AsQueryable().FirstAsync(x => x.CodeName == book.FORWARDERID && x.ShortName == book.FORWARDER);
//if (forwarder != null)
//{
// var contactList = await _repCustomerContact.AsQueryable().Where(x => x.CustomerId == forwarder.Id).ToListAsync();
// var arrSendTo = dto.SendTo.Split(';');
// foreach (var emil in arrSendTo)
// {
// if (contactList.Count(x => x.Email == emil) == 0)
// {
// DjyCustomerContact contact = new DjyCustomerContact();
// contact.Email = emil;
// contact.CustomerId = forwarder.Id;
// contact.CarrierProp = book.CARRIERID;
// await _repCustomerContact.InsertAsync(contact);
// }
// }
//}
}
#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 = seaComService.GetClientCode(order.ForwarderId, tenantDb);
if (!string.IsNullOrEmpty(Forwarder) && dictValue != null && 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);
if (!File.Exists(fileAbsPath))
{
return await Task.FromResult(DataResult<string>.Failed("未配置箱满舱上传Excel模板"));
}
_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 = seaComService.GetClientCode(order.YardId, tenantDb);
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("未配置箱满仓请求地址[xiangManCangPostUrl],请联系管理员!"));
}
var account = seaComService.GetCodeThirdParty("XiangManCang", user.UserId, tenantDb, order.CarrierId);
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 carrCode = seaComService.GetCarrierCode(order.CarrierId, tenantDb);
var carrMap = tenantDb.Queryable<MappingCarrier>().Where(t => t.Module.Equals("BOOK_OR_CLOSING_RT", StringComparison.OrdinalIgnoreCase)
&& t.Code == carrCode)
.First();
EDIRouteEnum ediRouteEnum = GetEDIRoute(carrCode, carrMap);
var check = CheckBookingOrClosingEDI(order, contaList, req.SendType, ediRouteEnum);
if (!check.Succeeded)
{
return DataResult<string>.Failed(check.Message);
}
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.Code == carrCode);
if (ediSOSICfg == null || string.IsNullOrWhiteSpace(ediSOSICfg.MapCode))
return DataResult<string>.Failed($"CARRIERID={carrCode} 发送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($"系统参数未配置{CONST_TSL_EDI_URL} 请联系管理员");
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人个人没有配置取公司对应配置
userWebAccountConfig = seaComService.GetCodeThirdParty(CONST_TSL_TYPE_CODE,user.UserId, tenantDb);
_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 mapPortList = new List<MappingPort>();
var portList = new List<CodePort>();
#region 收货地
//收货地
if (order.ReceiptPlaceId > 0)
{
var portRlt = GetPortEDICode(order.ReceiptPlaceId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.ReceiptPlace, "收货地");
if (portRlt.Succeeded)
primaryModel.PLACERECEIPTID = portRlt.Data;
}
#endregion
#region 装货港
//装货港
if (order.LoadPortId > 0)
{
var portRlt = GetPortEDICode(order.LoadPortId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.LoadPort, "装货港");
if (portRlt.Succeeded)
primaryModel.PORTLOADID = portRlt.Data;
}
#endregion
#region 签单地点
//签单地点
if (order.IssuePlaceId > 0)
{
var portRlt = GetPortEDICode(order.IssuePlaceId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.IssuePlace, "签单地点");
if (portRlt.Succeeded)
primaryModel.ISSUEPLACEID = portRlt.Data;
}
#endregion
#region 预付地点
//预付地点
if (order.PrepareAtId > 0)
{
var portRlt = GetPortEDICode(order.PrepareAtId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.PrepareAt, "预付地点");
if (portRlt.Succeeded)
primaryModel.PREPARDATID = portRlt.Data;
}
#endregion
string needMappingModule = string.Empty;
if (ediRouteEnum == EDIRouteEnum.INTTRA)
{
needMappingModule = "INTTRA_EDI";
}
#region 卸货港
//卸货港
if (order.DischargePortId > 0)
{
var portRlt = GetPortEDICode(order.DischargePortId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.DischargePort, "卸货港", needMappingModule);
if (portRlt.Succeeded)
primaryModel.PORTDISCHARGEID = portRlt.Data;
}
#endregion
#region 中转港
//中转港
if (order.TransPortId > 0)
{
var portRlt = GetPortEDICode(order.TransPortId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.TransPort, "中转港", needMappingModule);
if (portRlt.Succeeded)
primaryModel.TRANSPORTID = portRlt.Data;
}
#endregion
#region 交货地
//交货地
if (order.DeliveryPlaceId > 0)
{
var portRlt = GetPortEDICode(order.DeliveryPlaceId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.DeliveryPlace, "交货地", needMappingModule);
if (portRlt.Succeeded)
primaryModel.PLACEDELIVERYID = portRlt.Data;
}
#endregion
//INTTRA 订舱时改用交货地来填写到目的地
if (ediRouteEnum == EDIRouteEnum.INTTRA || ediRouteEnum == EDIRouteEnum.YT)
{
#region 目的地
//目的地
if (order.DeliveryPlaceId > 0)
{
var portRlt = GetPortEDICode(order.DeliveryPlaceId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.DischargePort, "交货地", needMappingModule);
if (portRlt.Succeeded)
primaryModel.DESTINATIONID = portRlt.Data;
}
#endregion
}
else
{
#region 目的地
//目的地
if (order.DestinationId > 0)
{
var portRlt = GetPortEDICode(order.DestinationId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.DischargePort, "目的地", needMappingModule);
if (portRlt.Succeeded)
primaryModel.DESTINATIONID = portRlt.Data;
}
#endregion
}
#region 到付地点
//到付地点
if (order.PayableAtId > 0)
{
var portRlt = GetPortEDICode(order.PayableAtId, portList, mapPortList, order.CarrierId, CONST_MAPPING_MODULE, order.PayableAt, "到付地点", needMappingModule);
if (portRlt.Succeeded)
primaryModel.PAYABLEATID = portRlt.Data;
}
#endregion
//如果处理的是到付,需要把预付地点来对应到付地点
if (!string.IsNullOrWhiteSpace(order.MBLFrt) && order.MBLFrt.IndexOf("COLLECT") >= 0)
{
primaryModel.PAYABLEATID = primaryModel.PREPARDATID;
primaryModel.PAYABLEAT = order.PrepareAt;
primaryModel.PREPARDATID = string.Empty;
primaryModel.PREPARDAT = string.Empty;
}
//起运港是CNTAO并且船公司是太平需要判断场站EDI
if (ediRouteEnum == EDIRouteEnum.WY)
{
//场站
var ediYardList = tenantDb.Queryable<MappingYard>()
.Where(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)).ToList();
var yardCode = seaComService.GetClientCode(order.YardId,tenantDb);
if (!string.IsNullOrWhiteSpace(yardCode))
{
var currYardInfo = ediYardList.FirstOrDefault(t => t.Code.Equals(yardCode, 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)
{
/*
1、先默认取映射如果没有映射配置默认取基础表EdiCode
*/
if (!string.IsNullOrWhiteSpace(order.MBLFrtCode))
{
var codeInfo = tenantDb.Queryable<CodeFrt>().First(x => x.Status == StatusEnum.Enable && x.EdiCode == order.MBLFrtCode);
if (codeInfo != null)
{
//primaryModel.BLFRTEDICODE = codeInfo.EdiCode;
primaryModel.BLFRT = codeInfo.FrtName;
var mapInfo = tenantDb.Queryable<MappingFrt>().First(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
&& t.CarrierId == order.CarrierId && t.LinkId == codeInfo.Id);
if (mapInfo != null)
{
primaryModel.BLFRTEDICODE = mapInfo.MapCode?.Trim();
}
else
{
primaryModel.BLFRTEDICODE = codeInfo.EdiCode;
}
}
else
{
return DataResult<string>.Failed($"付费方式{order.MBLFrt}的基础代码未找到");
}
}
else
{
return DataResult<string>.Failed($"付费方式{order.MBLFrt}不能为空");
}
}
#region 运输条款EDI
//运输条款EDI
if (!string.IsNullOrWhiteSpace(order.ServiceCode))
{
//long serviceId = long.Parse(order.Service);
var codeInfo = tenantDb.Queryable<CodeService>().First(x => x.Status == StatusEnum.Enable && x.EdiCode == order.ServiceCode);
if (codeInfo != null)
{
//primaryModel.BLFRTEDICODE = codeInfo.EdiCode;
primaryModel.SERVICE = codeInfo.ServiceName;
var mapInfo = tenantDb.Queryable<MappingService>().First(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase)
&& t.CarrierId == order.CarrierId && t.LinkId == codeInfo.Id);
if (mapInfo != null)
{
primaryModel.SERVICEEDICODE = mapInfo.MapCode?.Trim();
}
else
{
primaryModel.SERVICEEDICODE = codeInfo.EdiCode;
}
}
else
{
return DataResult<string>.Failed($"运输条款{order.MBLFrt}的基础代码未找到");
}
}
#endregion
#region 签单方式EDI
////签单方式EDI
if (!string.IsNullOrWhiteSpace(order.IssueTypeCode))
{
//long issueTypeId = long.Parse(order.IssueType);
var codeIssue = tenantDb.Queryable<CodeIssueType>().First(t => t.EdiCode == order.IssueTypeCode);
if (codeIssue == null)
{
return DataResult<string>.Failed($"签单方式{order.IssueTypeCode}的基础代码未找到");
}
var mapInfo = tenantDb.Queryable<MappingIssueType>()
.First(t => t.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && t.CarrierId == order.CarrierId && t.LinkId == codeIssue.Id);
if (mapInfo != null)
{
primaryModel.ISSUETYPE = mapInfo.MapCode;
}
else
{
//签单方式EDI
if (codeIssue != null && !string.IsNullOrWhiteSpace(codeIssue.EdiCode))
{
primaryModel.ISSUETYPE = codeIssue.EdiCode;
}
else
{
return DataResult<string>.Failed($"签单方式{order.Service}的基础代码 EdiCode 未配置");
}
}
}
#endregion
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
{
if (ediRouteEnum == EDIRouteEnum.INTTRA)
{
primaryModel.ORDERNO = order.CustomerNo;
}
else
{
primaryModel.ORDERNO = order.BookingNo;
}
}
if (ediRouteEnum != EDIRouteEnum.INTTRA)
{
//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;
}
}
}
}
List<CodeCtn> codeCtnList = new List<CodeCtn>();
List<MappingCtn> mapCtnList = new List<MappingCtn>();
List<CodePackage> codePackageList = new List<CodePackage>();
List<MappingPackage> mapPackageList = new List<MappingPackage>();
#region 包装方式EDI
if (!string.IsNullOrWhiteSpace(order.KindPkgs))
{
long packageId = long.Parse(order.KindPkgs);
var portRlt = GetPackageEDICode(packageId, codePackageList, mapPackageList, order.CarrierId, CONST_MAPPING_MODULE);
if (codePackageList.Any(b => b.Id == packageId))
primaryModel.KINDPKGS = codePackageList.FirstOrDefault(b => b.Id == packageId).PackageName;
if (portRlt.Succeeded)
{
primaryModel.KINDPKGS_EDI_CODE = portRlt.Data;
}
else
{
return DataResult<string>.Failed($"包装{order.KindPkgs}的映射数据代码未找到");
}
}
else
{
return DataResult<string>.Failed($"包装不能为空");
}
#endregion
//这里是订舱时,默认取SOREMARK赋值到EDIREMARK
if (req.SendType == "B")
{
primaryModel.EDIREMARK = order.SORemark;
}
else if (req.SendType == "E")
{
primaryModel.SIREMARK = order.CloseDocRemark;
}
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;
var opUser = db.Queryable<SysUser>().Filter(null, true).First(x => x.Id == order.OperatorId && x.TenantId == long.Parse(user.TenantId));
if (!string.IsNullOrWhiteSpace(ediExtModel.OpEName))
{
primaryModel.OpEName = ediExtModel.OpEName;
}
else
{
if (opUser != null && !string.IsNullOrWhiteSpace(opUser.UserEnName))
{
primaryModel.OpEName = opUser.UserEnName.Trim();
}
}
if (!string.IsNullOrWhiteSpace(ediExtModel.OpTel))
{
primaryModel.OpTel = ediExtModel.OpTel;
}
else
{
if (opUser != null && !string.IsNullOrWhiteSpace(opUser.Phone))
{
primaryModel.OpTel = opUser.Phone.Trim();
}
}
if (!string.IsNullOrWhiteSpace(ediExtModel.OpEmail))
{
primaryModel.OpEmail = ediExtModel.OpEmail;
}
else
{
if (opUser != null && !string.IsNullOrWhiteSpace(opUser.Email))
{
primaryModel.OpEmail = opUser.Email.Trim();
}
}
/*
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;
}
if (ediRouteEnum == EDIRouteEnum.INTTRA)
{
if (!string.IsNullOrWhiteSpace(ediExtModel.CustomerName))
primaryModel.WEITUO = ediExtModel.CustomerName;
}
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>();
var mapCtnRlt = GetCtnEDICode(conta.CtnCode, codeCtnList, mapCtnList, order.CarrierId, CONST_MAPPING_MODULE, conta.CtnAll, ediRouteEnum);
if (mapCtnRlt.Succeeded)
{
contaModel.CTNALLCODE = mapCtnRlt.Data;
}
else
{
return DataResult<string>.Failed($"箱型{conta.CtnAll}的映射数据代码未找到");
}
//截单时箱的包装必填
if (string.IsNullOrWhiteSpace(conta.KindPkgs) && req.SendType.Equals("E",StringComparison.OrdinalIgnoreCase))
return DataResult<string>.Failed($"集装箱包装不能为空!");
if (!string.IsNullOrWhiteSpace(conta.KindPkgs))
{
long packageId = long.Parse(conta.KindPkgs);
var mapRlt = GetPackageEDICode(packageId, codePackageList, mapPackageList, order.CarrierId, CONST_MAPPING_MODULE);
if (codePackageList.Any(b => b.Id == packageId))
contaModel.KINDPKGS = codePackageList.FirstOrDefault(b => b.Id == packageId).PackageName;
if (mapRlt.Succeeded)
{
contaModel.KINDPKGS_EDI_CODE = mapRlt.Data;
}
else
{
return DataResult<string>.Failed($"集装箱【{conta.CntrNo}】包装{conta.KindPkgs}的映射数据代码未找到");
}
}
else
{
if(req.SendType.Equals("E", StringComparison.OrdinalIgnoreCase))
{
return DataResult<string>.Failed($"集装箱【{conta.CntrNo}】包装{conta.KindPkgs} 不能为空");
}
}
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($"多品名包装不能为空!");
long packageId = long.Parse(cargo.KindPkgs);
var mapRlt = GetPackageEDICode(packageId, codePackageList, mapPackageList, order.CarrierId, CONST_MAPPING_MODULE);
if (codePackageList.Any(b => b.Id == packageId))
cargoModel.KINDPKGS = codePackageList.FirstOrDefault(b => b.Id == packageId).PackageName;
if (mapRlt.Succeeded)
{
cargoModel.KINDPKGS_EDI_CODE = mapRlt.Data;
}
else
{
return DataResult<string>.Failed($"货明细的包装{order.KindPkgs}的映射数据代码未找到");
}
primaryModel.CTNGOODSLIST.Add(cargoModel);
}
//这里增加NOR的判断
if (req.SendType == "B" && order.Carrier.Equals("MSK", StringComparison.OrdinalIgnoreCase) && ediRouteEnum == EDIRouteEnum.INTTRA)
{
//INTTRA 冻代干箱型出现RF、RH并且是普货的温度为空时需要默认温度999
if (contaList.Any(p => p.Ctn.EndsWith("RF") || p.Ctn.EndsWith("RH")) && order.CargoId.Equals("S", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(order.TemperatureSet))
{
primaryModel.TEMPSET = "999";
primaryModel.REEFERF = "999";
//是冻代干
primaryModel.IsNORCtn = true;
}
}
ediModel.BSLIST.Add(primaryModel);
var result = await InnerSendBookingOrClosingEDI(req, ediModel, ediRouteEnum, order.CarrierId);
_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, tenantDb);
//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="req"></param>
/// <returns></returns>
public async Task<DataResult<OpFileDownLoadRes>> DownloadBookingOrClosingEDI(BookingOrClosingEDIOrderReq req)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == req.Id);
var FORWARDER =seaComService.GetClientCode(order.ForwarderId, tenantDb);
var dictvalue = db.Queryable<SysDictData>().InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id)
.Where((a, b) => b.Code == "XiangManCang").Select((a, b) => a.Value).First();
_logger.Info("FORWARDER:" + FORWARDER + "dictvalue:" + dictvalue);
if (!string.IsNullOrEmpty(FORWARDER) && dictvalue == FORWARDER)
{
return await XMCEXCEL(req.Id, true);
}
var res = await InnerBookingOrClosingEDI(req);
if (!res.Succeeded)
{
return await Task.FromResult(DataResult<OpFileDownLoadRes>.Failed(res.Message));
}
var filePath = res.Data;
//var filePath = InnerBookingOrClosingEDI(req).GetAwaiter().GetResult().Data;
var fileInfo = new FileInfo(filePath);
//var result = new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileInfo.Name };
//return result;
var data = new OpFileDownLoadRes()
{
FileName = fileInfo.Name,
FilePath = filePath,
};
return await Task.FromResult(DataResult<OpFileDownLoadRes>.Success(data));
}
#endregion
#region 检查订舱、截单EDI订单信息
/// <summary>
/// 检查订舱、截单EDI订单信息
/// </summary>
/// <param name="order">订舱详情</param>
/// <param name="ctnList">集装箱列表</param>
/// <param name="sendType">发送类型 B-订舱 E-截单</param>
/// <param name="ediRouteEnum">EDI路由枚举</param>
/// <returns></returns>
private DataResult<string> CheckBookingOrClosingEDI(SeaExport order, List<OpCtn> ctnList,string sendType, EDIRouteEnum ediRouteEnum)
{
if (string.IsNullOrWhiteSpace(order.Carrier))
return DataResult<string>.Failed("船公司必须填写!");
//if (string.IsNullOrWhiteSpace(order.OPID))
// throw Oops.Bah("未填写操作人");
if (!(ediRouteEnum == EDIRouteEnum.INTTRA && sendType.Equals("B")))
{
if (string.IsNullOrWhiteSpace(order.KindPkgs))
return DataResult<string>.Failed("包装种类未填写!");
}
//增加箱包装和主信息的包装是否一致校验
if (!string.IsNullOrWhiteSpace(order.KindPkgs) && ctnList.Any(a => !string.IsNullOrWhiteSpace(a.KindPkgs)))
{
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 (sendType.Equals("E"))
{
//增加件、重、尺比对
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("集装箱尺码合计和订舱尺码不一致,请修改!");
}
StringBuilder checkBuilder = new StringBuilder();
if (ctnList.Any(a => string.IsNullOrWhiteSpace(a.CtnCode) || string.IsNullOrWhiteSpace(a.CtnAll)))
{
checkBuilder.Append("集装箱箱型不能为空");
}
if (ctnList.Any(a => a.CtnNum.HasValue || (a.CtnNum.HasValue && a.CtnNum.Value < 1)))
{
checkBuilder.Append("集装箱箱量不能小于1");
}
if(checkBuilder.Length > 0)
{
return DataResult<string>.Failed(checkBuilder.ToString());
}
}
}
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();
}
_logger.Info($"FTP参数{JsonConvert.SerializeObject(ediCfg)}");
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 = CommonFTPHelper.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.Success("请求成功!"));
}
}
#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,long carrierId)
{
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.LinkId == 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
#region 检索港口的EDI代码
/// <summary>
/// 检索港口的EDI代码
/// </summary>
/// <param name="portId">港口ID</param>
/// <param name="codePortList">港口基础表</param>
/// <param name="mapPortList">港口映射表</param>
/// <param name="carrierId">船公司ID</param>
/// <param name="moduleName">模块代码</param>
/// <param name="portName">港口名称</param>
/// <param name="portCategory">港口分类(装货港、卸货港、交货地等)</param>
/// <param name="isNeedMapping">是否必需用映射</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private DataResult<string> GetPortEDICode(long portId,List<CodePort> codePortList,List<MappingPort> mapPortList, long carrierId, string moduleName,
string portName,string portCategory,string needMappingModule = "")
{
//如果历史港口映射有记录直接返回
if (mapPortList.Any(a => a.LinkId == portId))
{
var edi = mapPortList.FirstOrDefault(a => a.LinkId == portId).MapCode;
if (!string.IsNullOrWhiteSpace(edi))
return DataResult<string>.Success(edi);
return DataResult<string>.FailedData(edi);
}
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
string MappingModule = CONST_MAPPING_MODULE;
if (!string.IsNullOrWhiteSpace(needMappingModule))
{
MappingModule = needMappingModule;
}
var mapPortInfo = tenantDb.Queryable<MappingPort>()
.First(a => a.Module.Equals(MappingModule, StringComparison.OrdinalIgnoreCase) && a.CarrierId == carrierId && a.LinkId == portId);
if (mapPortInfo != null)
{
mapPortList.Add(mapPortInfo);
if (!string.IsNullOrWhiteSpace(mapPortInfo.MapCode))
return DataResult<string>.Success(mapPortInfo.MapCode);
return DataResult<string>.FailedData(mapPortInfo.MapCode);
}
//else
//{
// if (!string.IsNullOrWhiteSpace(needMappingModule))
// throw new Exception($"{portCategory} {portName} 未配置模块{needMappingModule} 映射");
//}
if (codePortList.Any(a => a.Id == portId))
{
var edi = codePortList.FirstOrDefault(a => a.Id == portId).EdiCode;
if (!string.IsNullOrWhiteSpace(edi))
return DataResult<string>.Success(edi);
return DataResult<string>.FailedData(edi);
}
var loadPortCodeRlt = seaComService.GetPortInfo(portId, tenantDb).GetAwaiter().GetResult();
if (!loadPortCodeRlt.Succeeded)
{
throw new Exception($"{portCategory} {portName}的港口基础代码未找到");
}
codePortList.Add(loadPortCodeRlt.Data);
if (!string.IsNullOrWhiteSpace(loadPortCodeRlt.Data?.EdiCode))
return DataResult<string>.Success(loadPortCodeRlt.Data?.EdiCode);
return DataResult<string>.FailedData(loadPortCodeRlt.Data?.EdiCode);
}
#endregion
#region 检索集装箱型EDI代码
/// <summary>
/// 检索集装箱型EDI代码
/// </summary>
/// <param name="ctnCodeId">集装箱型ID</param>
/// <param name="codeCtnList">集装箱基础表</param>
/// <param name="mapCtnList">集装箱映射表</param>
/// <param name="carrierId">船公司ID</param>
/// <param name="moduleName">模块代码</param>
/// <param name="ctnName">集装箱名称</param>
/// <returns></returns>
private DataResult<string> GetCtnEDICode(string ctnCode, List<CodeCtn> codeCtnList, List<MappingCtn> mapCtnList, long carrierId, string moduleName
, string ctnName, EDIRouteEnum ediRouteEnum)
{
CodeCtn codeCtnInfo = null;
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
if (codeCtnList.Any(a => a.EdiCode == ctnCode))
{
codeCtnInfo = codeCtnList.FirstOrDefault(a => a.EdiCode == ctnCode);
}
if (codeCtnInfo == null)
{
codeCtnInfo = tenantDb.Queryable<CodeCtn>().First(a => a.EdiCode == ctnCode && a.Status == StatusEnum.Enable);
if (codeCtnInfo != null)
{
codeCtnList.Add(codeCtnInfo);
}
else
{
throw new Exception($"集装箱 {ctnName} 基础代码未找到");
}
}
//如果历史港口映射有记录直接返回
if (mapCtnList.Any(a => a.LinkId == codeCtnInfo.Id))
{
var edi = mapCtnList.FirstOrDefault(a => a.LinkId == codeCtnInfo.Id).MapCode;
if (!string.IsNullOrWhiteSpace(edi))
return DataResult<string>.Success(edi);
return DataResult<string>.FailedData(edi);
}
MappingCtn mapCtnInfo = null;
//如果是亿通需要读映射表,如果映射表没配置则提示错误
if(ediRouteEnum == EDIRouteEnum.YT)
{
mapCtnInfo = tenantDb.Queryable<MappingCtn>()
.First(a => a.Module.Equals("BOOK_OR_CLOSING_YT", StringComparison.OrdinalIgnoreCase) && a.CarrierId == carrierId && a.LinkId == codeCtnInfo.Id);
if (mapCtnInfo == null)
{
throw new Exception($"集装箱型 {ctnName} 未配置订舱或截单EDT亿通的映射代码未找到");
}
}
else
{
mapCtnInfo = tenantDb.Queryable<MappingCtn>()
.First(a => a.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && a.CarrierId == carrierId && a.LinkId == codeCtnInfo.Id);
}
if (mapCtnInfo != null)
{
mapCtnList.Add(mapCtnInfo);
if (!string.IsNullOrWhiteSpace(mapCtnInfo.MapCode))
return DataResult<string>.Success(mapCtnInfo.MapCode);
throw new Exception($"集装箱型 {ctnName}的映射代码未找到");
}
else
{
if (codeCtnInfo != null && !string.IsNullOrWhiteSpace(codeCtnInfo.EdiCode))
{
return DataResult<string>.Success(codeCtnInfo.EdiCode);
}
throw new Exception($"集装箱型 {ctnName}基础代码EDI 错误");
}
}
#endregion
#region 检索包装EDI代码
/// <summary>
/// 检索包装EDI代码
/// </summary>
/// <param name="packageCodeId">包装ID</param>
/// <param name="codePackageList">包装基础表</param>
/// <param name="mapPackageList">包装映射表</param>
/// <param name="carrierId">船公司ID</param>
/// <param name="moduleName">模块代码</param>
/// <param name="packageName">包装名称</param>
/// <returns></returns>
private DataResult<string> GetPackageEDICode(long packageCodeId, List<CodePackage> codePackageList, List<MappingPackage> mapPackageList, long carrierId, string moduleName)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
if (!codePackageList.Any(b => b.Id == packageCodeId))
{
var codePackage = tenantDb.Queryable<CodePackage>().First(a => a.Id == packageCodeId);
if (codePackage != null)
codePackageList.Add(codePackage);
}
//如果历史港口映射有记录直接返回
if (mapPackageList.Any(a => a.LinkId == packageCodeId))
{
var edi = mapPackageList.FirstOrDefault(a => a.LinkId == packageCodeId).MapCode;
if (!string.IsNullOrWhiteSpace(edi))
return DataResult<string>.Success(edi);
//return DataResult<string>.FailedData(edi);
}
//优先判断跟船公司设置包装映射,如果没有取默认映射
var mapPackageInfo = tenantDb.Queryable<MappingPackage>()
.First(a => a.Module.Equals(CONST_MAPPING_MODULE, StringComparison.OrdinalIgnoreCase) && a.CarrierId == carrierId && a.LinkId == packageCodeId);
if (mapPackageInfo != null)
{
mapPackageList.Add(mapPackageInfo);
if (!string.IsNullOrWhiteSpace(mapPackageInfo.MapCode))
return DataResult<string>.Success(mapPackageInfo.MapCode);
//return DataResult<string>.FailedData(mapPackageInfo.MapCode);
throw new Exception($"包装的映射代码未找到");
}
else
{
var codePackage = codePackageList.FirstOrDefault(b => b.Id == packageCodeId);
if(codePackage != null && !string.IsNullOrWhiteSpace(codePackage.EdiCode))
{
return DataResult<string>.Success(codePackage.EdiCode);
}
throw new Exception($"包装的基础信息EDI代码未找到");
}
//else
//{
//
//}
}
#endregion
#region 推送东胜(MQ)
/// <summary>
/// 推送东胜(MQ)
/// </summary>
/// <param name="ids">海运订单主键数组</param>
/// <returns></returns>
public async Task<DataResult> SendBookingOrder(long[] ids)
{
var logTitle = $"同步订舱数据ids:{string.Join(',', ids.ToList())}";
_logger.Info($"开始{logTitle}");
var BookingOrderMQUri = AppSetting.app(new string[] { "SyncDongSheng7", "MQConfig" });
var paramConfig = _configService.GetConfig(CONST_AUTO_SYNC_DONGSHENG_BY_MQ, long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
_logger.Info($"{logTitle}订舱数据回推地址:{BookingOrderMQUri}{CONST_AUTO_SYNC_DONGSHENG_BY_MQ}{paramConfig}");
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
if (!string.IsNullOrEmpty(paramConfig) && paramConfig.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
{
if (ids.Count() == 0)
{
_logger.Info($"{logTitle}请求参数错误,未提供上传订单的主键,结束");
throw new Exception("请求参数错误,未提供上传订单的主键");
}
var order = await tenantDb.Queryable<SeaExport>().Filter(null, true).Where(x => ids.Contains(x.Id) && x.Deleted == false).ToListAsync();
if (order.Count == 0)
{
_logger.Info($"{logTitle}未查到订舱数据,结束");
return DataResult.Failed($"{logTitle}未查到订舱数据,结束");
}
foreach (var item in order)
{
//2023-9-8增加校验分单不能单独推送东胜只能随主单推送
if (item.ParentId > 0)
{
_logger.Info($"Id:{item.Id}分单不能单独推送东胜只能随主单推送continue跳过");
continue;
}
//2023-9-26添加校验推送前通过Cache判断一下待推送的数据是否正在走删除逻辑
if (_redisBaseService.Exists($"DeletingBookingOrderId_{item.Id}"))
{
_logger.Info($"Id:{item.Id}正在走删除逻辑continue跳过");
continue;
}
var dto = item.Adapt<SyncBookingOrderDto>();
//if (syncTypeEnum != null)
//{
// dto.SyncType = syncTypeEnum.ToString();
//}
if (!string.IsNullOrWhiteSpace(dto.YARDREMARK))
{
dto.YARDREMARK += "\\n" + item.BookingSlotTypeName;
}
else
{
dto.YARDREMARK = item.BookingSlotTypeName;
}
List<EmbedServiceProjectStatusResultDto> statusList = new List<EmbedServiceProjectStatusResultDto>();
EmbedQueryServiceProjectWithStatus queryInfo = new EmbedQueryServiceProjectWithStatus
{
BusinessId = item.Id.ToString(),
QueryType = 2,
TenantId = long.Parse(user.TenantId)
};
var queryRlt = await _djyServiceStatusService.GetServiceStatusList(queryInfo);
if (queryRlt.success)
{
statusList = JsonConvert.DeserializeObject<List<EmbedServiceProjectStatusResultDto>>(JsonConvert.SerializeObject(queryRlt.data));
}
if (statusList != null && statusList.Any(x => x.StatusSKUCode == "SQXS" && x.IsYield))
{
dto.CtnDayNum = statusList.FirstOrDefault(x => x.StatusSKUCode == "SQXS" && x.IsYield)?.ActVal;
}
var ctn = await tenantDb.Queryable<OpCtn>().Filter(null, true).Where(x => x.BSNO == item.Id.ToString() && x.Deleted == false).ToListAsync();
dto.ctnInputs = ctn.Adapt<List<BookingCtnDto>>();
foreach (var it in dto.ctnInputs)
{
var ctnDetailInputs = await tenantDb.Queryable<OpCtnDetail>().Filter(null, true).Where(x => x.CtnId == it.Id && x.Deleted == false).ToListAsync();
it.ctnDetailInputs = ctnDetailInputs.Adapt<List<BookingCtnDetailDto>>();
}
//2024-06-20 这里如果遇到拆票情况需要重新组织提单号
if (item.SplitOrMergeFlag == 1 || item.SplitOrMergeFlag == 2)
{
dto.MBLNO = $"{item.MBLNO}-{item.HBLNO}";
//如果当前是合票时,需要所有子票的箱型箱量合并到主票同步到东胜,子票的箱型箱量不同步东胜
if (item.SplitOrMergeFlag == 2)
{
//如果当前是主票
if (dto.CUSTNO.Equals(dto.HBLNO, StringComparison.OrdinalIgnoreCase))
{
var allOrderList = await tenantDb.Queryable<SeaExport>().Filter(null, true).Where(x => dto.HBLNO == x.HBLNO && (x.SplitOrMergeFlag == 2)
&& x.Deleted == false).ToListAsync();
if (allOrderList.Count > 0)
{
var allOrderIds = allOrderList.Select(x => x.Id).ToList();
var currCtn = await tenantDb.Queryable<OpCtn>().Filter(null, true).Where(x => x.BSNO != null && allOrderIds.Contains(long.Parse(x.BSNO))
&& x.Deleted == false).ToListAsync();
dto.ctnInputs = currCtn.Adapt<List<BookingCtnDto>>();
foreach (var it in dto.ctnInputs)
{
var ctnDetailInputs = await tenantDb.Queryable<OpCtnDetail>().Filter(null, true).Where(x => x.CtnId == it.Id && x.Deleted == false).ToListAsync();
it.ctnDetailInputs = ctnDetailInputs.Adapt<List<BookingCtnDetailDto>>();
}
dto.CNTRTOTAL = string.Join(",", dto.ctnInputs.GroupBy(x => x.CTNALL).Select(x => $"{x.Key}*{x.Sum(b => b.CTNNUM)}").ToArray());
}
}
else
{
dto.ctnInputs = new List<BookingCtnDto>();
dto.CNTRTOTAL = string.Empty;
}
}
}
//EDI
var BookingEDIExt = await tenantDb.Queryable<SeaExportEdi>().Filter(null, true).Where(x => x.BusinessId == item.Id && x.Deleted == false).FirstAsync();
if (BookingEDIExt != null)
{
dto.BookingEDIExt = BookingEDIExt.Adapt<BookingEDIExtDto>();
}
if (statusList != null && statusList.Any(x => x.IsYield))
{
dto.GoodsStatus = statusList.Where(x => x.IsYield).OrderBy(x => x.SortNo).Select(x => new BookingGoodsStatusDto
{
StatusName = x.ShowName,
FinishTime = x.ActDate,
Remark = x.ActRemark,
ExtData = x.ActVal
}).ToList();
}
else
{
dto.GoodsStatus = new List<BookingGoodsStatusDto>();
}
//等拓展数据
var extData = await tenantDb.Queryable<BookingExtendState>().Filter(null, true).FirstAsync(x => x.BusinessId == item.Id);
if (extData != null)
{
dto.ExtendState = extData.Adapt<BookingExtendStateDto>();
}
//提箱返场
var statusloglist = tenantDb.Queryable<BookingStatusLog>().Filter(null, true).Where(x => x.BusinessId == item.Id && x.Deleted == false && x.Group == "yunzong").ToList();
var statuslogId = statusloglist.Select(x => x.Id).ToList();
//运踪状态详情
var statuslogdetaillist = tenantDb.Queryable<BookingStatusLogDetail>().Where(x => statuslogId.Contains(x.PId)).ToList();
var staLogListDto = statusloglist.Adapt<List<BookingStatusLogSyncDto>>();
dto.StatusLogs = staLogListDto;
foreach (var sl in dto.StatusLogs)
{
var detailList = statuslogdetaillist.Where(x => x.PId == sl.Id).ToList();
sl.Details = detailList.Adapt<List<BookingStatusLogDetailSyncDto>>();
}
var childrens = await tenantDb.Queryable<SeaExport>().Filter(null, true).Where(x => x.ParentId == item.Id && x.Deleted == false).ToListAsync();
dto.childrens = childrens.Adapt<List<Children>>();
var files = await tenantDb.Queryable<OpFile>().Filter(null, true).Where(x => x.LinkId == item.Id).ToListAsync();
dto.Files = files.Select(x => new DownloadFile()
{
Id = x.Id,
FileName = x.FileName,
FileType = x.TypeCode,
FilePath = x.FilePath
}).ToList();
foreach (var childitem in dto.childrens)
{
var ctnInputs = await tenantDb.Queryable<OpCtn>().Filter(null, true).Where(x => x.BSNO == childitem.Id.ToString() && x.Deleted == false).ToListAsync();
childitem.ctnInputs = ctnInputs.Adapt<List<BookingCtnDto>>();
foreach (var it in childitem.ctnInputs)
{
var ctnDetailInputs = await tenantDb.Queryable<OpCtnDetail>().Filter(null, true).Where(x => x.CtnId == it.Id && x.Deleted == false).ToListAsync();
it.ctnDetailInputs = ctnDetailInputs.Adapt<List<BookingCtnDetailDto>>();
}
var childBookingEDIExt = await tenantDb.Queryable<SeaExportEdi>().Filter(null, true).Where(x => x.BusinessId == childitem.Id && x.Deleted == false).FirstAsync();
if (childBookingEDIExt != null)
{
childitem.BookingEDIExt = childBookingEDIExt.Adapt<BookingEDIExtDto>();
}
}
var json = dto.ToJsonString();
json = $"[{json}]";
_logger.Info($"Id:{item.Id},订舱数据回推,消息内容:{json}");
string MqActionExchangeName = AppSetting.app(new string[] { "SyncDongSheng7", "MQExchangeNameDingCang" }); //djy.output.dingcang.ds6
string MqActionQueueName = AppSetting.app(new string[] { "SyncDongSheng7", "MQQueueNameDingCang" }); //djy.output.dingcang.ds6
var mqRlt = await _rabbitMQService.PublishMessage(new Module.MQ.MQPublishMessageReqDto
{
BusinessId = item.Id.ToString(),
IsZip = true,
json = JsonConvert.SerializeObject(dto),
mqUri = BookingOrderMQUri,
mqExchangeName = MqActionExchangeName,
mqQueueName = $"{MqActionQueueName}.{user.TenantId}"
});
if (!mqRlt.Succeeded)
{
_logger.Info(mqRlt.Message);
}
await SendLetterYard(item.Id);
}
return DataResult.Successed("同步完成");
}
else
{
_logger.Info($"当前未开启同步东胜功能需要开通请在系统参数增加【自动同步订单到东胜7通过MQ】AutoSyncBookingOrderToDongshengMQ");
}
return DataResult.Failed($"当前未开启同步东胜功能需要开通请在系统参数增加【自动同步订单到东胜7通过MQ】AutoSyncBookingOrderToDongshengMQ");
}
#endregion
#region 放舱推送东胜
/// <summary>
/// 放舱推送东胜
/// </summary>
/// <returns></returns>
public async Task<DataResult> SendLetterYard(long bookingId)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var entity = tenantDb.Queryable<BusinessYard>().Filter(null, true).First(x => x.BusinessId == bookingId && x.Deleted == false);
if (entity != null)
{
var json = entity.ToJsonString();
var BookingOrderMQUri = AppSetting.app(new string[] { "SyncDongSheng7", "MQConfig" });
string MqActionExchangeName = AppSetting.app(new string[] { "SyncDongSheng7", "MQExchangeNameFangCang" }); //djy.output.dingcang.ds6
string MqActionQueueName = AppSetting.app(new string[] { "SyncDongSheng7", "MQQueueNameFangCang" }); //djy.output.dingcang.ds6
var mqRlt = await _rabbitMQService.PublishMessage(new Module.MQ.MQPublishMessageReqDto
{
BusinessId = entity.BusinessId.ToString(),
IsZip = false,
json = JsonConvert.SerializeObject(entity),
mqUri = BookingOrderMQUri,
mqExchangeName = MqActionExchangeName,
mqQueueName = $"{MqActionQueueName}.{user.TenantId}"
});
if (!mqRlt.Succeeded)
{
_logger.Info(mqRlt.Message);
}
_logger.Info($"放舱数据回推,已发送数据到消息队列【{BookingOrderMQUri}】,数据内容:【{json}】 结果={mqRlt.Message}");
return mqRlt;
}
else
{
return DataResult.Failed($"bookingId={bookingId} 放舱信息获取失败");
}
}
#endregion
}
}