using System;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Aop.Api.Domain;
using Aspose.Cells;
using JNPF;
using JNPF.Common.Contracts;
using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.VisualDev;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Manager;
using JNPF.Common.Security;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NetTaste;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.OpenXmlFormats.Dml;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Crypto;
using SqlSugar;
using Tnb.BasicData.Entities;
using Tnb.Common.Extension;
using Tnb.Common.Redis;
using Tnb.Common.Utils;
using Tnb.ProductionMgr.Entities;
using Tnb.ProductionMgr.Entities.Entity;
using Tnb.QcMgr.Entities;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Configs;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
using Tnb.WarehouseMgr.Entities.Dto.Outputs;
using Tnb.WarehouseMgr.Entities.Dto.Queries;
using Tnb.WarehouseMgr.Entities.Entity;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
using static NPOI.HSSF.Util.HSSFColor;
using Tnb.BasicData;
using System.Reflection;
using NPOI.SS.Format;
using Aspose.Cells.Drawing;
using SQLitePCL;
using Tnb.BasicData.Entities.Entity;
using Tnb.BasicData.Interfaces;
namespace Tnb.WarehouseMgr
{
///
/// 库房业务类(出入库)
///
public class WareHouseService : DevServBase, IWareHouseService
{
private readonly ISqlSugarClient _db;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IBillRullService _billRullService;
private readonly IUserManager _userManager;
private readonly ICacheManager _cacheManager;
private readonly IElevatorControlService _elevatorControlService;
private readonly IWmsCarryBindService _wmsCarryBindService;
private readonly IWmsCarryUnbindService _wmsCarryUnbindService;
private readonly IWmsOutinStockDetailService _wmsOutinStockDetailService;
private static ISqlSugarClient db_agvElevatorTaskExceptionHandles;
private readonly IThirdApiRecordService _thirdApiRecordService;
private static readonly Dictionary _elevatorAgvCtlStatusMap = new(StringComparer.OrdinalIgnoreCase);
private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build();
private static Dictionary locMap = new Dictionary(StringComparer.OrdinalIgnoreCase);
private readonly IConfiguration _configuration;
private readonly StackExRedisHelper _redisData;
private readonly IVisualDevService _visualDevService;
private readonly IRunService _runService;
public static SemaphoreSlim s_floor2CreatePretask = new(1);
public static SemaphoreSlim s_taskCommonCreatePretask = new(1);
public static SemaphoreSlim s_taskGenPreTask = new(1);
public Func AddUnExecuteTask { get; set; }
public SemaphoreSlim _s_GenTaskExecute
{
get { return s_GenTaskExecute; }
}
public SemaphoreSlim s_taskExecuteSemaphore_YCLInstock
{
get { return _s_taskExecuteSemaphore_YCLInstock; }
}
public SemaphoreSlim s_taskExecuteSemaphore_YCLOutstock
{
get { return _s_taskExecuteSemaphore_YCLOutstock; }
}
public SemaphoreSlim s_taskExecuteSemaphore_F1ZCCInstock
{
get { return _s_taskExecuteSemaphore_F1ZCCInstock; }
}
public SemaphoreSlim s_taskExecuteSemaphore_F1ZCCOutstock
{
get { return _s_taskExecuteSemaphore_F1ZCCOutstock; }
}
public SemaphoreSlim s_taskExecuteSemaphore_F2ZCCInstock
{
get { return _s_taskExecuteSemaphore_F2ZCCInstock; }
}
public SemaphoreSlim s_taskExecuteSemaphore_F2ZCCOutstock
{
get { return _s_taskExecuteSemaphore_F2ZCCOutstock; }
}
public Dictionary s_elevatortaskDic
{
get { return _s_elevatortaskDic; }
}
public List db_ElevatorTaskExceptionHandles
{
get { return _db_ElevatorTaskExceptionHandles; }
}
///
/// WCS请求
///
public Dictionary s_elevatortaskWCSRequestDic
{
get { return _s_elevatortaskWCSRequestDic; }
}
public WareHouseService(ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, StackExRedisHelper redisData,
IBillRullService billRullService, IUserManager userManager, ICacheManager cacheManager, IElevatorControlService elevatorControlService,
IWmsCarryBindService wmsCarryBindService,
IWmsCarryUnbindService wmsCarryUnbindService,
IRunService runService,
IVisualDevService visualDevService,
IThirdApiRecordService thirdApiRecordService,
IWmsOutinStockDetailService wmsOutinStockDetailService
//IConfiguration configuration
) : base(repository.AsSugarClient())
{
_db = repository.AsSugarClient();
_dictionaryDataService = dictionaryDataService;
_billRullService = billRullService;
_userManager = userManager;
_cacheManager = cacheManager;
_elevatorControlService = elevatorControlService;
_redisData = redisData;
_wmsCarryBindService = wmsCarryBindService;
_wmsCarryUnbindService = wmsCarryUnbindService;
_runService = runService;
_visualDevService = visualDevService;
_thirdApiRecordService = thirdApiRecordService;
_wmsOutinStockDetailService = wmsOutinStockDetailService;
//_configuration = configuration;
}
///
/// 根据载具Id带出库位、仓库信息
///
/// 载具id
///
/// returns:
///
{
///
carry_id:载具Id
///
carry_name:载具名称
///
location_id:库位Id
///
location_name:库位名称
///
warehouse_id:库房Id
///
warehouse_name:库房名称
///
}
///
[HttpGet]
public async Task GetLocationAndWorkHouseByCarryId([FromRoute] string carryId)
{
var items = await _db.Queryable().LeftJoin((a, b) => a.location_id == b.id)
.LeftJoin((a, b, c) => b.wh_id == c.id)
.Where(a => a.id == carryId)
.Select((a, b, c) => new
{
carry_id = a.id,
a.carry_name,
location_id = b.id,
b.location_name,
warehouse_id = c.id,
warehouse_name = c.whname,
})
.ToListAsync();
return items ?? Enumerable.Empty();
}
///
/// 库房业务,入库、出库申请新增修改功能
///
///
///
[HttpPost]
public async Task ApplyFor(InOutStockApplyforUpInput input)
{
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
async Task _updateLocalFunc(InOutStockApplyforUpInput input)
where TStockD : BaseEntity, new()
where TStockCode : BaseEntity, IInOutStockCode, new()
{
TStockD instockD = input.Adapt();
global::System.Collections.Generic.List? stockCodes = input.InstockCodes?.Adapt>();
if (stockCodes?.Count > 0)
{
stockCodes.ForEach(x =>
{
if (x.id.IsNullOrWhiteSpace())
{
x.id = SnowflakeIdHelper.NextId();
}
x.bill_d_id = instockD.id;
});
}
return await Update(instockD, stockCodes!);
}
bool isOk = input.inoutStockType switch
{
EnumInOutStockType.In => await _updateLocalFunc(input),
EnumInOutStockType.Out => await _updateLocalFunc(input),
_ => throw new ArgumentOutOfRangeException(nameof(input.inoutStockType), $"Not expected EnumInOutStockType value: {input.inoutStockType}"),
};
if (!isOk)
{
throw Oops.Oh(ErrorCode.COM1001);
}
}
///
/// 根据明细Id获取出入库明细信息
///
///
[HttpGet]
public async Task GetInOutStockCodesById([FromQuery] InOutStockDetailQuery input)
{
dynamic? result = input.inoutStockType switch
{
EnumInOutStockType.In => await FetchInOutStockCodesById(input.bill_d_id),
EnumInOutStockType.Out => await FetchInOutStockCodesById(input.bill_d_id),
_ => throw new NotImplementedException(),
};
return result ?? Enumerable.Empty();
}
///
/// 入库策略
///
///
[HttpGet]
public async Task> InStockStrategy([FromQuery] InStockStrategyQuery input)
{
List items = new();
try
{
var db = input.dbConn;
if (input.dbConn == null)
{
db = _db.CopyNew();
}
WmsInstockPolicies policy = await db.Queryable().Where(it => it.status == 1 && (string.IsNullOrEmpty(input.PolicyCode)||
it.bill_code == input.PolicyCode)).FirstAsync();
if (policy == null)
{
throw new AppFriendlyException("没有可用的策略", 500);
}
List busyPassages = new();
if (input.AvoidBusyPassage)
{
busyPassages = await db.Queryable()
.InnerJoin((a, b) =>
(a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_CANCEL_ID)
&& (b.id == a.startlocation_id || b.id == a.endlocation_id))
.Where((a, b) => b.wh_id == input.warehouse_id)
.Where((a, b) => b.is_type == ((int)EnumLocationType.存储库位).ToString())
.WhereIF(!string.IsNullOrEmpty(input.Region_id), (a, b) => b.region_id == input.Region_id)
.Select((a, b) => b.passage).ToListAsync();
}
Expression> whereExp = Expressionable.Create()
.And(it => it.wh_id == input.warehouse_id)
.And(it => it.is_lock == 0)
.And(it => it.is_type == ((int)EnumLocationType.存储库位).ToString())
.And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString())
.AndIF(!string.IsNullOrEmpty(input.Region_id), it => it.region_id == input.Region_id)
.AndIF(input.AvoidBusyPassage, it => !busyPassages.Contains(it.passage))
.AndIF(!string.IsNullOrEmpty(input.passage), it => it.passage == input.passage)
.ToExpression();
items = await db.Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync();
}
catch (Exception)
{
throw;
}
return items.Take(input.Size).ToList();
}
///
/// 入库策略
///
///
[HttpGet]
public async Task> InStockStrategyBCK([FromQuery] InStockStrategyQuery input)
{
List items = new();
try
{
var db = input.dbConn;
if (input.dbConn == null)
{
db = _db.CopyNew();
}
WmsInstockPolicies policy = await db.Queryable().Where(it => it.status == 1).FirstAsync();
if (policy == null)
{
throw new AppFriendlyException("没有可用的策略", 500);
}
Expression> whereExp = Expressionable.Create()
.And(it => it.wh_id == input.warehouse_id)
.And(it => it.is_lock == 0)
.And(it => it.is_type == ((int)EnumLocationType.分拣库位).ToString())
.And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString())
.ToExpression();
items = await db.Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync();
}
catch (Exception)
{
throw;
}
return items.Take(input.Size).ToList();
}
///
/// 包材库2楼入库策略
///
///
[HttpGet]
public async Task> BCKF2InStockStrategy([FromQuery] InStockStrategyQuery input)
{
List items = new();
try
{
var db = input.dbConn;
if (input.dbConn == null)
{
db = _db.CopyNew();
}
WmsInstockPolicies policy = await db.Queryable().Where(it => it.status == 1).FirstAsync();
if (policy == null)
{
throw new AppFriendlyException("没有可用的策略", 500);
}
Expression> whereExp = Expressionable.Create()
.And(it => it.wh_id == input.warehouse_id)
.And(it => it.is_lock == 0)
.And(it => it.is_type == ((int)EnumLocationType.出入库位).ToString())
.And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString())
.ToExpression();
items = await db.Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync();
}
catch (Exception)
{
throw;
}
return items.Take(input.Size).ToList();
}
///
/// 是否为一楼出库工位
///
///
///
public string[] GetFloor1OutstockLocation()
{
return new string[23] { "30018211902485", "34355463261205", "34355450098709", "34355446145813"
, "34355443336981", "34355440377365", "34355436327189", "34355432397077", "34355428852501", "34355424568341"
, "34355421064213", "34355416966165", "34355407509269", "34355402216469", "34355397484565", "34355394965013"
, "34355391740181", "34355387110933", "34355383562005", "34355377989397", "34355374481173", "34355369617173"
, "30018211902485"};
}
///
/// 是否为二楼包材出库工位
///
///
///
public string[] GetFloor2BCOutstockLocation()
{
return new string[1] { "30018211902485" };
}
///
/// 是否为供料三工位库位
///
///
///
public string[] GetFloor1GLSGWOutstockLocation()
{
return new string[5] { WmsWareHouseConst.Floor1GLSGWOutstockStation1 , WmsWareHouseConst.Floor1GLSGWOutstockStation2
, WmsWareHouseConst.Floor1GLSGWOutstockStation3, WmsWareHouseConst.Floor1GLSGWOutstockStation4, WmsWareHouseConst.Floor1GLSGWOutstockStation5 };
}
///
/// 是否为原材料调拨出库库位
///
///
///
public string[] GetFloor1YCLDBOutstockLocation()
{
return new string[3] { WmsWareHouseConst.Floor1OutstockStation1 , WmsWareHouseConst.Floor1OutstockStation2
, WmsWareHouseConst.Floor1OutstockStation3 };
}
///
/// 是否为外协三工位库位
///
///
///
public string[] GetFloor1WXSGWOutstockLocation()
{
return new string[3] { WmsWareHouseConst.Floor1WXSGWOutstockStation1 , WmsWareHouseConst.Floor1WXSGWOutstockStation2
, WmsWareHouseConst.Floor1WXSGWOutstockStation3 };
}
/////
///// 是否为二楼(一楼外协三存位送上来)入暂存仓起点
/////
/////
/////
//public string[] GetFloor2WX2ZCCStartLocation()
//{
// return new string[3] { WmsWareHouseConst.Floor1WXSGWOutstockStation1 , WmsWareHouseConst.Floor1WXSGWOutstockStation2
// , WmsWareHouseConst.Floor1WXSGWOutstockStation3 };
//}
///
/// 出库策略-销售出库下发
///
///
[HttpGet]
public async Task>> OutStockStrategy_saleRelease([FromQuery] OutStockStrategyQuery input)
{
Expressionable whereExprable = Expressionable.Create()
.And((a, b, c) => a.is_lock == 0 && c.is_lock == 0)
.And((a, b, c) => !string.IsNullOrEmpty(a.location_id))
.And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString())
.And((a, b, c) => a.out_status == "0")
.And((a, b, c) => c.wh_id == input.warehouse_id)
.AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id)
.AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch)
.AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification)
.AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no)
.AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id)
.AndIF(!string.IsNullOrEmpty(input.Region_id), (a, b, c) => c.region_id == input.Region_id);
Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace()
? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString()
: (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString();
_ = whereExprable.And(carryStatusFilterExp);
Expression> whereExpr = whereExprable.ToExpression();
var cyDb = input.dbConn;
if (input.dbConn == null)
{
cyDb = _db.CopyNew();
}
List> items = cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id)
.LeftJoin((a, b, c) => a.location_id == c.id)
.Where(whereExpr)
//.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty())
.OrderBy("b.codeqty")
.Select((a, b, c) => new
{
WmsCarryH = a,
WmsCarryCode = b,
BasLocation = c,
codeqty = b.codeqty
}).ToList().Select(r =>
{
// 如果可出库数量已经扣减完
if (input.qty <= 0)
{
return new Tuple("", r.WmsCarryH, r.WmsCarryCode, r.BasLocation);
}
// 扣减可出库数量
input.qty = input.qty - r.codeqty;
// 出库数量与托盘上的数量不一致需要进行分拣
if (input.qty < 0)
{
r.WmsCarryCode.codeqty = input.qty + r.codeqty;
return new Tuple("分拣任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation);
}
else
{
// 正常预任务出库
return new Tuple("预任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation);
}
}).Where(r => r.Item1 != "").ToList();
return items;
}
public async Task> OutStockStrategy([FromQuery] OutStockStrategyQuery input)
{
var cyDb = input.dbConn;
if (input.dbConn == null)
{
cyDb = _db.CopyNew();
}
List busyPassages = new();
if (input.AvoidBusyPassage)
{
busyPassages = await cyDb.Queryable()
.InnerJoin((a, b) =>
(a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_CANCEL_ID)
&& (b.id == a.startlocation_id || b.id == a.endlocation_id))
.Where((a, b) => b.wh_id == input.warehouse_id)
.Where((a, b) => b.is_type == ((int)EnumLocationType.存储库位).ToString())
.WhereIF(!string.IsNullOrEmpty(input.Region_id), (a, b) => b.region_id == input.Region_id)
.Select((a, b) => b.passage).ToListAsync();
}
Expressionable whereExprable = Expressionable.Create()
.And((a, b, c) => a.is_lock == 0 && c.is_lock == 0)
.And((a, b, c) => !string.IsNullOrEmpty(a.location_id))
.And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString())
.And((a, b, c) => a.out_status == "0")
.And((a, b, c) => c.wh_id == input.warehouse_id)
.AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id)
.AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch)
.AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification)
.AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no)
.AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id)
.AndIF(input.AvoidBusyPassage, (a, b, c) => !busyPassages.Contains(c.passage))
.AndIF(!string.IsNullOrEmpty(input.Region_id), (a, b, c) => c.region_id == input.Region_id);
if (input.filter_carry_status)
{
Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace()
? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString()
: (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString();
_ = whereExprable.And(carryStatusFilterExp);
}
Expression> whereExpr = whereExprable.ToExpression();
WmsOutstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1 && (string.IsNullOrEmpty(input.PolicyCode) ||
it.bill_code == input.PolicyCode)).FirstAsync();
if (policy == null)
{
throw new AppFriendlyException("没有可用策略", 500);
}
List items = await cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id)
.LeftJoin((a, b, c) => a.location_id == c.id)
.Where(whereExpr)
//.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty())
.OrderBy(policy.policy)
.Select()
.ToListAsync();
items = items.DistinctBy(r => r.id).ToList();
return input.Size > 0 ? items.Take(input.Size).ToList() : items;
}
///
/// 缓存仓出库策略
///
///
///
///
public async Task> OutStockStrategyHCC([FromQuery] OutStockStrategyQuery input)
{
Expressionable whereExprable = Expressionable.Create()
.And((a, b, c) => a.is_lock == 0 && c.is_lock == 0)
.And((a, b, c) => !string.IsNullOrEmpty(a.location_id))
.And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString())
.And((a, b, c) => a.out_status == "0")
.And((a, b, c) => c.wh_id == input.warehouse_id)
.AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id)
.AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch)
.AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification)
.AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no)
.AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id);
Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace()
? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString()
: (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString();
_ = whereExprable.And(carryStatusFilterExp);
Expression> whereExpr = whereExprable.ToExpression();
SqlSugarClient cyDb = _db.CopyNew();
WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync();
if (policy == null)
{
throw new AppFriendlyException("没有可用策略", 500);
}
List items = await cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id)
.LeftJoin((a, b, c) => a.location_id == c.id)
.Where(whereExpr)
//.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty())
.OrderBy(policy.policy)
.Select()
.ToListAsync();
items = items.Distinct().ToList();
return input.Size > 0 ? items.Take(input.Size).ToList() : items;
}
///
/// 1->2出库策略
///
///
///
///
public async Task>> OutStockStrategyZCC2Floor2([FromQuery] OutStockStrategyZCC2Floor2Query input)
{
var cyDb = input.dbConn;
if (input.dbConn == null)
{
cyDb = _db.CopyNew();
}
Expressionable whereExprable = Expressionable.Create()
.And((a, b, c) => a.is_lock == 0 && c.is_lock == 0)
.And((a, b, c) => !string.IsNullOrEmpty(a.location_id))
.And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString())
.And((a, b, c) => a.out_status == "0")
.And((a, b, c) => c.wh_id == input.warehouse_id)
.AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id)
.AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch)
.AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification)
.AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no)
.AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id);
Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace()
? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString()
: (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString();
_ = whereExprable.And(carryStatusFilterExp);
Expression> whereExpr = whereExprable.ToExpression();
WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync();
if (policy == null)
{
throw new AppFriendlyException("没有可用策略", 500);
}
#region 只解决少数情况(比如只有60 59 60 60四个料箱,下发180,要取60 60 60) 其它情况不考虑
List>? carrysDESC = new List>();
var itemsDESC = await cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id)
.LeftJoin((a, b, c) => a.location_id == c.id)
.Where(whereExpr)
//.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty())
//.OrderBy(policy.policy)
.OrderBy("codeqty desc,a.location_code,layers,loc_line,loc_column")
.Select((a, b) => new { wmsCarryH = a, wmsCarryCode = b })
.ToListAsync();
itemsDESC = itemsDESC.Distinct().ToList();
// 数量正序
List>? carrysASC = new List>();
var itemsASC = await cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id)
.LeftJoin((a, b, c) => a.location_id == c.id)
.Where(whereExpr)
//.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty())
//.OrderBy(policy.policy)
.OrderBy("codeqty asc,a.location_code,layers,loc_line,loc_column")
.Select((a, b) => new { wmsCarryH = a, wmsCarryCode = b })
.ToListAsync();
itemsASC = itemsASC.Distinct().ToList();
// 6个下发一条任务链
int move_num = 6;
// 剩余分配数
{
decimal? needOut = input.needOut;
int endlocation_index = 0;
BasLocation endlocation_ssx = null;
for (int i = 0; i < itemsDESC.Count; i++)
{
WmsCarryH wmsCarryH = itemsDESC[i].wmsCarryH;
WmsCarryCode wmsCarryCode = itemsDESC[i].wmsCarryCode;
if (needOut <= 0)
{
break;
}
// 每6个重新获取一次终点
if (i % move_num == 0)
{
endlocation_ssx = await cyDb.Queryable().Where(r => input.endlocations.Contains(r.id)).OrderBy("is_lock, task_nums, location_code").FirstAsync();
}
// 查找是否有一个料箱可以正好满足剩余需求数量(目前只做这个额外判断,其它情形不考虑)
bool isFind = false;
for (int j = i + 1; j < itemsDESC.Count; j++)
{
WmsCarryCode _wmsCarryCode = itemsDESC[j].wmsCarryCode;
if (_wmsCarryCode.codeqty == needOut)
{
needOut -= _wmsCarryCode.codeqty;
WmsCarryH _wmsCarryH = itemsDESC[j].wmsCarryH;
await cyDb.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync();
carrysDESC.Add(new Tuple(_wmsCarryH, _wmsCarryCode.codeqty, endlocation_ssx));
isFind = true;
break;
}
}
if (isFind)
break;
// 目前只支持一个料箱只有一个物料
needOut -= wmsCarryCode.codeqty;
await cyDb.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync();
carrysDESC.Add(new Tuple(wmsCarryH, wmsCarryCode.codeqty, endlocation_ssx));
}
if (needOut > 0)
{
throw new AppFriendlyException($"物料{input.material_code}没有足够的库存!,缺失数量为{needOut}", 500);
}
}
{
decimal? needOut = input.needOut;
int endlocation_index = 0;
BasLocation endlocation_ssx = null;
for (int i = 0; i < itemsASC.Count; i++)
{
WmsCarryH wmsCarryH = itemsASC[i].wmsCarryH;
WmsCarryCode wmsCarryCode = itemsASC[i].wmsCarryCode;
if (needOut <= 0)
{
break;
}
// 每6个重新获取一次终点
if (i % move_num == 0)
{
endlocation_ssx = await cyDb.Queryable().Where(r => input.endlocations.Contains(r.id)).OrderBy("is_lock, task_nums, location_code").FirstAsync();
}
// 查找是否有一个料箱可以正好满足剩余需求数量(目前只做这个额外判断,其它情形不考虑)
bool isFind = false;
for (int j = i + 1; j < itemsASC.Count; j++)
{
WmsCarryCode _wmsCarryCode = itemsASC[j].wmsCarryCode;
if (_wmsCarryCode.codeqty == needOut)
{
needOut -= _wmsCarryCode.codeqty;
WmsCarryH _wmsCarryH = itemsASC[j].wmsCarryH;
await cyDb.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync();
carrysASC.Add(new Tuple(_wmsCarryH, _wmsCarryCode.codeqty, endlocation_ssx));
isFind = true;
break;
}
}
if (isFind)
break;
// 目前只支持一个料箱只有一个物料
needOut -= wmsCarryCode.codeqty;
await cyDb.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync();
carrysASC.Add(new Tuple(wmsCarryH, wmsCarryCode.codeqty, endlocation_ssx));
}
if (needOut > 0)
{
throw new AppFriendlyException($"物料{input.material_code}没有足够的库存!,缺失数量为{needOut}", 500);
}
}
#endregion
List>? carrys = new List>();
if (carrysDESC.Count == carrysASC.Count)
{
return carrysDESC.Sum(r => r.Item2) <= carrysASC.Sum(r => r.Item2) ? carrysDESC : carrysASC;
}
else
{
return carrysDESC.Count <= carrysASC.Count ? carrysDESC : carrysASC;
}
}
///
/// 判断CTU是否可以放货
///
///
[HttpPost]
[AllowAnonymous]
public async Task CheckPut(CheckPutInput input)
{
Logger.Information("联核请求CheckPut接口传入参数为:" + JsonConvert.SerializeObject(input));
Dictionary putdic = new Dictionary();
putdic.Add("SSX-011-006", new string[] { "YTCS", "AllowEmptyIn_CS06" });
putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7允许入箱" });
putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9允许入箱" });
putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10允许入箱" });
putdic.Add("SSX-021-003", new string[] { "YTCS", "AllowCtuEmptyIn_CS03" });
putdic.Add("SSX-021-001", new string[] { "YTCS", "AllowCtuEmptyIn_CS01" });
putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowCtuFullOut_CS04", });
putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowCtuFullOut_CS02", });
var strs = new string[] { };
if (!putdic.ContainsKey(input.targetName))
throw new AppFriendlyException("点位" + input.targetName + "不存在", 500);
strs = putdic.Where(p => p.Key == input.targetName).First().Value;
bool flag = await _redisData.HashExists(strs[0], strs[1]);
if (!flag)
{
throw new AppFriendlyException("点位" + input.targetName + "不存在", 500);
}
string data = await _redisData.GetHash(strs[0], strs[1]);
Logger.Information("wcs请求CheckPut接口查询X2Server数据:" + data);
JObject? res = JsonConvert.DeserializeObject(data);
bool result = res != null && res["Value"] != null && res["StatusCode"].ToString() == "0" ? res.Value("Value") : false;
if (!result)
throw new AppFriendlyException("点位" + input.targetName + "不可放", 500);
Logger.Information("wcs请求CheckPut接口结果:CTU可放货" + data);
}
///
/// 判断CTU是否可以取货
///
///
public async Task Check(string code, string action)
{
Logger.Information($"【Check】 判断KIVA是否可以{action} {code}");
Dictionary putdic = new Dictionary();
Dictionary getdic = new Dictionary();
putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvFullIn_CS04", });
putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvFullIn_CS02", });
getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvEmptyOut_CS01" });
getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvEmptyOut_CS03" });
#region 注塑车间点位
putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2允许入空箱", });
getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2允许取满箱" });
putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3允许入空箱", });
getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3允许取满箱" });
putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4允许入空箱", });
getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4允许取满箱" });
putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5允许入空箱", });
getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5允许取满箱" });
putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6允许入空箱", });
getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6允许取满箱" });
putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7允许入空箱", });
getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7允许取满箱" });
putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8允许入空箱", });
getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8允许取满箱" });
putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9允许入空箱", });
getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9允许取满箱" });
putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10允许入空箱", });
getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10允许取满箱" });
putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11允许入空箱", });
getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11允许取满箱" });
putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12允许入空箱", });
getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12允许取满箱" });
putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13允许入空箱", });
getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13允许取满箱" });
putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14允许入空箱", });
getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14允许取满箱" });
putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1允许入空箱", });
getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1允许取满箱" });
//putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3允许入空箱", });
//getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3允许取满箱" });
//putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4允许入空箱", });
//getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4允许取满箱" });
//putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5允许入空箱", });
//getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5允许取满箱" });
//putdic.Add("ZS-D06-1", new string[] { "hxjA", "A6允许入空箱", });
//getdic.Add("ZS-D06-2", new string[] { "hxjA", "A6允许取满箱" });
//putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7允许入空箱", });
//getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7允许取满箱" });
//putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8允许入空箱", });
//getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8允许取满箱" });
putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9允许入空箱", });
getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9允许取满箱" });
putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10允许入空箱", });
getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10允许取满箱" });
putdic.Add("ZS-D01-1", new string[] { "hxjA", "A1允许入空箱", });
getdic.Add("ZS-D01-2", new string[] { "hxjA", "A1允许取满箱" });
putdic.Add("ZS-D02-1", new string[] { "hxjA", "A2允许入空箱", });
getdic.Add("ZS-D02-2", new string[] { "hxjA", "A2允许取满箱" });
putdic.Add("ZS-D03-1", new string[] { "hxjA", "A3允许入空箱", });
getdic.Add("ZS-D03-2", new string[] { "hxjA", "A3允许取满箱" });
putdic.Add("ZS-D04-1", new string[] { "hxjA", "A4允许入空箱", });
getdic.Add("ZS-D04-2", new string[] { "hxjA", "A4允许取满箱" });
putdic.Add("ZS-D05-1", new string[] { "hxjA", "A5允许入空箱", });
getdic.Add("ZS-D05-2", new string[] { "hxjA", "A5允许取满箱" });
putdic.Add("ZS-D06-1", new string[] { "hxjA", "A6允许入空箱", });
getdic.Add("ZS-D06-2", new string[] { "hxjA", "A6允许取满箱" });
putdic.Add("ZS-D07-1", new string[] { "hxjA", "A7允许入空箱", });
getdic.Add("ZS-D07-2", new string[] { "hxjA", "A7允许取满箱" });
putdic.Add("ZS-D08-1", new string[] { "hxjA", "A8允许入空箱", });
getdic.Add("ZS-D08-2", new string[] { "hxjA", "A8允许取满箱" });
putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11允许入空箱", });
getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11允许取满箱" });
putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12允许入空箱", });
getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12允许取满箱" });
putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13允许入空箱", });
getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13允许取满箱" });
putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14允许入空箱", });
getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14允许取满箱" });
#endregion
var strs = new string[] { };
if (action == "LOAD")//取货
{
if (!getdic.ContainsKey(code))
{
return false;
}
strs = getdic.Where(p => p.Key == code).First().Value;
bool flag = await _redisData.HashExists(strs[0], strs[1]);
Logger.Information($"【Check】{action} 判断KIVA是否可以取货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} ");
if (!flag)
{
throw new Exception($"【Check】{action} 判断KIVA是否可以取货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} ");
}
string data = _redisData.GetHash(strs[0], strs[1]).Result;
JObject? res = JsonConvert.DeserializeObject(data);
bool result = res != null && res["Value"] != null && res["StatusCode"].ToString() == "0" ? res.Value("Value") : false;
Logger.Information($"【Check】{action} 判断KIVA是否可以取货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} ");
if (!result)
{
throw new Exception($"【Check】{action} 判断KIVA是否可以取货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} ");
}
return true;
}
else if (action == "UNLOAD")//放货
{
if (!putdic.ContainsKey(code))
return false;
strs = putdic.Where(p => p.Key == code).First().Value;
bool flag = await _redisData.HashExists(strs[0], strs[1]);
Logger.Information($"【Check】 判断CTU是否可以放货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} ");
if (!flag)
{
throw new Exception($"【Check】 判断CTU是否可以放货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} ");
}
string data = _redisData.GetHash(strs[0], strs[1]).Result;
JObject? res = JsonConvert.DeserializeObject(data);
bool result = res != null && res["Value"] != null && res["StatusCode"].ToString() == "0" ? res.Value("Value") : false;
Logger.Information($"【Check】 判断CTU是否可以放货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result}");
if (!result)
{
throw new Exception($"【Check】 判断CTU是否可以放货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} ");
}
return true;
}
return false;
}
public async Task SsxControl(WmsDistaskH disTask, string action)
{
Logger.Information($"输送线控制SsxControl传入参数: {JsonConvert.SerializeObject(disTask)} {action}");
Dictionary putdic = new Dictionary();
Dictionary getdic = new Dictionary();
getdic.Add("SSX-021-005", new string[] { "YTCS", "FullOut_CS05Done", "true" });
getdic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11出箱完毕", "true" });
getdic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12出箱完毕", "true" });
getdic.Add("ZZ-01-02", new string[] { "外包装箱码垛线", "WBZX_x1_take_mtp", "true" });
getdic.Add("ZZ-02-02", new string[] { "外包装箱码垛线", "WBZX_x2_take_mtp", "true" });
getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线上层允许出箱3", "true" });
getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线上层允许出箱1", "true" });
getdic.Add("SSX-011-008", new string[] { "东面提升机输送线", "入库输送线8出箱完毕", "true" });
getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2AGV允许入满箱", "true" });
getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3AGV允许入满箱", "true" });
getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4AGV允许入满箱", "true" });
getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5AGV允许入满箱", "true" });
getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6AGV允许入满箱", "true" });
getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7AGV允许入满箱", "true" });
getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8AGV允许入满箱", "true" });
getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9AGV允许入满箱", "true" });
getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10AGV允许入满箱", "true" });
getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11AGV允许入满箱", "true" });
getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12AGV允许入满箱", "true" });
getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13AGV允许入满箱", "true" });
getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14AGV允许入满箱", "true" });
getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1AGV允许入满箱", "true" });
//getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3AGV允许入满箱", "true" });
//getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4AGV允许入满箱", "true" });
//getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5AGV允许入满箱", "true" });
//getdic.Add("ZS-D06-2", new string[] { "hxjA", "A6AGV允许入满箱", "true" });
//getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7AGV允许入满箱", "true" });
//getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8AGV允许入满箱", "true" });
getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9AGV允许入满箱", "true" });
getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10AGV允许入满箱", "true" });
getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11AGV允许入满箱", "true" });
getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12AGV允许入满箱", "true" });
getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13AGV允许入满箱", "true" });
getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14AGV允许入满箱", "true" });
getdic.Add("ZS-D01-2", new string[] { "hxjA", "A1AGV允许入满箱", "true" });
getdic.Add("ZS-D02-2", new string[] { "hxjA", "A2AGV允许入满箱", "true" });
getdic.Add("ZS-D03-2", new string[] { "hxjA", "A3AGV允许入满箱", "true" });
getdic.Add("ZS-D04-2", new string[] { "hxjA", "A4AGV允许入满箱", "true" });
getdic.Add("ZS-D05-2", new string[] { "hxjA", "A5AGV允许入满箱", "true" });
getdic.Add("ZS-D06-2", new string[] { "hxjA", "A6AGV允许入满箱", "true" });
getdic.Add("ZS-D07-2", new string[] { "hxjA", "A7AGV允许入满箱", "true" });
getdic.Add("ZS-D08-2", new string[] { "hxjA", "A8AGV允许入满箱", "true" });
putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7入箱完毕", "true" });
putdic.Add("SSX-011-006", new string[] { "YTCS", "EmptyIn_CS06Done", "true" });
putdic.Add("SSX-021-003", new string[] { "YTCS", "AgvFullIn_CS03Done", "true" });
putdic.Add("SSX-021-001", new string[] { "YTCS", "CtuEmptyIn_CS01Done", "true" });
putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线下层允许入箱4", "true" });
putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线下层允许入箱2", "true" });
putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9入箱完毕", "true" });
putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10入箱完毕", "true" });
putdic.Add("YCLCKBGW", new string[] { "CP8", "PutDoneEmptyBox", "true" });
putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2AGV允许出空箱", "true" });
putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3AGV允许出空箱", "true" });
putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4AGV允许出空箱", "true" });
putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5AGV允许出空箱", "true" });
putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6AGV允许出空箱", "true" });
putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7AGV允许出空箱", "true" });
putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8AGV允许出空箱", "true" });
putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9AGV允许出空箱", "true" });
putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10AGV允许出空箱", "true" });
putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11AGV允许出空箱", "true" });
putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12AGV允许出空箱", "true" });
putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13AGV允许出空箱", "true" });
putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14AGV允许出空箱", "true" });
putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1AGV允许出空箱", "true" });
//putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3AGV允许出空箱", "true" });
//putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4AGV允许出空箱", "true" });
//putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5AGV允许出空箱", "true" });
//putdic.Add("ZS-D06-1", new string[] { "hxjA", "A6AGV允许出空箱", "true" });
//putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7AGV允许出空箱", "true" });
//putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8AGV允许出空箱", "true" });
putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9AGV允许出空箱", "true" });
putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10AGV允许出空箱", "true" });
putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11AGV允许出空箱", "true" });
putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12AGV允许出空箱", "true" });
putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13AGV允许出空箱", "true" });
putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14AGV允许出空箱", "true" });
// D线 待改成配置
putdic.Add("ZS-D01-1", new string[] { "hxjA", "A1AGV允许出空箱", "true" });
putdic.Add("ZS-D02-1", new string[] { "hxjA", "A2AGV允许出空箱", "true" });
putdic.Add("ZS-D03-1", new string[] { "hxjA", "A3AGV允许出空箱", "true" });
putdic.Add("ZS-D04-1", new string[] { "hxjA", "A4AGV允许出空箱", "true" });
putdic.Add("ZS-D05-1", new string[] { "hxjA", "A5AGV允许出空箱", "true" });
putdic.Add("ZS-D06-1", new string[] { "hxjA", "A6AGV允许出空箱", "true" });
putdic.Add("ZS-D07-1", new string[] { "hxjA", "A7AGV允许出空箱", "true" });
putdic.Add("ZS-D08-1", new string[] { "hxjA", "A8AGV允许出空箱", "true" });
if (action == "LOAD")//取货
{
if (getdic.Keys.Contains(disTask.startlocation_code))
{
var strarr = getdic.Where(p => p.Key == disTask.startlocation_code).First().Value;
Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = strarr[0],
["token"] = _eleCtlCfg.token,
["TagName"] = strarr[1],
["Value"] = strarr[2],
};
Logger.Information($"SsxControlLOAD:{JsonConvert.SerializeObject(dicCommand)}");
var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand);
Logger.Information($"SsxControlLOAD:{str}");
//Logger.Information($"SsxControlUNLOAD - 控制后查询:{_redisData.GetHash(strarr[0], strarr[1]).Result}");
}
}
else if (action == "UNLOAD")//放货
{
if (putdic.Keys.Contains(disTask.endlocation_code))
{
var strarr = putdic.Where(p => p.Key == disTask.endlocation_code).First().Value;
Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = strarr[0],
["token"] = _eleCtlCfg.token,
["TagName"] = strarr[1],
["Value"] = strarr[2],
};
Logger.Information($"SsxControlUNLOAD:{JsonConvert.SerializeObject(dicCommand)}");
var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand);
Logger.Information($"SsxControlUNLOAD:{str}");
//Logger.Information($"SsxControlUNLOAD - 控制后查询:{_redisData.GetHash(strarr[0], strarr[1]).Result}");
}
}
}
public async Task SsxControl_complete(WmsDistaskH disTask, string action)
{
Logger.Information($"输送线控制SsxControl_complete传入参数: {JsonConvert.SerializeObject(disTask)} {action}");
Dictionary putdic = new Dictionary();
Dictionary getdic = new Dictionary();
getdic.Add("SSX-021-005", new string[] { "YTCS", "FullOut_CS05Done", "true" });
getdic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11出箱完毕", "true" });
getdic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12出箱完毕", "true" });
getdic.Add("ZZ-01-02", new string[] { "外包装箱码垛线", "WBZX_x1_take_mtp", "true" });
getdic.Add("ZZ-02-02", new string[] { "外包装箱码垛线", "WBZX_x2_take_mtp", "true" });
getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线上层允许出箱3", "true" });
getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线上层允许出箱1", "true" });
getdic.Add("SSX-011-008", new string[] { "东面提升机输送线", "入库输送线8出箱完毕", "true" });
getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2AGV允许入满箱", "true" });
getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3AGV允许入满箱", "true" });
getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4AGV允许入满箱", "true" });
getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5AGV允许入满箱", "true" });
getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6AGV允许入满箱", "true" });
getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7AGV允许入满箱", "true" });
getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8AGV允许入满箱", "true" });
getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9AGV允许入满箱", "true" });
getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10AGV允许入满箱", "true" });
getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11AGV允许入满箱", "true" });
getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12AGV允许入满箱", "true" });
getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13AGV允许入满箱", "true" });
getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14AGV允许入满箱", "true" });
getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1AGV允许入满箱", "true" });
//getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3AGV允许入满箱", "true" });
//getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4AGV允许入满箱", "true" });
//getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5AGV允许入满箱", "true" });
//getdic.Add("ZS-D06-2", new string[] { "hxjA", "A6AGV允许入满箱", "true" });
//getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7AGV允许入满箱", "true" });
//getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8AGV允许入满箱", "true" });
getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9AGV允许入满箱", "true" });
getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10AGV允许入满箱", "true" });
getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11AGV允许入满箱", "true" });
getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12AGV允许入满箱", "true" });
getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13AGV允许入满箱", "true" });
getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14AGV允许入满箱", "true" });
getdic.Add("ZS-D01-2", new string[] { "hxjA", "A1AGV允许入满箱", "false" });
getdic.Add("ZS-D02-2", new string[] { "hxjA", "A2AGV允许入满箱", "false" });
getdic.Add("ZS-D03-2", new string[] { "hxjA", "A3AGV允许入满箱", "false" });
getdic.Add("ZS-D04-2", new string[] { "hxjA", "A4AGV允许入满箱", "false" });
getdic.Add("ZS-D05-2", new string[] { "hxjA", "A5AGV允许入满箱", "false" });
getdic.Add("ZS-D06-2", new string[] { "hxjA", "A6AGV允许入满箱", "false" });
getdic.Add("ZS-D07-2", new string[] { "hxjA", "A7AGV允许入满箱", "false" });
getdic.Add("ZS-D08-2", new string[] { "hxjA", "A8AGV允许入满箱", "false" });
putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7入箱完毕", "true" });
putdic.Add("SSX-011-006", new string[] { "YTCS", "EmptyIn_CS06Done", "true" });
putdic.Add("SSX-021-003", new string[] { "YTCS", "AgvFullIn_CS03Done", "true" });
putdic.Add("SSX-021-001", new string[] { "YTCS", "CtuEmptyIn_CS01Done", "true" });
putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线下层允许入箱4", "true" });
putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线下层允许入箱2", "true" });
putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9入箱完毕", "true" });
putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10入箱完毕", "true" });
putdic.Add("YCLCKBGW", new string[] { "CP8", "PutDoneEmptyBox", "true" });
putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2AGV允许出空箱", "true" });
putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3AGV允许出空箱", "true" });
putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4AGV允许出空箱", "true" });
putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5AGV允许出空箱", "true" });
putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6AGV允许出空箱", "true" });
putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7AGV允许出空箱", "true" });
putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8AGV允许出空箱", "true" });
putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9AGV允许出空箱", "true" });
putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10AGV允许出空箱", "true" });
putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11AGV允许出空箱", "true" });
putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12AGV允许出空箱", "true" });
putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13AGV允许出空箱", "true" });
putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14AGV允许出空箱", "true" });
putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1AGV允许出空箱", "true" });
//putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3AGV允许出空箱", "true" });
//putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4AGV允许出空箱", "true" });
//putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5AGV允许出空箱", "true" });
//putdic.Add("ZS-D06-1", new string[] { "hxjA", "A6AGV允许出空箱", "false" });
//putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7AGV允许出空箱", "true" });
//putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8AGV允许出空箱", "true" });
putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9AGV允许出空箱", "true" });
putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10AGV允许出空箱", "true" });
putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11AGV允许出空箱", "true" });
putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12AGV允许出空箱", "true" });
putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13AGV允许出空箱", "false" });
putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14AGV允许出空箱", "true" });
// D线 待改成配置
putdic.Add("ZS-D01-1", new string[] { "hxjA", "A1AGV允许出空箱", "false" });
putdic.Add("ZS-D02-1", new string[] { "hxjA", "A2AGV允许出空箱", "false" });
putdic.Add("ZS-D03-1", new string[] { "hxjA", "A3AGV允许出空箱", "false" });
putdic.Add("ZS-D04-1", new string[] { "hxjA", "A4AGV允许出空箱", "false" });
putdic.Add("ZS-D05-1", new string[] { "hxjA", "A5AGV允许出空箱", "false" });
putdic.Add("ZS-D06-1", new string[] { "hxjA", "A6AGV允许出空箱", "false" });
putdic.Add("ZS-D07-1", new string[] { "hxjA", "A7AGV允许出空箱", "false" });
putdic.Add("ZS-D08-1", new string[] { "hxjA", "A8AGV允许出空箱", "false" });
if (action == "LOAD")//取货
{
if (getdic.Keys.Contains(disTask.startlocation_code))
{
var strarr = getdic.Where(p => p.Key == disTask.startlocation_code).First().Value;
Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = strarr[0],
["token"] = _eleCtlCfg.token,
["TagName"] = strarr[1],
["Value"] = strarr[2],
};
Logger.Information($"SsxControlLOAD:{JsonConvert.SerializeObject(dicCommand)}");
var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand);
Logger.Information($"SsxControlLOAD:{str}");
//Logger.Information($"SsxControlUNLOAD - 控制后查询:{_redisData.GetHash(strarr[0], strarr[1]).Result}");
}
}
else if (action == "UNLOAD")//放货
{
if (putdic.Keys.Contains(disTask.endlocation_code))
{
var strarr = putdic.Where(p => p.Key == disTask.endlocation_code).First().Value;
Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = strarr[0],
["token"] = _eleCtlCfg.token,
["TagName"] = strarr[1],
["Value"] = strarr[2],
};
Logger.Information($"SsxControlUNLOAD:{JsonConvert.SerializeObject(dicCommand)}");
var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand);
Logger.Information($"SsxControlUNLOAD:{str}");
//Logger.Information($"SsxControlUNLOAD - 控制后查询:{_redisData.GetHash(strarr[0], strarr[1]).Result}");
}
}
}
///
/// 二楼机械臂
///
///
public async Task Floor2MechanicalConfirm(WmsDistaskH disTask, string action)
{
List rackAreaPointsUp = new List();
List rackAreaPointsDown = new List();
// 二楼上升降区料架区点位
rackAreaPointsUp.Add("AS01");
rackAreaPointsUp.Add("AS02");
// 二楼下升降区料架区点位
rackAreaPointsDown.Add("AX01");
rackAreaPointsDown.Add("AX02");
try {
List basLocations = _db.Queryable().Where(r => (r.location_code == disTask.endlocation_code || r.location_code == disTask.startlocation_code)
&& r.wh_id != "33780009364245").ToList();
// 暂存仓内任务
if (disTask.area_code == "E" && basLocations.Count() == 0)
{
await _db.Ado.BeginTranAsync();
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】收到到货确认信号 传入参数: {disTask.bill_code} {action}");
if (action == "UNLOAD")
{
// 去料架区放货
if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code))
{
ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.endlocation_code);
if (WmsMechanicalArmHs.Count() == 0)
{
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配");
throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配");
}
WmsMechanicalArmH target = WmsMechanicalArmHs.First();
// 回写料架和AGV确认
await _db.Updateable().SetColumns(r => new WmsMechanicalArmH
{
agvconfirm = 1,
rackid = disTask.carry_id,
rackcode = disTask.carry_code
}).Where(r => r.id == target.id).ExecuteCommandAsync();
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV已到货 {disTask.endpoint_code} 更新缓存表{target.id}");
if (rackAreaPointsDown.Contains(disTask.endlocation_code))
{
int LXCount = _db.Queryable().Where(a => a.carry_id == disTask.carry_id).Count();
// 绑定料架
await _db.Updateable().SetColumns(r => new WmsMechanicalArmH
{
mechanicalconfirm = 1,
maxnum = LXCount
}).Where(r => r.id == target.id).ExecuteCommandAsync();
Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱开始生成预任务");
bool pretask_result = await Floor2EmptyCarryCreateZZCPretask(disTask.carry_id);
if (pretask_result)
{
Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务完成");
}
else
{
Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务失败");
throw new Exception($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务失败");
}
}
}
else // 去暂存仓放货
{
// 回写料架料箱绑定表的库位
ISugarQueryable WmsCarryCodes = _db.Queryable()
.InnerJoin((a, b) => b.membercarry_id == a.carry_id)
.Where((a, b) => b.carry_id == disTask.carry_id);
var WmsCarryCodeList = WmsCarryCodes.ToList();
WmsCarryCodeList.ForEach(r =>
{
r.location_id = disTask.endlocation_id;
r.location_code = disTask.endlocation_code;
});
await _db.Updateable(WmsCarryCodeList).ExecuteCommandAsync();
}
}
else
{
// 去暂存仓取货
if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code))
{
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在暂存仓取货确认完成");
}
else // 去料架区取货
{
ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.startlocation_code);
if (WmsMechanicalArmHs.Count() == 0)
{
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配");
throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配");
}
WmsMechanicalArmH target = WmsMechanicalArmHs.First();
if (target.note == "上升降机")
{
bool result = await Floor2UpDownMachinecode_SetTag($"上升降机满托{target.stackingposition}移走", "true");
Logger.LogInformation($@"【上升降机】设定升上升降机满托{target.stackingposition}移走 结果为 {result}");
if (!result)
{
throw new Exception($@"【上升降机】设定升上升降机满托{target.stackingposition}移走 结果为 {result}");
}
// 更新料架在二楼配送的目标工位
// todo erp工位字段取数位置未确定
WmsMaterialTransferD wmsMaterialTransferD = await _db.Queryable()
.LeftJoin((a, b) => a.id == b.bill_id).Where((a, b) => a.bill_code == target.outbill)
.Select((a, b) => b).FirstAsync();
if (wmsMaterialTransferD == null)
{
Logger.LogWarning($@"【上升降机】 发生异常!,转库单{target.outbill}没有载具明细");
// 转库单删除 不执行后续,不返回失败是为了不卡流程
return;
}
string targetWorkstation = wmsMaterialTransferD.station_code;
if (string.IsNullOrEmpty(wmsMaterialTransferD.station_code))
{
throw new Exception($@"【上升降机】 发生异常!,转库单{target.outbill}的工位为空");
}
Logger.LogInformation($@"【上升降机】更新料架 {target.rackcode} 在二楼配送的目标工位 {targetWorkstation}");
await _db.Updateable().SetColumns(r => new WmsCarryH
{
work_station = targetWorkstation,
material_tranfer_billid = wmsMaterialTransferD.bill_id
}).Where(r => r.id == target.rackid).ExecuteCommandAsync();
}
else if (target.note == "下升降机")
{
bool result = await Floor2UpDownMachinecode_SetTag($"下升降机空托{target.stackingposition}移走", "true");
Logger.LogInformation($@"【上升降机】设定升下升降机空托{target.stackingposition}移走 结果为 {result}");
if (!result)
{
throw new Exception($@"【上升降机】设定升下升降机空托{target.stackingposition}移走 结果为 {result}");
}
}
// 重置料架区
await _db.Updateable().SetColumns(r => new WmsMechanicalArmH
{
stackingcount = 0,
barcodes = "",
outbill = "",
maxnum = 0,
iscreatepretask = 0,
rackcode = "",
rackid = "",
agvconfirm = 0,
mechanicalconfirm = 0
}).Where(r => r.id == target.id).ExecuteCommandAsync();
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在料架区取货完成");
}
}
await _db.Ado.CommitTranAsync();
}
}
catch(Exception ex)
{
Logger.LogError("【Floor2MechanicalComplete】" + ex.ToString());
await _db.Ado.RollbackTranAsync();
throw;
}
}
///
/// 二楼机械臂
///
///
public async Task Floor2MechanicalComplete(WmsDistaskH disTask, string action)
{
List rackAreaPointsUp = new List();
List rackAreaPointsDown = new List();
// 二楼上升降区料架区点位
rackAreaPointsUp.Add("AS01");
rackAreaPointsUp.Add("AS02");
// 二楼下升降区料架区点位
rackAreaPointsDown.Add("AX01");
rackAreaPointsDown.Add("AX02");
try
{
List basLocations = _db.Queryable().Where(r => (r.location_code == disTask.endlocation_code || r.location_code == disTask.startlocation_code)
&& r.wh_id != "33780009364245").ToList();
// 暂存仓内任务
if (disTask.area_code == "E" && basLocations.Count() == 0)
{
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】收到到货完成信号 传入参数: {disTask.bill_code} {action}");
if (action == "UNLOAD")
{
// 去料架区放货
if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code))
{
ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.endlocation_code);
if (WmsMechanicalArmHs.Count() == 0)
{
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配");
throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配");
}
WmsMechanicalArmH target = WmsMechanicalArmHs.First();
// 下升降机写满托数量和送到信号
if (rackAreaPointsDown.Contains(disTask.endlocation_code))
{
int LXCount = _db.Queryable().Where(a => a.carry_id == disTask.carry_id).Count();
bool result = await Floor2UpDownMachinecode_SetTag($"下升降机满托{target.stackingposition}数量", LXCount.ToString());
Logger.LogInformation($@"【送满托到下升降区】设定下升降机满托{target.stackingposition}满托数量为 {LXCount} 结果为 {result}");
if (!result)
{
throw new Exception($"下升降机满托{target.stackingposition}数量 写入失败");
}
// 尝试写入满托送到信号
bool result下升降机空托送到 = await Floor2UpDownMachinecode_SetTag($"下升降机满托{target.stackingposition}送到", "true");
Logger.LogInformation($@"【送满托到下升降区】回写 下升降机满托{target.stackingposition}送到 结果为{result下升降机空托送到}");
if (!result下升降机空托送到)
{
throw new Exception($"下升降机满托{target.stackingposition}送到 写入失败");
}
}
}
else // 去暂存仓放货
{
}
}
else
{
// 去暂存仓取货
if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code))
{
Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在暂存仓取货完成");
}
else // 去料架区取货
{
}
}
}
}
catch (Exception ex)
{
Logger.LogError("【Floor2MechanicalComplete】" + ex.ToString());
throw;
}
}
private async Task Floor2UpDownMachinecode_SetTag(string tag, string value)
{
string DevName = "东面提升机输送线";
Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = DevName,
["token"] = _eleCtlCfg.token,
["TagName"] = tag,
["Value"] = value,
};
string result = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand);
return result.Contains("Ok");
// 测试
//string DevName = "东面提升机输送线";
//JObject valueJson = new JObject();
//valueJson["Value"] = value;
//_redisData.SetHash(DevName, tag, valueJson.ToString());
//return true;
}
///
/// 生成任务执行
///
///
[HttpPost]
public async Task GenTaskExecute()
{
if (s_GenTaskExecute.CurrentCount == 0)
{
return;
}
await s_GenTaskExecute.WaitAsync();
Stopwatch sw = Stopwatch.StartNew();
CancellationTokenSource agvCts = new();
SqlSugarClient db = _db.CopyNew();
try
{
await CTUTaskExecute();
//获取所有未下发的预任务申请
Logger.Information("【GenTaskExecute】 开始获取未下发的预任务...");
ISugarQueryable sugarQueryable = db.Queryable()
.LeftJoin((a, b) => a.carry_id == b.id)
.InnerJoin((a, b, c) => a.area_id == c.id)
.InnerJoin((a, b, c, d) => a.endlocation_id == d.id && d.is_use == "0")
.Where((a, b) => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID && !string.IsNullOrWhiteSpace(a.startlocation_id)
// 载具为空时 不校验载具当前位置是否与预任务起点相同
&& (string.IsNullOrEmpty(a.carry_id) || (!string.IsNullOrEmpty(a.carry_id) && a.startlocation_id == b.location_id)))
.OrderBy(a => new { a.bill_code })
.OrderByDescending(a => new { priority = SqlFunc.Desc(a.priority) })
.Select((a, b, c, d) => new WmsPretaskH
{
move_num = c.move_num,
third_eqp_type = c.third_eqp_type,
}, true);
Logger.Information($"【GenTaskExecute】 获取到{sugarQueryable.Count()}条可执行的预任务...");
if (sugarQueryable.Count() == 0)
return;
//Logger.Information("【GenTaskExecute】 执行SQL: " + sugarQueryable.ToSqlString());
List preTasks = await sugarQueryable.ToListAsync();
//List executedPreTasks = await db.Queryable().Where(it => it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID && it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID).ToListAsync();
List agvElevatorTasks = preTasks
.Where(it => it.endlocation_code.StartsWith("DT", StringComparison.OrdinalIgnoreCase) &&
!it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase))
.ToList();
var elePreTasks = preTasks.Where(it => it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList();
var normalPreTasks = preTasks.Where(it => it.area_code != "B" && !agvElevatorTasks.Concat(elePreTasks).Select(x => x.endlocation_code).Contains(it.endlocation_code)).ToList();
//Logger.Information("【GenTaskExecute】 电梯预任务elePreTasks:" + JsonConvert.SerializeObject(elePreTasks));
//Logger.Information("【GenTaskExecute】 AGV/CTU/KIVA预任务normalPreTasks:" + JsonConvert.SerializeObject(normalPreTasks));
//Logger.Information("【GenTaskExecute】 AGV电梯预任务agvElevatorTasks:" + JsonConvert.SerializeObject(agvElevatorTasks));
/* IEnumerable firstEleGrp = agvElevatorTasks.GroupBy(g => g.endlocation_code).Select(t => t.OrderBy(o => o.bill_code).FirstOrDefault());
agvElevatorTasks = firstEleGrp?.ToList() ?? Enumerable.Empty().ToList()!;
*/
//如果电梯任务,预Agv任务存在相同目标库位,删除Agv任务保证电梯任务先行
var equalEndLocPreTasks = elePreTasks.Select(x => x.endlocation_code).Intersect(agvElevatorTasks.Select(x => x.endlocation_code));
if (equalEndLocPreTasks.Any())
{
Logger.Information("【GenTaskExecute】 执行:如果电梯任务,预Agv任务存在相同目标库位,删除Agv任务保证电梯任务先行 ");
agvElevatorTasks = agvElevatorTasks.Where(x => !equalEndLocPreTasks.Contains(x.endlocation_code)).ToList();
}
#region 原材料仓同巷道任务出库控制同时只发一条
// 原材料仓的未完成任务
List wmspretasks_ycl = await db.Queryable()
.InnerJoin((a, b) => a.endlocation_id == b.id)
.InnerJoin((a, b, c) => a.area_id == c.id)
.InnerJoin((a, b, c, d) => a.startlocation_id == d.id)
.Where((a, b, c, d) => a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_CANCEL_ID
&& b.is_use == "0" && d.is_type == "0" && b.wh_id == WmsWareHouseConst.WAREHOUSE_YCL_ID)
.Select((a, b, c, d) => new WmsPretaskH
{
move_num = c.move_num,
third_eqp_type = c.third_eqp_type,
passage = d.passage
}, true)
.ToListAsync();
// 原材料仓的执行中任务
List wmspretasksrun_ycl = wmspretasks_ycl.Where(r => r.status == WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID || r.status == WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID).ToList();
// 过滤normalPreTasks中的原材料仓的任务
normalPreTasks = normalPreTasks.Where(r => !wmspretasks_ycl.Select(a => a.id).Contains(r.id)).ToList();
// 过滤原材料仓同巷道的正在执行的任务
var yclTasks = wmspretasks_ycl.Where(r => !wmspretasksrun_ycl.Select(a => a.passage).Contains(r.passage)).ToList();
// 过滤重复巷道的预任务
yclTasks = yclTasks.OrderBy(r => r.passage).GroupBy(r => r.passage).Select(r => { return r.ToList()[0]; }).OrderBy(r => r.bill_code).ToList();
normalPreTasks = normalPreTasks.Concat(yclTasks).ToList();
#endregion
#region 三楼三四号梯如果与判断一托下有冲突
#region 电梯第三次改动
// 到暂存区的未完成任务
List wmsdistasks_agvElevator = await db.Queryable()
.InnerJoin((a, b) => a.endlocation_id == b.id)
.Where((a, b) => a.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID && a.status != WmsWareHouseConst.TASK_BILL_STATUS_CANCEL_ID
&& b.region_id == WmsWareHouseConst.REGION_CPOutstockCache_ID)
.ToListAsync();
// 到暂存区的未完成预任务
List wmspretasks_agvElevator = await db.Queryable()
.InnerJoin((a, b) => a.endlocation_id == b.id)
.InnerJoin((a, b, c) => a.area_id == c.id)
.Where((a, b) => a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_CANCEL_ID
&& b.region_id == WmsWareHouseConst.REGION_CPOutstockCache_ID && b.is_use == "0")
.Select((a, b, c) => new WmsPretaskH
{
move_num = c.move_num,
third_eqp_type = c.third_eqp_type,
}, true)
.ToListAsync();
// 过滤normalPreTasks中的到三楼暂存区任务
normalPreTasks = normalPreTasks.Where(r => !wmspretasks_agvElevator.Select(a => a.endlocation_id).Contains(r.endlocation_id)).ToList();
// 过滤到三楼暂存区同目标库位的正在执行的任务
var cacheLocTasks = wmspretasks_agvElevator.Where(r => !wmsdistasks_agvElevator.Select(a => a.endlocation_id).Contains(r.endlocation_id)).ToList();
// 过滤重复目标库位的预任务
cacheLocTasks = cacheLocTasks.OrderBy(r => r.endlocation_code).GroupBy(r => r.endlocation_code).Select(r => { return r.ToList()[0]; }).OrderBy(r => r.bill_code).ToList();
normalPreTasks = normalPreTasks.Concat(cacheLocTasks).ToList();
#endregion
if (s_elevatortaskWCSRequestDic.Count > 0)
{
for (int index_agvElevatorTasks = 0; index_agvElevatorTasks < agvElevatorTasks.Count; index_agvElevatorTasks++)
{
WmsPretaskH wmsPretaskH = agvElevatorTasks[index_agvElevatorTasks];
string area_code = "";
// 找到电梯任务的电梯区域
if (wmsPretaskH.start_floor == "3" && wmsPretaskH.end_floor == "3")
{
if (wmsPretaskH.endlocation_code == "DT-3-3")
{
area_code = "ELE03";
}
else if (wmsPretaskH.endlocation_code == "DT-3-4") { area_code = "ELE04"; }
}
// 如果不是三楼三四号梯出货
if (string.IsNullOrEmpty(area_code))
{
continue;
}
SemaphoreSlim s_elevatortaskWCSRequest = s_elevatortaskWCSRequestDic[area_code];
if (s_elevatortaskWCSRequest.CurrentCount == 0)
{
Logger.Information($"【GenTaskExecute】 获取到AGV到电梯{area_code}的预任务{wmsPretaskH.bill_code}正在执行一托下判断,此时不下发任务");
agvElevatorTasks.RemoveAt(index_agvElevatorTasks);
index_agvElevatorTasks--;
}
else
{
Logger.Information($"【GenTaskExecute】AGV到电梯{area_code}的预任务{wmsPretaskH.bill_code}没有在执行一托下判断,正常下发任务");
}
}
}
#endregion
preTasks = normalPreTasks.Concat(agvElevatorTasks).Concat(elePreTasks).ToList();
if (preTasks.Count() == 0)
return;
//一楼中储仓CTU
List ids = preTasks.Select(x => x.id).Distinct().ToList();
List? preTaskCodes = await db.Queryable().Where(it => ids.Contains(it.bill_id)).ToListAsync();
if (preTasks.Count > 0)
{
//根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID
List> preTaskGroups = preTasks.GroupBy(g => g.area_code).ToList();
List disTasks = new();
List distaskCodes = new();
foreach (IGrouping? itGroup in preTaskGroups)
{
List items = itGroup.Adapt>();
for (int i = 0, cnt = items.Count; i < cnt; i++)
{
items[i].id = SnowflakeIdHelper.NextId();
items[i].create_time = DateTime.Now;
items[i].status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID;
}
int moveNum = itGroup.First().move_num;
int itemsCount = items.Count;
int mod = itemsCount % moveNum > 0 ? (itemsCount / moveNum) + 1 : itemsCount / moveNum;
WmsDistaskH[] arrary = items.ToArray();
//for (int i = 1; i <= mod; i++)
{
if (moveNum >= 1)
{
List areaPreTasks = itGroup.ToList();
if (areaPreTasks.Any(x => x.third_eqp_type.ToEnum() != EnumTaskChainType.CTU))
{
Logger.Information("非CTU任务链生成");
for (int i = 0; i < items.Count; i++)
{
var num = (i + 1);
var x = items[i];
string groupCode = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).Result;
x.is_chain = 0;
x.groups = groupCode;
x.bill_code = $"{groupCode}-1";
}
}
else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum <= areaPreTasks.Count)
{
Logger.Information("CTU任务链生成");
string groupCode = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE);
items.ForEach(x => x.is_chain = 1);
int start = 0;
int end = Math.Min(itemsCount, moveNum);
List arrList = new(mod);
while (start < itemsCount)
{
WmsDistaskH[] subArray = arrary[start..end];
arrList.Add(subArray);
start = end;
end = Math.Min(end + moveNum, arrary.Length);
}
foreach (WmsDistaskH[] arr in arrList)
{
for (int j = 1, len = arr.Length; j <= len; j++)
{
arr[j - 1].groups = groupCode;
arr[j - 1].bill_code = $"{groupCode}-{j}";
}
}
}
Logger.Information($"已生成任务执行编码");
}
}
if (preTaskCodes?.Count > 0)
{
foreach (WmsDistaskH disTask in items)
{
List curPreTaskCodes = preTaskCodes.FindAll(x => x.bill_id == disTask.pretask_id);
List curDisTaskCodes = curPreTaskCodes.Adapt>();
curDisTaskCodes.ForEach(x =>
{
x.id = SnowflakeIdHelper.NextId();
x.bill_id = disTask.id;
x.create_time = DateTime.Now;
});
distaskCodes.AddRange(curDisTaskCodes);
}
}
disTasks.AddRange(items);
}
await db.Ado.BeginTranAsync();
int row = await db.Insertable(disTasks).ExecuteCommandAsync();
Logger.Information("【GenTaskExecute】 插入任务执行表数据: " + JsonConvert.SerializeObject(disTasks));
if (preTaskCodes?.Count > 0)
{
row = await db.Insertable(distaskCodes).ExecuteCommandAsync();
Logger.Information("【GenTaskExecute】 插入任务执行条码表数据: " + JsonConvert.SerializeObject(disTasks));
}
if (row > 0)
{
List preTaskIds = preTasks.Select(x => x.id).ToList();
List preTaskBill_codes = preTasks.Select(x => x.bill_code).ToList();
row = await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
Logger.Information("【GenTaskExecute】 更改这些预任务执行状态为 已下发: " + JsonConvert.SerializeObject(preTaskBill_codes));
}
await db.Ado.CommitTranAsync();
Logger.Information("【GenTaskExecute】 预任务执行完成");
Logger.Information($"【GenTaskExecute】_eleCtlCfg.Environment={_eleCtlCfg.Environment}");
if (string.Equals(_eleCtlCfg.Environment, ElevatorConsts.EnvironmentName, StringComparison.OrdinalIgnoreCase))
{
//呼梯操作
//获取目标库位为电梯库位的任务
Logger.Information("【GenTaskExecute】操作设备");
var agvDTTasks = disTasks.Where(it => it.endlocation_code.StartsWith("DT", StringComparison.OrdinalIgnoreCase) &&
!it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList();
foreach (var task in agvDTTasks)
{
ElevagorInfoQuery q = new() { endlocation_id = task.endlocation_id, taskCode = task.bill_code };
Logger.Information($"【GenTaskExecute】呼梯时 根据任务单号获取电梯参数 {JsonConvert.SerializeObject(q)}");
var e = await FindElevatorFromPars(q);
Logger.Information($"【GenTaskExecute】呼梯时 根据任务单号获取电梯结果 {JsonConvert.SerializeObject(e)}");
var tags = _eleCtlCfg.tags;
(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(e.elevator_code, tags, CancellationToken.None);
Logger.Information($"【GenTaskExecute】 电梯当前状态->系统状态:{sysStatus.ToEnum()},运行状态:{runStatus.ToEnum()},Agv状态:{agvStatus.ToEnum()},当前楼层:{floorNo},电梯占用状态{s_eleUseStatusDic[e.device_id]}");
var curFloor = await GetRealFloor(e.elevator_code, e.end_floor);
if (e != null && s_eleUseStatusDic[e.device_id] == (int)EnumElevatorUseStatus.空闲 && curFloor != floorNo)
{
task.device_id = e.device_id;
}
}
_ = CallingLanding(agvDTTasks);
//执行电梯任务
List? elevatorTasks = disTasks.Where(it => it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList();
Logger.Information($"【GenTaskExecute】当前电梯任务数:{elevatorTasks?.Count ?? 0}");
if (elevatorTasks?.Count > 0)
{
List> elevatorTaskGroup = elevatorTasks.GroupBy(r => $"{r.endlocation_code} {r.end_floor}").ToList();
foreach (IGrouping group in elevatorTaskGroup)
{
List wmsDistaskHs = group.ToList();
ElevagorInfoQuery q = new() { endlocation_id = wmsDistaskHs[0].endlocation_id, taskCode = wmsDistaskHs[0].bill_code };
Logger.Information($"【GenTaskExecute】执行电梯任务时 根据任务单号获取电梯参数 {JsonConvert.SerializeObject(q)}");
var e = await FindElevatorFromPars(q);
Logger.Information($"【GenTaskExecute】执行电梯任务时 根据任务单号获取电梯结果 {JsonConvert.SerializeObject(e)}");
// 三、四号梯发货带两托货进定时任务
string[] doubleCarryRunElevators = new string[2]
{
"Elevator3","Elevator4"
};
if (doubleCarryRunElevators.Contains(e.elevator_code) && wmsDistaskHs[0].end_floor == 1)
{
//Logger.Information($"【GenTaskExecute】判断为三四号梯任务");
//Logger.Information($"【GenTaskExecute】现在有{group.Count()}托货");
//// 电梯内放置两托货呼叫电梯下
//if (group.Count() == 2)
//{
// if (e != null)
// {
// wmsDistaskHs[0].device_id = e.device_id;
// wmsDistaskHs[1].device_id = e.device_id;
// }
// Logger.Information($"【GenTaskExecute】呼叫电梯");
// _ = ExecuteTargetFloorTask(wmsDistaskHs);
//}
//// 一托货
//else if (group.Count() == 1)
//{
// // 如果当前电梯没有执行中的任务 则呼叫电梯下
// if (_db.Queryable().Where(r => r.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID
// && r.status != WmsWareHouseConst.TASK_BILL_STATUS_CANCEL_ID && r.endlocation_id == wmsDistaskHs[0].startlocation_id).Count() == 0)
// {
// Logger.Information($"【GenTaskExecute】判断为三四号梯任务 没有执行中的任务 呼叫电梯");
// if (e != null)
// {
// wmsDistaskHs[0].device_id = e.device_id;
// }
// _ = ExecuteTargetFloorTask(wmsDistaskHs);
// }
//}
//else
//{
// Logger.LogError($"电梯 {e.elevator_code} 待执行的电梯任务数异常 目前是{group.Count()} 超过了两托");
//}
}
else
{
//Logger.Information($"【GenTaskExecute】判断为非三四号梯任务");
//if (e != null)
//{
// wmsDistaskHs[0].device_id = e.device_id;
//}
//Logger.Information($"【GenTaskExecute】呼叫电梯");
//_ = ExecuteTargetFloorTask(wmsDistaskHs);
}
}
}
List agvTasks = disTasks.Where(it => !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList();
if (agvTasks?.Count > 0)
{
Logger.Information($"【GenTaskExecute】Agv任务数量:{agvTasks.Count},taskCodes:{string.Join(",", agvTasks.Select(x => x.bill_code).Distinct())}");
_ = AgvDispatch(agvTasks, agvCts.Token);
}
}
}
}
catch (Exception ex) when (ex is HttpRequestException hReqEx)
{
agvCts.Cancel();
}
catch (Exception ex)
{
Logger.Error("【GenTaskExecute】任务执行时出现错误", ex);
Logger.Error(ex.StackTrace!);
await db.Ado.RollbackTranAsync();
throw;
}
finally
{
_ = s_GenTaskExecute.Release();
agvCts.Dispose();
sw.Stop();
Logger.Information($"【GenTaskExecute】 任务执行耗时{sw.ElapsedMilliseconds}毫秒");
}
}
///
/// 获取电梯根据任务单号
///
///
/// taskCode:子任务编号
/// endlocation_id:目标库位ID
///
///
public async Task FindElevatorFromPars(ElevagorInfoQuery input)
{
var whereExpable = Expressionable.Create()
.And((a, b, c) => a.enabled == 1);
Logger.Information($"【FindElevatorFromPars】 {JsonConvert.SerializeObject(input)}");
if (!input.taskCode.IsNullOrEmpty())
{
whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.taskCode), (a, b, c) => c.bill_code == input.taskCode);
}
if (!input.endlocation_id.IsNullOrEmpty())
{
whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.endlocation_id), (a, b, c) => b.location_id == input.endlocation_id);
}
if (!input.startlocation_id.IsNullOrEmpty())
{
whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.startlocation_id), (a, b, c) => b.location_id == input.startlocation_id);
}
var db = _db.CopyNew();
#region 如果是出到三楼出库缓存区
List queryable_f3outstock = db.Queryable()
.InnerJoin((a, b) => a.endlocation_id == b.id)
.InnerJoin((a, b, c) => a.endlocation_code == c.startlocation_code)
.InnerJoin((a, b, c, d) => c.endlocation_code == d.location_code)
.InnerJoin((a, b, c, d, e) => d.bill_id == e.id)
.Where((a, b, c, d, e) => a.endlocation_id == input.endlocation_id && a.bill_code == input.taskCode && b.region_id == WmsWareHouseConst.REGION_CPOutstockCache_ID)
.Select((a, b, c, d, e) => new WmsElevatorH
{
bill_code = a.bill_code,
device_id = e.elevator_id,
end_floor = a.end_floor
}).ToList();
if (queryable_f3outstock.Count() > 0)
{
var ele_f3outstock = queryable_f3outstock[0];
return ele_f3outstock;
}
#endregion
ISugarQueryable queryable = db.Queryable().InnerJoin((a, b) => a.id == b.bill_id)
.InnerJoin((a, b, c) => b.location_code == c.endlocation_code || b.location_code == c.startlocation_code)
.Where(whereExpable.ToExpression())
.WhereIF(!SqlFunc.IsNullOrEmpty(input.sourceName) && SqlFunc.StartsWith("DT-R", input.sourceName), (a, b, c) => c.startpoint_code == input.sourceName)
.WhereIF(!SqlFunc.IsNullOrEmpty(input.sourceName) && SqlFunc.StartsWith("DT-C", input.sourceName), (a, b, c) => c.endpoint_code == input.sourceName)
.Select((a, b, c) => new WmsElevatorH
{
bill_code = c.bill_code,
device_id = a.elevator_id,
end_floor = c.end_floor
}, true);
var ele = await queryable.FirstAsync();
Logger.Information($"【FindElevatorFromPars】 " + queryable.ToSqlString());
return ele;
}
#region CTU
///
/// 生成CTU任务执行
///
///
[HttpPost]
public async Task CTUTaskExecute()
{
try
{
Dictionary indic = new Dictionary();
indic.Add("SSX-021-005", new string[] { "YTCS", "CallCtuFullIn_CS05" });
indic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11呼叫CTU" });
indic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12呼叫CTU" });
var db = _db.CopyNew();
List CTUTasks = await db.Queryable()
.InnerJoin((a, b) => a.area_id == b.id)
.Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID)
.Where((a, b) => b.code == "B")//一楼中储仓
.OrderBy(a => a.create_id)
.Select((a, b) => new WmsPretaskH
{
move_num = b.move_num,
third_eqp_type = b.third_eqp_type,
}, true).ToListAsync();
if (CTUTasks.Count == 0)
return;
List TaskCodes = await db.Queryable().Where(it => CTUTasks.Select(p => p.id).ToList().Contains(it.bill_id)).ToListAsync();
//Logger.Information($@"【CTUTaskExecute】 获取任务TaskCodes: {JsonConvert.SerializeObject(TaskCodes)}");
var InTasks = CTUTasks.Where(a => a.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID).ToList();
var OutTasks = CTUTasks.Where(a => a.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID || a.task_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID).ToList();
//Logger.Information($@"【CTUTaskExecute】 获取任务InTasks: {JsonConvert.SerializeObject(InTasks)}");
//Logger.Information($@"【CTUTaskExecute】 获取任务OutTasks: {JsonConvert.SerializeObject(OutTasks)}");
var OriginDistaskHs = await db.Queryable()
.InnerJoin((a, b) => a.area_id == b.id)
.Where((a, b) => b.code == "B" && a.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID)
.OrderBy(a => a.bill_code)
.ToListAsync();
//Logger.Information($@"【CTUTaskExecute】 OriginDistaskHs: {JsonConvert.SerializeObject(OriginDistaskHs)}");
List DistaskHs = new List();
List UpDistaskHs = new List();
List DistaskCodes = new List();
var inCtuExec = new List();
var outCtuExec = new List();
foreach (var item in InTasks)
{
/*
if (indic.Keys.Contains(item.startlocation_code))
{
var strs = indic.Where(p => p.Key == item.startlocation_code).First().Value;
bool flag = _redisData.HashExist(strs[0], strs[1]).Result;
if (!flag)
continue;
string data = _redisData.GetHash(strs[0], strs[1]).Result;
JObject? res = JsonConvert.DeserializeObject(data);
bool result = res != null && res["Value"] != null ? res.Value("Value") : false;
if (!result)
continue;
}*/
WmsDistaskH distaskH = item.Adapt();
distaskH.id = SnowflakeIdHelper.NextId();
distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID;
distaskH.is_chain = 1;
distaskH.create_time = DateTime.Now;
var billcode = GetBillCode(OriginDistaskHs, DistaskHs, distaskH);
distaskH.groups = billcode.Substring(0, billcode.Length - 2);
distaskH.bill_code = billcode;
var num = int.Parse(distaskH.bill_code.Substring(billcode.Length - 1, 1));
Logger.Information($@"【CTUTaskExecute】 比对billcode:{num}和单次搬运数量move_num:{item.move_num},如果一致 会添加到inCtuExec");
if (num == item.move_num)
{
distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID;
inCtuExec.Add(distaskH);
if (OriginDistaskHs.Where(p => p.groups == distaskH.groups).Any())
{
OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID);
UpDistaskHs.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList());
inCtuExec.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList());
}
if (DistaskHs.Where(p => p.groups == distaskH.groups).Any())
{
DistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID);
inCtuExec.AddRange(DistaskHs.Where(p => p.groups == distaskH.groups).ToList());
}
}
List preTaskCodes = TaskCodes.FindAll(x => x.bill_id == distaskH.pretask_id);
List