|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using Furion;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Core;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
using Furion.DynamicApiController;
|
|
|
using Furion.DependencyInjection;
|
|
|
using Myshipping.Core.Service;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application.Helper;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Globalization;
|
|
|
|
|
|
namespace Myshipping.Application.Service.BookingOrder
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 马士基API订舱
|
|
|
/// </summary>
|
|
|
[ApiDescriptionSettings("Application", Name = "BookingMSKAPI", Order = 10)]
|
|
|
public class BookingMSKAPIService: IBookingMSKAPIService, IDynamicApiController, ITransient
|
|
|
{
|
|
|
private readonly SqlSugarRepository<BookingDeliveryRecord> _bookingDeliveryRecordRep;
|
|
|
private readonly SqlSugarRepository<BookingDeliveryRecordCtn> _bookingDeliveryRecordCtnRep;
|
|
|
private readonly ISysCacheService _cache;
|
|
|
private readonly IDjyWebsiteAccountConfigService _webAccountConfig;
|
|
|
private readonly ILogger<BookingMSKAPIService> _logger;
|
|
|
|
|
|
const string CONST_MSK_API_COMMODITY_URL = "MSKApiCommodity";
|
|
|
const string CONST_MSK_API_BOOKING_URL = "MSKApiBooking";
|
|
|
const string CONST_MSK_API_Poing2P_SECD_URL = "MSKApiSailingSchedulePoint2Point";
|
|
|
const string CONST_MSK_API_LOCATION_URL = "MSKApilocation";
|
|
|
|
|
|
public BookingMSKAPIService(ILogger<BookingMSKAPIService> logger, ISysCacheService cache,
|
|
|
IDjyWebsiteAccountConfigService webAccountConfig, SqlSugarRepository<BookingDeliveryRecord> bookingDeliveryRecordRep,
|
|
|
SqlSugarRepository<BookingDeliveryRecordCtn> bookingDeliveryRecordCtnRep)
|
|
|
{
|
|
|
_logger = logger;
|
|
|
_cache = cache;
|
|
|
_webAccountConfig = webAccountConfig;
|
|
|
_bookingDeliveryRecordRep = bookingDeliveryRecordRep;
|
|
|
_bookingDeliveryRecordCtnRep = bookingDeliveryRecordCtnRep;
|
|
|
|
|
|
}
|
|
|
|
|
|
#region 检索海运船期详情
|
|
|
/// <summary>
|
|
|
/// 检索海运船期详情
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求船期详情</param>
|
|
|
/// <returns>返回船期结果</returns>
|
|
|
[HttpPost("/BookingMSKAPI/SearchShipSailingSchedule")]
|
|
|
public async Task<List<SearchShipSailingScheduleResultDto>> SearchShipSailingSchedule(QueryShipSailingScheduleDto model)
|
|
|
{
|
|
|
List<SearchShipSailingScheduleResultDto> list = new List<SearchShipSailingScheduleResultDto>();
|
|
|
|
|
|
/*
|
|
|
MSKApiSailingSchedulePoint2Point
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.collectionOriginCityName))
|
|
|
throw Oops.Oh($"始发地不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.deliveryDestinationCityName))
|
|
|
throw Oops.Oh($"目的地不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.vesselOperatorCarrierCode))
|
|
|
throw Oops.Oh($"服务船公司不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierId))
|
|
|
throw Oops.Oh("船公司代码不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.startDate))
|
|
|
throw Oops.Oh($"预计离港日期不能为空");
|
|
|
|
|
|
DateTime etd = DateTime.MinValue;
|
|
|
|
|
|
if (!DateTime.TryParse(model.startDate, out etd))
|
|
|
throw Oops.Oh($"预计离港日期格式错误");
|
|
|
|
|
|
string queryUrl = string.Empty;
|
|
|
|
|
|
if (model.carrierId.Equals("MSK", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
queryUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == CONST_MSK_API_Poing2P_SECD_URL)?.Value;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw Oops.Oh($"当前船公司 {model.carrierId} 未配置相应的请求接口");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(queryUrl))
|
|
|
throw Oops.Oh("未配置查询船期请求接口地址,请联系管理员");
|
|
|
|
|
|
var webAccountConfig = _webAccountConfig
|
|
|
.GetAccountConfig("MSKApi", UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
if (webAccountConfig == null)
|
|
|
throw Oops.Oh("未配置个人账户,请先配置个人账户 类型-MSKApi");
|
|
|
|
|
|
MSKAPISearchPoint2PointScheduleDto queryInfo = new MSKAPISearchPoint2PointScheduleDto
|
|
|
{
|
|
|
userKey = App.Configuration["MSKAPIDjyUserKey"],
|
|
|
userSecret = App.Configuration["MSKAPIDjyUserSecret"],
|
|
|
operatingEnvironment = App.Configuration["MSKAPIOPEnvironment"],
|
|
|
mskAppKey = webAccountConfig.Account,
|
|
|
collectionOriginCityName = model.collectionOriginCityName,
|
|
|
collectionOriginCountryCode = model.collectionOriginCountryCode,
|
|
|
deliveryDestinationCityName = model.deliveryDestinationCityName,
|
|
|
deliveryDestinationCountryCode = model.deliveryDestinationCountryCode,
|
|
|
cargoType = model.cargoType,
|
|
|
exportServiceMode = model.exportServiceMode,
|
|
|
importServiceMode = model.importServiceMode,
|
|
|
vesselOperatorCarrierCode = model.vesselOperatorCarrierCode,
|
|
|
startDate = etd.ToString("yyyy-MM-dd"),
|
|
|
startDateType = "D",
|
|
|
};
|
|
|
|
|
|
MSKAPISearchPoint2PointScheduleResultDto resultInfo = null;
|
|
|
|
|
|
var rlt = await queryUrl.SetBody(queryInfo)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rlt))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
resultInfo = JSON.Deserialize<MSKAPISearchPoint2PointScheduleResultDto>(rlt);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"请求MSK API查询船期异常,原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"请求MSK API查询船期异常,原因:{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (resultInfo != null && resultInfo.code == 200
|
|
|
&& resultInfo.data != null && resultInfo.data.Count > 0)
|
|
|
{
|
|
|
resultInfo.data.ForEach(a =>
|
|
|
{
|
|
|
a.transportSchedules.ForEach(b =>
|
|
|
{
|
|
|
SearchShipSailingScheduleResultDto info = new SearchShipSailingScheduleResultDto
|
|
|
{
|
|
|
carrierProductId = a.carrierProductId,
|
|
|
carrierProductSequenceId = a.carrierProductSequenceId,
|
|
|
ETD = b.departureDateTime,
|
|
|
ATD = b.arrivalDateTime,
|
|
|
vesselOperatorCarrierCode = b.vesselOperatorCarrierCode
|
|
|
};
|
|
|
|
|
|
if (b.departureDateTime.HasValue && b.arrivalDateTime.HasValue)
|
|
|
{
|
|
|
TimeSpan ts = b.arrivalDateTime.Value.Subtract(b.departureDateTime.Value);
|
|
|
var timeDiff = ts.TotalHours;
|
|
|
|
|
|
info.days = (int)Math.Ceiling(timeDiff / 24.0);
|
|
|
}
|
|
|
|
|
|
if (b.facilities != null)
|
|
|
{
|
|
|
info.orignCityName = b.facilities.collectionOrigin?.cityName;
|
|
|
info.orignCarrierSiteGeoID = b.facilities.collectionOrigin?.carrierSiteGeoID;
|
|
|
info.orignLocationName = b.facilities.collectionOrigin?.locationName;
|
|
|
info.orignCountryCode = b.facilities.collectionOrigin?.countryCode;
|
|
|
info.orignLocationType = b.facilities.collectionOrigin?.locationType;
|
|
|
info.orignUNLocationCode = b.facilities.collectionOrigin?.UNLocationCode;
|
|
|
info.orignUNRegionCode = b.facilities.collectionOrigin?.UNRegionCode;
|
|
|
|
|
|
info.deliveryCityName = b.facilities.deliveryDestination?.cityName;
|
|
|
info.deliveryCarrierSiteGeoID = b.facilities.deliveryDestination?.carrierSiteGeoID;
|
|
|
info.deliveryLocationName = b.facilities.deliveryDestination?.locationName;
|
|
|
info.deliveryCountryCode = b.facilities.deliveryDestination?.countryCode;
|
|
|
info.deliveryLocationType = b.facilities.deliveryDestination?.locationType;
|
|
|
info.deliveryUNLocationCode = b.facilities.deliveryDestination?.UNLocationCode;
|
|
|
info.deliveryUNRegionCode = b.facilities.deliveryDestination?.UNRegionCode;
|
|
|
}
|
|
|
|
|
|
info.vesselIMONumber = b.firstDepartureVessel?.vesselIMONumber;
|
|
|
info.carrierVesselCode = b.firstDepartureVessel?.carrierVesselCode;
|
|
|
info.vesselName = b.firstDepartureVessel?.vesselName;
|
|
|
|
|
|
if (b.transportLegs != null && b.transportLegs.Count > 0)
|
|
|
{
|
|
|
var firstTransportLegs = b.transportLegs.FirstOrDefault();
|
|
|
|
|
|
if (firstTransportLegs.transport != null)
|
|
|
{
|
|
|
info.transportMode = firstTransportLegs.transport.transportMode;
|
|
|
info.carrierDepartureVoyageNumber = firstTransportLegs.transport.carrierDepartureVoyageNumber;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
list.Add(info);
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"检索海运船期详情异常,req={JSON.Serialize(model)} 原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"检索海运船期详情失败,{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 发送马士基订舱请求
|
|
|
/// <summary>
|
|
|
/// 发送马士基订舱请求
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求订舱详情</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/BookingMSKAPI/SendMSKBooking")]
|
|
|
public async Task<MSKBookingResultDto> SendMSKBooking(MSKBookingDto model)
|
|
|
{
|
|
|
MSKBookingResultDto result = new MSKBookingResultDto();
|
|
|
|
|
|
/*
|
|
|
MSKApiBooking
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierCode))
|
|
|
throw Oops.Oh($"服务船公司不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierId))
|
|
|
throw Oops.Oh("船公司代码不能为空");
|
|
|
|
|
|
string sendUrl = string.Empty;
|
|
|
|
|
|
if (model.carrierId.Equals("MSK", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
sendUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == CONST_MSK_API_BOOKING_URL)?.Value;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw Oops.Oh($"当前船公司 {model.carrierId} 未配置相应的请求接口");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(sendUrl))
|
|
|
throw Oops.Oh("未配置发送订舱请求接口地址,请联系管理员");
|
|
|
|
|
|
var webAccountConfig = _webAccountConfig
|
|
|
.GetAccountConfig("MSKApi", UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
if (webAccountConfig == null)
|
|
|
throw Oops.Oh("未配置个人账户,请先配置个人账户 类型-MSKApi");
|
|
|
|
|
|
//这里是校验必填项
|
|
|
ValidateMSKAPIData(model);
|
|
|
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
var recordInfo = model.Adapt<BookingDeliveryRecord>();
|
|
|
var recordCtnList = model.ctns.Adapt<List<BookingDeliveryRecordCtn>>();
|
|
|
|
|
|
var ctnCodeMappingList = _cache.GetAllMappingCtn().GetAwaiter().GetResult().ToList();
|
|
|
|
|
|
if (ctnCodeMappingList.Count > 0)
|
|
|
ctnCodeMappingList = ctnCodeMappingList.Where(x => x.CarrierCode == "MSK" && x.Module == "BOOK_OR_CLOSING").ToList();
|
|
|
|
|
|
MSKAPIBookingDto bookingDto = new MSKAPIBookingDto
|
|
|
{
|
|
|
userKey = App.Configuration["MSKAPIDjyUserKey"],
|
|
|
userSecret = App.Configuration["MSKAPIDjyUserSecret"],
|
|
|
operatingEnvironment = App.Configuration["MSKAPIOPEnvironment"],
|
|
|
mskAppKey = webAccountConfig.Account,
|
|
|
mskAppSecret = webAccountConfig.Password,
|
|
|
bookingBody = new MSKAPIBookingBodyDto()
|
|
|
};
|
|
|
|
|
|
bookingDto.bookingBody.references = new MSKAPIBookingReferenceDto
|
|
|
{
|
|
|
priceReference = model.priceReference,
|
|
|
productCode = model.productCode,
|
|
|
sender = model.sender,
|
|
|
bookingOfficeUNLocationCode = "CNTAO"
|
|
|
};
|
|
|
|
|
|
bookingDto.bookingBody.mandatoryParties = new MSKAPIBookingMandatoryParties
|
|
|
{
|
|
|
bookedByCompanyName = model.bookedByCompanyName,
|
|
|
bookedByMaerskPartyCode = model.bookedByMaerskPartyCode,
|
|
|
bookedByPartyContact = new MSKAPIBookingMandatoryPartyContact
|
|
|
{
|
|
|
name = model.bookedByCompanyContactName,
|
|
|
email = model.bookedByCompanyContactEmail
|
|
|
},
|
|
|
priceOwnerCompanyName = model.priceOwnerCompanyName,
|
|
|
priceOwnerMaerskPartyCode = model.priceOwnerMaerskPartyCode,
|
|
|
priceOwnerPartyContact = new MSKAPIBookingMandatoryPartyContact
|
|
|
{
|
|
|
name = model.priceOwnerContactName,
|
|
|
email = model.priceOwnerContactEmail
|
|
|
},
|
|
|
};
|
|
|
|
|
|
//排查怀疑这里是导致BC没有合约号胡的问题,开启这个值看看
|
|
|
//if (model.isBookingPartOwnPrice)
|
|
|
//{
|
|
|
// bookingDto.bookingBody.mandatoryParties.isPriceOwnerFromServiceContractAccepted = true;
|
|
|
//}
|
|
|
|
|
|
bookingDto.bookingBody.transport = new MSKAPIBookingTransport
|
|
|
{
|
|
|
carrierCode = model.carrierCode,
|
|
|
earliestDepartureDate = model.earliestDepartureDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"),
|
|
|
exportServiceMode = model.exportServiceMode,
|
|
|
importServiceMode = model.importServiceMode,
|
|
|
routeDetails = new MSKAPIBookingRouteDetails
|
|
|
{
|
|
|
placeOfReceipt = new MSKAPIBookingRouteDetailsBase
|
|
|
{
|
|
|
UNLocationCode = model.isSendNoSchedule ? model.userPlaceOfReceiptUnLocCode
|
|
|
: model.placeOfReceiptUnLocCode,
|
|
|
//cityName = model.placeOfReceiptCityName,
|
|
|
},
|
|
|
placeOfDelivery = new MSKAPIBookingRouteDetailsBase
|
|
|
{
|
|
|
UNLocationCode = model.isSendNoSchedule ? model.userPlaceOfDeliveryUnLocCode
|
|
|
: model.placeOfDeliveryUnLocCode,
|
|
|
//cityName = model.placeOfDeliveryCityName,
|
|
|
},
|
|
|
selectedRoute = new MSKAPIBookingRoute
|
|
|
{
|
|
|
bookingSchedules = new List<MSKAPIBookingSchedules> {
|
|
|
new MSKAPIBookingSchedules
|
|
|
{
|
|
|
originDepartureDateTimeLocal = model.originDepartureDateTimeLocal.Value.ToString("yyyy-MM-ddTHH:mm:ss"),
|
|
|
destinationArrivalDateTimeLocal = model.destinationArrivalDateTimeLocal.Value.ToString("yyyy-MM-ddTHH:mm:ss"),
|
|
|
transportMode = new MSKAPIBookingTransportMode
|
|
|
{
|
|
|
vessel = new MSKAPIBookingTransportModeVessel
|
|
|
{
|
|
|
name = model.vesselName,
|
|
|
maerskVesselCode = model.carrierVesselCode,
|
|
|
},
|
|
|
exportVoyageNumber = model.exportVoyageNumber,
|
|
|
},
|
|
|
startLocation = new MSKAPIBookingRouteDetailsBase
|
|
|
{
|
|
|
//cityName = model.placeOfReceiptCityName,
|
|
|
UNLocationCode = model.isSendNoSchedule ? model.userPlaceOfReceiptUnLocCode
|
|
|
: model.placeOfReceiptUnLocCode
|
|
|
},
|
|
|
endLocation = new MSKAPIBookingRouteDetailsBase
|
|
|
{
|
|
|
//cityName = model.placeOfDeliveryCityName,
|
|
|
UNLocationCode = model.isSendNoSchedule ? model.userPlaceOfDeliveryUnLocCode
|
|
|
: model.placeOfDeliveryUnLocCode
|
|
|
},
|
|
|
transportModeCode = model.transportMode
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
}
|
|
|
};
|
|
|
|
|
|
//if(!model.isSendNoSchedule)
|
|
|
//{
|
|
|
// bookingDto.bookingBody.transport.routeDetails.selectedRoute.routeScheduleId = model.carrierProductId;
|
|
|
//}
|
|
|
|
|
|
bookingDto.bookingBody.cargo = new MSKAPIBookingCargo
|
|
|
{
|
|
|
commodityCode = model.commodityCode,
|
|
|
commodityCodeType = "MaerskCode",
|
|
|
cargoType = model.cargoType,
|
|
|
totalCargoWeight = model.totalCargoWeight
|
|
|
};
|
|
|
|
|
|
//是否冷冻处理
|
|
|
if (model.isReefer)
|
|
|
{
|
|
|
bookingDto.bookingBody.cargo.reeferSettings = new MSKAPIBookingCargoReeferSettings();
|
|
|
|
|
|
bookingDto.bookingBody.cargo.reeferSettings.temperatureDetails = model.temperature;
|
|
|
bookingDto.bookingBody.cargo.reeferSettings.temperatureMeasureUnit = "C";
|
|
|
|
|
|
bookingDto.bookingBody.cargo.reeferSettings.noOfProbes = model.noOfProbes;
|
|
|
|
|
|
//每小时需要的通风量,单位为立方米(0-285)
|
|
|
bookingDto.bookingBody.cargo.reeferSettings.ventilation = model.ventilation;
|
|
|
|
|
|
bookingDto.bookingBody.cargo.reeferSettings.humidity = model.humidity;
|
|
|
}
|
|
|
|
|
|
bookingDto.bookingBody.equipmentAndHaulage = new List<MSKAPIBookingEquipmentAndHaulage>();
|
|
|
|
|
|
if (model.ctns != null && model.ctns.Count > 0)
|
|
|
{
|
|
|
model.ctns.ForEach(ctn =>
|
|
|
{
|
|
|
var ctnMapping = ctnCodeMappingList.FirstOrDefault(t => t.Code.Equals(ctn.ctnCode));
|
|
|
|
|
|
if(ctnMapping == null)
|
|
|
throw Oops.Oh($"未配置相应的箱型对应{ctn.ctnName},请联系管理员");
|
|
|
|
|
|
MSKAPIBookingEquipmentAndHaulage haulage = new MSKAPIBookingEquipmentAndHaulage
|
|
|
{
|
|
|
equipmentDetails = new MSKAPIBookingEquipmentAndHaulageItem(),
|
|
|
stuffingDetails = new List<MSKAPIBookingStuffingdetails>()
|
|
|
};
|
|
|
|
|
|
if (model.isShipperOwned)
|
|
|
haulage.equipmentDetails.isShipperOwned = model.isShipperOwned;
|
|
|
|
|
|
if (model.isImportReturned)
|
|
|
haulage.equipmentDetails.isImportReturned = model.isImportReturned;
|
|
|
|
|
|
haulage.equipmentDetails.ISOEquipmentCode = ctnMapping.MapCode;
|
|
|
haulage.equipmentDetails.equipmentQuantity = ctn.ctnNum;
|
|
|
|
|
|
haulage.stuffingDetails.Add(new MSKAPIBookingStuffingdetails
|
|
|
{
|
|
|
stuffingValue = (int)ctn.ctnSufferWeight.Value,
|
|
|
stuffingMeasurementType = "WEIGHT",
|
|
|
stuffingMeasurementUnit = "KGS"
|
|
|
});
|
|
|
|
|
|
bookingDto.bookingBody.equipmentAndHaulage.Add(haulage);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
var id = InnerSave(model, isSendApi: true).GetAwaiter().GetResult();
|
|
|
|
|
|
result.id = id;
|
|
|
|
|
|
MSKAPIBookingResultDto resultInfo = null;
|
|
|
|
|
|
_logger.LogInformation($"开始请求MSK API订舱,JSON={JSON.Serialize(bookingDto)}");
|
|
|
|
|
|
var jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(bookingDto);
|
|
|
var rlt = await sendUrl.SetBody(jsonBody)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
_logger.LogInformation($"开始请求MSK API订舱,返回结果 JSON={JSON.Serialize(rlt)}");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rlt))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
resultInfo = JSON.Deserialize<MSKAPIBookingResultDto>(rlt);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"请求MSK API订舱异常,原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"请求MSK API订舱异常,原因:{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
MSKAPIBookingResultDataDto resultData = null;
|
|
|
|
|
|
if(resultInfo.code == 200)
|
|
|
{
|
|
|
resultData = JSON.Deserialize<MSKAPIBookingResultDataDto>(JSON.Serialize(resultInfo.data));
|
|
|
}
|
|
|
|
|
|
var entity = _bookingDeliveryRecordRep
|
|
|
.FirstOrDefault(a => a.Id == id);
|
|
|
|
|
|
if (resultInfo != null && resultInfo.code == 200
|
|
|
&& resultData != null)
|
|
|
{
|
|
|
entity.REQUEST_ACKNOWLEDGEMENT_ID = resultData.requestAcknowledgementId;
|
|
|
entity.BOOKING_REFERENCE = resultData.bookingReference;
|
|
|
entity.STATUS = "SUCC";
|
|
|
entity.STATUS_NAME = "发送成功";
|
|
|
|
|
|
await _bookingDeliveryRecordRep.AsUpdateable(entity).UpdateColumns(x => new
|
|
|
{
|
|
|
x.REQUEST_ACKNOWLEDGEMENT_ID,
|
|
|
x.BOOKING_REFERENCE,
|
|
|
x.STATUS
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
entity.STATUS = "FAILURE";
|
|
|
entity.STATUS_NAME = "发送失败";
|
|
|
entity.NOTES = resultInfo.msg.Length > 500 ? resultInfo.msg.Substring(0, 500) : resultInfo.msg;
|
|
|
|
|
|
await _bookingDeliveryRecordRep.AsUpdateable(entity).UpdateColumns(x => new
|
|
|
{
|
|
|
x.STATUS,
|
|
|
x.NOTES
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
throw Oops.Bah(resultInfo.msg);
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"MSK API订舱异常,req={JSON.Serialize(model)} 原因:{ex.Message}");
|
|
|
|
|
|
//throw Oops.Bah($"MSK API订舱失败,{ex.Message}");
|
|
|
|
|
|
result.succ = false;
|
|
|
result.msg = $"MSK API订舱失败,{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 校验马士基API订舱必填项
|
|
|
/// <summary>
|
|
|
/// 校验马士基API订舱必填项
|
|
|
/// </summary>
|
|
|
/// <param name="model"></param>
|
|
|
private void ValidateMSKAPIData(MSKBookingDto model)
|
|
|
{
|
|
|
/*
|
|
|
马士基API订舱内容校验
|
|
|
1、合约号必填
|
|
|
2、请求类别必填
|
|
|
3、服务船公司必填
|
|
|
4、订舱公司名称、代码、联系人、邮箱必填
|
|
|
5、持约方公司名称、代码、联系、邮箱必填
|
|
|
6、始发地城市名称、UNLOC、国家代码、服务模式
|
|
|
7、目的地城市名称、UNLOC、国家代码、服务模式
|
|
|
8、船名、航次、ETD、ETA
|
|
|
9、商品名称、代码必填
|
|
|
10、总重必填
|
|
|
11、货物标志必填
|
|
|
12、如果选择了冷冻处理,至少要填个温度
|
|
|
13、箱型、箱量、重量必填
|
|
|
14、总重=箱量*单箱重量
|
|
|
15、预计离港日期必填
|
|
|
*/
|
|
|
if (string.IsNullOrWhiteSpace(model.priceReference))
|
|
|
throw Oops.Bah($"订舱合同惟一ID必填");
|
|
|
|
|
|
if(!Regex.IsMatch(model.priceReference,"[a-zA-Z0-9_/,-]{1,50}"))
|
|
|
throw Oops.Bah($"订舱合同惟一ID格式错误 [a-zA-Z0-9_/,-]{{1,50}}");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.sender))
|
|
|
throw Oops.Bah($"请求类别必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierCode))
|
|
|
throw Oops.Bah($"服务船公司必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.bookedByCompanyName))
|
|
|
throw Oops.Bah($"订舱公司名称必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.bookedByMaerskPartyCode))
|
|
|
throw Oops.Bah($"订舱方ID必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.bookedByCompanyContactName))
|
|
|
throw Oops.Bah($"订舱方公司联系人必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.bookedByCompanyContactEmail))
|
|
|
throw Oops.Bah($"订舱方公司邮箱必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.priceOwnerContactName))
|
|
|
throw Oops.Bah($"持约方公司名称必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.priceOwnerMaerskPartyCode))
|
|
|
throw Oops.Bah($"持约方ID必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.priceOwnerContactName))
|
|
|
throw Oops.Bah($"持约方公司联系人必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.priceOwnerContactEmail))
|
|
|
throw Oops.Bah($"持约方公司邮箱必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.placeOfReceiptCityName))
|
|
|
throw Oops.Bah($"始发地城市名称必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.placeOfReceiptUnLocCode))
|
|
|
throw Oops.Bah($"始发地UN CODE必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.placeOfReceiptCountryCode))
|
|
|
throw Oops.Bah($"始发地国家代码必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.exportServiceMode))
|
|
|
throw Oops.Bah($"始发地服务模式必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.placeOfDeliveryCityName))
|
|
|
throw Oops.Bah($"目的地城市名称必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.placeOfDeliveryUnLocCode))
|
|
|
throw Oops.Bah($"目的地UN CODE必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.placeOfDeliveryCountryCode))
|
|
|
throw Oops.Bah($"目的地国家代码必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.importServiceMode))
|
|
|
throw Oops.Bah($"目的地服务模式必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.vesselName))
|
|
|
throw Oops.Bah($"船名必填,请确认正确选择了船期");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.exportVoyageNumber))
|
|
|
throw Oops.Bah($"航次号必填,请确认正确选择了船期");
|
|
|
|
|
|
if (!model.originDepartureDateTimeLocal.HasValue)
|
|
|
throw Oops.Bah($"ETD必填,请确认正确选择了船期");
|
|
|
|
|
|
if (!model.destinationArrivalDateTimeLocal.HasValue)
|
|
|
throw Oops.Bah($"ETA必填,请确认正确选择了船期");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.commodityCode))
|
|
|
throw Oops.Bah($"商品代码必填,请确认正确选择了商品");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.commodityName))
|
|
|
throw Oops.Bah($"商品名称必填,请确认正确选择了商品");
|
|
|
|
|
|
if (!model.totalCargoWeight.HasValue || model.totalCargoWeight.Value < 1)
|
|
|
throw Oops.Bah($"总重必填");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.cargoType))
|
|
|
throw Oops.Bah($"货物标志必填");
|
|
|
|
|
|
if(!model.earliestDepartureDate.HasValue)
|
|
|
throw Oops.Bah($"预计离港日期必填");
|
|
|
|
|
|
if (!model.isSendNoSchedule && string.IsNullOrWhiteSpace(model.carrierProductId))
|
|
|
throw Oops.Bah($"船期信息不能为空,请查询船期信息");
|
|
|
|
|
|
if (model.isReefer)
|
|
|
{
|
|
|
if (!model.temperature.HasValue)
|
|
|
throw Oops.Bah($"选择了冷冻处理,温度必填");
|
|
|
}
|
|
|
|
|
|
if (model.ctns.Count == 0)
|
|
|
throw Oops.Bah($"箱型箱量信息必填");
|
|
|
|
|
|
if (model.ctns.Any(a => string.IsNullOrWhiteSpace(a.ctnCode)))
|
|
|
throw Oops.Bah($"箱型不能为空");
|
|
|
|
|
|
if (model.ctns.Any(a => !a.ctnNum.HasValue || a.ctnNum.Value < 1))
|
|
|
throw Oops.Bah($"箱量不能为空,并且不能小于1");
|
|
|
|
|
|
if (model.ctns.Any(a => !a.ctnSufferWeight.HasValue || a.ctnSufferWeight.Value < 1))
|
|
|
throw Oops.Bah($"箱内重量不能为空,并且不能小于1");
|
|
|
|
|
|
|
|
|
if (model.totalCargoWeight.Value != model.ctns.Sum(b => b.ctnNum.Value * b.ctnSufferWeight.Value))
|
|
|
{
|
|
|
throw Oops.Bah($"箱内重量合计不等于总重,请修改");
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检索商品名称
|
|
|
/// <summary>
|
|
|
/// 检索商品名称
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求详情</param>
|
|
|
/// <returns>返回检索结果</returns>
|
|
|
[HttpPost("/BookingMSKAPI/SearchCommodities")]
|
|
|
public async Task<List<SearchCommodityResultDto>> SearchCommodities(QueryCommoditiesDto model)
|
|
|
{
|
|
|
List<SearchCommodityResultDto> list = new List<SearchCommodityResultDto>();
|
|
|
|
|
|
/*
|
|
|
MSKApiCommodity
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.commodityName))
|
|
|
throw Oops.Oh("商品名称不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierId))
|
|
|
throw Oops.Oh("船公司代码不能为空");
|
|
|
|
|
|
if (model.commodityName.Length < 3)
|
|
|
throw Oops.Oh("商品名称至少输入3个以上字符");
|
|
|
|
|
|
string queryUrl = string.Empty;
|
|
|
|
|
|
if (model.carrierId.Equals("MSK", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
queryUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == CONST_MSK_API_COMMODITY_URL)?.Value;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw Oops.Oh($"当前船公司 {model.carrierId} 未配置相应的请求接口");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(queryUrl))
|
|
|
throw Oops.Oh("未配置商品请求接口地址,请联系管理员");
|
|
|
|
|
|
var webAccountConfig = _webAccountConfig
|
|
|
.GetAccountConfig("MSKApi", UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
if (webAccountConfig == null)
|
|
|
throw Oops.Oh("未配置个人账户,请先配置个人账户 类型-MSKApi");
|
|
|
|
|
|
MSKAPISearchCommodityDto queryInfo = new MSKAPISearchCommodityDto
|
|
|
{
|
|
|
userKey = App.Configuration["MSKAPIDjyUserKey"],
|
|
|
userSecret = App.Configuration["MSKAPIDjyUserSecret"],
|
|
|
operatingEnvironment = App.Configuration["MSKAPIOPEnvironment"],
|
|
|
commodityName = model.commodityName,
|
|
|
mskAppKey = webAccountConfig.Account
|
|
|
};
|
|
|
|
|
|
MSKAPISearchCommodityResultDto resultInfo = null;
|
|
|
|
|
|
var rlt = await queryUrl.SetBody(queryInfo)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rlt))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
resultInfo = JSON.Deserialize<MSKAPISearchCommodityResultDto>(rlt);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"请求MSK API检索商品异常,原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"请求MSK API检索商品异常,原因:{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (resultInfo != null && resultInfo.code == 200
|
|
|
&& resultInfo.data != null && resultInfo.data.Count > 0)
|
|
|
{
|
|
|
list = resultInfo.data.Adapt<List<SearchCommodityResultDto>>();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"检索商品名称异常,req={JSON.Serialize(model)} 原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"检索商品名称失败,{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 检索始发地、目的港口信息
|
|
|
/// <summary>
|
|
|
/// 检索始发地、目的港口信息
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求详情</param>
|
|
|
/// <returns>返回检索结果</returns>
|
|
|
[HttpPost("/BookingMSKAPI/SearchLocations")]
|
|
|
public async Task<List<QueryLocationsResultDto>> SearchLocations(QueryLocationsDto model)
|
|
|
{
|
|
|
List<QueryLocationsResultDto> list = new List<QueryLocationsResultDto>();
|
|
|
|
|
|
/*
|
|
|
MSKApiCommodity
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(model.cityName))
|
|
|
throw Oops.Oh("港口或城市名称不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierCode))
|
|
|
throw Oops.Oh("服务船公司不能为空");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.carrierId))
|
|
|
throw Oops.Oh("船公司代码不能为空");
|
|
|
|
|
|
if (model.cityName.Length < 3)
|
|
|
throw Oops.Oh("港口或城市名称至少输入3个以上字符");
|
|
|
|
|
|
|
|
|
string queryUrl = string.Empty;
|
|
|
|
|
|
if (model.carrierId.Equals("MSK", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
queryUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == CONST_MSK_API_LOCATION_URL)?.Value;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw Oops.Oh($"当前船公司 {model.carrierId} 未配置相应的请求接口");
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(queryUrl))
|
|
|
throw Oops.Oh("未配置商品请求接口地址,请联系管理员");
|
|
|
|
|
|
var webAccountConfig = _webAccountConfig
|
|
|
.GetAccountConfig("MSKApi", UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
if (webAccountConfig == null)
|
|
|
throw Oops.Oh("未配检索始发地、目的港口,请先配置个人账户 类型-MSKApi");
|
|
|
|
|
|
MSKAPISearchLocationDto queryInfo = new MSKAPISearchLocationDto
|
|
|
{
|
|
|
userKey = App.Configuration["MSKAPIDjyUserKey"],
|
|
|
userSecret = App.Configuration["MSKAPIDjyUserSecret"],
|
|
|
operatingEnvironment = App.Configuration["MSKAPIOPEnvironment"],
|
|
|
name = model.cityName,
|
|
|
mskAppKey = webAccountConfig.Account,
|
|
|
carrierCode = model.carrierCode
|
|
|
};
|
|
|
|
|
|
MSKAPISearchLocationResultDto resultInfo = null;
|
|
|
|
|
|
var rlt = await queryUrl.SetBody(queryInfo)
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rlt))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
resultInfo = JSON.Deserialize<MSKAPISearchLocationResultDto>(rlt);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation($"请求MSK API检索始发地、目的港口异常,原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"请求MSK API检索始发地、目的港口异常,原因:{ex.Message}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (resultInfo != null && resultInfo.code == 200
|
|
|
&& resultInfo.data != null && resultInfo.data.Count > 0)
|
|
|
{
|
|
|
list = resultInfo.data.Adapt<List<QueryLocationsResultDto>>();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"检索始发地、目的港口异常,req={JSON.Serialize(model)} 原因:{ex.Message}");
|
|
|
|
|
|
throw Oops.Bah($"检索始发地、目的港口失败,{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 马士基API订舱台账
|
|
|
/// <summary>
|
|
|
/// 马士基API订舱台账
|
|
|
/// </summary>
|
|
|
/// <param name="QuerySearch">查询条件</param>
|
|
|
/// <returns>返回台账列表</returns>
|
|
|
[HttpPost("/BookingMSKAPI/GetPage")]
|
|
|
public async Task<SqlSugarPagedList<BookingDeliveryRecordPageDto>> GetPageAsync([FromBody] QueryBookingDeliveryRecordDto QuerySearch)
|
|
|
{
|
|
|
|
|
|
//制单日期
|
|
|
DateTime createBegin = DateTime.MinValue;
|
|
|
DateTime createEnd = DateTime.MinValue;
|
|
|
//更新日期
|
|
|
DateTime updateBegin = DateTime.MinValue;
|
|
|
DateTime updateEnd = DateTime.MinValue;
|
|
|
//预计离港日期
|
|
|
DateTime edepartureBegin = DateTime.MinValue;
|
|
|
DateTime edepartureEnd = DateTime.MinValue;
|
|
|
//ETD日期
|
|
|
DateTime etdBegin = DateTime.MinValue;
|
|
|
DateTime etdEnd = DateTime.MinValue;
|
|
|
//ETA时间
|
|
|
DateTime etaBegin = DateTime.MinValue;
|
|
|
DateTime etaEnd = DateTime.MinValue;
|
|
|
|
|
|
//定时
|
|
|
DateTime jobBegin = DateTime.MinValue;
|
|
|
DateTime jobEnd = DateTime.MinValue;
|
|
|
|
|
|
#region 查询条件
|
|
|
|
|
|
//制单日期
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.CreateBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.CreateBegin, out createBegin))
|
|
|
throw Oops.Oh($"创建起始日期格式错误,{QuerySearch.CreateBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.CreateEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.CreateEnd, out createEnd))
|
|
|
throw Oops.Oh($"创建结束日期格式错误,{QuerySearch.CreateEnd}");
|
|
|
|
|
|
createEnd = createEnd.AddDays(1);
|
|
|
}
|
|
|
//更新日期
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.UpdateBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.UpdateBegin, out updateBegin))
|
|
|
throw Oops.Oh($"更新起始日期开始格式错误,{QuerySearch.UpdateBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.UpdateEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.UpdateEnd, out updateEnd))
|
|
|
throw Oops.Oh($"更新结束日期格式错误,{QuerySearch.UpdateEnd}");
|
|
|
|
|
|
updateEnd = updateEnd.AddDays(1);
|
|
|
}
|
|
|
//预计离港日期
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.EDepartureBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.EDepartureBegin, out edepartureBegin))
|
|
|
throw Oops.Oh($"预计离港日期起始格式错误,{QuerySearch.EDepartureBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.EDepartureEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.EDepartureEnd, out edepartureEnd))
|
|
|
throw Oops.Oh($"预计离港日期结束格式错误,{QuerySearch.EDepartureEnd}");
|
|
|
|
|
|
edepartureEnd = edepartureEnd.AddDays(1);
|
|
|
}
|
|
|
|
|
|
//ETD
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDBegin, out etdBegin))
|
|
|
throw Oops.Oh($"ETD起始日期格式错误,{QuerySearch.ETDBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDEnd, out etdEnd))
|
|
|
throw Oops.Oh($"ETD结束日期格式错误,{QuerySearch.ETDEnd}");
|
|
|
|
|
|
etdEnd = etdEnd.AddDays(1);
|
|
|
}
|
|
|
//ETA
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDBegin, out etaBegin))
|
|
|
throw Oops.Oh($"ETA起始日期格式错误,{QuerySearch.ETDBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETAEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETAEnd, out etaEnd))
|
|
|
throw Oops.Oh($"ETA结束日期格式错误,{QuerySearch.ETAEnd}");
|
|
|
|
|
|
etaEnd = etaEnd.AddDays(1);
|
|
|
}
|
|
|
|
|
|
//定时
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.JOBBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.JOBBegin, out jobBegin))
|
|
|
throw Oops.Oh($"返场起始日期格式错误,{QuerySearch.JOBBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.JOBEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.JOBEnd, out jobEnd))
|
|
|
throw Oops.Oh($"返场结束日期格式错误,{QuerySearch.JOBEnd}");
|
|
|
|
|
|
jobEnd = jobEnd.AddDays(1);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
//这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.SortField))
|
|
|
entityOrderCol = MapsterExtHelper.GetAdaptProperty<BookingDeliveryRecordDto, BookingDeliveryRecord>(QuerySearch.SortField);
|
|
|
|
|
|
var entities = await _bookingDeliveryRecordRep.AsQueryable()
|
|
|
.WhereIF(createBegin != DateTime.MinValue, t => t.CreatedTime.HasValue && t.CreatedTime.Value >= createBegin)
|
|
|
.WhereIF(createEnd != DateTime.MinValue, t => t.CreatedTime.HasValue && t.CreatedTime.Value < createEnd)
|
|
|
.WhereIF(updateBegin != DateTime.MinValue, t => t.UpdatedTime.HasValue && t.UpdatedTime.Value >= updateBegin)
|
|
|
.WhereIF(updateEnd != DateTime.MinValue, t => t.UpdatedTime.HasValue && t.UpdatedTime.Value < updateEnd)
|
|
|
.WhereIF(edepartureBegin != DateTime.MinValue, t => t.EARLIEST_DEPARTURE_DATE.HasValue && t.EARLIEST_DEPARTURE_DATE.Value >= edepartureBegin)
|
|
|
.WhereIF(edepartureEnd != DateTime.MinValue, t => t.EARLIEST_DEPARTURE_DATE.HasValue && t.EARLIEST_DEPARTURE_DATE.Value < edepartureEnd)
|
|
|
.WhereIF(etdBegin != DateTime.MinValue, t => t.ETD.HasValue && t.ETD.Value >= etdBegin)
|
|
|
.WhereIF(etdEnd != DateTime.MinValue, t => t.ETD.HasValue && t.ETA.Value < etdEnd)
|
|
|
.WhereIF(etaBegin != DateTime.MinValue, t => t.ETA.HasValue && t.ETA.Value >= etaBegin)
|
|
|
.WhereIF(etaEnd != DateTime.MinValue, t => t.ETA.HasValue && t.ETA.Value < etaEnd)
|
|
|
.WhereIF(jobBegin != DateTime.MinValue, t => t.JOB_TIME.HasValue && t.JOB_TIME.Value >= jobBegin)
|
|
|
.WhereIF(jobEnd != DateTime.MinValue, t => t.JOB_TIME.HasValue && t.JOB_TIME.Value < jobEnd)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.PriceReference), t => t.PRICE_REFERENCE.Contains(QuerySearch.PriceReference))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.BookedByCompanyName), t => t.BOOKEDBY_COMPANY_NAME.Contains(QuerySearch.BookedByCompanyName))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.BookedByCompanyPartyCode), t => t.BOOKEDBY_COMPANY_PARTYCODE.Contains(QuerySearch.BookedByCompanyPartyCode))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.PriceOwnerCompanyName), t => t.PRICE_OWNER_COMPANY_NAME.Contains(QuerySearch.PriceOwnerCompanyName))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.PriceOwnerCompanyPartyCode), t => t.PRICE_OWNER_COMPANY_PARTYCODE.Contains(QuerySearch.PriceOwnerCompanyPartyCode))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.PlaceReceiptCity), t => t.PLACERECEIPT_CITY.Contains(QuerySearch.PlaceReceiptCity) || t.PLACERECEIPT_UNLOC_CODE.Contains(QuerySearch.PlaceReceiptCity))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.PlaceDeliveryCity), t => t.PLACEDELIVERY_CITY.Contains(QuerySearch.PlaceDeliveryCity) || t.PLACEDELIVERY_UNLOC_CODE.Contains(QuerySearch.PlaceDeliveryCity))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.BookingReference), t => t.BOOKING_REFERENCE.Contains(QuerySearch.BookingReference))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.BookingCreator), t => t.CreatedUserName.Contains(QuerySearch.BookingCreator) || t.UpdatedUserName.Contains(QuerySearch.BookingCreator))
|
|
|
.OrderBy(entityOrderCol + (QuerySearch.descSort ? " desc " : " asc "))
|
|
|
.ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize);
|
|
|
|
|
|
|
|
|
return entities.Adapt<SqlSugarPagedList<BookingDeliveryRecordPageDto>>();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取马士基API订舱详情
|
|
|
/// <summary>
|
|
|
/// 获取马士基API订舱详情
|
|
|
/// </summary>
|
|
|
/// <param name="id">马士基API订舱ID</param>
|
|
|
/// <returns>返回详情</returns>
|
|
|
[HttpGet("/BookingMSKAPI/GetInfo")]
|
|
|
public async Task<MSKBookingDto> GetInfo(long id)
|
|
|
{
|
|
|
MSKBookingDto model = null;
|
|
|
|
|
|
var entity = await _bookingDeliveryRecordRep.AsQueryable()
|
|
|
.FirstAsync(a => a.Id == id);
|
|
|
|
|
|
if(entity == null)
|
|
|
throw Oops.Oh($"获取马士基API订舱详情失败,不存在或已作废");
|
|
|
|
|
|
model = entity.Adapt<MSKBookingDto>();
|
|
|
|
|
|
var ctnList = _bookingDeliveryRecordCtnRep.AsQueryable()
|
|
|
.Where(a => a.RECORD_ID == id && a.IsDeleted == false).ToList();
|
|
|
|
|
|
if (ctnList.Count > 0)
|
|
|
{
|
|
|
model.ctns = ctnList.Select(a => new MSKBookingCtnInfo
|
|
|
{
|
|
|
id = a.Id,
|
|
|
ctnCode = a.CTN_CODE,
|
|
|
carrierCtnCode = a.CARRIER_CTN_CODE,
|
|
|
ctnNum = a.CTN_NUM,
|
|
|
ctnName = a.CTN_NAME,
|
|
|
ctnSufferWeight = a.CTN_SUFFER_WEIGHT,
|
|
|
stuffingMeasurementType = a.STUFFING_MEASUREMENT_TYPE,
|
|
|
stuffingMeasurementUnit = a.STUFFING_MEASUREMENT_UNIT
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 保存
|
|
|
/// <summary>
|
|
|
/// 保存
|
|
|
/// </summary>
|
|
|
/// <param name="model">请求订舱详情</param>
|
|
|
/// <returns>返回ID</returns>
|
|
|
[HttpPost("/BookingMSKAPI/Save")]
|
|
|
public async Task<long> Save([FromBody] MSKBookingDto model)
|
|
|
{
|
|
|
return await InnerSave(model);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
/// 保存内部方法
|
|
|
/// </summary>
|
|
|
/// <param name="model">API订舱详情</param>
|
|
|
/// <param name="isSendApi">是否发送API,true-发送需要校验状态;false-不校验状态</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<long> InnerSave(MSKBookingDto model,bool isSendApi = false)
|
|
|
{
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
string ctnStat = string.Empty;
|
|
|
|
|
|
_logger.LogInformation($"获取请求马士基API订舱报文,JSON={JSON.Serialize(model)}");
|
|
|
|
|
|
if (model.ctns != null && model.ctns.Count > 0)
|
|
|
{
|
|
|
ctnStat = string.Join(",", model.ctns.GroupBy(a => a.ctnName)
|
|
|
.Select(a => $"{a.Key}*{a.ToList().Sum(b => b.ctnNum.HasValue ? b.ctnNum.Value : 0)}").ToArray());
|
|
|
}
|
|
|
|
|
|
if (model.id.HasValue && model.id.Value > 0)
|
|
|
{
|
|
|
var oldInfo = _bookingDeliveryRecordRep.AsQueryable()
|
|
|
.First(a=>a.Id == model.id);
|
|
|
|
|
|
if (oldInfo == null)
|
|
|
throw Oops.Oh("订舱数据不存在或已作废");
|
|
|
|
|
|
if (oldInfo.STATUS == "SUCC")
|
|
|
{
|
|
|
if(isSendApi)
|
|
|
throw Oops.Oh("订舱数据已发送成功,不能重复发送");
|
|
|
|
|
|
throw Oops.Oh("订舱数据已发送成功,不能修改");
|
|
|
}
|
|
|
|
|
|
|
|
|
BookingDeliveryRecord entity = model.Adapt<BookingDeliveryRecord>();
|
|
|
|
|
|
entity.Id = model.id.Value;
|
|
|
entity.UpdatedTime = nowDate;
|
|
|
entity.UpdatedUserId = UserManager.UserId;
|
|
|
entity.UpdatedUserName = UserManager.Name;
|
|
|
entity.CTN_STAT = ctnStat;
|
|
|
|
|
|
await _bookingDeliveryRecordRep.AsUpdateable(entity).IgnoreColumns(x => new
|
|
|
{
|
|
|
x.CreatedTime,
|
|
|
x.CreatedUserId,
|
|
|
x.CreatedUserName,
|
|
|
x.BOOKING_REFERENCE,
|
|
|
x.BookingId,
|
|
|
x.REQUEST_ACKNOWLEDGEMENT_ID,
|
|
|
x.STATUS,
|
|
|
x.TenantId,
|
|
|
x.IS_RECV_BC,
|
|
|
x.LST_RECV_BC_DATE,
|
|
|
x.IS_RECV_BK_CANCEL,
|
|
|
x.LST_RECV_BK_CANCEL_DATE
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
if (model.ctns != null && model.ctns.Count > 0)
|
|
|
{
|
|
|
var ctnEntityList = _bookingDeliveryRecordCtnRep.AsQueryable()
|
|
|
.Where(a => a.RECORD_ID == entity.Id && a.IsDeleted == false).ToList();
|
|
|
|
|
|
model.ctns.ForEach(ctn =>
|
|
|
{
|
|
|
if (ctn.id.HasValue && ctn.id.Value > 0)
|
|
|
{
|
|
|
if (ctnEntityList.Any(x => x.Id == ctn.id.Value))
|
|
|
{
|
|
|
ctnEntityList.Remove(ctnEntityList.FirstOrDefault(x => x.Id == ctn.id.Value));
|
|
|
}
|
|
|
|
|
|
//更新
|
|
|
var ctnEntity = ctn.Adapt<BookingDeliveryRecordCtn>();
|
|
|
|
|
|
ctnEntity.Id = ctn.id.Value;
|
|
|
ctnEntity.RECORD_ID = entity.Id;
|
|
|
ctnEntity.UpdatedTime = nowDate;
|
|
|
ctnEntity.UpdatedUserId = UserManager.UserId;
|
|
|
ctnEntity.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
_bookingDeliveryRecordCtnRep.AsUpdateable(ctnEntity).IgnoreColumns(x => new {
|
|
|
x.CreatedUserId,
|
|
|
x.CreatedUserName,
|
|
|
x.CreatedTime,
|
|
|
x.TenantId,
|
|
|
x.STUFFING_MEASUREMENT_TYPE,
|
|
|
x.STUFFING_MEASUREMENT_UNIT,
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var ctnEntity = new BookingDeliveryRecordCtn
|
|
|
{
|
|
|
CTN_CODE = ctn.ctnCode,
|
|
|
CTN_NAME = ctn.ctnName,
|
|
|
CTN_NUM = ctn.ctnNum.Value
|
|
|
};
|
|
|
|
|
|
ctnEntity.RECORD_ID = entity.Id;
|
|
|
ctnEntity.CreatedTime = nowDate;
|
|
|
ctnEntity.UpdatedTime = nowDate;
|
|
|
ctnEntity.CreatedUserId = UserManager.UserId;
|
|
|
ctnEntity.CreatedUserName = UserManager.Name;
|
|
|
ctnEntity.STUFFING_MEASUREMENT_TYPE = "WEIGHT";
|
|
|
ctnEntity.STUFFING_MEASUREMENT_UNIT = "KGS";
|
|
|
|
|
|
_bookingDeliveryRecordCtnRep.Insert(ctnEntity);
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (ctnEntityList.Count > 0)
|
|
|
{
|
|
|
ctnEntityList.ForEach(async ctn => {
|
|
|
ctn.IsDeleted = true;
|
|
|
ctn.UpdatedTime = nowDate;
|
|
|
ctn.UpdatedUserId = UserManager.UserId;
|
|
|
ctn.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _bookingDeliveryRecordCtnRep.AsUpdateable(ctn).UpdateColumns(x => new {
|
|
|
x.IsDeleted,
|
|
|
x.UpdatedTime,
|
|
|
x.UpdatedUserId,
|
|
|
x.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return model.id.Value;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
BookingDeliveryRecord entity = model.Adapt<BookingDeliveryRecord>();
|
|
|
|
|
|
entity.CreatedTime = nowDate;
|
|
|
entity.UpdatedTime = nowDate;
|
|
|
entity.CreatedUserId = UserManager.UserId;
|
|
|
entity.CreatedUserName = UserManager.Name;
|
|
|
entity.STATUS = "TEMP";
|
|
|
entity.STATUS_NAME = "暂存";
|
|
|
entity.CTN_STAT = ctnStat;
|
|
|
|
|
|
await _bookingDeliveryRecordRep.InsertAsync(entity);
|
|
|
|
|
|
if (model.ctns != null && model.ctns.Count > 0)
|
|
|
{
|
|
|
model.ctns.ForEach(ctn =>
|
|
|
{
|
|
|
var ctnEntity = new BookingDeliveryRecordCtn {
|
|
|
CTN_CODE = ctn.ctnCode,
|
|
|
CTN_NAME = ctn.ctnName,
|
|
|
CTN_NUM = ctn.ctnNum.Value
|
|
|
};
|
|
|
|
|
|
ctnEntity.RECORD_ID = entity.Id;
|
|
|
ctnEntity.CreatedTime = nowDate;
|
|
|
ctnEntity.UpdatedTime = nowDate;
|
|
|
ctnEntity.CreatedUserId = UserManager.UserId;
|
|
|
ctnEntity.CreatedUserName = UserManager.Name;
|
|
|
ctnEntity.STUFFING_MEASUREMENT_TYPE = "WEIGHT";
|
|
|
ctnEntity.STUFFING_MEASUREMENT_UNIT = "KGS";
|
|
|
|
|
|
_bookingDeliveryRecordCtnRep.Insert(ctnEntity);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return entity.Id;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 删除
|
|
|
/// <summary>
|
|
|
/// 删除
|
|
|
/// </summary>
|
|
|
/// <param name="id">请求订舱ID</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpGet("/BookingMSKAPI/Delete")]
|
|
|
public async Task Delete(long id)
|
|
|
{
|
|
|
var info = _bookingDeliveryRecordRep.AsQueryable().First(a => a.Id == id);
|
|
|
|
|
|
if(info == null)
|
|
|
throw Oops.Bah($"删除失败,业务信息不存在或已作废");
|
|
|
|
|
|
info.IsDeleted = true;
|
|
|
info.UpdatedTime = DateTime.Now;
|
|
|
info.UpdatedUserId = UserManager.UserId;
|
|
|
info.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
await _bookingDeliveryRecordRep.AsUpdateable(info).UpdateColumns(x => new {
|
|
|
x.IsDeleted,
|
|
|
x.UpdatedTime,
|
|
|
x.UpdatedUserId,
|
|
|
x.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 批量发送
|
|
|
/// <summary>
|
|
|
/// 批量发送
|
|
|
/// </summary>
|
|
|
/// <param name="ids">马士基API订舱ID组</param>
|
|
|
/// <returns>返回执行结果消息</returns>
|
|
|
public async Task<string> BatchSend(long[] ids)
|
|
|
{
|
|
|
var list = await _bookingDeliveryRecordRep.AsQueryable()
|
|
|
.Where(a => ids.Contains(a.Id)).ToListAsync();
|
|
|
|
|
|
if (list.Count != ids.Length)
|
|
|
throw Oops.Oh("订舱数据获取失败,请确认选中的记录是否存在");
|
|
|
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 批量发送
|
|
|
/// <summary>
|
|
|
/// 批量发送
|
|
|
/// </summary>
|
|
|
/// <param name="id">马士基API订舱ID</param>
|
|
|
/// <param name="copyNum">需要复制生成记录</param>
|
|
|
/// <returns>返回执行结果消息</returns>
|
|
|
public async Task<string> BatchCopy(long id, int copyNum)
|
|
|
{
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|