舱位引入功能调整

optimize
zhangxiaofeng 10 months ago
parent 930d5ae9dd
commit b5486ceb3b

@ -1588,43 +1588,22 @@ namespace Myshipping.Application
} }
// 【引入舱位】:如果存在舱位引入数据,则判断引入的舱位及箱子目前是否仍然可用 // 【引入舱位】:判断订舱是否引入过舱位数据,以及余量是否充足
if (input.Slots?.Any() == true) if (input.Slots?.Any() == true)
{ {
// 当前操作如果为订舱台账的“修改”操作,判断是否该票订舱是否引入过舱位,如果引入过,则后续不再执行舱位引入的逻辑 var checkResult = await bookingSlotService.CheckImportSlots(input.Slots, input.Id);
if (input.Id != 0 && await _repSlotAllocation.IsExistsAsync(a => a.BOOKING_ID == input.Id))
// 如果该票订舱引入过舱位则清空后续input.Slots不再执行舱位引入的逻辑
if (checkResult.isExists)
{ {
input.Slots.Clear(); input.Slots.Clear();
} }
else else
{ {
var slotIdList = input.Slots.Select(s => s.Id).ToList(); // 如果该票订舱没有引入过舱位,判断余量是否充足
if (!checkResult.isEnough)
var latestSlotList = await bookingSlotService.GetAvailableSlots(null, slotIdList);
foreach (var inSlotItem in input.Slots)
{ {
var latestSlot = latestSlotList.FirstOrDefault(b => b.Id == inSlotItem.Id); throw Oops.Bah(checkResult.message);
if (latestSlot == null)
{
throw Oops.Bah($"订舱编号为{inSlotItem.SLOT_BOOKING_NO}的舱位已被占用或取消,请重新引入");
}
if (inSlotItem.CtnList?.Any() == false)
{
throw Oops.Bah($"每个舱位至少选择一个箱子,订舱编号:{inSlotItem.SLOT_BOOKING_NO}");
}
foreach (var inCtnItem in inSlotItem.CtnList)
{
var latestCtn = latestSlot.CtnList.FirstOrDefault(c => c.CTNCODE == inCtnItem.CTNCODE);
if (latestCtn == null)
{
throw new Exception($"订舱编号为{latestSlot.SLOT_BOOKING_NO}的舱位中,箱型为{inCtnItem.CTNALL}的箱子已被占用或取消,请重新引入");
}
if (latestCtn.CTNNUM < inCtnItem.CTNNUM)
{
throw new Exception($"订舱编号为{latestSlot.SLOT_BOOKING_NO}的舱位中,箱型为{inCtnItem.CTNALL}的箱子当前剩余{latestCtn.CTNNUM}个,少于所需的{inCtnItem.CTNNUM}个,请重新引入");
}
}
} }
} }
} }
@ -1982,50 +1961,7 @@ namespace Myshipping.Application
// 【引入舱位】:保存引用信息 // 【引入舱位】:保存引用信息
if (input.Slots?.Any() == true) if (input.Slots?.Any() == true)
{ {
var slotIdList = input.Slots.Select(s => s.Id).ToList(); await bookingSlotService.ImportSlots(input.Slots, entity.Id, false);
List<BookingSlotBase> latestSlotList = await _repSlotBase.AsQueryable().Where(b => slotIdList.Contains(b.Id)).ToListAsync();
foreach (var inSlotItem in input.Slots)
{
var latestSlot = latestSlotList.First(b => b.Id == inSlotItem.Id);
var config = new TypeAdapterConfig();
config.ForType<BookingSlotBase, BookingSlotAllocation>()
.Ignore(dest => dest.CreatedTime)
.Ignore(dest => dest.UpdatedTime)
.Ignore(dest => dest.CreatedUserId)
.Ignore(dest => dest.UpdatedUserId)
.Ignore(dest => dest.CreatedUserName)
.Ignore(dest => dest.UpdatedUserName)
.Ignore(dest => dest.TenantId)
.Ignore(dest => dest.TenantName);
var newSlotAllocation = latestSlot.Adapt<BookingSlotAllocation>(config);
newSlotAllocation.Id = 0;
newSlotAllocation.BOOKING_SLOT_ID = latestSlot.Id;
newSlotAllocation.BOOKING_ID = entity.Id;
newSlotAllocation.ALLO_BILL_NO = latestSlot.SLOT_BOOKING_NO;
newSlotAllocation.FINAL_BILL_NO = latestSlot.SLOT_BOOKING_NO;
await _repSlotAllocation.InsertAsync(newSlotAllocation);
var insertCtnList = inSlotItem.CtnList.Select(c => new BookingSlotAllocationCtn()
{
SLOT_ALLOC_ID = newSlotAllocation.Id,
CTNCODE = c.CTNCODE,
CTNALL = c.CTNALL,
CTNNUM = c.CTNNUM
});
await _repSlotAllocationCtn.InsertAsync(insertCtnList);
// 更新库存
await _publisher.PublishAsync(new ChannelEventSource("BookingSlotStock:Update", new Event.BookingSlotStockUpdateModel
{
BOOKING_SLOT_TYPE = latestSlot.BOOKING_SLOT_TYPE,
CARRIERID = latestSlot.CARRIERID,
CONTRACT_NO = latestSlot.CONTRACT_NO,
VESSEL = latestSlot.VESSEL,
VOYNO = latestSlot.VOYNO
}));
}
} }
var Id = entity.Id; var Id = entity.Id;

