Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WmsPDAEmptyOutstockService .cs
2024-09-21 09:30:19 +08:00

281 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.VisualDev;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.EventBus;
using JNPF.FriendlyException;
using JNPF.Logging;
using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
using SqlSugar;
using Tnb.BasicData.Entities;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Attributes;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 空载具出库
/// </summary>
[OverideVisualDev(ModuleConsts.MODULE_WMSEMPTYOUTSTKPDA_ID)]
[ServiceModule(BizTypeId)]
public class WmsPDAEmptyOutstockService : BaseWareHouseService, IPdaStroage
{
private const string BizTypeId = "26475845405733";
private readonly ISqlSugarClient _db;
private readonly IRunService _runService;
private readonly IVisualDevService _visualDevService;
private readonly IWareHouseService _wareHouseService;
private readonly IBillRullService _billRullService;
private readonly IUserManager _userManager;
public WmsPDAEmptyOutstockService(
ISqlSugarRepository<WmsCarryH> repository,
IRunService runService,
IVisualDevService visualDevService,
IWareHouseService wareHouseService,
IUserManager userManager,
IBillRullService billRullService,
IEventPublisher eventPublisher
)
{
_db = repository.AsSugarClient();
_runService = runService;
_visualDevService = visualDevService;
_wareHouseService = wareHouseService;
_userManager = userManager;
_billRullService = billRullService;
OverideFuncs.CreateAsync = PDAWmsEmptyOut;
}
private async Task<dynamic> PDAWmsEmptyOut(VisualDevModelDataCrInput input)
{
SemaphoreSlim semaphoreSlim = null;
try
{
semaphoreSlim = _wareHouseService.GetSemaphore("outstock", input.data[nameof(OutStockStrategyQuery.warehouse_id)].ToString());
await semaphoreSlim.WaitAsync();
Logger.Information("开始PDA空载具出库");
await _db.Ado.BeginTranAsync();
//判断目标库位是否自动签收
BasLocation loc = await _db.Queryable<BasLocation>().SingleAsync(it => it.id == input.data[nameof(WmsPointH.location_id)].ToString());
//出库取起点,获取所有符合输入的载具规格的载具
WmsEmptyOutstockH setQty = await _db.Queryable<WmsEmptyOutstockH>().FirstAsync(it => it.bill_code == input.data[nameof(WmsEmptyOutstockH.bill_code)].ToString());
//出库取起点,获取所有符合输入的载具规格的载具
OutStockStrategyQuery OutStockStrategyInput = new()
{
carrystd_id = input.data[nameof(OutStockStrategyQuery.carrystd_id)].ToString(),
warehouse_id = input.data[nameof(OutStockStrategyQuery.warehouse_id)].ToString(),
Size = 1
};
List<WmsCarryH>? carrys = await _wareHouseService.OutStockStrategy(OutStockStrategyInput);
Logger.Information($"根据出库策略获取的载具数量:{carrys?.Count}");
WmsPointH sPoint = null!;
WmsPointH ePoint = null!;
if (input.data.ContainsKey(nameof(WmsPointH.location_id)))
{
ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == input.data[nameof(WmsPointH.location_id)].ToString());
}
int i = 0;
bool isOk = false;
Logger.Information($"PDA空载具出库实际可出载具数量:{carrys.Count}");
if (carrys.Count < 1)
{
throw new AppFriendlyException($"没有可以出库的空载具", 500);
}
//根据每个载具的起始库位做路径运算
if (carrys?.Count > 0)
{
sPoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == carrys[i].location_id);
}
if (sPoint != null && ePoint != null)
{
List<WmsPointH> points = new List<WmsPointH>();
if (sPoint.area_code != ePoint.area_code)
{
points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id);
if (points.Count <= 2)
{
throw new AppFriendlyException($"sPoint {sPoint.point_code} ePoint{ePoint.point_code}该路径不存在", 500);
}
}
else
{
points.Add(sPoint);
points.Add(ePoint);
}
//根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
if (points?.Count > 0)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSEMPTYOUTSTKPDA_ID, true);
await _runService.Create(templateEntity, input);
List<WmsPretaskH> preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it =>
{
WmsPointH? sPoint = it.FirstOrDefault();
WmsPointH? ePoint = it.LastOrDefault();
//生成预任务
WmsPretaskH preTask = new()
{
org_id = _userManager.User.OrganizeId,
startlocation_id = sPoint?.location_id!,
startlocation_code = sPoint?.location_code!,
endlocation_id = ePoint?.location_id!,
endlocation_code = ePoint?.location_code!,
start_floor = sPoint?.floor.ToString(),
end_floor = ePoint?.floor.ToString(),
startpoint_id = sPoint?.id!,
startpoint_code = sPoint?.point_code!,
endpoint_id = ePoint?.id!,
endpoint_code = ePoint?.point_code!,
bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(),
status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID,
biz_type = WmsWareHouseConst.BIZTYPE_WMSEPTYOUTSTK_ID,
task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID,
carry_id = carrys![i].id,
carry_code = carrys![i].carry_code,
area_id = sPoint?.area_id!,
area_code = it.Key,
require_id = input.data["ReturnIdentity"].ToString()
};
preTask.require_code = input.data[nameof(preTask.bill_code)]?.ToString()!;
preTask.create_id = _userManager.UserId;
preTask.create_time = DateTime.Now;
return preTask;
}).ToList();
//更新页面
if (loc.is_sign == 0)
{
preTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值
}
isOk = await _wareHouseService.GenPreTask(preTasks, null!, _db);
}
if (isOk)
{
//生成预任务上传输入
GenPreTaskUpInput preTaskUpInput = new()
{
RquireId = input.data["ReturnIdentity"].ToString()!,
CarryId = carrys![i].id,
CarryStartLocationId = points.FirstOrDefault()!.location_id!,
CarryStartLocationCode = points.FirstOrDefault()!.location_code!,
LocationIds = points.Select(x => x.location_id).ToList()!
};
//更新明细表
WmsEmptyOutstockD wmsEmptyOutstockD = new()
{
id = SnowflakeIdHelper.NextId(),
bill_id = preTaskUpInput.RquireId,
biz_type = WmsWareHouseConst.BIZTYPE_WMSEPTYOUTSTK_ID,
location_id = ePoint!.location_id!,
status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID,
carry_id = carrys[i].id,
carry_code = carrys[i].carry_code,
create_id = _userManager.UserId,
create_time = DateTime.Now
};
_ = await _db.Insertable(wmsEmptyOutstockD)
.ExecuteCommandAsync();
//生成操作记录表
//WmsHandleH handleH = new()
//{
// org_id = _userManager.User.OrganizeId,
// startlocation_id = carrys?[i].location_id!,
// endlocation_id = ePoint!.location_id!,
// bill_code = input.data[nameof(WmsHandleH.bill_code)]?.ToString()!,
// biz_type = input.data[nameof(WmsHandleH.biz_type)]?.ToString()!,
// carry_id = input.data[nameof(WmsHandleH.carry_id)]?.ToString()!,
// carry_code = input.data[nameof(WmsHandleH.carry_code)]?.ToString()!,
// require_id = input.data["ReturnIdentity"].ToString(),
// require_code = input.data[nameof(WmsHandleH.bill_code)]?.ToString()!,
// create_id = _userManager.UserId,
// create_time = DateTime.Now
//};
//preTaskUpInput.PreTaskRecord = handleH;
//根据空载具出库Id回更单据状态
_ = await _db.Updateable<WmsEmptyOutstockH>().SetColumns(it => new WmsEmptyOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == preTaskUpInput.RquireId).ExecuteCommandAsync();
await _wareHouseService.GenInStockTaskHandleAfter(preTaskUpInput,
it => new WmsCarryH { is_lock = 1, location_id = preTaskUpInput.CarryStartLocationId, location_code = preTaskUpInput.CarryStartLocationCode },
it => new BasLocation { is_lock = 1 }, _db);
}
}
else
{
throw new AppFriendlyException($"【PDAWmsEmptyOut】点位不存在", 500);
}
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
Logger.Error("PDA空载具出库错误", ex.Message);
Logger.Error("PDA空载具出库错误", ex.StackTrace);
await _db.Ado.RollbackTranAsync();
throw;
}
finally
{
semaphoreSlim.Release();
await InvokeGenPretaskExcute();
}
return Task.FromResult(true);
}
public override async Task ModifyAsync(WareHouseUpInput input)
{
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
//根据载具更新明细表状态
try
{
await _db.Ado.BeginTranAsync();
bool isOk = await _db.Updateable<WmsEmptyOutstockD>().SetColumns(it => new WmsEmptyOutstockD { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.bill_id == input.requireId && input.carryIds.Contains(it.carry_id)).ExecuteCommandHasChangeAsync();
List<WmsEmptyOutstockD> emptyCarrys = await _db.Queryable<WmsEmptyOutstockD>().Where(it => it.bill_id == input.requireId).ToListAsync();
// 判断所有明细是否都完成
if (emptyCarrys?.Count > 0 && emptyCarrys.All(x => x.status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID))
{
_ = await _db.Updateable<WmsEmptyOutstockH>().SetColumns(it => new WmsEmptyOutstockH { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandHasChangeAsync();
}
if (!isOk)
{
throw Oops.Oh(ErrorCode.COM1001);
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
}
}