齐套等

This commit is contained in:
2024-09-24 12:04:40 +08:00
parent 03d847aa94
commit 1007c7c23d
13 changed files with 759 additions and 11 deletions

View File

@@ -36,6 +36,8 @@ using Org.BouncyCastle.Asn1.X509.Qualified;
using Qiniu.Util;
using Senparc.CO2NET.Helpers.Serializers;
using SqlSugar;
using Tnb.BasicData;
//using Swashbuckle.AspNetCore.SwaggerGen;
using Tnb.BasicData.Entities;
using Tnb.Common.Extension;
@@ -95,6 +97,8 @@ namespace Tnb.ProductionMgr
private static Timer? F2KTPsupplementtimer;
// 原材料仓内转移
private static Timer? YCLInternalTransfertimer;
// 生成物料齐套配送计划
private static Timer? WmsMaterialkittimer;
// 电梯
private static Timer? elevatorTimer;
@@ -118,6 +122,8 @@ namespace Tnb.ProductionMgr
public SemaphoreSlim s_taskFloor4DMC2CPKService = new(1);
public SemaphoreSlim s_taskF2KTPsupplement = new(1);
public SemaphoreSlim s_taskYCLInternalTransfer = new(1);
public SemaphoreSlim s_taskWmsMaterialkit = new(1);
/// <summary>
/// AGV到电梯任务
/// </summary>
@@ -144,6 +150,7 @@ namespace Tnb.ProductionMgr
private ISqlSugarClient db_Floor4DMC2CPK;
private ISqlSugarClient db_F2KTPsupplement;
private ISqlSugarClient db_YCLInternalTransfer;
private ISqlSugarClient db_WmsMaterialkit;
@@ -202,6 +209,7 @@ namespace Tnb.ProductionMgr
db_Floor4DMC2CPK = repository.CopyNew();
db_F2KTPsupplement = repository.CopyNew();
db_YCLInternalTransfer = repository.CopyNew();
db_WmsMaterialkit = repository.CopyNew();
List<string> elevatorAreas = repository.CopyNew().Queryable<WmsElevatorH>().Select(r => r.area_code).Distinct().ToList();
foreach (var s_elevatorArea in elevatorAreas)
@@ -2700,7 +2708,233 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA
}
}
#endregion
// 物料齐套配送记录
private async void WmsMaterialkit(object? args)
{
if (s_taskWmsMaterialkit.CurrentCount == 0)
return;
await s_taskWmsMaterialkit.WaitAsync();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
try
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始执行生成物料齐套配送记录");
LoggerTimer.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始执行生成物料齐套配送记录");
List<PrdMoTask> prdMoTasks = await db_WmsMaterialkit.Queryable<PrdMoTask>().Where(r => r.mo_task_status == DictConst.InProgressEnCode
&& !string.IsNullOrEmpty(r.parent_id)).ToListAsync();
LoggerWmsMaterialkit.LogInformation($"查找到进行中的任务单:{string.Join(',', prdMoTasks.Select(r => r.mo_task_code))}");
foreach (PrdMoTask prdMoTask in prdMoTasks)
{
List<PrdMoTask> rep_prdMoTasks = prdMoTasks.Where(r => r.workline_id == prdMoTask.workline_id && r.id != prdMoTask.id).ToList();
if (rep_prdMoTasks.Count() > 0)
{
LoggerWmsMaterialkit.LogWarning($"存在与任务单{prdMoTask.mo_task_code}相同产线的状态为进行中的任务单{string.Join(',', rep_prdMoTasks.Select(r => r.mo_task_code))}");
continue;
}
await db_WmsMaterialkit.Ado.BeginTranAsync();
WmsMaterialkitRecordH wmsMaterialkitRecordH = await db_WmsMaterialkit.Queryable<WmsMaterialkitRecordH>().Where(r => (r.status == WmsWareHouseConst.BILLSTATUS_ADD_ID || r.status == WmsWareHouseConst.BILLSTATUS_ON_ID)
&& r.workline_id == prdMoTask.workline_id).FirstAsync();
LoggerWmsMaterialkit.LogInformation($"查找任务单{prdMoTask.mo_task_code}的物料配送记录:{JsonConvert.SerializeObject(wmsMaterialkitRecordH)}");
if (wmsMaterialkitRecordH == null || (wmsMaterialkitRecordH != null && prdMoTask.id != wmsMaterialkitRecordH.mo_task_id))
{
if (wmsMaterialkitRecordH != null && prdMoTask.id != wmsMaterialkitRecordH.mo_task_id)
{
LoggerWmsMaterialkit.LogInformation($"取消任务单{prdMoTask.mo_task_code}的旧物料配送记录:{wmsMaterialkitRecordH.bill_code}");
// 取消旧物料配送记录
await db_WmsMaterialkit.Updateable<WmsMaterialkitRecordH>().SetColumns(r =>
new WmsMaterialkitRecordH { status = WmsWareHouseConst.BILLSTATUS_CANCEL_ID, remark = $"由于任务单切换取消 {wmsMaterialkitRecordH.mo_task_code} -> {prdMoTask.mo_task_code}" })
.Where(r => r.id == wmsMaterialkitRecordH.id).ExecuteCommandAsync();
}
// 生成物料配送记录
BasMaterial basMaterial = await db_WmsMaterialkit.Queryable<BasMaterial>().Where(r => r.id == prdMoTask.material_id).FirstAsync();
string Code = await _billRullService.GetBillNumber("WmsMaterialkitRecordH");
wmsMaterialkitRecordH = new WmsMaterialkitRecordH();
wmsMaterialkitRecordH.org_id = WmsWareHouseConst.AdministratorOrgId;
wmsMaterialkitRecordH.create_id = WmsWareHouseConst.AdministratorUserId;
wmsMaterialkitRecordH.create_time = DateTime.Now;
wmsMaterialkitRecordH.bill_code = Code;
wmsMaterialkitRecordH.mo_task_id = prdMoTask.id;
wmsMaterialkitRecordH.mo_task_code = prdMoTask.mo_task_code;
wmsMaterialkitRecordH.bom_id = prdMoTask.bom_id;
wmsMaterialkitRecordH.material_id = prdMoTask.material_id;
wmsMaterialkitRecordH.material_code = basMaterial.code;
wmsMaterialkitRecordH.material_name = basMaterial.name;
wmsMaterialkitRecordH.material_specification = basMaterial.material_specification;
wmsMaterialkitRecordH.unit_code = prdMoTask.unit_id;
wmsMaterialkitRecordH.qty = prdMoTask.scheduled_qty;
wmsMaterialkitRecordH.workline_id = prdMoTask.workline_id;
wmsMaterialkitRecordH.status = WmsWareHouseConst.BILLSTATUS_ADD_ID;
wmsMaterialkitRecordH.times = 0;
wmsMaterialkitRecordH.total_time = 0;
BasMbom basMbom = await db_WmsMaterialkit.Queryable<BasMbom>().Where(r => r.id == prdMoTask.bom_id).FirstAsync();
if (basMbom == null)
{
LoggerWmsMaterialkit.LogWarning($"任务单{prdMoTask.mo_task_code}绑定的生产Bom id{prdMoTask.bom_id}找不到对应的生产Bom资料");
continue;
}
List<BasMbomInput> basMbomInputs = await db_WmsMaterialkit.Queryable<BasMbomInput>().Where(r => r.mbom_id == basMbom.id).ToListAsync();
List<BasMaterial> materials = await db_WmsMaterialkit.Queryable<BasMaterial>().Where(r => basMbomInputs.Select(x => x.material_id).Contains(r.id)).ToListAsync();
LoggerWmsMaterialkit.LogWarning($"任务单{prdMoTask.mo_task_code}绑定的生产Bom{prdMoTask.bom_id}找到对应的生产Bom清单{string.Join(',', basMbomInputs.Select(r => r.material_id))}");
List<WmsMaterialkitRecordD> wmsMaterialkitRecordDs = new List<WmsMaterialkitRecordD>();
foreach (BasMbomInput input in basMbomInputs)
{
BasMaterial material = materials.Where(r => r.id == input.material_id).First();
if (material == null)
{
LoggerWmsMaterialkit.LogWarning($"任务单{prdMoTask.mo_task_code}绑定的生产Bom id{prdMoTask.bom_id}下的物料id{input.material_id}在物料档案中不存在");
continue;
}
WmsMaterialkitRecordD wmsMaterialkitRecordD = new WmsMaterialkitRecordD();
wmsMaterialkitRecordD.create_id = WmsWareHouseConst.AdministratorUserId;
wmsMaterialkitRecordD.create_time = DateTime.Now;
wmsMaterialkitRecordD.bill_id = wmsMaterialkitRecordH.id;
wmsMaterialkitRecordD.material_id = material.id;
wmsMaterialkitRecordD.material_code = material.code;
wmsMaterialkitRecordD.material_name = material.name;
wmsMaterialkitRecordD.material_specification = material.material_specification;
wmsMaterialkitRecordD.unit_code = material.unit_id;
wmsMaterialkitRecordD.plan_qty = prdMoTask.scheduled_qty * input.denominator / input.molecule;
wmsMaterialkitRecordD.yxf_qty = 0;
wmsMaterialkitRecordD.molecule = input.molecule;
wmsMaterialkitRecordD.denominator = input.denominator;
wmsMaterialkitRecordD.status = WmsWareHouseConst.BILLSTATUS_ADD_ID;
wmsMaterialkitRecordD.times = 0;
wmsMaterialkitRecordD.total_time = 0;
wmsMaterialkitRecordDs.Add(wmsMaterialkitRecordD);
}
await db_WmsMaterialkit.Insertable(wmsMaterialkitRecordH).ExecuteCommandAsync();
await db_WmsMaterialkit.Insertable(wmsMaterialkitRecordDs).ExecuteCommandAsync();
LoggerWmsMaterialkit.LogInformation($"生成任务单{prdMoTask.mo_task_code}的新物料配送记录:{wmsMaterialkitRecordH.bill_code}");
}
await db_WmsMaterialkit.Ado.CommitTranAsync();
}
List<WmsMaterialkitRecordH> wmsMaterialkitRecordHs = await db_WmsMaterialkit.Queryable<WmsMaterialkitRecordH>().Where(r => (r.status == WmsWareHouseConst.BILLSTATUS_ADD_ID
|| r.status == WmsWareHouseConst.BILLSTATUS_ON_ID)).ToListAsync();
LoggerWmsMaterialkit.LogInformation($"查找到需要运算的物料配送记录:{JsonConvert.SerializeObject(string.Join(',', wmsMaterialkitRecordHs.Select(r => r.bill_code)))}");
if (wmsMaterialkitRecordHs.Count == 0)
return;
Stopwatch stopwatch_inv = new Stopwatch();
stopwatch_inv.Start();
// 暂存仓库存
var zccinventory = await db_WmsMaterialkit.Queryable<WmsCarryH>()
.InnerJoin<BasLocation>((a, b) => a.location_id == b.id)
.InnerJoin<WmsCarryD>((a, b, c) => a.id == c.carry_id)
.InnerJoin<WmsCarryCode>((a, b, c, d) => c.membercarry_id == d.carry_id)
.InnerJoin<BasMaterial>((a, b, c, d, e) => d.material_id == e.id)
.Where((a, b, c, d, e) => b.wh_id == WmsWareHouseConst.WAREHOUSE_ZCC_ID)
.Select((a, b, c, d, e) => new customInventoryEntity
{
material_id = e.id,
material_code = e.code,
material_name = e.name,
material_specification = e.material_specification,
codeqty = d.codeqty,
unit_code = d.unit_id
}).ToListAsync();
// 正在配送
var inroadinventory = await db_WmsMaterialkit.Queryable<WmsPretaskH>()
.InnerJoin<WmsCarryH>((a, b) => a.carry_id == b.id)
.InnerJoin<WmsCarryCode>((a, b, c) => c.carry_id == b.id)
.InnerJoin<BasMaterial>((a, b, c, d) => d.id == c.material_id)
.Where((a, b, c, d) => a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && a.status != WmsWareHouseConst.PRETASK_BILL_STATUS_CANCEL_ID
&& (a.endlocation_id == WmsWareHouseConst.ZZCSSX111011 || a.endlocation_id == WmsWareHouseConst.ZZCSSX111012))
.Select((a, b, c, d) => new customInventoryEntity
{
material_id = d.id,
material_code = d.code,
material_name = d.name,
material_specification = d.material_specification,
codeqty = c.codeqty,
unit_code = c.unit_id
}).ToListAsync();
// 中储仓库存
var inventory_中储 = await db_WmsMaterialkit.Queryable<WmsCarryH>()
.InnerJoin<BasLocation>((a, b) => a.location_id == b.id)
.InnerJoin<WmsCarryD>((a, b, c) => a.id == c.carry_id)
.InnerJoin<WmsCarryCode>((a, b, c, d) => c.membercarry_id == d.carry_id)
.InnerJoin<BasMaterial>((a, b, c, d, e) => d.material_id == e.id)
.Where((a, b, c, d, e) => b.wh_id == WmsWareHouseConst.WAREHOUSE_ZC_ID)
.Select((a, b, c, d, e) => new customInventoryEntity
{
material_id = e.id,
material_code = e.code,
material_name = e.name,
material_specification = e.material_specification,
codeqty = d.codeqty,
unit_code = d.unit_id
}).ToListAsync();
List<customInventoryEntity> inventory = new List<customInventoryEntity>();
inventory.AddRange(zccinventory);
inventory.AddRange(inroadinventory);
inventory.GroupBy(g => new { g.material_id, g.material_code, g.material_name, g.material_specification, g.unit_code }).Select(g =>
{
customInventoryEntity newinventory = new customInventoryEntity();
newinventory.material_id = g.Key.material_id;
newinventory.material_code = g.Key.material_code;
newinventory.material_name = g.Key.material_name;
newinventory.material_specification = g.Key.material_specification;
newinventory.unit_code = g.Key.unit_code;
newinventory.codeqty = inventory.Where(r => r.material_id == newinventory.material_id && r.unit_code == newinventory.unit_code).Sum(s => s.codeqty);
return newinventory;
});
stopwatch_inv.Stop();
LoggerWmsMaterialkit.LogInformation($"中储仓与暂存仓库存查询完成,耗时{stopwatch_inv.ElapsedMilliseconds} ms");
// 执行暂存仓库存检查与转库单下发
foreach (WmsMaterialkitRecordH wmsMaterialkitRecord in wmsMaterialkitRecordHs)
{
Stopwatch stopwatch2 = new Stopwatch();
stopwatch2.Start();
await db_WmsMaterialkit.Ado.BeginTranAsync();
await db_WmsMaterialkit.Ado.CommitTranAsync();
stopwatch2.Stop();
LoggerWmsMaterialkit.LogInformation($"物料配送记录{wmsMaterialkitRecord.bill_code}已下发,耗时{stopwatch2.ElapsedMilliseconds} ms");
}
}
catch (ObjectDisposedException ex)
{
LoggerWmsMaterialkit.LogWarning($"【物料齐套配送】 数据库连接异常:{ex.Message}");
LoggerWmsMaterialkit.LogWarning($"【物料齐套配送】 数据库连接异常:{ex.StackTrace}");
if (ex.Source == "Npgsql")
db_WmsMaterialkit = _repository.AsSugarClient().CopyNew();
}
catch (Exception ex)
{
Console.WriteLine("【物料齐套配送】" + ex.Message);
LoggerWmsMaterialkit.LogWarning($"【物料齐套配送】 {ex.Message}");
LoggerWmsMaterialkit.LogWarning($"【物料齐套配送】 {ex.StackTrace}");
// 数据库连接断开时会报错
try { await db_WmsMaterialkit.Ado.RollbackTranAsync(); } catch { };
}
finally
{
s_taskWmsMaterialkit.Release();
if (!db_WmsMaterialkit.Ado.Transaction.IsNull())
try { await db_WmsMaterialkit.Ado.CommitTranAsync(); } catch { };
_wareHouseService.GenTaskExecute();
stopwatch.Stop();
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 结束物料齐套配送记录 {stopwatch.ElapsedMilliseconds} ms");
LoggerTimer.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 结束物料齐套配送记录 {stopwatch.ElapsedMilliseconds} ms");
}
}
public Task StartAsync(CancellationToken cancellationToken)
{
@@ -2740,6 +2974,8 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA
elevatorTimer = new Timer(ElevatorTaskExceptionHandle, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
agvelevatorTimer = new Timer(AgvelevatorTimerTaskExceptionHandle, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
//WmsMaterialkittimer = new Timer(WmsMaterialkit, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(3600));
return Task.CompletedTask;
}
@@ -2773,7 +3009,7 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA
YCLInternalTransfertimer?.Dispose();
elevatorTimer?.Dispose();
agvelevatorTimer?.Dispose();
WmsMaterialkittimer?.Dispose();
}
#region
@@ -3197,7 +3433,49 @@ where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STA
return _LoggerYCLInternalTransfer;
}
}
protected string _LoggerWmsMaterialkitFileName = "";
protected ILogger _LoggerWmsMaterialkit;
protected ILogger LoggerWmsMaterialkit
{
get
{
string newFileName = $"{AppContext.BaseDirectory}/logs/{DateTime.Now:yyyyMMdd}/齐套配送/custom{DateTime.Now:yyyyMMdd}齐套配送.log";
if (_LoggerWmsMaterialkitFileName != newFileName)
{
ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddFile(newFileName, cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
}));
_LoggerWmsMaterialkit = loggerFactory.CreateLogger(this.GetType());
_LoggerWmsMaterialkitFileName = newFileName;
}
return _LoggerWmsMaterialkit;
}
}
#endregion
public class customInventoryEntity
{
public string material_id { get; set; }
public string material_code { get; set; }
public string material_name { get; set; }
public string material_specification { get; set; }
public decimal? codeqty { get; set; }
public string unit_code { get; set; }
}
}
}