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

341 lines
12 KiB
C#

using Furion.FriendlyException;
using Furion.Logging;
using Microsoft.Extensions.Logging;
using NPOI.HPSF;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Myshipping.Application.EDI.VOLTA
{
/// <summary>
/// VOLTA EDI帮助类
/// </summary>
public static class VOLTAEdiHelper
{
#region 生成VOLTA申报报文截单
/// <summary>
/// 生成VOLTA申报报文截单
/// </summary>
/// <param name="model">VOLTA申报详情</param>
/// <returns>返回回执</returns>
public static CommonWebApiResult CreateEdiVOLTA(VOLTAEDIBaseModel model)
{
CommonWebApiResult result = new CommonWebApiResult { succ = false };
//日志
var logger = Log.CreateLogger(nameof(VOLTAEdiHelper));
try
{
ValidateInput(model);
string bno = model.BookingId;
string filePath = model.FilePath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
//预先创建目录
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
string filename = filePath + "\\" + bno + ".txt";
//如果是部署linux需要修改路径
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
filename = filename.Replace("\\", "/");
FileStream f = new FileStream(filename, FileMode.Create);
StreamWriter r = new StreamWriter(f, Encoding.Default);
DateTime nowDate = DateTime.Now;
r.WriteLine("<FROMSHIPPER>FROMSHIPPER</FROMSHIPPER>");
//订舱号
r.WriteLine("<bok>" + model.BookingId + "</bok>");
//发货人
r.WriteLine("<spr>" + model.ShpperName + "</spr>");
//发货人地址
r.WriteLine("<sad>");
r.WriteLine(model.ShpperAddr);
r.WriteLine("</sad>");
//收货人
r.WriteLine("<cne>" + model.ConsigneeName + "</cne>");
//收货人地址
r.WriteLine("<cad>");
r.WriteLine(model.ConsigneeAddr);
r.WriteLine("</cad>");
//通知人
r.WriteLine("<nfy>" + model.NotifyName + "</nfy>");
//通知人地址
r.WriteLine("<nad>");
r.WriteLine(model.NotifyAddr);
r.WriteLine("</nad>");
//通知人1
if (!string.IsNullOrWhiteSpace(model.NotifySecondName))
{
r.WriteLine("<nf1>" + model.NotifySecondName + "</nf1>");
}
else
{
r.WriteLine("<nf1></nf1>");
}
//通知人1地址
if (!string.IsNullOrWhiteSpace(model.NotifySecondName))
{
r.WriteLine("<na1>");
r.WriteLine(model.ConsigneeAddr);
r.WriteLine("</na1>");
}
else
{
r.WriteLine("<na1></na1>");
}
//发货地
r.WriteLine("<Poo>" + model.PlaceOfOrigin + "</Poo>");
//起运港
r.WriteLine("<pol>" + model.LoadPort + "</pol>");
//卸货港
r.WriteLine("<pod>" + model.DischargePort + "</pod>");
//最终目的港
r.WriteLine("<fpd>" + model.FinalDestination + "</fpd>");
//最终交货地
r.WriteLine("<pdy>" + model.PlaceOfDelivery + "</pdy>");
//PlaceOfReceipt
r.WriteLine("<por></por>");
//提单正本份数默认3
r.WriteLine("<nob>3</nob>");
//提单状态(默认S) S-SHIPPED ON BOARD;R-RECEIVED FOR SHIPMENT;T-THRO BL
r.WriteLine("<blt>S</blt>");
//重量单位默认1 1-KGS2-TON3-QUINTAL4-MT5-CENTIMETER6-METER7-INCH
r.WriteLine("<uom>1</uom>");
//Payable At
r.WriteLine("<pat></pat>");
//Prepaid / Collect(默认P) P-PREPAIDC-COLLECT
r.WriteLine("<fst>P</fst>");
//EDNumber
r.WriteLine("<edn></edn>");
//货描
r.WriteLine("<des>");
r.WriteLine(model.CargoDescription);
r.WriteLine("</des>");
//唛头
r.WriteLine("<cmn>");
r.WriteLine(model.Marks);
r.WriteLine("</cmn>");
//模板版本号
r.WriteLine("<ver>");
r.WriteLine(model.TemplateVersion);
r.WriteLine("</ver>");
//箱明细
r.WriteLine("<cnt>");
r.Write(GetContaInfo(model.ContaList));
r.WriteLine("</cnt>");
r.Close();
f.Close();
result.succ = true;
result.extra = filename;
result.extra2 = $"截单样本:{model.Vessel} {model.VoyNo} {model.BookingId}";
}
catch(Exception ex)
{
result.succ = false;
result.msg = ex.Message;
}
return result;
}
#endregion
#region 拼接箱明细报文
/// <summary>
/// 拼接箱明细报文
/// </summary>
/// <param name="contaList">箱明细</param>
/// <returns>返回拼接后字符</returns>
private static string GetContaInfo(List<VOLTAEDIContaModel> contaList)
{
StringBuilder txtBuilder = new StringBuilder();
//日志
var logger = Log.CreateLogger(nameof(VOLTAEdiHelper));
try
{
contaList.ForEach(ctn =>
{
//箱拼接格式:序号~箱号~铅封号~Custom Seal No~毛重~净重~尺码~重量单位~~件数~~~包装
txtBuilder.AppendLine($"{ctn.SNo}~{ctn.ContaNo}~{ctn.SealNo}~~{ctn.GWt.Value.ToString("0.###")}~{(ctn.NWt.HasValue ? ctn.NWt.Value.ToString("0.###") : "")}~{ctn.CBM.Value.ToString("0.###")}~{ctn.WTUnit}~{ctn.Qty.Value.ToString("#.###")}~~~{ctn.EdiPkgs}");
});
}
catch (Exception ex)
{
logger.LogInformation("VOLTA拼接箱明细异常,原因:{0}", ex.Message);
throw ex;
}
return txtBuilder.ToString();
}
#endregion
#region 校验VOLTA请求参数s
/// <summary>
/// 校验VOLTA请求参数
/// </summary>
/// <param name="model">VOLTA请求参数</param>
public static void ValidateInput(VOLTAEDIBaseModel model)
{
StringBuilder msgBuilder = new StringBuilder();
if (string.IsNullOrEmpty(model.BookingId))
msgBuilder.AppendLine("提单号不能为空");
if (string.IsNullOrEmpty(model.ShpperName))
msgBuilder.AppendLine("发货人名称不能为空");
if (string.IsNullOrEmpty(model.ShpperAddr))
msgBuilder.AppendLine("发货人地址不能为空");
if (!string.IsNullOrEmpty(model.ShpperAddr))
{
if(model.ShpperAddr.Length > 450)
msgBuilder.AppendLine("发货人地址不能大于450个字符");
}
if (string.IsNullOrEmpty(model.ConsigneeName))
msgBuilder.AppendLine("收货人名称不能为空");
if (string.IsNullOrEmpty(model.ConsigneeAddr))
msgBuilder.AppendLine("收货人地址不能为空");
if (!string.IsNullOrEmpty(model.ConsigneeAddr))
{
if (model.ConsigneeAddr.Length > 450)
msgBuilder.AppendLine("收货人地址不能大于450个字符");
}
if (string.IsNullOrEmpty(model.NotifyName))
msgBuilder.AppendLine("通知人名称不能为空");
if (string.IsNullOrEmpty(model.NotifyAddr))
msgBuilder.AppendLine("通知人地址不能为空");
if (!string.IsNullOrEmpty(model.NotifyAddr))
{
if (model.NotifyAddr.Length > 450)
msgBuilder.AppendLine("通知人地址不能大于450个字符");
}
if (!string.IsNullOrEmpty(model.NotifySecondName) && string.IsNullOrEmpty(model.NotifySecondAddr))
msgBuilder.AppendLine("通知人1地址不能为空");
if (string.IsNullOrEmpty(model.NotifySecondName) && !string.IsNullOrEmpty(model.NotifySecondAddr))
msgBuilder.AppendLine("通知人1名称不能为空");
if (!string.IsNullOrEmpty(model.NotifySecondAddr))
{
if (model.NotifySecondAddr.Length > 450)
msgBuilder.AppendLine("通知人1地址不能大于450个字符");
}
if (string.IsNullOrEmpty(model.PlaceOfOrigin))
msgBuilder.AppendLine("发货地不能为空");
if (string.IsNullOrEmpty(model.LoadPort))
msgBuilder.AppendLine("起运港不能为空");
if (string.IsNullOrEmpty(model.DischargePort))
msgBuilder.AppendLine("卸货港不能为空");
if (string.IsNullOrEmpty(model.FinalDestination))
msgBuilder.AppendLine("最终目的港不能为空");
if (string.IsNullOrEmpty(model.PlaceOfDelivery))
msgBuilder.AppendLine("最终交货地不能为空");
if (string.IsNullOrEmpty(model.CargoDescription))
msgBuilder.AppendLine("品名不能为空");
if (!string.IsNullOrEmpty(model.CargoDescription))
{
if (model.CargoDescription.Length > 3000)
msgBuilder.AppendLine("品名不能大于3000个字符");
}
if (string.IsNullOrEmpty(model.Marks))
msgBuilder.AppendLine("唛头不能为空");
if (!string.IsNullOrEmpty(model.Marks))
{
if (model.Marks.Length > 1000)
msgBuilder.AppendLine("唛头不能大于1000个字符");
}
if (model.ContaList == null || model.ContaList.Count == 0)
msgBuilder.AppendLine("箱明细不能为空");
model.ContaList.ForEach(ctn =>
{
StringBuilder ctnMsgBuilder = new StringBuilder();
if (string.IsNullOrWhiteSpace(ctn.ContaNo))
{
ctnMsgBuilder.Append("箱号不能为空;");
}
else
{
if (ctn.ContaNo.Length > 11)
{
ctnMsgBuilder.Append("箱号长度不能大于11");
}
}
if (string.IsNullOrWhiteSpace(ctn.SealNo))
{
ctnMsgBuilder.Append("铅封号不能为空;");
}
if(!ctn.GWt.HasValue)
{
ctnMsgBuilder.Append("毛重不能为空;");
}
if (!ctn.CBM.HasValue)
{
ctnMsgBuilder.Append("尺寸不能为空;");
}
if (!ctn.Qty.HasValue)
{
ctnMsgBuilder.Append("件数不能为空;");
}
if (string.IsNullOrWhiteSpace(ctn.EdiPkgs))
{
ctnMsgBuilder.Append("包装不能为空;");
}
if (ctnMsgBuilder.Length > 0)
{
msgBuilder.AppendLine($"箱【{ctn.SNo}】{ctnMsgBuilder.ToString()}");
}
});
if (msgBuilder.Length > 0)
throw Oops.Bah(msgBuilder.ToString());
}
#endregion
}
}