576 lines
30 KiB
C#
576 lines
30 KiB
C#
using System.Security.Cryptography.X509Certificates;
|
||
using JNPF.Common.Core.Manager;
|
||
using JNPF.Common.Dtos.VisualDev;
|
||
using JNPF.Common.Enums;
|
||
using JNPF.Common.Security;
|
||
using JNPF.FriendlyException;
|
||
using JNPF.VisualDev;
|
||
using JNPF.VisualDev.Entitys;
|
||
using JNPF.VisualDev.Interfaces;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.Extensions.Logging;
|
||
using NPOI.POIFS.Storage;
|
||
using SqlSugar;
|
||
using Tnb.BasicData.Entities;
|
||
using Tnb.ProductionMgr.Entities;
|
||
using Tnb.WarehouseMgr.Entities;
|
||
using Tnb.WarehouseMgr.Entities.Attributes;
|
||
using Tnb.WarehouseMgr.Entities.Consts;
|
||
using Tnb.WarehouseMgr.Entities.Dto;
|
||
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
|
||
using Tnb.WarehouseMgr.Entities.Dto.Outputs;
|
||
using Tnb.WarehouseMgr.Entities.Entity;
|
||
using Tnb.WarehouseMgr.Entities.Enums;
|
||
using Tnb.WarehouseMgr.Interfaces;
|
||
|
||
namespace Tnb.WarehouseMgr
|
||
{
|
||
[OverideVisualDev(ModuleConsts.MODULE_WMSPRDRETURN_ID)]
|
||
[ServiceModule(BizTypeId)]
|
||
public class WmsPrdReturnService : BaseWareHouseService, IWmsPrdReturnService
|
||
{
|
||
private const string BizTypeId = WmsWareHouseConst.BIZTYPE_PRDRETURN_ID;
|
||
private readonly ISqlSugarClient _db;
|
||
private readonly IRunService _runService;
|
||
private readonly IVisualDevService _visualDevService;
|
||
private readonly IUserManager _userManager;
|
||
private readonly IWareHouseService _wareHouseService;
|
||
private readonly IWmsCarryBindService _wmsCarryBindService;
|
||
public WmsPrdReturnService(
|
||
ISqlSugarRepository<WmsCarryH> repository,
|
||
IRunService runService,
|
||
IVisualDevService visualDevService,
|
||
IWareHouseService wareHouseService,
|
||
IUserManager userManager,
|
||
IWmsCarryBindService wmsCarryBindService)
|
||
{
|
||
_db = repository.AsSugarClient();
|
||
_runService = runService;
|
||
_visualDevService = visualDevService;
|
||
_userManager = userManager;
|
||
_wareHouseService = wareHouseService;
|
||
_wmsCarryBindService = wmsCarryBindService;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从产线呼叫装料架到暂存仓/缓存仓(退料)
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost, NonUnify, AllowAnonymous]
|
||
public async Task<Result> PrdReturn(PrdReturnInput input)
|
||
{
|
||
WmsPrdReturnH wmsPrdReturnH = await _db.Queryable<WmsPrdReturnH>().Where(r => r.id == input.source_id).FirstAsync();
|
||
if (wmsPrdReturnH == null)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】不存在id为{input.source_id}的生产退料单!");
|
||
throw new AppFriendlyException($"【PrdReturn】不存在id为{input.startlocation_id}的生产退料单!", 500);
|
||
}
|
||
if (wmsPrdReturnH.status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】生产退料单{wmsPrdReturnH.bill_code}状态为已完成!");
|
||
throw new AppFriendlyException($"【PrdReturn】生产退料单{wmsPrdReturnH.bill_code}状态为已完成!", 500);
|
||
}
|
||
if (wmsPrdReturnH.status == WmsWareHouseConst.BILLSTATUS_CANCEL_ID)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】生产退料单{wmsPrdReturnH.bill_code}状态为已取消!");
|
||
throw new AppFriendlyException($"【PrdReturn】生产退料单{wmsPrdReturnH.bill_code}状态为已取消!", 500);
|
||
}
|
||
|
||
WmsCarryH wmsCarryH = await _db.Queryable<WmsCarryH>().Where(r => r.carry_code == input.carry_code).FirstAsync();
|
||
|
||
// 料架到暂存仓
|
||
if (wmsCarryH.carrystd_id == "26037267399717")
|
||
{
|
||
return await Return_到暂存仓(input, wmsCarryH, wmsPrdReturnH);
|
||
}
|
||
// 载运小车和载运料架到缓存仓
|
||
else if (wmsCarryH.carrystd_id == "26103233723941" || wmsCarryH.carrystd_id == "34995839046677")
|
||
{
|
||
return await Return_到缓存仓(input, wmsCarryH, wmsPrdReturnH);
|
||
}
|
||
else if (wmsCarryH.carrystd_id == "26032423715365")
|
||
{
|
||
return await Return_到原材料仓(input, wmsCarryH, wmsPrdReturnH);
|
||
}
|
||
else
|
||
{
|
||
Logger.LogError($"【PrdReturn】当前载具的规格id是{wmsCarryH.carrystd_id} 无法处理此类型的载具!");
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, $"【PrdReturn】当前载具的规格id是{wmsCarryH.carrystd_id} 无法处理此类型的载具!");
|
||
}
|
||
}
|
||
|
||
|
||
async Task<Result> Return_到暂存仓(PrdReturnInput input, WmsCarryH wmsCarryH, WmsPrdReturnH wmsPrdReturnH)
|
||
{
|
||
try
|
||
{
|
||
List<WmsCarryD> wmsCarryDs = _db.Queryable<WmsCarryD>().Where(r => r.carry_id == wmsCarryH.id).ToList();
|
||
if (wmsCarryDs.Count > 0)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】料架{wmsCarryH.carry_code}下有料箱未解绑!");
|
||
throw new AppFriendlyException($"【PrdReturn】料架{wmsCarryH.carry_code}下有料箱未解绑!", 500);
|
||
}
|
||
|
||
BasLocation startlocation = _db.Queryable<BasLocation>().Where(r => r.id == input.startlocation_id).First();
|
||
if (startlocation == null)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】不存在id为{input.startlocation_id}的库位!");
|
||
throw new AppFriendlyException($"【PrdReturn】不存在id为{input.startlocation_id}的库位!", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.carry_code))
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】料架不能为空!{input.carry_code}");
|
||
throw new AppFriendlyException($"【PrdReturn】料架不能为空!{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($"【PrdReturn】没有可用的终点库位");
|
||
throw new AppFriendlyException($"【PrdReturn】没有可用的终点库位!", 500);
|
||
}
|
||
|
||
BasLocation endlocation = rackEndLocations.First();
|
||
|
||
var memberCarryCodes = _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) => new
|
||
{
|
||
carry_code = a.carry_code,
|
||
barcode = b.barcode,
|
||
material_id = b.material_id,
|
||
material_code = b.material_code,
|
||
}).ToList();
|
||
|
||
List<string> matIds = memberCarryCodes.Select(r => r.material_id).Distinct().ToList();
|
||
|
||
// 匹配生产退料单明细的物料种类
|
||
List<string> existsMatIds = _db.Queryable<WmsPrdReturnD>().Where(r => r.bill_id == input.source_id).Select(r => r.material_id).Distinct().ToList();
|
||
List<string> notExistsMatIds = matIds.Where(r => !existsMatIds.Contains(r)).ToList();
|
||
|
||
if (notExistsMatIds.Count() > 0)
|
||
{
|
||
var existsMat = memberCarryCodes.Where(r => notExistsMatIds.Contains(r.material_id)).Select(r => new
|
||
{
|
||
carry_code = r.carry_code,
|
||
barcode = r.barcode,
|
||
});
|
||
|
||
string msg = "";
|
||
foreach (var row in existsMat)
|
||
{
|
||
msg += $",料箱{row.carry_code} 条码{row.barcode}";
|
||
}
|
||
Logger.LogWarning($"【PrdReturn】存在装有与生产退料单明细不匹配物料的料箱,请检查! {msg.Trim(',')}");
|
||
throw new AppFriendlyException($"【PrdReturn】存在装有与生产退料单明细不匹配物料的料箱,请检查!{msg.Trim(',')}", 500);
|
||
}
|
||
|
||
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($"【PrdReturn】此料架{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!");
|
||
throw new AppFriendlyException($"此料架{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!", 500);
|
||
}
|
||
|
||
await _db.Ado.BeginTranAsync();
|
||
|
||
// 标记为退料
|
||
int row2 = await _db.Updateable<WmsCarryH>().SetColumns(r => r.carry_status == ((int)(EnumCarryStatus.退料)).ToString()).Where(r => r.carry_code == wmsCarryH.carry_code).ExecuteCommandAsync();
|
||
if (row2 == 0)
|
||
{
|
||
throw new AppFriendlyException($"【PrdReturn】 料架 {wmsCarryH.carry_code} 退料状态回写失败", 500);
|
||
}
|
||
Logger.LogInformation($"【PrdReturn】料架 {wmsCarryH.carry_code} 退料状态回写成功!");
|
||
|
||
Logger.LogInformation($"【PrdReturn】绑定料箱到料架");
|
||
|
||
List<WmsCarryH> membercarrys = _db.Queryable<WmsCarryH>().Where(r => input.details.Select(r => r.carry_code).Contains(r.carry_code)).ToList();
|
||
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($"【PrdReturn】开始生成预任务");
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new();
|
||
commonCreatePretaskInput.startlocation_id = startlocation.id;
|
||
commonCreatePretaskInput.endlocation_id = endlocation.id;
|
||
commonCreatePretaskInput.source_id = input.source_id;
|
||
commonCreatePretaskInput.carry_id = wmsCarryH.id;
|
||
commonCreatePretaskInput.carry_code = input.carry_code;
|
||
commonCreatePretaskInput.task_type = "";
|
||
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_PRDRETURN_ID;
|
||
|
||
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
|
||
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($"【PrdReturn】生成预任务失败 载具 {input.carry_code}");
|
||
throw new AppFriendlyException($"生成预任务失败 载具 {input.carry_code}", 500);
|
||
}
|
||
Logger.LogWarning($"【PrdReturn】生成预任务成功");
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【PrdReturn】" + ex.Message);
|
||
Logger.LogError("【PrdReturn】" + ex.StackTrace);
|
||
await _db.Ado.RollbackTranAsync();
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
|
||
async Task<Result> Return_到缓存仓(PrdReturnInput input, WmsCarryH wmsCarryH, WmsPrdReturnH wmsPrdReturnH)
|
||
{
|
||
try
|
||
{
|
||
BasLocation startlocation = _db.Queryable<BasLocation>().Where(r => r.id == input.startlocation_id).First();
|
||
if (startlocation == null)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】不存在id为{input.startlocation_id}的库位!");
|
||
throw new AppFriendlyException($"【PrdReturn】不存在id为{input.startlocation_id}的库位!", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.carry_code))
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】料架/载运小车不能为空!{input.carry_code}");
|
||
throw new AppFriendlyException($"【PrdReturn】料架/载运小车不能为空!{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($"【PrdReturn】没有可用的终点库位");
|
||
throw new AppFriendlyException($"【PrdReturn】没有可用的终点库位!", 500);
|
||
}
|
||
|
||
BasLocation endlocation = rackEndLocations.First();
|
||
|
||
var memberCarryCodes = _db.Queryable<WmsCarryH>()
|
||
.InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id)
|
||
.Where((a, b) => a.id == wmsCarryH.id).Select((a, b) => new
|
||
{
|
||
carry_code = a.carry_code,
|
||
barcode = b.barcode,
|
||
material_id = b.material_id,
|
||
material_code = b.material_code,
|
||
}).ToList();
|
||
|
||
List<string> matIds = memberCarryCodes.Select(r => r.material_id).Distinct().ToList();
|
||
|
||
// 匹配生产退料单明细的物料种类
|
||
List<string> existsMatIds = _db.Queryable<WmsPrdReturnD>().Where(r => r.bill_id == input.source_id).Select(r => r.material_id).Distinct().ToList();
|
||
List<string> notExistsMatIds = matIds.Where(r => !existsMatIds.Contains(r)).ToList();
|
||
|
||
if (notExistsMatIds.Count() > 0)
|
||
{
|
||
var existsMat = memberCarryCodes.Where(r => notExistsMatIds.Contains(r.material_id)).Select(r => new
|
||
{
|
||
carry_code = r.carry_code,
|
||
barcode = r.barcode,
|
||
});
|
||
|
||
string msg = "";
|
||
foreach (var row in existsMat)
|
||
{
|
||
msg += $",料架/载运小车{row.carry_code} 条码{row.barcode}";
|
||
}
|
||
Logger.LogWarning($"【PrdReturn】存在装有与生产退料单明细不匹配物料的料架/载运小车,请检查! {msg.Trim(',')}");
|
||
throw new AppFriendlyException($"【PrdReturn】存在装有与生产退料单明细不匹配物料的料架/载运小车,请检查!{msg.Trim(',')}", 500);
|
||
}
|
||
|
||
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($"【PrdReturn】此料架/载运小车{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!");
|
||
throw new AppFriendlyException($"此料架/载运小车{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!", 500);
|
||
}
|
||
|
||
await _db.Ado.BeginTranAsync();
|
||
// 标记为退料
|
||
int row2 = await _db.Updateable<WmsCarryH>().SetColumns(r => r.carry_status == ((int)(EnumCarryStatus.退料)).ToString()).Where(r => r.id == wmsCarryH.id).ExecuteCommandAsync();
|
||
if (row2 == 0)
|
||
{
|
||
throw new AppFriendlyException($"【PrdReturn】 料架 {wmsCarryH.carry_code} 退料状态回写失败", 500);
|
||
}
|
||
Logger.LogInformation($"【PrdReturn】料架 {wmsCarryH.carry_code} 退料状态回写成功!");
|
||
|
||
Logger.LogInformation($"【PrdReturn】开始生成预任务");
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new();
|
||
commonCreatePretaskInput.startlocation_id = startlocation.id;
|
||
commonCreatePretaskInput.endlocation_id = endlocation.id;
|
||
commonCreatePretaskInput.source_id = input.source_id;
|
||
commonCreatePretaskInput.carry_id = wmsCarryH.id;
|
||
commonCreatePretaskInput.carry_code = input.carry_code;
|
||
commonCreatePretaskInput.task_type = "";
|
||
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_PRDRETURN_ID;
|
||
|
||
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
|
||
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($"【PrdReturn】生成预任务失败 载具 {input.carry_code}");
|
||
throw new AppFriendlyException($"生成预任务失败 载具 {input.carry_code}", 500);
|
||
}
|
||
Logger.LogWarning($"【PrdReturn】生成预任务成功");
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【PrdReturn】" + ex.Message);
|
||
Logger.LogError("【PrdReturn】" + ex.StackTrace);
|
||
await _db.Ado.RollbackTranAsync();
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
|
||
async Task<Result> Return_到原材料仓(PrdReturnInput input, WmsCarryH wmsCarryH, WmsPrdReturnH wmsPrdReturnH)
|
||
{
|
||
try
|
||
{
|
||
await _wareHouseService.s_taskExecuteSemaphore_YCLInstock.WaitAsync();
|
||
BasLocation startlocation = _db.Queryable<BasLocation>().Where(r => r.id == input.startlocation_id).First();
|
||
if (startlocation == null)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】不存在id为{input.startlocation_id}的库位!");
|
||
throw new AppFriendlyException($"【PrdReturn】不存在id为{input.startlocation_id}的库位!", 500);
|
||
}
|
||
if (string.IsNullOrEmpty(input.carry_code))
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】托盘不能为空!{input.carry_code}");
|
||
throw new AppFriendlyException($"【PrdReturn】托盘不能为空!{input.carry_code}!", 500);
|
||
}
|
||
|
||
InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = "1", Size = 1, AvoidBusyPassage = true, Region_id = WmsWareHouseConst.REGION_YCLCache_ID };
|
||
List<BasLocation> endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
|
||
|
||
if (endLocations.Count() == 0)
|
||
{
|
||
Logger.LogWarning($"【PrdReturn】没有可用的终点库位");
|
||
throw new AppFriendlyException($"【PrdReturn】没有可用的终点库位!", 500);
|
||
}
|
||
|
||
BasLocation endlocation = endLocations.First();
|
||
|
||
CarryMaterialBindInput carryMaterialBindInput = new CarryMaterialBindInput();
|
||
carryMaterialBindInput.carrycode = wmsCarryH.carry_code;
|
||
carryMaterialBindInput.create_id = input.create_id;
|
||
|
||
List<CarryMaterialDetail> carryMaterialDetails = new List<CarryMaterialDetail>();
|
||
|
||
|
||
List<WmsTempCode> wmsTempCodes = await _db.Queryable<WmsTempCode>().Where(r => input.matdetails.Select(x => x.barcode).Contains(r.barcode)).ToListAsync();
|
||
|
||
await _db.Ado.BeginTranAsync();
|
||
|
||
foreach (PrdReturnMatDetail prdReturnMatDetail in input.matdetails)
|
||
{
|
||
WmsTempCode wmsTempCode = _db.Queryable<WmsTempCode>().Where(r => r.barcode == prdReturnMatDetail.barcode).First();
|
||
if (wmsTempCode == null)
|
||
{
|
||
throw new AppFriendlyException($"【PrdReturn】条码{prdReturnMatDetail.barcode}!", 500);
|
||
}
|
||
CarryMaterialDetail carryMaterialDetail = new CarryMaterialDetail();
|
||
carryMaterialDetail.material_id = wmsTempCode.material_id;
|
||
carryMaterialDetail.material_code = wmsTempCode.material_code;
|
||
carryMaterialDetail.codeqty = prdReturnMatDetail.qty;
|
||
wmsTempCode.codeqty = prdReturnMatDetail.qty;
|
||
carryMaterialDetail.code_batch = wmsTempCode.code_batch;
|
||
carryMaterialDetail.barcode = wmsTempCode.barcode;
|
||
carryMaterialDetail.unit_id = wmsTempCode.unit_id;
|
||
carryMaterialDetails.Add(carryMaterialDetail);
|
||
}
|
||
carryMaterialBindInput.details = carryMaterialDetails;
|
||
await _wmsCarryBindService.CarryMaterialBind(carryMaterialBindInput, _db);
|
||
|
||
await _db.Updateable(wmsTempCodes).ExecuteCommandAsync();
|
||
|
||
var memberCarryCodes = _db.Queryable<WmsCarryH>()
|
||
.InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id)
|
||
.Where((a, b) => a.id == wmsCarryH.id).Select((a, b) => new
|
||
{
|
||
carry_code = a.carry_code,
|
||
barcode = b.barcode,
|
||
material_id = b.material_id,
|
||
material_code = b.material_code,
|
||
}).ToList();
|
||
|
||
List<string> matIds = memberCarryCodes.Select(r => r.material_id).Distinct().ToList();
|
||
|
||
// 匹配生产退料单明细的物料种类
|
||
List<string> existsMatIds = _db.Queryable<WmsPrdReturnD>().Where(r => r.bill_id == input.source_id).Select(r => r.material_id).Distinct().ToList();
|
||
List<string> notExistsMatIds = matIds.Where(r => !existsMatIds.Contains(r)).ToList();
|
||
|
||
if (notExistsMatIds.Count() > 0)
|
||
{
|
||
var existsMat = memberCarryCodes.Where(r => notExistsMatIds.Contains(r.material_id)).Select(r => new
|
||
{
|
||
carry_code = r.carry_code,
|
||
barcode = r.barcode,
|
||
});
|
||
|
||
string msg = "";
|
||
foreach (var row in existsMat)
|
||
{
|
||
msg += $",托盘{row.carry_code} 条码{row.barcode}";
|
||
}
|
||
Logger.LogWarning($"【PrdReturn】存在装有与生产退料单明细不匹配物料的托盘,请检查! {msg.Trim(',')}");
|
||
throw new AppFriendlyException($"存在装有与生产退料单明细不匹配物料的托盘,请检查!{msg.Trim(',')}", 500);
|
||
}
|
||
|
||
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($"【PrdReturn】此托盘{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!");
|
||
throw new AppFriendlyException($"此托盘{wmsCarryH.carry_code}存在未完成的预任务{wmsPretaskH.bill_code}!", 500);
|
||
}
|
||
|
||
|
||
Logger.LogInformation($"【PrdReturn】开始生成预任务");
|
||
CommonCreatePretaskInput commonCreatePretaskInput = new();
|
||
commonCreatePretaskInput.startlocation_id = startlocation.id;
|
||
commonCreatePretaskInput.endlocation_id = endlocation.id;
|
||
commonCreatePretaskInput.source_id = input.source_id;
|
||
commonCreatePretaskInput.carry_id = wmsCarryH.id;
|
||
commonCreatePretaskInput.carry_code = input.carry_code;
|
||
commonCreatePretaskInput.task_type = "";
|
||
commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_PRDRETURN_ID;
|
||
commonCreatePretaskInput.priority = WmsWareHouseConst.priority_instock;
|
||
|
||
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
|
||
if (res.code != JNPF.Common.Enums.HttpStatusCode.OK)
|
||
{
|
||
Logger.LogInformation($"【PrdReturn】生成预任务失败 载具 {input.carry_code}");
|
||
throw new AppFriendlyException($"生成预任务失败 载具 {input.carry_code}", 500);
|
||
}
|
||
Logger.LogWarning($"【PrdReturn】生成预任务成功");
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【PrdReturn】" + ex.Message);
|
||
Logger.LogError("【PrdReturn】" + ex.StackTrace);
|
||
await _db.Ado.RollbackTranAsync();
|
||
return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message);
|
||
}
|
||
finally
|
||
{
|
||
_wareHouseService.s_taskExecuteSemaphore_YCLInstock.Release();
|
||
}
|
||
return await ToApiResult(HttpStatusCode.OK, "成功");
|
||
}
|
||
|
||
public override async Task ModifyAsync(WareHouseUpInput input)
|
||
{
|
||
if (input == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input));
|
||
}
|
||
|
||
try
|
||
{
|
||
WmsCarryH wmsCarryH = await _db.Queryable<WmsCarryH>().Where(r => r.id == input.carryIds[0]).FirstAsync();
|
||
|
||
// 用于回写prd_material_receipt_d is_all_feeding
|
||
List<WmsCarryH> carryHs = new List<WmsCarryH>();
|
||
|
||
List<WmsCarryCode> wmsCarryCodes = null;
|
||
// 料架到暂存仓
|
||
if (wmsCarryH.carrystd_id == "26037267399717")
|
||
{
|
||
wmsCarryCodes = _db.Queryable<WmsCarryD>()
|
||
.InnerJoin<WmsCarryH>((a, b) => a.membercarry_id == b.id)
|
||
.InnerJoin<WmsCarryCode>((a, b, c) => b.id == c.carry_id)
|
||
.Where((a, b, c) => a.carry_id == wmsCarryH.id).Select((a, b, c) => c).ToList();
|
||
|
||
carryHs = _db.Queryable<WmsCarryD>()
|
||
.InnerJoin<WmsCarryH>((a, b) => a.membercarry_id == b.id)
|
||
.Where((a, b) => a.carry_id == wmsCarryH.id).Select((a, b) => b).ToList();
|
||
}
|
||
// 载运小车和载运料架到缓存仓
|
||
else if (wmsCarryH.carrystd_id == "26103233723941" || wmsCarryH.carrystd_id == "34995839046677")
|
||
{
|
||
carryHs.Add(wmsCarryH);
|
||
wmsCarryCodes = _db.Queryable<WmsCarryH>()
|
||
.InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id)
|
||
.Where((a, b) => a.id == wmsCarryH.id).Select((a, b) => b).ToList();
|
||
}
|
||
else
|
||
{
|
||
throw new Exception($"【WmsPrdReturnService ModifyAsync】当前载具的规格id是{wmsCarryH.carrystd_id} 无法处理此类型的载具!");
|
||
}
|
||
|
||
if (wmsCarryCodes.Count == 0)
|
||
{
|
||
throw new Exception($"【WmsPrdReturnService ModifyAsync】载具{input.carryIds[0]}没有绑定物料条码");
|
||
}
|
||
|
||
await _db.Ado.BeginTranAsync();
|
||
|
||
int row_is_all_feeding = await _db.Updateable<PrdMaterialReceiptD>().SetColumns(r => r.is_all_feeding == 1)
|
||
.Where(r => r.is_all_feeding == 0 && carryHs.Select(x => x.id).Contains(r.member_carry_id)).ExecuteCommandAsync();
|
||
|
||
Logger.LogInformation($"【WmsPrdReturnService ModifyAsync】更新签收表is_all_feeding 影响记录条数 {row_is_all_feeding}条 影响载具为{string.Join(',', carryHs.Select(x => x.carry_code).ToList())}");
|
||
|
||
|
||
// 更新已转数量
|
||
List<WmsPrdReturnD> wmsPrdReturnDs = _db.Queryable<WmsPrdReturnD>().Where(r => r.bill_id == input.source_id).ToList();
|
||
foreach (WmsPrdReturnD wmsPrdReturnD in wmsPrdReturnDs)
|
||
{
|
||
decimal qty = wmsCarryCodes.Where(r => r.material_id == wmsPrdReturnD.material_id).Sum(r => r.codeqty);
|
||
wmsPrdReturnD.ytqty = wmsPrdReturnD.ytqty + qty;
|
||
}
|
||
|
||
|
||
bool isOk = await _db.Updateable(wmsPrdReturnDs).UpdateColumns(r => r.ytqty).ExecuteCommandAsync() > 0;
|
||
|
||
// 如果所有明细已完成 更新主表状态为完成
|
||
wmsPrdReturnDs = _db.Queryable<WmsPrdReturnD>()
|
||
.Where(a => a.bill_id == input.source_id && a.ytqty < a.qty).ToList();
|
||
bool isOk2 = true;
|
||
if (wmsPrdReturnDs.Count == 0)
|
||
{
|
||
isOk2 = await _db.Updateable<WmsPrdReturnH>().SetColumns(it => new WmsPrdReturnH { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID })
|
||
.Where(it => it.id == input.source_id).ExecuteCommandHasChangeAsync();
|
||
}
|
||
|
||
// require_code是任务单
|
||
//string mo_task_code = input.require_code;
|
||
|
||
if (!isOk || !isOk2)
|
||
{
|
||
throw Oops.Oh(ErrorCode.COM1001);
|
||
}
|
||
await _db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.LogError("【WmsPrdReturnService ModifyAsync】" + ex.Message);
|
||
Logger.LogError("【WmsPrdReturnService ModifyAsync】" + ex.StackTrace);
|
||
await _db.Ado.RollbackTranAsync();
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|