using Furion;
using Furion.EventBus;
using Furion.FriendlyException;
using Furion.RemoteRequest.Extensions;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Myshipping.Application.ConfigOption;
using Myshipping.Application.Entity;
using Myshipping.Application.Service.BookingOrder.Dto;
using Myshipping.Core;
using Myshipping.Core.Entity;
using Myshipping.Core.Service;
using Newtonsoft.Json.Linq;
using NPOI.OpenXmlFormats.Wordprocessing;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;
namespace Myshipping.Application.Event
{
///
/// 运踪
///
public class BookingSlotStockSubscriber : IEventSubscriber
{
private readonly ILogger _logger;
public BookingSlotStockSubscriber(
ILogger logger)
{
_logger = logger;
}
//更新库存
[EventSubscribe("BookingSlotStock:Update")]
public async Task BookingSlotStock(EventHandlerExecutingContext context)
{
_logger.LogInformation($"收到更新库存订阅请求:{context.Source.Payload}");
var _repBase = App.GetService>();
var _repCtn = App.GetService>();
var _repStock = App.GetService>();
var _repAlloc = App.GetService>();
var _repAllocCtn = App.GetService>();
var paraObj = context.Source.Payload as BookingSlotStockUpdateModel;
var baseList = await _repBase.AsQueryable().Filter(null, true)
.Where(x => !x.IsDeleted
&& !x.IS_CANCELLATION
&& x.VESSEL == paraObj.VESSEL
&& x.VOYNO == paraObj.VOYNO
&& x.CONTRACT_NO == paraObj.CONTRACT_NO
&& x.BOOKING_SLOT_TYPE == paraObj.BOOKING_SLOT_TYPE
&& x.CARRIERID == paraObj.CARRIERID
&& x.PLACEDELIVERY == paraObj.PLACEDELIVERY
&& x.PLACERECEIPT == paraObj.PLACERECEIPT)
.OrderByDescending(x => x.UpdatedTime)
.ToListAsync();
if (!baseList.Any())
{
return;
}
var stockObj = await _repStock.AsQueryable()
.Filter(null, true)
.FirstAsync(x => !x.IsDeleted
&& x.VESSEL == paraObj.VESSEL
&& x.VOYNO == paraObj.VOYNO
&& x.CONTRACT_NO == paraObj.CONTRACT_NO
&& x.BOOKING_SLOT_TYPE == paraObj.BOOKING_SLOT_TYPE
&& x.CARRIERID == paraObj.CARRIERID
&& x.PLACEDELIVERY == paraObj.PLACEDELIVERY
&& x.PLACERECEIPT == paraObj.PLACERECEIPT);
if (stockObj == null)
{
stockObj = new BookingSlotStock();
stockObj.Id = YitIdHelper.NextId();
await _repStock.InsertAsync(stockObj);
}
var bkId = stockObj.Id;
baseList[0].Adapt(stockObj);
stockObj.Id = bkId;
// 总舱位数
stockObj.TOTAL_ORDERS = baseList.Count;
var lstBaseId = baseList.Select(x => x.Id).ToList();
// 总的箱型箱量
var ctnAllList = await _repCtn.AsQueryable().Filter(null, true)
.Where(x => !x.IsDeleted && lstBaseId.Contains(x.SLOT_ID))
.GroupBy(x => x.CTNALL)
.Select(x => new
{
x.CTNALL,
CTNNUM = SqlFunc.AggregateSum(x.CTNNUM)
}).ToListAsync();
stockObj.CTN_STAT = string.Join(' ', ctnAllList.Select(c => c.CTNALL + "*" + c.CTNNUM));
// 总箱数
stockObj.TOTAL_CTNS = ctnAllList.Sum(x => x.CTNNUM);
// 订舱引用表主键与订舱主表主键
var lstAllocKeyList = await _repAlloc.AsQueryable()
.Filter(null, true)
.Where(x => !x.IsDeleted && lstBaseId.Contains(x.BOOKING_SLOT_ID))
.Select(x => new { x.Id, x.BOOKING_SLOT_ID })
.ToListAsync();
// 如果舱位未被引用过,可以直接确定库存
if (!lstAllocKeyList.Any())
{
// 已使用舱位数
stockObj.USE_NUM = 0;
// 已使用的箱型箱量
stockObj.USE_CTN_STAT = "";
// 已使用的箱数
stockObj.USE_CTNS_NUM = 0;
// 剩余的箱型箱量
stockObj.REMAIN_CTN_STAT = stockObj.CTN_STAT;
// 剩余箱数
stockObj.REMAIN_CTNS_NUM = stockObj.TOTAL_CTNS;
}
else
{
// 已使用舱位数
stockObj.USE_NUM = lstAllocKeyList.DistinctBy(x => x.BOOKING_SLOT_ID).Count();
// 订舱引用表主键列表
var lstAllocIdList = lstAllocKeyList.Select(x => x.Id).ToList();
// 已使用的箱型箱量
var userCtnList = await _repAllocCtn.AsQueryable()
.Filter(null, true)
.Where(x => !x.IsDeleted && lstAllocIdList.Contains(x.SLOT_ALLOC_ID))
.GroupBy(x => x.CTNALL)
.Select(x => new
{
x.CTNALL,
CTNNUM = SqlFunc.AggregateSum(x.CTNNUM)
}).ToListAsync();
stockObj.USE_CTN_STAT = string.Join(' ', userCtnList.Select(c => c.CTNALL + "*" + c.CTNNUM));
// 已使用的箱数
stockObj.USE_CTNS_NUM = userCtnList.Sum(x => x.CTNNUM);
// 剩余的箱型箱量
Dictionary remainCtnList = new(ctnAllList.Count);
foreach (var item in ctnAllList)
{
var useItem = userCtnList.FirstOrDefault(x => x.CTNALL == item.CTNALL);
if (useItem == null)
{
remainCtnList.Add(item.CTNALL, item.CTNNUM);
}
else
{
int remainCtnNum = item.CTNNUM - useItem.CTNNUM;
if (remainCtnNum > 0)
{
remainCtnList.Add(item.CTNALL, remainCtnNum);
}
}
}
stockObj.REMAIN_CTN_STAT = string.Join(' ', remainCtnList.Select(x => x.Key + "*" + x.Value));
// 剩余箱数
stockObj.REMAIN_CTNS_NUM = stockObj.TOTAL_CTNS - stockObj.USE_CTNS_NUM;
}
await _repStock.UpdateAsync(stockObj);
}
}
///
/// 刷新库存统计对象
///
public class BookingSlotStockUpdateModel
{
///
/// 船名
///
public string VESSEL { get; set; }
///
/// 航次号
///
public string VOYNO { get; set; }
///
/// 合约号
///
public string CONTRACT_NO { get; set; }
///
/// 订舱方式 CONTRACT_ORDER-合约订舱;SPOT_ORDER-SPOT订舱
///
public string BOOKING_SLOT_TYPE { get; set; }
///
/// 船公司代号
///
public string CARRIERID { get; set; }
///
/// 收货地
///
public string PLACERECEIPT { get; set; }
///
/// 交货地
///
public string PLACEDELIVERY { get; set; }
}
}