using HH.WCS.Mobox3.pinggao.api;
|
using HH.WCS.Mobox3.pinggao.models.other;
|
using HH.WCS.Mobox3.pinggao.util;
|
using Newtonsoft.Json;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Reflection;
|
using System.Runtime.Remoting.Messaging;
|
using System.Security.Cryptography;
|
using System.Text;
|
using System.Threading.Tasks;
|
using static HH.WCS.Mobox3.pinggao.api.ApiModel;
|
using static HH.WCS.Mobox3.pinggao.api.OtherModel;
|
using static HH.WCS.Mobox3.pinggao.util.Settings;
|
|
namespace HH.WCS.Mobox3.pinggao.wms
|
{
|
/// <summary>
|
/// wms管到作业
|
/// </summary>
|
internal class WMSHelper
|
{
|
internal static string GenerateTaskNo()
|
{
|
var id = SYSHelper.GetSerialNumber("作业号", "OP");
|
var date = DateTime.Now.ToString("yyMMdd");
|
return $"OP{date}{id.ToString().PadLeft(4, '0')}";
|
}
|
internal static string GenerateCntrCodeNo()
|
{
|
var id = SYSHelper.GetSerialNumber("托盘号", "TP");
|
var date = DateTime.Now.ToString("yyMMdd");
|
return $"TP{date}{id.ToString().PadLeft(4, '0')}";
|
}
|
internal static string GenerateSortingNo()
|
{
|
var id = SYSHelper.GetSerialNumber("分拣单", "SO");
|
var date = DateTime.Now.ToString("yyMMdd");
|
return $"SO{date}{id.ToString().PadLeft(4, '0')}";
|
}
|
internal static string GenerateShippNo()
|
{
|
var id = SYSHelper.GetSerialNumber("出库单", "OU");
|
var date = DateTime.Now.ToString("yyMMdd");
|
return $"OU{date}{id.ToString().PadLeft(4, '0')}";
|
}
|
internal static string GenerateDistrbutionCntrNo()
|
{
|
var id = SYSHelper.GetSerialNumber("配盘号", "DC");
|
var date = DateTime.Now.ToString("yyMMdd");
|
return $"DC{date}{id.ToString().PadLeft(4, '0')}";
|
}
|
|
internal static List<WMSTask> GetOperationListByState(string state)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<WMSTask>().Where(a => a.S_B_STATE == state).ToList();
|
}
|
internal static List<WMSTask> GetOperationListByState(int state)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<WMSTask>().Where(a => a.N_B_STATE == state).ToList();
|
}
|
internal static List<WMSTask> GetWaitingOperationList()
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<WMSTask>().Where(a => a.N_B_STATE == 0 || a.N_B_STATE == 3).ToList();
|
}
|
internal static PutawayOrder GetPutawayOrder(string no)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<PutawayOrder>().Where(a => a.S_NO == no).First();
|
}
|
internal static bool CreatePutawayOrder(PutawayOrder model)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = db.Insertable<PutawayOrder>(model).ExecuteCommand() > 0;
|
db.Insertable<PutawayDetail>(model.Details).ExecuteCommand();
|
return result;
|
}
|
internal static TN_Inbound_Detail GetInboundOrderDetail(string no, string item_code)
|
{
|
try
|
{
|
|
var db = new SqlHelper<object>().GetInstance();
|
var inboud= db.Queryable<TN_Inbound_Detail>().Where(a => a.S_IO_NO == no && a.S_ITEM_CODE == item_code).First();
|
return inboud;
|
}
|
catch (Exception ex)
|
{
|
|
throw;
|
}
|
}
|
internal static void UpdateInboundOrderDetailQty(TN_Inbound_Detail model)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
db.Updateable(model).UpdateColumns(it => new { it.F_ACC_B_QTY }).ExecuteCommand();
|
}
|
internal static PutawayDetail GetPutawayOrderDetail(string no, string item_code)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<PutawayDetail>().Where(a => a.S_PUTAWAY_NO == no && a.S_ITEM_CODE == item_code).First();
|
}
|
internal static PutawayDetail GetPutawayOrderDetail(string item_code)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<PutawayDetail>().Where(a => a.S_ITEM_CODE == item_code && a.F_QTY - a.F_ACC_B_QTY > 0).OrderByDescending(a => a.T_CREATE).First();
|
}
|
|
internal static void UpdatePutawayOrderDetailQty(PutawayDetail model)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
db.Updateable(model).UpdateColumns(it => new { it.F_ACC_B_QTY }).ExecuteCommand();
|
}
|
|
|
internal static ShippingOrder GetShippingOrder(string no)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<ShippingOrder>().Includes(a => a.Details).Where(a => a.S_NO == no).First();
|
}
|
|
internal static TN_Outbound_Order GetOutboundOrder(string no)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<TN_Outbound_Order>().Includes(a => a.Details).Where(a => a.S_BS_NO == no).First();
|
}
|
internal static TN_Inbound_Order GetInboundOrder(string no)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<TN_Inbound_Order>().Includes(a => a.Details).Where(a => a.S_NO == no).First();
|
}
|
|
internal static TN_ASN_Order GetASNOrder(string no)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<TN_ASN_Order>().Includes(a => a.Details).Where(a => a.S_NO == no).First();
|
}
|
internal static bool CreateShippingOrder(ShippingOrder model)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = db.Insertable<ShippingOrder>(model).ExecuteCommand() > 0;
|
db.Insertable<ShippingDetail>(model.Details).ExecuteCommand();
|
return result;
|
}
|
|
internal static bool CreateOutboundOrder(TN_Outbound_Order model)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
try
|
{
|
db.BeginTran();
|
var result = db.Insertable<TN_Outbound_Order>(model).ExecuteCommand() > 0;
|
db.Insertable<TN_Outbound_Detail>(model.Details).ExecuteCommand();
|
db.CommitTran();
|
return result;
|
}
|
catch (Exception)
|
{
|
db.RollbackTran();
|
throw;
|
}
|
|
|
}
|
internal static bool CreateInboundOrder(TN_Inbound_Order model)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = db.Insertable<TN_Inbound_Order>(model).ExecuteCommand() > 0;
|
db.Insertable<TN_Inbound_Detail>(model.Details).ExecuteCommand();
|
return result;
|
}
|
|
internal static bool CreateASNOrder(TN_ASN_Order model)
|
{
|
LogHelper.Info($"子表长度{model.Details.Count} 数据{JsonConvert.SerializeObject(model.Details)}");
|
var db = new SqlHelper<object>().GetInstance();
|
var result = db.Insertable<TN_ASN_Order>(model).ExecuteCommand() > 0;
|
db.Insertable<TN_ASN_Detail>(model.Details).ExecuteCommand();
|
return result;
|
}
|
|
internal static bool CreateSortingOrder(List<string> list)
|
{
|
var res = false;
|
//遍历获取发货单,然后判断库存,如果全都没库存,则不生成分拣单,如果有生成分拣单
|
//更新波次单,即使只有一个发货单也更新波次单
|
var db = new SqlHelper<object>().GetInstance();
|
var sortingOrderNo = "";
|
SortingOrder sortingOrder = null;
|
try
|
{
|
db.BeginTran();
|
list.ForEach(a =>
|
{
|
var so = db.Queryable<ShippingOrder>().Includes(s => s.Details).Where(s => s.S_NO == a).First();
|
//判断库存,只有已经入库的才可以计算,码盘的不算,入库后出库途中的也要计算,码盘后默认叫待入库,入库后叫正常
|
//生成出库任务,只有托盘位置在立库才需要创建出库任务(先写死立库)
|
//只有全部分拣完成才允许回库(一个托盘可能对应多个分拣明细)
|
|
//查找仓库量表和库区量表,出库单需要定位仓库和库区了,出库定位物理库区就行,入库可能物料库区还要区分逻辑库区
|
|
//暂时只查仓库量表(量表如何重置,查找所有查找C_ENABLE=N的,判断如果在仓库中,改成Y,然后统计)
|
|
//生成分拣单时候增加仓库量表分配量,生成分拣单明细时候,增加库区量表分配量
|
if (so != null && so.Details.Count > 0)
|
{
|
var fail = true;
|
for (int i = 0; i < so.Details.Count; i++)
|
{
|
var whi = db.Queryable<WHInventory>().Where(w => w.S_ITEM_CODE == so.Details[i].S_ITEM_CODE).First();
|
if (whi != null && whi.F_QTY - whi.F_ALLOC_QTY > 0)
|
{
|
//有货就出
|
float qty = whi.F_QTY - whi.F_ALLOC_QTY > so.Details[i].F_QTY ? so.Details[i].F_QTY : whi.F_QTY - whi.F_ALLOC_QTY;
|
fail = false;
|
//有可用库存,生成分拣单
|
if (sortingOrderNo == "")
|
{
|
sortingOrderNo = GenerateSortingNo();
|
sortingOrder = new SortingOrder
|
{
|
S_NO = sortingOrderNo,
|
S_TYPE = so.S_BS_TYPE,
|
S_SHIPPING_NO = so.S_NO,
|
Composes = new List<SortingCompose>()
|
};
|
//创建分拣单
|
db.Insertable(sortingOrder).ExecuteCommand();
|
}
|
else
|
{
|
//获取最新分拣单
|
sortingOrder = db.Queryable<SortingOrder>().Includes(s => s.Composes).Where(s => s.S_NO == sortingOrderNo).First();
|
//更新分拣单中的发货单单号
|
//sortingOrder.S_SHIPPING_NO = sortingOrder.S_SHIPPING_NO + ";" + so.S_NO;
|
sortingOrder.T_MODIFY = DateTime.Now;
|
db.Updateable(sortingOrder).UpdateColumns(it => new { it.S_SHIPPING_NO, it.T_MODIFY }).ExecuteCommand();
|
}
|
|
Expression<Func<SortingCompose, bool>> expression = x => x.S_ITEM_CODE == so.Details[i].S_ITEM_CODE;
|
expression.AndAlso(x => x.S_SORTING_NO == sortingOrder.S_NO);
|
if (!string.IsNullOrEmpty(so.Details[i].S_BATCH_NO)) expression.AndAlso(x => x.S_BATCH_NO == so.Details[i].S_BATCH_NO);
|
if (!string.IsNullOrEmpty(so.Details[i].S_FAC_CODE)) expression.AndAlso(x => x.S_FAC_CODE == so.Details[i].S_FAC_CODE);
|
if (!string.IsNullOrEmpty(so.Details[i].S_ITEM_LOC)) expression.AndAlso(x => x.S_ITEM_LOC == so.Details[i].S_ITEM_LOC);
|
//查询分拣单子表(正常情况还需要增加批次判断)
|
var soc = db.Queryable<SortingCompose>()
|
.Where(expression)
|
.First();
|
if (soc == null)
|
{
|
soc = new SortingCompose
|
{
|
S_ITEM_CODE = so.Details[i].S_ITEM_CODE,
|
S_SORTING_NO = sortingOrder.S_NO,
|
F_QTY = qty,
|
N_ROW_NO = sortingOrder.Composes.Count() + 1,
|
S_BATCH_NO = so.Details[i].S_BATCH_NO,
|
S_FAC_CODE = so.Details[i].S_FAC_CODE,
|
S_ITEM_LOC = so.Details[i].S_ITEM_LOC
|
};
|
|
//创建分拣单子表
|
db.Insertable(soc).ExecuteCommand();
|
}
|
else
|
{
|
soc.F_QTY += qty;
|
soc.T_MODIFY = DateTime.Now;
|
//更新分拣单子表
|
db.Updateable(soc).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand();
|
}
|
//更新仓库量表分配量
|
//whi.F_ALLOC_QTY += qty;
|
//whi.T_MODIFY = DateTime.Now;
|
//db.Updateable(whi).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
//跟新发货单子表配货数量
|
so.Details[i].F_ACC_D_QTY += qty;
|
so.Details[i].T_MODIFY = DateTime.Now;
|
db.Updateable(so.Details[i]).UpdateColumns(it => new { it.F_ACC_D_QTY, it.T_MODIFY }).ExecuteCommand();
|
}
|
}
|
//更新发货单状态
|
so.N_B_STATE = fail ? 5 : 1;
|
if (fail)
|
{
|
so.S_NOTE = "没有库存";
|
}
|
so.S_WAVE_CODE = sortingOrderNo;
|
so.T_MODIFY = DateTime.Now;
|
db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY, it.S_WAVE_CODE, it.S_NOTE }).ExecuteCommand();
|
|
}
|
|
|
//查找库区内托盘生成托盘明细(包括分拣中)怎么判断库内?查找货位绑定?还是托盘上加标识比较好,如果是整托出的,分拣确认后去掉分拣标识。
|
//1、只有码盘入库后的才需要加标识,分拣回的不用,分拣回的标识还在,没有变。写死码盘入的完成后加标识,整托分拣的去掉标识,防止后面重新码盘脏数据
|
//2、或者关联查询库内的,只给分拣出的加标识,每次分拣回再把标识清除了(如果不清除带标识的会很多,还不如全部加标识),整托的清除。
|
//综合选择还是方案1,这样创建分拣明细,只需要托盘物料两表查询就能定位托盘(如果信息不准,可以重置),方案2需要货位、托盘、物料三表联查
|
|
//暂时不计库区,标识用容器表 C_ENABLE 来判断,表示能不能出库
|
|
//执行分拣创建任务,遍历分拣明细中的托盘,如果在仓库就出库,如果不在就不用出库
|
|
|
});
|
//全部分拣单生成之后将分拣单状态设置为开始配货,波次号为发货单
|
sortingOrder = db.Queryable<SortingOrder>().Where(s => s.S_NO == sortingOrderNo).First();
|
sortingOrder.N_B_STATE = 1;
|
sortingOrder.T_MODIFY = DateTime.Now;
|
db.Updateable(sortingOrder).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
db.CommitTran();
|
res = true;
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
db.RollbackTran();
|
}
|
return res;
|
|
}
|
|
internal static bool CreatOpenation(Location startLoc, Location endLoc, string trayNo, string Stype, int Ntype)
|
{
|
var res = false;
|
var db = new SqlHelper<object>().GetInstance();
|
var optask = new WMSTask
|
{
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_WH = startLoc.S_WH_CODE,
|
S_START_AREA = startLoc.S_AREA_CODE,
|
S_START_LOC = startLoc.S_CODE,
|
S_END_LOC = endLoc.S_CODE,
|
S_END_AREA = endLoc.S_AREA_CODE,
|
S_END_WH = endLoc.S_WH_CODE,
|
S_TYPE = GetType(Ntype),
|
N_TYPE = Ntype,
|
N_B_STATE = 0,
|
S_CNTR_CODE = trayNo,
|
S_OP_DEF_NAME = Stype
|
};
|
res = db.Insertable(optask).ExecuteCommand() > 0;
|
if (res)
|
{
|
LocationHelper.LockLoc(startLoc.S_CODE, 2);
|
LocationHelper.LockLoc(endLoc.S_CODE, 1);
|
}
|
return res;
|
}
|
|
private static string GetType(int ntype)
|
{
|
string result = "";
|
|
switch (ntype)
|
{
|
case 1: result = "入库"; break;
|
case 2: result = "出库"; break;
|
case 3: result = "转运"; break;
|
}
|
|
return result;
|
}
|
|
internal static void OnShelves(WCSTask task, int action)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var s_action = "";
|
if (action == 1)
|
{
|
s_action = "上架";
|
}
|
else
|
{
|
s_action = "下架";
|
}
|
try
|
{
|
var itemlist = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).ToList();
|
if (itemlist.Count > 0)
|
{
|
foreach (var item in itemlist)
|
{
|
var info = new TN_OnOff_Shelves
|
{
|
S_NO = task.S_OP_CODE,
|
N_ACTION = action,
|
S_ACTION = s_action,
|
S_ITEM_CODE = item.S_ITEM_CODE,
|
S_ITEM_NAME = item.S_ITEM_NAME,
|
S_LOC_CODE = task.S_END_LOC,
|
S_AREA_CODE = task.S_END_AREA,
|
S_CNTR_CODE = task.S_CNTR_CODE,
|
S_BATCH_NO = item.S_BATCH_NO,
|
S_SERIAL_NO = item.S_SERIAL_NO,
|
//D_PRD_DATE = item.D_PRD_DATE,
|
F_QTY = item.F_QTY
|
};
|
db.Insertable(info).ExecuteCommand();
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"上架记录添加异常 异常信息={ex.Message}", ex);
|
}
|
}
|
|
internal static void AddChange(WCSTask task)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
db.Updateable<Container>().SetColumns(it => new Container { C_ENABLE = "Y" }).Where(it => it.S_CODE == task.S_CNTR_CODE).ExecuteCommand();
|
var result = true;
|
try
|
{
|
var itemlist = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).ToList();
|
if (itemlist.Count > 0)
|
{
|
var url = Settings.MoboxSeverUrl + "inventory/AddChange";
|
//仓库量表升量
|
var req = new AddChangeModel { op_type = 5 };
|
//库区量表升量
|
var req2 = new AddChangeModel { op_type = 6 };
|
itemlist.ForEach(a =>
|
{
|
LogHelper.Info($"填充数据");
|
LogHelper.Info($"添加仓库量表数据 仓库{task.S_END_WH} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = task.S_END_WH,
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
LogHelper.Info($"添加库区量表数据 库区{task.S_END_AREA} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req2.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = task.S_END_WH,
|
area_code = task.S_END_AREA,
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
});
|
var reqData = JsonConvert.SerializeObject(req);
|
var AppKey = Settings.AppKey;
|
var AppSecret = Settings.AppSecret;
|
var ReqTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime}");
|
var ReqVerify = GetMd5FromString(AppKey + AppSecret + ReqTime);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime} ReqVerify={ReqVerify} url={url} req={reqData}");
|
var res = new HttpHelper().WebPost(url, reqData, "application/json", AppKey, ReqTime, ReqVerify);
|
if (!string.IsNullOrEmpty(res))
|
{
|
LogHelper.Info($"mobox 仓库升量接口返回 {res}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 仓库升量接口返回为空");
|
result = false;
|
}
|
var reqData2 = JsonConvert.SerializeObject(req2);
|
var ReqTime2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime2 = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2}");
|
var ReqVerify2 = GetMd5FromString(AppKey + AppSecret + ReqTime2);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2} ReqVerify={ReqVerify2} url={url} req={reqData2}");
|
var res2 = new HttpHelper().WebPost(url, reqData2, "application/json", AppKey, ReqTime2, ReqVerify2);
|
if (!string.IsNullOrEmpty(res2))
|
{
|
LogHelper.Info($"mobox 库区升量接口返回 {res2}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 库区升量接口返回为空");
|
result = false;
|
}
|
if (result) OnShelves(task, 1);
|
|
}
|
else LogHelper.Info($"托盘{task.S_CNTR_CODE} 在容器货品明细中找不到数据");
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"仓库升量异常 异常信息={ex.Message}", ex);
|
}
|
}
|
|
/// <summary>
|
/// 起始仓库 库区 升量
|
/// </summary>
|
/// <param name="task"></param>
|
internal static void AddChangeStart(WCSTask task)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = true;
|
try
|
{
|
var itemlist = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).ToList();
|
if (itemlist.Count > 0)
|
{
|
var url = Settings.MoboxSeverUrl + "inventory/AddChange";
|
//仓库量表升量
|
var req = new AddChangeModel { op_type = 5 };
|
//库区量表升量
|
var req2 = new AddChangeModel { op_type = 6 };
|
itemlist.ForEach(a =>
|
{
|
LogHelper.Info($"填充数据");
|
LogHelper.Info($"添加仓库量表数据 仓库{task.S_END_WH} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = task.S_END_WH,
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
LogHelper.Info($"添加库区量表数据 库区{task.S_END_AREA} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req2.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = task.S_END_WH,
|
area_code = task.S_END_AREA,
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
});
|
var reqData = JsonConvert.SerializeObject(req);
|
var AppKey = Settings.AppKey;
|
var AppSecret = Settings.AppSecret;
|
var ReqTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime}");
|
var ReqVerify = GetMd5FromString(AppKey + AppSecret + ReqTime);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime} ReqVerify={ReqVerify} url={url} req={reqData}");
|
var res = new HttpHelper().WebPost(url, reqData, "application/json", AppKey, ReqTime, ReqVerify);
|
if (!string.IsNullOrEmpty(res))
|
{
|
LogHelper.Info($"mobox 仓库升量接口返回 {res}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 仓库升量接口返回为空");
|
result = false;
|
}
|
var reqData2 = JsonConvert.SerializeObject(req2);
|
var ReqTime2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime2 = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2}");
|
var ReqVerify2 = GetMd5FromString(AppKey + AppSecret + ReqTime2);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2} ReqVerify={ReqVerify2} url={url} req={reqData2}");
|
var res2 = new HttpHelper().WebPost(url, reqData2, "application/json", AppKey, ReqTime2, ReqVerify2);
|
if (!string.IsNullOrEmpty(res2))
|
{
|
LogHelper.Info($"mobox 库区升量接口返回 {res2}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 库区升量接口返回为空");
|
result = false;
|
}
|
if (result) OnShelves(task, 1);
|
|
}
|
else LogHelper.Info($"托盘{task.S_CNTR_CODE} 在容器货品明细中找不到数据");
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"仓库升量异常 异常信息={ex.Message}", ex);
|
}
|
}
|
|
|
internal static void DeleteChange(WCSTask task)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = true;
|
try
|
{
|
var wmstask = db.Queryable<WMSTask>().Where(a => a.S_CODE == task.S_OP_CODE).First();
|
if (wmstask != null)
|
{
|
var itemlist = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).ToList();
|
if (itemlist.Count > 0)
|
{
|
var url = Settings.MoboxSeverUrl + "inventory/AddChange";
|
//仓库量表升量
|
var req = new AddChangeModel { op_type = 4 };
|
//库区量表升量
|
var req2 = new AddChangeModel { op_type = 7 };
|
itemlist.ForEach(a =>
|
{
|
LogHelper.Info($"填充数据");
|
LogHelper.Info($"减仓库量表数据 仓库{task.S_END_WH} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = wmstask.S_START_WH,
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
LogHelper.Info($"减库区量表数据 库区{task.S_END_AREA} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req2.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = wmstask.S_START_WH,
|
area_code = wmstask.S_START_AREA,
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
});
|
var reqData = JsonConvert.SerializeObject(req);
|
var AppKey = Settings.AppKey;
|
var AppSecret = Settings.AppSecret;
|
var ReqTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime}");
|
var ReqVerify = GetMd5FromString(AppKey + AppSecret + ReqTime);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime} ReqVerify={ReqVerify} url={url} req={reqData}");
|
var res = new HttpHelper().WebPost(url, reqData, "application/json", AppKey, ReqTime, ReqVerify);
|
if (!string.IsNullOrEmpty(res))
|
{
|
LogHelper.Info($"mobox 仓库降量接口返回 {res}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 仓库降量接口返回为空");
|
result = false;
|
}
|
var reqData2 = JsonConvert.SerializeObject(req2);
|
var ReqTime2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime2 = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2}");
|
var ReqVerify2 = GetMd5FromString(AppKey + AppSecret + ReqTime2);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2} ReqVerify={ReqVerify2} url={url} req={reqData2}");
|
var res2 = new HttpHelper().WebPost(url, reqData2, "application/json", AppKey, ReqTime2, ReqVerify2);
|
if (!string.IsNullOrEmpty(res2))
|
{
|
LogHelper.Info($"mobox 库区降量接口返回 {res2}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 库区降量接口返回为空");
|
result = false;
|
}
|
if (result) OnShelves(task, 2);
|
|
}
|
else LogHelper.Info($"托盘{task.S_CNTR_CODE} 在容器货品明细中找不到数据");
|
}
|
else LogHelper.Info($"未找到任务{task.S_CODE} 对应的作业");
|
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"仓库江量异常 异常信息={ex.Message}", ex);
|
}
|
}
|
internal static void QsDeleteChange(WCSTask task)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = true;
|
try
|
{
|
var wmstask = db.Queryable<WMSTask>().Where(a => a.S_CODE == task.S_OP_CODE).First();
|
if (wmstask != null)
|
{
|
var itemlist = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).ToList();
|
if (itemlist.Count > 0)
|
{
|
var url = Settings.MoboxSeverUrl + "inventory/AddChange";
|
//仓库量表升量
|
var req = new AddChangeModel { op_type = 4 };
|
//库区量表升量
|
var req2 = new AddChangeModel { op_type = 7 };
|
itemlist.ForEach(a =>
|
{
|
LogHelper.Info($"填充数据");
|
LogHelper.Info($"减仓库量表数据 仓库{task.S_END_WH} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = "cangku",
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
LogHelper.Info($"减库区量表数据 库区{task.S_END_AREA} 物料编码{a.S_ITEM_CODE} 物料名称{a.S_ITEM_NAME} 数量{a.F_QTY}");
|
req2.item_info.Add(new AddChangeModel.itemModel
|
{
|
wh_code = "cangku",
|
area_code = "kuqu",
|
item_code = a.S_ITEM_CODE,
|
item_name = a.S_ITEM_NAME,
|
qty = a.F_QTY
|
});
|
});
|
var reqData = JsonConvert.SerializeObject(req);
|
var AppKey = Settings.AppKey;
|
var AppSecret = Settings.AppSecret;
|
var ReqTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime}");
|
var ReqVerify = GetMd5FromString(AppKey + AppSecret + ReqTime);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime} ReqVerify={ReqVerify} url={url} req={reqData}");
|
var res = new HttpHelper().WebPost(url, reqData, "application/json", AppKey, ReqTime, ReqVerify);
|
if (!string.IsNullOrEmpty(res))
|
{
|
LogHelper.Info($"mobox 仓库降量接口返回 {res}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 仓库降量接口返回为空");
|
result = false;
|
}
|
var reqData2 = JsonConvert.SerializeObject(req2);
|
var ReqTime2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
//var ReqTime2 = GetTimeStamp(DateTime.Now.AddHours(-8), 1, 2);
|
LogHelper.Info($"加密前 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2}");
|
var ReqVerify2 = GetMd5FromString(AppKey + AppSecret + ReqTime2);
|
LogHelper.Info($"加密后 AppKey={AppKey} AppSecret={AppSecret} ReqTime={ReqTime2} ReqVerify={ReqVerify2} url={url} req={reqData2}");
|
var res2 = new HttpHelper().WebPost(url, reqData2, "application/json", AppKey, ReqTime2, ReqVerify2);
|
if (!string.IsNullOrEmpty(res2))
|
{
|
LogHelper.Info($"mobox 库区降量接口返回 {res2}");
|
var moboxres = JsonConvert.DeserializeObject<moboxres>(res);
|
if (moboxres.err_code != 0)
|
{
|
result = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"mobox 库区降量接口返回为空");
|
result = false;
|
}
|
if (result) OnShelves(task, 2);
|
|
}
|
else LogHelper.Info($"托盘{task.S_CNTR_CODE} 在容器货品明细中找不到数据");
|
}
|
else LogHelper.Info($"未找到任务{task.S_CODE} 对应的作业");
|
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"仓库江量异常 异常信息={ex.Message}", ex);
|
}
|
}
|
public class moboxres
|
{
|
public int err_code { get; set; }
|
public string err_msg { get; set; } = "";
|
}
|
|
|
/// <summary>
|
/// 任务信息接口--获取时间戳
|
/// </summary>
|
/// <param name="DataBitType">数据位数:值:32|64 含义:32位|64位</param>
|
/// <param name="TimeType">获取时间类型:值:1|2 含义:1-秒级 2-毫秒级</param>
|
/// <param name="TimeUtcType">获取时间Utc类型:值:1|2 含义:1-本地时间 2-Utc时间</param>
|
/// <returns></returns>
|
public static string GetTimeStamp(DateTime dateTime, int DataBitType, int TimeType)
|
{
|
string timeStamp = "";
|
|
//时间戳打印
|
TimeSpan ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0);//时间戳获取
|
double tsTime = TimeType == 1 ? ts.TotalSeconds : ts.TotalMilliseconds;//秒级|毫秒级时间获取
|
|
string TimeTypeInfo = TimeType == 1 ? "秒级" : "毫秒级";
|
timeStamp = DataBitType == 32 ? Convert.ToInt32(tsTime).ToString() : Convert.ToInt64(tsTime).ToString();
|
|
//double result = 0;
|
//result = DataBitType == 32 ? Convert.ToInt32(tsTime) : Convert.ToInt64(tsTime);
|
|
return timeStamp;
|
}
|
|
/// <summary>
|
/// MD5加密
|
/// </summary>
|
/// <param name="sInput"></param>
|
/// <returns></returns>
|
public static string GetMd5FromString(string sInput)
|
{
|
var lstData = Encoding.GetEncoding("utf-8").GetBytes(sInput);
|
var lstHash = new MD5CryptoServiceProvider().ComputeHash(lstData);
|
var result = new StringBuilder(32);
|
for (int i = 0; i < lstHash.Length; i++)
|
{
|
result.Append(lstHash[i].ToString("x2").ToUpper());
|
}
|
return result.ToString();
|
}
|
|
public class AddChangeModel
|
{
|
/// <summary>
|
/// 5 - 仓库加存储量,用于 入库完成
|
/// 6 - 库区加存储量,用于库区入库完成,
|
/// 7 - 库区减存储、分配量,用于 库区出库完成
|
/// 8 - 仓库减存储量,9 - 库区减存储量
|
/// 10 - 仓库减分配量,用于 配货后取消,
|
/// 11 - 库区减分配量,用于 配货后取消
|
/// </summary>
|
public int op_type { get; set; }
|
public List<itemModel> item_info { get; set; } = new List<itemModel>();
|
public class itemModel
|
{
|
public string wh_code { get; set; } = "";
|
public string area_code { get; set; } = "";
|
public string loc_code { get; set; } = "";
|
public string item_code { get; set; }
|
public string item_name { get; set; }
|
public float qty { get; set; }
|
}
|
}
|
|
|
internal static void End(WCSTask task)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var wmsTask = db.Queryable<WMSTask>().Where(a => a.S_CODE == task.S_OP_CODE).First();
|
|
//修改作业状态 重新启动
|
wmsTask.N_B_STATE = 2;
|
WMSHelper.UpdateTaskState(wmsTask);
|
WCSHelper.UpdateStorStatus(task.S_CNTR_CODE, 4);
|
}
|
|
internal static void EndTn(string S_CNTR_CODE)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var item = db.Queryable<TN_Distribution_CNTR>().Where(a => a.S_CNTR_CODE == S_CNTR_CODE).First();
|
|
//修改作业状态 重新启动
|
item.N_B_STATE = 2;
|
item.S_B_STATE = "作业完成";
|
db.Updateable(item).UpdateColumns(it => new { it.S_B_STATE, it.N_B_STATE }).ExecuteCommand();
|
}
|
|
|
|
|
internal static List<SortingDetail> GetSortingDetailByCntr(string cntr)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var result = db.Queryable<SortingDetail>().Where(a => a.S_CNTR_CODE == cntr && a.N_B_STATE == 1).ToList();
|
return result;
|
}
|
|
internal static bool CreateWmsTask(WMSTask wmsTask)
|
{
|
try
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Insertable<WMSTask>(wmsTask).ExecuteCommand() > 0;
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
throw;
|
}
|
}
|
|
public static bool CreateOpTask(string startLoc, string endLoc, string sType, string taskType, string trayCode)
|
{
|
bool result = false;
|
int nType = sType == "入库" ? 1 : 2;
|
var wmsTask = new WMSTask
|
{
|
S_CNTR_CODE = trayCode,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = startLoc,
|
S_END_LOC = endLoc,
|
N_TYPE = nType,
|
S_TYPE = sType,
|
S_OP_DEF_CODE = "",
|
S_OP_DEF_NAME = taskType
|
};
|
result = WMSHelper.CreateWmsTask(wmsTask);
|
if (result)
|
{
|
LocationHelper.LockLoc(startLoc, 2);
|
LocationHelper.LockLoc(endLoc, 1);
|
LogHelper.Info($"创建作业成功,作业号{wmsTask.S_CODE}");
|
}
|
|
return result;
|
}
|
|
internal static WMSTask GetWmsTaskByCntr(string cntr, bool active = true)
|
{
|
WMSTask result = null;
|
var db = new SqlHelper<object>().GetInstance();
|
if (active)
|
{
|
result = db.Queryable<WMSTask>().Where(a => a.S_CNTR_CODE.Contains(cntr) && a.N_B_STATE < 2).First();
|
}
|
else
|
{
|
result = db.Queryable<WMSTask>().Where(a => a.S_CNTR_CODE.Contains(cntr)).First();
|
}
|
return result;
|
}
|
|
internal static Location GetEnd(WMSTask a)
|
{
|
LogHelper.Info($"作业{a.S_CODE} 获取终点");
|
Location result = null;
|
//try
|
//{
|
var db = new SqlHelper<object>().GetInstance();
|
var start = db.Queryable<Location>().Where(it => it.S_CODE == a.S_START_LOC).First();
|
if (!string.IsNullOrEmpty(a.S_END_LOC))
|
{
|
LogHelper.Info($"作业终点有值 上锁");
|
result = db.Queryable<Location>().Where(it => it.S_CODE == a.S_END_LOC).First();
|
//这里可以作为提前上锁
|
//检查货位是否上过锁了 是否需要重新上锁
|
LocationHelper.LockLoc(a.S_END_LOC, 1);
|
}
|
else
|
{
|
//终点为空 选取终点库内位置
|
if (a.N_TYPE == 2)
|
{
|
LogHelper.Info($"作业终点不为接驳位 查找库区{a.S_END_AREA} 可用货位");
|
//其他库区
|
var endlist = db.Queryable<Location>()
|
.Where(it => it.S_AREA_CODE == a.S_END_AREA && it.N_CURRENT_NUM < it.N_CAPACITY)
|
.OrderBy(it => it.N_COL)
|
.PartitionBy(it => it.N_ROW)
|
.Take(1)
|
.ToList();
|
LogHelper.Info($"符合条件的数量{endlist.Count}");
|
foreach (var item in endlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(it => it.N_LOCK_STATE != 0 && it.S_AREA_CODE == item.S_AREA_CODE && it.N_ROW == item.N_ROW).First();
|
if (lockinfo == null)
|
{
|
result = item;
|
a.S_END_LOC = item.S_CODE;
|
break;
|
}
|
else LogHelper.Info($"货位{lockinfo.S_CODE} 有锁 当前排不可使用");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"入库任务 终点不为立库");
|
//终点不为立库的任务
|
//其他库区
|
var endlist = db.Queryable<Location>()
|
.Where(it => it.S_AREA_CODE == a.S_END_AREA && it.N_CURRENT_NUM < it.N_CAPACITY)
|
.OrderBy(it => it.N_COL)
|
.PartitionBy(it => it.N_ROW)
|
.Take(1)
|
.ToList();
|
foreach (var item in endlist)
|
{
|
var lockinfo = db.Queryable<Location>().Where(it => it.N_LOCK_STATE != 0 && it.S_AREA_CODE == item.S_AREA_CODE && it.N_ROW == item.N_ROW).First();
|
if (lockinfo == null)
|
{
|
result = item;
|
a.S_END_LOC = result.S_CODE;
|
break;
|
}
|
}
|
}
|
}
|
|
return result;
|
}
|
|
internal static Location GetStart(WMSTask a)
|
{
|
throw new NotImplementedException();
|
}
|
|
internal static void UpdateTaskState(WMSTask task)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
task.T_MODIFY = DateTime.Now;
|
task.S_B_STATE = WMSTask.GetStateStr(task.N_B_STATE);
|
db.Updateable<WMSTask>(task).UpdateColumns(a => new { a.N_B_STATE, a.S_B_STATE, a.T_MODIFY }).ExecuteCommand();
|
}
|
|
internal static bool UpdateTaskEnd(WMSTask a)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
a.T_MODIFY = DateTime.Now;
|
return db.Updateable<WMSTask>(a).UpdateColumns(it => new { it.S_END_LOC, it.T_MODIFY }).ExecuteCommand() > 0;
|
}
|
|
internal static WMSTask GetWmsTask(string code)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<WMSTask>().Where(a => a.S_CODE == code).First();
|
}
|
|
internal static void CreateSortingOrderDetail(string so_no)
|
{
|
//分拣单配货
|
var db = new SqlHelper<object>().GetInstance();
|
var so = db.Queryable<SortingOrder>().Includes(a => a.Composes).Where(a => a.S_NO == so_no && (a.N_B_STATE == 1 || a.N_B_STATE == 20)).First();//
|
if (so != null && so.Composes.Count > 0)
|
{
|
db.BeginTran();
|
try
|
{
|
int rowNo = 1;
|
so.Composes.ForEach(a =>
|
{
|
Expression<Func<CntrItemRel, bool>> expression = x => x.S_ITEM_CODE == a.S_ITEM_CODE;
|
expression.AndAlso(x => x.Cntr.C_ENABLE == "Y");
|
expression.AndAlso(x => (x.F_QTY - x.F_ALLOC_QTY) > (a.F_QTY - a.F_ACC_S_QTY));
|
expression.AndAlso(x => (x.F_QTY - x.F_ALLOC_QTY) / 2 < (a.F_QTY - a.F_ACC_S_QTY));
|
if (!string.IsNullOrEmpty(a.S_BATCH_NO)) expression.AndAlso(x => x.S_BATCH_NO == a.S_BATCH_NO);
|
if (!string.IsNullOrEmpty(a.S_FAC_CODE)) expression.AndAlso(x => x.S_OWNER == a.S_FAC_CODE);
|
//if (!string.IsNullOrEmpty(a.S_ITEM_LOC)) expression.AndAlso(x => x.S_ERP_WH_CODE == a.S_ITEM_LOC);
|
|
|
|
|
|
var result = false;
|
var fjlist = db.Queryable<CntrItemRel>().Includes(c => c.Cntr)
|
.Where(expression)
|
.OrderBy(c => c.T_CREATE)
|
.ToList();
|
for (int i = 0; i < fjlist.Count; i++)
|
{
|
//检测这个托盘物料是否单一
|
var cir = fjlist[i];
|
var isfj = db.Queryable<SortingDetail>().Where(c => c.S_CNTR_CODE == cir.S_CNTR_CODE && c.C_REVERSE == "Y" && c.N_B_STATE < 2).First();
|
if (isfj == null)
|
{
|
var itemlist = db.Queryable<CntrItemRel>().Where(c => c.S_CNTR_CODE == cir.S_CNTR_CODE && c.F_QTY > 0).ToList();
|
if (itemlist.Count == 1)
|
{
|
result = true;
|
var sd = new SortingDetail
|
{
|
N_ROW_NO = rowNo,
|
S_BATCH_NO = a.S_BATCH_NO,
|
S_ITEM_CODE = a.S_ITEM_CODE,
|
S_CNTR_CODE = cir.S_CNTR_CODE,
|
S_SORTING_NO = a.S_SORTING_NO,
|
S_FAC_CODE = a.S_FAC_CODE,
|
S_ITEM_LOC = a.S_ITEM_LOC,
|
F_QTY = (itemlist[0].F_QTY - itemlist[0].F_ALLOC_QTY) - (a.F_QTY - a.F_ACC_S_QTY),
|
C_REVERSE = "Y"
|
};
|
db.Insertable(sd).ExecuteCommand();
|
rowNo++;
|
//更新容器货品表分配量
|
cir.F_ALLOC_QTY += sd.F_QTY;
|
cir.T_MODIFY = DateTime.Now;
|
db.Updateable(cir).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
//更新分拣单子表的量
|
a.F_ACC_S_QTY += a.F_QTY - a.F_ACC_S_QTY;
|
a.T_MODIFY = DateTime.Now;
|
db.Updateable(a).UpdateColumns(it => new { it.F_ACC_S_QTY, it.T_MODIFY }).ExecuteCommand();
|
var whi = db.Queryable<WHInventory>().Where(it => it.S_ITEM_CODE == a.S_ITEM_CODE).First();
|
if (whi != null)
|
{
|
whi.F_ALLOC_QTY += a.F_QTY - a.F_ACC_S_QTY;
|
whi.T_MODIFY = DateTime.Now;
|
db.Updateable(whi).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
}
|
break;
|
}
|
}
|
|
}
|
|
|
Expression<Func<CntrItemRel, bool>> expression1 = x => x.S_ITEM_CODE == a.S_ITEM_CODE;
|
expression1.AndAlso(x => x.Cntr.C_ENABLE == "Y");
|
expression1.AndAlso(x => (x.F_QTY - x.F_ALLOC_QTY) > 0);
|
if (!string.IsNullOrEmpty(a.S_BATCH_NO)) expression1.AndAlso(x => x.S_BATCH_NO == a.S_BATCH_NO);
|
if (!string.IsNullOrEmpty(a.S_FAC_CODE)) expression1.AndAlso(x => x.S_OWNER == a.S_FAC_CODE);
|
//if (!string.IsNullOrEmpty(a.S_ITEM_LOC)) expression1.AndAlso(x => x.S_ERP_WH_CODE == a.S_ITEM_LOC);
|
|
if (!result)
|
{
|
|
//按分拣单子表去配货,查找可用托盘(先查所有符合的,后面再优化)
|
var cirList = db.Queryable<CntrItemRel>().Includes(c => c.Cntr)
|
.Where(expression1)
|
.OrderBy(c => c.T_CREATE)
|
.ToList();
|
for (int i = 0; i < cirList.Count; i++)
|
{
|
var cir = cirList[i];
|
var isfj = db.Queryable<SortingDetail>().Where(c => c.S_CNTR_CODE == cir.S_CNTR_CODE && c.C_REVERSE == "Y" && c.N_B_STATE < 2).First();
|
if (isfj == null)
|
{
|
var sd = new SortingDetail
|
{
|
N_ROW_NO = rowNo,
|
S_BATCH_NO = a.S_BATCH_NO,
|
S_ITEM_CODE = a.S_ITEM_CODE,
|
S_CNTR_CODE = cir.S_CNTR_CODE,
|
S_FAC_CODE = a.S_FAC_CODE,
|
S_ITEM_LOC = a.S_ITEM_LOC,
|
S_SORTING_NO = a.S_SORTING_NO
|
};
|
bool needBreak = false;
|
if (cir.F_QTY - cir.F_ALLOC_QTY >= (a.F_QTY - a.F_ACC_S_QTY))
|
{
|
sd.F_QTY = a.F_QTY - a.F_ACC_S_QTY;
|
needBreak = true;
|
}
|
else
|
{
|
//生成分拣明细,继续创建
|
sd.F_QTY = cir.F_QTY - cir.F_ALLOC_QTY;
|
}
|
db.Insertable(sd).ExecuteCommand();
|
rowNo++;
|
//更新容器货品表分配量
|
cir.F_ALLOC_QTY += sd.F_QTY;
|
cir.T_MODIFY = DateTime.Now;
|
db.Updateable(cir).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
//更新分拣单子表的量
|
a.F_ACC_S_QTY += sd.F_QTY;
|
a.T_MODIFY = DateTime.Now;
|
db.Updateable(a).UpdateColumns(it => new { it.F_ACC_S_QTY, it.T_MODIFY }).ExecuteCommand();
|
var whi = db.Queryable<WHInventory>().Where(it => it.S_ITEM_CODE == a.S_ITEM_CODE).First();
|
if (whi != null)
|
{
|
whi.F_ALLOC_QTY += sd.F_QTY;
|
whi.T_MODIFY = DateTime.Now;
|
db.Updateable(whi).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
}
|
if (needBreak)
|
{
|
break;
|
}
|
}
|
|
}
|
}
|
|
});
|
//全部分拣单子表生成分拣明细,修改分拣单状态为配货完成(反正仓库的货能配的都配完了,除非数据有异常)
|
so.N_B_STATE = 2;
|
so.T_MODIFY = DateTime.Now;
|
db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
db.CommitTran();
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
db.RollbackTran();
|
}
|
}
|
}
|
|
/// <summary>
|
/// 获取开始配货的分拣单,一次性生成分拣明细,避免生成一半再生成,所以创建分拣明细的时候加上事务
|
/// </summary>
|
/// <returns></returns>
|
internal static List<SortingOrder> GetWaitingSortingOrderList()
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<SortingOrder>().Includes(a => a.Composes).Where(a => a.N_B_STATE == 1 || a.N_B_STATE == 20).ToList();
|
}
|
/// <summary>
|
/// 获取配货完成的分拣单,每个分拣单单独创建分拣作业
|
/// </summary>
|
/// <returns></returns>
|
internal static List<TN_Distribution_CNTR> GetWaitingSortingOperationList()
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
return db.Queryable<TN_Distribution_CNTR>().Where(a => a.N_B_STATE == 1 && a.S_BS_TYPE != "人工库出库").ToList();
|
}
|
|
/// <summary>
|
///单个分拣单的分拣明细创建作业
|
/// </summary>
|
internal static void CreateSortingOperation(SortingOrder so)
|
{
|
var list = so.Details.Where(a => a.N_B_STATE == 0).ToList();
|
var db = new SqlHelper<object>().GetInstance();
|
if (list.Count > 0)
|
{
|
try
|
{
|
db.BeginTran();
|
list.GroupBy(g => g.S_CNTR_CODE).ToList().ForEach(g =>
|
{
|
var cntr = g.Key;
|
var sdList = g.ToList();
|
//查询托盘货位,查到了创建任务,查不到说明在别的分拣作业中,不创建任务,需要回库后重新创建
|
var lcr = db.Queryable<LocCntrRel>().Where(c => c.S_CNTR_CODE == cntr).First();
|
if (lcr != null)
|
{
|
var area = db.Queryable<Location>().Where(c => c.S_CODE == lcr.S_LOC_CODE).First();
|
if (area != null)
|
{
|
|
//判断托盘是否已经创建任务了,可能多个分拣明细是同一个托盘,如果创建任务了,其它分拣的要稍后,只出一次人工会搞不清楚是哪个分拣单的
|
var wmsTask = db.Queryable<WMSTask>().Where(op => op.S_CNTR_CODE.Contains(cntr) && op.N_B_STATE < 2).First();
|
if (wmsTask == null)
|
{
|
wmsTask = new WMSTask
|
{
|
S_CNTR_CODE = cntr,
|
S_CODE = WMSHelper.GenerateTaskNo(),
|
S_START_LOC = lcr.S_LOC_CODE,
|
S_END_LOC = "",
|
N_TYPE = 2,
|
S_TYPE = WMSTask.GetTypeStr(2),
|
//S_TYPE = so.S_TYPE,
|
S_OP_DEF_CODE = "",
|
S_OP_DEF_NAME = so.S_TYPE
|
};
|
if (db.Insertable(wmsTask).ExecuteCommand() > 0)
|
{
|
LocationHelper.LockLoc(lcr.S_LOC_CODE, 2);
|
}
|
|
sdList.ForEach(a =>
|
{
|
a.N_B_STATE = 1;
|
a.T_MODIFY = DateTime.Now;
|
db.Updateable(a).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
});
|
}
|
}
|
}
|
//修改分拣单状态为开始作业(不代表作业全部创建了,因为有的托盘可能已经被占用了)
|
so.N_B_STATE = 3;
|
//如果所有的作业都已经创建了,就设置为作业已经创建
|
if (so.Details.Count(s => s.N_B_STATE == 0) == 0)
|
{
|
so.N_B_STATE = 4;
|
}
|
so.T_MODIFY = DateTime.Now;
|
db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
|
});
|
db.CommitTran();
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
db.RollbackTran();
|
}
|
|
}
|
}
|
internal static void SortingConfrim(List<SortingResultCheck> models)
|
{
|
if (models.Count > 0)
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
try
|
{
|
db.BeginTran();
|
//先查寻该分拣单所有执行中的分拣明细
|
var sdList = db.Queryable<SortingDetail>().Where(a => a.S_SORTING_NO == models[0].sortNo).ToList();
|
var soList = db.Queryable<ShippingOrder>().Includes(a => a.Details).Where(a => a.S_WAVE_CODE == models[0].sortNo).ToList();
|
//查出所有关联的发货单
|
models.ForEach(a =>
|
{
|
Expression<Func<SortingDetail, bool>> expression = x => x.S_ITEM_CODE == a.itemCode;
|
if (!string.IsNullOrEmpty(a.batchNo)) expression.AndAlso(x => x.S_BATCH_NO == a.batchNo);
|
if (!string.IsNullOrEmpty(a.factoryCode)) expression.AndAlso(x => x.S_FAC_CODE == a.factoryCode);
|
if (!string.IsNullOrEmpty(a.stockLocation)) expression.AndAlso(x => x.S_ITEM_LOC == a.stockLocation);
|
|
//根据条目修改累计分拣数量,添加分拣结果表,同时批分到发货单中
|
var sd = sdList.Where(expression.Compile()).First();
|
//简单一点,要求人工必须一次性分拣完,分拣数量和分拣明细中一致才创建分拣结果,不支持一条分拣明细多次分拣,多条分拣结果
|
//(sd.F_QTY - sd.F_ACC_SR_QTY) == a.qty
|
if (sd != null && sd.F_QTY == a.qty)
|
{
|
//查询分拣结果是否已经存在,存在就累加
|
//分拣单结果
|
var sdr = new SortingResult
|
{
|
S_SORTING_NO = a.sortNo,
|
F_QTY = a.qty,
|
N_ROW_NO = sd.N_ROW_NO,
|
S_ITEM_CODE = sd.S_ITEM_CODE,
|
S_ITEM_NAME = sd.S_ITEM_NAME,
|
S_BATCH_NO = sd.S_BATCH_NO,
|
S_FAC_CODE = sd.S_FAC_CODE,
|
S_ITEM_LOC = sd.S_ITEM_LOC,
|
S_CNTR_CODE = a.cntrCode,
|
C_REVERSE = sd.C_REVERSE,
|
S_DEST_CNTR_CODE = a.targetcntrCode
|
};
|
db.Insertable(sdr).ExecuteCommand();
|
|
//反拣对于备货托盘进行锁定
|
if (sdr.C_REVERSE == "Y")
|
{
|
db.Updateable<Container>().SetColumns(it => new Container { C_ENABLE = "N" }).Where(it => it.S_CODE == a.cntrCode).ExecuteCommand();
|
}
|
else
|
{
|
db.Updateable<Container>().SetColumns(it => new Container { C_ENABLE = "N" }).Where(it => it.S_CODE == a.targetcntrCode).ExecuteCommand();
|
}
|
|
//sd.F_ACC_SR_QTY += a.qty;
|
sd.N_B_STATE = 2;
|
sd.T_MODIFY = DateTime.Now;
|
db.Updateable(sd).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
//批分到发货单中
|
|
Expression<Func<CntrItemRel, bool>> expression1 = x => x.S_ITEM_CODE == a.itemCode;
|
expression1.AndAlso(x => x.S_CNTR_CODE == a.cntrCode);
|
if (!string.IsNullOrEmpty(a.batchNo)) expression1.AndAlso(x => x.S_BATCH_NO == a.batchNo);
|
if (!string.IsNullOrEmpty(a.factoryCode)) expression1.AndAlso(x => x.S_OWNER == a.factoryCode);
|
//if (!string.IsNullOrEmpty(a.stockLocation)) expression1.AndAlso(x => x.S_ERP_WH_CODE == a.stockLocation);
|
|
//更新托盘明细表
|
var cir = db.Queryable<CntrItemRel>()
|
.Where(expression1).First();
|
|
|
cir.F_QTY -= a.qty;
|
cir.F_ALLOC_QTY -= a.qty;
|
cir.T_MODIFY = DateTime.Now;
|
db.Updateable(cir).UpdateColumns(it => new { it.F_QTY, it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
|
|
Expression<Func<CntrItemRel, bool>> expression2 = x => x.S_ITEM_CODE == a.itemCode;
|
expression2.AndAlso(x => x.S_CNTR_CODE == a.targetcntrCode);
|
if (!string.IsNullOrEmpty(a.batchNo)) expression2.AndAlso(x => x.S_BATCH_NO == a.batchNo);
|
if (!string.IsNullOrEmpty(a.factoryCode)) expression2.AndAlso(x => x.S_OWNER == a.factoryCode);
|
//if (!string.IsNullOrEmpty(a.stockLocation)) expression2.AndAlso(x => x.S_ERP_WH_CODE == a.stockLocation);
|
var cir1 = db.Queryable<CntrItemRel>()
|
.Where(expression2)
|
.First();
|
if (cir1 != null)
|
{
|
cir1.F_QTY += a.qty;
|
cir1.T_MODIFY = DateTime.Now;
|
db.Updateable(cir).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand();
|
}
|
else
|
{
|
CntrItemRel item = new CntrItemRel
|
{
|
S_CNTR_CODE = a.targetcntrCode,
|
S_ITEM_CODE = a.itemCode,
|
S_BATCH_NO = a.batchNo,
|
S_OWNER = a.factoryCode,
|
//S_ERP_WH_CODE = a.stockLocation,
|
F_QTY = a.qty,
|
T_MODIFY = DateTime.Now
|
};
|
db.Insertable(item).ExecuteCommand();
|
}
|
|
if (sdr.C_REVERSE == "Y")
|
{
|
a.qty = cir.F_QTY;
|
}
|
|
|
//更新仓库量表和库区量表
|
//查询仓库量表
|
var wi = db.Queryable<WHInventory>().Where(i => i.S_ITEM_CODE == a.itemCode).First();
|
if (wi != null)
|
{
|
wi.F_QTY -= a.qty;
|
wi.F_ALLOC_QTY -= a.qty;
|
wi.T_MODIFY = DateTime.Now;
|
db.Updateable(wi).UpdateColumns(it => new { it.F_QTY, it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
|
}
|
|
|
Expression<Func<ShippingDetail, bool>> expression3 = x => x.S_ITEM_CODE == a.itemCode;
|
expression3.AndAlso(x => (x.F_QTY - x.F_ACC_S_QTY) > 0);
|
if (!string.IsNullOrEmpty(a.batchNo)) expression3.AndAlso(x => x.S_BATCH_NO == a.batchNo);
|
if (!string.IsNullOrEmpty(a.factoryCode)) expression3.AndAlso(x => x.S_FAC_CODE == a.factoryCode);
|
if (!string.IsNullOrEmpty(a.stockLocation)) expression3.AndAlso(x => x.S_ITEM_LOC == a.stockLocation);
|
//分拣明细生成时 应该与发货单明细对应
|
var dList = soList.SelectMany(s => s.Details)
|
.Where(expression3.Compile())
|
.ToList();
|
var qty = a.qty;
|
for (int i = 0; i < dList.Count; i++)
|
{
|
var d = dList[i];
|
//发货信息中间表
|
//var dyo = new DayuanOut
|
//{
|
// CN_S_BATCH_NO = sd.S_BATCH_NO,
|
// CN_S_ITEM_CODE = sd.S_ITEM_CODE,
|
// CN_S_OUT_NO = d.S_SHIPPING_NO,
|
//
|
//};
|
if (d.F_QTY - d.F_ACC_S_QTY >= a.qty)
|
{
|
//发货单数量超过托盘分拣数量,批分qty
|
d.F_ACC_S_QTY += a.qty;
|
//dyo.CN_F_QUANTITY = a.qty;
|
qty = 0;
|
}
|
else
|
{
|
// 发货单数量小于托盘分拣数量
|
d.F_ACC_S_QTY = d.F_QTY;
|
qty -= (d.F_QTY - d.F_ACC_S_QTY);
|
//dyo.CN_F_QUANTITY = d.F_QTY - d.F_ACC_S_QTY;
|
}
|
d.T_MODIFY = DateTime.Now;
|
db.Updateable(d).UpdateColumns(it => new { it.F_ACC_S_QTY, it.T_MODIFY }).ExecuteCommand();
|
//插入到大元出库中间表
|
//db.Insertable(dyo).ExecuteCommand();
|
if (qty == 0)
|
{
|
break;
|
}
|
|
}
|
|
//麻烦了,分拣明细只记托盘,不记住起点,如果要统计库区量表,必须对托盘加标记,记录托盘的来源库区,托盘清空后再清除标记
|
|
//逻辑库区更不需要量表了,因为从一个逻辑库区出来,可能回其它逻辑库区,那就应该直接删除逻辑库区量表,后面再加到别的逻辑库区中
|
//但是会带来新的问题,就是分拣回的托盘不属于任何逻辑库区的量,只有回库了才能计算到
|
|
//var aziList = db.Queryable<AZInventory>().Where(i => i.S_ITEM_CODE == a.itemCode).ToList();
|
}
|
|
//
|
});
|
//判断分拣单是否全部完成
|
if (sdList.Count(sd => sd.N_B_STATE != 2) == 0)
|
{
|
var spo = db.Queryable<SortingOrder>().Where(s => s.S_NO == models[0].sortNo).First();
|
if (spo != null)
|
{
|
spo.N_B_STATE = 10;
|
spo.T_MODIFY = DateTime.Now;
|
db.Updateable(spo).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
}
|
}
|
//判断发货单配货是否分拣完成
|
soList.ForEach(s =>
|
{
|
if (s.Details.Count > 0 && s.Details.Count(sd => sd.F_ACC_D_QTY != sd.F_ACC_S_QTY) == 0)
|
{
|
//配货单的数量等于分拣的数量,分拣完成
|
s.N_B_STATE = 3;
|
s.T_MODIFY = DateTime.Now;
|
db.Updateable(s).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
|
}
|
});
|
db.CommitTran();
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
db.RollbackTran();
|
}
|
}
|
}
|
|
/// <summary>
|
/// 立库入库算法
|
/// </summary>
|
/// <param name="endArea"></param>
|
/// <param name="roadway"></param>
|
/// <returns></returns>
|
internal static Location GetLiKuLocationIn(string endArea, int roadway, string loctype = "", string IsLong = "0")
|
{
|
LogHelper.Info($"入库算法开始 终点库区={endArea} 巷道={roadway} 货位类型={loctype}");
|
Location endbit = null;
|
var res = false;
|
var loclist = new List<Location>();
|
var newendbitlist = new List<summodel>();
|
var db = new SqlHelper<object>().GetInstance();
|
//var endbitlist = new List<>();
|
//var ebitlist = new List<Location>();
|
//var endbitlist = db.Queryable<Location>()
|
// .Where(a => a.S_AREA_CODE == endArea && a.IsDouble == isDouble)
|
// .PartitionBy(a => a.N_ROADWAY)
|
// .Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM), ROADWAY = a.N_ROADWAY })
|
// .MergeTable()
|
// .OrderBy(a => a.sum)
|
// .ToList();
|
|
if (roadway == 0)
|
{
|
var endbitlist = db.Queryable<Location>()
|
.Where(a => a.S_AREA_CODE == endArea)
|
.Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM), a.N_ROADWAY })
|
//.PartitionBy(a => a.N_ROADWAY)
|
.GroupBy(a => a.N_ROADWAY)
|
.MergeTable()
|
.OrderBy(a => a.sum)
|
.ToList();
|
LogHelper.Info($"获取各个巷道数据 巷道数量={endbitlist.Count()}");
|
|
endbitlist.ForEach(a =>
|
{
|
//查找入库锁数量 加上去
|
var loc = db.Queryable<Location>()
|
.Where(it => it.S_AREA_CODE == endArea && it.N_ROADWAY == a.N_ROADWAY && it.N_LOCK_STATE == 1)
|
.ToList();
|
newendbitlist.Add(new summodel { sum = a.sum, roadway = a.N_ROADWAY, locksum = loc.Count });
|
});
|
|
newendbitlist = newendbitlist.OrderBy(a => a.sum).ToList();
|
newendbitlist = newendbitlist.OrderBy(a => a.locksum).ToList();
|
|
LogHelper.Info($"整合后数据 巷道数量={newendbitlist.Count()}");
|
foreach (var item in newendbitlist)
|
{
|
//if (DuiDuoBool(item.roadway))
|
//{
|
var exp = Expressionable.Create<Location>();
|
exp.And(a => a.S_AREA_CODE == endArea);
|
exp.And(a => a.N_ROADWAY == item.roadway);
|
exp.And(a => a.N_CURRENT_NUM == 0);
|
exp.And(a => a.N_LOCK_STATE == 0);
|
exp.AndIF(!string.IsNullOrEmpty(loctype), a => a.S_TYPE == loctype);
|
|
res = true;
|
if (IsLong == "0")
|
{
|
loclist = db.Queryable<Location>()
|
.Where(exp.ToExpression())
|
.OrderByDescending(it => new { N_LAYER = SqlFunc.Asc(it.N_LAYER), N_COL = SqlFunc.Asc(it.N_COL), N_ROW = SqlFunc.Asc(it.N_ROW) })
|
.ToList();
|
}
|
else
|
{
|
loclist = db.Queryable<Location>()
|
.Where(exp.ToExpression())
|
.OrderByDescending(it => new { N_LAYER = SqlFunc.Asc(it.N_LAYER), N_COL = SqlFunc.Desc(it.N_COL), N_ROW = SqlFunc.Asc(it.N_ROW) })
|
.ToList();
|
}
|
LogHelper.Info($"获取可用货位数量={loclist.Count}");
|
if (loclist.Count > 0)
|
{
|
endbit = loclist[0];
|
break;
|
}
|
}
|
}
|
else
|
{
|
var exp = Expressionable.Create<Location>();
|
exp.And(a => a.S_AREA_CODE == endArea);
|
exp.And(a => a.N_ROADWAY == roadway);
|
exp.And(a => a.N_CURRENT_NUM == 0);
|
exp.And(a => a.N_LOCK_STATE == 0);
|
exp.AndIF(!string.IsNullOrEmpty(loctype), a => a.S_TYPE == loctype);
|
//if (DuiDuoBool(int.Parse(roadway)))
|
//{
|
if (IsLong == "0")
|
{
|
loclist = db.Queryable<Location>()
|
.Where(exp.ToExpression())
|
.OrderByDescending(it => new { N_LAYER = SqlFunc.Asc(it.N_LAYER), N_COL = SqlFunc.Asc(it.N_COL), N_ROW = SqlFunc.Asc(it.N_ROW) })
|
.ToList();
|
}
|
else
|
{
|
loclist = db.Queryable<Location>()
|
.Where(exp.ToExpression())
|
.OrderByDescending(it => new { N_LAYER = SqlFunc.Asc(it.N_LAYER), N_COL = SqlFunc.Desc(it.N_COL), N_ROW = SqlFunc.Asc(it.N_ROW) })
|
.ToList();
|
}
|
if (loclist.Count > 0)
|
{
|
endbit = loclist[0];
|
}
|
//}
|
//else
|
//{
|
// msg = $"巷道{roadway} 对应堆垛机不可用";
|
// return endbit;
|
//}
|
}
|
LogHelper.Info($"入库算法结束 结果{endbit != null}");
|
|
return endbit;
|
}
|
|
public class summodel
|
{
|
public int sum { get; set; }
|
public int locksum { get; set; }
|
public int roadway { get; set; }
|
}
|
|
internal static bool CheckSortingWholeCntr(string cntr, bool autoSort)
|
{
|
var result = false;
|
//判断分拣明细是不是只有一个托盘,如果是,判断容器货品明细是不是和分拣明细完全一样
|
var db = new SqlHelper<object>().GetInstance();
|
var sdList = db.Queryable<SortingDetail>().Where(a => a.S_CNTR_CODE == cntr).ToList();
|
if (sdList.Count > 0)
|
{
|
var groups = sdList.GroupBy(a => a.S_SORTING_NO).ToList();
|
if (groups.Count == 1)
|
{
|
var list = groups.ToList();
|
//只有一个分拣单的情况下,分配量和托盘量都相同,表示是整托
|
var cirList = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntr).ToList();
|
if (list.Count == cirList.Count && cirList.Count(c => c.F_QTY != c.F_ALLOC_QTY) == 0)
|
{
|
result = true;
|
if (autoSort)
|
{
|
var data = sdList.Select(s => new SortingResultCheck { cntrCode = s.S_CNTR_CODE, itemCode = s.S_ITEM_CODE, qty = s.F_QTY, sortNo = s.S_SORTING_NO }).ToList();
|
SortingConfrim(data);
|
|
}
|
}
|
}
|
}
|
return result;
|
}
|
}
|
}
|