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(""); 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 } }