Files
tnb.server/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs

895 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
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 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,
material_name = b.name,
cavity_qty = a.cavity_qty,
})
.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 sb = new StringBuilder();
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 = sb.Append(code).Append("-").Append(n).ToString();
}
}
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"></param>
/// <returns></returns>
[HttpPost]
public async Task<dynamic> GetPackSchedulingTaskList(ProductionSchedulingCrInput input)
{
if (_dicWorkLine.Count < 1)
{
_dicWorkLine = await _db.Queryable<OrganizeEntity>().Where(it => it.Category == "workline").ToDictionaryAsync(x => x.Id, x => x.FullName);
}
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.workline_id = input.workline_id;
output.workline_name = _dicWorkLine.ContainsKey(input.workline_id) ? _dicWorkLine[input.workline_id].ToString() : "";
output.material_code = material?.code;
output.material_name = material?.name;
output.qty = item.num;
outputList.Add(output);
}
}
}
}
}
return outputList;
}
/// <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);
}
}
}