|
|
@@ -1,246 +0,0 @@
|
|
|
-using Business.Core.Utilities;
|
|
|
-using Business.EntityFrameworkCore.SqlRepositories;
|
|
|
-using Business.Model.MES.IC;
|
|
|
-using Business.Model.Production;
|
|
|
-using Business.MongoModel.Production;
|
|
|
-using Business.Quartz;
|
|
|
-using Newtonsoft.Json;
|
|
|
-using System;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.Linq;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
-using Volo.Abp.Application.Services;
|
|
|
-using Volo.Abp.DependencyInjection;
|
|
|
-using Volo.Abp.Domain.Repositories;
|
|
|
-using Volo.Abp.TenantManagement;
|
|
|
-
|
|
|
-namespace Business.ResourceExamineManagement
|
|
|
-{
|
|
|
- /// <summary>
|
|
|
- /// 生产排产接口实现类
|
|
|
- /// </summary>
|
|
|
- public class ProdScheduleAppService : ApplicationService
|
|
|
- {
|
|
|
- /// <summary>
|
|
|
- /// 雪花算法帮助类
|
|
|
- /// </summary>
|
|
|
- SnowFlake help = new SnowFlake();
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 生产工单主表
|
|
|
- /// </summary>
|
|
|
- private readonly IRepository<mes_morder, long> _mysql_mes_morder;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 工艺路线表
|
|
|
- /// </summary>
|
|
|
- private readonly ISqlRepository<RoutingOpDetail> _routingOpDetail;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 标准BOM表
|
|
|
- /// </summary>
|
|
|
- private readonly ISqlRepository<ProductStructureMaster> _productStructureMaster;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 工单工序表
|
|
|
- /// </summary>
|
|
|
- private readonly ISqlRepository<WorkOrdRouting> _workOrdRouting;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 工单主表
|
|
|
- /// </summary>
|
|
|
- private readonly ISqlRepository<WorkOrdMaster> _workOrdMaster;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 工单物料明细表
|
|
|
- /// </summary>
|
|
|
- private readonly ISqlRepository<WorkOrdDetail> _workOrdDetail;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 生产排产
|
|
|
- /// </summary>
|
|
|
- private readonly ProductionScheduleAppService _productionScheduleAppService;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 构造函数
|
|
|
- /// </summary>
|
|
|
- /// <param name="productionScheduleAppService"></param>
|
|
|
- public ProdScheduleAppService(
|
|
|
- ProductionScheduleAppService productionScheduleAppService,
|
|
|
- IRepository<mes_morder, long> mysql_mes_morder,
|
|
|
- ISqlRepository<RoutingOpDetail> routingOpDetail,
|
|
|
- ISqlRepository<ProductStructureMaster> productStructureMaster,
|
|
|
- ISqlRepository<WorkOrdRouting> workOrdRouting,
|
|
|
- ISqlRepository<WorkOrdMaster> workOrdMaster,
|
|
|
- ISqlRepository<WorkOrdDetail> workOrdDetail
|
|
|
- )
|
|
|
- {
|
|
|
- _productionScheduleAppService= productionScheduleAppService;
|
|
|
- _mysql_mes_morder= mysql_mes_morder;
|
|
|
- _routingOpDetail= routingOpDetail;
|
|
|
- _productStructureMaster= productStructureMaster;
|
|
|
- _workOrdRouting= workOrdRouting;
|
|
|
- _workOrdMaster= workOrdMaster;
|
|
|
- _workOrdDetail= workOrdDetail;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 生产排产
|
|
|
- /// </summary>
|
|
|
- /// <param name="workOrds">工单编号</param>
|
|
|
- /// <returns></returns>
|
|
|
- public async Task<string> ProductionSchedule(List<string> workOrds)
|
|
|
- {
|
|
|
- if (workOrds.Count() == 0)
|
|
|
- {
|
|
|
- return "";
|
|
|
- }
|
|
|
- //获取工单数据
|
|
|
- var mes_morders = await _mysql_mes_morder.GetListAsync(p => workOrds.Contains(p.morder_no));
|
|
|
- CreateWorkOrdDates(mes_morders);
|
|
|
-
|
|
|
- return JsonConvert.SerializeObject("ok");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 同步工单等相关数据
|
|
|
- /// </summary>
|
|
|
- /// <param name="morders"></param>
|
|
|
- public async void CreateWorkOrdDates(List<mes_morder> morders)
|
|
|
- {
|
|
|
- //获取工艺路线数据:product_code=物料编码
|
|
|
- List<RoutingOpDetail> allRoutings = _routingOpDetail.Select(p => morders.Select(m => m.product_code).Contains(p.RoutingCode));
|
|
|
- //获取标准BOM数据
|
|
|
- List<ProductStructureMaster> productStructures = GetProductStructure(morders.Select(p => p.product_code).Distinct().ToList());
|
|
|
- //工单主表
|
|
|
- List<WorkOrdMaster> workOrds = new List<WorkOrdMaster>();
|
|
|
- WorkOrdMaster workOrd;
|
|
|
- //工单工艺路线表
|
|
|
- List<WorkOrdRouting> workOrdRoutings = new List<WorkOrdRouting>();
|
|
|
- WorkOrdRouting woRouting;
|
|
|
- //工单物料表
|
|
|
- List<WorkOrdDetail> workOrdDetails = new List<WorkOrdDetail>();
|
|
|
- WorkOrdDetail woDetail;
|
|
|
- foreach (var item in morders)
|
|
|
- {
|
|
|
- //添加工单数据
|
|
|
- workOrd = new WorkOrdMaster();
|
|
|
- workOrd.Domain = "1001";
|
|
|
- workOrd.OrdDate = item.moentry_sys_stime;
|
|
|
- workOrd.ReleaseDate = Convert.ToDateTime(item.moentry_sys_stime.GetValueOrDefault().ToString("u"));
|
|
|
- workOrd.WorkOrd = item.morder_no;
|
|
|
- workOrd.ItemNum = item.product_code;//物料编码
|
|
|
- workOrd.QtyOrded = item.need_number.GetValueOrDefault();
|
|
|
- workOrd.RoutingCode = item.product_code;
|
|
|
- workOrd.Period = 1;
|
|
|
- workOrd.Priority = item.urgent;
|
|
|
- workOrd.Status = "";
|
|
|
- workOrd.IsActive = true;
|
|
|
- workOrd.IsConfirm = true;
|
|
|
- workOrds.Add(workOrd);
|
|
|
-
|
|
|
- //添加工单工艺路线数据
|
|
|
- var curRoutings = allRoutings.Where(p => p.RoutingCode == item.product_code).ToList();
|
|
|
- foreach (var dtl in curRoutings)
|
|
|
- {
|
|
|
- woRouting = new WorkOrdRouting();
|
|
|
- woRouting.Domain = "1001";
|
|
|
- woRouting.Descr = dtl.Descr;
|
|
|
- woRouting.MilestoneOp = dtl.MilestoneOp;
|
|
|
- woRouting.WorkOrd = item.morder_no;
|
|
|
- woRouting.OP = dtl.Op;
|
|
|
- woRouting.ParentOp = dtl.ParentOp;
|
|
|
- woRouting.RunTime = dtl.RunTime;
|
|
|
- woRouting.ItemNum = item.product_code;
|
|
|
- woRouting.QtyOrded = item.need_number.GetValueOrDefault();
|
|
|
- woRouting.OverlapUnits = dtl.OverlapUnits;
|
|
|
- woRouting.Status = "";
|
|
|
- woRouting.IsActive = true;
|
|
|
- workOrdRoutings.Add(woRouting);
|
|
|
- }
|
|
|
-
|
|
|
- //添加工单物料数据
|
|
|
- var curStructures = productStructures.Where(p => p.ParentItem == item.product_code).ToList();
|
|
|
- foreach (var structure in curStructures)
|
|
|
- {
|
|
|
- //添加工单的物料信息
|
|
|
- woDetail = new WorkOrdDetail();
|
|
|
- woDetail.Domain = "1001";
|
|
|
- woDetail.WorkOrd = item.morder_no;
|
|
|
- woDetail.Op = structure.Op;
|
|
|
- woDetail.ItemNum = structure.ComponentItem;
|
|
|
- woDetail.QtyRequired = item.need_number.GetValueOrDefault() * structure.Qty;
|
|
|
- woDetail.QtyPosted = 0m;
|
|
|
- woDetail.QtyReturned = 0m;
|
|
|
- woDetail.Status = "";
|
|
|
- woDetail.IsActive = true;
|
|
|
- workOrdDetails.Add(woDetail);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- _workOrdMaster.Insert(workOrds);
|
|
|
- _workOrdRouting.Insert(workOrdRoutings);
|
|
|
- _workOrdDetail.Insert(workOrdDetails);
|
|
|
-
|
|
|
- //排产
|
|
|
- await _productionScheduleAppService.DoProductShcedule(workOrds);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 获取标准Bom数据--TODO:存在循环查询数据库问题,后续调整
|
|
|
- /// </summary>
|
|
|
- /// <param name="itenNums">产品物料编码</param>
|
|
|
- /// <returns></returns>
|
|
|
- public List<ProductStructureMaster> GetProductStructure(List<string> itenNums)
|
|
|
- {
|
|
|
- List<ProductStructureMaster> rtnStructures = new List<ProductStructureMaster>();
|
|
|
- //根据itemNum获取bom数据
|
|
|
- var productStructures = _productStructureMaster.Select(p => itenNums.Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
|
|
|
- //添加非虚拟件
|
|
|
- rtnStructures.AddRange(productStructures.Where(p => p.StructureType.ToUpper() != "X").ToList());
|
|
|
- foreach (var item in itenNums)
|
|
|
- {
|
|
|
- //获取当前产品的虚拟件
|
|
|
- var curPhantoms = productStructures.Where(p => p.ParentItem == item && p.StructureType.ToUpper() == "X").ToList();
|
|
|
- if (curPhantoms.Count() == 0)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- //递归获取所有虚拟件对应的子物料
|
|
|
- RecursionProductStructure(item, curPhantoms, rtnStructures);
|
|
|
- }
|
|
|
- return rtnStructures;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 递归获取虚拟件的子物料
|
|
|
- /// </summary>
|
|
|
- /// <param name="parentItem">产品的物料编码</param>
|
|
|
- /// <param name="structures">当前产品的虚拟件</param>
|
|
|
- /// <param name="rtnStructures"></param>
|
|
|
- public void RecursionProductStructure(string parentItem, List<ProductStructureMaster> structures, List<ProductStructureMaster> rtnStructures)
|
|
|
- {
|
|
|
- //获取虚拟件的子物料
|
|
|
- var chdStructures = _productStructureMaster.Select(p => structures.Select(m => m.ComponentItem).Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
|
|
|
- //非虚拟件
|
|
|
- var notPhantoms = chdStructures.Where(p => p.StructureType.ToUpper() != "X").ToList();
|
|
|
- //存在非虚拟件
|
|
|
- if (notPhantoms.Count() > 0)
|
|
|
- {
|
|
|
- notPhantoms.ForEach(p =>
|
|
|
- {
|
|
|
- p.ParentItem = parentItem;
|
|
|
- });
|
|
|
- rtnStructures.AddRange(notPhantoms);
|
|
|
- }
|
|
|
- //虚拟件
|
|
|
- var phantoms = chdStructures.Where(p => p.StructureType.ToUpper() == "X").ToList();
|
|
|
- if (phantoms.Count() > 0)
|
|
|
- {
|
|
|
- //递归
|
|
|
- RecursionProductStructure(parentItem, phantoms, rtnStructures);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|