778 lines
39 KiB
C#
778 lines
39 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using JNPF.Common.Core.Manager;
|
||
using JNPF.Common.Filter;
|
||
using JNPF.EventBus;
|
||
using JNPF.Systems.Interfaces.System;
|
||
using JNPF.VisualDev;
|
||
using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
|
||
using JNPF.VisualDev.Interfaces;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Newtonsoft.Json.Linq;
|
||
using Newtonsoft.Json;
|
||
using SqlSugar;
|
||
using Tnb.WarehouseMgr.Entities;
|
||
using Tnb.WarehouseMgr.Entities.Attributes;
|
||
using Tnb.WarehouseMgr.Entities.Entity;
|
||
using Tnb.WarehouseMgr.Interfaces;
|
||
using JNPF.Common.Dtos.VisualDev;
|
||
using JNPF.Common.Extension;
|
||
using JNPF.Common.Security;
|
||
using JNPF.FriendlyException;
|
||
using JNPF.VisualDev.Entitys;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Tnb.BasicData.Entities;
|
||
using Tnb.WarehouseMgr.Entities.Consts;
|
||
using Tnb.WarehouseMgr.Entities.Dto;
|
||
using Tnb.WarehouseMgr.Entities.Enums;
|
||
using JNPF.Common.Enums;
|
||
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
|
||
using Microsoft.Extensions.Logging;
|
||
using JNPF.Systems.Entitys.System;
|
||
using JNPF.Systems.Entitys.Permission;
|
||
using Aop.Api.Domain;
|
||
using Senparc.Weixin.Work.AdvancedAPIs.OaDataOpen;
|
||
using NPOI.SS.Formula.Functions;
|
||
using Org.BouncyCastle.Asn1.X509;
|
||
|
||
namespace Tnb.WarehouseMgr
|
||
{
|
||
/// <summary>
|
||
/// 原材料转库单
|
||
/// </summary>
|
||
[OverideVisualDev(ModuleConsts.MODULE_WMSMATERIALTRANSFER_ID)]
|
||
[ServiceModule(BizTypeId)]
|
||
public class WmsMaterialTransferService : BaseWareHouseService
|
||
{
|
||
private const string BizTypeId = "34354738929685";
|
||
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 IWmsCarryBindService _wmsCarryBindService;
|
||
|
||
public static SemaphoreSlim s_taskDistributeToZCC = new(1);
|
||
|
||
public WmsMaterialTransferService(
|
||
ISqlSugarRepository<WmsCarryH> repository,
|
||
IRunService runService,
|
||
IVisualDevService visualDevService,
|
||
IWareHouseService wareHouseService,
|
||
IUserManager userManager,
|
||
IBillRullService billRullService,
|
||
IEventPublisher eventPublisher,
|
||
IWmsCarryBindService wmsCarryBindService)
|
||
{
|
||
_db = repository.AsSugarClient();
|
||
_runService = runService;
|
||
_visualDevService = visualDevService;
|
||
_wareHouseService = wareHouseService;
|
||
_userManager = userManager;
|
||
_billRullService = billRullService;
|
||
_wmsCarryBindService = wmsCarryBindService;
|
||
|
||
OverideFuncs.GetListAsync = GetList;
|
||
}
|
||
|
||
[NonAction]
|
||
private async Task<dynamic> GetList(VisualDevModelListQueryInput input)
|
||
{
|
||
try
|
||
{
|
||
SqlSugarPagedList<WmsMaterialTransfer> result = await _db.Queryable<WmsMaterialTransfer>()
|
||
.InnerJoin<DictionaryDataEntity>((a, b) => a.status == b.Id)
|
||
.InnerJoin<UserEntity>((a, b, c) => c.Id == a.create_id)
|
||
.InnerJoin<BasWarehouse>((a, b, c, d) => d.id == a.warehouse_outstock)
|
||
.InnerJoin<BasWarehouse>((a, b, c, d, e) => e.id == a.warehouse_instock)
|
||
// 只显示未完成的单据
|
||
.Where( a => a.status != "25065149810453")
|
||
.Select((a, b, c, d, e) => new WmsMaterialTransfer
|
||
{
|
||
id = a.id,
|
||
create_id = c.RealName,
|
||
create_time = a.create_time,
|
||
modify_id = a.modify_id,
|
||
modify_time = a.modify_time,
|
||
org_id = a.org_id,
|
||
tenant_id = a.tenant_id,
|
||
timestamp = a.timestamp,
|
||
bill_code = a.bill_code,
|
||
status = b.FullName,
|
||
bill_date = a.bill_date,
|
||
warehouse_outstock = d.whname,
|
||
warehouse_instock = e.whname,
|
||
type = a.type,
|
||
biller_out = a.biller_out,
|
||
depart_out = a.depart_out,
|
||
biller_in = a.biller_in,
|
||
depart_in = a.depart_in,
|
||
deliver_date = a.deliver_date,
|
||
arrival_date = a.arrival_date,
|
||
order_code = a.order_code,
|
||
})
|
||
.ToPagedListAsync(input.currentPage, input.pageSize);
|
||
|
||
var _data = PageResult<WmsMaterialTransfer>.SqlSugarPageResult(result);
|
||
var json = JsonConvert.SerializeObject(_data);
|
||
var data = JsonConvert.DeserializeObject<dynamic>(json);
|
||
JArray mainTable = data.list;
|
||
|
||
foreach (dynamic row in mainTable)
|
||
{
|
||
row.deliver_date = row.deliver_date.Value?.ToString("yyyy-MM-dd");
|
||
row.arrival_date = row.arrival_date.Value?.ToString("yyyy-MM-dd");
|
||
row.create_time = row.create_time.Value?.ToString("yyyy-MM-dd");
|
||
}
|
||
|
||
List<WmsMaterialTransferD> wmsTransferInstockDs = _db.Queryable<WmsMaterialTransferD, BasMaterial>((a, b) =>
|
||
new JoinQueryInfos(JoinType.Left, a.material_id == b.id)
|
||
)
|
||
.Select((a, b) => new WmsMaterialTransferD
|
||
{
|
||
id = a.id,
|
||
material_id = a.material_id,
|
||
material_code = b.code,
|
||
material_ex = b.name,
|
||
material_specification = b.material_specification,
|
||
unit_id = a.unit_id,
|
||
unit_code = a.unit_code,
|
||
code_batch = a.code_batch,
|
||
station_code = a.station_code,
|
||
qty = a.qty,
|
||
yxfqty = a.yxfqty,
|
||
yzqty = a.yzqty,
|
||
bill_id = a.bill_id,
|
||
lineno = a.lineno,
|
||
f_flowtaskid = a.f_flowtaskid,
|
||
f_flowid = a.f_flowid,
|
||
})
|
||
.Where(a => mainTable.Select(r => r["id"].ToString()).ToList().Contains(a.bill_id)).ToList();
|
||
|
||
foreach (JObject wmsTransferInstockH in mainTable)
|
||
{
|
||
wmsTransferInstockH["tablefield121"] = JArray.Parse(JsonConvert.SerializeObject(wmsTransferInstockDs.Where(r => r.bill_id == wmsTransferInstockH["id"].ToString())));
|
||
}
|
||
return data;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return Task.FromResult(ex);
|
||
}
|
||
}
|
||
|
||
|
||
/// <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_YCL_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).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)
|
||
{
|
||
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);
|
||
}
|
||
|
||
WmsMaterialTransferD wmsMaterialTransferD = await _db.Queryable<WmsMaterialTransferD>().FirstAsync(it => it.id == input.source_id);
|
||
WmsMaterialTransfer wmsMaterialTransfer = await _db.Queryable<WmsMaterialTransfer>().FirstAsync(it => it.id == wmsMaterialTransferD.bill_id);
|
||
|
||
if (wmsMaterialTransferD.yxfqty == wmsMaterialTransferD.qty)
|
||
{
|
||
throw new AppFriendlyException("已下发数量已达到转库数量", 500);
|
||
}
|
||
|
||
await s_taskExecuteSemaphore.WaitAsync();
|
||
await _db.Ado.BeginTranAsync();
|
||
|
||
//入库取终点 //出库起点
|
||
OutStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_YCL_ID, material_id = wmsMaterialTransferD.material_id, code_batch = wmsMaterialTransferD.code_batch, Size = input.palletCount };
|
||
List<WmsCarryH> items = await _wareHouseService.OutStockStrategyYCL(inStockStrategyInput);
|
||
|
||
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 == wmsMaterialTransferD.material_id).Sum(r => r.codeqty);
|
||
|
||
// 暂定PDA上查询到的物料批次和库存数量与提交时获取的不一致时,需要前台重新获取库存接口
|
||
if (input.palletCount != items.Count || input.qty != qty)
|
||
{
|
||
throw new AppFriendlyException($@"当前实际托盘数量为{input.palletCount} 实际库存数量为{qty},与前台数据不一致,请重新获取库存", HttpStatusCode.InternalServerError);
|
||
}
|
||
|
||
List<BasLocation> endLocations = new List<BasLocation>();
|
||
// 集中供料区三工位
|
||
if (wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_JZGL_ID)
|
||
{
|
||
// 根据三工位任务数平均分配任务 暂定
|
||
endLocations = _db.Queryable<BasLocation>().Where(r => _wareHouseService.GetFloor1GLSGWOutstockLocation().Contains(r.id) && r.is_lock == 0 && r.is_use == "0")
|
||
.OrderBy("is_lock, task_nums, location_code").ToList();
|
||
}
|
||
// 中储仓三工位
|
||
else if (wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_ZC_ID)
|
||
{
|
||
// 根据三工位任务数平均分配任务 暂定
|
||
endLocations = _db.Queryable<BasLocation>().Where(r => _wareHouseService.GetFloor1WXSGWOutstockLocation().Contains(r.id) && r.is_lock == 0 && r.is_use == "0")
|
||
.OrderBy("is_lock, task_nums, location_code").ToList();
|
||
}
|
||
|
||
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.location_code == wmsCarryH.location_code).FirstAsync();
|
||
|
||
BasLocation endLocation = null;
|
||
// 集中供料区三工位
|
||
if (wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_JZGL_ID)
|
||
{
|
||
// 根据三工位任务数平均分配任务 暂定
|
||
endLocation = await _db.Queryable<BasLocation>().Where(r => _wareHouseService.GetFloor1GLSGWOutstockLocation().Contains(r.id) && r.is_lock == 0 && r.is_use == "0").OrderBy("is_lock, task_nums, location_code").FirstAsync();
|
||
}
|
||
// 中储仓三工位
|
||
else if(wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_ZC_ID)
|
||
{
|
||
// 根据三工位任务数平均分配任务 暂定
|
||
endLocation = await _db.Queryable<BasLocation>().Where(r => _wareHouseService.GetFloor1WXSGWOutstockLocation().Contains(r.id) && r.is_lock == 0 && r.is_use == "0").OrderBy("is_lock, task_nums, location_code").FirstAsync();
|
||
}
|
||
|
||
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_WMSMATERIALTRANSFER_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);
|
||
|
||
if (res.code != HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($@"生成预任务失败");
|
||
throw new AppFriendlyException($@"生成预任务失败", 500);
|
||
}
|
||
}
|
||
|
||
// 更新子表已下发数量
|
||
await _db.Updateable<WmsMaterialTransferD>().SetColumns(r => r.yxfqty == r.yxfqty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync();
|
||
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
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_taskExecuteSemaphore.Release();
|
||
InvokeGenPretaskExcute();
|
||
}
|
||
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
|
||
public override async Task ModifyAsync(WareHouseUpInput input)
|
||
{
|
||
if (input == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input));
|
||
}
|
||
List<WmsCarryCode> wmsCarryCodes = await _db.Queryable<WmsCarryCode>().Where(r => r.carry_id == input.carryIds[0]).ToListAsync();
|
||
if (wmsCarryCodes.Count == 0)
|
||
{
|
||
Logger.LogWarning($"【ModifyAsync】载具{input.carryIds[0]}没有绑定物料条码");
|
||
return;
|
||
}
|
||
// 更新已转数量
|
||
bool isOk = await _db.Updateable<WmsMaterialTransferD>().SetColumns(it => new WmsMaterialTransferD { yzqty = it.yzqty + wmsCarryCodes.Sum(r => r.codeqty)})
|
||
.Where(it => it.id == input.requireId).ExecuteCommandHasChangeAsync();
|
||
|
||
// 如果所有明细已完成 更新主表状态为完成
|
||
WmsMaterialTransferD wmsMaterialTransferd = await _db.Queryable<WmsMaterialTransferD>().Where(r => r.id == input.requireId).SingleAsync();
|
||
List<WmsMaterialTransferD> wmsMaterialTransferDs = _db.Queryable<WmsMaterialTransferD>()
|
||
.Where(a => a.bill_id == wmsMaterialTransferd.bill_id && a.yzqty < a.qty).ToList();
|
||
bool isOk2 = true;
|
||
if (wmsMaterialTransferDs.Count == 0)
|
||
{
|
||
isOk2 = await _db.Updateable<WmsMaterialTransfer>().SetColumns(it => new WmsMaterialTransfer { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID })
|
||
.Where(it => it.id == wmsMaterialTransferd.bill_id).ExecuteCommandHasChangeAsync();
|
||
}
|
||
|
||
|
||
if (!isOk || !isOk2)
|
||
{
|
||
throw Oops.Oh(ErrorCode.COM1001);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 中储仓下发到二楼暂存仓
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="AppFriendlyException"></exception>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> DistributeToZCC(MaterialTransferDistributeToZCCInput input)
|
||
{
|
||
s_taskDistributeToZCC.Wait();
|
||
|
||
try
|
||
{
|
||
WmsMaterialTransfer wmsMaterialTransfer = _db.Queryable<WmsMaterialTransfer>().Where(r => r.id == input.source_id).First();
|
||
if (wmsMaterialTransfer == null)
|
||
{
|
||
Logger.LogWarning($"不存在id为{input.source_id}的转库单!");
|
||
throw new AppFriendlyException($"不存在id为{input.source_id}的转库单!", 500);
|
||
}
|
||
if (wmsMaterialTransfer.status != WmsWareHouseConst.BILLSTATUS_ADD_ID)
|
||
{
|
||
Logger.LogWarning($@"当前转库单状态为{wmsMaterialTransfer.status},不能下发中储仓下发到二楼暂存仓任务!");
|
||
throw new AppFriendlyException($@"当前转库单状态为{wmsMaterialTransfer.status},不能下发中储仓下发到二楼暂存仓任务!", 500);
|
||
}
|
||
|
||
List<WmsMaterialTransferD> wmsMaterialTransferds = _db.Queryable<WmsMaterialTransferD>().Where(r => r.bill_id == input.source_id).ToList();
|
||
|
||
// 转库单载具子表
|
||
List<WmsMaterialTransferCarry> wmsMaterialTransferCarrys = new List<WmsMaterialTransferCarry>();
|
||
|
||
foreach (WmsMaterialTransferD wmsMaterialTransferD in wmsMaterialTransferds)
|
||
{
|
||
//出库取起点,获取所有符合输入的载具规格的载具
|
||
OutStockStrategyQuery OutStockStrategyInput = new()
|
||
{
|
||
warehouse_id = "2",
|
||
material_id = wmsMaterialTransferD.material_id,
|
||
code_batch = wmsMaterialTransferD.code_batch
|
||
};
|
||
List<WmsCarryH>? carrys = await _wareHouseService.OutStockStrategyZCC2Floor2(OutStockStrategyInput);
|
||
|
||
// 需要转库数量
|
||
decimal? needOut = wmsMaterialTransferD.qty;
|
||
|
||
foreach (WmsCarryH wmsCarryH in carrys)
|
||
{
|
||
if (needOut <= 0)
|
||
{
|
||
break;
|
||
}
|
||
|
||
List<WmsCarryCode> wmsCarryCodes = _db.Queryable<WmsCarryCode>().Where(r => r.carry_id == wmsCarryH.id).ToList();
|
||
|
||
WmsCarryCode wmsCarryCode = wmsCarryCodes.First();
|
||
|
||
// 目前只支持一个料箱只有一个物料
|
||
foreach (WmsCarryCode _wmsCarryCode in wmsCarryCodes)
|
||
{
|
||
needOut -= wmsCarryCode.codeqty;
|
||
}
|
||
|
||
BasLocation endlocation_ssx = await _db.Queryable<BasLocation>().Where(r => new string[2] { "32609229889045", "32609238573589" }.Contains(r.id)).OrderBy("is_lock, task_nums, location_code").FirstAsync();
|
||
await _db.Updateable<BasLocation>().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync();
|
||
|
||
// 转库单载具子表
|
||
WmsMaterialTransferCarry wmsMaterialTransferCarry = new WmsMaterialTransferCarry();
|
||
wmsMaterialTransferCarry.bill_id = input.source_id;
|
||
wmsMaterialTransferCarry.carry_id = wmsCarryH.id;
|
||
wmsMaterialTransferCarry.carry_code = wmsCarryH.carry_code;
|
||
wmsMaterialTransferCarry.create_id = input.create_id;
|
||
wmsMaterialTransferCarry.create_time = DateTime.Now;
|
||
wmsMaterialTransferCarry.endlocation_id = endlocation_ssx.id;
|
||
wmsMaterialTransferCarry.endlocation_code = endlocation_ssx.location_code;
|
||
wmsMaterialTransferCarry.startlocation_id = wmsCarryH.location_id;
|
||
wmsMaterialTransferCarry.startlocation_code = wmsCarryH.location_code;
|
||
wmsMaterialTransferCarry.mat_bill_id = wmsMaterialTransferD.id;
|
||
wmsMaterialTransferCarry.qty = wmsCarryCode.codeqty;
|
||
wmsMaterialTransferCarrys.Add(wmsMaterialTransferCarry);
|
||
}
|
||
|
||
if (needOut > 0)
|
||
{
|
||
throw new AppFriendlyException($"物料{wmsMaterialTransferD.material_code}没有足够的库存!,缺失数量为{needOut}", 500);
|
||
}
|
||
}
|
||
|
||
await _db.Ado.BeginTranAsync();
|
||
|
||
await _db.Updateable<WmsMaterialTransfer>().SetColumns(r => new WmsMaterialTransfer
|
||
{
|
||
status = WmsWareHouseConst.BILLSTATUS_ON_ID,
|
||
carry_count = wmsMaterialTransferCarrys.Count,
|
||
remainbindracknum = wmsMaterialTransferCarrys.Count
|
||
}).Where(r => r.id == input.source_id).ExecuteCommandAsync();
|
||
Logger.LogInformation($"【DistributeToZCC】更新转库单{wmsMaterialTransfer.bill_code}主表的数据");
|
||
|
||
await _db.Insertable(wmsMaterialTransferCarrys).ExecuteCommandAsync();
|
||
Logger.LogInformation($"【DistributeToZCC插入转库单{wmsMaterialTransfer.bill_code}载具表的数据");
|
||
|
||
foreach (WmsMaterialTransferCarry wmsMaterialTransferCarry in wmsMaterialTransferCarrys)
|
||
{
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
|
||
commonCreatePretaskInput.startlocation_id = wmsMaterialTransferCarry.startlocation_id;
|
||
commonCreatePretaskInput.endlocation_id = wmsMaterialTransferCarry.endlocation_id;
|
||
commonCreatePretaskInput.carry_id = wmsMaterialTransferCarry.carry_id;
|
||
commonCreatePretaskInput.carry_code = wmsMaterialTransferCarry.carry_code;
|
||
commonCreatePretaskInput.task_type = WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID;
|
||
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
|
||
commonCreatePretaskInput.require_id = wmsMaterialTransferCarry.mat_bill_id;
|
||
commonCreatePretaskInput.isExcuteMission = false;
|
||
|
||
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
|
||
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($"【DistributeToZCC生成预任务失败 载具 {wmsMaterialTransferCarry.carry_code}");
|
||
throw new AppFriendlyException($"生成预任务失败 载具 {wmsMaterialTransferCarry.carry_code}", 500);
|
||
}
|
||
|
||
await _db.Updateable<WmsMaterialTransferD>().SetColumns(r => r.yxfqty == r.yxfqty + wmsMaterialTransferCarry.qty).Where(r => r.id == wmsMaterialTransferCarry.mat_bill_id).ExecuteCommandAsync();
|
||
}
|
||
Logger.LogInformation($"转库单{wmsMaterialTransfer.bill_code}预任务{wmsMaterialTransferCarrys.Count}条全部生成成功");
|
||
|
||
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
await _db.Ado.RollbackTranAsync();
|
||
Logger.LogError("【DistributeToZCC】" + ex.Message);
|
||
Logger.LogError("【DistributeToZCC】" + ex.StackTrace);
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
finally
|
||
{
|
||
s_taskDistributeToZCC.Release();
|
||
InvokeGenPretaskExcute();
|
||
}
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从暂存仓呼叫料架到产线
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="AppFriendlyException"></exception>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> CallRackToProductionLine(MaterialTransferCallRackToProductionLineInput input)
|
||
{
|
||
try
|
||
{
|
||
WmsCarryH wmsCarryH = _db.Queryable<WmsCarryH>().Where(r => r.carry_code == input.carry_code).First();
|
||
if (wmsCarryH == null)
|
||
{
|
||
Logger.LogWarning($"【CallRackToProductionLine】不存在编码为{input.carry_code}的料架号!");
|
||
throw new AppFriendlyException($"不存在编码为{input.carry_code}的料架号!", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(wmsCarryH.work_station))
|
||
{
|
||
Logger.LogWarning($"【CallRackToProductionLine】此料架目标工位为空!{input.carry_code}");
|
||
throw new AppFriendlyException($"此料架目标工位为空!{input.carry_code}!", 500);
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(wmsCarryH.location_id))
|
||
{
|
||
Logger.LogWarning($"【CallRackToProductionLine】此料架的库位为空!{input.carry_code}");
|
||
throw new AppFriendlyException($"此料架的库位为空!{input.carry_code}", 500);
|
||
}
|
||
|
||
BasLocation endlocation = _db.Queryable<BasLocation>().Where(r => r.location_code == wmsCarryH.work_station).First();
|
||
|
||
WmsPretaskH wmsPretaskH = _db.Queryable<WmsPretaskH>().Where(r => r.carry_code == wmsCarryH.carry_code && r.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID).First();
|
||
if (wmsPretaskH != null)
|
||
{
|
||
Logger.LogWarning($"【CallRackToProductionLine】此料架{input.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!");
|
||
throw new AppFriendlyException($"此料架{input.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!", 500);
|
||
}
|
||
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
|
||
commonCreatePretaskInput.startlocation_id = wmsCarryH.location_id;
|
||
commonCreatePretaskInput.endlocation_id = endlocation.id;
|
||
commonCreatePretaskInput.carry_id = wmsCarryH.id;
|
||
commonCreatePretaskInput.carry_code = wmsCarryH.carry_code;
|
||
commonCreatePretaskInput.task_type = "";
|
||
commonCreatePretaskInput.biz_type = "FloorCallMaterial";
|
||
|
||
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
|
||
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($"【CallRackToProductionLine】生成预任务失败 载具 {wmsCarryH.carry_code}");
|
||
throw new AppFriendlyException($"生成预任务失败 载具 {wmsCarryH.carry_code}", 500);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【CallRackToProductionLine】" + ex.Message);
|
||
Logger.LogError("【CallRackToProductionLine】" + ex.StackTrace);
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过工位查找料架信息
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="AppFriendlyException"></exception>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> RackAndMatByWorkstation(MaterialTransferGetRackAndMatByWorkStationInput input)
|
||
{
|
||
try
|
||
{
|
||
List<WmsCarryH> wmsCarryHs = _db.Queryable<WmsCarryH>().Where(r => r.work_station == input.work_station).ToList();
|
||
if (string.IsNullOrEmpty(input.work_station))
|
||
{
|
||
Logger.LogWarning($"【RackAndMatByWorkstation】工位不能为空!");
|
||
throw new AppFriendlyException($"工位不能为空!", 500);
|
||
}
|
||
if (wmsCarryHs.Count == 0)
|
||
{
|
||
Logger.LogWarning($"【RackAndMatByWorkstation】工位{input.work_station}未绑定料架!");
|
||
throw new AppFriendlyException($"工位{input.work_station}未绑定料架!", 500);
|
||
}
|
||
|
||
JObject keyValuePairs = new JObject();
|
||
JArray jArray = new JArray();
|
||
foreach (WmsCarryH wmsCarryH in wmsCarryHs)
|
||
{
|
||
if (wmsCarryH.carrystd_id != "26037267399717")
|
||
{
|
||
Logger.LogWarning($"【RackAndMatByWorkstation】工位{input.work_station}绑定的{wmsCarryH.carry_code}载具不是料架类型!请检查");
|
||
continue;
|
||
}
|
||
|
||
var matCodes = _db.Queryable<WmsCarryD>()
|
||
.InnerJoin<WmsCarryCode>((a, b) => a.membercarry_id == b.carry_id)
|
||
.InnerJoin<BasMaterial>((a, b, c) => b.material_id == c.id)
|
||
.Where((a, b, c) => a.carry_id == wmsCarryH.id)
|
||
.Select((a, b, c) => new
|
||
{
|
||
b.org_id,
|
||
a.membercarry_id,
|
||
a.membercarry_code,
|
||
b.material_id,
|
||
b.material_code,
|
||
material_name = c.name,
|
||
c.material_specification,
|
||
b.unit_id,
|
||
b.barcode,
|
||
b.code_batch,
|
||
b.codeqty,
|
||
b.create_id,
|
||
b.create_time
|
||
}).ToList();
|
||
|
||
JObject pairs = new JObject();
|
||
pairs["carry_id"] = wmsCarryH.id;
|
||
pairs["carry_code"] = wmsCarryH.carry_code;
|
||
pairs["details"] = JArray.Parse(JsonConvert.SerializeObject(matCodes));
|
||
jArray.Add(pairs);
|
||
}
|
||
return await ToApiResult(HttpStatusCode.OK, "成功", jArray);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【RackAndMatByWorkstation】" + ex.Message);
|
||
Logger.LogError("【RackAndMatByWorkstation】" + ex.StackTrace);
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从产线呼叫装料架到暂存仓
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> RackInstock(MaterialTransferRackInstockInput input)
|
||
{
|
||
try
|
||
{
|
||
BasLocation startlocation = _db.Queryable<BasLocation>().Where(r => r.id == input.startlocation_id).First();
|
||
if (startlocation == null)
|
||
{
|
||
Logger.LogWarning($"【RackEmptyInstock】不存在id为{input.startlocation_id}的库位!");
|
||
throw new AppFriendlyException($"【RackEmptyInstock】不存在id为{input.startlocation_id}的库位!", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.carry_code))
|
||
{
|
||
Logger.LogWarning($"【RackEmptyInstock】料架不能为空!{input.carry_code}");
|
||
throw new AppFriendlyException($"【RackEmptyInstock】料架不能为空!{input.carry_code}!", 500);
|
||
}
|
||
if (input.judgeEmptyCarry)
|
||
{
|
||
List<WmsCarryCode> wmsCarryCodes = _db.Queryable<WmsCarryH>()
|
||
.InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id)
|
||
.Where((a, b) => input.details.Select(r => r.carry_code).Contains(a.carry_code)).Select((a, b) => b).ToList();
|
||
if (wmsCarryCodes.Count > 0)
|
||
{
|
||
Logger.LogWarning($"【RackEmptyInstock】存在非空料箱,不能入库!{input.carry_code}");
|
||
throw new AppFriendlyException($"【RackEmptyInstock】存在非空料箱,不能入库!{input.carry_code}!", 500);
|
||
}
|
||
}
|
||
|
||
// 找到未占用且未锁定的库位
|
||
ISugarQueryable<BasLocation> rackEndLocations =
|
||
_db.Queryable<BasLocation>()
|
||
.Where(r => r.wh_id == "33780009364245" && r.is_use == "0" && r.is_lock == 0).OrderBy(a => a.id).Take(1);
|
||
|
||
if (rackEndLocations.Count() == 0)
|
||
{
|
||
Logger.LogWarning($"【RackEmptyInstock】没有可用的终点库位");
|
||
throw new AppFriendlyException($"【RackEmptyInstock】没有可用的终点库位!", 500);
|
||
}
|
||
|
||
BasLocation endlocation = rackEndLocations.First();
|
||
|
||
WmsCarryH wmsCarryH = await _db.Queryable<WmsCarryH>().Where(r => r.carry_code == input.carry_code).FirstAsync();
|
||
// 重新绑定料箱到料架
|
||
// 清空料架
|
||
Logger.LogWarning($"【RackEmptyInstock】清空料架");
|
||
|
||
List<WmsCarryH> membercarrys = _db.Queryable<WmsCarryH>().Where(r => input.details.Select(r => r.carry_code).Contains(r.carry_code)).ToList();
|
||
|
||
await _db.Ado.BeginTranAsync();
|
||
// 解除绑定料箱到料架
|
||
CarryBindInput carryBindInput = new();
|
||
carryBindInput.carry_id = wmsCarryH.id;
|
||
carryBindInput.carry_code = wmsCarryH.carry_code;
|
||
var resCarryUnbind = await _wmsCarryBindService.CarryUnbind(carryBindInput);
|
||
if (resCarryUnbind.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
throw new AppFriendlyException($"解除绑定料箱到料架失败 载具 {input.carry_code}", 500);
|
||
}
|
||
Logger.LogWarning($"【RackEmptyInstock】绑定料箱到料架");
|
||
foreach (WmsCarryH membercarry in membercarrys)
|
||
{
|
||
// 绑定料箱到料架
|
||
CarryBindInput _carryBindInput = new();
|
||
_carryBindInput.carry_id = wmsCarryH.id;
|
||
_carryBindInput.carry_code = wmsCarryH.carry_code;
|
||
_carryBindInput.membercarry_id = membercarry.id;
|
||
_carryBindInput.membercarry_code = membercarry.carry_code;
|
||
_carryBindInput.carrystd_id = wmsCarryH.carrystd_id;
|
||
var resCarrybind = await _wmsCarryBindService.CarryBind(_carryBindInput);
|
||
if (resCarrybind.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
throw new AppFriendlyException($"绑定料箱到料架失败 载具 {input.carry_code}", 500);
|
||
}
|
||
}
|
||
|
||
Logger.LogWarning($"【RackEmptyInstock】开始生成预任务");
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new ();
|
||
commonCreatePretaskInput.startlocation_id = startlocation.id;
|
||
commonCreatePretaskInput.endlocation_id = endlocation.id;
|
||
commonCreatePretaskInput.carry_id = wmsCarryH.id;
|
||
commonCreatePretaskInput.carry_code = input.carry_code;
|
||
commonCreatePretaskInput.task_type = "";
|
||
commonCreatePretaskInput.biz_type = "FloorCallMaterial";
|
||
|
||
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
|
||
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($"【RackEmptyInstock】生成预任务失败 载具 {input.carry_code}");
|
||
throw new AppFriendlyException($"生成预任务失败 载具 {input.carry_code}", 500);
|
||
}
|
||
Logger.LogWarning($"【RackEmptyInstock】生成预任务成功");
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【RackEmptyInstock】" + ex.Message);
|
||
Logger.LogError("【RackEmptyInstock】" + ex.StackTrace);
|
||
await _db.Ado.RollbackTranAsync();
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
|
||
}
|
||
}
|
||
}
|