| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- 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.Domain.Repositories;
- using Volo.Abp.TenantManagement;
- namespace Business.ResourceExamineManagement
- {
- /// <summary>
- /// 生产排产接口实现类
- /// </summary>
- public class ProdScheduleAppService : ApplicationService, IProductionScheduleAppService
- {
- /// <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 = _mysql_mes_morder.GetListAsync(p => workOrds.Contains(p.morder_no)).Result;
- CreateWorkOrdDates(mes_morders);
- return JsonConvert.SerializeObject("ok");
- }
- /// <summary>
- /// 同步工单等相关数据
- /// </summary>
- /// <param name="morders"></param>
- public 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).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);
- }
- }
- //await _businessDbContext.BulkInsertAsync(workOrds);
- //await _businessDbContext.BulkInsertAsync(workOrdRoutings);
- //await _businessDbContext.BulkInsertAsync(workOrdDetails);
- _workOrdMaster.Insert(workOrds);
- _workOrdRouting.Insert(workOrdRoutings);
- _workOrdDetail.Insert(workOrdDetails);
- //排产
- _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);
- }
- }
- }
- }
|