|
|
@@ -14,6 +14,7 @@ using Business.StructuredDB.MES.IC;
|
|
|
using Business.StructuredDB.Replenishment;
|
|
|
using Business.StructuredDB.SaleFcst;
|
|
|
using Business.StructuredDB.WMS;
|
|
|
+using DnsClient;
|
|
|
using EFCore.BulkExtensions;
|
|
|
using IdentityModel.Client;
|
|
|
using Microsoft.AspNetCore.DataProtection.Repositories;
|
|
|
@@ -24,6 +25,7 @@ using MongoDB.Driver.Linq;
|
|
|
using Newtonsoft.Json;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using Org.BouncyCastle.Crypto.Generators;
|
|
|
+using Org.BouncyCastle.Utilities;
|
|
|
using RazorEngine.Compilation.ImpromptuInterface.Optimization;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
@@ -344,7 +346,7 @@ namespace Business.ResourceExamineManagement
|
|
|
private ISqlRepository<PurOrdDetail> _purOrdDetail;
|
|
|
private ISqlRepository<ItemPackMaster> _itemPackMaster;
|
|
|
private ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
|
|
|
-
|
|
|
+ private readonly ISqlRepository<SAPInv> _SAPInv;
|
|
|
/// <summary>
|
|
|
/// 生产排产
|
|
|
/// </summary>
|
|
|
@@ -511,6 +513,7 @@ namespace Business.ResourceExamineManagement
|
|
|
_ic_bom = ic_bom;
|
|
|
_ic_bom_child = ic_bom_child;
|
|
|
_ic_item_stock = ic_item_stock;
|
|
|
+ _SAPInv = SAPInv;
|
|
|
_mes_oorder = mes_oorder;
|
|
|
_srm_pr_main = srm_pr_main;
|
|
|
_srm_po_main = srm_po_main;
|
|
|
@@ -2021,13 +2024,17 @@ namespace Business.ResourceExamineManagement
|
|
|
locationList = locationRange.Val.SplitToArray(",").ToList();
|
|
|
}
|
|
|
var locStock = _invMaster.Select(a => numbers.Contains(a.ItemNum) && a.IsActive && a.Domain == factoryId.ToString() && locationList.Contains(a.Location));
|
|
|
+ var sapInvList = _SAPInv.Select(a => a.WERKS == factoryId.ToString() && numbers.Contains(a.MATNR) && (a.SOBKZ.ToUpper() == "O"));
|
|
|
+
|
|
|
//设置当前计算bangid
|
|
|
icitemStokc.ForEach(item => {
|
|
|
item.bang_id = bangid;
|
|
|
- var pret = pretreatments.Find(s => s.item_id == item.icitem_id);
|
|
|
+ /*var pret = pretreatments.Find(s => s.item_id == item.icitem_id);
|
|
|
if(pret != null) {
|
|
|
- item.sqty = locStock.Where(s => s.ItemNum == pret.item_number).Sum(p => p.AvailStatusQty.GetValueOrDefault() + p.Assay.GetValueOrDefault());
|
|
|
- }
|
|
|
+ }*/
|
|
|
+ item.sqty = 0;
|
|
|
+ item.sqty = locStock.Where(s => s.ItemNum == item.icitem_number).Sum(p => p.AvailStatusQty.GetValueOrDefault() + p.Assay.GetValueOrDefault());
|
|
|
+ item.sqty += sapInvList.Where(x => x.MATNR == item.icitem_number).Sum(p => p.LABST + p.INSME);
|
|
|
});
|
|
|
var moIcitemStokc = ObjectMapper.Map<List<ic_item_stock>, List<mo_ic_item_stock>>(icitemStokc);
|
|
|
moIcitemStokc.ForEach(item => { item.GenerateNewId(help.NextId()); });
|
|
|
@@ -5077,5 +5084,282 @@ namespace Business.ResourceExamineManagement
|
|
|
}
|
|
|
return "ok";
|
|
|
}
|
|
|
+
|
|
|
+ public async Task<string> AutoMergeMo(string domain)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var workOrds = _workOrdMaster.Select(x => x.Domain == domain && x.Status.ToUpper() == "P" && string.IsNullOrEmpty(x.Typed) == true).ToList();
|
|
|
+ var periodSd = _periodSequenceDet.Select(s => s.Domain == domain && workOrds.Select(x => x.WorkOrd).Contains(s.WorkOrds)).ToList();
|
|
|
+ workOrds = workOrds.Where(x => !periodSd.Select(c => c.WorkOrds).Contains(x.WorkOrd)).ToList();
|
|
|
+
|
|
|
+ //Close_state
|
|
|
+ List<string> works = workOrds.Select(x => x.WorkOrd).ToList();
|
|
|
+ List<string> items = workOrds.Select(x => x.ItemNum).Distinct().ToList();
|
|
|
+ var memorder = _mysql_mes_morder.GetListAsync(x => x.factory_id.ToString() == domain && works.Contains(x.morder_no)).Result;
|
|
|
+ var mentrys = _mysql_mes_moentry.GetListAsync(x => x.factory_id.ToString() == domain && memorder.Select(c => c.Id).Contains(x.moentry_moid.GetValueOrDefault())).Result;
|
|
|
+
|
|
|
+ var itemList = _itemMaster.Select(x => items.Contains(x.ItemNum)).ToList();
|
|
|
+ var workRoutings = _workOrdRouting.Select(x => x.Domain == domain && works.Contains(x.WorkOrd)).ToList();
|
|
|
+ var workDetings = _workOrdRouting.Select(x => x.Domain == domain && works.Contains(x.WorkOrd)).ToList();
|
|
|
+
|
|
|
+ var stock_occupys = _mysql_ic_item_stockoccupy.GetListAsync(x => x.factory_id.ToString() == domain && works.Contains(x.morder_mo)).Result;
|
|
|
+ var po_occupy = _mysql_srm_po_occupy.GetListAsync(x => x.factory_id.ToString() == domain && works.Contains(x.morder_mo)).Result;
|
|
|
+ var mooccupy = _mysql_mes_mooccupy.GetListAsync(x => x.factory_id.ToString() == domain && works.Contains(x.moo_mo)).Result;
|
|
|
+
|
|
|
+ List<mes_morder> MRPmorder = new List<mes_morder>();
|
|
|
+ List<WorkOrdMaster> InsertList = new List<WorkOrdMaster>();
|
|
|
+ List<WorkOrdMaster> UpdateList = new List<WorkOrdMaster>();
|
|
|
+ List<mes_morder> moIstList = new List<mes_morder>();
|
|
|
+ List<mes_morder> moUpdList = new List<mes_morder>();
|
|
|
+ List<mes_moentry> meIstList = new List<mes_moentry>();
|
|
|
+ List<ic_item_stockoccupy> stockUpdList = new List<ic_item_stockoccupy>();
|
|
|
+ List<srm_po_occupy> pooccuypUpdList = new List<srm_po_occupy>();
|
|
|
+ List<mes_mooccupy> mooccupuUpdList = new List<mes_mooccupy>();
|
|
|
+ List<WorkOrdRouting> routingInsList = new List<WorkOrdRouting>();
|
|
|
+ //按开工时间进行一次排序
|
|
|
+ workOrds = workOrds.OrderBy(x => x.OrdDate).ToList();
|
|
|
+
|
|
|
+ //先将工单按经济批量汇总成DTO,然后再判断是否有多个,需要合并,如果只有一个,则无需合并。
|
|
|
+ List<WorkOrdDto> workListDto = new List<WorkOrdDto>();
|
|
|
+ foreach (var work in workOrds)
|
|
|
+ {
|
|
|
+ var workDto = workListDto.Find(x => x.itemNum == work.ItemNum && x.SumQty < x.MinQty);
|
|
|
+
|
|
|
+ if (workDto != null)
|
|
|
+ {
|
|
|
+ workDto.WorkList.Add(work);
|
|
|
+ workDto.SumQty += work.QtyOrded;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ workDto = new WorkOrdDto();
|
|
|
+ var item = itemList.Find(x => x.ItemNum == work.ItemNum);
|
|
|
+ workDto.MinQty = 0;
|
|
|
+ if (item != null)
|
|
|
+ {
|
|
|
+ workDto.MinQty = item.MinOrd.GetValueOrDefault();
|
|
|
+ }
|
|
|
+ workDto.itemNum = work.ItemNum;
|
|
|
+ workDto.SumQty = work.QtyOrded;
|
|
|
+ workDto.WorkList.Add(work); ;
|
|
|
+ workListDto.Add(workDto);
|
|
|
+ }
|
|
|
+ var mo = memorder.Find(x => x.morder_no == work.WorkOrd);
|
|
|
+ if (mo != null)
|
|
|
+ {
|
|
|
+ workDto.morderList.Add(mo);
|
|
|
+ var me = mentrys.Find(x => x.moentry_mono == mo.morder_no);
|
|
|
+ if (me != null)
|
|
|
+ {
|
|
|
+ workDto.meOrderList.Add(me);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<string> GenerateMoList = new List<string>();
|
|
|
+ var moNbrlistDto = _serialNumberAppService.GetBillNo(domain, "M5", workListDto.Where(x => x.WorkList.Count > 1).Count(), "", 1);
|
|
|
+ if (moNbrlistDto.Any())
|
|
|
+ {
|
|
|
+ foreach (var nbr in moNbrlistDto)
|
|
|
+ {
|
|
|
+ GenerateMoList.Add(nbr.NbrResult);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach (var dto in workListDto)
|
|
|
+ {
|
|
|
+ //经济批量圆整
|
|
|
+ if (dto.SumQty < dto.MinQty)
|
|
|
+ {
|
|
|
+ dto.SumQty = dto.MinQty;
|
|
|
+ }
|
|
|
+ //如果有多个工单需要合并,才做合并工单处理。
|
|
|
+ if (dto.WorkList.Count() > 1)
|
|
|
+ {
|
|
|
+ //添加工单数据
|
|
|
+ WorkOrdMaster workOrd = new WorkOrdMaster();
|
|
|
+ workOrd.Domain = dto.WorkList[0].Domain;
|
|
|
+ var ord = dto.WorkList.OrderBy(x => x.OrdDate).FirstOrDefault();
|
|
|
+ workOrd.OrdDate = ord.OrdDate;
|
|
|
+ workOrd.DueDate = ord.DueDate;
|
|
|
+ workOrd.ReleaseDate = ord.OrdDate;
|
|
|
+ if (GenerateMoList.Any())
|
|
|
+ {
|
|
|
+ workOrd.WorkOrd = GenerateMoList[0];//工单编号
|
|
|
+ GenerateMoList.Remove(workOrd.WorkOrd);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var nbrDto = _serialNumberAppService.GetBillNo(domain, "M5", 1, "", 1);
|
|
|
+ if (nbrDto.Any())
|
|
|
+ {
|
|
|
+ workOrd.WorkOrd = nbrDto[0].NbrResult;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (string.IsNullOrEmpty(workOrd.WorkOrd))
|
|
|
+ {
|
|
|
+ //补救措施,使用雪花ID作为主键。
|
|
|
+ workOrd.WorkOrd = help.NextId().ToString();
|
|
|
+ }
|
|
|
+ workOrd.ItemNum = dto.itemNum;//物料编码
|
|
|
+ workOrd.QtyOrded = dto.SumQty;
|
|
|
+ workOrd.Period = 1;
|
|
|
+ workOrd.Priority = ord.Priority;
|
|
|
+ workOrd.Status = "p";
|
|
|
+ workOrd.IsActive = true;
|
|
|
+ workOrd.IsConfirm = true;
|
|
|
+ workOrd.CreateTime = DateTime.Now;
|
|
|
+ workOrd.Typed = "";
|
|
|
+ workOrd.SalesJob = ord.SalesJob;
|
|
|
+ //组装DOP工单和工单子表
|
|
|
+ mes_morder mes_Morder = new mes_morder();
|
|
|
+ mes_Morder.GenerateNewId(help.NextId());
|
|
|
+ //mes_Morder.morder_type = generateMorderDto.morder_type;
|
|
|
+ //mes_Morder.parent_id = generateMorderDto.ParentId;
|
|
|
+ mes_Morder.work_order_type = MorderEnum.CgMorder;
|
|
|
+ mes_Morder.morder_state = MorderEnum.Initial_state;
|
|
|
+ mes_Morder.morder_no = workOrd.WorkOrd;
|
|
|
+ if (dto.morderList.Any())
|
|
|
+ {
|
|
|
+ var refMorder = dto.morderList[0];
|
|
|
+ mes_Morder.fms_number = refMorder.fms_number;
|
|
|
+ mes_Morder.bom_number = refMorder.bom_number;
|
|
|
+ mes_Morder.fmodel = refMorder.fmodel;
|
|
|
+ mes_Morder.tenant_id = refMorder.tenant_id;
|
|
|
+ mes_Morder.factory_id = refMorder.factory_id;
|
|
|
+ mes_Morder.company_id = refMorder.company_id;
|
|
|
+ mes_Morder.org_id = param.org_id;
|
|
|
+ mes_Morder.product_code = refMorder.product_code;
|
|
|
+ mes_Morder.product_name = refMorder.product_name;
|
|
|
+ mes_Morder.project_name = refMorder.project_name;
|
|
|
+ mes_Morder.unit = refMorder.unit;
|
|
|
+ }
|
|
|
+
|
|
|
+ mes_Morder.urgent = 0;//暂时不用这个字段
|
|
|
+ mes_Morder.moentry_startup_status = 0;
|
|
|
+ mes_Morder.morder_date = DateTime.Now.Date.AddDays(1);
|
|
|
+ //mes_Morder.morder_fstate = "计划";
|
|
|
+ //TODO:目前没有取值位置
|
|
|
+ mes_Morder.moentry_prd = null;
|
|
|
+ mes_Morder.moentry_prdname = null;
|
|
|
+ mes_Morder.moentry_wrkc = null;
|
|
|
+ mes_Morder.moentry_wrkcname = null;
|
|
|
+ mes_Morder.picking_qty = 0;
|
|
|
+ mes_Morder.morder_production_number = dto.SumQty;
|
|
|
+ mes_Morder.need_number = dto.SumQty;
|
|
|
+ mes_Morder.remaining_number = 0;
|
|
|
+ mes_Morder.create_time = DateTime.Now;
|
|
|
+ //生成工单子表数据
|
|
|
+ mes_moentry mes_Moentry = new mes_moentry();
|
|
|
+ mes_Moentry.GenerateNewId(help.NextId());
|
|
|
+ mes_Moentry.moentry_moid = mes_Morder.Id;
|
|
|
+ mes_Moentry.moentry_mono = mes_Morder.morder_no;
|
|
|
+ mes_Moentry.unit = mes_Morder.unit;
|
|
|
+ mes_Moentry.morder_production_number = dto.SumQty;
|
|
|
+ mes_Moentry.need_number = dto.SumQty;
|
|
|
+ mes_Moentry.remaining_number = 0;
|
|
|
+ mes_Moentry.tenant_id = mes_Morder.tenant_id;
|
|
|
+ mes_Moentry.factory_id = mes_Morder.factory_id;
|
|
|
+ mes_Moentry.company_id = mes_Morder.company_id;
|
|
|
+ mes_Moentry.org_id = param.org_id;
|
|
|
+ mes_Moentry.create_time = DateTime.Now;
|
|
|
+ InsertList.Add(workOrd);
|
|
|
+ moIstList.Add(mes_Morder);
|
|
|
+ meIstList.Add(mes_Moentry);
|
|
|
+ dto.WorkList.ForEach(x =>
|
|
|
+ {
|
|
|
+ x.Status = "C";
|
|
|
+ var morder = memorder.Find(c => c.morder_no == x.WorkOrd);
|
|
|
+ if (morder != null)
|
|
|
+ {
|
|
|
+ morder.morder_state = MorderEnum.Accomplish_state;
|
|
|
+ moUpdList.Add(morder);
|
|
|
+ }
|
|
|
+ /*var stock = stock_occupys.Where(c => c.morder_mo == x.WorkOrd).ToList();
|
|
|
+ stock.ForEach(f => { f.morder_mo = workOrd.WorkOrd; });
|
|
|
+ stockUpdList.AddRange(stock);
|
|
|
+ var pooccupy = po_occupy.Where(c => c.morder_mo == x.WorkOrd).ToList();
|
|
|
+ pooccupy.ForEach(f => { f.morder_mo = workOrd.WorkOrd; });
|
|
|
+ pooccuypUpdList.AddRange(pooccupy);
|
|
|
+ var moocc = mooccupy.Where(c => c.moo_mo == x.WorkOrd).ToList();
|
|
|
+ moocc.ForEach(f => { f.moo_mo = workOrd.WorkOrd; });
|
|
|
+ mooccupuUpdList.AddRange(moocc);*/
|
|
|
+ });
|
|
|
+ UpdateList.AddRange(dto.WorkList);
|
|
|
+ //工艺数据汇总
|
|
|
+ var routingList = workRoutings.Where(x => x.WorkOrd == dto.WorkList[0].WorkOrd).ToList();
|
|
|
+ foreach (var r in routingList)
|
|
|
+ {
|
|
|
+ WorkOrdRouting woRouting = help.DeepCopy(r);
|
|
|
+ woRouting.WorkOrd = workOrd.WorkOrd;
|
|
|
+ routingInsList.Add(woRouting);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dto.morderList.ForEach(x => { x.morder_production_number = dto.SumQty; x.need_number = dto.SumQty; });
|
|
|
+ dto.meOrderList.ForEach(x => { x.morder_production_number = dto.SumQty; x.need_number = dto.SumQty; });
|
|
|
+ dto.WorkList.ForEach(x => { x.QtyOrded = dto.SumQty; });
|
|
|
+ UpdateList.AddRange(dto.WorkList);
|
|
|
+ MRPmorder.AddRange(dto.morderList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (InsertList.Any())
|
|
|
+ {
|
|
|
+ _businessDbContext.BulkInsert(moIstList);
|
|
|
+ _businessDbContext.BulkInsert(meIstList);
|
|
|
+ _businessDbContext.BulkUpdate(UpdateList);
|
|
|
+ _workOrdMaster.Insert(InsertList);
|
|
|
+ var DBworkOrdList = _workOrdMaster.Select(a => a.Domain == workOrds[0].Domain && InsertList.Select(c => c.WorkOrd).Contains(a.WorkOrd));
|
|
|
+ if (routingInsList.Any())
|
|
|
+ {
|
|
|
+ routingInsList.ForEach(c =>
|
|
|
+ {
|
|
|
+ c.WorkOrdMasterRecID = DBworkOrdList.Where(a => a.WorkOrd == c.WorkOrd).First().RecID;
|
|
|
+ });
|
|
|
+ _workOrdRouting.Insert(routingInsList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (mooccupuUpdList.Any())
|
|
|
+ {
|
|
|
+ _businessDbContext.BulkUpdate(mooccupuUpdList);
|
|
|
+ }
|
|
|
+ if (stockUpdList.Any())
|
|
|
+ {
|
|
|
+ _businessDbContext.BulkUpdate(stockUpdList);
|
|
|
+ }
|
|
|
+ if (pooccuypUpdList.Any())
|
|
|
+ {
|
|
|
+ _businessDbContext.BulkUpdate(pooccuypUpdList);
|
|
|
+ }
|
|
|
+ MRPmorder.AddRange(moIstList);
|
|
|
+ if (MRPmorder.Any())
|
|
|
+ {
|
|
|
+ var rtn = await OrderKittingCheck(MRPmorder, true);
|
|
|
+ }
|
|
|
+ return "ok";
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ new NLogHelper("ResourceExamineAppService").WriteLog("AutoMergeMo", "自动合并工单任务失败:" + e.Message, _currentTenant.Id.ToString());
|
|
|
+ return "保存失败,请联系管理员。";
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class WorkOrdDto
|
|
|
+ {
|
|
|
+ public string itemNum { get; set; }
|
|
|
+
|
|
|
+ public List<WorkOrdMaster> WorkList { get; set; } = new List<WorkOrdMaster>();
|
|
|
+
|
|
|
+ public List<mes_morder> morderList { get; set; } = new List<mes_morder>();
|
|
|
+
|
|
|
+ public List<mes_moentry> meOrderList { get; set; } = new List<mes_moentry>();
|
|
|
+
|
|
|
+ public decimal MinQty { get; set; }
|
|
|
+
|
|
|
+ public decimal SumQty { get; set; }
|
|
|
}
|
|
|
}
|