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/ZhongYuanSoApiHelper.cs

783 lines
26 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 Furion;
using Furion.Logging;
using Furion.RemoteRequest.Extensions;
using Myshipping.Application.Entity;
using Myshipping.Application.Helper;
using Myshipping.Core;
using Myshipping.Core.Entity;
using Myshipping.Core.Service;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Myshipping.Application.EDI
{
/// <summary>
/// 中远API订舱
/// </summary>
public static class ZhongYuanSoApiHelper
{
public async static Task<KeyValuePair<bool, string>> DoPost(long custOrderId)
{
var repCustOrder = App.GetService<SqlSugarRepository<BookingCustomerOrder>>();
var repOrder = App.GetService<SqlSugarRepository<BookingOrder>>();
var repCtn = App.GetService<SqlSugarRepository<BookingCtn>>();
var repCustomer = App.GetService<SqlSugarRepository<DjyCustomer>>();
var repContact = App.GetService<SqlSugarRepository<DjyCustomerContact>>();
var repTemplate = App.GetService<SqlSugarRepository<BookingSoTemplate>>();
var cache = App.GetService<ISysCacheService>();
var cacheService = App.GetService<ISysCacheService>();
var custOrder = await repCustOrder.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == custOrderId);
if (custOrder == null)
{
return new KeyValuePair<bool, string>(false, "客户订舱信息未找到");
}
var sysConfigList = await cache.GetAllSysConfig();
var sCfgSpiderUrl = sysConfigList.FirstOrDefault(x => x.Code == "ZhongYuanApiSpiderUrl" && x.GroupCode == "DJY_CONST");
if (sCfgSpiderUrl == null)
{
return new KeyValuePair<bool, string>(false, "中远订舱API的爬虫URL地址未配置请联系管理员");
}
var sCfgUserKey = sysConfigList.FirstOrDefault(x => x.Code == "ZhongYuanApiSpiderKey" && x.GroupCode == "DJY_CONST");
var sCfgUserSecret = sysConfigList.FirstOrDefault(x => x.Code == "ZhongYuanApiSpiderSecret" && x.GroupCode == "DJY_CONST");
if (sCfgUserKey == null || sCfgUserSecret == null)
{
return new KeyValuePair<bool, string>(false, "中远订舱API的KEY和密钥未配置请联系管理员");
}
BookingSoTemplate template = null;
DjyCustomerContact custContact = null;
var postModel = new ZhongYuanSoApiModel();
postModel.webAccount = custOrder.BookingAccount;
postModel.webPassword = custOrder.BookingPassword;
//查找模板:
//1.根据客户订舱信息中的BookingUserId和BookingTenantId去客户信息中根据CustSysId查找客户公司及联系人员工信息
//2.根据找到的客户及联系人信息,查找中远订舱模板
if (custOrder.BookingUserId > 0 && custOrder.BookingTenantId > 0)
{
custContact = await repCustomer.AsQueryable().Filter(null, true)
.InnerJoin<DjyCustomerContact>((cust, contact) => cust.Id == contact.CustomerId)
.Where((cust, contact) => cust.CustSysId == custOrder.BookingTenantId && contact.CustSysId == custOrder.BookingUserId)
.Select((cust, contact) => contact)
.SingleAsync();
if (custContact == null)
{
return new KeyValuePair<bool, string>(false, "未找到客户及联系人信息");
}
//根据:用户+船司+船司账号+约号,找到启用的模板
template = await repTemplate.AsQueryable().Filter(null, true).FirstAsync(x => x.IsDeleted == false && x.CarrierId == custOrder.CARRIERID && x.UserId == custContact.Id && x.IsEnable);
if (template == null)
{
return new KeyValuePair<bool, string>(false, "未找到订舱模板");
}
}
else
{
return new KeyValuePair<bool, string>(false, "未找到客户端公司和用户ID");
}
var mappingCtn = await cache.GetAllMappingCtn();
var mappingFrt = await cache.GetAllMappingFrt();
var mappingPortLoad = await cache.GetAllMappingPortLoad();
var mappingPort = await cache.GetAllMappingPort();
postModel.userKey = sCfgUserKey.Value;
postModel.userSecret = sCfgUserSecret.Value;
postModel.uploadType = template.Category; //DRAFT, TEMPLATE, BOOKING分别对应草稿, 模板, 订舱
postModel.saveName = template.TemplateName;
//起运港
var mapPortLoad = mappingPortLoad.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.PORTLOADCODE);
if (mapPortLoad == null)
{
return new KeyValuePair<bool, string>(false, $"未找到起运港映射信息:{custOrder.PORTLOADCODE}");
}
//目的地2024-5-9衣国豪需求由目的港改为目的地
var mapPort = mappingPort.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.DESTINATIONCODE);
if (mapPort == null)
{
return new KeyValuePair<bool, string>(false, $"未找到目的地映射信息:{custOrder.DESTINATIONCODE}");
}
//运输条款
var mappingService = await cacheService.GetAllMappingService();
var mappService = mappingService.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.SERVICE);
if (mappService == null)
{
return new KeyValuePair<bool, string>(false, $"未找到运输条款映射信息:{custOrder.SERVICE}");
}
if (!Regex.IsMatch(mappService.MapCode, "^[A-Za-z]+-[A-Za-z]+$"))
{
return new KeyValuePair<bool, string>(false, $"映射配置不正确:{mappService.MapCode}");
}
var mapServArr = mappService.MapCode.Split('-');
//var startDay = template.StartDay.HasValue ? template.StartDay.Value : 1;
//var endWeek = template.EndWeek.HasValue ? template.EndWeek.Value : 2;
postModel.routes = new ZhongYuanSoApiRoute()
{
originCity = mapPortLoad.MapCode,
destinationCity = mapPort.MapCode,
polPortName = custOrder.PolPortName,
podPortName = custOrder.PodPortName,
vesselName = custOrder.VESSEL,
voyageNumber = custOrder.VOYNO,
serviceCode = custOrder.LANECODE,
//sailSchedulePriority = template.Priority.Split(',').ToList(),
outboundHaulage = mapServArr[0],
inboundHaulage = mapServArr[1],
searchConditionDate = custOrder.ETD.Value.AddDays(-2).ToString("yyyy-MM-dd"),
numberOfWeeks = 2,
etd = custOrder.ETD.Value.ToString("yyyy-MM-dd"),
};
#region 收发通及货代
//发货人
ZhongYuanSoApiPhone shipperPhone = null;
//if (string.IsNullOrEmpty(template.ShipperName))
//{
shipperPhone = new ZhongYuanSoApiPhone()
{
countryCode = custOrder.ShipperPhoneCountryCode,
areaCode = custOrder.ShipperPhoneCode,
number = custOrder.ShipperPhone
};
//}
//else
//{
// shipperPhone = new ZhongYuanSoApiPhone()
// {
// countryCode = template.ShipperPhoneCountryCode,
// areaCode = template.ShipperPhoneCode,
// number = template.ShipperPhone
// };
//}
shipperPhone.countryCode = shipperPhone.countryCode == null ? "" : shipperPhone.countryCode;
shipperPhone.areaCode = shipperPhone.areaCode == null ? "" : shipperPhone.areaCode;
shipperPhone.number = shipperPhone.number == null ? "" : shipperPhone.number;
postModel.shipperInfo = new ZhongYuanSoApiSFT()
{
firstName = custOrder.ShipperFirstName,
lastName = custOrder.ShipperLastName,
country = custOrder.ShipperCountry,
state = custOrder.ShipperProvince,
city = custOrder.ShipperCity,
partyName = custOrder.ShipperName,
addressDes = custOrder.ShipperAddress,
phone = shipperPhone,
postalCode = custOrder.ShipperPostCode
};
//收货人
ZhongYuanSoApiPhone consigneePhone = null;
//if (string.IsNullOrEmpty(template.ConsigneeName))
//{
consigneePhone = new ZhongYuanSoApiPhone()
{
countryCode = custOrder.ConsigneePhoneCountryCode,
areaCode = custOrder.ConsigneePhoneCode,
number = custOrder.ConsigneePhone
};
//}
//else
//{
// consigneePhone = new ZhongYuanSoApiPhone()
// {
// countryCode = template.ConsigneePhoneCountryCode,
// areaCode = template.ConsigneePhoneCode,
// number = template.ConsigneePhone
// };
//}
consigneePhone.countryCode = consigneePhone.countryCode == null ? "" : consigneePhone.countryCode;
consigneePhone.areaCode = consigneePhone.areaCode == null ? "" : consigneePhone.areaCode;
consigneePhone.number = consigneePhone.number == null ? "" : consigneePhone.number;
postModel.consigneeInfo = new ZhongYuanSoApiSFT()
{
firstName = custOrder.ConsigneeFirstName,
lastName = custOrder.ConsigneeLastName,
country = custOrder.ConsigneeCountry,
state = custOrder.ConsigneeProvince,
city = custOrder.ConsigneeCity,
partyName = custOrder.ConsigneeName,
addressDes = custOrder.ConsigneeAddress,
phone = consigneePhone,
postalCode = custOrder.ConsigneePostCode
};
//通知人
ZhongYuanSoApiPhone notifyPhone = null;
//if (string.IsNullOrEmpty(template.NotifypartName))
//{
notifyPhone = new ZhongYuanSoApiPhone()
{
countryCode = custOrder.NotifypartPhoneCountryCode,
areaCode = custOrder.NotifypartPhoneCode,
number = custOrder.NotifypartPhone
};
//}
//else
//{
// notifyPhone = new ZhongYuanSoApiPhone()
// {
// countryCode = template.NotifypartPhoneCountryCode,
// areaCode = template.NotifypartPhoneCode,
// number = template.NotifypartPhone
// };
//}
notifyPhone.countryCode = notifyPhone.countryCode == null ? "" : notifyPhone.countryCode;
notifyPhone.areaCode = notifyPhone.areaCode == null ? "" : notifyPhone.areaCode;
notifyPhone.number = notifyPhone.number == null ? "" : notifyPhone.number;
postModel.notifyInfo = new ZhongYuanSoApiSFT()
{
firstName = custOrder.NotifypartFirstName,
lastName = custOrder.NotifypartLastName,
country = custOrder.NotifypartCountry,
state = custOrder.NotifypartProvince,
city = custOrder.NotifypartCity,
partyName = custOrder.NotifypartName,
addressDes = custOrder.NotifypartAddress,
phone = notifyPhone,
postalCode = custOrder.NotifypartPostCode
};
//货代
ZhongYuanSoApiPhone forwarderPhone = null;
//if (string.IsNullOrEmpty(template.BookingName))
//{
forwarderPhone = new ZhongYuanSoApiPhone()
{
countryCode = custOrder.BookingPhoneCountryCode,
areaCode = custOrder.BookingPhoneCode,
number = custOrder.BookingPhone
};
//}
//else
//{
// forwarderPhone = new ZhongYuanSoApiPhone()
// {
// countryCode = template.BookingPhoneCountryCode,
// areaCode = template.BookingPhoneCode,
// number = template.BookingPhone
// };
//}
forwarderPhone.countryCode = forwarderPhone.countryCode == null ? "" : forwarderPhone.countryCode;
forwarderPhone.areaCode = forwarderPhone.areaCode == null ? "" : forwarderPhone.areaCode;
forwarderPhone.number = forwarderPhone.number == null ? "" : forwarderPhone.number;
postModel.forwarderInfo = new ZhongYuanSoApiSFT()
{
firstName = custOrder.BookingFirstName,
lastName = custOrder.BookingLastName,
country = custOrder.BookingCountry,
state = custOrder.BookingProvince,
city = custOrder.BookingCity,
partyName = custOrder.BookingName,
addressDes = custOrder.BookingAddress,
phone = forwarderPhone,
postalCode = custOrder.BookingPostCode,
};
#endregion
postModel.cargoInfo = new ZhongYuanSoApiCargoInfo()
{
cargoName = CargoIdZhongyuan(custOrder.CARGOID),
cargoDes = custOrder.DESCRIPTION,
hsCode = custOrder.HSCODE,
};
var ctns = await repCtn.AsQueryable().Filter(null, true).Where(x => x.BILLID == custOrder.Id).ToListAsync();
postModel.boxInfos = new List<ZhongYuanSoApiBoxInfo>();
foreach (var ctn in ctns)
{
if (!ctn.CTNNUM.HasValue || !ctn.KGS.HasValue)
{
return new KeyValuePair<bool, string>(false, $"所有箱的箱量和毛重都不能为空");
}
var mapCtn = mappingCtn.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == ctn.CTNCODE);
if (mapCtn == null)
{
return new KeyValuePair<bool, string>(false, $"未找箱型映射信息:{ctn.CTNCODE}");
}
var apiBox = new ZhongYuanSoApiBoxInfo()
{
boxType = mapCtn.MapCode,
boxNum = ctn.CTNNUM.Value,
weight = ctn.KGS.Value.ToString(),
weightUnit = "KGS"
};
postModel.boxInfos.Add(apiBox);
}
var mapFrt = mappingFrt.FirstOrDefault(x => x.Module == "DjyCustBooking" && x.CarrierCode == "COSCO" && x.Code == custOrder.FRTCODE);
if (mapFrt == null)
{
return new KeyValuePair<bool, string>(false, $"未找到付款方式映射信息:{custOrder.FRTCODE}");
}
postModel.truckingContacts = new ZhongYuanSoApiTruckingContacts()
{
isDoorAdvised = true
};
postModel.rateInfos = new ZhongYuanSoApiRateInfo()
{
paymentMethod = mapFrt.MapCode,
serviceContractNum = custOrder.CONTRACTNO
};
//大简云客户订舱接收BC邮箱
var djyBookMail = sysConfigList.FirstOrDefault(x => x.Code == "DjyCustomerBookReceiveBcMail");
var bcMail = "";
if (!string.IsNullOrEmpty(custOrder.OpMail)) //优先使用东胜上传的邮箱
{
bcMail = custOrder.OpMail;
}
else if (!string.IsNullOrEmpty(custContact.Email))
{
bcMail = custContact.Email;
}
//else
//{
// bcMail = template.BcReceiveEmail;
//}
if (djyBookMail != null)
{
bcMail += ";" + djyBookMail.Value;
}
postModel.special = new ZhongYuanSoApiSpecial()
{
emailAddresses = bcMail,
remarksForEntireBooking = custOrder.SOREMARK
};
Log.Information($"发送API数据给爬虫{sCfgSpiderUrl.Value}{postModel.ToJsonString()}");
var rtn = await sCfgSpiderUrl.Value.SetBody(postModel)
.PostAsStringAsync();
Log.Information($"爬虫返回:{rtn}");
var jobjRtn = JObject.Parse(rtn);
if (jobjRtn.GetIntValue("code") == 200)
{
var jdata = jobjRtn.GetJObjectValue("data");
if (jdata != null)
{
JObject extObj = null;
if (!string.IsNullOrEmpty(custOrder.ExtendData))
{
extObj = JObject.Parse(custOrder.ExtendData);
}
else
{
extObj = new JObject();
}
var bookingNo = jdata.GetStringValue("bookingNo");
if (!string.IsNullOrEmpty(bookingNo))
{
extObj["CustNO"] = bookingNo;
custOrder.ExtendData = extObj.ToJsonString();
await repCustOrder.AsUpdateable(custOrder).UpdateColumns(x => new { x.ExtendData }).ExecuteCommandAsync();
Log.Information($"回写CC号{bookingNo} {custOrder.Id} {custOrder.BOOKINGNO}");
}
}
return new KeyValuePair<bool, string>(true, "发送成功");
}
else
{
return new KeyValuePair<bool, string>(false, jobjRtn.GetStringValue("msg"));
}
}
/// <summary>
/// 获取中远货物类型
/// </summary>
/// <param name="cargoId"></param>
/// <returns></returns>
private static string CargoIdZhongyuan(string cargoId)
{
if (cargoId is "S")
{
return "General";
}
else if (cargoId is "R")
{
return "Reefer";
}
else if (cargoId is "D")
{
return "Dangerous";
}
return null;
}
}
/// <summary>
/// 中远API订舱传输对象
/// </summary>
public class ZhongYuanSoApiModel
{
/// <summary>
/// 用户key
/// </summary>
public string userKey { get; set; }
/// <summary>
/// 用户secret
/// </summary>
public string userSecret { get; set; }
/// <summary>
/// 网站账户
/// </summary>
public string webAccount { get; set; }
/// <summary>
/// 网站密码
/// </summary>
public string webPassword { get; set; }
/// <summary>
/// 上传类型
/// </summary>
public string uploadType { get; set; }
/// <summary>
/// 在选择草稿及模板时, 保存时填写的名称
/// </summary>
public string saveName { get; set; }
/// <summary>
/// 在选择草稿及模板时的描述
/// </summary>
public string saveDes { get; set; }
/// <summary>
/// 路线信息
/// </summary>
public ZhongYuanSoApiRoute routes { get; set; }
/// <summary>
/// 发货人信息
/// </summary>
public ZhongYuanSoApiSFT shipperInfo { get; set; }
/// <summary>
/// 收货人信息
/// </summary>
public ZhongYuanSoApiSFT consigneeInfo { get; set; }
/// <summary>
/// 通知人信息
/// </summary>
public ZhongYuanSoApiSFT notifyInfo { get; set; }
/// <summary>
/// 货代信息
/// </summary>
public ZhongYuanSoApiSFT forwarderInfo { get; set; }
/// <summary>
/// 货物信息
/// </summary>
public ZhongYuanSoApiCargoInfo cargoInfo { get; set; }
/// <summary>
/// 箱信息
/// </summary>
public List<ZhongYuanSoApiBoxInfo> boxInfos { get; set; }
/// <summary>
/// 拖运方式:到门卸货预约
/// </summary>
public ZhongYuanSoApiTruckingContacts truckingContacts { get; set; }
/// <summary>
/// 费率相关信息
/// </summary>
public ZhongYuanSoApiRateInfo rateInfos { get; set; }
/// <summary>
/// 特殊要求及备注
/// </summary>
public ZhongYuanSoApiSpecial special { get; set; }
}
/// <summary>
/// 路线信息
/// </summary>
public class ZhongYuanSoApiRoute
{
/// <summary>
/// 出发城市
/// </summary>
public string originCity { get; set; }
/// <summary>
/// 目的城市
/// </summary>
public string destinationCity { get; set; }
/// <summary>
/// 起始港名
/// </summary>
public string polPortName { get; set; }
/// <summary>
/// 目的港名
/// </summary>
public string podPortName { get; set; }
/// <summary>
/// 船名
/// </summary>
public string vesselName { get; set; }
/// <summary>
/// 航次
/// </summary>
public string voyageNumber { get; set; }
/// <summary>
/// 航线代码
/// </summary>
public string serviceCode { get; set; }
///// <summary>
///// 船期选择优先级
///// </summary>
//public List<string> sailSchedulePriority { get; set; }
/// <summary>
/// 出发地运输条款
/// </summary>
public string outboundHaulage { get; set; }
/// <summary>
/// 目的地运输条款
/// </summary>
public string inboundHaulage { get; set; }
/// <summary>
/// 起运时间
/// </summary>
public string searchConditionDate { get; set; }
/// <summary>
/// 时间范围,按周计算, 默认为2
/// </summary>
public int numberOfWeeks { get; set; } = 2;
/// <summary>
/// etd
/// </summary>
public string etd { get; set; }
}
/// <summary>
/// 收发通信息
/// </summary>
public class ZhongYuanSoApiSFT
{
/// <summary>
/// 名字
/// </summary>
public string partyName { get; set; }
/// <summary>
/// 国家
/// </summary>
public string country { get; set; }
/// <summary>
/// 省
/// </summary>
public string state { get; set; }
/// <summary>
/// 城市名
/// </summary>
public string city { get; set; }
/// <summary>
/// 区
/// </summary>
public string county { get; set; }
/// <summary>
/// 详细地址
/// </summary>
public string addressDes { get; set; }
/// <summary>
/// 邮编
/// </summary>
public string postalCode { get; set; }
/// <summary>
/// 姓
/// </summary>
public string firstName { get; set; }
/// <summary>
/// 名
/// </summary>
public string lastName { get; set; }
/// <summary>
/// 电话
/// </summary>
public ZhongYuanSoApiPhone phone { get; set; }
}
/// <summary>
/// 收发通电话
/// </summary>
public class ZhongYuanSoApiPhone
{
/// <summary>
/// 国家代码
/// </summary>
public string countryCode { get; set; }
/// <summary>
/// 区号
/// </summary>
public string areaCode { get; set; }
/// <summary>
/// 电话号码
/// </summary>
public string number { get; set; }
}
/// <summary>
/// 货物信息
/// </summary>
public class ZhongYuanSoApiCargoInfo
{
/// <summary>
/// 货物类型
/// </summary>
public string cargoName { get; set; }
/// <summary>
/// 货物描述
/// </summary>
public string cargoDes { get; set; }
/// <summary>
/// HS代码
/// </summary>
public string hsCode { get; set; }
}
/// <summary>
/// 箱信息
/// </summary>
public class ZhongYuanSoApiBoxInfo
{
/// <summary>
/// 箱量
/// </summary>
public int boxNum { get; set; }
/// <summary>
/// 箱型
/// </summary>
public string boxType { get; set; }
/// <summary>
/// 毛重
/// </summary>
public string weight { get; set; }
/// <summary>
/// 重量单位
/// </summary>
public string weightUnit { get; set; }
}
/// <summary>
/// 费率
/// </summary>
public class ZhongYuanSoApiRateInfo
{
/// <summary>
/// 付款方式
/// </summary>
public string paymentMethod { get; set; }
/// <summary>
/// 服务合同号
/// </summary>
public string serviceContractNum { get; set; }
}
/// <summary>
/// 托运方式
/// </summary>
public class ZhongYuanSoApiTruckingContacts
{
/// <summary>
/// 是否进一步通知
/// </summary>
public bool isDoorAdvised { get; set; }
}
/// <summary>
/// 特殊要求及备注
/// </summary>
public class ZhongYuanSoApiSpecial
{
/// <summary>
/// 备注信息
/// </summary>
public string remarksForEntireBooking { get; set; }
/// <summary>
/// 邮箱地址
/// </summary>
public string emailAddresses { get; set; }
}
}