272 lines
13 KiB
C#
272 lines
13 KiB
C#
using System.Security.Cryptography.X509Certificates;
|
||
using JNPF.Common.Core.Manager;
|
||
using JNPF.Common.Dtos.VisualDev;
|
||
using JNPF.Common.Enums;
|
||
using JNPF.Common.Extension;
|
||
using JNPF.Common.Security;
|
||
using JNPF.FriendlyException;
|
||
using JNPF.Systems.Interfaces.System;
|
||
using JNPF.VisualDev;
|
||
using JNPF.VisualDev.Entitys;
|
||
using JNPF.VisualDev.Interfaces;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.Extensions.Logging;
|
||
using Newtonsoft.Json.Linq;
|
||
using NPOI.POIFS.Storage;
|
||
using SqlSugar;
|
||
using Tnb.BasicData.Entities;
|
||
using Tnb.ProductionMgr.Entities;
|
||
using Tnb.WarehouseMgr.Entities;
|
||
using Tnb.WarehouseMgr.Entities.Attributes;
|
||
using Tnb.WarehouseMgr.Entities.Consts;
|
||
using Tnb.WarehouseMgr.Entities.Dto;
|
||
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
|
||
using Tnb.WarehouseMgr.Entities.Dto.Outputs;
|
||
using Tnb.WarehouseMgr.Entities.Entity;
|
||
using Tnb.WarehouseMgr.Entities.Enums;
|
||
using Tnb.WarehouseMgr.Interfaces;
|
||
|
||
namespace Tnb.WarehouseMgr
|
||
{
|
||
[OverideVisualDev(ModuleConsts.MODULE_WMSPACKOUTSTOCK_ID)]
|
||
[ServiceModule(BizTypeId)]
|
||
public class WmsPackOutstockService : BaseWareHouseService, IWmsPrdReturnService
|
||
{
|
||
private const string BizTypeId = WmsWareHouseConst.BIZTYPE_WMSPACKOUTSTOCK_ID;
|
||
private readonly ISqlSugarClient _db;
|
||
private readonly IRunService _runService;
|
||
private readonly IVisualDevService _visualDevService;
|
||
private readonly IUserManager _userManager;
|
||
private readonly IWareHouseService _wareHouseService;
|
||
private readonly IWmsCarryBindService _wmsCarryBindService;
|
||
private readonly IBillRullService _billRullService;
|
||
public static SemaphoreSlim s_packOutstockSemaphore = new(1);
|
||
private readonly IWmsCarryUnbindService _wmsCarryUnbindService;
|
||
public WmsPackOutstockService(
|
||
ISqlSugarRepository<WmsCarryH> repository,
|
||
IRunService runService,
|
||
IVisualDevService visualDevService,
|
||
IWareHouseService wareHouseService,
|
||
IUserManager userManager,
|
||
IWmsCarryBindService wmsCarryBindService,
|
||
IWmsCarryUnbindService wmsCarryUnbindService,
|
||
IBillRullService billRullService)
|
||
{
|
||
_db = repository.AsSugarClient();
|
||
_runService = runService;
|
||
_visualDevService = visualDevService;
|
||
_userManager = userManager;
|
||
_wareHouseService = wareHouseService;
|
||
_wmsCarryBindService = wmsCarryBindService;
|
||
_wmsCarryUnbindService = wmsCarryUnbindService;
|
||
_billRullService = billRullService;
|
||
}
|
||
|
||
public override async Task ModifyAsync(WareHouseUpInput input)
|
||
{
|
||
if (input == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input));
|
||
}
|
||
|
||
try
|
||
{
|
||
// TODO 二楼工位放货完成后更新出库明细的实际出库数量
|
||
//if (input.wmsDistaskH.start_floor == 2 && input.wmsDistaskH.end_floor == 2)
|
||
{
|
||
WmsCarryCode wmsCarryCode = await _db.Queryable<WmsCarryCode>().Where(r => r.carry_id == input.wmsDistaskH.carry_id).FirstAsync();
|
||
await _db.Updateable<WmsPackOutstockD>().SetColumns(r => r.prqty == r.prqty + wmsCarryCode.codeqty).Where(r => r.id == input.wmsDistaskH.require_id).ExecuteCommandAsync();
|
||
|
||
CarryCodeUnbindInput carryCodeUnbindInput = new CarryCodeUnbindInput();
|
||
carryCodeUnbindInput.carry_id = input.wmsDistaskH.carry_id;
|
||
await _wmsCarryUnbindService.CarryCodeUnbind(carryCodeUnbindInput, _db);
|
||
}
|
||
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【WmsPackOutStockService ModifyAsync】" + ex.Message);
|
||
Logger.LogError("【WmsPackOutStockService ModifyAsync】" + ex.StackTrace);
|
||
await _db.Ado.RollbackTranAsync();
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 获取物料库存
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="AppFriendlyException"></exception>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> MaterialInventory(MaterialTransferGetMaterialInventoryInput input)
|
||
{
|
||
try
|
||
{
|
||
if (input.palletCount <= 0)
|
||
{
|
||
throw new AppFriendlyException("托盘数必须大于0", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.material_id))
|
||
{
|
||
throw new AppFriendlyException("物料id不可为空", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.code_batch))
|
||
{
|
||
throw new AppFriendlyException("批号不可为空", 500);
|
||
}
|
||
|
||
//入库取终点 //出库起点
|
||
OutStockStrategyQuery inStockStrategyInput = new()
|
||
{
|
||
warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID,
|
||
material_id = input.material_id,
|
||
code_batch = input.code_batch,
|
||
Size = input.palletCount
|
||
};
|
||
List<WmsCarryH> items = await _wareHouseService.OutStockStrategyYCL(inStockStrategyInput);
|
||
|
||
decimal qty = _db.Queryable<WmsCarryCode>().Where(r => items.Select(a => a.id).Contains(r.carry_id) && r.material_id == input.material_id && r.code_batch == input.code_batch).Sum(r => r.codeqty);
|
||
|
||
JObject keyValuePairs = new JObject();
|
||
keyValuePairs["realPalletCount"] = items.Count;
|
||
keyValuePairs["realInvQty"] = qty;
|
||
|
||
return await ToApiResult(HttpStatusCode.OK, "成功", keyValuePairs);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
await _db.Ado.RollbackTranAsync();
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按托下发
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="AppFriendlyException"></exception>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> Distribute(MaterialTransferDistributeInput input)
|
||
{
|
||
Logger.LogInformation($"【Distribute】 包材出库下发");
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(input.source_id))
|
||
{
|
||
throw new AppFriendlyException("来源单据id不可为空", 500);
|
||
}
|
||
if (input.palletCount <= 0)
|
||
{
|
||
throw new AppFriendlyException("托盘数必须大于0", 500);
|
||
}
|
||
if (input.qty <= 0)
|
||
{
|
||
throw new AppFriendlyException("数量必须大于0", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.code_batch))
|
||
{
|
||
throw new AppFriendlyException("批号不可为空", 500);
|
||
}
|
||
|
||
WmsPackOutstockD wmsPackOutstockD = await _db.Queryable<WmsPackOutstockD>().FirstAsync(it => it.id == input.source_id);
|
||
WmsPackOutstockH wmsPackOutstockH = await _db.Queryable<WmsPackOutstockH>().FirstAsync(it => it.id == wmsPackOutstockD.bill_id);
|
||
|
||
if (wmsPackOutstockD.prqty == wmsPackOutstockD.qty)
|
||
{
|
||
throw new AppFriendlyException("已下发数量已达到出库数量", 500);
|
||
}
|
||
|
||
await s_packOutstockSemaphore.WaitAsync();
|
||
await _db.Ado.BeginTranAsync();
|
||
|
||
//入库取终点 //出库起点
|
||
OutStockStrategyQuery outStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID, material_id = wmsPackOutstockD.material_id, code_batch = input.code_batch, Size = input.palletCount };
|
||
List<WmsCarryH> items = await _wareHouseService.OutStockStrategyYCL(outStockStrategyInput);
|
||
|
||
if (items.Count == 0)
|
||
{
|
||
throw new AppFriendlyException($@"没有可以出库的载具", 500);
|
||
}
|
||
|
||
decimal qty = _db.Queryable<WmsCarryCode>().Where(r => items.Select(a => a.id).Contains(r.carry_id) && r.material_id == wmsPackOutstockD.material_id && r.code_batch == input.code_batch).Sum(r => r.codeqty);
|
||
|
||
// 暂定PDA上查询到的物料批次和库存数量与提交时获取的不一致时,需要前台重新获取库存接口
|
||
if (input.palletCount != items.Count || input.qty != qty)
|
||
{
|
||
throw new AppFriendlyException($@"当前实际托盘数量为{input.palletCount} 实际库存数量为{qty},与前台数据不一致,请重新获取库存", HttpStatusCode.InternalServerError);
|
||
}
|
||
|
||
InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_F2BCQ_ID, Size = input.palletCount };
|
||
List<BasLocation> endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
|
||
if (endLocations.Count == 0)
|
||
{
|
||
throw new AppFriendlyException("没有可用的入库库位", 500);
|
||
}
|
||
|
||
if (endLocations.Count() < input.palletCount)
|
||
{
|
||
throw new AppFriendlyException($@"可用的终点库位数量为{endLocations.Count()}个 下发数量为{input.palletCount}个 请检查终点库位的锁定和占用状态", 500);
|
||
}
|
||
|
||
foreach (var wmsCarryH in items)
|
||
{
|
||
WmsCarryCode wmsCarryCode = await _db.Queryable<WmsCarryCode>().Where(r => r.carry_id == wmsCarryH.id).FirstAsync();
|
||
BasLocation startLocation = await _db.Queryable<BasLocation>().Where(r => r.id == wmsCarryH.location_id).FirstAsync();
|
||
|
||
InStockStrategyQuery _inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_F2BCQ_ID, Size = 1 };
|
||
List<BasLocation> _endLocations = await _wareHouseService.InStockStrategy(_inStockStrategyInput);
|
||
|
||
BasLocation endLocation = _endLocations.First();
|
||
if (endLocation == null)
|
||
{
|
||
throw new AppFriendlyException($@"没有可用的终点库位!请检查终点库位的锁定和占用状态", 500);
|
||
}
|
||
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
|
||
commonCreatePretaskInput.startlocation_id = startLocation.id;
|
||
commonCreatePretaskInput.endlocation_id = endLocation.id;
|
||
commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID;
|
||
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSPACKOUTSTOCK_ID;
|
||
commonCreatePretaskInput.require_id = input.source_id;
|
||
commonCreatePretaskInput.carry_id = wmsCarryH.id;
|
||
commonCreatePretaskInput.carry_code = wmsCarryH.carry_code;
|
||
commonCreatePretaskInput.isExcuteMission = false;
|
||
|
||
Entities.Dto.Outputs.Result res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput, _db);
|
||
|
||
if (res.code != HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($@"生成预任务失败");
|
||
throw new AppFriendlyException($@"生成预任务失败", 500);
|
||
}
|
||
}
|
||
|
||
// 更新子表已下发数量
|
||
await _db.Updateable<WmsPackOutstockD>().SetColumns(r => r.sendqty == r.sendqty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync();
|
||
|
||
await _db.Ado.CommitTranAsync();
|
||
Logger.LogInformation($"【Distribute】 包材出库下发完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
await _db.Ado.RollbackTranAsync();
|
||
Logger.LogError("【Distribute】 包材出库" + ex.Message);
|
||
Logger.LogError("【Distribute】 包材出库" + ex.StackTrace);
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
finally
|
||
{
|
||
_ = s_packOutstockSemaphore.Release();
|
||
InvokeGenPretaskExcute();
|
||
}
|
||
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
}
|
||
}
|