1004 lines
46 KiB
C#
1004 lines
46 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Aspose.Cells.Drawing;
|
||
using DbModels;
|
||
using JNPF.Common.Core.Manager;
|
||
using JNPF.DependencyInjection;
|
||
using JNPF.DynamicApiController;
|
||
using JNPF.Systems.Interfaces.System;
|
||
using JNPF.VisualDev;
|
||
using Mapster;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using SqlSugar;
|
||
using Tnb.BasicData.Entities;
|
||
using Tnb.BasicData;
|
||
using Tnb.EquipMgr.Entities;
|
||
using Tnb.ProductionMgr.Entities;
|
||
using Tnb.ProductionMgr.Entities.Dto.PrdManage;
|
||
using Tnb.ProductionMgr.Entities.Dto;
|
||
using Tnb.ProductionMgr.Interfaces;
|
||
using JNPF.Common.Enums;
|
||
using JNPF.Common.Extension;
|
||
using JNPF.Common.Security;
|
||
using JNPF.FriendlyException;
|
||
using Tnb.ProductionMgr.Entities.Enums;
|
||
using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
|
||
using JNPF.VisualDev.Interfaces;
|
||
using JNPF.VisualDev.Entitys;
|
||
using Aop.Api.Domain;
|
||
using Senparc.Weixin.MP.AdvancedAPIs.Card;
|
||
using Aspose.Cells.Drawing.Texts;
|
||
using JNPF.Systems.Entitys.Permission;
|
||
using WebSocketSharp.Frame;
|
||
|
||
namespace Tnb.ProductionMgr
|
||
{
|
||
[ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)]
|
||
[Route("api/[area]/[controller]/[action]")]
|
||
[OverideVisualDev(ModuleId)]
|
||
|
||
public class PrdMoTaskService : IOverideVisualDevService, IPrdMoTaskService, IDynamicApiController, ITransient
|
||
{
|
||
private const string ModuleId = "25567924238373";
|
||
private readonly ISqlSugarRepository<PrdTask> _repository;
|
||
private readonly IUserManager _userManager;
|
||
private readonly IDictionaryDataService _dictionaryDataService;
|
||
private readonly IRunService _runService;
|
||
private readonly IVisualDevService _visualDevService;
|
||
private static Dictionary<string, object> _dicDefect = new Dictionary<string, object>();
|
||
private static Dictionary<string, object> _dicWorkLine = new Dictionary<string, object>();
|
||
private static Dictionary<string, object> _dicProcess = new Dictionary<string, object>();
|
||
private readonly ISqlSugarClient _db;
|
||
|
||
|
||
public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc();
|
||
public PrdMoTaskService(
|
||
ISqlSugarRepository<PrdTask> repository,
|
||
IUserManager userManager,
|
||
IDictionaryDataService dictionaryDataService,
|
||
IRunService runService,
|
||
IVisualDevService visualDevService
|
||
)
|
||
{
|
||
_repository = repository;
|
||
_userManager = userManager;
|
||
_dictionaryDataService = dictionaryDataService;
|
||
_runService = runService;
|
||
_visualDevService = visualDevService;
|
||
_db = _repository.AsSugarClient();
|
||
OverideFuncs.DeleteAsync = Delete;
|
||
OverideFuncs.GetListAsync = GetList;
|
||
|
||
}
|
||
|
||
|
||
#region Get
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 根据产品ID获取模具列表
|
||
/// </summary>
|
||
/// <param name="itemId">产品ID</param>
|
||
/// <returns></returns>
|
||
/// <remarks>
|
||
/// <br/>return results:
|
||
/// <br/>[
|
||
/// <br/> {
|
||
/// <br/> mold_code:模具编号
|
||
/// <br/> mold_name:模具名称
|
||
/// <br/> item_name:产品名称
|
||
/// <br/> item_code:产品编号
|
||
/// <br/> cavity_qty:模穴数
|
||
/// <br/> }
|
||
/// <br/>]
|
||
/// </remarks>
|
||
|
||
|
||
[HttpGet("{materialId}")]
|
||
public async Task<dynamic> GetMoldListByItemId(string materialId)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
var list = await db.Queryable<Molds>().InnerJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.Where((a, b) => a.material_id == materialId)
|
||
.Select((a, b) => new MoldListOutput
|
||
{
|
||
mold_id = a.id,
|
||
mold_code = a.mold_code,
|
||
mold_name = a.mold_name,
|
||
mold_type_code = a.mold_type_code,
|
||
material_name = b.name,
|
||
material_code = b.code,
|
||
available_stations = SqlFunc.Subqueryable<EqpEquipment>().Where(it => it.mold_id == a.id).Count(),
|
||
})
|
||
.ToListAsync();
|
||
return list;
|
||
|
||
}
|
||
/// <summary>
|
||
/// 根据模具Id获取设备列表
|
||
/// </summary>
|
||
/// <param name="moldId"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{moldId}")]
|
||
public async Task<dynamic> GetEquipmentListByMoldId(string moldId)
|
||
{
|
||
var items = await _repository.AsSugarClient().Queryable<EqpEquipment>()
|
||
.Where(it => it.mold_id == moldId)
|
||
.Select(it => new EquipmentListOutput
|
||
{
|
||
eqp_id = it.id,
|
||
eqp_code = it.code,
|
||
eqp_type_code = SqlFunc.Subqueryable<EqpEquipType>().Where(iit => iit.id == it.equip_type_id).Select(iit => iit.code),
|
||
eqp_machine_num = it.eqp_machine_num,
|
||
tonnage = it.tonnage,
|
||
task_list_qty = SqlFunc.Subqueryable<PrdTask>().Where(x => x.eqp_id == it.id).Count(),
|
||
estimated_end_date = SqlFunc.Subqueryable<PrdTask>().Where(x => x.eqp_id == it.id).OrderByDesc(o => o.plan_end_date).Select(x => x.plan_end_date)
|
||
})
|
||
.Mapper(x =>
|
||
{
|
||
x.first_date = x.estimated_end_date.HasValue ? x.estimated_end_date.Value.ToString("yyyy-MM-dd HH:mm:ss") : "";
|
||
})
|
||
.ToListAsync();
|
||
return items;
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单调整-生产任务重新排序
|
||
/// </summary>
|
||
/// <param name="eqpId">设备ID</param>
|
||
/// <returns>排序后生产任务列表</returns>
|
||
/// <remarks>
|
||
/// returns:
|
||
/// <br/>[
|
||
/// <br/> {
|
||
/// <br/> no:生产序号
|
||
/// <br/> mo_id:工单编号
|
||
/// <br/> group_flag:同组标识
|
||
/// <br/> plan_qty:计划生产数量
|
||
/// <br/> comple_qty:完成数量
|
||
/// <br/> item_name:产品名称
|
||
/// <br/> mold_code:模具编号
|
||
/// <br/> }
|
||
/// <br/>]
|
||
/// </remarks>
|
||
[HttpGet("{eqpId}")]
|
||
public async Task<dynamic> PrdTaskSort(string eqpId)
|
||
{
|
||
var taskStatusDic = await _dictionaryDataService.GetDicByTypeId(DictConst.PrdTaskStatusTypeId);
|
||
var list = await _repository.AsSugarClient().Queryable<PrdMoTask>()
|
||
.LeftJoin<PrdMo>((a, b) => a.mo_id == b.id)
|
||
.LeftJoin<BasMaterial>((a, b, c) => a.material_id == c.id)
|
||
.LeftJoin<Molds>((a, b, c, d) => a.mold_id == d.id)
|
||
.Where((a, b, c, d) => a.eqp_id == eqpId)
|
||
.OrderBy((a, b, c, d) => a.estimated_start_date)
|
||
.Select((a, b, c, d) => new PrdTaskSortOutput
|
||
{
|
||
mo_status_code = a.mo_task_code,
|
||
status = a.mo_task_status,
|
||
group_flag = a.group_flag,
|
||
plan_qty = b.plan_qty,
|
||
comple_qty = a.complete_qty,
|
||
item_name = c.name,
|
||
mold_code = d.mold_code,
|
||
})
|
||
.ToListAsync();
|
||
var data = list.Select((x, idx) => new PrdTaskSortOutput
|
||
{
|
||
no = idx + 1,
|
||
mo_status_code = x.mo_status_code,
|
||
status = taskStatusDic.ContainsKey(x.status) ? taskStatusDic[x.status].ToString() : "",
|
||
group_flag = x.group_flag,
|
||
plan_qty = x.plan_qty,
|
||
comple_qty = x.comple_qty,
|
||
item_name = x.item_name,
|
||
mold_code = x.mold_code,
|
||
})
|
||
.ToList();
|
||
return data;
|
||
}
|
||
/// <summary>
|
||
/// 查看生产任务操作记录
|
||
/// </summary>
|
||
/// <param name="taskId">任务ID</param>
|
||
/// <returns></returns>
|
||
[HttpGet("{taskId}")]
|
||
public async Task<dynamic> GetMoOperRecord(string taskId)
|
||
{
|
||
var list = await _repository.AsSugarClient().Queryable<PrdTaskLog>().Where(it => it.mo_task_id == taskId).ToListAsync();
|
||
var data = list.Adapt<List<PrdTaskOperOutput>>();
|
||
var dic = await _dictionaryDataService.GetDicByTypeId(DictConst.PrdTaskStatusTypeId);
|
||
_repository.AsSugarClient().ThenMapper(data, x => x.statusName = dic.ContainsKey(x.status) ? dic[x.status].ToString() : "");
|
||
return data;
|
||
}
|
||
/// <summary>
|
||
/// 根据任务单号获取提报记录明细
|
||
/// </summary>
|
||
/// <param name="icmoCode">任务单号</param>
|
||
/// <remarks>
|
||
/// returns:
|
||
///<br/> {
|
||
///<br/> icmo_qty:任务计划数量
|
||
///<br/> reported_work_qty:已报工数量
|
||
///<br/> reported_qty:报工数量
|
||
///<br/> prd_qty:生产数量
|
||
///<br/> }
|
||
/// </remarks>
|
||
[HttpGet("{mo_task_code}")]
|
||
public async Task<dynamic> GetPrdReportByIcmoCode(string mo_task_code)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
var prdTask = await db.Queryable<PrdMoTask>().FirstAsync(it => it.mo_task_code == mo_task_code);
|
||
var eqpCode = "";
|
||
var moldCode = "";
|
||
var materialCode = "";
|
||
var materialName = "";
|
||
var materialProp = "";
|
||
if (prdTask != null)
|
||
{
|
||
var eqp = await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == prdTask.eqp_id);
|
||
var mold = await db.Queryable<Molds>().FirstAsync(it => it.id == prdTask.mold_id);
|
||
var material = await db.Queryable<BasMaterial>().FirstAsync(it => it.id == prdTask.material_id);
|
||
eqpCode = eqp != null ? eqp.code : "";
|
||
moldCode = mold != null ? mold.mold_code : "";
|
||
materialCode = material != null ? material.code : "";
|
||
materialName = material != null ? material.name : "";
|
||
materialProp = material != null ? material.material_property : "";
|
||
}
|
||
|
||
|
||
var res = await db.Queryable<PrdReport>().Where(it => it.mo_task_code == mo_task_code)
|
||
.Select(it => new PrdReportOutput
|
||
{
|
||
icmo_qty = it.icmo_qty,
|
||
reported_work_qty = it.reported_work_qty,
|
||
//reported_qty = it.reported_qty,
|
||
eqp_code = eqpCode,
|
||
mold_code = moldCode,
|
||
material_code = materialCode,
|
||
material_name = materialName,
|
||
prd_qty = it.prd_qty,
|
||
scrap_qty = SqlFunc.Subqueryable<PrdScrapped>().Select(x => x.scrap_qty),
|
||
})
|
||
.Mapper(it =>
|
||
{
|
||
it.icmo_qty = it.icmo_qty ?? (db.Queryable<PrdTask>().First(it => it.icmo_code == mo_task_code)?.scheduled_qty < 1 ? 0 : it.icmo_qty ?? db.Queryable<PrdTask>().First(it => it.icmo_code == mo_task_code).scheduled_qty);
|
||
it.reported_work_qty = it.reported_work_qty ?? 0;
|
||
//it.reported_qty = it.reported_qty ?? 0;
|
||
it.prd_qty = it.prd_qty ?? 0;
|
||
it.scrap_qty = it.scrap_qty ?? 0;
|
||
})
|
||
.FirstAsync();
|
||
res ??= new PrdReportOutput
|
||
{
|
||
icmo_qty = db.Queryable<PrdMoTask>().First(it => it.mo_task_code == mo_task_code)?.scheduled_qty,
|
||
reported_work_qty = 0,
|
||
//reported_qty = 0,
|
||
prd_qty = 0,
|
||
scrap_qty = 0,
|
||
};
|
||
return res;
|
||
}
|
||
/// <summary>
|
||
/// 获取自检报废批次记录
|
||
/// </summary>
|
||
/// <param name="moTaskId">任务单Id</param>
|
||
/// <returns></returns>
|
||
[HttpGet("{moTaskId}")]
|
||
public async Task<dynamic> GetScarpStatRecord(string moTaskId)
|
||
{
|
||
var output = new PrdMoTaskDefectOutput();
|
||
var db = _repository.AsSugarClient();
|
||
if (_dicDefect.Count < 1)
|
||
{
|
||
_dicDefect = await db.Queryable<BasDefectType>().ToDictionaryAsync(x => x.id, x => x.defect_type_name);
|
||
}
|
||
output.mo_task_code = (await db.Queryable<PrdMoTask>().FirstAsync(it => it.id == moTaskId))?.mo_task_code;
|
||
var defects = await db.Queryable<PrdMoTaskDefect>().Where(it => it.mo_task_id == moTaskId).ToListAsync();
|
||
if (defects?.Count > 0)
|
||
{
|
||
output.batchItems = defects.GroupBy(g => new { g.batch }).Select(t => new BatchItem
|
||
{
|
||
scrap_qty = t.Sum(d => d.defective_item_qty),
|
||
batch = t.Key.batch,
|
||
create_time = t.Key.batch.ParseToDateTime().ToString("yyyy-MM-dd HH:mm:ss"),
|
||
categoryItems = t.GroupBy(g => g.defective_cagetory_id).Select(c => new CategoryItem
|
||
{
|
||
name = _dicDefect[c.Key]?.ToString(),
|
||
qty = c.Sum(d => d.defective_item_qty),
|
||
defectItems = c.Select(d => new DefectItem
|
||
{
|
||
name = d.defective_item,
|
||
qty = d.defective_item_qty,
|
||
}).ToList(),
|
||
}).ToList(),
|
||
}).ToList();
|
||
}
|
||
return output;
|
||
}
|
||
/// <summary>
|
||
/// 根据工单Id获取任务单列表
|
||
/// </summary>
|
||
/// <param name="moId"></param>
|
||
/// <remarks>
|
||
/// output:
|
||
/// <br/>{
|
||
/// <br/> mo_task_code:生产任务单号
|
||
/// <br/> material_code:物料编码
|
||
/// <br/> mold_code:模具编码
|
||
/// <br/> mold_name:模具名称
|
||
/// <br/> eqp_code:设备编码
|
||
/// <br/> eqp_name:设备名称
|
||
/// <br/> eqp_type_code:设备型号
|
||
/// <br/> mo_task_qty:任务单数量
|
||
/// <br/> mo_task_status:任务状态
|
||
/// <br/> scheduled_qty:计划生产数量
|
||
/// <br/> complete_qty:完成数量
|
||
/// <br/> estimated_start_date:预计开工时间
|
||
/// <br/> estimated_end_date:预计完工时间
|
||
/// <br/>}
|
||
/// </remarks>
|
||
[HttpGet("{moId}")]
|
||
public async Task<dynamic> GetPrdTaskInfoByMoId(string moId)
|
||
{
|
||
|
||
var dic = await _dictionaryDataService.GetDicByTypeId(DictConst.PrdTaskStatusTypeId);
|
||
var result = await _db.Queryable<PrdMoTask>().LeftJoin<PrdMo>((a, b) => a.mo_id == b.id)
|
||
.LeftJoin<BasMaterial>((a, b, c) => a.material_id == c.id)
|
||
.LeftJoin<Molds>((a, b, c, d) => a.mold_id == d.id)
|
||
.LeftJoin<EqpEquipment>((a, b, c, d, e) => a.eqp_id == e.id)
|
||
.Where((a, b, c, d, e) => a.mo_id == moId)
|
||
.Select((a, b, c, d, e) => new PrdMoTaskOutput
|
||
{
|
||
mo_task_code = a.mo_task_code,
|
||
mo_task_status = a.mo_task_status,
|
||
mold_code = d.mold_code,
|
||
mold_name = d.mold_name,
|
||
material_code = c.code,
|
||
material_name = c.name,
|
||
eqp_code = e.code,
|
||
eqp_name = e.name,
|
||
eqp_type_code = SqlFunc.Subqueryable<EqpEquipType>().Where(it => it.id == e.equip_type_id).Select(it => it.code),
|
||
mo_task_qty = SqlFunc.Subqueryable<PrdMoTask>().Where(a => a.mo_id == moId).Count(),
|
||
estimated_start_date = a.estimated_start_date,
|
||
estimated_end_date = a.estimated_end_date,
|
||
plan_qty = b.plan_qty,
|
||
complete_qty = a.complete_qty,
|
||
})
|
||
.Mapper(it =>
|
||
{
|
||
it.mo_task_status = dic.ContainsKey(it.mo_task_status) ? dic[it.mo_task_status].ToString() : "";
|
||
})
|
||
.ToListAsync();
|
||
return result;
|
||
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
#region Post
|
||
|
||
/// <summary>
|
||
/// 生产工单-生产排产
|
||
/// </summary>
|
||
/// <param name="input">
|
||
///<br/>{
|
||
///<br/> Id:生产任务主键Id
|
||
///<br/> MoType:工单类型 1、注塑/挤出 2、组装/包装
|
||
///<br/> MoId:工单Id
|
||
///<br/> ItemId:产品编号
|
||
///<br/> ItemName:产品名称
|
||
///<br/> MoldId:模具Id
|
||
///<br/> MoldName:模具名称
|
||
///<br/> EqpId:设备Id
|
||
///<br/> EqpName:设备名称
|
||
///<br/> LineId:产线编号
|
||
///<br/> LineName:产线名称
|
||
///<br/>}
|
||
/// </param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> ProductionScheduling(ProductionSchedulingCrInput input)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
var row = -1;
|
||
if (input.schedule_type.HasValue)
|
||
{
|
||
if (input.schedule_type.Value == 1) //注塑、基础排产
|
||
{
|
||
var moTask = input.Adapt<PrdMoTask>();
|
||
moTask.id = SnowflakeIdHelper.NextId();
|
||
moTask.create_id = _userManager.UserId;
|
||
moTask.create_time = DateTime.Now;
|
||
moTask.mo_task_status = DictConst.ToBeScheduledEncode;
|
||
moTask.scheduled_qty = input.scheduled_qty;
|
||
|
||
var mo = await db.Queryable<PrdMo>().FirstAsync(it => it.id == input.mo_id);
|
||
var moCode = mo?.mo_code;
|
||
var taskCode = await db.Queryable<PrdMoTask>().Where(it => !string.IsNullOrEmpty(it.mo_task_code) && it.mo_task_code.Contains(moCode)).OrderByDescending(it => it.mo_task_code).Select(it => it.mo_task_code).FirstAsync();
|
||
if (taskCode.IsNullOrEmpty())
|
||
{
|
||
moTask.mo_task_code = $"{moCode}-01";
|
||
}
|
||
else
|
||
{
|
||
var pos = taskCode.IndexOf("-", StringComparison.Ordinal);
|
||
if (pos > -1)
|
||
{
|
||
var num = taskCode.AsSpan().Slice(pos + 1).ToString().ParseToInt();
|
||
var code = taskCode.AsSpan().Slice(0, pos).ToString();
|
||
var n = (num + 1).ToString().PadLeft(2, '0');
|
||
moTask.mo_task_code = $"{code}-{n}";
|
||
}
|
||
}
|
||
try
|
||
{
|
||
await db.Ado.BeginTranAsync();
|
||
row = await db.Insertable(moTask).ExecuteCommandAsync();
|
||
|
||
//根据工单号获取当前工单包含的已排产数
|
||
var schedQty = db.Queryable<PrdMoTask>().Where(it => it.mo_id == input.mo_id)?.Sum(d => d.scheduled_qty);
|
||
|
||
if (mo != null)
|
||
{//判断如果当前 工单的已排产数大于工单计划数量则更新工单状态为 已排产
|
||
if (schedQty.HasValue && schedQty.Value >= mo.plan_qty)
|
||
{
|
||
mo.mo_status = DictConst.AlreadyId;
|
||
row = await db.Updateable(mo).ExecuteCommandAsync();
|
||
}
|
||
else
|
||
{
|
||
if (schedQty.HasValue)
|
||
mo.scheduled_qty = schedQty.Value;
|
||
}
|
||
}
|
||
var material = await db.Queryable<BasMaterial>().FirstAsync(it => it.id == moTask.material_id);
|
||
|
||
var taskLog = new PrdTaskLog();
|
||
taskLog.id = SnowflakeIdHelper.NextId();
|
||
taskLog.mo_code = (await db.Queryable<PrdMo>().FirstAsync(it => it.id == input.mo_id))?.mo_code;
|
||
taskLog.eqp_code = (await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == input.eqp_id))?.code;
|
||
taskLog.mold_code = (await db.Queryable<Molds>().FirstAsync(it => it.id == input.mold_id))?.mold_code;
|
||
taskLog.item_code = material?.code;
|
||
taskLog.item_standard = material?.material_standard;
|
||
taskLog.status = DictConst.ToBeScheduledEncode;
|
||
taskLog.operator_name = _userManager.RealName;
|
||
taskLog.create_id = _userManager.UserId;
|
||
taskLog.create_time = DateTime.Now;
|
||
taskLog.mo_task_id = moTask.id;
|
||
taskLog.mo_task_code = moTask.mo_task_code;
|
||
|
||
await db.Insertable(taskLog).ExecuteCommandAsync();
|
||
//将生产任务插入到自检报废记录表
|
||
var sacipRecord = new PrdMoTaskDefectRecord();
|
||
sacipRecord.id = SnowflakeIdHelper.NextId();
|
||
sacipRecord.material_code = material?.code;
|
||
sacipRecord.material_name = material?.name;
|
||
sacipRecord.eqp_code = (await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == moTask.eqp_id))?.code;
|
||
sacipRecord.mold_name = (await db.Queryable<Molds>().FirstAsync(it => it.id == moTask.mold_id))?.mold_name;
|
||
sacipRecord.estimated_start_date = moTask.plan_start_date;
|
||
sacipRecord.estimated_end_date = moTask.plan_end_date;
|
||
sacipRecord.plan_qty = moTask.plan_qty;
|
||
sacipRecord.scrap_qty = moTask.scrap_qty;
|
||
sacipRecord.status = moTask.mo_task_status;
|
||
sacipRecord.create_id = _userManager.UserId;
|
||
sacipRecord.create_time = DateTime.Now;
|
||
sacipRecord.mo_task_id = moTask.id;
|
||
sacipRecord.mo_task_code = moTask.mo_task_code;
|
||
await db.Insertable(sacipRecord).ExecuteCommandAsync();
|
||
|
||
await db.Ado.CommitTranAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
await db.Ado.RollbackTranAsync();
|
||
}
|
||
}
|
||
else if (input.schedule_type.Value == 2) //组装、包装排产
|
||
{
|
||
|
||
}
|
||
}
|
||
return row > 0;
|
||
}
|
||
/// <summary>
|
||
/// 获取组装包装排产任务列表
|
||
/// </summary>
|
||
/// <param name="input">拆解bom,生成组装包装任务列表,输入参数</param>
|
||
/// <remarks>
|
||
/// output:
|
||
///<br/>{
|
||
///<br/> workline_id:产线Id
|
||
///<br/> workline_name:产线名称
|
||
///<br/> material_code:物料编码
|
||
///<br/> material_name:物料名称
|
||
///<br/> qty:输出料数量
|
||
///<br/>}
|
||
/// </remarks>
|
||
[HttpPost]
|
||
public async Task<dynamic> GetPackSchedulingTaskList(UnPackSchedlingInput input)
|
||
{
|
||
if (_dicWorkLine.Count < 1)
|
||
{
|
||
_dicWorkLine = await _db.Queryable<OrganizeEntity>().Where(it => it.Category == "workline").ToDictionaryAsync(x => x.Id, x => x.FullName);
|
||
}
|
||
if (_dicProcess.Count < 1)
|
||
{
|
||
_dicProcess = await _db.Queryable<BasProcess>().Select(it => new { id = it.id, process_name = it.process_name }).Distinct().ToDictionaryAsync(x => x.id, x => x.process_name);
|
||
}
|
||
var outputList = new List<PackingSchedulingListOutput>();
|
||
var bom = await _db.Queryable<BasMbom>().FirstAsync(it => it.id == input.bom_id);
|
||
if (bom != null && bom.route_id.IsNotEmptyOrNull())
|
||
{
|
||
var routes = await _db.Queryable<BasRouteD>().Where(it => it.route_id == bom.route_id).ToListAsync();
|
||
if (routes?.Count > 0)
|
||
{
|
||
var processIds = routes.Select(x => x.process_id).ToList();
|
||
if (processIds?.Count > 0)
|
||
{
|
||
var bomOutputs = await _db.Queryable<BasMbomOutput>().Where(it => processIds.Contains(it.process_id)).ToListAsync();
|
||
if (bomOutputs?.Count > 0)
|
||
{
|
||
foreach (var item in bomOutputs)
|
||
{
|
||
var material = await _db.Queryable<BasMaterial>().FirstAsync(it => it.id == item.material_id);
|
||
var output = new PackingSchedulingListOutput();
|
||
output.mo_id = input.mo_id;
|
||
output.process_id = item.process_id;
|
||
output.workline_id = input.workline_id;
|
||
output.workline_name = _dicWorkLine.ContainsKey(input.workline_id) ? _dicWorkLine[input.workline_id].ToString() : "";
|
||
output.process_name = _dicProcess[item.process_id]?.ToString();
|
||
output.material_id = item.material_id;
|
||
output.material_code = material?.code;
|
||
output.material_name = material?.name;
|
||
output.qty = item.num;
|
||
outputList.Add(output);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//生成任务单号
|
||
if (outputList.Count > 0)
|
||
{
|
||
var mo = await _db.Queryable<PrdMo>().FirstAsync(it => it.id == input.mo_id);
|
||
if (mo != null && mo.mo_code.IsNotEmptyOrNull())
|
||
{
|
||
var taskCodes = outputList.Where(it => it.mo_task_code.IsNotEmptyOrNull()).ToList();
|
||
if (taskCodes == null || taskCodes.Count < 1)
|
||
{
|
||
for (int i = 1, len = outputList.Count; i <= len; i++)
|
||
{
|
||
outputList[i - 1].mo_task_code = $"{mo.mo_code}-{i.ToString().PadLeft(2, '0')}";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return outputList;
|
||
}
|
||
/// <summary>
|
||
/// 组装包装排产
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="ArgumentNullException"></exception>
|
||
[HttpPost]
|
||
public async Task<dynamic> PackSchedling(PackSchedlingCrInput input)
|
||
{
|
||
if (input.items == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input.items));
|
||
}
|
||
DbResult<bool> dbResult = null;
|
||
if (input.items.Count > 0)
|
||
{
|
||
var moTasks = input.items.Select(x => new PrdMoTask
|
||
{
|
||
id = SnowflakeIdHelper.NextId(),
|
||
mo_task_code = x.mo_task_code,
|
||
material_id = x.material_id,
|
||
mo_id = x.mo_id,
|
||
bom_id = x.bom_id,
|
||
create_id = _userManager.UserId,
|
||
scheduled_qty = x.qty.ParseToInt(),
|
||
create_time = DateTime.Now
|
||
}).ToList();
|
||
dbResult = await _db.Ado.UseTranAsync(async () =>
|
||
{
|
||
await _db.Insertable(moTasks).ExecuteCommandAsync();
|
||
List<PrdTaskLog> taskLogList = new();
|
||
List<PrdMoTaskDefectRecord> taskDefectRecordList = new();
|
||
|
||
foreach (var moTask in moTasks)
|
||
{
|
||
var material = await _db.Queryable<BasMaterial>().FirstAsync(it => it.id == moTask.material_id);
|
||
var mo = await _db.Queryable<PrdMo>().FirstAsync(it => it.id == moTask.mo_id);
|
||
var taskLog = new PrdTaskLog();
|
||
taskLog.id = SnowflakeIdHelper.NextId();
|
||
taskLog.mo_code = mo?.mo_code;
|
||
taskLog.eqp_code = (await _db.Queryable<EqpEquipment>().FirstAsync(it => it.id == moTask.eqp_id))?.code;
|
||
taskLog.mold_code = (await _db.Queryable<Molds>().FirstAsync(it => it.id == moTask.mold_id))?.mold_code;
|
||
taskLog.item_code = material?.code;
|
||
taskLog.item_standard = material?.material_standard;
|
||
taskLog.status = DictConst.ToBeScheduledEncode;
|
||
taskLog.operator_name = _userManager.RealName;
|
||
taskLog.create_id = _userManager.UserId;
|
||
taskLog.create_time = DateTime.Now;
|
||
taskLog.mo_task_id = moTask.id;
|
||
taskLog.mo_task_code = moTask.mo_task_code;
|
||
taskLogList.Add(taskLog);
|
||
//将生产任务插入到自检报废记录表
|
||
var sacipRecord = new PrdMoTaskDefectRecord();
|
||
sacipRecord.id = SnowflakeIdHelper.NextId();
|
||
sacipRecord.material_code = material?.code;
|
||
sacipRecord.material_name = material?.name;
|
||
sacipRecord.estimated_start_date = mo?.plan_start_date;
|
||
sacipRecord.estimated_end_date = mo?.plan_end_date;
|
||
sacipRecord.plan_qty = moTask.plan_qty;
|
||
sacipRecord.scrap_qty = moTask.scrap_qty;
|
||
sacipRecord.status = moTask.mo_task_status;
|
||
sacipRecord.create_id = _userManager.UserId;
|
||
sacipRecord.create_time = DateTime.Now;
|
||
sacipRecord.mo_task_id = moTask.id;
|
||
sacipRecord.mo_task_code = moTask.mo_task_code;
|
||
taskDefectRecordList.Add(sacipRecord);
|
||
}
|
||
await _db.Insertable(taskLogList).ExecuteCommandAsync();
|
||
await _db.Insertable(taskDefectRecordList).ExecuteCommandAsync();
|
||
});
|
||
}
|
||
return dbResult!.IsSuccess;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生产任务下发,开始 、结束、完成
|
||
/// </summary>
|
||
/// <param name="input">输入参数</param>
|
||
/// <returns></returns>
|
||
/// <exception cref="ArgumentNullException"></exception>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdTaskRelease(PrdTaskReleaseUpInput input)
|
||
{
|
||
var row = -1;
|
||
if (input is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input));
|
||
}
|
||
if (input.TaskIds is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input.TaskIds));
|
||
}
|
||
if (input.Behavior.IsNullOrWhiteSpace())
|
||
{
|
||
throw new ArgumentException($"{nameof(input.Behavior)} not be null or empty");
|
||
}
|
||
string SetTaskStatus(PrdTaskBehavior behavior) => behavior switch
|
||
{
|
||
PrdTaskBehavior.Release => DictConst.ToBeStartedEnCode,
|
||
PrdTaskBehavior.Start => DictConst.InProgressEnCode,
|
||
PrdTaskBehavior.Closed => DictConst.ClosedEnCode,
|
||
PrdTaskBehavior.Compled => DictConst.ComplatedEnCode,
|
||
_ => throw new NotImplementedException(),
|
||
};
|
||
PrdTaskBehavior behavior = input.Behavior.ToEnum<PrdTaskBehavior>();
|
||
var status = SetTaskStatus(behavior);
|
||
var db = _repository.AsSugarClient();
|
||
var list = await db.Queryable<PrdMoTask>().Where(it => input.TaskIds.Contains(it.id)).Select(it => it).ToListAsync();
|
||
if (behavior == PrdTaskBehavior.Compled)
|
||
{
|
||
|
||
if (list?.Count > 0)
|
||
{
|
||
var schedQtySum = list.Sum(x => x.scheduled_qty);
|
||
var planQtySum = list.Sum(x => x.plan_qty);
|
||
if (schedQtySum < planQtySum)
|
||
{
|
||
throw new AppFriendlyException("任务数量必须大于等于生产计划数量,才可完成", 500);
|
||
}
|
||
}
|
||
}
|
||
row = await db.Updateable<PrdMoTask>()
|
||
.SetColumns(it => new PrdMoTask { mo_task_status = status })
|
||
.Where(it => input.TaskIds.Contains(it.id))
|
||
.ExecuteCommandAsync();
|
||
//插入操作记录日志
|
||
List<PrdTaskLog> taskLogEntities = new();
|
||
foreach (var taskId in input.TaskIds)
|
||
{
|
||
var taskLog = await db.Queryable<PrdTaskLog>().FirstAsync(it => it.mo_task_id == taskId);
|
||
if (taskLog is null)
|
||
{
|
||
var taskItem = list?.Find(x => x.id == taskId);
|
||
taskLog = new PrdTaskLog();
|
||
taskLog.id = SnowflakeIdHelper.NextId();
|
||
if (taskItem != null)
|
||
{
|
||
if (taskItem.mo_id.IsNotEmptyOrNull())
|
||
{
|
||
taskLog.mo_code = (await db.Queryable<PrdMo>().FirstAsync(it => it.id == taskItem.mo_id))?.mo_code;
|
||
}
|
||
if (taskItem.eqp_id.IsNotEmptyOrNull())
|
||
{
|
||
taskLog.eqp_code = (await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == taskItem.eqp_id))?.code;
|
||
}
|
||
if (taskItem.mold_id.IsNotEmptyOrNull())
|
||
{
|
||
taskLog.mold_code = (await db.Queryable<Molds>().FirstAsync(it => it.id == taskItem.mold_id))?.mold_code;
|
||
}
|
||
if (taskItem.material_id.IsNotEmptyOrNull())
|
||
{
|
||
var material = await db.Queryable<BasMaterial>().FirstAsync(it => it.id == taskItem.material_id);
|
||
taskLog.item_code = material?.code;
|
||
taskLog.item_standard = material?.material_standard;
|
||
}
|
||
taskLog.operator_name = _userManager.RealName;
|
||
taskLog.status = status;
|
||
taskLog.create_id = _userManager.UserId;
|
||
taskLog.create_time = DateTime.Now;
|
||
taskLog.mo_task_id = taskItem.id;
|
||
}
|
||
taskLogEntities.Add(taskLog);
|
||
}
|
||
else
|
||
{
|
||
var records = await db.Queryable<PrdTaskLog>().Where(it => it.mo_task_id == taskLog.mo_task_id).ToListAsync();
|
||
if (records != null && !records.Select(x => x.status).Contains(status))
|
||
{
|
||
|
||
taskLog.id = SnowflakeIdHelper.NextId();
|
||
taskLog.status = status;
|
||
taskLogEntities.Add(taskLog);
|
||
}
|
||
}
|
||
}
|
||
row = await db.Insertable(taskLogEntities).ExecuteCommandAsync();
|
||
return (row > 0);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生产任务单修改
|
||
/// </summary>
|
||
/// <param name="input">生产任务单修改输入参数</param>
|
||
/// <returns></returns>
|
||
/// <exception cref="AppFriendlyException"></exception>
|
||
[HttpPost]
|
||
public async Task<dynamic> IcmoModify(IcmoUpInput input)
|
||
{
|
||
var row = -1;
|
||
var db = _repository.AsSugarClient();
|
||
if (input.icmo_id.IsNullOrWhiteSpace())
|
||
throw new ArgumentNullException(nameof(input.icmo_id));
|
||
var icmoItem = await db.Queryable<PrdMoTask>().FirstAsync(it => it.id == input.icmo_id);
|
||
switch (input.category)
|
||
{
|
||
case 1: //设备
|
||
|
||
if (icmoItem != null)
|
||
{
|
||
var eqpItem = await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == icmoItem.eqp_id);
|
||
icmoItem.eqp_id = eqpItem.id;
|
||
icmoItem.eqp_type_code = db.Queryable<EqpEquipType>().First(it => it.id == eqpItem.equip_type_id)?.code;
|
||
//if (input.scheduled_qty > icmoItem.plan_qty)
|
||
//{
|
||
// throw new AppFriendlyException("任务单数量不能大于计划数量", 500);
|
||
//}
|
||
//row = await db.Updateable<PrdMo>().SetColumns(it => new PrdMo { input_qty = input.scheduled_qty }).Where(it => it.id == input.mo_id).ExecuteCommandAsync();
|
||
}
|
||
|
||
break;
|
||
case 2: //模具
|
||
if (icmoItem != null)
|
||
{
|
||
var moldItem = await db.Queryable<Molds>().FirstAsync(it => it.id == icmoItem.mold_id);
|
||
icmoItem.mold_id = moldItem.id;
|
||
icmoItem.mold_code = moldItem.mold_code;
|
||
icmoItem.mold_name = moldItem.mold_name;
|
||
icmoItem.mold_cavity_qty = moldItem.cavity_qty;
|
||
}
|
||
break;
|
||
}
|
||
row = await db.Updateable(icmoItem).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
|
||
return (row > 0);
|
||
}
|
||
/// <summary>
|
||
/// 生产提报
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <remarks>
|
||
/// input:
|
||
/// <br/>{
|
||
/// <br/> icmo_id:生产任务ID
|
||
/// <br/> icmo_code:任务单号
|
||
/// <br/> prd_qty:生产数量
|
||
/// <br/> reported_work_qty:已报工数量
|
||
/// <br/> reported_qty:提报数量
|
||
/// <br/> icmo_qty:生产任务量
|
||
/// <br/>}
|
||
/// </remarks>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdReport(PrdReportCrInput input)
|
||
{
|
||
var row = -1;
|
||
var db = _repository.AsSugarClient();
|
||
var report = await db.Queryable<PrdReport>().FirstAsync(it => it.mo_task_code == input.mo_task_code);
|
||
|
||
if (report is not null)
|
||
{
|
||
report.mo_task_code = input.mo_task_code;
|
||
report.mo_task_id = input.mo_task_id;
|
||
report.reported_work_qty += input.reported_qty;
|
||
report.prd_qty += input.reported_qty;
|
||
|
||
}
|
||
else
|
||
{
|
||
report = input.Adapt<PrdReport>();
|
||
report.id = SnowflakeIdHelper.NextId();
|
||
report.reported_work_qty = input.reported_qty;
|
||
report.prd_qty = input.reported_qty;
|
||
}
|
||
row = await db.Storageable(report).ExecuteCommandAsync();
|
||
var prdTask = await db.Queryable<PrdMoTask>().FirstAsync(it => it.mo_task_code == input.mo_task_code);
|
||
var record = prdTask.Adapt<PrdReportRecord>();
|
||
if (prdTask != null)
|
||
{
|
||
record.id = SnowflakeIdHelper.NextId();
|
||
record.eqp_code = (await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == prdTask.eqp_id))?.code;
|
||
record.completed_qty = input.reported_qty;
|
||
row = await db.Insertable(record).ExecuteCommandAsync();
|
||
}
|
||
return row > 0;
|
||
}
|
||
/// <summary>
|
||
/// 自检报废提交
|
||
/// </summary>
|
||
/// <param name="input">自检报废输入参数</param>
|
||
/// <returns>true/false</returns>
|
||
/// <remarks>
|
||
/// input:
|
||
///<br/>{
|
||
///<br/> "icmo_code": 任务单号,
|
||
///<br/> "scrap_qty": 报废数量,
|
||
///<br/> "remark": 备注,
|
||
///<br/> "categoryItems": [
|
||
///<br/> {
|
||
///<br/> "defective_category":次品分类,
|
||
///<br/> "category_qty": 分类数量,
|
||
///<br/> "items": [
|
||
///<br/> {
|
||
///<br/> "defective_item": 次品项,
|
||
///<br/> "defective_item_qty": 次品项数量
|
||
///<br/> }
|
||
///<br/> ]
|
||
///<br/> }
|
||
///<br/> ]
|
||
///<br/>}
|
||
/// </remarks>
|
||
[HttpPost]
|
||
public async Task<dynamic> SelfTestScrapped(SelfTestScrappedInput input)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
var result = await db.Ado.UseTranAsync(async () =>
|
||
{
|
||
List<PrdMoTaskDefect> destDefects = new();
|
||
var batch = DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
|
||
foreach (var categoryItem in input.categoryItems)
|
||
{
|
||
foreach (var dItem in categoryItem.items)
|
||
{
|
||
var defect = new PrdMoTaskDefect();
|
||
defect.id = SnowflakeIdHelper.NextId();
|
||
defect.mo_task_id = input.mo_task_id;
|
||
defect.batch = batch;
|
||
defect.defective_cagetory_id = categoryItem.category_id;
|
||
defect.defective_item = dItem.defective_item;
|
||
defect.defective_item_qty = dItem.defective_item_qty;
|
||
defect.create_id = _userManager.UserId;
|
||
|
||
destDefects.Add(defect);
|
||
}
|
||
}
|
||
await db.Insertable(destDefects).ExecuteCommandAsync();
|
||
|
||
var scrapQty = db.Queryable<PrdMoTaskDefect>().Where(it => it.mo_task_id == input.mo_task_id)?.Sum(d => d.defective_item_qty);
|
||
if (scrapQty.HasValue && scrapQty.Value > 0)//更新生产任务表报废数量
|
||
{
|
||
await db.Updateable<PrdMoTask>().SetColumns(it => new PrdMoTask { scrap_qty = scrapQty.Value }).Where(it => it.id == input.mo_task_id).ExecuteCommandAsync();
|
||
}
|
||
|
||
});
|
||
return result.IsSuccess;
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
private async Task<dynamic> GetList(VisualDevModelListQueryInput input)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleId, true);
|
||
var data = await _runService.GetListResult(templateEntity, input);
|
||
if (data?.list?.Count > 0)
|
||
{
|
||
foreach (var row in data.list)
|
||
{
|
||
var dic = row.ToDictionary(x => x.Key, x => x.Value);
|
||
var pkName = "material_id_id";
|
||
if (dic.ContainsKey(pkName))
|
||
{
|
||
var materialId = dic[pkName]?.ToString();
|
||
var material = await db.Queryable<BasMaterial>().FirstAsync(it => it.id == materialId);
|
||
if (material != null)
|
||
{
|
||
row["material_id"] = $"{material.code}/{material.name}";
|
||
}
|
||
|
||
|
||
}
|
||
//模具
|
||
if (dic.ContainsKey("mold_id"))
|
||
{
|
||
var moldId = dic["mold_id"]?.ToString();
|
||
var mold = await db.Queryable<Molds>().FirstAsync(it => it.id == moldId);
|
||
if (mold != null)
|
||
{
|
||
row["mold_id"] = $"{mold.mold_code}/{mold.mold_name}";
|
||
}
|
||
}
|
||
//设备
|
||
if (dic.ContainsKey("eqp_id"))
|
||
{
|
||
var eqpId = dic["eqp_id"]?.ToString();
|
||
var eqp = await db.Queryable<EqpEquipment>().FirstAsync(it => it.id == eqpId);
|
||
if (eqp != null)
|
||
{
|
||
row["eqp_id"] = $"{eqp.code}/{eqp.name}";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return data!;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
private async Task Delete(string id)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
var result = await db.Ado.UseTranAsync(async () =>
|
||
{
|
||
var row = -1;
|
||
var prdTask = await db.Queryable<PrdMoTask>().FirstAsync(it => it.id == id);
|
||
row = await db.Deleteable<PrdTask>().Where(it => it.id == id).ExecuteCommandAsync();
|
||
if (row > 0)
|
||
{
|
||
var prdMo = await db.Queryable<PrdMo>().FirstAsync(it => it.id == prdTask.mo_id);
|
||
if (prdMo is not null)
|
||
{
|
||
prdMo.scheduled_qty += prdTask.scheduled_qty;
|
||
prdMo.mo_status = DictConst.ScheduledId;
|
||
row = await db.Updateable(prdMo).ExecuteCommandAsync();
|
||
}
|
||
}
|
||
return row > 0;
|
||
});
|
||
if (!result.IsSuccess) throw Oops.Oh(ErrorCode.COM1002);
|
||
|
||
}
|
||
|
||
}
|
||
}
|