You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Aucma.Scada/Aucma.Scada.Business/OutStoreBusiness.cs

1021 lines
40 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Aucma.Scada.Model.domain;
using HighWayIot.Config;
using HighWayIot.Log4net;
using HighWayIot.Repository;
using HighWayIot.Repository.service;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Aucma.Scada.Business
{
/// <summary>
/// 出库业务逻辑
/// </summary>
public sealed class OutStoreBusiness
{
#region 单例实现
private static readonly Lazy<OutStoreBusiness> lazy = new Lazy<OutStoreBusiness>(() => new OutStoreBusiness());
public static OutStoreBusiness Instance
{
get
{
return lazy.Value;
}
}
#endregion
#region 对象引用
private LogHelper logHelper = LogHelper.Instance;
private AppConfig appConfig = AppConfig.Instance;
private RegisterServices registerServices = RegisterServices.Instance;
private AssemblyPlanBusiness assemblyPlanBusiness = AssemblyPlanBusiness.Instance;
private OutStoreTaskHandle taskHandleBusiness = OutStoreTaskHandle.Instance;
#endregion
#region 接口引用
/// <summary>
/// 货道信息
/// </summary>
private IBaseSpaceInfoService _spaceInfoService;
/// <summary>
/// 实时任务
/// </summary>
private IRealTaskInfoService _taskInfoService;
/// <summary>
/// BOM信息
/// </summary>
private IBaseBomInfoService _bomInfoService;
/// <summary>
/// 货道明细
/// </summary>
private IBaseSpaceDetailService _spaceDetailService;
private IExecutePlanInfoService _executePlanInfoService;
private IProductPlanInfoService _productPlanInfoService;
private IRecordOutStoreService _recordOutStoreService;
private IRecordProductfinishService _recordProductfinishService;
#endregion
#region 委托事件
/// <summary>
/// 初始化出库任务
/// </summary>
/// <param name="message"></param>
public delegate void RefreshOutStoreTask(RealTaskInfo taskInfos);
public event RefreshOutStoreTask RefreshOutStoreTaskEvent;
/// <summary>
/// 扫码信息刷新
/// </summary>
/// <param name="materialCode"></param>
/// <param name="materialName"></param>
/// <param name="spaceName"></param>
/// <param name="storeCode"></param>
public delegate void RefreshScanMateriaCode(string materialCode, string materialName, string spaceName, string storeCode);
public event RefreshScanMateriaCode RefreshScanMateriaCodeEvent;
/// <summary>
/// 日志信息刷新
/// </summary>
/// <param name="message"></param>
public delegate void RefreshLogMessage(string message);
public event RefreshLogMessage RefreshLogMessageEvent;
public delegate void RefreshAssemblyPlanInit(int isFlag = 0);
public event RefreshAssemblyPlanInit RefreshAssemblyPlanInitEvent;
public delegate Task RefreshStoreStock();
public event RefreshStoreStock RefreshStoreStockEvent;
#endregion
private OutStoreBusiness()
{
try
{
_spaceInfoService = registerServices.GetService<IBaseSpaceInfoService>();
_taskInfoService = registerServices.GetService<IRealTaskInfoService>();
_bomInfoService = registerServices.GetService<IBaseBomInfoService>();
_spaceDetailService = registerServices.GetService<IBaseSpaceDetailService>();
_executePlanInfoService = registerServices.GetService<IExecutePlanInfoService>();
_productPlanInfoService = registerServices.GetService<IProductPlanInfoService>();
_recordOutStoreService = registerServices.GetService<IRecordOutStoreService>();
_recordProductfinishService = registerServices.GetService<IRecordProductfinishService>();
assemblyPlanBusiness.NextPassExecutePlanInfoEvent += PlanHandleAsync;
taskHandleBusiness.OutStoreAnswerEvent += OutStoreAnswer;
taskHandleBusiness.OutStoreFinsihEvent += OutStoreFinish;
taskHandleBusiness.UpdateMesPlanCompleteEvent += UpdatePlanInfo;
StartPassDown();
}
catch (Exception ex)
{
Console.WriteLine($"OutStoreBusiness异常{ex.Message}");
PrintLogErrorMessage($"OutStoreBusiness异常{ex.Message}");
Console.ReadLine();
}
}
private async Task PlanHandleAsync(ExecutePlanInfo planInfo)
{
await Task.Run(() =>
{
if (planInfo != null)
{
//var shellBomInfo = _bomInfoService.GetChildenBomInfoByMaterialCode(planInfo.materialCode, appConfig.shellMaterialType);
var shellBomInfo = _bomInfoService.GetBomInfoByMaterialCode(planInfo.materialCode);
var linerBomInfo = _bomInfoService.GetChildenBomInfoByMaterialCode(planInfo.materialCode, appConfig.linerMaterialType);
if (shellBomInfo != null && linerBomInfo != null)
{
for (int i = 0; i < planInfo.planAmount - planInfo.completeAmount; i++)
{
string taskCode = System.Guid.NewGuid().ToString("N").Substring(0, 10);
var shellSpaceInfo = GetSpaceInfoInAssem(appConfig.shellStoreCode, shellBomInfo.materialCode);
// GetSpaceInfoByMaterialType
var linerSpaceInfo = GetSpaceInfoInAssem(appConfig.linerStoreCode, linerBomInfo.materialCode);
//判断库存
if (shellSpaceInfo != null && linerSpaceInfo != null)
{
RealTaskInfo shell_task = CreateOutStoreTask(shellSpaceInfo, planInfo.executePlanCode, taskCode); //创建出库任务
if (shell_task != null)
{
PrintLogInfoMessage("箱壳出库计划创建成功");
}
else
{
PrintLogInfoMessage("箱壳出库计划创建失败");
assemblyPlanBusiness.autoFlag = false;
RefreshAssemblyPlanInitEvent?.Invoke(2);
}
RealTaskInfo liner_task = CreateOutStoreTask(linerSpaceInfo, planInfo.executePlanCode, taskCode); //创建出库任务
if (shell_task != null)
{
PrintLogInfoMessage("内胆出库计划创建成功");
}
else
{
PrintLogInfoMessage("内胆出库计划创建失败");
assemblyPlanBusiness.autoFlag = false;
RefreshAssemblyPlanInitEvent?.Invoke(2);
}
}
else
{
PrintLogInfoMessage($"组装计划:{planInfo.executePlanCode};出库失败,货道不匹配,未匹配到相同型号物料");
assemblyPlanBusiness.autoFlag = false;
}
// await Task.Delay(1000*2);
}
}
else
{
PrintLogInfoMessage($"物料:{planInfo.materialCode}获取Bom信息为空");
}
}
});
}
/// <summary>
/// 下达组装计划出库筛选货道
/// </summary>
/// <param name="storeCode"></param>
/// <param name="materialType"></param>
/// <returns></returns>
private BaseSpaceInfo GetSpaceInfoInAssem(string storeCode, string materialType)
{
BaseSpaceInfo result = null;
try
{
// 先查询当前每个货道出库任务数
List<RealTaskInfo> realList = _taskInfoService.GetTaskInfosByStoreCode(new string[] { appConfig.shellStoreCode, appConfig.linerStoreCode }, 2);
var spaceCodeCounts = realList
.GroupBy(x => x.spaceCode)
.Select(g => new { SpaceCode = g.Key, Count = g.Count() })
.ToList();
List<BaseSpaceInfo> info = _spaceInfoService.OutStoreGetSpaceInfoByMaterialCode(storeCode, materialType);
if (info != null)
{
if (info.Count > 0)
{
foreach (BaseSpaceInfo item in info)
{
var spaceInfo = taskHandleBusiness.ReadSpaceInfoByPlc(item);
item.spaceStock = spaceInfo.spaceStock;
item.outRouteAmount = spaceCodeCounts.FirstOrDefault(x => x.SpaceCode == item.spaceCode)?.Count ?? 0;
PrintLogInfoMessage($"通过PLC读取货道信息货道{spaceInfo.spaceName};在库数量:{item.spaceStock};货道状态:{item.spaceStatus}");
}
var list = info.Where(x => x.spaceStatus == 1 && x.spaceStock > 0 && x.unusualFlag == 1 && (x.spaceStock - x.outRouteAmount) > 0).ToList();
if (list.Count > 0)
{
result = list.OrderBy(x => x.spaceStock).First();
}
else
{
PrintLogInfoMessage("未获取到匹配的货道,请排查货道库存及货道状态是否可用");
}
}
}
}
catch (Exception ex)
{
PrintLogErrorMessage("货道信息读取异常", ex);
}
return result;
}
/// <summary>
/// 接收下达的组装计划根据BOM获取需要出库的箱壳、内胆物料信息
/// </summary>
/// <param name="planInfo"></param>
private void PlanHandle(ExecutePlanInfo planInfo)
{
lock (string.Empty)
{
Task.Run(() =>
{
if (planInfo != null)
{
//var shellBomInfo = _bomInfoService.GetChildenBomInfoByMaterialCode(planInfo.materialCode, appConfig.shellMaterialType);
var shellBomInfo = _bomInfoService.GetBomInfoByMaterialCode(planInfo.materialCode);
var linerBomInfo = _bomInfoService.GetChildenBomInfoByMaterialCode(planInfo.materialCode, appConfig.linerMaterialType);
if (shellBomInfo != null && linerBomInfo != null)
{
for (int i = 0; i < planInfo.planAmount - planInfo.completeAmount; i++)
{
string taskCode = System.Guid.NewGuid().ToString("N").Substring(0, 10);
//RealTaskInfo shellTask = OutStore(appConfig.shellStoreCode, shellBomInfo, planInfo.executePlanCode, taskCode);
//Thread.Sleep(500);
//RealTaskInfo linerTask = OutStore(appConfig.linerStoreCode, linerBomInfo, planInfo.executePlanCode, taskCode);
//Thread.Sleep(500);
var shellSpaceInfo = GetSpaceInfoByMaterialType(appConfig.shellStoreCode, shellBomInfo.materialCode);
Thread.Sleep(100);
var linerSpaceInfo = GetSpaceInfoByMaterialType(appConfig.linerStoreCode, linerBomInfo.materialCode);
Thread.Sleep(100);
//判断库存
if (shellSpaceInfo != null && linerSpaceInfo != null)
{
RealTaskInfo shell_task = CreateOutStoreTask(shellSpaceInfo, planInfo.executePlanCode, taskCode); //创建出库任务
if (shell_task != null)
{
PrintLogInfoMessage("箱壳出库计划创建成功");
}
else
{
PrintLogInfoMessage("箱壳出库计划创建失败");
assemblyPlanBusiness.autoFlag = false;
RefreshAssemblyPlanInitEvent?.Invoke(2);
}
Thread.Sleep(100);
RealTaskInfo liner_task = CreateOutStoreTask(linerSpaceInfo, planInfo.executePlanCode, taskCode); //创建出库任务
if (shell_task != null)
{
PrintLogInfoMessage("内胆出库计划创建成功");
}
else
{
PrintLogInfoMessage("内胆出库计划创建失败");
assemblyPlanBusiness.autoFlag = false;
RefreshAssemblyPlanInitEvent?.Invoke(2);
}
}
else
{
PrintLogInfoMessage($"组装计划:{planInfo.executePlanCode};出库失败,货道不匹配,未匹配到相同型号物料");
assemblyPlanBusiness.autoFlag = false;
}
// Thread.Sleep(1000*2);
}
}
else
{
PrintLogInfoMessage($"物料:{planInfo.materialCode}获取Bom信息为空");
}
}
});
}
}
/// <summary>
/// 解析计划创建出库任务
/// </summary>
/// <param name="storeCode"></param>
/// <param name="bomInfo"></param>
/// <param name="planCode"></param>
private RealTaskInfo OutStore(string storeCode, BaseBomInfo bomInfo, string planCode, string taskCode)
{
try
{
PrintLogInfoMessage($"收到出库计划,物料码:{bomInfo.materialCode}");
BaseSpaceInfo spaceInfo = GetSpaceInfoByMaterialType(storeCode, bomInfo.materialCode);
if (spaceInfo != null)
{
PrintLogInfoMessage($"匹配货道:{spaceInfo.spaceName}");
RealTaskInfo task = CreateOutStoreTask(spaceInfo, planCode, taskCode); //创建出库任务
if (task != null)
{
PrintLogInfoMessage("出库任务创建成功");
return task;
}
else
{
PrintLogInfoMessage("出库任务创建失败");
return null;
}
}
else
{
//报警停线
PrintLogInfoMessage($"{storeCode};仓库内未获取到{bomInfo.materialCode}相匹配的物料及货道");
return null;
}
}
catch (Exception ex)
{
PrintLogErrorMessage("出库业务异常", ex);
return null;
}
}
/// <summary>
/// 创建出库任务
/// </summary>
/// <param name="spaceInfo"></param>
private RealTaskInfo CreateOutStoreTask(BaseSpaceInfo spaceInfo, string planCode, string taksCode, int taskModel = 0, int emptyDetailFlag = 0)
{
bool result = false;
try
{
#region Delete By wenjy 2024-03-16 14:43:00 取消通过货道明细创建出库惹怒
//获取出库的货道明细物料信息
//string type = emptyDetailFlag == 1 ? "1111111111" : spaceInfo.materialType;
//BaseSpaceDetail spaceDetail = GetSpaceDetailFirstOrderByCreatTime(spaceInfo,type);
//if (spaceDetail != null)
//{
// List<BaseSpaceDetail> emptyList = GetAllFrontEmptySpaceDetail(spaceDetail);
// if (emptyList!=null && emptyList.Count > 0)
// { // 判断要出的货道明细前面是否有空板,有的话先给前面所有空板递归创建任务
// for(int i = 0; i < emptyList.Count; i++)
// {
// CreateOutStoreTask(spaceInfo, System.Guid.NewGuid().ToString("N"), System.Guid.NewGuid().ToString("N"), taskModel,1);
// }
// }
//}
//else
//{
// PrintLogInfoMessage("出库任务创建失败,该类型货道明细为空");
//}
#endregion
#region 出库任务赋值
RealTaskInfo realTaskInfo = new RealTaskInfo();
realTaskInfo.planCode = planCode;
realTaskInfo.taskType = 2;
realTaskInfo.taskCode = taksCode;
realTaskInfo.taskModel = taskModel;
realTaskInfo.storeCode = spaceInfo.storeCode;
realTaskInfo.spaceCode = spaceInfo.spaceCode;
realTaskInfo.spaceName = spaceInfo.spaceName;
realTaskInfo.materialType = spaceInfo.materialType;
//realTaskInfo.materialCode = spaceDetail.materialCode;
realTaskInfo.planAmount = 1;
realTaskInfo.taskStatus = 1;
realTaskInfo.createTime = DateTime.Now;
//realTaskInfo.detailCode = spaceDetail.detailCode;
#endregion
result = _taskInfoService.AddTaskInfo(realTaskInfo);
if (result)
{
PrintLogInfoMessage("出库任务创建成功");
RefreshOutStoreTaskEvent?.Invoke(realTaskInfo);
spaceInfo.outRouteAmount += 1;
_spaceInfoService.UpdateSpaceInfo(spaceInfo);
return realTaskInfo;
}
else
{
PrintLogInfoMessage("出库任务创建失败");
}
}
catch (Exception ex)
{
PrintLogErrorMessage("出库任务创建异常", ex);
}
return null;
}
/// <summary>
/// 根据创建时间获取第一个该型号的货道明细
/// </summary>
/// <param name="spaceInfo"></param>
/// <returns></returns>
private BaseSpaceDetail GetSpaceDetailFirstOrderByCreatTime(BaseSpaceInfo spaceInfo, string type)
{
BaseSpaceDetail spaceDetail = null;
try
{
List<BaseSpaceDetail> spaceDetails = _spaceDetailService.GetSpaceDetailsBySpaceCode(spaceInfo.storeCode, spaceInfo.spaceCode);
if (spaceDetails.Count > 0)
{
spaceDetails = spaceDetails.Where(x => x.isFlag != 1 && x.materialType == type).ToList();
if (spaceDetails.Count > 0)
{
spaceDetail = spaceDetails.OrderBy(x => x.createTime).First();
}
}
}
catch (Exception ex)
{
PrintLogErrorMessage("获取货道明细信息异常", ex);
}
return spaceDetail;
}
#region 轮询获取出库任务下发至PLC等待PLC执行反馈完成后再次下发
private SemaphoreSlim semaphore = new SemaphoreSlim(0);
private int completedTasks = 0;
private int taskAmount = 2;
private SemaphoreSlim shellSemaphore = new SemaphoreSlim(0);
private SemaphoreSlim linerSemaphore = new SemaphoreSlim(0);
private void StartPassDown1()
{
Thread shellOutThread = new Thread(() =>
{
while (true)
{
Console.WriteLine("箱壳出库线程任务下发");
PassDownShellTask();
Thread.Sleep(2000);
}
});
Thread linerOutThread = new Thread(() =>
{
while (true)
{
Console.WriteLine("内胆出库线程任务下发");
PassDownLinerTask();
Thread.Sleep(2000);
}
});
shellOutThread.Start();
linerOutThread.Start();
}
private void StartPassDown()
{
Task.Run(() =>
{
while (true)
{
Console.WriteLine("箱壳出库线程任务下发");
PassDownShellTask();
Thread.Sleep(2000);
}
});
Task.Run(() =>
{
while (true)
{
Console.WriteLine("内胆出库线程任务下发");
PassDownLinerTask();
Thread.Sleep(2000);
}
});
}
/// <summary>
/// 下传箱壳出库任务至PLC
/// </summary>
private void PassDownShellTask()
{
try
{
lock (string.Empty)
{
//获取箱壳出库任务
RealTaskInfo taskInfo = _taskInfoService.GetTaskInfoByStoreCode(appConfig.shellStoreCode, appConfig.outstoreTaskType);
if (taskInfo != null)
{
PrintLogInfoMessage($"下发箱壳出库任务:{taskInfo.taskCode};仓库{taskInfo.storeCode};货道:{taskInfo.spaceCode}");
int result = taskHandleBusiness.SendShellTask_OutStore(taskInfo);
if (result == 1)
{
PrintLogInfoMessage($"箱壳出库任务:{taskInfo.taskCode}下发成功等待PLC执行反馈");
// shellSemaphore.Wait(); //一直堵塞直到信号量释放
PrintLogInfoMessage($"箱壳入库任务:{taskInfo.taskCode};开始执行");
taskInfo.taskStatus = 2;
_taskInfoService.UpdateTaskInfo(taskInfo);
RefreshScanMateriaCodeEvent?.Invoke(taskInfo.materialCode, taskInfo.materialType, taskInfo.spaceName, taskInfo.storeCode);
}
else if (result == 2)
{
PrintLogInfoMessage("箱壳出库任务下发失败PLC接收任务未就绪");
}
else
{
PrintLogInfoMessage($"箱壳出库任务:{taskInfo.taskCode}下发失败请排除PLC连接");
}
}
else
{
// PrintLogInfoMessage("未获取到需要下发的箱壳出库任务");
}
}
}
catch (Exception ex)
{
PrintLogErrorMessage("下传箱壳出库任务逻辑处理异常", ex);
}
}
/// <summary>
/// 依次获取内胆任务队列进行下发
/// </summary>
private void PassDownLinerTask()
{
try
{
lock (string.Empty)
{
RealTaskInfo taskInfo = _taskInfoService.GetTaskInfoByStoreCode(appConfig.linerStoreCode, appConfig.outstoreTaskType);
if (taskInfo != null)
{
PrintLogInfoMessage($"下发内胆出库任务:{taskInfo.taskCode};仓库{taskInfo.storeCode};货道:{taskInfo.spaceCode}");
int result = taskHandleBusiness.SendLinerTask_OutStore(taskInfo);
if (result == 1)
{
PrintLogInfoMessage($"内胆出库任务:{taskInfo.taskCode}下发成功等待PLC执行反馈");
// linerSemaphore.Wait(); //一直堵塞直到信号量释放
PrintLogInfoMessage($"内胆出库任务:{taskInfo.taskCode};开始执行");
taskInfo.taskStatus = 2;
_taskInfoService.UpdateTaskInfo(taskInfo);
RefreshScanMateriaCodeEvent?.Invoke(taskInfo.materialCode, taskInfo.materialType, taskInfo.spaceName, taskInfo.storeCode);
}
else if (result == 2)
{
PrintLogInfoMessage("内胆出库任务下发失败PLC接收任务未就绪");
}
else
{
PrintLogInfoMessage($"内胆出库任务:{taskInfo.taskCode}下发失败请排除PLC连接");
}
}
else
{
// PrintLogInfoMessage("未获取到需要下发的内胆出库任务");
}
}
}
catch (Exception ex)
{
PrintLogErrorMessage("下传内胆出库任务逻辑处理异常", ex);
}
}
#endregion
#region PLC应答反馈
/// <summary>
/// 出库应答
/// </summary>
/// <param name="storeCode"></param>
/// <param name="taskCode"></param>
private void OutStoreAnswer(string storeCode, string taskCode)
{
if (storeCode == appConfig.shellStoreCode)
{
//Interlocked.Increment(ref completedTasks);
//CheckCompletedTasks();
PrintLogInfoMessage("箱壳应答成功,自动释放信号量,进行下发新任务");
// shellSemaphore.Release();
}
else
{
//Interlocked.Increment(ref completedTasks);
//CheckCompletedTasks();
PrintLogInfoMessage("内胆应答成功,自动释放信号量,进行下发新任务");
// linerSemaphore.Release();
}
}
/// <summary>
/// 出库完成
/// </summary>
/// <param name="storeCode"></param>
/// <param name="taskCode"></param>
private void OutStoreFinish(string storeCode, string taskCode)
{
if (storeCode == appConfig.shellStoreCode)
{
PrintLogInfoMessage($"箱壳任务:{taskCode};执行完成");
OutStoreFinishHandle(taskCode, appConfig.shellStoreCode);
}
else
{
PrintLogInfoMessage($"内胆任务:{taskCode};执行完成");
OutStoreFinishHandle(taskCode, appConfig.linerStoreCode);
}
}
/// <summary>
/// 信号量释放,根据任务完成数量,执行完成后进行释放
/// </summary>
private void CheckCompletedTasks()
{
if (completedTasks == taskAmount)
{
// 释放信号量
semaphore.Release();
}
}
#endregion
/// <summary>
/// 出库完成
/// </summary>
/// <param name="storeCode"></param>
/// <param name="spaceCode"></param>
/// <param name="materialType"></param>
private void OutStoreFinishHandle(string taskCode, string storeCode)
{
try
{
var taskInfo = _taskInfoService.GetTaskInfoByTaskCode(taskCode, storeCode);
if (taskInfo != null)
{
var spaceInfo = _spaceInfoService.GetSpaceInfoBySpaceCode(taskInfo.storeCode, taskInfo.spaceCode);
if (spaceInfo != null)
{
#region Add By wenjy 2023-10-30 13:44:00 通过PLC获取货道信息
var item = taskHandleBusiness.ReadSpaceInfoByPlc(spaceInfo);
spaceInfo.spaceStock = item.spaceStock;
spaceInfo.outRouteAmount = spaceInfo.outRouteAmount == 0 ? 0 : (spaceInfo.outRouteAmount - 1);
spaceInfo.spaceStatus = item.spaceStatus;
#endregion
if (spaceInfo.spaceStock == 0)
{
spaceInfo.materialType = string.Empty;
spaceInfo.typeNameA = string.Empty;
}
_spaceInfoService.UpdateSpaceInfo(spaceInfo);
#region 添加出库记录
RecordOutstore recordOutstore = new RecordOutstore();
recordOutstore.storeCode = taskInfo.storeCode;
recordOutstore.spaceCode = taskInfo.spaceCode;
recordOutstore.materialCode = taskInfo.materialCode;
recordOutstore.materialType = taskInfo.materialType;
recordOutstore.materialName = GetMaterialName(taskInfo.materialType);
recordOutstore.outStoreAmount = 1;
recordOutstore.outStoreTime = DateTime.Now;
_recordOutStoreService.InsertReocrdOutStoreService(recordOutstore);
#endregion
}
RefreshStoreStockEvent?.Invoke();
//更新任务状态
// taskInfo.taskStatus = 3;
// _taskInfoService.UpdateTaskInfo(taskInfo);
_taskInfoService.DeleteTaskInfoById(taskInfo.objId);
//刷新界面
RefreshAssemblyPlanInitEvent?.Invoke();
RefreshScanMateriaCodeEvent?.Invoke(string.Empty, string.Empty, string.Empty, taskInfo.storeCode);
}
}
catch (Exception ex)
{
PrintLogErrorMessage("出库完成逻辑处理异常", ex);
}
}
/// <summary>
/// 更新计划信息
/// </summary>
/// <param name="planCode"></param>
public void UpdatePlanInfo(string planCode)
{
try
{
var executeInfo = _executePlanInfoService.GetExecutePlanInfoByPlanCode(planCode);
if (executeInfo != null)
{
executeInfo.completeAmount += 1;
if (executeInfo.completeAmount == executeInfo.planAmount)
{
executeInfo.executeStatus = 3;
}
_executePlanInfoService.UpdateExecutePlanInfo(executeInfo);
var productInfo = _productPlanInfoService.GetProductPlanByPlanCode(executeInfo.productPlanCode);
if (productInfo != null)
{
productInfo.completeAmount += 1;
if (productInfo.completeAmount == productInfo.planAmount)
{
productInfo.endTime = DateTime.Now;
}
_productPlanInfoService.UpdateProductPlanInfo(productInfo);
}
#region 添加完成记录
RecordProductfinish productfinish = new RecordProductfinish();
productfinish.planCode = executeInfo.executePlanCode;
productfinish.productlineCode = appConfig.stationCode;
productfinish.materialCode = executeInfo.materialCode;
productfinish.completeAmount = 1; //目前一个箱体一个任务下发给plc
productfinish.recordTime = DateTime.Now;
_recordProductfinishService.InsertRecordProductfinish(productfinish);
#endregion
}
RefreshAssemblyPlanInitEvent?.Invoke();
}
catch (Exception ex)
{
PrintLogErrorMessage("计划信息更新异常", ex);
}
}
/// <summary>
/// 获取出库任务
/// </summary>
/// <returns></returns>
public List<RealTaskInfo> GetOutStoreTask()
{
var taskInfos = _taskInfoService.GetTaskInfosByStoreCode(new string[] { appConfig.shellStoreCode, appConfig.linerStoreCode }, appConfig.outstoreTaskType);
return taskInfos;
}
/// <summary>
/// 通过任务编号删除任务
///
/// 任务删除后是否需要还原库存,如果出库完成后减少库存则不需要
///
/// </summary>
/// <param name="taskCode"></param>
/// <returns></returns>
public bool DeleteTaskInfoByTaskCode(string taskCode, bool isFlag)
{
bool result = false;
var info = _taskInfoService.GetTaskInfosByTaskCode(taskCode);
if (info != null && info.Count > 0)
{
RealTaskInfo taskInfo = info[0];
//foreach(var taskInfo in info)
//{
//if(taskInfo.taskStatus == 2)
//{
// PrintLogInfoMessage("任务正在执行中不运行删除");
// continue;
//}
result = _taskInfoService.DeleteTaskInfoById(taskInfo.objId);
if (result)
{
var spaceDetailInfo = _spaceDetailService.GetSpaceDetailByMaterialCode(taskInfo.spaceCode, taskInfo.materialCode, taskInfo.detailCode);
if (spaceDetailInfo != null)
{
if (!isFlag)
{
spaceDetailInfo.isFlag = 0;
_spaceDetailService.UpdateSpaceDetail(spaceDetailInfo);
}
else
{
_spaceDetailService.DeleteSpaceDetailByMaterialCode(spaceDetailInfo.spaceCode, spaceDetailInfo.materialCode, spaceDetailInfo.detailCode);
}
}
// }
}
}
return result;
}
/// <summary>
/// 根据货道手动出一个
/// </summary>
/// <param name="storeCode"></param>
/// <param name="spaceCode"></param>
/// <returns></returns>
public bool OutOnlyOneBySpaceCode(string storeCode, string spaceCode)
{
bool result = false;
try
{
BaseSpaceInfo spaceInfo = _spaceInfoService.GetSpaceInfoBySpaceCode(storeCode, spaceCode);
if (spaceInfo.spaceStock > 0)
{
RealTaskInfo task = this.CreateOutStoreTask(spaceInfo, System.Guid.NewGuid().ToString("N"), System.Guid.NewGuid().ToString("N"), 1);
if (task != null)
result = true;
}
else
{
PrintLogInfoMessage($"仓库:{storeCode};货道:{spaceCode};出一个失败:库存不足");
}
}
catch (Exception ex)
{
logHelper.Error("根据货道出一个异常", ex);
}
return result;
}
/// <summary>
/// 手动释放信号量
/// </summary>
/// <param name="sph"></param>
private void GetAllRelese(Semaphore sph)
{
bool res = sph.WaitOne(1, false);
if (res)
{
GetAllRelese(sph);
}
}
/// <summary>
/// 通过BOM获取物料名称
/// </summary>
/// <param name="materialType"></param>
/// <returns></returns>
public string GetMaterialName(string materialType)
{
string materialName = string.Empty;
var info = _bomInfoService.GetBomInfoByMaterialCode(materialType);
if (info != null)
{
materialName = info.materialName;
}
if (materialName == "1111111111") materialName = "空板";
return materialName;
}
#region 通过PLC读取货道信息
/// <summary>
/// 通过PLC读取货道信息在库数量、货道状态)
/// </summary>
/// <param name="storeCode"></param>
/// <param name="materialType"></param>
/// <returns></returns>
private BaseSpaceInfo GetSpaceInfoByMaterialType(string storeCode, string materialType)
{
BaseSpaceInfo result = null;
try
{
List<BaseSpaceInfo> info = _spaceInfoService.OutStoreGetSpaceInfoByMaterialCode(storeCode, materialType);
if (info != null)
{
if (info.Count > 0)
{
foreach (BaseSpaceInfo item in info)
{
var spaceInfo = taskHandleBusiness.ReadSpaceInfoByPlc(item);
item.spaceStock = spaceInfo.spaceStock;
PrintLogInfoMessage($"通过PLC读取货道信息货道{spaceInfo.spaceName};在库数量:{item.spaceStock};货道状态:{item.spaceStatus}");
}
var list = info.Where(x => x.spaceStatus == 1 && x.spaceStock > 0 && x.unusualFlag == 1).ToList(); // && (x.spaceStock - x.outRouteAmount) > 0
if (list.Count > 0)
{
result = info.OrderBy(x => x.spaceStock).First();
}
else
{
PrintLogInfoMessage("未获取到匹配的货道,请排查货道库存及货道状态是否可用");
}
}
}
}
catch (Exception ex)
{
PrintLogErrorMessage("货道信息读取异常", ex);
}
return result;
}
#endregion
#region 日志输出
/// <summary>
/// 日志输出,界面刷新同时记录文件
/// </summary>
/// <param name="message"></param>
private void PrintLogInfoMessage(string message)
{
RefreshLogMessageEvent?.Invoke(message);
logHelper.Info(message);
}
/// <summary>
/// 异常日志输出
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
private void PrintLogErrorMessage(string message, Exception ex = null)
{
logHelper.Error(message, ex);
RefreshLogMessageEvent?.Invoke(message);
}
#endregion
}
}