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
{
///
/// VOLTA EDI帮助类
///
public static class VOLTAEdiHelper
{
#region 生成VOLTA申报报文(截单)
///
/// 生成VOLTA申报报文(截单)
///
/// VOLTA申报详情
/// 返回回执
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");
//订舱号
r.WriteLine("" + model.BookingId + "");
//发货人
r.WriteLine("" + model.ShpperName + "");
//发货人地址
r.WriteLine("");
r.WriteLine(model.ShpperAddr);
r.WriteLine("");
//收货人
r.WriteLine("" + model.ConsigneeName + "");
//收货人地址
r.WriteLine("");
r.WriteLine(model.ConsigneeAddr);
r.WriteLine("");
//通知人
r.WriteLine("" + model.NotifyName + "");
//通知人地址
r.WriteLine("");
r.WriteLine(model.NotifyAddr);
r.WriteLine("");
//通知人1
if (!string.IsNullOrWhiteSpace(model.NotifySecondName))
{
r.WriteLine("" + model.NotifySecondName + "");
}
else
{
r.WriteLine("");
}
//通知人1地址
if (!string.IsNullOrWhiteSpace(model.NotifySecondName))
{
r.WriteLine("");
r.WriteLine(model.ConsigneeAddr);
r.WriteLine("");
}
else
{
r.WriteLine("");
}
//发货地
r.WriteLine("" + model.PlaceOfOrigin + "");
//起运港
r.WriteLine("" + model.LoadPort + "");
//卸货港
r.WriteLine("" + model.DischargePort + "");
//最终目的港
r.WriteLine("" + model.FinalDestination + "");
//最终交货地
r.WriteLine("" + model.PlaceOfDelivery + "");
//PlaceOfReceipt
r.WriteLine("");
//提单正本份数默认3
r.WriteLine("3");
//提单状态(默认S) S-SHIPPED ON BOARD;R-RECEIVED FOR SHIPMENT;T-THRO BL
r.WriteLine("S");
//重量单位(默认1) 1-KGS;2-TON;3-QUINTAL;4-MT;5-CENTIMETER;6-METER;7-INCH
r.WriteLine("1");
//Payable At
r.WriteLine("");
//Prepaid / Collect(默认P) P-PREPAID;C-COLLECT
r.WriteLine("P");
//EDNumber
r.WriteLine("");
//货描
r.WriteLine("");
r.WriteLine(model.CargoDescription);
r.WriteLine("");
//唛头
r.WriteLine("");
r.WriteLine(model.Marks);
r.WriteLine("");
//模板版本号
r.WriteLine("");
r.WriteLine(model.TemplateVersion);
r.WriteLine("");
//箱明细
r.WriteLine("");
r.Write(GetContaInfo(model.ContaList));
r.WriteLine("");
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 拼接箱明细报文
///
/// 拼接箱明细报文
///
/// 箱明细
/// 返回拼接后字符
private static string GetContaInfo(List 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
///
/// 校验VOLTA请求参数
///
/// VOLTA请求参数
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
}
}