using Model.InterFaceModel;
|
using Model.ModelDto.BllSoDto;
|
using Model.ModelVm.BllSoVm;
|
using SqlSugar;
|
using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Data;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Xml;
|
using Model.ModelDto.DataDto;
|
using Newtonsoft.Json;
|
using Utility.Tools;
|
using WMS.BLL.DataServer;
|
using WMS.BLL.Logic;
|
using WMS.BLL.LogServer;
|
using WMS.DAL;
|
using WMS.Entity.BllSoEntity;
|
using WMS.Entity.Context;
|
using WMS.Entity.DataEntity;
|
using WMS.Entity.LogEntity;
|
using WMS.Entity.SysEntity;
|
using WMS.IBLL.IBllSoServer;
|
using Model.ModelVm;
|
using System.Runtime.Intrinsics.X86;
|
using ZXing.OneD;
|
using System.Threading.Tasks;
|
using System.Diagnostics;
|
using System.Drawing.Drawing2D;
|
using Model.ModelDto.LogDto;
|
using AutoMapper.Internal;
|
|
namespace WMS.BLL.BllSoServer
|
{
|
public class ExportNoticeServer : DbHelper<BllExportNotice>, IExportNoticeServer
|
{
|
private static readonly SqlSugarScope Db = DataContext.Db;
|
private readonly object IssueOutLock = new object();
|
public ExportNoticeServer() : base(Db)
|
{
|
}
|
|
#region 上游接口
|
|
/* /// <summary>
|
/// 创建出库单据--20240611不能用重写
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
public bool ErpAddExportNotice(SoInfo model)
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(model.SoType))
|
{
|
throw new Exception("单据类型不可为空!");
|
}
|
if (string.IsNullOrEmpty(model.Customer))
|
{
|
throw new Exception("客户不可为空!");
|
}
|
if (string.IsNullOrEmpty(model.OrderCode))
|
{
|
throw new Exception("系统单号不可为空!");
|
}
|
if (model.SoDetails.Count <= 0)
|
{
|
throw new Exception("出库单明细不可为空!");
|
}
|
var skuNos = model.SoDetails.Select(a => a.SkuNo).Distinct().ToList();
|
//根据物料号获取物料信息、库存明细中获取批次描述供货批次等
|
var skuList = Db.Queryable<SysMaterials>().Where(a => skuNos.Contains(a.SkuNo) && a.IsDel == "0").ToList();
|
var stockList = Db.Queryable<DataStock>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList();
|
|
//客户信息
|
var customer = Db.Queryable<SysCustomer>().First(m => m.IsDel == "0" && m.CustomerNo == model.Customer);
|
if (customer == null)
|
{
|
throw new Exception("客户不可为空!");
|
}
|
var logistics = Db.Queryable<SysLogisticsInfo>().First(m => m.IsDel == "0" && m.CarrierName == model.LogisticsNo);
|
int? logisticsId = null;
|
if (logistics != null)
|
{
|
logisticsId = logistics.Id;
|
}
|
var billNo = "";
|
var bl = true;
|
do
|
{
|
//获取自增单据号
|
billNo = new Common().GetMaxNo("SO");
|
var no = billNo;
|
bl = Db.Queryable<BllExportNotice>().Any(m => m.SONo == no);
|
} while (bl);
|
|
|
Db.BeginTran();//开启事务
|
|
try
|
{
|
var list = new List<BllExportNoticeDetail>();
|
//添加出库单
|
foreach (var d in model.SoDetails)
|
{
|
if (d.Qty < 1)
|
{
|
throw new Exception("出库数量必须大于0");
|
}
|
var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo);
|
if (sku == null)
|
{
|
throw new Exception($"物料信息中未查询到出库物料信息:{d.SkuNo}");
|
}
|
|
//0:成品出库、1:领料出库、3:物料取样出库、4:不合格品出库、6:代储出库、7:其他出库、 ///2:抽检出库、5:中间品出库、8:寄存出库
|
if (model.SoType == "0" || model.SoType == "3" || model.SoType == "4" || model.SoType == "7" )
|
{
|
if (string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
throw new Exception("批次不可为空!");
|
}
|
}
|
//库存
|
List<DataStock> stocks;
|
|
decimal q1 = 0;
|
Dictionary<int, decimal> dic = new Dictionary<int, decimal>();
|
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList();
|
if (stocks.Count < 1)
|
{
|
throw new Exception($"总库存中未查询到出库物料信息:{d.SkuNo}");
|
}
|
//判断数量
|
var qty = stocks.First().Qty - stocks.First().LockQty - stocks.First().FrozenQty;
|
if (d.Qty > qty)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足");
|
}
|
if (qty > d.Qty - q1)
|
{
|
q1 += d.Qty - q1;
|
dic.Add(stocks.First().Id, d.Qty - q1);
|
}
|
else
|
{
|
q1 += qty;
|
dic.Add(stocks.First().Id, qty);
|
}
|
|
}
|
else
|
{
|
//首先查询当前这种物料批次号为空的
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList();
|
var i = 0;
|
if (stocks.Count > 0)
|
{
|
var q2 = stocks.First().Qty - stocks.First().LockQty - stocks.First().FrozenQty;
|
if (q2 > d.Qty - q1)
|
{
|
q1 += d.Qty - q1;
|
dic.Add(stocks.First().Id, d.Qty - q1);
|
}
|
else
|
{
|
q1 += q2;
|
dic.Add(stocks.First().Id, q2);
|
}
|
i++ ;
|
}
|
//如果批次号为空的数量不够,根据批次先进先出原则查找其它批次的
|
if (d.Qty >= q1)
|
{
|
stocks = stockList.Where(m => m.SkuNo == d.SkuNo && !string.IsNullOrWhiteSpace(m.LotNo)).OrderBy(s => s.LotNo).ToList();
|
|
foreach (var demo in stocks)
|
{
|
if (model.SoType == "1")
|
{
|
if (i >= 2)
|
{
|
throw new Exception("领料出库单同单据同物料不允许超过3个批次混批出库");
|
}
|
}
|
else
|
{
|
if (i >= 1)
|
{
|
throw new Exception("出库单同单据同物料不允许超过2个批次混批出库");
|
}
|
}
|
|
if (q1 >= d.Qty)
|
{
|
continue;
|
}
|
var q2 = demo.Qty - demo.LockQty - demo.FrozenQty;
|
|
if (q2 > d.Qty - q1)
|
{
|
q1 += d.Qty - q1;
|
dic.Add(demo.Id, d.Qty - q1);
|
}
|
else
|
{
|
q1 += q2;
|
dic.Add(demo.Id, q2);
|
}
|
|
i++;
|
}
|
}
|
if (d.Qty > q1)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo} 库存数量不足");
|
}
|
}
|
|
foreach (var s in dic)
|
{
|
var st = stockList.First(a => a.Id == s.Key);
|
var item = new BllExportNoticeDetail()
|
{
|
SONo = billNo,
|
SkuNo = sku.SkuNo,
|
SkuName = sku.SkuName,
|
Standard = sku.Standard,
|
LotNo = st.LotNo,
|
LotText = st.LotText,
|
Qty = s.Value,
|
AllotQty = 0,
|
FactQty = 0,
|
CompleteQty = 0,
|
PackagNo = sku.PackagNo,
|
Price = sku.Price,
|
Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * d.Qty,
|
IsBale = "",
|
IsBelt = "",
|
SupplierLot = stocks.First().SupplierLot,
|
IsWave = "0",
|
WaveNo = "",
|
IsIssueLotNo = string.IsNullOrWhiteSpace(d.LotNo) ? "0" : "1",
|
|
CreateUser = 0,
|
};
|
list.Add(item);
|
|
st.LockQty += s.Value;//锁定数量
|
var i = Db.Updateable(st).UpdateColumns(it => new { it.LockQty })
|
.ExecuteCommand();
|
}
|
|
}
|
var notice = new BllExportNotice()
|
{
|
SONo = billNo,
|
Type = model.SoType,
|
Status = "0",
|
Origin = "WMS",
|
CustomerNo = model.Customer,
|
CustomerName = customer.CustomerName,
|
LogisticsId = logisticsId,
|
IsWave = "0",
|
WaveNo = "",
|
IsDespatch = "0",
|
|
CreateUser = 0,
|
};
|
|
var n = Db.Insertable<BllExportNotice>(notice).ExecuteCommand();
|
var m = Db.Insertable<BllExportNoticeDetail>(list).ExecuteCommand();
|
|
if (n <= 0 || m <= 0)
|
{
|
Db.RollbackTran();
|
return false;
|
}
|
Db.CommitTran();
|
//回传上游系统锁定数量信息
|
return true;
|
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
|
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
}*/
|
|
/// <summary>
|
/// 创建出库单据
|
/// </summary>
|
/// <param name="model"></param>
|
/// <returns></returns>
|
public SoResInfo ErpAddExportNotice(SoInfo model)
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(model.SoType))
|
{
|
throw new Exception("单据类型不可为空!");
|
}
|
if (string.IsNullOrEmpty(model.OrderCode))
|
{
|
throw new Exception("系统单号不可为空!");
|
}
|
if (model.SoDetails.Count <= 0)
|
{
|
throw new Exception("出库单明细不可为空!");
|
}
|
//返回信息
|
SoResInfo result = new SoResInfo();
|
|
var skuNos = model.SoDetails.Select(a => a.SkuNo).Distinct().ToList();
|
//根据物料号获取物料信息
|
var skuList = Db.Queryable<SysMaterials>().Where(a => skuNos.Contains(a.SkuNo) && a.IsDel == "0").ToList();
|
//获取库存明细
|
var stockDetailList = Db.Queryable<DataStockDetail>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0 && s.InspectStatus == "1").ToList();
|
//获取库存
|
var stockList = Db.Queryable<DataStock>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList();
|
|
string CustomerName = string.Empty;
|
if (!string.IsNullOrEmpty(model.Customer))
|
{
|
//客户信息
|
var customer = Db.Queryable<SysCustomer>().First(m => m.IsDel == "0" && m.CustomerNo == model.Customer);
|
if (customer == null)
|
{
|
throw new Exception("客户信息不存在!");
|
}
|
CustomerName = customer.CustomerName;
|
}
|
//承运商信息
|
var logistics = Db.Queryable<SysLogisticsInfo>().First(m => m.IsDel == "0" && m.CarrierName == model.LogisticsNo);
|
int? logisticsId = null;
|
if (logistics != null)
|
{
|
logisticsId = logistics.Id;
|
}
|
var billNo = "";
|
var bl = true;
|
do
|
{
|
//获取自增单据号
|
billNo = new Common().GetMaxNo("SO");
|
var no = billNo;
|
bl = Db.Queryable<BllExportNotice>().Any(m => m.SONo == no);
|
} while (bl);
|
|
List<SoDetailInfo> soDetailList = new List<SoDetailInfo>();
|
//开启事务
|
Db.BeginTran();
|
try
|
{
|
var list = new List<BllExportNoticeDetail>();
|
//添加出库单
|
foreach (var d in model.SoDetails)
|
{
|
if (d.Qty < 1)
|
{
|
throw new Exception("出库数量必须大于0");
|
}
|
var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo);
|
if (sku == null)
|
{
|
throw new Exception($"物料信息中未查询到出库物料信息:{d.SkuNo}");
|
}
|
//0:成品出库、1:领料出库、3:物料取样出库、4:不合格品出库、6:代储出库、7:其他出库、 ///2:抽检出库、5:中间品出库、8:寄存出库
|
if (model.SoType == "0" || model.SoType == "3" || model.SoType == "4" || model.SoType == "7")
|
{
|
if (string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
throw new Exception("批次不可为空!");
|
}
|
}
|
//库存明细
|
List<DataStockDetail> stockDetails;
|
//指定批次
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
stockDetails = stockDetailList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList();
|
if (stockDetails.Count < 1)
|
{
|
throw new Exception($"库存中未查询到出库物料信息:{d.SkuNo}");
|
}
|
//判断数量
|
var qty = stockDetails.Sum(s => s.Qty - s.FrozenQty - s.LockQty);
|
if (d.Qty > qty)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足");
|
}
|
//库存信息
|
var stockInfo = stockList.First(w => w.SkuNo == d.SkuNo && w.LotNo == d.LotNo);
|
if (stockInfo == null)
|
{
|
throw new Exception($"总库存中未查询到出库物料信息:{d.SkuNo}");
|
}
|
//判断总库存数量
|
if (d.Qty > stockInfo.Qty - stockInfo.FrozenQty - stockInfo.LockQty)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足");
|
}
|
//添加出库单明细
|
var noticeDetail = new BllExportNoticeDetail()
|
{
|
SONo = billNo,
|
SkuNo = sku.SkuNo,
|
SkuName = sku.SkuName,
|
Standard = sku.Standard,
|
LotNo = d.LotNo,
|
LotText = stockInfo.LotText,
|
Qty = d.Qty,
|
AllotQty = 0,
|
FactQty = 0,
|
CompleteQty = 0,
|
PackagNo = sku.PackagNo,
|
Price = sku.Price,
|
Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * d.Qty,
|
IsBale = "",
|
IsBelt = "",
|
SupplierLot = stockInfo.SupplierLot,
|
IsWave = "0",
|
WaveNo = "",
|
IsIssueLotNo = string.IsNullOrWhiteSpace(d.LotNo) ? "0" : "1",
|
IsMixBox = d.IsMixBox,
|
|
OrderDetailCode = d.OrderDetailCode,
|
|
CreateUser = 0,
|
};
|
list.Add(noticeDetail);
|
//更新库存锁定数量
|
stockInfo.LockQty += d.Qty;
|
var i = Db.Updateable(stockInfo).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
|
SoDetailInfo soDetail = new SoDetailInfo();
|
soDetail.OrderDetailCode = d.OrderDetailCode;
|
soDetail.LockQty = d.Qty;
|
soDetail.LotNo = d.LotNo;
|
|
soDetailList.Add(soDetail);
|
}
|
else//未指定批次
|
{
|
Dictionary<int, decimal> dic = new Dictionary<int, decimal>();
|
decimal q1 = 0;
|
//首先查询当前这种物料批次号为空的
|
stockDetails = stockDetailList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList();
|
if (stockDetails.Count > 0)
|
{
|
q1 = (decimal)stockDetails.Sum(s => s.Qty - s.FrozenQty - s.LockQty);
|
//库存信息
|
var stockInfo = stockList.FirstOrDefault(w => w.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(w.LotNo));
|
if (stockInfo != null)
|
{
|
var q2 = stockInfo.Qty - stockInfo.FrozenQty - stockInfo.LockQty;
|
if (q2 < q1)
|
{
|
q1 = q2;
|
}
|
if (d.Qty > q1)
|
{
|
dic.Add(stockInfo.Id, q1);
|
}
|
else
|
{
|
dic.Add(stockInfo.Id, d.Qty);
|
}
|
}
|
}
|
//如果批次号为空的数量不够,根据批次先进先出原则查找其它批次的
|
if (d.Qty > q1)
|
{
|
stockDetails = stockDetailList.Where(m => m.SkuNo == d.SkuNo && !string.IsNullOrWhiteSpace(m.LotNo)).OrderBy(s => s.LotNo).ToList();
|
foreach (var demo in stockDetails)
|
{
|
if (q1 >= d.Qty)
|
{
|
break;
|
}
|
var q2 = demo.Qty - demo.FrozenQty - demo.LockQty;
|
//库存信息
|
var stockInfo = stockList.FirstOrDefault(w => w.SkuNo == d.SkuNo && w.LotNo == demo.LotNo);
|
if (stockInfo == null)
|
{
|
continue;
|
}
|
decimal q4 = 0;
|
if (dic.ContainsKey(stockInfo.Id))
|
{
|
q4 = dic[stockInfo.Id];
|
}
|
var q3 = stockInfo.Qty - stockInfo.FrozenQty - stockInfo.LockQty - q4;
|
if (q3 < q2)
|
{
|
q2 = q3;
|
}
|
if (q2 > d.Qty - q1)
|
{
|
if (!dic.ContainsKey(stockInfo.Id))
|
{
|
dic.Add(stockInfo.Id, d.Qty - q1);
|
}
|
else
|
{
|
//更新值
|
dic[stockInfo.Id] += d.Qty - q1;
|
}
|
q1 += d.Qty - q1;
|
}
|
else
|
{
|
if (!dic.ContainsKey(stockInfo.Id))
|
{
|
dic.Add(stockInfo.Id, (decimal)q2);
|
}
|
else
|
{
|
//更新值
|
dic[stockInfo.Id] = dic[stockInfo.Id] + (decimal)q2;
|
}
|
q1 += (decimal)q2;
|
}
|
}
|
}
|
if (d.Qty > q1)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo} 库存数量不足");
|
}
|
foreach (var s in dic)
|
{
|
var st = stockList.First(a => a.Id == s.Key);
|
var item = new BllExportNoticeDetail()
|
{
|
SONo = billNo,
|
OrderDetailCode = d.OrderDetailCode,
|
SkuNo = sku.SkuNo,
|
SkuName = sku.SkuName,
|
Standard = sku.Standard,
|
LotNo = st.LotNo,
|
LotText = st.LotText,
|
Qty = s.Value,
|
AllotQty = 0,
|
FactQty = 0,
|
CompleteQty = 0,
|
PackagNo = sku.PackagNo,
|
Price = sku.Price,
|
Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * d.Qty,
|
IsBale = "",
|
IsBelt = "",
|
SupplierLot = st.SupplierLot,
|
IsWave = "0",
|
WaveNo = "",
|
IsIssueLotNo = string.IsNullOrWhiteSpace(d.LotNo) ? "0" : "1",
|
IsMixBox = d.IsMixBox,
|
|
CreateUser = 0,
|
};
|
list.Add(item);
|
|
st.LockQty += s.Value;//锁定数量
|
var i = Db.Updateable(st).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
|
SoDetailInfo soDetail = new SoDetailInfo();
|
soDetail.OrderDetailCode = d.OrderDetailCode;
|
soDetail.LockQty = s.Value;
|
soDetail.LotNo = st.LotNo;
|
|
soDetailList.Add(soDetail);
|
}
|
}
|
}
|
var notice = new BllExportNotice()
|
{
|
SONo = billNo,
|
OrderCode=model.OrderCode,
|
Type = model.SoType,
|
Status = "0",
|
Origin = "WMS",
|
CustomerNo = model.Customer,
|
CustomerName = CustomerName,
|
LogisticsId = logisticsId,
|
IsWave = "0",
|
WaveNo = "",
|
IsDespatch = "0",
|
|
CreateUser = 0,
|
};
|
|
var n = Db.Insertable<BllExportNotice>(notice).ExecuteCommand();
|
var m = Db.Insertable<BllExportNoticeDetail>(list).ExecuteCommand();
|
|
if (n <= 0 || m <= 0)
|
{
|
Db.RollbackTran();
|
throw new Exception("操作失败");
|
}
|
Db.CommitTran();
|
//回传上游系统锁定数量信息
|
result.Success = "0";
|
result.Message = "操作成功";
|
result.SoDetails = soDetailList;
|
return result;
|
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
}
|
|
//回传出库单
|
public bool FinishSo(int id, string url, int userId)
|
{
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.Id == id && m.IsDel == "0");
|
if (notice == null)
|
{
|
throw new Exception("未查询到单据信息");
|
}
|
if (notice.Status != "5")
|
{
|
throw new Exception("复核失败,单据非关闭状态");
|
}
|
var detail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.SONo == notice.SONo && m.IsDel == "0").ToList();
|
if (detail.Count == 0)
|
{
|
throw new Exception("未查询到单据明细信息");
|
}
|
if (userId == notice.UpdateUser)
|
{
|
throw new Exception("复核失败,复核人员和关闭订单人员不能相同!");
|
}
|
var list = new List<SoDetail>();
|
foreach (var d in detail)
|
{
|
var item = new SoDetail()
|
{
|
SkuNo = d.SkuNo,
|
LotNo = d.LotNo,
|
Qty = (decimal)d.CompleteQty
|
};
|
list.Add(item);
|
}
|
var soInfo = new SoInfo()
|
{
|
OrderCode = notice.OrderCode,
|
SoDetails = list
|
};
|
#region 通过接口发送至erp
|
//系统对接后放开
|
/*var jsonData = JsonConvert.SerializeObject(soInfo);
|
|
var response = HttpHelper.DoPost(url, jsonData, "出库单完成上传", "ERP");
|
|
var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据
|
if (obj.Success != 0)
|
{
|
throw new Exception("上传失败" + obj.Message);
|
}*/
|
#endregion
|
|
notice.Status = "6";
|
notice.CheckTime = DateTime.Now;
|
notice.CheckUser = userId;
|
Db.Updateable(notice).ExecuteCommand();
|
|
new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "复核", $"复核了单据号为{notice.SONo}的单据信息", userId);
|
return true;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//生产叫料
|
public bool MESProductionCall(ProductionCallVm model)
|
{
|
try
|
{
|
//验证是否备料完成
|
var notice = Db.Queryable<BllExportNotice>().First(m=>m.IsDel == "0" && m.OrderCode == model.OrderCode);
|
if (notice == null)
|
{
|
throw new Exception("未查询到此工单号");
|
}
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList();
|
var task = Db.Queryable<BllExportTimingTask>().First(m => m.SoNo == notice.SONo);
|
if (task == null)
|
{
|
throw new Exception("此工单还未备料");
|
}
|
if (task.Status != 2)
|
{
|
throw new Exception("此工单未备料完成");
|
}
|
var call = Db.Queryable<BllProductionCallTask>().First(m => m.IsDel == "0" && m.PutInLocation == model.PutInLocation && m.OrderCode == model.OrderCode);
|
if (call != null)
|
{
|
throw new Exception("当前单据物料在此投料口叫料信息已收到,无需重复下发");
|
}
|
//判断当前投料口是否有其它工单投料
|
var call2 = Db.Queryable<BllProductionCallTask>().First(m => m.IsDel == "0" && m.PutInLocation == model.PutInLocation && m.OrderCode != model.OrderCode );
|
if (call2 != null)
|
{
|
throw new Exception("此投料口有其它单据物料叫料信息");
|
}
|
//创建任务
|
var locateList = Db.Queryable<SysStorageLocat>().Where(m => m.AreaNo == model.PutInLocation && m.Flag == "0").ToList();
|
if (locateList.Count(m => m.Status != "0" || !string.IsNullOrWhiteSpace(m.SkuNo)) > 0)
|
{
|
throw new Exception("当前投料口工位有不能运料的工位,请通知管理员查看");
|
}
|
try
|
{
|
Db.BeginTran();
|
var proCallList = new List<BllProductionCallTask>();
|
foreach (var item in noticeDetail)
|
{
|
var proCall = new BllProductionCallTask()
|
{
|
PutInLocation = model.PutInLocation,
|
OrderCode = notice.SONo,
|
SkuNo = model.SkuNo,
|
CreateUser = 1
|
};
|
Db.Insertable(proCall).ExecuteCommand();
|
proCallList.Add(proCall);
|
}
|
var list = new List<int>();
|
foreach (var pro in proCallList)
|
{
|
foreach (var item in locateList)
|
{
|
//获取备好料的托盘信息
|
var allotList = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.Status == "2" && m.SONo == notice.SONo && m.SkuNo == pro.SkuNo && !list.Contains(m.Id)).Select(m => m.PalletNo).ToList();
|
|
var stockDetail = Db.Queryable<DataStockDetail>().Where(m => allotList.Contains(m.PalletNo)).OrderBy(m => m.LocatNo).First();
|
var taskNo = new Common().GetMaxNo("TK");
|
//出库任务
|
var exTask = new LogTask
|
{
|
TaskNo = taskNo,
|
Sender = "WMS",
|
Receiver = "AGV",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = stockDetail.LocatNo,//起始位置
|
EndLocat = item.LocatNo,//目标位置
|
PalletNo = stockDetail.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + stockDetail.LocatNo + "到" + item.LocatNo + "的出库任务", //关键信息
|
FinishIsPick = "1"
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
//更改分配表的任务号列
|
var allot = Db.Queryable<BllExportAllot>().First(m=>m.IsDel == "0" && m.Status =="2" && m.SONo == notice.SONo && m.StockId == stockDetail.Id);
|
allot.TaskNo = taskNo;
|
Db.Updateable(allot).ExecuteCommand();
|
list.Add(allot.Id);
|
item.Status = "4";
|
item.SkuNo = stockDetail.SkuNo;
|
item.PalletNo = stockDetail.PalletNo;
|
Db.Updateable(item).ExecuteCommand();
|
|
var locate = Db.Queryable<SysStorageLocat>().First(m=>m.LocatNo == stockDetail.LocatNo);
|
locate.Status = "5";
|
Db.Updateable(locate).ExecuteCommand();
|
|
break;
|
}
|
}
|
|
|
Db.CommitTran();
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
return true;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
#endregion
|
|
#region JC34
|
|
#region 基础功能
|
|
public async Task<List<ExportNoticeDto>> GetExportNoticeList(GetExportNoticeVm model, RefAsync<int> count)
|
{
|
var strList = new List<string>();
|
|
if (!string.IsNullOrWhiteSpace(model.LotNo))
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.LotNo.Contains(model.LotNo.Trim())).Select(m => m.SONo).Distinct().ToList();
|
strList = detailList;
|
}
|
Expression<Func<BllExportNotice, bool>> item = Expressionable.Create<BllExportNotice>()
|
.AndIF(!string.IsNullOrWhiteSpace(model.No), it => it.SONo.Contains(model.No.Trim()))
|
.AndIF(!string.IsNullOrWhiteSpace(model.Type), it => it.Type == model.Type)
|
.AndIF(!string.IsNullOrWhiteSpace(model.Status), it => it.Status == model.Status)
|
.AndIF(model.LogisticsId != null, it => it.LogisticsId == model.LogisticsId)
|
.AndIF(!string.IsNullOrWhiteSpace(model.IsWave), it => it.IsWave == model.IsWave)
|
.AndIF(!string.IsNullOrWhiteSpace(model.IsDespatch), it => it.IsDespatch == model.IsDespatch)
|
.AndIF(!string.IsNullOrWhiteSpace(model.WaveNo), it => it.WaveNo.Contains(model.WaveNo.Trim()))
|
.AndIF(!string.IsNullOrWhiteSpace(model.LotNo), it => strList.Contains(it.SONo))
|
.ToExpression();//注意 这一句 不能少
|
|
var data = await GetAllWhereAsync(item)
|
.LeftJoin<SysLogisticsInfo>((a, b) => a.LogisticsId == b.Id)
|
.LeftJoin<SysUserInfor>((a, b, c) => a.CreateUser == c.Id)
|
.LeftJoin<SysUserInfor>((a, b, c, d) => a.CreateUser == d.Id)
|
.LeftJoin<SysUserInfor>((a, b, c, d, e) => a.CheckUser == e.Id)
|
.LeftJoin<SysWareHouse>((a, b, c, d, e,f) => a.WareHouseNo == f.WareHouseNo)
|
.Select((a, b, c, d, e,f) => new ExportNoticeDto()
|
{
|
Id = a.Id,
|
SONo = a.SONo,
|
Type = a.Type,
|
Status = a.Status,
|
WareHouseName = f.WareHouseName,
|
Origin = a.Origin,
|
CustomerNo = a.CustomerNo,
|
CustomerName = a.CustomerName,
|
LotNo = a.LotNo,
|
LotText = a.LotText,
|
SupplierLot = a.SupplierLot,
|
LogisticsId = a.LogisticsId,
|
LogisticsName = b.CarrierName,
|
IsWave = a.IsWave,
|
WaveNo = a.WaveNo,
|
IsDespatch = a.IsDespatch,
|
Demo = a.Demo,
|
|
CreateUserName = c.RealName,
|
UpdateUserName = c.RealName,
|
CreateTime = a.CreateTime,
|
UpdateTime = a.UpdateTime,
|
|
CheckUserName = e.RealName,
|
CheckTime = a.CheckTime
|
})
|
.OrderByDescending(a => a.CreateTime)
|
.ToPageListAsync(model.Page, model.Limit, count);
|
|
return data;
|
}
|
|
//获取添加/编辑出库单时选择物料明细信息
|
public List<ExStockInfoDto> GetStockGroupList(string house, string type, string ownerNo, string msg)
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(house))
|
{
|
throw new Exception("请选择出库仓库");
|
}
|
if (string.IsNullOrEmpty(type))
|
{
|
throw new Exception("请选择出库单类型");
|
}
|
if (type == "6" && string.IsNullOrEmpty(ownerNo))
|
{
|
throw new Exception("代储单据请选择货主");
|
}
|
var plnList = new List<string>() { "100099" };
|
var skuStrList = new List<string>();
|
var sku = Db.Queryable<SysMaterials>().Where(m => m.IsDel == "0" && !plnList.Contains(m.SkuNo)); //排除空托盘的物料集合
|
string skuType = string.Empty;
|
string inspectStatus = string.Empty;
|
switch (type)//0:原料 1:包材 2:成品 3:耗材 4:半成品
|
{
|
case "0"://成品出库
|
if (house !="W01")
|
{
|
throw new Exception("成品出库只能选择成品库");
|
}
|
skuType = "(2)";
|
inspectStatus = "1";
|
break;
|
case "1"://领料出库
|
if (house != "W02")
|
{
|
throw new Exception("领料出库只能选择原料库");
|
}
|
skuType = "(0,1,3)";
|
inspectStatus = "1";
|
break;
|
case "2"://抽检出库
|
if (house == "W01")
|
{
|
skuType = "(2)";
|
}
|
if (house == "W02")
|
{
|
skuType = "(0,1,3)";
|
}
|
inspectStatus = "0,1,2";
|
break;
|
case "3"://物料取样出库
|
if (house == "W01")
|
{
|
skuType = "(2)";
|
}
|
if (house == "W02")
|
{
|
skuType = "(0,1,3)";
|
}
|
inspectStatus = "0";
|
break;
|
case "4"://不合格品出库
|
if (house == "W01")
|
{
|
skuType = "(2)";
|
}
|
if (house == "W02")
|
{
|
skuType = "(0,1,3)";
|
}
|
inspectStatus = "2";
|
break;
|
case "5"://中间品出库
|
skuType = "(4)";
|
inspectStatus = "0,1";
|
break;
|
case "6"://代储出库
|
skuType = "(2)";
|
inspectStatus = "0,1";
|
break;
|
case "7"://其它出库
|
if (house == "W01")
|
{
|
skuType = "(2)";
|
}
|
if (house == "W02")
|
{
|
skuType = "(0,1,3,4)";
|
}
|
inspectStatus = "0,1";
|
break;
|
case "8"://寄存出库
|
if (house == "W01")
|
{
|
skuType = "(2)";
|
}
|
if (house == "W02")
|
{
|
skuType = "(0,1,3)";
|
}
|
inspectStatus = "0,1";
|
break;
|
case "9"://生产领料出库
|
if (house != "W02")
|
{
|
throw new Exception("生产领料出库只能选择原料库");
|
}
|
skuType = "(0,1,3)";
|
inspectStatus = "1";
|
break;
|
default: //其它出库
|
throw new Exception("单据类型错误");
|
}
|
var skuList = sku.Where(m => skuType.Contains(m.Type)).ToList();
|
if (skuList.Count == 0)
|
{
|
throw new Exception("未查到对应出库类型的物料");
|
}
|
|
if (type == "6")
|
{
|
skuList = skuList.Where(m => string.IsNullOrWhiteSpace(m.PackagNo)).ToList();
|
}
|
if (type != "8")
|
{
|
skuList = skuList.Where(m => m.SkuNo != "100088").ToList();
|
}
|
else
|
{
|
skuList = skuList.Where(m => m.SkuNo == "100088").ToList();
|
}
|
skuStrList = skuList.Select(m => m.SkuNo).ToList();
|
var areaStr = new List<string>() { "B06", "B07", "B09" };
|
var stockRst = new StockServer();
|
var stockDetailRst = new StockDetailServer();
|
Expression<Func<DataStockDetail, bool>> item = Expressionable.Create<DataStockDetail>()
|
.And(it => it.WareHouseNo == house || string.IsNullOrWhiteSpace(it.LocatNo) || (it.WareHouseNo == "W04" && !areaStr.Contains(it.AreaNo)))
|
.AndIF(!string.IsNullOrWhiteSpace(inspectStatus), it => inspectStatus.Contains(it.InspectStatus))
|
.And(m => skuStrList.Contains(m.SkuNo))
|
.AndIF(type == "6", m => m.OwnerNo == ownerNo)//代储出库需要关联货主
|
.AndIF(!string.IsNullOrWhiteSpace(msg), it => (it.SkuNo.Contains(msg) || it.SkuName.Contains(msg) || it.LotNo.Contains(msg)))
|
.And(it => (it.Qty - it.LockQty - it.FrozenQty) > 0)
|
.And(it => (it.Status == "0" || it.Status == "1"))
|
.ToExpression();//注意 这一句 不能少
|
//库存明细
|
var stockDetail = stockDetailRst.GetAllWhereAsync(item).GroupBy(m => new
|
{
|
m.SkuNo,
|
m.SkuName,
|
m.LotNo,
|
m.Standard,
|
|
}).Select(it => new ExStockInfoDto
|
{
|
SkuNo = it.SkuNo,
|
SkuName = it.SkuName,
|
LotNo = it.LotNo,
|
Standard = it.Standard,
|
Qty = SqlFunc.AggregateSumNoNull(it.Qty - it.LockQty - it.FrozenQty),
|
|
}).ToList();
|
//库存总表
|
var stock = stockRst.GetAllAsync().Select(it => new ExStockInfoDto
|
{
|
SkuNo = it.SkuNo,
|
SkuName = it.SkuName,
|
LotNo = it.LotNo,
|
Standard = it.Standard,
|
//Qty = type == "4" ? it.Qty : it.Qty - it.LockQty - it.FrozenQty,
|
Qty = it.Qty - it.LockQty - it.FrozenQty,
|
|
}).ToList();
|
|
foreach (var l in stockDetail.ToArray())
|
{
|
var fq = stock.Where(s => s.SkuNo == l.SkuNo);
|
if (!string.IsNullOrWhiteSpace(l.LotNo))
|
{
|
fq = fq.Where(s => s.LotNo == l.LotNo);
|
}
|
else
|
{
|
fq = fq.Where(s => string.IsNullOrWhiteSpace(s.LotNo));
|
}
|
var f = fq.FirstOrDefault();
|
if (f == null)
|
{
|
throw new Exception("库存信息错误,请核实");
|
}
|
if (f.Qty != null && f.Qty.Value < l.Qty)
|
{
|
l.Qty = f.Qty.Value;
|
}
|
if (l.Qty <= 0)
|
{
|
stockDetail.Remove(l);
|
}
|
}
|
|
return stockDetail;
|
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//WMS添加出库单
|
public bool AddExportNotice(AddEditExportNoticeVm model, int userId)
|
{
|
try
|
{
|
if (model == null || model.Detail.Count == 0)
|
{
|
throw new Exception("参数异常");
|
}
|
var skuNos = model.Detail.Select(a => a.SkuNo).Distinct().ToList();
|
//根据物料号获取物料信息、库存明细中获取批次描述供货批次等
|
var skuList = Db.Queryable<SysMaterials>().Where(a => skuNos.Contains(a.SkuNo) && a.IsDel == "0").ToList();
|
switch (model.WareHouseNo)
|
{
|
case "W01"://成品库
|
if (skuList.Any(m=>m.Type !="2"))
|
{
|
throw new Exception("仓库与出库物料不符");
|
}
|
break;
|
case "W02"://原料库
|
if (skuList.Any(m => m.Type == "2"))
|
{
|
throw new Exception("仓库与出库物料不符");
|
}
|
break;
|
default:
|
throw new Exception("仓库号错误");
|
}
|
var stockList = Db.Queryable<DataStock>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList();
|
//var palletList = contextDb.Queryable<DataStockDetail>().Where(s => skuNos.Contains(s.SkuNo) && (s.Qty - s.FrozenQty - s.LockQty) > 0).ToList();
|
//客户信息
|
var customer = Db.Queryable<SysCustomer>().Where(m => m.IsDel == "0" && m.CustomerNo == model.CustomerNo).ToList();
|
var billNo = "";
|
var bl = true;
|
do
|
{
|
//获取自增单据号
|
billNo = new Common().GetMaxNo("SO");
|
var no = billNo;
|
bl = Db.Queryable<BllExportNotice>().Any(m => m.SONo == no);
|
} while (bl);
|
|
|
Db.BeginTran();//开启事务
|
|
try
|
{
|
var list = new List<BllExportNoticeDetail>();
|
//添加出库单
|
foreach (var d in model.Detail)
|
{
|
if (d.Qty < 1)
|
{
|
throw new Exception("出库数量必须大于0");
|
}
|
var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo);
|
if (sku == null)
|
{
|
throw new Exception($"物料信息中未查询到出库物料信息:{d.SkuNo}");
|
}
|
|
//0:成品出库、1:领料出库、2:抽检出库、4:不合格品出库、7:其他出库、9生产领料出库 ///3:物料取样出库、5:中间品出库、6:代储出库、8:寄存出库
|
if (model.Type == "0" || model.Type == "2" || model.Type == "4" || model.Type == "7")
|
{
|
if (string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
throw new Exception("批次不可为空!");
|
}
|
}
|
|
//if (model.Type == "1")
|
//{
|
// if (list.Count(m=>m.SkuNo == d.SkuNo)>=2)
|
// {
|
// throw new Exception("领料出库单同单据同物料不允许超过3个批次混批出库");
|
// }
|
//}
|
//else
|
//{
|
// if (list.Count(m => m.SkuNo == d.SkuNo) >= 1)
|
// {
|
// throw new Exception("出库单同单据同物料不允许超过2个批次混批出库");
|
// }
|
//}
|
//库存
|
List<DataStock> stocks;
|
|
decimal q1 = 0;
|
Dictionary<int, decimal> dic = new Dictionary<int, decimal>();
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList();
|
}
|
else
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList();
|
}
|
if (stocks.Count < 1)
|
{
|
throw new Exception($"总库存中未查询到出库物料信息:{d.SkuNo}");
|
}
|
//判断数量
|
var qty = stocks.First().Qty - stocks.First().LockQty - stocks.First().FrozenQty;
|
if (d.Qty > qty)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足");
|
}
|
|
var item = new BllExportNoticeDetail()
|
{
|
SONo = billNo,
|
SkuNo = sku.SkuNo,
|
SkuName = sku.SkuName,
|
Standard = sku.Standard,
|
LotNo = d.LotNo,
|
LotText = "",
|
Status = "0",
|
Qty = d.Qty,
|
AllotQty = 0,
|
FactQty = 0,
|
CompleteQty = 0,
|
PackagNo = sku.PackagNo,
|
Price = sku.Price,
|
Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * d.Qty,
|
IsBale = d.IsBale,
|
IsBelt = d.IsBelt,
|
SupplierLot = stocks.First().SupplierLot,
|
IsWave = "0",
|
WaveNo = "",
|
|
CreateUser = userId,
|
};
|
list.Add(item);
|
|
|
stocks.First().LockQty += d.Qty;//锁定数量
|
var i = Db.Updateable(stocks.First()).UpdateColumns(it => new { it.LockQty })
|
.ExecuteCommand();
|
|
//foreach (var s in dic)
|
//{
|
// var st = stockList.First(m => m.Id == s.Key);
|
// st.LockQty += s.Value;//锁定数量
|
// var i = Db.Updateable(st).UpdateColumns(it => new { it.LockQty })
|
// .ExecuteCommand();
|
//}
|
|
}
|
var notice = new BllExportNotice()
|
{
|
SONo = billNo,
|
Type = model.Type,
|
Status = "0",
|
Origin = "WMS",
|
CustomerNo = model.CustomerNo,
|
CustomerName = customer.FirstOrDefault() == null ? "" : customer.First().CustomerName,
|
LogisticsId = model.LogisticsId,
|
IsWave = "0",
|
WaveNo = "",
|
IsDespatch = "0",
|
WareHouseNo = model.WareHouseNo,
|
CreateUser = userId,
|
};
|
|
var n = Db.Insertable<BllExportNotice>(notice).ExecuteCommand();
|
var m = Db.Insertable<BllExportNoticeDetail>(list).ExecuteCommand();
|
|
if (n <= 0 || m <= 0)
|
{
|
Db.RollbackTran();
|
return false;
|
}
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", billNo, "添加", $"添加了单据号为{billNo}的单据信息", userId);
|
Db.CommitTran();
|
return true;
|
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//获取编辑出库单及明细信息
|
public EditExportNotifyDto GetEditExportNotice(string code)
|
{
|
try
|
{
|
var notify = Db.Queryable<BllExportNotice>().Where(m => m.SONo == code && m.IsDel == "0").ToList().FirstOrDefault();
|
if (notify == null)
|
{
|
throw new Exception($"未查询到{code}的单据信息");
|
}
|
|
var detail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.SONo == code && m.IsDel == "0").ToList();
|
var skuList = detail.Select(m => m.SkuNo).ToList();
|
var stock = Db.Queryable<DataStock>().Where(m => skuList.Contains(m.SkuNo) && m.IsDel == "0").ToList();
|
|
|
var model = new EditExportNotifyDto
|
{
|
SoNo = notify.SONo,
|
Type = notify.Type,
|
WareHouseNo = notify.WareHouseNo,
|
CustomerNo = notify.CustomerNo,
|
LogisticsId = notify.LogisticsId,
|
//ExportWarehouseId = notify.ExportWarehouseId,
|
};
|
model.Detail = new List<SelectStockSkuDto>();
|
DataStock s;
|
foreach (var d in detail)
|
{
|
if (string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
s = stock.FirstOrDefault(m => m.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(m.LotNo));
|
}
|
else
|
{
|
s = stock.FirstOrDefault(m => m.SkuNo == d.SkuNo && m.LotNo == d.LotNo);
|
}
|
|
var stockCount = 0.00m; //st.StockQuantity.Value
|
if (s != null)
|
{
|
stockCount = s.Qty - s.FrozenQty - s.LockQty + d.Qty;
|
}
|
|
var dm = new SelectStockSkuDto()
|
{
|
SkuNo = d.SkuNo,
|
SkuName = d.SkuName,
|
Standard = d.Standard,
|
LotNo = d.LotNo,
|
Qty = stockCount,
|
ExQty = d.Qty,
|
IsBale = d.IsBale,
|
IsBelt = d.IsBelt
|
};
|
model.Detail.Add(dm);
|
}
|
|
return model;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//修改出库单
|
public EditExportNotifyDto EditExportNotice(AddEditExportNoticeVm model, int userId)
|
{
|
try
|
{
|
if (model == null || model.Detail.Count == 0)
|
{
|
throw new Exception("参数异常");
|
}
|
|
var notice = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.Id == model.Id).ToList().FirstOrDefault();
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
if (notice.Origin != "WMS" || notice.Status != "0")
|
{
|
throw new Exception("参数异常,请检查状态是否未等待执行或来源是否是WMS");
|
}
|
//出库单明细
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList();
|
|
//根据物料号获取物料信息、库存明细中获取批次描述供货批次等
|
var skuList = Db.Queryable<SysMaterials>().Where(a => a.IsDel == "0").ToList();
|
var stockList = Db.Queryable<DataStock>().Where(s => (s.Qty - s.FrozenQty - s.LockQty + noticeDetail[0].Qty) > 0).ToList();
|
var palletList = Db.Queryable<DataStockDetail>().Where(s => (s.Qty - s.FrozenQty - s.LockQty + noticeDetail[0].Qty) > 0).ToList();
|
|
|
Db.BeginTran();//开启事务
|
|
try
|
{
|
if (notice.Origin == "WMS")
|
{
|
//删除旧
|
foreach (var d in noticeDetail)
|
{
|
var mq = model.Detail.Where(o => o.SkuNo == d.SkuNo).ToList();
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
mq = mq.Where(o => o.LotNo == d.LotNo).ToList();
|
}
|
if (mq.Any()) //如果有这个物料及批次则跳过
|
{
|
continue;
|
}
|
//
|
var fl = stockList.Where(s => s.SkuNo == d.SkuNo).ToList();
|
DataStock fls;
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
fls = fl.FirstOrDefault(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo);
|
}
|
else
|
{
|
fls = fl.FirstOrDefault(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo));
|
}
|
if (fls == null)
|
{
|
throw new Exception($"未找到物料{d.SkuNo}、批次{d.LotNo} 的库存信息");
|
}
|
fls.LockQty -= d.Qty;
|
d.IsDel = "1";
|
d.UpdateUser = userId;
|
d.UpdateTime = DateTime.Now;
|
Db.Updateable(d).ExecuteCommand();
|
Db.Updateable(fls).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
|
//更新出库单
|
foreach (var d in model.Detail)
|
{
|
if (d.Qty < 1)
|
{
|
throw new Exception("出库数据必须大于0");
|
}
|
var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo);
|
if (sku == null)
|
{
|
throw new Exception("出库物品为空");
|
}
|
//库存
|
List<DataStock> stocks;
|
List<DataStockDetail> pallet;
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo).ToList();
|
pallet = palletList.Where(p => p.SkuNo == d.SkuNo && p.LotNo == d.LotNo).ToList();
|
}
|
else
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList();
|
pallet = palletList.Where(p => p.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(p.LotNo)).ToList();
|
}
|
|
if (stocks.Count < 1)
|
{
|
throw new Exception("出库物品库存不足");
|
}
|
var stock = stocks.First();//总库存
|
//
|
BllExportNoticeDetail old;
|
if (string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
old = noticeDetail.FirstOrDefault(o => o.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(o.LotNo));
|
}
|
else
|
{
|
old = noticeDetail.FirstOrDefault(o => o.SkuNo == d.SkuNo && o.LotNo == d.LotNo);
|
}
|
|
//新加项
|
if (old == null)
|
{
|
//判断数量
|
var qty = stock.Qty - stock.LockQty - stock.FrozenQty;
|
if (d.Qty > qty)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足");
|
}
|
|
var item = new BllExportNoticeDetail()
|
{
|
SONo = notice.SONo,
|
SkuNo = sku.SkuNo,
|
SkuName = sku.SkuName,
|
Standard = sku.Standard,
|
LotNo = d.LotNo,
|
LotText = "",
|
Status = "0",
|
Qty = d.Qty,
|
AllotQty = 0,
|
FactQty = 0,
|
CompleteQty = 0,
|
PackagNo = sku.PackagNo,
|
Price = sku.Price,
|
Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * qty,
|
IsBale = d.IsBale,
|
IsBelt = d.IsBelt,
|
SupplierLot = stocks.First().SupplierLot,
|
IsWave = "0",
|
WaveNo = "",
|
|
CreateUser = userId,
|
};
|
|
stock.LockQty += d.Qty;//锁定数量
|
var m = Db.Insertable<BllExportNoticeDetail>(item).ExecuteCommand();
|
var i = Db.Updateable(stock).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
else if (old.Qty != d.Qty || old.IsBale != d.IsBale || old.IsBelt != d.IsBelt)
|
{
|
if (d.Qty > (stock.Qty - stock.FrozenQty - stock.LockQty) + old.Qty)
|
{
|
throw new Exception("物品库存数量不足");
|
}
|
//增加
|
if (d.Qty > old.Qty)
|
{
|
stock.LockQty += d.Qty - old.Qty;
|
}
|
else
|
{
|
stock.LockQty -= old.Qty - d.Qty;
|
}
|
old.IsBale = d.IsBale;
|
old.IsBelt = d.IsBelt;
|
old.Qty = d.Qty;
|
old.UpdateUser = userId;
|
old.UpdateTime = DateTime.Now;
|
var m = Db.Updateable(old).UpdateColumns(it => new { it.IsBale, it.IsBelt, it.Qty, it.UpdateUser, it.UpdateTime }).ExecuteCommand();
|
var i = Db.Updateable(stock).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
}
|
|
//客户信息
|
var customer = Db.Queryable<SysCustomer>().Where(m => m.IsDel == "0" && m.CustomerNo == model.CustomerNo).ToList().FirstOrDefault();
|
notice.Type = model.Type;
|
notice.CustomerNo = model.CustomerNo;
|
notice.CustomerName = customer == null ? "" : customer.CustomerName;
|
notice.LogisticsId = model.LogisticsId;
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
|
var n = Db.Updateable(notice).ExecuteCommand();
|
if (n <= 0)
|
{
|
Db.RollbackTran();
|
return null;
|
}
|
}
|
else //erp/mes
|
{
|
//删除旧
|
foreach (var d in noticeDetail)
|
{
|
var mq = model.Detail.Where(o => o.SkuNo == d.SkuNo).ToList();
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
mq = mq.Where(o => o.LotNo == d.LotNo).ToList();
|
}
|
if (mq.Any()) //如果有这个物料及批次则跳过
|
{
|
continue;
|
}
|
//
|
var fl = stockList.Where(s => s.SkuNo == d.SkuNo).ToList();
|
DataStock fls;
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
fls = fl.FirstOrDefault(s => s.SkuNo == d.SkuNo && s.LotNo == d.LotNo);
|
}
|
else
|
{
|
fls = fl.FirstOrDefault(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo));
|
}
|
if (fls == null)
|
{
|
throw new Exception($"未找到物料{d.SkuNo}、批次{d.LotNo} 的库存信息");
|
}
|
fls.LockQty -= d.Qty;
|
d.IsDel = "1";
|
d.UpdateUser = userId;
|
d.UpdateTime = DateTime.Now;
|
Db.Updateable(d).ExecuteCommand();
|
Db.Updateable(fls).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
|
//更新出库单
|
foreach (var d in model.Detail)
|
{
|
if (d.Qty < 1)
|
{
|
throw new Exception("出库数据必须大于0");
|
}
|
var sku = skuList.FirstOrDefault(a => a.SkuNo == d.SkuNo);
|
if (sku == null)
|
{
|
throw new Exception("出库物品为空");
|
}
|
//库存
|
List<DataStock> stocks;
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && d.LotNo.Contains(s.LotNo)).ToList();
|
}
|
else
|
{
|
stocks = stockList.Where(s => s.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(s.LotNo)).ToList();
|
}
|
|
if (stocks.Count < 1)
|
{
|
throw new Exception("出库物品库存不足");
|
}
|
var stock = stocks.First();//总库存
|
//
|
BllExportNoticeDetail old;
|
if (string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
old = noticeDetail.FirstOrDefault(o => o.SkuNo == d.SkuNo && string.IsNullOrWhiteSpace(o.LotNo));
|
}
|
else
|
{
|
old = noticeDetail.FirstOrDefault(o => o.SkuNo == d.SkuNo && o.LotNo == d.LotNo);
|
}
|
|
//新加项
|
if (old == null)
|
{
|
//判断数量
|
var qty = stock.Qty - stock.LockQty - stock.FrozenQty;
|
if (d.Qty > qty)
|
{
|
throw new Exception($"总库存中出库物料信息:{d.SkuNo}、{d.LotNo} 库存数量不足");
|
}
|
|
var item = new BllExportNoticeDetail()
|
{
|
SONo = notice.SONo,
|
SkuNo = sku.SkuNo,
|
SkuName = sku.SkuName,
|
Standard = sku.Standard,
|
LotNo = d.LotNo,
|
LotText = "",
|
Status = "0",
|
Qty = d.Qty,
|
AllotQty = 0,
|
FactQty = 0,
|
CompleteQty = 0,
|
PackagNo = sku.PackagNo,
|
Price = sku.Price,
|
Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * qty,
|
IsBale = d.IsBale,
|
IsBelt = d.IsBelt,
|
SupplierLot = stocks.First().SupplierLot,
|
IsWave = "0",
|
WaveNo = "",
|
|
CreateUser = userId,
|
};
|
|
stock.LockQty += d.Qty;//锁定数量
|
var m = Db.Insertable<BllExportNoticeDetail>(item).ExecuteCommand();
|
var i = Db.Updateable(stock).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
else if (old.Qty != d.Qty || old.IsBale != d.IsBale || old.IsBelt != d.IsBelt)
|
{
|
if (d.Qty > (stock.Qty - stock.FrozenQty - stock.LockQty) + old.Qty)
|
{
|
throw new Exception("物品库存数量不足");
|
}
|
//增加
|
if (d.Qty > old.Qty)
|
{
|
stock.LockQty += d.Qty - old.Qty;
|
}
|
else
|
{
|
stock.LockQty -= old.Qty - d.Qty;
|
}
|
old.IsBale = d.IsBale;
|
old.IsBelt = d.IsBelt;
|
old.Qty = d.Qty;
|
old.UpdateUser = userId;
|
old.UpdateTime = DateTime.Now;
|
var m = Db.Updateable(old).UpdateColumns(it => new { it.IsBale, it.IsBelt, it.Qty, it.UpdateUser, it.UpdateTime }).ExecuteCommand();
|
var i = Db.Updateable(stock).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
}
|
|
//客户信息
|
var customer = Db.Queryable<SysCustomer>().Where(m => m.IsDel == "0" && m.CustomerNo == model.CustomerNo).ToList().FirstOrDefault();
|
notice.Type = model.Type;
|
notice.CustomerNo = model.CustomerNo;
|
notice.CustomerName = customer == null ? "" : customer.CustomerName;
|
notice.LogisticsId = model.LogisticsId;
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
|
var n = Db.Updateable(notice).ExecuteCommand();
|
if (n <= 0)
|
{
|
Db.RollbackTran();
|
return null;
|
}
|
//回传ERP/MES
|
}
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "编辑", $"编辑了单据号为{notice.SONo}的单据信息", userId);
|
Db.CommitTran();
|
|
//查询改后的单据信息 后期接口对接完后需改动回传参数
|
var detail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).Select(m => new SelectStockSkuDto
|
{
|
LotNo = m.LotNo,
|
SkuNo = m.SkuNo,
|
SkuName = m.SkuName,
|
Qty = m.Qty,
|
ExQty = decimal.Parse(m.CompleteQty.ToString()),
|
Standard = m.Standard,
|
IsBale = m.IsBale,
|
IsBelt = m.IsBelt
|
}).ToList();
|
|
var data = new EditExportNotifyDto();
|
data.Origin = notice.Origin;
|
data.SoNo = notice.SONo;
|
data.Type = notice.Type;
|
data.CustomerNo = notice.CustomerNo;
|
data.LogisticsId = notice.LogisticsId;
|
data.Detail = detail;
|
|
|
return data;
|
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//删除出库单
|
public bool DelExportNotice(int id, int userId)
|
{
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.Id == id).ToList().FirstOrDefault();
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
if (notice.Origin != "WMS" || notice.Status != "0")
|
{
|
throw new Exception("参数异常,请检查状态是否未等待执行或来源是否是WMS");
|
}
|
|
//总库存信息
|
var stockList = Db.Queryable<DataStock>().ToList();
|
//出库单明细
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList();
|
Db.BeginTran();//开启事务
|
try
|
{
|
foreach (var d in noticeDetail)
|
{
|
//总库存
|
var sq = stockList.Where(s => s.SkuNo == d.SkuNo);
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
sq = sq.Where(s => s.LotNo == d.LotNo);
|
}
|
else
|
{
|
sq = sq.Where(s => string.IsNullOrWhiteSpace(s.LotNo));
|
}
|
var fd = sq.FirstOrDefault();
|
if (fd == null)
|
{
|
throw new Exception($"未找到物料{d.SkuNo}、批次{d.LotNo} 的库存信息");
|
}
|
fd.LockQty -= d.Qty;
|
d.IsDel = "1";
|
d.UpdateUser = userId;
|
d.UpdateTime = DateTime.Now;
|
Db.Updateable(d).ExecuteCommand();
|
Db.Updateable(fd).UpdateColumns(it => new { it.LockQty }).ExecuteCommand();
|
}
|
//删除出库单
|
notice.IsDel = "1";
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
|
var n = Db.Updateable(notice).ExecuteCommand();
|
if (n <= 0)
|
{
|
Db.RollbackTran();
|
return false;
|
}
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "删除", $"删除了单据号为{notice.SONo}的单据信息", userId);
|
|
Db.CommitTran();
|
return true;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//订单关闭
|
public bool CloseExportNotice(int id, int userId)
|
{
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.Id == id).ToList().FirstOrDefault();
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
if (notice.Status != "4")
|
{
|
throw new Exception("参数异常,请检查状态是否为执行完成或订单关闭");
|
}
|
//总库存信息
|
var stockList = Db.Queryable<DataStock>().ToList();
|
//出库单明细
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList();
|
|
Db.BeginTran();//开启事务
|
try
|
{
|
//修改出库单状态
|
notice.Status = "5";
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
Db.Updateable(notice).ExecuteCommand();
|
|
var skuList = noticeDetail.Select(d => d.SkuNo).ToList();
|
var stocks = stockList.Where(s => skuList.Contains(s.SkuNo)).ToList();
|
|
foreach (var d in noticeDetail)
|
{
|
//更改库存明细锁定数量
|
//var orders = dataContext.WmsExportOrder.Where(o => o.ExportDetailId == d.Id
|
// && o.ExportExecuteFlag != "4" && o.ExportExecuteFlag == "3" && o.pickingType == 0).ToList();
|
//foreach (var o in orders)
|
//{
|
// if (o.ExportQuantity > o.PickedNum) //判断拣货是否已拣完
|
// {
|
// var pq = dataContext.WmsStockTray.Where(t => t.StockGoodId == o.ExportGoodsCode && t.StockStockCode == o.ExportStockCode);
|
|
// if (string.IsNullOrWhiteSpace(o.ExportLotNo))
|
// {
|
// pq = pq.Where(t => t.StockLotNo == null || t.StockLotNo == "");
|
// }
|
// else
|
// {
|
// pq = pq.Where(t => t.StockLotNo == o.ExportLotNo);
|
// }
|
// var pallet = pq.FirstOrDefault();
|
// //库存托盘信息锁定数量还原为未锁定
|
// if (pq != null)
|
// {
|
// pallet.LockQuantity -= o.ExportQuantity.Value - o.PickedNum;
|
// pallet.StockQuantity += o.ExportQuantity.Value - o.PickedNum;
|
// }
|
// }
|
//}
|
|
if (d.Qty != d.CompleteQty)
|
{
|
throw new Exception("当前单据明细中计划数量与拣货数量不符,请核实");
|
}
|
#region 库存表减去锁定数量与总数量(PDA拣货的时候已经减去数量了)
|
/*var sq = stocks.Where(s => s.SkuNo == d.SkuNo);
|
if (!string.IsNullOrWhiteSpace(d.LotNo))
|
{
|
sq = sq.Where(s => s.LotNo == d.LotNo);
|
}
|
else
|
{
|
sq = sq.Where(s => string.IsNullOrWhiteSpace(s.LotNo));
|
}
|
var st = sq.FirstOrDefault();
|
if (st != null)
|
{
|
if (d.CompleteQty <= d.Qty)
|
{
|
st.Qty += d.Qty - d.CompleteQty.Value;
|
}
|
else
|
{
|
st.Qty -= d.CompleteQty.Value - d.Qty;
|
}
|
st.LockQty -= d.Qty;
|
st.Qty -= d.Qty;
|
//修改总库存表
|
Db.Updateable(st).UpdateColumns(it => new { it.Qty, it.LockQty }).ExecuteCommand();
|
}*/
|
#endregion
|
}
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "关单", $"关闭了单据号为{notice.SONo}的单据信息", userId);
|
|
Db.CommitTran();
|
return true;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception("关闭出库单据失败:" + ex.Message);
|
}
|
}
|
|
public XmlNode AddExXmlStr(int id, int userId)
|
{
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.Id == id).ToList().FirstOrDefault();
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
var statusLis = new List<string>() { "4", "5", "6" };
|
if (!statusLis.Contains(notice.Status))
|
{
|
throw new Exception("参数异常,请检查状态是否为执行完成或订单关闭/已上传");
|
}
|
//出库单明细
|
var comDetail = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.SONo == notice.SONo).Select(m => m.BoxNo3).ToList();
|
Db.BeginTran();//开启事务
|
|
try
|
{
|
//Hashtable pars = new Hashtable(); //用来存放参数
|
var pars = new List<string>();
|
//for (int i = 0; i < 10; i++)
|
//{
|
// pars.Add("202203240009000479940290");
|
//}
|
|
var dom = HttpHelper.EncodeParsToFuMa(comDetail, "ceshi", "ExInfoXml");
|
////添加操作日志记录
|
//var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "关单", $"关闭了单据号为{notice.SONo}的单据信息", userId);
|
|
Db.CommitTran();
|
return dom;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception("生成XML文件错误:" + ex.Message);
|
}
|
}
|
|
#endregion
|
|
#region 托盘出库
|
|
/// <summary>
|
/// 获取托盘出库明细
|
/// </summary>
|
/// <param name="skuNo">物料号</param>
|
/// <param name="skuName">物料名称</param>
|
/// <param name="palletNo">托盘号</param>
|
/// <param name="lotNo">批次号</param>
|
/// <param name="inspectMark">检验标记</param>
|
/// <param name="bitPalletMark">零托标记</param>
|
/// <param name="page">零托标记</param>
|
/// <param name="limit">零托标记</param>
|
/// <param name="count">零托标记</param>
|
/// <returns></returns>
|
public async Task<List<DataStockDetail>> GetPalletNoOutList(GetPalletNoOutVm model, RefAsync<int> count)
|
{
|
Expression<Func<DataStockDetail, bool>> item = Expressionable.Create<DataStockDetail>()
|
.AndIF(!string.IsNullOrWhiteSpace(model.SkuNo), m => m.SkuNo.Contains(model.SkuNo.Trim()))
|
.AndIF(!string.IsNullOrWhiteSpace(model.SkuName), m => m.SkuName.Contains(model.SkuName.Trim()))
|
.AndIF(!string.IsNullOrWhiteSpace(model.PalletNo), m => m.PalletNo.Contains(model.PalletNo.Trim()))
|
.AndIF(!string.IsNullOrWhiteSpace(model.LotNo), m => m.LotNo.Contains(model.LotNo.Trim()))
|
.AndIF(!string.IsNullOrWhiteSpace(model.InspectMark), m => m.InspectMark == model.InspectMark)
|
.AndIF(!string.IsNullOrWhiteSpace(model.BitPalletMark), m => m.BitPalletMark == model.BitPalletMark)
|
.And(m => !string.IsNullOrWhiteSpace(m.WareHouseNo))
|
.And(a => a.Status == "0")
|
.And(a => a.WareHouseNo == "W01")
|
.ToExpression();
|
var data = await Db.Queryable<DataStockDetail>().Where(item).OrderBy(m => m.LocatNo).ToPageListAsync(model.Page, model.Limit, count);
|
//data.Select(m => m.Status == "0" && m.IsDel == "0");
|
|
return data;
|
}
|
|
//托盘出库
|
public List<OutCommandDto> IssuePalletNoOut(string palletNo, string outMode, int userId, string url, out string str)
|
{
|
try
|
{
|
//判断托盘号是否为空
|
if (string.IsNullOrWhiteSpace(palletNo))
|
{
|
throw new Exception($"托盘号不能为空,请核实");
|
}
|
|
var outDtoList = new List<OutCommandDto>(); //出库数据的集合
|
str = "";
|
var stockDetailList = Db.Queryable<DataStockDetail>().Where(m => m.PalletNo == palletNo && m.IsDel == "0").ToList();
|
|
if (stockDetailList.Count == 0)
|
{
|
throw new Exception($"未在库内查询到该托盘信息");
|
}
|
var stocka = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetailList[0].SkuNo);
|
|
|
//验证库存托盘状态
|
if (stockDetailList[0].Status != "0")
|
{
|
throw new Exception($"当前托盘未处于待分配状态,请核实!");
|
}
|
//判断托盘库存信息分组后是否大于1条
|
var detailGroup = stockDetailList.GroupBy(m => new { m.SkuNo, m.PalletNo, m.WareHouseNo, m.LocatNo }).ToList();
|
if (detailGroup.Count > 1)
|
{
|
throw new Exception($"未在库内查询到该托盘信息");
|
}
|
|
|
#region 集合
|
|
Db.BeginTran();
|
try
|
{
|
// 储位号
|
var de = stockDetailList.First();
|
var locateNo = de.LocatNo;
|
#region 判断
|
|
//判断托盘是否在库内
|
if (string.IsNullOrWhiteSpace(locateNo))
|
{
|
if (de.WareHouseNo == "W02")//盘断是否是零箱库
|
{
|
if (de.SkuNo == "100099")//判断是否是空托出库
|
{
|
//判断总库存是否为0,如果为0删除 否则减去数量
|
var stock = Db.Queryable<DataStock>().First(m => m.SkuNo == "100099");
|
|
if (stock != null)
|
{
|
if (de.Qty != null)
|
{
|
stock.Qty -= de.Qty.Value;
|
Db.Updateable(stock).ExecuteCommand();
|
}
|
|
if (stock.Qty == 0)
|
{
|
Db.Deleteable(stock).ExecuteCommand();
|
}
|
}
|
|
//托盘状态改为未使用
|
var sCode = Db.Queryable<SysPallets>().First(m => m.PalletNo == de.PalletNo);
|
if (sCode != null)
|
{
|
sCode.Status = "0";
|
Db.Updateable(sCode).ExecuteCommand();
|
}
|
|
foreach (var item in stockDetailList)
|
{
|
Db.Deleteable(item).ExecuteCommand();
|
}
|
|
str = "出库完成";
|
return outDtoList;
|
}
|
|
foreach (var item in stockDetailList)
|
{
|
item.LocatNo = "";//储位更改(改为空)
|
item.WareHouseNo = "";//所属仓库更改(改为空)
|
item.RoadwayNo = "";//所属巷道更改(改为空)
|
item.AreaNo = "";//所属区域更改(改为空)
|
Db.Updateable(de).ExecuteCommand();
|
}
|
str = "出库完成";
|
return outDtoList;
|
|
}
|
|
}
|
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
|
if (locate == null)
|
{
|
throw new Exception($"出库的托盘储位信息错误、在储位表中未查询到");
|
}
|
//判断储位标志是否为损坏
|
if (locate.Flag == "2")
|
{
|
throw new Exception($"当前托盘所在的储位已损坏,不能出库,请核实");
|
}
|
|
if (locate.Status != "1")
|
{
|
throw new Exception($"当前托盘所在的储位状态不是有物品,不能出库,请核实");
|
}
|
|
#endregion
|
|
|
#region 添加出库任务
|
|
var taskNo = new Common().GetMaxNo("TK");
|
var exTask = new LogTask //出库任务
|
{
|
TaskNo = taskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = outMode,//目标位置
|
PalletNo = de.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + locate.LocatNo + "到" + outMode + "的出库任务", //关键信息
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
|
outDtoList.Add(new OutCommandDto()
|
{
|
PalletNo = palletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,
|
EndLocate = outMode, // 目标位置
|
TaskNo = exTask.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = outMode, //目标地址
|
Order = 1
|
});
|
#endregion
|
|
#region 改变数据
|
//判断是否为空托盘
|
if (de.SkuNo == "100099")
|
{
|
//增加锁定数量
|
de.LockQty += de.Qty; //增加锁定数量
|
de.Status = "2"; //状态 2:已分配
|
stocka.LockQty += (int)de.Qty; //增加库存总量锁定数量
|
|
Db.Updateable(de).ExecuteCommand();
|
Db.Updateable(stocka).ExecuteCommand();
|
}
|
|
locate.Status = "3"; //要出库的储位改变状态 正在出库
|
Db.Updateable(locate).ExecuteCommand();
|
|
|
#endregion
|
|
//添加操作日志记录
|
new OperationSOServer().AddLogOperationSo("出库作业", "托盘出库", palletNo, "出库", $"点击出库按钮出库托盘为:{palletNo}", userId);
|
Db.CommitTran();
|
|
|
|
if (outDtoList.Count > 0)
|
{
|
// 正式运行程序放开
|
var list2 = outDtoList.Select(m => m.TaskNo).ToList();
|
var jsonData = JsonConvert.SerializeObject(outDtoList);
|
string response = "";
|
|
try
|
{
|
var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
|
var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
////解析返回数据
|
var wcsModel = JsonConvert.DeserializeObject<WcsModel2>(response);
|
if (wcsModel.code == 200)
|
{
|
//更改任务的发送返回时间//
|
new TaskServer().EditTaskIssueOk(list2, time1, time2);
|
str += "下发成功";
|
}
|
else
|
{
|
new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.message);
|
throw new Exception(wcsModel.message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
|
}
|
|
return outDtoList;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
|
#endregion
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
#endregion
|
|
#region 自动分配、取消分配、获取手动分配的数据源、手动分配
|
|
// 判断是否是跨批出库
|
public bool IsCrossLotNo(string soNo)
|
{
|
try
|
{
|
//方法返回结果:bl
|
var bl = true;
|
//查询单据信息
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
|
//判断单据类型 成品出库、领料出库(其它类型跳出此方法)
|
if (notice.Type != "0" && notice.Type != "1")
|
{
|
return bl;
|
}
|
//查询到当前单据下的出库单明细信息
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList();
|
//库存总表信息
|
var data = Db.Queryable<DataStock>().Where(m => m.IsDel == "0").ToList();
|
//库存明细中检验合格批次集合
|
var dataDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.InspectStatus == "1").GroupBy(g => g.LotNo).Select(s => s.LotNo).ToList();
|
//库存明细表信息
|
var dataBoxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0").ToList();
|
|
|
//循环单据明细信息
|
foreach (var item in noticeDetail)
|
{
|
//验证先进先出原则
|
//获取当前物料的所有批次信息(排除单据的批次,防止单据所在批次锁定数量后验证小于等于0)
|
var forData = data.Where(m => m.SkuNo == item.SkuNo
|
&& m.LotNo != item.LotNo && (m.Qty - m.FrozenQty - m.LockQty) > 0
|
&& dataDetail.Contains(m.LotNo)).Select(m => m.LotNo).ToList();
|
|
forData.Add(item.LotNo); //集合添加单据的批次
|
//获取排序后的第一个批次
|
var firstLotNo = forData.OrderBy(m => m).First();
|
if (firstLotNo != item.LotNo)
|
{
|
bl = false;
|
break;
|
}
|
|
//验证效期优先原则
|
var forDataBox = dataBoxInfo.Where(m => m.SkuNo == item.SkuNo && m.LotNo != item.LotNo && m.Qty > 0).ToList();
|
//获取当前单据批次的最近效期
|
var expirationTimedt = dataBoxInfo.Where(m => m.SkuNo == item.SkuNo
|
&& m.LotNo == item.LotNo && m.Qty > 0).ToList();
|
if (expirationTimedt.Count > 0)
|
{
|
var expirationTime = expirationTimedt.OrderBy(m => m.ExpirationTime).Select(m => m.ExpirationTime).First();
|
//获取库存中其它批次效期大于当前单据批次的效期数量
|
var num = forDataBox.Count(m => m.ExpirationTime > expirationTime);
|
//判断是否大于0
|
if (num > 0)
|
{
|
bl = false;
|
break;
|
}
|
}
|
else
|
{
|
var dataDetailtime = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.InspectStatus == "1").
|
Where(m => m.SkuNo == item.SkuNo
|
&& m.LotNo == item.LotNo && m.Qty > 0)
|
.OrderBy(m => m.ExpirationTime)
|
.Select(m => m.ExpirationTime).First();
|
|
var num = forDataBox.Count(m => m.ExpirationTime > dataDetailtime);
|
//判断是否大于0
|
if (num > 0)
|
{
|
bl = false;
|
break;
|
}
|
}
|
}
|
|
|
return bl;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
/// <summary>
|
/// 自动分配
|
/// </summary>
|
/// <param name="soNo"></param>
|
/// <param name="userId"></param>
|
/// <returns></returns>
|
/// <exception cref="Exception"></exception>
|
public bool AutoAllot(string soNo, int userId)
|
{
|
try
|
{
|
#region 判断条件(出库单、出库单明细)
|
//出库单
|
var notice = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList().FirstOrDefault();
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
if (notice.Status != "0" && notice.Status != "1")
|
{
|
throw new Exception("参数异常,请检查状态是否为等待执行或部分分配;");
|
}
|
//出库单明细
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == soNo && (m.AllotQty - m.Qty) <= 0).ToList();
|
if (!detailList.Any())
|
{
|
throw new Exception("未查询到符合分配条件的出库单据明细信息");
|
}
|
|
#endregion
|
|
var exAllotList = new List<BllExportAllot>();
|
var assign = new AllotSku();
|
Db.BeginTran();
|
try
|
{
|
List<SoDetailInfo> soDetailList = new List<SoDetailInfo>();
|
foreach (var detail in detailList)
|
{
|
if (detail.AllotQty >= detail.Qty)
|
{
|
continue;
|
}
|
//还需要分配的数量
|
decimal needQty = detail.Qty - (detail.AllotQty == null ? 0 : decimal.Parse(detail.AllotQty.ToString()));
|
//库存明细 Status 0:待分配 1:部分分配 2:已分配
|
var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.SkuNo == detail.SkuNo && (m.Qty - m.FrozenQty - m.LockQty + m.InspectQty) > 0 && (m.Status == "0" || m.Status == "1") && m.IsDel == "0").ToList();
|
|
|
//判断单号是否指定批次
|
if (!string.IsNullOrWhiteSpace(detail.LotNo))
|
{
|
stockDetail = stockDetail.Where(m => m.SkuNo == detail.SkuNo && m.LotNo == detail.LotNo && m.IsDel == "0").ToList();
|
}
|
else
|
{
|
stockDetail = stockDetail.Where(m => m.SkuNo == detail.SkuNo && m.IsDel == "0" && string.IsNullOrWhiteSpace(m.LotNo)).ToList();
|
}
|
|
if (stockDetail.Count < 1)
|
{
|
throw new Exception("库存不足,无可出库库存");
|
}
|
//0:成品出库、1:领料出库、2:抽检出库、4:不合格品出库、7:其他出库、9:生产领料出库 ///3:取样出库、5:中间品出库、8:寄存出库
|
if (notice.Type == "0" || notice.Type == "1" || notice.Type == "9")//成品、领料出库
|
{
|
stockDetail = stockDetail.Where(m => m.InspectStatus == "1").ToList();
|
}
|
else if (notice.Type == "2")//抽检出库
|
{
|
stockDetail = stockDetail.Where(m => m.InspectStatus == "0" || m.InspectStatus == "1" || m.InspectStatus == "2").ToList();
|
}
|
else if (notice.Type == "4")//不合格出库
|
{
|
stockDetail = stockDetail.Where(m => m.InspectStatus == "2").ToList();
|
}
|
else if (notice.Type == "7") //、其它
|
{
|
stockDetail = stockDetail.Where(m => m.InspectStatus == "0" || m.InspectStatus == "1").ToList();
|
}
|
if (stockDetail.Sum(m => m.Qty - m.LockQty) < needQty)
|
{
|
throw new Exception("库存明细数量不足");
|
}
|
#region 包装信息
|
|
var pNum = 0;//托盘物品数量
|
var bNum = 0;//箱物品数量
|
//公共方法获取包装数量
|
new Common().GetPackQtyInfo(detail.PackagNo, ref pNum, ref bNum);
|
|
#endregion
|
|
//取合适库存商品
|
Dictionary<int, decimal> stockQtyDic = new Dictionary<int, decimal>();//托出库物品数
|
var qty = 0m;
|
var house = "";
|
|
//分配货物
|
qty += assign.AllotPallets(stockDetail, needQty, pNum, bNum, stockQtyDic, notice.WareHouseNo);
|
foreach (var sc in stockQtyDic)
|
{
|
var s = stockDetail.FirstOrDefault(m => m.Id == sc.Key);
|
//添加分配表信息
|
var allot = new BllExportAllot
|
{
|
SONo = notice.SONo,
|
WaveNo = "",
|
SODetailNo = detail.Id,
|
StockId = sc.Key,
|
LotNo = s.LotNo,
|
LotText = s.LotText,
|
SupplierLot = s.SupplierLot,
|
SkuNo = s.SkuNo,
|
SkuName = s.SkuName,
|
Standard = s.Standard,
|
PalletNo = s.PalletNo,
|
IsBale = detail.IsBale == "0" ? "0" : s.IsBale == "1" ? "0" : "1", //是否裹包
|
IsBelt = detail.IsBelt == "0" ? "0" : s.IsBelt == "1" ? "0" : "1", //是否打带
|
|
Qty = sc.Value,
|
CompleteQty = 0,
|
//BoxexQty = s.Qty, //箱内数量
|
Status = "0",
|
LogisticsId = notice.LogisticsId,
|
IsAdvance = "0",
|
OutMode = "",//出库口
|
|
CreateUser = userId,
|
CreateTime = DateTime.Now
|
};
|
exAllotList.Add(allot);
|
|
s.LockQty += stockQtyDic[s.Id];
|
|
if (s.LockQty == s.Qty)
|
{
|
s.Status = "2";
|
}
|
else
|
{
|
s.Status = "1";
|
}
|
|
var sd = Db.Updateable(s).UpdateColumns(it => new { it.LockQty, it.Status }).ExecuteCommand();
|
|
}
|
detail.AllotQty += qty;
|
detail.UpdateUser = userId;
|
detail.UpdateTime = DateTime.Now;
|
if (detail.Status == "0")
|
{
|
detail.Status = "1";
|
}
|
if (qty > detail.Qty)
|
{
|
//库存总表
|
var stock = Db.Queryable<DataStock>().First(d => d.IsDel == "0"
|
&& d.SkuNo == detail.SkuNo
|
&& d.LotNo == detail.LotNo);
|
stock.LockQty += qty - detail.Qty;
|
Db.Updateable(stock).ExecuteCommand();
|
|
//添加回传上游系统锁定数量更改代码
|
SoDetailInfo soDetail = new SoDetailInfo();
|
soDetail.OrderDetailCode = detail.OrderDetailCode;
|
soDetail.LockQty = qty - detail.Qty;
|
soDetail.LotNo = detail.LotNo;
|
|
soDetailList.Add(soDetail);
|
}
|
|
}
|
|
var mx = Db.Updateable(detailList).ExecuteCommand();
|
var fp = Db.Insertable(exAllotList).ExecuteCommand();
|
|
//修改分配单据的状态
|
if (notice.Status == "0" || notice.Status == "1")
|
{
|
var bl = 0;
|
var bl2 = 0;
|
foreach (var item in detailList)
|
{
|
if (item.AllotQty <= 0)
|
{
|
continue;
|
}
|
if (item.AllotQty < item.Qty)
|
{
|
bl = 1;
|
}
|
else
|
{
|
bl2 = 1;
|
}
|
}
|
|
switch (bl2)
|
{
|
case 1 when bl == 1:
|
notice.Status = "1";//证明部分分配数量全部大于等于出库数量 修改为已分配
|
break;
|
case 0 when bl == 1:
|
notice.Status = "1";//证明部分分配数量全部大于等于出库数量 修改为已分配
|
break;
|
case 1 when bl == 0:
|
notice.Status = "2";//证明分配数量全部大于等于出库数量 修改为已分配
|
break;
|
case 0 when bl == 0:
|
//证明所有分配数量全部小于等于出库数量 不做修改
|
break;
|
}
|
|
}
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
var zd = Db.Updateable(notice).ExecuteCommand();
|
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据",
|
notice.SONo, "分配", $"自动分配了单据号为{notice.SONo}的单据信息", userId);
|
|
if (zd > 0 && mx > 0 && fp > 0 && k)
|
{
|
#region 通过接口发送至erp
|
//系统对接后放开
|
/*var jsonData = JsonConvert.SerializeObject(soDetailList);
|
|
var response = HttpHelper.DoPost(url, jsonData, "库存锁定数量变更", "ERP");
|
|
var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据
|
if (obj.Success != 0)
|
{
|
throw new Exception("上传失败" + obj.Message);
|
}*/
|
#endregion
|
|
Db.CommitTran();
|
return true;
|
}
|
Db.RollbackTran();
|
return false;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
catch (Exception e)
|
{
|
throw new Exception("自动分配失败:" + e.Message);
|
}
|
}
|
|
//取消分配
|
public bool CancelAllot(string soNo, int userId)
|
{
|
try
|
{
|
|
var notice = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.SONo == soNo).ToList().FirstOrDefault();
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
if (notice.Status != "1" && notice.Status != "2")
|
{
|
throw new Exception("参数异常,请检查状态是否为已分配或部分分配或来源是否是WMS");
|
}
|
//该单据的分配信息 Status 0:任务下发 1:待拣货 2:部分拣货 3:待回库 4:已完成
|
var allotList = Db.Queryable<BllExportAllot>().Where(o => o.IsDel == "0" && o.SONo == soNo).ToList();
|
//有已执行的分配数据不能取消
|
if (allotList.Any(o => o.Status != "0"))
|
{
|
throw new Exception("当前单据的分配信息已有执行中,不能取消分配");
|
}
|
List<SoDetailInfo> soDetailList = new List<SoDetailInfo>();
|
//开启事务
|
Db.BeginTran();
|
try
|
{
|
//查询分配的明细
|
var detail = Db.Queryable<BllExportNoticeDetail>().Where(d => d.SONo == soNo && d.AllotQty > 0 && d.IsDel == "0").ToList();
|
foreach (var d in detail)
|
{
|
var orders = allotList.Where(o => o.SODetailNo == d.Id).ToList();
|
foreach (var o in orders)
|
{
|
var pq = Db.Queryable<DataStockDetail>().Where(t => t.Id == o.StockId);
|
|
var pq2 = !string.IsNullOrWhiteSpace(o.LotNo) ? pq.Where(t => t.LotNo == o.LotNo).ToList() : pq.Where(t => string.IsNullOrWhiteSpace(t.LotNo)).ToList();
|
|
var pallet = pq2.FirstOrDefault();
|
if (pallet != null)
|
{
|
pallet.LockQty -= o.Qty;
|
pallet.Status = pallet.LockQty == 0 ? "0" : "1"; //如果锁定数量是0状态变更为待分配 否则为部分分配
|
Db.Updateable(pallet).ExecuteCommand();
|
|
//库存总表
|
//var stock = Db.Queryable<DataStock>().First(t => t.SkuNo == pallet.SkuNo && t.IsDel == "0");
|
//stock.LockQty -= o.Qty;
|
//Db.Updateable(stock).ExecuteCommand();
|
}
|
|
}
|
Db.Deleteable<BllExportAllot>(orders).ExecuteCommand();
|
|
if (d.AllotQty > d.Qty)
|
{
|
//库存总表
|
var stock = Db.Queryable<DataStock>().First(m => m.IsDel == "0" && m.SkuNo == d.SkuNo && m.LotNo == d.LotNo);
|
stock.LockQty -= (decimal)d.AllotQty - d.Qty;
|
Db.Updateable(stock).ExecuteCommand();
|
|
//添加回传上游系统锁定数量更改代码
|
SoDetailInfo soDetail = new SoDetailInfo();
|
soDetail.OrderDetailCode = d.OrderDetailCode;
|
soDetail.LockQty = (decimal)(d.Qty - d.AllotQty);
|
soDetail.LotNo = d.LotNo;
|
|
soDetailList.Add(soDetail);
|
}
|
d.AllotQty = 0;
|
d.Status = "0";
|
d.UpdateUser = userId;
|
d.UpdateTime = DateTime.Now;
|
//if (notice.Type == "1" || notice.Type == "5" || notice.Type == "6" || notice.Type == "7" || notice.Type == "8")//1:领料出库、
|
//{
|
// if (d.IsIssueLotNo != "1")
|
// {
|
// d.LotNo = "";
|
// }
|
|
//}
|
}
|
|
//查询当前单据是否已添加备料任务
|
if (notice.Type == "1")
|
{
|
var task = Db.Queryable<BllExportTimingTask>().First(m => m.IsDel == "0" && m.SoNo == soNo);
|
if (task != null)
|
{
|
task.IsDel = "1";
|
task.UpdateUser = userId;
|
task.UpdateTime = DateTime.Now;
|
Db.Updateable(task).ExecuteCommand();
|
}
|
}
|
notice.Status = "0";
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
Db.Updateable(detail).ExecuteCommand();
|
Db.Updateable(notice).ExecuteCommand();
|
|
//系统对接后放开
|
/*var jsonData = JsonConvert.SerializeObject(soDetailList);
|
|
var response = HttpHelper.DoPost(url, jsonData, "库存锁定数量变更", "ERP");
|
|
var obj = JsonConvert.DeserializeObject<ErpModel>(response);//解析返回数据
|
if (obj.Success != 0)
|
{
|
throw new Exception("上传失败" + obj.Message);
|
}*/
|
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "取消分配", $"取消分配了单据号为{notice.SONo}的单据信息", userId);
|
Db.CommitTran();
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
return true;
|
}
|
catch (Exception e)
|
{
|
throw new Exception("取消分配失败" + e.Message);
|
}
|
}
|
|
/// <summary>
|
/// 维护出库单备注信息
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="demo"></param>
|
/// <param name="userId"></param>
|
public void EditNoticeDemo(int id, string demo, int userId)
|
{
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.Id == id);
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单据信息");
|
}
|
notice.Demo = demo + "".Trim();
|
notice.UpdateUser = userId;
|
notice.UpdateTime = DateTime.Now;
|
|
int i = Db.Updateable(notice).ExecuteCommand();
|
if (i > 0)
|
{
|
//添加操作日志
|
new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "编辑", $"编辑了单据号为{notice.SONo}的备注信息", userId);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
}
|
|
//获取库存明细信息(出库单手动分配选择数据源)
|
public List<StockDetailDto> GetHandOutList(int detailId, string houseNo, string roadwayNo, string locateNo, string msg, string palletNo)
|
{
|
try
|
{
|
var detail = Db.Queryable<BllExportNoticeDetail>().First(d => d.Id == detailId);
|
|
#region 判断条件
|
|
if (detail == null)
|
{
|
throw new Exception("获取失败,未找到指定出库单!");
|
}
|
if (detail.Status != "0" && detail.Status != "1" && detail.AllotQty >= detail.Qty)
|
{
|
throw new Exception("获取失败,出库单状态不是等待执行或分配中!");
|
}
|
if (detail.AllotQty >= detail.Qty)
|
{
|
throw new Exception("获取失败,出库单已分配完成!");
|
}
|
var notice = Db.Queryable<BllExportNotice>().First(a => a.SONo == detail.SONo);
|
if (notice == null)
|
{
|
throw new Exception("获取失败,未找到指定出库单!");
|
}
|
if (notice.Status == "3" && detail.AllotQty >= detail.Qty || notice.Status == "4" || notice.Status == "5")
|
{
|
throw new Exception("获取失败,出库单状态不允许!");
|
}
|
#endregion
|
|
Expression<Func<DataStockDetail, bool>> item = Expressionable.Create<DataStockDetail>()
|
.AndIF(!string.IsNullOrWhiteSpace(houseNo), m => m.WareHouseNo == houseNo)
|
.AndIF(!string.IsNullOrWhiteSpace(roadwayNo), m => m.RoadwayNo == roadwayNo)
|
.AndIF(!string.IsNullOrWhiteSpace(locateNo), m => m.LocatNo == locateNo)
|
.AndIF(!string.IsNullOrWhiteSpace(palletNo), m => m.PalletNo == palletNo)
|
.AndIF(!string.IsNullOrWhiteSpace(msg),
|
m => m.SkuNo.Contains(msg.Trim())
|
|| m.SkuName.Contains(msg.Trim())
|
|| m.LocatNo.Contains(msg.Trim()))
|
.And(m => m.IsDel == "0" && m.SkuNo == detail.SkuNo && m.LotNo == detail.LotNo && (m.Status == "0" || m.Status == "1"))
|
.ToExpression();//注意 这一句 不能少
|
|
var list = Db.Queryable<DataStockDetail>().Where(item).Select(a => new StockDetailDto
|
{
|
Id = a.Id,
|
SkuNo = a.SkuNo,
|
SkuName = a.SkuName,
|
Standard = a.Standard,
|
LotNo = a.LotNo,
|
LotText = a.LotText,
|
SupplierLot = a.SupplierLot,
|
Qty = a.Qty - a.LockQty - a.FrozenQty,
|
LocatNo = a.LocatNo,
|
RoadwayNo = a.RoadwayNo,
|
PalletNo = a.PalletNo,
|
Demo = a.Demo,
|
}).ToList();
|
|
return list;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//手动分配出库单明细
|
public void AddHandOutAllot(AddHandOutVm model, int userId)
|
{
|
try
|
{
|
#region 判断条件
|
//数据验证
|
var detail = Db.Queryable<BllExportNoticeDetail>().First(a => a.IsDel == "0" && a.Id == model.Id);
|
if (detail == null)
|
{
|
throw new Exception("操作失败,未找到指定出库单详情!");
|
}
|
if (detail.AllotQty >= detail.Qty || (detail.Status != "0" && detail.Status != "1"))
|
{
|
throw new Exception("操作失败,出库单已分配完成!");
|
}
|
var notice = Db.Queryable<BllExportNotice>().First(a => a.IsDel == "0" && a.SONo == detail.SONo);
|
if (notice == null)
|
{
|
throw new Exception("操作失败,未找到指定出库单!");
|
}
|
if (notice.Status == "3" && detail.AllotQty >= detail.Qty || notice.Status == "4" || notice.Status == "5")
|
{
|
throw new Exception("操作失败,出库单已分配完成!");
|
}
|
#endregion
|
|
//单据明细需要的出库数量
|
var needQty = detail.Qty - detail.AllotQty;
|
//分配的出库数量
|
var outQty = model.StockList.Select(s => s.Qty).ToList().Sum();
|
if (outQty != needQty)
|
{
|
throw new Exception("操作失败,出库数量与计划数量不一致!");
|
}
|
var stockIds = model.StockList.Select(a => a.StockId).ToList();
|
//库存明细
|
var stockList = Db.Queryable<DataStockDetail>().Where(a => stockIds.Contains(a.Id)).ToList();
|
|
//分配信息
|
var allots = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.SODetailNo == detail.Id && m.Status == "0").ToList();
|
|
//库存总表
|
//var stockz = Db.Queryable<DataStock>().First(d => d.IsDel == "0" && d.SkuNo == detail.SkuNo && d.LotNo == detail.LotNo);
|
|
var allotList = new List<BllExportAllot>();
|
decimal outQtys = 0;
|
foreach (var st in model.StockList)
|
{
|
var stock = stockList.First(a => a.Id == st.StockId);
|
if (stock == null)
|
{
|
throw new Exception("操作失败,部分储位库存异常!");
|
}
|
if (st.Qty > (stock.Qty - stock.LockQty - stock.FrozenQty)) // 输入的数量 - 托盘上可用的数量(托盘上数量-锁定的数量-冻结的数量)
|
{
|
throw new Exception("操作失败,出库数量超出库存数量!");
|
}
|
|
var bl = allots.FirstOrDefault(m => m.StockId == st.StockId);
|
if (bl == null)
|
{
|
//添加分配表信息
|
var allot = new BllExportAllot
|
{
|
SONo = notice.SONo,
|
WaveNo = "",
|
SODetailNo = detail.Id,
|
StockId = st.StockId,
|
LotNo = stock.LotNo,
|
LotText = stock.LotText,
|
SupplierLot = stock.SupplierLot,
|
SkuNo = stock.SkuNo,
|
SkuName = stock.SkuName,
|
Standard = stock.Standard,
|
PalletNo = stock.PalletNo,
|
IsBale = stock.IsBale,
|
IsBelt = stock.IsBelt,
|
Qty = st.Qty,
|
CompleteQty = 0,
|
Status = "0",
|
LogisticsId = notice.LogisticsId,
|
IsAdvance = "0",
|
OutMode = "",//出库口
|
|
CreateUser = userId,
|
CreateTime = DateTime.Now
|
};
|
allotList.Add(allot);
|
}
|
else
|
{
|
bl.Qty += st.Qty;
|
Db.Updateable(bl).ExecuteCommand();
|
}
|
|
//库存明细
|
stock.LockQty += st.Qty;
|
stock.Status = stock.LockQty == stock.Qty ? "2" : "1";
|
|
//库存总表
|
//stockz.LockQty += st.Qty;
|
//Db.Updateable(stockz).ExecuteCommand();
|
|
|
Db.Updateable(stock).UpdateColumns(it => new { it.LockQty, it.Status }).ExecuteCommand();
|
outQtys += st.Qty;
|
}
|
Db.Insertable(allotList).ExecuteCommand();
|
//修改单据明细
|
detail.AllotQty += outQtys;
|
detail.UpdateUser = userId;
|
detail.UpdateTime = DateTime.Now;
|
if (detail.Status == "0")
|
{
|
detail.Status = "1";
|
}
|
|
Db.Updateable(detail).ExecuteCommand();
|
var detailList = Db.Queryable<BllExportNoticeDetail>()
|
.Where(m => m.IsDel == "0" && m.SONo == notice.SONo).ToList();
|
//修改出库单状态
|
if (notice.Status == "0" || notice.Status == "1")
|
{
|
decimal totalQty = 0;
|
decimal totalAllotQty = 0;
|
foreach (var item in detailList)
|
{
|
totalQty += item.Qty;
|
totalAllotQty += Convert.ToInt32(item.AllotQty);
|
}
|
|
if (totalAllotQty >= totalQty)
|
{
|
notice.Status = "2";//证明分配数量大于等于出库数量 修改为已分配
|
}
|
else if (totalAllotQty < totalQty && totalAllotQty > 0)
|
{
|
notice.Status = "1";//证明分配数量小于等于出库数量 修改为部分分配
|
}
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", notice.SONo, "分配", $"手动分配了单据号为{notice.SONo}、物料:{detail.SkuNo}、批次:{detail.LotNo}的单据信息", userId);
|
|
Db.CommitTran();
|
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
|
#endregion
|
|
#region 下发出库、出库完成、重新下发任务、取消任务、异常处理
|
|
public string GetHouseBySo(string soNo)
|
{
|
try
|
{
|
var notcie = Db.Queryable<BllExportNotice>().First(m=>m.IsDel == "0" && m.SONo == soNo);
|
if (notcie == null)
|
{
|
throw new Exception("未查询到出库单信息");
|
}
|
return notcie.WareHouseNo;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
public List<OutCommandDto> IssueOutHouseLk(string soNo, string outMode, int userId, string url, out string str)
|
{
|
try
|
{
|
var outDto1 = new List<OutCommandDto>(); //出库数据的集合(深度为1的储位)
|
//记录错误信息的集合 //1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库
|
var flagList = new List<int>();
|
|
var com = new Common();
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
|
if (notice == null)
|
{
|
throw new Exception($"未找到{soNo}出库单信息");
|
}
|
if (notice.WareHouseNo != "W02")
|
{
|
throw new Exception("仓库号错误");
|
}
|
//所有要出库的出库分配信息(未下发的信息和待拣货的信息)
|
var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList();
|
if (list.Count == 0) //判断是否有需要下发的出库流水
|
{
|
throw new Exception("当前出库单据无需要下发的托盘");
|
}
|
|
#region 集合
|
//要出库的托盘集合
|
var outLpnList = list.Select(m => m.PalletNo).ToList();
|
//要出库的明细集合
|
var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList();
|
//物料编码表
|
var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
|
//包装表
|
var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
|
Db.BeginTran();
|
try
|
{
|
List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库
|
var i = 0;
|
var outLocatelist1 = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.AreaNo == "B02" && m.Flag == "0").ToList();
|
var outLocatelist2 = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.AreaNo == "B05" && m.Flag == "0").ToList();
|
//循环分配的信息生成出库任务
|
foreach (var item in list)
|
{
|
var outModeLocate = "";
|
if (outMode == "17")
|
{
|
if (i < outLocatelist1.Count)
|
{
|
outModeLocate = outLocatelist1[i].LocatNo;
|
}
|
else
|
{
|
var j = i % outLocatelist1.Count;
|
|
outModeLocate = outLocatelist1[j].LocatNo;
|
}
|
}
|
else if (outMode == "18")
|
{
|
if (i < outLocatelist1.Count)
|
{
|
outModeLocate = outLocatelist2[i].LocatNo;
|
}
|
else
|
{
|
var j = i % outLocatelist1.Count;
|
|
outModeLocate = outLocatelist2[j].LocatNo;
|
}
|
}
|
else
|
{
|
throw new Exception("出库口工位异常");
|
}
|
|
var taskNoStr = "";
|
|
// 储位号
|
var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo;
|
|
#region 判断
|
|
//判断托盘是否在库内
|
if (string.IsNullOrWhiteSpace(locateNo)) //库外
|
{
|
//判断托盘是否在入库中
|
var imBl = com.GetImTask(item.PalletNo);
|
if (imBl != null)
|
{
|
flagList.Add(4);
|
continue;
|
}
|
//判断是否是已经出过库又回库(状态为待拣货的)
|
if (item.Status == "0")
|
{
|
//如果不在仓库内,当前分配信息直接更新出库完成
|
item.Status = "2";//状态
|
item.OutMode = outModeLocate;//出库口
|
Db.Updateable(item).ExecuteCommand();
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
flagList.Add(0);
|
continue;
|
|
}
|
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
|
if (locate == null)
|
{
|
flagList.Add(2);
|
continue;
|
}
|
//判断储位标志是否为损坏
|
if (locate.Flag == "2")
|
{
|
flagList.Add(3);
|
continue;
|
}
|
|
#endregion
|
|
if (locate.Status == "1") //有物品
|
{
|
#region 添加出库任务
|
|
var taskNo = new Common().GetMaxNo("TK");
|
var exTask = new LogTask //出库任务
|
{
|
TaskNo = taskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = outModeLocate,//目标位置
|
PalletNo = item.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + locate.LocatNo + "到" + outModeLocate + "的出库任务", //关键信息
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
logTaskList.Add(exTask);
|
|
outDto1.Add(new OutCommandDto()
|
{
|
TaskNo = exTask.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)0入 1出 2移
|
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,//其实巷道
|
EndLocate = outModeLocate, // 目标位置
|
|
Order = 999,
|
Type = PLCTypeEnum.AGV
|
|
});
|
taskNoStr = exTask.TaskNo;
|
|
#endregion
|
|
#region 改变数据
|
if (item.Status == "0")//判断托盘是否下发过
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
locate.Status = "3"; //要出库的储位改变状态 正在出库
|
Db.Updateable(locate).ExecuteCommand();
|
var locate2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == outModeLocate && m.IsDel == "0");//当前出库的目标储位信息
|
locate2.Status = "4";
|
Db.Updateable(locate2).ExecuteCommand();
|
|
item.TaskNo = taskNoStr; // 出库分配信息中更新任务号
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
//item.UnstackingMode = unstackingMode2;//拆垛方式
|
item.OutMode = outModeLocate;//出库口
|
//item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口
|
Db.Updateable(item).ExecuteCommand();
|
|
#endregion
|
|
flagList.Add(0);
|
i++;
|
}
|
else if (locate.Status == "3") //出库中
|
{
|
#region 改变数据
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
var taskNo = Db.Queryable<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo);
|
if (taskNo == null)
|
{
|
taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库
|
}
|
if (taskNo == null)
|
{
|
throw new Exception($"托盘号:{item.PalletNo},出库异常");
|
}
|
item.TaskNo = taskNo.TaskNo;
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.OutMode = item.OutMode;//出库口
|
//item.UnstackingMode = unstackingMode2;//拆垛模式
|
Db.Updateable(item).ExecuteCommand();
|
flagList.Add(0);
|
#endregion
|
}
|
else if (locate.Status == "5") //移出中
|
{
|
flagList.Add(1);
|
}
|
}
|
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击出库按钮出库单号为:{soNo}的出库单", userId);
|
Db.CommitTran();
|
|
str = string.Empty;
|
if (flagList.Count(m => m == 0) > 0)
|
{
|
str += "0.下发成功、";
|
}
|
if (flagList.Count(m => m == 1) > 0)
|
{
|
str += "1.当前要出库的储位正在移出、";
|
}
|
if (flagList.Count(m => m == 2) > 0)
|
{
|
str += "2.出库的托盘储位信息错误(在储位表中未查询到)、";
|
}
|
if (flagList.Count(m => m == 3) > 0)
|
{
|
str += "4.储位损坏不能出库、";
|
}
|
if (flagList.Count(m => m == 4) > 0)
|
{
|
str += "3.要出库的托盘正在入库、";
|
}
|
if (flagList.Count(m => m == 5) > 0)
|
{
|
str += "3.要出库的托盘正在拆托请稍后下发、";
|
}
|
if (outDto1.Count > 0)
|
{
|
// 正式运行程序放开
|
var list2 = outDto1.Select(m => m.TaskNo).ToList();
|
var jsonData = JsonConvert.SerializeObject(outDto1);
|
string response = "";
|
|
try
|
{
|
var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
//response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
|
var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
//////解析返回数据
|
//var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
|
//if (wcsModel.StatusCode == 0)
|
//{
|
// //更改任务的发送返回时间//
|
new TaskServer().EditTaskIssueOk(list2, time1, time2);
|
str += "下发成功";
|
//}
|
//if (wcsModel.StatusCode == -1)
|
//{
|
// new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
|
// throw new Exception(wcsModel.Msg);
|
//}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
|
}
|
|
return outDto1;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
|
#endregion
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
public List<OutCommandDto> IssueOutHouseMk(string soNo, string outMode, int userId, string url, out string str)
|
{
|
try
|
{
|
#region 集合
|
|
var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位)
|
var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位)
|
var moveDto = new List<OutCommandDto>(); //要移库数据的集合
|
//记录错误信息的集合
|
var flagList = new List<int>();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库
|
|
#endregion
|
var com = new Common();
|
var allot = new AllotLocation();
|
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
|
if (notice == null)
|
{
|
throw new Exception($"未找到{soNo}出库单信息");
|
}
|
//所有要出库的出库分配信息(未下发的信息和待拣货的信息)
|
var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList();
|
if (list.Count == 0) //判断是否有需要下发的出库流水
|
{
|
throw new Exception("当前出库单据无需要下发的托盘");
|
}
|
|
#region 集合
|
//要出库的托盘集合
|
var outLpnList = list.Select(m => m.PalletNo).ToList();
|
//要出库的明细集合
|
var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList();
|
//所有要出库的储位集合
|
var locateListStrs = outStockDetail.Where(m=> !string.IsNullOrWhiteSpace(m.LocatNo)).Select(m => m.LocatNo).Distinct().ToList();
|
//物料编码表
|
var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
|
//包装表
|
var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
|
Db.BeginTran();
|
try
|
{
|
List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库
|
|
|
//循环分配的信息生成出库任务
|
foreach (var item in list)
|
{
|
var taskNoStr = "";
|
|
// 储位号
|
var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo;
|
|
#region 判断托盘是否在库内
|
|
//判断托盘是否在库内
|
if (string.IsNullOrWhiteSpace(locateNo)) //库外
|
{
|
//if (notice.Type == "0")
|
//{
|
// flagList.Add(5);
|
// continue;
|
//}
|
//判断托盘是否在入库中
|
var imBl = com.GetImTask(item.PalletNo);
|
if (imBl != null)
|
{
|
flagList.Add(4);
|
continue;
|
}
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
//如果不在仓库内,当前分配信息直接更新出库完成
|
item.Status = "2";//状态
|
item.OutMode = outMode;//出库口
|
Db.Updateable(item).ExecuteCommand();
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
flagList.Add(0);
|
continue;
|
}
|
|
//判断储位
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
|
if (locate == null)
|
{
|
flagList.Add(2);
|
continue;
|
}
|
//判断储位标志是否为损坏
|
if (locate.Flag == "2")
|
{
|
flagList.Add(3);
|
continue;
|
}
|
|
#endregion
|
|
if (locate.Status == "1") //有物品
|
{
|
var row1 = int.Parse(locate.LocatNo.Substring(2,2));
|
var row2 = int.Parse(locate.AisleOne.Substring(2, 2));
|
//需要移库的信息
|
var NeedMoveInfo = IsNeedMoveLocate(locate, locateListStrs, out int isOut);
|
if (isOut == 1)
|
{
|
//巷道组中有入库或移入的储位,或者是当前储位前有储位未下发成功的任务
|
flagList.Add(2);
|
continue;
|
}
|
if (NeedMoveInfo.Count > 0)//需要移库
|
{
|
//判断库内空储位是否够
|
var okRoad = Db.Queryable<SysStorageRoadway>().Where(m => m.Status == "0" && m.IsDel == "0" && m.WareHouseNo == notice.WareHouseNo).Select(m => m.RoadwayNo).ToList();
|
var nullSlotNum = Db.Queryable<SysStorageLocat>().Count(m => m.RoadwayNo != locate.RoadwayNo && okRoad.Contains(m.RoadwayNo) && m.Status == "0");
|
//判断空储位的数量是否大于需要移库的数量
|
if (nullSlotNum >= NeedMoveInfo.Count)
|
{
|
var isYk = false;
|
foreach (var s in NeedMoveInfo)
|
{
|
//储位列
|
var rows = int.Parse(s.Substring(2,2));
|
|
//获取移库储位
|
var moveAddress = GetMiJiMoveAddress(s, locate.AisleOne);
|
var tary = Db.Queryable<DataStockDetail>().First(m => m.LocatNo == s);
|
if (string.IsNullOrWhiteSpace(moveAddress)) // 判断是否获取到移库的库位
|
{
|
isYk = true;
|
flagList.Add(5);//出库前有货物,需移库但未查询到空储位
|
break; //没有移库的库位了
|
}
|
else
|
{
|
//判断托盘有没有回移的任务
|
//var hy = GetHyTask(item.ExportStockCode);
|
//if (hy != null)
|
//{
|
// var hyentity = dataContext.WmsExportTask.FirstOrDefault(m => m.TaskId == hy.TaskId);
|
// if (hyentity != null)
|
// {
|
// isYk = true;
|
// msgList.Add(6);//出库前有货物,需移库但是回移托盘
|
// break; //没有移库的库位了
|
// }
|
//}
|
var ykTaskNo = new Common().GetMaxNo("TK");
|
var ykTask = new LogTask //出库任务
|
{
|
TaskNo = ykTaskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = s,//起始位置
|
EndLocat = moveAddress,//outMode,//目标位置
|
PalletNo = tary.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + locate.LocatNo + "到" + moveAddress + "的移库任务", //关键信息
|
};
|
Db.Insertable(ykTask).ExecuteCommand();
|
logTaskList.Add(ykTask);
|
|
outDto1.Add(new OutCommandDto()
|
{
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,//其实巷道
|
EndLocate = moveAddress,//outMode, // 目标位置
|
TaskNo = ykTaskNo, // 任务号
|
TaskType = "2",// 任务类型 (出库)0入 1出 2移
|
Order = Math.Abs(row2 - rows),
|
Type = PLCTypeEnum.ShuttleCar
|
|
});
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == s);
|
var slotChange2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == moveAddress);
|
|
slotChange.Status = "5"; //改变状态(正在出库)
|
slotChange2.Status = "4"; // 改变状态(正在移入)
|
Db.Updateable(slotChange).ExecuteCommand();
|
Db.Updateable(slotChange2).ExecuteCommand();
|
}
|
}
|
if (isYk)
|
{
|
break;
|
}
|
}
|
else
|
{
|
flagList.Add(5);
|
break;
|
}
|
}
|
#region 添加出库任务
|
|
var taskNo = new Common().GetMaxNo("TK");
|
var exTask = new LogTask //出库任务
|
{
|
TaskNo = taskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = outMode,//outMode,//目标位置
|
PalletNo = item.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + locate.LocatNo + "到" + outMode + "的出库任务", //关键信息
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
logTaskList.Add(exTask);
|
var endroad = allot.RoadwayToStationNum(locate.RoadwayNo, outMode);
|
outDto1.Add(new OutCommandDto()
|
{
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,//起始巷道
|
EndLocate = outMode,//, // 目标位置
|
EndRoadway = endroad,
|
TaskNo = exTask.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)0入 1出 2移
|
OutMode = outMode, //出库口
|
Order = Math.Abs(row2 - row1),
|
Type = PLCTypeEnum.ShuttleCar
|
|
});
|
taskNoStr = exTask.TaskNo;
|
|
#endregion
|
|
#region 改变数据
|
if (item.Status == "0")//判断托盘是否下发过
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
locate.Status = "3"; //要出库的储位改变状态 正在出库
|
Db.Updateable(locate).ExecuteCommand();
|
|
item.TaskNo = taskNoStr; // 出库分配信息中更新任务号
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
//item.UnstackingMode = unstackingMode2;//拆垛方式
|
item.OutMode = outMode;//出库口
|
//item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口
|
Db.Updateable(item).ExecuteCommand();
|
|
#endregion
|
|
flagList.Add(0);
|
}
|
else if (locate.Status == "3") //出库中
|
{
|
#region 改变数据
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
var taskNo = Db.Queryable<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo);
|
if (taskNo == null)
|
{
|
taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库
|
}
|
if (taskNo == null)
|
{
|
throw new Exception($"托盘号:{item.PalletNo},出库异常");
|
}
|
item.TaskNo = taskNo.TaskNo;
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.OutMode = item.OutMode;//出库口
|
//item.UnstackingMode = unstackingMode2;//拆垛模式
|
Db.Updateable(item).ExecuteCommand();
|
flagList.Add(0);
|
#endregion
|
}
|
else if (locate.Status == "5") //移出中
|
{
|
flagList.Add(1);
|
}
|
}
|
outDto1.AddRange(moveDto);
|
outDto1.AddRange(outDto2);
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击出库按钮出库单号为:{soNo}的出库单", userId);
|
Db.CommitTran();
|
|
str = string.Empty;
|
if (flagList.Count(m => m == 0) > 0)
|
{
|
str += "0.下发成功、";
|
}
|
if (flagList.Count(m => m == 1) > 0)
|
{
|
str += "1.当前要出库的储位正在移出、";
|
}
|
if (flagList.Count(m => m == 2) > 0)
|
{
|
str += "2.出库的托盘储位信息错误(在储位表中未查询到)、";
|
}
|
if (flagList.Count(m => m == 3) > 0)
|
{
|
str += "4.储位损坏不能出库、";
|
}
|
if (flagList.Count(m => m == 4) > 0)
|
{
|
str += "3.要出库的托盘正在入库、";
|
}
|
if (flagList.Count(m => m == 5) > 0)
|
{
|
str += "3.要出库的托盘正在拆托请稍后下发、";
|
}
|
if (outDto1.Count > 0)
|
{
|
// 正式运行程序放开
|
var list2 = outDto1.Select(m => m.TaskNo).ToList();
|
var jsonData = JsonConvert.SerializeObject(outDto1);
|
string response = "";
|
|
try
|
{
|
var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
|
var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
////解析返回数据
|
var wcsModel = JsonConvert.DeserializeObject<WcsModel2>(response);
|
if (wcsModel.code == 200)
|
{
|
//更改任务的发送返回时间//
|
new TaskServer().EditTaskIssueOk(list2, time1, time2);
|
str += "下发成功";
|
}
|
else
|
{
|
new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.message);
|
throw new Exception(wcsModel.message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
|
}
|
|
return outDto1;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
|
#endregion
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
/// <summary>
|
/// 判断是否需要进行移库操作
|
/// </summary>
|
/// <param name="oldAddress">要出库的库位地址</param>
|
/// <param name="aisle">通道口</param>
|
/// <param name="addressList">要出口的储位集合</param>
|
/// <param name="isOut">是否出库 1:有未下发的任务在前面</param>
|
/// <returns>需要移库的集合(如果为空则不需移库)</returns>
|
private List<string> IsNeedMoveLocate(SysStorageLocat lcoate,List<string> locateStrList, out int isOut)
|
{
|
var nowAddress = new List<string>(); //需要移库的集合
|
// 010101 派列层
|
//var bol = String.CompareOrdinal(lcoate.LocatNo, lcoate.AisleOne);
|
|
var sArray = lcoate.LocatNo.Substring(4,2);
|
var row = int.Parse(sArray);//储位列
|
var sArray2 = lcoate.AisleOne.Substring(4, 2);
|
var row2 = int.Parse(sArray2); //通道口列
|
|
isOut = 0;
|
|
var bol = row2 - row > 0;
|
|
//同组的储位集合
|
var slotList = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == lcoate.RoadwayNo).ToList();
|
List<string> list;
|
|
|
if (bol)
|
{
|
//储位小于通道口 倒序
|
list = slotList.Where(m => m.Column < row2 && m.Column > row).Select(m => m.LocatNo).ToList();
|
}
|
else
|
{
|
//储位大于通道口 正序
|
list = slotList.Where(m => m.Column > row2 && m.Column < row).Select(m => m.LocatNo).ToList();
|
}
|
|
if (list.Any())
|
{
|
//排除掉同巷道组中要出库的储位
|
if (locateStrList.Count != 0)
|
{
|
list = list.Where(m => !locateStrList.Contains(m)).ToList();
|
}
|
//判断是否有入库中或正在移入的
|
var s = slotList.Where(m => list.Contains(m.LocatNo) && (m.Status == "2" || m.Status == "4")).Select(m => m.LocatNo).ToList();
|
if (s.Count > 0)
|
{
|
isOut = 1;
|
return nowAddress;
|
}
|
//判断是否有在当前储位前未下发的任务(防止撞车)
|
var w = Db.Queryable<LogTask>().Where(m => list.Contains(m.StartLocat) && m.IsSuccess == 0).Select(m => m.StartLocat).ToList();
|
if (w.Count > 0)
|
{
|
isOut = 1;
|
return nowAddress;
|
}
|
if (bol)
|
{
|
//储位小于通道口 倒序
|
nowAddress = slotList.Where(m => list.Contains(m.LocatNo) && m.Status == "1").OrderByDescending(m => m.LocatNo).Select(m => m.LocatNo).ToList();
|
}
|
else
|
{
|
//储位大于通道口 正序
|
nowAddress = slotList.Where(m => list.Contains(m.LocatNo) && m.Status == "1").OrderBy(m => m.LocatNo).Select(m => m.LocatNo).ToList();
|
|
}
|
if (nowAddress.Count > 0)
|
{
|
return nowAddress;
|
}
|
}
|
else
|
{
|
return nowAddress;
|
}
|
|
|
return nowAddress;
|
}
|
|
/// <summary>
|
/// 获取移库目标库位 密集库
|
/// </summary>
|
/// <param name="oldAddress">需要移动的库位地址</param>
|
/// <param name="slotOut">需要移动的库位的出口中转位</param>
|
/// <param name="billCode">出库单据或是波次单据</param>
|
/// <param name="flags">中转口</param>
|
/// <param name="refLanWayId">需回移的巷道id</param>
|
/// <param name="refLanOutCode">需回移的巷道中转口</param>
|
/// <returns>目标库位地址 为"" 直接下发两次出库指令</returns>
|
public string GetMiJiMoveAddress(string oldAddress, string slotOut)
|
{
|
var newAddress = ""; //新库位
|
var newLaneWayAddress = ""; //新巷道口库位
|
|
// 获取移库目标储位
|
|
//
|
var sArray = oldAddress.Substring(4,2);
|
var ceng = int.Parse(sArray);
|
//
|
var sArray2 = slotOut.Substring(2, 2);
|
var row2 = sArray2;
|
//十字口
|
var shiKou = new List<string>()
|
{
|
slotOut,
|
"070501",
|
"071301",
|
"070502",
|
"071302",
|
};
|
var shiKou3 = new List<addreClass>();
|
foreach (var item in shiKou)
|
{
|
var a = item.Substring(4, 2);
|
var b = item.Substring(2, 2);
|
if (int.Parse(a) != ceng) continue;
|
var s = Math.Abs(int.Parse(b) - int.Parse(row2));
|
if (shiKou3.Any(m => m.distNum == s)) continue;
|
shiKou3.Add(new addreClass()
|
{
|
slotCode = item,
|
distNum = s
|
});
|
}
|
//根据十字口差值最小的排序
|
shiKou3 = shiKou3.OrderBy(m => m.distNum).ToList();
|
|
/**
|
//1 移动到最近的空储位,必须回移。
|
//根据四向车移动轨迹计算出最近空储位。
|
//出库完成后根据批次号 生产日期 出口计算回移储位。
|
|
//2 移动适合存放的组,系统自动计算是否回移。
|
//根据批次号 生产日期 出口 物料等计算出移库目标储位
|
//出库完成后,判断是否有比当前库位更合适的存储储位,有移动,无不移动。
|
*/
|
|
var oldSlot = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == oldAddress);
|
if (oldSlot == null)
|
{
|
throw new Exception("未能找到储位信息");
|
}
|
#region 1不需要回移的
|
|
//后期库存托盘表改了后需要加筛选条件托盘的状态(退货/预拣)
|
var tray1 = Db.Queryable<DataStockDetail>().Where(m => m.LocatNo == oldAddress).ToList();
|
//根据物料、批次、托盘状态(退货/预拣/暂存等)分组判断
|
var d = tray1.GroupBy(m => new { m.SkuNo, m.LotNo, m.PalletTags });
|
var location = string.Empty;
|
if (d.Any())
|
{
|
//旧储位同组的储位集合
|
var slotList = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == oldSlot.RoadwayNo).Select(m => m.LocatNo).ToList();
|
foreach (var item in d)
|
{
|
foreach (var item2 in item)
|
{
|
var okLan = Db.Queryable<SysStorageRoadway>().Where(m => m.Status == "0" && m.IsDel == "0").Select(m => m.RoadwayNo).ToList();
|
var tray2 = Db.Queryable<DataStockDetail>().Where(m => m.SkuNo == item2.SkuNo
|
&& m.LotNo == item2.LotNo && !slotList.Contains(m.LocatNo) && m.PalletTags == item2.PalletTags && okLan.Contains(m.RoadwayNo)).ToList();
|
foreach (var s in tray2)
|
{
|
if (string.IsNullOrWhiteSpace(s.RoadwayNo))//判断是否在库外,如是跳过
|
{
|
continue;
|
}
|
var lan = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == s.RoadwayNo).OrderBy(m => m.LocatNo).ToList();
|
//判断是否有入库中、出库中、移入中、移出中
|
if (lan.Count(m => m.Status == "2" || m.Status == "3" || m.Status == "4" || m.Status == "5") > 0)
|
{
|
continue;
|
}
|
if (lan.Count(m => m.Status == "0") > 0)
|
{
|
|
var bol = GetBecomingLocation(s.RoadwayNo, ref location);
|
if (bol && !string.IsNullOrWhiteSpace(location))
|
{
|
newAddress = location;
|
return newAddress;
|
|
}
|
|
}
|
}
|
}
|
}
|
|
}
|
|
#endregion
|
|
#region 2需要回移的
|
|
////如果没有找到合适的储位
|
//if (string.IsNullOrWhiteSpace(newAddress))
|
//{
|
// foreach (var s in shiKou3)
|
// {
|
|
// var r = int.Parse(s.slotCode.Substring(0, 2));
|
// var l = int.Parse(s.slotCode.Substring(2, 2));
|
// var c = int.Parse(s.slotCode.Substring(4, 2));
|
// //查询空储位
|
// var sqlString = $@"select LocatNo,Row,Column,Layer,(ABS(Row-{r}) + ABS(Column-{l}) ) as distNum
|
// from SysStorageLocat where (AisleOneRow = {r} or AisleTwoRow = {r}) and Status in (0) and
|
// RoadwayNo !='{oldSlot.RoadwayNo}' and RoadwayNo not in(select RoadwayNo from SysStorageRoadway where Status = 1) order by distNum,SlotCode";
|
|
// var addressModels = dataContext.ExecuteQuery<addreClass>(sqlString).ToList();
|
// foreach (var item in addressModels)
|
// { 、
|
|
|
// newAddress = item.slotCode;
|
// var dz = newAddress.Split(new char[] { '-' });
|
// var l1 = dz[1];
|
// var c1 = dz[0];
|
// newLaneWayAddress = $"{c1}-{l1}-{a[2]}";
|
// flags = newLaneWayAddress;
|
|
// var slotModel = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == item.slotCode);
|
|
// var lan = dataContext.WmsBaseSlot.Where(m => m.SlotLanewayId == slotModel.SlotLanewayId).ToList();
|
// if (slotModel.SlotRow > int.Parse(a[2]))
|
// {
|
// // 取最上面一排
|
// lan = lan.OrderBy(m => m.SlotCode).ToList();
|
// for (int i = 0; i < lan.Count; i++)
|
// {
|
// var slot = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == lan[i].SlotCode);
|
// if (slot.SlotStatus == 0)
|
// {
|
// if (i == lan.Count - 1)
|
// {
|
// newAddress = lan[lan.Count - 1].SlotCode;
|
|
// break;
|
// }
|
// else
|
// {
|
// continue;
|
// }
|
|
// }
|
// else
|
// {
|
// newAddress = lan[i - 1].SlotCode;
|
// break;
|
// }
|
// }
|
|
// }
|
// else
|
// {
|
// // 取最下面一排
|
// lan = lan.OrderByDescending(m => m.SlotCode).ToList();
|
// for (int i = 0; i < lan.Count; i++)
|
// {
|
// var slot = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == lan[i].SlotCode);
|
// if (slot.SlotStatus == 0)
|
// {
|
// if (i == lan.Count - 1)
|
// {
|
// newAddress = lan[lan.Count - 1].SlotCode;
|
// break;
|
// }
|
// else
|
// {
|
// continue;
|
// }
|
|
// }
|
// else
|
// {
|
// newAddress = lan[i - 1].SlotCode;
|
// break;
|
// }
|
// }
|
// }
|
// //添加回移任务
|
// AddHyTask(oldAddress, newAddress, newLaneWayAddress, oldSlot.SlotLanewayId, slotOut, billCode);
|
// refLanWayId = slotModel.SlotLanewayId;
|
// refLanOutCode = newLaneWayAddress;
|
// //9:锁定储位
|
// var updateSlot = dataContext.WmsBaseSlot.Where(m => m.SlotLanewayId == slotModel.SlotLanewayId).ToList();
|
// var newAddressRow = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == newAddress);
|
// if (newAddressRow.SlotRow > int.Parse(a[2]))
|
// {
|
// updateSlot = updateSlot.Where(m => m.SlotRow < newAddressRow.SlotRow && m.SlotRow > int.Parse(a[2])).OrderBy(m => m.SlotCode).ToList();
|
// }
|
// else
|
// {
|
// updateSlot = updateSlot.Where(m => m.SlotRow > newAddressRow.SlotRow && m.SlotRow < int.Parse(a[2])).OrderByDescending(m => m.SlotCode).ToList();
|
|
// }
|
// foreach (var source in updateSlot)
|
// {
|
// if (source.SlotCode == newAddress)
|
// {
|
// continue;
|
// }
|
// if (source.SlotStatus == 0)
|
// {
|
// source.SlotStatus = 8;
|
// }
|
// }
|
|
// if (updateSlot.Count <= 0)
|
// {
|
// refLanWayId = "";
|
// refLanOutCode = "";
|
// }
|
// dataContext.SubmitChanges();
|
// return newAddress;
|
|
|
|
// }
|
|
// }
|
|
//}
|
|
return newAddress;
|
#endregion
|
|
|
}
|
|
/// <summary>
|
/// 获取移库合适的储位 密集库
|
/// </summary>
|
/// <param name="laneWayId">合适组的巷道号</param>
|
/// <param name="location">分配储位</param>
|
/// <returns>true:存在合适储位 False:不存在合适储位</returns>
|
private bool GetBecomingLocation(string laneWayId, ref string location)
|
{
|
bool bl = false;
|
|
// 循环判断当前组是否有剩余储位
|
string sqlString = string.Empty;
|
location = "";
|
|
// 判断储位组是否有空储位 关联库存明细表可防止储位状态不准确避免造成满入异常//not in ('1','2','4','6','7','8')
|
sqlString = $"select LocatNo,Column,AisleOne from SysStorageLocat where RoadwayNo = {laneWayId} and Status in ('0') and LocatNo not in (select LocatNo from DataStockDetail where RoadwayNo = { laneWayId}) order by Row;";
|
var slotModel =Db.SqlQueryable<LocateInfo>(sqlString).ToList();
|
if (slotModel.Count == 0)
|
{
|
bl = false;
|
}
|
else // 存在空储位
|
{
|
// 判断当前组合适的储位地址
|
var numstr = slotModel[0].AisleOne.Substring(4,2);
|
int aisleRow = int.Parse(numstr);
|
|
if (slotModel[0].Column > aisleRow)
|
{
|
// 取最上面一排
|
location = slotModel[0].LocatNo;
|
|
}
|
else
|
{
|
// 取最下面一排
|
|
location = slotModel[slotModel.Count - 1].LocatNo;
|
}
|
|
bl = true;
|
}
|
|
|
|
return bl;
|
}
|
|
private class addreClass
|
{
|
public string slotCode { get; set; }
|
public int distNum { get; set; }
|
}
|
public class LocateInfo
|
{
|
public string LocatNo { get; set; }
|
public int Column { get; set; }
|
public string AisleOne { get; set; }
|
|
}
|
|
/// <summary>
|
/// wcs返回的成功信号(出库成功)
|
/// </summary>
|
/// <param name="taskNo"></param>
|
/// <param name="userId"></param>
|
/// <exception cref="Exception"></exception>
|
public void ExportSuccess(string taskNo, int userId)
|
{
|
try
|
{
|
//当前任务信息
|
var task = Db.Queryable<LogTask>().First(m => m.TaskNo == taskNo && m.IsDel == "0");
|
if (task == null)
|
{
|
throw new Exception($"未查询到任务号为:‘{taskNo}’的任务信息");
|
}
|
if (task.Status == "2")
|
{
|
throw new Exception("当前任务已完成");
|
}
|
Db.BeginTran();
|
//库存中当前托盘的信息
|
var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList();
|
var locateNo = stockDetail.Select(m => m.LocatNo).Distinct().FirstOrDefault();
|
//当前任务中的储位信息
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo);
|
try
|
{
|
task.Status = "2";//任务状态
|
task.IsSend = 0;
|
task.IsCancel = 0;
|
task.IsFinish = 0;
|
task.FinishDate = DateTime.Now;//完成时间
|
Db.Updateable(task).ExecuteCommand();
|
if (locate != null)
|
{
|
locate.Status = "0"; // 更改当前任务中的储位状态(改为0空储位)
|
Db.Updateable(locate).ExecuteCommand();
|
}
|
foreach (var item in stockDetail)
|
{
|
if (item.SkuNo == "100099")//判断是否是空托出库
|
{
|
//判断总库存是否为0,如果为0删除 否则减去数量
|
var stock = Db.Queryable<DataStock>().First(m => m.SkuNo == "100099");
|
|
if (stock != null)
|
{
|
if (item.LockQty != null)
|
{
|
stock.Qty -= item.LockQty.Value;
|
stock.LockQty -= item.LockQty.Value;
|
Db.Updateable(stock).ExecuteCommand();
|
}
|
|
if (stock.Qty == 0)
|
{
|
Db.Deleteable(stock).ExecuteCommand();
|
}
|
}
|
|
//托盘状态改为未使用
|
var sCode = Db.Queryable<SysPallets>().First(m => m.PalletNo == item.PalletNo);
|
if (sCode != null)
|
{
|
sCode.Status = "0";
|
Db.Updateable(sCode).ExecuteCommand();
|
}
|
Db.Deleteable(item).ExecuteCommand();
|
|
continue;
|
}
|
item.LocatNo = "";//储位更改(改为空)
|
item.WareHouseNo = "";//所属仓库更改(改为空)
|
item.RoadwayNo = "";//所属巷道更改(改为空)
|
item.AreaNo = "";//所属区域更改(改为空)
|
|
}
|
//出库流水(更改状态)
|
var allot = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && (m.TaskNo == taskNo || (m.Status == "1" && m.PalletNo == task.PalletNo))).ToList();
|
var PalletType = "0"; //0:物料托 1:空托盘托
|
|
foreach (var item in allot)
|
{
|
if (item.SkuNo == "100099")
|
{
|
item.Status = "5";
|
item.CompleteQty += stockDetail[0].Qty;
|
PalletType = "1";
|
}
|
else
|
{
|
item.Status = "2";
|
}
|
|
}
|
|
var endLocateList = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && (m.AreaNo == "B02" || m.AreaNo == "B05")).Select(m=>m.LocatNo).ToList();
|
//判断是否是原辅料出库任务 货架储位=》平库储位
|
if ( endLocateList.Contains(task.EndLocat) && PalletType == "0")
|
{
|
//修改目标地址状态
|
var endLocat = Db.Queryable<SysStorageLocat>().First(m => m.IsDel == "0" && m.LocatNo == task.EndLocat);
|
endLocat.Status = "1";
|
Db.Updateable(endLocat).ExecuteCommand();
|
foreach (var item in stockDetail)
|
{
|
item.LocatNo = endLocat.LocatNo;//储位更改(改为空)
|
item.WareHouseNo = endLocat.WareHouseNo;//所属仓库更改(改为空)
|
item.RoadwayNo = endLocat.RoadwayNo;//所属巷道更改(改为空)
|
item.AreaNo = endLocat.AreaNo;//所属区域更改(改为空)
|
}
|
}
|
Db.Updateable(stockDetail).ExecuteCommand();
|
Db.Updateable(allot).ExecuteCommand();
|
|
if (userId != 0)
|
{
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "完成", $"点击完成按钮、完成任务号为:{taskNo}的任务", userId);
|
}
|
|
Db.CommitTran();
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception("完成反馈失败:" + ex.Message);
|
}
|
}
|
|
/// <summary>
|
/// wcs返回的成功信号(移库成功)
|
/// </summary>
|
/// <param name="taskNo">任务号</param>
|
/// <param name="userId">操作人</param>
|
/// <exception cref="Exception"></exception>
|
public void RelocationSuccess(string taskNo, int userId)
|
{
|
try
|
{
|
//当前任务信息
|
var task = Db.Queryable<LogTask>().First(m => m.TaskNo == taskNo && m.IsDel == "0");
|
if (task == null)
|
{
|
throw new Exception($"未查询到任务号为:‘{taskNo}’的任务信息");
|
}
|
if (task.Status == "2")
|
{
|
throw new Exception("当前任务已完成");
|
}
|
Db.BeginTran();
|
//库存中当前托盘的信息
|
var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList();
|
//当前任务中的目标储位信息
|
//当前任务中的原储位
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat);
|
if (locate == null)
|
{
|
throw new Exception($"WMS系统中没有该{task.StartLocat}储位对应的信息");
|
}
|
var locate2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.EndLocat);
|
if (locate2 == null)
|
{
|
throw new Exception($"WMS系统中没有该{task.EndLocat}储位对应的信息");
|
}
|
//平库中储位集合
|
var pingKuLocate = Db.Queryable<SysStorageLocat>().Where(m => m.WareHouseNo == "W04" && m.IsDel == "0").ToList();
|
var pingKuList = pingKuLocate.Select(m => m.LocatNo).ToList();
|
try
|
{
|
|
//task.Status = "5";//任务状态
|
////判断起始目标位置都是平库
|
//if (pingKuList.Contains(task.StartLocat) && pingKuList.Contains(task.EndLocat))
|
//{
|
task.Status = "2";
|
//}
|
|
task.IsSend = 0;
|
task.IsCancel = 0;
|
task.IsFinish = 0;
|
task.FinishDate = DateTime.Now;//完成时间
|
Db.Updateable(task).ExecuteCommand();
|
|
#region 修改储位状态
|
|
if (!pingKuList.Contains(task.StartLocat))
|
{
|
//原储位改为空储位 0
|
locate.Status = "0";
|
Db.Updateable(locate).ExecuteCommand();
|
}
|
|
|
//目标储位改为有货物 1
|
locate2.Status = "1";
|
Db.Updateable(locate2).ExecuteCommand();
|
//判断起始目标位置都是平库
|
if ( pingKuList.Contains(task.EndLocat))
|
{
|
foreach (var item in stockDetail)
|
{
|
item.WareHouseNo = locate2.WareHouseNo;
|
item.AreaNo = locate2.AreaNo;
|
item.RoadwayNo = locate2.RoadwayNo;
|
item.LocatNo = locate2.LocatNo;
|
}
|
Db.Updateable(stockDetail).ExecuteCommand();
|
}
|
|
|
#endregion
|
|
Db.CommitTran();
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception("完成反馈失败:" + ex.Message);
|
}
|
}
|
|
/// <summary>
|
/// AGV任务取货完成反馈
|
/// </summary>
|
/// <param name="taskNo"></param>
|
public void AGVQuHuoSuccess(string taskNo)
|
{
|
try
|
{
|
Db.BeginTran();
|
var task = Db.Queryable<LogTask>().First(m=>m.IsDel =="0" && m.TaskNo == taskNo);
|
if (task == null)
|
{
|
throw new Exception("没有查询到任务信息");
|
}
|
if (task.Status!="1")
|
{
|
throw new Exception("任务状态不是正在执行,请核实");
|
}
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat && m.IsDel == "0");
|
if (locate == null)
|
{
|
throw new Exception("没有查询到起始储位信息");
|
}
|
if (locate.WareHouseNo!="W04")
|
{
|
throw new Exception("起始储位不是平库储位,请核实");
|
}
|
locate.Status = "0"; //更改储位状态为空储位
|
Db.Updateable(locate).ExecuteCommand();
|
//查询出托盘信息 更改库存储位信息
|
var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.PalletNo == task.PalletNo).ToList();
|
foreach (var item in stockDetail)
|
{
|
item.WareHouseNo = "";
|
item.AreaNo = "";
|
item.RoadwayNo = "";
|
item.LocatNo = "";
|
}
|
Db.Updateable(stockDetail).ExecuteCommand();
|
Db.CommitTran();
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
|
|
#endregion
|
|
#endregion
|
|
|
|
//------------------------------------------------------------------
|
|
#region 备料、备料出库
|
|
//生产备料定时任务
|
public void AddBeiLiaoTimer(string soNo, int userId)
|
{
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
|
if (notice == null)
|
{
|
throw new Exception("未查询到出库单信息");
|
}
|
var task = Db.Queryable<BllExportTimingTask>().Count(m => m.SoNo == soNo);
|
if (task>0)
|
{
|
throw new Exception("当前出库单已生成备料任务,无需重复点击");
|
}
|
var exTask = new BllExportTimingTask()
|
{
|
SoNo = soNo,
|
Status = 0,
|
CreateUser = userId
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
notice.Status = "3";//修改单据状态未正在执行
|
notice.UpdateTime = DateTime.Now;
|
notice.UpdateUser = userId;
|
|
Db.Updateable(notice).ExecuteCommand();
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击备料按钮出库单号为:{soNo}的出库单", userId);
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
// JC23 备料定时任务开始 领料单备料下发出库(调用wcs接口给他库位地址)
|
public List<OutCommandDto> BeiLiaoIssueOutHouse(string url)
|
{
|
try
|
{
|
var taskList = Db.Queryable<BllExportTimingTask>().Where(m => m.IsDel == "0").ToList();
|
var taskList1 = taskList.Where(m => m.Status == 1).ToList();
|
if (taskList1.Count > 0)
|
{
|
return null; //单据备料出库一个一个下发,防止托盘前后挡着下发不成功
|
}
|
var task = taskList.Where(m => m.Status == 0).OrderBy(m => m.Id).First();
|
if (taskList == null)
|
{
|
return null; //未查询到待备料出库的单据任务
|
}
|
#region 集合
|
|
var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位)
|
var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位)
|
var moveDto = new List<OutCommandDto>(); //要移库数据的集合
|
//记录错误信息的集合
|
var flagList = new List<int>();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库
|
|
#endregion
|
var com = new Common();
|
//assign.IsHavePyTask();
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == task.SoNo && m.IsDel == "0");
|
if (notice == null)
|
{
|
throw new Exception($"未找到{task.SoNo}出库单信息");
|
}
|
//所有要出库的出库分配信息(未下发的信息和待拣货的信息)
|
var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == task.SoNo && a.Status == "0").ToList();
|
if (list.Count == 0) //判断是否有需要下发的出库流水
|
{
|
throw new Exception("当前出库单据无需要下发的托盘");
|
}
|
|
#region 集合
|
//要出库的托盘集合
|
var outLpnList = list.Select(m => m.PalletNo).ToList();
|
//要出库的明细集合
|
var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList();
|
//物料编码表
|
var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
|
//包装表
|
var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
|
Db.BeginTran();
|
try
|
{
|
List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库
|
//循环分配的信息生成出库任务
|
foreach (var item in list)
|
{
|
var taskNoStr = "";
|
string toLocation = "outMode";//目标位置
|
string unstackingMode2 = "1";//拆垛方式,0:机器人拆垛 1:PDA拆垛
|
|
// 储位号
|
var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo;
|
|
#region 判断
|
|
decimal boxexQty = 0;//托盘上总数量
|
//判断托盘是否在库内
|
if (string.IsNullOrWhiteSpace(locateNo))
|
{
|
|
//判断托盘是否在入库中
|
var imBl = com.GetImTask(item.PalletNo);
|
if (imBl != null)
|
{
|
flagList.Add(4);
|
throw new Exception("要出库的托盘正在入库,等待入库完成后再出库");
|
}
|
var de = outStockDetail.First(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo);
|
if (de != null && de.WareHouseNo == "W02")//平库备料区的过滤掉不下发
|
{
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.OutMode = toLocation;//出库口
|
Db.Updateable(item).ExecuteCommand();
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.FactQty>0) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
flagList.Add(0);
|
continue;
|
}
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
//如果不在仓库内,当前分配信息直接更新出库完成
|
item.Status = "2";//状态
|
item.OutMode = toLocation;//出库口
|
Db.Updateable(item).ExecuteCommand();
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.FactQty>0) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
flagList.Add(0);
|
continue;
|
}
|
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
|
if (locate == null)
|
{
|
throw new Exception("出库的托盘储位信息错误(在储位表中未查询到)");
|
}
|
//判断储位标志是否为损坏
|
if (locate.Flag == "2")
|
{
|
throw new Exception($"{locate.LocatNo}储位损坏不能出库");
|
}
|
|
#endregion
|
|
if (locate.Status == "1") //有物品
|
{
|
#region 添加出库任务
|
if (locate.Depth == "01") //深度为1
|
{
|
var taskNo = new Common().GetMaxNo("TK");
|
var exTask = new LogTask //出库任务
|
{
|
TaskNo = taskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = toLocation,//outMode,//目标位置
|
PalletNo = item.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + locate.LocatNo + "到" + toLocation + "的出库任务", //关键信息
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
logTaskList.Add(exTask);
|
|
outDto1.Add(new OutCommandDto()
|
{
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,//其实巷道
|
EndLocate = toLocation,//outMode, // 目标位置
|
TaskNo = exTask.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = "", //目标地址
|
Order = 1,
|
|
//PalletType="0",//托盘类型
|
//UnstackingMode=unstackingMode,//拣货方式
|
//BoxexQty=boxexQty,//托盘上总数量
|
//CompleteQty=
|
});
|
taskNoStr = exTask.TaskNo;
|
}
|
else if (locate.Depth == "02") //深度为2
|
{
|
//获取出库深度为2储位前面的储位信息
|
var slotBefore = com.GetLocateNoDepth1(locate.WareHouseNo, locate.LocatNo);
|
if (slotBefore.Status == "1") //前面的储位有货物、进行移库操作
|
{
|
//要出库深度为2的储位前面的储位中货物是否要出库
|
var isout = outStockDetail.Count(m => m.LocatNo == slotBefore.LocatNo);
|
|
if (isout <= 0) //进行移库
|
{
|
//去库存表中找到储位对应的托盘码操作
|
var stockNew = Db.Queryable<DataStockDetail>().First(m => m.LocatNo == slotBefore.LocatNo);
|
if (stockNew == null)
|
{
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == slotBefore.LocatNo);
|
slotChange.Status = "0";
|
Db.Updateable(slotChange).ExecuteCommand();
|
}
|
else
|
{
|
//获取移库的库位
|
var newSlot = com.MoveAddress(slotBefore.LocatNo, slotBefore.RoadwayNo, item.SkuNo);
|
//当前移库库位的储位信息
|
var locatey = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == newSlot && m.IsDel == "0");
|
if (!string.IsNullOrEmpty(newSlot))
|
{
|
#region 添加出库时发生的移库任务
|
|
var exYkTaskNo = new Common().GetMaxNo("TK");
|
var exYkTask = new LogTask //出库时产生移库任务
|
{
|
TaskNo = exYkTaskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = stockNew.LocatNo,//起始位置
|
EndLocat = newSlot,//目标位置
|
PalletNo = stockNew.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
|
Msg = stockNew.LocatNo + " ==>> " + newSlot + "的移库任务",
|
};
|
Db.Insertable(exYkTask).ExecuteCommand();
|
|
moveDto.Add(new OutCommandDto()
|
{
|
StartRoadway = slotBefore.RoadwayNo, //起始巷道
|
PalletNo = stockNew.PalletNo,//托盘号
|
StartLocate = stockNew.LocatNo, // 起始位置
|
EndLocate = newSlot, // 目标位置
|
EndRoadway = locatey.RoadwayNo, // 目标巷道
|
TaskNo = exYkTask.TaskNo, // 任务号
|
TaskType = "2",// 任务类型 (移库)
|
OutMode = "", //目标地址
|
Order = 1,
|
});
|
#endregion
|
|
#region 改变储位状态
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.Id == slotBefore.Id);
|
var slotChange2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == newSlot);
|
slotChange.Status = "5"; //改变状态(正在移出)
|
slotChange2.Status = "4"; // 改变状态(正在移入)
|
Db.Updateable(slotChange).ExecuteCommand();
|
Db.Updateable(slotChange2).ExecuteCommand();
|
#endregion
|
}
|
else
|
{
|
#region 添加出库任务
|
|
var exYkTaskNo1 = new Common().GetMaxNo("TK");
|
var exYkTask1 = new LogTask //出库移库没有库位了进行出库任务
|
{
|
TaskNo = exYkTaskNo1,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = stockNew.LocatNo,//起始位置
|
EndLocat = toLocation,//目标位置
|
PalletNo = stockNew.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = locate.LocatNo + "的出库任务"
|
};
|
Db.Insertable(exYkTask1).ExecuteCommand();
|
|
outDto1.Add(new OutCommandDto()
|
{
|
StartRoadway = slotBefore.RoadwayNo, //起始巷道
|
PalletNo = stockNew.PalletNo,//托盘号
|
StartLocate = stockNew.LocatNo, // 起始位置
|
EndLocate = toLocation, // 目标位置
|
EndRoadway = "", // 目标巷道
|
TaskNo = exYkTask1.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = "", //目标地址
|
Order = 1,
|
});
|
#endregion
|
|
#region MyRegion
|
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.Id == slotBefore.Id);
|
slotChange.Status = "3"; //改变状态(正在出库)
|
Db.Updateable(slotChange).ExecuteCommand();
|
|
#endregion
|
}
|
}
|
}
|
}
|
else if (slotBefore.Status == "2" || slotBefore.Status == "4") //前面储位状态是入库中或者移入中
|
{
|
throw new Exception($"当前要出库的储位前{slotBefore.LocatNo}储位正在入库或移入");
|
}
|
|
#region 添加出库任务
|
|
var taskNo1 = new Common().GetMaxNo("TK");
|
var exTask1 = new LogTask //出库任务
|
{
|
TaskNo = taskNo1,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = toLocation,//目标位置
|
PalletNo = item.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = locate.LocatNo + "的出库任务"
|
};
|
Db.Insertable(exTask1).ExecuteCommand();
|
logTaskList.Add(exTask1);
|
outDto2.Add(new OutCommandDto()
|
{
|
StartRoadway = locate.RoadwayNo, //起始巷道
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
EndLocate = toLocation, // 目标位置
|
EndRoadway = locate.RoadwayNo, //目标巷道
|
TaskNo = exTask1.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = "", //目标地址
|
Order = 1,
|
});
|
taskNoStr = exTask1.TaskNo;
|
#endregion
|
|
}
|
#endregion
|
|
#region 改变数据
|
if (item.Status == "0")//判断托盘是否下发过
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.FactQty > 0) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
locate.Status = "3"; //要出库的储位改变状态 正在出库
|
Db.Updateable(locate).ExecuteCommand();
|
|
item.TaskNo = taskNoStr; // 出库分配信息中更新任务号
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.UnstackingMode = unstackingMode2;//拆垛方式
|
item.OutMode = toLocation;//出库口
|
//item.LoadingAddre = "";//装车口
|
Db.Updateable(item).ExecuteCommand();
|
|
#endregion
|
|
flagList.Add(0);
|
}
|
else if (locate.Status == "3") //出库中
|
{
|
#region 改变数据
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.FactQty > 0) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
var taskNo = Db.Queryable<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo);
|
if (taskNo == null)
|
{
|
taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库
|
}
|
if (taskNo == null)
|
{
|
throw new Exception($"托盘号:{item.PalletNo},出库异常");
|
}
|
item.TaskNo = taskNo.TaskNo;
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.OutMode = item.OutMode;//出库口
|
//item.LoadingAddre = unstackingMode2 == "0" ? taskNo.EndLocat : "";//装车口
|
Db.Updateable(item).ExecuteCommand();
|
flagList.Add(0);
|
#endregion
|
}
|
else if (locate.Status == "5") //移出中
|
{
|
throw new Exception($"当前要出库的储位{locate.LocatNo}正在移出");
|
}
|
}
|
outDto1.AddRange(moveDto);
|
outDto1.AddRange(outDto2);
|
////添加操作日志记录
|
//var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", task.SoNo, "出库", $"点击出库按钮出库单号为:{task.SoNo}的出库单", userId);
|
Db.CommitTran();
|
|
if (outDto1.Count > 0)
|
{
|
// 正式运行程序放开
|
var list2 = outDto1.Select(m => m.TaskNo).ToList();
|
var jsonData = JsonConvert.SerializeObject(outDto1);
|
string response = "";
|
|
try
|
{
|
//var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
//response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
|
//var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
//////解析返回数据
|
//var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
|
//if (wcsModel.StatusCode == 0)
|
//{
|
// //更改任务的发送返回时间//
|
// new TaskServer().EditTaskIssueOk(list2, time1, time2);
|
// str += "下发成功";
|
//}
|
//if (wcsModel.StatusCode == -1)
|
//{
|
// new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
|
// throw new Exception(wcsModel.Msg);
|
//}
|
|
//修改定时任务表
|
task.Status = 1;
|
task.UpdateTime = DateTime.Now;
|
Db.Updateable(task).ExecuteCommand();
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
|
}
|
|
return outDto1;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
|
#endregion
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//JC23 生产叫料定时任务开时
|
public List<OutCommandDto> ProCallIssueOutHouse(string url)
|
{
|
try
|
{
|
//先查询任务表中要有任务的投料口信息
|
var proCallList = Db.Queryable<BllProductionCallTask>().Where(m => m.IsDel == "0").ToList();
|
var proLocationList = proCallList.Select(m=>m.PutInLocation).ToList();
|
if (proCallList.Count == 0)
|
{
|
return null;
|
}
|
//获取任务中涉及到的投料口包含的工位集合
|
var locate = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && proLocationList.Contains(m.AreaNo)).ToList();
|
var outlist = new List<OutCommandDto>();
|
//判断任务表中是否有未下发成功的,如果有重新下发
|
foreach (var item in proLocationList)
|
{
|
//当前投料口包含的工位
|
var list = locate.Where(m => m.AreaNo == item).ToList();
|
var listStr = locate.Where(m => m.AreaNo == item).Select(m=>m.LocatNo).ToList();
|
//判断投料口的工位中是否有未下发成功的任务
|
var task = Db.Queryable<LogTask>().Where(m => m.Type == "1" && m.IsSuccess == 0 && m.Status == "0" && listStr.Contains(m.EndLocat) ).OrderBy(m=>m.TaskNo).ToList();
|
if(task.Count > 0)
|
{
|
|
foreach (var item2 in task)
|
{
|
//添加下发任务的信息
|
var outInfo = new OutCommandDto()
|
{
|
PalletNo = item2.PalletNo,//托盘号
|
StartLocate = item2.StartLocat, // 起始位置
|
StartRoadway = item2.StartRoadway,//起始巷道
|
EndLocate = item2.EndLocat,//outMode, // 目标位置
|
TaskNo = item2.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = "", //目标地址
|
Order = 1,
|
};
|
outlist.Add(outInfo);
|
//item2.IsSuccess = 1;
|
//item2.Status = "1";
|
//Db.Updateable(item2).ExecuteCommand();
|
}
|
|
//return outlist;
|
}
|
|
}
|
if (outlist.Count>0)
|
{
|
//将任务发送至AGV
|
// 正式运行程序放开
|
var list2 = outlist.Select(m => m.TaskNo).ToList();
|
var jsonData = JsonConvert.SerializeObject(outlist);
|
string response = "";
|
|
try
|
{
|
var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
//response = HttpHelper.DoPost(url, jsonData, "下发给AGV叫料出库命令", "AGV");
|
var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
////解析返回数据
|
//var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
|
//if (wcsModel.StatusCode == 0)
|
//{
|
// //更改任务的发送返回时间//
|
new TaskServer().EditTaskIssueOk(list2, time1, time2);
|
|
//}
|
//if (wcsModel.StatusCode == -1)
|
//{
|
// new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
|
// throw new Exception(wcsModel.Msg);
|
//}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
}
|
|
return null;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
|
//agv返回的成功信号(出库成功)
|
public void ExportSuccessAGV(string taskNo, int userId)
|
{
|
try
|
{
|
//当前任务信息
|
var task = Db.Queryable<LogTask>().First(m => m.TaskNo == taskNo && m.IsDel == "0");
|
if (task == null)
|
{
|
throw new Exception($"未查询到任务号为:‘{taskNo}’的任务信息");
|
}
|
if (task.Status == "2")
|
{
|
throw new Exception("当前任务已完成");
|
}
|
|
Db.BeginTran();
|
//库存中当前托盘的信息
|
var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.PalletNo == task.PalletNo).ToList();
|
var locateNo = stockDetail.Select(m => m.LocatNo).Distinct().FirstOrDefault();
|
//当前任务中的储位信息
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat);
|
var locate2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.EndLocat);
|
try
|
{
|
task.Status = "2";//任务状态
|
task.IsSend = 0;
|
task.IsCancel = 0;
|
task.IsFinish = 0;
|
task.FinishDate = DateTime.Now;//完成时间
|
Db.Updateable(task).ExecuteCommand();
|
if (locate != null)
|
{
|
locate.Status = "0"; // 更改当前任务中的储位状态(改为0空储位)
|
Db.Updateable(locate).ExecuteCommand();
|
}
|
if (locate2 != null)
|
{
|
locate2.Status = "1"; // 更改当前任务中的储位状态(改为1有物品)
|
Db.Updateable(locate2).ExecuteCommand();
|
}
|
|
#region 添加下一条叫料任务
|
var list = new List<string>()
|
{
|
"B02"
|
};
|
|
if (task.EndLocat == "空托盘收集器储位" && list.Contains(task.StartRoadway))
|
{
|
var exTime = Db.Queryable<BllProductionCallTask>().First(m => m.IsDel == "0" && m.PutInLocation == locate.AreaNo && m.SkuNo == locate.SkuNo);
|
if (exTime != null)
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(m=>m.IsDel =="0" && m.SONo == exTime.OrderCode);
|
//获取备好料的托盘信息
|
var taskStr = Db.Queryable<LogTask>().Where(m => m.IsDel == "0" && (m.Status == "0" || m.Status == "1") && m.Receiver == "AGV").Select(m => m.TaskNo).ToList();
|
var allotList = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.Status == "2" && m.SONo == notice.SONo && m.SkuNo == locate.SkuNo && !taskStr.Contains(m.TaskNo)).Select(m => m.PalletNo).ToList();
|
if (allotList.Count >0)
|
{
|
var stockDetail2 = Db.Queryable<DataStockDetail>().Where(m => allotList.Contains(m.PalletNo)).OrderBy(m => m.LocatNo).First();
|
|
//出库任务
|
var exTask = new LogTask
|
{
|
TaskNo = new Common().GetMaxNo("TK"),
|
Sender = "WMS",
|
Receiver = "AGV",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = stockDetail2.LocatNo,//起始位置
|
EndLocat = task.StartLocat,//目标位置
|
PalletNo = stockDetail2.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + stockDetail2.LocatNo + "到" + task.StartLocat + "的出库任务", //关键信息
|
FinishIsPick = "1"
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
//更改状态及信息
|
var locateStart = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == stockDetail2.LocatNo);
|
locateStart.Status = "5";
|
Db.Updateable(locateStart).ExecuteCommand();
|
var locateEnd = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == task.StartLocat);
|
locateEnd.Status = "4";
|
locateEnd.SkuNo = stockDetail2.SkuNo;
|
locateEnd.PalletNo = stockDetail2.PalletNo;
|
Db.Updateable(locateStart).ExecuteCommand();
|
}
|
else
|
{
|
var listLocate = Db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.AreaNo == locate.AreaNo).ToList();
|
if (listLocate.Count(m=>m.SkuNo == locate.SkuNo && m.Status != "0") == 0)
|
{
|
Db.Deleteable(exTime).ExecuteCommand();
|
}
|
|
locate.SkuNo = ""; // 更改当前任务中的物料记录(改为空)
|
locate.PalletNo = "";
|
Db.Updateable(locate).ExecuteCommand();
|
}
|
}
|
Db.CommitTran();
|
|
return;
|
}
|
|
#endregion
|
|
foreach (var item in stockDetail)
|
{
|
if (task.FinishIsPick == "1")
|
{
|
//出库流水(更改状态)
|
var allot = Db.Queryable<BllExportAllot>().First(m => m.IsDel == "0" && (m.TaskNo == taskNo || (m.Status == "2" && m.PalletNo == task.PalletNo)));
|
|
#region 拣货信息
|
var stockInfoList = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.StockDetailId == item.Id).ToList();
|
var pickQty = 0m;//拣货的数量
|
var comList = new List<BllCompleteDetail>();
|
foreach (var item2 in stockInfoList)
|
{
|
//添加拣货明细
|
var completeDetail = new BllCompleteDetail()
|
{
|
SONo = allot.SONo,
|
SODetailNo = allot.SODetailNo,
|
ExportAllotId = allot.Id,
|
StockId = item.Id,
|
BoxNo = item2.BoxNo,
|
BoxNo2 = item2.BoxNo2,
|
BoxNo3 = item2.BoxNo3,
|
|
LotNo = item2.LotNo,
|
LotText = item2.LotText,
|
SupplierLot = item2.SupplierLot,
|
SkuNo = item2.SkuNo,
|
SkuName = item2.SkuName,
|
Standard = item2.Standard,
|
PalletNo = item2.PalletNo,
|
CompleteQty = item.Qty,
|
|
CreateUser = userId
|
};
|
comList.Add(completeDetail);
|
pickQty += item2.Qty;
|
//删除库存箱码明细
|
Db.Deleteable(item2).ExecuteCommand();
|
}
|
if (comList.Count>0)
|
{
|
Db.Insertable(comList).ExecuteCommand();
|
}
|
|
#endregion
|
|
#region 更改库存总表数据
|
//更改库存总表数据
|
var stock = Db.Queryable<DataStock>().First(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo);
|
|
if (stock != null)
|
{
|
if (item.LockQty != null)
|
{
|
stock.Qty -= item.LockQty.Value;
|
stock.LockQty -= item.LockQty.Value;
|
Db.Updateable(stock).ExecuteCommand();
|
}
|
|
if (stock.Qty == 0)
|
{
|
Db.Deleteable(stock).ExecuteCommand();
|
}
|
}
|
|
#endregion
|
|
#region 出库流水(更改状态)
|
|
allot.Status = "5";
|
|
if (stockInfoList.Count == 0)
|
{
|
allot.CompleteQty += item.LockQty;
|
}
|
else
|
{
|
allot.CompleteQty += pickQty;
|
}
|
Db.Updateable(allot).ExecuteCommand();
|
#endregion
|
|
#region 出库单及明细
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.Id == allot.SODetailNo && m.IsDel == "0");
|
|
if (stockInfoList.Count == 0)
|
{
|
noticeDetail.CompleteQty += item.LockQty;
|
}
|
else
|
{
|
noticeDetail.CompleteQty += pickQty;
|
}
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
var num = Db.Queryable<BllExportNoticeDetail>().Count(m => m.IsDel == "0" && m.SONo == allot.SONo && m.CompleteQty < m.Qty);
|
if (num <= 0)
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == noticeDetail.SONo);
|
notice.Status = "4"; //更改为执行完成//修改出库单信息
|
|
Db.Updateable(notice).ExecuteCommand();
|
|
}
|
#endregion
|
|
Db.Deleteable(item).ExecuteCommand();
|
continue;
|
}
|
|
if (task.StartLocat == "outMode")
|
{
|
var count = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.Status != "2" && m.SONo == item.SONo && m.TaskNo != taskNo).Count();
|
if (count == 0)
|
{
|
var exportTimingTask = Db.Queryable<BllExportTimingTask>().First(m => m.SoNo == item.SONo && m.IsDel == "0");
|
if (exportTimingTask != null)
|
{
|
exportTimingTask.Status = 2;
|
exportTimingTask.UpdateTime = DateTime.Now;
|
|
Db.Updateable(exportTimingTask).ExecuteCommand();//删除定时任务;
|
}
|
}
|
}
|
|
item.LocatNo = locate2.LocatNo;//储位更改(改为空)
|
item.WareHouseNo = locate2.WareHouseNo;//所属仓库更改(改为空)
|
item.RoadwayNo = locate2.RoadwayNo;//所属巷道更改(改为空)
|
item.AreaNo = locate2.AreaNo;//所属区域更改(改为空)
|
Db.Updateable(item).ExecuteCommand();
|
}
|
|
if (userId != 0)
|
{
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "完成", $"点击完成按钮、完成任务号为:{taskNo}的任务", userId);
|
}
|
Db.CommitTran();
|
}
|
catch (Exception ex)
|
{
|
Db.RollbackTran();
|
throw new Exception(ex.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception("完成反馈失败:" + ex.Message);
|
}
|
}
|
|
#endregion
|
|
#region 下发出库、出库完成、重新下发任务、取消任务、异常处理
|
|
// 下发出库(调用cs接口给他库位地址)
|
public List<OutCommandDto> IssueOutHouse(string soNo, string unstackingMode, string outMode, string loadingAddre, int userId, string url, out string str)
|
{
|
try
|
{
|
#region 集合
|
|
var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位)
|
var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位)
|
var moveDto = new List<OutCommandDto>(); //要移库数据的集合
|
//记录错误信息的集合
|
var flagList = new List<int>();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库
|
|
#endregion
|
var com = new Common();
|
//assign.IsHavePyTask();
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
|
if (notice == null)
|
{
|
throw new Exception($"未找到{soNo}出库单信息");
|
}
|
//所有要出库的出库分配信息(未下发的信息和待拣货的信息)
|
var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList();
|
if (list.Count == 0) //判断是否有需要下发的出库流水
|
{
|
throw new Exception("当前出库单据无需要下发的托盘");
|
}
|
|
#region 集合
|
//要出库的托盘集合
|
var outLpnList = list.Select(m => m.PalletNo).ToList();
|
//要出库的明细集合
|
var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList();
|
//物料编码表
|
var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
|
//包装表
|
var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
|
Db.BeginTran();
|
try
|
{
|
List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库
|
//循环分配的信息生成出库任务
|
foreach (var item in list)
|
{
|
var taskNoStr = "";
|
string toLocation = string.Empty;//目标位置
|
string unstackingMode2 = unstackingMode;//拆垛方式,0:机器人拆垛 1:PDA拆垛
|
decimal? outCount = 0;
|
decimal? outCount2 = 0;
|
#region 判断是否需要拆箱
|
if (notice.Type == "0")//成品出库
|
{
|
string isChai = "0";//是否需要拆箱,0:否 1:是
|
var skuInfo = skuList.First(w => w.SkuNo == item.SkuNo);
|
if (skuInfo == null)
|
{
|
throw new Exception("物料信息不存在!");
|
}
|
var packagInfo = packagList.First(w => w.PackagNo == skuInfo.PackagNo);
|
if (packagInfo == null)
|
{
|
throw new Exception("包装信息不存在!");
|
}
|
if (packagInfo.L2Name == "箱")
|
{
|
if (item.Qty % (decimal)packagInfo.L2Num != 0)//能整除说明不用拆箱,不能整除说明需要拆箱
|
{
|
isChai = "1";
|
unstackingMode2 = "1";//需要拆箱需走PDA拆垛
|
}
|
}
|
if (isChai == "0")
|
{
|
var boxInfo = Db.Queryable<DataBoxInfo>().Where(w => w.IsDel == "0" && w.PalletNo == item.PalletNo && w.BitBoxMark == "1").ToList();
|
if (boxInfo != null)//托盘上有零箱需要拆箱
|
{
|
isChai = "1";
|
unstackingMode2 = "1";//需要拆箱需走PDA拆垛
|
}
|
}
|
|
if (unstackingMode2 == "0")//机器人拆垛
|
{
|
toLocation = outMode;//装车口
|
var zongNum = outStockDetail.First(m => m.Id == item.StockId).Qty;
|
outCount = zongNum / (decimal)packagInfo.L2Num; //托盘总件数
|
outCount2 = item.Qty / (decimal)packagInfo.L2Num; //要拣货件数
|
}
|
else //PDA拆垛
|
{
|
toLocation = outMode;//出库口
|
}
|
}
|
else
|
{
|
unstackingMode2 = "1";//非成品出库走PDA拆垛
|
toLocation = outMode;//出库口
|
}
|
#endregion
|
|
// 储位号
|
var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo;
|
|
#region 判断
|
|
decimal boxexQty = 0;//托盘上总数量
|
//判断托盘是否在库内
|
if (string.IsNullOrWhiteSpace(locateNo)) //库外
|
{
|
if (notice.Type == "0")
|
{
|
flagList.Add(5);
|
continue;
|
}
|
//判断托盘是否在入库中
|
var imBl = com.GetImTask(item.PalletNo);
|
if (imBl != null)
|
{
|
flagList.Add(4);
|
continue;
|
}
|
var de = outStockDetail.First(m => m.SkuNo == item.SkuNo && m.LotNo == item.LotNo && m.PalletNo == item.PalletNo);
|
if (de != null && de.WareHouseNo == "W02")
|
{
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.OutMode = outMode;//出库口
|
Db.Updateable(item).ExecuteCommand();
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
flagList.Add(0);
|
continue;
|
}
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
//如果不在仓库内,当前分配信息直接更新出库完成
|
item.Status = "2";//状态
|
item.OutMode = outMode;//出库口
|
Db.Updateable(item).ExecuteCommand();
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
flagList.Add(0);
|
continue;
|
}
|
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
|
if (locate == null)
|
{
|
flagList.Add(2);
|
continue;
|
}
|
//判断储位标志是否为损坏
|
if (locate.Flag == "2")
|
{
|
flagList.Add(3);
|
continue;
|
}
|
|
#endregion
|
|
if (locate.Status == "1") //有物品
|
{
|
#region 添加出库任务
|
if (locate.Depth == "01") //深度为1
|
{
|
var taskNo = new Common().GetMaxNo("TK");
|
var exTask = new LogTask //出库任务
|
{
|
TaskNo = taskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = toLocation,//outMode,//目标位置
|
PalletNo = item.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = "从" + locate.LocatNo + "到" + toLocation + "的出库任务", //关键信息
|
};
|
Db.Insertable(exTask).ExecuteCommand();
|
logTaskList.Add(exTask);
|
|
outDto1.Add(new OutCommandDto()
|
{
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,//其实巷道
|
EndLocate = toLocation,//outMode, // 目标位置
|
TaskNo = exTask.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)0入 1出 2移
|
OutMode = toLocation, //出库口
|
Order = 1,
|
|
});
|
taskNoStr = exTask.TaskNo;
|
}
|
else if (locate.Depth == "02") //深度为2
|
{
|
//获取出库深度为2储位前面的储位信息
|
var slotBefore = com.GetLocateNoDepth1(locate.WareHouseNo, locate.LocatNo);
|
if (slotBefore.Status == "1") //前面的储位有货物、进行移库操作
|
{
|
//要出库深度为2的储位前面的储位中货物是否要出库
|
var isout = outStockDetail.Count(m => m.LocatNo == slotBefore.LocatNo);
|
|
if (isout <= 0) //进行移库
|
{
|
//去库存表中找到储位对应的托盘码操作
|
var stockNew = Db.Queryable<DataStockDetail>().First(m => m.LocatNo == slotBefore.LocatNo);
|
if (stockNew == null)
|
{
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == slotBefore.LocatNo);
|
slotChange.Status = "0";
|
Db.Updateable(slotChange).ExecuteCommand();
|
}
|
else
|
{
|
//获取移库的库位
|
var newSlot = com.MoveAddress(slotBefore.LocatNo, slotBefore.RoadwayNo, item.SkuNo);
|
//当前移库库位的储位信息
|
var locatey = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == newSlot && m.IsDel == "0");
|
if (!string.IsNullOrEmpty(newSlot))
|
{
|
#region 添加出库时发生的移库任务
|
|
var exYkTaskNo = new Common().GetMaxNo("TK");
|
var exYkTask = new LogTask //出库时产生移库任务
|
{
|
TaskNo = exYkTaskNo,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = stockNew.LocatNo,//起始位置
|
EndLocat = newSlot,//目标位置
|
PalletNo = stockNew.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
|
Msg = stockNew.LocatNo + " ==>> " + newSlot + "的移库任务",
|
};
|
Db.Insertable(exYkTask).ExecuteCommand();
|
|
moveDto.Add(new OutCommandDto()
|
{
|
StartRoadway = slotBefore.RoadwayNo, //起始巷道
|
PalletNo = stockNew.PalletNo,//托盘号
|
StartLocate = stockNew.LocatNo, // 起始位置
|
EndLocate = newSlot, // 目标位置
|
EndRoadway = locatey.RoadwayNo, // 目标巷道
|
TaskNo = exYkTask.TaskNo, // 任务号
|
TaskType = "2",// 任务类型 (移库)
|
OutMode = "", //目标地址
|
Order = 1,
|
});
|
#endregion
|
|
#region 改变储位装填
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.Id == slotBefore.Id);
|
var slotChange2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == newSlot);
|
slotChange.Status = "5"; //改变状态(正在移出)
|
slotChange2.Status = "4"; // 改变状态(正在移入)
|
Db.Updateable(slotChange).ExecuteCommand();
|
Db.Updateable(slotChange2).ExecuteCommand();
|
#endregion
|
}
|
else
|
{
|
#region 添加出库任务
|
|
var exYkTaskNo1 = new Common().GetMaxNo("TK");
|
var exYkTask1 = new LogTask //出库移库没有库位了进行出库任务
|
{
|
TaskNo = exYkTaskNo1,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = stockNew.LocatNo,//起始位置
|
EndLocat = toLocation,//目标位置
|
PalletNo = stockNew.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = locate.LocatNo + "的出库任务"
|
};
|
Db.Insertable(exYkTask1).ExecuteCommand();
|
|
outDto1.Add(new OutCommandDto()
|
{
|
StartRoadway = slotBefore.RoadwayNo, //起始巷道
|
PalletNo = stockNew.PalletNo,//托盘号
|
StartLocate = stockNew.LocatNo, // 起始位置
|
EndLocate = toLocation, // 目标位置
|
EndRoadway = "", // 目标巷道
|
TaskNo = exYkTask1.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = toLocation, //目标地址
|
Order = 1,
|
|
|
});
|
#endregion
|
|
#region MyRegion
|
|
var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.Id == slotBefore.Id);
|
slotChange.Status = "3"; //改变状态(正在出库)
|
Db.Updateable(slotChange).ExecuteCommand();
|
|
#endregion
|
}
|
}
|
}
|
}
|
else if (slotBefore.Status == "2" || slotBefore.Status == "4") //前面储位状态是入库中或者移入中
|
{
|
flagList.Add(5);
|
continue;
|
}
|
|
#region 添加出库任务
|
|
var taskNo1 = new Common().GetMaxNo("TK");
|
var exTask1 = new LogTask //出库任务
|
{
|
TaskNo = taskNo1,
|
Sender = "WMS",
|
Receiver = "WCS",
|
IsSuccess = 0, //是否下发成功 0失败 1成功
|
|
StartLocat = locate.LocatNo,//起始位置
|
EndLocat = toLocation,//目标位置
|
PalletNo = item.PalletNo,//托盘码
|
IsSend = 1,//是否可再次下发
|
IsCancel = 1,//是否可取消
|
IsFinish = 1,//是否可完成
|
Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务
|
Status = "0",//任务状态0:等待执行1正在执行2执行完成
|
OrderType = "1",//0 入库单 1 出库单 2 盘点单 3 移库单
|
Msg = locate.LocatNo + "的出库任务"
|
};
|
Db.Insertable(exTask1).ExecuteCommand();
|
logTaskList.Add(exTask1);
|
outDto2.Add(new OutCommandDto()
|
{
|
StartRoadway = locate.RoadwayNo, //起始巷道
|
PalletNo = item.PalletNo,//托盘号
|
StartLocate = locate.LocatNo, // 起始位置
|
EndLocate = toLocation, // 目标位置
|
EndRoadway = locate.RoadwayNo, //目标巷道
|
TaskNo = exTask1.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = toLocation, //目标地址
|
Order = 1,
|
|
});
|
taskNoStr = exTask1.TaskNo;
|
#endregion
|
|
}
|
#endregion
|
|
#region 改变数据
|
if (item.Status == "0")//判断托盘是否下发过
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
locate.Status = "3"; //要出库的储位改变状态 正在出库
|
Db.Updateable(locate).ExecuteCommand();
|
|
item.TaskNo = taskNoStr; // 出库分配信息中更新任务号
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.UnstackingMode = unstackingMode2;//拆垛方式
|
item.OutMode = outMode ;//出库口
|
//item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口
|
Db.Updateable(item).ExecuteCommand();
|
|
#endregion
|
|
flagList.Add(0);
|
}
|
else if (locate.Status == "3") //出库中
|
{
|
#region 改变数据
|
//判断是否是已经出过库又回库(状态为待拣货的 1)
|
if (item.Status == "0")
|
{
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail != null) //更新出库单据的下发数量
|
{
|
noticeDetail.FactQty += item.Qty;
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
}
|
|
//var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
|
{
|
var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
|
if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
|
{
|
notice.Status = "3"; //变更状态为正在执行
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
var taskNo = Db.Queryable<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo);
|
if (taskNo == null)
|
{
|
taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库
|
}
|
if (taskNo == null)
|
{
|
throw new Exception($"托盘号:{item.PalletNo},出库异常");
|
}
|
item.TaskNo = taskNo.TaskNo;
|
item.Status = "1"; // 出库分配信息状态改为正在执行
|
item.OutMode = item.OutMode;//出库口
|
item.UnstackingMode = unstackingMode2 ;//拆垛模式
|
Db.Updateable(item).ExecuteCommand();
|
flagList.Add(0);
|
#endregion
|
}
|
else if (locate.Status == "5") //移出中
|
{
|
flagList.Add(1);
|
}
|
}
|
outDto1.AddRange(moveDto);
|
outDto1.AddRange(outDto2);
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击出库按钮出库单号为:{soNo}的出库单", userId);
|
Db.CommitTran();
|
|
str = string.Empty;
|
if (flagList.Count(m => m == 0) > 0)
|
{
|
str += "0.下发成功、";
|
}
|
if (flagList.Count(m => m == 1) > 0)
|
{
|
str += "1.当前要出库的储位正在移出、";
|
}
|
if (flagList.Count(m => m == 2) > 0)
|
{
|
str += "2.出库的托盘储位信息错误(在储位表中未查询到)、";
|
}
|
if (flagList.Count(m => m == 3) > 0)
|
{
|
str += "4.储位损坏不能出库、";
|
}
|
if (flagList.Count(m => m == 4) > 0)
|
{
|
str += "3.要出库的托盘正在入库、";
|
}
|
if (flagList.Count(m => m == 5) > 0)
|
{
|
str += "3.要出库的托盘正在拆托请稍后下发、";
|
}
|
if (outDto1.Count > 0)
|
{
|
// 正式运行程序放开
|
var list2 = outDto1.Select(m => m.TaskNo).ToList();
|
var jsonData = JsonConvert.SerializeObject(outDto1);
|
string response = "";
|
|
try
|
{
|
//var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
//response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
|
//var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
//////解析返回数据
|
//var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
|
//if (wcsModel.StatusCode == 0)
|
//{
|
// //更改任务的发送返回时间//
|
// new TaskServer().EditTaskIssueOk(list2, time1, time2);
|
// str += "下发成功";
|
//}
|
//if (wcsModel.StatusCode == -1)
|
//{
|
// new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
|
// throw new Exception(wcsModel.Msg);
|
//}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
|
}
|
|
return outDto1;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
|
|
#endregion
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
//重新下发出库任务
|
public OutCommandDto AgainSendSoTask(string taskNo, int userId, string url)
|
{
|
try
|
{
|
var task = Db.Queryable<LogTask>().First(m => m.TaskNo == taskNo && m.IsDel == "0");
|
if (task == null)
|
{
|
throw new Exception("未查询到任务信息");
|
}
|
var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.PalletNo == task.PalletNo);
|
if (stockDetail == null)
|
{
|
throw new Exception(task.PalletNo + " 当前托盘未在库内,请核实信息");
|
}
|
Db.BeginTran();
|
var locateNo = task.StartLocat;
|
//判断任务中起始位置是否和库存中位置一致
|
if (task.StartLocat != stockDetail.LocatNo)
|
{
|
locateNo = stockDetail.LocatNo;
|
task.StartLocat = locateNo;
|
Db.Updateable(task).ExecuteCommand();
|
}
|
var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo);
|
if (locate != null && locate.Status != "3")
|
{
|
locate.Status = "3";
|
Db.Updateable(locate).ExecuteCommand();
|
}
|
var outDto = new OutCommandDto()
|
{
|
PalletNo = task.PalletNo,//托盘号
|
StartLocate = locateNo, // 起始位置
|
StartRoadway = locate.RoadwayNo,
|
EndLocate = task.EndLocat, // 目标位置
|
TaskNo = task.TaskNo, // 任务号
|
TaskType = "1",// 任务类型 (出库)
|
OutMode = "", //目标地址
|
Order = 1
|
}; //出库数据
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "下发", $"点击下发按钮、重新下发了任务号为:{taskNo}的任务", (int)userId);
|
Db.CommitTran();
|
// 正式运行程序放开
|
var list = new List<string> { outDto.TaskNo };
|
var jsonData = JsonConvert.SerializeObject(outDto);
|
|
try
|
{
|
//程序正式发布后放开
|
var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
var response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
|
var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
|
|
////解析返回数据
|
var wcsModel = JsonConvert.DeserializeObject<WcsModel2>(response);
|
if (wcsModel.code == 200)
|
{
|
//更改任务的发送返回时间//
|
new TaskServer().EditTaskIssueOk(list, time1, time2);
|
|
}
|
else
|
{
|
new TaskServer().EditTaskIssueNo(list, time1, time2, wcsModel.message);
|
throw new Exception($"wcs返回状态异常:{wcsModel.message}");
|
}
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
return outDto;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
|
//取消出库任务
|
public void CancelSoTask(string taskNo, int userId)
|
{
|
try
|
{
|
Db.BeginTran();
|
try
|
{
|
var task = Db.Queryable<LogTask>().First(m => m.TaskNo == taskNo && m.IsDel == "0");
|
if (task == null)
|
{
|
throw new Exception("未查询到任务信息");
|
}
|
//获取对应库位信息
|
var startlocat = Db.Queryable<SysStorageLocat>().First(a => a.IsDel == "0" && a.WareHouseNo == "W01" && a.LocatNo == task.StartLocat);
|
if (startlocat == null)
|
{
|
throw new Exception("未查询到储位信息");
|
}
|
startlocat.Status = "0";//修改分配信息状态
|
//获取储位信息
|
var locat = Db.Queryable<SysStorageLocat>().First(a => a.IsDel == "0" && a.WareHouseNo == "W01" && a.LocatNo == task.StartLocat);
|
//获取移库任d务对应目标储位信息
|
SysStorageLocat endlocat = new SysStorageLocat();
|
if (task.Type == "2")
|
{
|
endlocat = Db.Queryable<SysStorageLocat>().First(a => a.IsDel == "0" && a.WareHouseNo == "W01" && a.LocatNo == task.EndLocat);
|
if (endlocat == null)
|
{
|
throw new Exception("未查询到目标储位信息");
|
}
|
}
|
if (locat == null)
|
{
|
Db.RollbackTran();
|
throw new Exception("未查询到储位信息,请核实!");
|
}
|
locat.Status = "1"; //有物品
|
Db.Updateable(locat).ExecuteCommand();
|
if (endlocat != null)
|
{
|
endlocat.Status = "0"; //空储位 0
|
Db.Updateable(endlocat).ExecuteCommand();
|
}
|
|
//修改任务
|
task.IsSuccess = 1;
|
task.IsSend = 0;
|
task.IsCancel = 0;
|
task.IsFinish = 0;
|
task.Status = "4";
|
task.CancelDate = DateTime.Now;
|
Db.Updateable(task).ExecuteCommand();
|
|
//出库分配信息
|
var allot = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.TaskNo == taskNo).ToList();
|
foreach (var item in allot)
|
{
|
item.Status = "0";//修改分配信息状态
|
item.TaskNo = "";
|
var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
|
if (noticeDetail == null)
|
{
|
throw new Exception("未查询到出库单明细信息");
|
}
|
|
noticeDetail.FactQty -= item.Qty; //修改出库单明细的下架数量
|
Db.Updateable(noticeDetail).ExecuteCommand();
|
|
if (noticeDetail.FactQty == 0)
|
{
|
var noticeDetail2 = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo && m.Id != noticeDetail.Id).ToList();
|
var num = noticeDetail2.Count(m => m.FactQty > 0);
|
//判断出库单的所有明细是否都为0;如果为0变更出库单状态为已分配
|
if (num == 0)
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
|
notice.Status = "2";
|
Db.Updateable(notice).ExecuteCommand();
|
}
|
}
|
}
|
//判断是否存在分配信息
|
if (allot == null)
|
{
|
//获取库存明细
|
var stockDetail = Db.Queryable<DataStockDetail>().First(a => a.IsDel == "0" && a.PalletNo == task.PalletNo);
|
//获取库存
|
var datastock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo);
|
//获取储位信息
|
var locate = Db.Queryable<SysStorageLocat>().First(a => a.IsDel == "0" && a.WareHouseNo == "W01" && a.LocatNo == stockDetail.LocatNo);
|
|
//判断是否为空托盘
|
if (stockDetail.SkuNo == "100099")
|
{
|
//修改库存明细
|
stockDetail.LockQty -= stockDetail.Qty; //锁定数量
|
stockDetail.Status = "0"; //库存状态 0:待分配
|
|
//修改库存总表
|
datastock.LockQty -= (int)stockDetail.Qty; //锁定数量
|
|
//修改储位状态
|
locate.Status = "1"; //储位状态 1:有物品
|
|
Db.Updateable(stockDetail).ExecuteCommand();
|
Db.Updateable(datastock).ExecuteCommand();
|
Db.Updateable(locate).ExecuteCommand();
|
}
|
else
|
{
|
//修改储位状态
|
locate.Status = "1"; //储位状态 1:有物品
|
Db.Updateable(locate).ExecuteCommand();
|
|
}
|
|
}
|
else
|
{
|
Db.Updateable(allot).ExecuteCommand();
|
}
|
|
//添加操作日志记录
|
var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库日志", taskNo, "取消", $"点击取消按钮、取消了任务号为:{taskNo}的任务", (int)userId);
|
Db.CommitTran();
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception(e.Message);
|
}
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
}
|
|
/// <summary>
|
/// 空取异常
|
/// </summary>
|
/// <param name="model">任务反馈信息</param>
|
/// <returns></returns>
|
public bool EmptyException(ReceiveWcsSignal model)
|
{
|
try
|
{
|
// 判断当前任务状态 Status 1:正在执行 3:异常结束
|
var taskModel = Db.Queryable<LogTask>().First(m => m.TaskNo == model.TaskNo && m.IsDel == "0" && m.Status == "1");
|
if (taskModel == null)
|
{
|
throw new Exception("此任务不存在或任务状态已变更!");
|
}
|
|
Db.BeginTran();
|
// 将当前任务状态变更异常结束
|
taskModel.Status = "3";
|
taskModel.Information = "空取异常";
|
taskModel.IsSend = 0;
|
taskModel.IsCancel = 0;
|
taskModel.IsFinish = 0;
|
taskModel.FinishDate = DateTime.Now;
|
Db.Updateable(taskModel).ExecuteCommand();
|
|
// 改变当前储位地址的储位标志变更为屏蔽
|
var locatModel = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == taskModel.StartLocat && m.IsDel == "0");
|
locatModel.Flag = "1";
|
Db.Updateable(locatModel).ExecuteCommand();
|
|
var allotModels = Db.Queryable<BllExportAllot>().Where(m => m.PalletNo == taskModel.PalletNo && (m.Status == "1" || m.Status == "0")).ToList();
|
// 循环处理应对同个托盘多个分配任务
|
foreach (BllExportAllot allotModel in allotModels)
|
{
|
// 出库明细表 状态修改为分配中 分配数量回滚
|
var noticeDetailModel = Db.Queryable<BllExportNoticeDetail>().First(m => m.Id == allotModel.SODetailNo && m.IsDel == "0");
|
noticeDetailModel.AllotQty = noticeDetailModel.AllotQty - allotModel.Qty;
|
if (allotModel.Status == "1")
|
{
|
noticeDetailModel.FactQty = noticeDetailModel.FactQty - allotModel.Qty;
|
}
|
noticeDetailModel.Status = "1";
|
Db.Updateable(noticeDetailModel).ExecuteCommand();
|
|
// 出库分配表 状态修改为异常取消
|
allotModel.Status = "6";
|
|
// 出库总表 状态改为部分分配
|
var noticeModel = Db.Queryable<BllExportNotice>().First(m => m.SONo == noticeDetailModel.SONo && m.IsDel == "0");
|
noticeModel.Status = "1";
|
Db.Updateable(noticeModel).ExecuteCommand();
|
|
// 库存明细表 状态修改为异常锁定 锁定数量修改为托盘上数量
|
|
var stockDetailModel = Db.Queryable<DataStockDetail>().First(m => m.Id == allotModel.StockId && m.IsDel == "0");
|
|
var lockQty = stockDetailModel.LockQty;
|
stockDetailModel.Status = "5";
|
stockDetailModel.LockQty = stockDetailModel.Qty;
|
Db.Updateable(stockDetailModel).ExecuteCommand();
|
|
// 库存总表 锁定数量=当前锁定数量 + (库存明细托盘上数量-库存明细托盘上已锁定的数量)
|
var stockModel = Db.Queryable<DataStock>().First(m => m.LotNo == stockDetailModel.LotNo && m.SkuNo == stockDetailModel.SkuNo && m.IsDel == "0");
|
stockModel.LockQty = stockModel.LockQty + (int)(stockDetailModel.Qty - lockQty);
|
Db.Updateable(stockModel).ExecuteCommand();
|
|
// 拣货明细表 删除
|
var completeDetailModels = Db.Queryable<BllCompleteDetail>().Where(m => m.ExportAllotId == allotModel.Id && m.IsDel == "0").ToList();
|
Db.Deleteable(completeDetailModels).ExecuteCommand();
|
|
// 插入异常处理表
|
string exceptionNo = new Common().GetMaxNo("EX");
|
var exceptionModel = new SysException()
|
{
|
ExceptionNo = exceptionNo,
|
Type = "0",
|
PalletNo = taskModel.PalletNo,
|
ExcLocatNo = taskModel.StartLocat,
|
OrderNo = noticeModel.SONo,
|
TaskNo = taskModel.TaskNo,
|
Status = "0",
|
Text = "", // 处理描述
|
CreateUser = 0
|
};
|
Db.Insertable(exceptionModel).ExecuteCommand();
|
}
|
|
Db.Updateable(allotModels).ExecuteCommand();
|
|
Db.CommitTran();
|
return true;
|
}
|
catch (Exception e)
|
{
|
Db.RollbackTran();
|
throw new Exception("程序错误:" + e.Message);
|
}
|
}
|
#endregion
|
|
|
|
/// <summary>
|
/// 判断出库是否需要拆箱
|
/// </summary>
|
/// <param name="soNo"></param>
|
/// <returns></returns>
|
public string IsNeedUnpack(string soNo)
|
{
|
string result = "0";//是否需要拆箱,0:否 1:是
|
if (string.IsNullOrEmpty(soNo))
|
{
|
throw new Exception("未找到对应出库单!");
|
}
|
try
|
{
|
var notice = Db.Queryable<BllExportNotice>().First(w => w.IsDel == "0" && w.SONo == soNo);
|
if (notice == null)
|
{
|
throw new Exception("未找到对应出库单!");
|
}
|
//物料编码表
|
var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
|
//包装表
|
var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
|
//出库分配信息
|
var allotList = Db.Queryable<BllExportAllot>().Where(w => w.IsDel == "0" && w.SONo == soNo).ToList();
|
foreach (var item in allotList)
|
{
|
var skuInfo = skuList.First(w => w.SkuNo == item.SkuNo);
|
if (skuInfo == null)
|
{
|
throw new Exception("物料信息不存在!");
|
}
|
var packagInfo = packagList.First(w => w.PackagNo == skuInfo.PackagNo);
|
if (packagInfo == null)
|
{
|
throw new Exception("包装信息不存在!");
|
}
|
if (packagInfo.L2Name == "箱")
|
{
|
if (item.Qty % (decimal)packagInfo.L2Num != 0)//能整除说明不用拆箱,不能整除说明需要拆箱
|
{
|
result = "1";//需要拆箱
|
break;
|
}
|
}
|
var boxInfo = Db.Queryable<DataBoxInfo>().Where(w => w.IsDel == "0" && w.PalletNo == item.PalletNo && w.BitBoxMark == "1").ToList();
|
if (boxInfo != null)//托盘上有零箱需要拆箱
|
{
|
result = "1";//需要拆箱
|
break;
|
}
|
}
|
return result;
|
}
|
catch (Exception ex)
|
{
|
throw new Exception(ex.Message);
|
}
|
}
|
|
|
#region 数据归档
|
/// <summary>
|
/// 查询出库单据 - 数据归档
|
/// </summary>
|
/// <param name="no"></param>
|
/// <param name="type"></param>
|
/// <param name="status"></param>
|
/// <param name="lotNo"></param>
|
/// <param name="logisticsId"></param>
|
/// <param name="isWave"></param>
|
/// <param name="isDespatch"></param>
|
/// <param name="waveNo"></param>
|
/// <param name="page"></param>
|
/// <param name="limit"></param>
|
/// <param name="count"></param>
|
/// <returns></returns>
|
public List<ExportNoticeDto> GetArchivingExportNoticeList(string no, string type, string status, string lotNo, int? logisticsId, string isWave, string isDespatch, string waveNo, int page, int limit, out int count)
|
{
|
string sqlString = string.Empty;
|
string sqlCount = string.Empty;
|
string sqlPub = string.Empty;
|
try
|
{
|
sqlCount += "SELECT DISTINCT COUNT(tb1.ID) FROM ArchivingExportNotice AS tb1 ";
|
|
sqlString += "SELECT DISTINCT tb1.Id,tb1.SONo,tb1.Type,tb1.Status,tb1.Origin,tb1.CustomerNo,tb1.CustomerName,tb1.LotNo, ";
|
sqlString += "tb1.LotText,tb1.SupplierLot,tb1.LogisticsId,tb2.CarrierName as LogisticsName,tb1.IsWave,tb1.WaveNo,";
|
sqlString += "tb1.IsDespatch,tb1.Demo,tb3.RealName as CreateUserName,tb4.RealName as UpdateUserName,tb1.CreateTime,tb1.UpdateTime,";
|
sqlString += "tb5.RealName as CheckUserName,tb1.CheckTime ";
|
sqlString += " FROM ArchivingExportNotice AS tb1 ";
|
|
sqlPub += "LEFT JOIN SysLogisticsInfo AS tb2 ON tb1.LogisticsId = tb2.Id ";
|
sqlPub += "LEFT JOIN SysUserInfor AS tb3 ON tb1.CreateUser = tb3.Id ";
|
sqlPub += "LEFT JOIN SysUserInfor AS tb4 ON tb1.UpdateUser = tb4.Id ";
|
sqlPub += "LEFT JOIN SysUserInfor AS tb5 ON tb1.CheckUser = tb5.Id ";
|
|
sqlPub += $"WHERE tb1.SONo LIKE '%{no}%' AND tb1.waveNo LIKE '%{waveNo}%' ";
|
sqlPub += $"AND tb1.SoNo in " +
|
$"(select DISTINCT SoNo from ArchivingExportNoticeDetail where isDel = '0' and lotNo like '%" + lotNo.Trim() + "%') ";
|
|
if (!string.IsNullOrWhiteSpace(type))
|
{
|
sqlPub += $"AND tb1.Type = '{type}' ";
|
}
|
if (!string.IsNullOrWhiteSpace(status))
|
{
|
sqlPub += $"AND tb1.Status = '{status}' ";
|
}
|
if (!string.IsNullOrWhiteSpace(isWave))
|
{
|
sqlPub += $"AND tb1.IsWave = '{isWave}' ";
|
}
|
if (!string.IsNullOrWhiteSpace(isDespatch))
|
{
|
sqlPub += $"AND tb1.IsDespatch = '{isDespatch}' ";
|
}
|
if (logisticsId != null)
|
{
|
sqlPub += $"AND tb1.LogisticsId = '{logisticsId}' ";
|
}
|
|
sqlCount += sqlPub + "AND tb1.IsDel = '0' ";
|
sqlPub += "AND tb1.IsDel = '0' order by tb1.SONo desc ";
|
|
|
if (page == 0)
|
{
|
page = 1;
|
}
|
sqlString += sqlPub + $" offset {((page - 1) * limit)} rows fetch next {limit} rows only;";
|
|
var com = new Common();
|
count = com.GetRowCount(sqlCount);
|
|
var modelList = Db.Ado.SqlQuery<ExportNoticeDto>(sqlString);
|
|
return modelList;
|
}
|
catch (Exception ex)
|
{
|
throw ex;
|
}
|
}
|
#endregion
|
}
|
}
|