修改盘点任务代码
This commit is contained in:
@@ -13,6 +13,7 @@ using JNPF.VisualDev.Interfaces;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using SqlSugar;
|
||||
using Tnb.BasicData.Entities;
|
||||
using Tnb.WarehouseMgr.Entities;
|
||||
@@ -29,7 +30,7 @@ namespace Tnb.WarehouseMgr
|
||||
/// 盘点任务
|
||||
/// </summary>
|
||||
[OverideVisualDev(ModuleConsts.MODULE_WMSCHECKTASK_ID)]
|
||||
public class WmsCheckTaskService : BaseWareHouseService
|
||||
public class WmsCheckTaskService : BaseWareHouseService<WmsCheckTaskService>
|
||||
{
|
||||
private readonly ISqlSugarClient _db;
|
||||
private readonly IWareHouseService _warehouseService;
|
||||
@@ -99,39 +100,49 @@ namespace Tnb.WarehouseMgr
|
||||
}
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSCHECKTASK_ID, true);
|
||||
await _runService.Create(templateEntity, input);
|
||||
List<WmsCarryCode> carryCodes = new();
|
||||
List<WmsCheckstockD> details = new();
|
||||
switch (checkType!.ToEnum<EnumCheckType>())
|
||||
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)
|
||||
{
|
||||
case EnumCheckType.全库盘点:
|
||||
carryCodes = await _db.Queryable<BasLocation>().InnerJoin<WmsCarryCode>((a, b) => a.id == b.location_id)
|
||||
.Where(a => a.wh_id == input.data[nameof(WmsCheckstockH.warehouse_id)].ToString() && a.is_type == ((int)EnumLocationType.存储库位).ToString())
|
||||
.Select<WmsCarryCode>()
|
||||
.ToListAsync();
|
||||
carryCodes ??= Enumerable.Empty<WmsCarryCode>().ToList();
|
||||
List<WmsCheckstockD>? checkStockDs = carryCodes.Adapt<List<WmsCheckstockD>>();
|
||||
var prQtyDic = checkStockDs.GroupBy(g => new { 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.create_id = _userManager.UserId;
|
||||
checkstockD.create_time = DateTime.Now;
|
||||
checkstockD.pr_qty = v;
|
||||
details.Add(checkstockD);
|
||||
}
|
||||
}
|
||||
_ = await _db.Insertable(details).ExecuteCommandAsync();
|
||||
break;
|
||||
case EnumCheckType.物料盘点:
|
||||
|
||||
break;
|
||||
case EnumCheckType.批次盘点:
|
||||
break;
|
||||
areaIds = input.data[nameof(WmsCheckstockH.area_id)].ToObject<string[]>();
|
||||
}
|
||||
|
||||
filterExpable = checkType!.ToEnum<EnumCheckType>() switch
|
||||
{
|
||||
EnumCheckType.物料盘点 => filterExpable.AndIF(input.data.ContainsKey(nameof(WmsCarryCode.material_id)) && input.data[nameof(WmsCarryCode.material_id)] != null, (a, b, c) => b.material_id == input.data[nameof(WmsCarryCode.material_id)].ToString()),
|
||||
EnumCheckType.批次盘点 => filterExpable.AndIF(areaIds?.Length > 0, (a, b, c) => areaIds.Contains(a.region_id)),
|
||||
_ => filterExpable,
|
||||
};
|
||||
|
||||
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<WmsCarryCode>()
|
||||
.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);
|
||||
}
|
||||
}
|
||||
_ = await _db.Insertable(details).ExecuteCommandAsync();
|
||||
//生成预任务信息
|
||||
if (details.Count > 0 && carryCodes.Count > 0)
|
||||
{
|
||||
@@ -142,7 +153,7 @@ namespace Tnb.WarehouseMgr
|
||||
int randomIndex = 0;
|
||||
if (wcsConf != null)
|
||||
{
|
||||
if (wcsConf.location_id == null)
|
||||
if (wcsConf.location_id.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new AppFriendlyException("盘点签收配置库位为空,请查看配置!", 500);
|
||||
}
|
||||
@@ -152,7 +163,7 @@ namespace Tnb.WarehouseMgr
|
||||
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 = new Random().Next(0, endLocs.GetUpperBound(0));
|
||||
randomIndex = Random.Shared.Next(0, endLocs.GetUpperBound(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -164,7 +175,7 @@ namespace Tnb.WarehouseMgr
|
||||
{
|
||||
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 = new Random().Next(0, endLocs.GetUpperBound(0));
|
||||
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();
|
||||
@@ -243,7 +254,7 @@ namespace Tnb.WarehouseMgr
|
||||
bool isOk = await _warehouseService.GenPreTask(preTasks, pretaskCodes);
|
||||
if (isOk)
|
||||
{
|
||||
_ = await _db.Updateable<WmsCheckstockH>().SetColumns(it => it.status == ((int)EnumCheckStatus.盘点中).ToString()).ExecuteCommandAsync();
|
||||
_ = 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(),
|
||||
@@ -258,9 +269,10 @@ namespace Tnb.WarehouseMgr
|
||||
|
||||
await _db.Ado.CommitTranAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
row = 0;
|
||||
Logger.Error("盘点任务新增失败", ex);
|
||||
await _db.Ado.RollbackTranAsync();
|
||||
throw;
|
||||
}
|
||||
@@ -276,6 +288,18 @@ namespace Tnb.WarehouseMgr
|
||||
return _db.CopyNew().Queryable<WmsDistaskH>().InnerJoin<BasLocation>(joinExp).Where(whereExp).Select<WmsDistaskH>().ToListAsync();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据盘点任务ID获取盘点任务明细
|
||||
/// </summary>
|
||||
/// <param name="checkStockId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("checkStockId")]
|
||||
public async Task<List<WmsCheckstockD>> GetCheckStockDList(string checkStockId)
|
||||
{
|
||||
return await _db.Queryable<WmsCheckstockD>().Where(it => it.checkstock_id == checkStockId).ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据盘点类型获取任务明细
|
||||
/// </summary>
|
||||
@@ -296,19 +320,38 @@ namespace Tnb.WarehouseMgr
|
||||
_carryMap = await _db.Queryable<WmsCarryH>().ToDictionaryAsync(x => x.id, x => x.carry_code);
|
||||
}
|
||||
|
||||
var filterExpable = 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);
|
||||
filterExpable = input.CheckType switch
|
||||
//var filterExpable = Expressionable.Create<BasLocation, WmsCarryCode, WmsCarryH>();
|
||||
Expression<Func<BasLocation, WmsCarryCode, WmsCarryH, bool>> filterExp = (a, b, c) => false;
|
||||
switch (input.CheckType)
|
||||
{
|
||||
EnumCheckType.物料盘点 => filterExpable.AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id),
|
||||
EnumCheckType.批次盘点 => filterExpable.AndIF(input.regionIds?.Count > 0, (a, b, c) => input.regionIds.Contains(a.region_id)),
|
||||
_ => filterExpable,
|
||||
};
|
||||
case EnumCheckType.全库盘点:
|
||||
{
|
||||
filterExp.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);
|
||||
}
|
||||
break;
|
||||
case EnumCheckType.物料盘点:
|
||||
{
|
||||
if (!input.material_id.IsNullOrWhiteSpace())
|
||||
{
|
||||
filterExp.And((a, b, c) => b.material_id == input.material_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EnumCheckType.批次盘点:
|
||||
{
|
||||
if (input.regionIds?.Count > 0)
|
||||
{
|
||||
filterExp.And((a, b, c) => input.regionIds.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())
|
||||
.Where(filterExp)
|
||||
.Select<WmsCarryCode>()
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
@@ -23,8 +23,81 @@ namespace JNPF.Common.Extension
|
||||
}
|
||||
setAction(instance, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lambda表达式拼接
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="first"></param>
|
||||
/// <param name="second"></param>
|
||||
/// <param name="merge"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T1, T2, T3, bool>> Compose<T1, T2, T3>(this Expression<Func<T1, T2, T3, bool>> first, Expression<Func<T1, T2, T3, bool>> second,
|
||||
Func<Expression, Expression, Expression> merge)
|
||||
{
|
||||
// build parameter map (from parameters of second to parameters of first)
|
||||
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
|
||||
// replace parameters in the second lambda expression with parameters from the first
|
||||
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
|
||||
// apply composition of lambda expression bodies to parameters from the first expression
|
||||
return Expression.Lambda<Func<T1, T2, T3, bool>>(merge(first.Body, secondBody), first.Parameters);
|
||||
}
|
||||
/// <summary>
|
||||
/// and扩展
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="first"></param>
|
||||
/// <param name="second"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression<Func<T1,T2,T3, bool>> And<T1, T2, T3>(this Expression<Func<T1, T2, T3, bool>> first, Expression<Func<T1, T2, T3, bool>> second)
|
||||
{
|
||||
if (first.IsNull())
|
||||
{
|
||||
first = second;
|
||||
return first;
|
||||
}
|
||||
|
||||
return first.Compose(second, Expression.And);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ParameterRebinder : ExpressionVisitor
|
||||
{
|
||||
private readonly Dictionary<ParameterExpression, ParameterExpression> map;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
|
||||
{
|
||||
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="exp"></param>
|
||||
/// <returns></returns>
|
||||
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
|
||||
{
|
||||
return new ParameterRebinder(map).Visit(exp);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="p"></param>
|
||||
/// <returns></returns>
|
||||
protected override Expression VisitParameter(ParameterExpression p)
|
||||
{
|
||||
ParameterExpression replacement;
|
||||
if (map.TryGetValue(p, out replacement))
|
||||
{
|
||||
p = replacement;
|
||||
}
|
||||
return base.VisitParameter(p);
|
||||
}
|
||||
}
|
||||
public class PropertySet<T>
|
||||
{
|
||||
public static Dictionary<string, Action<object, object>> ValueFactories = new Dictionary<string, Action<object, object>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
Reference in New Issue
Block a user