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;
namespace Tiger.Business.WMS.Transaction
{
///
/// 仓库作业任务,包括清点、上架、下架、移库、盘点等
///
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; }
///
/// 跟客户端通讯时的指令,有具体功能定义,默认为Normal
///
public string Command { get; set; } = "Normal";
///
/// 是否需要临时存储数据库提交操作,待需要的时候再提交
///
public bool NeedTemporaryStoreDBCommitAction { get; set; } = false;
protected Dictionary> 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;
}
///
/// 获取提交数据的DbClient对象
///
///
public DbClient GetCommitDB()
{
return CommitDB ??= Biz.Db;
}
///
/// 增加暂存的数据库操作
///
/// 暂存的分组
/// 暂存的数据库操作
public void AddCommitAction(string group, Action action)
{
//增加附加的保存内容
if (!action.IsNullOrEmpty())
{
if (!DBCommitList.ContainsKey(group))
{
DBCommitList.Add(group, new List());
}
var commitList = DBCommitList[group];
commitList.Add(action);
}
}
///
/// 暂存的数据库操作提交到数据库
///
/// 附加的保存内容
public void SaveCommitListToDB(Action appendToSave = null)
{
//增加附加的保存内容
if (!appendToSave.IsNullOrEmpty())
{
if (!DBCommitList.ContainsKey("AppendSaveAction"))
{
DBCommitList.Add("AppendSaveAction", new List());
}
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();
}
}
});
if (dbTran.IsSuccess)
{
//保存成功则清空提交操作列表
DBCommitList.Clear();
}
else
{
//抛出异常
throw dbTran.ErrorException;
}
}
}
///
/// 上架
///
/// 要上架的库存对象
/// 授权查询选项
/// 要上架的储位代码
/// 是否移库操作
///
public Result PutOn(AuthOption option, string targetLocation)
{
var result = new Result(Result.Flags.Success);
try
{
var location = Biz.Db.Queryable().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;
}
///
/// 下架
///
/// 授权查询选项
/// 下架后状态
/// 是否清理储区货架储位信息
///
public Result TakeDown(AuthOption option, WMS_ITEM.STATUSs status)
{
return TakeDown(CurInvItem.Items.ToDictionary(k => k.SN, v => v.QTY), option, status);
}
///
/// 下架
///
/// 要下架的库存对象
/// 要下架的最小包装数量字典,key:sn,value:qty
/// 授权查询选项
/// 下架后状态
/// 是否清理储区货架储位信息
///
public Result TakeDown(Dictionary 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()}],操作单据[{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;
}
#endregion Functions
public override bool Close(bool needSaveHistoryLog = false)
{
//needSaveHistoryLog = true;
//保存操作日志
this.IsFinished = true;
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
}
}
}