Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WmsPackOutstockService.cs

272 lines
13 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 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, "成功");
}
}
}