using Amazon.Auth.AccessControlPolicy; using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Util; using Business.Core.Enum; using Business.Core.Utilities; using Business.Domain; using Business.DOP; using Business.Dto; using Business.EntityFrameworkCore; using Business.EntityFrameworkCore.SqlRepositories; using Business.PriorityManagement; using Business.Replenishment; using Business.ResourceExamineManagement.Dto; using Business.StructuredDB.MES; using Business.StructuredDB.MES.IC; using Business.StructuredDB.Replenishment; using Business.StructuredDB.SaleFcst; using Business.StructuredDB.WMS; using Business.SystemJobManagement; using EFCore.BulkExtensions; using Microsoft.EntityFrameworkCore; using MongoDB.Driver; using MongoDB.Driver.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NPOI.SS.Formula.Functions; using NPOI.XWPF.UserModel; using NUglify.JavaScript.Syntax; using Org.BouncyCastle.Asn1.X500; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using SixLabors.ImageSharp; using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Linq.Dynamic.Core; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Services; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; namespace Business.ResourceExamineManagement { /// /// 资源检查 /// //[Authorize(BusinessPermissions.ResourceExamine.Default)] public class ResourceExamineAppService : ApplicationService, IResourceExamineAppService, ITransientDependency { #region 服务 SnowFlake help = new SnowFlake(); private readonly ICurrentTenant _currentTenant; /// /// 工艺路径 /// private readonly IRepository _mes_technique; /// /// 工序 /// private readonly IRepository _mes_process; /// /// 工艺关联工序 /// private readonly IRepository _mes_tech_process; /// /// 工艺工序关联工位 /// private readonly IRepository _mes_tech_proc_workshop; /// /// 物料占用记录 /// private readonly IRepository _ic_item_stockoccupy; private IRepository _mysql_ic_item_stockoccupy; /// /// 物料详情 /// private readonly IRepository _ic_item; private IRepository _mysql_ic_item; private IRepository _mysql_ic_demandschedule; /// /// 物料BOM /// private readonly IRepository _ic_bom; private IRepository _mysql_ic_bom; /// /// 物料BOM明细 /// private readonly IRepository _ic_bom_child; private IRepository _mysql_ic_bom_child; /// /// 物料库存表 /// private readonly IRepository _ic_item_stock; private IRepository _mysql_ic_item_stock; /// /// 物料采购报价单 /// private readonly IRepository _srm_purchase; private IRepository _mysql_srm_purchase; /// /// 交期回复 /// private readonly ISqlRepository _scm_jhjh_jq; /// /// 采购申请单 /// private readonly IRepository _srm_pr_main; private IRepository _mysql_srm_pr_main; /// /// 采购订单表 /// private readonly IRepository _srm_po_main; private IRepository _mysql_srm_po_main; /// /// 采购订单明细表 /// private readonly IRepository _srm_po_list; private IRepository _mysql_srm_po_list; private readonly IRepository _replenishmentWeekPlan; /// /// 采购订单占用详情 /// private readonly IRepository _srm_po_occupy; private IRepository _mysql_srm_po_occupy; /// /// 供应商 /// private readonly IRepository _srm_supplier; private IRepository _mysql_srm_supplier; /// /// 委外工单 /// private readonly IRepository _mes_oorder; private IRepository _mysql_mes_oorder; private IRepository _mysql_b_bom_pretreatment; private IRepository _mysql_examine_result; private IRepository _mysql_bom_child_examine; private IRepository _mysql_mo_occupy; private IRepository _mysql_mo_order; private IRepository _mysql_ooder; private IRepository _mysql_purchase; private IRepository _mysql_purchase_occupy; /// /// 库存主数据 /// private ISqlRepository _invMaster; /// /// 替代方案 /// private readonly IRepository _ic_substitute; /// /// 替代方案群组 /// private readonly IRepository _ic_substitute_group; /// /// 替代明细 /// private readonly IRepository _ic_substitute_group_detail; /// /// 替代方案 /// private readonly IRepository _mysql_ic_substitute; /// /// 替代方案群组 /// private readonly IRepository _mysql_ic_substitute_group; /// /// 替代明细 /// private readonly IRepository _mysql_ic_substitute_group_detail; /// /// 生产工单主表 /// private readonly IRepository _mes_morder; /// /// 生产工单子表 /// private readonly IRepository _mes_moentry; /// /// 在制工单占用记录表 /// private readonly IRepository _mes_mooccupy; /// /// mysql在制工单占用表 /// private readonly IRepository _mysql_mes_mooccupy; /// /// 销售订单 /// private readonly IRepository _mysql_crm_seorder; /// /// 销售订单明细 /// private readonly IRepository _mysql_crm_seorderentry; /// /// 生产工单主表 /// private readonly IRepository _mysql_mes_morder; /// /// 生产工单子表 /// private readonly IRepository _mysql_mes_moentry; /// /// 工艺路线表 /// private readonly ISqlRepository _routingOpDetail; /// /// 生产线明细 /// private readonly ISqlRepository _prodLineDetail; /// /// 排产记录表 /// private readonly ISqlRepository _periodSequenceDet; /// /// 物料职责表 /// private readonly ISqlRepository _empWorkDutyMaster; /// /// 雇员信息表 /// private readonly ISqlRepository _employeeMaster; /// /// 排产结果明细 /// private ISqlRepository _scheduleResultOpMaster; /// /// 工作日历 /// private readonly ISqlRepository _shopCalendarWorkCtr; /// /// 休息时间段 /// private readonly ISqlRepository _qualityLineWorkDetail; /// /// 节假日 /// private readonly ISqlRepository _holidayMaster; /// /// 标准BOM表 /// private readonly ISqlRepository _productStructureMaster; /// /// 工单工序表 /// private ISqlRepository _workOrdRouting; /// /// 工单主表 /// private ISqlRepository _workOrdMaster; /// /// 成品虚拟件工序关系表 /// private readonly ISqlRepository _productStructureOp; /// /// 工单物料明细 /// private ISqlRepository _workOrdDetail; private readonly ISqlRepository _rf_serialnumber; private readonly ISqlRepository _locationDetail; private readonly ISqlRepository _configurationItem; /// /// 资源检查入参 /// private readonly SeorderentryDto param = new SeorderentryDto(); /// /// 预处理 /// private readonly PretreatmentAppService _pretreatmentAppService; /// /// 在途检查 /// private readonly PurchaseOrderAppService _purchaseOrderAppService; /// /// 工单App /// private readonly MorderAppService _morderAppService; private readonly SerialNumberAppService _serialNumberAppService; private readonly HolidayHelper _holidayHelper; /// /// 优先级 /// private readonly ReplenishmentAppService _replenishmentAppService; /// /// 计算BOM平铺物料情况 /// private readonly CalcBomViewAppService _CalcBomViewAppService; /// /// 账号时效性验证 /// private readonly AccountValidityAppService _AccountValidityAppService; private List leadTimeList; private List supplierList; private readonly BusinessBangDbContext _businessBangDbContext; private readonly BusinessDbContext _businessDbContext; private readonly ISqlRepository _tagMasterRepository; /// /// 生产线维护表 /// private ISqlRepository _lineMaster; private ISqlRepository _itemMaster; private ISqlRepository _nbrMaster; private ISqlRepository _nbrDetail; private ISqlRepository _srm_polist_ds; private ISqlRepository _purOrdMaster; private ISqlRepository _purOrdDetail; private ISqlRepository _purOrdDetailBatch; private ISqlRepository _itemPackMaster; private ISqlRepository _generalizedCodeMaster; private readonly ISqlRepository _SAPInv; /// /// 生产排产 /// private readonly ProductionScheduleAppService _productionScheduleAppService; /// /// 优先级 /// private readonly PriorityAppService _priorityAppService; /// /// 产能检查 /// private readonly ProductExamineAppService _productExamineAppService; /// /// 生产线明细表 /// public List prodLines = new List(); /// /// 标准工艺路径表 /// public List routingOps = new List(); /// /// 排产记录表 /// public List periodSequences = new List(); /// /// 工作日历 /// public List calendarWorks = new List(); /// /// 休息时间段 /// public List qualityLineWorks = new List(); /// /// 节假日 /// public List holidays = new List(); public IDataFilter dataFilter { get; set; } private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly SystemJobAppService _systemJobAppService; #endregion #region 构造函数 /// /// 构造函数 /// /// /// public ResourceExamineAppService( IRepository mes_technique, IRepository mes_process, IRepository mes_tech_process, IRepository mes_tech_proc_workshop, IRepository ic_item, IRepository ic_bom, IRepository ic_bom_child, IRepository ic_item_stock, IRepository mes_oorder, IRepository srm_pr_main, IRepository srm_po_main, IRepository srm_po_list, IRepository srm_po_occupy, IRepository srm_purchase, IRepository ic_substitute, IRepository ic_substitute_group, IRepository ic_substitute_group_detail, IRepository mes_morder, IRepository mes_moentry, IRepository mes_mooccupy, IRepository ic_item_stockoccupy, IRepository srm_supplier, IRepository mysql_ic_item, IRepository mysql_ic_demandschedule, IRepository mysql_ic_bom, IRepository mysql_ic_bom_child, IRepository mysql_mes_technique, IRepository mysql_crm_seorder, IRepository mysql_crm_seorderentry, IRepository mysql_ic_item_stock, IRepository mysql_ic_item_stockoccupy, IRepository mysql_mes_oorder, IRepository mysql_srm_pr_main, IRepository mysql_mes_mooccupy, IRepository mysql_mes_morder, IRepository mysql_mes_moentry, IRepository mysql_mes_process, IRepository mysql_mes_tech_process, IRepository mysql_srm_po_main, IRepository mysql_srm_po_list, IRepository mysql_srm_po_occupy, IRepository mysql_srm_purchase, IRepository mysql_examine_result, IRepository mysql_bom_child_examine, IRepository mysql_mo_occupy, IRepository mysql_mo_order, IRepository mysql_ooder, IRepository mysql_purchase, IRepository mysql_purchase_occupy, IRepository mysql_b_bom_pretreatment, IRepository mysql_srm_supplier, ISqlRepository tagMasterRepository, ISqlRepository periodSequenceDet, ISqlRepository employeeMaster, ISqlRepository empWorkDutyMaster, ISqlRepository lineMaster, ISqlRepository itemMaster, PretreatmentAppService pretreatmentAppService, CalcBomViewAppService calcbomviewAppService, AccountValidityAppService accountValidityAppService, PurchaseOrderAppService purchaseOrderAppService, ICurrentTenant currentTenant, MorderAppService morderAppService, BusinessBangDbContext businessBangDbContext, BusinessDbContext businessDbContext, ProductionScheduleAppService productionScheduleAppService, ISqlRepository routingOpDetail, ISqlRepository productStructureMaster, ISqlRepository workOrdRouting, ISqlRepository workOrdMaster, ISqlRepository productStructureOp, ISqlRepository workOrdDetail, ISqlRepository nbrMaster, ISqlRepository nbrDetail, ISqlRepository srmpolistds, ISqlRepository purOrdMaster, ISqlRepository purOrdDetail, ISqlRepository purOrdDetailBatch, PriorityAppService priorityAppService, ISqlRepository prodLineDetail, ISqlRepository shopCalendarWorkCtr, ISqlRepository qualityLineWorkDetail, ISqlRepository holidayMaster, ProductExamineAppService productExamineAppService, ISqlRepository rf_serialnumber, ISqlRepository locationDetail, ISqlRepository configurationItem, ISqlRepository itemPackMaster, ISqlRepository generalizedCodeMaster, ISqlRepository scheduleResultOpMaster, IRepository mysql_ic_substitute, IRepository mysql_ic_substitute_group, IRepository mysql_ic_substitute_group_detail, IRepository domesticTerminalFcst, ISqlRepository ASNBOLShipperDetail, IRepository standardItemModelSet, ISqlRepository invTransHist, ISqlRepository SAPInv, ISqlRepository monthlyShipmentPlan, IRepository srmPurchase, IUnitOfWorkManager unitOfWorkManager, SerialNumberAppService serialNumberAppService, HolidayHelper holidayHelper, ReplenishmentAppService replenishmentAppService, IRepository replenishmentWeekPlan, ISqlRepository invMaster, ISqlRepository scm_jhjh_jq, SystemJobAppService systemJobAppService ) { _mes_technique = mes_technique; _mes_process = mes_process; _mes_tech_process = mes_tech_process; _mes_tech_proc_workshop = mes_tech_proc_workshop; _ic_item = ic_item; _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; _srm_po_list = srm_po_list; _srm_po_occupy = srm_po_occupy; _srm_purchase = srm_purchase; _ic_substitute = ic_substitute; _ic_substitute_group = ic_substitute_group; _ic_substitute_group_detail = ic_substitute_group_detail; _mysql_ic_substitute = mysql_ic_substitute; _mysql_ic_substitute_group = mysql_ic_substitute_group; _mysql_ic_substitute_group_detail = mysql_ic_substitute_group_detail; _mes_morder = mes_morder; _mes_moentry = mes_moentry; _mes_mooccupy = mes_mooccupy; _ic_item_stockoccupy = ic_item_stockoccupy; _srm_supplier = srm_supplier; _mysql_ic_item = mysql_ic_item; _mysql_ic_demandschedule = mysql_ic_demandschedule; _mysql_ic_bom = mysql_ic_bom; _mysql_ic_bom_child = mysql_ic_bom_child; _mysql_crm_seorder = mysql_crm_seorder; _mysql_crm_seorderentry = mysql_crm_seorderentry; _mysql_ic_item_stock = mysql_ic_item_stock; _mysql_ic_item_stockoccupy = mysql_ic_item_stockoccupy; _mysql_mes_oorder = mysql_mes_oorder; _mysql_srm_pr_main = mysql_srm_pr_main; _mysql_mes_mooccupy = mysql_mes_mooccupy; _mysql_mes_morder = mysql_mes_morder; _mysql_mes_moentry = mysql_mes_moentry; _mysql_srm_po_main = mysql_srm_po_main; _mysql_srm_po_list = mysql_srm_po_list; _mysql_srm_po_occupy = mysql_srm_po_occupy; _mysql_srm_purchase = mysql_srm_purchase; _mysql_examine_result = mysql_examine_result; _mysql_bom_child_examine = mysql_bom_child_examine; _mysql_mo_occupy = mysql_mo_occupy; _mysql_mo_order = mysql_mo_order; _mysql_ooder = mysql_ooder; _mysql_purchase = mysql_purchase; _mysql_purchase_occupy = mysql_purchase_occupy; _mysql_b_bom_pretreatment = mysql_b_bom_pretreatment; _mysql_srm_supplier = mysql_srm_supplier; _tagMasterRepository = tagMasterRepository; _periodSequenceDet = periodSequenceDet; _employeeMaster = employeeMaster; _empWorkDutyMaster = empWorkDutyMaster; _pretreatmentAppService = pretreatmentAppService; _CalcBomViewAppService = calcbomviewAppService; _AccountValidityAppService = accountValidityAppService; _purchaseOrderAppService = purchaseOrderAppService; _currentTenant = currentTenant; _morderAppService = morderAppService; _businessBangDbContext = businessBangDbContext; _businessDbContext = businessDbContext; _productionScheduleAppService = productionScheduleAppService; _routingOpDetail = routingOpDetail; _productStructureMaster = productStructureMaster; _workOrdRouting = workOrdRouting; _workOrdMaster = workOrdMaster; _productStructureOp = productStructureOp; _workOrdDetail = workOrdDetail; _lineMaster = lineMaster; _itemMaster = itemMaster; _nbrMaster = nbrMaster; _nbrDetail = nbrDetail; _srm_polist_ds = srmpolistds; _purOrdMaster = purOrdMaster; _purOrdDetail = purOrdDetail; _purOrdDetailBatch = purOrdDetailBatch; _priorityAppService = priorityAppService; _rf_serialnumber = rf_serialnumber; _prodLineDetail = prodLineDetail; _shopCalendarWorkCtr = shopCalendarWorkCtr; _qualityLineWorkDetail = qualityLineWorkDetail; _holidayMaster = holidayMaster; _productExamineAppService = productExamineAppService; _locationDetail = locationDetail; _configurationItem = configurationItem; _itemPackMaster = itemPackMaster; _generalizedCodeMaster = generalizedCodeMaster; _unitOfWorkManager = unitOfWorkManager; _scheduleResultOpMaster = scheduleResultOpMaster; _serialNumberAppService = serialNumberAppService; _holidayHelper = holidayHelper; _replenishmentAppService = replenishmentAppService; _replenishmentWeekPlan = replenishmentWeekPlan; _invMaster = invMaster; _scm_jhjh_jq = scm_jhjh_jq; _systemJobAppService = systemJobAppService; } #endregion /// /// 自动任务执行资源检查 /// /// /// public async Task receiveresultControllerApi(string companyid) { //var IsActived = _AccountValidityAppService.IsActived(); //if (!IsActived) //{ // return "此账号已限制访问"; //} ////获取订单行数据 var sentrys = await _mysql_crm_seorderentry.GetListAsync(p => (p.progress == "1" || p.progress == "2") && p.company_id.ToString() == companyid && !p.IsDeleted); var seorders = _mysql_crm_seorder.GetListAsync(s => sentrys.Select(x => x.seorder_id.GetValueOrDefault()).Contains(s.Id) && s.company_id.ToString() == companyid).Result; string ids = string.Join(',', seorders.Select(x => x.Id)); var rtn = await ReceiveResult(ids, 0, companyid); if (rtn == "ok") { rtn = await ReviewExamineResult(ids, 0); } return rtn; } /// /// 资源检查 -- TODO:根据客户的不同标准交货期(假如客户设定10天),如果检查交期小于标准交货期(10天),则默认把建议交期调整为10天。 /// /// /// 类型(0,销售订单 1,全域订单) /// /// public async Task ReceiveResult(string ids, int type, string companyid) { //var IsActived = _AccountValidityAppService.IsActived(); //if (!IsActived) //{ // return "此账号已限制访问"; //} if (string.IsNullOrEmpty(ids)) { throw new NotImplementedException("请输入正确的订单号!"); } ResourceCheckInputDto input = new ResourceCheckInputDto(); input.sorderId = AnalysisIdList(ids); //资源检查结果 PschedDto rtn = new PschedDto(); List sorders = new List(); List sentrys = new List(); //生成当前计算bangid long bangid = help.NextId(); if (type == 0) { //获取订单数据 sorders = _mysql_crm_seorder.GetListAsync(p => input.sorderId.Contains(p.Id) && !p.IsDeleted).Result; if (!sorders.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单数据不存在", _currentTenant.Id.ToString()); return "订单数据不存在"; } //获取订单行数据 sentrys = await _mysql_crm_seorderentry.GetListAsync(p => input.sorderId.Contains(p.seorder_id.GetValueOrDefault()) && (p.progress == "1" || p.progress == "2" || p.progress == "0") && !p.IsDeleted); if (!sentrys.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单行数据不存在", _currentTenant.Id.ToString()); return "订单行数据不存在"; } } else { //获取订单行数据 sentrys = await _mysql_crm_seorderentry.GetListAsync(p => (p.progress == "1" || p.progress == "2" || p.progress == "0") && p.company_id.ToString() == companyid && !p.IsDeleted); if (!sentrys.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单行数据不存在", _currentTenant.Id.ToString()); return "没有需要检查的订单行。"; } sorders = _mysql_crm_seorder.GetListAsync(p => sentrys.Select(s => s.seorder_id).Contains(p.Id) && !p.IsDeleted).Result; if (!sorders.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单数据不存在", _currentTenant.Id.ToString()); return "没有需要检查的订单。"; } } input.company_id = sorders[0].company_id; input.factoryId = sorders[0].factory_id.GetValueOrDefault(); //资源检查入参全局变量赋值 param.company_id = input.company_id; param.factoryId = input.factoryId; param.checkflag = true; rtn.sorderid = input.sorderId; //资源检查明细list List examines = new List(); ExamineResult dtl; //var oldwork = _mysql_mes_moentry.GetListAsync(m => sentrys.Select(s => s.Id).ToList().Contains(m.soentry_id.GetValueOrDefault())).Result; //if (oldwork.Any()) //{ // //判断工单状态,已投产就关闭处理,未下达则删除--pr_MES_DeleteWorkOrdMaster--pr_MES_CloseWorkOrders // var workord = _workOrdMaster.Select(w=> oldwork.Select(m=>m.moentry_mono).ToList().Contains(w.WorkOrd)).ToList(); // if (workord.Any()) // { // } //} //处理销售订单优先级 sorders = _priorityAppService.CalcOrderPriority(sorders, sentrys); //处理订单行优先级 sentrys = _priorityAppService.CalcOrderEntryPriority(sorders, sentrys); //删除同步Mysql后旧数据 await DeleteMySqlOldData(sentrys); //通过订单行的产品代码获取物料BOM数据 List boms = _ic_bom.GetListAsync(p => sentrys.Select(m => m.item_number).Contains(p.item_number) && p.factory_id == input.factoryId && p.company_id == input.company_id && !p.IsDeleted).Result.ToList(); //物料信息 List icitemlist = new List(); //物料库存表 List stocklist = new List(); //物料占用记录 List sklist = new List(); var pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; List autoCreates = new List(); boms.ForEach(p => { if (!pretreatments.Where(s => s.sourceid == p.mysql_id).Any()) { autoCreates.Add(p); } }); if (autoCreates.Any()) { AutoCreateBomBill(param.company_id.ToString(), autoCreates); pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; } await AsyncItemStockFromWMS(pretreatments); //数据库快照-同步mysql库数据到mongoDB中 await DbSnapShot(input.company_id, input.factoryId, bangid, pretreatments); //记录订单行的物料齐套时间 List kittingTimes = new List(); DataInitialization(boms, bangid, icitemlist, stocklist, pretreatments, sklist); List GenerateMoList = new List(); var moNbrlistDto = _serialNumberAppService.GetBillNo(input.factoryId.ToString(), "M5", sentrys.Count, "", 1); if (moNbrlistDto.Any()) { foreach (var nbr in moNbrlistDto) { GenerateMoList.Add(nbr.NbrResult); } } _CalcBomViewAppService.GenerateMoList = GenerateMoList; foreach (var sorder in sorders) { param.sorderId = sorder.Id; param.company_id = input.company_id; param.factoryId = input.factoryId; //param.checkflag = true; _morderAppService.param = param; _purchaseOrderAppService.param = param; if (sorder.order_type.GetValueOrDefault() == 1) { _CalcBomViewAppService.morder_type = MorderEnum.XsMorder; } else { _CalcBomViewAppService.morder_type = MorderEnum.JhMorder; } _CalcBomViewAppService.param = param; //_CalcBomViewAppService.IsStraight = true; _CalcBomViewAppService.seorder = sorder;//销售订单 var orderSentrys = sentrys.Where(s => s.seorder_id == sorder.Id).ToList(); foreach (var item in orderSentrys) { //工单资源检查信息 dtl = new ExamineResult(); dtl.sorderid = sorder.Id; dtl.bill_no = sorder.bill_no; dtl.sentry_id = item.Id; dtl.entry_seq = item.entry_seq; dtl.need_qty = item.qty.GetValueOrDefault(); dtl.need_time = item.plan_date; dtl.bangid = bangid; dtl.prd_code = item.item_number; //获取当前物料bom数据 var childBom = boms.Where(p => p.item_number == item.item_number).FirstOrDefault(); dtl.bom_number = childBom.bom_number; var itemPrelist = pretreatments.Where(s => s.sourceid == childBom.mysql_id).ToList(); if (!itemPrelist.Any()) { continue; } var getBomList = ObjectMapper.Map, List>(itemPrelist); getBomList.ForEach(s => s.sentry_id = item.Id); //库存初始化 _CalcBomViewAppService.BomStock(getBomList, stocklist, bangid); _CalcBomViewAppService.newStockOccList = new List(); //计算 _CalcBomViewAppService.CalcView(getBomList, bangid, item.qty.GetValueOrDefault(), item.plan_date, sklist, item, icitemlist); //TODO:最晚开始时间 var curFacDtl = leadTimeList.FirstOrDefault(p => p.item_id == childBom.icitem_id); //最晚开工时间=订单行客户要求交期-运输提前期-库存提前期-生产提前期-下单提前期-生产时间 dtl.latest_times = item.plan_date.GetValueOrDefault().AddDays(-Convert.ToDouble(curFacDtl?.transportation_leadtime.GetValueOrDefault() + curFacDtl?.stock_leadtime.GetValueOrDefault() + curFacDtl?.production_leadtime.GetValueOrDefault() + curFacDtl?.order_leadtime.GetValueOrDefault() + _CalcBomViewAppService.ProductionTimeDay)); //物料齐套时间 dtl.kitting_times = getBomList.Where(p => p.is_use).OrderByDescending(m => m.kitting_time).First().kitting_time.GetValueOrDefault(); //TODO:最早开始时间默认3天后(后期调整,因为要计算排产,计算产能这一类,才能得到开工时间) dtl.earliest_times = dtl.kitting_times.AddDays(1); //再评审状态改为确认 item.progress = item.progress == "0" ? "3" : "2"; //替代关系展开list dtl.BomChildExamineList = getBomList; //添加订单行开工信息 examines.Add(dtl); //记录订单行的建议交期 KittingTimeDto dto = new KittingTimeDto(); dto.sentry_id = item.Id; dto.ItemNum = item.item_number; dto.LackQty = getBomList.First(p => p.level == 1).lack_qty; dto.kitting_time = dtl.kitting_times; kittingTimes.Add(dto); } } //计算订单行的建议交期(产能/物料) CalcSuggestDate(sentrys, kittingTimes, icitemlist); examines.ForEach(p => { var sent = sentrys.Find(s => s.Id == p.sentry_id); if (sent != null) { p.sys_material_date = sent.sys_material_date; p.sys_capacity_date = sent.sys_capacity_date; } }); rtn.mordersList = _CalcBomViewAppService.mordersInsertList; List prmainlist = new List(); if (_CalcBomViewAppService.SRMPRDtoList.Any()) { List> prlist = _CalcBomViewAppService.SRMPRDtoList.Where(f => f.srm_Pr_Main != null).Select(s => s.srm_Pr_Main).ToList(); foreach (var pr in prlist) { foreach (var item in pr) { prmainlist.Add(item); } } rtn.srm_pr_list = _CalcBomViewAppService.SRMPRDtoList; } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { await _businessDbContext.BulkUpdateAsync(sentrys); /*//批量保存 后期考虑子工单 if (moderlist.Any()) { await _mes_morder.InsertMany(_CalcBomViewAppService.mordersInsertList); _businessDbContext.BulkInsert(moderlist); if (workOrds.Any()) { _workOrdMaster.Insert(workOrds); } if (workOrdRoutings.Any()) { _workOrdRouting.Insert(workOrdRoutings); } if (workOrdDetails.Any()) { _workOrdDetail.Insert(workOrdDetails); } }*/ if (_CalcBomViewAppService.mordersInsertList.Any()) { await MongoHelper.InsertManyAsync(_CalcBomViewAppService.mordersInsertList); } if (prmainlist.Any()) { await MongoHelper.InsertManyAsync(prmainlist); } if (_CalcBomViewAppService.mooccupyAllInsertList.Any()) { _CalcBomViewAppService.mooccupyAllInsertList.ForEach(s => { s.tenant_id = param.company_id.GetValueOrDefault(); s.company_id = param.company_id; s.factory_id = param.factoryId; }); await MongoHelper.InsertManyAsync(_CalcBomViewAppService.mooccupyAllInsertList); /*var moOccupy = ObjectMapper.Map, List>(_CalcBomViewAppService.mooccupyAllInsertList); _businessDbContext.BulkInsert(moOccupy);*/ rtn.mooccupyAllList = _CalcBomViewAppService.mooccupyAllInsertList; } if (_CalcBomViewAppService.moentriesInsertList.Any()) { _CalcBomViewAppService.moentriesInsertList.ForEach(s => { s.tenant_id = param.company_id.GetValueOrDefault(); s.company_id = param.company_id; s.factory_id = param.factoryId; }); await MongoHelper.InsertManyAsync(_CalcBomViewAppService.moentriesInsertList); /*var mesmoentrys = ObjectMapper.Map, List>(_CalcBomViewAppService.moentriesInsertList); _businessDbContext.BulkInsert(mesmoentrys);*/ } if (_CalcBomViewAppService.orderList.Any()) { _CalcBomViewAppService.orderList.ForEach(s => { s.tenant_id = param.company_id.GetValueOrDefault(); s.company_id = param.company_id; s.factory_id = param.factoryId; }); await MongoHelper.InsertManyAsync(_CalcBomViewAppService.orderList); /*var ooders = ObjectMapper.Map, List>(_CalcBomViewAppService.orderList); _businessDbContext.BulkInsert(ooders);*/ rtn.order_list = _CalcBomViewAppService.orderList; } if (_CalcBomViewAppService.newStockOccList.Any()) { _CalcBomViewAppService.newStockOccList.ForEach(s => { s.GenerateNewId(help.NextId()); s.tenant_id = param.company_id.GetValueOrDefault(); s.company_id = param.company_id; s.factory_id = param.factoryId; }); await MongoHelper.InsertManyAsync(_CalcBomViewAppService.newStockOccList); } if (_CalcBomViewAppService.srm_Po_OccupiesInsert.Any()) { _CalcBomViewAppService.srm_Po_OccupiesInsert.ForEach(s => { s.GenerateNewId(help.NextId()); s.tenant_id = param.company_id.GetValueOrDefault(); s.company_id = param.company_id; s.factory_id = param.factoryId; }); await MongoHelper.InsertManyAsync(_CalcBomViewAppService.srm_Po_OccupiesInsert); /*var poOccupies = ObjectMapper.Map, List>(_CalcBomViewAppService.srm_Po_OccupiesInsert); _businessDbContext.BulkInsert(poOccupies);*/ } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "资源检查工单相关数据更新失败:" + e.Message, _currentTenant.Id.ToString()); return e.Message; }; } rtn.examines = examines; rtn.item_stockoccupy_list = sklist; //检查结果写入数据库 await ExamineResultInsertDBAsync(rtn.examines); //清空快照数据 await ClearSnapShot(bangid); return JsonConvert.SerializeObject("ok"); } public async Task ExamineResultInsertDBAsync(List examines) { //检查结果写入数据库 List examineList = new List(); List bomExamineList = new List(); List mooccupyList = new List(); List moorderList = new List(); List ooderList = new List(); List purchaseList = new List(); List purchaseoccupyList = new List(); foreach (var ex in examines) { var b_ex = ObjectMapper.Map(ex); b_ex.GenerateNewId(help.NextId());// = help.NextId(); if (_CalcBomViewAppService.mordersInsertList.Any() && b_ex.sentry_id != null && string.IsNullOrEmpty(ex.morder_no)) { var moentry = _CalcBomViewAppService.moentriesInsertList.Where(s => s.soentry_id == b_ex.sentry_id).ToList(); if (moentry != null) { var sentryMo = _CalcBomViewAppService.mordersInsertList.Where(s => moentry.Select(x => x.moentry_moid).Contains(s.mysql_id) && s.product_code == ex.prd_code).FirstOrDefault(); if (sentryMo != null) { b_ex.morder_id = sentryMo.mysql_id; b_ex.morder_no = sentryMo.morder_no; } } } else { b_ex.morder_id = ex.morder_id; b_ex.morder_no = ex.morder_no; } b_ex.create_time = DateTime.Now; b_ex.company_id = param.company_id; b_ex.tenant_id = param.company_id; b_ex.factory_id = param.factoryId; examineList.Add(b_ex); ex.BomChildExamineList.ForEach(s => { var bc_ex = ObjectMapper.Map(s); bc_ex.GenerateNewId(help.NextId()); bc_ex.examine_id = b_ex.Id; bc_ex.company_id = param.company_id; bc_ex.tenant_id = param.company_id; bc_ex.factory_id = param.factoryId; bc_ex.create_time = DateTime.Now; bomExamineList.Add(bc_ex); if (s.mo_occupy_list != null) { var olist = ObjectMapper.Map, List>(s.mo_occupy_list); olist.ForEach(o => { o.bom_child_examine_id = bc_ex.Id; o.company_id = param.company_id; o.tenant_id = param.company_id; o.factory_id = param.factoryId; }); mooccupyList.AddRange(olist); } if (s.make_list != null) { var mlist = ObjectMapper.Map, List>(s.make_list); mlist.ForEach(o => { o.bom_child_examine_id = bc_ex.Id; o.company_id = param.company_id; o.tenant_id = param.company_id; o.factory_id = param.factoryId; }); moorderList.AddRange(mlist); } if (s.subcontracting_list != null) { var slist = ObjectMapper.Map, List>(s.subcontracting_list); slist.ForEach(o => { o.bom_child_examine_id = bc_ex.Id; o.company_id = param.company_id; o.tenant_id = param.company_id; o.factory_id = param.factoryId; }); ooderList.AddRange(slist); } if (s.purchase_list != null) { var plist = ObjectMapper.Map, List>(s.purchase_list); plist.ForEach(o => { o.bom_child_examine_id = bc_ex.Id; o.company_id = param.company_id; o.tenant_id = param.company_id; o.factory_id = param.factoryId; o.create_time = DateTime.Now; }); purchaseList.AddRange(plist); } if (s.purchase_occupy_list != null) { var purlist = ObjectMapper.Map, List>(s.purchase_occupy_list); purlist.ForEach(o => { o.bom_child_examine_id = bc_ex.Id; o.company_id = param.company_id; o.tenant_id = param.company_id; o.factory_id = param.factoryId; o.create_time = DateTime.Now; }); purchaseoccupyList.AddRange(purlist); } }); } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { if (examineList.Any()) { _businessBangDbContext.BulkInsert(examineList); } if (bomExamineList.Any()) { _businessBangDbContext.BulkInsert(bomExamineList.OrderBy(s => s.num_order).ToList()); } if (mooccupyList.Any()) { _businessBangDbContext.BulkInsert(mooccupyList); } if (moorderList.Any()) { _businessBangDbContext.BulkInsert(moorderList); } if (ooderList.Any()) { _businessBangDbContext.BulkInsert(ooderList); } if (purchaseList.Any()) { _businessBangDbContext.BulkInsert(purchaseList); } if (purchaseoccupyList.Any()) { _businessBangDbContext.BulkInsert(purchaseoccupyList); } await unitOfWork.CompleteAsync(); } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "资源检查计算结果相关数据更新失败:" + e.Message, _currentTenant.Id.ToString()); unitOfWork.Dispose(); } } } //PR手动合并--排除委外 public async Task PrMerge(string ids) { //物料、供应商为相同才允许合并。 var idList = AnalysisIdList(ids); List prlist = _mysql_srm_pr_main.GetListAsync(s => idList.Contains(s.Id)).Result; if (prlist.Any()) { if (prlist.Where(s => s.state == 0).Count() > 0) { return JsonConvert.SerializeObject("所选包含已关闭采购申请,请重新选择。"); } if (prlist.Where(s => s.state == 2).Count() > 0) { return JsonConvert.SerializeObject("所选包含已提交评审采购申请,请重新选择。"); } if (prlist.Where(s => s.state == 4).Count() > 0) { return JsonConvert.SerializeObject("所选包含已评审通过采购申请,请重新选择。"); } var list = prlist.GroupBy(s => new { s.icitem_id, s.pr_purchaseid, s.IsRequireGoods, s.supplier_type }); if (list.Count() > 1) { return JsonConvert.SerializeObject("所选行的物料编码、供应商名称、采购类型、供应类别必须相同"); } } else { return JsonConvert.SerializeObject("所选采购申请单未找到,请刷新界面重新操作。"); } List occupylist = _mysql_srm_po_occupy.GetListAsync(s => idList.Contains(s.polist_id.GetValueOrDefault())).Result; srm_pr_main srm_Pr = help.DeepCopy(prlist[0]); srm_Pr.GenerateNewId(help.NextId()); var nbrResult = _serialNumberAppService.GetBillNo(srm_Pr.factory_id.ToString(), "PR", 1, "admin", 1); if (nbrResult.Any()) { srm_Pr.pr_billno = nbrResult[0].NbrResult; } else { srm_Pr.pr_billno = prlist[0].pr_type == 2 ? _CalcBomViewAppService.getOrderNum("WWPR") : _CalcBomViewAppService.getOrderNum("PR");//pr单号 } srm_Pr.state = 1; /*if (mes_morder != null) { srm_Pr.pr_mono = mes_morder.morder_no;//关联工单号 srm_Pr.entity_id = 1;//工单行号 }*/ srm_Pr.pr_purchaseid = prlist[0].pr_purchaseid;//供应商id srm_Pr.pr_purchasenumber = prlist[0].pr_purchasenumber;//供应商编码 srm_Pr.pr_purchasename = prlist[0].pr_purchasename;//供应商名称 srm_Pr.pr_purchaser = prlist[0].pr_purchaser;//采购员 srm_Pr.pr_purchaser_num = prlist[0].pr_purchaser_num;//采购员工号(采购信息表)*//* srm_Pr.pr_rqty = prlist.Sum(s => s.pr_rqty);//需求数量 srm_Pr.pr_aqty = prlist.Sum(s => s.pr_aqty);//申请数量 srm_Pr.pr_sqty = prlist.Sum(s => s.pr_sqty);//建议数量 srm_Pr.pr_ssend_date = prlist.Min(s => s.pr_ssend_date);//系统建议下单日期 srm_Pr.pr_sarrive_date = prlist.Min(s => s.pr_sarrive_date);//系统建议到达日期(建议到货日期) /* srm_Pr.pr_psend_date = prlist.Min(s => s.pr_psend_date);//计划下单日期 srm_Pr.pr_parrive_date = prlist.Min(s => s.pr_parrive_date);//计划到达日期 srm_Pr.pr_rarrive_date = prlist.Min(s => s.pr_rarrive_date);//需求到货日期*/ //srm_Pr.pr_sysprice = prlist.Sum(s => s.pr_rqty) * prlist[0].pr_price * (1 + prlist[0].pr_rate);//系统价格(含税) srm_Pr.pr_orderprice = prlist.Sum(s => s.pr_aqty) * prlist[0].pr_sysprice;//订单价格(含税) /*srm_Pr.icitem_id = returnlist.item_id;//物料id srm_Pr.icitem_name = returnlist.item_name;//物料名称 srm_Pr.pr_order_type = 1;//单据类型 srm_Pr.pr_ssend_date = DateTime.Now;//系统建议下单日期 srm_Pr.pr_price = prlist[0].pr_price;//采购净价(不含税) srm_Pr.pr_rate = prlist[0].pr_rate;//税率 srm_Pr.pr_unit = prlist[0].pr_unit;//单位 srm_Pr.state = prlist[0].state;//状态 srm_Pr.old_apply_aqty = prlist[0].old_apply_aqty;//已申请数量 srm_Pr.pr_type = prlist[0].pr_type;//申请类型 srm_Pr.currencytype = prlist[0].currencytype;//币种 srm_Pr.secInv_ratio = prlist[0].secInv_ratio;//安全库存触发采购比例 srm_Pr.tenant_id = prlist[0].tenant_id; srm_Pr.factory_id = prlist[0].factory_id;*/ prlist.ForEach(s => { s.state = 0; s.refer_pr_billno = srm_Pr.pr_billno; }); occupylist.ForEach(s => { s.polist_id = srm_Pr.Id; }); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { _businessDbContext.BulkUpdate(prlist); _businessDbContext.BulkInsert(new List { srm_Pr }); _businessDbContext.BulkUpdate(occupylist); await unitOfWork.CompleteAsync(); } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("PrMerge", "采购申请单合并数据更新失败:" + e.Message, _currentTenant.Id.ToString()); unitOfWork.Dispose(); return JsonConvert.SerializeObject(e.Message); } } return JsonConvert.SerializeObject("ok"); } //PR自动合并 public async Task PrAutoMerge(string domain) { try { DateTime tomorrow = DateTime.Now.AddDays(1).Date; var formerlylist = _mysql_srm_pr_main.GetListAsync(x => x.pr_ssend_date < tomorrow && x.state == 1 && x.factory_id.ToString() == domain).Result; if (formerlylist.Any()) { formerlylist.ForEach(x => { TimeSpan difference = tomorrow.Subtract(x.pr_ssend_date.GetValueOrDefault()); int daysDifference = difference.Days; x.pr_ssend_date = tomorrow; x.pr_sarrive_date = x.pr_sarrive_date.GetValueOrDefault().AddDays(daysDifference); }); _businessDbContext.BulkUpdate(formerlylist); } DateTime toTime = DateTime.Now.Date; int dayOfWeek = (int)toTime.DayOfWeek; // 获取今天是星期几(0-6) switch (dayOfWeek) { case 0: toTime = toTime.AddDays(-7); break; default: toTime = toTime.AddDays(-dayOfWeek); break; } DateTime starttime = toTime.Date.AddDays(1); DateTime endtime = toTime.Date.AddDays(35); //只合并要货令 List alllist = _mysql_srm_pr_main.GetListAsync(s => s.factory_id.ToString() == domain && s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime && s.state == 1 && string.IsNullOrEmpty(s.analogcalcversion) == true).Result; List ic_Items = _mysql_ic_item.GetListAsync(s => s.factory_id.ToString() == domain && alllist.Select(c => c.icitem_id).Distinct().Contains(s.Id)).Result; var occupyListLINQ = _businessDbContext.srm_po_occupy.Where(x => x.factory_id.ToString() == domain && !x.IsDeleted).Join(_businessDbContext.srm_pr_main.Where(s => s.factory_id.ToString() == domain && s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime && s.state == 1), p => p.polist_id, pr => pr.Id, (p, pr) => new { p, pr }).ToList(); List occupylist = new List(); for (int i = 0; i < occupyListLINQ.Count; i++) { occupylist.Add(occupyListLINQ[i].p); } //var occupylist = _mysql_srm_po_occupy.GetListAsync(s => alllist.Select(c => c.Id).Contains(s.polist_id.GetValueOrDefault()) && s.company_id.ToString() == companyid && s.IsDeleted == false).Result; var purList = _mysql_srm_purchase.GetListAsync(x => x.factory_id.ToString() == domain).Result; List insetAllList = new List(); List updateAllList = new List(); //每次发布四周的数据 for (int i = 0; i < 5; i++) { starttime = toTime.Date.AddDays(i * 7 + 1); endtime = toTime.Date.AddDays((i + 1) * 7); List prlist = alllist.Where(s => s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime).ToList(); List insetPrList = new List(); List updatePrList = new List(); long Nbr = help.NextId(); foreach (var pr in prlist) { bool bl = pr.sentry_id == null;//区分是销售订单和非销售订单的合并。 //找到是否生成了新的PR 当前数据是否已经产生合并,则不再合并。 var newPr = insetPrList.Find(s => s.pr_purchaseid == pr.pr_purchaseid && s.icitem_id == pr.icitem_id && s.IsRequireGoods == pr.IsRequireGoods && s.supplier_type == pr.supplier_type && (s.sentry_id == null) == bl); if (newPr == null) { //有多条才进行合并 var ilist = prlist.Where(s => s.pr_purchaseid == pr.pr_purchaseid && s.icitem_id == pr.icitem_id && s.IsRequireGoods == pr.IsRequireGoods && s.supplier_type == pr.supplier_type && (s.sentry_id == null) == bl).ToList(); //var ilist = prlist.Where(s => s.pr_purchaseid == pr.pr_purchaseid && s.icitem_id == pr.icitem_id).ToList(); var pur = purList.Find(x => x.icitem_id == pr.icitem_id && x.supplier_id == pr.pr_purchaseid); if (ilist.Count > 1) { var icitem = ic_Items.Find(s => s.Id == pr.icitem_id); var prRefoccupy = occupylist.Where(s => ilist.Select(c => c.Id).ToList().Contains(s.polist_id.GetValueOrDefault())).ToList(); newPr = help.DeepCopy(pr); newPr.GenerateNewId(help.NextId()); prRefoccupy.ForEach(a => { a.polist_id = newPr.Id; }); newPr.pr_billno = Nbr.ToString();//pr单号 newPr.state = pr.state; newPr.pr_rqty = ilist.Sum(s => s.pr_rqty);//需求数量 newPr.pr_aqty = ilist.Sum(s => s.pr_aqty);//申请数量 newPr.pr_sqty = ilist.Sum(s => s.pr_sqty);//建议数量 decimal qty = newPr.pr_rqty.GetValueOrDefault(); //if (pur != null && newPr.pr_type == 2 && pur.quota_rate.GetValueOrDefault() == 100)//委外的采购申请通过委外圆整逻辑处理 if (pur != null)//按卫亮要求所有的全部圆整 { //数量圆整 按最小包装量向上圆整 if (pur.packaging_qty.GetValueOrDefault() != 0) { decimal count = Math.Ceiling(qty / pur.packaging_qty.GetValueOrDefault()); qty = count * pur.packaging_qty.GetValueOrDefault(); } //判断最小起订量 qty = qty > pur.qty_min.GetValueOrDefault() ? qty : pur.qty_min.GetValueOrDefault(); newPr.pr_aqty = qty;//申请数量 newPr.pr_sqty = qty;//建议数量 } newPr.pr_ssend_date = ilist.Min(s => s.pr_ssend_date);//系统建议下单日期 newPr.pr_sarrive_date = ilist.Min(s => s.pr_sarrive_date);//系统建议到达日期(建议到货日期) /* newPr.pr_psend_date = ilist.Min(s => s.pr_psend_date);//计划下单日期 newPr.pr_parrive_date = ilist.Min(s => s.pr_parrive_date);//计划到达日期 newPr.pr_rarrive_date = ilist.Min(s => s.pr_rarrive_date);//需求到货日期*/ //newPr.pr_sysprice = newPr.pr_rqty * pr.pr_price * (1 + pr.pr_rate);//系统价格(含税) newPr.pr_orderprice = newPr.pr_aqty * pr.pr_sysprice;//订单价格(含税) ilist.ForEach(s => { s.refer_pr_billno = newPr.pr_billno; }); insetPrList.Add(newPr); ilist.ForEach(s => { s.state = 0; }); updatePrList.AddRange(ilist); Nbr++; } else { decimal qty = pr.pr_rqty.GetValueOrDefault(); if (pur != null)//按卫亮要求所有的全部圆整 { //数量圆整 按最小包装量向上圆整 if (pur.packaging_qty.GetValueOrDefault() != 0) { decimal count = Math.Ceiling(qty / pur.packaging_qty.GetValueOrDefault()); qty = count * pur.packaging_qty.GetValueOrDefault(); } //判断最小起订量 qty = qty > pur.qty_min.GetValueOrDefault() ? qty : pur.qty_min.GetValueOrDefault(); pr.pr_aqty = qty;//申请数量 pr.pr_sqty = qty;//建议数量 } } } } insetAllList.AddRange(insetPrList); updateAllList.AddRange(updatePrList); } if (insetAllList.Any()) { var nbrlistDto = _serialNumberAppService.GetBillNo(insetAllList[0].factory_id.ToString(), "PR", insetAllList.Count, "admin", 1); int index = 0; foreach (var p in insetAllList) { if (nbrlistDto[index] != null) { updateAllList.Where(x => x.refer_pr_billno == p.pr_billno).ToList().ForEach(c => { c.refer_pr_billno = nbrlistDto[index].NbrResult.ToString(); }); p.pr_billno = nbrlistDto[index].NbrResult.ToString(); } index++; if (p.pr_purchaseid.GetValueOrDefault() == 0) { //数据丢失 var list = _mysql_srm_purchase.GetListAsync(s => s.icitem_id == p.icitem_id).Result; if (list.Any()) { var purchase = list.OrderBy(s => s.quota_priority).FirstOrDefault(); p.pr_purchaseid = purchase.supplier_id; p.pr_purchasename = purchase.supplier_name; p.pr_purchasenumber = purchase.supplier_number; } } } } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { if (insetAllList.Any()) { _businessDbContext.BulkInsert(insetAllList); } if (updateAllList.Any()) { _businessDbContext.BulkUpdate(updateAllList); } if (occupylist.Any()) { _businessDbContext.BulkUpdate(occupylist); } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("PrAutoMerge", "采购申请单自动合并更新失败:" + e.Message, _currentTenant.Id.ToString()); }; } //暂时固定传8010后面有时间再改 await CreateDemandSchedule(domain); return "ok"; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("PrAutoMerge", "PR自动合并:" + e.Message, _currentTenant.Id.ToString()); return "PR自动合并失败,请联系管理员。"; } } /// /// 采购申请推送SAP /// /// public async Task PrSendSAP(string domain) { DateTime toTime = DateTime.Now.Date; int dayOfWeek = (int)toTime.DayOfWeek; // 获取今天是星期几(0-6) switch (dayOfWeek) { case 0: toTime = toTime.AddDays(-7); break; default: toTime = toTime.AddDays(-dayOfWeek); break; } DateTime starttime = toTime.Date.AddDays(1); DateTime endtime = toTime.Date.AddDays(35); //取出采购申请数据 List prapplyList = _mysql_srm_pr_main.GetListAsync(s => s.factory_id.ToString() == domain && s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime && s.state == 1 && s.IsRequireGoods == 0 && string.IsNullOrEmpty(s.analogcalcversion) == true).Result; //List prapplyList = _mysql_srm_pr_main.GetListAsync(s => s.company_id.ToString() == companyid && s.pr_ssend_date <= starttime && s.state == 1 && s.IsRequireGoods == 0).Result; string seqSql = ""; if (prapplyList.Any()) { //请购单插入事务 var rstSeqId = _serialNumberAppService.GetSeqIdList(prapplyList[0].factory_id.ToString(), 1, 1); long seqId = 0; if (long.TryParse(rstSeqId, out seqId)) { prapplyList.ForEach(p => { p.state = 2; seqSql += "insert QadTracking(Ufld1,Domain,SeqID,TransType,Subject,[Order],Int1,CreateTime,CreateUser,UpdateTime,UpdateUser) values('C','" + p.factory_id.ToString() + "'," + seqId.ToString() + ",'nbr-pr-mes','请购单','" + p.pr_billno + "'," + p.Id.ToString() + ",getdate(),'',getdate(),'');"; seqId++; }); } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { if (!string.IsNullOrEmpty(seqSql)) { _businessBangDbContext.Database.ExecuteSqlRaw(seqSql); } await _businessDbContext.BulkUpdateAsync(prapplyList); await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("PrSendSAP", "写入采购单推送SAP事务失败:" + e.Message, _currentTenant.Id.ToString()); return "推送SAP失败,请联系管理员"; }; } return "ok"; } else { return "ok"; } } /// /// 解析按周频率送货方式 /// /// /// /// private List AnalysisIntervalData(string is_days, mo_srm_pr_main pr) { List prWeekDtos = new List(); //周期送货,需要对数据进行按周期区分 if (!string.IsNullOrEmpty(is_days)) { string[] days = JsonConvert.DeserializeObject(is_days); List weekInt = new List(); foreach (var d in days) { if (!string.IsNullOrEmpty(d)) { weekInt.Add(int.Parse(d)); } } weekInt.Sort(); //解析区间值 for (int idx = 0; idx < weekInt.Count; idx++) { PrWeekDto dto = new PrWeekDto(); dto.week = weekInt[idx]; dto.weekList = new List(); dto.icitem_id = pr.icitem_id.Value; dto.pr_purchaseid = pr.pr_purchaseid.Value; //判断如果还有送货日期,则需要设定区间范围包含本次和下次之前的周期 if (idx + 1 < weekInt.Count) { int end = weekInt[idx + 1]; for (int start = dto.week; start < end; start++) { dto.weekList.Add(start); } } else { //假设 就定了周一 int count = 7 - dto.week + weekInt[0]; for (int start = 0; start < count; start++) { if (dto.week + start > 7) { dto.weekList.Add(dto.week + start - 7); } else { dto.weekList.Add(dto.week + start); } } } prWeekDtos.Add(dto); } } return prWeekDtos; } /* int getDateWeekRang(DateTime tmpDate) { var startDateStr = tmpDate.Date.AddDays(-(int)(tmpDate.DayOfWeek) + 1).ToString("yyyy-MM-dd");//当前周的开始日期 var endDateStr = tmpDate.Date.AddDays(7 - (int)(tmpDate.DayOfWeek)).ToString("yyyy-MM-dd");//当前周的结束日期 GregorianCalendar gc = new System.Globalization.GregorianCalendar(); int weekOfYear = gc.GetWeekOfYear(tmpDate, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday); return weekOfYear; }*/ //PR自动审核 public async Task PrAutoApprove(string domain) { DateTime toTime = DateTime.Now.Date; int dayOfWeek = (int)toTime.DayOfWeek; // 获取今天是星期几(0-6) switch (dayOfWeek) { case 0: toTime = toTime.AddDays(-7); break; default: toTime = toTime.AddDays(-dayOfWeek); break; } DateTime starttime = toTime.Date.AddDays(1); DateTime endtime = toTime.Date.AddDays(35); List alllist = _mysql_srm_pr_main.GetListAsync(s => s.factory_id.ToString() == domain && s.IsRequireGoods == 1 && s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime && s.state == 1 && string.IsNullOrEmpty(s.analogcalcversion) == true).Result; if (alllist.Any()) { List purchaselist = _mysql_srm_purchase.GetListAsync(s => s.factory_id.ToString() == domain && alllist.Select(c => c.icitem_id).Contains(s.icitem_id) && alllist.Select(c => c.pr_purchaseid).Contains(s.supplier_id)).Result; List itemsupplierList = _mysql_srm_supplier.GetListAsync(s => s.factory_id.ToString() == domain && alllist.Select(c => c.pr_purchaseid).Contains(s.Id)).Result; List ic_Items = _mysql_ic_item.GetListAsync(s => s.factory_id.ToString() == domain && alllist.Select(c => c.icitem_id).Contains(s.Id)).Result; PoActionListDto poaction = new PoActionListDto(); param.company_id = alllist[0].company_id; param.factoryId = alllist[0].factory_id.GetValueOrDefault(); for (int i = 0; i < 5; i++) { starttime = toTime.Date.AddDays(i * 7 + 1); endtime = toTime.Date.AddDays((i + 1) * 7); List prlist = alllist.Where(s => s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime).ToList(); AutoCreatePOFromPR(prlist, ic_Items, itemsupplierList, purchaselist, poaction); } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { if (poaction.poMain.Any()) { _businessDbContext.BulkUpdate(alllist); _businessDbContext.BulkInsert(poaction.poMain); } if (poaction.polist.Any()) { _businessDbContext.BulkInsert(poaction.polist); } if (poaction.poOccupiesList.Any()) { _businessDbContext.BulkUpdate(poaction.poOccupiesList); } if (poaction.poMasterList.Any()) { poaction.poMasterList.ForEach(s => { s.ReqBy = "DO"; }); _purOrdMaster.Insert(poaction.poMasterList); //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值 List nbrs = poaction.poMasterList.Select(a => a.PurOrd).ToList(); var nbrList = _purOrdMaster.Select(a => a.Domain == poaction.poMasterList[0].Domain && nbrs.Contains(a.PurOrd)); poaction.poDetailList.ForEach(c => { var master = nbrList.Where(a => a.PurOrd == c.PurOrd).FirstOrDefault(); if (master != null) { c.PurOrdRecID = master.RecID; string location = "1001"; switch (master.USAGE) { case "标准": break; case "VMI": location = "VMI01"; break; case "研发": location = "1101"; break; case "ECR": location = "1003"; break; } c.Location = location; } }); _purOrdDetail.Insert(poaction.poDetailList); if (poaction.poDetailBatchList.Any()) { var detailNbrList = _purOrdDetail.Select(a => a.Domain == poaction.poMasterList[0].Domain && nbrs.Contains(a.PurOrd)); poaction.poDetailBatchList.ForEach(b => { var detail = detailNbrList.Where(d => d.PurOrd == b.PurOrd && d.Line == b.Line).FirstOrDefault(); if (detail != null) { b.PurOrdDetailRecID = detail.RecID; } }); _purOrdDetailBatch.Insert(poaction.poDetailBatchList); } } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("PrAutoApprove", "要货令转采购订单失败:" + e.Message, _currentTenant.Id.ToString()); return "要货令转采购订单失败,请联系管理员。"; } } return "ok"; } else { return "ok"; } } /// /// //PR手动审核 /// /// /// public async Task PrApprove(string ids) { var idList = AnalysisIdList(ids); List prlist = _mysql_srm_pr_main.GetListAsync(s => idList.Contains(s.Id)).Result; if (!prlist.Any()) { return JsonConvert.SerializeObject("所选要货令未找到,请刷新界面重新操作。"); } if (prlist.Where(s => s.state == 0).Count() > 0) { return JsonConvert.SerializeObject("所选包含已关闭要货令,请重新选择。"); } /*if (prlist.Where(s => s.state == 3).Count() > 0) { return JsonConvert.SerializeObject("所选包含评审未通过要货令,请重新选择。"); }*/ if (prlist.Where(s => s.IsRequireGoods == 0).Count() > 0) { return JsonConvert.SerializeObject("包含采购申请,不允许与要货令转采购订单。"); } if (prlist.Select(s => s.supplier_type).Count() > 1) { return JsonConvert.SerializeObject("供应类别不同,不允许一起转采购订单。"); } List purchaselist = _mysql_srm_purchase.GetListAsync(s => prlist.Select(c => c.icitem_id).Contains(s.icitem_id) && prlist.Select(c => c.pr_purchaseid).Contains(s.supplier_id)).Result; List itemsupplierList = _mysql_srm_supplier.GetListAsync(s => prlist.Select(c => c.pr_purchaseid).Contains(s.Id)).Result; var purclist = purchaselist.GroupBy(s => new { s.supplier_type, s.supplier_id }); if (purclist.Count() > 1) { return JsonConvert.SerializeObject("要货令的供应类别必须相同。"); } List ic_Items = _mysql_ic_item.GetListAsync(s => prlist.Select(c => c.icitem_id).Contains(s.Id)).Result; PoActionListDto poaction = new PoActionListDto(); param.company_id = prlist[0].company_id; param.factoryId = prlist[0].factory_id.GetValueOrDefault(); AutoCreatePOFromPR(prlist, ic_Items, itemsupplierList, purchaselist, poaction); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { if (poaction.poMain.Any()) { _businessDbContext.BulkUpdate(prlist); _businessDbContext.BulkInsert(poaction.poMain); } if (poaction.polist.Any()) { _businessDbContext.BulkInsert(poaction.polist); } if (poaction.poOccupiesList.Any()) { _businessDbContext.BulkUpdate(poaction.poOccupiesList); } if (poaction.poMasterList.Any()) { poaction.poMasterList.ForEach(s => { s.ReqBy = "DO"; }); _purOrdMaster.Insert(poaction.poMasterList); //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值 List nbrs = poaction.poMasterList.Select(a => a.PurOrd).ToList(); var nbrList = _purOrdMaster.Select(a => a.Domain == poaction.poMasterList[0].Domain && nbrs.Contains(a.PurOrd)); poaction.poDetailList.ForEach(c => { c.PurOrdRecID = nbrList.Where(a => a.PurOrd == c.PurOrd).First().RecID; }); _purOrdDetail.Insert(poaction.poDetailList); } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("PrApprove", "要货令转采购订单失败:" + e.Message, _currentTenant.Id.ToString()); return JsonConvert.SerializeObject("要货令转采购订单失败,请联系管理员。"); } } return JsonConvert.SerializeObject("ok"); } private List AnalysisIdList(string ids) { if (string.IsNullOrEmpty(ids)) { throw new NotImplementedException("传入参数不正确,请选择"); } Array alist = ids.Split(','); List idList = new List(); foreach (string longid in alist) { idList.Add(long.Parse(longid)); } return idList; } /// /// 资源检查结果评审 /// /// /// 类型(0,销售订单 1,销售订单行) public async Task ReviewExamineResult(string ids, int type) { if (string.IsNullOrEmpty(ids)) { throw new NotImplementedException("订单号错误,请联系管理员!"); } Array alist = ids.Split(','); List sorderId = new List(); foreach (string longid in alist) { sorderId.Add(long.Parse(longid)); } List sorders = new List(); List sentrys = new List(); if (type == 0) { //获取订单数据 sorders = _mysql_crm_seorder.GetListAsync(p => sorderId.Contains(p.Id) && !p.IsDeleted).Result; if (!sorders.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单数据不存在", _currentTenant.Id.ToString()); //throw new NotImplementedException("订单数据不存在!"); return "订单数据不存在"; } //获取订单行数据 sentrys = await _mysql_crm_seorderentry.GetListAsync(p => sorderId.Contains(p.seorder_id.GetValueOrDefault()) && !p.IsDeleted); if (!sentrys.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单行数据不存在", _currentTenant.Id.ToString()); //throw new NotImplementedException("订单行数据不存在!"); return "订单行数据不存在"; } } else { //获取订单行数据 sentrys = await _mysql_crm_seorderentry.GetListAsync(p => sorderId.Contains(p.Id) && !p.IsDeleted); if (!sentrys.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单行数据不存在", _currentTenant.Id.ToString()); //throw new NotImplementedException("订单行数据不存在!"); return "订单行数据不存在"; } sorders = _mysql_crm_seorder.GetListAsync(p => sentrys.Select(s => s.seorder_id).Contains(p.Id) && !p.IsDeleted).Result; if (!sorders.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单数据不存在", _currentTenant.Id.ToString()); //throw new NotImplementedException("订单数据不存在!"); return "订单数据不存在"; } } //获取订单行数据 progress == "2"已做检查但是未评审的订单行 sentrys = sentrys.Where(s => s.progress == "2").ToList(); if (!sentrys.Any()) { new NLogHelper("ResourceExamineAppService").WriteLog("ReceiveResult", "订单行数据不存在", _currentTenant.Id.ToString()); //throw new NotImplementedException("订单行数据不存在!"); return "没有需要评审的订单行数据"; } List seIds = sentrys.Select(s => s.Id).ToList(); //找到当前计算周期里工单 List moentry = _mes_moentry.GetListAsync(x => seIds.Contains(x.soentry_id.Value)).Result; List mordersList = _mes_morder.GetListAsync(x => moentry.Select(p => p.moentry_moid).ToList().Contains(x.mysql_id)).Result; List WriteMoentry = new List(); List WriteMorder = new List(); //找最新计算结果 List exmlist = _mysql_examine_result.GetListAsync(s => seIds.Contains(s.sentry_id.GetValueOrDefault())).Result; List exmResult = new List(); List bangidList = new List(); #region 回写工单 foreach (var se in sentrys) { var newExm = exmlist.Where(s => s.sentry_id == se.Id).OrderByDescending(p => p.create_time).FirstOrDefault(); if (newExm != null) { se.progress = "3"; se.rstate = 1; se.sys_material_date = newExm.sys_material_date; se.sys_capacity_date = newExm.sys_capacity_date; //如果计算记录有工单id,则代表有生成工单,而不是占用计划工单 if (newExm.morder_id.GetValueOrDefault() != 0) { var meList = moentry.Where(s => s.soentry_id == se.Id && s.bang_id == newExm.bangid).ToList(); if (!meList.Any()) { //补救场景,假设mongdb数据丢失,从一个json格式中获取数据//此处暂不考虑 } var molist = mordersList.Where(s => meList.Select(c => c.moentry_moid).Contains(s.mysql_id) && s.bang_id == newExm.bangid).ToList(); if (!molist.Any()) { //补救场景,假设mongdb数据丢失,从一个json格式中获取数据//此处暂不考虑 } WriteMoentry.AddRange(meList); WriteMorder.AddRange(molist); } exmResult.Add(newExm); bangidList.Add(newExm.bangid.GetValueOrDefault()); } } //如果已经回写,则不需要回写 List dborders = _mysql_mes_morder.GetListAsync(x => WriteMorder.Select(c => c.mysql_id).Contains(x.Id)).Result; //过滤掉已经回写的数据 WriteMorder = WriteMorder.Where(x => !dborders.Select(c => c.Id).Contains(x.mysql_id)).ToList(); #endregion //批量保存 后期考虑子工单 List moderlist = new List(); List workOrds = new List(); List workOrdRoutings = new List(); List workOrdDetails = new List(); if (WriteMorder.Any()) { WriteMorder.ForEach(s => { s.create_time = DateTime.Now; }); moderlist = ObjectMapper.Map, List>(WriteMorder); List allRoutings = _routingOpDetail.Select(p => moderlist.Select(m => m.product_code).Contains(p.RoutingCode)); List childExamineList = _mysql_bom_child_examine.GetListAsync(c => exmResult.Select(x => x.Id).Contains(c.examine_id.GetValueOrDefault())).Result; param.factoryId = WriteMorder[0].factory_id.GetValueOrDefault(); //同步工单 CreateWorkOrdDates(moderlist, WriteMoentry, allRoutings, workOrds, workOrdRoutings, workOrdDetails, exmResult, childExamineList); } //当前订单号所关联的最新计算结果里的占用记录 List mooccupyList = await _mes_mooccupy.GetListAsync(s => seIds.Contains(s.moo_id_billid.Value) && bangidList.Contains(s.bang_id.Value)); //委外工单计算记录 List oorderList = await _mes_oorder.GetListAsync(s => seIds.Contains(s.sentry_id.Value) && bangidList.Contains(s.bang_id.Value)); //PO占用记录 List po_occupy = await _srm_po_occupy.GetListAsync(s => seIds.Contains(s.eid.Value) && bangidList.Contains(s.bang_id.Value)); List prmainlist = await _srm_pr_main.GetListAsync(s => seIds.Contains(s.sentry_id.Value) && bangidList.Contains(s.bang_id.Value)); if (prmainlist.Any()) { var nbrlistDto = _serialNumberAppService.GetBillNo(prmainlist[0].factory_id.ToString(), "PR", prmainlist.Count, "admin", 1); int index = 0; foreach (var p in prmainlist) { if (nbrlistDto[index] != null) { p.pr_billno = nbrlistDto[index].NbrResult.ToString(); } index++; if (p.pr_purchaseid.GetValueOrDefault() == 0) { //数据丢失 var list = _mysql_srm_purchase.GetListAsync(s => s.icitem_id == p.icitem_id).Result; if (list.Any()) { p.pr_purchaseid = list[0].supplier_id; p.pr_purchasename = list[0].supplier_name; p.pr_purchasenumber = list[0].supplier_number; } } } } List item_stockoccupy = await _ic_item_stockoccupy.GetListAsync(s => seIds.Contains(s.orderentry_id.Value) && bangidList.Contains(s.bang_id)); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { await _businessDbContext.BulkUpdateAsync(sentrys); //批量保存 后期考虑子工单 if (moderlist.Any()) { _businessDbContext.BulkInsert(moderlist); if (workOrds.Any()) { _workOrdMaster.Insert(workOrds); } var DBworkOrdList = _workOrdMaster.Select(a => workOrds.Count > 0 && a.Domain == workOrds[0].Domain && workOrds.Select(c => c.WorkOrd).Contains(a.WorkOrd)); if (workOrdRoutings.Any()) { workOrdRoutings.ForEach(c => { c.WorkOrdMasterRecID = DBworkOrdList.Where(a => a.WorkOrd == c.WorkOrd).First().RecID; }); _workOrdRouting.Insert(workOrdRoutings); } if (workOrdDetails.Any()) { workOrdDetails.ForEach(c => { c.WorkOrdMasterRecID = DBworkOrdList.Where(a => a.WorkOrd == c.WorkOrd).First().RecID; }); _workOrdDetail.Insert(workOrdDetails); } if (WriteMoentry.Any()) { var mesmoentrys = ObjectMapper.Map, List>(WriteMoentry); _businessDbContext.BulkInsert(mesmoentrys); } } if (mooccupyList.Any()) { mooccupyList.ForEach(s => { s.create_time = DateTime.Now; }); var moOccupy = ObjectMapper.Map, List>(mooccupyList); _businessDbContext.BulkInsert(moOccupy); } if (oorderList.Any()) { oorderList.ForEach(s => { s.create_time = DateTime.Now; }); var ooders = ObjectMapper.Map, List>(oorderList); _businessDbContext.BulkInsert(ooders); } if (item_stockoccupy.Any()) { var sklist = ObjectMapper.Map, List>(item_stockoccupy); sklist.ForEach(s => { s.create_time = DateTime.Now; s.GenerateNewId(help.NextId()); }); _businessDbContext.BulkInsert(sklist); } if (po_occupy.Any()) { po_occupy.ForEach(s => { s.mysql_id = help.NextId(); s.create_time = DateTime.Now; }); var poOccupies = ObjectMapper.Map, List>(po_occupy); _businessDbContext.BulkInsert(poOccupies); } if (prmainlist.Any()) { var pr_mainlist = ObjectMapper.Map, List>(prmainlist); _businessDbContext.BulkInsert(pr_mainlist); } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("ReviewExamineResult", "资源检查评审数据更新失败:" + e.Message, _currentTenant.Id.ToString()); return e.Message; }; } return "ok"; } ///// ///// 通过ic_bom获取工艺路径数据 ///// ///// ///// //public List GetMesTechniques(List ic_Boms) //{ // List techniques = new List(); // var builder = Builders.Filter; // var filters = new List>(); // ic_Boms?.ForEach(item => // { // var filter = builder.Eq(x => x.bom, item.bom_number) // & builder.Eq(x => x.bomver, item.version) // & builder.Eq(x => x.tenant_id, param.tenantId) // & builder.Eq(x => x.factory_id, param.factoryId) // & builder.Eq(x => x.IsDeleted, false); // filters.Add(filter); // }); // techniques = _mes_technique.Find(builder.Or(filters)).Result; // return techniques; //} /// /// 递归:获取icbom,icbomchild数据 /// /// /// /// public void GetIcBomData(List icBoms, List bomlist, List bomchildlist, bool flag) { if (icBoms.Count == 0) { return; } //添加物料bom数据 foreach (var ib in icBoms) { if (!bomlist.Exists(s => s.mysql_id == ib.mysql_id)) { bomlist.Add(ib); } } List icBomIds = icBoms.Select(m => m.mysql_id).ToList(); int page = 1; page = (int)Math.Ceiling(icBomIds.Count() / (decimal)1500); List childList = new List(); for (int i = 0; i < page; i++) { var pageBomsIds = icBomIds.Skip(i * 1500).Take(1500).ToList(); childList.AddRange(_ic_bom_child.GetListAsync(p => pageBomsIds.Contains(p.bom_id) && p.company_id == param.company_id && !p.IsDeleted).Result); } //没有明细数据,终止 if (childList.Count == 0) { return; } foreach (var bchild in childList) { if (!bomchildlist.Exists(s => s.mysql_id == bchild.mysql_id)) { bomchildlist.Add(bchild); } } if (flag) { return; } page = 1; page = (int)Math.Ceiling(childList.Count() / (decimal)1500); List boms = new List(); for (int i = 0; i < page; i++) { var pageChild = childList.Skip(i * 1500).Take(1500).ToList(); boms.AddRange(_ic_bom.GetListAsync(p => pageChild.Select(m => m.icitem_id).ToList().Contains(p.icitem_id) && p.use_status == 1 && p.company_id == param.company_id && !p.IsDeleted).Result); } //通过物料bom明细数据反查物料bom数据 // = _ic_bom.GetListAsync(p => childList.Select(m => m.icitem_id).ToList().Contains(p.icitem_id) && p.use_status == 1 && p.company_id == param.company_id && !p.IsDeleted).Result; foreach (var chd in childList) { var curBoms = boms.Where(p => p.icitem_id == chd.icitem_id).ToList(); GetIcBomData(curBoms, bomlist, bomchildlist, flag); } } /// /// 删除旧订单行数据 /// /// /// /// /// public async Task DeleteMySqlOldData(List soentry_id) { List sentryids = soentry_id.Select(p => p.Id).ToList(); //删除工单相关表数据 /*var mes_moentry = _mysql_mes_moentry.GetListAsync(x => sentryids.Contains(x.soentry_id.Value)).Result; var mes_morder = _mysql_mes_morder.GetListAsync(x => mes_moentry.Select(p => p.moentry_moid).ToList().Contains(x.Id)).Result; if (mes_moentry.Count > 0) { await _mysql_mes_moentry.DeleteManyAsync(mes_moentry); } if (mes_morder.Count > 0) { await _mysql_mes_morder.DeleteManyAsync(mes_morder); }*/ var mysql_mes_mooccupy = _mysql_mes_mooccupy.GetListAsync(x => soentry_id.Select(p => p.Id).Contains(x.moo_id_billid.Value)).Result; if (mysql_mes_mooccupy.Count > 0) { await _businessDbContext.BulkDeleteAsync(mysql_mes_mooccupy); } /*var srm_pr_main = _mysql_srm_pr_main.GetListAsync(x => soentry_id.Select(p => p.Id).Contains(x.sentry_id.GetValueOrDefault())).Result; if (srm_pr_main.Count > 0) { await _mysql_srm_pr_main.DeleteManyAsync(srm_pr_main); }*/ /*var mes_oorders = _mysql_mes_oorder.GetListAsync(x => soentry_id.Select(p => p.Id).Contains(x.sentry_id.GetValueOrDefault())).Result; if (mes_oorders.Count > 0) { await _mysql_mes_oorder.DeleteManyAsync(mes_oorders); }*/ } /// /// 数据库快照 /// /// public async Task DbSnapShot(long? companyId, long factoryId, long bangid, List pretreatments) { //TODO:申老师明确后续需要调整 根据需要使用的字段,来同步表数据。 //同步物料库存数据 根据预处理,来只找出部分数据同步。 List itemIds = pretreatments.Select(s => s.item_id.GetValueOrDefault()).Distinct().ToList(); //var icitemStokc = _mysql_ic_item_stock.GetListAsync(p => p.tenant_id == tenantId && p.factory_id == factoryId).Result; var icitemStokc = _mysql_ic_item_stock.GetListAsync(p => p.company_id == companyId && itemIds.Contains(p.icitem_id)).Result; if (icitemStokc.Count > 0) { List numbers = pretreatments.Select(s => s.item_number).Distinct().ToList(); var locationRange = _configurationItem.Select(x => x.FldName == "MRPLocationRange" && x.Domain == factoryId.ToString()).FirstOrDefault(); List locationList = new List { "1000", "1001", "5008", "8000", "8001" }; if (locationRange != null && locationRange.Val != null) { locationList = locationRange.Val.SplitToArray(",").ToList(); } if (!param.checkPlan) { if (locationList.Contains("1000")) { locationList.Remove("1000"); } } 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" || locationList.Contains(a.LGORT))); //var sapInvList = _SAPInv.Select(a => a.WERKS == factoryId.ToString() && numbers.Contains(a.MATNR) && locationList.Contains(a.LGORT)); //设置当前计算bangid icitemStokc.ForEach(item => { item.bang_id = bangid; item.sqty = 0; foreach (var lct in locationList) { var lctQty = locStock.Where(s => s.ItemNum == item.icitem_number && s.Location == lct).Sum(p => p.AvailStatusQty.GetValueOrDefault() + p.Assay.GetValueOrDefault()); //if (lctQty == 0) //{ // lctQty = sapInvList.Where(x => x.MATNR == item.icitem_number && x.LGORT == lct).Sum(p => p.LABST + p.INSME); //} item.sqty += lctQty; } /*if (param.checkPlan) { item.sqty += sapInvList.Where(x => x.MATNR == item.icitem_number && x.SOBKZ.ToUpper() == "O").Sum(p => p.LABST + p.INSME); }*/ }); var moIcitemStokc = ObjectMapper.Map, List>(icitemStokc); moIcitemStokc.ForEach(item => { item.GenerateNewId(help.NextId()); item.create_time = DateTime.Now; }); //插入数据 await MongoHelper.InsertManyAsync(moIcitemStokc); } var workordmsters = _workOrdMaster.Select(s => s.Domain == factoryId.ToString() && string.IsNullOrEmpty(s.Status) != true && s.Status.ToLower() != "c" && string.IsNullOrEmpty(s.AnalogCalcVersion)); if (workordmsters.Any()) { //根据工单表找到工单明细,然后根据DOP工单占用记录,对比工单明细发货数量,来做冲销。 //var workdetails = _workOrdDetail.Select(s => workordmsters.Select(c => c.WorkOrd).Contains(s.WorkOrd)); List item_occupy = new List(); /*if (!param.checkPlan) { //在库检,只计算下达工单的占用。 var pwork = workordmsters.Where(x => x.Status.ToLower() == "r").ToList(); item_occupy = _mysql_ic_item_stockoccupy.GetListAsync(p => p.company_id == companyId && itemIds.Contains(p.icitem_id) && pwork.Select(c => c.WorkOrd).Contains(p.morder_mo)).Result; } else { //物料库存占用记录表 item_occupy = _mysql_ic_item_stockoccupy.GetListAsync(p => p.company_id == companyId && itemIds.Contains(p.icitem_id) && workordmsters.Select(c => c.WorkOrd).Contains(p.morder_mo)).Result; }*/ //不论计划还是在库检,都是按全量跑工单,所以每次计算已占用库存,只算下达工单的占用。 var pwork = workordmsters.Where(x => x.Status.ToLower() == "r").ToList(); item_occupy = _mysql_ic_item_stockoccupy.GetListAsync(p => p.company_id == companyId && itemIds.Contains(p.icitem_id) && pwork.Select(c => c.WorkOrd).Contains(p.morder_mo)).Result; var nbrList = _nbrMaster.Select(x => pwork.Select(c => c.WorkOrd).Contains(x.WorkOrd) && x.Status.ToUpper() != "C").ToList(); if (nbrList.Any()) { var nbrDtlList = _nbrDetail.Select(x => nbrList.Select(c => c.RecID).Contains(x.NbrRecID) && x.Status.ToUpper() != "C").ToList(); if (nbrDtlList.Any()) { if (item_occupy.Any()) { item_occupy.ForEach(s => { //TODO:对发布数量和占用数量进行对冲,因为目前没有处理不同层级下使用相同物料的占用的问题。dop占用有项次号,而wms的发布数量明细没有项次号 var wdtl = nbrDtlList.Find(x => x.WorkOrd == s.morder_mo && x.ItemNum == s.icitem_number); if (wdtl != null) { s.quantity = wdtl.QtyOrd - wdtl.QtyRec; s.quantity = s.quantity < 0 ? 0 : s.quantity; } }); item_occupy = item_occupy.Where(s => s.quantity > 0).ToList(); if (item_occupy.Count > 0) { var mo_item_occupy = ObjectMapper.Map, List>(item_occupy); mo_item_occupy.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(mo_item_occupy); } } } } //工单主表 var mes_morder = _mysql_mes_morder.GetListAsync(x => string.IsNullOrEmpty(x.morder_state) == false && x.morder_state != "完成" && x.company_id == companyId && x.factory_id == factoryId && string.IsNullOrEmpty(x.analogcalcversion) == true && workordmsters.Select(c => c.WorkOrd).Contains(x.morder_no)).Result; if (mes_morder.Count > 0) { mes_morder.ForEach(item => { item.bang_id = bangid; }); var moMes_morder = ObjectMapper.Map, List>(mes_morder); moMes_morder.ForEach(item => { item.GenerateNewId(help.NextId()); }); await MongoHelper.InsertManyAsync(moMes_morder); } //工单子表 var mes_moentry = _mysql_mes_moentry.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId).Result; if (mes_moentry.Count > 0) { mes_moentry.ForEach(item => { item.bang_id = bangid; }); var moMes_moentry = ObjectMapper.Map, List>(mes_moentry); moMes_moentry.ForEach(item => { item.GenerateNewId(help.NextId()); item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moMes_moentry); } //在制工单占用记录表 var mes_mooccupy = _mysql_mes_mooccupy.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && mes_morder.Select(c => c.morder_no).Contains(x.moo_mo)).Result; if (mes_mooccupy.Count > 0) { var moMes_mooccupy = ObjectMapper.Map, List>(mes_mooccupy); moMes_mooccupy.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moMes_mooccupy); } } //根据物料信息,只同步在途未关闭的采购订单和采购申请 //采购订单明细 var srm_po_list = _mysql_srm_po_list.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && itemIds.Contains(x.icitem_id.GetValueOrDefault())).Result; if (srm_po_list.Count > 0) { //采购订单--取出状态为在途的PO var srm_po_main = _mysql_srm_po_main.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && srm_po_list.Select(c => c.po_id).Contains(x.Id) && x.state != 3).Result; if (srm_po_main.Count > 0) { var moSrm_po_main = ObjectMapper.Map, List>(srm_po_main); moSrm_po_main.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moSrm_po_main); //订单明细--根据在途PO过滤出有效的Po_list srm_po_list = srm_po_list.Where(s => srm_po_main.Select(x => x.Id).Contains(s.po_id.GetValueOrDefault())).ToList(); var moSrm_po_list = ObjectMapper.Map, List>(srm_po_list); moSrm_po_list.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moSrm_po_list); } //采购订单明细占用详情 var srm_po_occupy = _mysql_srm_po_occupy.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && srm_po_list.Select(c => c.Id).Contains(x.polist_id.GetValueOrDefault())).Result; if (srm_po_occupy.Count > 0) { var moSrm_po_occupy = ObjectMapper.Map, List>(srm_po_occupy); moSrm_po_occupy.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moSrm_po_occupy); } } //pr var srm_pr_main = _mysql_srm_pr_main.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && x.state != 0 && string.IsNullOrEmpty(x.analogcalcversion) == true && itemIds.Contains(x.icitem_id.GetValueOrDefault())).Result; if (srm_pr_main.Count > 0) { var moSrm_pr_main = ObjectMapper.Map, List>(srm_pr_main); moSrm_pr_main.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moSrm_pr_main); var occupyListLINQ = _businessDbContext.srm_po_occupy.Where(x => x.company_id == companyId && x.factory_id == factoryId && !x.IsDeleted).Join(_businessDbContext.srm_pr_main.Where(x => x.company_id == companyId && x.factory_id == factoryId && x.state != 0 && itemIds.Contains(x.icitem_id.GetValueOrDefault())), p => p.polist_id, pr => pr.Id, (p, pr) => new { p, pr }).ToList(); List occupylist = new List(); for (int i = 0; i < occupyListLINQ.Count; i++) { occupylist.Add(occupyListLINQ[i].p); } //采购申请占用详情 //var srm_pr_occupy = _mysql_srm_po_occupy.GetListAsync(x => x.company_id == companyId && x.factory_id == factoryId && srm_pr_main.Select(c => c.Id).Contains(x.polist_id.GetValueOrDefault())).Result; if (occupylist.Count > 0) { var moSrm_pr_occupy = ObjectMapper.Map, List>(occupylist); moSrm_pr_occupy.ForEach(item => { item.GenerateNewId(help.NextId()); item.bang_id = bangid; item.create_time = DateTime.Now; }); await MongoHelper.InsertManyAsync(moSrm_pr_occupy); } } var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "ScheduleAgreement" && s.Domain == factoryId.ToString()).ToList(); int ScheduleAgreement = 0;//计划协议 if (sysSet.Any()) { if (!string.IsNullOrEmpty(sysSet[0].Ufld1)) { int.TryParse(sysSet[0].Ufld1, out ScheduleAgreement); } } _CalcBomViewAppService.ScheduleAgreement = ScheduleAgreement == 1; } /// /// 清处数据库快照 /// /// public async Task ClearSnapShot(long bangid) { //清除物料库存数据 await _ic_item_stock.DeleteAsync(p => p.bang_id == bangid); //清除工单占用记录表 //await _mes_mooccupy.DeleteAsync(p => p.bang_id == bangid); //清除工单主表 //await _mes_morder.Delete(p => p.bang_id == bangid); //清除工单子表 //await _mes_moentry.Delete(p => p.bang_id == bangid); //清除采购订单 await _srm_po_main.DeleteAsync(p => p.bang_id == bangid); //清除采购订单明细 await _srm_po_list.DeleteAsync(p => p.bang_id == bangid); //清除采购订单占用详情 //await _srm_po_occupy.DeleteAsync(p => p.bang_id == bangid); //清除PR //await _srm_pr_main.DeleteAsync(p => p.bang_id == bangid); } /// /// 根据物料id获取物料4个提前期 /// /// 物料id /// 企业id /// 工厂id /// private List GetLeadTime(List icItemIds, long? companyId, long factoryid) { return icItemIds.Where(p => p.factory_id == factoryid && p.company_id == companyId && !p.IsDeleted). Select(x => new ICItemLeadTimeDto { item_id = x.mysql_id, transportation_leadtime = x.transportation_leadtime, stock_leadtime = x.stock_leadtime, production_leadtime = x.production_leadtime, order_leadtime = x.order_leadtime, minorderqty = x.minorderqty, put_integer = x.put_integer, minpackqty = x.minpackqty, ordissu_days = x.ordissu_days }).AsQueryable().ToList(); } //根据物料id获取物料供应商 private List GetSupplier(List icItemIds, long? companyId, long factoryid) { return _srm_purchase.GetListAsync(p => icItemIds.Contains(p.icitem_id) && p.company_id == companyId && p.factory_id == factoryid && !p.IsDeleted).Result; } /// /// 同一周以周五为合并采购申请单截点判断是否为同一周 /// /// 基准订单时间 /// 目标订单时间 /// private bool IsSameWeek(DateTime orderTime1, DateTime orderTime2) { int week = (int)orderTime1.DayOfWeek; bool isSameWeek = false; DateTime dateTime = orderTime1; switch (week) { case 0: //星期天 dateTime = dateTime.AddDays(0); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; case 1: //星期一 dateTime = dateTime.AddDays(4); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; case 2: //星期二 dateTime = dateTime.AddDays(3); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; case 3: //星期三 dateTime = dateTime.AddDays(2); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; case 4: //星期四 dateTime = dateTime.AddDays(1); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; case 5: //星期五 dateTime = dateTime.AddDays(0); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; case 6: //星期六 dateTime = dateTime.AddDays(0); dateTime = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); isSameWeek = orderTime2 < dateTime; break; } return isSameWeek; } private void AutoCreatePOFromPR(List list, List icitemlist, List itemsupplierList, List purchaselist, PoActionListDto poaction) { var zcPr = list.Where(a => a.pr_billno.StartsWith("PR") && a.supplier_type != "委外").ToList(); //var zcPr = list.Where(a => a.pr_billno.StartsWith("PR")).ToList(); if (zcPr.Any()) { AutoCreatePOFromPRByType(zcPr, icitemlist, itemsupplierList, purchaselist, poaction, 1); } var wwPr = list.Where(a => a.pr_billno.StartsWith("PR") && a.supplier_type == "委外").ToList(); if (wwPr.Any()) { AutoCreatePOFromPRByType(wwPr, icitemlist, itemsupplierList, purchaselist, poaction, 2); } } /// /// 根据PR生成PO /// /// /// /// /// /// /// 1正常PO,2是委外 private void AutoCreatePOFromPRByType(List list, List itemList, List itemsupplierList, List purchaselist, PoActionListDto poaction, int poType) { List polist = new List(); List podetaillist = new List(); List pooccupylist = new List(); List pOGroupDtos = new List(); var occupyList = _mysql_srm_po_occupy.GetListAsync(s => list.Select(c => c.Id).Contains(s.polist_id.GetValueOrDefault()) && s.company_id == list[0].company_id && s.factory_id == list[0].factory_id && s.IsDeleted == false).Result; string domain = list[0].factory_id.ToString(); //合并条件:目前传入的数据是一周的数据,暂时不考虑多周数据合并。 //标准类 1.销售订单产生 2.计划工单产生 //物料属性 委外 外购 //供应商类别 标准类 外协类 VMI类 费用类 资产类 //此逻辑已经在PR按周合并了。这一块直接转PO_list,然后根据此类型,再生成PO foreach (var item in list) { var pur = purchaselist.Find(s => s.supplier_id == item.pr_purchaseid && s.icitem_id == item.icitem_id); if (pur == null) { //无货源清单的PR不处理 continue; } POGroupDto poDto = pOGroupDtos.Find(s => s.supplier_type == pur.supplier_type && s.supplier_id == item.pr_purchaseid); if (poDto == null) { poDto = new POGroupDto(); poDto.supplier_id = item.pr_purchaseid.GetValueOrDefault(); poDto.supplier_type = pur.supplier_type; poDto.polist = new List(); pOGroupDtos.Add(poDto); } item.state = 4; srm_po_list podetail = new srm_po_list(); podetail.GenerateNewId(help.NextId()); podetail.pr_id = item.Id; podetail.pr_billno = item.pr_billno; var icitem = itemList.First(a => a.Id == item.icitem_id); if (icitem == null) { continue; } podetail.icitem_id = item.icitem_id; podetail.model = icitem.model; podetail.ItemNum = icitem.number; podetail.icitem_name = icitem.name; podetail.qty = item.pr_aqty; podetail.netprice = item.pr_price; podetail.netmoney = item.pr_aqty.GetValueOrDefault() * item.pr_price.GetValueOrDefault(); podetail.rate = item.pr_rate; podetail.price = item.pr_sysprice; podetail.total_price = item.pr_orderprice; podetail.taxamount = item.pr_orderprice.GetValueOrDefault() - podetail.netmoney; podetail.plan_qty = item.pr_aqty; podetail.unit = item.pr_unit; podetail.state = 1; podetail.rarrdate = item.pr_sarrive_date; podetail.rnumber = 0; podetail.currencytype = item.currencytype; podetail.create_time = DateTime.Now; podetail.update_time = DateTime.Now; podetail.factory_id = param.factoryId; podetail.company_id = param.company_id; podetail.stock_id = 1; var refProccupy = occupyList.Where(s => s.polist_id == item.Id).ToList(); refProccupy.ForEach(f => { f.polist_id = podetail.Id; }); poaction.poOccupiesList.AddRange(refProccupy); podetaillist.Add(podetail); poDto.polist.Add(podetail); } /*List referlist = new List(); RecursionGetDbPr(list, referlist);*/ //组合PO foreach (var dto in pOGroupDtos) { srm_po_main po_Main = new srm_po_main(); po_Main.GenerateNewId(help.NextId()); po_Main.po_billno = help.NextId().ToString(); var pr = list.Find(s => s.Id == dto.polist[0].pr_id); var itemsupplier = itemsupplierList.Find(a => a.Id == pr.pr_purchaseid); po_Main.po_purchaser = pr.pr_purchaser; po_Main.po_purchaser_no = pr.pr_purchaser_num; po_Main.po_ssend_date = list.Min(x => x.pr_ssend_date); po_Main.po_tax_rate = pr.pr_rate; po_Main.po_express = 1; po_Main.state = 0; po_Main.po_note = ""; po_Main.po_order_type = 1; po_Main.po_total = 0; po_Main.supplier_type = dto.supplier_type; po_Main.currency = pr.currencytype; po_Main.bill_type = poType; po_Main.supplier_id = pr.pr_purchaseid; po_Main.supplier_name = pr.pr_purchasename; po_Main.supplier_no = pr.pr_purchasenumber; po_Main.contact = itemsupplier is null ? "" : itemsupplier.contact; po_Main.suppliertelephone = itemsupplier is null ? "" : itemsupplier.telephone; po_Main.deliveryaddress = ""; po_Main.supplierdddress = itemsupplier is null ? "" : itemsupplier.supplier_address; po_Main.confirmstate = 1; po_Main.logisticsstate = 0; po_Main.financialstate = 0; po_Main.create_time = DateTime.Now; po_Main.update_time = DateTime.Now; po_Main.factory_id = param.factoryId; po_Main.company_id = param.company_id; po_Main.po_delivery = 1; polist.Add(po_Main); int row = 1; dto.polist.ForEach(p => { var toPr = list.Find(s => s.Id == p.pr_id); List clist = new List(); /*RecursionPr(toPr, referlist, clist); if (clist.Any()) { clist.ForEach(c => { if (!string.IsNullOrEmpty(c.pr_mono)) { srm_po_occupy srm_Po_Occupy = new srm_po_occupy(); srm_Po_Occupy.GenerateNewId(help.NextId()); //srm_Po_Occupy.bang_id = bangid; srm_Po_Occupy.morder_mo = c.pr_mono; srm_Po_Occupy.qty = c.pr_rqty; srm_Po_Occupy.eid = c.sentry_id; srm_Po_Occupy.polist_id = p.Id; srm_Po_Occupy.polist_row = p.polist_row; srm_Po_Occupy.type = MorderEnum.Zyjc_Type;//TODO:类型未知 srm_Po_Occupy.stime = p.create_time; srm_Po_Occupy.etime = p.rarrdate; srm_Po_Occupy.state = 1; srm_Po_Occupy.company_id = param.company_id;//取销售子表企业ID srm_Po_Occupy.factory_id = param.factoryId; srm_Po_Occupy.create_time = DateTime.Now; srm_Po_Occupy.create_by_name = "admin"; srm_Po_Occupy.update_time = DateTime.Now; srm_Po_Occupy.update_by_name = "admin"; poaction.poOccupiesList.Add(srm_Po_Occupy); } }); }*/ po_Main.po_total += p.total_price; p.po_id = po_Main.Id; p.po_billno = po_Main.po_billno; p.polist_row = row; p.pr_purchase_id = po_Main.supplier_id; p.pr_purchase_name = po_Main.supplier_name; row++; }); } poaction.poMain.AddRange(polist); poaction.polist.AddRange(podetaillist); var nbrlistDto = _serialNumberAppService.GetBillNo(domain, "DO", polist.Count, "admin", 1); int index = 0; foreach (var p in polist) { if (nbrlistDto[index] != null) { var podtls = podetaillist.Where(s => s.po_billno == p.po_billno).ToList(); p.po_billno = nbrlistDto[index].NbrResult.ToString(); podtls.ForEach(s => { s.po_billno = p.po_billno; }); } index++; } List purOrdMasters = new List(); var itemMasterList = _itemMaster.Select(s => itemList.Select(x => x.number).Contains(s.ItemNum)).ToList(); polist.ForEach(a => { string buyer = "110"; switch (a.supplier_type) { case "标准": case "VMI": case "委外": break; case "研发": buyer = "130"; break; case "ECR": buyer = "170"; break; } purOrdMasters.Add(new PurOrdMaster { Domain = domain, Potype = poType == 1 ? "po" : "PW", PurOrd = a.po_billno, Buyer = buyer, OrdDate = a.po_ssend_date, Curr = "CNY", Supp = a.supplier_no, Tax1 = a.po_tax_rate.GetValueOrDefault(), Department = a.purchasing_orgname, CustPhone = a.suppliertelephone, CustAddress = a.supplierdddress, USAGE = poType == 1 ? a.supplier_type : "委外加工", //a.supplier_type, IsActive = true, CreateTime = a.create_time, UpdateTime = a.update_time, FSTID = a.supplier_type == "VMI" ? "3" : "", Typed = poType == 1 ? "" : "s", Status = "" }); }); poaction.poMasterList.AddRange(purOrdMasters); List purOrdDetails = new List(); podetaillist.ForEach(a => { var refItem = itemMasterList.Find(x => x.ItemNum == a.ItemNum); short line = 1; short.TryParse(a.polist_row.GetValueOrDefault().ToString(), out line); purOrdDetails.Add(new PurOrdDetail { Domain = domain, Potype = poType == 1 ? "po" : "PW", PurOrd = a.po_billno, IsActive = true, CreateTime = a.create_time, UpdateTime = a.update_time, Line = line, Location = refItem?.Location, UM = refItem?.UM, ItemNum = a.ItemNum, QtyOrded = a.qty.GetValueOrDefault(), RctQty = a.rqty.GetValueOrDefault(), PurCost = a.price.GetValueOrDefault(), StdCost = a.price.GetValueOrDefault() / (1 + a.rate.GetValueOrDefault()), TaxRate = a.rate.GetValueOrDefault(), DueDate = a.rarrdate, Rev = refItem?.Rev, Req = a.pr_billno, ReqLine = 1, Typed = poType == 1 ? "" : "s", Project = poType == 1 ? "" : "3", Drawing = refItem?.Drawing, Status = "" }); }); poaction.poDetailList.AddRange(purOrdDetails); if (poType == 2) { var purOrdDetailBatches = GetPurOrdDetailBatches(purOrdDetails, domain, list[0].company_id.ToString()).Result; poaction.poDetailBatchList.AddRange(purOrdDetailBatches); } } public async Task> GetPurOrdDetailBatches(List purOrdDetails, string domain, string company_id) { List purOrdDetailBatches = new List(); var icbomList = _mysql_ic_bom.GetListAsync(i => purOrdDetails.Select(p => p.ItemNum).Contains(i.bom_number)).Result; var allBomlist = _mysql_b_bom_pretreatment.GetListAsync(b => icbomList.Select(c => c.Id).Contains(b.sourceid)).Result; var itemList = _itemMaster.Select(m => allBomlist.Select(b => b.item_number).ToList().Contains(m.ItemNum)); //生成当前计算bangid long bangid = help.NextId(); //数据库快照-同步mysql库数据到mongoDB中 await DbSnapShot(long.Parse(company_id), long.Parse(domain), bangid, allBomlist); param.company_id = long.Parse(company_id); param.factoryId = long.Parse(domain); _CalcBomViewAppService.param = param; if (allBomlist.Any()) { foreach (var a in purOrdDetails) { var icBom = icbomList.Where(i => i.bom_number == a.ItemNum).First(); var bomList = allBomlist.Where(a => a.sourceid == icBom.Id).ToList(); if (bomList.Any()) { if (bomList.Where(b => b.haveicsubs == 1).Count() > 0) { //物料库存表 List stocklist = new List(); var bomitem = bomList.Where(b => !string.IsNullOrEmpty(b.substitute_code)).ToList(); var itemBomList = ObjectMapper.Map(bomitem.First()); var getBomList = ObjectMapper.Map, List>(bomList); var icitemlist = _ic_item.GetListAsync(i => bomList.Select(b => b.item_number).Contains(i.number)).Result; var lista = _ic_item_stock.GetListAsync(p => p.factory_id == param.factoryId && p.bang_id == bangid && icitemlist.Select(i => i.mysql_id).Contains(p.icitem_id)).Result; //物料库存 stocklist.AddRange(lista); _CalcBomViewAppService.BomStock(getBomList, stocklist, bangid); List stockoccupies = new List(); foreach (var item in getBomList) { mo_ic_item_stockoccupy itemStockoccupyDto = new mo_ic_item_stockoccupy(); itemStockoccupyDto.bang_id = bangid; itemStockoccupyDto.icitem_id = item.item_id; itemStockoccupyDto.icitem_number = item.item_number; itemStockoccupyDto.item_no = item.num; itemStockoccupyDto.occupy_time = DateTime.Now; //计算库存减去占用 //level1Dto.sqty -= itemSockoccupy.Sum(s => s.quantity); item.needCount = item.unit == "KG" || item.unit == "M" ? a.QtyOrded * (item.qty + ((item.qty * item.scrap.GetValueOrDefault()) / 100)) : Math.Ceiling(a.QtyOrded * (item.qty + ((item.qty * item.scrap.GetValueOrDefault()) / 100))); item.sqty = item.sqty < 0 ? 0 : item.sqty; item.lack_qty = item.needCount - item.sqty; item.lack_qty = item.lack_qty < 0 ? 0 : item.lack_qty; itemStockoccupyDto.quantity = item.sqty; stockoccupies.Add(itemStockoccupyDto); } _CalcBomViewAppService.CalcStrategy(itemBomList, getBomList, bangid, stockoccupies, DateTime.Now, icitemlist, null, null); var subBomList = getBomList.Where(b => !string.IsNullOrEmpty(b.substitute_code)).ToList(); var batchs = new List(); foreach (var item in subBomList) { var groupList = subBomList.Where(s => s.substitute_code == item.substitute_code).ToList(); if (groupList.Where(g => g.stock_state == 1).Count() > 0) { batchs.Add(groupList.Where(g => g.stock_state == 1).First()); } else { batchs.Add(groupList.OrderBy(g => g.substitute_all_num).First()); } if (groupList.Count == subBomList.Count) break; else subBomList.RemoveAll(groupList); } batchs.AddRange(getBomList.Where(b => string.IsNullOrEmpty(b.substitute_code) && b.item_number != a.ItemNum).ToList()); short num = 1; foreach (var item in batchs) { purOrdDetailBatches.Add(new PurOrdDetailBatch { Domain = domain, Potype = "PW", PurOrd = a.PurOrd, IsActive = true, IsConfirm = true, CreateTime = DateTime.Now, UpdateTime = DateTime.Now, Line = a.Line, Batch = num, Location = itemList.Where(m => m.ItemNum == item.item_number).First().Location, UM = item.unit, ItemNum = a.ItemNum, SuppItem = item.item_number, QtyOrded = a.QtyOrded, QtyBO = item.qty, QtyReleased = item.unit == "KG" || item.unit == "M" ? a.QtyOrded * (item.qty + ((item.qty * item.scrap.GetValueOrDefault()) / 100)) : Math.Ceiling(a.QtyOrded * (item.qty + ((item.qty * item.scrap.GetValueOrDefault()) / 100))), Status = "" }); num++; } } else { bomList = bomList.Where(b => b.item_number != a.ItemNum).ToList(); short num = 1; foreach (var item in bomList) { purOrdDetailBatches.Add(new PurOrdDetailBatch { Domain = domain, Potype = "PW", PurOrd = a.PurOrd, IsActive = true, IsConfirm = true, CreateTime = DateTime.Now, UpdateTime = DateTime.Now, Line = a.Line, Batch = num, Location = itemList.Where(m => m.ItemNum == item.item_number).First().Location, UM = item.unit, ItemNum = a.ItemNum, SuppItem = item.item_number, QtyOrded = a.QtyOrded, QtyBO = item.qty, QtyReleased = item.unit == "KG" || item.unit == "M" ? a.QtyOrded * (item.qty.GetValueOrDefault() + ((item.qty.GetValueOrDefault() * item.Scrap) / 100)) : Math.Ceiling(a.QtyOrded * (item.qty.GetValueOrDefault() + ((item.qty.GetValueOrDefault() * item.Scrap) / 100)).GetValueOrDefault()), Status = "" }); num++; } } } } } return purOrdDetailBatches; } /// /// 递归寻找PR,找到最末级数据,生成占用关系 /// public void RecursionGetDbPr(List list, List referlist) { List prlist = _mysql_srm_pr_main.GetListAsync(s => list.Select(c => c.pr_billno).Contains(s.refer_pr_billno)).Result; if (prlist.Any()) { referlist.AddRange(prlist); RecursionGetDbPr(prlist, referlist); } } /// /// 递归寻找当前PR所关联的真实工单生成的PR,需要形成占用关系。 /// /// /// public void RecursionPr(srm_pr_main pr, List referlist, List clist) { var list = referlist.Where(s => s.refer_pr_billno == pr.pr_billno).ToList(); if (list.Any()) { foreach (var child in list) { RecursionPr(child, referlist, clist); } } else { clist.Add(pr); } } /// /// 计划工单资源检查 /// /// /// public async Task PlanOrderResourceCheck(string domain) { return await PlanOrderResourceCheckByWorkOrd(domain); } /// /// 根据工单范围资源检查 /// /// /// public async Task PlanOrderResourceCheckByWorkOrd(string domain, string workords = null) { if (string.IsNullOrEmpty(domain)) { return "当前任务工厂编号为空,请检查。"; } List tsWork = new List { "test", "tcn", "rw" }; List ordlist = new List(); List workordList = new List(); if (string.IsNullOrEmpty(workords)) { ordlist = _workOrdMaster.Select(x => x.Domain == domain && (string.IsNullOrEmpty(x.Typed) == true || tsWork.Contains(x.Typed)) && x.Status.ToLower() == "p").ToList(); workordList = ordlist.Select(c => c.WorkOrd).ToList(); } else { Array alist = workords.Split(','); foreach (var w in alist) { if (!string.IsNullOrEmpty(w.ToString())) { workordList.Add(w.ToString()); } } } List Mes_Morders = _mysql_mes_morder.GetListAsync(x => workordList.Contains(x.morder_no) && x.factory_id.ToString() == domain).Result; /*//先排除锁定期内的工单 //优先级排序 var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "WorkOrderLockPeriod" && s.Domain == domain).ToList(); decimal lookDay = 0; if (sysSet.Any()) { //锁定期 lookDay = sysSet[0].UDeci1; } lookDay = lookDay == 0 ? 7 : lookDay; DateTime lookTime = DateTime.Now.Date.AddDays((double)lookDay); Mes_Morders = Mes_Morders.Where(s => s.moentry_sys_stime > lookTime || s.moentry_sys_stime == null).OrderBy(s => s.moentry_sys_stime).ToList();*/ if (Mes_Morders.Any()) { List monolist = Mes_Morders.Select(c => c.morder_no).ToList(); #region PR的清除目前不处理,待后续二期方案解决。 /*Mes_Morders.ForEach(s => { s.moentry_sys_stime = DateTime.Now.Date.AddDays((double)lookDay + 1); }); //清理PR的占用。 //如果PR没有转PO,则PR没有合并,就删除,有合并,就减少合并后的PR的数量。 var prlist = _mysql_srm_pr_main.GetListAsync(s => monolist.Contains(s.pr_mono)).Result; List alllist = new List(); List updatelist = new List(); List dellist = new List(); RecursionGetDbPr2(prlist, alllist); foreach (var pr in prlist) { //找到没有关闭的PR,如果关联上的PR都是已关闭,则说明已经转了PO。 //TODO:解决Database operation expected to affect 1 row(s) but actually affected 0 row(s). 如果业务逻辑有问题自行修改 var getPr = RerunPr(pr, alllist); if (getPr != null) { if (getPr.pr_aqty - pr.pr_aqty <= 0) { //删除这个pr,没有小于0则是更新 dellist.Add(getPr); } else { getPr.pr_aqty = getPr.pr_aqty - pr.pr_aqty; updatelist.Add(getPr); } } }*/ #endregion List occupy = await _mysql_srm_po_occupy.GetListAsync(s => monolist.Contains(s.morder_mo)); _businessDbContext.BulkDelete(occupy); /*if (updatelist.Any()) { _businessDbContext.BulkUpdate(updatelist); } if (dellist.Any()) { _businessDbContext.BulkDelete(dellist); }*/ //清理工单占用 List mooccupy = await _mysql_mes_mooccupy.GetListAsync(s => Mes_Morders.Select(c => c.Id).Contains(s.moo_id.GetValueOrDefault())); if (mooccupy.Any()) { _businessDbContext.BulkDelete(mooccupy); } //清理掉库存占用 var itemstockoccupy = _mysql_ic_item_stockoccupy.GetListAsync(s => monolist.Contains(s.morder_mo)).Result; if (itemstockoccupy.Any()) { _businessDbContext.BulkDelete(itemstockoccupy); } //清理锁定期外的排程数据.工单排产会清理重排 /*var periodList = _periodSequenceDet.Select(s => monolist.Contains(s.WorkOrds)); if (periodList.Any()) { _periodSequenceDet.Delete(s => monolist.Contains(s.WorkOrds)); } var schedulList = _scheduleResultOpMaster.Select(s => monolist.Contains(s.WorkOrd)); if (schedulList.Any()) { _scheduleResultOpMaster.Delete(s => monolist.Contains(s.WorkOrd)); }*/ //只走计划工单 var rtn = await OrderKittingCheck(Mes_Morders, true); } else { return "没有需要检查的工单。"; } return "ok"; } /// /// 递归寻找PR,找到合并后的PR /// public void RecursionGetDbPr2(List list, List referlist) { List prlist = _mysql_srm_pr_main.GetListAsync(s => list.Select(c => c.refer_pr_billno).Contains(s.pr_billno)).Result; if (prlist.Any()) { referlist.AddRange(prlist); RecursionGetDbPr2(prlist, referlist); } } //找到没有关闭的PR,做数量的减少 public srm_pr_main RerunPr(srm_pr_main pr, List referlist) { //如果当前PR已经关闭,则检查合并数据 if (pr.state == 0) { //已关闭,并且没有关联数据,则代表转PO了。 var refPr = referlist.Find(s => s.pr_billno == pr.refer_pr_billno); //如果有关联,继续往下查 if (refPr != null) { return RerunPr(refPr, referlist); } else { return null; } } else { return pr; } } /// /// 范围内工单齐套检查 /// /// /// /// public async Task OrderCompleteInspection(string domain, string userAccount) { var workords = _workOrdMaster.Select(s => s.Domain == domain && (s.Status.ToLower() == "r" || string.IsNullOrEmpty(s.Status) == true)).ToList(); List morders = _mysql_mes_morder.GetListAsync(x => x.factory_id.ToString() == domain && workords.Select(s => s.WorkOrd).Contains(x.morder_no) && (x.morder_state == MorderEnum.Initial_state || x.morder_state == MorderEnum.Xd_state) && !x.IsDeleted).Result; if (morders.Any()) { var rst = await OrderResourceCheck(morders, domain, userAccount); if (rst == "ok") { try { await _businessDbContext.BulkUpdateAsync(morders); } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("OrderCompleteInspection", "工单齐套检查失败:" + e.Message, _currentTenant.Id.ToString()); } } else { return rst; } } return "ok"; } /// /// 原材料在库检查 /// /// /// public async Task OrderResourceCheck(List mo_Mes_Morders, string domain, string userAccount) { List checkMo = new List(); //只做库存是否齐套检查 if (mo_Mes_Morders.Any()) { //检查工单是否已经下了领料单 var nbrList = _nbrMaster.Select(a => a.Domain == domain && a.Type == "SM" && mo_Mes_Morders.Select(c => c.morder_no).Contains(a.WorkOrd)); var nbrDList = _nbrDetail.Select(a => a.Domain == domain && a.Type == "SM" && mo_Mes_Morders.Select(c => c.morder_no).Contains(a.WorkOrd)); foreach (var mo in mo_Mes_Morders) { //查出已产生领料单、过滤掉,取出未领料的工单 var nbrs = nbrList.Where(s => s.WorkOrd == mo.morder_no).ToList(); if (nbrs.Any()) { var nbrDs = nbrDList.Where(s => s.WorkOrd == mo.morder_no).ToList(); //查出没有备料完成的数据 var noCompletedList = nbrs.Where(x => (x.TransType == "PrevProcess" && x.PretreatmentState != "completed") || x.Status.ToUpper() != "C").ToList(); if (noCompletedList.Any()) { //代表还有没有备料完成 if (noCompletedList.Where(x => x.EffDate.GetValueOrDefault().Date <= DateTime.Now.Date).Any()) { //如果有结束日期小于等于当天,因为考虑备料会晚上才备完 mo.MaterialSituation = MorderEnum.Lag;//工单状态为 “备料滞后” } else { var maxQtyform = nbrDs.Max(x => x.QtyFrom); var minQtyform = nbrDs.Min(x => x.QtyFrom); if (minQtyform > 0) { //工单状态为 “备料完成” mo.MaterialSituation = MorderEnum.Part; } else if (maxQtyform > 0) { //工单状态为 “备料中” mo.MaterialSituation = MorderEnum.Preparation; } else { //工单状态为 “未备料” mo.MaterialSituation = MorderEnum.Begin; } } } else { mo.MaterialSituation = MorderEnum.ProduceComplete;//工单状态为 “生产齐套” } } else { checkMo.Add(mo); } } if (checkMo.Any()) { var rtn = await OrderKittingCheck(checkMo); if (rtn != null && rtn.examines != null) { //循环处理工单 foreach (var cmo in checkMo) { bool flag = true; var exm = rtn.examines.Find(s => s.morder_no == cmo.morder_no); if (exm != null && exm.BomChildExamineList != null && exm.BomChildExamineList.Any()) { var child = exm.BomChildExamineList.Where(bce => bce.is_use && bce.level != 1); //&& (bce.stock_state == 0 || bce.stock_state == 99)); //有缺料 if (child.Any()) { var num = child.Max(b => b.kitting_state); switch (num) { case 1://仓库齐套 cmo.MaterialSituation = MorderEnum.CarehouseComplete; break; case 2://在途齐套 case 3://在途齐套 cmo.MaterialSituation = MorderEnum.OnWayComplete; break; case 4://承诺齐套 cmo.MaterialSituation = MorderEnum.PromiseComplete; break; default://不齐套 cmo.MaterialSituation = MorderEnum.NoCarehouseComplete; break; } } else { cmo.MaterialSituation = MorderEnum.CarehouseComplete; } } //if (exm != null && exm.BomChildExamineList != null && exm.BomChildExamineList.Any()) //{ //foreach (var bce in exm.BomChildExamineList) //{ // //如果有缺料 // if (bce.is_use && (bce.stock_state == 0 || bce.stock_state == 99)) // { // //如果当前数据没有子级,则代表原材料齐套 // if (exm.BomChildExamineList.Where(s => s.parent_id == bce.fid).Count() == 0) // { // flag = false; // break; // } // } //} //} //else //{ // flag = false; //} //if (flag) //{ // //锁定期内生产备料单,并且更新为备料中,锁定期外的则更新成仓库齐套。 // cmo.MaterialSituation = MorderEnum.CarehouseComplete; //} //else //{ // //工单状态为 “仓库不齐套” // cmo.MaterialSituation = MorderEnum.NoCarehouseComplete; //} } } } return "ok"; } else { return "没有需要下达的工单"; } } //寻找子工序生成排产计划 public List GetCopyOP(string workords, string domain) { List returnList = new List(); if (string.IsNullOrEmpty(workords)) { return returnList; } List workOrd = workords.Split(",").ToList(); //工单信息 var workOrdMasters = _workOrdMaster.Select(p => p.Domain == domain && workOrd.Contains(p.WorkOrd)); //当前工单所有工序 var workordRList = _workOrdRouting.Select(s => s.Domain == domain && s.IsActive && workOrd.Contains(s.WorkOrd)).ToList(); //产线 List prodLines = _prodLineDetail.Select(p => workOrdMasters.Select(m => m.ItemNum).Contains(p.Part) && p.Domain == domain && p.IsActive); //获取已排产的工单 List dbPeriodSequences = _periodSequenceDet.Select(p => workOrd.Contains(p.WorkOrds) && p.Domain == domain && p.IsActive); List copyList = new List(); foreach (var work in workOrd) { List alllist = workordRList.Where(s => s.WorkOrd == work).ToList(); List parentlist = alllist.Where(s => s.WorkOrd == work && s.ParentOp == 0).ToList(); //父级工序,根据工序代码排序, WorkOrdRouting upperOp = null; List worouting = parentlist.Where(x => x.MilestoneOp).OrderBy(s => s.OP).ToList(); foreach (var wt in worouting) { List refMilestoneOpList = new List(); copyList = new List(); if (upperOp == null) { refMilestoneOpList.AddRange(parentlist.Where(x => x.OP <= wt.OP).ToList()); } else { refMilestoneOpList.AddRange(parentlist.Where(x => upperOp.OP < x.OP && x.OP <= wt.OP).ToList()); } upperOp = wt; GetChildOP(refMilestoneOpList, alllist, copyList); var workPsd = dbPeriodSequences.Where(s => s.ItemNum == wt.ItemNum && s.WorkOrds == work && s.Op == wt.OP).ToList(); foreach (var psd in workPsd) { copyList.ForEach(wor => { var line = prodLines.Where(p => p.Part == wor.ItemNum && p.Op == wor.OP).FirstOrDefault(); var newPsd = new PeriodSequenceDet { Domain = domain, //Line = psd.Line, ItemNum = wor.ItemNum, PlanDate = psd.PlanDate, Period = 1,//目前只考虑一班制 OrdQty = psd.OrdQty, WorkOrds = wor.WorkOrd, Op = wor.OP, IsActive = true, Status = "", CreateTime = DateTime.Now }; if (line != null) { newPsd.Line = line.Line; } else { newPsd.Line = psd.Line; } returnList.Add(newPsd); }); } } } return returnList; } //递归寻找到子级工序里工序编码最大的一条记录。 public void GetChildOP(List parentlist, List alllist, List copyList) { foreach (var parent in parentlist) { var list = alllist.Where(s => s.ParentOp == parent.OP).ToList(); if (list.Any()) { var maxOp = list.OrderByDescending(s => s.OP).FirstOrDefault(); if (maxOp != null) { copyList.Add(maxOp); } GetChildOP(list, alllist, copyList); } } } /// /// 自动下达 /// /// /// /// /// public async Task ProduceDayPlanKittingCheck(string startime, string endtime, string domain, string userAccount) { /*DateTime stime = DateTime.Now.AddMonths(1).Date; if (!string.IsNullOrEmpty(startime)) { DateTime.TryParse(startime, out stime); } DateTime etime = stime.AddDays(6); if (!string.IsNullOrEmpty(endtime)) { DateTime.TryParse(endtime, out etime); }*/ List tsWork = new List { "test", "tcn", "rw" }; //var ordlist = _workOrdMaster.Select(x => x.Domain == domain && x.OrdDate>= stime && x.OrdDate <= etime && (string.IsNullOrEmpty(x.Typed) == true || tsWork.Contains(x.Typed)) && (x.Status.ToLower() == "p" || x.Status.ToLower() == "r")).ToList(); var ordlist = _workOrdMaster.Select(x => x.Domain == domain && (string.IsNullOrEmpty(x.Typed) == true || tsWork.Contains(x.Typed)) && (x.Status.ToLower() == "p" || x.Status.ToLower() == "r")).ToList(); List morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && ordlist.Select(s => s.WorkOrd).Contains(x.morder_no) && (x.morder_state == MorderEnum.Initial_state || x.morder_state == MorderEnum.Xd_state) && !x.IsDeleted).Result; if (!morders.Any()) { return "没有需要下达的工单"; } var rst = await OrderResourceCheck(morders, domain, userAccount); if (rst == "ok") { //屏蔽日期过滤 /*var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "WorkOrderLockPeriod" && s.Domain == domain).ToList(); decimal lookDay = 0; if (sysSet.Any()) { //锁定期 lookDay = sysSet[0].UDeci1; } lookDay = lookDay == 0 ? 7 : lookDay; DateTime lookTime = DateTime.Now.Date.AddDays((double)lookDay);*/ string workords = ""; foreach (var mo in morders) { //if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state && mo.moentry_sys_stime.GetValueOrDefault().Date <= lookTime) if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state) { workords += "," + mo.morder_no; //mo.morder_state = MorderEnum.Xd_state; } } await _businessDbContext.BulkUpdateAsync(morders); //按卫亮要求。屏蔽自动下达 /*if (workords.Length > 0) { workords = workords.Substring(1, workords.Length - 1); //如果生成领料单,需清理掉当前工单的占用,然后根据领料单的数据,来生成工单的占用 var pickRst = await CreatePickBill(workords, domain, userAccount); if (pickRst != "ok") { new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + pickRst, _currentTenant.Id.ToString()); return pickRst; } var insertList = GetCopyOP(workords, domain); if (insertList.Any()) { _periodSequenceDet.Insert(insertList); } }*/ return "ok"; } else { return rst; } #region /*//根据排产日计划来获取 var periodSd = _periodSequenceDet.Select(s => s.Domain == domain && ordlist.Select(x => x.WorkOrd).Contains(s.WorkOrds)).ToList(); if (periodSd.Any()) { ordlist = ordlist.Where(x => periodSd.Select(c => c.WorkOrds).Contains(x.WorkOrd)).ToList(); List morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && ordlist.Select(s => s.WorkOrd).Contains(x.morder_no) && (x.morder_state == MorderEnum.Initial_state || x.morder_state == MorderEnum.Xd_state) && !x.IsDeleted).Result; if (!morders.Any()) { return "没有需要下达的工单"; } var rst = await OrderResourceCheck(morders, domain, userAccount); if (rst == "ok") { //屏蔽日期过滤 *//*var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "WorkOrderLockPeriod" && s.Domain == domain).ToList(); decimal lookDay = 0; if (sysSet.Any()) { //锁定期 lookDay = sysSet[0].UDeci1; } lookDay = lookDay == 0 ? 7 : lookDay; DateTime lookTime = DateTime.Now.Date.AddDays((double)lookDay);*//* string workords = ""; foreach (var mo in morders) { //if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state && mo.moentry_sys_stime.GetValueOrDefault().Date <= lookTime) if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state) { workords += "," + mo.morder_no; //mo.morder_state = MorderEnum.Xd_state; } } await _businessDbContext.BulkUpdateAsync(morders); //按卫亮要求。屏蔽自动下达 *//*if (workords.Length > 0) { workords = workords.Substring(1, workords.Length - 1); //如果生成领料单,需清理掉当前工单的占用,然后根据领料单的数据,来生成工单的占用 var pickRst = await CreatePickBill(workords, domain, userAccount); if (pickRst != "ok") { new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + pickRst, _currentTenant.Id.ToString()); return pickRst; } var insertList = GetCopyOP(workords, domain); if (insertList.Any()) { _periodSequenceDet.Insert(insertList); } }*//* return "ok"; } else { return rst; } } else { return "选定范围内没有工单需要检查领料。"; }*/ #endregion } /// /// 工单单独在库检 /// /// /// /// /// public async Task ProduceDayPlanKittingCheckByWorkOrd(string workord, string domain, string userAccount) { if (string.IsNullOrEmpty(workord)) { return "请输入DOP工单号"; } if (string.IsNullOrEmpty(domain)) { return "当前用户无工厂编码"; } workord = workord.Trim(); var worklist = _workOrdMaster.Select(x => x.WorkOrd == workord && x.Domain == domain && x.IsActive).ToList(); WorkOrdMaster work = null; if (worklist.Any()) { work = worklist[0]; } if (work == null) { return "当前工单不存在,请检查"; } string stateText = ""; if (!string.IsNullOrEmpty(work.Status)) { switch (work.Status.ToUpper()) { case "C": stateText = "关闭"; break; case "W": stateText = "投产"; break; case "R": stateText = "下达"; break; case "S": stateText = "暂停"; break; case "P": stateText = ""; break; default: stateText = "未知"; break; } } if (stateText != "") { return "当前工单为【" + stateText + "】,不允许进行在库检"; } List morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && x.morder_no == workord && (string.IsNullOrEmpty(x.morder_state) || x.morder_state == MorderEnum.Initial_state || x.morder_state == MorderEnum.Xd_state) && !x.IsDeleted).Result; if (!morders.Any()) { return "当前工单不存在,请检查"; } var rst = await OrderResourceCheck(morders, domain, userAccount); if (rst == "ok") { //屏蔽日期过滤 /*var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "WorkOrderLockPeriod" && s.Domain == domain).ToList(); decimal lookDay = 0; if (sysSet.Any()) { //锁定期 lookDay = sysSet[0].UDeci1; } lookDay = lookDay == 0 ? 7 : lookDay; DateTime lookTime = DateTime.Now.Date.AddDays((double)lookDay);*/ string workords = ""; foreach (var mo in morders) { //if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state && mo.moentry_sys_stime.GetValueOrDefault().Date <= lookTime) if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state) { workords += "," + mo.morder_no; //mo.morder_state = MorderEnum.Xd_state; } } await _businessDbContext.BulkUpdateAsync(morders); //按卫亮要求。屏蔽自动下达 /*if (workords.Length > 0) { workords = workords.Substring(1, workords.Length - 1); //如果生成领料单,需清理掉当前工单的占用,然后根据领料单的数据,来生成工单的占用 var pickRst = await CreatePickBill(workords, domain, userAccount); if (pickRst != "ok") { new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + pickRst, _currentTenant.Id.ToString()); return pickRst; } var insertList = GetCopyOP(workords, domain); if (insertList.Any()) { _periodSequenceDet.Insert(insertList); } }*/ return "ok"; } else { return rst; } /*var periodSd = _periodSequenceDet.Select(s => s.Domain == domain && s.WorkOrds == workord && s.IsActive).ToList(); if (periodSd.Any()) { List morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && x.morder_no == workord && (string.IsNullOrEmpty(x.morder_state) || x.morder_state == MorderEnum.Initial_state || x.morder_state == MorderEnum.Xd_state) && !x.IsDeleted).Result; if (!morders.Any()) { return "工单不存在,请检查"; } var rst = await OrderResourceCheck(morders, domain, userAccount); if (rst == "ok") { //屏蔽日期过滤 *//*var sysSet = _generalizedCodeMaster.Select(s => s.FldName == "SystemConfig" && s.Val == "WorkOrderLockPeriod" && s.Domain == domain).ToList(); decimal lookDay = 0; if (sysSet.Any()) { //锁定期 lookDay = sysSet[0].UDeci1; } lookDay = lookDay == 0 ? 7 : lookDay; DateTime lookTime = DateTime.Now.Date.AddDays((double)lookDay);*//* string workords = ""; foreach (var mo in morders) { //if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state && mo.moentry_sys_stime.GetValueOrDefault().Date <= lookTime) if (mo.MaterialSituation == MorderEnum.CarehouseComplete && mo.morder_state == MorderEnum.Initial_state) { workords += "," + mo.morder_no; //mo.morder_state = MorderEnum.Xd_state; } } await _businessDbContext.BulkUpdateAsync(morders); //按卫亮要求。屏蔽自动下达 *//*if (workords.Length > 0) { workords = workords.Substring(1, workords.Length - 1); //如果生成领料单,需清理掉当前工单的占用,然后根据领料单的数据,来生成工单的占用 var pickRst = await CreatePickBill(workords, domain, userAccount); if (pickRst != "ok") { new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + pickRst, _currentTenant.Id.ToString()); return pickRst; } var insertList = GetCopyOP(workords, domain); if (insertList.Any()) { _periodSequenceDet.Insert(insertList); } }*//* return "ok"; } else { return rst; } } else { return "当前工单未生成日计划"; }*/ } /// /// 手动按工单下达 /// /// /// /// /// public async Task ProduceWorkOrdKittingCheck(string workord, string domain, string userAccount) { if (!string.IsNullOrEmpty(workord)) { List morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && x.morder_no == workord && !x.IsDeleted).Result; if (morders.Any()) { if (!string.IsNullOrEmpty(morders[0].morder_state) && morders[0].morder_state != MorderEnum.Initial_state) { return "工单信息为" + morders[0].morder_state + ",不允许下达。"; } var itemMs = _itemMaster.Select(x => x.ItemNum == morders[0].product_code && x.Domain == domain).FirstOrDefault(); if (itemMs == null) { return "当前物料未未维护主数据,请先维护物料主数据。"; } else { string msg = ""; if (!string.IsNullOrEmpty(itemMs.PORcptStatus)) { switch (itemMs.PORcptStatus.ToUpper()) { case "01": msg = "因采购/仓库而被冻结。"; break; case "02": msg = "因任务清单/BOM而被冻结。"; break; case "81": msg = "MPN:BOM抬头冻结"; break; case "CO": msg = "未跑成本-财务冻结"; break; case "RS": msg = "瑞奇物料冻结"; break; default: msg = "未知冻结,类型:" + itemMs.PORcptStatus; break; } } if (!string.IsNullOrEmpty(msg)) { return msg; } } try { //如果生成领料单,需清理掉当前工单的占用,然后根据领料单的数据,来生成工单的占用 var pickRst = await CreatePickBill(morders[0].morder_no, domain, userAccount); if (pickRst != "ok") { new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + pickRst, _currentTenant.Id.ToString()); return pickRst; } morders[0].morder_state = MorderEnum.Xd_state; morders[0].MaterialSituation = morders[0].MaterialSituation == MorderEnum.NoCarehouseComplete ? MorderEnum.Begin : morders[0].MaterialSituation; //MorderEnum.Part : morders[0].MaterialSituation;部分备料改为未备料 //await _mysql_mes_morder.UpdateManyAsync(morders); await _businessDbContext.BulkUpdateAsync(morders); //复制子工序 var insertList = GetCopyOP(morders[0].morder_no, domain); if (insertList.Any()) { _periodSequenceDet.Insert(insertList); } return "ok"; } catch (Exception e) { return "下达失败,请联系管理员。"; } /*var rst = await OrderResourceCheck(morders, domain, userAccount); if (rst == "ok") { try { //如果生成领料单,需清理掉当前工单的占用,然后根据领料单的数据,来生成工单的占用 var pickRst = await CreatePickBill(morders[0].morder_no, domain, userAccount); if (pickRst != "ok") { new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + pickRst, _currentTenant.Id.ToString()); return pickRst; } morders[0].morder_state = MorderEnum.Xd_state; morders[0].MaterialSituation = morders[0].MaterialSituation == MorderEnum.NoCarehouseComplete ? MorderEnum.Part : morders[0].MaterialSituation; //await _mysql_mes_morder.UpdateManyAsync(morders); await _businessDbContext.BulkUpdateAsync(morders); //复制子工序 var insertList = GetCopyOP(morders[0].morder_no, domain); if (insertList.Any()) { _periodSequenceDet.Insert(insertList); } return "ok"; } catch (Exception e) { return "下达失败,请联系管理员。"; } } else { return rst; }*/ } else { return "工单信息不存在,请重新检查。"; } } else { return "没有需要下达的工单"; } } /// /// 工单齐套检查/替代料齐套检查结果保存 /// /// /// public async void SaveExamineResult(List KittingCheckResultList, List DayBulletinBoardList, int type) { //检查结果写入数据库 List examineList = new List(); List orderDetails = new List(); List daybulletinboards = new List(); foreach (var ex in KittingCheckResultList) { var examine = ObjectMapper.Map(ex); examine.GenerateNewId(help.NextId()); examine.type = type; examine.create_time = DateTime.Now; examine.company_id = param.company_id; examine.factory_id = param.factoryId; examine.create_time = DateTime.Now; examineList.Add(examine); ex.order_item_list.ForEach(s => { var detail = ObjectMapper.Map(s); detail.GenerateNewId(help.NextId()); detail.order_examine_id = examine.Id; detail.company_id = param.company_id; detail.factory_id = param.factoryId; detail.create_time = DateTime.Now; orderDetails.Add(detail); }); } foreach (var item in DayBulletinBoardList) { var detail = ObjectMapper.Map(item); detail.GenerateNewId(help.NextId()); detail.type = type; detail.create_time = DateTime.Now; detail.company_id = param.company_id; detail.factory_id = param.factoryId; daybulletinboards.Add(detail); } if (examineList.Any()) { _businessBangDbContext.BulkInsert(examineList); } if (daybulletinboards.Any()) { _businessBangDbContext.BulkInsert(daybulletinboards); } if (orderDetails.Any()) { _businessBangDbContext.BulkInsert(orderDetails); } } /// /// 替代关系检查 /// /// /// public async Task SubstituteResourceCheck(int day, string workOrd) { //先屏蔽此功能,暂未使用 /*List mo_Mes_Morders = new List(); if (day == 0) { List workOrds = workOrd.Split(",").ToList(); if (workOrds.Count == 0) { return ""; } mo_Mes_Morders = _mysql_mes_morder.GetListAsync(x => workOrds.Contains(x.morder_no)).Result; } else { mo_Mes_Morders = _mysql_mes_morder.GetListAsync(x => x.start_time > DateTime.Now.Date.AddDays(1) && x.start_time < DateTime.Now.Date.AddDays(day) && x.morder_state != MorderEnum.Accomplish_state && !x.IsDeleted).Result; } if (mo_Mes_Morders.Any()) { var result = await OrderKittingCheck(mo_Mes_Morders); OrderResourceViewDto rtn = DataPackage(result, true); rtn.DayBulletinBoardList = rtn.DayBulletinBoardList.OrderByDescending(d => d.day).ToList(); //保存检查结果 替代关系不计算每日物料情况 SaveExamineResult(rtn.KittingCheckResultList, new List(), 2); return JsonConvert.SerializeObject(rtn); } else { return JsonConvert.SerializeObject("没有需要检查的工单"); }*/ return "ok"; } /// /// 检查结果组装 /// /// /// /// public OrderResourceViewDto DataPackage(PschedDto result, bool flag = false) { OrderResourceViewDto rtn = new OrderResourceViewDto(); rtn.KittingCheckResultList = new List(); rtn.DayBulletinBoardList = new List(); result.examines.ForEach(examine => { OrderResourceDto dto = new OrderResourceDto(); dto.orderId = examine.morder_id.GetValueOrDefault(); dto.order_no = examine.morder_no; dto.time = examine.order_statr_time.GetValueOrDefault(); dto.ketting_time = examine.kitting_times; dto.need_qty = examine.need_qty; dto.bom_number = examine.bom_number; dto.order_item_list = new List(); var list = examine.BomChildExamineList; if (flag) { list = list.Where(s => s.type == 1 || s.haveicsubs == 1).ToList(); } list.ForEach(subitem => { var cdto = ObjectMapper.Map(subitem); /*OrderItemDto cdto = new OrderItemDto(); cdto.fid = subitem.fid; cdto.parent_id = subitem.parent_id; cdto.bom_number = subitem.bom_number; cdto.item_id = subitem.item_id; cdto.item_name = subitem.item_name; cdto.item_number = subitem.item_number; cdto.num = subitem.num; cdto.num_order = subitem.num_order; cdto.qty = subitem.qty; cdto.self_lack_qty = subitem.self_lack_qty; cdto.sqty = subitem.sqty; cdto.use_qty = subitem.use_qty; cdto.mo_qty = subitem.mo_qty; cdto.mo_occupy_list = subitem.mo_occupy_list; cdto.make_qty = subitem.make_qty; cdto.make_list = subitem.make_list; cdto.purchase_qty = subitem.purchase_qty; cdto.purchase_list = subitem.purchase_list; cdto.purchase_occupy_qty = subitem.purchase_occupy_qty; cdto.purchase_occupy_list = subitem.purchase_occupy_list; cdto.subcontracting_qty = subitem.subcontracting_qty; cdto.subcontracting_list = subitem.subcontracting_list; cdto.kitting_time = subitem.kitting_time; cdto.substitute_code = subitem.substitute_code; cdto.substitute_strategy = subitem.substitute_strategy; cdto.substitute_mode = subitem.substitute_mode; cdto.is_use = subitem.is_use;*/ dto.order_item_list.Add(cdto); string day = dto.time.ToString("yyyy-MM-dd HH:mm"); if (subitem.is_use && subitem.level != 1) { //每日每物料使用情况 DayBulletinBoard dbb = rtn.DayBulletinBoardList.Find(s => s.day == day && s.item_number == cdto.item_number); if (dbb == null) { dbb = new DayBulletinBoard(); dbb.day = day; dbb.item_name = cdto.item_name; dbb.item_number = cdto.item_number; rtn.DayBulletinBoardList.Add(dbb); } dbb.self_lack_qty += subitem.lack_qty; dbb.use_qty += subitem.use_qty; dbb.make_qty += cdto.make_qty; dbb.mo_qty += subitem.mo_qty; dbb.purchase_occupy_qty += subitem.purchase_occupy_qty; } }); rtn.KittingCheckResultList.Add(dto); }); return rtn; } /// /// 工单检查物料齐套 /// /// public async Task OrderKittingCheck(List mo_Mes_Morders, bool planCheck = false, List moentryList = null, bool writeNum = false, List workOrds = null) { //资源检查结果 PschedDto rtn = new PschedDto(); //资源检查明细list List examines = new List(); //OrderCheckDto input = new OrderCheckDto(); if (!mo_Mes_Morders.Any()) { return rtn; } List db_mes_morder = new List(); if (writeNum) { db_mes_morder = mo_Mes_Morders; } //资源检查入参全局变量赋值 param.company_id = mo_Mes_Morders[0].company_id; param.factoryId = mo_Mes_Morders[0].factory_id.GetValueOrDefault(); param.checkflag = false; param.checkPlan = planCheck; param.writeNum = writeNum; //生成当前计算bangid long bangid = help.NextId(); /*List mo_Mes_Morders = _mes_morder.GetManyByCondition(x => x.start_time > DateTime .Now.Date.AddDays(1) && x.start_time < DateTime .Now.Date.AddDays(input.Day) && x.morder_state == MorderEnum.Initial_state && !x.IsDeleted && x.tenant_id == param.tenantId && x.bang_id == bangid).Result; List mo_Mes_Moentries = _mes_moentry.GetManyByCondition(x=> mo_Mes_Morders.Select(s => s.id).Contains(x.moentry_moid.Value)).Result;*/ var morderIdList = mo_Mes_Morders.Select(s => s.Id).ToList(); List mo_Mes_Moentries = new List(); if (moentryList != null) { mo_Mes_Moentries = moentryList; } else { mo_Mes_Moentries = _mysql_mes_moentry.GetListAsync(x => morderIdList.Contains(x.moentry_moid.Value)).Result; } //获取订单行数据 List sentrys = _mysql_crm_seorderentry.GetListAsync(p => p.company_id == param.company_id && p.factory_id == param.factoryId && !p.IsDeleted && mo_Mes_Moentries.Select(x => x.soentry_id).Contains(p.Id)).Result; //删除同步Mysql后旧数据 await DeleteMySqlOldData(sentrys); List boms = _ic_bom.GetListAsync(p => mo_Mes_Morders.Select(m => m.bom_number).Contains(p.bom_number) && p.factory_id == param.factoryId && p.company_id == param.company_id && !p.IsDeleted).Result.ToList(); //物料bom List bomlist = new List(); //物料bom明细 List bomchildlist = new List(); //物料信息 List icitemlist = new List(); //替代关系 List sublist = new List(); List suballlist = new List(); List subdtllist = new List(); //物料库存表 List stocklist = new List(); //物料占用记录 List sklist = new List(); //sorder=null 是因为齐套检查不需要生成工单、采购、委外等信息,所以不需要关联的工单信息传递进去。 var pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; List autoCreates = new List(); boms.ForEach(p => { if (!pretreatments.Where(s => s.sourceid == p.mysql_id).Any()) { autoCreates.Add(p); } }); if (autoCreates.Any()) { AutoCreateBomBill(param.company_id.ToString(), autoCreates); pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; } //增加特殊工单的预处理结果,因为特殊工单是自定义物料清单 List tsWork = new List { "试制工单", "返工工单" }; var specialWork = mo_Mes_Morders.Where(x => tsWork.Contains(x.morder_type)).ToList(); pretreatments.AddRange(_mysql_b_bom_pretreatment.GetListAsync(s => specialWork.Select(c => c.Id).ToList().Contains(s.sourceid)).Result); await AsyncItemStockFromWMS(pretreatments); //数据库快照-同步mysql库数据到mongoDB中 await DbSnapShot(param.company_id, param.factoryId, bangid, pretreatments); DataInitialization(boms, bangid, icitemlist, stocklist, pretreatments, sklist); //调用优先级计算算法 //var workOrds = _replenishmentAppService.CalcPriority(mo_Mes_Morders.Select(p => p.morder_no).ToList(), param.factoryId.ToString()); if (!writeNum) { workOrds = _workOrdMaster.Select(a => mo_Mes_Morders.Select(p => p.morder_no).Contains(a.WorkOrd) && a.Domain == param.factoryId.ToString() && a.IsActive).OrderBy(c => c.Priority).ToList(); } var workOrdRoutings = _workOrdRouting.Select(a => mo_Mes_Morders.Select(p => p.morder_no).Contains(a.WorkOrd) && a.Domain == param.factoryId.ToString() && a.IsActive).ToList(); //var recid = workOrds.Select(c => c.RecID).ToList(); //清理工单物料明细 var delWorkOrddetails = _workOrdDetail.Select(x => workOrds.Select(c => c.RecID).Contains((int)x.WorkOrdMasterRecID) && x.Domain == param.factoryId.ToString()); //var productStructureMs = _productStructureMaster.Select(x => workOrds.Select(c => c.WorkOrd).Contains(x.ParentItem) && x.Domain == param.factoryId.ToString()); List priorityMorderList = new List(); foreach (var work in workOrds) { var mo = mo_Mes_Morders.Find(s => s.morder_no == work.WorkOrd); if (writeNum) { var routings = workOrdRoutings.Where(r => r.WorkOrd == work.WorkOrd).ToList(); if (routings.Any() && mo != null) { //最大生产数量 var QtyComplete = routings.Max(r => r.QtyComplete); //修改订单需求数为在制数量 mo.need_number = mo.need_number - QtyComplete; work.OpQtyCompleted = QtyComplete; work.InProdcutQty = mo.need_number; } } if (mo != null) { if (mo.need_number > 0) { priorityMorderList.Add(mo); } } } if (!priorityMorderList.Any()) { priorityMorderList = mo_Mes_Morders; } /*if (!planCheck) { //如果是齐套检查,则不考虑其他数据的占用,只看原材料库存 sklist = new List(); }*/ _morderAppService.param = param; _purchaseOrderAppService.param = param; _CalcBomViewAppService.param = param; List GenerateMoList = new List(); /*var moNbrlistDto = _serialNumberAppService.GetBillNo(input.factoryId.ToString(), "M5", priorityMorderList.Count, "", 1); if (moNbrlistDto.Any()) { foreach (var nbr in moNbrlistDto) { GenerateMoList.Add(nbr.NbrResult); } }*/ _CalcBomViewAppService.GenerateMoList = GenerateMoList; _CalcBomViewAppService.newStockOccList = new List(); sklist = sklist.Where(s => !priorityMorderList.Select(p => p.morder_no).Contains(s.morder_mo)).ToList(); foreach (var item in priorityMorderList) { var moentry = mo_Mes_Moentries.Find(s => s.moentry_moid == item.Id); if (moentry == null) { continue; } var sentry = sentrys.Find(s => s.Id == moentry.soentry_id); //工单资源检查信息 ExamineResult dtl = new ExamineResult(); dtl.morder_id = item.Id; dtl.morder_no = item.morder_no; dtl.bangid = bangid; dtl.order_statr_time = item.start_time; dtl.bom_number = item.bom_number; dtl.need_qty = item.need_number.GetValueOrDefault(); dtl.prd_code = item.product_code; //获取当前物料bom数据 List itemPrelist = new List(); //通过工单ID读取,考虑特殊工单的预处理 itemPrelist = pretreatments.Where(s => s.sourceid == item.Id).ToList(); if (!itemPrelist.Any()) { var childBom = boms.Where(p => p.bom_number == item.bom_number).FirstOrDefault(); if (childBom != null) { itemPrelist = pretreatments.Where(s => s.sourceid == childBom.mysql_id).ToList(); } else { continue; } } if (!itemPrelist.Any()) { continue; } var getBomList = ObjectMapper.Map, List>(itemPrelist); if (sentry != null) { dtl.sentry_id = sentry.Id; getBomList.ForEach(s => s.sentry_id = item.Id); } if (getBomList.Count == 1) { var isy = 1; } _CalcBomViewAppService.morder_type = item.morder_type; _CalcBomViewAppService.mes_morder = item; //库存初始化 _CalcBomViewAppService.BomStock(getBomList, stocklist, bangid); //计算 _CalcBomViewAppService.CalcView(getBomList, bangid, item.need_number.GetValueOrDefault(), item.moentry_sys_stime, sklist, sentry, icitemlist); //TODO:最晚开始时间 //var curFacDtl = leadTimeList.FirstOrDefault(p => p.item_id == childBom.icitem_id); //物料齐套时间 dtl.kitting_times = getBomList.Where(p => p.is_use && p.kitting_time != null).OrderByDescending(m => m.kitting_time).First().kitting_time.GetValueOrDefault(); //kitting_time=null为自制组件跳过数据未进行计算,kitting_state=0的数据未参与计算 var qllist = getBomList.Where(x => x.use_qty == 0 && x.kitting_time != null && x.needCount != 0 && x.erp_cls != 4 && x.level != 1 && x.kitting_state != 0).ToList(); var work = workOrds.Find(x => x.WorkOrd == item.morder_no); if (qllist.Any()) { work.LocationStock = 0; } else { qllist = getBomList.Where(x => x.use_qty > 0 && x.kitting_time != null && x.needCount != 0 && x.erp_cls != 4 && x.level == 2 && x.kitting_state == 1).ToList(); if (qllist.Any()) { //按比例计算成品齐套个数 work.LocationStock = qllist.Min(b => b.use_qty / b.qty) > work.QtyOrded ? work.QtyOrded : qllist.Min(b => b.use_qty / b.qty); } else { work.LocationStock = 0; } } //替代关系展开list dtl.BomChildExamineList = getBomList; //添加订单行开工信息 examines.Add(dtl); } rtn.examines = examines; if (writeNum) { //回写工单需求数 foreach (var item in mo_Mes_Morders) { var curInfo = db_mes_morder.FirstOrDefault(p => p.morder_no == item.morder_no); if (curInfo != null) { item.need_number = curInfo.need_number; } } _businessDbContext.BulkUpdate(workOrds); } List mainWorkOrdDetails = new List(); if (!writeNum) { if (moentryList == null) { //成品虚拟件对应关系 var productOpList = _productStructureOp.Select(x => priorityMorderList.Select(c => c.product_code).Contains(x.ProductItem) && x.Domain == param.factoryId.ToString()); List itemMasterList = _itemMaster.Select(p => p.Domain == param.factoryId.ToString()).ToList(); foreach (var workord in priorityMorderList) { long fid = GetParentMo(priorityMorderList, workord); var exm = examines.Find(s => s.morder_id == fid); if (exm != null) { var childs = exm.BomChildExamineList.Where(s => s.is_use == true).ToList(); var child = childs.Find(s => s.item_number == workord.product_code); if (workord.morder_type == "返工工单") { child = childs.Find(s => s.item_number == workord.product_code && s.level == 1); } if (child == null) { continue; } List returnList = new List(); var productOps = productOpList.Where(x => x.ProductItem == workord.product_code).ToList(); GetWorkDetalis(childs.Where(s => s.parent_id == child.fid).ToList(), returnList, childs, productOps); if (returnList.Any()) { WorkOrdDetail woDetail = null; var calereturnList = returnList.OrderBy(c => c.item_number).Select(x => x.item_number).Distinct().ToList(); var work = workOrds.Find(x => x.WorkOrd == workord.morder_no); if (work == null) { continue; } short num = 1; foreach (var caleNumber in calereturnList) { var caleList = returnList.Where(x => x.item_number == caleNumber).ToList(); var itemMst = itemMasterList.Find(x => x.ItemNum == caleNumber); //添加工单的物料信息 woDetail = new WorkOrdDetail(); woDetail.Domain = workord.factory_id.ToString(); woDetail.WorkOrd = workord.morder_no; var oplist = caleList.Where(x => x.Op > 0).ToList(); woDetail.Op = 0; if (oplist.Any()) { woDetail.Op = oplist.Min(f => f.Op); } woDetail.ItemNum = caleNumber; woDetail.QtyPosted = 0m; woDetail.QtyReturned = 0m; woDetail.Status = ""; woDetail.IsActive = true; woDetail.CreateTime = DateTime.Now; woDetail.Line = num; woDetail.QtyRequired = caleList.Sum(c => c.needCount); woDetail.WorkOrdMasterRecID = work.RecID; woDetail.Location = itemMst == null ? "" : itemMst.Location; if (workord.need_number != 0) { woDetail.FrozenBOMQty = Math.Round(woDetail.QtyRequired / workord.need_number.GetValueOrDefault(), 10); } mainWorkOrdDetails.Add(woDetail); num++; } } } } if (delWorkOrddetails.Any()) { _businessDbContext.BulkDelete(delWorkOrddetails); } if (mainWorkOrdDetails.Any()) { _businessDbContext.BulkInsert(mainWorkOrdDetails); } } } if (planCheck) { //如果有计划工单,则需要生成pr po oo List prmainlist = new List(); if (_CalcBomViewAppService.SRMPRDtoList.Any()) { List> prlist = _CalcBomViewAppService.SRMPRDtoList.Where(f => f.srm_Pr_Main != null).Select(s => s.srm_Pr_Main).ToList(); List list = new List(); foreach (var pr in prlist) { foreach (var item in pr) { list.Add(item); prmainlist.Add(item); } } if (list.Any()) rtn.srm_pr_list = _CalcBomViewAppService.SRMPRDtoList; } if (prmainlist.Any()) { var nbrlistDto = _serialNumberAppService.GetBillNo(prmainlist[0].factory_id.ToString(), "PR", prmainlist.Count, "admin", 1); int index = 0; foreach (var p in prmainlist) { if (nbrlistDto[index] != null) { p.pr_billno = nbrlistDto[index].NbrResult.ToString(); } index++; if (p.pr_purchaseid.GetValueOrDefault() == 0) { //数据丢失 var list = _mysql_srm_purchase.GetListAsync(s => s.icitem_id == p.icitem_id).Result; if (list.Any()) { var purchase = list.OrderBy(s => s.quota_priority).FirstOrDefault(); p.pr_purchaseid = purchase.supplier_id; p.pr_purchasename = purchase.supplier_name; p.pr_purchasenumber = purchase.supplier_number; } } } } /*if (_CalcBomViewAppService.mordersInsertList.Any()) { var molist = ObjectMapper.Map, List>(_CalcBomViewAppService.mordersInsertList); _businessDbContext.BulkInsert(molist); List workOrdSave = new List(); List workOrdRoutingSave = new List(); List workOrdDetails = new List(); if (molist.Any()) { molist.ForEach(s => { s.create_time = DateTime.Now; s.factory_id = param.factoryId; s.company_id = param.company_id; }); //同步工单 CreateWorkOrdDates(molist, _CalcBomViewAppService.moentriesInsertList, routingOps, workOrdSave, workOrdRoutingSave, workOrdDetails, new List(), new List()); if (workOrdSave.Any()) { _businessDbContext.BulkInsert(workOrdSave); } var DBworkOrdList = _workOrdMaster.Select(a => workOrdSave.Count > 0 && a.Domain == workOrdSave[0].Domain && workOrdSave.Select(c => c.WorkOrd).Contains(a.WorkOrd)); if (workOrdRoutingSave.Any()) { workOrds.AddRange(DBworkOrdList); workOrdRoutingSave.ForEach(c => { c.WorkOrdMasterRecID = DBworkOrdList.Where(a => a.WorkOrd == c.WorkOrd).First().RecID; }); _businessDbContext.BulkInsert(workOrdRoutingSave); } priorityMorderList.AddRange(molist); } }*/ //获取工单数据 /*var workOrdMasters = _workOrdMaster.Select(p => mo_Mes_Morders.Select(c => c.morder_no).Contains(p.WorkOrd) && p.Domain == param.factoryId.ToString()); workOrdMasters.ForEach(s => { var mo = mo_Mes_Morders.Find(m => m.morder_no == s.WorkOrd); if (mo != null) { s.OrdDate = mo.moentry_sys_stime; s.DueDate = mo.moentry_sys_stime; } });*/ using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { _businessDbContext.BulkUpdate(mo_Mes_Morders); /*if (workOrdMasters.Any()) { _workOrdMaster.Update(workOrdMasters); }*/ if (prmainlist.Any()) { var pr_mainlist = ObjectMapper.Map, List>(prmainlist); _businessDbContext.BulkInsert(pr_mainlist); } if (_CalcBomViewAppService.newStockOccList.Any()) { var stockoccupylist = ObjectMapper.Map, List>(_CalcBomViewAppService.newStockOccList); stockoccupylist.ForEach(s => { s.GenerateNewId(help.NextId()); s.create_time = DateTime.Now; s.tenant_id = param.company_id.GetValueOrDefault(); s.company_id = param.company_id; s.factory_id = param.factoryId; }); _businessDbContext.BulkInsert(stockoccupylist); } if (_CalcBomViewAppService.srm_Po_OccupiesInsert.Any()) { _CalcBomViewAppService.srm_Po_OccupiesInsert.ForEach(s => { s.company_id = param.company_id; s.factory_id = param.factoryId; }); var srmpooccupyInsert = ObjectMapper.Map, List>(_CalcBomViewAppService.srm_Po_OccupiesInsert); srmpooccupyInsert.ForEach(x => { x.GenerateNewId(help.NextId()); }); _businessDbContext.BulkInsert(srmpooccupyInsert); } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("OrderKittingCheck", "工单检查数据更新失败:" + e.Message, _currentTenant.Id.ToString()); } } } if (!writeNum) { //检查结果写入数据库 await ExamineResultInsertDBAsync(examines); } //清空快照数据 await ClearSnapShot(bangid); return rtn; } #region 齐套数量测试 /// /// 工单物料齐套检查 /// /// public async Task OrderDetailKittingCheck(string domain, string userAccount, List mo_Mes_Morders = null) { // 调用优先级计算算法 //var workOrds = _replenishmentAppService.CalcPriority(mo_Mes_Morders.Select(p => p.morder_no).ToList(), param.factoryId.ToString()); List tsWork = new List { "test", "tcn", "rw" }; var workOrds = _workOrdMaster.Select(x => x.Domain == domain && x.IsActive && (string.IsNullOrEmpty(x.Typed) == true || tsWork.Contains(x.Typed)) && (x.Status.ToLower() == "p" || x.Status.ToLower() == "r")).OrderBy(c => c.Priority).ToList(); if (mo_Mes_Morders == null) { mo_Mes_Morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && workOrds.Select(s => s.WorkOrd).Contains(x.morder_no) && (x.morder_state == MorderEnum.Initial_state || x.morder_state == MorderEnum.Xd_state) && !x.IsDeleted).Result; } var workOrdRoutings = _workOrdRouting.Select(a => mo_Mes_Morders.Select(p => p.morder_no).Contains(a.WorkOrd) && a.Domain == param.factoryId.ToString() && a.IsActive).ToList(); //清理工单物料明细 var workOrdDetails = _workOrdDetail.Select(x => workOrds.Select(c => c.RecID).Contains((int)x.WorkOrdMasterRecID) && x.Domain == param.factoryId.ToString()); //资源检查结果 PschedDto rtn = new PschedDto(); //资源检查明细list List examines = new List(); if (!mo_Mes_Morders.Any()) { return rtn; } List db_mes_morder = new List(); db_mes_morder = mo_Mes_Morders; //资源检查入参全局变量赋值 param.company_id = mo_Mes_Morders[0].company_id; param.factoryId = mo_Mes_Morders[0].factory_id.GetValueOrDefault(); param.checkflag = false; param.checkPlan = false; param.writeNum = true; //生成当前计算bangid long bangid = help.NextId(); var morderIdList = mo_Mes_Morders.Select(s => s.Id).ToList(); List mo_Mes_Moentries = _mysql_mes_moentry.GetListAsync(x => morderIdList.Contains(x.moentry_moid.Value)).Result; //获取订单行数据 List sentrys = _mysql_crm_seorderentry.GetListAsync(p => p.company_id == param.company_id && p.factory_id == param.factoryId && !p.IsDeleted && mo_Mes_Moentries.Select(x => x.soentry_id).Contains(p.Id)).Result; List boms = _ic_bom.GetListAsync(p => mo_Mes_Morders.Select(m => m.bom_number).Contains(p.bom_number) && p.factory_id == param.factoryId && p.company_id == param.company_id && !p.IsDeleted).Result.ToList(); //List Items = _ic_item.GetListAsync(p => mo_Mes_Morders.Select(m => m.bom_number).Contains(p.number) && !p.IsDeleted).Result; //删除同步Mysql后旧数据 await DeleteMySqlOldData(sentrys); //物料信息 List icitemlist = _ic_item.GetListAsync(p => (mo_Mes_Morders.Select(m => m.bom_number).Contains(p.number) || workOrdDetails.Select(w => w.ItemNum).Contains(p.number)) && !p.IsDeleted).Result; //new List(); //物料库存表 List stocklist = new List(); //物料占用记录 List sklist = new List(); //工单物料和领料信息组成bom清单 var nbrDetails = _nbrDetail.Select(n=> workOrds.Select(s => s.WorkOrd).Contains(n.WorkOrd)); //排除领料单已发料数量 AutoCreateBomFromOrderDetail(boms, icitemlist, mo_Mes_Morders, workOrdDetails, nbrDetails); //排除已发完料的工单 var pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => mo_Mes_Morders.Select(c => c.Id).ToList().Contains(s.sourceid) && s.version != "ok").Result; await AsyncItemStockFromWMS(pretreatments); //数据库快照-同步mysql库数据到mongoDB中 await DbSnapShot(param.company_id, param.factoryId, bangid, pretreatments); DataInitialization(boms, bangid, icitemlist, stocklist, pretreatments, sklist); List priorityMorderList = new List(); foreach (var work in workOrds) { var mo = mo_Mes_Morders.Find(s => s.morder_no == work.WorkOrd); var routings = workOrdRoutings.Where(r => r.WorkOrd == work.WorkOrd).ToList(); if (routings.Any() && mo != null) { //最大生产数量 var QtyComplete = routings.Max(r => r.QtyComplete); //修改订单需求数为在制数量 mo.need_number = mo.need_number - QtyComplete; work.OpQtyCompleted = QtyComplete; work.InProdcutQty = mo.need_number; } if (mo != null) { if (mo.need_number > 0) { priorityMorderList.Add(mo); } } } if (!priorityMorderList.Any()) { priorityMorderList = mo_Mes_Morders; } _morderAppService.param = param; _purchaseOrderAppService.param = param; _CalcBomViewAppService.param = param; List GenerateMoList = new List(); _CalcBomViewAppService.GenerateMoList = GenerateMoList; _CalcBomViewAppService.newStockOccList = new List(); sklist = sklist.Where(s => !priorityMorderList.Select(p => p.morder_no).Contains(s.morder_mo)).ToList(); foreach (var item in priorityMorderList) { var moentry = mo_Mes_Moentries.Find(s => s.moentry_moid == item.Id); if (moentry == null) { continue; } var sentry = sentrys.Find(s => s.Id == moentry.soentry_id); //工单资源检查信息 ExamineResult dtl = new ExamineResult(); dtl.morder_id = item.Id; dtl.morder_no = item.morder_no; dtl.bangid = bangid; dtl.order_statr_time = item.start_time; dtl.bom_number = item.bom_number; dtl.need_qty = item.need_number.GetValueOrDefault(); dtl.prd_code = item.product_code; //获取当前物料bom数据 List itemPrelist = new List(); //通过工单ID读取,考虑特殊工单的预处理 itemPrelist = pretreatments.Where(s => s.sourceid == item.Id).ToList(); if (!itemPrelist.Any()) { var childBom = boms.Where(p => p.bom_number == item.bom_number).FirstOrDefault(); if (childBom != null) { itemPrelist = pretreatments.Where(s => s.sourceid == childBom.mysql_id).ToList(); } else { continue; } } if (!itemPrelist.Any()) { continue; } var getBomList = ObjectMapper.Map, List>(itemPrelist); if (sentry != null) { dtl.sentry_id = sentry.Id; getBomList.ForEach(s => s.sentry_id = item.Id); } if (getBomList.Count == 1) { var isy = 1; } _CalcBomViewAppService.morder_type = item.morder_type; _CalcBomViewAppService.mes_morder = item; //库存初始化 _CalcBomViewAppService.BomStock(getBomList, stocklist, bangid); //计算 _CalcBomViewAppService.CalcView(getBomList, bangid, item.need_number.GetValueOrDefault(), item.moentry_sys_stime, sklist, sentry, icitemlist); //TODO:最晚开始时间 //var curFacDtl = leadTimeList.FirstOrDefault(p => p.item_id == childBom.icitem_id); //物料齐套时间 dtl.kitting_times = getBomList.Where(p => p.is_use && p.kitting_time != null).OrderByDescending(m => m.kitting_time).First().kitting_time.GetValueOrDefault(); //kitting_time=null为自制组件跳过数据未进行计算,kitting_state=0的数据未参与计算 var qllist = getBomList.Where(x => x.use_qty == 0 && x.kitting_time != null && x.needCount != 0 && x.erp_cls != 4 && x.level != 1 && x.kitting_state != 0).ToList(); var work = workOrds.Find(x => x.WorkOrd == item.morder_no); if (qllist.Any()) { work.LocationStock = 0; } else { qllist = getBomList.Where(x => x.use_qty > 0 && x.kitting_time != null && x.needCount != 0 && x.erp_cls != 4 && x.level == 2 && x.kitting_state == 1).ToList(); if (qllist.Any()) { //按比例计算成品齐套个数 work.LocationStock = qllist.Min(b => b.use_qty / b.qty) > work.QtyOrded ? work.QtyOrded : qllist.Min(b => b.use_qty / b.qty); } else { work.LocationStock = 0; } } //替代关系展开list dtl.BomChildExamineList = getBomList; //添加订单行开工信息 examines.Add(dtl); } rtn.examines = examines; //检查结果写入数据库 await ExamineResultInsertDBAsync(examines); //清空快照数据 await ClearSnapShot(bangid); return rtn; } public void AutoCreateBomFromOrderDetail(List boms, List icitemlist, List mo_Mes_Morders,List workOrdDetails, List nbrDetails) { List bomChildExamineDtos = new List(); List deleteList = new List(); List addList = new List(); var pretreatment = _mysql_b_bom_pretreatment.GetListAsync(s => mo_Mes_Morders.Select(c => c.Id).ToList().Contains(s.sourceid)).Result; if (pretreatment.Any()) { //版本不同则重新生成 deleteList.AddRange(pretreatment); } mo_Mes_Morders.ForEach(x => { var curicbom = boms.Where(p => p.bom_number == x.product_code).FirstOrDefault(); var curicitem = icitemlist.Where(p => p.number == x.product_code).FirstOrDefault(); var fid= help.NextId(); BomChildExamineDto bomChildExamineDto = new BomChildExamineDto(); bomChildExamineDto.id = help.NextId(); bomChildExamineDto.fid = fid; bomChildExamineDto.bom_child_id = null; bomChildExamineDto.bom_id = curicbom == null ? null : curicbom.mysql_id; bomChildExamineDto.bom_number = x.product_code; bomChildExamineDto.qty = 1; bomChildExamineDto.erp_cls = curicitem == null ? 4 : curicitem.erp_cls.GetValueOrDefault(); bomChildExamineDto.item_id = curicitem == null ? 0 : curicitem.Id; bomChildExamineDto.item_name = curicitem == null ? "" : curicitem.name; bomChildExamineDto.item_number = x.product_code; bomChildExamineDto.level = 1; bomChildExamineDto.model = curicitem == null ? "" : curicitem.model; bomChildExamineDto.unit = curicitem == null ? "" : curicitem.unit; bomChildExamineDto.num = "1"; bomChildExamineDto.parent_id = 0; bomChildExamineDto.type = 0; bomChildExamineDto.PurLT = curicitem == null ? 0 : curicitem.PurLT; bomChildExamineDto.clean_leadtime = curicitem == null ? 0 : curicitem.clean_leadtime; var curworkOrdDetails = workOrdDetails.Where(w=>w.WorkOrd==x.morder_no).ToList(); if (curworkOrdDetails.Any()) { var curnbrDetails = nbrDetails.Where(n=>n.WorkOrd==x.morder_no).ToList(); if (curnbrDetails.Any()) { curnbrDetails = curnbrDetails.Where(n=>n.Status!="C").ToList(); if (!curnbrDetails.Any()) { bomChildExamineDto.version = "ok"; } else { curnbrDetails.ForEach(d => { var curicbom = boms.Where(p => p.bom_number == d.ItemNum).FirstOrDefault(); var curicitem = icitemlist.Where(p => p.number == d.ItemNum).FirstOrDefault(); BomChildExamineDto bomChildExamineDto = new BomChildExamineDto(); bomChildExamineDto.id = help.NextId(); bomChildExamineDto.fid = help.NextId(); bomChildExamineDto.bom_child_id = null; bomChildExamineDto.bom_id = null; bomChildExamineDto.bom_number = ""; bomChildExamineDto.qty = x.morder_production_number.GetValueOrDefault() == 0 ? 1 : d.QtyOrd - d.QtyRec / x.morder_production_number.GetValueOrDefault(); bomChildExamineDto.erp_cls = curicitem == null ? 4 : curicitem.erp_cls.GetValueOrDefault(); bomChildExamineDto.item_id = curicitem == null ? 0 : curicitem.Id; bomChildExamineDto.item_name = curicitem == null ? "" : curicitem.name; bomChildExamineDto.item_number = d.ItemNum; bomChildExamineDto.level = 2; bomChildExamineDto.model = curicitem == null ? "" : curicitem.model; bomChildExamineDto.unit = curicitem == null ? "" : curicitem.unit; bomChildExamineDto.num = "1." + d.Line; bomChildExamineDto.parent_id = fid; bomChildExamineDto.type = 0; bomChildExamineDto.PurLT = curicitem == null ? 0 : curicitem.PurLT; bomChildExamineDto.clean_leadtime = curicitem == null ? 0 : curicitem.clean_leadtime; bomChildExamineDtos.Add(bomChildExamineDto); }); } } else { curworkOrdDetails.ForEach(d => { var curicbom = boms.Where(p => p.bom_number == d.ItemNum).FirstOrDefault(); var curicitem = icitemlist.Where(p => p.number == d.ItemNum).FirstOrDefault(); BomChildExamineDto bomChildExamineDto = new BomChildExamineDto(); bomChildExamineDto.id = help.NextId(); bomChildExamineDto.fid = help.NextId(); bomChildExamineDto.bom_child_id = null; bomChildExamineDto.bom_id = null; bomChildExamineDto.bom_number = ""; bomChildExamineDto.qty = d.FrozenBOMQty; bomChildExamineDto.erp_cls = curicitem == null ? 4 : curicitem.erp_cls.GetValueOrDefault(); bomChildExamineDto.item_id = curicitem == null ? 0 : curicitem.Id; bomChildExamineDto.item_name = curicitem == null ? "" : curicitem.name; bomChildExamineDto.item_number = d.ItemNum; bomChildExamineDto.level = 2; bomChildExamineDto.model = curicitem == null ? "" : curicitem.model; bomChildExamineDto.unit = curicitem == null ? "" : curicitem.unit; bomChildExamineDto.num = "1." + d.Line; bomChildExamineDto.parent_id = fid; bomChildExamineDto.type = 0; bomChildExamineDto.PurLT = curicitem == null ? 0 : curicitem.PurLT; bomChildExamineDto.clean_leadtime = curicitem == null ? 0 : curicitem.clean_leadtime; bomChildExamineDtos.Add(bomChildExamineDto); }); } } bomChildExamineDtos.Add(bomChildExamineDto); var list = ObjectMapper.Map, List>(bomChildExamineDtos); list.ForEach(s => { s.sourceid = x.Id; s.company_id = param.company_id; s.tenant_id = param.org_id; s.factory_id = param.factoryId; }); addList.AddRange(list); }); if (deleteList.Any()) { _businessDbContext.BulkDelete(deleteList); } if (addList.Any()) { _businessDbContext.BulkInsert(addList); } } //public void DetailDataInitialization(List boms, long bangid, List icitemlist, List stocklist, List pretreatments, List sklist, bool writeNum = false) //{ // List itemIds = pretreatments.Select(p => p.item_id.GetValueOrDefault()).Distinct().ToList(); // icitemlist.AddRange(_ic_item.GetListAsync(p => itemIds.Contains(p.mysql_id) && !p.IsDeleted).Result); // #region 1、数据准备 // //产线明细 // prodLines = _prodLineDetail.Select(p => p.Domain == param.factoryId.ToString()).ToList(); // //标准工序 // routingOps = _routingOpDetail.Select(p => p.Domain == param.factoryId.ToString()).ToList(); // List lines = prodLines.Select(p => p.Line).Distinct().ToList(); // //工作日历 // calendarWorks = _shopCalendarWorkCtr.Select(p => lines.Contains(p.ProdLine)).ToList(); // //休息日 // qualityLineWorks = _qualityLineWorkDetail.Select(p => lines.Contains(p.ProdLine)).ToList(); // //节假日 // holidays = _holidayMaster.Select(p => p.Dated >= DateTime.Now.Date); // //主工单 // var ordlist = _workOrdMaster.Select(x => x.Domain == param.factoryId.ToString() && string.IsNullOrEmpty(x.Typed) == true && !string.IsNullOrEmpty(x.Status) && x.Status.ToUpper() != "C" && x.Status.ToUpper() != "P").ToList(); // List mo_Mes_Morders = _mes_morder.GetListAsync(x => ordlist.Select(c => c.WorkOrd).Contains(x.morder_no) && x.company_id == param.company_id && x.factory_id == param.factoryId && x.bang_id == bangid).Result; // List moids = mo_Mes_Morders.Select(p => p.mysql_id).ToList(); // List mo_Mes_Moentry = _mes_moentry.GetListAsync(x => moids.Contains(x.moentry_moid)).Result; // //工单占用表 // List mes_mooccupyList = _mes_mooccupy.GetListAsync(x => x.moo_state == 1 && !x.IsDeleted && x.company_id == param.company_id // && boms.Select(p => p.item_number).Contains(x.fitem_number) && x.bang_id == bangid).Result; // List occoupyRefId = new List(); // //物料采购订单明细 // var poDetailList = _srm_po_list.GetListAsync(x => icitemlist.Select(p => p.mysql_id).ToList().Contains(x.icitem_id.Value) && x.bang_id == bangid && x.state == 1 && !x.IsDeleted).Result; // occoupyRefId.AddRange(poDetailList.Select(p => p.mysql_id).ToList()); // var srm_pr_mains = _srm_pr_main.GetListAsync(x => icitemlist.Select(p => p.mysql_id).ToList().Contains(x.icitem_id.Value) && x.bang_id == bangid && x.state != 0 && x.state != 4 && !x.IsDeleted).Result; // occoupyRefId.AddRange(srm_pr_mains.Select(p => p.mysql_id).ToList()); // //采购订单或采购申请占用数据 // var poOccupys = _srm_po_occupy.GetListAsync(x => occoupyRefId.Contains(x.polist_id) && x.bang_id == bangid && !x.IsDeleted).Result; // #endregion // //物料库存 // stocklist.AddRange(_ic_item_stock.GetListAsync(p => p.factory_id == param.factoryId && p.bang_id == bangid && itemIds.Contains(p.icitem_id)).Result); // //物料库存占用表 // sklist.AddRange(_ic_item_stockoccupy.GetListAsync(x => x.bang_id == bangid && !x.IsDeleted && itemIds.Contains(x.icitem_id)).Result); // //物料提前期 // leadTimeList = GetLeadTime(icitemlist, param.company_id, param.factoryId);//提前期列表 // supplierList = GetSupplier(itemIds, param.company_id, param.factoryId);//供应商列表 // //交期回复 // var sql = $"select b.id as polist_id,b.po_id,a.id,a.wlbm,a.cgdd,a.ddhh,iif(a.jhdsl>c.QtyOrded,c.QtyOrded,a.jhdsl) as jhdsl,TRY_CONVERT(DATE,jqhf, 23) as jqhf,a.flag,a.gysdm,b.pr_purchase_id " + // $"from (select wlbm,cgdd,ddhh,flag,gysdm,sum(cast(isnull(jhdsl,0) as decimal(18,8))) as jhdsl,max(TRY_CONVERT(DATE,jqhf, 23)) as jqhf,max(id) as id from scm_jhjh_jq where flag =0 or (flag=2 and DATEDIFF(DAY, isnull(TRY_CONVERT(DATE,jqhf, 23),GETDATE()), GETDATE())>=1 ) group by wlbm,cgdd,ddhh,flag,gysdm) a " + // $"inner join srm_po_list b on a.cgdd=b.po_billno and a.ddhh=b.polist_row inner join PurOrdDetail c on b.po_billno=c.PurOrd and b.polist_row=c.Line where c.status!='C' and c.QtyOrded>c.RctQty"; // _CalcBomViewAppService.scm_Jhjh_Jqs = _businessDbContext.scm_jhjh_jqDto.FromSqlRaw(sql).ToList(); // //送货单子表所有未完成的数据,并且排除检验中数量 // sql = $"select b.id,[po_billline],[jhdbh],isnull([shzt],'待收') shzt,[jhdhh] ,b.sh_material_code,b.sh_material_name,b.po_bill,b.sh_delivery_quantity-isnull(m.qty,0) as sh_delivery_quantity,a.sh_purchase_num,c.id as sh_purchase_id,CONVERT(DATE,a.jhshrq,23) jhshrq,CONVERT(DATE,a.yjdhrq,23) yjdhrq,d.id as polist_id " + // $"from scm_shd a INNER join scm_shdzb b on a.id=b.glid INNER join srm_po_list d on b.sh_material_code=d.ItemNum and b.po_bill=d.po_billno and b.po_billline=d.polist_row and d.state=1 left join srm_po_main e on d.po_id=e.id " + // $"left join srm_supplier c on a.sh_purchase_num=c.supplier_no left join (select PurOrd,PurLine,ShipperNbr,ShipperLine,sum(qty) as qty from MissedPrint where Status = 'I' GROUP BY PurOrd,PurLine,ShipperNbr,ShipperLine) m on b.po_bill=m.PurOrd AND b.po_billline=m.PurLine and m.ShipperNbr=a.shddh and m.ShipperLine=b.hh " + // $"where jhdbh!='' and e.state<>'3' and isnull([shzt],'待收')!='完成' and (isnull(m.qty,0)=0 or isnull(m.qty,0)=b.sh_delivery_quantity and isnull(m.qty,0)<>0 and e.state<>'3'"; // _CalcBomViewAppService.scm_ShdzbJYs = _businessDbContext.scm_shdzbDto.FromSqlRaw(sql).ToList(); // _CalcBomViewAppService.leadTimeList = leadTimeList; // _CalcBomViewAppService.supplierList = supplierList; // //资源检查添加产线工序等数据 // _CalcBomViewAppService.prodLines = prodLines; // _CalcBomViewAppService.routingOps = routingOps; // _CalcBomViewAppService.calendarWorks = calendarWorks; // _CalcBomViewAppService.qualityLineWorks = qualityLineWorks; // _CalcBomViewAppService.holidays = holidays; // _CalcBomViewAppService.mordersList = mo_Mes_Morders;//工单 // _CalcBomViewAppService.moentriesList = mo_Mes_Moentry;//工单子表 // _CalcBomViewAppService.mooccupyAllList = mes_mooccupyList;//工单占用表 // _CalcBomViewAppService.srm_Po_Lists = poDetailList; //采购明细 // _CalcBomViewAppService.srm_Po_Occupies = poOccupys; //采购占用表 // _CalcBomViewAppService.ic_item_List = icitemlist; //物料表 // _CalcBomViewAppService.srm_Pr_Mains = srm_pr_mains.Where(s => s.state != 4).ToList();//PR // DateTime dt = DateTime.Now; // _CalcBomViewAppService.quarter_starttime = dt.AddMonths(0 - (dt.Month - 1) % 3).AddDays(1 - dt.Day).Date; // _CalcBomViewAppService.quarter_endtime = _CalcBomViewAppService.quarter_starttime.AddMonths(3); // _CalcBomViewAppService.quarter_srm_pr_mains = _srm_pr_main.GetListAsync(s => s.state != 0 && s.pr_psend_date >= _CalcBomViewAppService.quarter_starttime && s.pr_psend_date < _CalcBomViewAppService.quarter_endtime).Result;//本季度PR //} #endregion /// /// 物料数据计算前准备 /// /// /// /// /// /// /// /// /// /// /// /// /// public void DataInitialization(List boms, long bangid, List icitemlist, List stocklist, List pretreatments, List sklist, bool writeNum = false) { List itemIds = pretreatments.Select(p => p.item_id.GetValueOrDefault()).Distinct().ToList(); if (!icitemlist.Any()) { icitemlist.AddRange(_ic_item.GetListAsync(p => itemIds.Contains(p.mysql_id) && !p.IsDeleted).Result); } #region 1、数据准备 //产线明细 prodLines = _prodLineDetail.Select(p => p.Domain == param.factoryId.ToString()).ToList(); //标准工序 routingOps = _routingOpDetail.Select(p => p.Domain == param.factoryId.ToString()).ToList(); List lines = prodLines.Select(p => p.Line).Distinct().ToList(); //工作日历 calendarWorks = _shopCalendarWorkCtr.Select(p => lines.Contains(p.ProdLine)).ToList(); //休息日 qualityLineWorks = _qualityLineWorkDetail.Select(p => lines.Contains(p.ProdLine)).ToList(); //节假日 holidays = _holidayMaster.Select(p => p.Dated >= DateTime.Now.Date); //主工单 var ordlist = _workOrdMaster.Select(x => x.Domain == param.factoryId.ToString() && string.IsNullOrEmpty(x.Typed) == true && !string.IsNullOrEmpty(x.Status) && x.Status.ToUpper() != "C" && x.Status.ToUpper() != "P").ToList(); List mo_Mes_Morders = _mes_morder.GetListAsync(x => ordlist.Select(c => c.WorkOrd).Contains(x.morder_no) && x.company_id == param.company_id && x.factory_id == param.factoryId && x.bang_id == bangid).Result; List moids = mo_Mes_Morders.Select(p => p.mysql_id).ToList(); List mo_Mes_Moentry = _mes_moentry.GetListAsync(x => moids.Contains(x.moentry_moid)).Result; //工单占用表 List mes_mooccupyList = _mes_mooccupy.GetListAsync(x => x.moo_state == 1 && !x.IsDeleted && x.company_id == param.company_id && boms.Select(p => p.item_number).Contains(x.fitem_number) && x.bang_id == bangid).Result; List occoupyRefId = new List(); //物料采购订单明细 var poDetailList = _srm_po_list.GetListAsync(x => icitemlist.Select(p => p.mysql_id).ToList().Contains(x.icitem_id.Value) && x.bang_id == bangid && x.state == 1 && !x.IsDeleted).Result; occoupyRefId.AddRange(poDetailList.Select(p => p.mysql_id).ToList()); var srm_pr_mains = _srm_pr_main.GetListAsync(x => icitemlist.Select(p => p.mysql_id).ToList().Contains(x.icitem_id.Value) && x.bang_id == bangid && x.state != 0 && x.state != 4 && !x.IsDeleted).Result; occoupyRefId.AddRange(srm_pr_mains.Select(p => p.mysql_id).ToList()); //采购订单或采购申请占用数据 var poOccupys = _srm_po_occupy.GetListAsync(x => occoupyRefId.Contains(x.polist_id) && x.bang_id == bangid && !x.IsDeleted).Result; #endregion //物料库存 stocklist.AddRange(_ic_item_stock.GetListAsync(p => p.factory_id == param.factoryId && p.bang_id == bangid && itemIds.Contains(p.icitem_id)).Result); //物料库存占用表 sklist.AddRange(_ic_item_stockoccupy.GetListAsync(x => x.bang_id == bangid && !x.IsDeleted && itemIds.Contains(x.icitem_id)).Result); //物料提前期 leadTimeList = GetLeadTime(icitemlist, param.company_id, param.factoryId);//提前期列表 supplierList = GetSupplier(itemIds, param.company_id, param.factoryId);//供应商列表 //交期回复 var sql = $"select b.id as polist_id,b.po_id,a.id,a.wlbm,a.cgdd,a.ddhh,iif(a.jhdsl>c.QtyOrded,c.QtyOrded,a.jhdsl) as jhdsl,TRY_CONVERT(DATE,jqhf, 23) as jqhf,a.flag,a.gysdm,b.pr_purchase_id " + $"from (select wlbm,cgdd,ddhh,flag,gysdm,sum(cast(isnull(jhdsl,0) as decimal(18,8))) as jhdsl,max(TRY_CONVERT(DATE,jqhf, 23)) as jqhf,max(id) as id from scm_jhjh_jq where flag =0 or (flag=2 and DATEDIFF(DAY, isnull(TRY_CONVERT(DATE,jqhf, 23),GETDATE()), GETDATE())>=1 ) group by wlbm,cgdd,ddhh,flag,gysdm) a " + $"inner join srm_po_list b on a.cgdd=b.po_billno and a.ddhh=b.polist_row inner join PurOrdDetail c on b.po_billno=c.PurOrd and b.polist_row=c.Line where c.status!='C' and c.QtyOrded>c.RctQty"; _CalcBomViewAppService.scm_Jhjh_Jqs = _businessDbContext.scm_jhjh_jqDto.FromSqlRaw(sql).ToList(); //送货单子表所有未完成的数据,并且排除检验中数量 sql = $"select b.id,[po_billline],[jhdbh],isnull([shzt],'待收') shzt,[jhdhh] ,b.sh_material_code,b.sh_material_name,b.po_bill,b.sh_delivery_quantity-isnull(m.qty,0) as sh_delivery_quantity,a.sh_purchase_num,c.id as sh_purchase_id,CONVERT(DATE,a.jhshrq,23) jhshrq,CONVERT(DATE,a.yjdhrq,23) yjdhrq,d.id as polist_id " + $"from scm_shd a INNER join scm_shdzb b on a.id=b.glid INNER join srm_po_list d on b.sh_material_code=d.ItemNum and b.po_bill=d.po_billno and b.po_billline=d.polist_row and d.state=1 left join srm_po_main e on d.po_id=e.id " + $"left join srm_supplier c on a.sh_purchase_num=c.supplier_no left join (select PurOrd,PurLine,ShipperNbr,ShipperLine,sum(qty) as qty from MissedPrint where Status = 'I' GROUP BY PurOrd,PurLine,ShipperNbr,ShipperLine) m on b.po_bill=m.PurOrd AND b.po_billline=m.PurLine and m.ShipperNbr=a.shddh and m.ShipperLine=b.hh " + $"where jhdbh!='' and e.state<>'3' and isnull([shzt],'待收')!='完成' and (isnull(m.qty,0)=0 or isnull(m.qty,0)=b.sh_delivery_quantity and isnull(m.qty,0)<>0 and e.state<>'3'"; _CalcBomViewAppService.scm_ShdzbJYs = _businessDbContext.scm_shdzbDto.FromSqlRaw(sql).ToList(); _CalcBomViewAppService.leadTimeList = leadTimeList; _CalcBomViewAppService.supplierList = supplierList; //资源检查添加产线工序等数据 _CalcBomViewAppService.prodLines = prodLines; _CalcBomViewAppService.routingOps = routingOps; _CalcBomViewAppService.calendarWorks = calendarWorks; _CalcBomViewAppService.qualityLineWorks = qualityLineWorks; _CalcBomViewAppService.holidays = holidays; _CalcBomViewAppService.mordersList = mo_Mes_Morders;//工单 _CalcBomViewAppService.moentriesList = mo_Mes_Moentry;//工单子表 _CalcBomViewAppService.mooccupyAllList = mes_mooccupyList;//工单占用表 _CalcBomViewAppService.srm_Po_Lists = poDetailList; //采购明细 _CalcBomViewAppService.srm_Po_Occupies = poOccupys; //采购占用表 _CalcBomViewAppService.ic_item_List = icitemlist; //物料表 _CalcBomViewAppService.srm_Pr_Mains = srm_pr_mains.Where(s => s.state != 4).ToList();//PR DateTime dt = DateTime.Now; _CalcBomViewAppService.quarter_starttime = dt.AddMonths(0 - (dt.Month - 1) % 3).AddDays(1 - dt.Day).Date; _CalcBomViewAppService.quarter_endtime = _CalcBomViewAppService.quarter_starttime.AddMonths(3); _CalcBomViewAppService.quarter_srm_pr_mains = _srm_pr_main.GetListAsync(s => s.state != 0 && s.pr_psend_date >= _CalcBomViewAppService.quarter_starttime && s.pr_psend_date < _CalcBomViewAppService.quarter_endtime).Result;//本季度PR } public void GenerateSort(List returnlist) { int level = returnlist.Max(s => s.level); returnlist.ForEach(s => { int num = level - s.level; if (num > 0) { s.num_order = long.Parse((s.num_order * Math.Pow(1000, num)).ToString()); } }); } /// /// 物料和BOM前置数据准备 /// /// /// /// /// /// /// /// public void IcItemPretreatment(bool flag, List boms, List bomlist, List bomchildlist, List icitemlist, List sublist, List suballlist, List subdtllist) { //获取物料bom,物料bom明细 GetIcBomData(boms, bomlist, bomchildlist, flag); //根据明细集合查出所有得替代关系表数据集合 List codeList = bomchildlist.Select(c => c.substitute_code).Distinct().ToList(); sublist.AddRange(_ic_substitute.GetListAsync(p => codeList.Contains(p.substitute_code) && !p.IsDeleted).Result); List subidlist = sublist.Select(c => c.mysql_id).Distinct().ToList(); suballlist.AddRange(_ic_substitute_group.GetListAsync(p => subidlist.Contains(p.substitute_group_id) && !p.IsDeleted).Result); List suballidlist = suballlist.Select(c => c.mysql_id).Distinct().ToList(); subdtllist.AddRange(_ic_substitute_group_detail.GetListAsync(p => suballidlist.Contains(p.substitute_group_id) && !p.IsDeleted).Result); //获取物料数据 List itemIds = bomlist.Select(p => p.icitem_id).ToList(); itemIds.AddRange(bomchildlist.Select(p => p.icitem_id).ToList()); itemIds.AddRange(subdtllist.Select(p => p.icitem_id).ToList()); icitemlist.AddRange(_ic_item.GetListAsync(p => itemIds.Contains(p.mysql_id) && !p.IsDeleted).Result); } /// /// 自动生成BOM预处理清单 /// public void AutoCreateBomBill(string companyid, List ic_Boms = null) { try { bool flag = false; if (ic_Boms == null) { flag = true; ic_Boms = _ic_bom.GetListAsync(p => p.company_id.ToString() == companyid && !p.IsDeleted).Result.ToList(); } var pretreatment = _mysql_b_bom_pretreatment.GetListAsync(s => ic_Boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; param.company_id = long.Parse(companyid); //物料bom List bomlist = new List(); List bomchildlist = new List(); //物料信息 List icitemlist = new List(); //替代关系 List sublist = new List(); List suballlist = new List(); List subdtllist = new List(); IcItemPretreatment(flag, ic_Boms, bomlist, bomchildlist, icitemlist, sublist, suballlist, subdtllist); List deleteList = new List(); List addList = new List(); foreach (var bom in ic_Boms) { var pret = pretreatment.Where(s => s.sourceid == bom.mysql_id).ToList(); if (pret.Any()) { //版本不同则重新生成 deleteList.AddRange(pret); } //bom层级组装 var getBomList = _pretreatmentAppService.BomPretreatment(bom.mysql_id, bomlist, bomchildlist, icitemlist); //bom替代关系组装 _pretreatmentAppService.BomSubstitute(getBomList, bomlist, bomchildlist, icitemlist, sublist, suballlist, subdtllist); //GenerateSort(getBomList); var list = ObjectMapper.Map, List>(getBomList); list.ForEach(s => { s.sourceid = bom.mysql_id; s.company_id = bom.company_id; s.tenant_id = bom.tenant_id; s.factory_id = bom.factory_id; }); addList.AddRange(list); } if (deleteList.Any()) { _businessDbContext.BulkDelete(deleteList); } if (addList.Any()) { _businessDbContext.BulkInsert(addList); } } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("AutoCreateBomBill", "自动生成BOM预处理清单:" + e.Message, _currentTenant.Id.ToString()); } } /// /// BOM清单批量预处理 /// public void AutoCreateBomBillInterface(string companyid) { AutoCreateBomBill(companyid); } public async Task AutoCreatePickBill(List workOrdMasters, List dbPeriodSequences, List nbrMasterList, List nbrDetailList, string userAccount, List workDetails) { //获取工序对应的产线,根据优先级排序 var lines = _prodLineDetail.Select(p => workOrdMasters.Select(x=>x.ItemNum).ToList().Contains( p.Part)).OrderBy(p => p.Sequence).ToList(); if (lines.Any()) { //List AllLines = dbPeriodSequences.Where(a => workOrdMasters.Select(b => b.WorkOrd).Contains(a.WorkOrds)).Select(a => a.Line).Distinct().ToList(); List AllLines = lines.Select(a => a.Line).Distinct().ToList(); List AllLineMasters = _lineMaster.Select(p => AllLines.Contains(p.Line) && p.Domain == workOrdMasters[0].Domain && p.IsActive); var user = _employeeMaster.Select(s => s.Employee == userAccount && s.Domain == workOrdMasters[0].Domain).FirstOrDefault(); var ewdmList = _empWorkDutyMaster.Select(s => s.Domain == workOrdMasters[0].Domain).ToList(); //需要前处理物料 var Items = _mysql_ic_item.GetListAsync(s => workDetails.Select(c => c.ItemNum).Contains(s.number) && s.factory_id.ToString() == workOrdMasters[0].Domain).Result; List itemMasterList = _itemMaster.Select(p => workDetails.Select(c => c.ItemNum).Contains(p.ItemNum) && p.Domain == workOrdMasters[0].Domain).Distinct().ToList(); //1.读取配置的补班、法休。默认周六周日休息,如果周六是工作日,需在配置中维护好每周六的都设置为补班。 var holidayList = _holidayMaster.Select(x => x.IsActive == true && x.Domain == workOrdMasters[0].Domain && (x.Dated.Value.Year == DateTime.Now.Year || x.Dated.Value.Year == DateTime.Now.Year + 1)).ToList(); //按照工单领料,之前是按照排产日期和产线分别领料 foreach (var workord in workOrdMasters) { Dictionary dictItemQty = new Dictionary(); string LocationTo = ""; LineMaster defaultLine = null; //var dftPs = dbPeriodSequences.Where(a => a.WorkOrds == workord.WorkOrd).OrderBy(s => s.CreateTime).FirstOrDefault(); var dftPs = lines.Where(a => a.Part == workord.ItemNum).OrderBy(s => s.Sequence).FirstOrDefault(); if (dftPs != null) { List lineMasters = AllLineMasters.Where(p => p.Line == dftPs.Line && p.Domain == workord.Domain && p.IsActive).ToList(); if (lineMasters.Any()) { defaultLine = lineMasters.FirstOrDefault(); } LocationTo = defaultLine?.Location; } var workdtls = workDetails.Where(s => s.WorkOrd == workord.WorkOrd).ToList(); //List itemList = GetProductStructure(dbPeriodSequences.First(a => a.WorkOrds == workord.WorkOrd).ItemNum, QtyOrdSum, workord.Domain); //var childrenList = itemList.Select(a => a.ComponentItem).Distinct().ToList(); List itemLocList = itemMasterList.Where(p => workdtls.Select(c => c.ItemNum).Contains(p.ItemNum) && p.Domain == workord.Domain).Distinct().ToList(); List cleanDetail = new List(); List noCleanDetail = new List(); workdtls.ForEach(s => { var i = Items.Find(x => x.number == s.ItemNum && x.is_clean == 1); if (i != null) { cleanDetail.Add(s); } else { noCleanDetail.Add(s); } }); //获取预处理提前期最大值 decimal cleanTime = 0; if (noCleanDetail.Any()) { //无需前处理领料单 GenerateNbr(workord, cleanTime, defaultLine, userAccount, nbrMasterList, nbrDetailList, noCleanDetail, itemLocList, ewdmList, LocationTo, user, "", holidayList); } if (cleanDetail.Any()) { //需要前处理的领料单 cleanTime = Items.Where(s => cleanDetail.Select(i => i.ItemNum).Contains(s.number)).Max(s => s.clean_leadtime.GetValueOrDefault()); GenerateNbr(workord, cleanTime, defaultLine, userAccount, nbrMasterList, nbrDetailList, cleanDetail, itemLocList, ewdmList, LocationTo, user, "PrevProcess", holidayList); } //List itemPackList = _itemPackMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == workord.Domain && p.IsActive).Distinct().ToList(); /*//先屏蔽备料单扣除库存的DEMO演示。 nbrDetailList.ForEach(a => { if (a.Nbr == Nbr) { var find = itemLocList?.Find(c => c.ItemNum == a.ItemNum); var packfind = itemPackList?.Find(c => c.ItemNum == a.ItemNum); if (find != null && !find.TraceDetail && packfind != null && packfind.PackingQty > 0) { a.CurrQtyOpened = Math.Ceiling(a.CurrQtyOpened.GetValueOrDefault() / packfind.PackingQty.GetValueOrDefault()) * packfind.PackingQty; dictItemQty.Add(a.ItemNum, QtyOrdSum * itemList.First(b => b.ComponentItem == a.ItemNum).Qty); } else { dictItemQty.Add(a.ItemNum, QtyOrdSum * itemList.First(b => b.ComponentItem == a.ItemNum).Qty); } } }); List itemKeys = dictItemQty.Keys.ToList(); decimal leadTimes = itemLocList.Select(a => a.MFGMTTR).Max(); //没有维护备料提前期,默认取7天 if (leadTimes > 0) { nbrMasterList.First(a => a.Nbr == Nbr).Date = dbPeriodSequences.Where(a => a.WorkOrds == workord.WorkOrd).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-1 * Convert.ToDouble(leadTimes)); } else { nbrMasterList.First(a => a.Nbr == Nbr).Date = dbPeriodSequences.Where(a => a.WorkOrds == workord.WorkOrd).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-7); } //TODO: //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。 //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。 var locStock = _locationDetail.Select(a => itemKeys.Contains(a.ItemNum) && a.IsActive && a.Domain == workOrdMasters[0].Domain); locStock?.ForEach(a => { nbrDetailList.ForEach(b => { if (a.ItemNum == b.ItemNum && a.Location == b.LocationFrom && a.QtyOnHand - dictItemQty[a.ItemNum] > 0) { a.QtyOnHand -= dictItemQty[a.ItemNum]; } }); }); _locationDetail.Update(locStock);*/ } if (nbrMasterList.Any()) { var nbrlistDto = _serialNumberAppService.GetBillNo(workOrdMasters[0].Domain, "SM", nbrMasterList.Count, userAccount, 1); if (nbrlistDto.Any()) { int index = 0; foreach (var nm in nbrMasterList) { var nbrDtls = nbrDetailList.Where(s => s.Nbr == nm.Nbr).ToList(); if (nbrlistDto[index] != null) { nm.Nbr = nbrlistDto[index].NbrResult.ToString(); nbrDtls.ForEach(i => { i.Nbr = nm.Nbr; }); } index++; } } } } } private void GenerateNbr(WorkOrdMaster workord, decimal cleanTime, LineMaster defaultLine, string userAccount, List nbrMasterList, List nbrDetailList, List detail, List itemLocList, List ewdmList, string LocationTo, EmployeeMaster user, string TransType, List holidayList) { string Nbr = help.NextId().ToString(); //DateTime eff = workord.OrdDate.GetValueOrDefault().Date.AddDays(-1); DateTime eff = _holidayHelper.GetWorkDateByWorkCalendar(workord.OrdDate.GetValueOrDefault(), 1, holidayList); DateTime start = _holidayHelper.GetWorkDateByWorkCalendar(eff, (int)Math.Ceiling(cleanTime), holidayList); if (start <= DateTime.Now.Date) { start = DateTime.Now.Date; } if (eff <= DateTime.Now.Date) { eff = DateTime.Now.Date; } var newNbr = new NbrMaster { Domain = workord.Domain, Type = "SM", Nbr = Nbr, Remark = "下达自动领料", //Date = dbPeriodSequences.Where(a => a.WorkOrds == workord.WorkOrd).Min(a => a.PlanDate), ProdLine = defaultLine?.Line, EffDate = eff, Date = start, Status = "", WorkOrd = workord.WorkOrd, QtyOrd = workord.QtyOrded, IsActive = true, IsChanged = true, Name = userAccount, Department = "101", CreateTime = DateTime.Now, UpdateTime = DateTime.Now, CreateUser = user?.Name, UpdateUser = user?.Name, TransType = TransType }; nbrMasterList.Add(newNbr); List headAccount = new List(); short i = 1; //bool typed = !string.IsNullOrEmpty(workord.Typed); detail.ForEach(a => { var find = itemLocList?.Find(c => c.ItemNum == a.ItemNum); string LocationFrom = ""; if (find != null) { //LocationFrom = find.Location; //找出职责范围负责人 var ewdm = ewdmList.Find(s => 0 >= string.Compare(s.ItemNum1, a.ItemNum) && 0 >= string.Compare(a.ItemNum, s.ItemNum2)); if (ewdm != null && !string.IsNullOrEmpty(ewdm.Employee)) { headAccount.Add(ewdm.Employee); } //相同物料汇总 var itemComponent = nbrDetailList.Find(b => b.Nbr == Nbr && b.ItemNum == a.ItemNum); if (itemComponent == null) { nbrDetailList.Add(new NbrDetail { Domain = workord.Domain, Type = "SM", Nbr = Nbr, ItemNum = a.ItemNum, QtyFrom = 0, QtyTo = 0, LocationFrom = string.IsNullOrEmpty(a.Location) == true ? find.Location : a.Location, LocationTo = LocationTo,//现在这几条线是同一线边仓,暂时不考虑多个线边仓 WorkOrd = workord.WorkOrd, QtyOrd = a.QtyRequired, CurrQtyOpened = a.QtyRequired, Line = i, IsActive = true, CreateTime = DateTime.Now, UpdateTime = DateTime.Now, CreateUser = user?.Name, UpdateUser = user?.Name, UM = find.UM, LotSerial = a.LotSerial, ItemName = find.Descr, Status = "" }); i++; } else { itemComponent.QtyOrd += a.QtyRequired; itemComponent.CurrQtyOpened += a.QtyRequired; //nbrDetailList.First(b => b.Nbr == Nbr && b.ItemNum == a.ItemNum).QtyOrd = itemComponent.QtyOrd + a.QtyRequired; //nbrDetailList.First(b => b.Nbr == Nbr && b.ItemNum == a.ItemNum).CurrQtyOpened = itemComponent.CurrQtyOpened + a.QtyRequired; } } }); if (headAccount.Any()) { newNbr.User1 = string.Join(",", headAccount.Distinct()); string[] user2 = headAccount.Distinct().ToArray(); newNbr.User2 = JsonConvert.SerializeObject(user2); } } public async Task AsyncItemStockFromWMS(List bom_Pretreatments) { //释放库存占用记录 await _systemJobAppService.SyncItemStockOccupyClear(); //产品编码 var itemList = bom_Pretreatments.Select(a => a.item_number).Distinct().ToList(); List itemChildList = new List(); itemChildList.AddRange(itemList); if (!itemChildList.Any()) { return; } //List locationList = new List { "1000", "1001", "5008", "8000", "8001" }; var locationRange = _configurationItem.Select(x => x.FldName == "MRPLocationRange" && x.Domain == param.factoryId.ToString()).FirstOrDefault(); List locationList = new List { "1000", "1001", "5008", "8000", "8001" }; if (locationRange != null && locationRange.Val != null) { locationList = locationRange.Val.SplitToArray(",").ToList(); } if (!param.checkPlan) { if (locationList.Contains("1000")) { locationList.Remove("1000"); } } var locStock = _invMaster.Select(a => itemChildList.Contains(a.ItemNum) && a.IsActive && a.Domain == param.factoryId.ToString() && locationList.Contains(a.Location)); //var sapInvList = _SAPInv.Select(a => a.WERKS == param.factoryId.ToString() && itemChildList.Contains(a.MATNR) && (a.SOBKZ.ToUpper() == "O" || locationList.Contains(a.LGORT))); //var sapInvList = _SAPInv.Select(a => a.WERKS == param.factoryId.ToString() && itemChildList.Contains(a.MATNR) && locationList.Contains(a.LGORT)); //根据WMS物料,取出DOP物料数据 var items = _mysql_ic_item.GetListAsync(a => itemChildList.Contains(a.number) && a.factory_id == param.factoryId).Result; var itemIds = items.Select(b => b.Id).ToList();//需要处理的dop物料id集合 List mysqlStock = _mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.icitem_id) && a.factory_id == param.factoryId).Result; List needAddList = new List(); List needupdList = new List(); foreach (var stockWMS in itemChildList) { var num = items.Find(x => x.number == stockWMS); if (num != null) { var item = mysqlStock.Find(a => a.icitem_id == num.Id); if (item != null) { needupdList.Add(item); } else { item = new ic_item_stock(); item.GenerateNewId(help.NextId()); item.tenant_id = param.company_id; item.factory_id = param.factoryId; item.company_id = param.company_id; item.icitem_id = num.Id; item.icitem_number = num.number; item.icitem_name = num.name; needAddList.Add(item); } item.sqty = 0; foreach (var lct in locationList) { var lctQty = locStock.Where(s => s.ItemNum == item.icitem_number && s.Location == lct).Sum(p => p.AvailStatusQty.GetValueOrDefault() + p.Assay.GetValueOrDefault()); //if (lctQty == 0) //{ // lctQty = sapInvList.Where(x => x.MATNR == item.icitem_number && x.LGORT == lct).Sum(p => p.LABST + p.INSME); //} item.sqty += lctQty; } /*if (param.checkPlan) { item.sqty += sapInvList.Where(x => x.MATNR == item.icitem_number && x.SOBKZ.ToUpper() == "O").Sum(p => p.LABST + p.INSME); }*/ } } if (needAddList.Count > 0) { _businessDbContext.BulkInsert(needAddList); } _businessDbContext.BulkUpdate(needupdList); } /// /// 生成领料单 /// /// public async Task CreatePickBill(string workOrd, string domain, string userAccount) { List workOrds = new List(); List workOrdMasters = new List(); if (string.IsNullOrEmpty(workOrd)) { //获取工单数据 workOrdMasters = _workOrdMaster.Select(p => p.Domain == domain && p.OrdDate >= DateTime.Now.Date.AddDays(1) && p.OrdDate < DateTime.Now.Date.AddDays(4) && p.Status.ToLower() == "p"); } else { workOrds = workOrd.Split(",").ToList(); if (workOrds.Count == 0) { return "没有需要下达的工单。"; } workOrdMasters = _workOrdMaster.Select(p => p.Domain == domain && workOrds.Contains(p.WorkOrd) && p.Status.ToLower() == "p"); } if (workOrdMasters.Count == 0) { return "没有需要下达的工单。"; } //获取已排产的工单 //List dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == domain && p.IsActive); //List dbWorkOrds = dbPeriodSequences.Select(p => p.WorkOrds).Distinct().ToList(); //查出已排产的工单 //workOrdMasters = workOrdMasters.Where(p => dbWorkOrds.Contains(p.WorkOrd)).ToList(); //查出已产生领料单、过滤掉,取出未领料的工单 var nbrList = _nbrMaster.Select(a => a.Domain == domain && a.Type == "SM"); //&& dbWorkOrds.Contains(a.WorkOrd)); var noNbrlist = nbrList.Select(p => p.WorkOrd).ToList(); workOrdMasters = workOrdMasters.Where(p => !noNbrlist.Contains(p.WorkOrd)).ToList(); if (workOrdMasters.Count == 0) { return "当前选择的工单包含已生成领料单。"; } //增加判断当前工单是否进行过齐套检查,并且是仓库齐套 /*var mes_morders = _mysql_mes_morder.GetListAsync(s => dbWorkOrds.Contains(s.morder_no) && s.factory_id.ToString() == domain).Result; if (mes_morders.Where(s => s.MaterialSituation != MorderEnum.CarehouseComplete).Any()) { return "请选择物料情况为“仓库齐套”的工单。"; }*/ List nbrMasterList = new List();//需要生成领料单列表 List nbrDetailList = new List();//需要生成领料单明细列表 var ords = workOrdMasters.Select(p => p.WorkOrd).ToList(); var workDetails = _workOrdDetail.Select(p => p.Domain == domain && p.IsActive && workOrds.Contains(p.WorkOrd)); List morders = _mysql_mes_morder.GetListAsync(x => domain == x.factory_id.ToString() && workOrdMasters.Select(s => s.WorkOrd).Contains(x.morder_no) && !x.IsDeleted).Result; if (!workDetails.Any()) { var rtn = await OrderKittingCheck(morders); workDetails = _workOrdDetail.Select(p => p.Domain == domain && p.IsActive && workOrds.Contains(p.WorkOrd)); } //dbPeriodSequences = dbPeriodSequences.Where(p => ords.Contains(p.WorkOrds)).ToList(); await AutoCreatePickBill(workOrdMasters, null, nbrMasterList, nbrDetailList, userAccount, workDetails); if (nbrMasterList.Any()) { workOrdMasters = workOrdMasters.Where(x => nbrMasterList.Select(c => c.WorkOrd).Contains(x.WorkOrd)).ToList(); morders.ForEach(x => { x.morder_state = MorderEnum.Xd_state; }); string seqSql = ""; var weekplan = _replenishmentWeekPlan.GetListAsync(s => s.factory_id.ToString() == domain && s.IsReplenishmentModel == "N" && workOrdMasters.Select(x => x.WorkOrd).Contains(s.ProductionOrder)).Result; //var worklistDto = _serialNumberAppService.GetBillNo(domain, "WOlot", workOrdMasters.Count, userAccount, 1); var rstSeqId = _serialNumberAppService.GetSeqIdList(domain, 1, 1); long seqId = 0; long.TryParse(rstSeqId, out seqId); //string strWoSql = ""; //string strWoStuSql = ""; int index = 0; workOrdMasters.ForEach(p => { p.Status = "r"; /*if (worklistDto.Any()) { if (worklistDto[index] != null) { p.LotSerial = worklistDto[index].NbrResult.ToString(); var weekp = weekplan.Find(s => s.ProductionOrder == p.WorkOrd && s.IsReplenishmentModel == "N"); if (weekp != null) { weekp.ProductionBatch = p.LotSerial; } } index++; }*/ //生成工单事务、工单下达事务 //strWoSql += "A," + p.Domain + "," + seqId.ToString() + ",nbr-wo-mes,工单," + p.WorkOrd + "," + p.RecID + "|"; //seqId++; //strWoStuSql += "REL," + p.Domain + "," + seqId.ToString() + ",nbr-wo-stu,工单下达," + p.WorkOrd + "," + p.RecID + "|"; //seqId++; p.Batch = p.WorkOrd.Substring(1); }); var nbrlistDto = _serialNumberAppService.GetBillNo(workOrdMasters[0].Domain, "SM", nbrMasterList.Count, userAccount, 1); if (nbrlistDto.Any()) { index = 0; foreach (var nm in nbrMasterList) { var nbrDtls = nbrDetailList.Where(s => s.Nbr == nm.Nbr).ToList(); if (nbrlistDto[index] != null) { nm.Nbr = nbrlistDto[index].NbrResult.ToString(); nm.Address = nm.WorkOrd.Substring(1); nm.Ufld1 = nm.WorkOrd.Substring(1); nbrDtls.ForEach(i => { i.Nbr = nm.Nbr; }); } index++; } } //清理掉库存占用 这里考虑的是资源检查的占用没有完全占用备料单数据,而其他数据再进行齐套检查时,无法考虑到备料单的占用。 var itemstockoccupy = _mysql_ic_item_stockoccupy.GetListAsync(s => workOrdMasters.Select(x => x.WorkOrd).Contains(s.morder_mo) && s.factory_id.ToString() == domain).Result; var icitem = _mysql_ic_item.GetListAsync(s => s.factory_id.ToString() == domain && nbrDetailList.Select(c => c.ItemNum).Contains(s.number)).Result; //根据领料单生成一次工单的数据占用 List insertOccuyy = new List(); nbrMasterList.ForEach(s => { var nbrdtls = nbrDetailList.Where(a => a.Nbr == s.Nbr).ToList(); nbrdtls.ForEach(x => { ic_item_stockoccupy itemStockoccupyDto = new ic_item_stockoccupy(); itemStockoccupyDto.GenerateNewId(help.NextId()); itemStockoccupyDto.morder_mo = s.WorkOrd; itemStockoccupyDto.occupy_time = DateTime.Now; var nbrItem = icitem.Find(c => c.number == x.ItemNum); if (nbrItem != null) { itemStockoccupyDto.icitem_id = nbrItem.Id; itemStockoccupyDto.icitem_number = nbrItem.number; itemStockoccupyDto.tenant_id = nbrItem.tenant_id; itemStockoccupyDto.factory_id = nbrItem.factory_id; itemStockoccupyDto.org_id = nbrItem.org_id; itemStockoccupyDto.company_id = nbrItem.company_id; itemStockoccupyDto.quantity = x.CurrQtyOpened.GetValueOrDefault(); insertOccuyy.Add(itemStockoccupyDto); } }); seqSql += "insert QadTracking(Ufld1,Domain,SeqID,TransType,Subject,[Order],Int1,Ufld2,CreateTime,CreateUser,UpdateTime,UpdateUser) " + "select 'A','" + domain + "'," + seqId.ToString() + ",'nbr-sm-mes','领料申请单',Nbr,RecID,'sm',getdate(),CreateUser,getdate(),UpdateUser from NbrMaster where RecID=" + s.RecID + ";"; seqId++; }); //获取工单工艺路径数据 List workOrdRoutings = _workOrdRouting.Select(p => workOrdMasters.Select(x => x.WorkOrd).Contains(p.WorkOrd) && p.MilestoneOp && p.Domain == domain && p.Status != "C" && p.IsActive); workOrdRoutings.ForEach(p => { p.Status = "r"; }); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { _workOrdMaster.Update(workOrdMasters); _workOrdRouting.Update(workOrdRoutings); _nbrMaster.Insert(nbrMasterList); //nbrMasterList.ForEach(a => //{ // string sql = string.Format("exec pr_WMS_BPM_AddMobileTask @TaskID='{0}',@PlanDate='{1}',@ExecuterTypeID=2,@CreateUser='{2}'", a.Nbr, a.Date.Value.ToString("yyyy-MM-dd"), a.CreateUser); // _businessDbContext.Database.ExecuteSqlRaw(sql); //}); //if (!string.IsNullOrEmpty(strWoSql)) //{ // strWoSql = strWoSql.Substring(0, strWoSql.Length - 1); // strWoStuSql = strWoStuSql.Substring(0, strWoStuSql.Length - 1); // string sql = string.Format("exec pr_WMS_AddWorkOrdSeq @strWoSql='{0}',@strWoStuSql='{1}'", strWoSql, strWoStuSql); // _businessBangDbContext.Database.ExecuteSqlRaw(sql); //} if (!string.IsNullOrEmpty(seqSql)) { _businessBangDbContext.Database.ExecuteSqlRaw(seqSql); } if (itemstockoccupy.Any()) { await _mysql_ic_item_stockoccupy.HardDeleteAsync(itemstockoccupy); } if (insertOccuyy.Any()) { _businessDbContext.BulkInsert(insertOccuyy); } //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值 List nbrs = nbrMasterList.Select(a => a.Nbr).ToList(); var DBnbrList = _nbrMaster.Select(a => a.Domain == workOrdMasters[0].Domain && a.Type == "SM" && nbrs.Contains(a.Nbr)); nbrDetailList.ForEach(c => { c.NbrRecID = DBnbrList.Where(a => a.Nbr == c.Nbr).First().RecID; c.Address = c.WorkOrd.Substring(1); c.OrdNbr = c.WorkOrd.Substring(1); c.ERPfld1 = c.WorkOrd.Substring(1); c.OrdLine = c.Line; c.ERPfld2 = c.Line.ToString(); }); _nbrDetail.Insert(nbrDetailList); await _businessDbContext.BulkUpdateAsync(weekplan); if (morders != null) { await _businessDbContext.BulkUpdateAsync(morders); } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + e.Message, _currentTenant.Id.ToString()); return e.Message; } } } else { return "当前工单下达失败,请检查工单信息。"; } return "ok"; } /// /// 同步工单等相关数据 /// /// /// 工艺路线数据 public void CreateWorkOrdDates(List morders, List WriteMoentry, List allRoutings, List workOrds, List workOrdRoutings, List workOrdDetails, List exmResult, List childExamineList) { //var IsActived = _AccountValidityAppService.IsActived(); //if (!IsActived) //{ // return; //} //工单主表 WorkOrdMaster workOrd; //工单工艺路线表 WorkOrdRouting woRouting; List orderCode = morders.Select(c => c.product_code).ToList(); //成品虚拟件对应关系 var productOpList = _productStructureOp.Select(x => orderCode.Contains(x.ProductItem) && x.Domain == param.factoryId.ToString()); //获取物料主数据 List itemMasters = _itemMaster.Select(p => p.Domain == param.factoryId.ToString()).ToList(); var dbworklist = _workOrdMaster.Select(x => (string.IsNullOrEmpty(x.Status) || x.Status == "p" || x.Status == "P") && (string.IsNullOrEmpty(x.Typed) || (!string.IsNullOrEmpty(x.Typed) && x.Typed.ToUpper() != "PW" && x.BusinessID > 0))).ToList(); decimal Priority = 0; if (dbworklist.Any()) { Priority = dbworklist.Max(x => x.Priority); } foreach (var item in morders) { Priority++; //添加工单数据 workOrd = new WorkOrdMaster(); workOrd.Domain = item.factory_id.ToString(); workOrd.OrdDate = item.moentry_sys_stime.GetValueOrDefault().Date; workOrd.DueDate = item.moentry_sys_etime; 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.Period = 1; workOrd.Priority = Priority; workOrd.Status = "P"; workOrd.IsActive = true; workOrd.IsConfirm = true; var curItem = itemMasters.FirstOrDefault(p => p.ItemNum == item.product_code); workOrd.CreateGLforLaborVar = curItem == null ? false : curItem.Install; workOrd.CreateTime = DateTime.Now; workOrd.Typed = ""; var me = WriteMoentry.Find(s => s.moentry_moid == item.Id); workOrd.SalesJob = me?.fbill_no; workOrd.IssueSite = "VMI"; workOrds.Add(workOrd); //添加工单工艺路线数据 var curRoutings = allRoutings.Where(p => p.RoutingCode == item.product_code).ToList(); foreach (var dtl in curRoutings) { woRouting = new WorkOrdRouting(); woRouting.Domain = item.factory_id.ToString(); 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; woRouting.CommentIndex = dtl.CommentIndex; woRouting.CreateTime = DateTime.Now; woRouting.StdOp = dtl.StdOp; woRouting.PackingQty = dtl.PackingQty.GetValueOrDefault(); workOrdRoutings.Add(woRouting); } long fid = GetParentMo(morders, item); var exm = exmResult.Find(s => s.morder_id == fid); if (exm != null) { var childs = childExamineList.Where(s => s.examine_id == exm.Id && s.is_use == true).ToList(); var child = childs.Find(s => s.item_number == item.product_code); if (child == null) { continue; } List returnList = new List(); var productOps = productOpList.Where(x => x.ProductItem == item.product_code).ToList(); GetWorkDetalis(childs.Where(s => s.parent_id == child.fid).ToList(), returnList, childs, productOps); if (returnList.Any()) { WorkOrdDetail woDetail = null; var calereturnList = returnList.OrderBy(c => c.item_number).Select(x => x.item_number).Distinct().ToList(); short num = 1; foreach (var caleNumber in calereturnList) { var caleList = returnList.Where(x => x.item_number == caleNumber).ToList(); var itemMst = itemMasters.Find(x => x.ItemNum == caleNumber); //添加工单的物料信息 woDetail = new WorkOrdDetail(); woDetail.Domain = item.factory_id.ToString(); woDetail.WorkOrd = item.morder_no; var oplist = caleList.Where(x => x.Op > 0).ToList(); woDetail.Op = 0; if (oplist.Any()) { woDetail.Op = oplist.Min(f => f.Op); } woDetail.ItemNum = caleNumber; woDetail.QtyPosted = 0m; woDetail.QtyReturned = 0m; woDetail.Status = ""; woDetail.IsActive = true; woDetail.CreateTime = DateTime.Now; woDetail.Line = num; woDetail.QtyRequired = caleList.Sum(c => c.needCount.GetValueOrDefault()); woDetail.Location = itemMst == null ? "" : itemMst.Location; if (workOrd.QtyOrded != 0) { woDetail.FrozenBOMQty = Math.Round(woDetail.QtyRequired / workOrd.QtyOrded, 10); } workOrdDetails.Add(woDetail); num++; } } } } } public long GetParentMo(List morders, mes_morder item) { if (item.parent_id != null) { var parentMo = morders.Find(s => s.Id == item.parent_id); if (parentMo != null) { return GetParentMo(morders, parentMo); } else { return item.Id; } } else { return item.Id; } } /// /// 获取虚拟件明细 /// /// /// /// public void GetWorkDetalis(List dtl, List returnList, List childs, List productOps) { returnList.AddRange(dtl.Where(x => x.erp_cls != 4).ToList()); var rst = childs.Where(s => dtl.Where(x => x.erp_cls == 4).Select(c => c.fid).Contains(s.parent_id.GetValueOrDefault())).ToList(); if (rst.Any()) { if (productOps.Any()) { //rst 虚拟件的子物料 foreach (var item in rst) { var parent = childs.Find(x => x.fid == item.parent_id); if (parent != null) { var proOp = productOps.Find(x => x.ParentItem == parent.item_number && x.ComponentItem == item.item_number); if (proOp != null) { item.Op = proOp.Op; } } } } GetWorkDetalis(rst, returnList, childs, productOps); } return; } /// /// 获取虚拟件明细 /// /// /// /// public void GetWorkDetalis(List dtl, List returnList, List childs, List productOps) { returnList.AddRange(dtl.Where(x => x.erp_cls != 4).ToList()); var rst = childs.Where(s => dtl.Where(x => x.erp_cls == 4).Select(c => c.fid).Contains(s.parent_id.GetValueOrDefault())).ToList(); if (rst.Any()) { if (productOps.Any()) { //rst 虚拟件的子物料 foreach (var item in rst) { var parent = childs.Find(x => x.fid == item.parent_id); if (parent != null) { var proOp = productOps.Find(x => x.ParentItem == parent.item_number && x.ComponentItem == item.item_number); if (proOp != null) { item.Op = proOp.Op; } } } } GetWorkDetalis(rst, returnList, childs, productOps); } return; } /// /// 获取标准Bom数据--TODO:存在循环查询数据库问题,后续调整 /// /// 产品物料编码 /// public List GetProductStructure(string itenNum, decimal QtyOrdSum, string domain) { List rtnStructures = new List(); //根据itemNum获取bom数据 var productStructures = _productStructureMaster.Select(p => itenNum == p.ParentItem && p.Domain == domain && p.IsActive); productStructures.ForEach(s => { s.Qty = s.Qty * QtyOrdSum; }); //添加非虚拟件 rtnStructures.AddRange(productStructures.Where(p => p.StructureType.ToUpper() != "X").ToList()); //获取当前产品的虚拟件 var curPhantoms = productStructures.Where(p => p.StructureType.ToUpper() == "X").ToList(); if (curPhantoms.Count == 0) { return rtnStructures; } //递归获取所有虚拟件对应的子物料 RecursionProductStructure(curPhantoms, rtnStructures); return rtnStructures; } /// /// 递归获取虚拟件的子物料 /// /// 产品的物料编码 /// 当前产品的虚拟件 /// public void RecursionProductStructure(List structures, List rtnStructures) { //获取虚拟件的子物料 List chdStructures = _productStructureMaster.Select(p => structures.Select(m => m.ComponentItem).Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive); chdStructures.ForEach(s => { var parent = structures.Find(x => x.ComponentItem == s.ParentItem); s.Qty = parent.Qty * s.Qty; }); //非虚拟件 var notPhantoms = chdStructures.Where(p => p.StructureType.ToUpper() != "X").ToList(); rtnStructures.AddRange(notPhantoms); //虚拟件 var phantoms = chdStructures.Where(p => p.StructureType.ToUpper() == "X").ToList(); if (phantoms.Count > 0) { //递归 RecursionProductStructure(phantoms, rtnStructures); } } /// /// 计算订单行的系统建议交期 /// /// /// public void CalcSuggestDate(List sentrys, List kittingTimes, List icitemlist) { //获取排产记录 List itemNums = sentrys.Select(p => p.item_number).Distinct().ToList(); DateTime eralist = kittingTimes.Min(p => p.kitting_time).Date; List periodSequences = _periodSequenceDet.Select(p => itemNums.Contains(p.ItemNum) && p.PlanDate >= eralist).ToList(); //资源检查添加产线工序等数据 _productExamineAppService.prodLines = prodLines; _productExamineAppService.routingOps = routingOps; _productExamineAppService.calendarWorks = calendarWorks; _productExamineAppService.qualityLineWorks = qualityLineWorks; _productExamineAppService.holidays = holidays; _productExamineAppService.periodSequences = periodSequences; if (sentrys.Count == 0) { return; } _productExamineAppService.CalcSuggestTime(sentrys, kittingTimes, icitemlist); } /// /// 替代方案保存 /// /// /// public async Task SubstituteSave(SubstituteDto dto) { var rst = SubstituteSaveHandle(dto).Result; if (rst == "ok") { //如果保存成功,则同步到mongodb。 var list = _mysql_ic_substitute.GetListAsync(s => s.substitute_code == dto.scode && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; //同步替代群组数据 //var subtitutes = _mysql_ic_substitute.GetListAsync().Result; if (list.Count > 0) { var moSubstitute = _ic_substitute.GetListAsync(s => s.substitute_code == dto.scode).Result; if (moSubstitute.Any()) { await MongoHelper.DeleteManyAsync(s => s.substitute_code == dto.scode); } var moSubtitutes = ObjectMapper.Map, List>(list); moSubtitutes.ForEach(s => s.GenerateNewId(help.NextId())); await MongoHelper.InsertManyAsync(moSubtitutes); //同步物料替代多群组数据 var subAlls = _mysql_ic_substitute_group.GetListAsync(s => s.substitute_code == dto.scode && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; if (subAlls.Count > 0) { var moSubAll = _ic_substitute_group.GetListAsync(s => s.substitute_code == dto.scode).Result; if (moSubAll.Any()) { await _ic_substitute_group.DeleteManyAsync(moSubAll); } var moSubAlls = ObjectMapper.Map, List>(subAlls); moSubAlls.ForEach(s => s.GenerateNewId(help.NextId())); await MongoHelper.InsertManyAsync(moSubAlls); } //同步物料替代多群组明细数据 var subAllDtls = _mysql_ic_substitute_group_detail.GetListAsync(s => s.substitute_code == dto.scode && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; if (subAllDtls.Count > 0) { var moSuballDtl = _ic_substitute_group_detail.GetListAsync(s => s.substitute_code == dto.scode).Result; if (moSuballDtl.Any()) { await MongoHelper.DeleteManyAsync(s => s.substitute_code == dto.scode); } var moSubAllDtls = ObjectMapper.Map, List>(subAllDtls); moSubAllDtls.ForEach(s => s.GenerateNewId(help.NextId())); await MongoHelper.InsertManyAsync(moSubAllDtls); } } return rst; } else { return rst; } } /// /// 替代方案保存 /// /// /// public async Task SubstituteSaveHandle(SubstituteDto dto) { ic_substitute stt; if (dto.id == null) { if (_mysql_ic_substitute.GetListAsync(s => s.substitute_code == dto.scode).Result.Count > 0) { return "已存在【" + dto.scode + "】替代方案。"; } var check = SubstituteSaveBeforCheck(dto); if (check != "ok") { return check; } //新增 stt = new ic_substitute(); stt.GenerateNewId(help.NextId()); stt.substitute_code = dto.scode; stt.substitute_mode = dto.smode; stt.substitute_strategy = dto.sstrategy; stt.create_by = dto.create_by; stt.create_by_name = dto.create_by_name; stt.create_time = DateTime.Now; stt.update_by = dto.create_by; stt.update_by_name = dto.create_by_name; stt.update_time = DateTime.Now; stt.tenant_id = dto.tenant_id; stt.company_id = dto.company_id; stt.factory_id = dto.factory_id; List glist = new List(); List dlist = new List(); SubstituteSaveGenerate(dto, stt, glist, dlist); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { _businessDbContext.BulkInsert(new List { stt }); if (glist.Any()) { _businessDbContext.BulkInsert(glist); } if (dlist.Any()) { _businessDbContext.BulkInsert(dlist); } await unitOfWork.CompleteAsync(); } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("SubstituteSave", "替代方案保存失败:" + e.Message, _currentTenant.Id.ToString()); unitOfWork.Dispose(); return "保存失败,请联系管理员。"; } } return "ok"; } else { //修改 stt = _mysql_ic_substitute.FirstAsync(s => s.Id == dto.id.Value).Result; if (stt != null) { if (_mysql_ic_substitute.GetListAsync(s => s.Id != dto.id && s.substitute_code == dto.scode && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result.Count > 0) { return "已存在【" + dto.scode + "】替代方案。"; } if (_mysql_ic_bom_child.GetListAsync(s => s.substitute_code == stt.substitute_code).Result.Count() > 0) { return "替代方案已被关联使用,不允许修改。"; } var check = SubstituteSaveBeforCheck(dto); if (check != "ok") { return check; } stt.substitute_code = dto.scode; stt.substitute_mode = dto.smode; stt.substitute_strategy = dto.sstrategy; stt.update_by = dto.create_by; stt.update_by_name = dto.create_by_name; stt.update_time = DateTime.Now; List glist = new List(); List dlist = new List(); SubstituteSaveGenerate(dto, stt, glist, dlist); var delgList = _mysql_ic_substitute_group.GetListAsync(s => s.substitute_group_id == stt.Id).Result; var deldList = _mysql_ic_substitute_group_detail.GetListAsync(s => delgList.Select(c => c.Id).Contains(s.substitute_group_id)).Result; using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { _businessDbContext.BulkUpdate(new List { stt }); if (delgList.Any()) { await _mysql_ic_substitute_group.HardDeleteAsync(delgList); } if (deldList.Any()) { await _mysql_ic_substitute_group_detail.HardDeleteAsync(deldList); } if (glist.Any()) { _businessDbContext.BulkInsert(glist); } if (dlist.Any()) { _businessDbContext.BulkInsert(dlist); } await unitOfWork.CompleteAsync(); } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("SubstituteSave", "替代方案保存失败:" + e.Message, _currentTenant.Id.ToString()); unitOfWork.Dispose(); return "保存失败,请联系管理员。"; } } return "ok"; } else { return "当前方案已被删除,请刷新重试。"; } } } /// /// 校验 /// /// /// public string SubstituteSaveBeforCheck(SubstituteDto dto) { if (!dto.srows.Any()) { return "替代明细不能为空。"; } if (dto.srows.Where(s => s.field_83817a9f5a15a4f78686105c694b0a39 == "是").Count() == 0) { return "请设置替代方案里的标准件。"; } if (dto.srows.Where(s => s.field_83817a9f5a15a4f78686105c694b0a39 == "否").Count() == 0) { return "请设置替代方案里的替代件。"; } if (dto.srows.Select(s => s.field_f8988ed2955a264f8f762faaed2c5f6a.GetValueOrDefault()).Count() < 2) { return "替代方案最低存在两个优先级。"; } //判断同一个优先级里,相同是否标准料 foreach (var r in dto.srows) { if (dto.srows.Where(s => s.field_f8988ed2955a264f8f762faaed2c5f6a == r.field_f8988ed2955a264f8f762faaed2c5f6a && s.field_83817a9f5a15a4f78686105c694b0a39 != r.field_83817a9f5a15a4f78686105c694b0a39).Count() > 0) { return "同优先级群组里不允许既有标准件又有替代件。"; } } /*if (dto.srows.GroupBy(s => new { s.field_f8988ed2955a264f8f762faaed2c5f6a, s.field_83817a9f5a15a4f78686105c694b0a39 }).Where(g => g.Count() > 1).Count() > 0) { return "同优先级群组里不允许既有标准件又有替代件。"; }*/ return "ok"; } /// /// 组装数据 /// public void SubstituteSaveGenerate(SubstituteDto dto, ic_substitute stt, List glist, List dlist) { dto.srows.ForEach(s => { ic_substitute_group g = glist.Where(x => x.order_num == s.field_f8988ed2955a264f8f762faaed2c5f6a.GetValueOrDefault()).FirstOrDefault(); if (g == null) { g = new ic_substitute_group(); g.GenerateNewId(help.NextId()); g.substitute_group_id = stt.Id; g.substitute_code = stt.substitute_code; g.replace_name = s.substitute_code; g.order_num = s.field_f8988ed2955a264f8f762faaed2c5f6a.GetValueOrDefault(); g.main_material = s.field_83817a9f5a15a4f78686105c694b0a39 == "是" ? 1 : 0; g.update_by = dto.create_by; g.update_by_name = dto.create_by_name; g.update_time = DateTime.Now; g.tenant_id = dto.tenant_id; g.company_id = dto.company_id; g.factory_id = dto.factory_id; glist.Add(g); } ic_substitute_group_detail d = new ic_substitute_group_detail(); d.GenerateNewId(help.NextId()); d.substitute_group_id = g.Id; d.substitute_code = stt.substitute_code; d.icitem_id = s.icitem_id.GetValueOrDefault(); d.icitem_number = s.icitem_number; d.seq = s.seq; d.replace_qty = s.replace_qty; d.update_by = dto.create_by; d.update_by_name = dto.create_by_name; d.update_time = DateTime.Now; d.tenant_id = dto.tenant_id; d.company_id = dto.company_id; d.factory_id = dto.factory_id; dlist.Add(d); }); } /// /// 手动排产接口 /// /// /// /// public async Task ProductionSchedule(string domain) { //var IsActived = _AccountValidityAppService.IsActived(); //if (!IsActived) //{ // return "此账号已限制访问"; //} //取数开始时间为当前日期 DateTime startTime = DateTime.Now; ////获取需要排产的工单(获取四周的工单:正常工单+已审批通过的特殊工单) //DateTime endDate = DateTime.Now.Date.AddDays(28).AddDays(1); ////尚未开始生产的工单+正在生产的工单 //var workOrds = _workOrdMaster.Select(p => p.IsActive && p.Domain == domain && ((p.OrdDate < endDate && p.OrdDate >= startTime && p.Status.ToUpper() == "P" && (string.IsNullOrEmpty(p.Typed) || (!string.IsNullOrEmpty(p.Typed) && p.Typed.ToUpper() != "PW" && p.BusinessID > 0))) || p.Status.ToUpper() == "W")).ToList(); var workOrds = _workOrdMaster.Select(p => p.IsActive && p.Domain == domain && (p.QtyOrded - p.QtyCompleted) > 0 && p.Status != "C" && p.Status != "c" && !string.IsNullOrEmpty(p.Status) && (string.IsNullOrEmpty(p.Typed) || (!string.IsNullOrEmpty(p.Typed) && p.Typed.ToUpper() != "PW" && p.BusinessID > 0))).ToList(); //获取工单领料单 var nbrMasterList = _nbrMaster.Select(x => x.Domain == domain && x.Type.ToUpper() == "SM" && workOrds.Select(s => s.WorkOrd).Contains(x.WorkOrd)).ToList(); //获取领料单明细 var nbrDtlLists = _nbrDetail.Select(x => x.Domain == domain && nbrMasterList.Select(s => s.Nbr).Contains(x.Nbr)).ToList(); workOrds = workOrds.OrderBy(p => p.Priority).ToList(); //记录工单数据 List dbWorkOrds = workOrds.Select(p => new WorkPriorityDto { WorkOrd = p.WorkOrd, Priority = p.Priority, QtyOrded = p.QtyOrded }).ToList(); //处理工单优先级:正常投产工单优先级最高,其次是前处理状态为部分完成/全部完成,其他按照工单优先级排 decimal ytc = 1m; decimal ktc = 10000m; decimal bktc = 20000m; for (int i = 0; i < workOrds.Count; i++) { //正在投产 if (!string.IsNullOrEmpty(workOrds[i].Status) && workOrds[i].Status.ToUpper() == "W") { workOrds[i].Priority = ytc; ytc++; continue; } //需要前处理的领料单 var qclNbr = nbrMasterList.FirstOrDefault(p => p.WorkOrd == workOrds[i].WorkOrd && p.TransType == "PrevProcess"); //不需要前处理的领料单 var bqclNbr = nbrMasterList.FirstOrDefault(p => p.WorkOrd == workOrds[i].WorkOrd && p.TransType != "PrevProcess"); List bqclNbrDtls = new List(); if (bqclNbr != null) { bqclNbrDtls = nbrDtlLists.Where(p => p.Nbr == bqclNbr.Nbr).ToList(); } //存在领料单:不需要前处理-领料单明细存在已关闭物料,需要前处理-状态为部分完成或者全部完成 if (qclNbr != null && bqclNbr != null) { //if ((qclNbr.PretreatmentState == "50" || qclNbr.PretreatmentState == "completed") && bqclNbrDtls.Exists(p => p.Status.ToUpper() == "C")) //{ // workOrds[i].Priority = ktc; // ktc++; // continue; //} workOrds[i].Priority = ktc;//bktc; //bktc++; ktc++; continue; } if (qclNbr != null && bqclNbr == null) { //if (qclNbr.PretreatmentState == "50" || qclNbr.PretreatmentState == "completed") //{ // workOrds[i].Priority = ktc; // ktc++; // continue; //} workOrds[i].Priority = ktc;//bktc; //bktc++; ktc++; continue; } if (qclNbr == null && bqclNbr != null) { //if (bqclNbrDtls.Exists(p => p.Status.ToUpper() == "C")) //{ // workOrds[i].Priority = ktc; // ktc++; // continue; //} //workOrds[i].Priority = bktc; //bktc++; //continue; workOrds[i].Priority = ktc; ktc++; continue; } if (qclNbr == null && bqclNbr == null) { workOrds[i].Priority = bktc; bktc++; continue; } } //按照优先级排序 workOrds = workOrds.OrderBy(p => p.Priority).ToList(); var morders = _mysql_mes_morder.GetListAsync(p => workOrds.Select(x => x.WorkOrd).ToList().Contains(p.morder_no) && !p.IsDeleted && p.factory_id.ToString() == domain).Result; //var rtn = await OrderKittingCheck(morders, false, null, true, workOrds); //刷新在库齐套个数 var rtn = await OrderDetailKittingCheck(domain,""); if (workOrds.Any()) { workOrds = workOrds.Where(w => w.LocationStock + w.OpQtyCompleted > 0).ToList(); await _productionScheduleAppService.DoProductSchedule(startTime, workOrds, domain, 2, dbWorkOrds); } return "OK"; } /// /// 日计划日期调整 /// /// 日计划调整入参 /// /// public async Task UpdatePlanDate(UpdateDto input) { ////获取需要排产的工单(获取四周的工单:正常工单+已审批通过的特殊工单) //DateTime endDate = DateTime.Now.Date.AddDays(28).AddDays(1); //取数开始时间为当前天的下一天 DateTime startTime = DateTime.Now; //尚未开始生产的工单+正在生产的工单 var workOrds = _workOrdMaster.Select(p => p.IsActive && p.Domain == input.domain && (p.QtyOrded - p.QtyCompleted) > 0 && p.Status != "C" && p.Status != "c" && !string.IsNullOrEmpty(p.Status) && (p.WorkOrd == input.workord || (string.IsNullOrEmpty(p.Typed) || (!string.IsNullOrEmpty(p.Typed) && p.Typed.ToUpper() != "PW" && p.BusinessID > 0)))).ToList(); if (!workOrds.Exists(p => p.WorkOrd == input.workord)) { return "NO|工单【" + input.workord + "】不存在,请联系系统管理员!"; } //计算工单优先级 //var workInfos = _replenishmentAppService.CalcPriority(workOrds.Select(p => p.WorkOrd).ToList(), input.domain); workOrds.ForEach(p => { p.OrdDate = p.WorkOrd == input.workord ? input.planDate : p.OrdDate; p.JointTyped = p.WorkOrd == input.workord ? "B" : p.JointTyped; //p.Priority = p.WorkOrd == input.workord ? workInfos.First(p => p.WorkOrd == input.workord).Priority : p.Priority; }); //执行排产 if (workOrds.Any()) { await _productionScheduleAppService.DoProductSchedule(startTime, workOrds, input.domain, 2); } //更新原工单优先级 WorkOrdMaster workOrd = _workOrdMaster.Select(p => p.IsActive && p.Domain == input.domain && p.WorkOrd == input.workord).FirstOrDefault(); //workOrd.Priority = workInfos.First(p => p.WorkOrd == workOrd.WorkOrd).Priority; workOrd.JointTyped = ""; _workOrdMaster.Update(workOrd); return "OK"; } /// /// BOM关联替代方案 /// /// /// public async Task BindingSubstituteHandle(BindingSubstituteDto dto) { var list = _mysql_ic_bom_child.GetListAsync(s => s.bom_id == dto.id && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; if (dto.bomDetail.Any()) { list.ForEach(s => { s.substitute_code = ""; s.haveicsubs = 0; }); var codeList = dto.bomDetail.Where(s => string.IsNullOrEmpty(s.substitute_code) == false).Select(x => x.substitute_code).Distinct().ToList(); if (codeList.Any()) { var subGdtls = _mysql_ic_substitute_group.GetListAsync(s => s.tenant_id == dto.tenant_id && s.company_id == dto.company_id && s.factory_id == dto.factory_id && codeList.Contains(s.substitute_code)).Result; var subDetalis = _mysql_ic_substitute_group_detail.GetListAsync(s => s.tenant_id == dto.tenant_id && s.company_id == dto.company_id && s.factory_id == dto.factory_id && codeList.Contains(s.substitute_code)).Result; foreach (var code in codeList) { var g = subGdtls.Find(s => s.substitute_code == code && s.main_material == 1); if (g != null) { var dtls = subDetalis.Where(s => s.substitute_group_id == g.Id).ToList(); foreach (var dtl in dtls) { var l = list.Find(s => s.item_number == dtl.icitem_number); if (l == null) { return "当前替代方案【" + code + "】的标准件未找到相同数量相同物料的BOM明细。"; } if (string.IsNullOrEmpty(l.substitute_code)) { l.haveicsubs = 1; l.substitute_code = code; } else { return "当前替代方案【" + code + "】的标准件【" + l.item_number + "】与替代方案【" + l.substitute_code + "】冲突。"; } } } else { return "当前替代方案【" + code + "】未设置标准件。"; } } } //await _businessDbContext.BulkUpdateAsync(list); _businessDbContext.ic_bom_child.UpdateRange(list); } return "ok"; } public async Task BindingSubstitute(BindingSubstituteDto dto) { var rst = BindingSubstituteHandle(dto).Result; if (rst == "ok") { var list = _mysql_ic_bom_child.GetListAsync(s => s.bom_id == dto.id && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; //这个产生了绑定集合,需同步至mongodb,同时清除BOM预处理,再产生新的BOM预处理 var moBomChild = _ic_bom_child.GetListAsync(s => s.bom_id == dto.id && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; if (moBomChild.Any()) { await MongoHelper.DeleteManyAsync(s => s.bom_id == dto.id && s.company_id == dto.company_id && s.factory_id == dto.factory_id); } //同步物料BOM明细数据 if (list.Count > 0) { var moIcbom_childs = ObjectMapper.Map, List>(list); moIcbom_childs.ForEach(s => s.GenerateNewId(help.NextId())); await MongoHelper.InsertManyAsync(moIcbom_childs); } //清除BOM预处理记录 var refList = _mysql_b_bom_pretreatment.GetListAsync(s => s.bom_id == dto.id && s.company_id == dto.company_id && s.factory_id == dto.factory_id).Result; if (refList.Any()) { var refBomList = _mysql_b_bom_pretreatment.GetListAsync(s => refList.Select(c => c.sourceid).Contains(s.sourceid)).Result; if (refBomList.Any()) { await _businessDbContext.BulkDeleteAsync(refBomList); } var boms = _ic_bom.GetListAsync(s => refList.Select(c => c.sourceid).Contains(s.mysql_id)).Result; if (boms.Any()) { AutoCreateBomBill(dto.company_id.ToString(), boms); } } else { var boms = _ic_bom.GetListAsync(s => s.mysql_id == dto.id).Result; if (boms.Any()) { AutoCreateBomBill(dto.company_id.ToString(), boms); } } return rst; } else { return rst; } } /// /// 日计划自动发布 /// public async Task ProductionDailyPlanAutoPublish(string domain) { //取数开始时间为当前日期 DateTime startTime = DateTime.Now.Date; DateTime endDate = DateTime.Now.Date.AddDays(6); var periodList = _periodSequenceDet.Select(x => x.PlanDate >= startTime && x.PlanDate <= endDate && string.IsNullOrEmpty(x.Status) == true && x.Domain == domain).ToList(); if (periodList.Any()) { try { List updateList = new List(); var workords = periodList.Select(s => s.WorkOrds); var workordList = _workOrdMaster.Select(x => x.Domain == domain && x.Status.ToLower() == "r" && workords.Contains(x.WorkOrd)).ToList(); var nbrMasterList = _nbrMaster.Select(x => x.Domain == domain && x.Type == "SM" && workords.Contains(x.WorkOrd)).ToList(); var nbrDetailList = _nbrDetail.Select(x => x.Domain == domain && x.Type == "SM" && workords.Contains(x.WorkOrd)).ToList(); foreach (var work in workordList) { bool flag = false; var nbrlist = nbrMasterList.Where(s => s.WorkOrd == work.WorkOrd).ToList(); if (nbrlist.Any()) { flag = true; foreach (var nbr in nbrlist) { //还有未出库数据 //如果有任意一个出库,则下达 if (!nbrDetailList.Where(x => x.NbrRecID == nbr.RecID && x.Status.ToUpper() == "C").Any()) { flag = false; break; } /*if (nbr.Status.ToLower() != "c") { flag = false; break; }*/ //需要前处理,但是前处理还未完成 if (nbr.TransType == "PrevProcess" && nbr.PretreatmentState != "completed" && nbr.PretreatmentState != "50") { flag = false; break; } } } if (flag) { var publish = periodList.Where(x => x.WorkOrds == work.WorkOrd).ToList(); publish.ForEach(x => { x.Status = "r"; }); updateList.AddRange(publish); } } if (updateList.Any()) { _periodSequenceDet.Update(updateList); } } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("ProductionDailyPlanAutoPublish", "日计划自动任务失败:" + e.Message, _currentTenant.Id.ToString()); return "保存失败,请联系管理员。"; } } return "ok"; } public async Task 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 works = workOrds.Select(x => x.WorkOrd).ToList(); List 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 MRPmorder = new List(); List InsertList = new List(); List UpdateList = new List(); List moIstList = new List(); List moUpdList = new List(); List meIstList = new List(); List stockUpdList = new List(); List pooccuypUpdList = new List(); List mooccupuUpdList = new List(); List routingInsList = new List(); //按开工时间进行一次排序 workOrds = workOrds.OrderBy(x => x.OrdDate).ToList(); //先将工单按经济批量汇总成DTO,然后再判断是否有多个,需要合并,如果只有一个,则无需合并。 List workListDto = new List(); 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; } 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 GenerateMoList = new List(); 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.RecID = 0; 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 "保存失败,请联系管理员。"; } } //自动合并委外PR,按周频次 public async Task AutoMergeWWPR(string domain) { try { //合并委外数据 List alllist = _mysql_srm_pr_main.GetListAsync(s => s.factory_id.ToString() == domain && s.pr_type == 2 && s.pr_ssend_date >= DateTime.Now.Date && s.state == 1).Result; List ic_Items = _mysql_ic_item.GetListAsync(s => s.factory_id.ToString() == domain && alllist.Select(c => c.icitem_id).Distinct().Contains(s.Id)).Result; var occupyListLINQ = _businessDbContext.srm_po_occupy.Where(x => x.factory_id.ToString() == domain && !x.IsDeleted).Join(_businessDbContext.srm_pr_main.Where(s => s.factory_id.ToString() == domain && s.pr_ssend_date >= DateTime.Now.Date && s.state == 1), p => p.polist_id, pr => pr.Id, (p, pr) => new { p, pr }).ToList(); List occupylist = new List(); for (int i = 0; i < occupyListLINQ.Count; i++) { occupylist.Add(occupyListLINQ[i].p); } var purList = _mysql_srm_purchase.GetListAsync(x => x.factory_id.ToString() == domain).Result; //占用不清除,只按照圆整的数量,来买料。 List wwprList = new List(); var itemIds = alllist.Select(x => x.icitem_id).Distinct().ToList(); foreach (var id in itemIds) { var itemPrList = alllist.Where(x => x.icitem_id == id).ToList(); var purIdList = itemPrList.Select(x => x.pr_purchaseid).Distinct().ToList(); var icitem = ic_Items.Find(x => x.Id == id); foreach (var purid in purIdList) { var purItemList = itemPrList.Where(x => x.pr_purchaseid == purid).ToList(); var pur = purList.Find(x => x.icitem_id == id && x.supplier_id == purid); var minTime = purItemList.Min(x => x.pr_ssend_date).GetValueOrDefault(); var maxTime = purItemList.Max(x => x.pr_ssend_date).GetValueOrDefault(); int diff = 7 - Convert.ToInt16(minTime.DayOfWeek); bool flag = true; DateTime endTime = minTime.AddDays(diff); while (flag) { WWPRDto dto = new WWPRDto(); var weekList = purItemList.Where(x => x.pr_ssend_date >= minTime && x.pr_ssend_date <= endTime).ToList(); if (weekList.Any()) { dto.prList = weekList; dto.itemId = id.Value; dto.SumQty = weekList.Sum(x => x.pr_aqty.GetValueOrDefault()); dto.MinQty = 0; dto.icitem = icitem; if (pur != null) { dto.MinQty = pur.qty_min.GetValueOrDefault(); dto.diffQty = dto.MinQty > dto.SumQty ? dto.MinQty - dto.SumQty : 0; } wwprList.Add(dto); } minTime = endTime.AddDays(1); endTime = endTime.AddDays(7); if (endTime >= maxTime) { flag = false; } } } } List insetList = new List(); List updateList = new List(); List occupyUptList = new List(); List moList = new List(); List moentryList = new List(); //委外数据合并加圆整 if (wwprList.Any()) { List GenerateMoList = new List(); var moNbrlistDto = _serialNumberAppService.GetBillNo(domain, "PR", wwprList.Count(), "admin", 1); long bang_id = help.NextId(); if (moNbrlistDto.Any()) { foreach (var nbr in moNbrlistDto) { GenerateMoList.Add(nbr.NbrResult); } } foreach (var wwDto in wwprList) { //如果需要圆整,圆整数量生成虚拟工单 if (wwDto.diffQty > 0) { if (wwDto.icitem != null) { mes_morder mes_Morder = new mes_morder(); mes_Morder.GenerateNewId(help.NextId()); mes_Morder.morder_type = MorderEnum.JhMorder; mes_Morder.work_order_type = MorderEnum.CgMorder; mes_Morder.morder_state = ""; mes_Morder.morder_no = Guid.NewGuid().ToString(); mes_Morder.fms_number = ""; mes_Morder.bom_number = wwDto.icitem.number; mes_Morder.fmodel = wwDto.icitem.model; mes_Morder.moentry_startup_status = 0; mes_Morder.tenant_id = wwDto.icitem.tenant_id; mes_Morder.factory_id = wwDto.icitem.factory_id; mes_Morder.company_id = wwDto.icitem.company_id; mes_Morder.org_id = wwDto.icitem.org_id; mes_Morder.product_code = wwDto.icitem.number; mes_Morder.product_name = wwDto.icitem.name; mes_Morder.morder_date = DateTime.Now.Date.AddDays(1); 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.unit = wwDto.icitem.unit; mes_Morder.morder_production_number = wwDto.diffQty; mes_Morder.need_number = wwDto.diffQty; //成品半成品取周一为入库时间开始往前推 mes_Morder.moentry_sys_stime = wwDto.prList.OrderBy(x => x.pr_ssend_date).FirstOrDefault().pr_ssend_date; //mes_Morder.moentry_sys_etime = weekTime; mes_Morder.remaining_number = 0; mes_Morder.create_time = DateTime.Now; mes_Morder.bang_id = bang_id; moList.Add(mes_Morder); //生成工单子表数据 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 = wwDto.icitem.unit; mes_Moentry.morder_production_number = wwDto.diffQty; mes_Moentry.need_number = wwDto.diffQty; mes_Moentry.remaining_number = 0; mes_Moentry.tenant_id = wwDto.icitem.tenant_id; mes_Moentry.factory_id = wwDto.icitem.factory_id; mes_Moentry.company_id = wwDto.icitem.company_id; mes_Moentry.org_id = wwDto.icitem.org_id; mes_Moentry.create_time = DateTime.Now; mes_Moentry.bang_id = bang_id; moentryList.Add(mes_Moentry); } } /*//如果有多条,需要合并 if (wwDto.prList.Count() > 1) { var first = wwDto.prList.OrderBy(x => x.pr_ssend_date).FirstOrDefault(); srm_pr_main pr = help.DeepCopy(first); pr.GenerateNewId(help.NextId()); if (GenerateMoList.Any()) { pr.pr_billno = GenerateMoList[0]; GenerateMoList.Remove(pr.pr_billno); } else { var nbrDto = _serialNumberAppService.GetBillNo(domain, "PR", 1, "admin", 1); if (nbrDto.Any()) { pr.pr_billno = nbrDto[0].NbrResult; } } if (string.IsNullOrEmpty(pr.pr_billno)) { pr.pr_billno = help.NextId().ToString(); } pr.pr_sqty = wwDto.SumQty; pr.pr_aqty = wwDto.SumQty; pr.pr_rqty = wwDto.prList.Sum(x => x.pr_rqty.GetValueOrDefault()); pr.pr_orderprice = pr.pr_rqty * pr.pr_sysprice;//订单价格(含税) insetList.Add(pr); wwDto.prList.ForEach(x => { x.state = 0; }); updateList.AddRange(wwDto.prList); var wwoccupy = occupylist.Where(x => wwDto.prList.Select(c => c.Id).Contains(x.polist_id.GetValueOrDefault())).ToList(); wwoccupy.ForEach(x => { x.polist_id = pr.Id; }); occupyUptList.AddRange(wwoccupy); }*/ /*else { wwDto.prList.ForEach(x => { x.pr_sqty = wwDto.SumQty; x.pr_aqty = wwDto.SumQty; }); updateList.AddRange(wwDto.prList); }*/ } /*if (insetList.Any()) { _businessDbContext.BulkInsert(insetList); } if (updateList.Any()) { _businessDbContext.BulkUpdate(updateList); } if (occupyUptList.Any()) { _businessDbContext.BulkUpdate(occupyUptList); }*/ if (moList.Any()) { var rtn = await OrderKittingCheck(moList, true, moentryList); } } return "ok"; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("AutoMergeMo", "自动合并工单任务失败:" + e.Message, _currentTenant.Id.ToString()); return "保存失败,请联系管理员。"; } } //委外采购申请自动生成组件 public string AutoCreatePWDetailBatch(string domain) { try { string sql = string.Format("exec pr_WMS_AutoCreatePWDetailBatch @domain='{0}',@PurOrds='',@User='{1}'", domain,"Admin"); _businessDbContext.Database.ExecuteSqlRaw(sql); return "OK"; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("AutoCreatePWDetailBatch", "委外采购申请自动生成组件任务失败:" + e.Message, _currentTenant.Id.ToString()); return "生成失败,请联系管理员。"+ e.Message; } } public async Task CreateDemandSchedule(string domain) { try { var demanddeletedList = _mysql_ic_demandschedule.GetListAsync(a => a.ishistoryversion != "Y" && a.status != "P").Result; demanddeletedList.ForEach(ds => { ds.IsDeleted = true; ds.update_time = DateTime.Now; ds.remarks = $"{DateTime.Now.ToString()},重新生成交货计划把未发布交货计划软删除"; }); await _businessDbContext.BulkUpdateAsync(demanddeletedList); var dsdeletedList = _srm_polist_ds.Select(a => a.isactive == 1 && a.status == "N"); dsdeletedList.ForEach(ds => { ds.isactive = 0; ds.updatetime = DateTime.Now; ds.remarks = $"{DateTime.Now.ToString()},重新生成交货计划把未发布交货单禁用"; }); await _businessDbContext.BulkUpdateAsync(dsdeletedList); using (dataFilter.Disable()) { var historyversionList = _mysql_ic_demandschedule.GetListAsync(a => a.ishistoryversion != "Y").Result; historyversionList.ForEach(a => { a.ishistoryversion = "Y"; a.historyversionTime = DateTime.Now; }); await _businessDbContext.BulkUpdateAsync(historyversionList); } var weekday = (int)DateTime.Now.DayOfWeek; int adddays = weekday == 0 ? 1 : 8 - weekday; DateTime beginTime = Convert.ToDateTime(DateTime.Now.AddDays(adddays).ToString("yyyy-MM-dd 00:00:00.000")); DateTime endTime = Convert.ToDateTime(DateTime.Now.AddDays(adddays + 21 + 28 + 6).ToString("yyyy-MM-dd 23:59:59.999")); var workords = _workOrdMaster.Select(a => a.OrdDate >= beginTime && a.OrdDate <= endTime && a.Domain == domain && (string.IsNullOrEmpty(a.Status) || a.Status.ToUpper() == "P")); var workordList = workords.Select(x => x.WorkOrd).Distinct().ToList(); //存在提前开工的情况 var workordsPickBill = _workOrdMaster.Select(a => (!string.IsNullOrEmpty(a.Status) && a.Status != "C" && a.Status != "P") && a.Domain == domain); var workordListPickBill = workordsPickBill.Select(x => x.WorkOrd).Distinct().ToList(); if (workordList.Count > 0) { workordListPickBill.AddRange(workordList); } var workExamineResult = _businessBangDbContext.b_examine_result.Where(a => workordList.Contains(a.morder_no) && a.factory_id.ToString() == domain).GroupBy(i => i.morder_no).Select(g => new { workOrd = g.Key, examineId = g.Max(row => row.Id), bangid= g.Max(row => row.bangid) }).ToList(); //需要测试工单没有做资源检查会不会报错 var examineIds = workExamineResult.Select(s => s.examineId).ToList(); var examines = _mysql_bom_child_examine.GetListAsync(a => examineIds.Contains(a.examine_id.Value) && (a.erp_cls == 3 || a.erp_cls == 2) && a.is_use && a.factory_id.ToString() == domain).Result; var pickBills = _nbrDetail.Select(a => workordListPickBill.Contains(a.WorkOrd) && a.Type.ToUpper() == "SM" && (a.QtyOrd - a.QtyRec) > 0 && a.Domain == domain && a.Status.ToUpper() != "C"); var dsList = _srm_polist_ds.Select(a => a.domain == domain && a.isactive == 1 && a.status == "P"); var items = examines.Select(e => e.item_number).Distinct().ToList(); var itempickbills = pickBills.Select(s => s.ItemNum); items.AddRange(itempickbills); items = items.Distinct().ToList(); var itemList = _itemMaster.Select(a => items.Contains(a.ItemNum) && a.Domain == domain); var locationRange = _configurationItem.Select(x => x.FldName == "MRPLocationRange" && x.Domain == domain).FirstOrDefault(); List locationList = new List { "1001", "5007", "5008", "8000", "8001" }; if (locationRange != null && locationRange.Val != null) { locationList = locationRange.Val.SplitToArray(",").ToList(); } //SAP库存表 //var itemListStock = _SAPInv.Select(a => items.Contains(a.MATNR) && locationList.Contains(a.LGORT) && a.WERKS == domain); //Dop库存表包含VMI库存 var itemListVMIStock = _invMaster.Select(a => items.Contains(a.ItemNum) && a.IsActive && locationList.Contains(a.Location) && a.Domain == domain); List ds = new List(); Dictionary weekStockQty = new Dictionary(); Dictionary weekdsQty = new Dictionary(); //foreach (var item in itemListStock) //{ // if (!weekStockQty.ContainsKey(item.MATNR)) // { // weekStockQty.Add(item.MATNR, item.LABST); // } else // { // weekStockQty[item.MATNR] += (item.LABST); // } //} foreach (var item in items) { foreach (var loc in locationList) { var lctQty = itemListVMIStock.Where(s => s.ItemNum == item && s.Location==loc).Sum(p => p.AvailStatusQty.GetValueOrDefault() + p.Assay.GetValueOrDefault()); //if (lctQty == 0) //{ // lctQty = itemListStock.Where(s => s.MATNR == item && s.LGORT == loc).Sum(p => p.LABST + p.INSME); //} if (!weekStockQty.ContainsKey(item)) { weekStockQty.Add(item, lctQty); } else { weekStockQty[item] += lctQty; } } } foreach (var item in dsList) { if (!weekdsQty.ContainsKey(item.itemnum)) { weekdsQty.Add(item.itemnum, item.schedqty - item.sentqty); } else { weekdsQty[item.itemnum] += (item.schedqty - item.sentqty); } } for (int i = 0; i < 8; i++) { var itemBegin = beginTime.AddDays(i * 7); var itemEnd = endTime.AddDays(7 * i - 21 - 28); var workItem = workords.Where(a => a.OrdDate >= itemBegin && a.OrdDate <= itemEnd).ToList(); List itemQty = new List(); if (workItem.Count > 0) { foreach (var item in workItem) { //存在提前开工,提前下达的已经算在待发料里面了 if (item.Status.ToUpper() != "R") { var examids = workExamineResult.Find(a => item.WorkOrd == a.workOrd); if (examids != null && examids.examineId > 0) { var itemLackList = examines.Where(a => a.examine_id == examids.examineId).ToList(); itemLackList?.ForEach(a => { if (itemQty.Any(s => s.ItemNum == a.item_number)) { itemQty.Find(s => s.ItemNum == a.item_number).LackQty += a.lack_qty.GetValueOrDefault(); itemQty.Find(s => s.ItemNum == a.item_number).NeedQty += a.needCount.GetValueOrDefault(); if (!itemQty.Find(s => s.ItemNum == a.item_number).WorkOrds.Contains(item.WorkOrd)) itemQty.Find(s => s.ItemNum == a.item_number).WorkOrds += "," + item.WorkOrd; if (!itemQty.Find(s => s.ItemNum == a.item_number).bangid.Contains(examids.bangid.GetValueOrDefault().ToString())) itemQty.Find(s => s.ItemNum == a.item_number).bangid += "," + examids.bangid.GetValueOrDefault().ToString(); } else { DemandscheduleDto demandscheduleDto = new DemandscheduleDto() { ItemNum = a.item_number, LackQty = a.lack_qty.GetValueOrDefault(), NeedQty = a.needCount.GetValueOrDefault(),WorkOrds= item.WorkOrd,bangid= examids.bangid.GetValueOrDefault().ToString() }; itemQty.Add(demandscheduleDto); } }); } else { new NLogHelper("ResourceExamineAppService").WriteLog("CreateDemandSchedule", "生成交货计划:" + item.WorkOrd + "找不到资源检查记录", _currentTenant.Id.ToString()); } } } var requestdate = workItem.Min(a => a.OrdDate); if (itemQty.Count > 0) { foreach (var d in itemQty) { var itemNum = itemList.Find(a => a.ItemNum == d.ItemNum); ic_demandschedule itemds = new ic_demandschedule(); itemds.GenerateNewId(help.NextId()); itemds.itemnum = d.ItemNum; itemds.fversion = itemNum.Rev; itemds.drawing = itemNum.Drawing; itemds.requestdate = requestdate.GetValueOrDefault(); itemds.arrivaldate = requestdate.GetValueOrDefault().AddDays(-1).AddDays(-itemNum.InsLT).AddDays(-(int)Math.Ceiling(itemNum.MFGMTTR)); itemds.shortqty = d.LackQty; //工单需求+已下达工单领料单待发料(只算第一次) if (i == 0) { itemds.mesqty = d.NeedQty + pickBills.Where(a => a.ItemNum == d.ItemNum).Sum(q => q.QtyOrd - q.QtyRec); pickBills.RemoveAll(a => a.ItemNum == d.ItemNum); } else { itemds.mesqty = d.NeedQty; } //库存扣减量 decimal stockDeduction = 0; if (weekStockQty.ContainsKey(d.ItemNum)) { itemds.locqty = weekStockQty[d.ItemNum]; if (itemds.mesqty >= itemds.locqty) { weekStockQty[d.ItemNum] = 0; stockDeduction = itemds.locqty; } else { weekStockQty[d.ItemNum] -= itemds.mesqty; stockDeduction = itemds.mesqty; } } else { itemds.locqty = 0; } if (weekdsQty.ContainsKey(d.ItemNum)) { itemds.sechedqty = weekdsQty[d.ItemNum]; //优先扣减库存,库存不够扣减交货单在途 if (itemds.mesqty - stockDeduction - itemds.sechedqty >= 0) { weekdsQty[d.ItemNum] = 0; } else { weekdsQty[d.ItemNum] -= itemds.mesqty - stockDeduction; } } else { itemds.sechedqty = 0; } itemds.tosechedqty = itemds.mesqty - (itemds.locqty + itemds.sechedqty); itemds.status = ""; itemds.remarks = ""; itemds.wolist = d.WorkOrds; itemds.bangid = d.bangid; itemds.tenant_id = examines.Count > 0 ? examines[0].tenant_id : 1000; itemds.company_id = examines.Count > 0 ? examines[0].company_id : 1000; itemds.factory_id = examines.Count > 0 ? examines[0].factory_id : 8010; itemds.create_time = DateTime.Now; itemds.update_time = DateTime.Now; ds.Add(itemds); } } } if (i == 0) { var pickbillItems = pickBills.Select(a => a.ItemNum).Distinct().ToList(); foreach (var item in pickbillItems) { var itemNum = itemList.Find(a => a.ItemNum == item); if (itemNum != null) { ic_demandschedule itemds = new ic_demandschedule(); itemds.GenerateNewId(help.NextId()); itemds.itemnum = item; itemds.fversion = itemNum.Rev; itemds.drawing = itemNum.Drawing; itemds.requestdate = itemBegin; itemds.arrivaldate = itemBegin.AddDays(-1).AddDays(-itemNum.InsLT).AddDays(-(int)Math.Ceiling(itemNum.MFGMTTR)); itemds.shortqty = 0; itemds.mesqty = pickBills.Where(a => a.ItemNum == item).Sum(q => q.QtyOrd - q.QtyRec); //库存扣减量 decimal stockDeduction = 0; if (weekStockQty.ContainsKey(item)) { itemds.locqty = weekStockQty[item]; if (itemds.mesqty >= itemds.locqty) { weekStockQty[item] = 0; stockDeduction = itemds.locqty; } else { weekStockQty[item] -= itemds.mesqty; stockDeduction = itemds.mesqty; } } else { itemds.locqty = 0; } if (weekdsQty.ContainsKey(item)) { itemds.sechedqty = weekdsQty[item]; //优先扣减库存,库存不够扣减交货单在途 if (itemds.mesqty - stockDeduction - itemds.sechedqty >= 0) { weekdsQty[item] = 0; } else { weekdsQty[item] -= itemds.mesqty - stockDeduction; } } else { itemds.sechedqty = 0; } itemds.tosechedqty = itemds.mesqty - (itemds.locqty + itemds.sechedqty); itemds.status = ""; itemds.remarks = ""; itemds.tenant_id = examines.Count > 0 ? examines[0].tenant_id : 1000; itemds.company_id = examines.Count > 0 ? examines[0].company_id : 1000; itemds.factory_id = examines.Count > 0 ? examines[0].factory_id : 8010; itemds.create_time = DateTime.Now; itemds.update_time = DateTime.Now; ds.Add(itemds); } } } } await _businessDbContext.BulkInsertAsync(ds); return "ok"; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("CreateDemandSchedule", "生成交货计划失败:" + e.Message, _currentTenant.Id.ToString()); return "保存失败,请联系管理员。"; } } public async Task WorkOrdKittingCheckByNo(string workord, string qty, string instockdate, string priority, string domain, string userAccount) { if (string.IsNullOrEmpty(qty)) return "数量不正确,请检查"; if (string.IsNullOrEmpty(instockdate)) return "工单开工日期不正确,请检查"; if (string.IsNullOrEmpty(priority)) return "优先级不正确,请检查"; if (string.IsNullOrEmpty(workord)) return "工单号为空,请检查"; try { //先执行工单数量、优先级、开工日期、完工日期的修改 decimal newpriority = Convert.ToDecimal(priority); DateTime newinstockdate = Convert.ToDateTime(instockdate); decimal newqty = Convert.ToDecimal(qty); WorkOrdMaster work = null; var workords = _workOrdMaster.Select(x => x.WorkOrd == workord && x.Domain == domain).ToList(); if (workords.Any()) { work = workords[0]; } if (work == null) return "未查找到对应工单,请刷新界面重试。"; if (!string.IsNullOrEmpty(work.Status) && work.Status.ToUpper() != "P") { return "当前工单不是未下达,不允许调整。"; } var isExistSamePriority = _workOrdMaster.Select(a => a.WorkOrd != workord && (string.IsNullOrEmpty(a.Status) || a.Status.ToUpper() == "P") && (string.IsNullOrEmpty(a.Typed) || (!string.IsNullOrEmpty(a.Typed) && a.Typed.ToUpper() != "PW" && a.BusinessID > 0)) && a.Priority == newpriority); if (isExistSamePriority.Any()) return "优先级重复,请重新调整。"; if (newinstockdate <= DateTime.Now.Date) return "请调整开工日期为今天之后。"; TimeSpan difference = newinstockdate.Subtract(work.OrdDate.GetValueOrDefault()); int daysDifference = difference.Days; work.OrdDate = newinstockdate; work.QtyOrded = newqty; work.Priority = newpriority; work.DueDate = work.DueDate.GetValueOrDefault().AddDays(daysDifference); var molist = _mysql_mes_morder.GetListAsync(x => x.morder_no == work.WorkOrd && x.factory_id.ToString() == domain).Result; if (molist.Any()) { molist.ForEach(x => { x.morder_production_number = newqty; x.need_number = newqty; x.moentry_sys_stime = work.OrdDate; x.moentry_sys_etime = work.DueDate; }); _businessDbContext.BulkUpdate(molist); } //再执行工单的MRP,更新工单物料明细 _workOrdMaster.Update(work); return await PlanOrderResourceCheckByWorkOrd(domain, work.WorkOrd); } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("WorkOrdKittingCheckByNo", "修改计划工单失败:" + e.Message, _currentTenant.Id.ToString()); return "修改失败,请联系管理员。"; } } /// /// 将下单时间为过去的采购申请调整为明天。 /// /// /// public async Task AutomaticPrAdjustDate(string domain) { try { string result = await PrAutoMerge(domain); if (result != "ok") { return result; } result = await PrAutoApprove(domain); if (result != "ok") { return result; } result = await PrSendSAP(domain); if (result != "ok") { return result; } return result; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("AutomaticPrAdjustDate", "PR推送失败失败:" + e.Message, _currentTenant.Id.ToString()); return "更新失败,请联系管理员。"; } } /// /// 交货单生成PR后,自动合并,转DO或者推送SAP /// /// /// public async Task AutoTransferDoOrPo(string domain) { try { string result = await PrAutoMerge2(domain); if (result != "ok") { return result; } result = await PrAutoApprove(domain); if (result != "ok") { return result; } result = await PrSendSAP(domain); if (result != "ok") { return result; } return result; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("AutoTransferDoOrPo", "PR推送失败失败:" + e.Message, _currentTenant.Id.ToString()); return "PR推送失败失败,请联系管理员。"; } } /// /// PR自动合并,不生成 /// /// /// public async Task PrAutoMerge2(string domain) { try { DateTime tomorrow = DateTime.Now.AddDays(1).Date; var formerlylist = _mysql_srm_pr_main.GetListAsync(x => x.pr_ssend_date < tomorrow && x.state == 1 && x.factory_id.ToString() == domain).Result; if (formerlylist.Any()) { formerlylist.ForEach(x => { TimeSpan difference = tomorrow.Subtract(x.pr_ssend_date.GetValueOrDefault()); int daysDifference = difference.Days; x.pr_ssend_date = tomorrow; x.pr_sarrive_date = x.pr_sarrive_date.GetValueOrDefault().AddDays(daysDifference); }); _businessDbContext.BulkUpdate(formerlylist); } DateTime toTime = DateTime.Now.Date; int dayOfWeek = (int)toTime.DayOfWeek; // 获取今天是星期几(0-6) switch (dayOfWeek) { case 0: toTime = toTime.AddDays(-7); break; default: toTime = toTime.AddDays(-dayOfWeek); break; } DateTime starttime = toTime.Date.AddDays(1); DateTime endtime = toTime.Date.AddDays(35); //只合并要货令 List alllist = _mysql_srm_pr_main.GetListAsync(s => s.factory_id.ToString() == domain && s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime && s.state == 1 && string.IsNullOrEmpty(s.analogcalcversion) == true).Result; List ic_Items = _mysql_ic_item.GetListAsync(s => s.factory_id.ToString() == domain && alllist.Select(c => c.icitem_id).Distinct().Contains(s.Id)).Result; var occupyListLINQ = _businessDbContext.srm_po_occupy.Where(x => x.factory_id.ToString() == domain && !x.IsDeleted).Join(_businessDbContext.srm_pr_main.Where(s => s.factory_id.ToString() == domain && s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime && s.state == 1), p => p.polist_id, pr => pr.Id, (p, pr) => new { p, pr }).ToList(); List occupylist = new List(); for (int i = 0; i < occupyListLINQ.Count; i++) { occupylist.Add(occupyListLINQ[i].p); } //var occupylist = _mysql_srm_po_occupy.GetListAsync(s => alllist.Select(c => c.Id).Contains(s.polist_id.GetValueOrDefault()) && s.company_id.ToString() == companyid && s.IsDeleted == false).Result; var purList = _mysql_srm_purchase.GetListAsync(x => x.factory_id.ToString() == domain).Result; List insetAllList = new List(); List updateAllList = new List(); //每次发布四周的数据 for (int i = 0; i < 5; i++) { starttime = toTime.Date.AddDays(i * 7 + 1); endtime = toTime.Date.AddDays((i + 1) * 7); List prlist = alllist.Where(s => s.pr_ssend_date >= starttime && s.pr_ssend_date <= endtime).ToList(); List insetPrList = new List(); List updatePrList = new List(); long Nbr = help.NextId(); foreach (var pr in prlist) { bool bl = pr.sentry_id == null;//区分是销售订单和非销售订单的合并。 //找到是否生成了新的PR 当前数据是否已经产生合并,则不再合并。 var newPr = insetPrList.Find(s => s.pr_purchaseid == pr.pr_purchaseid && s.icitem_id == pr.icitem_id && s.IsRequireGoods == pr.IsRequireGoods && s.supplier_type == pr.supplier_type && (s.sentry_id == null) == bl); if (newPr == null) { //有多条才进行合并 var ilist = prlist.Where(s => s.pr_purchaseid == pr.pr_purchaseid && s.icitem_id == pr.icitem_id && s.IsRequireGoods == pr.IsRequireGoods && s.supplier_type == pr.supplier_type && (s.sentry_id == null) == bl).ToList(); //var ilist = prlist.Where(s => s.pr_purchaseid == pr.pr_purchaseid && s.icitem_id == pr.icitem_id).ToList(); var pur = purList.Find(x => x.icitem_id == pr.icitem_id && x.supplier_id == pr.pr_purchaseid); if (ilist.Count > 1) { var icitem = ic_Items.Find(s => s.Id == pr.icitem_id); var prRefoccupy = occupylist.Where(s => ilist.Select(c => c.Id).ToList().Contains(s.polist_id.GetValueOrDefault())).ToList(); newPr = help.DeepCopy(pr); newPr.GenerateNewId(help.NextId()); prRefoccupy.ForEach(a => { a.polist_id = newPr.Id; }); newPr.pr_billno = Nbr.ToString();//pr单号 newPr.state = pr.state; newPr.pr_rqty = ilist.Sum(s => s.pr_rqty);//需求数量 newPr.pr_aqty = ilist.Sum(s => s.pr_aqty);//申请数量 newPr.pr_sqty = ilist.Sum(s => s.pr_sqty);//建议数量 decimal qty = newPr.pr_rqty.GetValueOrDefault(); if (pur != null)//委外的采购申请通过委外圆整逻辑处理 { //数量圆整 按最小包装量向上圆整 if (pur.packaging_qty.GetValueOrDefault() != 0) { decimal count = Math.Ceiling(qty / pur.packaging_qty.GetValueOrDefault()); qty = count * pur.packaging_qty.GetValueOrDefault(); } //判断最小起订量 qty = qty > pur.qty_min.GetValueOrDefault() ? qty : pur.qty_min.GetValueOrDefault(); newPr.pr_aqty = qty;//申请数量 newPr.pr_sqty = qty;//建议数量 } newPr.pr_ssend_date = ilist.Min(s => s.pr_ssend_date);//系统建议下单日期 newPr.pr_sarrive_date = ilist.Min(s => s.pr_sarrive_date);//系统建议到达日期(建议到货日期) /* newPr.pr_psend_date = ilist.Min(s => s.pr_psend_date);//计划下单日期 newPr.pr_parrive_date = ilist.Min(s => s.pr_parrive_date);//计划到达日期 newPr.pr_rarrive_date = ilist.Min(s => s.pr_rarrive_date);//需求到货日期*/ //newPr.pr_sysprice = newPr.pr_rqty * pr.pr_price * (1 + pr.pr_rate);//系统价格(含税) newPr.pr_orderprice = newPr.pr_aqty * pr.pr_sysprice;//订单价格(含税) ilist.ForEach(s => { s.refer_pr_billno = newPr.pr_billno; }); insetPrList.Add(newPr); ilist.ForEach(s => { s.state = 0; }); updatePrList.AddRange(ilist); Nbr++; } else { decimal qty = pr.pr_rqty.GetValueOrDefault(); if (pur != null) { //数量圆整 按最小包装量向上圆整 if (pur.packaging_qty.GetValueOrDefault() != 0) { decimal count = Math.Ceiling(qty / pur.packaging_qty.GetValueOrDefault()); qty = count * pur.packaging_qty.GetValueOrDefault(); } //判断最小起订量 qty = qty > pur.qty_min.GetValueOrDefault() ? qty : pur.qty_min.GetValueOrDefault(); pr.pr_aqty = qty;//申请数量 pr.pr_sqty = qty;//建议数量 } } } } insetAllList.AddRange(insetPrList); updateAllList.AddRange(updatePrList); } if (insetAllList.Any()) { var nbrlistDto = _serialNumberAppService.GetBillNo(insetAllList[0].factory_id.ToString(), "PR", insetAllList.Count, "admin", 1); int index = 0; foreach (var p in insetAllList) { if (nbrlistDto[index] != null) { updateAllList.Where(x => x.refer_pr_billno == p.pr_billno).ToList().ForEach(c => { c.refer_pr_billno = nbrlistDto[index].NbrResult.ToString(); }); p.pr_billno = nbrlistDto[index].NbrResult.ToString(); } index++; if (p.pr_purchaseid.GetValueOrDefault() == 0) { //数据丢失 var list = _mysql_srm_purchase.GetListAsync(s => s.icitem_id == p.icitem_id).Result; if (list.Any()) { var purchase = list.OrderBy(s => s.quota_priority).FirstOrDefault(); p.pr_purchaseid = purchase.supplier_id; p.pr_purchasename = purchase.supplier_name; p.pr_purchasenumber = purchase.supplier_number; } } } } using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { if (insetAllList.Any()) { _businessDbContext.BulkInsert(insetAllList); } if (updateAllList.Any()) { _businessDbContext.BulkUpdate(updateAllList); } if (occupylist.Any()) { _businessDbContext.BulkUpdate(occupylist); } await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("PrAutoMerge", "采购申请单自动合并更新失败:" + e.Message, _currentTenant.Id.ToString()); }; } return "ok"; } catch (Exception e) { new NLogHelper("ResourceExamineAppService").WriteLog("PrAutoMerge", "PR自动合并:" + e.Message, _currentTenant.Id.ToString()); return "PR自动合并失败,请联系管理员。"; } } } public class WorkOrdDto { public string itemNum { get; set; } public List WorkList { get; set; } = new List(); public List morderList { get; set; } = new List(); public List meOrderList { get; set; } = new List(); public decimal MinQty { get; set; } public decimal SumQty { get; set; } } public class WWPRDto { public long itemId { get; set; } public List prList { get; set; } = new List(); public ic_item icitem { get; set; } public decimal MinQty { get; set; } public decimal SumQty { get; set; } public decimal diffQty { get; set; } } }