Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WmsOutStockService.cs
alex b5feba2109 1
2023-09-05 17:40:39 +08:00

790 lines
47 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.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Aop.Api.Domain;
using JNPF.Common.Contracts;
using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.VisualDev;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Permission;
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.Linq;
using SqlSugar;
using SqlSugar.DbConvert;
using Tnb.BasicData.Entities;
using Tnb.Common.Utils;
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.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 出库申请业务类
/// </summary>
[OverideVisualDev(ModuleConsts.MODULE_WMSOUTSTOCK_ID)]
[ServiceModule(BizTypeId)]
public class WmsOutStockService : BaseWareHouseService, IWmsOutStockService
{
private const string BizTypeId = "26191522660645";
private readonly ISqlSugarClient _db;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IRunService _runService;
private readonly IVisualDevService _visualDevService;
private readonly IWareHouseService _wareHouseService;
private readonly IUserManager _userManager;
private readonly IBillRullService _billRullService;
private readonly IWmsCarryMoveInStockService _wmsCarryMoveInStockService;
private readonly IWmsCarryService _wareCarryService;
public WmsOutStockService(
ISqlSugarRepository<WmsOutstockD> repository,
IDictionaryDataService dictionaryDataService,
IRunService runService,
IVisualDevService visualDevService,
IWareHouseService wareHouseService,
IUserManager userManager,
IBillRullService billRullService,
IWmsCarryMoveInStockService wmsCarryMoveInStockService,
IWmsCarryService wareCarryService,
ITaskMessageNotify taskMessageNotify) : base(taskMessageNotify.Writer)
{
_db = repository.AsSugarClient();
_dictionaryDataService = dictionaryDataService;
_runService = runService;
_visualDevService = visualDevService;
_wareHouseService = wareHouseService;
_userManager = userManager;
_billRullService = billRullService;
_wmsCarryMoveInStockService = wmsCarryMoveInStockService;
_wareCarryService = wareCarryService;
OverideFuncs.CreateAsync = OutStockApplyFor;
}
private async Task<dynamic> OutStockApplyFor(VisualDevModelDataCrInput input)
{
try
{
await _db.Ado.BeginTranAsync();
//判断目标库位是否自动签收
var loc = await _db.Queryable<BasLocation>().SingleAsync(it => it.id == input.data[nameof(WmsPointH.location_id)].ToString());
var carryIds = new List<string>();
//tablefield120 出库物料明细
if (input.data.ContainsKey("tablefield120") && input.data["tablefield120"].IsNotEmptyOrNull())
{
var outStockDList = input.data["tablefield120"].ToObject<List<WmsOutstockD>>();
if (outStockDList?.Count > 0)
{
List<WmsCarryMat> carryMats = new();
List<WmsCarryCode> carryCodes = new();
foreach (var os in outStockDList)
{
var OutStockStrategyInput = new OutStockStrategyQuery
{
carry_id = input.data[nameof(OutStockStrategyQuery.carry_id)].ToString(),
warehouse_id = input.data[nameof(WmsOutstockH.warehouse_id)].ToString(),
material_id = os.material_id,
code_batch = os.code_batch,
};
var outStkCarrys = await _wareHouseService.OutStockStrategy(OutStockStrategyInput);
Expression<Func<WmsCarryH, WmsCarryCode, bool>> whereExp = input.data.ContainsKey(nameof(WmsOutstockH.carry_id))
? (a, b) => a.id == input.data[nameof(WmsOutstockH.carry_id)].ToString()
: (a, b) => outStkCarrys.Select(x => x.id).Contains(b.carry_id);
List<WmsCarryCode>? carryCodesPart = await _db.Queryable<WmsCarryH>().InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id).InnerJoin<BasLocation>((a, b, c) => a.location_id == c.id)
.Where(whereExp)
.Select<WmsCarryCode>()
.ToListAsync();
if (carryCodesPart?.Count > 0)
{
var codeQty = carryCodesPart.Sum(x => x.codeqty);
if (codeQty < os.pr_qty)
{
throw new AppFriendlyException($"需要出库[{os.pr_qty}],实际库存{codeQty},数量不足", 500);
}
List<WmsCarryCode> curCarryCodes = new();
for (int i = 0; i < carryCodesPart.Count; i++)
{
if (os.pr_qty > carryCodesPart[i].codeqty)
{
os.pr_qty -= carryCodesPart[i].codeqty;
curCarryCodes.Add(carryCodesPart[i]);
}
else if (os.pr_qty <= carryCodesPart[i].codeqty)
{
WmsCarryCode curCarryCode = DeepCopyHelper<WmsCarryCode>.DeepCopy(carryCodesPart[i]);
curCarryCode.codeqty = os.pr_qty;
curCarryCodes.Add(curCarryCode);
break;
}
}
carryCodes.AddRange(curCarryCodes);
var partCarryMats = curCarryCodes.Adapt<List<WmsCarryMat>>();
for (int i = 0; i < partCarryMats.Count; i++)
{
partCarryMats[i].need_qty = curCarryCodes[i].codeqty;
}
carryMats.AddRange(partCarryMats);
}
}
if (carryMats.Count > 0)
{
carryMats.ForEach(x => x.id = SnowflakeIdHelper.NextId());
carryMats = carryMats.OrderBy(o => o.create_time).GroupBy(g => new { g.carry_id, g.material_id, g.code_batch })
.Select(x =>
{
var arr = x.ToArray();
WmsCarryMat carryMat = arr[^arr.Length];
carryMat.need_qty = x.Sum(d => d.need_qty);
return carryMat;
})
.ToList();
await _db.Insertable(carryMats).ExecuteCommandAsync();
var dic = carryMats.DistinctBy(x => x.carry_id).ToDictionary(x => x.carry_id, x => x.need_qty);
var allOutIds = new List<string>();
var sortingOutIds = new List<string>();
foreach (var pair in dic)
{
var codes = carryCodes.FindAll(x => x.carry_id == pair.Key);
if (codes?.Count > 0)
{
if (pair.Value == codes.Sum(d => d.codeqty))
{
allOutIds.Add(pair.Key);
}
else
{
sortingOutIds.Add(pair.Key);
}
}
}
carryIds = allOutIds.Concat(sortingOutIds).ToList();
await _db.Updateable<WmsCarryH>().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.).ToString(), source_id = input.data[nameof(WmsOutstockH.source_id)].ToString(), source_code = input.data[nameof(WmsOutstockH.source_code)].ToString() }).Where(it => allOutIds.Contains(it.id)).ExecuteCommandAsync();
await _db.Updateable<WmsCarryH>().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.).ToString(), source_id = input.data[nameof(WmsOutstockH.source_id)].ToString(), source_code = input.data[nameof(WmsOutstockH.source_code)].ToString() }).Where(it => sortingOutIds.Contains(it.id)).ExecuteCommandAsync();
}
var carrys = await _db.Queryable<WmsCarryH>().Where(it => carryIds.Contains(it.id)).ToListAsync();
if (carrys?.Count > 0)
{
var curCarry = carrys[^carrys.Count];
var isMatch = await IsCarryAndLocationMatchByCarryStd(curCarry, loc);
if (!isMatch) throw new AppFriendlyException("该载具无法放置到目标库位", 500);
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSOUTSTOCK_ID, true);
await _runService.Create(templateEntity, input);
List<WmsPretaskH> preTasks = new();
List<string> locIds = new();
foreach (var carry in carrys)
{
WmsPointH sPoint = null!;
WmsPointH ePoint = null!;
if (input.data.ContainsKey(nameof(WmsPointH.location_id)))
{
sPoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == carry.location_id);
}
if (input.data.ContainsKey(nameof(WmsPointH.location_id)) && input.data[nameof(WmsPointH.location_id)].IsNotEmptyOrNull())
{
ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == input.data[nameof(WmsPointH.location_id)].ToString());
}
else if (input.data.ContainsKey(nameof(WmsOutstockH.station_id)))
{
//多个投料库位
/*
* 潍柴
* 1、那个库位状态是空的出那个
* 1.1、没有空位直接抛异常
*
* 天益
* 2、不管库位是否为空 获取到所有库位 A B
* 2.1 根据这些库位去查任务执行 目的库位是这些库位的未完成任务数。 A 10 B 9
* 2.2 哪个最少给哪个
*/
var org = await _db.Queryable<OrganizeEntity>().FirstAsync(it => it.Id == input.data[nameof(WmsOutstockH.station_id)].ToString());
if (!org?.FeedingLocationId.IsNullOrWhiteSpace() ?? false)
{
var fLocIds = JArray.Parse(org.FeedingLocationId).Values<string>();
var minTaskNumLoc = await _db.Queryable<WmsPretaskH>().Where(it => it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && fLocIds.Contains(it.endlocation_id))
.GroupBy(it => it.endlocation_id)
.Select(it => new
{
it.endlocation_id,
count = SqlFunc.AggregateCount(it.endlocation_id)
})
.MergeTable()
.OrderBy(it => it.count)
.FirstAsync();
ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == minTaskNumLoc.endlocation_id);
}
}
if (sPoint != null && ePoint != null)
{
var points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id);
locIds.AddRange(points.Select(x => x.location_id).ToList()!);
//根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
if (points?.Count > 0)
{
if (points.Count <= 2) throw new AppFriendlyException("该路径不存在", 500);
var curPreTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it =>
{
var sPoint = it.FirstOrDefault();
var ePoint = it.LastOrDefault();
WmsPretaskH preTask = new()
{
org_id = _userManager.User.OrganizeId,
startlocation_id = sPoint?.location_id ?? string.Empty,
startlocation_code = sPoint?.location_code ?? string.Empty,
endlocation_id = ePoint?.location_id ?? string.Empty,
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_WMSOUTSTOCK_ID,
task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID,
carry_id = carry.id,
carry_code = carry.carry_code,
area_id = sPoint?.area_id ?? string.Empty,
area_code = it.Key,
require_id = input.data["ReturnIdentity"].ToString(),
require_code = input.data[nameof(preTask.bill_code)]?.ToString()!,
create_id = _userManager.UserId,
create_time = DateTime.Now
};
return preTask;
}).ToList();
if (loc.is_sign == 0)
{
curPreTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值
}
preTasks.AddRange(curPreTasks);
}
}
}
List<WmsPretaskCode> pretaskCodes = new();
foreach (var pt in preTasks)
{
var partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList();
var 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);
}
var isOk = await _wareHouseService.GenPreTask(preTasks, pretaskCodes);
if (isOk)
{
outStockDList.ForEach(x => x.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID);
await _db.Updateable(outStockDList).UpdateColumns(it => it.line_status).ExecuteCommandAsync();
await _db.Updateable<WmsOutstockH>().SetColumns(it => it.status == WmsWareHouseConst.BILLSTATUS_ON_ID).Where(it => it.id == input.data["ReturnIdentity"].ToString()).ExecuteCommandAsync();
GenPreTaskUpInput genPreTaskAfterUpInput = new();
genPreTaskAfterUpInput.CarryIds = preTasks.Select(x => x.carry_id).ToList();
genPreTaskAfterUpInput.LocationIds = new HashSet<string>(locIds).ToList();
await _wareHouseService.GenInStockTaskHandleAfter(genPreTaskAfterUpInput, it => new WmsCarryH { is_lock = 1 }, it => new BasLocation { is_lock = 1 });
}
}
else throw new AppFriendlyException("库存不足", 500);
}
else throw new AppFriendlyException($"请输入物料明细", 500);
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
finally
{
await Publish(nameof(IWareHouseService.GenTaskExecute));
}
return Task.FromResult(true);
}
/// <summary>
/// 根据出库申请单ID获取申请单明细信息
/// </summary>
/// <param name="billId"></param>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> GetInStockDetailsListById([FromRoute] string billId)
{
var dic = await _dictionaryDataService.GetDictionaryByTypeId(WmsWareHouseConst.WMS_INSTOCK_D_BILL_STATUS_TYPEID);
var items = await _db.Queryable<WmsOutstockD>().Where(it => it.bill_id == billId).ToListAsync();
_db.ThenMapper(items,
it => it.line_status = dic.ContainsKey(it.line_status) ? dic[it.line_status]?.ToString()! : "");
return items;
}
/// <summary>
/// 生产出库接口
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
//[NonUnify]
public async Task<dynamic> MESCreateOutstock(MESCreateOutstockInput input)
{
var isSuccessful = true;
try
{
await _db.Ado.BeginTranAsync();
//出库申请主表
WmsOutstockH outstock = input.outstock.Adapt<WmsOutstockH>();
//出库申请明细表
List<WmsOutstockD> outstockDs = input.outstockDs.Adapt<List<WmsOutstockD>>();
var location = await _db.Queryable<BasLocation>().SingleAsync(it => it.location_code == input.outstock.location_code && it.is_type != EnumLocationType..ToString());
//如果数据不全或有误,
if (location.IsNull() || outstockDs?.Count < 1)
{
//报错, 提示数据不全或有误。
throw new AppFriendlyException("数据不全或有误!", 500);
}
// 生成出库申请数据,添加其他数据 主表
outstock.id = SnowflakeIdHelper.NextId();
outstock.location_id = location.id;
outstock.biz_type = WmsWareHouseConst.BIZTYPE_WMSOUTSTOCK_ID;
outstock.bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_OUTSTOCK_ENCODE).GetAwaiter().GetResult();
outstock.generate_type = "1";// 自动
outstock.sync_status = WmsWareHouseConst.SYNC_STATUS__NOTSYNC;//未同步
outstock.status = WmsWareHouseConst.BILLSTATUS_ADD_ID;// 新增
outstock.create_id = _userManager.UserId;
outstock.create_time = DateTime.Now;
//明细表
foreach (var outstockD in outstockDs!)
{
outstockD.id = SnowflakeIdHelper.NextId();
outstockD.bill_id = outstock.id;
outstockD.line_status = WmsWareHouseConst.BILLSTATUS_ADD_ID;
outstockD.qty = 0;
outstock.create_time = outstock.create_time;
outstock.create_id = outstock.create_id;
}
//var loc = await _db.Queryable<BasLocation>().SingleAsync(it => it.id == outstock.location_id.ToString());
var carryIds = new List<string>();
//tablefield120 出库物料明细
var outStockDList = outstockDs.ToObject<List<WmsOutstockD>>();
if (outStockDList?.Count > 0)
{
List<WmsCarryMat> carryMats = new();
List<WmsCarryCode> carryCodes = new();
foreach (var os in outStockDList)
{
var whereExp = Expressionable.Create<WmsCarryH, WmsCarryCode, BasLocation>()
.And((a, b, c) => a.is_lock == 0)
.And((a, b, c) => !string.IsNullOrEmpty(a.location_id))
.And((a, b, c) => a.status == (int)EnumCarryStatus.)
.And((a, b, c) => c.is_type == ((int)EnumLocationType.).ToString())
.And((a, b, c) => b.material_id == os.material_id)
.AndIF(!string.IsNullOrEmpty(os.code_batch), (a, b, c) => b.code_batch == os.code_batch);
var carryCodesPart = await _db.Queryable<WmsCarryH>().InnerJoin<WmsCarryCode>((a, b) => a.id == b.carry_id).InnerJoin<BasLocation>((a, b, c) => a.location_id == c.id)
.Where(whereExp.ToExpression())
.Select<WmsCarryCode>()
.ToListAsync();
if (carryCodesPart?.Count > 0)
{
var codeQty = carryCodes.Sum(x => x.codeqty);
if (codeQty < os.pr_qty)
{
throw new AppFriendlyException($"需要出库[{os.pr_qty}],实际库存{codeQty},数量不足", 500);
}
List<WmsCarryCode> curCarryCodes = new();
for (int i = 0; i < carryCodesPart.Count; i++)
{
if (os.pr_qty > carryCodesPart[i].codeqty)
{
os.pr_qty -= carryCodesPart[i].codeqty;
curCarryCodes.Add(carryCodesPart[i]);
}
else if (os.pr_qty <= carryCodesPart[i].codeqty)
{
var tmp = DeepCopyHelper<WmsCarryCode>.DeepCopy(carryCodesPart[i]);
tmp.codeqty = os.pr_qty;
curCarryCodes.Add(tmp);
break;
}
}
carryCodes.AddRange(curCarryCodes);
var partCarryMats = curCarryCodes.Adapt<List<WmsCarryMat>>();
for (int i = 0; i < partCarryMats.Count; i++)
{
partCarryMats[i].need_qty = curCarryCodes[i].codeqty;
}
carryMats.AddRange(partCarryMats);
}
}
if (carryMats.Count > 0)
{
carryMats.ForEach(x => x.id = SnowflakeIdHelper.NextId());
carryMats = carryMats.OrderBy(o => o.create_time).GroupBy(g => new { g.carry_id, g.material_id, g.code_batch })
.Select(x =>
{
var arr = x.ToArray();
WmsCarryMat carryMat = arr[^arr.Length];
carryMat.need_qty = x.Sum(d => d.need_qty);
return carryMat;
})
.ToList();
await _db.Insertable(carryMats).ExecuteCommandAsync();
var dic = carryMats.DistinctBy(x => x.carry_id).ToDictionary(x => x.carry_id, x => x.need_qty);
var allOutIds = new List<string>();
var sortingOutIds = new List<string>();
foreach (var pair in dic)
{
var codes = carryCodes.FindAll(x => x.carry_id == pair.Key);
if (codes?.Count > 0)
{
if (pair.Value == codes.Sum(d => d.codeqty))
{
allOutIds.Add(pair.Key);
}
else
{
sortingOutIds.Add(pair.Key);
}
}
}
carryIds = allOutIds.Concat(sortingOutIds).ToList();
if (carryIds?.Count > 0)
{
var carryId = carryIds[^carryIds.Count];
var curCurry = await _db.Queryable<WmsCarryH>().SingleAsync(it => it.id == carryId);
var isMatch = await IsCarryAndLocationMatchByCarryStd(curCurry, location);
if (!isMatch) throw new AppFriendlyException("该载具无法放置到目标库位", 500);
}
await _db.Insertable(outstock).ExecuteCommandAsync();
await _db.Insertable(outstockDs).ExecuteCommandAsync();
await _db.Updateable<WmsCarryH>().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.).ToString(), source_id = outstock.source_id, source_code = outstock.source_code }).Where(it => allOutIds.Contains(it.id)).ExecuteCommandAsync();
await _db.Updateable<WmsCarryH>().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.).ToString(), source_id = outstock.source_id, source_code = outstock.source_code }).Where(it => sortingOutIds.Contains(it.id)).ExecuteCommandAsync();
}
var carrys = await _db.Queryable<WmsCarryH>().Where(it => carryIds.Contains(it.id)).ToListAsync();
if (carrys?.Count > 0)
{
List<WmsPretaskH> preTasks = new();
List<string> locIds = new();
foreach (var carry in carrys)
{
WmsPointH sPoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == carry.location_id);
WmsPointH ePoint = await _db.Queryable<WmsPointH>().FirstAsync(it => it.location_id == outstock.location_id.ToString());
if (sPoint != null && ePoint != null)
{
var points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id);
locIds.AddRange(points.Select(x => x.location_id).ToList()!);
//根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
if (points?.Count > 0)
{
if (points.Count <= 2) throw new AppFriendlyException("该路径不存在", 500);
var curPreTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it =>
{
var sPoint = it.FirstOrDefault();
var ePoint = it.LastOrDefault();
WmsPretaskH preTask = new()
{
org_id = _userManager.User.OrganizeId,
startlocation_id = sPoint?.location_id ?? string.Empty,
startlocation_code = sPoint?.location_code ?? string.Empty,
endlocation_id = ePoint?.location_id ?? string.Empty,
endlocation_code = ePoint?.location_code ?? string.Empty,
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_WMSOUTSTOCK_ID,
task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID,
carry_id = carry.id,
carry_code = carry.carry_code,
area_id = sPoint?.area_id ?? string.Empty,
area_code = it.Key,
require_id = outstock.id.ToString(),
require_code = outstock.bill_code?.ToString(),
create_id = _userManager.UserId,
create_time = DateTime.Now,
source_id = outstock.source_id,
source_code = outstock.source_code,
};
return preTask;
}).ToList();
if (location.is_sign == 0)
{
curPreTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值
}
preTasks.AddRange(curPreTasks);
}
}
}
List<WmsPretaskCode> pretaskCodes = new();
foreach (var pt in preTasks)
{
var partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList();
var 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);
}
var isOk = await _wareHouseService.GenPreTask(preTasks, pretaskCodes);
if (isOk)
{
outstockDs.ForEach(x => x.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID);
await _db.Updateable(outstockDs).UpdateColumns(it => it.line_status).ExecuteCommandAsync();
await _db.Updateable<WmsOutstockH>().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == outstock.id).ExecuteCommandAsync();
GenPreTaskUpInput genPreTaskAfterUpInput = new();
genPreTaskAfterUpInput.CarryIds = preTasks.Select(x => x.carry_id).ToList();
genPreTaskAfterUpInput.LocationIds = new HashSet<string>(locIds).ToList();
await _wareHouseService.GenInStockTaskHandleAfter(genPreTaskAfterUpInput, it => new WmsCarryH { is_lock = 1 }, it => new BasLocation { is_lock = 1 });
}
}
else throw new AppFriendlyException("库存不足", 500);
}
else throw new AppFriendlyException($"请输入物料明细", 500);
await _db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
isSuccessful = false;
JNPF.Logging.Log.Error(ex.Message);
await _db.Ado.RollbackTranAsync();
throw;
}
finally
{
await Publish(nameof(IWareHouseService.GenTaskExecute));
}
return isSuccessful;
}
public override async Task ModifyAsync(WareHouseUpInput input)
{
if (input == null) throw new ArgumentNullException(nameof(input));
try
{
await _db.Ado.BeginTranAsync();
var carryId = input.carryIds[^input.carryIds.Count];
var carry = await _db.Queryable<WmsCarryH>().SingleAsync(it => it.id == carryId);
if (carry != null)
{
var otds = await _db.Queryable<WmsOutstockD>().Where(it => it.bill_id == input.requireId).ToListAsync();
var outStatus = carry.out_status.ToEnum<EnumOutStatus>();
if (outStatus == EnumOutStatus.)
{
//当前载具对应的所有条码插入
var carryCodes = await _db.Queryable<WmsCarryCode>().Where(it => it.carry_id == carryId).ToListAsync();
var outStockCodes = carryCodes.Adapt<List<WmsOutstockCode>>();
outStockCodes.ForEach(x =>
{
var billDId = otds?.Find(xx => xx.material_id == x.material_id && xx.code_batch == x.code_batch)?.id;
if (billDId.IsNullOrEmpty())
{
billDId = otds?.Find(xx => xx.material_id == x.material_id)?.id;
}
x.id = SnowflakeIdHelper.NextId();
x.bill_id = input.requireId;
x.bill_d_id = billDId!;
x.org_id = _userManager.User.OrganizeId;
x.create_id = _userManager.UserId;
x.create_time = DateTime.Now;
});
await _db.Insertable(outStockCodes).ExecuteCommandAsync();
var detailIds = outStockCodes.Select(x => x.bill_d_id).ToList();
var curOutstockDetails = otds.FindAll(x => detailIds.Contains(x.id));
var dic = outStockCodes.GroupBy(g => g.bill_d_id).ToDictionary(x => x.Key, x => x.Select(x => x.codeqty).ToList());
foreach (var osd in curOutstockDetails)
{
if (dic.ContainsKey(osd.id))
{
osd.qty += dic[osd.id].Sum(d => d);
if (osd.qty >= osd.pr_qty)
{
osd.line_status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID;
}
else
{
osd.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID;
}
}
}
await _db.Updateable(curOutstockDetails).ExecuteCommandAsync();
if (otds.All(x => x.line_status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID))
{
await _db.Updateable<WmsOutstockH>().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync();
//如果是自动单据,需要回更上层系统
}
else
{
//如果没有完成,修改为工作中
await _db.Updateable<WmsOutstockH>().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync();
}
await _wareCarryService.UpdateNullCarry(carry).Unwrap();
}
else if (outStatus == EnumOutStatus.)
{
if (input.distaskCodes?.Count > 0)
{
var osCodes = input.distaskCodes.Adapt<List<WmsOutstockCode>>();
osCodes.ForEach(x =>
{
var billDId = otds?.Find(xx => xx.material_id == x.material_id && xx.code_batch == x.code_batch)?.id;
if (billDId.IsNullOrEmpty())
{
billDId = otds?.Find(xx => xx.material_id == x.material_id)?.id;
}
x.id = SnowflakeIdHelper.NextId();
x.bill_id = input.requireId;
x.bill_d_id = billDId!;
x.org_id = _userManager.User.OrganizeId;
x.create_id = _userManager.UserId;
x.create_time = DateTime.Now;
});
await _db.Insertable(osCodes).ExecuteCommandAsync();
// 更新主表
var detailIds = osCodes.Select(x => x.bill_d_id).ToList();
var curOutstockDetails = otds.FindAll(x => detailIds.Contains(x.id));
var dic = osCodes.GroupBy(g => g.bill_d_id).ToDictionary(x => x.Key, x => x.Select(x => x.codeqty).ToList());
foreach (var osd in curOutstockDetails)
{
if (dic.ContainsKey(osd.id))
{
osd.qty += dic[osd.id].Sum(d => d);
if (osd.qty >= osd.pr_qty)
{
osd.qty = osd.pr_qty;
osd.line_status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID;
}
else
{
osd.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID;
}
}
}
await _db.Updateable(curOutstockDetails).ExecuteCommandAsync();
if (otds.All(x => x.line_status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID))
{
//如果是自动单据,需要回更上层系统
await _db.Updateable<WmsOutstockH>().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync();
}
else
{
//如果没有完成,修改为工作中
await _db.Updateable<WmsOutstockH>().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync();
}
var carryCodes = await _db.Queryable<WmsCarryCode>().Where(it => input.carryIds.Contains(it.carry_id!)).ToListAsync();
var dicCodeQty = carryCodes.GroupBy(g => g.barcode).ToDictionary(x => x.Key, x => x.First().codeqty);
var dicUpdate = new Dictionary<string, decimal>();
var delBarcodes = new List<string>();
foreach (var dtc in input.distaskCodes)
{
if (dicCodeQty.ContainsKey(dtc.barcode))
{
if (dtc.codeqty < dicCodeQty[dtc.barcode])
{
dicUpdate[dtc.barcode] = dicCodeQty[dtc.barcode] - dtc.codeqty;
}
else
{
delBarcodes.Add(dtc.barcode);
}
}
}
if (dicUpdate.Count > 0)
{
foreach (var pair in dicUpdate)
{
WmsCarryCode? carryCode = carryCodes.Find(x => x.barcode == pair.Key);
if (carryCode != null)
{
carryCode.codeqty = pair.Value;
await _db.Updateable(carryCode).UpdateColumns(it => it.codeqty).ExecuteCommandAsync();
}
}
var row = await _db.Updateable<WmsCarryH>().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.).ToString() }).Where(it => input.carryIds.Contains(it.id)).ExecuteCommandAsync();
await _db.Deleteable<WmsCarryMat>().Where(it => input.carryIds.Contains(it.carry_id)).ExecuteCommandAsync();
}
if (delBarcodes.Count > 0)
{
await _db.Deleteable<WmsCarryCode>().Where(it => delBarcodes.Contains(it.barcode)).ExecuteCommandAsync();
}
//载具移入
var outStockH = await _db.Queryable<WmsOutstockH>().SingleAsync(it => it.id == input.requireId);
var visulDevInput = new VisualDevModelDataCrInput();
visulDevInput.data = new Dictionary<string, object>
{
[nameof(InStockStrategyQuery.warehouse_id)] = outStockH.warehouse_id,
[nameof(WmsPointH.location_id)] = outStockH.location_id,
[nameof(WmsCarryD.carry_id)] = input.carryIds.First(),
[nameof(WmsCarryH.carry_code)] = carry.carry_code,
[nameof(WmsHandleH.biz_type)] = input.bizTypeId,
[nameof(WmsHandleH.create_id)] = _userManager.UserId,
[nameof(WmsHandleH.create_time)] = DateTime.Now,
[nameof(WmsMoveInstock.status)] = WmsWareHouseConst.BILLSTATUS_ADD_ID,
[nameof(WmsHandleH.bill_code)] = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_CARRYMOINSTK_ENCODE).GetAwaiter().GetResult(),
};
await _wmsCarryMoveInStockService.CarryMoveIn(visulDevInput);
}
}
await _db.Ado.CommitTranAsync();
}
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
}
}