using ServiceCenter.Extensions;
using ServiceCenter.Logs;
using ServiceCenter.Redis;
using ServiceCenter.SqlSugars;
using SqlSugar;
using SqlSugar.Extensions;
using System.Text;
using WCS.Core;
using WCS.Entity;
using TaskStatus = WCS.Entity.TaskStatus;
namespace WCS.WorkEngineering.Extensions
{
///
/// 任务扩展
///
public static class TaskExtension
{
///
/// 更新任务执行记录
/// 同步更新历史任务
///
/// 任务信息
/// 数据库上下文
/// 当前地址
/// 描述
public static void AddWCS_TASK_DTL(this WCS_TaskInfo task, SqlSugarScopeProvider db, string curPoint, string desc) => task.AddWCS_TASK_DTL(db, curPoint, "", desc);
///
/// 更新任务执行记录
/// 同步更新历史任务
///
/// 任务信息
/// 数据库上下文
/// 当前地址
/// 下一个地址
/// 描述
public static void AddWCS_TASK_DTL(this WCS_TaskInfo task, SqlSugarScopeProvider db, string curPoint, string nextPoint, string desc)
{
db.InsertableRowLock(new WCS_TaskDtl
{
ID = Guid.NewGuid(),
ParentTaskCode = task.ID,
CurPoint = curPoint,
NextPoint = nextPoint,
Desc = desc,
AddWho = "WCS"
}).SplitTable().ExecuteCommand();
task.UpdateableOldTask(db);
}
///
/// 更新任务执行记录
/// 同步更新历史任务
///
/// 任务信息
/// 数据库上下文
/// 当前地址
/// 描述
public static void AddWCS_TASK_DTL(this WCS_TaskOld task, SqlSugarScopeProvider db, string curPoint, string desc) => task.AddWCS_TASK_DTL(db, curPoint, "", desc);
///
/// 更新任务执行记录
/// 同步更新历史任务
///
/// 任务信息
/// 数据库上下文
/// 当前地址
/// 下一个地址
/// 描述
public static void AddWCS_TASK_DTL(this WCS_TaskOld task, SqlSugarScopeProvider db, string curPoint, string nextPoint, string desc)
{
db.Insertable(new WCS_TaskDtl
{
ID = Guid.NewGuid(),
ParentTaskCode = task.Id,
CurPoint = curPoint,
NextPoint = nextPoint,
Desc = desc,
AddWho = "WCS"
}).SplitTable().ExecuteCommand();
}
///
/// 更新历史表数据
///
///
///
public static void UpdateableOldTask(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
{
if (taskInfo.Status == TaskStatus.NewBuild) return;
// 同步任务信息
var taskOld = db.Queryable().Where(v => v.Id == taskInfo.ID).SplitTable(tabs => tabs.Take(2)).ToList().OrderByDescending(v => v.AddTime).First();
if (taskOld is not null)
{
if (taskInfo.Status >= TaskStatus.Finish) taskInfo.CompleteOrCancelTasks(db);
else
{
taskOld = taskInfo.Mapper();
taskOld.Id = taskInfo.ID;
db.UpdateableRowLock(taskOld).Where(x => x.Id == taskOld.Id).SplitTable(tabs => tabs.Take(2)).ExecuteCommand();
}
}
else
{
throw new KnownException($"WCS_TaskOld表中不存在任务:{taskInfo.ID},无法执行WCS_TaskInfo与WCS_TaskOld同步动作", LogLevelEnum.Mid);
}
}
///
/// 完成或取消任务
///
///
///
public static void CompleteOrCancelTasks(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
{
if (taskInfo.Status is not Entity.TaskStatus.Finish and not Entity.TaskStatus.Cancel) throw new KnownException("任务未完成或取消,无法执行WCS_TaskInfo与WCS_TaskOld同步动作", LogLevelEnum.Mid);
// 任务完成或取消,进行相关同步动作
var taskOld = db.Queryable().Where(v => v.Id == taskInfo.ID).SplitTable(tabs => tabs.Take(2)).ToList().OrderByDescending(v => v.AddTime).First();
if (taskOld is not null)
{
taskOld = taskInfo.Mapper();
taskOld.Id = taskInfo.ID;
//更新任务历史表,删除任务当前表
db.UpdateableRowLock(taskOld).Where(x => x.Id == taskOld.Id).SplitTable(tabs => tabs.Take(2)).ExecuteCommand();
db.DeleteableRowLock(taskInfo).ExecuteCommand();
}
else
{
throw new KnownException($"WCS_TaskOld表中不存在任务:{taskInfo.ID},无法执行WCS_TaskInfo与WCS_TaskOld同步动作", LogLevelEnum.Mid);
}
}
///
/// 更新表数据
///
///
///
public static void Updateable(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
{
}
/////
///// 获取出库任务
/////
///// 任务
///// db
///// 可用出库站台
///// 楼层
///// 堆垛机
///// 递归次数
/////
/////
//public static WCS_TaskInfo GetOutTask(this WCS_TaskInfo taskInfo, SqlSugarHelper db, List allOutCode, int floor, SRM obj, int index = 1)
//{
// return task;
//}
///
/// 获取AGV任务ID
///
/// db
///
public static int GetAgvTaskId(this SqlSugarHelper db)
{
//最多任务号不再连续
var id = db.Default.Queryable().NoLock().SplitTable(v => v.Take(2)).Max(v => v.ID);
return id + 1;
}
///
/// 更新任务执行记录
///
/// 任务信息
public static void UpdateRedisHash(this WCS_TaskInfo task)
{
var key = $"Hash:{task.ID}";
if (task.Status >= TaskStatus.Finish)
{
RedisHub.WMS.Del(key);
}
else
{
RedisHub.WMS.HMSet(key, task.ToDic());
}
}
#region 工字轮支线分流
///
/// 初始化码垛信息
///
///
public static void InitStackStructure(this WCS_TaskInfo task, SqlSugarScopeProvider db, World world)
{
var billBomsetgrp = db.Queryable().Single(x => x.IsStop == 0 && x.BomCode.Contains(task.MatCode));
if (billBomsetgrp == null)
{
world.Log($"物料规格[{task.MatCode}]无可用码垛垛形");
return;
};
var billBomsetinfos = db.Queryable().Where(x => x.BomSetHdrId == billBomsetgrp.Id).ToList();
//开始构造垛形信息
var palletizing = new WCS_Palletizing()
{
Code = billBomsetgrp.Code,
ShortCode = billBomsetgrp.ShortCode,
ProMaterCode = billBomsetgrp.ProMaterCode,
TpTypeCode = billBomsetgrp.TpTypeCode,
LayerCountQty = 2,
StampType = billBomsetgrp.StampType,
Finish = false,
AddTime = DateTime.Now,
TaskId = task.ID,
WarehouseCode = task.WarehouseCode,
DeviceCode = task.Device
};
palletizing = db.InsertableRowLock(palletizing).ExecuteReturnEntity();
foreach (var item in billBomsetinfos.Where(x => x.IsEmpty == 0).GroupBy(x => x.Row).OrderBy(x => x.Key))
{
var layerNo = item.Key <= 6 ? 1 : 2;
//获取层信息
var palletizingLayer = db.Queryable().Single(x => x.PalletizingId == palletizing.Id && x.LayerNo == layerNo);
if (palletizingLayer == null)
{
palletizingLayer = new WCS_PalletizingLayer()
{
LayerNo = layerNo,
PalletizingId = palletizing.Id,
WarehouseCode = palletizing.WarehouseCode,
};
palletizingLayer = db.InsertableRowLock(palletizingLayer).ExecuteReturnEntity();
}
//获取行信息
var palletizingRow = db.Queryable().Single(x => x.PalletizingLayerId == palletizingLayer.Id && x.RowNo == item.Key);
if (palletizingRow == null)
{
palletizingRow = new WCS_PalletizingRow()
{
RowNo = item.Key,
PalletizingLayerId = palletizingLayer.Id,
PalletizingId = palletizing.Id,
WarehouseCode = palletizingLayer.WarehouseCode
};
palletizingRow = db.InsertableRowLock(palletizingRow).ExecuteReturnEntity();
}
//重新查询最新的数据
var layer = palletizingLayer;
palletizingLayer = db.Queryable().Single(x => x.Id == layer.Id);
var row = palletizingRow;
palletizingRow = db.Queryable().Single(x => x.Id == row.Id);
//构造位信息
foreach (var loc in item)
{
var palletizingLoc = db.Queryable().Single(x => x.PalletizingRowId == palletizingRow.Id && x.XYNo == loc.XYNo);
if (palletizingLoc == null)
{
palletizingLoc = new WCS_PalletizingLoc()
{
IsEmpty = loc.IsEmpty != 0,
XYNo = loc.XYNo,
MatCode = loc.MatCode,
SideNum = loc.SideNum,
SpoolType = loc.SpoolType,
TaskId = task.ID,
PalletizingRowId = palletizingRow.Id,
Finish = false,
WarehouseCode = palletizingRow.WarehouseCode
};
db.InsertableRowLock(palletizingLoc).ExecuteReturnEntity();
}
//同步是否混合料行
palletizingRow.IsMixRow = loc.IsMixRow != 0;
db.UpdateableRowLock(palletizingRow).ExecuteCommand();
}
//更新行信息
palletizingRow = db.Queryable().Includes(x => x.Locs).Single(x => x.Id == row.Id);
palletizingRow.QtyMaxCount = palletizingRow.Locs.Count(x => !x.IsEmpty);
palletizingRow.IsEmpty = palletizingRow.QtyMaxCount <= 0;
palletizingRow.MatCodeList = palletizingRow.Locs.Select(x => x.MatCode).ToList().GetMatList();
db.UpdateableRowLock(palletizingRow).ExecuteCommand();
//更新层信息
palletizingLayer = db.Queryable().Includes(x => x.Rows, l => l.Locs).Single(x => x.Id == layer.Id);
var count = palletizingLayer.Rows.Count(x => !x.IsEmpty); //计算所有不空数量
palletizingLayer.IsEmpty = count <= 0;
palletizingLayer.RowCountQty = palletizingLayer.Rows.Count;
palletizingLayer.Finish = false;
palletizingLayer.MatCodeList = palletizingLayer.Rows.SelectMany(x => x.Locs).Select(x => x.MatCode).ToList().GetMatList();
db.UpdateableRowLock(palletizingLayer).ExecuteCommand();
}
var palletizing1 = palletizing;
palletizing = db.Queryable().Includes(x => x.Layers, r => r.Rows, l => l.Locs).Single(x => x.Id == palletizing1.Id);
//计算垛形信息
var goods = palletizing.Layers.Select(x => x.Rows).SelectMany(x => x).Select(x => x.Locs).SelectMany(x => x).ToList();
palletizing.CountQty = goods.Count(x => !x.IsEmpty);
palletizing.MatCodeList = palletizing.Layers.SelectMany(x => x.Rows).SelectMany(x => x.Locs).Select(x => x.MatCode).ToList().GetMatList();
db.UpdateableRowLock(palletizing).ExecuteCommand();
}
public static string GetMatList(this List matList)
{
return matList.Distinct().Aggregate("", (current, mat) => current + $"[{mat}]");
}
///
/// 去除转义字符
///
///
///
public static string RemoveEscapeCharacters(this string? value)
{
return value.Trim('\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v').Trim();
}
#endregion 工字轮支线分流
public static string ToSqlString(this QuestDBInsertBuilder questDb)
{
if (questDb.IsNoInsertNull)
{
questDb.DbColumnInfoList = questDb.DbColumnInfoList.Where(it => it.Value != null).ToList();
}
var groupList = questDb.DbColumnInfoList.GroupBy(it => it.TableId).ToList();
var isSingle = groupList.Count() == 1;
string columnsString = string.Join(",", groupList.First().Select(it => questDb.Builder.GetTranslationColumnName(it.DbColumnName)));
if (isSingle)
{
string columnParametersString = string.Join(",", questDb.DbColumnInfoList.Select(it =>
{
var spk = questDb.Builder.SqlParameterKeyWord + it.DbColumnName;
//if (it.Value is DateTime)
//{
// return $"to_timestamp('{it.Value.ObjToString("yyyy-MM-ddTHH:mm:ss")}', 'yyyy-MM-ddTHH:mm:ss')";
//}
return questDb.GetDbColumn(it, spk);
}
));
questDb.ActionMinDate();
return string.Format(questDb.SqlTemplate, questDb.GetTableNameString, columnsString, columnParametersString);
}
else
{
StringBuilder batchInsetrSql = new StringBuilder();
int pageSize = 200;
int pageIndex = 1;
int totalRecord = groupList.Count;
int pageCount = (totalRecord + pageSize - 1) / pageSize;
while (pageCount >= pageIndex)
{
batchInsetrSql.AppendFormat(questDb.SqlTemplateBatch, questDb.GetTableNameString, columnsString);
int i = 0;
foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList())
{
var isFirst = i == 0;
if (isFirst)
{
batchInsetrSql.Append(questDb.SqlTemplateBatchUnion);
}
batchInsetrSql.Append("\r\n ( " + string.Join(",", columns.Select(it =>
{
if (it.InsertServerTime || it.InsertSql.HasValue())
{
return questDb.GetDbColumn(it, null);
}
object value = null;
if (it.Value is DateTime)
{
return $" cast('{it.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.ffffff")}' as timestamp)";
}
else if (it.Value is int || it.Value is long || it.Value is short || it.Value is short || it.Value is byte || it.Value is double)
{
return it.Value;
}
else if (it.Value is bool)
{
return it.Value.ObjToString().ToLower();
}
else
{
value = it.Value;
}
if (value == null || value == DBNull.Value)
{
return string.Format(questDb.SqlTemplateBatchSelect, "NULL");
}
return string.Format(questDb.SqlTemplateBatchSelect, "'" + value.ObjToString().ToSqlFilter() + "'");
})) + "),");
++i;
}
pageIndex++;
batchInsetrSql.Remove(batchInsetrSql.Length - 1, 1).Append("\r\n;\r\n");
}
return batchInsetrSql.ToString();
}
}
public static bool HasValue(this object thisValue)
{
if (thisValue == null || thisValue == DBNull.Value) return false;
return thisValue.ToString() != "";
}
}
///
/// 垛形位信息
///
public class StackPosInfo
{
///
/// 任务号
///
public int TaskNumber { get; set; }
///
/// 是否空置
///
public bool IsEmpty { get; set; }
///
/// 坐标号
///
public string XYNo { get; set; }
///
/// 物料编码
///
public string MatCode { get; set; }
///
/// 正反面
///
public int SideNum { get; set; }
///
/// 工字轮类型
///
public string SpoolType { get; set; }
///
/// 是否结束
///
public bool Finish { get; set; }
}
///
/// 垛型明细表
///
[SugarTable("Bill_BomSetInfo", tableDescription: "垛型明细表")]
public partial class BillBomsetinfo
{
///
/// ID
///
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, ColumnDescription = "ID")]
public virtual long Id { get; set; }
///
/// 备注
///
[SugarColumn(ColumnName = "Memo", Length = 500, IsNullable = true, ColumnDataType = "nvarchar", DefaultValue = "", ColumnDescription = "备注")]
public virtual string Memo { get; set; }
///
/// 创建用户
///
[SugarColumn(ColumnName = "AddWho", Length = 50, ColumnDataType = "nvarchar", DefaultValue = "", IsNullable = false, ColumnDescription = "创建用户")]
public virtual string AddWho { get; set; } = "";
///
/// 更新用户
///
[SugarColumn(ColumnName = "EditWho", Length = 50, ColumnDataType = "nvarchar", DefaultValue = "", IsNullable = false, ColumnDescription = "更新用户")]
public virtual string EditWho { get; set; } = "";
///
/// 创建时间
///
[SugarColumn(ColumnName = "AddTime", DefaultValue = "1900-1-1", IsNullable = false, ColumnDescription = "创建时间")]
public virtual DateTime AddTime { get; set; } = DateTime.Now;
///
/// 更新时间
///
[SugarColumn(ColumnName = "EditTime", DefaultValue = "1900-1-1", IsNullable = false, ColumnDescription = "更新时间")]
public virtual DateTime EditTime { get; set; } = DateTime.Now;
///
/// 垛型id
///
[SugarColumn(ColumnDataType = "bigint", IsNullable = false, ColumnDescription = "垛型id")]
public long BomSetHdrId { get; set; }
///
/// 是否停用
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "是否停用")]
public int IsStop { get; set; }
///
/// 是否空置
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "是否空置")]
public int IsEmpty { get; set; }
///
/// 坐标号
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false, ColumnDescription = "坐标号")]
public string XYNo { get; set; }
///
/// 物料id
///
[SugarColumn(ColumnDataType = "bigint", ColumnDescription = "物料id")]
public long MatId { get; set; }
///
/// 物料编码
///
[SugarColumn(ColumnDataType = "nvarchar", IsNullable = true, Length = 50, ColumnDescription = "物料编码")]
public string MatCode { get; set; }
///
/// 正反面
///
[SugarColumn(ColumnDataType = "int", IsNullable = true, ColumnDescription = "正反面")]
public int SideNum { get; set; }
///
/// 工字轮类型
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true, ColumnDescription = "工字轮类型")]
public string SpoolType { get; set; }
///
/// 钢丝类型
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true, ColumnDescription = "钢丝类型")]
public string SilkType { get; set; }
///
/// 钢丝直径
///
[SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = true, ColumnDescription = "钢丝直径")]
public decimal SilkDiam { get; set; }
///
/// 钢丝直径上限
///
[SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = true, ColumnDescription = "钢丝直径上限")]
public decimal SilkDiamMaxCount { get; set; }
///
/// 数量上限
///
[SugarColumn(ColumnDataType = "int", IsNullable = true, ColumnDescription = "数量上限")]
public int QtyMaxCount { get; set; }
///
/// 是否芯股
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "是否芯股")]
public int IsCore { get; set; }
///
/// 09垛型里面的行(1-12)
///
[SugarColumn(ColumnDataType = "int", IsNullable = true, ColumnDescription = "09垛型里面的行(1-12)")]
public int Row { get; set; }
///
/// 是否混合料行(09垛型使用,1是0否)
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "是否混合料行(09垛型使用,1是0否)")]
public int IsMixRow { get; set; }
///
/// 混合料行编码
///
[SugarColumn(ColumnDataType = "nvarchar", IsNullable = true, Length = 50, ColumnDescription = "混合料行编码")]
public string MixRowCode { get; set; }
///
/// 第一种第二种第三种
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "第一种第二种第三种")]
public int CategoryId { get; set; }
}
///
/// 垛形主表
///
[Tenant("fj")]
[SugarTable("Bill_BomSetGrp", tableDescription: "垛形主表")]
public partial class BillBomsetgrp
{
///
/// ID
///
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, ColumnDescription = "ID")]
public virtual long Id { get; set; }
///
/// 备注
///
[SugarColumn(ColumnName = "Memo", Length = 500, IsNullable = true, ColumnDataType = "nvarchar", DefaultValue = "", ColumnDescription = "备注")]
public virtual string Memo { get; set; }
///
/// 创建用户
///
[SugarColumn(ColumnName = "AddWho", Length = 50, ColumnDataType = "nvarchar", DefaultValue = "", IsNullable = false, ColumnDescription = "创建用户")]
public virtual string AddWho { get; set; } = "";
///
/// 更新用户
///
[SugarColumn(ColumnName = "EditWho", Length = 50, ColumnDataType = "nvarchar", DefaultValue = "", IsNullable = false, ColumnDescription = "更新用户")]
public virtual string EditWho { get; set; } = "";
///
/// 创建时间
///
[SugarColumn(ColumnName = "AddTime", DefaultValue = "1900-1-1", IsNullable = false, ColumnDescription = "创建时间")]
public virtual DateTime AddTime { get; set; } = DateTime.Now;
///
/// 更新时间
///
[SugarColumn(ColumnName = "EditTime", DefaultValue = "1900-1-1", IsNullable = false, ColumnDescription = "更新时间")]
public virtual DateTime EditTime { get; set; } = DateTime.Now;
///
/// 是否停用
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "是否停用")]
public int IsStop { get; set; }
///
/// 垛型编码
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false, ColumnDescription = "垛型编码")]
public string Code { get; set; }
///
/// 短垛型编码
///
[SugarColumn(ColumnDataType = "smallint", IsNullable = false, ColumnDescription = "短垛型编码")]
public short ShortCode { get; set; }
///
/// 垛型名称
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = false, ColumnDescription = "垛型名称")]
public string Name { get; set; }
///
/// BomCode(投料信息)
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 200, IsNullable = false, ColumnDescription = "BomCode(投料信息)")]
public string BomCode { get; set; }
///
/// 帘线物料编码
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false, ColumnDescription = "帘线物料编码")]
public string ProMaterCode { get; set; }
///
/// 工字轮个数
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "工字轮个数")]
public int HWCountQty { get; set; }
///
/// 托盘类型
///
[SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false, ColumnDescription = "托盘类型")]
public string TpTypeCode { get; set; }
///
/// 层数
///
[SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "层数")]
public int LayerCountQty { get; set; }
///
/// 垛型大类
///
[SugarColumn(ColumnDataType = "int", IsNullable = true, ColumnDescription = "垛型大类")]
public int StampType { get; set; }
}
}