|
|
|
|
using DS.Module.Core;
|
|
|
|
|
using DS.Module.Core.Extensions;
|
|
|
|
|
using DS.Module.Core.Helpers;
|
|
|
|
|
using DS.WMS.Core.Code.Entity;
|
|
|
|
|
using DS.WMS.Core.Info.Entity;
|
|
|
|
|
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 Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
using Org.BouncyCastle.Ocsp;
|
|
|
|
|
|
|
|
|
|
namespace DS.WMS.Core.Op.Method
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 海运出口VGM接口
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class SeaExportService
|
|
|
|
|
{
|
|
|
|
|
#region VGM及VMG链接
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取VGM、VGM SI链接
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">业务Id</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DataResult<string[]>> VgmLink(string id)
|
|
|
|
|
{
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
|
|
|
|
var bookingId = long.Parse(id);
|
|
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == bookingId);
|
|
|
|
|
if (order == null)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("海运出口信息不存在!", MultiLanguageConst.SeaExportNotExist));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var orderUrl = tenantDb.Queryable<BookingOrderUrl>().First(x => x.BusinessId == bookingId);
|
|
|
|
|
if (orderUrl == null)
|
|
|
|
|
{
|
|
|
|
|
orderUrl = new BookingOrderUrl()
|
|
|
|
|
{
|
|
|
|
|
BusinessId = bookingId
|
|
|
|
|
};
|
|
|
|
|
await tenantDb.Insertable(orderUrl).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(orderUrl.UrlVgm))
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Success(new string[] { orderUrl.UrlVgm, orderUrl.UrlVgmSi }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//校验船公司
|
|
|
|
|
if (string.IsNullOrEmpty(order.Carrier) || order.CarrierId == 0 || order.CarrierId.IsNull())
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("船公司未正确填写!"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ctns = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == id).ToList();
|
|
|
|
|
//判断船公司是否支持
|
|
|
|
|
//db.Queryable<SysDictData>().Where(x => x.TypeId == 1790194688729419776).Select(x => x.Value).ToList();
|
|
|
|
|
var allowCarrier = db.Queryable<SysDictData>()
|
|
|
|
|
.InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id).Where((a, b) => b.Code == "vgm_carrier_list").Select((a, b) => a.Value).ToList();
|
|
|
|
|
var carrCode = seaComService.GetClientCode(order.CarrierId, tenantDb);
|
|
|
|
|
if (!allowCarrier.Contains(carrCode))
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("不支持的船公司"));
|
|
|
|
|
|
|
|
|
|
//船公司网站账号
|
|
|
|
|
var carrWebAccMap = db.Queryable<SysDictData>()
|
|
|
|
|
.InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id).Where((a, b) => b.Code == "carrier_web_account_mapping" && a.Name == carrCode)
|
|
|
|
|
.Select((a, b) => new { Value = a.Value, Name = a.Name }).First();
|
|
|
|
|
//x.CustomerId == order.CarrierId &&
|
|
|
|
|
var webacc = seaComService.GetCodeThirdParty(carrWebAccMap.Value, user.UserId, tenantDb);
|
|
|
|
|
if (webacc == null)
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("船公司VGM网站账号未配置"));
|
|
|
|
|
|
|
|
|
|
//场站转换
|
|
|
|
|
var yardset = tenantDb.Queryable<MappingYard>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingVgm" && x.LinkId == order.YardId).First();
|
|
|
|
|
if (yardset == null)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed(String.Format("场站EDI配置未找到:{0}", $"{order.Yard}(VGM)")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//校验箱子数据录入
|
|
|
|
|
if (ctns.Where(c => string.IsNullOrEmpty(c.CtnAll) || !c.CtnNum.HasValue).Count() > 0)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed("所有箱型箱量必须录入完整!"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//箱型映射
|
|
|
|
|
var ctnMapping = tenantDb.Queryable<MappingCtn>().Where(x => x.Module == "BookingVgm").ToList();
|
|
|
|
|
//if (ctnMapping.Count == 0)
|
|
|
|
|
//{
|
|
|
|
|
// throw Oops.Bah(BookingErrorCode.BOOK122);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
var expCode = ctns.Select(x => x.CtnCode).Distinct().Except(ctnMapping.Select(y => y.Code)).ToList();
|
|
|
|
|
if (expCode.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed(String.Format("箱型EDI配置未找到:{0}", $"{string.Join(',', expCode)}(VGM)")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////接收反馈地址 TODO 0626注释
|
|
|
|
|
//var dicUrlVgmResp = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "vgm_si_post_reponse" && x.TenantId == 1288018625843826688).First();
|
|
|
|
|
//var dicUrlSiResp = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "si_post_response" && x.TenantId == 1288018625843826688).First();
|
|
|
|
|
|
|
|
|
|
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == long.Parse(user.UserId));
|
|
|
|
|
var tenant = db.Queryable<SysTenant>().Filter(null, true).First(x => x.Id == long.Parse(user.TenantId));
|
|
|
|
|
|
|
|
|
|
var destinationCode = seaComService.GetPortCode(order.DestinationId, tenantDb);
|
|
|
|
|
var loadPortCode = seaComService.GetPortCode(order.LoadPortId, tenantDb);
|
|
|
|
|
var dischargePortCode = seaComService.GetPortCode(order.DischargePortId, tenantDb);
|
|
|
|
|
|
|
|
|
|
//调用vgm链接服务
|
|
|
|
|
var postUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "vgm_link_service" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
var postObj = new
|
|
|
|
|
{
|
|
|
|
|
SystemCode = "djy_hechuan",
|
|
|
|
|
billOrderId = order.Id.ToString(),
|
|
|
|
|
sendOrderCode = order.MBLNO,
|
|
|
|
|
customerName = $"{tenant.Name}+{userInfo.UserName}", //公司名称+用户姓名
|
|
|
|
|
customerId = order.CustomerId.ToString(),
|
|
|
|
|
agentName = string.IsNullOrEmpty(order.Forwarder) ? tenant.Name : order.Forwarder,
|
|
|
|
|
carrierCode = carrCode,
|
|
|
|
|
userName = webacc.AppKey,
|
|
|
|
|
userPassword = webacc.AppSecret,
|
|
|
|
|
depotCode = yardset.MapCode,
|
|
|
|
|
depotName = yardset.MapName,
|
|
|
|
|
linkName = userInfo.UserName,
|
|
|
|
|
linkMobile = userInfo.Phone,
|
|
|
|
|
linkEmail = userInfo.Email,
|
|
|
|
|
//userId = userInfo.DjyUserId,
|
|
|
|
|
userId = order.SaleId,
|
|
|
|
|
signatory = userInfo.UserName,
|
|
|
|
|
//returnUrl = dicUrlVgmResp?.Value,
|
|
|
|
|
shipName = order.Vessel,
|
|
|
|
|
voyNo = order.Voyno,
|
|
|
|
|
etdstr = order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
|
|
potrSend = order.LoadPort,
|
|
|
|
|
potrGoal = order.DischargePort,
|
|
|
|
|
boxinfoStr = order.CntrTotal.Replace("'", ""),
|
|
|
|
|
vgmEndTimeStr = order.CloseVgmDate.HasValue ? order.CloseVgmDate.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
|
|
returnOkUrl = "",
|
|
|
|
|
//SiReturnUrl = dicUrlSiResp?.Value,
|
|
|
|
|
DataInfoJson = new
|
|
|
|
|
{
|
|
|
|
|
order.Shipper,
|
|
|
|
|
order.Consignee,
|
|
|
|
|
order.NotifyParty,
|
|
|
|
|
order.Marks,
|
|
|
|
|
order.Description,
|
|
|
|
|
order.MBLFrt,
|
|
|
|
|
order.Service,
|
|
|
|
|
order.IssueType,
|
|
|
|
|
order.TransPort,
|
|
|
|
|
order.TransPortCode,
|
|
|
|
|
order.Destination,
|
|
|
|
|
//order.DestinationId,
|
|
|
|
|
destinationCode,
|
|
|
|
|
order.KindPkgs,
|
|
|
|
|
order.ThirdPayAt,
|
|
|
|
|
order.LoadPort,
|
|
|
|
|
//order.LoadPortId,
|
|
|
|
|
loadPortCode,
|
|
|
|
|
order.DischargePort,
|
|
|
|
|
//order.DischargePortId
|
|
|
|
|
dischargePortCode
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
string strPostObj = postObj.ToJsonString();
|
|
|
|
|
_logger.Info($"调用VGM链接接口 {postUrl} 传递数据:{strPostObj}");
|
|
|
|
|
var result = RequestHelper.Post(strPostObj, postUrl);
|
|
|
|
|
_logger.Info($"调用VGM链接接口返回:{result}");
|
|
|
|
|
|
|
|
|
|
var jobjResp = JObject.Parse(result);
|
|
|
|
|
int respCode = jobjResp.GetIntValue("code");
|
|
|
|
|
if (respCode != 200)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Failed(jobjResp.GetStringValue("message")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//保存url
|
|
|
|
|
var memoData = jobjResp.GetJObjectValue("memoData");
|
|
|
|
|
orderUrl.UrlVgm = memoData.GetStringValue("vgmUrl");
|
|
|
|
|
orderUrl.UrlVgmSi = memoData.GetStringValue("vgmAndSiUrl");
|
|
|
|
|
await tenantDb.Updateable(orderUrl).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//货运动态
|
|
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BusinessId = bookingId,
|
|
|
|
|
Status = $"生成VGM链接",
|
|
|
|
|
Group = "ship",
|
|
|
|
|
OpTime = DateTime.Now,
|
|
|
|
|
MBLNO = order.MBLNO
|
|
|
|
|
};
|
|
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
return await Task.FromResult(DataResult<string[]>.Success(new string[] { orderUrl.UrlVgm, orderUrl.UrlVgmSi }));
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发送VGM
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">业务Id</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DataResult<string>> VgmSend(string id)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
|
|
|
|
var bookingId = long.Parse(id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var order = tenantDb.Queryable<SeaExport>().First(x => x.Id == bookingId);
|
|
|
|
|
var ctns = tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == id).ToList();
|
|
|
|
|
|
|
|
|
|
//船公司
|
|
|
|
|
if (order.CarrierId == 0 || order.CarrierId.ToString().IsNull())
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("船公司未正确填写!"));
|
|
|
|
|
|
|
|
|
|
//提单号不能为空
|
|
|
|
|
if (string.IsNullOrEmpty(order.MBLNO))
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("主提单号不能为空!"));
|
|
|
|
|
|
|
|
|
|
var vgmApiSendCarrierIdStr = db.Queryable<SysConfig>().Where(x => x.Code == "VgmApiSendCarrierId").First();
|
|
|
|
|
//if (config == null)
|
|
|
|
|
// return await Task.FromResult(DataResult<string>.Failed("请配置租户的VGM直发船司参数!配置名称:[VgmDirectSendCarrierCode]"));
|
|
|
|
|
|
|
|
|
|
var arrCarr = vgmApiSendCarrierIdStr.IsNull()
|
|
|
|
|
? new string[0] : vgmApiSendCarrierIdStr.Value.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
|
|
|
|
var carrCode = seaComService.GetClientCode(order.CarrierId, tenantDb);
|
|
|
|
|
// VGM发送方式1:通过API发送
|
|
|
|
|
if (arrCarr.Contains(carrCode))
|
|
|
|
|
{
|
|
|
|
|
if (!carrCode.Equals("MSK", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"[{carrCode}]船公司暂不支持通过API发送VGM"));
|
|
|
|
|
}
|
|
|
|
|
var urlConfig = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "VgmSendMskApiUrl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
var userKey = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "MSKAPIDjyUserKey" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
var userPwd = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "MSKAPIDjyUserSecret" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
var env = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "MSKAPIOPEnvironment" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
if (userKey.IsNull() || userPwd.IsNull() || env.IsNull())
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("通过MSKAPI发送VGM所需的Key或Secret或Environment未配置,请联系管理员!"));
|
|
|
|
|
|
|
|
|
|
if (urlConfig.IsNull())
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("通过MSKAPI发送VGM所需的Url未配置,请联系管理员,配置名称:[VgmSendMskApiUrl]"));
|
|
|
|
|
|
|
|
|
|
var webAccount = seaComService.GetCodeThirdParty("MSKApi", user.UserId, tenantDb);
|
|
|
|
|
if (webAccount.IsNull())
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未配置第三方账户,类型:MSKApi"));
|
|
|
|
|
|
|
|
|
|
var vgmSendMskCustomerCode = db.Queryable<SysConfig>().Where(x => x.Code == "VgmSendMskCustomerCode").First().Value;
|
|
|
|
|
if (webAccount.IsNull())
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("通过MSKAPI发送VGM所需的[客户编号],请联系管理员,配置名称:[VgmSendMskCustomerCode]"));
|
|
|
|
|
|
|
|
|
|
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == long.Parse(user.UserId));
|
|
|
|
|
var param = new
|
|
|
|
|
{
|
|
|
|
|
userKey,
|
|
|
|
|
userPwd,
|
|
|
|
|
operatingEnvironment = env,
|
|
|
|
|
mskAppKey = webAccount.AppKey,
|
|
|
|
|
mskAppSecret = webAccount.AppSecret,
|
|
|
|
|
shipmentNumber = order.MBLNO,
|
|
|
|
|
brandCode = "MAEU",
|
|
|
|
|
customerCode = vgmSendMskCustomerCode,
|
|
|
|
|
terminalCode = "",
|
|
|
|
|
containerList = new List<object>()
|
|
|
|
|
};
|
|
|
|
|
foreach (var ctn in ctns)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(ctn.CntrNo)
|
|
|
|
|
|| !ctn.WeightKGS.HasValue
|
|
|
|
|
|| ctn.WeightKGS == 0
|
|
|
|
|
|| string.IsNullOrWhiteSpace(ctn.WeightType))
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("所有箱子的箱号、称重重量、称重方式都不能为空!"));
|
|
|
|
|
}
|
|
|
|
|
var vgmMethod = ctn.WeightType switch
|
|
|
|
|
{
|
|
|
|
|
"累加" => "CALCULATED",
|
|
|
|
|
"总重" => "SCALED",
|
|
|
|
|
_ => throw new Exception($"箱号为[{ctn.CntrNo}]的箱子称重方式非[累加]或[总重],请检查")
|
|
|
|
|
};
|
|
|
|
|
param.containerList.Add(new
|
|
|
|
|
{
|
|
|
|
|
containerNumber = ctn.CntrNo,
|
|
|
|
|
vgmSource = "Shipper",
|
|
|
|
|
vgm = ctn.WeightKGS,
|
|
|
|
|
vgmUnit = "KGS",
|
|
|
|
|
vgmMethod,
|
|
|
|
|
authorizedPersonName = userInfo.UserName,
|
|
|
|
|
authorizedPersonEmail = userInfo.Email
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
_logger.Info("通过MSKAPI发送VGM,单号:{mblno},入参:{param}", order.MBLNO, param.ToJson());
|
|
|
|
|
var result = RequestHelper.Post(JsonConvert.SerializeObject(param), urlConfig);
|
|
|
|
|
|
|
|
|
|
_logger.Info("通过MSKAPI发送VGM,单号:{mblno},响应:{resp}", order.MBLNO, result.ToJson());
|
|
|
|
|
var resp = JsonConvert.DeserializeObject<MSKAPISendVgmResultDto>(result);
|
|
|
|
|
object result1 = null;
|
|
|
|
|
if (resp.code == 200)
|
|
|
|
|
{
|
|
|
|
|
if (resp.data.Any(x => !x.status))
|
|
|
|
|
{
|
|
|
|
|
result1 = resp.data.Select(x => new
|
|
|
|
|
{
|
|
|
|
|
CNTRNO = x.containerNumber,
|
|
|
|
|
IsSuccess = x.status,
|
|
|
|
|
FailReason = x.error_msg
|
|
|
|
|
}).ToList();
|
|
|
|
|
_logger.Info("通过MSKAPI发送VGM,部分成功,单号:{mblno},详细结果:{data}", order.MBLNO, result1.ToJson());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Info("通过MSKAPI发送VGM,全部成功,单号:{mblno},详细结果:{data}", order.MBLNO, result1.ToJson());
|
|
|
|
|
//货运动态
|
|
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BusinessId = bookingId,
|
|
|
|
|
Status = $"直发VGM(API)",
|
|
|
|
|
Group = "ship",
|
|
|
|
|
MBLNO = order.MBLNO
|
|
|
|
|
};
|
|
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Info("通过MSKAPI发送VGM,VGM服务接口返回失败结果,单号:{mblno}", order.MBLNO);
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed($"VGM服务接口返回失败结果:{resp.msg}"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var config = db.Queryable<SysConfig>().Where(x => x.Code == "VgmDirectSendCarrierId").First();
|
|
|
|
|
if (config == null)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("请配置租户的VGM直发船司参数!配置名称:[VgmDirectSendCarrierId]"));
|
|
|
|
|
}
|
|
|
|
|
var allowCarr = config.Value.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
|
|
|
|
if (!allowCarr.Contains(carrCode)) //使用大简云发送vgm
|
|
|
|
|
{
|
|
|
|
|
//ETD不能为空
|
|
|
|
|
if (!order.ETD.HasValue)
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("ETD不能为空!"));
|
|
|
|
|
|
|
|
|
|
//重量不能为空
|
|
|
|
|
if (!order.KGS.HasValue)
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("重量不能为空!"));
|
|
|
|
|
|
|
|
|
|
var urlConfig = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "DjyVgmApiMyshppingUrl" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
//var userKey = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "DjyVgmApiMyshppingUserKey" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
//var userPwd = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "DjyVgmApiMyshppingUserPwd" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
var webAccount = seaComService.GetCodeThirdParty("DjyVgm", user.UserId, tenantDb);
|
|
|
|
|
if (webAccount.IsNull())
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("请在网站账号中维护VGM接口的用户id和秘钥!,类型:DjyVgm"));;
|
|
|
|
|
|
|
|
|
|
var objMdata = new
|
|
|
|
|
{
|
|
|
|
|
MBLNO = order.MBLNO,
|
|
|
|
|
CARRIER = carrCode,
|
|
|
|
|
ChuanMing = order.Vessel,
|
|
|
|
|
HangCi = order.VoucherNo,
|
|
|
|
|
ETD = order.ETD.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
|
|
|
|
ZongZhongLiang = order.KGS.ToString(),
|
|
|
|
|
BeiZhu = "",
|
|
|
|
|
ORDERNO = order.CustomerNo,
|
|
|
|
|
VGMCLOSETIME = order.CloseVgmDate.HasValue ? order.CloseVgmDate.Value.ToString("yyyy-MM-dd HH:mm:ss") : ""
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var listCtn = new List<dynamic>();
|
|
|
|
|
foreach (var ctn in ctns)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(ctn.CtnAll)
|
|
|
|
|
|| string.IsNullOrEmpty(ctn.CntrNo)
|
|
|
|
|
|| string.IsNullOrEmpty(ctn.SealNo)
|
|
|
|
|
|| !ctn.WeightKGS.HasValue
|
|
|
|
|
|| string.IsNullOrEmpty(ctn.WeightDate))
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("所有箱子的箱型、箱号、封号、称重重量和称重时间都不能为空!"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
listCtn.Add(new
|
|
|
|
|
{
|
|
|
|
|
ChengZhongZhongLiang = ctn.WeightKGS.Value.ToString(),
|
|
|
|
|
ChengZhongShiJian = ctn.WeightDate,
|
|
|
|
|
CTNALL = ctn.CtnAll.Replace("'", ""),
|
|
|
|
|
CNTRNO = ctn.CntrNo,
|
|
|
|
|
SEALNO = ctn.SealNo
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dictParam = new Dictionary<string, string> {
|
|
|
|
|
{ "ac", "vgm" },
|
|
|
|
|
{ "uid", webAccount.AppKey },
|
|
|
|
|
{ "skey", webAccount.AppSecret },
|
|
|
|
|
{ "optype", "9"},
|
|
|
|
|
{ "mdata", JsonConvert.SerializeObject(objMdata)},
|
|
|
|
|
{ "ctndata", JsonConvert.SerializeObject(listCtn)}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_logger.Info($"调用vgm发送接口:{urlConfig},参数:{JsonConvert.SerializeObject(dictParam)}");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var result = RequestHelper.Post(JsonConvert.SerializeObject(dictParam), urlConfig);
|
|
|
|
|
|
|
|
|
|
_logger.Info($"调用vgm发送接口:{urlConfig},返回:{result}");
|
|
|
|
|
|
|
|
|
|
var jobjRtn = JObject.Parse(result);
|
|
|
|
|
if (jobjRtn.GetBooleanValue("Success"))
|
|
|
|
|
{
|
|
|
|
|
//货运动态
|
|
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BusinessId = bookingId,
|
|
|
|
|
Status = $"发送VGM",
|
|
|
|
|
Group = "ship",
|
|
|
|
|
MBLNO = order.MBLNO
|
|
|
|
|
};
|
|
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed(jobjRtn.GetStringValue("Message")));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else //直接调用vgm接口直发
|
|
|
|
|
{
|
|
|
|
|
//判断船公司是否支持
|
|
|
|
|
var allowCarrier = db.Queryable<SysDictData>()
|
|
|
|
|
.InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id).Where((a, b) => b.Code == "vgm_carrier_list" && a.Name == carrCode)
|
|
|
|
|
.Select((a, b) => a.Value).ToList();
|
|
|
|
|
if (!allowCarrier.Contains(carrCode))
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("不支持的船公司"));
|
|
|
|
|
|
|
|
|
|
////船公司网站账号
|
|
|
|
|
//var carrWebAccMap = _cache.GetAllDictData().Result.FirstOrDefault(x => x.TypeCode == "carrier_web_account_mapping" && x.Code == order.Carrier);
|
|
|
|
|
//if (carrWebAccMap == null)
|
|
|
|
|
// return await Task.FromResult(DataResult<string>.Failed("不支持的船公司或账号映射未配置"));
|
|
|
|
|
var carrWebAccMap = db.Queryable<SysDictData>()
|
|
|
|
|
.InnerJoin<SysDictType>((a, b) => a.TypeId == b.Id).Where((a, b) => b.Code == "carrier_web_account_mapping" && a.Name == carrCode)
|
|
|
|
|
.Select((a, b) => new { Value = a.Value, Name = a.Name }).First();
|
|
|
|
|
|
|
|
|
|
if (carrWebAccMap == null)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("不支持的船公司或账号映射未配置"));
|
|
|
|
|
}
|
|
|
|
|
var webacc = seaComService.GetCodeThirdParty(carrWebAccMap.Value, user.UserId, tenantDb, order.CarrierId);
|
|
|
|
|
if (webacc == null)
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("船公司VGM网站账号未配置"));
|
|
|
|
|
|
|
|
|
|
//var webacc = tenantDb.Queryable<CodeThirdParty>().Where(x => x.CustomerId == order.CarrierId && x.AccountType == "VgmSet").First(); ;
|
|
|
|
|
//if (webacc == null)
|
|
|
|
|
// return await Task.FromResult(DataResult<string>.Failed("船公司网站账号未配置"));
|
|
|
|
|
|
|
|
|
|
#region 箱信息校验,2022-7-1修改:【累加】的必须有重量、皮重和称重重量;【总重】的只需要称重重量不为空
|
|
|
|
|
if (ctns.Where(c => c.WeightType == "累加" &&
|
|
|
|
|
(
|
|
|
|
|
string.IsNullOrEmpty(c.CntrNo)
|
|
|
|
|
|| !c.WeightKGS.HasValue
|
|
|
|
|
|| c.WeightKGS == 0
|
|
|
|
|
|| !c.TareWeight.HasValue
|
|
|
|
|
|| c.TareWeight == 0
|
|
|
|
|
|| !c.KGS.HasValue
|
|
|
|
|
|| c.KGS == 0)
|
|
|
|
|
).Count() > 0)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("称重方式为累加时,箱号、重量、箱皮重以及称重重量都不能为空"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctns.Where(c => c.WeightType == "总重" &&
|
|
|
|
|
(
|
|
|
|
|
string.IsNullOrEmpty(c.CntrNo)
|
|
|
|
|
|| !c.WeightKGS.HasValue
|
|
|
|
|
|| c.WeightKGS == 0)
|
|
|
|
|
).Count() > 0)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("称重方式为总重时,箱号和称重重量都不能为空"));
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(order.Yard) || order.YardId == 0)
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("场站未正确选择!"));
|
|
|
|
|
// 场站映射
|
|
|
|
|
string mappingYard, mappingYardId;
|
|
|
|
|
var yardMapList = tenantDb.Queryable<MappingYard>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingVgm" && x.LinkId == order.YardId && (x.CarrierId == 0 || x.CarrierId == order.CarrierId))?.ToList();
|
|
|
|
|
if (yardMapList?.Any() == true)
|
|
|
|
|
{
|
|
|
|
|
var yardset = yardMapList.FirstOrDefault(x => x.CarrierId == order.CarrierId)
|
|
|
|
|
?? yardMapList.FirstOrDefault(x => x.CarrierId == 0 || x.CarrierId.ToString() == "");
|
|
|
|
|
|
|
|
|
|
mappingYard = yardset.MapName;
|
|
|
|
|
mappingYardId = yardset.MapCode;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var yard = tenantDb.Queryable<InfoClient>().First(x => x.Id == order.YardId);
|
|
|
|
|
mappingYard = yard.ShortName;
|
|
|
|
|
mappingYardId = yard.CodeName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 船司映射
|
|
|
|
|
var carrMap = tenantDb.Queryable<MappingCarrier>().Where(x => x.Status == StatusEnum.Enable && x.Module == "BookingVgm" && x.LinkId == order.CarrierId).First();
|
|
|
|
|
string mappingCarrierCode = carrMap != null ? carrMap.MapCode : order.Carrier;
|
|
|
|
|
|
|
|
|
|
var userInfo = await db.Queryable<SysUser>().Filter(null, true).FirstAsync(x => x.Id == long.Parse(user.UserId));
|
|
|
|
|
|
|
|
|
|
var tenant = db.Queryable<SysTenant>().Filter(null, true).First(x => x.Id == long.Parse(user.TenantId));
|
|
|
|
|
int idx = 1;
|
|
|
|
|
//调用接口
|
|
|
|
|
var postUrl = db.Queryable<SysConfig>().Filter(null, true).Where(x => x.Code == "vgm_service_single" && x.TenantId == 1288018625843826688).First().Value;
|
|
|
|
|
//var dicUrl = _cache.GetAllDictData().Result.First(x => x.TypeCode == "url_set" && x.Code == "vgm_service_single");
|
|
|
|
|
var customerCode = seaComService.GetClientCode(order.CustomerId,tenantDb);
|
|
|
|
|
//var destinationCode = seaComService.GetPortCode(order.DestinationId, tenantDb);
|
|
|
|
|
//var loadPortCode = seaComService.GetPortCode(order.LoadPortId, tenantDb);
|
|
|
|
|
//var dischargePortCode = seaComService.GetPortCode(order.DischargePortId, tenantDb);
|
|
|
|
|
var sendObj = new
|
|
|
|
|
{
|
|
|
|
|
SystemCode = "djy_hechuan",
|
|
|
|
|
billOrderId = order.Id.ToString(),
|
|
|
|
|
sendOrderCode = order.MBLNO,
|
|
|
|
|
customerName = $"{tenant.Name}+{userInfo.UserName}", //公司名称+用户姓名
|
|
|
|
|
customerId = customerCode,
|
|
|
|
|
agentName = string.IsNullOrEmpty(order.Forwarder) ? tenant.Name : order.Forwarder,
|
|
|
|
|
carrierCode = mappingCarrierCode,
|
|
|
|
|
userName = webacc.AppKey,
|
|
|
|
|
userPassword = webacc.AppSecret,
|
|
|
|
|
depotCode = mappingYardId,
|
|
|
|
|
depotName = mappingYard,
|
|
|
|
|
linkName = userInfo.UserName,
|
|
|
|
|
linkMobile = userInfo.Phone,
|
|
|
|
|
linkEmail = userInfo.Email,
|
|
|
|
|
//userId = userInfo.DjyUserId,
|
|
|
|
|
userId = order.SaleId,
|
|
|
|
|
signatory = userInfo.UserName, //2023年8月28日,董怡含:把用户昵称当做vgm上传人
|
|
|
|
|
returnUrl = "",
|
|
|
|
|
shipName = order.Vessel,
|
|
|
|
|
voyNo = order.Voyno,
|
|
|
|
|
etdstr = order.ETD.HasValue ? order.ETD.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
|
|
potrSend = order.LoadPort,
|
|
|
|
|
potrGoal = order.DischargePort,
|
|
|
|
|
boxinfoStr = order.CntrTotal.Replace("'", ""),
|
|
|
|
|
vgmEndTimeStr = order.CloseVgmDate.HasValue ? order.CloseVgmDate.Value.ToString("yyyy-MM-dd") : string.Empty,
|
|
|
|
|
BoxInfo = ctns.Select(c => new
|
|
|
|
|
{
|
|
|
|
|
index = idx++,
|
|
|
|
|
boxType = c.CtnAll.Replace("'", ""),
|
|
|
|
|
boxcount = c.CtnNum.HasValue ? c.CtnNum.Value : 0,
|
|
|
|
|
code = c.CntrNo,
|
|
|
|
|
sealCode = c.SealNo,
|
|
|
|
|
weigth = c.KGS,
|
|
|
|
|
weigthTare = c.TareWeight,
|
|
|
|
|
weigthTotal = c.WeightKGS,
|
|
|
|
|
weigthType = c.WeightType == "累加" ? "SM2" : "SM1"
|
|
|
|
|
}).ToList(),
|
|
|
|
|
returnOkUrl = ""
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
string strPostObj = sendObj.ToJsonString();
|
|
|
|
|
_logger.Info($"调用VGM直发接口 {postUrl} 传递数据:{strPostObj}");
|
|
|
|
|
var result = RequestHelper.Post(strPostObj, postUrl);
|
|
|
|
|
|
|
|
|
|
_logger.Info($"调用VGM直发接口返回:{result}");
|
|
|
|
|
|
|
|
|
|
var jobjResp = JObject.Parse(result);
|
|
|
|
|
int respCode = jobjResp.GetIntValue("code");
|
|
|
|
|
if (respCode != 200)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed(jobjResp.GetStringValue("message")));
|
|
|
|
|
}
|
|
|
|
|
//货运动态
|
|
|
|
|
var bookingStatus = new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BusinessId = bookingId,
|
|
|
|
|
Status = $"直发VGM",
|
|
|
|
|
Group = "ship",
|
|
|
|
|
OpTime = DateTime.Now,
|
|
|
|
|
MBLNO = order.MBLNO
|
|
|
|
|
};
|
|
|
|
|
await tenantDb.Insertable(bookingStatus).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////设置货物状态:已发VGM,并回传东胜
|
|
|
|
|
await seaComService.SetGoodsStatus("YFVGM", bookingId);
|
|
|
|
|
//await SendBookingOrder(new long[] { bookingId });
|
|
|
|
|
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Success("Vgm发送成功!"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 批量获取vgm
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="ids">业务id 逗号拼接</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DataResult<List<BatchVGM>>> GetVmgDataList(string ids)
|
|
|
|
|
{
|
|
|
|
|
var arr = ids.Split(',');
|
|
|
|
|
if (arr.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<List<BatchVGM>>.Failed("请传入正确数据!"));
|
|
|
|
|
}
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
|
|
|
|
|
var main = await tenantDb.Queryable<SeaExport>().Where(x => x.ParentId == 0).ToListAsync();
|
|
|
|
|
List<BatchVGM> batchVGMs = new List<BatchVGM>();
|
|
|
|
|
foreach (var item in arr)
|
|
|
|
|
{
|
|
|
|
|
BatchVGM batchVGM = new BatchVGM();
|
|
|
|
|
batchVGM.Id = Convert.ToInt64(item);
|
|
|
|
|
batchVGM.MBLNO = main.Where(x => x.Id == batchVGM.Id).Select(x => x.MBLNO).FirstOrDefault();
|
|
|
|
|
batchVGM.ctnlist = await tenantDb.Queryable<OpCtn>().Where(x => x.BSNO == item).Select(x => new BatchVGMList
|
|
|
|
|
{
|
|
|
|
|
Id = x.Id,
|
|
|
|
|
CtnCode = x.CtnCode,
|
|
|
|
|
CtnAll = x.CtnAll,
|
|
|
|
|
CntrNo = x.CntrNo,
|
|
|
|
|
KGS = x.KGS,
|
|
|
|
|
TareWeight = x.TareWeight,
|
|
|
|
|
WeightType = x.WeightType,
|
|
|
|
|
WeightKGS = x.WeightKGS
|
|
|
|
|
}).ToListAsync();
|
|
|
|
|
|
|
|
|
|
batchVGMs.Add(batchVGM);
|
|
|
|
|
}
|
|
|
|
|
return await Task.FromResult(DataResult<List<BatchVGM>>.Success(batchVGMs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 批量保存vgm
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DataResult<string>> SaveBatchVgm(List<BatchVGMList> dto)
|
|
|
|
|
{
|
|
|
|
|
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
|
|
|
|
|
if (dto == null)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Failed("未提交数据!"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in dto)
|
|
|
|
|
{
|
|
|
|
|
var dic = item.GetPropertiesArray();
|
|
|
|
|
var info = tenantDb.Queryable<OpCtn>().Where(x => x.Id == item.Id).First();
|
|
|
|
|
info = item.Adapt(info);
|
|
|
|
|
|
|
|
|
|
tenantDb.Updateable(info).UpdateColumns(dic).ExecuteCommand();
|
|
|
|
|
}
|
|
|
|
|
return await Task.FromResult(DataResult<string>.Success("更新成功!", MultiLanguageConst.DataUpdateSuccess));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|