using Rhea.Common;
|
using Tiger.IBusiness;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using Tiger.Model;
|
using Tiger.Model.Sharetronic.Shelf;
|
|
namespace Tiger.Business.WMS.Transaction
|
{
|
/// <summary>
|
/// 调拨调度事务
|
/// </summary>
|
public class OutTransfer : WMSTransactionBase, IOutTransfer
|
{
|
public IOutTransfer Init(string id, string userCode, string apiHost, string orgCode)
|
{
|
TransID = id;
|
UserCode = userCode;
|
ApiHost = apiHost;
|
OrgCode = orgCode;
|
Logger.Console.Info($"Start {this.GetType().Name} Transaction[ID: {TransID}]");
|
return this;
|
}
|
|
#region Propertys & Variables
|
|
public string UserCode { get; set; }
|
public long UserId { get; set; }
|
public string OrgCode { get; set; }
|
public List<SuggestItem> Suggests { get; set; } = new();
|
public List<WMS_ITEM_POOL> CurPoolList => Suggests.Where(q => !q.poolItem.IsNullOrEmpty()).Select(q => q.poolItem).ToList();
|
public List<WMS_LOCATION> LocationHis { get; set; } = new();
|
public Inventory CurInv { get; set; }
|
public BIZ_WMS_TRANSFER req { get; set; }
|
public List<BIZ_WMS_TRANSFER_DTL> dtls { get; set; }
|
public ReqType CurReqType { get; set; }
|
public bool isExceed { get; set; }
|
public bool isCutting { get; set; }
|
public ProductionPickToMes toMes { get; set; }
|
public bool his_isComplete { get; set; }
|
public bool isManual { get; set; }
|
public double cutQty { get; set; }
|
|
#endregion Propertys & Variables
|
|
#region Functions
|
|
/// <summary>
|
/// 调拨单选择事件
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
public async Task<ApiAction<ProdReqOutput>> SelectOrder(ProdReqInput input)
|
{
|
var action = new ApiAction<ProdReqOutput>();
|
try
|
{
|
req = await Biz.Db.Queryable<BIZ_WMS_TRANSFER>().Where(x => x.ORDER_NO == input.ReqNo).Includes(q => q.DtlsWithGhost, d => d.ItemInfo).IncludesAllFirstLayer().FirstAsync();
|
//验证明细是否正确
|
if (!req.Dtls.Any())
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = new("WMS.ProdMReq.SelectOrder.DtlsException", input.ReqNo);
|
return action;
|
}
|
|
//如果是手工创建的调拨单
|
isManual = req.STATUS == BIZ_WMS_TRANSFER.STATUSs.Imported.GetValue();
|
|
Biz.Db.Deleteable<WMS_ITEM_POOL>().Where(q => q.TRANS_CODE == req.ORDER_NO).ExecuteCommand();
|
//如果上一次推荐有数据,则先灭掉亮的灯
|
if (Suggests.Any())
|
{
|
await CloseLight(LocationHis);
|
}
|
|
var begin = DateTime.Now;
|
var ElapsedTime = 0.0;
|
var sumDtls = req.Dtls.Where(q => q.STATUS != BIZ_WMS_TRANSFER.STATUSs.Finished.GetValue())
|
.GroupBy(x => new { x.ITEM_CODE }).Select(x => new { ItemCode = x.Key.ITEM_CODE.ToString(), WarehouseCode = x.Max(t => t.OUT_WH_CODE), actQty = x.Sum(t => t.QTY_REQ - t.QTY_OUT), lockObj = new object() });
|
var dic = sumDtls.ToDictionary(k => k, v => new Result<List<SuggestItem>>());
|
foreach (var item in dic)
|
{
|
var key = item.Key;
|
Work.DoAsync(() =>
|
{
|
lock (item.Key.lockObj)
|
{
|
dic[item.Key] = WMS_ITEM_Biz.WmsItem.Suggest(req.ORDER_NO, item.Key.ItemCode, item.Key.WarehouseCode, null, null, null, input.AuthOption, item.Key.actQty);
|
}
|
});
|
}
|
while (dic.Any() && dic.Any(q => q.Value.IsNormal)) ;
|
ElapsedTime = (DateTime.Now - begin).TotalSeconds;
|
//Debug.WriteLine($"Async suggest end, elapsed total {ElapsedTime} seconds");
|
if (dic.Any(q => q.Value.IsException))
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = dic.Where(q => q.Value.IsException).Select(q => q.Value.LocaleMsg).First();
|
return action;
|
}
|
if (dic.Any(q => q.Value.IsWarning))
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = new("WMS.WmsItem.Suggest.Warning", string.Join(", ", dic.Where(q => q.Value.IsWarning).Select(q => q.Key.ItemCode)));
|
}
|
Suggests.Clear();
|
dic.Select(x => x.Value.Data).ToList().ForEach((item) =>
|
{
|
Suggests.AddRange(item);
|
});
|
Suggests.ForEach((inv) =>
|
{
|
var actQty = sumDtls.ToList().Where(x => x.ItemCode.Trim() == inv.Item.ITEM_CODE.Trim()).Select(x => x.actQty).FirstOrDefault();
|
if (actQty > 0)
|
{
|
inv.poolItem = inv.Item.GetPoolItem(input.AuthOption.OrgCode, nameof(req), req.ORDER_NO, null, actQty, false);
|
}
|
else
|
{
|
inv.poolItem = null;
|
}
|
});
|
Suggests.RemoveAll(q => q.poolItem.IsNullOrEmpty());
|
|
//保存物料池到数据库
|
Biz.Db.Insertable(CurPoolList).ExecuteCommand();
|
action = await LightAll(new() { AuthOption = input.AuthOption, ReqType = CurReqType, Color = LedColor.Blue });
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"调拨单选择异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 调拨单推荐所有物料亮灯
|
/// </summary>
|
/// <param name="light"></param>
|
/// <returns></returns>
|
public async Task<ApiAction<ProdReqOutput>> LightAll(LightEntityInput light)
|
{
|
var action = new ApiAction<ProdReqOutput>();
|
try
|
{
|
var list = Suggests.WhereIF(!light.ItemCode.IsNullOrEmpty(), q => q.Item.ITEM_CODE == light.ItemCode);
|
if (list.Any())
|
{
|
list = list.Where(q => q.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.Smart.GetValue() || q.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.QRCode.GetValue());
|
if (list.Any())
|
{
|
list = list.Where(q => q.poolItem.STATUS < WMS_ITEM_POOL.STATUSs.WaitSend.GetValue());
|
if (list.Any())
|
{
|
var locs = list.Select(x => x.Location.AddShelf(x.Shelf)).ToList();
|
LocationHis.AddRange(locs);
|
//亮灯前先灭一遍
|
foreach (var shelf in list.Select(q => q.Shelf))
|
{
|
await Share.Shelf.DownAll(shelf);
|
}
|
await Share.Shelf.LightMulti(TransID, light.Color, locs);
|
action.Data = new ProdReqOutput()
|
{
|
ReqNo = req.ORDER_NO,
|
ReqType = light.ReqType.GetValue()
|
};
|
action.LocaleMsg = Biz.L("亮灯成功,亮灯颜色[{0}]", light.Color.GetDesc());
|
}
|
else
|
{
|
action.LocaleMsg = Biz.L($"无需亮灯,推荐的物料已全部下架");
|
}
|
}
|
else
|
{
|
action.LocaleMsg = Biz.L($"无需亮灯,推荐的物料不在智能货架上");
|
}
|
}
|
else
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L($"亮灯失败,未找到推荐下架的物料");
|
}
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"亮灯异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 调拨单发料明细
|
/// </summary>
|
/// <returns></returns>
|
public async Task<ApiAction> ProdReqDtl(string itemcode)
|
{
|
var action = new ApiAction();
|
try
|
{
|
var dtls = req.Dtls.GroupBy(x => new { x.ORDER_LINE, x.ITEM_CODE, x.ItemInfo.ITEM_NAME }).Select(x => new ProdReqDtl() { BillLine = x.Key.ORDER_LINE.ToInt32(), ItemCode = x.Key.ITEM_CODE, ItemName = x.Key.ITEM_NAME, Status = "", Items = new List<ProdReqDtlItems>() }).ToList();
|
foreach (var d in dtls)
|
{
|
d.Items = Suggests.Where(x => x.Item.ITEM_CODE == d.ItemCode).Select(x => new ProdReqDtlItems { WHCode = x.Warehouse.WH_CODE, LocationCode = x.Location.LOCATION_CODE, SN = x.Item.SN, QTY = x.Item.QTY }).ToList();
|
d.Status = $"{(double)req.Dtls.Where(x => x.ITEM_CODE == d.ItemCode).Sum(x => x.QTY_OUT)} / {(double)req.Dtls.Where(x => x.ITEM_CODE == d.ItemCode).Sum(x => x.QTY_REQ)} {Suggests.FirstOrDefault()?.Item?.UNIT} (还需{d.Items.Count}个)";
|
}
|
action.Data = itemcode.IsNullOrEmpty() ? dtls.OrderBy(q => q.BillLine) : dtls.Where(x => x.ItemCode == itemcode).FirstOrDefault()?.Items.OrderBy(q => q.SN);
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"获取调拨单明细异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 发料明细提示信息
|
/// </summary>
|
/// <returns></returns>
|
public async Task<ApiAction> GetItemTips(string itemcode)
|
{
|
var action = new ApiAction();
|
try
|
{
|
action.Data = $"物料{itemcode}:已下架[{(double)req.Dtls.Where(x => x.ITEM_CODE == itemcode).Sum(x => x.QTY_OUT)}],共{(double)req.Dtls.Where(x => x.ITEM_CODE == itemcode).Sum(x => x.QTY_REQ)} {Suggests.FirstOrDefault()?.Item?.UNIT}";
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"获取发料明细提示信息异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 灭灯
|
/// </summary>
|
/// <returns></returns>
|
public async Task<ApiAction> CloseLight(List<WMS_LOCATION> locations = null)
|
{
|
var action = new ApiAction();
|
try
|
{
|
if (locations != null)
|
{
|
foreach (var shelf in locations.Select(q => q.Shelf))
|
{
|
await Share.Shelf.DownAll(shelf);
|
}
|
}
|
//灭灯
|
await Share.Shelf.DownMulti(TransID, locations.IsNullOrEmpty(Suggests.Where(q => q.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.Smart.GetValue() || q.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.QRCode.GetValue())
|
.Select(x => x.Location).ToList()));
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"灭灯异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 扫描物料调度下架
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
public async Task<ApiAction<ProdReqOutput>> ScanItem(BaseInput input)
|
{
|
var action = new ApiAction<ProdReqOutput>();
|
try
|
{
|
if (input.SN.IsNullOrEmpty())
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("条码不能为空");
|
return action;
|
}
|
|
//解析条码
|
Result<IInventory> result = WMS_ITEM_Biz.WmsItem.Get(input.SN, input.AuthOption, true);
|
if (!result.IsSuccessed)
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = result.LocaleMsg;
|
return action;
|
}
|
CurInv = result.Data as Inventory;
|
|
//验证条码是否正确
|
if (!CurInv.isNormalStatus || CurInv.Status != WMS_ITEM.STATUSs.InStore)
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("WMS.ProdMReq.ScanItem.StatusException", string.Join(',', CurInv.StatusList.Select(x => x.GetDesc())));
|
return action;
|
}
|
|
//储位验证
|
if (CurInv.Location.IsNullOrEmpty())
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("WMS.ProdMReq.ScanItem.LocationIsNull", CurInv.CurPkg.SN, CurInv.CurPkg.LOCATION_ID);
|
return action;
|
}
|
|
//物料验证
|
if (CurInv.ItemInfo.IsNullOrEmpty() || CurInv.ItemInfo.IS_ACTIVE == "N")
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("WMS.ProdMReq.ScanItem.ItemCodeNotExistsOrNotActive", CurInv.ItemInfo.ITEM_CODE.IsNullOrEmpty(CurInv.Barcode.ItemCode));
|
return action;
|
}
|
|
//仓库卡控
|
if (!req.Dtls.Any(q => q.ITEM_CODE == CurInv.ItemInfo.ITEM_CODE && q.OUT_WH_CODE == CurInv.Warehouse.WH_CODE))
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L($"条码[{CurInv.Barcode.SN}]的料号或者仓库跟单据[{req.ORDER_NO}]上的不一致");
|
return action;
|
}
|
|
//1.判断FIFO
|
//if (Suggests.Where(x => Barcode.IsReprint(x.Item.SN) && x.Item.ITEM_CODE == CurInv.ItemInfo.ITEM_CODE).Any() && !CurInv.Barcode.IsReprintSn)
|
//{
|
// action.IsSuccessed = false;
|
// action.LocaleMsg = Biz.L("需要先出拆包的物料");
|
// return action;
|
//}
|
var MaxDC = CurPoolList.Any(x => x.ITEM_CODE == CurInv.ItemInfo.ITEM_CODE) ? CurPoolList.Where(x => x.ITEM_CODE == CurInv.ItemInfo.ITEM_CODE).Max(t => t.PROD_DATE) : DateTime.MinValue;
|
//判断系统参数是否设置先进先出
|
if (Cache.SysParam["YesOrNo"].PARAM_VALUE == "Y")
|
{
|
if (CurInv.Items.Max(x => x.PROD_DATE).Date > MaxDC.Date)
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("必需先进先出", CurInv.Items.Max(x => x.PROD_DATE).Date, MaxDC.Date);
|
return action;
|
}
|
}
|
//判断物料是否在超期日期范围内
|
//if (CurInv.ItemInfo.VALIDITY_DAYS > 0)
|
//{
|
// var time = DateTime.Now;
|
// if (CurInv.Items.Count() > 0)
|
// {
|
// foreach (var item in CurInv.Items)
|
// {
|
// //判断是否有生产日期
|
// if (!item.PROD_DATE.IsNullOrEmpty() && item.PROD_DATE.ToString() != "1900/1/1 0:00:00")
|
// {
|
// var t = time - item.PROD_DATE;
|
// decimal timeDifference = (decimal)t.TotalDays;
|
// if (timeDifference > CurInv.ItemInfo.VALIDITY_DAYS)
|
// {
|
// action.IsSuccessed = false;
|
// action.LocaleMsg = Biz.L("产品超出有效期范围", timeDifference);
|
// return action;
|
// }
|
// }
|
// //否则以首次入库时间
|
// else if (!item.FIRST_IN_DATE.IsNullOrEmpty() && item.FIRST_IN_DATE.ToString() != "1900/1/1 0:00:00")
|
// {
|
// var t = time - item.PROD_DATE;
|
// decimal timeDifference = (decimal)t.TotalDays;
|
// if (timeDifference > CurInv.ItemInfo.VALIDITY_DAYS)
|
// {
|
// action.IsSuccessed = false;
|
// action.LocaleMsg = Biz.L("产品超出有效期范围", timeDifference);
|
// return action;
|
// }
|
// }
|
|
// }
|
// }
|
//}
|
|
//2.是否超发
|
isExceed = false;
|
req = await Biz.Db.Queryable<BIZ_WMS_TRANSFER>().Where(x => x.ORDER_NO == req.ORDER_NO).Includes(q => q.DtlsWithGhost, d => d.ItemInfo).IncludesAllFirstLayer().FirstAsync();
|
dtls = req.Dtls.Where(x => x.ITEM_CODE == CurInv.ItemInfo.ITEM_CODE).ToList();
|
if (dtls.IsNullOrEmpty())
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("调拨单明细没有这个物料");
|
return action;
|
}
|
|
//如果状态完成
|
if (dtls.Where(x => x.STATUS == BIZ_WMS_TRANSFER.STATUSs.Finished.GetValue()).Count() == dtls.Count)
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("料已经发完");
|
return action;
|
}
|
var actQty = dtls.Sum(x => x.QTY_OUT > x.QTY_REQ ? 0 : x.QTY_REQ - x.QTY_OUT);
|
cutQty = 0;
|
if (actQty < CurInv.CurPkg.QTY)
|
{
|
isExceed = true;
|
cutQty = CurInv.CurPkg.QTY - actQty;
|
}
|
|
//3.是否截料,不允许超发的物料,所有的单别都需要做拆包处理,自动调用拆包,允许超发的物料,单别5408或者5409的要拆包
|
isCutting = false;
|
double curQty = CurInv.CurPkg.QTY;
|
foreach (var d in dtls)
|
{
|
var actPrQty = d.QTY_REQ - d.QTY_OUT;
|
if (actPrQty > 0 && curQty > 0)
|
{
|
if (actPrQty >= curQty)
|
{
|
d.QTY_OUT += curQty;
|
curQty = 0;
|
}
|
else
|
{
|
d.QTY_OUT = d.QTY_REQ;
|
curQty -= actPrQty;
|
}
|
d.STATUS = d.QTY_OUT >= d.QTY_REQ ? BIZ_WMS_TRANSFER.STATUSs.Finished.GetValue() : BIZ_WMS_TRANSFER.STATUSs.Storing.GetValue();
|
//d.OUTWAREHOUSECODE = CurInv.Warehouse.WH_CODE;
|
}
|
}
|
if (isExceed)
|
{
|
if (CurInv.ItemInfo.DLVY_TYPE == BAS_ITEM.DLVY_TYPEs.ByDemand.GetValue() || req.ORDER_NO.Substring(2, 4) == "5408" || req.ORDER_NO.Substring(2, 4) == "5409")
|
{
|
isCutting = true;
|
isExceed = false;
|
if (CurInv.Items.Count > 1)
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = Biz.L("扫描的条码不是最小包装,不能拆包!");
|
return action;
|
}
|
}
|
else
|
{
|
//最大数量明细行用于调拨,该行发料数量加上应截料数量
|
var tfdtl = dtls.OrderBy(q => q.ORDER_LINE.ToDecimal()).Last();
|
tfdtl.QTY_OUT += cutQty;
|
}
|
}
|
|
//var reqSn = new BIZ_WMS_TRANSFER_SN()
|
//{
|
// AUTH_ORG = OrgCode,
|
// SN = CurInv.CurPkg.SN,
|
// ITEM_CODE = CurInv.ItemInfo.ITEM_CODE,
|
// QTY = CurInv.CurPkg.QTY,
|
// META_SN = CurInv.Barcode.MetaSn,
|
// BILLCODE = req.BILLCODE,
|
// BILLDATE = req.BILLDATE,
|
// //BILLLINE = tfdtl.BILLLINE
|
//};
|
|
////4.更新业务单据,BIZ_WMS_TRANSFER、BIZ_WMS_TRANSFER_DTL、BIZ_WMS_TRANSFER_SN 判断明细行状态是否完成
|
//var isComplete = !req.Dtls.Any(x => x.LINESTATUS != BIZ_WMS_TRANSFER.STATUSs.COMPLETE.GetValue() && x.PRQTY > 0);
|
//his_isComplete = isComplete;
|
//if (isComplete)
|
//{
|
// //detail全部完成了
|
// req.STATUS = BIZ_WMS_TRANSFER.STATUSs.COMPLETE.GetValue();
|
//}
|
//else
|
//{
|
// req.STATUS = BIZ_WMS_TRANSFER.STATUSs.WORKING.GetValue();
|
//}
|
////如果是Agv
|
//if (CurReqType == ReqType.IsAgv)
|
//{
|
// req.STATUS = BIZ_WMS_TRANSFER.STATUSs.COMPLETE.GetValue();
|
//}
|
|
////5.出库下架
|
//foreach (var item in CurInv.Items)
|
//{
|
// item.TRANS_CODE = nameof(BIZ_WMS_TRANSFER);
|
// item.TRANS_NO = req.BILLCODE;
|
// item.TRANS_LINE = string.Join(",", dtls.Select(x => x.BILLLINE));
|
// item.SOURCE_CODE = "WORK_ORDER";
|
// item.SOURCE_ORDER = dtls.First().SOURCECODE;
|
//}
|
//Result<TakeDownInfo> downResult = WMS_ITEM_Biz.WmsItem.TakeDown(CurInv, input.AuthOption, WMS_ITEM.STATUSs.Sended);
|
//if (!downResult.IsSuccessed)
|
//{
|
// action.IsSuccessed = false;
|
// action.LocaleMsg = result.LocaleMsg;
|
// return action;
|
//}
|
//TakeDownInfo downInfo = downResult.Data;
|
////物料池中删除已下架物料
|
//var poolItems = CurPoolList.Where(q => downInfo.Items.Select(x => x.SN).Contains(q.SN)).ToList();
|
|
////5.保存数据库
|
//var db = Business.Biz.Db;
|
//var dbTran = db.UseTran(() =>
|
//{
|
// //入库
|
// db.Updateable(downInfo.Items, UserCode).ExecuteCommand();
|
// db.Insertable(downInfo.History, UserCode).ExecuteCommand();
|
// db.Updateable(downInfo.Packages, UserCode).ExecuteCommand();
|
// db.Deleteable(poolItems).ExecuteCommand();
|
// db.Updateable(req, UserCode).ExecuteCommand();
|
// db.Updateable(dtls, UserCode).ExecuteCommand();
|
|
// if (reqSn != null)
|
// {
|
// db.Insertable(reqSn, UserCode).ExecuteCommand();
|
// }
|
// //db.Updateable(billDetail, UserCode).ExecuteCommand();
|
// //db.Updateable(billHeader, UserCode).ExecuteCommand();
|
|
//});
|
//if (!dbTran.IsSuccess)
|
//{
|
//Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
|
//this.Close(!dbTran.IsSuccess);
|
// throw dbTran.ErrorException;
|
//}
|
|
////6. 对接MES、Agv
|
|
//增加储位操作历史
|
if (!LocationHis.Any(q => q.SHELF_ID == CurInv.Location.SHELF_ID && q.LOCATION_CODE == CurInv.Location.LOCATION_CODE))
|
{
|
LocationHis.Add(CurInv.Location);
|
}
|
|
//action.LocaleMsg = Biz.L($"调拨出库完成,单号:[{req.BILLCODE}],状态:{req.STATUS.GetEnumDesc<BIZ_WMS_TRANSFER.STATUSs>()}");
|
action.Data = new ProdReqOutput()
|
{
|
SN = CurInv.SN,
|
ItemCode = CurInv.ItemInfo.ITEM_CODE,
|
Qty = CurInv.CurPkg.QTY,
|
CutQty = CurInv.CurPkg.QTY - cutQty,
|
isCutting = isCutting,
|
isExceed = isExceed,
|
ReqNo = req.ORDER_NO,
|
regionCode = CurInv.Region.REGION_CODE,
|
locationCode = CurInv.Location?.LOCATION_CODE,
|
};
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"扫描物料[{input.SN}]复核异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 确认是否超发
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
public async Task<ApiAction<ProdReqOutput>> ConfirmExceed(OutOtherInput input)
|
{
|
var action = new ApiAction<ProdReqOutput>();
|
try
|
{
|
//灭灯
|
if (CurInv.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.Smart.GetValue() || CurInv.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.QRCode.GetValue())
|
{
|
await Share.Shelf.DownSingle(TransID, CurInv.Location);
|
}
|
Suggests.Where(q => CurInv.Items.Select(x => x.SN).Contains(q.Item.SN)).ToList().ForEach((i) => { i.poolItem.STATUS = WMS_ITEM_POOL.STATUSs.WaitSend.GetValue(); });
|
|
var reqSn = new BIZ_WMS_TRANSFER_SN()
|
{
|
AUTH_ORG = OrgCode,
|
SN = CurInv.CurPkg.SN,
|
ITEM_CODE = CurInv.ItemInfo.ITEM_CODE,
|
QTY = CurInv.CurPkg.QTY,
|
ORDER_NO = req.ORDER_NO,
|
//BILLLINE = tfdtl.BILLLINE
|
};
|
|
//4.更新业务单据,BIZ_WMS_TRANSFER、BIZ_WMS_TRANSFER_DTL、BIZ_WMS_TRANSFER_SN 判断明细行状态是否完成
|
var isComplete = !req.Dtls.Any(x => x.STATUS != BIZ_WMS_TRANSFER.STATUSs.Finished.GetValue() && x.STATUS != BIZ_WMS_TRANSFER.STATUSs.Picked.GetValue() && x.QTY_REQ > 0);
|
his_isComplete = isComplete;
|
if (isComplete)
|
{
|
//detail全部完成了
|
req.STATUS = isManual ? BIZ_WMS_TRANSFER.STATUSs.Picked.GetValue() : BIZ_WMS_TRANSFER.STATUSs.Finished.GetValue();
|
}
|
else
|
{
|
req.STATUS = BIZ_WMS_TRANSFER.STATUSs.Storing.GetValue();
|
}
|
//如果是Agv
|
if (CurReqType == ReqType.IsAgv)
|
{
|
req.STATUS = isManual ? BIZ_WMS_TRANSFER.STATUSs.Picked.GetValue() : BIZ_WMS_TRANSFER.STATUSs.Finished.GetValue();
|
}
|
|
//5.出库下架
|
foreach (var item in CurInv.Items)
|
{
|
item.TRANS_CODE = nameof(BIZ_WMS_TRANSFER);
|
item.TRANS_NO = req.ORDER_NO;
|
item.TRANS_LINE = string.Join(",", dtls.Select(x => x.ORDER_LINE));
|
item.SOURCE_CODE = "WORK_ORDER";
|
item.SOURCE_ORDER = dtls.First().SOURCE_ORDER;
|
}
|
Result<TakeDownInfo> downResult = WMS_ITEM_Biz.WmsItem.TakeDown(CurInv, input.AuthOption, WMS_ITEM.STATUSs.Sended, !isCutting);
|
if (!downResult.IsSuccessed)
|
{
|
action.IsSuccessed = false;
|
action.LocaleMsg = downResult.LocaleMsg;
|
return action;
|
}
|
TakeDownInfo downInfo = downResult.Data;
|
//物料池中删除已下架物料
|
var poolItems = CurPoolList.Where(q => downInfo.Items.Select(x => x.SN).Contains(q.SN)).ToList();
|
|
//5.保存数据库
|
var db = Business.Biz.Db;
|
var dbTran = db.UseTran(() =>
|
{
|
//入库
|
db.Updateable(downInfo.Items, UserCode).ExecuteCommand();
|
db.Insertable(downInfo.History, UserCode).ExecuteCommand();
|
db.Updateable(downInfo.Packages, UserCode).ExecuteCommand();
|
db.Deleteable(poolItems).ExecuteCommand();
|
db.Updateable(req, UserCode).ExecuteCommand();
|
db.Updateable(dtls, UserCode).ExecuteCommand();
|
|
if (reqSn != null)
|
{
|
db.Insertable(reqSn, UserCode).ExecuteCommand();
|
}
|
//db.Updateable(billDetail, UserCode).ExecuteCommand();
|
//db.Updateable(billHeader, UserCode).ExecuteCommand();
|
});
|
if (!dbTran.IsSuccess)
|
{
|
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
|
this.Close(!dbTran.IsSuccess);
|
throw dbTran.ErrorException;
|
}
|
|
//6. 对接MES、Agv
|
|
action.LocaleMsg = Biz.L($"调拨出库完成,单号[{req.ORDER_NO}],条码[{CurInv.SN}],状态[{req.STATUS.GetEnumDesc<BIZ_WMS_TRANSFER.STATUSs>()}]");
|
action.Data = new ProdReqOutput()
|
{
|
SN = CurInv.SN,
|
ItemCode = CurInv.ItemInfo.ITEM_CODE,
|
Qty = CurInv.CurPkg.QTY,
|
CutQty = CurInv.CurPkg.QTY - cutQty,
|
isCutting = isCutting,
|
isExceed = isExceed,
|
ReqNo = req.ORDER_NO,
|
regionCode = CurInv.Region.REGION_CODE,
|
locationCode = CurInv.Location?.LOCATION_CODE,
|
};
|
}
|
catch (Exception ex)
|
{
|
action.CatchExceptionWithLog(ex, $"确认调拨单超发异常");
|
}
|
return action;
|
}
|
|
/// <summary>
|
/// 添加一个ApiAction的历史记录
|
/// </summary>
|
/// <param name="action"></param>
|
public override void AddHistory<T>(Microsoft.AspNetCore.Http.HttpRequest request, ApiAction<T> action)
|
{
|
var his = action.History();
|
his.TraceDic.Add("CurReqType", CurReqType);
|
his.TraceDic.Add("CurInv", CurInv);
|
his.TraceDic.Add("req", req);
|
his.TraceDic.Add("toMes", toMes);
|
his.TraceDic.Add("CurPoolList", CurPoolList);
|
his.TraceDic.Add("isComplete", his_isComplete);
|
ActionHistoryList.Add($"{request.HttpContext.TraceIdentifier} at {action.Timestamp:yyyy/MM/dd HH:mm:ss.fff}: {request.Path}", his);
|
LastActionTime = DateTime.Now;
|
}
|
|
#endregion Functions
|
|
public override bool Close(bool needSaveHistoryLog = false)
|
{
|
//needSaveHistoryLog = true;
|
CloseLight(LocationHis).Wait();
|
if (!(req?.ORDER_NO ?? "").IsNullOrEmpty())
|
{
|
Biz.Db.Deleteable<WMS_ITEM_POOL>().Where(x => x.TRANS_NO == req.ORDER_NO).ExecuteCommand();
|
}
|
Biz.Db.Deleteable<WMS_ITEM_POOL>().Where(q => CurPoolList.Select(q => q.SN).Contains(q.SN)).ExecuteCommand();
|
//保存操作日志
|
|
this.IsFinished = true;
|
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
|
}
|
}//endClass
|
}
|