using Rhea.Common;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using Tiger.IBusiness;
|
using Tiger.Model;
|
using Tiger.Model.Entitys.MES.Position;
|
|
namespace Tiger.Business.WMS.Transaction
|
{
|
/// <summary>
|
/// 仓库作业任务,包括清点、上架、下架、移库、盘点等
|
/// </summary>
|
public class WmsTask : WMSTransactionBase, IWmsTask
|
{
|
#region Propertys & Variables
|
public string UserCode { get; set; }
|
public string OrgCode { get; set; }
|
private DbClient _MainDB;
|
public DbClient MainDB => _MainDB;
|
private DbClient CommitDB;
|
public Inventory CurInvItem { get; set; }
|
public ScanShelfInfo CurScanShelf { get; set; }
|
/// <summary>
|
/// 跟客户端通讯时的指令,有具体功能定义,默认为Normal
|
/// </summary>
|
public string Command { get; set; } = "Normal";
|
/// <summary>
|
/// 是否需要临时存储数据库提交操作,待需要的时候再提交
|
/// </summary>
|
public bool NeedTemporaryStoreDBCommitAction { get; set; } = false;
|
protected Dictionary<string, List<Action>> DBCommitList { get; set; } = new();
|
#endregion Propertys & Variables
|
|
#region Functions
|
public IWmsTask Init(string id, string userCode, string apiHost, string orgCode)
|
{
|
TransID = id;
|
UserCode = userCode;
|
ApiHost = apiHost;
|
OrgCode = orgCode;
|
_MainDB = Biz.Db;
|
|
return this;
|
}
|
|
/// <summary>
|
/// 获取提交数据的DbClient对象
|
/// </summary>
|
/// <returns></returns>
|
public DbClient GetCommitDB()
|
{
|
return CommitDB ??= Biz.Db;
|
}
|
|
/// <summary>
|
/// 增加暂存的数据库操作
|
/// </summary>
|
/// <param name="groupName">暂存的分组</param>
|
/// <param name="action">暂存的数据库操作</param>
|
public void AddCommitAction(string group, Action action)
|
{
|
//增加附加的保存内容
|
if (!action.IsNullOrEmpty())
|
{
|
if (!DBCommitList.ContainsKey(group))
|
{
|
DBCommitList.Add(group, new List<Action>());
|
}
|
var commitList = DBCommitList[group];
|
commitList.Add(action);
|
}
|
}
|
|
/// <summary>
|
/// 暂存的数据库操作提交到数据库
|
/// </summary>
|
/// <param name="appendToSave">附加的保存内容</param>
|
public void SaveCommitListToDB(Action appendToSave = null)
|
{
|
//增加附加的保存内容
|
if (!appendToSave.IsNullOrEmpty())
|
{
|
if (!DBCommitList.ContainsKey("AppendSaveAction"))
|
{
|
DBCommitList.Add("AppendSaveAction", new List<Action>());
|
}
|
var appendList = DBCommitList["AppendSaveAction"];
|
appendList.Add(appendToSave);
|
}
|
|
//如果不需要临时存储数据库提交操作,则把提交操作列表提交到数据库
|
if (!NeedTemporaryStoreDBCommitAction)
|
{
|
//恢复临时存储标记为false
|
NeedTemporaryStoreDBCommitAction = false;
|
|
var dbTran = GetCommitDB().UseTran(() =>
|
{
|
//在同一个事务中保存所有工步的数据
|
foreach (var wipSn in DBCommitList.Keys.Where(q => q != "AppendSaveAction"))
|
{
|
foreach (var action in DBCommitList[wipSn])
|
{
|
action.Invoke();
|
}
|
}
|
//附加的保存内容
|
if (DBCommitList.ContainsKey("AppendSaveAction"))
|
{
|
foreach (var action in DBCommitList["AppendSaveAction"])
|
{
|
action.Invoke();
|
}
|
}
|
});
|
//保存成功则清空提交操作列表
|
DBCommitList.Clear();
|
if (!dbTran.IsSuccess)
|
{
|
//抛出异常
|
throw dbTran.ErrorException;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 上架
|
/// </summary>
|
/// <param name="inventory">要上架的库存对象</param>
|
/// <param name="option">授权查询选项</param>
|
/// <param name="targetLocation">要上架的储位代码</param>
|
/// <param name="isTransfer">是否移库操作</param>
|
/// <returns></returns>
|
public Result PutOn(AuthOption option, string targetLocation)
|
{
|
var result = new Result(Result.Flags.Success);
|
try
|
{
|
var location = Biz.Db.Queryable<V_WH_UNIT>().Where(q => q.LOCATION_CODE == targetLocation && q.AUTH_ORG == option.CurOrg).IncludesAllFirstLayer().First();
|
if (!location.IsNullOrEmpty())
|
{
|
var isTransfer = CurInvItem?.Location?.LOCATION_CODE != location.LOCATION_CODE;
|
foreach (var item in CurInvItem.Items)
|
{
|
item.STATUS = WMS_ITEM.STATUSs.InStore.GetValue();
|
item.SUPP_LOTNO = CurInvItem.Barcode.LotNo;
|
item.FIRST_IN_DATE = item.FIRST_IN_DATE <= DateTime.MinValue ? DateTime.Now : item.FIRST_IN_DATE;
|
item.PROD_DATE = item.PROD_DATE <= DateTime.MinValue ? item.FIRST_IN_DATE : item.PROD_DATE;
|
item.WH_ID = location.WH_ID;
|
item.REGION_ID = location.REGION_ID;
|
item.SHELF_ID = location.SHELF_ID;
|
item.LOCATION_ID = location.LOCATION_ID;
|
CurInvItem.History.Add(new WMS_ITEM_HIS(item, $"条码[{CurInvItem.SN}]{(isTransfer ? $"从储位[{CurInvItem?.Location?.LOCATION_CODE}]移库" : "上架")}到储位[{location.LOCATION_CODE}]成功{(isTransfer ? "" : $",操作单据[{item.TRANS_NO}]")}"));
|
}
|
foreach (var item in CurInvItem.Packages)
|
{
|
item.WH_ID = location.WH_ID;
|
item.REGION_ID = location.REGION_ID;
|
item.SHELF_ID = location.SHELF_ID;
|
item.LOCATION_ID = location.LOCATION_ID;
|
}
|
foreach (var item in CurInvItem.ItemsExt)
|
{
|
item.AUTH_ORG = option.OrgCode;
|
item.SN = CurInvItem.Barcode.SN;
|
}
|
//更新储存信息
|
CurInvItem.Warehouse = location.Warehouse;
|
CurInvItem.Region = location.Region;
|
CurInvItem.Shelf = location.Shelf;
|
CurInvItem.Location = location.Location;
|
|
//创建变量克隆对象用于传入DBSubmitAction中保存当前需要暂存的数据值
|
var _Items = CurInvItem.Items.Clone();
|
var _Packages = CurInvItem.Packages.Clone();
|
var _History = CurInvItem.History.Clone();
|
var _ItemsExt = CurInvItem.ItemsExt.Clone();
|
AddCommitAction("PutOn", () =>
|
{
|
//使用统一的事务DB对象
|
var db = GetCommitDB();
|
//数据保存逻辑
|
db.Storageable(_Items, UserCode).ExecuteCommand();
|
db.Storageable(_Packages, UserCode).ExecuteCommand();
|
db.Insertable(_History, UserCode).ExecuteCommand();
|
var x = db.Storageable(_ItemsExt, UserCode).ToStorage();
|
x.AsInsertable.ExecuteCommand();//不存在插入
|
x.AsUpdateable.ExecuteCommand();//存在更新
|
});
|
}
|
else
|
{
|
result.Flag = Result.Flags.Failed;
|
result.LocaleMsg = new("WMS.WmsItem.PutOn.LocationNotExists", targetLocation);
|
}
|
}
|
catch (Exception ex)
|
{
|
result.CatchExceptionWithLog(ex, Biz.L("WMS.WmsItem.PutOn.Exception", CurInvItem.SN, targetLocation));
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 下架
|
/// </summary>
|
/// <param name="option">授权查询选项</param>
|
/// <param name="status">下架后状态</param>
|
/// <param name="clearLocation">是否清理储区货架储位信息</param>
|
/// <returns></returns>
|
public Result TakeDown(AuthOption option, WMS_ITEM.STATUSs status)
|
{
|
return TakeDown(CurInvItem.Items.ToDictionary(k => k.SN, v => v.QTY), option, status);
|
}
|
|
/// <summary>
|
/// 下架
|
/// </summary>
|
/// <param name="inventory">要下架的库存对象</param>
|
/// <param name="qtyList">要下架的最小包装数量字典,key:sn,value:qty</param>
|
/// <param name="option">授权查询选项</param>
|
/// <param name="status">下架后状态</param>
|
/// <param name="clearLocation">是否清理储区货架储位信息</param>
|
/// <returns></returns>
|
public Result TakeDown(Dictionary<string, double> qtyList, AuthOption option, WMS_ITEM.STATUSs status)
|
{
|
var result = new Result(Result.Flags.Success);
|
try
|
{
|
//如果要下架的数量字典为空则认为是全部下架
|
qtyList = qtyList.IsNullOrEmpty(CurInvItem.Items.ToDictionary(k => k.SN, v => v.QTY));
|
|
foreach (var item in CurInvItem.Items)
|
{
|
if (qtyList.ContainsKey(item.SN) && qtyList[item.SN] > 0)
|
{
|
var downQty = qtyList[item.SN];
|
if (item.QTY > downQty)
|
{
|
item.QTY -= downQty;
|
var pkg = CurInvItem.Packages.First(q => q.SN == item.SN);
|
pkg.QTY = item.QTY;
|
}
|
else
|
{
|
item.STATUS = status.GetValue();
|
var pkg = CurInvItem.Packages.First(q => q.SN == item.SN);
|
pkg.PARENT_SN = null;
|
pkg.Parent = null;
|
//如果下架数量等于库存数量则清理储区货架储位信息,否则保留仓库信息
|
//item.WH_ID = null;
|
item.REGION_ID = null;
|
item.SHELF_ID = null;
|
item.LOCATION_ID = null;
|
//pkg.WH_ID = null;
|
pkg.REGION_ID = null;
|
pkg.SHELF_ID = null;
|
pkg.LOCATION_ID = null;
|
}
|
CurInvItem.History.Add(new WMS_ITEM_HIS(item, $"条码[{CurInvItem.SN}]从储位[{CurInvItem?.Location?.LOCATION_CODE}]下架数量[{downQty}]成功,状态[{item.STATUS.GetEnumDesc<WMS_ITEM.STATUSs>()}],操作单据[{item.TRANS_NO}]"));
|
}
|
}
|
CurInvItem.Packages = WMS_ITEM_PKG.UpdateQty(CurInvItem.Packages);
|
|
//创建变量克隆对象用于传入DBSubmitAction中保存当前需要暂存的数据值
|
var _Items = CurInvItem.Items.Clone();
|
var _Packages = CurInvItem.Packages.Clone();
|
var _History = CurInvItem.History.Clone();
|
AddCommitAction("TakeDown", () =>
|
{
|
//使用统一的事务DB对象
|
var db = GetCommitDB();
|
//数据保存逻辑
|
db.Updateable(_Items, UserCode).ExecuteCommand();
|
db.Insertable(_History, UserCode).ExecuteCommand();
|
db.Updateable(_Packages, UserCode).ExecuteCommand();
|
});
|
}
|
catch (Exception ex)
|
{
|
result.CatchExceptionWithLog(ex, Biz.L("WMS.WmsItem.TakeDown.Exception", CurInvItem.SN, CurInvItem?.Location?.LOCATION_CODE));
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 设置当前条码的工序信息
|
/// </summary>
|
public ApiAction<ScanOutput> SetOutPutMqttMsg(ApiAction<ScanOutput> action, string locale = null)
|
{
|
MQTT.Message msg = new()
|
{
|
IsSuccessed = action.IsSuccessed,
|
Content = Biz.T(action.LocaleMsg, locale),
|
};
|
switch (action.Status)
|
{
|
case ApiAction.StatusCodes.Success:
|
msg.Voice = MQTT.Voice.Success;
|
msg.Color = "#FF1E90FF";
|
break;
|
case ApiAction.StatusCodes.Warning:
|
msg.Voice = MQTT.Voice.Warning;
|
msg.Color = "#FFB8860B";
|
break;
|
case ApiAction.StatusCodes.Error:
|
case ApiAction.StatusCodes.Failed:
|
msg.Voice = MQTT.Voice.Fail;
|
msg.Color = "#FFFF0000";
|
break;
|
case ApiAction.StatusCodes.Exception:
|
msg.Voice = MQTT.Voice.Fail;
|
msg.Color = "#FF8B0000";
|
break;
|
case ApiAction.StatusCodes.Normal:
|
case ApiAction.StatusCodes.NeedConfrim:
|
case ApiAction.StatusCodes.Confrimed:
|
default:
|
msg.Voice = MQTT.Voice.Silent;
|
msg.Color = "#FF000000";
|
break;
|
}
|
if (action.IsSuccessed)
|
{
|
msg.Voice = MQTT.Voice.Pass;
|
msg.Color = "#FF228B22";
|
}
|
else if (!action.IsSuccessed)
|
{
|
msg.Voice = MQTT.Voice.Fail;
|
msg.Color = "#FFFF0000";
|
}
|
else
|
{
|
msg.Voice = MQTT.Voice.Silent;
|
msg.Color = "#FF000000";
|
}
|
action.Data.MqttMsg = msg;
|
return action;
|
}
|
#endregion Functions
|
|
public override bool Close(bool needSaveHistoryLog = false)
|
{
|
//needSaveHistoryLog = true;
|
//保存操作日志
|
|
this.IsFinished = true;
|
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
|
}
|
}
|
}
|