@ -17,6 +17,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -52,7 +53,8 @@ namespace Myshipping.Application
ILogger<BookingSlotService> logger, ILogger<BookingSlotService> logger,
ISysCacheService cache, ISysCacheService cache,
IEventPublisher publisher, IEventPublisher publisher,
SqlSugarRepository<BookingSlotAllocation> repAllocation) SqlSugarRepository<BookingSlotAllocation> repAllocation,
SqlSugarRepository<BookingSlotAllocationCtn> repAllocationCtn)
{ {
_repBase = repBase; _repBase = repBase;
_repCtn = repCtn; _repCtn = repCtn;
@ -60,6 +62,7 @@ namespace Myshipping.Application
_repBookingLog = repBookingLog; _repBookingLog = repBookingLog;
_repBookingLogDetail = repBookingLogDetail; _repBookingLogDetail = repBookingLogDetail;
_repAllocation = repAllocation; _repAllocation = repAllocation;
_repAllocationCtn = repAllocationCtn;
_logger = logger; _logger = logger;
@ -530,7 +533,7 @@ namespace Myshipping.Application
/// </summary> /// </summary>
/// <param name="slots">待引入的舱位列表</param> /// <param name="slots">待引入的舱位列表</param>
/// <param name="bookingOrderId">待关联的订舱记录</param> /// <param name="bookingOrderId">待关联的订舱记录</param>
/// <returns>(指定订舱记录是否已经引入过舱位数据,现有舱位及箱子是否满足需求,提示信息)</returns> /// <returns>isExists指定订舱记录是否已经引入过舱位数据,isEnough现有舱位及箱子是否满足需求,message提示信息</returns>
[NonAction] [NonAction]
public async Task<(bool isExists, bool isEnough, string message)> CheckImportSlots(List<BookingSlotBaseWithCtnDto> slots, long bookingOrderId) public async Task<(bool isExists, bool isEnough, string message)> CheckImportSlots(List<BookingSlotBaseWithCtnDto> slots, long bookingOrderId)
{ {
@ -573,70 +576,79 @@ namespace Myshipping.Application
} }
return (false, true, $"可以引入"); return (false, true, $"可以引入");
} }
public static object ImportLockObj = new object();
/// <summary> /// <summary>
/// 为指定订舱记录引入舱位信息 /// 为指定订舱记录引入舱位信息
/// </summary> /// </summary>
/// <param name="slots">待引入的舱位列表</param> /// <param name="slots">待引入的舱位列表</param>
/// <param name="bookingOrderId">待关联的订舱记录</param> /// <param name="bookingOrderId">待关联的订舱记录</param>
/// <param name="isCheck">是否进行剩余量检查</param> /// <param name="isCheck">是否进行剩余量检查</param>
/// <returns>(是否成功,提示消息)</returns> /// <returns>isSuccess检查余量及已引用检查是否成功通过message提示信息</returns>
[NonAction] [NonAction]
public async Task<(bool isSuccess, string message)> ImportSlots(List<BookingSlotBaseWithCtnDto> slots, long bookingOrderId, bool isCheck) public async Task<(bool isSuccess, string message)> ImportSlots(List<BookingSlotBaseWithCtnDto> slots, long bookingOrderId, bool isCheck)
{ {
slots ??= new List<BookingSlotBaseWithCtnDto>(); slots ??= new List<BookingSlotBaseWithCtnDto>();
if (isCheck) Monitor.Enter(ImportLockObj);
try
{ {
(bool isExists, bool isEnough, string message) checkResult = await CheckImportSlots(slots, bookingOrderId); if (isCheck)
{
(bool isExists, bool isEnough, string message) checkResult = await CheckImportSlots(slots, bookingOrderId);
if (checkResult.isExists || !checkResult.isEnough) if (checkResult.isExists || !checkResult.isEnough)
return (false, checkResult.message); return (false, checkResult.message);
} }
var slotIdList = slots.Select(s => s.Id).ToList(); var slotIdList = slots.Select(s => s.Id).ToList();
List<BookingSlotBase> latestSlotList = await _repBase.AsQueryable().Where(b => slotIdList.Contains(b.Id)).ToListAsync(); List<BookingSlotBase> latestSlotList = await _repBase.AsQueryable().Where(b => slotIdList.Contains(b.Id)).ToListAsync();
foreach (var inSlotItem in slots) foreach (var inSlotItem in slots)
{
var latestSlot = latestSlotList.First(b => b.Id == inSlotItem.Id);
var config = new TypeAdapterConfig();
config.ForType<BookingSlotBase, BookingSlotAllocation>()
.Ignore(dest => dest.CreatedTime)
.Ignore(dest => dest.UpdatedTime)
.Ignore(dest => dest.CreatedUserId)
.Ignore(dest => dest.UpdatedUserId)
.Ignore(dest => dest.CreatedUserName)
.Ignore(dest => dest.UpdatedUserName)
.Ignore(dest => dest.TenantId)
.Ignore(dest => dest.TenantName);
var newSlotAllocation = latestSlot.Adapt<BookingSlotAllocation>(config);
newSlotAllocation.Id = 0;
newSlotAllocation.BOOKING_SLOT_ID = latestSlot.Id;
newSlotAllocation.BOOKING_ID = bookingOrderId;
newSlotAllocation.ALLO_BILL_NO = latestSlot.SLOT_BOOKING_NO;
newSlotAllocation.FINAL_BILL_NO = latestSlot.SLOT_BOOKING_NO;
await _repAllocation.InsertAsync(newSlotAllocation);
var insertCtnList = inSlotItem.CtnList.Select(c => new BookingSlotAllocationCtn()
{ {
SLOT_ALLOC_ID = newSlotAllocation.Id, var latestSlot = latestSlotList.First(b => b.Id == inSlotItem.Id);
CTNCODE = c.CTNCODE,
CTNALL = c.CTNALL, var config = new TypeAdapterConfig();
CTNNUM = c.CTNNUM config.ForType<BookingSlotBase, BookingSlotAllocation>()
}); .Ignore(dest => dest.CreatedTime)
await _repAllocationCtn.InsertAsync(insertCtnList); .Ignore(dest => dest.UpdatedTime)
.Ignore(dest => dest.CreatedUserId)
.Ignore(dest => dest.UpdatedUserId)
.Ignore(dest => dest.CreatedUserName)
.Ignore(dest => dest.UpdatedUserName)
.Ignore(dest => dest.TenantId)
.Ignore(dest => dest.TenantName);
var newSlotAllocation = latestSlot.Adapt<BookingSlotAllocation>(config);
newSlotAllocation.Id = 0;
newSlotAllocation.BOOKING_SLOT_ID = latestSlot.Id;
newSlotAllocation.BOOKING_ID = bookingOrderId;
newSlotAllocation.ALLO_BILL_NO = latestSlot.SLOT_BOOKING_NO;
newSlotAllocation.FINAL_BILL_NO = latestSlot.SLOT_BOOKING_NO;
await _repAllocation.InsertAsync(newSlotAllocation);
var insertCtnList = inSlotItem.CtnList.Select(c => new BookingSlotAllocationCtn()
{
SLOT_ALLOC_ID = newSlotAllocation.Id,
CTNCODE = c.CTNCODE,
CTNALL = c.CTNALL,
CTNNUM = c.CTNNUM
});
await _repAllocationCtn.InsertAsync(insertCtnList);
// 更新库存 // 更新库存
await _publisher.PublishAsync(new ChannelEventSource("BookingSlotStock:Update", new Event.BookingSlotStockUpdateModel await _publisher.PublishAsync(new ChannelEventSource("BookingSlotStock:Update", new Event.BookingSlotStockUpdateModel
{ {
BOOKING_SLOT_TYPE = latestSlot.BOOKING_SLOT_TYPE, BOOKING_SLOT_TYPE = latestSlot.BOOKING_SLOT_TYPE,
CARRIERID = latestSlot.CARRIERID, CARRIERID = latestSlot.CARRIERID,
CONTRACT_NO = latestSlot.CONTRACT_NO, CONTRACT_NO = latestSlot.CONTRACT_NO,
VESSEL = latestSlot.VESSEL, VESSEL = latestSlot.VESSEL,
VOYNO = latestSlot.VOYNO VOYNO = latestSlot.VOYNO
})); }));
}
}
finally
{
Monitor.Exit(ImportLockObj);
} }
return (true, "引入成功"); return (true, "引入成功");

Loading…
Cancel
Save