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/Service/BookingOrder/BookingMSKAPIService.cs

2721 lines
118 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.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;
using Myshipping.Core.Const;
using System.Reflection.Metadata;
using Org.BouncyCastle.Crypto;
using Yitter.IdGenerator;
using MySqlX.XDevAPI.Common;
using NPOI.OpenXmlFormats.Wordprocessing;
using Newtonsoft.Json;
using StackExchange.Profiling.Internal;
using SqlSugar;
using static Aliyun.OSS.Model.InventoryConfigurationModel;
using System.Threading;
using System.Collections;
using MathNet.Numerics;
using Myshipping.Core.Entity;
using HtmlAgilityPack;
using System.Security.Cryptography;
using Myshipping.Application.ConfigOption;
using System.IO;
using System.Net.Http;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.EMMA;
using Microsoft.AspNetCore.Authorization;
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 SqlSugarRepository<BookingDeliveryRecordShipSchedule> _bookingDeliveryRecordShipScheduleRep;
private readonly SqlSugarRepository<BookingDeliveryRecordJobRun> _bookingDeliveryRecordJobRunScheduleRep;
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccount;
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
private readonly ISysCacheService _cache;
private readonly IDjyWebsiteAccountConfigService _webAccountConfig;
private readonly ILogger<BookingMSKAPIService> _logger;
private readonly ISysDataUserMenu _sysDataUserMenuService;
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,
ISysDataUserMenu sysDataUserMenuService,
SqlSugarRepository<BookingDeliveryRecordCtn> bookingDeliveryRecordCtnRep, SqlSugarRepository<BookingDeliveryRecordShipSchedule> bookingDeliveryRecordShipScheduleRep,
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccount, SqlSugarRepository<BookingDeliveryRecordJobRun> bookingDeliveryRecordJobRunScheduleRep, SqlSugarRepository<SysUser> sysUserRepository)
{
_logger = logger;
_cache = cache;
_webAccountConfig = webAccountConfig;
_bookingDeliveryRecordRep = bookingDeliveryRecordRep;
_bookingDeliveryRecordCtnRep = bookingDeliveryRecordCtnRep;
_sysDataUserMenuService = sysDataUserMenuService;
_bookingDeliveryRecordShipScheduleRep = bookingDeliveryRecordShipScheduleRep;
_djyUserMailAccount = djyUserMailAccount;
_bookingDeliveryRecordJobRunScheduleRep = bookingDeliveryRecordJobRunScheduleRep;
_sysUserRepository = sysUserRepository;
}
#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,
cargoType = model.cargoType,
exportServiceMode = model.exportServiceMode,
importServiceMode = model.importServiceMode,
vesselOperatorCarrierCode = model.vesselOperatorCarrierCode,
startDate = etd.ToString("yyyy-MM-dd"),
startDateType = "D",
};
if(!string.IsNullOrWhiteSpace(model.carrierCollectionOriginGeoID) && !string.IsNullOrWhiteSpace(model.carrierDeliveryDestinationGeoID))
{
queryInfo.carrierCollectionOriginGeoID = model.carrierCollectionOriginGeoID;
queryInfo.carrierDeliveryDestinationGeoID = model.carrierDeliveryDestinationGeoID;
}
else
{
queryInfo.collectionOriginCityName = model.collectionOriginCityName;
queryInfo.collectionOriginCountryCode = model.collectionOriginCountryCode;
queryInfo.deliveryDestinationCityName = model.deliveryDestinationCityName;
queryInfo.deliveryDestinationCountryCode = model.deliveryDestinationCountryCode;
}
//有时候船期需要带上箱型检索
if (!string.IsNullOrWhiteSpace(model.ISOEquipmentCode))
{
//这里需要翻译一下箱型
var ctnCodeMappingList = _cache.GetAllMappingCtn().GetAwaiter().GetResult().ToList();
if (ctnCodeMappingList.Count > 0)
ctnCodeMappingList = ctnCodeMappingList.Where(x => x.CarrierCode == "MSK" && x.Module == "BOOK_MSK_API").ToList();
var ctnMapping = ctnCodeMappingList.FirstOrDefault(t => t.Code.Equals(model.ISOEquipmentCode));
if (ctnMapping == null)
{
queryInfo.ISOEquipmentCode = model.ISOEquipmentCode;
}
else
{
queryInfo.ISOEquipmentCode = ctnMapping.MapCode;
}
}
if (!string.IsNullOrWhiteSpace(model.stuffingWeight))
{
queryInfo.stuffingWeight = model.stuffingWeight;
}
if (model.stuffingVolume > 0)
{
queryInfo.stuffingVolume = model.stuffingVolume;
}
MSKAPISearchPoint2PointScheduleResultDto resultInfo = null;
var jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(queryInfo, Formatting.Indented, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
var rlt = await queryUrl.SetBody(jsonBody)
.PostAsStringAsync();
_logger.LogInformation($"请求MSK API查询船期请求{jsonBody}");
if (!string.IsNullOrWhiteSpace(rlt))
{
try
{
_logger.LogInformation($"请求MSK API查询船期结果{rlt}");
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(t =>
{
t.transportSchedules.ForEach(a =>
{
a.originGeoId = model.carrierCollectionOriginGeoID;
a.originUnLocCode = model.collectionOriginUNLocationCode;
a.originRegionName = model.collectionOriginUNRegionName;
a.originCityName = model.collectionOriginCityName;
a.originCountryName = model.collectionOriginCountryName;
a.destinationGeoId = model.carrierDeliveryDestinationGeoID;
a.destinationUnLocCode = model.deliveryDestinationUNLocationCode;
a.destinationRegionName = model.deliveryDestinationUNRegionName;
a.destinationCityName = model.deliveryDestinationCityName;
a.destinationCountryName = model.deliveryDestinationCountryName;
CacheShipSailingSchedule(a).GetAwaiter().GetResult();
});
var currList = t.transportSchedules.Select(a =>
{
return GetShipScheduleShow(a);
}).ToList();
if (currList.Count > 0)
list.AddRange(currList);
});
}
}
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>
private SearchShipSailingScheduleResultDto GetShipScheduleShow(MSKAPISearchTransportSchedules model)
{
SearchShipSailingScheduleResultDto showDto = new SearchShipSailingScheduleResultDto
{
PId = model.PId,
MD5 = model.MD5,
orignCarrierCityGeoID = model.originGeoId,
orignUNLocationCode = model.originUnLocCode,
orignCityName = model.originCityName,
originRegionName = model.originRegionName,
originCountryName = model.originCountryName,
deliveryCarrierCityGeoID = model.destinationGeoId,
deliveryUNLocationCode = model.destinationUnLocCode,
deliveryCityName = model.destinationCityName,
deliveryRegionName = model.destinationRegionName,
deliveryCountryName = model.destinationCountryName,
vesselName = model.firstDepartureVessel.vesselName,
carrierDepartureVoyageNumber = model.transportLegs.FirstOrDefault().transport.carrierDepartureVoyageNumber,
Legs = new List<MSKAPISPOTScheduleRateResultShowLegsDto>()
};
//ETD
if (model.departureDateTime.HasValue)
{
showDto.ETD = model.departureDateTime.Value;
}
else
{
throw Oops.Bah($"查询船期错误,预计离港日期查询为空");
}
//ETA
if (model.arrivalDateTime.HasValue)
{
showDto.ETA = model.arrivalDateTime.Value;
}
else
{
throw Oops.Bah($"查询船期错误,预计到港日期查询为空");
}
//计算预计天数
if (showDto.ETD.HasValue && showDto.ETD.HasValue)
{
TimeSpan ts = showDto.ETA.Value.Subtract(showDto.ETD.Value);
var timeDiff = ts.TotalHours;
showDto.days = (int)Math.Ceiling(timeDiff / 24.0);
}
if (model.transportLegs.Count > 1)
showDto.isTransfer = true;
//Legs
if (model.facilities != null)
{
showDto.orignCountryCode = model.facilities.collectionOrigin.countryCode;
showDto.deliveryCountryCode = model.facilities.deliveryDestination.countryCode;
var legs = new List<MSKAPISPOTScheduleRateResultShowLegsDto>();
for (int i = 0; i < model.transportLegs.Count; i++)
{
var b = model.transportLegs[i];
MSKAPISPOTScheduleRateResultShowLegsDto leg = new MSKAPISPOTScheduleRateResultShowLegsDto
{
vesselName = b.transport.vessel?.vesselName,
VoyageNo = b.transport?.carrierDepartureVoyageNumber,
From = new MSKAPISPOTScheduleRateResultShowLegsLocationDto
{
CityName = b.facilities.startLocation.cityName,
CountryCode = b.facilities.startLocation.countryCode,
SiteGeoId = b.facilities.startLocation.carrierSiteGeoID,
LocationType = "From",
},
To = new MSKAPISPOTScheduleRateResultShowLegsLocationDto
{
CityName = b.facilities.endLocation.cityName,
CountryCode = b.facilities.endLocation.countryCode,
SiteGeoId = b.facilities.endLocation.carrierSiteGeoID,
LocationType = "To",
}
};
//ETD
if (b.departureDateTime.HasValue)
{
leg.ETD = b.departureDateTime.Value;
}
else
{
throw Oops.Bah($"查询船期错误,预计离港日期查询为空");
}
//ETA
if (b.arrivalDateTime.HasValue)
{
leg.ETA = b.arrivalDateTime.Value;
}
else
{
throw Oops.Bah($"查询船期错误,预计到港日期查询为空");
}
leg.SortNo = i + 1;
leg.From.SiteGeoId = b.facilities.startLocation.carrierSiteGeoID;
leg.From.CityName = b.facilities.startLocation.cityName;
leg.From.CountryCode = b.facilities.startLocation.countryCode;
leg.From.UnLocCode = b.facilities.startLocation.UNLocationCode;
leg.To.SiteGeoId = b.facilities.endLocation.carrierSiteGeoID;
leg.To.CityName = b.facilities.endLocation.cityName;
leg.To.CountryCode = b.facilities.endLocation.countryCode;
leg.To.UnLocCode = b.facilities.endLocation.UNLocationCode;
if (i == 0 && i == model.transportLegs.Count - 1)
{
leg.From.CityGeoId = model.originGeoId;
leg.From.CountryName = model.originCountryName;
leg.From.RegionName = model.originRegionName;
leg.To.CityGeoId= model.destinationGeoId;
leg.To.CountryName = model.destinationCountryName;
leg.To.RegionName = model.destinationRegionName;
}
else
{
if(i == 0)
{
leg.From.CityGeoId = model.originGeoId;
leg.From.CountryName = model.originCountryName;
leg.From.RegionName = model.originRegionName;
leg.From.UnLocCode = model.originUnLocCode;
}
else if(i == model.transportLegs.Count - 1)
{
leg.To.CityGeoId = model.destinationGeoId;
leg.To.CountryName = model.destinationCountryName;
leg.To.RegionName = model.destinationRegionName;
leg.To.UnLocCode = model.destinationUnLocCode;
}
}
legs.Add(leg);
}
showDto.Legs = legs.OrderBy(t => t.ETD).Select((t, idx) => {
t.SortNo = idx + 1;
return t;
}).ToList();
}
return showDto;
}
#endregion
#region 缓存船期数据
/// <summary>
/// 缓存船期数据
/// </summary>
/// <param name="model">船期查询结果明细</param>
/// <param name="busiType">船期类型 MSKSPOT-马士基即期</param>
/// <returns>返回主键ID</returns>
private async Task CacheShipSailingSchedule(MSKAPISearchTransportSchedules model, string busiType = "MSKCON")
{
/*
1、按照船期明细缓存并把ID作为缓存的KEY
2、对数据进行JSON串行化的文本提取MD5
3、写入缓存并返回ID
*/
var newModel = model.Adapt<MSKAPISearchTransportSchedules>();
//newModel.priceID = null;
var json = Newtonsoft.Json.JsonConvert.SerializeObject(newModel);
model.PId = YitIdHelper.NextId();
string md5 = json.ToMd5();
model.MD5 = md5;
var shareKey = model.PId.ToString();
DateTime nowDate = DateTime.Now;
DateTime expireDateTime = DateTime.Now.AddHours(4);
var expireTimeSpan = expireDateTime.Subtract(nowDate).Duration();
if (!_cache.Exists($"{shareKey}_{busiType}"))
{
await _cache.SetTimeoutAsync($"{shareKey}_{busiType}", Newtonsoft.Json.JsonConvert.SerializeObject(model), expireTimeSpan);
}
}
#endregion
private MSKAPISearchTransportSchedules GetCacheShipSailingSchedule(long pid, string busiType = "MSKCON")
{
if (_cache.Exists($"{pid}_{busiType}"))
{
return _cache.Get<MSKAPISearchTransportSchedules>($"{pid}_{busiType}");
}
return null;
}
#region 发送马士基订舱请求
/// <summary>
/// 发送马士基订舱请求
/// </summary>
/// <param name="model">请求订舱详情</param>
/// <returns></returns>
[HttpPost("/BookingMSKAPI/SendMSKBooking")]
public async Task<MSKBookingResultDto> SendMSKBooking(MSKBookingDto model)
{
MSKBookingResultDto result = await InnerSendMSKBooking(model, 0);
return result;
}
#endregion
#region 发送马士基订舱请求(内部方法)
/// <summary>
/// 发送马士基订舱请求(内部方法)
/// </summary>
/// <param name="model">请求订舱详情</param>
/// <param name="currId">当前马士基订舱主键</param>
/// <param name="isDefaultSave">是否默认保存</param>
/// <returns></returns>
private async Task<MSKBookingResultDto> InnerSendMSKBooking(MSKBookingDto model, long currId, bool isDefaultSave = true)
{
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);
BookingDeliveryRecordShipSchedule shipScheduleRecord = null;
MSKAPISearchTransportSchedules selectedShipSchedule = null;
if (model.PId == 0)
throw Oops.Oh("船期信息不能为空,请重新检索船期");
if (model.PId > 0)
{
if (model.id.HasValue && model.id.Value > 0)
{
var recordId = model.id.Value;
shipScheduleRecord = await _bookingDeliveryRecordShipScheduleRep.AsQueryable().Filter(null, true)
.FirstAsync(a => a.RECORD_ID == recordId && a.SHIP_RATE_PID != null &&
a.SHIP_RATE_PID.Value == model.PId && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID);
}
if (shipScheduleRecord == null)
{
selectedShipSchedule = GetCacheShipSailingSchedule(model.PId);
}
else
{
selectedShipSchedule = JSON.Deserialize<MSKAPISearchTransportSchedules>(shipScheduleRecord.SHIP_JSON);
}
if (selectedShipSchedule == null)
throw Oops.Oh("船期数据校验失败,请重新查询船期信息");
}
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_MSK_API").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
},
};
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.userPlaceOfReceiptUnLocCode,
maerskCityGeoId = selectedShipSchedule.originGeoId,
},
placeOfDelivery = new MSKAPIBookingRouteDetailsBase
{
UNLocationCode = model.userPlaceOfDeliveryUnLocCode,
maerskCityGeoId = selectedShipSchedule.destinationGeoId,
},
selectedRoute = new MSKAPIBookingRoute
{
bookingSchedules = new List<MSKAPIBookingSchedules>(),
},
}
};
//ETD
if (selectedShipSchedule.departureDateTime.HasValue)
{
bookingDto.bookingBody.transport.earliestDepartureDate = selectedShipSchedule.departureDateTime.Value.ToString("yyyy-MM-ddTHH:mm:ss");
}
else
{
throw Oops.Bah($"查询船期错误pid={model.PId} 预计离港日期departureDate 格式解析错误");
}
for (int i = 0; i < selectedShipSchedule.transportLegs.Count; i++)
{
var detail = selectedShipSchedule.transportLegs[i];
var currDto = new MSKAPIBookingSchedules();
//ETD
if (detail.departureDateTime.HasValue)
{
currDto.originDepartureDateTimeLocal = detail.departureDateTime.Value.ToString("yyyy-MM-ddTHH:mm:ss");
}
else
{
throw Oops.Bah($"查询船期错误pid={model.PId} 预计离港日期departureDate 格式解析错误");
}
//ETA
if (detail.arrivalDateTime.HasValue)
{
currDto.destinationArrivalDateTimeLocal = detail.arrivalDateTime.Value.ToString("yyyy-MM-ddTHH:mm:ss");
}
else
{
throw Oops.Bah($"查询船期错误pid={model.PId} 预计到港日期arrivalDateTime 格式解析错误");
}
if(detail.transport.vessel != null)
{
currDto.transportMode = new MSKAPIBookingTransportMode
{
vessel = new MSKAPIBookingTransportModeVessel
{
name = detail.transport.vessel.vesselName,
maerskVesselCode = detail.transport.vessel.carrierVesselCode,
vesselIMONumber = detail.transport.vessel.vesselIMONumber
},
exportVoyageNumber = detail.transport.carrierDepartureVoyageNumber,
};
}
currDto.serviceCode = detail.transport.carrierServiceCode;
currDto.transportModeCode = detail.transport.transportMode;
//首个
if (i == 0)
{
currDto.startLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.startLocation.cityName,
ISOcountryCode = detail.facilities.startLocation.countryCode,
UNLocationCode = detail.facilities.startLocation.UNLocationCode,
maerskCityGeoId = selectedShipSchedule.originGeoId,
};
if (i == selectedShipSchedule.transportLegs.Count - 1)
{
currDto.endLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.endLocation.cityName,
ISOcountryCode = detail.facilities.endLocation.countryCode,
UNLocationCode = detail.facilities.endLocation.UNLocationCode,
maerskCityGeoId = selectedShipSchedule.destinationGeoId,
};
}
else
{
currDto.endLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.endLocation.cityName,
ISOcountryCode = detail.facilities.endLocation.countryCode,
UNLocationCode = detail.facilities.endLocation.UNLocationCode,
maerskSiteGeoId = detail.facilities.endLocation.carrierSiteGeoID,
};
}
}
else if (i == selectedShipSchedule.transportLegs.Count - 1)
{
currDto.startLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.startLocation.cityName,
ISOcountryCode = detail.facilities.startLocation.countryCode,
UNLocationCode = detail.facilities.startLocation.UNLocationCode,
maerskSiteGeoId = detail.facilities.startLocation.carrierSiteGeoID,
};
currDto.endLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.endLocation.cityName,
ISOcountryCode = detail.facilities.endLocation.countryCode,
UNLocationCode = detail.facilities.endLocation.UNLocationCode,
maerskCityGeoId = selectedShipSchedule.destinationGeoId,
};
}
else
{
currDto.startLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.startLocation.cityName,
ISOcountryCode = detail.facilities.startLocation.countryCode,
UNLocationCode = detail.facilities.startLocation.UNLocationCode,
maerskSiteGeoId = detail.facilities.startLocation.carrierSiteGeoID,
};
currDto.endLocation = new MSKAPIBookingRouteDetailsBase
{
cityName = detail.facilities.endLocation.cityName,
ISOcountryCode = detail.facilities.endLocation.countryCode,
UNLocationCode = detail.facilities.endLocation.UNLocationCode,
maerskSiteGeoId = detail.facilities.endLocation.carrierSiteGeoID,
};
}
bookingDto.bookingBody.transport.routeDetails.selectedRoute.bookingSchedules.Add(currDto);
}
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);
});
}
long id = 0;
if (isDefaultSave)
{
id = InnerSave(model, isSendApi: true).GetAwaiter().GetResult();
}
else
{
id = currId;
}
result.id = id;
MSKAPIBookingResultDto resultInfo = null;
var jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(bookingDto);
_logger.LogInformation($"开始请求MSK API订舱JSON={jsonBody}");
DateTime sendTime = DateTime.Now;
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.AsQueryable().Filter(null,true)
.First(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 = "发送成功";
entity.SEND_TIME = sendTime;
await _bookingDeliveryRecordRep.AsUpdateable(entity).UpdateColumns(x => new
{
x.REQUEST_ACKNOWLEDGEMENT_ID,
x.BOOKING_REFERENCE,
x.STATUS,
x.STATUS_NAME,
x.SEND_TIME
}).ExecuteCommandAsync();
}
else
{
entity.STATUS = "FAILURE";
entity.STATUS_NAME = "发送失败";
entity.NOTES = resultInfo.msg.Length > 500 ? resultInfo.msg.Substring(0, 500) : resultInfo.msg;
entity.SEND_TIME = sendTime;
await _bookingDeliveryRecordRep.AsUpdateable(entity).UpdateColumns(x => new
{
x.STATUS,
x.STATUS_NAME,
x.NOTES,
x.SEND_TIME
}).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}";
throw Oops.Bah($"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.priceOwnerCompanyName))
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(string.IsNullOrWhiteSpace(model.userPlaceOfReceiptUnLocCode))
throw Oops.Bah($"始发地必填");
if (string.IsNullOrWhiteSpace(model.userPlaceOfDeliveryUnLocCode))
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($"箱内重量合计不等于总重,请修改");
}
if (!model.isBookingPartOwnPrice)
{
if (model.bookedByMaerskPartyCode.Equals(model.priceOwnerMaerskPartyCode))
{
throw Oops.Bah($"当前订舱合同号是非订舱方合约持约方不能和订舱方ID信息一样请根据实际情况填写");
}
if (model.bookedByCompanyName.Equals(model.priceOwnerCompanyName))
{
throw Oops.Bah($"当前订舱合同号是非订舱方合约,持约方公司名称不能和订舱方公司名称信息一样,请根据实际情况填写");
}
}
else
{
if (!model.bookedByMaerskPartyCode.Equals(model.priceOwnerMaerskPartyCode))
{
throw Oops.Bah($"当前订舱合同号是订舱方合约持约方ID必需和订舱方ID信息一致请根据实际情况填写");
}
if (!model.bookedByCompanyName.Equals(model.priceOwnerCompanyName))
{
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);
//菜单375504048771141=我的任务台账
List<long> userlist = await _sysDataUserMenuService.GetDataScopeList(MenuConst.MenuMSKApi);
bool isAdmin = false;
if(userlist == null)
{
isAdmin = true;
userlist = new List<long>();
}
else if (userlist != null && userlist.Count > 0)
{
userlist.Add(UserManager.UserId);
userlist = userlist.Distinct().ToList();
}
_logger.LogInformation("任务台账权限范围 {list}", userlist);
var entities = await _bookingDeliveryRecordRep.AsQueryable()
.Where(t => isAdmin || userlist.Contains(t.CreatedUserId.Value))
.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.TotalAmountStart), t => t.SHIP_RATE_TOTAL_AMOUNT != null && t.SHIP_RATE_TOTAL_AMOUNT.Value >= decimal.Parse(QuerySearch.TotalAmountStart))
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TotalAmountEnd), t => t.SHIP_RATE_TOTAL_AMOUNT != null && t.SHIP_RATE_TOTAL_AMOUNT.Value <= decimal.Parse(QuerySearch.TotalAmountEnd))
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.BookingChannelType), t => t.BOOKING_CHANNEL_TYPE == QuerySearch.BookingChannelType)
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TotalCurrency), t => t.SHIP_RATE_TOTAL_CURRENCY == QuerySearch.TotalCurrency)
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Carrier), t => t.CARRIERID.Equals(QuerySearch.Carrier))
.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().Filter(null,true)
.FirstAsync(a => a.Id == id && a.TenantId == UserManager.TENANT_ID);
if(entity == null)
throw Oops.Oh($"获取马士基API订舱详情失败不存在或已作废");
model = entity.Adapt<MSKBookingDto>();
var ctnList = _bookingDeliveryRecordCtnRep.AsQueryable().Filter(null, true)
.Where(a => a.RECORD_ID == id && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID).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();
}
MSKAPISearchTransportSchedules selectedShipSchedule = null;
if (model.PId > 0)
{
var shipScheduleRecord = await _bookingDeliveryRecordShipScheduleRep.AsQueryable().Filter(null, true)
.FirstAsync(a => a.SHIP_RATE_PID != null && a.SHIP_RATE_PID.Value == model.PId && a.TenantId == UserManager.TENANT_ID);
if (shipScheduleRecord != null)
{
selectedShipSchedule = JSON.Deserialize<MSKAPISearchTransportSchedules>(shipScheduleRecord.SHIP_JSON);
if (selectedShipSchedule != null)
{
model.selectedShipScheduleShow = GetShipScheduleShow(selectedShipSchedule);
}
}
}
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
#region 保存内部方法
/// <summary>
/// 保存内部方法
/// </summary>
/// <param name="model">API订舱详情</param>
/// <param name="isSendApi">是否发送APItrue-发送需要校验状态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)}");
BookingDeliveryRecordShipSchedule shipScheduleRecord = null;
MSKAPISearchTransportSchedules selectedShipSchedule = null;
if (model.PId > 0)
{
if (model.id.HasValue && model.id.Value > 0)
{
var recordId = model.id.Value;
shipScheduleRecord = await _bookingDeliveryRecordShipScheduleRep.AsQueryable().Filter(null, true)
.FirstAsync(a => a.RECORD_ID == recordId && a.SHIP_RATE_PID != null &&
a.SHIP_RATE_PID.Value == model.PId && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID);
}
if (shipScheduleRecord == null)
{
selectedShipSchedule = GetCacheShipSailingSchedule(model.PId);
}
else
{
selectedShipSchedule = JSON.Deserialize<MSKAPISearchTransportSchedules>(shipScheduleRecord.SHIP_JSON);
}
if (selectedShipSchedule == null)
throw Oops.Oh("船期数据校验失败,请重新查询船期信息");
model.placeOfReceiptCountryName = selectedShipSchedule.originCountryName;
model.placeOfReceiptRegionName = selectedShipSchedule.originRegionName;
model.carrierCollectionOriginGeoID = selectedShipSchedule.originGeoId;
model.placeOfDeliveryCountryName = selectedShipSchedule.destinationCountryName;
model.placeOfDeliveryRegionName = selectedShipSchedule.destinationRegionName;
model.carrierDeliveryDestinationGeoID = selectedShipSchedule.destinationGeoId;
}
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;
entity.BOOKING_CHANNEL_TYPE = "CON_API";
entity.BOOKING_CHANNEL_TYPE_NAME = "合约订舱";
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,
x.IS_JOB,
x.JOB_TIME,
x.TIMER_PLAN_ID,
x.TIMER_PLAN_NAME
}).ExecuteCommandAsync();
if (model.ctns != null && model.ctns.Count > 0)
{
var ctnEntityList = _bookingDeliveryRecordCtnRep.AsQueryable().Filter(null, true)
.Where(a => a.RECORD_ID == entity.Id && a.IsDeleted == false && a.TenantId == UserManager.TENANT_ID).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,
x.CTN_SUFFER_WEIGHT
}).ExecuteCommand();
}
else
{
var ctnEntity = new BookingDeliveryRecordCtn
{
CTN_CODE = ctn.ctnCode,
CTN_NAME = ctn.ctnName,
CTN_NUM = ctn.ctnNum.Value,
CTN_SUFFER_WEIGHT = (int)ctn.ctnSufferWeight.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();
});
}
}
if (shipScheduleRecord == null)
{
if (model.PId > 0 && selectedShipSchedule != null)
{
shipScheduleRecord = new BookingDeliveryRecordShipSchedule
{
Id = YitIdHelper.NextId(),
RECORD_ID = model.id.Value,
SHIP_RATE_PID = selectedShipSchedule.PId,
SHIP_RATE_MD5 = selectedShipSchedule.MD5,
SHIP_JSON = Newtonsoft.Json.JsonConvert.SerializeObject(selectedShipSchedule),
CreatedTime = nowDate,
UpdatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name
};
await _bookingDeliveryRecordShipScheduleRep.InsertAsync(shipScheduleRecord);
}
}
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;
entity.BOOKING_CHANNEL_TYPE = "CON_API";
entity.BOOKING_CHANNEL_TYPE_NAME = "合约订舱";
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,
CTN_SUFFER_WEIGHT = (int)ctn.ctnSufferWeight.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 (shipScheduleRecord == null)
{
if (model.PId > 0 && selectedShipSchedule != null)
{
shipScheduleRecord = new BookingDeliveryRecordShipSchedule
{
Id = YitIdHelper.NextId(),
RECORD_ID = entity.Id,
SHIP_RATE_PID = selectedShipSchedule.PId,
SHIP_RATE_MD5 = selectedShipSchedule.MD5,
SHIP_JSON = Newtonsoft.Json.JsonConvert.SerializeObject(selectedShipSchedule),
CreatedTime = nowDate,
UpdatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name
};
await _bookingDeliveryRecordShipScheduleRep.InsertAsync(shipScheduleRecord);
}
}
else
{
//只有船期发生变化时才重新写入新的船期记录
if (model.PId != shipScheduleRecord.SHIP_RATE_PID.Value)
{
_logger.LogInformation($"MSK CON id={model.id} 换了船期 原记录:{selectedShipSchedule.PId} 新记录:{model.PId} 作废原船期,插入新船期");
shipScheduleRecord.IsDeleted = true;
shipScheduleRecord.UpdatedTime = nowDate;
shipScheduleRecord.UpdatedUserId = UserManager.UserId;
shipScheduleRecord.UpdatedUserName = UserManager.Name;
await _bookingDeliveryRecordShipScheduleRep.AsUpdateable(shipScheduleRecord).UpdateColumns(x => new {
x.IsDeleted,
x.UpdatedUserId,
x.UpdatedUserName,
x.UpdatedTime
}).ExecuteCommandAsync();
shipScheduleRecord = new BookingDeliveryRecordShipSchedule
{
Id = YitIdHelper.NextId(),
RECORD_ID = model.id.Value,
SHIP_RATE_PID = selectedShipSchedule.PId,
SHIP_RATE_MD5 = selectedShipSchedule.MD5,
SHIP_JSON = Newtonsoft.Json.JsonConvert.SerializeObject(selectedShipSchedule),
CreatedTime = nowDate,
UpdatedTime = nowDate,
CreatedUserId = UserManager.UserId,
CreatedUserName = UserManager.Name
};
await _bookingDeliveryRecordShipScheduleRep.InsertAsync(shipScheduleRecord);
}
else
{
_logger.LogInformation($"MSK CON id={model.id} 船期没变化 model.PId={model.PId} shipScheduleRecord.SHIP_RATE_PID={shipScheduleRecord.SHIP_RATE_PID.Value}");
}
}
return entity.Id;
}
}
#endregion
#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>
[HttpPost("/BookingMSKAPI/BatchSend")]
public async Task<string> BatchSend([FromBody] long[] ids)
{
var list = await _bookingDeliveryRecordRep.AsQueryable()
.Where(a => ids.Contains(a.Id)).ToListAsync();
if (list.Count != ids.Length)
throw Oops.Oh("订舱数据获取失败,请确认选中的记录是否存在");
List<string> msgList = new List<string>();
int totalNum = list.Count;
int succNum = 0;
int failNum = 0;
if (list.Count > 1)
{
list.ForEach(entity =>
{
MSKBookingResultDto result = null;
try
{
var model = GetInfo(entity.Id).GetAwaiter().GetResult();
result = InnerSendMSKBooking(model, entity.Id, false).GetAwaiter().GetResult();
succNum++;
}
catch (Exception ex)
{
msgList.Add(ex.Message);
failNum++;
}
Thread.Sleep(1000);
});
msgList.Add($"共计{totalNum} 条 成功{succNum}条 失败:{failNum}");
}
else
{
MSKBookingResultDto result = null;
try
{
var entity = list.FirstOrDefault();
var model = GetInfo(entity.Id).GetAwaiter().GetResult();
result = InnerSendMSKBooking(model, entity.Id, false).GetAwaiter().GetResult();
if (result.succ)
return string.Empty;
}
catch (Exception ex)
{
msgList.Add(ex.Message);
}
}
return string.Join("#", msgList.ToArray());
}
#endregion
#region 批量复制
/// <summary>
/// 批量复制
/// </summary>
/// <param name="model">马士基API批量复制指定数据</param>
/// <returns>返回执行结果消息</returns>
[HttpPost("/BookingMSKAPI/BatchCopy")]
public async Task<string> BatchCopy(MSKAPIBookingCopyDto model)
{
if (model.copyNum < 1)
throw Oops.Oh($"复制数量不能小于1");
if (model.copyNum > 1000)
throw Oops.Oh($"复制数量不能大于1000");
if (string.IsNullOrWhiteSpace(model.opType))
throw Oops.Oh($"请求的操作类型不能为空");
var entity = await _bookingDeliveryRecordRep.AsQueryable()
.FirstAsync(a => a.Id == model.originalId);
if (entity == null)
throw Oops.Oh($"获取马士基API订舱详情失败不存在或已作废");
var ctnList = _bookingDeliveryRecordCtnRep.AsQueryable()
.Where(a => a.RECORD_ID == model.originalId && a.IsDeleted == false).ToList();
var shipScheduleRecord = await _bookingDeliveryRecordShipScheduleRep.AsQueryable()
.FirstAsync(a => a.RECORD_ID == model.originalId && a.SHIP_RATE_PID != null &&
a.SHIP_RATE_PID.Value == entity.SHIP_RATE_PID && a.IsDeleted == false);
var numArg = "".PadLeft(model.copyNum, '0').Select((a, idx) => idx + 1).ToList();
DateTime nowDate = DateTime.Now;
_logger.LogInformation("获取到批量复制功能");
//如果是指定的编辑信息需要先把编辑数据同步到实体类,再进行复制
if (model.opType == "copy_edit")
{
string ctnStat = string.Empty;
if (model.bookingDto.ctns != null && model.bookingDto.ctns.Count > 0)
{
ctnStat = string.Join(",", model.bookingDto.ctns.GroupBy(a => a.ctnName)
.Select(a => $"{a.Key}*{a.ToList().Sum(b => b.ctnNum.HasValue ? b.ctnNum.Value : 0)}").ToArray());
ctnList = new List<BookingDeliveryRecordCtn>();
model.bookingDto.ctns.ForEach(ctn =>
{
var ctnEntity = new BookingDeliveryRecordCtn
{
CTN_CODE = ctn.ctnCode,
CTN_NAME = ctn.ctnName,
CTN_NUM = ctn.ctnNum.Value,
CTN_SUFFER_WEIGHT = (int)ctn.ctnSufferWeight.Value,
};
ctnEntity.CreatedTime = nowDate;
ctnEntity.UpdatedTime = nowDate;
ctnEntity.CreatedUserId = UserManager.UserId;
ctnEntity.CreatedUserName = UserManager.Name;
ctnEntity.STUFFING_MEASUREMENT_TYPE = "WEIGHT";
ctnEntity.STUFFING_MEASUREMENT_UNIT = "KGS";
ctnList.Add(ctnEntity);
});
}
entity = model.bookingDto.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;
entity.BOOKING_CHANNEL_TYPE = "CON_API";
entity.BOOKING_CHANNEL_TYPE_NAME = "合约订舱";
}
int totalNum = 0;
foreach (var a in numArg)
{
var copyEntity = entity.Adapt<BookingDeliveryRecord>();
copyEntity.Id = 0;
copyEntity.CreatedTime = nowDate;
copyEntity.CreatedUserId = UserManager.UserId;
copyEntity.CreatedUserName = UserManager.Name;
copyEntity.UpdatedTime = nowDate;
copyEntity.STATUS = "TEMP";
copyEntity.STATUS_NAME = "暂存";
copyEntity.IS_RECV_BC = false;
copyEntity.LST_RECV_BC_DATE = null;
copyEntity.IS_RECV_BK_CANCEL = false;
copyEntity.LST_RECV_BK_CANCEL_DATE = null;
copyEntity.REQUEST_ACKNOWLEDGEMENT_ID = null;
copyEntity.BOOKING_REFERENCE = null;
copyEntity.NOTES = $"COPY NO.{a} BY={model.originalId}";
await _bookingDeliveryRecordRep.InsertAsync(copyEntity);
totalNum++;
if (ctnList.Count > 0)
{
ctnList.ForEach(async ctn =>
{
var ctnEntity = ctn.Adapt<BookingDeliveryRecordCtn>();
ctnEntity.Id = 0;
ctnEntity.RECORD_ID = copyEntity.Id;
ctnEntity.CreatedTime = nowDate;
ctnEntity.UpdatedTime = nowDate;
ctnEntity.CreatedUserId = UserManager.UserId;
ctnEntity.CreatedUserName = UserManager.Name;
await _bookingDeliveryRecordCtnRep.InsertAsync(ctnEntity);
});
}
if (shipScheduleRecord != null)
{
var currShipScheduleRecord = shipScheduleRecord.Adapt<BookingDeliveryRecordShipSchedule>();
currShipScheduleRecord.Id = 0;
currShipScheduleRecord.RECORD_ID = copyEntity.Id;
currShipScheduleRecord.CreatedTime = nowDate;
currShipScheduleRecord.UpdatedTime = nowDate;
currShipScheduleRecord.CreatedUserId = UserManager.UserId;
currShipScheduleRecord.CreatedUserName = UserManager.Name;
await _bookingDeliveryRecordShipScheduleRep.InsertAsync(currShipScheduleRecord);
}
}
return JSON.Serialize(new { Total = totalNum });
}
#endregion
#region 同步BC状态BC,Cancellation
/// <summary>
/// 同步BC状态BC,Cancellation
/// </summary>
/// <param name="mblno">提单号</param>
/// <param name="tenantId">租户ID</param>
/// <param name="opTypeName">操作类型 BC-同步BC状态 Cancellation-同步取消状态</param>
/// <returns>返回回执</returns>
[HttpGet("/BookingMSKAPI/SyncBCInfo")]
public async Task<MSKBookingResultDto> SyncBCInfo(string mblno, long tenantId, string opTypeName = "BookingConfirmation")
{
MSKBookingResultDto result = new MSKBookingResultDto();
try
{
var model = await _bookingDeliveryRecordRep.AsQueryable().Filter(null, true)
.FirstAsync(a => a.BOOKING_REFERENCE == mblno && a.IsDeleted == false && a.TenantId == tenantId);
if(model == null)
throw Oops.Oh("订舱数据不存在或已作废");
if(opTypeName == "BookingConfirmation")
{
model.IS_RECV_BC = true;
model.LST_RECV_BC_DATE = DateTime.Now;
model.UpdatedTime = model.LST_RECV_BC_DATE;
model.UpdatedUserId = UserManager.UserId;
model.UpdatedUserName = UserManager.Name;
await _bookingDeliveryRecordRep.AsUpdateable(model).UpdateColumns(x => new {
x.IS_RECV_BC,
x.LST_RECV_BC_DATE,
x.UpdatedTime,
x.UpdatedUserId,
x.UpdatedUserName
}).ExecuteCommandAsync();
}
else if (opTypeName == "Cancellation")
{
model.IS_RECV_BK_CANCEL = true;
model.LST_RECV_BK_CANCEL_DATE = DateTime.Now;
model.UpdatedTime = model.LST_RECV_BC_DATE;
model.UpdatedUserId = UserManager.UserId;
model.UpdatedUserName = UserManager.Name;
await _bookingDeliveryRecordRep.AsUpdateable(model).UpdateColumns(x => new {
x.IS_RECV_BK_CANCEL,
x.LST_RECV_BK_CANCEL_DATE,
x.UpdatedTime,
x.UpdatedUserId,
x.UpdatedUserName
}).ExecuteCommandAsync();
}
result.succ = true;
}
catch(Exception ex)
{
result.succ = false;
result.msg = $"同步BC状态异常原因{ex.Message}";
}
return result;
}
#endregion
#region 批量复制前调取校验预警
/// <summary>
/// 批量复制前调取校验预警
/// </summary>
/// <param name="model">马士基API批量复制指定数据</param>
/// <returns>返回提示信息</returns>
[HttpPost("/BookingMSKAPI/CheckWarningBatchCopy")]
public async Task<string> CheckWarningBatchCopy(MSKAPIBookingCopyDto model)
{
/*
主要校验内容
1、如果待复制的单子里还有“托运人自己的集装箱”或“进口退货集装箱或者其他三角集运”需要做提醒是否继续复制。
2、如果是opType=copy_edit-复制使用提交的编辑信息,需要判断原始货物标志变化是否继续。
3、如果是冷冻处理的提示是否继续。
*/
var entity = await _bookingDeliveryRecordRep.AsQueryable()
.FirstAsync(a => a.Id == model.originalId);
if (entity != null)
{
List<string> msgList = new List<string>();
if (entity.IS_SHIPPER_OWNED || (model.bookingDto != null && model.bookingDto.isShipperOwned))
{
msgList.Add("含有指定托运人自己的集装箱");
}
if (entity.IS_IMPORT_RETURNED || (model.bookingDto != null && model.bookingDto.isImportReturned))
{
msgList.Add("含有指定进口退货集装箱或者其他三角集运");
}
if (entity.IS_REEFER || (model.bookingDto != null && model.bookingDto.isReefer))
{
msgList.Add("含有是冷冻处理");
}
if (model.bookingDto != null && model.bookingDto.cargoType != entity.CARGO_TYPE)
{
msgList.Add("货物标志与被复制货物标志不一致");
}
if (msgList.Count > 0)
throw Oops.Oh(string.Join(",", msgList.ToArray()));
}
else
{
return string.Empty;
}
return "校验成功";
}
#endregion
#region 批量发送API前调取校验预警
/// <summary>
/// 批量发送API前调取校验预警
/// </summary>
/// <param name="ids">马士基API订舱ID组</param>
/// <returns>返回提示信息</returns>
[HttpPost("/BookingMSKAPI/CheckWarningBatchSend")]
public async Task<string> CheckWarningBatchSend([FromBody] long[] ids)
{
var list = await _bookingDeliveryRecordRep.AsQueryable().Where(a => ids.Contains(a.Id)).ToListAsync();
if (list.Count > 0)
{
List<string> msgList = new List<string>();
if (list.Any(a => a.IS_SHIPPER_OWNED))
{
msgList.Add("含有指定托运人自己的集装箱");
}
if (list.Any(a => a.IS_IMPORT_RETURNED))
{
msgList.Add("含有指定进口退货集装箱或者其他三角集运");
}
if (list.Any(a => a.IS_REEFER))
{
msgList.Add("含有是冷冻处理");
}
if (msgList.Count > 0)
throw Oops.Oh(string.Join("#", msgList.ToArray()));
}
return "校验成功";
}
#endregion
#region 获取初始化页面默认值
/// <summary>
/// 获取初始化页面默认值
/// </summary>
/// <returns>返回详情</returns>
[HttpGet("/BookingMSKAPI/GetInitInfo")]
public async Task<MSKSPOTBookingInitDto> GetInitInfo()
{
MSKSPOTBookingInitDto dto = null;
var webAccountConfig = await _webAccountConfig.GetAccountConfigByTenantId("MSKApi", UserManager.UserId, UserManager.TENANT_ID);
if (webAccountConfig == null)
throw Oops.Oh("未配置公司账户维护-MSK即期请联系管理员");
if (string.IsNullOrWhiteSpace(webAccountConfig.RegistPartyCode)
|| string.IsNullOrWhiteSpace(webAccountConfig.RegistPartyName) || string.IsNullOrWhiteSpace(webAccountConfig.RegistContractName)
|| string.IsNullOrWhiteSpace(webAccountConfig.RegistContractEmail))
{
throw Oops.Oh("账户维护-MSK即期,未配置完整注册信息(备案代码、备案全称、联系人、邮箱必填),请联系管理员");
}
dto = new MSKSPOTBookingInitDto
{
bookedByMaerskPartyCode = webAccountConfig.RegistPartyCode,
bookedByCompanyName = webAccountConfig.RegistPartyName,
priceOwnerMaerskPartyCode = webAccountConfig.RegistPartyCode,
priceOwnerCompanyName = webAccountConfig.RegistPartyName,
bookedByCompanyContactName = webAccountConfig.RegistContractName,
bookedByCompanyContactEmail = webAccountConfig.RegistContractEmail,
priceOwnerContactName = webAccountConfig.RegistContractName,
priceOwnerContactEmail = webAccountConfig.RegistContractEmail,
};
return dto;
}
#endregion
#region 批量设定定时订舱时间
/// <summary>
/// 批量设定定时订舱时间
/// </summary>
/// <param name="model">请求详情</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingMSKAPI/BatchSetupTimerBooking")]
public async Task<string> BatchSetupTimerBooking([FromBody] MSKAPITimerBookingDto model)
{
/*
1、校验当前预订舱是否存在。
2、更新定时时间和设置。
3、判断当前定时是否已有记录没有新增加定时。
4、
*/
string result = string.Empty;
var list = await _bookingDeliveryRecordRep.AsQueryable()
.Where(a => model.ids.Contains(a.Id)).ToListAsync();
if (list.Count != model.ids.Length)
throw Oops.Oh("订舱数据获取失败,请确认选中的记录是否存在");
StringBuilder msgBuilder = new StringBuilder();
foreach (var item in list)
{
var bookingOrder = GetInfo(item.Id).GetAwaiter().GetResult();
try
{
if (item.STATUS == "SUCC")
{
throw Oops.Bah($"当前状态是已发送成功,不能重复发送");
}
ValidateMSKAPIData(bookingOrder);
var runInfo = _bookingDeliveryRecordJobRunScheduleRep.AsQueryable().Filter(null, true)
.First(a => a.RECORD_ID == item.Id && a.IsDeleted == false);
if (runInfo != null)
{
throw Oops.Bah($"当前记录已开始定时发送不能修改");
}
item.IS_JOB = true;
DateTime jobTime = DateTime.MinValue;
if (DateTime.TryParse(model.StartTime, out jobTime))
{
item.JOB_TIME = jobTime;
}
item.TIMER_PLAN_ID = model.TimerSchemeType;
item.TIMER_PLAN_NAME = string.Format(((MSKAPITimerSchemeTypeEnum)System.Enum.Parse(typeof(MSKAPITimerSchemeTypeEnum), model.TimerSchemeType)).GetDescription(), model.StartTime);
item.UpdatedTime = DateTime.Now;
item.UpdatedUserId = UserManager.UserId;
item.UpdatedUserName = UserManager.Name;
_bookingDeliveryRecordRep.AsUpdateable(item).UpdateColumns(x => new
{
x.IS_JOB,
x.JOB_TIME,
x.TIMER_PLAN_ID,
x.TIMER_PLAN_NAME,
x.UpdatedTime,
x.UpdatedUserId,
x.UpdatedUserName
}).ExecuteCommand();
}
catch (Exception ex)
{
msgBuilder.Append(ex.Message);
}
}
var msg = msgBuilder.ToString();
if (!string.IsNullOrWhiteSpace(msg))
throw Oops.Oh(msg);
return msg;
}
#endregion
/// <summary>
/// 获取定时订舱方案列表
/// </summary>
/// <returns></returns>
[HttpGet("/BookingMSKAPI/GetTimerSchemeList")]
public async Task<List<MSKAPITimerSchemeDto>> GetTimerSchemeList()
{
List<MSKAPITimerSchemeDto> list = new List<MSKAPITimerSchemeDto>();
list.Add(new MSKAPITimerSchemeDto
{
code = MSKAPITimerSchemeTypeEnum.SpecificTimeDoOnce.ToString(),
name = MSKAPITimerSchemeTypeEnum.SpecificTimeDoOnce.GetDescription()
});
return list;
}
#region 发送马士基订舱请求
/// <summary>
/// 发送马士基订舱请求
/// </summary>
/// <param name="id">请求订舱ID</param>
/// <returns>返回检索结果</returns>
[HttpGet("/BookingMSKAPI/SendMSKBookingById"), AllowAnonymous, ApiUser(ApiCode = "BCTaskManage")]
public async Task<MSKBookingResultDto> SendMSKBookingById(long id)
{
var model = await GetInfo(id);
if (model != null)
{
if (model.Status == "SUCC")
{
return new MSKBookingResultDto
{
succ = false,
msg = "订舱数据已发送成功,不能重复发送"
};
}
return await InnerSendMSKBooking(model, id, false);
}
return new MSKBookingResultDto
{
succ = false,
msg = "预订舱信息不存在"
};
}
#endregion
#region 生成订舱报告邮件并自动转发
/// <summary>
/// 生成订舱报告邮件并自动转发
/// </summary>
/// <returns></returns>
[HttpGet("/BookingMSKAPI/GenerateTimerReportEmail")]
public async Task<string> GenerateTimerReportEmail()
{
DateTime nowDate = DateTime.Now;
DateTime startDate = new DateTime(nowDate.Year, nowDate.Month, nowDate.Day);
var runList = _bookingDeliveryRecordJobRunScheduleRep.AsQueryable().Filter(null, true)
.Where(a => a.SEND_TIME >= startDate && a.IsDeleted == false && a.IS_SEND_REPORT == false).ToList();
if (runList.Count > 0)
{
var idList = runList.Select(a => a.RECORD_ID).ToList();
var orderList = _bookingDeliveryRecordRep.AsQueryable().Filter(null, true)
.Where(a => a.IsDeleted == false && idList.Contains(a.Id)).ToList();
_logger.LogInformation($"获取相关预订舱记录,{string.Join(",", idList.ToArray())}");
orderList.GroupBy(a => a.CreatedUserId.Value).ToList().ForEach(b =>
{
var nextJobTime = DateTime.MinValue;
var waitList = _bookingDeliveryRecordRep.AsQueryable().Filter(null, true)
.Where(a => a.IsDeleted == false && a.JOB_TIME != null && a.JOB_TIME.Value >= nowDate && a.CreatedUserId == b.Key && a.STATUS == "TEMP").OrderBy(a=>a.JOB_TIME.Value).ToList();
if (waitList.Count > 0)
nextJobTime = waitList.FirstOrDefault().JOB_TIME.Value;
_logger.LogInformation($"获取完待订舱的记录");
var opUser = _sysUserRepository.AsQueryable().Filter(null, true).First(a => a.Id == b.Key);
DjyUserMailAccount publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.TenantId == opUser.TenantId && x.ShowName == "PublicSend"
&& x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
if (publicMailAccount == null)
{
_logger.LogInformation($"提取公共邮箱配置失败请在用户邮箱账号管理增加配置显示名为PublicSend或者配置个人邮箱");
}
_logger.LogInformation($"取完邮箱配置");
string emailHtml = string.Empty;
var currList = b.OrderBy(t=> t.SEND_TIME.Value).ToList();
string templatePath = App.Configuration["EmailTemplateFilePath"];
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
templatePath = $"{dirAbs}{templatePath}\\MSKAPITimerReportTemplate.html";
_logger.LogInformation($"取完模板");
string baseHtml = File.ReadAllText(templatePath);
baseHtml = baseHtml.Replace("#ReportTime#", nowDate.ToString("yyyy-MM-dd HH:mm:ss"));
baseHtml = baseHtml.Replace("#total#", currList.Count.ToString());
baseHtml = baseHtml.Replace("#succ#", currList.Count(x=>x.STATUS == "SUCC").ToString());
baseHtml = baseHtml.Replace("#failure#", currList.Count(x => x.STATUS == "FAILURE").ToString());
if(waitList.Count > 0)
{
baseHtml = baseHtml.Replace("#wait#", currList.Count().ToString());
}
else
{
baseHtml = baseHtml.Replace("#wait#", "0");
}
if (nextJobTime != DateTime.MinValue)
{
baseHtml = baseHtml.Replace("#NextTime#", nextJobTime.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#NextTime#", "");
}
HtmlDocument html = new HtmlDocument();
html.LoadHtml(baseHtml);
var tableNode = html.DocumentNode.SelectSingleNode(".//table[@id='show-table']");
if (tableNode != null)
{
for (int i = 0; i < currList.Count; i++)
{
StringBuilder tableBuilder = new StringBuilder();
tableBuilder.Append($"<tr><td>{i+1}</td><td>{(currList[i].SEND_TIME.HasValue ? currList[i].SEND_TIME.Value.ToString("yyyy-MM-dd HH:mm:ss") : "")}</td>");
tableBuilder.Append($"<td>{currList[i].STATUS_NAME}</td><td>{currList[i].BOOKING_REFERENCE}</td><td>{currList[i].PLACERECEIPT_CITY}</td><td>{currList[i].PLACEDELIVERY_CITY}</td>");
tableBuilder.Append($"<td>{currList[i].CTN_STAT}</td><td>{(currList[i].ETD.HasValue ? currList[i].ETD.Value.ToString("yyyy-MM-dd HH:mm") : "")}</td>");
tableBuilder.Append($"<td>{(currList[i].TOTAL_CARGO_WEIGHT.HasValue? currList[i].TOTAL_CARGO_WEIGHT.Value.ToString():"")}</td><td>{currList[i].PRICE_REFERENCE}</td>");
tableBuilder.Append($"<td>{(currList[i].IS_RECV_BC ? "1" : "")}</td><td>{(currList[i].IS_RECV_BK_CANCEL ? "1" : "")}</td><td>{(currList[i].JOB_TIME.HasValue ? currList[i].JOB_TIME.Value.ToString("yyyy-MM-dd HH:mm") : "")}</td></tr>");
tableNode.ChildNodes.Add(HtmlNode.CreateNode(tableBuilder.ToString()));
}
}
emailHtml = html.DocumentNode.OuterHtml;
_logger.LogInformation($"填充完邮件正文");
EmailApiUserDefinedDto emailApiUserDefinedDto = new EmailApiUserDefinedDto
{
SendTo = opUser.Email,
CCTo = string.Join(";", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList().ToArray()),
Title = $"马士基API定时订舱统计报告 {nowDate.ToString("yyyy-MM-dd HH:mm:ss")}",
Body = emailHtml,
Account = publicMailAccount.MailAccount?.Trim(),
Password = publicMailAccount.Password?.Trim(),
Server = publicMailAccount.SmtpServer?.Trim(),
Port = publicMailAccount.SmtpPort.HasValue ? publicMailAccount.SmtpPort.Value : 465,
UseSSL = publicMailAccount.SmtpSSL.HasValue ? publicMailAccount.SmtpSSL.Value : true,
Attaches = new List<AttachesInfo>()
};
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
var emailUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
.FirstOrDefault(x => x.TypeCode == "url_set" && x.Code == "email_api_url")?.Value;
_logger.LogInformation($"获取完邮件API地址");
if (emailUrl == null)
_logger.LogInformation("字典未配置 url_set->email_api_url 请联系管理员");
emailList.Add(emailApiUserDefinedDto);
//string strJoin = System.IO.File.ReadAllText(filePath);
DateTime bDate = DateTime.Now;
HttpResponseMessage res = null;
try
{
res = emailUrl.SetBody(emailList, "application/json").PostAsync().GetAwaiter().GetResult();
}
catch (Exception ex)
{
_logger.LogInformation($"发送邮件异常:{ex.Message}");
}
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
_logger.LogInformation($"发送邮件返回:{JSON.Serialize(res)}");
if (res != null && res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = res.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var respObj = JsonConvert.DeserializeAnonymousType(userResult, new
{
Success = false,
Message = string.Empty,
Code = -9999,
});
if(respObj.Success)
{
var updateList = currList.Join(runList, l => l.Id, r => r.RECORD_ID, (l, r) =>
{
return r;
}).ToList();
foreach (var update in updateList) {
update.IS_SEND_REPORT = true;
update.REPORT_TIME = DateTime.Now;
_bookingDeliveryRecordJobRunScheduleRep.AsUpdateable(update).UpdateColumns(x => new
{
x.IS_SEND_REPORT,
x.REPORT_TIME
}).ExecuteCommand();
};
}
}
});
}
else
{
_logger.LogInformation($"自动订舱报告失败,没有可执行的记录");
}
return "";
}
#endregion
#region 批量取消定时订舱时间
/// <summary>
/// 批量取消定时订舱时间
/// </summary>
/// <param name="ids">马士基API订舱ID组</param>
/// <returns>返回回执</returns>
[HttpPost("/BookingMSKAPI/BatchCancelTimerBooking")]
public async Task<string> BatchCancelTimerBooking([FromBody] long[] ids)
{
string result = string.Empty;
var list = await _bookingDeliveryRecordRep.AsQueryable()
.Where(a => ids.Contains(a.Id)).ToListAsync();
if (list.Count != ids.Length)
throw Oops.Oh("订舱数据获取失败,请确认选中的记录是否存在");
StringBuilder msgBuilder = new StringBuilder();
foreach (var item in list)
{
var bookingOrder = GetInfo(item.Id).GetAwaiter().GetResult();
try
{
if (item.STATUS == "SUCC")
{
throw Oops.Bah($"当前状态是已发送成功,不能取消");
}
var runInfo = _bookingDeliveryRecordJobRunScheduleRep.AsQueryable().Filter(null, true)
.First(a => a.RECORD_ID == item.Id && a.IsDeleted == false);
if (runInfo != null)
{
throw Oops.Bah($"当前记录已开始定时发送不能修改");
}
item.IS_JOB = false;
item.JOB_TIME = null;
item.TIMER_PLAN_ID = null;
item.TIMER_PLAN_NAME = null;
item.UpdatedTime = DateTime.Now;
item.UpdatedUserId = UserManager.UserId;
item.UpdatedUserName = UserManager.Name;
_bookingDeliveryRecordRep.AsUpdateable(item).UpdateColumns(x => new
{
x.IS_JOB,
x.JOB_TIME,
x.TIMER_PLAN_ID,
x.TIMER_PLAN_NAME,
x.UpdatedTime,
x.UpdatedUserId,
x.UpdatedUserName
}).ExecuteCommand();
}
catch (Exception ex)
{
msgBuilder.Append(ex.Message);
}
}
var msg = msgBuilder.ToString();
if(!string.IsNullOrWhiteSpace(msg))
throw Oops.Oh(msg);
return msg;
}
#endregion
}
}