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

2002 lines
105 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;
using System.Collections;
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 JNPF.Systems.Interfaces.Permission;
using Senparc.Weixin.Work.AdvancedAPIs.OaDataOpen;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1.X509;
using Tnb.ProductionMgr.Entities;
using Tnb.BasicData;
using Tnb.ProductionMgr.Entities.Entity;
using Tnb.WarehouseMgr.Entities.Dto.Outputs;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 原材料转库单
/// </summary>
[OverideVisualDev(ModuleConsts.MODULE_WMSMATERIALTRANSFER_ID)]
[ServiceModule(BizTypeId)]
public class WmsMaterialTransferService : BaseWareHouseService
{
private const string BizTypeId = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
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;
private readonly IWmsCarryUnbindService _wmsCarryUnbindService;
private readonly IOrganizeService _organizeService;
private readonly IWmsCarryQueryService _wmsCarryQueryService;
public static SemaphoreSlim s_taskDistributeToZCC = new(1);
public static SemaphoreSlim s_taskDistributeYCL2ZCC = new(1);
public static SemaphoreSlim s_taskDistributeZCCToYCL = new(1);
public WmsMaterialTransferService(
ISqlSugarRepository<WmsCarryH> repository,
IRunService runService,
IVisualDevService visualDevService,
IWareHouseService wareHouseService,
IUserManager userManager,
IBillRullService billRullService,
IEventPublisher eventPublisher,
IWmsCarryUnbindService wmsCarryUnbindService,
IOrganizeService organizeService,
IWmsCarryQueryService wmsCarryQueryService,
IWmsCarryBindService wmsCarryBindService)
{
_db = repository.AsSugarClient();
_runService = runService;
_visualDevService = visualDevService;
_wareHouseService = wareHouseService;
_userManager = userManager;
_billRullService = billRullService;
_wmsCarryBindService = wmsCarryBindService;
_wmsCarryUnbindService = wmsCarryUnbindService;
_organizeService = organizeService;
_wmsCarryQueryService = wmsCarryQueryService;
OverideFuncs.GetListAsync = GetList;
}
[NonAction]
private async Task<dynamic> GetList(VisualDevModelListQueryInput input)
{
try
{
JObject queryJson = null;
if (!string.IsNullOrEmpty(input.queryJson))
{
queryJson = JObject.Parse(input.queryJson);
}
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)
.LeftJoin<DictionaryDataEntity>((a, b, c, d, e, f) => a.type == f.EnCode)
// 只显示未完成的单据
.Where(a => a.status != "25065149810453")
.WhereIF(queryJson != null && queryJson["type"] != null, a => a.type == queryJson["type"].ToString())
.WhereIF(queryJson != null && queryJson["bill_code"] != null, a => a.bill_code.Contains(queryJson["bill_code"].ToString()))
.Select((a, b, c, d, e, f) => 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 = f.FullName,
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,
})
.OrderBy("a.bill_code desc")
.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["tablefield120"] = 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 && 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> MaterialInventoryHCC(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_HCC_ID,
material_id = input.material_id,
code_batch = input.code_batch,
Size = input.palletCount
};
List<WmsCarryH> items = await _wareHouseService.OutStockStrategyHCC(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<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);
await s_taskExecuteSemaphore.WaitAsync();
if (wmsMaterialTransferD.yxfqty >= wmsMaterialTransferD.qty)
{
throw new AppFriendlyException("已下发数量已达到转库数量", 500);
}
await _db.Ado.BeginTranAsync();
//入库取终点 //出库起点
OutStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_YCL_ID, material_id = wmsMaterialTransferD.material_id, code_batch = input.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 && 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);
}
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)
{
BasLocation startLocation = await _db.Queryable<BasLocation>().Where(r => r.id == wmsCarryH.location_id).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.source_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<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, "成功");
}
/// <summary>
/// PDA操作(8线到中储仓)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Entities.Dto.Outputs.Result> DistributeYCLToZCC(MaterialTransferDistributeYCL2ZCCInput input)
{
try
{
if (string.IsNullOrEmpty(input.source_id))
{
throw new AppFriendlyException("来源单据id不可为空", 500);
}
if (input.details.Count == 0)
{
throw new AppFriendlyException("请先扫描料箱", 500);
}
input.details.ForEach(r =>
{
if (string.IsNullOrEmpty(r.carry_code))
{
throw new AppFriendlyException($"料箱编码不能为空", 500);
}
if (r.qty <= 0)
{
throw new AppFriendlyException($"料箱{r.carry_code}的数量必须大于0", 500);
}
});
await s_taskDistributeYCL2ZCC.WaitAsync();
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_rk >= wmsMaterialTransferD.qty)
{
throw new AppFriendlyException("已下发数量已达到转库数量", 500);
}
decimal qty = input.details.Sum(r => r.qty);
if (qty > wmsMaterialTransferD.qty - wmsMaterialTransferD.yxfqty_rk)
{
throw new AppFriendlyException($"下发数量{qty}已超过可下发数量{wmsMaterialTransferD.qty - wmsMaterialTransferD.yxfqty_rk}", 500);
}
await _db.Ado.BeginTranAsync();
//入库取终点 //出库起点
InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_ZC_ID, Size = input.details.Count };
List<BasLocation> endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
if (endLocations.Count == 0)
{
Logger.LogWarning("没有可用的入库库位");
throw new AppFriendlyException("没有可用的入库库位", 500);
}
if (input.details.Count > endLocations.Count)
{
throw new AppFriendlyException("可用的入库库位数量少于扫描的料箱数量", 500);
}
int index = 0;
List<WmsCarryH> wmsCarryHs = await _db.Queryable<WmsCarryH>().Where(r => input.details.Select(x => x.carry_code).Contains(r.carry_code)).ToListAsync();
foreach (var wmsCarryH in input.details)
{
BasLocation startLocation = await _db.Queryable<BasLocation>().Where(r => r.id == WmsWareHouseConst.ZZCSSX011008).FirstAsync();
BasLocation endLocation = endLocations[index];
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
commonCreatePretaskInput.startlocation_id = startLocation.id;
commonCreatePretaskInput.endlocation_id = endLocation.id;
commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID;
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
commonCreatePretaskInput.source_id = input.source_id;
commonCreatePretaskInput.carry_id = wmsCarryHs[index].id;
commonCreatePretaskInput.carry_code = wmsCarryHs[index].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);
}
CarryMaterialBindInput carryMaterialBindInput = new CarryMaterialBindInput();
carryMaterialBindInput.carrycode = wmsCarryHs[index].carry_code;
carryMaterialBindInput.create_id = input.create_id;
List<CarryMaterialDetail> carryMaterialDetails = new List<CarryMaterialDetail>();
CarryMaterialDetail carryMaterialDetail = new CarryMaterialDetail();
carryMaterialDetail.material_id = wmsMaterialTransferD.material_id;
carryMaterialDetail.material_code = wmsMaterialTransferD.material_code;
carryMaterialDetail.codeqty = wmsCarryH.qty.ToString();
carryMaterialDetail.code_batch = wmsMaterialTransferD.code_batch;
carryMaterialDetail.barcode = wmsCarryHs[index].carry_code;
carryMaterialDetail.unit_id = wmsMaterialTransferD.unit_id;
carryMaterialDetails.Add(carryMaterialDetail);
carryMaterialBindInput.details = carryMaterialDetails;
await _wmsCarryBindService.CarryMaterialBind(carryMaterialBindInput, _db);
await _db.Updateable<WmsCarryH>().SetColumns(r => r.carry_status == "1").Where(r => r.id == wmsCarryHs[index].id).ExecuteCommandAsync();
index++;
}
// 更新子表已下发数量
await _db.Updateable<WmsMaterialTransferD>().SetColumns(r => r.yxfqty_rk == r.yxfqty_rk + qty).Where(r => r.id == input.source_id).ExecuteCommandAsync();
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
await _db.Ado.RollbackTranAsync();
Logger.LogError("【DistributeYCLToZCC】" + ex.Message);
Logger.LogError("【DistributeYCLToZCC】" + ex.StackTrace);
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
}
finally
{
_ = s_taskDistributeYCL2ZCC.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<Entities.Dto.Outputs.Result> DistributeHCC(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);
}
OrganizeEntity organizeEntity = _db.Queryable<OrganizeEntity>().Where(r => r.EnCode == wmsMaterialTransferD.station_code).First();
if (organizeEntity == null)
{
Logger.LogWarning($"【DistributeHCC】不存在工位code为{wmsMaterialTransferD.station_code}的工位!");
throw new AppFriendlyException($"不存在工位code为{wmsMaterialTransferD.station_code}的工位!", 500);
}
// 获取产线
OrganizeEntity organizeEntityCX = _db.Queryable<OrganizeEntity>().Where(r => r.Id == organizeEntity.ParentId).First();
if (organizeEntityCX == null)
{
Logger.LogWarning($"【DistributeHCC】基础资料错误工位{organizeEntity.EnCode}的上级产线不存在,请检查!");
throw new AppFriendlyException($"【DistributeHCC】基础资料错误工位{organizeEntity.EnCode}的上级产线不存在,请检查!", 500);
}
if (organizeEntityCX.Category != "workline")
{
Logger.LogWarning($"【DistributeHCC】基础资料错误工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}不属于产线类型,请检查!");
throw new AppFriendlyException($"【DistributeHCC】基础资料错误工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}不属于产线类型,请检查!", 500);
}
// 获取任务单
List<PrdMoTask> organizeEntityCXs = _db.Queryable<PrdMoTask>().Where(r => r.workline_id == organizeEntityCX.Id && r.mo_task_status == DictConst.InProgressEnCode && !string.IsNullOrEmpty(r.parent_id)).ToList();
if (organizeEntityCXs.Count > 1)
{
Logger.LogWarning($"【DistributeHCC】工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单不唯一(需要有parentid),请检查!");
throw new AppFriendlyException($"【DistributeHCC】工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单不唯一,请检查!", 500);
}
if (organizeEntityCXs.Count == 0)
{
Logger.LogWarning($"【DistributeHCC】未找到工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单(需要有parentid请检查");
throw new AppFriendlyException($"【DistributeHCC】未找到工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单),请检查!", 500);
}
PrdMoTask prdMoTask = organizeEntityCXs.First();
await s_taskExecuteSemaphore.WaitAsync();
await _db.Ado.BeginTranAsync();
//入库取终点 //出库起点
OutStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_HCC_ID, material_id = wmsMaterialTransferD.material_id, code_batch = input.code_batch, Size = input.palletCount };
List<WmsCarryH> items = await _wareHouseService.OutStockStrategyHCC(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 && 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);
}
if (wmsMaterialTransfer.warehouse_instock != WmsWareHouseConst.WAREHOUSE_ZZXBK_ID)
{
throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}入库仓库不是线边库,请检查!", HttpStatusCode.InternalServerError);
}
foreach (var wmsCarryH in items)
{
BasLocation startLocation = await _db.Queryable<BasLocation>().Where(r => r.id == wmsCarryH.location_id).FirstAsync();
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
commonCreatePretaskInput.startlocation_id = startLocation.id;
commonCreatePretaskInput.endlocation_id = input.endlocation_id;
commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID;
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
// 转库单id
commonCreatePretaskInput.source_id = input.source_id;
// 任务单code
commonCreatePretaskInput.require_id = prdMoTask.id;
commonCreatePretaskInput.require_code = prdMoTask.mo_task_code;
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, "成功");
}
/// <summary>
/// 获取物料库存(通用)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="AppFriendlyException"></exception>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Tnb.WarehouseMgr.Entities.Dto.Outputs.Result> MaterialInventoryCommon(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);
//}
if (string.IsNullOrEmpty(input.warehouse_id))
{
throw new AppFriendlyException("仓库不可为空", 500);
}
//入库取终点 //出库起点
OutStockStrategyQuery inStockStrategyInput = new()
{
warehouse_id = input.warehouse_id,
material_id = input.material_id,
code_batch = input.code_batch,
Size = input.palletCount
};
List<WmsCarryH> items = await _wareHouseService.OutStockStrategy(inStockStrategyInput);
if (string.IsNullOrEmpty(input.code_batch))
input.code_batch = null;
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<Entities.Dto.Outputs.Result> DistributeBCK(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);
//}
if (string.IsNullOrEmpty(input.code_batch))
input.code_batch = null;
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);
}
if (wmsMaterialTransfer.warehouse_outstock != WmsWareHouseConst.WAREHOUSE_BCK_ID)
{
throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}入库仓库不是四楼包材库,请检查!", HttpStatusCode.InternalServerError);
}
if (wmsMaterialTransfer.warehouse_instock != WmsWareHouseConst.WAREHOUSE_F2BCQ_ID)
{
throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}入库仓库不是二楼包材库,请检查!", HttpStatusCode.InternalServerError);
}
await s_taskExecuteSemaphore.WaitAsync();
await _db.Ado.BeginTranAsync();
//入库取终点 //出库起点
OutStockStrategyQuery outStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID, material_id = wmsMaterialTransferD.material_id, code_batch = input.code_batch, Size = input.palletCount };
List<WmsCarryH> items = await _wareHouseService.OutStockStrategy(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 == wmsMaterialTransferD.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.InStockStrategyBCK(inStockStrategyInput);
if (endlocations.Count < 1)
{
throw new AppFriendlyException($@"没有可以入库的库位", 500);
}
if (items.Count == 0)
{
throw new AppFriendlyException($@"没有可以出库的载具", 500);
}
int index = 0;
foreach (var wmsCarryH in items)
{
BasLocation startLocation = await _db.Queryable<BasLocation>().Where(r => r.id == wmsCarryH.location_id).FirstAsync();
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
commonCreatePretaskInput.startlocation_id = startLocation.id;
commonCreatePretaskInput.endlocation_id = endlocations[index].id;
commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID;
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
// 转库单id
commonCreatePretaskInput.source_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);
}
index++;
}
// 更新子表已下发数量
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));
}
try
{
List<WmsCarryCode> wmsCarryCodes = await _db.Queryable<WmsCarryCode>().Where(r => r.carry_id == input.carryIds[0]).ToListAsync();
//if (wmsCarryCodes.Count == 0)
//{
// Logger.LogWarning($"【WmsMaterialTransferService ModifyAsync】载具{input.carryIds[0]}没有绑定物料条码");
// return;
//}
await _db.Ado.BeginTranAsync();
WmsMaterialTransferD wmsMaterialTransferd = await _db.Queryable<WmsMaterialTransferD>().Where(r => r.id == input.source_id).SingleAsync();
WmsMaterialTransfer wmsMaterialTransfer = await _db.Queryable<WmsMaterialTransfer>().SingleAsync(x => x.id == wmsMaterialTransferd.bill_id);
bool isOk = false;
#region
// 8线到中储仓入库或三工位退回原材料操作时回写数量
if ((wmsMaterialTransfer.warehouse_outstock == WmsWareHouseConst.WAREHOUSE_YCL_ID && wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_ZC_ID)
|| (wmsMaterialTransfer.warehouse_outstock == WmsWareHouseConst.WAREHOUSE_ZC_ID && wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_YCL_ID)
&& input.wmsDistaskH.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID)
{
// 更新已转数量(入库)
isOk = await _db.Updateable<WmsMaterialTransferD>().SetColumns(it => new WmsMaterialTransferD { yzqty_rk = it.yzqty_rk + wmsCarryCodes.Sum(r => r.codeqty) })
.Where(it => it.id == input.source_id).ExecuteCommandHasChangeAsync();
}
else
{
// 中储仓到8线后自动解绑物料
if ((wmsMaterialTransfer.warehouse_outstock == WmsWareHouseConst.WAREHOUSE_ZC_ID && wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_YCL_ID)
&& input.wmsDistaskH.task_type == WmsWareHouseConst.WMS_PRETASK_TRANSFER_TYPE_ID)
{
CarryCodeUnbindInput carryCodeUnbindInput = new();
carryCodeUnbindInput.carry_id = input.wmsDistaskH.carry_id;
var resCarryUnbind = await _wmsCarryUnbindService.CarryCodeUnbind(carryCodeUnbindInput, _db);
if (resCarryUnbind.code != JNPF.Common.Enums.HttpStatusCode.OK)
{
throw new AppFriendlyException($"载具{input.wmsDistaskH.carry_code}解绑条码", 500);
}
}
// 更新已转数量
isOk = await _db.Updateable<WmsMaterialTransferD>().SetColumns(it => new WmsMaterialTransferD { yzqty = it.yzqty + wmsCarryCodes.Sum(r => r.codeqty) })
.Where(it => it.id == input.source_id).ExecuteCommandHasChangeAsync();
}
#endregion
#region
bool isOk2 = true;
// 原材料到中储仓入库操作时回写状态
if ((wmsMaterialTransfer.warehouse_outstock == WmsWareHouseConst.WAREHOUSE_YCL_ID && wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_ZC_ID)
|| (wmsMaterialTransfer.warehouse_outstock == WmsWareHouseConst.WAREHOUSE_ZC_ID && wmsMaterialTransfer.warehouse_instock == WmsWareHouseConst.WAREHOUSE_YCL_ID))
{
if (input.wmsDistaskH.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID)
{
List<WmsMaterialTransferD> wmsMaterialTransferDs = _db.Queryable<WmsMaterialTransferD>()
.Where(a => a.bill_id == wmsMaterialTransferd.bill_id && a.yxfqty_rk < a.yzqty_rk).ToList();
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();
}
}
}
else
{
List<WmsMaterialTransferD> wmsMaterialTransferDs = _db.Queryable<WmsMaterialTransferD>()
.Where(a => a.bill_id == wmsMaterialTransferd.bill_id && a.yzqty < a.qty).ToList();
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();
}
}
#endregion
// require_code是任务单
//string mo_task_code = input.require_code;
if (!isOk || !isOk2)
{
throw Oops.Oh(ErrorCode.COM1001);
}
await _db.Ado.CommitTranAsync();
if (input.area_code == "E")
await sign(input);
// 其它入库
if (input.wmsDistaskH.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID)
{
Logger.LogInformation("【WmsMaterialTransferService ModifyAsync】同步其它入库单到erp...");
}
// 其它出库
else
{
Logger.LogInformation("【WmsMaterialTransferService ModifyAsync】同步其它出库单到erp...");
List<WmsMaterialTransferD> dList = await _db.Queryable<WmsMaterialTransferD>().Where(x => x.bill_id == wmsMaterialTransferd.bill_id).OrderBy(x => x.id).ToListAsync();
DictionaryDataEntity unitData = await _db.Queryable<DictionaryTypeEntity>()
.LeftJoin<DictionaryDataEntity>((x, y) => x.Id == y.DictionaryTypeId)
.Where((x, y) => x.EnCode == DictConst.MeasurementUnit && y.EnCode == wmsMaterialTransferd.unit_id)
.Select((x, y) => y)
.FirstAsync();
List<string> ids = new List<string>();
ids.Add(wmsMaterialTransfer.create_id);
ids.Add(WmsWareHouseConst.AdministratorOrgId);
ids.Add(wmsMaterialTransfer.warehouse_outstock);
ids.Add(wmsMaterialTransfer.warehouse_instock);
ids.Add(wmsMaterialTransferd.material_id);
if (unitData != null)
{
ids.Add(unitData.Id);
}
List<ErpExtendField> erpExtendFields = await _db.Queryable<ErpExtendField>().Where(x => ids.Contains(x.table_id)).ToListAsync();
ErpExtendField erpOrg = erpExtendFields.Find(x => x.table_id == (wmsMaterialTransfer.org_id ?? WmsWareHouseConst.AdministratorOrgId));
string erpCreateId = erpExtendFields.Find(x => x.table_id == wmsMaterialTransfer.create_id)?.user_id ?? "";
List<Dictionary<string, object>> requestData = new List<Dictionary<string, object>>();
Dictionary<string, object> erpRequestData = new Dictionary<string, object>();
string nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
erpRequestData.Add("billmaker", erpCreateId);
erpRequestData.Add("cdptid", "1001A1100000000JRLI1");// 先写死
erpRequestData.Add("cdptvid", "0001A11000000007GGO8");// 先写死
erpRequestData.Add("corpoid", erpOrg.corpoid);
erpRequestData.Add("corpvid", erpOrg.corpoid);
erpRequestData.Add("cothercalbodyoid", erpOrg.pk_org);
erpRequestData.Add("cotherwhid", erpExtendFields.Find(x => x.table_id == wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? "");
erpRequestData.Add("creationtime", nowStr);
erpRequestData.Add("creator", erpCreateId);
erpRequestData.Add("ctrantypeid", "0001H11000000000D31W");
erpRequestData.Add("cwarehouseid", erpExtendFields.Find(x => x.table_id == wmsMaterialTransfer.warehouse_outstock)?.cotherwhid ?? "");
erpRequestData.Add("dbilldate", nowStr);
erpRequestData.Add("dmakedate", nowStr);
erpRequestData.Add("ntotalnum", wmsCarryCodes.Sum(r => r.codeqty));
erpRequestData.Add("pk_group", erpOrg.pk_group);
erpRequestData.Add("pk_org", erpOrg.pk_org);
erpRequestData.Add("pk_org_v", erpOrg.pk_org_v);
erpRequestData.Add("vbillcode", wmsMaterialTransfer.bill_code);
erpRequestData.Add("vtrantypecode", "4I-01");//其他出库 先写死
List<Dictionary<string, object>> erpRequestDataDetails = new List<Dictionary<string, object>>();
erpRequestDataDetails.Add(new Dictionary<string, object>()
{
["cbodytranstypecode"] = "4I-01",
["cbodywarehouseid"] = erpExtendFields.Find(x => x.table_id == wmsMaterialTransfer.warehouse_outstock)?.cotherwhid ?? "",
["cmaterialoid"] = erpExtendFields.Find(x => x.table_id == wmsMaterialTransferd.material_id)?.cmaterialoid ?? "",
["cmaterialvid"] = erpExtendFields.Find(x => x.table_id == wmsMaterialTransferd.material_id)?.cmaterialvid ?? "",
["corpoid"] = erpOrg.corpoid,
["corpvid"] = erpOrg.corpvid,
["crowno"] = wmsMaterialTransferd.lineno,
["csourcebillbid"] = wmsMaterialTransferd.erp_line_pk,
["csourcebillhid"] = wmsMaterialTransfer.erp_pk,
["cunitid"] = erpExtendFields.Find(x => x.table_id == unitData?.Id)?.cunitid ?? "",
["cvendorid"] = "",
["cvendorvid"] = "",
["dbizdate"] = nowStr,
["nnum"] = wmsCarryCodes.Sum(r => r.codeqty),
["nshouldnum"] = wmsMaterialTransferd.qty,
["pk_group"] = erpOrg.pk_group,
["pk_org"] = erpOrg.pk_org,
["pk_org_v"] = erpOrg.pk_org_v,
["vbatchcode"] = wmsMaterialTransferd.code_batch,
});
erpRequestData.Add("dtls", erpRequestDataDetails);
requestData.Add(erpRequestData);
ThirdWebapiRecord thirdWebapiRecord = new ThirdWebapiRecord();
thirdWebapiRecord.id = SnowflakeIdHelper.NextId();
thirdWebapiRecord.third_name = WmsWareHouseConst.BIP;
thirdWebapiRecord.name = "其它出库";
thirdWebapiRecord.method = "POST";
thirdWebapiRecord.url = WmsWareHouseConst.BIP_DOMAIN + "uapws/rest/generalout/save";
thirdWebapiRecord.request_data = JsonConvert.SerializeObject(requestData);
thirdWebapiRecord.create_time = DateTime.Now;
await _db.Insertable(thirdWebapiRecord).ExecuteCommandAsync();
Logger.LogInformation("【WmsMaterialTransferService ModifyAsync】同步其它出库单到erp成功");
}
}
catch(Exception ex)
{
Logger.LogError("【WmsMaterialTransferService ModifyAsync】" + ex.Message);
Logger.LogError("【WmsMaterialTransferService 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<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();
int count = wmsMaterialTransferds.Where(r => string.IsNullOrEmpty(r.station_code)).Count();
if (count > 0)
{
Logger.LogWarning($@"转库单{wmsMaterialTransfer.bill_code}表体存在未填写工位的明细!");
throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}表体存在未填写工位的明细!", 500);
}
var wmsMaterialTransferdsDistinct = wmsMaterialTransferds.Select(r => new
{
material_id = r.material_id,
code_batch = r.code_batch,
}).Distinct();
if (wmsMaterialTransferdsDistinct.Count() < wmsMaterialTransferds.Count)
{
Logger.LogWarning($@"转库单{wmsMaterialTransfer.bill_code}表体存在物料和批号重复的明细!");
throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}表体存在物料和批号重复的明细!", 500);
}
// 转库单载具子表
List<WmsMaterialTransferCarry> wmsMaterialTransferCarrys = new List<WmsMaterialTransferCarry>();
foreach (WmsMaterialTransferD wmsMaterialTransferD in wmsMaterialTransferds)
{
// 需要转库数量
decimal? needOut = wmsMaterialTransferD.qty;
//出库取起点,获取所有符合输入的载具规格的载具
OutStockStrategyZCC2Floor2Query OutStockStrategyInput = new()
{
warehouse_id = "2",
material_id = wmsMaterialTransferD.material_id,
code_batch = wmsMaterialTransferD.code_batch,
needOut = needOut,
material_code = wmsMaterialTransferD.material_code,
endlocations = new string[2] { WmsWareHouseConst.ZZCSSX121009, WmsWareHouseConst.ZZCSSX121010 }
};
List<Tuple<WmsCarryH, decimal, BasLocation>>? carrys = await _wareHouseService.OutStockStrategyZCC2Floor2(OutStockStrategyInput);
foreach (var item in carrys)
{
WmsCarryH wmsCarryH = item.Item1;
decimal codeqty = item.Item2;
BasLocation endlocation_ssx = item.Item3;
// 转库单载具子表
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 = codeqty;
wmsMaterialTransferCarrys.Add(wmsMaterialTransferCarry);
}
}
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.WMS_PRETASK_OUTSTOCK_TYPE_ID;
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
commonCreatePretaskInput.source_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<Entities.Dto.Outputs.Result> DistributeZCCToYCL(MaterialTransferDistributeToZCCInput input)
{
s_taskDistributeZCCToYCL.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();
var wmsMaterialTransferdsDistinct = wmsMaterialTransferds.Select(r => new
{
material_id = r.material_id,
code_batch = r.code_batch,
}).Distinct();
if (wmsMaterialTransferdsDistinct.Count() < wmsMaterialTransferds.Count)
{
Logger.LogWarning($@"转库单{wmsMaterialTransfer.bill_code}表体存在物料和批号重复的明细!");
throw new AppFriendlyException($@"转库单{wmsMaterialTransfer.bill_code}表体存在物料和批号重复的明细!", 500);
}
// 转库单载具子表
List<WmsMaterialTransferCarry> wmsMaterialTransferCarrys = new List<WmsMaterialTransferCarry>();
foreach (WmsMaterialTransferD wmsMaterialTransferD in wmsMaterialTransferds)
{
// 需要转库数量
decimal? needOut = wmsMaterialTransferD.qty;
//出库取起点,获取所有符合输入的载具规格的载具
OutStockStrategyZCC2Floor2Query OutStockStrategyInput = new()
{
warehouse_id = "2",
material_id = wmsMaterialTransferD.material_id,
code_batch = wmsMaterialTransferD.code_batch,
needOut = needOut,
material_code = wmsMaterialTransferD.material_code,
endlocations = new string[] {WmsWareHouseConst.ZZCSSX021007 }
};
List<Tuple<WmsCarryH, decimal, BasLocation>>? carrys = await _wareHouseService.OutStockStrategyZCC2Floor2(OutStockStrategyInput);
foreach (var item in carrys)
{
WmsCarryH wmsCarryH = item.Item1;
decimal codeqty = item.Item2;
BasLocation endlocation_ssx = item.Item3;
// 转库单载具子表
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 = codeqty;
wmsMaterialTransferCarrys.Add(wmsMaterialTransferCarry);
}
}
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($"【DistributeZCCToYCL】更新转库单{wmsMaterialTransfer.bill_code}主表的数据");
await _db.Insertable(wmsMaterialTransferCarrys).ExecuteCommandAsync();
Logger.LogInformation($"【DistributeZCCToYCL】插入转库单{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.WMS_PRETASK_OUTSTOCK_TYPE_ID;
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
commonCreatePretaskInput.source_id = wmsMaterialTransferCarry.mat_bill_id;
commonCreatePretaskInput.isExcuteMission = false;
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
{
Logger.LogInformation($"【DistributeZCCToYCL生成预任务失败 载具 {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("【DistributeZCCToYCL】" + ex.Message);
Logger.LogError("【DistributeZCCToYCL】" + ex.StackTrace);
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
}
finally
{
s_taskDistributeZCCToYCL.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<Entities.Dto.Outputs.Result> DistributeSCWToYCL(MaterialTransferDistributeSCWToYCLInput input)
{
try
{
if (string.IsNullOrEmpty(input.source_id))
{
throw new AppFriendlyException("来源单据id不可为空", 500);
}
if (string.IsNullOrEmpty(input.carry_code))
{
throw new AppFriendlyException("载具不可为空", 500);
}
if (input.qty <= 0)
{
throw new AppFriendlyException("数量必须大于0", 500);
}
WmsMaterialTransferD wmsMaterialTransferD = await _db.Queryable<WmsMaterialTransferD>().FirstAsync(it => it.id == input.source_id);
if (wmsMaterialTransferD == null)
{
Logger.LogWarning($"不存在id为{input.source_id}的转库单明细!");
throw new AppFriendlyException($"不存在id为{input.source_id}的转库单明细!", 500);
}
if (wmsMaterialTransferD.yxfqty_rk >= wmsMaterialTransferD.yzqty)
{
throw new AppFriendlyException("已下发数量已达到中储仓的转出数量", 500);
}
WmsCarryH wmsCarryH = await _db.Queryable<WmsCarryH>().FirstAsync(it => it.carry_code == input.carry_code);
if (wmsCarryH == null)
{
Logger.LogWarning($"不存在编码为{input.carry_code}的载具!");
throw new AppFriendlyException($"不存在编码为{input.carry_code}的载具!", 500);
}
if (wmsCarryH.carry_status != "0")
{
Logger.LogWarning($"载具{input.carry_code}状态为占用!");
throw new AppFriendlyException($"载具{input.carry_code}状态为占用!", 500);
}
if (wmsCarryH.is_lock == 1)
{
Logger.LogWarning($"载具{input.carry_code}已锁定!");
throw new AppFriendlyException($"载具{input.carry_code}已锁定!", 500);
}
if (string.IsNullOrEmpty(wmsCarryH.location_id))
{
Logger.LogWarning($"载具{input.carry_code}的库位为空!");
throw new AppFriendlyException($"载具{input.carry_code}的库位为空!", 500);
}
if (!_wareHouseService.GetFloor1WXSGWOutstockLocation().Contains(wmsCarryH.location_id))
{
Logger.LogWarning($"载具{input.carry_code}当前所在库位不是三工位!");
throw new AppFriendlyException($"载具{input.carry_code}当前所在库位不是三工位!", 500);
}
await s_taskExecuteSemaphore.WaitAsync();
await _db.Ado.BeginTranAsync();
InStockStrategyQuery inStockStrategyInput = new()
{
warehouse_id = WmsWareHouseConst.WAREHOUSE_YCL_ID,
Size = 1
};
List<BasLocation> endlocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
if (endlocations.Count < 1)
{
throw new AppFriendlyException($@"没有可以入库的库位", 500);
}
BasLocation startLocation = await _db.Queryable<BasLocation>().Where(r => r.id == wmsCarryH.location_id).FirstAsync();
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
commonCreatePretaskInput.startlocation_id = startLocation.id;
commonCreatePretaskInput.endlocation_id = endlocations[0].id;
commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID;
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSMATERIALTRANSFER_ID;
// 转库单id
commonCreatePretaskInput.source_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);
}
CarryMaterialBindInput carryMaterialBindInput = new CarryMaterialBindInput();
carryMaterialBindInput.carrycode = wmsCarryH.carry_code;
carryMaterialBindInput.create_id = input.create_id;
List<CarryMaterialDetail> carryMaterialDetails = new List<CarryMaterialDetail>();
CarryMaterialDetail carryMaterialDetail = new CarryMaterialDetail();
carryMaterialDetail.material_id = wmsMaterialTransferD.material_id;
carryMaterialDetail.material_code = wmsMaterialTransferD.material_code;
carryMaterialDetail.codeqty = input.qty.ToString();
carryMaterialDetail.code_batch = wmsMaterialTransferD.code_batch;
carryMaterialDetail.barcode = wmsCarryH.carry_code;
carryMaterialDetail.unit_id = wmsMaterialTransferD.unit_id;
carryMaterialDetails.Add(carryMaterialDetail);
carryMaterialBindInput.details = carryMaterialDetails;
await _wmsCarryBindService.CarryMaterialBind(carryMaterialBindInput, _db);
await _db.Updateable<WmsCarryH>().SetColumns(r => r.carry_status == "1").Where(r => r.id == wmsCarryH.id).ExecuteCommandAsync();
// 更新子表已下发数量
await _db.Updateable<WmsMaterialTransferD>().SetColumns(r => r.yxfqty_rk == r.yxfqty_rk + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync();
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
await _db.Ado.RollbackTranAsync();
Logger.LogError("【DistributeSCWToYCL】" + ex.Message);
Logger.LogError("【DistributeSCWToYCL】" + ex.StackTrace);
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
}
finally
{
_ = s_taskExecuteSemaphore.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<Entities.Dto.Outputs.Result> CallRackToProductionLine(MaterialTransferCallRackToProductionLineInput input)
{
try
{
OrganizeEntity organizeEntity = _db.Queryable<OrganizeEntity>().Where(r => r.Id == input.workstation_id).First();
if (organizeEntity == null)
{
Logger.LogWarning($"【CallRackToProductionLine】不存在工位id为{input.workstation_id}的工位!");
throw new AppFriendlyException($"不存在工位id为{input.workstation_id}的工位!", 500);
}
//WmsCarryH wmsCarryH = _db.Queryable<WmsCarryH>().Where(r => r.work_station == organizeEntity.EnCode).First();
//if (wmsCarryH == null)
//{
// Logger.LogWarning($"【CallRackToProductionLine】不存在工位为{organizeEntity.EnCode}的料架号!");
// throw new AppFriendlyException($"不存在工位为{organizeEntity.EnCode}的料架号!", 500);
//}
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($"【CallRackToProductionLine】不存在料架号为{input.carry_code}的料架!", 500);
}
// 获取产线
OrganizeEntity organizeEntityCX = _db.Queryable<OrganizeEntity>().Where(r => r.Id == organizeEntity.ParentId).First();
if (organizeEntityCX == null)
{
Logger.LogWarning($"【CallRackToProductionLine】基础资料错误工位{organizeEntity.EnCode}的上级产线不存在,请检查!");
throw new AppFriendlyException($"【CallRackToProductionLine】基础资料错误工位{organizeEntity.EnCode}的上级产线不存在,请检查!", 500);
}
if (organizeEntityCX.Category != "workline")
{
Logger.LogWarning($"【CallRackToProductionLine】基础资料错误工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}不属于产线类型,请检查!");
throw new AppFriendlyException($"【CallRackToProductionLine】基础资料错误工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}不属于产线类型,请检查!", 500);
}
// 获取任务单
List<PrdMoTask> organizeEntityCXs = _db.Queryable<PrdMoTask>().Where(r => r.workline_id == organizeEntityCX.Id && r.mo_task_status == DictConst.InProgressEnCode && !string.IsNullOrEmpty(r.parent_id)).ToList();
if (organizeEntityCXs.Count > 1)
{
Logger.LogWarning($"【CallRackToProductionLine】工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单不唯一(需要有parentid),请检查!");
throw new AppFriendlyException($"【CallRackToProductionLine】工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单不唯一,请检查!", 500);
}
if (organizeEntityCXs.Count == 0)
{
Logger.LogWarning($"【CallRackToProductionLine】未找到工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单(需要有parentid),请检查!");
throw new AppFriendlyException($"【CallRackToProductionLine】未找到工位{organizeEntity.EnCode}的上级{organizeEntityCX.EnCode}对应的进行中的任务单,请检查!", 500);
}
PrdMoTask prdMoTask = organizeEntityCXs.First();
//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);
//}
if (string.IsNullOrEmpty(input.endlocation_id))
{
Logger.LogWarning($"【CallRackToProductionLine】终点库位不能为空{input.endlocation_id}");
throw new AppFriendlyException($"终点库位不能为空!{input.endlocation_id}", 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 && r.status != WmsWareHouseConst.PRETASK_BILL_STATUS_CANCEL_ID).First();
if (wmsPretaskH != null)
{
Logger.LogWarning($"【CallRackToProductionLine】此料架{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}");
throw new AppFriendlyException($"此料架{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}", 500);
}
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
commonCreatePretaskInput.startlocation_id = wmsCarryH.location_id;
commonCreatePretaskInput.endlocation_id = input.endlocation_id;
commonCreatePretaskInput.carry_id = wmsCarryH.id;
commonCreatePretaskInput.carry_code = wmsCarryH.carry_code;
commonCreatePretaskInput.task_type = "";
commonCreatePretaskInput.biz_type = "FloorCallMaterial";
commonCreatePretaskInput.source_id = "";
commonCreatePretaskInput.require_code = "";
commonCreatePretaskInput.require_id = prdMoTask.id;
commonCreatePretaskInput.require_code = prdMoTask.mo_task_code;
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<Entities.Dto.Outputs.Result> RackAndMatByWorkstation(MaterialTransferGetRackAndMatByWorkStationInput input)
{
try
{
List<WmsCarryH> wmsCarryHs = _db.Queryable<WmsCarryH>().Where(r => r.work_station == input.work_station && r.is_lock == 0 && r.carrystd_id == WmsWareHouseConst.CARRY_LJSTD_ID
&& (r.carry_status == ((int)(EnumCarryStatus.)).ToString() || r.carry_status == ((int)(EnumCarryStatus.)).ToString())).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<Entities.Dto.Outputs.Result> RackInstock(MaterialTransferRackInstockInput input)
{
WmsCarryH wmsCarryH = await _db.Queryable<WmsCarryH>().Where(r => r.carry_code == input.carry_code).FirstAsync();
// 料架到暂存仓
if (wmsCarryH.carrystd_id == "26037267399717")
{
return await RackInstock_到暂存仓(input, wmsCarryH);
}
// 载运小车和载运料架到缓存仓
else if (wmsCarryH.carrystd_id == "26103233723941" || wmsCarryH.carrystd_id == "34995839046677")
{
return await RackInstock_到缓存仓(input, wmsCarryH);
}
else
{
Logger.LogError($"【RackInstock】当前载具的规格id是{wmsCarryH.carrystd_id} 无法处理此类型的载具!");
return await ToApiResult(HttpStatusCode.InternalServerError, $"【RackInstock】当前载具的规格id是{wmsCarryH.carrystd_id} 无法处理此类型的载具!");
}
}
async Task<Entities.Dto.Outputs.Result> RackInstock_到暂存仓(MaterialTransferRackInstockInput input, WmsCarryH wmsCarryH)
{
try
{
List<WmsCarryD> wmsCarryDs = _db.Queryable<WmsCarryD>().Where(r => r.carry_id == wmsCarryH.id).ToList();
if (wmsCarryDs.Count > 0)
{
Logger.LogWarning($"【RackInstock】料架{wmsCarryH.carry_code}下有料箱未解绑!");
throw new AppFriendlyException($"【RackInstock】料架{wmsCarryH.carry_code}下有料箱未解绑!", 500);
}
BasLocation startlocation = _db.Queryable<BasLocation>().Where(r => r.id == input.startlocation_id).First();
if (startlocation == null)
{
Logger.LogWarning($"【RackInstock】不存在id为{input.startlocation_id}的库位!");
throw new AppFriendlyException($"【RackInstock】不存在id为{input.startlocation_id}的库位!", 500);
}
if (string.IsNullOrEmpty(input.carry_code))
{
Logger.LogWarning($"【RackInstock】料架不能为空{input.carry_code}");
throw new AppFriendlyException($"【RackInstock】料架不能为空{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($"【RackInstock】存在非空料箱不能入库{input.carry_code}");
throw new AppFriendlyException($"【RackInstock】存在非空料箱不能入库{input.carry_code}", 500);
}
}
// 找到未占用且未锁定的库位
ISugarQueryable<BasLocation> rackEndLocations =
_db.Queryable<BasLocation>()
.Where(r => r.wh_id == "33780009364245" && r.is_use == "0" && r.is_lock == 0 && r.is_type == "0").OrderBy(a => a.id).Take(1);
if (rackEndLocations.Count() == 0)
{
Logger.LogWarning($"【RackInstock】没有可用的终点库位");
throw new AppFriendlyException($"【RackInstock】没有可用的终点库位", 500);
}
BasLocation endlocation = rackEndLocations.First();
// 重新绑定料箱到料架
// 清空料架
Logger.LogWarning($"【RackInstock】清空料架");
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 _wmsCarryUnbindService.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, _db);
if (resCarrybind.code != JNPF.Common.Enums.HttpStatusCode.OK)
{
throw new AppFriendlyException($"绑定料箱到料架失败 载具 {input.carry_code}", 500);
}
}
Logger.LogWarning($"【RackInstock】开始生成预任务");
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($"【RackInstock】生成预任务失败 载具 {input.carry_code}");
throw new AppFriendlyException($"生成预任务失败 载具 {input.carry_code}", 500);
}
Logger.LogWarning($"【RackEmptyInstock】生成预任务成功");
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
Logger.LogError("【RackInstock】" + ex.Message);
Logger.LogError("【RackInstock】" + ex.StackTrace);
await _db.Ado.RollbackTranAsync();
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
}
return await ToApiResult(HttpStatusCode.OK, "成功");
}
async Task<Entities.Dto.Outputs.Result> RackInstock_到缓存仓(MaterialTransferRackInstockInput input, WmsCarryH wmsCarryH)
{
try
{
BasLocation startlocation = _db.Queryable<BasLocation>().Where(r => r.id == input.startlocation_id).First();
if (startlocation == null)
{
Logger.LogWarning($"【RackInstock】不存在id为{input.startlocation_id}的库位!");
throw new AppFriendlyException($"【RackInstock】不存在id为{input.startlocation_id}的库位!", 500);
}
if (string.IsNullOrEmpty(input.carry_code))
{
Logger.LogWarning($"【RackInstock】料架不能为空{input.carry_code}");
throw new AppFriendlyException($"【RackInstock】料架不能为空{input.carry_code}", 500);
}
// 找到未占用且未锁定的库位
ISugarQueryable<BasLocation> rackEndLocations =
_db.Queryable<BasLocation>()
.Where(r => r.wh_id == "26103348825381" && r.is_use == "0" && r.is_lock == 0 && r.is_type == "0").OrderBy(a => a.id).Take(1);
if (rackEndLocations.Count() == 0)
{
Logger.LogWarning($"【RackInstock】没有可用的终点库位");
throw new AppFriendlyException($"【RackInstock】没有可用的终点库位", 500);
}
BasLocation endlocation = rackEndLocations.First();
await _db.Ado.BeginTranAsync();
Logger.LogWarning($"【RackInstock】开始生成预任务");
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($"【RackInstock】生成预任务失败 载具 {input.carry_code}");
throw new AppFriendlyException($"生成预任务失败 载具 {input.carry_code}", 500);
}
Logger.LogWarning($"【RackInstock】生成预任务成功");
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
Logger.LogError("【RackInstock】" + ex.Message);
Logger.LogError("【RackInstock】" + ex.StackTrace);
await _db.Ado.RollbackTranAsync();
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
}
return await ToApiResult(HttpStatusCode.OK, "成功");
}
/// <summary>
/// 长管签收
/// </summary>
/// <param name="input"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="AppFriendlyException"></exception>
private async Task sign(WareHouseUpInput input)
{
JNPF.Logging.Log.Information($"物料呼叫完成回更参数:{JsonConvert.SerializeObject(input)}");
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
if (string.IsNullOrEmpty(input.requireId))
{
throw Oops.Bah("来源id为空");
}
PrdMoTask moTask = await _db.Queryable<PrdMoTask>().SingleAsync(x => x.id == input.requireId);
if (moTask == null)
{
throw Oops.Bah($"未找到来源id为{input.requireId}的生产任务单");
}
string code = await _billRullService.GetBillNumber(Tnb.BasicData.CodeTemplateConst.MATERIAL_RECEIPT_CODE);
OrganizeEntity workshop = await _organizeService.GetAnyParentByWorkstationId(moTask.workstation_id, DictConst.RegionCategoryWorkshopCode);
List<PrdMaterialReceiptH> insertHList = new List<PrdMaterialReceiptH>();
List<PrdMaterialReceiptD> insertDList = new List<PrdMaterialReceiptD>();
string orgId = WmsWareHouseConst.AdministratorOrgId;
string userId = moTask.worker_id;
foreach(string carryId in input.carryIds)
{
WmsCarryH carry = await _db.Queryable<WmsCarryH>().SingleAsync(x => x.id == carryId);
PrdMaterialReceiptH prdMaterialReceiptH = new PrdMaterialReceiptH()
{
code = code,
station_id = moTask.workstation_id,
mo_task_id = moTask.id,
process_id = moTask.process_id,
equip_id = moTask.eqp_id,
workshop_id = workshop?.Id ?? "",
carry_id = carry.id,
workline_id = moTask.workline_id,
carry_code = carry.carry_code,
mbom_process_id = moTask.mbom_process_id,
create_id = userId,
create_time = DateTime.Now,
org_id = orgId
};
insertHList.Add(prdMaterialReceiptH);
List<WmsCarryCode> wmsCarryCodes = await _db.Queryable<WmsCarryCode>().Where(x=>x.carry_id==carry.id).ToListAsync();
if (wmsCarryCodes != null && wmsCarryCodes.Count > 0)
{
JNPF.Logging.Log.Information($"签收载具信息{JsonConvert.SerializeObject(wmsCarryCodes)}");
foreach (var item in wmsCarryCodes)
{
insertDList.Add(new PrdMaterialReceiptD
{
material_receipt_id = prdMaterialReceiptH.id,
material_id = item.material_id,
num = item.codeqty,
batch = item.code_batch,
unit_id = item.unit_id,
carry_id = carry.id,
barcode = item.barcode,
is_all_feeding = 0,
// member_carry_id = item.member_carryid,
// member_carry_code = item.member_carrycode,
feeding_num = 0,
supplier_id = item.supplier_id,
instock_time = item.instock_time,
// check_conclusion = item.check_conclusion,
});
}
}
else
{
throw Oops.Bah("未找到物料明细");
}
}
if (insertHList.Count <= 0 || insertDList.Count <= 0)
{
throw Oops.Bah(ErrorCode.COM1000);
}
int row1 = await _db.Insertable(insertHList).ExecuteCommandAsync();
int row2 = await _db.Insertable(insertDList).ExecuteCommandAsync();
if (row1 <= 0 || row2 <= 0)
{
throw Oops.Bah(ErrorCode.COM1000);
}
}
}
}