diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs
index 7f6b7c93..7af0180e 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs
@@ -32,6 +32,10 @@ namespace Tnb.WarehouseMgr.Entities.Consts
///
public const string WMS_CARRYMOINSTK_ENCODE = "CarryMoInStk";
///
+ /// 出库申请生成Encode
+ ///
+ public const string WMS_OUTSTOCK_ENCODE = "WmsOutStock";
+ ///
/// 入库申请生成Encode
///
public const string WMS_INSTOCK_ENCODE = "WmsInStock";
diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESCreateOutstockInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESCreateOutstockInput.cs
new file mode 100644
index 00000000..7b955ca4
--- /dev/null
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESCreateOutstockInput.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tnb.WarehouseMgr.Entities.Dto.Inputs
+{
+ public class MESCreateOutstockInput
+ {
+ ///
+ /// 生产出库主表
+ ///
+ public WmsOutstockH? outstock { get; set; }
+ ///
+ /// 生产出库明细表
+ ///
+ public List? outstockDs { get; set; }
+ }
+}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsOutStockService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsOutStockService.cs
index 85cbaa0d..1bfc9734 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr/WmsOutStockService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsOutStockService.cs
@@ -19,10 +19,12 @@ using Microsoft.AspNetCore.Mvc;
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;
@@ -305,7 +307,215 @@ namespace Tnb.WarehouseMgr
//}
//var str = "";
}
+ [HttpPost]
+ public async Task MESCreateOutstock(MESCreateOutstockInput input)
+ {
+ try
+ {
+ await _db.Ado.BeginTranAsync();
+ //出库申请主表
+ WmsOutstockH outstock = input.outstock;
+ //出库申请明细表
+ List outstockDs = input.outstockDs;
+ //如果数据不全,
+ if (outstock.IsNull() || outstock.location_id.IsNullOrWhiteSpace() || outstockDs?.Count < 1)
+ {
+ //报错, 提示数据不全。
+ throw new AppFriendlyException("数据不全!", 500);
+ }
+ // 生成入库申请数据,添加其他数据 主表
+ outstock.id = SnowflakeIdHelper.NextId();
+ 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;
+ await _db.Insertable(outstock).ExecuteCommandAsync();
+ //明细表
+ 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;
+ }
+ await _db.Insertable(outstockDs).ExecuteCommandAsync();
+ var loc = await _db.Queryable().SingleAsync(it => it.id == outstock.location_id.ToString());
+ var carryIds = new List();
+ //tablefield120 出库物料明细
+ var outStockDList = outstockDs.ToObject>();
+ if (outStockDList?.Count > 0)
+ {
+ List carryMats = new();
+ List carryCodes = new();
+ foreach (var os in outStockDList)
+ {
+ var carryCodesPart = await _db.Queryable().InnerJoin((a, b) => a.id == b.carry_id).InnerJoin((a, b, c) => a.location_id == c.id)
+ .Where((a, b, c) => b.material_id == os.material_id && a.is_lock == 0 && !string.IsNullOrEmpty(a.location_id) && a.status == (int)EnumCarryStatus.占用 && c.is_type == ((int)EnumLocationType.存储库位).ToString())
+ .WhereIF(!string.IsNullOrEmpty(os.code_batch), (a, b) => b.code_batch == os.code_batch)
+ .Select()
+ .ToListAsync();
+ if (carryCodesPart?.Count > 0)
+ {
+ carryCodes.AddRange(carryCodesPart);
+ var codeQty = carryCodes.Sum(x => x.codeqty);
+ if (codeQty < os.pr_qty)
+ {
+ throw new AppFriendlyException($"需要出库[{os.pr_qty}],实际库存{codeQty},数量不足", 500);
+ }
+ List 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)
+ {
+ carryCodesPart[i].codeqty = os.pr_qty;
+ curCarryCodes.Add(carryCodesPart[i]);
+ break;
+ }
+ }
+ var partCarryMats = curCarryCodes.Adapt>();
+ for (int i = 0; i < partCarryMats.Count; i++)
+ {
+ partCarryMats[i].need_qty = carryCodesPart[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 =>
+ {
+ WmsCarryMat? carryMat = x.FirstOrDefault()!;
+ 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();
+ var sortingOutIds = new List();
+ 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().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.全部出).ToString() }).Where(it => allOutIds.Contains(it.id)).ExecuteCommandAsync();
+ await _db.Updateable().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.分拣出).ToString() }).Where(it => sortingOutIds.Contains(it.id)).ExecuteCommandAsync();
+ }
+ var carrys = await _db.Queryable().Where(it => carryIds.Contains(it.id)).ToListAsync();
+ if (carrys?.Count > 0)
+ {
+ List preTasks = new();
+ List locIds = new();
+ foreach (var carry in carrys)
+ {
+ WmsPointH sPoint = null!;
+ WmsPointH ePoint = null!;
+ sPoint = await _db.Queryable().FirstAsync(it => it.location_id == carry.location_id);
+ ePoint = await _db.Queryable().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!,
+ 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(),
+ 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!,
+ area_code = it.Key,
+ require_id = outstock.id.ToString()
+ };
+ preTask.require_code = outstock.bill_code?.ToString()!;
+ preTask.create_id = _userManager.UserId;
+ preTask.create_time = DateTime.Now;
+ return preTask;
+ }).ToList();
+ if (loc.is_sign == 0)
+ {
+ curPreTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值
+ }
+ preTasks.AddRange(curPreTasks);
+
+ }
+ }
+ }
+ List pretaskCodes = new();
+ foreach (var pt in preTasks)
+ {
+ var partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList();
+ var curPreTaskCodes = partCodes.Adapt>();
+ 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);
+ GenPreTaskUpInput genPreTaskAfterUpInput = new();
+ genPreTaskAfterUpInput.CarryIds = preTasks.Select(x => x.carry_id).ToList();
+ genPreTaskAfterUpInput.LocationIds = new HashSet(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)
+ {
+ JNPF.Logging.Log.Error(ex.Message);
+ await _db.Ado.RollbackTranAsync();
+ return await ToApiResult(JNPF.Common.Enums.HttpStatusCode.InternalServerError, ex.Message);
+ }
+ return await ToApiResult();
+ }
public override async Task ModifyAsync(WareHouseUpInput input)
{