Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WmsCheckTaskService.cs
2024-04-23 10:16:16 +08:00

638 lines
35 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.Linq;
using System.Linq.Expressions;
using Aop.Api.Domain;
using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.VisualDev;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.EventBus;
using JNPF.FriendlyException;
using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.OpenXmlFormats.Dml.Spreadsheet;
using NPOI.SS.Formula.PTG;
using SqlSugar;
using Tnb.BasicData.Entities;
using Tnb.WarehouseMgr.Entities;
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.Dto.Queries;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 盘点任务
/// </summary>
[OverideVisualDev(ModuleConsts.MODULE_WMSCHECKTASK_ID)]
public class WmsCheckTaskService : BaseWareHouseService
{
private readonly ISqlSugarClient _db;
private readonly IWareHouseService _warehouseService;
private readonly IUserManager _userManager;
private readonly IVisualDevService _visualDevService;
private readonly IRunService _runService;
private readonly IBillRullService _billRullService;
private readonly IDictionaryDataService _dataService;
private static Dictionary<string, object> _carryMap = new();
public WmsCheckTaskService(
ISqlSugarRepository<WmsCheckstockH> repository,
IWareHouseService wareHouseService,
IVisualDevService visualDevService,
IRunService runService,
IBillRullService billRullService,
IUserManager userManager,
IDictionaryDataService dataService,
IEventPublisher eventPublisher
)
{
_db = repository.AsSugarClient();
_warehouseService = wareHouseService;
_visualDevService = visualDevService;
_runService = runService;
_billRullService = billRullService;
_dataService = dataService;
_userManager = userManager;
OverideFuncs.CreateAsync = Create;
}
private async Task<dynamic> Create(VisualDevModelDataCrInput input)
{
int row = 1;
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
try
{
await _db.Ado.BeginTranAsync();
if (input.data?.Count > 0)
{
string? checkType = input.data[nameof(WmsCheckstockH.checkstock_type)]?.ToString();
if (!checkType.IsNullOrEmpty())
{
List<string> billStatus = new()
{
WmsWareHouseConst.TASK_BILL_STATUS_CANCEL_ID,
WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID,
};
Expression<Func<WmsDistaskH, BasLocation, bool>> filter = Expressionable.Create<WmsDistaskH, BasLocation>()
.And((a, b) => b.wh_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString())
.And((a, b) => b.is_type == ((int)EnumLocationType.).ToString())
.And((a, b) => !billStatus.Contains(a.status))
.ToExpression();
List<Task<List<WmsDistaskH>>> queryTasks = new()
{
Task.Run(() => FetchDisTasks((a, b) => a.startlocation_id == b.id, filter)),
Task.Run(() => FetchDisTasks((a, b) => a.endlocation_id == b.id, filter))
};
List<WmsDistaskH>[] disTasks = await Task.WhenAll(queryTasks);
if (disTasks?.Length > 0 && disTasks.Any(list => list?.Count > 0))
{
throw new AppFriendlyException("该仓库还有未完成的任务,不允许盘点!", 500);
}
input.data["tablefield114"] = null;
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSCHECKTASK_ID, true);
await _runService.Create(templateEntity, input);
List<WmsCheckstockD> details = new();
var filterExpable = Expressionable.Create<BasLocation, WmsCarryCode, WmsCarryH>()
.And((a, b, c) => a.wh_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString())
.And((a, b, c) => a.is_type == ((int)EnumLocationType.).ToString())
.And((a, b, c) => c.is_lock == 0);
var areaIds = new string[] { };
if (input.data.ContainsKey(nameof(WmsCheckstockH.area_id)) && input.data[nameof(WmsCheckstockH.area_id)] != null)
{
areaIds = input.data[nameof(WmsCheckstockH.area_id)].ToObject<string[]>();
}
Expression<Func<BasLocation, WmsCarryCode, WmsCarryH, bool>> filterExp = (a, b, c) => false;
var filerExpable = Expressionable.Create<BasLocation, WmsCarryCode, WmsCarryH>()
.And((a, b, c) => a.wh_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString())
.And((a, b, c) => a.is_type == ((int)EnumLocationType.).ToString())
.And((a, b, c) => c.is_lock == 0);
switch (checkType?.ToEnum<EnumCheckType>())
{
case EnumCheckType.:
{
filterExp = filerExpable.ToExpression();
}
break;
case EnumCheckType.:
{
if (!input.data.ContainsKey(nameof(WmsCarryCode.material_id)) && input.data[nameof(WmsCarryCode.material_id)] != null)
{
filterExp = (a, b, c) => b.material_id == input.data[nameof(WmsCarryCode.material_id)].ToString();
}
}
break;
case EnumCheckType.:
{
if (areaIds?.Length > 0)
{
filterExp = (a, b, c) => areaIds.Contains(a.region_id);
}
}
break;
}
var carryCodes = await _db.Queryable<BasLocation>().InnerJoin<WmsCarryCode>((a, b) => a.id == b.location_id)
.InnerJoin<WmsCarryH>((a, b, c) => b.carry_id == c.id)
.Where(filterExpable.ToExpression())
.Select((a, b, c) => new WmsCarryCode { carry_code = c.carry_code }, true)
.ToListAsync();
carryCodes ??= Enumerable.Empty<WmsCarryCode>().ToList();
List<WmsCheckstockD>? checkStockDs = carryCodes.Adapt<List<WmsCheckstockD>>();
var prQtyDic = checkStockDs.GroupBy(g => $"{g.carry_id}{g.material_id}{g.code_batch}").ToDictionary(x => x.Key, x => x.Sum(d => d.codeqty));
foreach ((object k, decimal v) in prQtyDic)
{
WmsCheckstockD? checkstockD = checkStockDs?.Find(x => string.Equals(k, $"{x.carry_id}{x.material_id}{x.code_batch}"));
if (checkstockD != null)
{
checkstockD.id = SnowflakeIdHelper.NextId();
checkstockD.checkstock_id = input.data["ReturnIdentity"].ToString();
checkstockD.create_id = _userManager.UserId;
checkstockD.create_time = DateTime.Now;
checkstockD.pr_qty = v;
details.Add(checkstockD);
}
}
var r = await _db.Insertable(details).ExecuteCommandAsync();
//生成预任务信息
if (details.Count > 0 && carryCodes.Count > 0)
{
// 判断当前仓库是否有盘点签收配置
var wcsConf = await _db.Queryable<WmsCheckSignConfig>().Where(it => it.warehouse_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString() && it.enabled == 1)
.FirstAsync();
BasLocation[] endLocs = Array.Empty<BasLocation>();
int randomIndex = 0;
if (wcsConf != null)
{
if (wcsConf.location_id.IsNullOrWhiteSpace())
{
throw new AppFriendlyException("盘点签收配置库位为空,请查看配置!", 500);
}
JArray? jsonArr = null;
jsonArr = JArray.Parse(wcsConf.location_id);
string?[] locArr = jsonArr.Select(x => x.ToObject<string>()).ToArray();
if (locArr != null)
{
endLocs = await _db.Queryable<BasLocation>().Where(it => it.wh_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString() && locArr.Contains(it.id)).ToArrayAsync();
randomIndex = Random.Shared.Next(0, endLocs.Length);
}
else
{
throw new AppFriendlyException("盘点签收配置有误,请查看配置!", 500);
}
}
else
{
string[] locTypes = new[] { ((int)EnumLocationType.).ToString(), ((int)EnumLocationType.).ToString() };
endLocs = await _db.Queryable<BasLocation>().Where(it => it.wh_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString() && locTypes.Contains(it.is_type)).ToArrayAsync();
randomIndex = Random.Shared.Next(0, endLocs.GetUpperBound(0));
}
List<WmsCarryH> carrys = await _db.Queryable<WmsCarryH>().Where(it => carryCodes.Select(x => x.carry_id).Distinct().Contains(it.id)).ToListAsync();
List<WmsCheckstockD> curDetails = details.DistinctBy(x => x.carry_id).ToList();
List<WmsCarryCode> curCarryCodes = carryCodes.FindAll(x => curDetails.Select(d => d.carry_id).Contains(x.carry_id));
if (curCarryCodes.Count > 0)
{
List<WmsPretaskH> preTasks = new();
List<string> locIds = new();
foreach (WmsCarryH item in carrys)
{
WmsPointH? sPoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == item.location_id);
WmsPointH? ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == endLocs[randomIndex].id);
if (sPoint != null && ePoint != null)
{
List<WmsPointH> points = await _warehouseService.PathAlgorithms(sPoint.id, ePoint.id);
if (points.Count <= 2)
{
throw new AppFriendlyException("该路径不存在", 500);
}
if (points?.Count > 0)
{
locIds.AddRange(points.Select(x => x.location_id).ToList()!);
List<WmsPretaskH> curPreTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it =>
{
WmsPointH? sPoint = it.FirstOrDefault();
WmsPointH? ePoint = it.LastOrDefault();
WmsPretaskH preTask = new()
{
org_id = _userManager.User.OrganizeId,
startlocation_id = sPoint?.location_id!,
startlocation_code = sPoint?.location_code!,
endlocation_id = ePoint?.location_id!,
endlocation_code = ePoint?.location_code!,
startpoint_id = sPoint?.id!,
startpoint_code = sPoint?.point_code!,
endpoint_id = ePoint?.id!,
endpoint_code = ePoint?.point_code!,
start_floor = sPoint?.floor.ToString(),
end_floor = ePoint?.floor.ToString(),
bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(),
status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID,
biz_type = WmsWareHouseConst.BIZTYPE_WMSCHECKOUTSTOCK_ID,
task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID,
carry_id = item.id,
carry_code = item.carry_code!,
area_id = sPoint?.area_id!,
area_code = it.Key,
require_id = input.data["ReturnIdentity"].ToString(),
require_code = input.data[nameof(WmsCheckstockH.checkstock_code)]?.ToString(),
create_id = _userManager.UserId,
create_time = DateTime.Now
};
return preTask;
}).ToList();
if (endLocs[randomIndex].is_sign == 0)
{
curPreTasks[^1].is_sign = 0;
}
preTasks.AddRange(curPreTasks);
}
}
}
List<WmsPretaskCode> pretaskCodes = new();
foreach (WmsPretaskH pt in preTasks)
{
List<WmsCarryCode> partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList();
List<WmsPretaskCode> curPreTaskCodes = partCodes.Adapt<List<WmsPretaskCode>>();
curPreTaskCodes.ForEach(x =>
{
x.id = SnowflakeIdHelper.NextId();
x.bill_id = pt.id;
x.create_time = DateTime.Now;
});
pretaskCodes.AddRange(curPreTaskCodes);
}
bool isOk = await _warehouseService.GenPreTask(preTasks, pretaskCodes);
if (isOk)
{
_ = await _db.Updateable<WmsCheckstockH>().SetColumns(it => it.status == ((int)EnumCheckStatus.).ToString()).Where(it => it.id == input.data["ReturnIdentity"].ToString()).ExecuteCommandAsync();
GenPreTaskUpInput genPreTaskAfterUpInput = new()
{
CarryIds = preTasks.Select(x => x.carry_id).ToList(),
LocationIds = new HashSet<string>(locIds).ToList()
};
await _warehouseService.GenInStockTaskHandleAfter(genPreTaskAfterUpInput, it => new WmsCarryH { is_lock = 1 }, it => new BasLocation { is_lock = 1 });
}
}
}
}
}
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
row = 0;
Logger.Error("盘点任务新增失败", ex);
await _db.Ado.RollbackTranAsync();
throw;
}
finally
{
await InvokeGenPretaskExcute();
}
return Task.FromResult(row);
}
private Task<List<WmsDistaskH>> FetchDisTasks(Expression<Func<WmsDistaskH, BasLocation, bool>> joinExp, Expression<Func<WmsDistaskH, BasLocation, bool>> whereExp)
{
var details = _db.CopyNew().Queryable<WmsDistaskH>().InnerJoin<BasLocation>(joinExp).Where(whereExp).Select<WmsDistaskH>().ToListAsync();
return details;
}
/// <summary>
/// 根据盘点任务ID获取盘点任务明细
/// </summary>
/// <param name="checkStockId">盘点任务主表ID</param>
/// <returns>盘点任务明细列表</returns>
[HttpGet("{checkStockId}")]
public async Task<List<WmsCheckstockD>> GetCheckStockDList(string checkStockId)
{
var details = await _db.Queryable<WmsCheckstockD>().Where(it => it.checkstock_id == checkStockId)
.Select<WmsCheckstockD>()
.Mapper(it => it.delayeqty = Math.Max(0, it.pr_qty.Value - it.qty.Value))
.ToListAsync();
return details;
}
/// <summary>
/// 根据盘点类型获取任务明细
/// </summary>
/// <param name="input">
/// <br/>{
/// <br/> warehouse_id:仓库ID
/// <br/> CheckType:盘点类型 0 全库盘点、1 物料盘点 2 区域盘点
/// <br/> material_id:物料ID
/// <br/> regionIds: 区域ID列表
/// <br/>}
/// </param>
/// <returns></returns>
[HttpPost]
public async Task<dynamic> GetTaskDetailByCheckType(CheckDetailQuery input)
{
if (_carryMap.Count == 0)
{
_carryMap = await _db.Queryable<WmsCarryH>().ToDictionaryAsync(x => x.id, x => x.carry_code);
}
Expression<Func<BasLocation, WmsCarryCode, WmsCarryH, bool>> filterExp = (a, b, c) => false;
var filerExpable = Expressionable.Create<BasLocation, WmsCarryCode, WmsCarryH>()
.And((a, b, c) => a.wh_id == input.warehouse_id)
.And((a, b, c) => a.is_type == ((int)EnumLocationType.).ToString())
.And((a, b, c) => c.is_lock == 0);
switch (input.CheckType)
{
case EnumCheckType.:
{
filterExp = filerExpable.ToExpression();
}
break;
case EnumCheckType.:
{
if (!input.material_id.IsNullOrWhiteSpace())
{
filterExp = filerExpable.And((a, b, c) => b.material_id == input.material_id).ToExpression();
}
}
break;
case EnumCheckType.:
{
if (input.regionIds?.Count > 0)
{
filterExp = filerExpable.And((a, b, c) => input.regionIds.Contains(a.region_id)).ToExpression();
}
}
break;
}
var carryCodes = await _db.Queryable<BasLocation>().InnerJoin<WmsCarryCode>((a, b) => a.id == b.location_id)
.InnerJoin<WmsCarryH>((a, b, c) => b.carry_id == c.id)
.Where(filterExp)
.Select<WmsCarryCode>()
.ToListAsync();
List<WmsCheckstockD> outputs = carryCodes.GroupBy(g => new { g.material_code, g.code_batch, g.location_code, g.carry_id }).Select(x => new WmsCheckstockD
{
material_code = x.Key.material_code,
code_batch = x.Key.code_batch,
carry_id = x.Key.carry_id,
carry_code = _carryMap[x.Key.carry_id]?.ToString() ?? string.Empty,
location_id = x.FirstOrDefault(y => y.location_code == x.Key.location_code)?.location_id ?? string.Empty,
location_code = x.Key.location_code,
pr_qty = x.Sum(d => d.codeqty),
closing_status = WmsWareHouseConst.CLOSINGSTATUS_WJS_ID,
qty = 0,
})
.ToList();
return outputs;
}
/// <summary>
/// 获取盘点任务信息
/// </summary>
/// <param name="carryCode">载具编号</param>
/// <returns></returns>
/// <remarks>
///
/// </remarks>
[HttpGet("{carryCode}")]
public async Task<dynamic> GetCheckTaskInfo(string carryCode)
{
var checkTypeMap = await _dataService.GetDicByKey("CheckType");
var checkSpeciesMap = await _dataService.GetDicByKey("CheckSpecies");
var result = await _db.Queryable<WmsDistaskH>().InnerJoin<WmsCheckstockH>((a, b) => a.require_id == b.id)
.InnerJoin<BasWarehouse>((a, b, c) => b.warehouse_id == c.id)
.Where(a => a.carry_code == carryCode)
.Select((a, b, c) => new WmsCheckstockH { warehouse_name = c.whname }, true)
.Mapper(it =>
{
it.checkstock_type = checkTypeMap.ContainsKey(it.checkstock_type!) ? checkTypeMap[it.checkstock_type!]?.ToString() ?? "" : "";
it.handle_kinds = checkTypeMap.ContainsKey(it.handle_kinds!) ? checkTypeMap[it.handle_kinds!]?.ToString() ?? "" : "";
})
.ToListAsync();
return result;
}
/// <summary>
/// 根据条码编号和载具id获取对应载具条码信息
/// </summary>
/// <param name="q"></param>
/// <returns></returns>
public async Task<dynamic> GetCarryCodeInfoByBarCode([FromQuery] CarryCodeInfoQuery q)
{
var items = await _db.Queryable<WmsCarryH>().InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id)
.Where((a, b) => b.barcode == q.barcode && b.carry_id == q.carryId)
.Select((a, b) => new WmsCarryCode { carry_code = a.carry_code }, true)
.ToListAsync();
return items;
}
/// <summary>
/// 盘点签收
/// </summary>
/// <param name="input">盘点签收输入参数</param>
/// <returns>有异常信息为失败,无异常为正常</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="AppFriendlyException"></exception>
[HttpPost]
public async Task TakeStockSign(TakeStockSignInput input)
{
if (input == null) throw new ArgumentNullException("input");
if (input.details == null) throw new ArgumentNullException(nameof(input.details));
var checkStockCodes = input.details.Adapt<List<WmsCheckstockCode>>();
var disTask = await _db.Queryable<WmsDistaskH>().Where(it => it.carry_id == checkStockCodes[0].carry_id &&
it.status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID &&
it.is_sign == 0).FirstAsync();
try
{
await _db.Ado.BeginTranAsync();
if (disTask != null)
{
disTask.is_sign = 1;
_ = await _db.Updateable(disTask).UpdateColumns(it => it.is_sign).ExecuteCommandAsync();
}
var checkStock = await _db.Queryable<WmsCheckstockH>().SingleAsync(it => it.id == checkStockCodes[0].checkstock_id);
if (checkStock != null)
{
InStockStrategyQuery q = new() { warehouse_id = checkStock!.warehouse_id! };
var endLocs = await _warehouseService.InStockStrategy(q);
WmsPointH? sPoint = null, ePoint = null;
var carry = await _db.Queryable<WmsCarryH>().SingleAsync(it => it.id == checkStockCodes[0].carry_id);
sPoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == carry.location_id);
if (endLocs?.Count > 0)
{
ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == endLocs[0].id);
}
if (sPoint == null || ePoint == null) throw new AppFriendlyException("起点或终点不能为空", 500);
List<WmsPointH> points = await _warehouseService.PathAlgorithms(sPoint.id, ePoint.id);
//根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
if (points?.Count > 0)
{
if (points.Count <= 2)
{
throw new AppFriendlyException("该路径不存在", 500);
}
/* var genPreTask = BuildPreTaskHelper.GenPretaskCurried<WmsCheckstockH>(null, WmsWareHouseConst.BIZTYPE_CARRYMOVEINSTOCK_ID, WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID);
var genPreTaskUpInput = await genPreTask(carry, sPoint, ePoint);
*/
List<WmsPretaskH> preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it =>
{
WmsPointH? sPoint = it.FirstOrDefault();
WmsPointH? ePoint = it.LastOrDefault();
WmsPretaskH preTask = new()
{
org_id = _userManager.User.OrganizeId!,
startlocation_id = sPoint?.location_id!,
startlocation_code = sPoint?.location_code!,
endlocation_id = ePoint?.location_id!,
endlocation_code = ePoint?.location_code!,
start_floor = sPoint?.floor.ToString(),
end_floor = ePoint?.floor.ToString(),
startpoint_id = sPoint?.id!,
startpoint_code = sPoint?.point_code!,
endpoint_id = ePoint?.id!,
endpoint_code = ePoint?.point_code!,
bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(),
status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID,
biz_type = WmsWareHouseConst.BIZTYPE_CARRYMOVEINSTOCK_ID,
task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID,
carry_id = carry?.id ?? string.Empty,
carry_code = carry?.carry_code ?? string.Empty,
area_id = sPoint?.area_id!,
area_code = it.Key,
create_id = _userManager.UserId,
create_time = DateTime.Now
};
return preTask;
}).ToList();
bool isOk = await _warehouseService.GenPreTask(preTasks, null!);
if (isOk)
{
GenPreTaskUpInput preTaskUpInput = new()
{
//RquireId = input.data["ReturnIdentity"].ToString()!,
CarryId = checkStockCodes[0].carry_id,
CarryStartLocationId = points.FirstOrDefault()!.location_id!,
CarryStartLocationCode = points.FirstOrDefault()!.location_code!,
LocationIds = points.Select(x => x.location_id).ToList()!
};
WmsHandleH handleH = new()
{
org_id = _userManager.User.OrganizeId,
startlocation_id = carry?.location_id ?? string.Empty,
endlocation_id = endLocs?[0].id ?? string.Empty,
bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_CARRYMOINSTK_ENCODE).GetAwaiter().GetResult(),
biz_type = WmsWareHouseConst.BIZTYPE_CARRYMOVEINSTOCK_ID,
carry_id = checkStockCodes?[0].carry_id ?? string.Empty,
carry_code = carry?.carry_code ?? string.Empty,
create_id = _userManager.UserId,
create_time = DateTime.Now
};
preTaskUpInput.PreTaskRecord = handleH;
//根据载具移入Id回更单据状态
_ = await _db.Updateable<WmsMoveInstock>().SetColumns(it => new WmsMoveInstock { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == preTaskUpInput.RquireId).ExecuteCommandAsync();
await _warehouseService.GenInStockTaskHandleAfter(preTaskUpInput,
it => new WmsCarryH { is_lock = 1, location_id = preTaskUpInput.CarryStartLocationId, location_code = preTaskUpInput.CarryStartLocationCode },
it => new BasLocation { is_lock = 1 });
}
}
}
foreach (var csCode in checkStockCodes!)
{
csCode.id = SnowflakeIdHelper.NextId();
var checkStockPartDs = await _db.Queryable<WmsCheckstockD>().Where(it => it.checkstock_id == csCode.checkstock_id).ToListAsync();
var checkStockDMap = checkStockPartDs.GroupBy(g => $"{g.carry_id}{g.material_id}{g.code_batch}").ToDictionary(x => x.Key, x => x.First().id);
csCode.checkstock_d_id = checkStockDMap.ContainsKey($"{csCode.carry_id}{csCode.material_id}{csCode.code_batch}") ? checkStockDMap[$"{csCode.carry_id}{csCode.material_id}{csCode.code_batch}"] : "";
}
//插入 盘点code表
_ = await _db.Insertable(checkStockCodes).ExecuteCommandAsync();
var detailIds = checkStockCodes.Select(x => x.checkstock_d_id).ToList();
var checkStockDs = await _db.Queryable<WmsCheckstockD>().Where(it => detailIds.Contains(it.id)).ToListAsync();
foreach (var csd in checkStockDs)
{
var csCode = checkStockCodes.Find(x => x.checkstock_d_id == csd.id);
if (csCode != null)
{
csd.qty += csCode.codeqty;
var residueQty = csd.qty - csd.pr_qty;
if (residueQty == 0)
{
csd.closing_status = WmsWareHouseConst.CLOSINGSTATUS_NORMAL_ID;
}
else if (residueQty > 0)
{
csd.closing_status = WmsWareHouseConst.CLOSINGSTATUS_PY_ID;
}
else if (residueQty < 0)
{
csd.closing_status = WmsWareHouseConst.CLOSINGSTATUS_PK_ID;
}
}
}
_ = await _db.Updateable(checkStockDs).UpdateColumns(it => new { it.qty, it.closing_status }).ExecuteCommandAsync();
var checkStockDsGrp = checkStockDs.GroupBy(g => g.checkstock_id);
var checkStocks = await _db.Queryable<WmsCheckstockH>().Where(it => checkStockDsGrp.Select(g => g.Key).Contains(it.id)).ToListAsync();
var tasks = new List<Task<int>>(checkStockDsGrp.Count());
foreach (var grp in checkStockDsGrp)
{
if (grp.All(x => x.closing_status != WmsWareHouseConst.CLOSINGSTATUS_WJS_ID))
{
var cs = checkStocks.Find(x => x.id == grp.Key);
if (cs != null)
{
cs.status = WmsWareHouseConst.CHECKSTATUS_PDJZ_ID;
tasks.Add(_db.Updateable(cs).UpdateColumns(it => it.status).ExecuteCommandAsync());
}
}
}
_ = await Task.WhenAll(tasks);
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
Logger.Error("盘点签收失败", ex);
await _db.Ado.RollbackTranAsync();
throw;
}
}
}
}