using Rhea.Common;
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.IBusiness;
using Tiger.Business.WMS.Common;
using Org.BouncyCastle.Ocsp;
using Tiger.Model.Sharetronic.Shelf;
using MailKit.Search;
using Tiger.Business.WMS.Extensions;
using static Tiger.Model.BIZ_WMS_PREP_BTH;
namespace Tiger.Business.WMS.Transaction
{
///
/// 备料任务下架事务
///
public class Out_BIZ_WMS_PREP : WmsTask, IOut_BIZ_WMS_PREP
{
public IOut_BIZ_WMS_PREP Init(string id, string userCode, string apiHost, string orgCode)
{
base.Init(id, userCode, apiHost, orgCode);
CurPREP = new(MainDB, userCode, orgCode);
Logger.Console.Info($"Start {this.GetType().Name} Transaction[ID: {TransID}]");
return this;
}
#region Propertys & Variables
public Preparation CurPREP { get; set; }
private List CurSn = new();
private BIZ_WMS_PREP_DTL CurPrepDtl = new();
public List Suggests { get; set; } = new();
public List CurPoolList => Suggests.Where(q => !q.poolItem.IsNullOrEmpty()).Select(q => q.poolItem).ToList();
public List LocationHis { get; set; } = new();
private bool isExceed = false;
private bool isNeedCut = false;
#endregion
#region Functions
///
/// 扫描入口
///
public async Task> Scan(BaseInput input)
{
var action = new ApiAction(new ScanOutput());
try
{
if (input.Command == "ScanOrder")
{
action = await ScanOrder(input);
}
else if (input.Command == "SelectItem")
{
action = await SelectItem(input);
}
else if (input.Command == "ConfirmExceed")
{
action = await ConfirmExceed(input);
}
else
{
if (CurPREP.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("备料前请先选择需要备料的单据");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanItem.NotScanOrder");
action.Data.Command = "ScanOrder";
return SetOutPutMqttMsg(action, input.Locale);
}
if (CurPrepDtl.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("备料前请先选择需要备料的物料行");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanItem.NotSelectItem");
action.Data.Command = "SelectItem";
return SetOutPutMqttMsg(action, input.Locale);
}
if (input.SN.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("条码不能为空");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.SnEmptyFailure");
return SetOutPutMqttMsg(action, input.Locale);
}
//扫描物料并复核
{
action = await ScanItem(input);
}
}
}
catch (Exception ex)
{
//取消当前操作
ResetTrans();
//action.CatchExceptionWithLog(ex, $"扫描[{input.SN}]异常");
action.CatchExceptionWithLog(ex, Biz.L("WMS.Default.Scan.ScanException", input.SN));
}
return SetOutPutMqttMsg(action, input.Locale);
}
///
/// 扫描下架单据号码
///
public async Task> ScanOrder(BaseInput input)
{
var action = new ApiAction(new ScanOutput());
try
{
var inputOrder = input?.Data?.JsonToObject();
if ((inputOrder?.BIZ_TYPE).IsNullOrEmpty() || (inputOrder?.SOURCE_ORDER ?? "").IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L($"请选择正确的备料任务类型和单号");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanOrder.InputOrderIsNull");
return action;
}
if (!CurPREP.Order.IsNullOrEmpty() && inputOrder.BIZ_TYPE != CurPREP.Order.BIZ_TYPE)
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L($"当前备料任务[{0}]的业务类型为{1},如需切换备料业务,请退出后重新选择");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanOrder.BizTypeError", CurPREP.Order.ORDER_NO, CurPREP.Order.BIZ_TYPE.GetEnumDesc());
return action;
}
if (CurPREP.Order.IsNullOrEmpty() || !CurPREP.Order.SourceOrders.Any(q => q.SOURCE_ORDER == inputOrder.SOURCE_ORDER))
{
action = CurPREP.AddOrder(inputOrder.BIZ_TYPE.GetEnum(), inputOrder.SOURCE_CODE);
}
else
{
//action.LocaleMsg = Biz.L($"当前备料任务[{0}]已包含单据[{1}],无需重复操作");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanOrder.Repeat", CurPREP.Order.ORDER_NO, inputOrder.SOURCE_ORDER);
}
action.Data.Command = "SelectItem";
action.Data.Data = CurPREP.Order;
}
catch (Exception ex)
{
//取消当前操作
ResetTrans();
//action.CatchExceptionWithLog(ex, $"备料任务扫描单据异常(Data: {0})");
action.CatchExceptionWithLog(ex, Biz.L("WMS.Out_BIZ_WMS_PREP.ScanOrderException", input?.Data));
}
return action;
}
///
/// 获取当前备料的备料任务信息
///
///
public async Task> GetPrepInfo()
{
var action = new ApiAction();
CurPREP.Order = MainDB.Queryable().Where(q => q.ID == CurPREP.Order.ID).IncludesAllFirstLayer().First();
action.Data = CurPREP.Order;
return action;
}
///
/// 选择备料任务中要下架物料行
///
public async Task> SelectItem(BaseInput input)
{
var action = new ApiAction(new ScanOutput());
try
{
var option = CurPREP.Option = new BaseInput(input).Data;
var prepDtl = MainDB.Queryable().Where(q => q.ID == option.LineID).First();
if (prepDtl.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("备料前请先选择需要备料的物料行");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanItem.NotSelectItem");
return action;
}
if (prepDtl.QTY_PREP > CurPREP.BizType.GetActReqQty(prepDtl))
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("当前选择物料行[{0}]已备料数量[{1}],以满足实际需求数量[{2}],无需继续备料");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.SelectItem.PrepFinish", prepDtl.ITEM_CODE, prepDtl.QTY_PREP, CurPREP.BizType.GetActReqQty(prepDtl));
return action;
}
//删除物料池中上一次分配的物料
MainDB.Deleteable().Where(q => q.TRANS_NO == prepDtl.ORDER_NO && q.TRANS_LINE == prepDtl.ORDER_LINE).ExecuteCommand();
if (!CurPrepDtl.IsNullOrEmpty())
{
MainDB.Deleteable().Where(q => q.TRANS_NO == CurPrepDtl.ORDER_NO && q.TRANS_LINE == CurPrepDtl.ORDER_LINE).ExecuteCommand();
}
CurPrepDtl = prepDtl;
//如果上一次推荐有数据,则先灭掉亮的灯
if (Suggests.Any())
{
//await CloseLight(LocationHis);
}
//如果是首套发料,则只推荐当前物料行的一盘物料
if (option.DlvyMode == WMS_ITEM_POOL.DLVY_MODEs.First)
{
//推荐物料
Result> result = Suggest(CurPrepDtl.ORDER_NO, CurPrepDtl.ITEM_CODE, option, input.AuthOption, 1);
action.LocaleMsg = result.LocaleMsg;
if (result.IsException)
{
action.IsSuccessed = false;
return action;
}
Suggests.Clear();
Suggests = result.Data;
if (Suggests.Count > 0)
{
var inv = Suggests.First();
var actQty = CurPrepDtl.QTY_PREP > CurPREP.BizType.GetActReqQty(CurPrepDtl) ? 0 : (CurPREP.BizType.GetActReqQty(CurPrepDtl) - CurPrepDtl.QTY_PREP);
if (inv != null && actQty > 0)
{
inv.poolItem = inv.Item.GetPoolItem(OrgCode, nameof(CurPREP.Order), CurPrepDtl.ORDER_NO, CurPrepDtl.ORDER_LINE, actQty, true);
}
else
{
inv.poolItem = null;
}
}
Suggests.RemoveAll(q => q.poolItem.IsNullOrEmpty());
}
//如果是正常发料,则按实际需求数量推荐当前物料行的所有物料
if (option.DlvyMode == WMS_ITEM_POOL.DLVY_MODEs.Supply)
{
//推荐物料
var actQty = CurPrepDtl.QTY_PREP > CurPREP.BizType.GetActReqQty(CurPrepDtl) ? 0 : (CurPREP.BizType.GetActReqQty(CurPrepDtl) - CurPrepDtl.QTY_PREP);
Result> result = Suggest(CurPrepDtl.ORDER_NO, CurPrepDtl.ITEM_CODE, option, input.AuthOption, actQty);
action.LocaleMsg = result.LocaleMsg;
if (result.IsException)
{
action.IsSuccessed = false;
return action;
}
Suggests.Clear();
var remain = actQty;
Suggests.ForEach((inv) =>
{
if (remain > 0)
{
inv.poolItem = inv.Item.GetPoolItem(input.AuthOption.OrgCode, nameof(CurPREP.Order), CurPrepDtl.ORDER_NO, CurPrepDtl.ORDER_LINE, remain, false);
remain -= inv.poolItem.ALLOC_QTY;
}
else
{
inv.poolItem = null;
}
});
Suggests.RemoveAll(q => q.poolItem.IsNullOrEmpty());
}
//保存物料池到数据库
MainDB.Insertable(CurPoolList).ExecuteCommand();
CurPrepDtl.Suggests = Suggests;
//action = await LightAll(new() { AuthOption = input.AuthOption, Color = LedColor.Blue });
action.Data.Command = "Normal";
action.Data.Data = CurPrepDtl;
//action.LocaleMsg = Biz.L($"已选择要备料物料行[{0},可以开始备料下架");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.SelectItem.Success", CurPrepDtl.ITEM_CODE);
}
catch (Exception ex)
{
//取消当前操作
ResetTrans();
//action.CatchExceptionWithLog(ex, $"备料任务选择要物料行异常(Data: {0})");
action.CatchExceptionWithLog(ex, Biz.L("WMS.Out_BIZ_WMS_PREP.SelectItemException", input?.Data));
}
return action;
}
///
/// 获取当前备料的物料行信息
///
///
public async Task> GetCurPrepItem()
{
var action = new ApiAction();
var prepDtl = MainDB.Queryable().Where(q => q.ID == CurPrepDtl.ID).First();
prepDtl.Suggests = Suggests;
CurPrepDtl = prepDtl;
CurPREP.Order.Details.RemoveAll(q => q.ID == CurPrepDtl.ID);
CurPREP.Order.Details.Add(CurPrepDtl);
action.Data = CurPrepDtl;
return action;
}
///
/// 领料单推荐所有物料亮灯
///
///
///
public async Task> LightAll(LightEntityInput light)
{
var action = new ApiAction();
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.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;
}
///
/// 灭灯
///
///
public async Task CloseLight(List 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;
}
///
/// 扫描物料并复核,如果物料已经完成移库则货架上亮灯提醒储位
///
public async Task> ScanItem(BaseInput input)
{
var action = new ApiAction(new ScanOutput() { Command = Command });
try
{
//解析条码
Result result = GetInventory(input.SN, input.AuthOption, true);
if (!result.IsSuccessed)
{
action.IsSuccessed = false;
action.LocaleMsg = result.LocaleMsg;
return SetOutPutMqttMsg(action, input.Locale);
}
var inv = result.Data as Inventory;
//验证条码是否正确
if (!inv.isNormalStatus || inv.Status != WMS_ITEM.STATUSs.InStore)
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("状态[{0}]异常,请重新扫描");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.StatusException", string.Join(',', inv.StatusList.Select(q => q.GetDesc())));
return SetOutPutMqttMsg(action, input.Locale);
}
//验证条码是否被锁定
if (inv.Items.Any(q => q.IS_LOCKED == "Y"))
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("条码[{0}]已被锁定,请重新扫描");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.ItemIsLock", inv.CurPkg.SN);
return SetOutPutMqttMsg(action, input.Locale);
}
//验证条码是否被其他用户和单据锁定
if (inv.Items.Any(q => q.IS_LOCKED == "Y"))
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("条码[{0}]已被锁定,请重新扫描");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.ItemIsLock", inv.CurPkg.SN);
return SetOutPutMqttMsg(action, input.Locale);
}
//储位验证
if (inv.Location.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L($"条码[{0}]库存信息异常: 没有储位信息,请先上架后再扫描(储位Id: {1})");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.LocationIsNull", inv.CurPkg.SN, inv.CurPkg.LOCATION_ID);
return SetOutPutMqttMsg(action, input.Locale);
}
//物料验证
if (inv.ItemInfo.IsNullOrEmpty() || inv.ItemInfo.IS_ACTIVE == "N")
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L($"物料编码[{0}]不存在或者该物料未启用");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.ItemCodeNotExistsOrNotActive", inv.ItemInfo.ITEM_CODE.IsNullOrEmpty(inv.Barcode.ItemCode));
return SetOutPutMqttMsg(action, input.Locale);
}
//判断是否在备料中的物料
if (inv.ItemInfo.ITEM_CODE != CurPrepDtl.ITEM_CODE)
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L($"条码[{0}]不是当前选中的物料行[{1}],请放回原储位或者重新选择下架物料行");
action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanItem.NoNeedItemCode", inv.CurPkg.SN, CurPrepDtl.ITEM_CODE);
return action;
}
//判断是否在备料中的物料
//if (!CurPREP.Order.Details.Any(q => q.ITEM_CODE == inv.ItemInfo.ITEM_CODE))
//{
// action.IsSuccessed = false;
// //action.LocaleMsg = Biz.L($"当前备料任务[{0}]不包含条码[{1}]的物料编码[{2}],请放回原储位");
// action.LocaleMsg = Biz.L("WMS.Out_BIZ_WMS_PREP.ScanItem.NoNeedItemCode", inv.ItemInfo.ITEM_CODE.IsNullOrEmpty(inv.Barcode.ItemCode));
// return action;
//}
//ProcessingOrderDetail = input.SN;
//if (WMSContext.TransactionDic.Where(q => !string.IsNullOrWhiteSpace(q.Value.ProcessingSn)).Any(q => q.Value.ProcessingSn == ProcessingSn && q.Value.TransID != this.TransID))
//{
// action.IsSuccessed = false;
// action.LocaleMsg = Biz.L("当前条码正在执行中,无法扫描");
// return action;
//}
CurInvItem = inv;
CurSn = CurInvItem.Items.Select(q => new BIZ_WMS_PREP_SN() {
ORDER_NO = CurPREP.Order.ORDER_NO,
ORDER_LINE = CurPrepDtl.ORDER_LINE,
SN = q.SN,
ITEM_CODE = q.ITEM_CODE,
UNIT = q.UNIT,
QTY = q.QTY,
QTY_DLVY = q.QTY,
STATUS = q.STATUS,
LOTNO = q.LOTNO,
WH_ID = CurInvItem.Warehouse.ID,
WH_CODE = CurInvItem.Warehouse.WH_CODE,
REGION_ID = CurInvItem.Region.ID,
REGION_CODE = CurInvItem.Region.REGION_CODE,
SHELF_ID = CurInvItem.Shelf.ID,
SHELF_CODE = CurInvItem.Shelf.SHELF_CODE,
LOCATION_ID = CurInvItem.Location.ID,
LOCATION_CODE = CurInvItem.Location.LOCATION_CODE,
PREP_USER = UserCode,
DOWN_TIME = DateTime.Now,
SMT_NO = CurPrepDtl.SMT_NO,
STATION_NO = CurPrepDtl.STATION_NO,
FEEDER_NO = CurPrepDtl.FEEDER_NO,
FEEDER_TYPE = CurPrepDtl.FEEDER_TYPE,
IS_FIRST = CurPREP.Option.DlvyMode == WMS_ITEM_POOL.DLVY_MODEs.First ? "Y" : "N",
NEED_CUTTING = "N",
TRACE_ID = TransID,
}).ToList();
//判断是否超发
isExceed = false;
//计算剩余需求数量和条码中的发出数量
var actQty = CurPrepDtl.QTY_PREP > CurPREP.BizType.GetActReqQty(CurPrepDtl) ? 0 : (CurPREP.BizType.GetActReqQty(CurPrepDtl) - CurPrepDtl.QTY_PREP);
if (actQty < CurInvItem.CurPkg.QTY)
{
isExceed = true;
var remain = actQty;
foreach (var sn in CurSn.OrderByDescending(q => q.QTY))
{
sn.QTY_DLVY = remain >= sn.QTY ? sn.QTY : remain;
sn.NEED_CUTTING = remain >= sn.QTY ? "N" : "Y";
remain -= sn.QTY_DLVY;
}
}
//判断物料是否允许超发,如果不允许则必须截料,否则由用户在PDA选择是否截料
isNeedCut = CurInvItem.ItemInfo.DLVY_TYPE == BAS_ITEM.DLVY_TYPEs.ByDemand.GetValue();
//如果超发则返回前端处理,否则直接发出
if (isExceed)
{
//action.LocaleMsg = Biz.L($"条码[{0}]扫描成功,备料物料[{1}]需求[{2}]还需备料[{3}],条码需要截料,发出数量[{4}]");
//action.LocaleMsg = Biz.L($"条码[{0}]扫描成功,备料物料[{1}]需求[{2}]还需备料[{3}],请选择要超发还是截料?");
action.LocaleMsg = Biz.L($"WMS.Out_BIZ_WMS_PREP.ScanItem.Success{(isNeedCut ? "" : "Confirm")}", CurInvItem.SN, CurInvItem.ItemInfo.ITEM_CODE, CurPREP.BizType.GetActReqQty(CurPrepDtl), actQty);
action.Data.Command = "ConfirmExceed";
action.Data.Data = new
{
isExceed,
isNeedCut,
CurSn,
};
}
else
{
input.Data = CurSn.ToJson();
action = await ConfirmExceed(input);
}
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"扫描物料[{input.SN}]复核异常");
}
return SetOutPutMqttMsg(action, input.Locale);
}
///
/// 前端确认超发或者返回截料后的信息
///
///
///
public async Task> ConfirmExceed(BaseInput input)
{
var action = new ApiAction(new ScanOutput() { Command = "Normal" });
try
{
var sns = (input.Data ?? "").JsonToObject>() ?? new List();
if (!sns.Any())
{
var actQty = CurPrepDtl.QTY_PREP > CurPREP.BizType.GetActReqQty(CurPrepDtl) ? 0 : (CurPREP.BizType.GetActReqQty(CurPrepDtl) - CurPrepDtl.QTY_PREP);
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L($"条码[{0}]扫描成功,备料物料[{1}]需求[{2}]还需备料[{3}],条码需要截料,发出数量[{4}]");
//action.LocaleMsg = Biz.L($"条码[{0}]扫描成功,备料物料[{1}]需求[{2}]还需备料[{3}],请选择要超发还是截料?");
action.LocaleMsg = Biz.L($"WMS.Out_BIZ_WMS_PREP.ScanItem.Success{(isNeedCut ? "" : "Confirm")}", CurInvItem.SN, CurInvItem.ItemInfo.ITEM_CODE, CurPREP.BizType.GetActReqQty(CurPrepDtl), actQty);
action.Data.Command = "ConfirmExceed";
action.Data.Data = new
{
isExceed,
isNeedCut,
CurSn,
};
return SetOutPutMqttMsg(action, input.Locale);
}
else
{
foreach (var item in sns)
{
var sn = CurSn.First(q => q.ID == item.ID);
sn.NEED_CUTTING = item.NEED_CUTTING;//前端返回Y认为是截料发料,N认为是整盘发料
sn.DeliverySN = item.DeliverySN;
sn.ReserveSN = item.ReserveSN;
}
Command = "Normal";
}
//出库下架
foreach (var item in CurInvItem.Items)
{
item.SOURCE_CODE = item.TRANS_CODE;
item.SOURCE_ORDER = item.TRANS_NO;
item.SOURCE_LINE = item.TRANS_LINE;
item.TRANS_CODE = nameof(BIZ_WMS_PREP);
item.TRANS_NO = CurPREP.Order.ORDER_NO;
item.TRANS_LINE = CurPrepDtl.ORDER_LINE;
}
foreach (var item in CurInvItem.Packages)
{
item.SOURCE_CODE = item.TRANS_CODE;
item.SOURCE_ORDER = item.TRANS_NO;
item.SOURCE_LINE = item.TRANS_LINE;
item.TRANS_CODE = nameof(BIZ_WMS_PREP);
item.TRANS_NO = CurPREP.Order.ORDER_NO;
item.TRANS_LINE = CurPrepDtl.ORDER_LINE;
}
Result downResult = TakeDown(CurSn, input.AuthOption, WMS_ITEM.STATUSs.OffShelf);
if (!downResult.IsSuccessed)
{
action.IsSuccessed = false;
action.LocaleMsg = downResult.LocaleMsg;
ResetScan();
return SetOutPutMqttMsg(action, input.Locale);
}
else//处理备料任务数据
{
foreach (var sn in CurSn)
{
sn.STATUS = WMS_ITEM.STATUSs.OffShelf.GetValue();
sn.DOWN_TIME = DateTime.Now;
if (sn.NEED_CUTTING == "Y")
{
sn.NEED_CUTTING = "N";
sn.SN = sn.DeliverySN;
sn.QTY = sn.QTY_DLVY;
}
}
CurPrepDtl.QTY_PREP += CurSn.Sum(q => q.QTY_DLVY);
CurPREP.Order.STATUS = BIZ_WMS_PREP.STATUSs.Picking.GetValue();
//创建变量克隆对象用于传入DBSubmitAction中保存当前需要暂存的数据值
var _CurSn = CurSn.Clone();
var _CurPrepDtl = CurPrepDtl.Clone();
var _CurPREPOrder = CurPREP.Order.Clone();
AddCommitAction("UpdatePrep", () =>
{
//使用统一的事务DB对象
var db = GetCommitDB();
//数据保存逻辑
db.Insertable(_CurSn, UserCode).ExecuteCommand();
_CurPrepDtl.QTY_PREP = db.Queryable().Where(q => q.ORDER_NO == _CurPrepDtl.ORDER_NO && q.ORDER_LINE == _CurPrepDtl.ORDER_LINE).Sum(q => q.QTY_DLVY);
db.Updateable(_CurPrepDtl, UserCode).UpdateColumns(q => new { q.QTY_PREP, q.UPDATE_TIME, q.UPDATE_USER }).ExecuteCommand();
db.Updateable(_CurPREPOrder, UserCode).UpdateColumns(q => new { q.STATUS, q.UPDATE_TIME, q.UPDATE_USER }).ExecuteCommand();
});
//灭灯
if (CurInvItem.Shelf.IsLightShelf)
{
await Share.Shelf.DownSingle(TransID, CurInvItem.Location);
}
}
//完成所有处理后使用事务保存数据
action = DoIfFinish(action, input.Locale);
}
catch (Exception ex)
{
//取消当前操作
ResetTrans();
//action.CatchExceptionWithLog(ex, $"扫描条码[{input.SN}]复核异常");
action.CatchExceptionWithLog(ex, Biz.L("WMS.Default.ScanItem.ScanException", input.SN));
}
return SetOutPutMqttMsg(action, input.Locale);
}
///
/// 扫描货架或者储位
///
public async Task> ScanShelf(string Code, V_WH_UNIT whUnit)
{
var action = new ApiAction(new ScanOutput() { Command = Command });
try
{
if (Code.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("请输入或扫描有效的货架/储位码");
action.LocaleMsg = Biz.L("WMS.Default.ScanShelf.ShelfCanNotEmpty");
return action;
}
CurScanShelf = new ScanShelfInfo();
// 查询货架信息
whUnit = whUnit.IsNullOrEmpty(await MainDB.Queryable().Where(t => (t.SHELF_CODE.ToUpper() == Code || t.LOCATION_CODE.ToUpper() == Code) && t.AUTH_ORG == OrgCode).IncludesAllFirstLayer().FirstAsync());
// 扫描货架代码,且为智能货架
if (!whUnit.IsNullOrEmpty() && whUnit.SHELF_CODE == Code)
{
CurScanShelf.Shelf = whUnit.Shelf;
CurScanShelf.WarehouseCode = whUnit.WH_CODE;
CurScanShelf.RegionCode = whUnit.REGION_CODE;
CurScanShelf.ShelfCode = whUnit.SHELF_CODE;
CurScanShelf.ShelfType = whUnit.SHELF_TYPE;
CurScanShelf.IsSmartRack = true;
}
// 扫描库位代码
else if (!whUnit.IsNullOrEmpty() && whUnit.LOCATION_CODE == Code)
{
//var nLocation = await MainDB.Queryable().Where(t => t.LOCATION_CODE.ToUpper() == Code.ToUpper() && t.AUTH_ORG == OrgCode).IncludesAllFirstLayer().FirstAsync();
//if (nLocation == null)
//{
// action.IsSuccessed = false;
// //action.LocaleMsg = Biz.L("储位[{0}]不存在");
// action.LocaleMsg = Biz.L("WMS.Default.ScanShelf.LocationNotExist", Code);
// return action;
//}
if (whUnit.IS_ACTIVE == "N")
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("扫描的储位[{0}]未启用");
action.LocaleMsg = Biz.L("WMS.Default.ScanShelf.ShelfOrLocationDisabled", Code);
return action;
}
if (whUnit.Shelf.IsLightShelf || whUnit.Location.IS_SINGLE == "Y")
{
var locationData = MainDB.Queryable().Where(q => q.LOCATION_ID == whUnit.LOCATION_ID && q.AUTH_ORG == OrgCode).First();
if (!locationData.IsNullOrEmpty())
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("储位[{0}]已存有物料[{1}],请检查系统库存信息");
action.LocaleMsg = Biz.L($"WMS.Default.ScanShelf.ItemAlreadyExistsInLocation", Code, locationData.SN);
return action;
}
}
CurScanShelf.Shelf = whUnit.Shelf;
CurScanShelf.Location = whUnit.Location;
CurScanShelf.WarehouseCode = whUnit.WH_CODE;
CurScanShelf.RegionCode = whUnit.REGION_CODE;
CurScanShelf.ShelfCode = whUnit .SHELF_CODE;
CurScanShelf.LocationCode = whUnit.LOCATION_CODE;
CurScanShelf.IsSmartRack = false;
}
else
{
action.IsSuccessed = false;
//action.LocaleMsg = Biz.L("请输入或扫描有效的货架/储位码");
action.LocaleMsg = Biz.L("WMS.Default.ScanShelf.ShelfCanNotEmpty");
return action;
}
CurScanShelf.IsScanShelf = true;
//action.LocaleMsg = Biz.L("扫描货架/储位[{0}]成功");
action.LocaleMsg = Biz.L("WMS.Default.ScanShelf.ScanSucceeded", Code);
action.Data.Data = CurScanShelf;
}
catch (Exception ex)
{
//取消当前操作
ResetTrans();
//action.CatchExceptionWithLog(ex, $"扫描货架/储位[{0}]异常");
action.CatchExceptionWithLog(ex, Biz.L("WMS.Default.ScanShelf.ScanException", Code));
}
return action;
}
///
/// 完成所有处理后使用事务保存数据
///
///
///
///
///
public ApiAction DoIfFinish(ApiAction action, string locale, Action doAfterSave = null)
{
//保存数据库
SaveCommitListToDB();
//保存数据成功后执行
doAfterSave?.Invoke();
// 返回数据
action.Data.Data = new DefaultScanItemOutput()
{
SN = CurInvItem.SN,
ItemCode = CurInvItem.ItemInfo.ITEM_CODE,
MaterialName = CurInvItem.ItemInfo.ITEM_NAME,
Qty = CurInvItem.CurPkg.QTY,
Unit = CurInvItem.CurPkg.UNIT,
regionCode = CurInvItem.Region.REGION_CODE,
locationCode = CurInvItem.Location?.LOCATION_CODE,
DateCode = CurInvItem.Items[0].PROD_DATE,
ScanAfCut = CurInvItem.Warehouse.SCAN_AF_CUT
};
//action.LocaleMsg = Biz.L($"扫描条码[{0}]从储位[{1}]下架成功");
action.LocaleMsg = Biz.L("WMS.Default.ScanItem.TakeDownSucceeded", CurInvItem.SN, CurInvItem.Location?.LOCATION_CODE);
//重置工序
ResetScan();
return SetOutPutMqttMsg(action, locale);
}
///
/// 创建发料批次以完成本次发料,调用发料单据的ERP接口
///
///
///
public async Task GenerateDlvyBatch(BaseInput input)
{
var range = input.Data.ToInt32().GetEnum();
var action = await CurPREP.Order.BIZ_TYPE.GetEnum() .GenerateDlvyBatch(this, range);
return action;
}
#endregion
///
/// 重置事务数据,有需要则重写此方法
///
public override void ResetTrans()
{
ResetScan();
CurPREP = new(MainDB, UserCode, OrgCode);
CurPrepDtl = new();
CurScanShelf = null;
base.ResetTrans();
}
///
/// 重置本次扫码信息
///
public override void ResetScan()
{
Command = "Normal";
CurInvItem = null;
CurSn = new();
base.ResetScan();
}
public override bool Close(bool needSaveHistoryLog = false)
{
//CloseLight(LocationHis).Wait();
if (!(CurPREP?.Order?.ORDER_NO ?? "").IsNullOrEmpty())
{
MainDB.Deleteable().Where(x => x.TRANS_NO == CurPREP.Order.ORDER_NO).ExecuteCommand();
}
this.IsFinished = true;
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
}
}//endClass
}