using Rhea.Common;
using Tiger.Model.Minsun;
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.IBusiness;
using Tiger.Model;
using Newtonsoft.Json;
namespace Tiger.Business.WMS.Transaction
{
///
/// 客供料入库清点事务
///
public class CustomerSupplyIn : WMSTransactionBase, ICustomerSupplyIn
{
public ICustomerSupplyIn Init(string id, string userCode, string apiHost)
{
TransID = id;
UserCode = userCode;
ApiHost = apiHost;
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 RackCode { get; set; }
public string WarehouseCode { get; set; }
public string WarehouseName { get; set; }
public CustomerSupplyPuton CustomerSupplyPuton { get; set; }
#endregion
#region Functions
///
/// 扫描物料并复核,如果物料已经完成移库则货架上亮灯提醒储位
///
public async Task ScanItem(string sn)
{
var action = new ApiAction();
var multiRet = new MultiInvInStorageOutput();
try
{
if (string.IsNullOrEmpty(RackCode))
{
action.IsSuccessed = false;
action.Message = $"货架不能为空!";
return action;
}
if (string.IsNullOrEmpty(sn))
{
action.IsSuccessed = false;
action.Message = $"条码不能为空!";
return action;
}
var nLocation = new Model.Minsun.WMS_LOCATION();
var nDisassembleBarcode = iWMS.SplitFullBarcode(sn).Data;
//验证条码是否已经存在
var nBarcode = Biz.Db.Queryable().Where(t => t.BARCODE.ToUpper() == nDisassembleBarcode.Barcode.ToUpper()).First();
if (nBarcode != null)
{
action.IsSuccessed = false;
action.Message = $"扫描的条码已经入过库,无法重复扫描!";
return action;
}
// 根据物料Barcode 检索清点扫描表
var barcodeScanned = Biz.Db.Queryable().Where(t => t.BARCODE.ToUpper() == nDisassembleBarcode.Barcode.ToUpper()).First();
if (barcodeScanned == null)
{
action.IsSuccessed = false;
action.Message = $"此物料条码未做清点,不能入库";
return action;
}
else
{
if (barcodeScanned.STATUS != ScannedBarcodeStatus.Billed.ToString() || barcodeScanned.BUSINESSCODE.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.Message = $"此物料条码未生成库存单据,不能入库";
return action;
}
if (barcodeScanned.WAREHOUSECODE.ToUpper() != WarehouseCode.ToUpper())
{
action.IsSuccessed = false;
action.Message = $"此物料条码清点仓库与库位仓库不同,不能入库";
return action;
}
if (barcodeScanned.QTY != nDisassembleBarcode.LotQty)
{
action.IsSuccessed = false;
action.Message = $"此物料条码入库数量与清点数量不同,不能入库";
return action;
}
}
// 判断是否智能货架
if (CustomerSupplyPuton.IsSmartRack)
{
Result result = await Shelf.UpShelf(new ShelfOperateInput
{
ShelfNo = CustomerSupplyPuton.RackCode,
OperateType = "1"
});
if (result.Flag != Result.Flags.Success)
{
action.IsSuccessed = false;
action.Message = result.Message;
return action;
}
var reaultShelf = result.Data;
Logger.Default.Info($"智能货架返回信息:${JsonConvert.SerializeObject(reaultShelf)}");
if (reaultShelf.IsSuccess?.ToUpper() == "TRUE")
{
var rackCode = reaultShelf.ShelfNo;
var locationCode = reaultShelf.LocationCode;
//增加判断系统当前库位是否存在料盘 2022/07/30 Ben Lin
var storageBarcode = await Biz.Db.Queryable().Where(t => t.LOCATIONCODE == locationCode).FirstAsync();
if (storageBarcode != null)
{
action.IsSuccessed = false;
action.Message = $"系统当前库位存在料盘,请检查系统库存信息";
return action;
}
CustomerSupplyPuton.LocationCode = locationCode;
action.Message += $", 储位[{CustomerSupplyPuton.LocationCode}]";
nLocation = await Biz.Db.Queryable().Where(t => t.LOCATIONCODE == locationCode && t.RACKCODE == rackCode).FirstAsync();
}
else
{
action.IsSuccessed = false;
action.Message = $"发起上架失败,货架服务器异常";
return action;
}
}
else
{
if (CustomerSupplyPuton.LocationCode.IsNullOrEmpty() || CustomerSupplyPuton.WarehouseCode.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.Message = $"请先扫描库位码";
return action;
}
//验证库位盘数 和 剩余可放数量
var nStorageLotInfos = await Biz.Db.Queryable().Where(t => t.LOCATIONCODE == CustomerSupplyPuton.LocationCode.ToUpper()).ToListAsync();
if (nStorageLotInfos.Count >= CustomerSupplyPuton.LotCount)
{
action.IsSuccessed = false;
action.Message = $"库位盘数已满,该库位只能存放[{CustomerSupplyPuton.LotCount}]盘";
return action;
}
var nUsedCapacity = nStorageLotInfos.Any() ? nStorageLotInfos.Sum(x => x.QTY) : 0;
if (CustomerSupplyPuton.MaxSize <= (nUsedCapacity + nDisassembleBarcode.LotQty))
{
action.IsSuccessed = false;
action.Message = $"该库位的剩余容量[{Math.Round(CustomerSupplyPuton.MaxSize - nUsedCapacity, 2)}]无法放入当前条码,请确认";
return action;
}
nLocation = await Biz.Db.Queryable().Where(t => t.LOCATIONCODE == CustomerSupplyPuton.LocationCode).FirstAsync();
}
string billCode = barcodeScanned.BUSINESSCODE;
int? billLine = barcodeScanned.BUSINESSLINE;
int nScanStatus = (int)InvStorageInfoSides.ScanStatus.WORKING;
int? nSourceBillType = (int)InventoryTransferSides.BillType.ProductInstock;
int? nTargetBillType = null;
var nScanMain = await Biz.Db.Queryable().Where(t => t.SOURCEBILLTYPE == nSourceBillType && t.TARGETBILLTYPE == nTargetBillType
&& t.SOURCEBILLCODE.ToUpper() == billCode.ToUpper() && t.BILLSTATUS == nScanStatus).FirstAsync();
if (nScanMain == null)
{
nScanMain = new WMS_SCAN_H
{
Id = Guid.NewGuid().ToString(),
SOURCEBILLTYPE = nSourceBillType,
TARGETBILLTYPE = null,
BILLSTATUS = nScanStatus,
BILLCODE = DateTime.Now.ToString("yyyyMMddHHmmss"),
SOURCEBILLCODE = nDisassembleBarcode.OrderNo,
WAREHOUSECODE = CustomerSupplyPuton.WarehouseCode,
SUBMITTIME = DateTime.Now,
LastModificationTime = DateTime.Now,
CreationTime = DateTime.Now,
CreatorUserId = UserId,
SUBMITSTATUS = (int)InvStorageInfoSides.ScanSubmitStatus.INIT
};
}
//插入条码表
nBarcode = new WMS_BARCODE
{
Id = Guid.NewGuid().ToString(),
BARCODE = nDisassembleBarcode.Barcode, //接口直接将拆分好的Barcode传入
BARCODESTATUS = (int)InvStorageInfoSides.BarcodeStatus.Instock,
BARCODETYPE = (int)InvStorageInfoSides.BarcodeType.SN,
LOTNO = nDisassembleBarcode.Barcode, //批次代码采用外包装条码
DATECODE = nDisassembleBarcode.LotDate,
PERIOD = (nDisassembleBarcode.PeriodDays??0) >0 ? nDisassembleBarcode.LotDate.AddDays(nDisassembleBarcode.PeriodDays.Value) : (DateTime?)null,
MATERIALCODE = nDisassembleBarcode.MaterialCode,
SOURCETYPE = (int)InventoryTransferSides.BillType.OtherInStock,
SOURCECODE = billCode,
SOURCEDETAILLINE = billLine,
PACKQTY = nDisassembleBarcode.LotQty,
CURRENTQTY = nDisassembleBarcode.LotQty,
INITIALQTY = nDisassembleBarcode.LotQty,
QCSTATUS = (int)InvStorageInfoSides.QCStatus.GOOD,
SOURCEORDER = nDisassembleBarcode.OrderNo,
CreationTime = DateTime.Now,
CreatorUserId = UserId,
STATEFLAG = nDisassembleBarcode.StateFlag
};
var nScanDetail = Biz.Db.Queryable().Where(t => t.SCANMAINID == nScanMain.Id && t.SOURCEDETAILLINE == billLine
&& t.WAREHOUSECODE.ToUpper() == CustomerSupplyPuton.WarehouseCode.ToUpper() && t.MATERIALCODE.ToUpper() == nBarcode.MATERIALCODE.ToUpper()).ToList().FirstOrDefault();
if (nScanDetail != null)
{
nScanDetail.SCANQTY = (nScanDetail.SCANQTY ?? 0) + nDisassembleBarcode.LotQty < 0 ? 0 : (nScanDetail.SCANQTY ?? 0) + nDisassembleBarcode.LotQty;
}
else
{
nScanDetail = new WMS_SCAN_D
{
Id = Guid.NewGuid().ToString(),
SCANMAINID = nScanMain.Id,
BILLCODE = nScanMain.BILLCODE,
SOURCEDETAILLINE = billLine,
WAREHOUSECODE = CustomerSupplyPuton.WarehouseCode,
MATERIALCODE = nBarcode.MATERIALCODE,
SCANQTY = nDisassembleBarcode.LotQty,
LastModificationTime = DateTime.Now,
CreationTime = DateTime.Now,
CreatorUserId = UserId
};
}
//执行入库
action = iWMS.MultiInStorageAsync(new MultiInvInStorageInput
{
InvBarcodes = new List() { nBarcode },
InvBarcodeLogs = new List
{
new WMS_BARCODE_LOG
{
Id = Guid.NewGuid().ToString(),
INOUTTYPE = (int)InvStorageInfoSides.InOutType.InStock,
SOURCEBILLTYPE = (int)InventoryTransferSides.BillType.ProductInstock,
TARGETBILLTYPE = null,
BILLCODE = billCode,
BARCODE = nBarcode.BARCODE,
BARCODEREMARK = null,
BARCODETYPE = nBarcode.BARCODETYPE,
BOXTYPE = nBarcode.BOXTYPE,
PARENTBOXBARCODE = nBarcode.PARENTBOXBARCODE,
SOURCEBARCODE = nBarcode.SOURCEBARCODE,
LOTNO = nBarcode.LOTNO,
DATECODE = nBarcode.DATECODE,
MATERIALCODE = nBarcode.MATERIALCODE,
WAREHOUSECODE = WarehouseCode,
LOCATIONCODE = CustomerSupplyPuton.LocationCode,
SOURCETYPE = nBarcode.SOURCETYPE,
SOURCECODE = nBarcode.SOURCECODE,
SOURCEDETAILLINE = billLine,
INITIALQTY = 0,
QTY = nDisassembleBarcode.LotQty,
LASTQTY = nBarcode.CURRENTQTY ?? 0,
SCANMAINID = nScanMain.Id,
LastModificationTime = DateTime.Now,
CreationTime = DateTime.Now,
CreatorUserId = UserId,
SCANDETAILID = nScanDetail.Id
}
},
InvStorageLotInfos = new List{
new WMS_STORAGELOTINFO
{
Id = Guid.NewGuid().ToString(),
BARCODE = nBarcode.BARCODE,
BARCODESTATUS = (int)InvStorageInfoSides.BarcodeStatus.Instock,
MATERIALCODE = nBarcode.MATERIALCODE,
QTY = nBarcode.CURRENTQTY ?? 0,
WAREHOUSECODE = WarehouseCode,
LOCATIONCODE = CustomerSupplyPuton.LocationCode,
INSTOCKTYPE = (int)InventoryTransferSides.BillType.ProductInstock,
INSTOCKCODE = billCode,
INSTOCKDETAILLINE = billLine,
CreationTime = DateTime.Now,
CreatorUserId = UserId
}
},
InvStorageInfos = new List{
new WMS_STORAGEINFO
{
Id = Guid.NewGuid().ToString(),
WAREHOUSECODE = WarehouseCode,
MATERIALCODE = nBarcode.MATERIALCODE,
QTY = nBarcode.CURRENTQTY ?? 0,
LOCKQTY = 0,
CreationTime = DateTime.Now,
LastModificationTime = DateTime.Now,
CreatorUserId = UserId
}
},
InvScanDetails = new List{
nScanDetail
},
InvScanMains = new List {
nScanMain
},
WarehousCode = CustomerSupplyPuton.WarehouseCode,
LocationCode = CustomerSupplyPuton.LocationCode,
BusinessCode = billCode,
BusinessType = (int)InventoryTransferSides.BillType.ProductInstock,
});
if (!action.IsSuccessed)
{
return action;
}
action.Message += $"{action.Message.IsNullOrEmpty("", ";")}执行入库成功";
#region 更新单据信息
//其他出入库单
//新单据行状态
var billDetail = Biz.Db.Queryable().Where(t => t.BILLCODE.ToUpper() == billCode.ToUpper() && t.BILLLINE == billLine).First();
billDetail.DELIVERYDATE = DateTime.Now.Date;
billDetail.QTY += nDisassembleBarcode.LotQty;
var isCompleted = false;
// 更新单据HEADER状态
var billHeader = Biz.Db.Queryable().Where(t => t.BILLCODE.ToUpper() == billCode).First();
if (billDetail.QTY == billDetail.PRQTY)
{
billDetail.LINESTATUS = OtherInstockSides.Status.COMPLETE.ToString();
if (!Biz.Db.Queryable().Where(t => t.BILLCODE.ToUpper() == billCode.ToUpper() && t.BILLLINE != billLine && t.LINESTATUS != OtherInstockSides.Status.COMPLETE.ToString()).Any())
{
billHeader.STATUS = OtherInstockSides.Status.COMPLETE.ToString();
isCompleted = true;
}
}
else
{
billDetail.LINESTATUS = OtherInstockSides.Status.WORKING.ToString();
}
Logger.Default.Info($"更新单据明细信息[WMS_OTHERINSTOCK_D]:单号[{billCode}],项次[{billLine}],数量[{billDetail.QTY}],状态[{billDetail.LINESTATUS}]");
#endregion
//保存到数据库
var db = Business.Biz.Db;
var dbTran = db.UseTran(() =>
{
// 删除清点扫描条码记录
db.Deleteable(barcodeScanned).ExecuteCommand();
db.Updateable(billDetail).ExecuteCommand();
db.Updateable(billHeader).ExecuteCommand();
});
if (!dbTran.IsSuccess)
{
throw dbTran.ErrorException;
}
//生成其他入库单
if (isCompleted)
{
List detail2s = new List();
var Details = await Biz.Db.Queryable().Where(t => t.BILLCODE.ToUpper() == billCode.ToUpper()).ToListAsync();
foreach (var item in Details)
{
detail2s.Add(new Detail4
{
pmdtseq = "1",
pmdt027 = billHeader.ERP_BILL_CODE,
pmdt028 = item.BILLLINE.ToString(),
pmdt006 = item.MATERIALCODE,
pmdt020 = item.QTY.ToString(),
pmdtud011 = "0",
pmdt016 = item.WAREHOUSECODE,
pmdt017 = "",
pmdt018 = billHeader.REMARK
});
}
var ret = ErpT100.GenerateOtherIn(new OtherInputParameter
{
parameter = new InParameter
{
pmdstype = "6",
pmdsdocno = "3538", //--单别
pmdsdocdt = DateTime.Now.ToString("yyyy-MM-dd"), //"2022/3/24",
pmds002 = UserCode == "admin" ? "00000" : UserCode, //"00000",
pmds003 = "",
pmds006 = billHeader.ERP_BILL_CODE,
pmds007 = "C0006",
detail = detail2s
},
datakey = new Datakey
{
EntId = "88",
CompanyId = "DGXC"
}
});
if (ret.payload.std_data.execution.code != "0")
{
action.IsSuccessed = false;
action.Message = $"其他入库单[{billCode}],收货单[{billHeader.ERP_BILL_CODE}],错误信息:[{ret.payload.std_data.execution.description}]";
return action;
}
else
{
action.Message += $"其他入库单[{billCode}],收货单[{billHeader.ERP_BILL_CODE}]入库完成,扣账成功返回T100入库单据[{ret.payload.std_data.parameter.docno}]";
}
}
// 返回其他入库对象
action.Data = new OtherInstockBarcodeOutput
{
Barcode = nDisassembleBarcode.Barcode,
MaterialCode = nDisassembleBarcode.MaterialCode,
MaterialName = nDisassembleBarcode?.MaterialName,
MaterialStandard = nDisassembleBarcode?.MaterialStandard,
InitialQty = nDisassembleBarcode.LotQty,
CurrentQty = nDisassembleBarcode.LotQty,
Unit = nDisassembleBarcode.Unit,
DateCode = nDisassembleBarcode.LotDate,
Period = nDisassembleBarcode.PeriodDays.HasValue ? nDisassembleBarcode.LotDate.AddDays(nDisassembleBarcode.PeriodDays.Value) : (DateTime?)null,
LotNo = nDisassembleBarcode.Barcode, //批次号默认为外包装条码
SourceBillCode = billCode,
SourceBillLine = billLine,
StateFlag = nDisassembleBarcode.StateFlag,
LocationCode = nLocation.LOCATIONCODE,
ReceiptCode = barcodeScanned?.BUSINESSCODE,
IncompleteTips = isCompleted? "数量:0 (0盘)" : iWMS.GetIncompleteTips(barcodeScanned?.BUSINESSCODE, barcodeScanned?.MATERIALCODE),
};
}
catch (Exception ex)
{
//取消当前操作
action.CatchExceptionWithLog(ex, $"扫描物料[{sn}]复核异常");
}
return action;
}
///
/// 扫描货架或者储位
///
public async Task> ScanShelf(string Code)
{
var action = new ApiAction();
try
{
if (Code.IsNullOrEmpty())
{
action.IsSuccessed = false;
action.Message = $"请输入或扫描有效的货架/储位码";
return action;
}
CustomerSupplyPuton = new CustomerSupplyPuton();
// 查询货架信息
var nRack = await Biz.Db.Queryable().Where(t => t.RACKCODE.ToUpper() == Code.ToUpper()).FirstAsync();
// 扫描货架代码,且为智能货架
if (nRack != null && nRack.RACKTYPE.ToUpper() == "SMARTRACK")
{
CustomerSupplyPuton.WarehouseCode = nRack.WHCODE;
CustomerSupplyPuton.RackCode = nRack.RACKCODE;
CustomerSupplyPuton.RackType = nRack.RACKTYPE;
CustomerSupplyPuton.IsSmartRack = true;
}
// 扫描库位代码
else
{
var nLocation = await Biz.Db.Queryable().Where(t => t.LOCATIONCODE.ToUpper() == Code.ToUpper()).FirstAsync();
if (nLocation == null)
{
action.IsSuccessed = false;
action.Message = $"扫描的库位不存在";
return action;
}
if (!nLocation.ISUSE)
{
action.IsSuccessed = false;
action.Message = $"扫描的库位未启用";
return action;
}
var nStorageLotInfos = await Biz.Db.Queryable().Where(x => x.LOCATIONCODE.ToUpper() == nLocation.LOCATIONCODE.ToUpper()).ToListAsync();
if (nStorageLotInfos.Count >= nLocation.LOTCOUNT)
{
action.IsSuccessed = false;
action.Message = $"库位盘数已满,该库位只能存放[{nLocation.LOTCOUNT}]盘";
return action;
}
// 计算库位剩余容量
var nUsedCapacity = nStorageLotInfos.Any() ? nStorageLotInfos.Sum(x => x.QTY) : 0;
if (nLocation.MAXSIZE <= nUsedCapacity)
{
action.IsSuccessed = false;
action.Message = $"该库位已经放满";
return action;
}
CustomerSupplyPuton.LocationCode = nLocation.LOCATIONCODE;
CustomerSupplyPuton.WarehouseCode = nLocation.WHCODE;
CustomerSupplyPuton.Capacity = nLocation.MAXSIZE - nUsedCapacity;
CustomerSupplyPuton.LotCount = nLocation.LOTCOUNT;
CustomerSupplyPuton.MaxSize = nLocation.MAXSIZE;
CustomerSupplyPuton.IsSmartRack = false;
CustomerSupplyPuton.RackCode = nLocation.RACKCODE;
}
WarehouseCode = CustomerSupplyPuton.WarehouseCode;
RackCode = CustomerSupplyPuton.RackCode;
action.Data = CustomerSupplyPuton;
}
catch (Exception ex)
{
//取消当前操作
action.CatchExceptionWithLog(ex, $"扫描货架或者储位[{Code}]异常");
}
return action;
}
///
/// 测试用
///
///
///
public async Task Test(string Code)
{
var action = new ApiAction();
try
{
List detail2s = new List();
var Details = await Biz.Db.Queryable().Where(t => t.BILLCODE.ToUpper() == Code).ToListAsync();
foreach (var item in Details)
{
detail2s.Add(new Detail4
{
pmdtseq = "1",
pmdt027 = "DG3453-230500213",
pmdt028 = item.BILLLINE.ToString(),
pmdt006 = item.MATERIALCODE,
pmdt020 = item.QTY.ToString(),
pmdtud011 = "0",
pmdt016 = item.WAREHOUSECODE,
pmdt017 = "",
pmdt018 ="创米科技"
});
}
var ret = ErpT100.GenerateOtherIn(new OtherInputParameter
{
parameter = new InParameter
{
pmdstype = "6",
pmdsdocno = "3538", //--单别
pmdsdocdt = DateTime.Now.ToString("yyyy-MM-dd"), //"2022/3/24",
pmds002 = UserCode == "admin" ? "00000" : UserCode, //"00000",
pmds003 = "",
pmds006 = "DG3453-230500213",
pmds007 = "C0006",
detail = detail2s //
},
datakey = new Datakey
{
EntId = "88",
CompanyId = "DGXC"
}
});
if (ret.payload.std_data.execution.code != "0")
{
action.IsSuccessed = false;
action.Message = $"错误信息:[{ret.payload.std_data.execution.description}]";
return action;
}
else
{
action.Message = $"入库完成,扣账成功返回T100入库单据[{ret.payload.std_data.parameter.docno}]";
}
}
catch (Exception ex)
{
//取消当前操作
action.CatchExceptionWithLog(ex, $"扫描货架或者储位[{Code}]异常");
}
return action;
}
#endregion
public override bool Close(bool needSaveHistoryLog = false)
{
//如果CurItem不为空则清空,且判断是否亮灯储位,如果是则灭灯
//if (CurItem != null)
//{
// try
// {
// LocationLightOff(CurItem).Wait();
// }
// catch (System.Exception ex)
// {
// Logger.Console.Fatal(ex, "一般移库事务Close关灯异常");
// }
// CurItem = null;
//}
//保存操作日志
this.IsFinished = true;
return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished;
}
}//endClass
}