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.

252 lines
12 KiB
C#

using DS.Module.Core;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.Op.Entity;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using NLog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Mapster;
using DS.WMS.Core.Op.Interface;
namespace DS.WMS.Core.Op.Method
{
/// <summary>
/// 舱位库存
/// </summary>
public class BookingSlotStockService: IBookingSlotStockService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
private readonly ISaasDbService saasService;
private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
/// <summary>
///
/// </summary>
/// <param name="serviceProvider"></param>
public BookingSlotStockService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
}
/// <summary>
/// 计算舱位库存
/// </summary>
/// <param name="paraObj">请求参数</param>
/// <returns>返回回执</returns>
public async Task<DataResult<string>> BookingSlotStock(BookingSlotStockUpdateModel paraObj)
{
Logger.Log(NLog.LogLevel.Info, $"收到更新库存订阅请求:{ JsonConvert.SerializeObject(paraObj)}");
if (string.IsNullOrEmpty(paraObj.Vessel)
|| string.IsNullOrEmpty(paraObj.Voyno)
|| string.IsNullOrEmpty(paraObj.ContractNo)
|| string.IsNullOrEmpty(paraObj.BookingSlotType)
|| string.IsNullOrEmpty(paraObj.CarrierCode)
|| string.IsNullOrEmpty(paraObj.PortLoadId)
|| string.IsNullOrEmpty(paraObj.PortDischargeId))
{
Logger.Log(NLog.LogLevel.Info, $"收到更新库存订阅请求:部分参数存在空值,结束");
return DataResult<string>.FailedData(string.Empty);
}
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var baseList = await tenantDb.Queryable<BookingSlotBase>()
.Where(x => !x.Deleted
//&& x.TenantId == paraObj.TenantId
&& x.Vessel == paraObj.Vessel
&& x.Voyno == paraObj.Voyno
&& x.ContractNo == paraObj.ContractNo
&& x.BookingSlotType == paraObj.BookingSlotType
&& x.CarrierCode == paraObj.CarrierCode
&& x.PortLoadId == paraObj.PortLoadId
&& x.PortDischargeId == paraObj.PortDischargeId)
.OrderByDescending(x => x.UpdateTime)
.ToListAsync();
var stockObj = await tenantDb.Queryable<BookingSlotStock>()
.FirstAsync(x => !x.Deleted
//&& x.TenantId == paraObj.TenantId
&& x.Vessel == paraObj.Vessel
&& x.Voyno == paraObj.Voyno
&& x.ContractNo == paraObj.ContractNo
&& x.BookingSlotType == paraObj.BookingSlotType
&& x.CarrierCode == paraObj.CarrierCode
&& x.PortLoadId == paraObj.PortLoadId
&& x.PortDischargeId == paraObj.PortDischargeId);
if (!baseList.Any())
{
if (stockObj != null)
{
// 从库存表删除这7项维度的库存数据
await tenantDb.Deleteable<BookingSlotStock>(stockObj).ExecuteCommandAsync();
}
return DataResult<string>.FailedData(string.Empty);
}
var isInsert = stockObj == null;
var idTemp = stockObj?.Id;
stockObj = baseList[0].Adapt(stockObj);
if (isInsert)
{
stockObj.Id = 0;
}
else
{
stockObj.Id = (long)idTemp;
}
// 总舱位数
stockObj.TotalOrders = baseList.Count;
// 取消舱位数
stockObj.CancelNum = baseList.Count(x => x.IsCancellation);
// 舱位主键列表
var slotBaseIdList = baseList.Select(x => x.Id).ToList();
// 总的箱型箱量
var ctnAllList = await tenantDb.Queryable<BookingSlotCtn>()
.Where(x => !x.Deleted && slotBaseIdList.Contains(x.SlotId))
.GroupBy(x => x.CtnAll)
.Select(x => new
{
x.CtnAll,
CTNNUM = SqlFunc.AggregateSum(x.CtnNum)
}).ToListAsync();
stockObj.CtnStat = string.Join(' ', ctnAllList.Select(c => c.CtnAll + "*" + c.CTNNUM));
// 总箱数
stockObj.TotalCtns = ctnAllList.Sum(x => x.CTNNUM);
// 订舱引用表主键与订舱主表主键
var lstAllocKeyList = await tenantDb.Queryable<BookingSlotAllocation>()
//.Filter(null, true)
.Where(x => !x.Deleted && slotBaseIdList.Contains(x.BookingSlotId))
.Select(x => new { x.Id, x.BookingSlotId })
.ToListAsync();
// 如果舱位未被引用过,可以直接确定库存
if (!lstAllocKeyList.Any())
{
// 已使用舱位数
stockObj.UseNum = 0;
// 已使用的箱型箱量
stockObj.UseCtnStat = "";
// 已使用的箱数
stockObj.UseCtnsNum = 0;
// 剩余的箱型箱量
stockObj.RemainCtnStat = stockObj.CtnStat;
// 剩余箱数
stockObj.RemainCtnsNum = stockObj.TotalCtns;
}
else
{
// 已使用舱位数
//stockObj.USE_NUM = lstAllocKeyList.DistinctBy(x => x.BOOKING_SLOT_ID).Count();
// 订舱引用表主键列表
var allocIdList = lstAllocKeyList.Select(x => x.Id).ToList();
var allocSlotIdList = lstAllocKeyList.Select(x => x.BookingSlotId).Distinct().ToList();
var userCtnNumList = await tenantDb.Queryable<BookingSlotAllocationCtn>().Filter(null, true)
.Where(x => !x.Deleted && allocIdList.Contains(x.SlotAllocId))
.GroupBy(x => x.SlotAllocId)
.Select(x => new
{
x.SlotAllocId,
CTNNUM = SqlFunc.AggregateSum(x.CtnNum)
}).ToListAsync();
var hasCtnNumList = await tenantDb.Queryable<BookingSlotCtn>().Filter(null, true)
.Where(x => !x.Deleted && allocSlotIdList.Contains(x.SlotId))
.GroupBy(x => x.SlotId)
.Select(x => new
{
x.SlotId,
CTNNUM = SqlFunc.AggregateSum(x.CtnNum)
})
.ToListAsync();
var useNum = 0;
foreach (long slotId in allocSlotIdList)
{
List<long> temp1 = lstAllocKeyList.Where(x => x.BookingSlotId == slotId).Select(x => x.Id).ToList();
var userNum = userCtnNumList.Where(x => temp1.Contains(x.SlotAllocId)).Sum(x => x.CTNNUM);
var hasNum = hasCtnNumList.Where(x => x.SlotId == slotId).Sum(x => x.CTNNUM);
if (userNum >= hasNum)
{
useNum++;
}
}
// 已使用舱位数
stockObj.UseNum = useNum;
// 已使用的箱型箱量
var userCtnList = await tenantDb.Queryable<BookingSlotAllocationCtn>()
.Filter(null, true)
.Where(x => !x.Deleted && allocIdList.Contains(x.SlotAllocId))
.GroupBy(x => x.CtnAll)
.Select(x => new
{
x.CtnAll,
CTNNUM = SqlFunc.AggregateSum(x.CtnNum)
}).ToListAsync();
stockObj.UseCtnStat = string.Join(' ', userCtnList.Select(c => c.CtnAll + "*" + c.CTNNUM));
// 已使用的箱数
stockObj.UseCtnsNum = userCtnList.Sum(x => x.CTNNUM);
// 剩余的箱型箱量
Dictionary<string, int> 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.RemainCtnStat = string.Join(' ', remainCtnList.Select(x => x.Key + "*" + x.Value));
// 剩余箱数
stockObj.RemainCtnsNum = stockObj.TotalCtns - stockObj.UseCtnsNum;
}
if (isInsert)
{
await tenantDb.Insertable<BookingSlotStock>(stockObj).ExecuteCommandAsync();
}
else
{
await tenantDb.Updateable<BookingSlotStock>(stockObj).ExecuteCommandAsync();
}
return DataResult<string>.Success(string.Empty);
}
}
}