using Rhea.Common;
using Tiger.Business.WMS.Seastone;
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 System.Reflection.Emit;
using Tiger.Model;
using Tiger.IBusiness;
namespace Tiger.Business.WMS.Transaction
{
///
/// 其他入库清点事务
///
public class OtherInLocationChecking : WMSTransactionBase, IOtherInLocationChecking
{
public IOtherInLocationChecking 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 VenderCode { get; set; }
public string LotNo { get; set; }
public string SecondVenderCode { get; set; }
public string WarehouseCode { get; set; }
public string WarehouseName { get; set; }
public string OrgCode { get; set; }
public string CustomsNo { get; set; }
public List suppliers { get; set; }
#endregion Propertys & Variables
#region Functions
///
/// 扫描物料并复核,如果物料已经完成移库则货架上亮灯提醒储位
///
public async Task ScanItem(CustSupplyCheckingInput input)
{
var action = new ApiAction();
try
{
if (string.IsNullOrEmpty(input.SN))
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.SnEmptyFailure", input.SN);
return action;
}
#region 报关单号判断
if (input.AuthOption.CurOrg == "YTXC" && string.IsNullOrWhiteSpace(CustomsNo))
{
if (string.IsNullOrWhiteSpace(input.SN))
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L($"盐田据点请扫描报关单号二维码!");
return action;
}
var customsNo = input.SN.Replace(",", ",").Trim();
if (customsNo.Split(",").Length != 2)
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L($"报关单号格式错误,请确认格式是否为【报关单号,核算清单号】!");
return action;
}
CustomsNo = input.SN;
action.Data = new IncomingMatStorage
{
sn = CustomsNo,
IsCustomsNo = true
};
action.IsSuccessed = true;
action.LocaleMsg = Biz.L($"报关单号二维码扫描成功");
return action;
}
#endregion 报关单号判断
//判断是否扫描的仓库,并查询是否存在
var query = Biz.Db.Queryable().Where(t => t.WH_CODE == input.SN.Trim()).First();
if (query != null)
{
WarehouseCode = query.WH_CODE;
WarehouseName = query.WH_NAME;
action.Data = query;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.GetWhSuccess", WarehouseCode);
return action;
}
if (string.IsNullOrEmpty(WarehouseCode))
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.NotExist", input.SN);
return action;
}
input.AuthOption.OrgCode = input.AuthOption.OrgCode.IsNullOrEmpty() ? input.AuthOption.CurOrg : input.AuthOption.OrgCode;
Result result = WarehouseName.Contains("客供") ? WMS_ITEM_Biz.WmsItem.GetK(input.SN, input.AuthOption, false) : WMS_ITEM_Biz.WmsItem.Get(input.SN, input.AuthOption, false);
if (result.Flag != Result.Flags.Success)
{
action.IsSuccessed = false;
action.LocaleMsg = result.LocaleMsg;
return action;
}
var curInv = result.Data as Inventory;
if (!curInv.IsQRCode)
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.NotQrCode", curInv.Barcode.MetaSn);
return action;
}
//判断条码是否为最少包装
if (!new[] { Barcode.Types.Small, Barcode.Types.Other }.Contains(curInv.Barcode.Type))
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.TypeError", curInv.SN);
return action;
}
//判断条码状态为不存在或已下架可以清点(!nDisassembleBarcode.isNormalStatus ||)
//物料验证
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 (!new[] { WMS_ITEM.STATUSs.NotExists, WMS_ITEM.STATUSs.OffShelf }.Contains(curInv.Status))
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.ExistItem", curInv.ItemInfo.ITEM_CODE);
return action;
}
BIZ_ERP_OTH_IN_SNExt snExt = new();
// BIZ_ERP_OTH_IN_SN scanResult = Business.Biz.Db.Queryable().Where(q=>q.SN==curBarcode.Barcode.SN).First();
//验证条码是否已做过清点
var scanResult = Biz.Db.Queryable().Where(t => t.SN.ToUpper() == curInv.SN.ToUpper()).First();
if (!scanResult.IsNullOrEmpty() && scanResult.STATUS > WMS_ITEM.STATUSs.Counted.GetValue())
{
action.IsSuccessed = false;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.BarcodeCounted", curInv.SN);
return action;
}
var isNo = true;
//判断物料是否存在
if (scanResult.IsNullOrEmpty())
{
isNo = false;
scanResult = new();
scanResult.ID = Guid.NewGuid().ToString();
scanResult.CREATE_USER = UserCode;
scanResult.BUSINESSCODE = "OTH_" + UserCode;
scanResult.WAREHOUSECODE = WarehouseCode;
scanResult.SN = curInv.Barcode.SN;
scanResult.ITEM_CODE = curInv.Barcode.ItemCode;
scanResult.QTY = curInv.Barcode.Qty ?? 0;
scanResult.DATECODE = curInv.Barcode.ProdDate ?? DateTime.MinValue;
scanResult.LOTNO = LotNo; //item.Barcode.LotNo;
scanResult.STATUS = WMS_ITEM.STATUSs.Counted.GetValue();
scanResult.META_SN = input.SN;
scanResult.AUTH_ORG = input.AuthOption.CurOrg;
}
else
{
isNo = true;
//scanResult.ID = Guid.NewGuid().ToString();
scanResult.BUSINESSCODE = "OTH_" + UserCode;
scanResult.WAREHOUSECODE = WarehouseCode;
scanResult.SN = curInv.SN;
scanResult.ITEM_CODE = curInv.ItemInfo.ITEM_CODE;
scanResult.QTY = curInv.Barcode.Qty ?? 0;
scanResult.DATECODE = curInv.Barcode.ProdDate ?? DateTime.MinValue;
scanResult.LOTNO = LotNo; //item.Barcode.LotNo;
scanResult.STATUS = WMS_ITEM.STATUSs.Counted.GetValue();
scanResult.META_SN = input.SN;
scanResult.AUTH_ORG = input.AuthOption.CurOrg;
}
OrgCode = input.AuthOption.CurOrg;
snExt.BUSINESSCODE = scanResult.BUSINESSCODE;
snExt.WAREHOUSECODE = scanResult.WAREHOUSECODE;
snExt.SN = scanResult.SN;
snExt.ITEM_CODE = scanResult.ITEM_CODE;
snExt.QTY = scanResult.QTY;
snExt.DATECODE = scanResult.DATECODE;
snExt.DATECODESTR = scanResult.DATECODESTR;
snExt.LOTNO = scanResult.LOTNO;
snExt.STATUS = scanResult.STATUS;
snExt.WH_CODE = scanResult.WAREHOUSECODE;
snExt.WH_NAME = WarehouseName;
snExt.MName = curInv.ItemInfo?.ITEM_NAME;
snExt.MDesc = curInv.ItemInfo?.SPEC;
snExt.MUom = curInv.ItemInfo?.UNIT;
//保存到数据库
var db = Business.Biz.Db;
var model = new BIZ_ERP_CUSTOMS()
{
AUTH_ORG = input.AuthOption.CurOrg,
CREATE_USER = UserCode,
OrderNo = UserCode,
Barcodes = curInv.SN,
CustomsNo = CustomsNo.Replace(",", ",").Trim().Split(',')[0],
AccountingNo = CustomsNo.Replace(",", ",").Trim().Split(',')[1],
CountsType = BIZ_ERP_CUSTOMS.CountsEnum.OtherInput
};
if (model != null)
{
db.Insertable(model).ExecuteCommand();
}
var dbTran = db.UseTran(() =>
{
db.Storageable(scanResult).ExecuteCommand();
});
if (!dbTran.IsSuccess)
{
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
this.Close(!dbTran.IsSuccess);
throw dbTran.ErrorException;
}
action.Data = snExt;
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.CountSuccess", input.SN);
}
catch (Exception ex)
{
//取消当前操作
action.CatchExceptionWithLog(ex, $"扫描物料[{input.SN}]复核异常");
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.ScanException", input.SN);
}
return action;
}
//
/// 生成其他物料入库单据
///
///
///
public async Task SubmitInvBill()
{
var action = new ApiAction();
bool isIQCOk = true;
try
{
//获取当前用户所有已清点、未制单的条码数据
var nScannedBarcodes = await Biz.Db.Queryable((t, m) =>
new JoinQueryInfos(
JoinType.Left, t.ITEM_CODE == m.ITEM_CODE
))
.Where((t, m) => t.CREATE_USER == UserCode
&& t.WAREHOUSECODE.ToUpper() == WarehouseCode.ToUpper()
&& t.STATUS == WMS_ITEM.STATUSs.Counted.GetValue()
&& t.BUSINESSCODE == "OTH_" + UserCode
&& t.AUTH_ORG == OrgCode)
.Select((t, m) => new BIZ_ERP_OTH_IN_SNExt
{
ID = t.ID,
SN = t.SN,
ITEM_CODE = t.ITEM_CODE,
QTY = t.QTY,
META_SN = t.META_SN,
BUSINESSCODE = t.BUSINESSCODE,
BUSINESSLINE = t.BUSINESSLINE,
UPDATE_TIME = t.UPDATE_TIME,
UPDATE_USER = t.UPDATE_USER,
CREATE_TIME = t.CREATE_TIME,
CREATE_USER = t.CREATE_USER,
DATECODE = t.DATECODE,
DATECODESTR = t.DATECODESTR,
LOTNO = t.LOTNO,
STATUS = t.STATUS,
WAREHOUSECODE = t.WAREHOUSECODE,
MUom = m.UNIT,
MName = m.ITEM_NAME,
MDesc = m.SPEC,
})
.ToListAsync();
if (!nScannedBarcodes.Any())
{
action.IsSuccessed = false;
action.Message = $"没有可以提交的清点数据";
action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.NotDataToSubmit");
return action;
}
// 查询条码清点表所有仓库代码
//var nWarehouseCodes = nScannedBarcodes.Select(x => x.WarehouseCode).Distinct().ToList();
//新建其他入库单据头 OtherInstockHeader
Result ruleResult = Cache.CodeRule["OI001"].Generate("OI"); //iWMS.GetBillNoByType("CI");
if (!ruleResult.IsSuccessed)
{
throw new Exception(ruleResult.ExceptionMsg.Message);
}
var billcode = ruleResult.Data.ToString();
var nBillHeader = new BIZ_ERP_OTH_IN
{
BILLCODE = billcode,
BILLDATE = DateTime.Now.Date,
WAREHOUSECODE = WarehouseCode,
STATUS = BIZ_ERP_OTH_IN.STATUSs.WORKING.GetValue(),
REMARK = LotNo,
AUTH_ORG = OrgCode
};
// 查找待处理记录料号列表
var nMaterials = nScannedBarcodes.Select(x => x.ITEM_CODE).Distinct().ToList();
// 单据行号变量,初始值1
var nLineSeq = 1;
List scanList = new List();
List detailList = new List();
//List iqcHeaders = new List();
//List details = new List();
// 按照料号列表处理单据明细
foreach (var matCode in nMaterials)
{
// 按照料号、计量单位汇总scanBarcode
var lineMaterials = (from codes in nScannedBarcodes.Where(x => x.ITEM_CODE.ToUpper() == matCode.ToUpper())
group codes by new { codes.ITEM_CODE, codes.MUom } into g
select new
{
g.Key.ITEM_CODE,
g.Key.MUom,
sumQty = g.Sum(x => x.QTY)
}
).ToList();
// 循环处理每一行
foreach (var matLine in lineMaterials)
{
//插入单据明细行
var billDetail = new BIZ_ERP_OTH_IN_DTL
{
WAREHOUSECODE = WarehouseCode,
BILLCODE = billcode,
BILLLINE = nLineSeq.ToString(),
LINESTATUS = BIZ_ERP_OTH_IN.STATUSs.WORKING.GetValue(),
ITEM_CODE = matLine.ITEM_CODE,
UNITCODE = matLine.MUom,
PRQTY = matLine.sumQty,
AUTH_ORG = OrgCode,
QTY = 0
};
detailList.Add(billDetail);
// 更新清点表,单据号
foreach (BIZ_ERP_OTH_IN_SN barcode in nScannedBarcodes.Where(x => x.ITEM_CODE == matLine.ITEM_CODE))
{
barcode.BUSINESSCODE = billcode;
barcode.BUSINESSLINE = nLineSeq.ToString();
barcode.STATUS = WMS_ITEM.STATUSs.WaitIn.GetValue();
barcode.AUTH_ORG = OrgCode;
scanList.Add(barcode);
}
// 单据明细行号 ++
nLineSeq++;
}
}
////调用T100接口生成到货单
List Items = new List();
List ItemPkgs = new List();
List ItemHistorys = new List();
#region 生成库存数据
foreach (var wi in nScannedBarcodes)
{
Barcode barcode = new Barcode(wi.META_SN);
WMS_ITEM wmsItem = new WMS_ITEM
{
SN = wi.SN,
ITEM_CODE = wi.ITEM_CODE,
QTY = wi.QTY,
PROD_DATE = barcode.ProdDate ?? DateTime.MinValue,
SUPP_CODE = VenderCode,
LOTNO = LotNo,
ERP_WH = WarehouseCode,
STATUS = WMS_ITEM.STATUSs.WaitIn.GetValue(),
TRANS_CODE = nameof(BIZ_ERP_OTH_IN),
TRANS_NO = billcode,
TRANS_LINE = wi.BUSINESSLINE,
//SOURCE_CODE = nameof(BIZ_ERP_IQC),
//SOURCE_ORDER = item.BILLCODE,
AUTH_ORG = OrgCode,
};
Items.Add(wmsItem);
WMS_ITEM_HIS his = new WMS_ITEM_HIS(wmsItem, $"其他入库单清点,到货单[{billcode}]");
ItemHistorys.Add(his);
WMS_ITEM_PKG pKG = new WMS_ITEM_PKG
{
SN = wi.SN,
ITEM_CODE = wi.ITEM_CODE,
PARENT_SN = "",
PKG_TYPE = WMS_ITEM_PKG.PKG_TYPEs.OnePiece.GetValue(),
QTY = wi.QTY,
SUPP_CODE = VenderCode,
LOTNO = LotNo,
ERP_WH = WarehouseCode,
TRANS_CODE = nameof(BIZ_ERP_OTH_IN),
TRANS_NO = billcode,
TRANS_LINE = wi.BUSINESSLINE,
//SOURCE_CODE = nameof(BIZ_ERP_IQC),
//SOURCE_ORDER = item.BILLCODE,
AUTH_ORG = OrgCode,
};
ItemPkgs.Add(pKG);
}
#endregion 生成库存数据
//保存到数据库
var db = Business.Biz.Db;
var dbTran = db.UseTran(() =>
{
// 插入单据表头
var headerId = Biz.Db.Insertable(nBillHeader, UserCode).ExecuteReturnBigIdentity();
var x = db.Storageable(detailList, UserCode).ToStorage();
x.AsInsertable.ExecuteCommand();//不存在插入
x.AsUpdateable.IgnoreColumns(z => new { z.CREATE_TIME, z.CREATE_USER }).ExecuteCommand();//存在更新,更新时忽略字段CreationTime、CreatorUserId
db.Updateable(scanList, UserCode).ExecuteCommand();
//if (action.IsSuccessed && isIQCOk)
//{
// db.Insertable(iqcHeaders, UserCode).ExecuteCommand();
// action.Message += $"{action.Message.IsNullOrEmpty("", ";")}生成其他物料入库单据和送检单成功";
//}
//db.Insertable(Items, UserCode).ExecuteCommand();
var y = db.Storageable(Items, UserCode).WhereColumns(t => t.SN).ToStorage();
y.AsInsertable.ExecuteCommand();//不存在插入
y.AsUpdateable.ExecuteCommand();
db.Insertable(ItemPkgs, UserCode).ExecuteCommand();
db.Insertable(ItemHistorys, UserCode).ExecuteCommand();
});
if (!dbTran.IsSuccess)
{
Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception");
this.Close(!dbTran.IsSuccess);
throw dbTran.ErrorException;
}
}
catch (System.Exception ex)
{
return action.CatchExceptionWithLog(ex, Biz.L(""));
}
return action;
}
///
/// 删除当前用户的已扫记录(缓存表)
///
///
public async Task DeleteAllScannedBarcode()
{
var action = new ApiAction();
try
{
if (WarehouseCode.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.Message = $"空,无法删除已清点条码";
return action;
}
else
{
await Biz.Db.Deleteable(x => x.CREATE_USER == UserCode
&& x.WAREHOUSECODE == WarehouseCode
&& x.STATUS == WMS_ITEM.STATUSs.Counted.GetValue()
&& x.BUSINESSCODE == "OTH_" + UserCode).ExecuteCommandAsync();
}
}
catch (System.Exception ex)
{
}
return action;
}
///
/// 删除单个条码(缓存表)
///
///
public async Task DeleteScannedBarcode(CustSupplyInInput input)
{
var action = new ApiAction();
try
{
if (WarehouseCode.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.Message = $"空,无法删除已清点条码";
return action;
}
else
{
await Biz.Db.Deleteable(x => x.SN == input.SN).ExecuteCommandAsync();
}
}
catch (System.Exception ex)
{
}
return action;
}
///
/// 获取已清点的物料汇总
///
///
public async Task> GetScannedMaterialSummarys()
{
var query = Biz.Db.Queryable((t, m) =>
new JoinQueryInfos(
JoinType.Left, t.ITEM_CODE == m.ITEM_CODE
))
.Where((t, m) => t.CREATE_USER == UserCode
&& t.WAREHOUSECODE.ToUpper() == WarehouseCode.ToUpper()
&& t.STATUS == WMS_ITEM.STATUSs.Counted.GetValue()
&& t.BUSINESSCODE == "OTH_" + UserCode)
.GroupBy((t, m) => new { t.WAREHOUSECODE, t.ITEM_CODE })
.Select((t, m) => new Model.Minsun.CustSupplyCheckList
{
WarehouseCode = t.WAREHOUSECODE,
MaterialCode = t.ITEM_CODE,
MaterialName = SqlFunc.AggregateMax(m.ITEM_NAME),
MaterialStandard = SqlFunc.AggregateMax(m.SPEC),
InventoryQty = SqlFunc.AggregateSum(t.QTY),
Unit = SqlFunc.AggregateMax(m.UNIT)
})
.ToList();
return await Task.FromResult(new PageAble()
{
data = query,
totals = query.Count(),
});
}
///
/// 查询物料对应的条码
///
///
///
public async Task> GetScannedMaterialDetailBarcodes(string MaterialCode)
{
var query = await Biz.Db.Queryable((t, m) =>
new JoinQueryInfos(
JoinType.Left, t.ITEM_CODE == m.ITEM_CODE
))
.Where((t, m) => t.CREATE_USER == UserCode
&& t.WAREHOUSECODE.ToUpper() == WarehouseCode.ToUpper()
&& t.STATUS == WMS_ITEM.STATUSs.Counted.GetValue()
&& t.ITEM_CODE.ToUpper() == MaterialCode.ToUpper()
&& t.BUSINESSCODE == "OTH_" + UserCode)
.Select((t, m) => new Model.Minsun.CustSupplyCheckDetail
{
Barcode = t.SN,
BarcodeQty = t.QTY,
Unit = m.UNIT
})
.ToListAsync();
return new PageAble()
{
data = query,
totals = query.Count(),
};
}
#endregion Functions
public override bool Close(bool needSaveHistoryLog = false)
{
//保存操作日志
this.IsFinished = true;
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
}
}//endClass
}