using ServiceCenter.Extensions;
using ServiceCenter.SqlSugars;
using SqlSugar;
using System.ComponentModel;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.Station;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.WebApi.Controllers;
using WCS.WorkEngineering.WebApi.Models.WMS.Response;
using WCS.WorkEngineering.Worlds;
using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
using TaskStatus = WCS.Entity.TaskStatus;
namespace WCS.WorkEngineering.Systems
{
///
/// 环形库码垛区补空托盘任务生成
///
[BelongTo(typeof(PalletizingWorld))]
[Description("码垛区域生成空托盘任务")]
public class 码垛区域生成空托盘任务 : DeviceSystem>
{
protected override bool ParallelDo => true;
public override void Do(Device objDev)
{
var lastIsTruss = objDev.Entity.GetFlag("LastIsTruss");
objDev.Entity.SetFlag("LastIsTruss", !lastIsTruss);
if (lastIsTruss)
{
WCS_Palletizing palletizing = null;
SqlSugarHelper.Do(_db =>
{
var db = _db.Default;
//取一个时间最靠前的,没有绑定码垛工位的码垛记录
var palletizingInfoList = db.Queryable().Where(x => x.PalletizingStation == null && !x.Finish && !x.isItHalf).OrderBy(x => x.AddTime).ToList();
if (!palletizingInfoList.Any())
{
World.Log("没有码垛信息可用!");
return;
}
foreach (var palletizingInfo in palletizingInfoList)
{
if (palletizing != null) continue;
//获取可以使用的放货站台信息
var taskAddNext = Device.All.FirstOrDefault(x => x.Code == palletizingInfo.TaskAddNext)?.Targets.FirstOrDefault()?.Targets.Where(x => x.HasFlag(DeviceFlags.桁架码垛位));
if (taskAddNext == null)
{
World.Log($"未找到{palletizingInfo.TaskAddNext}可去的码垛工位:{palletizingInfo.Id}");
continue;
}
var devs = Device.All.Where(x => taskAddNext.Contains(x)).Select(x => new Device(x, World)).ToList();
//获取所有的未结束且有码垛工位的码垛记录
var palletizingStation = db.Queryable().Where(x => !x.Finish && x.PalletizingStation != null).Select(x => x.PalletizingStation).ToList();
//取一个可用用于码垛的地方
var dev = devs.Where(x => !palletizingStation.Contains(x.Entity.Code)).FirstOrDefault(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status));
if (dev == null)
{
World.Log("没有可用码垛工");
continue;
}
var addrFromCode = palletizingInfo.WarehouseCode switch
{
"1N" => "1602",
"1S" => "1612",
"2N" => "1622",
"2S" => "1632",
"3N" => "1642",
"3S" => "1652",
_ => "9999"
};
var endDev = Device.All.Where(x => x.Code == addrFromCode).Select(x => new Device(x, World)).FirstOrDefault();
if (endDev.Data.TaskNumber != 0 || endDev.Data.GoodsEnd != 0)
{
World.Log($"{endDev.Entity.Code}有残留任务信息{endDev.Data.TaskNumber}-{endDev.Data.GoodsEnd},请确认处理!");
continue;
}
palletizingInfo.PalletizingStation = dev.Entity.Code;
db.UpdateableRowLock(palletizingInfo).UpdateColumns(x => new { x.PalletizingStation }).ExecuteCommand();
palletizing = palletizingInfo;
}
});
if (palletizing == null) return;
var addrFromCode = palletizing.WarehouseCode switch
{
"1N" => "1602",
"1S" => "1612",
"2N" => "1622",
"2S" => "1632",
"3N" => "1642",
"3S" => "1652",
_ => "9999"
};
var dev = Device.All.Where(x => x.Code == addrFromCode).Select(x => new Device(x, World)).FirstOrDefault();
dev.Data.TaskNumber = palletizing.Id;
dev.Data.GoodsEnd = palletizing.PalletizingStation!.ToShort();
}
else
{
var devs = Device.All.Where(x => x.HasFlag(DeviceFlags.环形库码垛工位)).Select(x => new Device(x, World));
devs = devs.Where(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status));
WCS_TaskInfo deliveryTask = null;
foreach (var obj in devs)
{
if (deliveryTask != null)
{
continue;
}
SqlSugarHelper.Do(_db =>
{
var db = _db.Default;
//检查是否有待执行状态放货点是自己的出库任务
var ringTask = db.Queryable().NoLock().First(x => x.Type == TaskType.OutDepot && x.Status <= TaskStatus.WaitingToExecute && x.SrmStation == obj.Entity.Code);
if (ringTask == null)
{
var code = obj.Entity.Code.GetWareCode();
var wareHouse = db.Queryable().First(x => x.Code == code);
if (wareHouse == null)
{
World.Log($"无对应仓库--[{code}]");
return;
}
//检查是否有满跺记录
var ringPalletizingInfo = db.Queryable().Where(x => x.WareHouseId == wareHouse.Id && x.HaveQty > 0 && !x.Out).ToList()
.OrderBy(x => x.AddTime).FirstOrDefault(x => x.HaveQty == x.HWCountQty || x.AddTime < DateTime.Now.AddHours(-6));
if (ringPalletizingInfo == null)
{
World.Log("无满跺码垛信息");
return;
}
//开始申请码垛任务
var resData = WmsApi.ApplyPalletizingStockOut(obj.Entity.Code, obj.Entity.Sources.Single(x => x.HasFlag(DeviceFlags.Robot)).Code);
if (resData.ResCode != ResponseStatusCodeEnum.Sucess)
{
World.Log(resData.ResMsg,ServiceCenter.Logs.LogLevelEnum.Mid);
}
return;
}
var task = db.Queryable().NoLock().First(x => x.Type == TaskType.Delivery && x.AddrTo == obj.Entity.Code && x.Status < TaskStatus.Finish);
if (task != null) return;
//开始获取当前地址上个设备的上一个设备中的非零九托盘拆机
var addrFrom = obj.Entity.Sources.SelectMany(x => x.Sources).Single(x => x.HasFlag(DeviceFlags.拆盘机));
var dev = Device.All.Where(x => x.Code == addrFrom.Code).Select(x => new Device(x, World)).FirstOrDefault();
if (dev.Data.TaskNumber != 0 || dev.Data.GoodsEnd != 0)
{
World.Log($"{dev.Entity.Code}有残留任务信息 {dev.Data.TaskNumber} - {dev.Data.GoodsEnd} ,请确认处理!");
return;
}
//开始创建搬运任务
task = new WCS_TaskInfo()
{
AddrFrom = addrFrom.Code,
AddrTo = obj.Entity.Code,
BarCode = "码垛托盘搬运-" + obj.Entity.Code,
Status = Entity.TaskStatus.NewBuild,
PalletType = ringTask.PalletType,
FullQty = ringTask.FullQty,
Type = TaskType.Delivery,
AddWho = "WCS",
AddTime = DateTime.Now
};
var res = db.InsertableRowLock(task).ExecuteReturnEntity();
var taskOld = res.Mapper();
taskOld.Id = res.ID;
taskOld.AddTime = DateTime.Now;
db.InsertableRowLock(taskOld).SplitTable().ExecuteCommand();
res.AddWCS_TASK_DTL(db, obj.Entity.Code, task.AddrTo, "初始化码垛托盘搬运任务");
deliveryTask = res;
});
}
if (deliveryTask == null) return;
var dev = Device.All.Where(x => x.Code == deliveryTask.AddrFrom).Select(x => new Device(x, World)).FirstOrDefault();
dev.Data.TaskNumber = deliveryTask.ID;
dev.Data.GoodsEnd = deliveryTask.AddrTo.ToShort();
}
}
public override bool Select(Device dev)
{
return dev.Code == nameof(PalletizCreateEmptyTray);
}
}
//
// 摘要:
// 环形库码垛缓存信息
[Tenant("fj")]
[SugarTable("Bill_RingPalletizingInfo")]
public class BillRingPalletizingInfo : BaseModel
{
//
// 摘要:
// 仓库ID
[SugarColumn(IsNullable = false, ColumnDescription = "仓库ID")]
public long WareHouseId { get; set; }
//
// 摘要:
// 任务
[Navigate(NavigateType.OneToOne, "WareHouseId")]
public BaseWarehouse WareHouse { get; set; }
//
// 摘要:
// 垛形主表ID
[SugarColumn(IsNullable = false, ColumnDescription = "垛形主表ID")]
public long BomSetGrpId { get; set; }
//
// 摘要:
// 工字轮个数
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "工字轮个数")]
public int HWCountQty { get; set; }
//
// 摘要:
// BomCode(投料信息)/物料号
[SugarColumn(ColumnDataType = "nvarchar", Length = 200, IsNullable = false, ColumnDescription = "BomCode(投料信息)")]
public string BomCode { get; set; }
//
// 摘要:
// 已有工字轮个数
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "已有工字轮个数")]
public int HaveQty { get; set; }
//
// 摘要:
// 是否出库
[SugarColumn(IsNullable = false, ColumnDescription = "是否出库")]
public bool Out { get; set; }
//
// 摘要:
// 上一次分配时的放置位信息
[SugarColumn(ColumnDataType = "int", IsNullable = true)]
public int LastXYNO { get; set; }
}
//
// 摘要:
// 仓库表
[Tenant("fj")]
[SugarTable("Base_Warehouse")]
public class BaseWarehouse : BaseModel
{
//
// 摘要:
// 是否停用
[SugarColumn(ColumnDataType = "int", IsNullable = false)]
public int IsStop { get; set; }
//
// 摘要:
// 编号
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false)]
public string Code { get; set; }
//
// 摘要:
// 名称
[SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = false)]
public string Name { get; set; }
////
//// 摘要:
//// 类型
//[SugarColumn(IsNullable = false)]
//public FjLocationType TypeNum { get; set; }
//
// 摘要:
// ConfigId
[SugarColumn(ColumnName = "ConfigId", ColumnDescription = "ConfigId")]
public long ConfigId { get; set; }
}
}