using Rhea.Common;
using Microsoft.AspNetCore.Http;
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;
using Tiger.Business.WMS.Sharetronic.Shelf;
using Tiger.IBusiness;
namespace Tiger.Business.WMS.Transaction
{
///
/// 仓库盘点事务
///
public class WmsCount : WMSTransactionBase, IWmsCount
{
public IWmsCount 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 Inventory CurInv { get; set; }
public WMS_COUNT count { get; set; }
public List Shelfs { get; set; }
public List locations { get; set; }
public List mdtls { get; set; }
public List ldtls { get; set; }
public List sumlist { get; set; }
#endregion
#region Functions
///
/// 盘点单列表
///
///
///
///
///
///
public ApiAction> GetCountHeaders(int pageIndex, int pageSize, string orgcode, string billcode)
{
var action = new ApiAction>();
try
{
var query = Biz.Db.Queryable().Where(x =>
(x.STATUS < WMS_COUNT.STATUSs.Paused.GetValue())
&& x.AUTH_ORG == orgcode)
.WhereIF(!billcode.IsNullOrEmpty(), x => x.COUNT_NO.Contains(billcode))
.OrderByDescending(x => x.UPDATE_TIME)
.OrderBy(x => x.CREATE_TIME)
.ToPage(pageIndex, pageSize);
action.Data = query;
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"盘点单获取列表异常");
}
return action;
}
///
/// 盘点单选择事件
///
///
///
public async Task> SelectOrder(CountEntity input)
{
var action = new ApiAction();
try
{
count = await Biz.Db.Queryable().ByAuth(input.AuthOption).Where(x => x.COUNT_NO == input.CountNo)
.Includes(q => q.MDtlsWithGhost, d => d.Warehouse)
.Includes(q => q.MDtlsWithGhost, d => d.Region)
.Includes(q => q.MDtlsWithGhost, d => d.Shelf)
.Includes(q => q.MDtlsWithGhost, d => d.Location)
.IncludesAllFirstLayer().FirstAsync();
mdtls = count.MDtls;
ldtls = count.LDtls;
sumlist = count.SumList;
locations = count.MDtls.Where(x => x.STATUS == WMS_COUNT_MDTL.STATUSs.WaitCount.GetValue()).Select(x => x.Location).Distinct().ToList();
Shelfs = count.MDtls.Where(q => q.SHELF_ID != null && q.STATUS==0).Select(x => x.Shelf).Distinct().ToList();
action.Data = new CountEntityReturn()
{
CountNo = input.CountNo,
Shelfs = Shelfs.Select(q => new ShelfDropDown { SHELF_CODE = q.SHELF_CODE, SHELF_NAME = q.SHELF_NAME }).ToList(),
Warehouse = count.MDtls.Select(x => x.Warehouse).First(),
COUNT_TYPE = count.COUNT_TYPE
};
action.LocaleMsg = Biz.L($"选择盘点单[{input.CountNo}]成功");
//action = await LightAll(new() { AuthOption = input.AuthOption, ReqType = CurReqType, Color = LedColor.Blue });
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"盘点单选择异常");
}
return action;
}
///
/// 盘点单推荐所有物料亮灯
///
///
///
public async Task> LightAll(CountLightEntity light)
{
var action = new ApiAction();
try
{
var _shelf = Shelfs.Where(q => q.SHELF_CODE == light.ShelfCode).FirstOrDefault();
var list = locations.Where(q => q.SHELF_ID == _shelf.ID).ToList();
if (list.Any())
{
await Share.Shelf.LightMulti(TransID, light.Color, list);
action.Data = new CountOutput()
{
CountNo = count.COUNT_NO,
};
Logger.Interface.Info($"亮灯成功,亮灯颜色[{light.Color.GetDesc()}],亮灯位置[{string.Join(",", list.Select(t => t.LOCATION_CODE))}]");
action.LocaleMsg = Biz.L("亮灯成功,亮灯颜色[{0}]", light.Color.GetDesc());
}
else
{
action.LocaleMsg = Biz.L($"无需亮灯,盘点的物料不在智能货架上");
}
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"亮灯异常");
}
return action;
}
///
/// 盘点单明细
///
///
public async Task>> CountSumDtl(BasePageInput input)
{
var action = new ApiAction>();
try
{
var query = Biz.Db.Queryable().ByAuth(input.AuthOption)
.WhereIF(!input.Code.IsNullOrEmpty(), x => x.ITEM_CODE.Contains(input.Code))
.Where(t => t.COUNT_NO == count.COUNT_NO)
.OrderByDescending(x => x.UPDATE_TIME.ToString("yyyy-MM-dd"))
.OrderBy(x => x.CREATE_TIME)
.ToPage(input.pageIndex, input.pageSize);
action.Data = await Task.FromResult(query);
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"获取盘点单明细异常");
}
return action;
}
/////
///// 发料明细提示信息
/////
/////
//public async Task GetItemTips(string itemcode)
//{
// var action = new ApiAction();
// try
// {
// action.Data = $"物料{itemcode}:已下架[{(double)req.Dtls.Where(x => x.ITEM_CODE == itemcode).Sum(x => x.OUTQTY)}],共{(double)req.Dtls.Where(x => x.ITEM_CODE == itemcode).Sum(x => x.PRQTY)} {Suggests.FirstOrDefault()?.Item?.UNIT}";
// }
// catch (Exception ex)
// {
// action.CatchExceptionWithLog(ex, $"获取发料明细提示信息异常");
// }
// return action;
//}
///
/// 扫描物料调度下架
///
///
///
public async Task> ScanItem(BaseInput input)
{
var action = new ApiAction();
try
{
if (input.SN.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("条码不能为空");
return action;
}
//解析条码
Result 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.WmsCount.ScanItem.StatusException", string.Join(',', CurInv.StatusList.Select(x => x.GetDesc())));
return action;
}
//储位验证
if (CurInv.Location.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.WmsCount.ScanItem.LocationIsNull", CurInv.CurPkg.SN, CurInv.CurPkg.LOCATION_ID);
return action;
}
//物料验证
if (CurInv.ItemInfo.IsNullOrEmpty() || !mdtls.Where(t => t.ITEM_CODE == CurInv.ItemInfo?.ITEM_CODE).Any())
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.WmsCount.ScanItem.NotFound", CurInv.ItemInfo.ITEM_CODE.IsNullOrEmpty(CurInv.Barcode.ItemCode));
return action;
}
//var aa = mdtls.Where(t => t.SN == CurInv.CurPkg.SN).First();
//V076420231110000003
//更新条码盘点明细状态
var mItem = mdtls.Where(q=> CurInv.Items.Any(a=>q.SN==a.SN)).ToList() ?? new List()
{
new()
{
COUNT_NO = count.COUNT_NO,
SN = CurInv.SN,
QTY = CurInv.CurPkg.QTY,
ITEM_CODE = CurInv.ItemInfo.ITEM_CODE,
UNIT = CurInv.ItemInfo.UNIT,
PROD_DATE = CurInv.Items[0].PROD_DATE,
FIRST_IN_DATE = CurInv.Items[0].FIRST_IN_DATE,
SUPP_CODE = CurInv.CurPkg.SUPP_CODE,
SUPP_LOTNO = CurInv.CurPkg.SUPP_LOTNO,
WH_ID = CurInv.CurPkg.WH_ID,
REGION_ID = CurInv.CurPkg.REGION_ID,
SHELF_ID = CurInv.CurPkg.SHELF_ID,
LOCATION_ID = CurInv.CurPkg.LOCATION_ID,
ERP_WH = CurInv.CurPkg.ERP_WH,
RESULT = WMS_COUNT_MDTL.RESULTs.NewFound.GetValue(),
}
};
//如果是新发现的条码就添加到列表中
foreach (var item in mItem)
{
if (item.RESULT == WMS_COUNT_MDTL.RESULTs.NewFound.GetValue()) { mdtls.Add(item); }
if (item.STATUS == WMS_COUNT_MDTL.STATUSs.Counted.GetValue())
{
//灭灯
var _action = await DownLight(input);
if (!_action.IsSuccessed)
{
return _action;
}
action.IsSuccessed = false;
action.LocaleMsg = Biz.L($"该条码已经盘点过,请扫描其他未盘点的条码!");
return action;
}
item.ACTION = WMS_COUNT_MDTL.ACTIONs.NoAdjust.GetValue();
item.STATUS = WMS_COUNT_MDTL.STATUSs.Counted.GetValue();
item.REVIEWER = UserCode;
item.REVIEW_DATE = DateTime.Now;
item.ACT_QTY = CurInv.CurPkg.QTY;
item.RESULT = item.RESULT == WMS_COUNT_MDTL.RESULTs.NewFound.GetValue() ? WMS_COUNT_MDTL.RESULTs.NewFound.GetValue() : WMS_COUNT_MDTL.RESULTs.Founded.GetValue();
//var lItem = ldtls.Where(t => t.LOCATION_ID == CurInv.CurPkg.LOCATION_ID).FirstOrDefault();
////如果是新发现的条码,其原储位又没有在盘点储位列表中
//bool isNewFound = false;
//if (lItem == null && item.RESULT == WMS_COUNT_MDTL.RESULTs.NewFound.GetValue())
//{
// lItem = new()
// {
// COUNT_NO = count.COUNT_NO,
// ITEM_CODE = CurInv.ItemInfo.ITEM_CODE,
// UNIT = CurInv.ItemInfo.UNIT,
// WH_ID = CurInv.CurPkg.WH_ID,
// REGION_ID = CurInv.CurPkg.REGION_ID,
// SHELF_ID = CurInv.CurPkg.SHELF_ID,
// LOCATION_ID = CurInv.CurPkg.LOCATION_ID,
// ERP_WH = CurInv.CurPkg.ERP_WH,
// QTY = CurInv.CurPkg.QTY,
// SN_QTY = 1,
// ACT_SN_QTY = 1,
// ACT_QTY = CurInv.CurPkg.QTY,
// STATUS = WMS_COUNT_LDTL.STATUSs.Counted.GetValue(),
// RESULT = lItem.QTY == lItem.ACT_QTY ? WMS_COUNT_LDTL.RESULTs.Balance.GetValue() : (lItem.QTY > lItem.ACT_QTY ? WMS_COUNT_LDTL.RESULTs.Losses.GetValue() : WMS_COUNT_LDTL.RESULTs.Profit.GetValue())
// };
// isNewFound = true;
//}
var sumItem = sumlist.Where(t => t.ITEM_CODE == CurInv.ItemInfo.ITEM_CODE).FirstOrDefault();
count.STATUS = count.STATUS == WMS_COUNT.STATUSs.New.GetValue() ? WMS_COUNT.STATUSs.Counting.GetValue() : count.STATUS;
//如果扫描列表状态都是已盘点,则结束并更新盘点单状态
if (mdtls.Count == mdtls.Where(t => t.STATUS == WMS_COUNT_MDTL.STATUSs.Counted.GetValue()).Count())
{
count.STATUS = WMS_COUNT.STATUSs.Closed.GetValue();
}
locations = mdtls.Where(x => x.STATUS == WMS_COUNT_MDTL.STATUSs.WaitCount.GetValue()).Select(x => x.Location).Distinct().ToList();
//灭灯
var Action = await DownLight(input);
if (!Action.IsSuccessed)
{
item.STATUS = WMS_COUNT_MDTL.STATUSs.WaitCount.GetValue();
return Action;
}
//保存数据库
var db = Business.Biz.Db;
var dbTran = db.UseTran(() =>
{
db.Storageable(mItem, UserCode).ExecuteCommand();
//if (isNewFound)
//{
// ldtls.Add(lItem);
// db.Insertable(lItem, UserCode).ExecuteCommand();
//}
//else
//{
// db.Updateable().SetColumns(t => new WMS_COUNT_LDTL
// {
// STATUS = WMS_COUNT_LDTL.STATUSs.Counted.GetValue(),
// ACT_QTY = t.ACT_QTY + CurInv.CurPkg.QTY,
// ACT_SN_QTY = t.ACT_SN_QTY + 1,
// UPDATE_USER = UserCode,
// UPDATE_TIME = DateTime.Now,
// RESULT = Convert.ToInt32(SqlFunc.IF(t.QTY == t.ACT_QTY + CurInv.CurPkg.QTY).Return(WMS_COUNT_LDTL.RESULTs.Balance.GetValue()).ElseIF(t.QTY > t.ACT_QTY + CurInv.CurPkg.QTY).Return(WMS_COUNT_LDTL.RESULTs.Losses.GetValue()).End(WMS_COUNT_LDTL.RESULTs.Profit.GetValue()))
// }).Where(q => q.ID == lItem.ID).ExecuteCommand();
//}
if (sumItem != null)
{
db.Updateable().SetColumns(t => new WMS_COUNT_SUM
{
ACT_QTY = t.ACT_QTY + CurInv.CurPkg.QTY,
ACT_SN_QTY = t.ACT_SN_QTY + 1,
UPDATE_USER = UserCode,
UPDATE_TIME = DateTime.Now,
RESULT = Convert.ToInt32(SqlFunc.IF(t.QTY == t.ACT_QTY + CurInv.CurPkg.QTY).Return(WMS_COUNT_SUM.RESULTs.Balance.GetValue()).ElseIF(t.QTY > t.ACT_QTY + CurInv.CurPkg.QTY).Return(WMS_COUNT_SUM.RESULTs.Losses.GetValue()).End(WMS_COUNT_SUM.RESULTs.Profit.GetValue()))
}).Where(q => q.ID == sumItem.ID).ExecuteCommand();
}
db.Updateable(count, UserCode).UpdateColumns(t => new { t.UPDATE_TIME, t.UPDATE_USER, t.STATUS }).ExecuteCommand();
});
if (!dbTran.IsSuccess)
{
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
this.Close(!dbTran.IsSuccess);
throw dbTran.ErrorException;
}
}
if (count.STATUS == WMS_COUNT.STATUSs.Closed.GetValue())
{
CloseLight(new CountLightEntity() { ShelfCode = "" });
}
action.LocaleMsg = Biz.L($"条码[{CurInv.CurPkg.SN}]核实成功,单号:[{count.COUNT_NO}],状态:{count.STATUS.GetEnumDesc()}");
//var shelfs = Biz.Db.Queryable().Where(q =>q.COUNT_NO==count.COUNT_NO && q.SHELF_ID != null && q.STATUS == 0).Select(x => x.Shelf).Distinct().ToList();
var shelfs = mdtls.Where(q => q.SHELF_ID != null && q.STATUS == 0).Select(x => x.Shelf).Distinct().ToList();
action.Data = new CountOutput()
{
SN = CurInv.CurPkg.SN,
ItemCode = CurInv.ItemInfo.ITEM_CODE,
ItemName = CurInv.ItemInfo.ITEM_VER,
ItemDesc = CurInv.ItemInfo.ITEM_NAME,
Qty = CurInv.CurPkg.QTY,
regionCode = CurInv.Region.REGION_CODE,
locationCode = CurInv.Location?.LOCATION_CODE,
Unit = CurInv.CurPkg.UNIT,
Shelfs= shelfs.Select(q => new ShelfDropDown { SHELF_CODE = q.SHELF_CODE, SHELF_NAME = q.SHELF_NAME }).ToList(),
Status = $"已盘点数:[{mdtls.Where(t => t.STATUS == WMS_COUNT_MDTL.STATUSs.Counted.GetValue()).Count()}]/总数:[{mdtls.Count}]"
};
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"扫描物料[{input.SN}]复核异常");
}
return action;
}
///
/// 选普通货架带出储位
///
///
///
public async Task> ChangeShelf(BaseInput input)
{
var action = new ApiAction();
try
{
//检查是否是智能货架
var whUnit = await Biz.Db.Queryable().Where(t => t.SHELF_CODE.ToUpper() == input.SN.ToUpper() && t.AUTH_ORG == OrgCode).IncludesAllFirstLayer().FirstAsync();
if (whUnit != null && whUnit.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.Smart.GetValue())
{
var shelfs = mdtls.Where(q => q.SHELF_ID != null && q.STATUS == 0).Select(x => x.Shelf).Distinct().ToList();
action.Data = new CountOutput()
{
locationCode = "",
Shelfs = shelfs.Select(q => new ShelfDropDown { SHELF_CODE = q.SHELF_CODE, SHELF_NAME = q.SHELF_NAME }).ToList(),
};
}
else
{
//查询出所有储位
var locations = mdtls.Where(q=>q.Shelf.SHELF_CODE==input.SN && q.STATUS==0).Select(q=>q.Location.LOCATION_CODE).Distinct().ToList();
string joined = String.Join(",", locations);
var shelfs = mdtls.Where(q => q.SHELF_ID != null && q.STATUS == 0).Select(x => x.Shelf).Distinct().ToList();
action.Data = new CountOutput()
{
locationCode = joined,
Shelfs = shelfs.Select(q => new ShelfDropDown { SHELF_CODE = q.SHELF_CODE, SHELF_NAME = q.SHELF_NAME }).ToList(),
};
}
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"选择货架[{input.SN}]复核异常");
}
return action;
}
///
/// 灭灯
///
///
///
private async Task> DownLight(BaseInput input)
{
var action = new ApiAction();
try
{
if (CurInv.Shelf.SHELF_TYPE == WMS_SHELF.SHELF_TYPEs.Smart.GetValue())
{
ShelfApiResult shelfApiResult = await Share.Shelf.PutOn(TransID, CurInv.Shelf, CurInv.Items[0]);
if (!shelfApiResult.IsSuccess)
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L(shelfApiResult.GetData());
return action;
}
var reaultShelf = shelfApiResult.GetData();
var nLocation = reaultShelf.GetLocation();
if (nLocation == null)
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L($"系统不存在储位,请先维护货架信息");
return action;
}
if (nLocation.LOCATION_CODE != CurInv.Location.LOCATION_CODE)
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L($"货架返回的储位跟条码所在的储位不一样");
return action;
}
}
//灭灯
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);
}
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"扫描物料[{input.SN}]复核异常");
}
return action;
}
///
/// 灭灯
///
///
public async Task CloseLight(CountLightEntity light)
{
var action = new ApiAction();
try
{
var _shelf = Shelfs.Where(q => q.SHELF_CODE == light.ShelfCode).FirstOrDefault();
var list = light.ShelfCode.IsNullOrEmpty() ? mdtls.Select(x => x.Location).Distinct().ToList() : locations.Where(q => q.SHELF_ID == _shelf.ID).ToList();
if (list.Any())
{
//灭灯
await Share.Shelf.DownMulti(TransID, list);
action.Data = new CountOutput()
{
CountNo = count.COUNT_NO,
};
action.LocaleMsg = Biz.L("灭灯成功");
}
else
{
action.LocaleMsg = Biz.L($"无需灭灯");
}
}
catch (Exception ex)
{
action.CatchExceptionWithLog(ex, $"灭灯异常");
}
return action;
}
///
/// 添加一个ApiAction的历史记录
///
///
public override void AddHistory(Microsoft.AspNetCore.Http.HttpRequest request, ApiAction action)
{
var his = action.History();
his.TraceDic.Add("mdtls", mdtls);
his.TraceDic.Add("ldtls", ldtls);
his.TraceDic.Add("count", count);
his.TraceDic.Add("sumlist", sumlist);
ActionHistoryList.Add($"{request.HttpContext.TraceIdentifier} at {action.Timestamp:yyyy/MM/dd HH:mm:ss.fff}: {request.Path}", his);
LastActionTime = DateTime.Now;
}
#endregion
///
/// 关闭
///
///
///
public override bool Close(bool needSaveHistoryLog = false)
{
//检查盘点单是否关闭
Biz.Db.Ado.UseStoredProcedure().ExecuteCommand("pkg_count_status", new SugarParameter("CountNo", count.COUNT_NO));
//needSaveHistoryLog = true;
CloseLight(new CountLightEntity() { ShelfCode = "" }).Wait();
//保存操作日志
this.IsFinished = true;
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
}
}//endClass
}