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

305 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 System.Threading.Channels;
using Aop.Api.Domain;
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.Systems.Interfaces.System;
using JNPF.VisualDev;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NPOI.SS.Formula.PTG;
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.Dto.Inputs;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 空载具入库
/// </summary>
[OverideVisualDev(ModuleConsts.MODULE_WMSEMPTYINSTOCK_ID)]
[ServiceModule(BizTypeId)]
public class WmsEmptyInstockService : BaseWareHouseService, IWmsEmptyInstockService
{
private const string BizTypeId = "26121986416677";
private readonly ISqlSugarClient _db;
private readonly IRunService _runService;
private readonly IVisualDevService _visualDevService;
private readonly IWareHouseService _wareHouseService;
private readonly IBillRullService _billRullService;
private readonly IUserManager _userManager;
private readonly ChannelWriter<NotifyMessage> _channelWriter;
private readonly IConfiguration _configuration;
public WmsEmptyInstockService(
ISqlSugarRepository<WmsCarryH> repository,
IRunService runService,
IVisualDevService visualDevService,
IWareHouseService wareHouseService,
IUserManager userManager,
IBillRullService billRullService,
IEventPublisher eventPublisher,
IConfiguration configuration
)
{
_db = repository.AsSugarClient();
_runService = runService;
_visualDevService = visualDevService;
_wareHouseService = wareHouseService;
_userManager = userManager;
_billRullService = billRullService;
_configuration = configuration;
OverideFuncs.CreateAsync = WmsEmptyIn;
}
public async Task<dynamic> WmsEmptyIn(VisualDevModelDataCrInput input)
{
if (input.data[nameof(OutStockStrategyQuery.warehouse_id)].ToString() == WmsWareHouseConst.WAREHOUSE_ZC_ID)
{
await _s_taskExecuteSemaphore_F1ZCCInstock.WaitAsync();
}
try
{
await _db.Ado.BeginTranAsync();
//入库取终点
InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = input.data[nameof(InStockStrategyQuery.warehouse_id)].ToString()!, Size = 1 };
//test
//BasLocation llll = await _db.Queryable<BasLocation>().FirstAsync(it => it.location_code == _configuration["TestLocation"]);
List<BasLocation> endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
WmsPointH? sPoint = null;
WmsPointH? ePoint = null;
if (input.data.ContainsKey(nameof(WmsPointH.location_id)))
{
sPoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == input.data[nameof(WmsPointH.location_id)].ToString());
}
if (endLocations?.Count > 0)
{
WmsCarryH carry = await _db.Queryable<WmsCarryH>().SingleAsync(it => it.id == input.data[nameof(WmsCarryD.carry_id)].ToString());
BasLocation loc = await _db.Queryable<BasLocation>().SingleAsync(it => it.id == endLocations[0].id);
Logger.Information($"loc.location_code={loc?.location_code}");
bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, loc);
if (!isMatch)
{
throw new AppFriendlyException("库位与载具规格不匹配", 500);
}
ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == endLocations[0].id);
}
//在线开发
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSEMPTYINSTOCK_ID, true);
await _runService.Create(templateEntity, input);
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);
}
//根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
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_WMSEMPTYINSTOCK_ID,
task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID,
carry_id = input.data[nameof(preTask.carry_id)]?.ToString()!,
carry_code = input.data[nameof(preTask.carry_code)]?.ToString()!,
area_id = sPoint?.area_id!,
area_code = it.Key,
require_id = input.data["ReturnIdentity"].ToString(),
require_code = input.data[nameof(preTask.bill_code)]?.ToString()!,
create_id = _userManager.UserId,
create_time = DateTime.Now,
};
return preTask;
}).ToList();
bool isOk = await _wareHouseService.GenPreTask(preTasks, null!);
if (isOk)
{
GenPreTaskUpInput preTaskUpInput = new()
{
RquireId = input.data["ReturnIdentity"].ToString()!,
CarryId = input.data[nameof(WmsCarryD.carry_id)]?.ToString()!,
CarryStartLocationId = points.FirstOrDefault()!.location_id!,
CarryStartLocationCode = points.FirstOrDefault()!.location_code!,
LocationIds = points.Select(x => x.location_id).ToList()!,
PreTaskRecords = preTasks.Adapt<List<WmsHandleH>>()
};
preTaskUpInput.PreTaskRecords.ForEach(x => x.id = SnowflakeIdHelper.NextId());
WmsHandleH handleH = new()
{
org_id = _userManager.User.OrganizeId,
startlocation_id = input.data[nameof(WmsPointH.location_id)]?.ToString()!,
endlocation_id = endLocations![0].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<WmsEmptyInstock>().SetColumns(it => new WmsEmptyInstock { 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 });
}
else
{
throw new AppFriendlyException("预任务生成失败,路径或者设备相关配置错误", 500);
}
}
else
{
throw new AppFriendlyException("起始库位不可用或无可用的目标库位", 500);
}
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
Logger.Error("空载具入库失败", ex);
await _db.Ado.RollbackTranAsync();
throw;
}
finally
{
if (input.data[nameof(OutStockStrategyQuery.warehouse_id)].ToString() == WmsWareHouseConst.WAREHOUSE_ZC_ID)
{
_s_taskExecuteSemaphore_F1ZCCInstock.Release();
}
//向队列写入消息
await InvokeGenPretaskExcute();
}
return Task.FromResult(true);
}
/// <summary>
/// MES空载具入库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<dynamic> MesEmptyCarryInStock(MESEmptyCarryInStockInput input)
{
bool isSuccessful = false;
if (input.IsNull())
{
throw new ArgumentNullException("input");
}
try
{
WmsCarryH carry = await _db.Queryable<WmsCarryH>().SingleAsync(it => it.carry_code == input.carry_code);
BasLocation loc = await _db.Queryable<BasLocation>().SingleAsync(it => it.location_code == input.location_code);
WmsEmptyInstock emptyInstock = await _db.Queryable<WmsEmptyInstock>().FirstAsync(it => it.carry_code == input.carry_code && it.status == WmsWareHouseConst.BILLSTATUS_ADD_ID);
if (emptyInstock != null)
{
return isSuccessful;
}
if (carry != null && loc != null)
{
List<string> cols = new();
Dictionary<string, object> dic = new()
{
[nameof(WmsEmptyInstock.id)] = SnowflakeIdHelper.NextId(),
[nameof(WmsEmptyInstock.org_id)] = input.org_id ?? _userManager.User.OrganizeId,
[nameof(WmsEmptyInstock.location_id)] = loc.id,
[nameof(WmsEmptyInstock.bill_code)] = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_EMPTYINSTK_ENCODE),
[nameof(WmsEmptyInstock.status)] = WmsWareHouseConst.BILLSTATUS_ADD_ID,
[nameof(WmsEmptyInstock.carry_id)] = carry.id,
[nameof(WmsEmptyInstock.carry_code)] = input.carry_code!,
[nameof(WmsEmptyInstock.biz_type)] = WmsWareHouseConst.BIZTYPE_WMSEMPTYINSTOCK_ID,
[nameof(WmsEmptyInstock.create_id)] = input.create_id ?? _userManager.UserId,
[nameof(WmsEmptyInstock.create_time)] = DateTime.Now,
[nameof(WmsEmptyInstock.warehouse_id)] = input.warehouse_id!
};
VisualDevModelDataCrInput visualDevModelDataCrInput = new()
{
data = dic
};
await WmsEmptyIn(visualDevModelDataCrInput);
isSuccessful = true;
}
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
//return await ToApiResult(JNPF.Common.Enums.HttpStatusCode.InternalServerError, ex.Message);
}
return isSuccessful;
}
public override async Task ModifyAsync(WareHouseUpInput input)
{
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
bool isOk = await _db.Updateable<WmsEmptyInstock>().SetColumns(it => new WmsEmptyInstock { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandHasChangeAsync();
if (!isOk)
{
throw Oops.Oh(ErrorCode.COM1001);
}
}
}
}