using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_WCS.IRepositories;
|
using WIDESEA_WCS.Repositories;
|
using WIDESEA_Core.EFDbContext;
|
using WIDESEA_Entity.DomainModels;
|
using WIDESEA_Comm;
|
using static System.Collections.Specialized.BitVector32;
|
using WIDESEA_Comm.TaskNo;
|
using WIDESEA_Entity.ToAGV;
|
using WIDESEA_WCS.WCSClient;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
|
using WIDESEA_WMS.IRepositories;
|
using WIDESEA_WMS.Repositories;
|
using static FreeSql.Internal.GlobalFilter;
|
using WIDESEA_Comm.LogInfo;
|
|
namespace WIDESEA_WCS.JobsPart.Common
|
{
|
public class StationTask
|
{
|
|
/// <summary>
|
/// 创建入库任务
|
/// </summary>
|
public static void CreateTask()
|
{
|
try
|
{
|
VOLContext context = new VOLContext();
|
Idt_stationinfoRepository stationinfoRepository = new dt_stationinfoRepository(context);
|
Idt_mes_headRepository mes_HeadRepository = new dt_mes_headRepository(context);
|
Idt_agvtaskRepository agvtaskRepository = new dt_agvtaskRepository(context);
|
IVV_Mes_WorkinfoRepository workinfoRepository = new VV_Mes_WorkinfoRepository(context);
|
|
var Pipeline_client = PLCClient.Clients.FirstOrDefault(t => t.PLCName == "链条机");
|
if (Pipeline_client == null) throw new Exception("链条机调度服务未开启!");
|
if (!Pipeline_client.IsConnected) throw new Exception("与链条机连接超时!");
|
|
List<dt_stationinfo> stationinfos = stationinfoRepository.Find(x => x.stationCode.Contains("X") && x.enable && x.quantity > 0 && !string.IsNullOrEmpty(x.stationType) && !string.IsNullOrEmpty(x.Number)).ToList();
|
|
foreach (var item in stationinfos)
|
{
|
//判定任务是否已创建//如已存在
|
if (agvtaskRepository.Find(x => x.agv_fromaddress == item.stationCode).Any())
|
continue;
|
|
var PalletSignal = Pipeline_client.ReadByOrder<Int16>("R_PalletSignal", item.stationCode);//读取托盘信号:1:有,2无
|
var MaterialSignal = Pipeline_client.ReadByOrder<Int16>("R_MaterialSignal", item.stationCode);//读取货物信号:1:有,2无
|
if (PalletSignal != 1 || MaterialSignal != 1) continue;
|
|
//根据下料口的绑定信息查询对应工单,检测此工单是否已完成 完成即可将其送入库
|
|
var work = workinfoRepository.Find(x => x.workOrder == item.Number && x.drawingNo == x.drawingNo && x.heatID == item.heatNumber && x.processCode == "17").FirstOrDefault();
|
if (work == null)
|
{
|
item.remark = "触发入库任务,但未找到工单信息!";
|
item.location_state = LocationStateEnum.Abnormal.ToString();
|
stationinfoRepository.Update(item, true);
|
continue;
|
}
|
|
dt_stationinfo TargetLocation = null;
|
string tasktype = "";
|
if (item.quantity == 5 /*|| CompeletedNum == 0*/)
|
{
|
|
|
if (/*(mesinfo.quantity <= 50 &&*/ !string.IsNullOrEmpty(work.area) || item.stationCode.Contains("3"))
|
{
|
//todo 寻找可放货外协放货台
|
tasktype = "TaskType_OutsourceInbound";
|
TargetLocation = GetEmptyLocation(stationinfoRepository);
|
|
}
|
else
|
{
|
//todo: 调用WMS接口创建任务
|
tasktype = "TaskType_Inbound";
|
TargetLocation = GetLocation.GetEmptyLocation(stationinfoRepository, work, item);
|
}
|
if (TargetLocation != null)
|
{
|
dt_agvtask agvtask = new dt_agvtask()
|
{
|
agv_fromaddress = item.stationCode,
|
agv_id = Guid.NewGuid(),
|
agv_tasknum = IdenxManager.GetTaskNo("KH-", "WMS"),
|
agv_grade = 1,
|
agv_createtime = DateTime.Now,
|
agv_taskstate = "Create",
|
agv_materielid = item.stationType,
|
agv_qty = item.quantity,
|
agv_tasktype = tasktype,
|
agv_toaddress = TargetLocation.stationCode,
|
agv_userid = "系统",
|
bindSN = item.bindSN,
|
agv_worktype = Convert.ToInt32(work.processCode),
|
agv_materbarcode = work.materialCode,
|
agv_Traytype = item.tray_type,
|
jobID = item.Number,
|
agv_TrayStatus = item.tray_status
|
};
|
agvtaskRepository.Add(agvtask, true);
|
|
item.location_state = LocationStateEnum.InBusy.ToString();
|
stationinfoRepository.Update(item, true);
|
|
TargetLocation.location_state = LocationStateEnum.InBusy.ToString();
|
TargetLocation.stationType = agvtask.agv_materielid;
|
TargetLocation.heatNumber = item.heatNumber;
|
TargetLocation.billetID = item.billetID;
|
TargetLocation.Number = agvtask.jobID;
|
stationinfoRepository.Update(TargetLocation, true);
|
WriteDBLog.Success("创建入库任务", $"任务编号:{agvtask.agv_tasknum}", "PCS");
|
}
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
WriteDBLog.Error("创建入库任务", $"错误信息: {ex.Message}", "PCS");
|
}
|
|
}
|
|
/// <summary>
|
/// 获取空库位
|
/// </summary>
|
/// <param name="stationinfoRepository">库存</param>
|
/// <param name="workinfo">订单</param>
|
/// <param name="stationinfo">下料口信息</param>
|
/// <returns></returns>
|
public static dt_stationinfo GetEmptyLocation(Idt_stationinfoRepository stationinfoRepository, dt_mes_head mesinfo, dt_stationinfo stationinfo, int CompeletedNum, float e)
|
{
|
//放货位
|
dt_stationinfo TargetLocation = null;
|
|
#region 同类型放一行
|
//if (area1 == "1")
|
TargetLocation = stationinfoRepository.Find(x => x.stationType == mesinfo.drawingNo).FirstOrDefault();
|
|
//TargetLocation = stationinfoRepository.Find(x => x.stationType == mesinfo.drawingNo && x.area == area1).OrderByDescending(x => x.line).OrderBy(x => x.column).FirstOrDefault();
|
if (TargetLocation != null)
|
{
|
#region 同一行只允许一个任务
|
//var count = stationinfoRepository.Find(x => x.line == TargetLocation.line && x.enable && x.area == TargetLocation.area && x.location_state == LocationStateEnum.Busy.ToString()).ToList();
|
//if (count.Count > 0)
|
// return null;
|
#endregion
|
|
#region 出库任务优先,存在出库任务则不能入库
|
bool OutTask = false;
|
if (TargetLocation.area == "1")
|
{
|
TargetLocation = stationinfoRepository.Find(x => x.column == TargetLocation.column && x.area == TargetLocation.area && x.enable && x.location_state == LocationStateEnum.Empty.ToString()).OrderByDescending(x => x.line).FirstOrDefault();
|
if (TargetLocation != null)
|
OutTask = stationinfoRepository.Find(x => x.column == TargetLocation.column && x.area == TargetLocation.area && x.enable && x.location_state == LocationStateEnum.OutBusy.ToString()).Any();
|
if (OutTask)//这列存在出库任务,寻找一列空货位
|
TargetLocation = stationinfoRepository.Find(x => x.line == 2 && x.area == TargetLocation.area && x.enable && x.location_state == LocationStateEnum.Empty.ToString()).OrderBy(x => x.column).FirstOrDefault();
|
if (TargetLocation != null) return TargetLocation;
|
}
|
else
|
{
|
TargetLocation = stationinfoRepository.Find(x => x.line == TargetLocation.line && x.area == TargetLocation.area && x.enable && x.location_state == LocationStateEnum.Empty.ToString()).OrderBy(x => x.column).FirstOrDefault();
|
if (TargetLocation != null)
|
OutTask = stationinfoRepository.Find(x => x.line == TargetLocation.line && x.area == TargetLocation.area && x.location_state == LocationStateEnum.OutBusy.ToString()).Any();
|
//库内存在出库任务,重新开一行入库
|
if (OutTask)
|
TargetLocation = stationinfoRepository.Find(x => x.column == (TargetLocation.area == "2" ? 1 : 10) && x.area == TargetLocation.area && x.enable && x.location_state == LocationStateEnum.Empty.ToString()).OrderBy(x => x.line).FirstOrDefault();
|
if (TargetLocation != null) return TargetLocation;
|
}
|
|
#endregion
|
|
//TargetLocation = stationinfoRepository.Find(x => x.line == TargetLocation.line && x.area == TargetLocation.area && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.column).FirstOrDefault();
|
//if (TargetLocation != null)
|
// return TargetLocation;
|
}
|
#endregion
|
|
#region 根据订单数量来寻找对应库区且同物料类型库位
|
//if (workinfo.PlannedQuantity < 50) //库区1 物料类型多
|
//{
|
// dt_stationinfo station = stationinfoRepository.Find(x => x.stationType == stationinfo.stationType && x.area == "1").OrderByDescending(x => x.lastUpdateTime).FirstOrDefault();
|
// if (station != null)
|
// {
|
// //如存在同物料类型且在1行的库存则新入库的物料放至同列 不存在则寻找新行库位
|
// if (station.line == 1)
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == station.area && x.location_state == LocationStateEnum.Empty.ToString() && x.column == station.column && x.enable).OrderBy(x => x.line).ThenBy(x => x.column).FirstOrDefault();
|
// }
|
// TargetLocation = stationinfoRepository.Find(x => x.area == station.area && x.location_state == LocationStateEnum.Empty.ToString() && x.line == 1 && x.enable).OrderBy(x => x.line).ThenBy(x => x.column).FirstOrDefault();
|
// }
|
// else
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == "1" && x.location_state == LocationStateEnum.Empty.ToString() && x.line == 1 && x.enable).OrderBy(x => x.line).ThenBy(x => x.column).FirstOrDefault();
|
// }
|
//}
|
//else
|
//{
|
//int quantity = Convert.ToInt32(workinfo.PlannedQuantity);
|
//string area = GetArea(quantity);
|
|
//dt_materielinfo materielinfo = freeDB.Select<dt_materielinfo>().Where(x => x.materiel_id == stationinfo.stationType).First();
|
|
//if (materielinfo == null)
|
// throw new Exception($"无此物料类型{stationinfo.stationType}库区");
|
|
//string area = materielinfo.materiel_areaid.ToString();
|
|
//如存在同类型物料则放置同行库位 不存在则放置新行的第一列中
|
//dt_stationinfo station = stationinfoRepository.Find(x => x.stationType == stationinfo.stationType && x.area == area).OrderBy(x => x.lastUpdateTime).FirstOrDefault();
|
//if (station != null)
|
//{
|
// TargetLocation = stationinfoRepository.Find(x => x.area == station.area && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.line == station.line).OrderBy(x => x.column).FirstOrDefault();
|
// if (TargetLocation == null)
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == area && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.column == '1').OrderBy(x => x.line).FirstOrDefault();
|
// }
|
//}
|
//else
|
//{
|
// TargetLocation = stationinfoRepository.Find(x => x.area == area && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.column == '1').OrderBy(x => x.line).FirstOrDefault();
|
//}
|
|
//todo 如物料已满则放置其他库区
|
//if (TargetLocation == null)
|
//{
|
// stationinfoRepository.Find(x => x.area == area && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.column == '1').OrderBy(x => x.line).FirstOrDefault();
|
//}
|
//}
|
//if (TargetLocation == null)
|
//{
|
// throw new Exception("库位已满");
|
//}
|
|
//else if (workinfo.PlannedQuantity >= 50 && workinfo.PlannedQuantity < 110) //库区2
|
//{
|
// //如存在同类型物料则放置同行库位 不存在则放置新行的第一列中
|
// dt_stationinfo station = stationinfoRepository.Find(x => x.stationType == stationinfo.stationType && x.area == "2").OrderBy(x => x.lastUpdateTime).FirstOrDefault();
|
// if (station != null)
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == station.area && x.location_state == LocationStateEnum.Empty.ToString() && x.line == station.line).OrderBy(x => x.column).FirstOrDefault();
|
// }
|
// else
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == "2" && x.location_state == LocationStateEnum.Empty.ToString() && x.column == '1').OrderBy(x => x.line).FirstOrDefault();
|
// }
|
//}
|
//else if(workinfo.PlannedQuantity >= 110 && workinfo.PlannedQuantity < 180)
|
//{
|
|
//}
|
#endregion
|
|
VOLContext context = new VOLContext();
|
Idt_mes_detailRepository mes_DetailRepository = new dt_mes_detailRepository(context);
|
Idt_inventoryRepository inventoryRepository = new dt_inventoryRepository(context);
|
var detail = mes_DetailRepository.Find(x => x.jobID == mesinfo.jobID).FirstOrDefault();
|
if (detail == null)
|
{
|
stationinfo.remark = "触发入库任务,但未找到工单子表!";
|
stationinfo.location_state = LocationStateEnum.Abnormal.ToString();
|
stationinfoRepository.Update(stationinfo, true);
|
return null;
|
}
|
|
#region 查找库存
|
dt_inventory inventory = null;
|
if (detail.heatID != null)
|
{
|
inventory = inventoryRepository.Find(x => /*x.HeatNumber == detail.heatID &&*/ x.FigureNumber == mesinfo.drawingNo /*&& x.jobID == mesinfo.jobID*/).OrderByDescending(x => x.OnlineTime).FirstOrDefault();
|
}
|
else
|
{
|
inventory = inventoryRepository.Find(x => x.FigureNumber == mesinfo.drawingNo /*&& x.jobID == mesinfo.jobID*/).OrderByDescending(x => x.OnlineTime).FirstOrDefault();
|
}
|
#endregion
|
|
|
#region 根据库存查找可入库空货位
|
if (inventory != null)
|
{
|
var station = stationinfoRepository.FindFirst(x => x.stationCode == inventory.stationCode);
|
if (/*CompeletedNum <= 15 ||*/ station.area == "1")
|
{
|
TargetLocation = stationinfoRepository.Find(x => x.column == station.column && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == inventory.area).OrderByDescending(x => x.line).FirstOrDefault();
|
}
|
else
|
{
|
TargetLocation = stationinfoRepository.Find(x => x.line == station.line && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == inventory.area).OrderBy(x => x.column).FirstOrDefault();
|
}
|
if (TargetLocation != null) return TargetLocation;
|
}
|
#endregion
|
|
|
|
var area1 = string.IsNullOrEmpty(mesinfo.area) ? GetArea(mesinfo.quantity, e) : mesinfo.area;
|
|
if (CompeletedNum <= 15 || area1 == "1")
|
{
|
TargetLocation = stationinfoRepository.Find(x => x.line == 2 && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == "1").OrderBy(x => x.column).FirstOrDefault();
|
}
|
else
|
{
|
//if (50 < mesinfo.quantity && mesinfo.quantity <= 180 && e < 1100)
|
// TargetLocation = stationinfoRepository.Find(x => x.column == 1 && x.area == "2" && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).FirstOrDefault();
|
//else if (180 < mesinfo.quantity && mesinfo.quantity <= 225 && e < 1100)
|
// TargetLocation = stationinfoRepository.Find(x => x.column == 1 && x.area == "3" && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).FirstOrDefault();
|
//if (50 < mesinfo.quantity && e > 1100 || TargetLocation == null)
|
|
//var area = GetArea(mesinfo.quantity, e);
|
|
|
TargetLocation = stationinfoRepository.Find(x => x.column == (area1 == "2" ? 1 : 10) && x.area == area1 && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).OrderBy(x => x.column).FirstOrDefault();
|
if (TargetLocation == null)
|
{
|
if (area1 == "2")
|
area1 = "3";
|
else if (area1 == "3")
|
area1 = "2";
|
TargetLocation = stationinfoRepository.Find(x => x.column == (area1 == "2" ? 1 : 10) && x.area == area1 && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).OrderBy(x => x.column).FirstOrDefault();
|
if (TargetLocation == null)
|
{
|
//TargetLocation = stationinfoRepository.Find(x => x.stationType == mesinfo.drawingNo && x.area == "1").OrderByDescending(x => x.column).FirstOrDefault();
|
|
//if (TargetLocation != null)
|
// TargetLocation = stationinfoRepository.Find(x => x.column == TargetLocation.column && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == "1").OrderByDescending(x => x.line).FirstOrDefault();
|
//if (TargetLocation == null)
|
// TargetLocation = stationinfoRepository.Find(x => x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == "1").OrderBy(x => x.column).OrderByDescending(x => x.line).FirstOrDefault();
|
if (TargetLocation == null)
|
TargetLocation = stationinfoRepository.Find(x => x.line == 2 && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == "1").OrderBy(x => x.column).FirstOrDefault();
|
|
}
|
|
}
|
|
//if (TargetLocation == null)
|
// TargetLocation = stationinfoRepository.Find(x => x.column == 1 && x.area == "4" && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).FirstOrDefault();
|
}
|
|
#region
|
|
//根据订单炉号/工单号/类型
|
//if (mesinfo.quantity >= 180)
|
//{
|
// //查询库存记录中是否存在同类型/工单/炉号的记录 如有则放置同一行,无则寻找新库位
|
// var detail = freeDB.Select<dt_mes_detail>().Where(x => x.jobID == mesinfo.jobID).First();
|
// var inventory = freeDB.Select<dt_inventory>().Where(x => x.HeatNumber == detail.heatID && x.FigureNumber == mesinfo.drawingNo && x.jobID == mesinfo.jobID).First();
|
// if (inventory != null)
|
// {
|
// //int line = Convert.ToInt16(inventory.stationCode.Split("-")[0]);
|
// var line = stationinfoRepository.FindFirst(x => x.stationCode == inventory.stationCode).line;
|
// TargetLocation = stationinfoRepository.Find(x => x.line == line && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == inventory.area).OrderBy(x => x.column).FirstOrDefault();
|
// if (TargetLocation == null && CompeletedNum <= 15)
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == "1" && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).ThenBy(x => x.column).FirstOrDefault();
|
// }
|
// }
|
// else
|
// {
|
// TargetLocation = stationinfoRepository.Find(x => x.area == "2" && x.location_state == LocationStateEnum.Empty.ToString() && x.enable).OrderBy(x => x.line).ThenBy(x => x.column).FirstOrDefault();
|
|
// }
|
//}
|
#endregion
|
|
if (TargetLocation == null)
|
{
|
throw new Exception("库位已满");
|
}
|
return TargetLocation;
|
}
|
/// <summary>
|
/// 临时使用
|
/// </summary>
|
/// <param name="stationinfoRepository"></param>
|
/// <returns></returns>
|
public static dt_stationinfo GetEmptyLocation1(Idt_stationinfoRepository stationinfoRepository)
|
{
|
return stationinfoRepository.Find(x => x.line == 1 && x.location_state == LocationStateEnum.Empty.ToString() && x.enable && x.area == "3").OrderBy(x => x.column).FirstOrDefault();//行和区域需写死
|
}
|
/// <summary>
|
/// 去外协
|
/// </summary>
|
/// <param name="stationinfoRepository"></param>
|
/// <returns></returns>
|
/// <exception cref="Exception"></exception>
|
public static dt_stationinfo GetEmptyLocation(Idt_stationinfoRepository stationinfoRepository)
|
{
|
dt_stationinfo TargetLocation = null;
|
List<string> target = new List<string>() { "W01001003", "W01001002", "W01001001" };
|
var Pipeline_client = PLCClient.Clients.FirstOrDefault(t => t.PLCName == "链条机");
|
if (Pipeline_client == null) throw new Exception("链条机调度服务未开启!");
|
if (!Pipeline_client.IsConnected) throw new Exception("与链条机连接超时!");
|
foreach (var item in target)
|
{
|
TargetLocation = stationinfoRepository.Find(x => x.stationCode == item && x.location_state == "Empty" /*LocationStateEnum.Empty.ToString()*/ && x.enable).FirstOrDefault();
|
|
var PalletSignal = Pipeline_client.ReadByOrder<Int16>("R_PalletSignal", item);//读取托盘信号:1:有,2无
|
var MaterialSignal = Pipeline_client.ReadByOrder<Int16>("R_MaterialSignal", item);//读取货物信号:1:有,2无
|
if (TargetLocation != null && PalletSignal == 2 && MaterialSignal == 2) return TargetLocation;
|
}
|
|
if (TargetLocation == null)
|
{
|
throw new Exception("外协入库口已满");
|
}
|
return TargetLocation;
|
}
|
/// <summary>
|
/// 根据订单数量返回库区(暂时弃用) //更换为库位类型匹配
|
/// </summary>
|
/// <param name="quantity"></param>
|
/// <returns></returns>
|
private static string GetArea(int quantity, float e)
|
{
|
if (e < 1100)
|
{
|
if (quantity <= 180)
|
return "2";
|
else /*if (quantity <= 225)*/
|
return "3";
|
}
|
else
|
{
|
return "4";
|
}
|
|
//if (quantity > 50 && quantity <= 180 && e < 1100)
|
// return "2";
|
//else if (quantity > 180 && quantity <= 225 && e < 1100)
|
// return "3";
|
//else if (quantity > 50 && e > 1100)
|
// return "4";
|
//return null;
|
}
|
}
|
}
|