using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
|
using iWareSql;
|
using System.Data.Entity.Migrations;
|
using iWareSql.Orm;
|
using iWareCommon;
|
using iWareCommon.Utils;
|
using iWareSql.Entity.ViewMode;
|
|
using iWareSql.DBModel;
|
using iWareModel;
|
using iWareCommon.Common.Globle;
|
using XiGang.Core.Model;
|
|
namespace iWareSql.DataAccess
|
{
|
/// <summary>
|
/// 库存处理类
|
/// </summary>
|
public class StoreHandler
|
{
|
|
|
private static readonly object lockObject = new object();
|
private static readonly object lockRemoveObject = new object();
|
private static Dictionary<int, string> lockPlaceDict = new Dictionary<int, string>();
|
|
/// <summary>
|
/// 增加空托盘的库存
|
/// </summary>
|
/// <param name="edm"></param>
|
/// <param name="remark"></param>
|
/// <param name="place"></param>
|
public static void AddStoreForEmptySalverTransfer(DbModel edm, string remark, Base_Station place, int qty, string user, ref Base_Salver salver, ref Base_Material newMaterial)
|
{
|
//绑定托盘和站点的关系
|
//新建物料
|
newMaterial = MaterialHandler.CreateEmptySlaverMaterial(edm, remark, qty);
|
//判断托盘是否存在,如果存在,就不需要重建,如果不存在,就新建托盘
|
salver = SalverHandler.CreateVirtualSalver(edm, remark);
|
//绑定托盘和物料的关系
|
Salver_Material_Handler.CreateCvIRelation(edm, user, salver, newMaterial, remark);
|
//绑定托盘和站点的关系
|
Salver_Station_Handler.CreateCvPRelation(edm, user, salver, place, Salver_V_Station_StateEnum.入库绑定, remark);
|
|
|
}
|
|
/// <summary>
|
/// 根据RGV站点号获取库存
|
/// </summary>
|
/// <param name="context"></param>
|
/// <param name="rgvStationCode"></param>
|
/// <returns></returns>
|
public static V_AllStore GetV_AllStoreByRgvStationCode(DbModel context, string rgvStationCode)
|
{
|
return context.V_AllStore.Where(x => x.RgvStationCode == rgvStationCode).FirstOrDefault();
|
}
|
|
/// <summary>
|
/// 根据库位ID获取库存
|
/// </summary>
|
/// <param name="context"></param>
|
/// <param name="rgvStationCode"></param>
|
/// <returns></returns>
|
public static V_AllStore GetV_AllStoreByPlaceId(DbModel context, int placeId)
|
{
|
return context.V_AllStore.Where(x => x.StationId == placeId).FirstOrDefault();
|
}
|
|
/// <summary>
|
/// 发动机是否有货
|
/// </summary>
|
/// <param name="orderNo"></param>
|
/// <returns>true:系统有货,false:系统无货</returns>
|
public static bool IsSys_HasCatogryForOrderNo(DbModel context, string orderNo, ref V_AllStore store)
|
{
|
store = context.V_AllStore.Where(x => x.OrderNo == orderNo).FirstOrDefault();
|
if (store != null)
|
{//有货
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 托盘是否有货
|
/// </summary>
|
/// <param name="salverCode"></param>
|
/// <returns>true:系统有货,false:系统无货</returns>
|
public static bool IsSys_HasCatogryForSalverCode(DbModel context, string salverCode, ref V_AllStore store)
|
{
|
store = context.V_AllStore.Where(x => x.SalverCode == salverCode).FirstOrDefault();
|
if (store != null)
|
{//有货
|
return true;
|
}
|
return false;
|
}
|
|
#region 出库计划下发时,寻找库存
|
|
/// <summary>
|
/// 出库计划下发时,寻找库存
|
/// </summary>
|
/// <param name="context"></param>
|
/// <param name="outDetailTask"></param>
|
/// <param name="errMsg"></param>
|
/// <param name="queliaoReason">缺料原因</param>
|
public static V_Store FindStoreForOutPlan(DbModel context, Plan_OutTaskDetail outDetailTask, ref string errMsg, ref string queliaoReason)
|
{
|
var isOrderByInStoreTimeForOut = Base_CodeItemsHandler.IsOrderByInStoreTimeForOut(context);
|
|
List<V_Store> findStoreList = null;
|
|
if (outDetailTask.StationId != null && outDetailTask.StationId > 0)
|
{
|
findStoreList = context.V_Store.Where(x => x.StationId == outDetailTask.StationId
|
&& x.StationIsHasTaskDoing == false && x.StationIsLock == false
|
&& x.StationIsDeleted == false).ToList();
|
}
|
else if (!string.IsNullOrEmpty(outDetailTask.SerialNumber))
|
{//按序列号出库
|
findStoreList = context.V_Store.Where(x => x.SerialNumber == outDetailTask.SerialNumber
|
&& x.StationIsHasTaskDoing == false && x.StationIsLock == false
|
&& x.StationIsDeleted == false).ToList();
|
}
|
else if (!string.IsNullOrEmpty(outDetailTask.OrderNo))
|
{//按订货号出库,按照入库时间升序排序
|
findStoreList = context.V_Store.Where(x => x.OrderNo == outDetailTask.OrderNo
|
&& x.StationIsHasTaskDoing == false && x.StationIsLock == false
|
&& x.StationIsDeleted == false).ToList();
|
//增加动态排序 【Editby shaocx,2024-07-02】
|
|
if (isOrderByInStoreTimeForOut.data)
|
{
|
findStoreList = findStoreList.OrderBy(x => x.InStoreTime).ToList();//按照入库时间排序
|
}
|
else
|
{
|
findStoreList = findStoreList.OrderBy(x => x.SerialNumber).ToList();//按照序列化排序
|
}
|
}
|
else
|
{
|
throw new Exception("出库明细既不是按照序列号出库,也不是按照订货号出库,明细ID:" + outDetailTask.Id);
|
}
|
if (findStoreList == null || findStoreList.Count == 0)
|
{
|
errMsg = "未找到库存,序列号:" + (string.IsNullOrEmpty(outDetailTask.SerialNumber) ? "" : outDetailTask.SerialNumber)
|
+ ",订货号:" + (string.IsNullOrEmpty(outDetailTask.OrderNo) ? "" : outDetailTask.OrderNo)
|
+ ",计划号:" + outDetailTask.M_PlanNo;
|
queliaoReason = "立体库中无库存";
|
return null;
|
}
|
else
|
{
|
//过滤掉 堆垛机故障的库区
|
findStoreList = StationHandler.FindPlacesFilterByBreakdown(findStoreList);//通过设备状态来过滤库位 [EditBy shaocx,2020-12-13]
|
}
|
|
if (findStoreList == null || findStoreList.Count == 0)
|
{
|
errMsg = "未找到库存,序列号:" + (string.IsNullOrEmpty(outDetailTask.SerialNumber) ? "" : outDetailTask.SerialNumber)
|
+ ",订货号:" + (string.IsNullOrEmpty(outDetailTask.OrderNo) ? "" : outDetailTask.OrderNo)
|
+ ",计划号:" + outDetailTask.M_PlanNo;
|
queliaoReason = "有库存,但由于该区域堆垛机故障,不能出库";
|
return null;
|
}
|
//重新排序
|
if (isOrderByInStoreTimeForOut.data)
|
{
|
findStoreList = findStoreList.OrderBy(x => x.InStoreTime).ToList();//按照入库时间排序
|
}
|
else
|
{
|
findStoreList = findStoreList.OrderBy(x => x.SerialNumber).ToList();//按照序列化排序
|
}
|
|
List<V_Store> new_findStoreList = new List<V_Store>();
|
//增加该库位是否被任务占用的筛选 [EditBy shaocx,2022-06-02]
|
if (findStoreList != null && findStoreList.Count > 0)
|
{
|
foreach (var _findStore in findStoreList)
|
{
|
var isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, _findStore.StationId);
|
if (!isExistOtherTaskDoing)
|
{
|
new_findStoreList.Add(_findStore);
|
}
|
}
|
}
|
//重新排序
|
//new_findStoreList = new_findStoreList.OrderBy(x => x.InStoreTime).ToList();
|
if (isOrderByInStoreTimeForOut.data)
|
{
|
new_findStoreList = new_findStoreList.OrderBy(x => x.InStoreTime).ToList();//按照入库时间排序
|
}
|
else
|
{
|
new_findStoreList = new_findStoreList.OrderBy(x => x.SerialNumber).ToList();//按照序列化排序
|
}
|
|
V_Store findStore = new_findStoreList.FirstOrDefault();
|
if (findStore == null)
|
{
|
errMsg = "未找到库存,序列号:" + (string.IsNullOrEmpty(outDetailTask.SerialNumber) ? "" : outDetailTask.SerialNumber)
|
+ ",订货号:" + (string.IsNullOrEmpty(outDetailTask.OrderNo) ? "" : outDetailTask.OrderNo)
|
+ ",计划号:" + outDetailTask.M_PlanNo;
|
queliaoReason = "有库存,但由于该库位被其他任务占用,不能出库";
|
return null;
|
}
|
return findStore;
|
}
|
|
/// <summary>
|
/// 出库计划下发时,寻找库存,库存从虚拟库存中查找 【Editby shaocx,2022-07-28】
|
/// </summary>
|
/// <param name="context"></param>
|
/// <param name="outDetailTask"></param>
|
/// <param name="errMsg"></param>
|
public static Wms_VirtualStore FindStoreForOutPlanByVirtual(DbModel context, Plan_OutTaskDetail outDetailTask, ref string errMsg)
|
{
|
var isOrderByInStoreTimeForOut = Base_CodeItemsHandler.IsOrderByInStoreTimeForOut(context);
|
List<Wms_VirtualStore> findStoreList = null;
|
|
if (outDetailTask.StationId != null && outDetailTask.StationId > 0)
|
{
|
return null;
|
}
|
else if (!string.IsNullOrEmpty(outDetailTask.SerialNumber))
|
{//按序列号出库
|
findStoreList = context.Wms_VirtualStore.Where(x => x.SerialNumber == outDetailTask.SerialNumber
|
&& (x.IsDeleted == null || x.IsDeleted == false) //只查没有被锁定的库存数据
|
).ToList();
|
}
|
else if (!string.IsNullOrEmpty(outDetailTask.OrderNo))
|
{//按订货号出库,按照入库时间升序排序
|
findStoreList = context.Wms_VirtualStore.Where(x => x.OrderNo == outDetailTask.OrderNo
|
&& (x.IsDeleted == null || x.IsDeleted == false) //只查没有被锁定的库存数据
|
).ToList();
|
if (isOrderByInStoreTimeForOut.data)
|
{
|
findStoreList = findStoreList.OrderBy(x => x.InStoreTime).ToList();//按照入库时间排序
|
}
|
else
|
{
|
findStoreList = findStoreList.OrderBy(x => x.SerialNumber).ToList();//按照序列化排序
|
}
|
}
|
else
|
{
|
throw new Exception("出库明细既不是按照序列号出库,也不是按照订货号出库,明细ID:" + outDetailTask.Id);
|
}
|
if (findStoreList == null || findStoreList.Count == 0)
|
{
|
errMsg = "未找到库存,序列号:" + (string.IsNullOrEmpty(outDetailTask.SerialNumber) ? "" : outDetailTask.SerialNumber)
|
+ ",订货号:" + (string.IsNullOrEmpty(outDetailTask.OrderNo) ? "" : outDetailTask.OrderNo)
|
+ ",计划号:" + outDetailTask.M_PlanNo;
|
return null;
|
}
|
else
|
{
|
|
}
|
|
if (findStoreList == null || findStoreList.Count == 0)
|
{
|
errMsg = "未找到库存,序列号:" + (string.IsNullOrEmpty(outDetailTask.SerialNumber) ? "" : outDetailTask.SerialNumber)
|
+ ",订货号:" + (string.IsNullOrEmpty(outDetailTask.OrderNo) ? "" : outDetailTask.OrderNo)
|
+ ",计划号:" + outDetailTask.M_PlanNo;
|
return null;
|
}
|
//重新排序
|
if (isOrderByInStoreTimeForOut.data)
|
{
|
findStoreList = findStoreList.OrderBy(x => x.InStoreTime).ToList();//按照入库时间排序
|
}
|
else
|
{
|
findStoreList = findStoreList.OrderBy(x => x.SerialNumber).ToList();//按照序列化排序
|
}
|
|
Wms_VirtualStore findStore = findStoreList.FirstOrDefault();
|
if (findStore == null)
|
{
|
errMsg = "未找到库存,序列号:" + (string.IsNullOrEmpty(outDetailTask.SerialNumber) ? "" : outDetailTask.SerialNumber)
|
+ ",订货号:" + (string.IsNullOrEmpty(outDetailTask.OrderNo) ? "" : outDetailTask.OrderNo)
|
+ ",计划号:" + outDetailTask.M_PlanNo;
|
return null;
|
}
|
return findStore;
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
/// 校验库存是否允许被出库
|
/// </summary>
|
/// <param name="findStore"></param>
|
/// <param name="errMsg"></param>
|
/// <returns></returns>
|
private static bool ValidateStoreIsAllowOut(V_Store findStore, ref string errMsg)
|
{
|
var stationName = "库号:" + findStore.SrmStationCode;
|
if (findStore.StationIsLock == true)
|
{
|
errMsg = stationName + "被锁定,不允许出库";
|
return false;
|
}
|
if (findStore.StationIsDeleted == true)
|
{
|
errMsg = stationName + "被禁用,不允许出库";
|
return false;
|
}
|
if (findStore.StationIsHasTaskDoing == true)
|
{
|
errMsg = stationName + "有任务被占用,不允许出库";
|
return false;
|
}
|
|
return true;
|
}
|
|
|
/// <summary>
|
/// 根据库位Id去清空库存(慎用!)
|
/// </summary>
|
/// <param name="placeId"></param>
|
public static void ClearStockByPlaceId(DbModel edm, Base_Station place, string remark)
|
{
|
try
|
{
|
if (place != null)
|
{
|
place.Remark = remark;
|
place.IsFull = false;
|
place.IsLock = false;
|
|
|
var cvps = edm.Base_Salver_V_Station.Where(x => x.StationId == place.Id);
|
|
|
List<Base_Salver_V_Station> removeCVP = new List<Base_Salver_V_Station>();
|
List<Base_Salver_V_Material> removeIVC = new List<Base_Salver_V_Material>();
|
|
#region 计算
|
|
if (cvps != null)
|
{
|
foreach (var cvp in cvps)
|
{
|
removeCVP.Add(cvp);
|
|
var cviList = edm.Base_Salver_V_Material.Where(x => x.SalverId == cvp.SalverId).ToList();
|
if (cviList != null)
|
{
|
foreach (var item in cviList)
|
{
|
removeIVC.Add(item);
|
}
|
}
|
|
}
|
}
|
|
#endregion
|
|
foreach (var item in removeCVP)
|
{
|
edm.Base_Salver_V_Station.Remove(item);
|
}
|
foreach (var item in removeIVC)
|
{
|
edm.Base_Salver_V_Material.Remove(item);
|
|
//删除物料表
|
var material = edm.Base_Material.Where(x => x.Id == item.MaterialId).FirstOrDefault();
|
if (material != null)
|
{
|
edm.Base_Material.Remove(material);
|
}
|
}
|
|
}
|
|
|
}
|
catch (Exception)
|
{
|
throw;
|
}
|
}
|
|
/// <summary>
|
/// 根据托盘号去清空库存(慎用!)
|
/// </summary>
|
/// <param name="placeId"></param>
|
public static void ClearStockBySalverCode(DbModel edm, Base_Salver salver, string remark)
|
{
|
try
|
{
|
if (salver != null)
|
{
|
var cvps = edm.Base_Salver_V_Station.Where(x => x.SalverCode == salver.SalverCode);
|
|
List<Base_Salver_V_Station> removeCVP = new List<Base_Salver_V_Station>();
|
List<Base_Salver_V_Material> removeIVC = new List<Base_Salver_V_Material>();
|
|
#region 计算
|
|
if (cvps != null && cvps.Count() > 0)
|
{
|
foreach (var cvp in cvps)
|
{
|
removeCVP.Add(cvp);
|
}
|
}
|
//增加 获取svm 数据加载 [Editby shaocx,2023-01-14]
|
var cviList = edm.Base_Salver_V_Material.Where(x => x.SalverId == salver.Id).ToList();
|
if (cviList != null)
|
{
|
foreach (var item in cviList)
|
{
|
removeIVC.Add(item);
|
}
|
}
|
|
|
#endregion
|
|
foreach (var item in removeCVP)
|
{
|
//查找Station,并处理Station
|
Base_Station station = edm.Base_Station.Where(x => x.Id == item.StationId).FirstOrDefault();
|
if (station != null)
|
{
|
station.Remark = remark;
|
station.IsFull = false;
|
station.IsLock = false;
|
}
|
|
edm.Base_Salver_V_Station.Remove(item);
|
}
|
foreach (var item in removeIVC)
|
{
|
edm.Base_Salver_V_Material.Remove(item);
|
|
//删除物料表
|
var material = edm.Base_Material.Where(x => x.Id == item.MaterialId).FirstOrDefault();
|
if (material != null)
|
{
|
edm.Base_Material.Remove(material);
|
}
|
}
|
|
}
|
|
|
}
|
catch (Exception)
|
{
|
throw;
|
}
|
}
|
|
}
|
}
|