using Business.Core.Enum; using Business.Core.MongoDBHelper; using Business.Core.Utilities; using Business.Dto; using Business.EntityFrameworkCore; using Business.EntityFrameworkCore.SqlRepositories; using Business.Model.Bang; using Business.Model.MES.IC; using Business.Model.Production; using Business.Model.Sale; using Business.Model.SRM; using Business.Model.Tech; using Business.MongoModel.MES.IC; using Business.MongoModel.Production; using Business.MongoModel.SRM; using Business.MongoModel.Tech; using Business.PriorityManagement; using Business.Quartz; using Business.ResourceExamineManagement.Dto; using EFCore.BulkExtensions; using Microsoft.EntityFrameworkCore; using MongoDB.Driver; using MongoDB.Driver.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; using System.Threading.Tasks; using Volo.Abp.Application.Services; 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 IMongoDB _mes_technique; /// /// 工序 /// private readonly IMongoDB _mes_process; /// /// 工艺关联工序 /// private readonly IMongoDB _mes_tech_process; /// /// 工艺工序关联工位 /// private readonly IMongoDB _mes_tech_proc_workshop; /// /// 物料占用记录 /// private readonly IMongoDB _ic_item_stockoccupy; private IRepository _mysql_ic_item_stockoccupy; /// /// 物料详情 /// private readonly IMongoDB _ic_item; private IRepository _mysql_ic_item; /// /// 物料BOM /// private readonly IMongoDB _ic_bom; private IRepository _mysql_ic_bom; /// /// 物料BOM明细 /// private readonly IMongoDB _ic_bom_child; private IRepository _mysql_ic_bom_child; /// /// 物料库存表 /// private readonly IMongoDB _ic_item_stock; private IRepository _mysql_ic_item_stock; /// /// 物料采购报价单 /// private readonly IMongoDB _srm_purchase; private IRepository _mysql_srm_purchase; /// /// 采购申请单 /// private readonly IMongoDB _srm_pr_main; private IRepository _mysql_srm_pr_main; /// /// 采购订单表 /// private readonly IMongoDB _srm_po_main; private IRepository _mysql_srm_po_main; /// /// 采购订单明细表 /// private readonly IMongoDB _srm_po_list; private IRepository _mysql_srm_po_list; /// /// 采购订单占用详情 /// private readonly IMongoDB _srm_po_occupy; private IRepository _mysql_srm_po_occupy; /// /// 供应商 /// private readonly IMongoDB _srm_supplier; private IRepository _mysql_srm_supplier; /// /// 委外工单 /// private readonly IMongoDB _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 readonly IMongoDB _ic_substitute; /// /// 替代群组 /// private readonly IMongoDB _ic_substitute_group; /// /// 替代群组 /// private readonly IMongoDB _ic_substitute_group_detail; /// /// 生产工单主表 /// private readonly IMongoDB _mes_morder; /// /// 生产工单子表 /// private readonly IMongoDB _mes_moentry; /// /// 在制工单占用记录表 /// private readonly IMongoDB _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 _shopCalendarWorkCtr; /// /// 休息时间段 /// private readonly ISqlRepository _qualityLineWorkDetail; /// /// 节假日 /// private readonly ISqlRepository _holidayMaster; /// /// 标准BOM表 /// private readonly ISqlRepository _productStructureMaster; /// /// 工单工序表 /// private ISqlRepository _workOrdRouting; /// /// 工单主表 /// private ISqlRepository _workOrdMaster; /// /// 工单物料明细 /// private ISqlRepository _workOrdDetail; private readonly ISqlRepository _rf_serialnumber; private readonly ISqlRepository _locationDetail; /// /// 资源检查入参 /// private readonly SeorderentryDto param = new SeorderentryDto(); /// /// 预处理 /// private readonly PretreatmentAppService _pretreatmentAppService; /// /// 在途检查 /// private readonly PurchaseOrderAppService _purchaseOrderAppService; /// /// 工单App /// private readonly MorderAppService _morderAppService; /// /// 计算BOM平铺物料情况 /// private readonly CalcBomViewAppService _CalcBomViewAppService; 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 _purOrdMaster; private ISqlRepository _purOrdDetail; private ISqlRepository _itemPackMaster; private ISqlRepository _generalizedCodeMaster; /// /// 生产排产 /// 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(); private readonly IUnitOfWorkManager _unitOfWorkManager; #endregion #region 构造函数 /// /// 构造函数 /// /// /// public ResourceExamineAppService( IMongoDB mes_technique, IMongoDB mes_process, IMongoDB mes_tech_process, IMongoDB mes_tech_proc_workshop, IMongoDB ic_item, IMongoDB ic_bom, IMongoDB ic_bom_child, IMongoDB ic_item_stock, IMongoDB mes_oorder, IMongoDB srm_pr_main, IMongoDB srm_po_main, IMongoDB srm_po_list, IMongoDB srm_po_occupy, IMongoDB srm_purchase, IMongoDB ic_substitute, IMongoDB ic_substitute_group, IMongoDB ic_substitute_group_detail, IMongoDB mes_morder, IMongoDB mes_moentry, IMongoDB mes_mooccupy, IMongoDB ic_item_stockoccupy, IMongoDB srm_supplier, IRepository mysql_ic_item, 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 lineMaster, ISqlRepository itemMaster, PretreatmentAppService pretreatmentAppService, CalcBomViewAppService calcbomviewAppService, PurchaseOrderAppService purchaseOrderAppService, ICurrentTenant currentTenant, MorderAppService morderAppService, BusinessBangDbContext businessBangDbContext, BusinessDbContext businessDbContext, ProductionScheduleAppService productionScheduleAppService, ISqlRepository routingOpDetail, ISqlRepository productStructureMaster, ISqlRepository workOrdRouting, ISqlRepository workOrdMaster, ISqlRepository workOrdDetail, ISqlRepository nbrMaster, ISqlRepository nbrDetail, ISqlRepository purOrdMaster, ISqlRepository purOrdDetail, PriorityAppService priorityAppService, ISqlRepository prodLineDetail, ISqlRepository shopCalendarWorkCtr, ISqlRepository qualityLineWorkDetail, ISqlRepository holidayMaster, ProductExamineAppService productExamineAppService, ISqlRepository rf_serialnumber, ISqlRepository locationDetail, ISqlRepository itemPackMaster, ISqlRepository generalizedCodeMaster, IUnitOfWorkManager unitOfWorkManager ) { _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; _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; _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_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; _pretreatmentAppService = pretreatmentAppService; _CalcBomViewAppService = calcbomviewAppService; _purchaseOrderAppService = purchaseOrderAppService; _currentTenant = currentTenant; _morderAppService = morderAppService; _businessBangDbContext = businessBangDbContext; _businessDbContext = businessDbContext; _productionScheduleAppService = productionScheduleAppService; _routingOpDetail = routingOpDetail; _productStructureMaster = productStructureMaster; _workOrdRouting = workOrdRouting; _workOrdMaster = workOrdMaster; _workOrdDetail = workOrdDetail; _lineMaster = lineMaster; _itemMaster = itemMaster; _nbrMaster = nbrMaster; _nbrDetail = nbrDetail; _purOrdMaster = purOrdMaster; _purOrdDetail= purOrdDetail; _priorityAppService = priorityAppService; _rf_serialnumber = rf_serialnumber; _prodLineDetail = prodLineDetail; _shopCalendarWorkCtr = shopCalendarWorkCtr; _qualityLineWorkDetail = qualityLineWorkDetail; _holidayMaster = holidayMaster; _productExamineAppService = productExamineAppService; _locationDetail = locationDetail; _itemPackMaster = itemPackMaster; _generalizedCodeMaster = generalizedCodeMaster; _unitOfWorkManager = unitOfWorkManager; } #endregion /// /// 资源检查 /// /// /// 类型(0,销售订单 1,销售订单行) /// /// public async Task ReceiveResult(string ids,int type) { if (string.IsNullOrEmpty(ids)) { throw new NotImplementedException("请输入正确的订单号!"); } Array alist = ids.Split(','); ResourceCheckInputDto input = new ResourceCheckInputDto(); input.sorderId = new List(); foreach (string longid in alist) { input.sorderId.Add(long.Parse(longid)); } //资源检查结果 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()); //throw new NotImplementedException("订单数据不存在!"); return "订单数据不存在"; } //获取订单行数据 sentrys = await _mysql_crm_seorderentry.GetListAsync(p => input.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 => input.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 "订单数据不存在"; } } input.tenantId = sorders[0].tenant_id; input.factoryId = sorders[0].factory_id.GetValueOrDefault(); //资源检查入参全局变量赋值 param.tenantId = input.tenantId; param.factoryId = input.factoryId; param.checkflag = true; rtn.sorderid = input.sorderId; //资源检查明细list List examines = new List(); ExamineResult dtl; //处理销售订单优先级 sorders = _priorityAppService.CalcOrderPriority(sorders, sentrys); AsyncItemStockFromWMS(sentrys); //处理订单行优先级 sentrys = _priorityAppService.CalcOrderEntryPriority(sorders, sentrys); //删除同步Mysql后旧数据 await DeleteMySqlOldData(sentrys); //通过订单行的产品代码获取物料BOM数据 List boms = _ic_bom.Find(p => sentrys.Select(m => m.item_number).Contains(p.item_number) && p.factory_id == input.factoryId && p.tenant_id == input.tenantId && !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(autoCreates); pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; } //数据库快照-同步mysql库数据到mongoDB中 await DbSnapShot(input.tenantId, input.factoryId, bangid, pretreatments); //记录订单行的物料齐套时间 List kittingTimes = new List(); DataInitialization(boms, bangid, icitemlist, stocklist, pretreatments); foreach (var sorder in sorders) { param.sorderId = sorder.Id; param.tenantId = input.tenantId; param.factoryId = input.factoryId; //param.checkflag = true; _morderAppService.param = param; _purchaseOrderAppService.param = param; _CalcBomViewAppService.param = param; _CalcBomViewAppService.seorder = sorder;//销售订单 var orderSentrys = sentrys.Where(s => s.seorder_id == sorder.Id).ToList(); foreach (var item in orderSentrys) { //获取销售订单“是否加急”字段 int urgent = sorder.urgent; //工单资源检查信息 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; //获取当前物料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, urgent, 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 = "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 _mysql_crm_seorderentry.UpdateManyAsync(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 _mes_morder.InsertMany(_CalcBomViewAppService.mordersInsertList); } if (prmainlist.Any()) { await _srm_pr_main.InsertMany(prmainlist); } if (_CalcBomViewAppService.mooccupyAllInsertList.Any()) { _CalcBomViewAppService.mooccupyAllInsertList.ForEach(s => { s.tenant_id = param.tenantId; s.factory_id = param.factoryId; }); await _mes_mooccupy.InsertMany(_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.tenantId; s.factory_id = param.factoryId; }); await _mes_moentry.InsertMany(_CalcBomViewAppService.moentriesInsertList); /*var mesmoentrys = ObjectMapper.Map, List>(_CalcBomViewAppService.moentriesInsertList); _businessDbContext.BulkInsert(mesmoentrys);*/ } if (_CalcBomViewAppService.orderList.Any()) { _CalcBomViewAppService.orderList.ForEach(s => { s.tenant_id = param.tenantId; s.factory_id = param.factoryId; }); await _mes_oorder.InsertMany(_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.id = help.NextId(); s.tenant_id = param.tenantId; s.factory_id = param.factoryId; }); await _ic_item_stockoccupy.InsertMany(_CalcBomViewAppService.newStockOccList); } if (_CalcBomViewAppService.srm_Po_OccupiesInsert.Any()) { _CalcBomViewAppService.srm_Po_OccupiesInsert.ForEach(s => { s.tenant_id = param.tenantId; s.factory_id = param.factoryId; }); await _srm_po_occupy.InsertMany(_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; //检查结果写入数据库 var b_Examine_Results = ObjectMapper.Map, List>(rtn.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 rtn.examines) { var b_ex = ObjectMapper.Map(ex); b_ex.GenerateNewId(help.NextId());// = help.NextId(); if (_CalcBomViewAppService.mordersInsertList.Any()) { var moentry = _CalcBomViewAppService.moentriesInsertList.Where(s => s.soentry_id == b_ex.sentry_id).FirstOrDefault(); if (moentry != null) { var sentryMo = _CalcBomViewAppService.mordersInsertList.Where(s => s.mysql_id == moentry.moentry_moid).FirstOrDefault(); if (sentryMo != null) { b_ex.morder_id = sentryMo.mysql_id; b_ex.morder_no = sentryMo.morder_no; } } } b_ex.create_time = DateTime.Now; b_ex.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; o.factory_id = param.factoryId; }); 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.tenant_id = param.tenantId; o.factory_id = param.factoryId; }); 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(); return e.Message; } } //清空快照数据 await ClearSnapShot(bangid); return JsonConvert.SerializeObject("ok"); } /// /// 资源检查结果评审 /// /// /// 类型(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.GetManyByCondition(x => seIds.Contains(x.soentry_id.Value)).Result; List mordersList = _mes_morder.GetManyByCondition(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.sys_material_date = newExm.sys_material_date; se.sys_capacity_date = newExm.sys_capacity_date; //如果计算记录有工单id,则代表有生成工单,而不是占用计划工单 if (newExm.morder_id.GetValueOrDefault() != 0) { var me = moentry.Find(s => s.soentry_id == se.Id && s.bang_id == newExm.bangid); if (me == null) { //补救场景,假设mongdb数据丢失,从一个json格式中获取数据 } var mo = mordersList.Find(s => s.mysql_id == me.moentry_moid && s.bang_id == newExm.bangid); if (mo == null) { //补救场景,假设mongdb数据丢失,从一个json格式中获取数据 } WriteMoentry.Add(me); WriteMorder.Add(mo); } 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)); //同步工单 CreateWorkOrdDates(moderlist, allRoutings, workOrds, workOrdRoutings, workOrdDetails); } //当前订单号所关联的最新计算结果里的占用记录 List mooccupyList = await _mes_mooccupy.GetManyByCondition(s => seIds.Contains(s.moo_id_billid.Value) && bangidList.Contains(s.bang_id.Value)); //委外工单计算记录 List oorderList = await _mes_oorder.GetManyByCondition(s => seIds.Contains(s.sentry_id.Value) && bangidList.Contains(s.bang_id.Value)); //PO占用记录 List po_occupy = await _srm_po_occupy.GetManyByCondition(s => seIds.Contains(s.eid.Value) && bangidList.Contains(s.bang_id.Value)); List prmainlist = await _srm_pr_main.GetManyByCondition(s => seIds.Contains(s.sentry_id.Value) && bangidList.Contains(s.bang_id.Value)); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { await _mysql_crm_seorderentry.UpdateManyAsync(sentrys); //批量保存 后期考虑子工单 if (moderlist.Any()) { _businessDbContext.BulkInsert(moderlist); if (workOrds.Any()) { _workOrdMaster.Insert(workOrds); } if (workOrdRoutings.Any()) { _workOrdRouting.Insert(workOrdRoutings); } if (workOrdDetails.Any()) { _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); } //沟通方老师与何腾,库存与库存占用,使用方老师得locationDetail和workorddetital 做需求数量和已发数量来实现库存占用和已扣减库存? /*if (sklist.Any()) { sklist.ForEach(s => { s.id = help.NextId(); s.tenant_id = param.tenantId; s.factory_id = param.factoryId; }); await _ic_item_stockoccupy.InsertMany(sklist); }*/ if (po_occupy.Any()) { po_occupy.ForEach(s => { 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) { if (icBoms.Count == 0) { return; } //添加物料bom数据 foreach (var ib in icBoms) { if (!bomlist.Exists(s => s.mysql_id == ib.mysql_id)) { bomlist.Add(ib); } } //获取物料bom明细数据 //List childList = _ic_bom_child.GetManyByCondition(p => icBoms.Select(m => m.mysql_id).Contains(p.bom_id) && p.use_status == 1 && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result.ToList(); List childList = _ic_bom_child.GetManyByCondition(p => icBoms.Select(m => m.mysql_id).Contains(p.bom_id) && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result.ToList(); //没有明细数据,终止 if (childList.Count == 0) { return; } foreach (var bchild in childList) { if (!bomchildlist.Exists(s => s.mysql_id == bchild.mysql_id)) { bomchildlist.Add(bchild); } } //通过物料bom明细数据反查物料bom数据 var boms = _ic_bom.GetManyByCondition(p => childList.Select(m => m.icitem_id).ToList().Contains(p.icitem_id) && p.use_status == 1 && p.tenant_id == param.tenantId && p.factory_id == param.factoryId && !p.IsDeleted).Result.ToList(); foreach (var chd in childList) { var curBoms = boms.Where(p => p.icitem_id == chd.icitem_id).ToList(); GetIcBomData(curBoms, bomlist, bomchildlist); } } /// /// 删除旧订单行数据 /// /// /// /// /// 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 _mysql_mes_mooccupy.DeleteManyAsync(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 tenantId, long factoryId, long bangid,List pretreatments) { //同步物料库存数据 根据预处理,来只找出部分数据同步。 List itemIds = pretreatments.Select(s => s.item_id.GetValueOrDefault()).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 => itemIds.Contains(p.icitem_id)).Result; if (icitemStokc.Count > 0) { List numbers = pretreatments.Select(s => s.item_number).ToList(); var locStock = _locationDetail.Select(a => numbers.Contains(a.ItemNum) && a.IsActive && a.Domain == factoryId.ToString()); //设置当前计算bangid icitemStokc.ForEach(item => { item.bang_id = bangid; var pret = pretreatments.Find(s => s.item_id == item.icitem_id); if(pret != null) { item.sqty = locStock.Where(s => s.ItemNum == pret.item_number).Sum(p => p.QtyOnHand.GetValueOrDefault()); } }); var moIcitemStokc = ObjectMapper.Map, List>(icitemStokc); moIcitemStokc.ForEach(item => { item.id = help.NextId(); }); //插入数据 await _ic_item_stock.InsertMany(moIcitemStokc); } //在制工单占用记录表 var mes_mooccupy = _mysql_mes_mooccupy.GetListAsync(x => x.tenant_id == tenantId && x.factory_id == factoryId).Result; if (mes_mooccupy.Count > 0) { mes_mooccupy.ForEach(item => { item.bang_id = bangid; }); var moMes_mooccupy = ObjectMapper.Map, List>(mes_mooccupy); moMes_mooccupy.ForEach(item => { item.id = help.NextId(); }); await _mes_mooccupy.InsertMany(moMes_mooccupy); } //工单主表 var mes_morder = _mysql_mes_morder.GetListAsync(x => x.tenant_id == tenantId && x.factory_id == factoryId).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.id = help.NextId(); }); await _mes_morder.InsertMany(moMes_morder); } //工单子表 var mes_moentry = _mysql_mes_moentry.GetListAsync(x => x.tenant_id == tenantId && 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.id = help.NextId(); }); await _mes_moentry.InsertMany(moMes_moentry); } //TODO:要不要根据某些条件只同步有效的数据 //采购订单 var srm_po_main = _mysql_srm_po_main.GetListAsync(x => x.tenant_id == tenantId && x.factory_id == factoryId).Result; if (srm_po_main.Count > 0) { srm_po_main.ForEach(item => { item.bang_id = bangid; }); var moSrm_po_main = ObjectMapper.Map, List>(srm_po_main); moSrm_po_main.ForEach(item => { item.id = help.NextId(); }); await _srm_po_main.InsertMany(moSrm_po_main); } //采购订单明细 var srm_po_list = _mysql_srm_po_list.GetListAsync(x => x.tenant_id == tenantId && x.factory_id == factoryId).Result; if (srm_po_list.Count > 0) { srm_po_list.ForEach(item => { item.bang_id = bangid; }); var moSrm_po_list = ObjectMapper.Map, List>(srm_po_list); moSrm_po_list.ForEach(item => { item.id = help.NextId(); }); await _srm_po_list.InsertMany(moSrm_po_list); } //采购订单占用详情 var srm_po_occupy = _mysql_srm_po_occupy.GetListAsync(x => x.tenant_id == tenantId && x.factory_id == factoryId).Result; if (srm_po_occupy.Count > 0) { srm_po_occupy.ForEach(item => { item.bang_id = bangid; }); var moSrm_po_occupy = ObjectMapper.Map, List>(srm_po_occupy); moSrm_po_occupy.ForEach(item => { item.id = help.NextId(); }); await _srm_po_occupy.InsertMany(moSrm_po_occupy); } } /// /// 清处数据库快照 /// /// public async Task ClearSnapShot(long bangid) { //清除物料库存数据 await _ic_item_stock.Delete(p => p.bang_id == bangid); //清除工单占用记录表 await _mes_mooccupy.Delete(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.Delete(p => p.bang_id == bangid); //清除采购订单明细 await _srm_po_list.Delete(p => p.bang_id == bangid); //清除采购订单占用详情 await _srm_po_occupy.Delete(p => p.bang_id == bangid); } /// /// 根据物料id获取物料4个提前期 /// /// 物料id /// 企业id /// 工厂id /// private List GetLeadTime(List icItemIds, long tenantId, long factoryid) { return icItemIds.Where(p => p.factory_id == factoryid && p.tenant_id == tenantId && !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 tenantId, long factoryid) { return _srm_purchase.Find(p => icItemIds.Contains(p.icitem_id) && p.tenant_id == tenantId && 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, long bangid, List icitemlist, List itemsupplierList, PoActionListDto poaction) { var zcPr = list.Where(a => a.pr_billno.StartsWith("PR")).ToList(); if (zcPr.Any()) { AutoCreatePOFromPRByType(zcPr, bangid, icitemlist, itemsupplierList, poaction,1); } var wwPr = list.Where(a => a.pr_billno.StartsWith("WWPR")).ToList(); if (wwPr.Any()) { AutoCreatePOFromPRByType(wwPr, bangid, icitemlist, itemsupplierList, poaction,2); } } /// /// 根据PR生成PO /// /// /// /// /// /// /// 1正常PO,2是委外 private void AutoCreatePOFromPRByType(List list, long bangid, List itemList, List itemsupplierList, PoActionListDto poaction,int poType) { List polist = new List(); List podetaillist = new List(); //var itemList = _ic_item.Find(a => a.tenant_id == input.tenantId && a.factory_id == input.factoryId).Result; //将PR按供应商和物料和日期(一周内)进行合并,生成PO //1.按照供应商、需求日期排序 //2.判断是不是同一个供应商,不是的话就新建一个PO;是的话判断是不是同一周,不是的话就新建一个PO,是的话判断有没有相同物料,有的话合并物料数量价格,没有的话新建一条明细 list = list.OrderBy(a => a.pr_purchaseid).ThenBy(b => b.pr_rarrive_date).ToList(); long? supplierId = -1; DateTime supplierDate = DateTime.Now; foreach (var item in list) { mo_srm_po_occupy srm_Po_Occupy = new mo_srm_po_occupy(); srm_Po_Occupy.id = help.NextId(); srm_Po_Occupy.mysql_id = help.NextId(); srm_Po_Occupy.bang_id = bangid; srm_Po_Occupy.morder_mo = item.pr_mono; srm_Po_Occupy.qty = item.pr_aqty; srm_Po_Occupy.eid = item.sentry_id; if (item.pr_purchaseid != supplierId) { var itemsupplier = itemsupplierList.Find(a => a.mysql_id == item.pr_purchaseid && a.tenant_id == param.tenantId && a.factory_id == param.factoryId); //新建一个PO mo_srm_po_main po_Main = new mo_srm_po_main(); po_Main.id = help.NextId(); po_Main.mysql_id = help.NextId(); po_Main.po_billno = poType==1? GetMaxSerialNumber(416188684804165) : GetMaxSerialNumber(416555323363397); po_Main.po_purchaser = item.pr_purchaser; po_Main.po_purchaser_no = item.pr_purchaser_num; po_Main.po_ssend_date = DateTime.Now; po_Main.po_total = item.pr_orderprice; po_Main.po_tax_rate = item.pr_rate; po_Main.po_express = 1; po_Main.state = 0; po_Main.po_note = "PR自动转PO"; po_Main.po_order_type = 1; po_Main.currency = item.currencytype; po_Main.bill_type = poType; po_Main.supplier_id = item.pr_purchaseid; po_Main.supplier_name = item.pr_purchasename; po_Main.supplier_no = item.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.factory_id = param.factoryId; po_Main.tenant_id = param.tenantId; po_Main.bang_id = bangid; po_Main.po_delivery = 1; polist.Add(po_Main); mo_srm_po_list podetail = new mo_srm_po_list(); podetail.id = help.NextId(); podetail.mysql_id = help.NextId(); podetail.po_id = po_Main.mysql_id; podetail.po_billno = po_Main.po_billno; podetail.polist_row = podetaillist.Where(a => a.po_billno == po_Main.po_billno).Count() + 1; podetail.pr_id = item.mysql_id; podetail.pr_billno = item.pr_billno; podetail.pr_purchase_id = po_Main.supplier_id; podetail.pr_purchase_name = po_Main.supplier_name; podetail.icitem_id = item.icitem_id; podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number; podetail.icitem_name = item.icitem_name; podetail.qty = item.pr_aqty; podetail.netprice = item.pr_price; podetail.rate = item.pr_rate; podetail.price = item.pr_orderprice / item.pr_aqty; podetail.total_price = item.pr_orderprice; podetail.plan_qty = item.pr_aqty; podetail.unit = item.pr_unit; podetail.state = item.state; podetail.rarrdate = item.pr_rarrive_date; podetail.rnumber = 0; podetail.currencytype = item.currencytype; podetail.create_time = DateTime.Now; podetail.factory_id = param.factoryId; podetail.tenant_id = param.tenantId; podetail.bang_id = bangid; podetail.stock_id = 1; podetaillist.Add(podetail); srm_Po_Occupy.polist_id = podetail.mysql_id; srm_Po_Occupy.polist_row = podetail.polist_row; srm_Po_Occupy.type = MorderEnum.Zyjc_Type;//TODO:类型未知 srm_Po_Occupy.stime = podetail.create_time; srm_Po_Occupy.etime = podetail.rarrdate; supplierId = item.pr_purchaseid; supplierDate = item.pr_rarrive_date.Value; } else { //同一个供应商先判断需求日期是否在同一周 if (IsSameWeek(supplierDate, item.pr_rarrive_date.Value)) { var pomain = polist.FindAll(x => x.supplier_id == item.pr_purchaseid).OrderByDescending(b => b.create_time).First(); List detail = podetaillist.FindAll(a => a.po_billno == pomain.po_billno && a.icitem_id == item.icitem_id); if (detail.Count > 0) { //TODO:只能记录一条PR,可能需要先合PR //存在同一种物料,存在就计算数量和价格, detail[0].qty = detail[0].qty + item.pr_aqty; detail[0].netprice = detail[0].netprice + item.pr_price; detail[0].total_price = detail[0].total_price + item.pr_orderprice; detail[0].plan_qty = detail[0].plan_qty + item.pr_aqty; detail[0].rarrdate = item.pr_rarrive_date; srm_Po_Occupy.polist_id = detail[0].mysql_id; srm_Po_Occupy.polist_row = detail[0].polist_row; srm_Po_Occupy.type = MorderEnum.Zyjc_Type;//TODO:类型未知 srm_Po_Occupy.stime = detail[0].create_time; srm_Po_Occupy.etime = detail[0].rarrdate; pomain.po_total += item.pr_orderprice; } else { //不存在同一种物料新增一条明细 mo_srm_po_list podetail = new mo_srm_po_list(); podetail.id = help.NextId(); podetail.mysql_id = help.NextId(); podetail.po_id = pomain.mysql_id; podetail.po_billno = pomain.po_billno; podetail.polist_row = podetaillist.Where(a => a.po_billno == pomain.po_billno).Count() + 1; podetail.pr_id = item.mysql_id; podetail.pr_billno = item.pr_billno; podetail.pr_purchase_id = pomain.supplier_id; podetail.pr_purchase_name = pomain.supplier_name; podetail.icitem_id = item.icitem_id; podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number; podetail.icitem_name = item.icitem_name; podetail.qty = item.pr_aqty; podetail.netprice = item.pr_price; podetail.rate = item.pr_rate; podetail.price = item.pr_orderprice / item.pr_aqty; podetail.total_price = item.pr_orderprice; podetail.plan_qty = item.pr_aqty; podetail.unit = item.pr_unit; podetail.state = item.state; podetail.rarrdate = item.pr_rarrive_date; podetail.rnumber = 0; podetail.currencytype = item.currencytype; podetail.create_time = DateTime.Now; podetail.factory_id = param.factoryId; podetail.tenant_id = param.tenantId; podetail.bang_id = bangid; podetail.stock_id = 1; podetaillist.Add(podetail); srm_Po_Occupy.polist_id = podetail.mysql_id; srm_Po_Occupy.polist_row = podetail.polist_row; srm_Po_Occupy.type = MorderEnum.Zyjc_Type;//TODO:类型未知 srm_Po_Occupy.stime = podetail.create_time; srm_Po_Occupy.etime = podetail.rarrdate; pomain.po_total += item.pr_orderprice; } } else { //不在同一周需要新建一张PO var itemsupplier = itemsupplierList.Find(a => a.mysql_id == item.pr_purchaseid && a.tenant_id == param.tenantId && a.factory_id == param.factoryId); //新建一个PO单 mo_srm_po_main po_Main = new mo_srm_po_main(); po_Main.id = help.NextId(); po_Main.mysql_id = help.NextId(); po_Main.po_billno = poType == 1 ? GetMaxSerialNumber(416188684804165) : GetMaxSerialNumber(416555323363397); po_Main.po_purchaser = item.pr_purchaser; po_Main.po_purchaser_no = item.pr_purchaser_num; po_Main.po_ssend_date = DateTime.Now; po_Main.po_total = item.pr_orderprice; po_Main.po_tax_rate = item.pr_rate; po_Main.po_express = 1; po_Main.state = 0; po_Main.po_note = "PR自动转PO"; po_Main.po_order_type = 1; po_Main.currency = item.currencytype; po_Main.bill_type = poType; po_Main.supplier_id = item.pr_purchaseid; po_Main.supplier_name = item.pr_purchasename; po_Main.supplier_no = item.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.factory_id = param.factoryId; po_Main.tenant_id = param.tenantId; po_Main.bang_id = bangid; po_Main.po_delivery = 1; polist.Add(po_Main); mo_srm_po_list podetail = new mo_srm_po_list(); podetail.id = help.NextId(); podetail.mysql_id = help.NextId(); podetail.po_id = po_Main.mysql_id; podetail.po_billno = po_Main.po_billno; podetail.polist_row = podetaillist.Where(a => a.po_billno == po_Main.po_billno).Count() + 1; podetail.pr_id = item.mysql_id; podetail.pr_billno = item.pr_billno; podetail.pr_purchase_id = po_Main.supplier_id; podetail.pr_purchase_name = po_Main.supplier_name; podetail.icitem_id = item.icitem_id; podetail.ItemNum = itemList.First(a => a.mysql_id == item.icitem_id).number; podetail.icitem_name = item.icitem_name; podetail.qty = item.pr_aqty; podetail.netprice = item.pr_price; podetail.rate = item.pr_rate; podetail.price = item.pr_orderprice / item.pr_aqty; podetail.total_price = item.pr_orderprice; podetail.plan_qty = item.pr_aqty; podetail.unit = item.pr_unit; podetail.state = item.state; podetail.rarrdate = item.pr_rarrive_date; podetail.rnumber = 0; podetail.currencytype = item.currencytype; podetail.create_time = DateTime.Now; podetail.factory_id = param.factoryId; podetail.tenant_id = param.tenantId; podetail.bang_id = bangid; podetail.stock_id = 1; podetaillist.Add(podetail); srm_Po_Occupy.polist_id = podetail.mysql_id; srm_Po_Occupy.polist_row = podetail.polist_row; srm_Po_Occupy.type = MorderEnum.Zyjc_Type;//TODO:类型未知 srm_Po_Occupy.stime = podetail.create_time; srm_Po_Occupy.etime = podetail.rarrdate; supplierId = item.pr_purchaseid; supplierDate = item.pr_rarrive_date.Value; } } srm_Po_Occupy.state = 1; srm_Po_Occupy.tenant_id = param.tenantId;//取销售子表企业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); } List po_mainlist = ObjectMapper.Map, List>(polist); var po_listlist = ObjectMapper.Map, List>(podetaillist); poaction.poMain.AddRange(po_mainlist); poaction.polist.AddRange(po_listlist); poaction.mopoMain.AddRange(polist); poaction.mopolist.AddRange(podetaillist); List purOrdMasters = new List(); po_mainlist.ForEach(a => { purOrdMasters.Add(new PurOrdMaster { Domain = "1001", Potype = poType==1?"po":"pw", PurOrd = a.po_billno, Buyer = a.po_purchaser, OrdDate = a.po_ssend_date, Curr = "CNY", Supp = a.supplier_no, Tax1 = a.po_tax_rate, Department = a.purchasing_orgname, CustPhone = a.suppliertelephone, CustAddress = a.supplierdddress, IsActive = true, CreateTime = a.create_time, UpdateTime = a.update_time }); }); poaction.poMasterList.AddRange(purOrdMasters); List purOrdDetails = new List(); po_listlist.ForEach(a => { purOrdDetails.Add(new PurOrdDetail { Domain = "1001", Potype = poType == 1 ? "po" : "pw", PurOrd = a.po_billno, IsActive = true, CreateTime = a.create_time, UpdateTime = a.update_time, Line = a.polist_row, ItemNum = a.ItemNum, QtyOrded = a.qty.GetValueOrDefault(), QtyReceived = a.rqty.GetValueOrDefault(), PurCost = a.price, StdCost = a.price / (1 + a.rate), TaxRate = a.rate, DueDate = a.rarrdate }); }); poaction.poDetailList.AddRange(purOrdDetails); } /// /// 计划工单齐套检查 /// /// /// public async Task PlanOrderResourceCheck(string workOrd) { List workOrds = workOrd.Split(",").ToList(); if (workOrds.Count == 0) { return ""; } List mo_Mes_Morders = _mysql_mes_morder.GetListAsync(x => workOrds.Contains(x.morder_no)).Result; if (mo_Mes_Morders.Any()) { //只走计划工单 await OrderKittingCheck(mo_Mes_Morders, true); } else { JsonConvert.SerializeObject("未查找到对应的计划工单,请联系管理员。"); } return JsonConvert.SerializeObject("ok"); } /// /// 按未来N天工单齐套检查 /// /// /// public async Task OrderResourceCheck(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 rtn = await OrderKittingCheck(mo_Mes_Morders); OrderResourceViewDto result = DataPackage(rtn); result.DayBulletinBoardList = result.DayBulletinBoardList.OrderByDescending(d => d.day).ToList(); //保存检查结果 SaveExamineResult(result.KittingCheckResultList, result.DayBulletinBoardList, 1); return JsonConvert.SerializeObject("ok"); } else { return JsonConvert.SerializeObject("没有需要检查的工单"); } } /// /// 工单齐套检查/替代料齐套检查结果保存 /// /// /// 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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("没有需要检查的工单"); } } /// /// 检查结果组装 /// /// /// /// 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) { //资源检查结果 PschedDto rtn = new PschedDto(); //资源检查明细list List examines = new List(); OrderCheckDto input = new OrderCheckDto(); if (mo_Mes_Morders.Any()) { input.tenantId = mo_Mes_Morders[0].tenant_id; input.factoryId = mo_Mes_Morders[0].factory_id.GetValueOrDefault(); } //资源检查入参全局变量赋值 param.tenantId = input.tenantId; param.factoryId = input.factoryId; param.checkflag = false; param.checkPlan = planCheck; //生成当前计算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;*/ List mo_Mes_Moentries = _mysql_mes_moentry.GetListAsync(x => mo_Mes_Morders.Select(s => s.Id).Contains(x.moentry_moid.Value)).Result; //获取订单行数据 List sentrys = _mysql_crm_seorderentry.GetListAsync(p => p.tenant_id == input.tenantId && p.factory_id == input.factoryId && !p.IsDeleted && mo_Mes_Moentries.Select(x => x.soentry_id).Contains(p.Id)).Result; //删除同步Mysql后旧数据 await DeleteMySqlOldData(sentrys); List boms = _ic_bom.Find(p => mo_Mes_Morders.Select(m => m.bom_number).Contains(p.bom_number) && p.factory_id == input.factoryId && p.tenant_id == input.tenantId && !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(autoCreates); pretreatments = _mysql_b_bom_pretreatment.GetListAsync(s => boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; } //数据库快照-同步mysql库数据到mongoDB中 await DbSnapShot(input.tenantId, input.factoryId, bangid, pretreatments); DataInitialization(boms, bangid, icitemlist, stocklist, pretreatments); _morderAppService.param = param; _purchaseOrderAppService.param = param; _CalcBomViewAppService.param = param; foreach (var item in mo_Mes_Morders) { 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.order_statr_time = item.start_time; dtl.bom_number = item.bom_number; dtl.need_qty = item.need_number.GetValueOrDefault(); //获取当前物料bom数据 var childBom = boms.Where(p => p.bom_number == item.bom_number).FirstOrDefault(); var itemPrelist = pretreatments.Where(s => s.sourceid == childBom.mysql_id).ToList(); 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); } _CalcBomViewAppService.newStockOccList = new List(); _CalcBomViewAppService.mes_morder = item; //库存初始化 _CalcBomViewAppService.BomStock(getBomList, stocklist, bangid); //计算 _CalcBomViewAppService.CalcView(getBomList, bangid, item.need_number.GetValueOrDefault(), item.start_time, sklist, sentry, item.urgent, 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(); //替代关系展开list dtl.BomChildExamineList = getBomList; //添加订单行开工信息 examines.Add(dtl); } rtn.examines = examines; 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; } var itemsupplierList = _srm_supplier.Find(a => prmainlist.Select(i => i.pr_purchaseid).Contains(a.mysql_id) && a.tenant_id == input.tenantId && a.factory_id == input.factoryId).Result; if (prmainlist.Any()) { var pr_mainlist = ObjectMapper.Map, List>(prmainlist); PoActionListDto poaction = new PoActionListDto(); AutoCreatePOFromPR(prmainlist, bangid, icitemlist, itemsupplierList, poaction); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { await _srm_pr_main.InsertMany(prmainlist); _businessDbContext.BulkInsert(pr_mainlist); if (poaction.mopoMain.Any()) { await _srm_po_main.InsertMany(poaction.mopoMain); } if (poaction.mopolist.Any()) { await _srm_po_list.InsertMany(poaction.mopolist); } if (poaction.poMain.Any()) { _businessDbContext.BulkInsert(poaction.poMain); } if (poaction.polist.Any()) { _businessDbContext.BulkInsert(poaction.polist); } if (poaction.poOccupiesList.Any()) { var poOccupies = ObjectMapper.Map, List>(poaction.poOccupiesList); _businessDbContext.BulkInsert(poOccupies); } if (poaction.poMasterList.Any()) { _purOrdMaster.Insert(poaction.poMasterList); //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值 List nbrs = poaction.poMasterList.Select(a => a.PurOrd).ToList(); var nbrList = _purOrdMaster.Select(a => a.Domain == "1001" && 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("OrderKittingCheck", "工单检查数据更新失败:" + e.Message, _currentTenant.Id.ToString()); } } } //检查结果写入数据库 var b_Examine_Results = ObjectMapper.Map, List>(rtn.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 rtn.examines) { var b_ex = ObjectMapper.Map(ex); b_ex.GenerateNewId(help.NextId());// = help.NextId(); if (_CalcBomViewAppService.mordersInsertList.Any()) { var moentry = _CalcBomViewAppService.moentriesInsertList.Where(s => s.soentry_id == b_ex.sentry_id).FirstOrDefault(); if (moentry != null) { var sentryMo = _CalcBomViewAppService.mordersInsertList.Where(s => s.mysql_id == moentry.moentry_moid).FirstOrDefault(); if (sentryMo != null) { b_ex.morder_id = sentryMo.mysql_id; b_ex.morder_no = sentryMo.morder_no; } } } b_ex.create_time = DateTime.Now; b_ex.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; 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.tenant_id = param.tenantId; o.factory_id = param.factoryId; }); 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.tenant_id = param.tenantId; o.factory_id = param.factoryId; }); 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("OrderKittingCheck", "工单检查资源检查计算结果数据更新失败:" + e.Message, _currentTenant.Id.ToString()); unitOfWork.Dispose(); } } } //清空快照数据 await ClearSnapShot(bangid); return rtn; } /// /// 物料数据计算前准备 /// /// /// /// /// /// /// /// /// /// /// /// /// public void DataInitialization(List boms, long bangid, List icitemlist, List stocklist, List pretreatments) { List itemIds = pretreatments.Select(p => p.item_id.GetValueOrDefault()).ToList(); icitemlist.AddRange(_ic_item.GetManyByCondition(p => itemIds.Contains(p.mysql_id) && !p.IsDeleted).Result); #region 1、数据准备 //1.1、获取产能检查相关数据 //产品物料编码 List itemnums = pretreatments.Where(p => p.level == 1).Select(p => p.item_number).Distinct().ToList(); //产线明细 prodLines = _prodLineDetail.Select(p => itemnums.Contains(p.Part)).ToList(); //标准工序 routingOps = _routingOpDetail.Select(p => itemnums.Contains(p.RoutingCode)).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); //主工单 List mo_Mes_Morders = _mes_morder.GetManyByCondition(x => boms.Select(p => p.bom_number).Contains(x.bom_number) && (x.morder_state != MorderEnum.Accomplish_state || x.morder_state != MorderEnum.Close_state && x.morder_icitem_type != MorderEnum.XgwyMorder) && x.tenant_id == param.tenantId && x.bang_id == bangid).Result; List moids = mo_Mes_Morders.Select(p => p.mysql_id).ToList(); List mo_Mes_Moentry = _mes_moentry.GetManyByCondition(x => moids.Contains(x.moentry_moid)).Result; //工单占用表 List mes_mooccupyList = _mes_mooccupy.GetManyByCondition(x => x.moo_state == 1 && !x.IsDeleted && x.tenant_id == param.tenantId && boms.Select(p => p.item_number).Contains(x.fitem_number) && x.bang_id == bangid).Result; //物料采购订单明细 var poDetailList = _srm_po_list.GetManyByCondition(x => icitemlist.Select(p => p.mysql_id).ToList().Contains(x.icitem_id.Value) && x.bang_id == bangid && x.state == 1 && x.rstate == 1 && !x.IsDeleted).Result; //采购订单占用数据 var poOccupys = _srm_po_occupy.GetManyByCondition(x => poDetailList.Select(p => p.id).ToList().Contains(x.polist_id) && x.bang_id == bangid && !x.IsDeleted).Result; #endregion //处理一下已经插入得占用记录 //物料库存 stocklist.AddRange(_ic_item_stock.GetManyByCondition(p => p.factory_id == param.factoryId && p.bang_id == bangid && itemIds.Contains(p.icitem_id)).Result); //物料提前期 leadTimeList = GetLeadTime(icitemlist, param.tenantId, param.factoryId);//提前期列表 supplierList = GetSupplier(itemIds, param.tenantId, param.factoryId);//供应商列表 _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; //物料表 } 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(List boms, List bomlist, List bomchildlist, List icitemlist, List sublist, List suballlist, List subdtllist) { //获取物料bom,物料bom明细 GetIcBomData(boms, bomlist, bomchildlist); //根据明细集合查出所有得替代关系表数据集合 List codeList = bomchildlist.Select(c => c.substitute_code).ToList(); sublist.AddRange(_ic_substitute.GetManyByCondition(p => codeList.Contains(p.substitute_code) && !p.IsDeleted).Result); List subidlist = sublist.Select(c => c.mysql_id).ToList(); suballlist.AddRange(_ic_substitute_group.GetManyByCondition(p => subidlist.Contains(p.substitute_group_id) && !p.IsDeleted).Result); List suballidlist = suballlist.Select(c => c.mysql_id).ToList(); subdtllist.AddRange(_ic_substitute_group_detail.GetManyByCondition(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.GetManyByCondition(p => itemIds.Contains(p.mysql_id) && !p.IsDeleted).Result); } /// /// 自动生成BOM预处理清单 /// public void AutoCreateBomBill(List ic_Boms = null) { ic_Boms ??= _ic_bom.Find(p => p.factory_id == 10101 && p.tenant_id == 101 && !p.IsDeleted).Result.ToList(); var pretreatment = _mysql_b_bom_pretreatment.GetListAsync(s => ic_Boms.Select(c => c.mysql_id).ToList().Contains(s.sourceid)).Result; //物料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(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.Find(s => s.sourceid == bom.mysql_id && s.bom_id == bom.mysql_id); if (pret != null) { if (pret.version == bom.version) { //如果存在,且版本相同,则不需要处理 continue; } //版本不同则重新生成 deleteList.Add(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; }); addList.AddRange(list); } if (deleteList.Any()) { _businessDbContext.BulkDelete(deleteList); } if (addList.Any()) { _businessDbContext.BulkInsert(addList); //await _mysql_b_bom_pretreatment.InsertManyAsync(addList); } } /// /// BOM清单批量预处理 /// public void AutoCreateBomBillInterface() { AutoCreateBomBill(); } public async Task AutoCreatePickBill(List workOrds, List dbPeriodSequences, List nbrMasterList, List nbrDetailList) { if (dbPeriodSequences.Any()) { //按照工单领料,一个工单一个领料单,之前是按照排产日期和产线分别领料 foreach (var workord in workOrds) { Dictionary dictItemQty = new Dictionary(); List lines = dbPeriodSequences.Where(a => a.WorkOrds == workord).Select(a => a.Line).Distinct().ToList(); List lineMasters = _lineMaster.Select(p => lines.Contains(p.Line) && p.Domain == "1001" && p.IsActive); List itemList = GetProductStructure(dbPeriodSequences.First(a => a.WorkOrds == workord).ItemNum); var childrenList = itemList.Select(a => a.ComponentItem).Distinct().ToList(); List itemLocList = _itemMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList(); List itemPackList = _itemPackMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList(); var Nbr = GetMaxSerialNumber(417416915624005); //根据某一产线汇总即该工单的总数 decimal QtyOrdSum = dbPeriodSequences.Where(a => a.WorkOrds == workord && a.Line == lines[0]).Sum(a => a.OrdQty.GetValueOrDefault()); string LocationTo= lineMasters.FirstOrDefault()?.Location; nbrMasterList.Add(new NbrMaster { Domain = "1001", Type = "SM", Nbr = Nbr, Remark = "下达自动领料", Date = dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a => a.PlanDate), //ProdLine = item.Line, Status = "", WorkOrd = workord, QtyOrd = QtyOrdSum, IsActive = true, IsChanged = true, Name = "1001", Department = "101", CreateTime = DateTime.Now, UpdateTime = DateTime.Now, CreateUser = "1001", UpdateUser = "1001" }); int i = 1; itemList?.ForEach(a => { var find = itemLocList?.Find(c => c.ItemNum == a.ComponentItem); string LocationFrom = ""; if (find != null) { LocationFrom = find.Location; } //相同物料汇总 var itemComponent = nbrDetailList.Find(b => b.Nbr == Nbr && b.ItemNum == a.ComponentItem); if (itemComponent == null) { nbrDetailList.Add(new NbrDetail { Domain = "1001", Type = "SM", Nbr = Nbr, ItemNum = a.ComponentItem, QtyFrom = 0, QtyTo = 0, LocationFrom = LocationFrom, LocationTo = LocationTo,//现在这几条线是同一线边仓,暂时不考虑多个线边仓 WorkOrd = workord, QtyOrd = QtyOrdSum * a.Qty, CurrQtyOpened = QtyOrdSum * a.Qty, Line = i, IsActive = true, CreateTime = DateTime.Now, UpdateTime = DateTime.Now, CreateUser = "1001", UpdateUser = "1001", UM = a.UM }); i++; } else { nbrDetailList.First(b => b.Nbr == Nbr && b.ItemNum == a.ComponentItem).QtyOrd = itemComponent.QtyOrd + QtyOrdSum * a.Qty; nbrDetailList.First(b => b.Nbr == Nbr && b.ItemNum == a.ComponentItem).CurrQtyOpened = itemComponent.CurrQtyOpened + QtyOrdSum * a.Qty; } }); 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(); //var items = _mysql_ic_item.GetListAsync(a => itemKeys.Contains(a.number) && a.factory_id == 1001 && a.tenant_id == 1000).Result; //var itemIds = items.Select(b => b.Id).ToList(); //var leadTimes = GetLeadTime(itemIds, 1000, 1001).Max(a=>a.ordissu_days.GetValueOrDefault()); 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).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-1 * Convert.ToDouble(leadTimes)); } else { nbrMasterList.First(a => a.Nbr == Nbr).Date = dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-7); } //TODO: //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。 //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。 var locStock = _locationDetail.Select(a => itemKeys.Contains(a.ItemNum) && a.IsActive && a.Domain == "1001"); 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); } } } public void AsyncItemStockFromWMS(List sentrys) { //产品编码 var itemList = sentrys.Select(a => a.item_number).Distinct().ToList(); List itemChildList = new List(); itemList.ForEach(a => { itemChildList.AddRange(GetChildItemNumber(a, new List())); }); var stockList = _locationDetail.Select(a => a.Domain == "1001" && a.IsActive && itemChildList.Distinct().Contains(a.ItemNum)); var groupList = stockList. GroupBy(m => new { m.ItemNum }). Select(a => new { ItemNum = a.Key.ItemNum, Qty = a.Sum(c => c.QtyOnHand) }).ToList(); var itemNums = groupList.Select(b => b.ItemNum).ToList();//需要处理的dop物料编码集合 var items = _mysql_ic_item.GetListAsync(a => itemNums.Contains(a.number) && a.factory_id == 1001 && a.tenant_id == 1000).Result; var itemIds = items.Select(b => b.Id).ToList();//需要处理的dop物料id集合 List mysqlStock = _mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.Id) && a.factory_id == 1001 && a.tenant_id == 1000).Result; List needAddList = new List(); foreach (var stockWMS in groupList) { foreach (var num in items) { if (stockWMS.ItemNum == num.number) { var item = mysqlStock.Find(a => a.Id == num.Id); if (item != null) { item.sqty = groupList.First(a => a.ItemNum == num.number).Qty; } else { ic_item_stock stock = new ic_item_stock(); stock.GenerateNewId(help.NextId()); stock.factory_id = 1001; stock.tenant_id = 1000; stock.icitem_id = num.Id; stock.icitem_name = num.name; stock.sqty = groupList.First(a => a.ItemNum == num.number).Qty; } break; } }; } if (needAddList.Count > 0) { _businessDbContext.BulkInsert(needAddList); } _businessDbContext.BulkUpdate(mysqlStock); } //循环获取子级物料编码,包括产品本身,有重复的结果去重即可 public List GetChildItemNumber(string itemNum, List list) { list.Add(itemNum); var productStructures = _productStructureMaster.Select(p => p.ParentItem == itemNum && p.Domain == "1001" && p.IsActive); list.AddRange(productStructures.Select(a => a.ComponentItem)); foreach (var item in productStructures) { if (item.StructureType.ToUpper() == "X") { GetChildItemNumber(item.ComponentItem, list); } } return list; } /// /// 得到一个流水号的最大流水号 /// /// 流水号id /// json数据,可以用json中的某个字段值作为通配符字替换流水号格式。 /// public string GetMaxSerialNumber(long id, JObject? formData = null) { var modelList = _rf_serialnumber.Select(s => s.Id == id); if (modelList == null && modelList.Count < 1) { return string.Empty; } var model = modelList[0]; int max = model.CurrentNumber + 1; var date = DateTime.Now; var lastDate = model.LastTime; switch (model.NumberType) { case 1: //年流水 if (date.Year > lastDate.Year) { max = 1; } break; case 2: //月流水 if (date.Year > lastDate.Year || date.Month > lastDate.Month) { max = 1; } break; case 3: //日流水 if (date.Year > lastDate.Year || date.Month > lastDate.Month || date.Day > lastDate.Day) { max = 1; } break; } string number = max.ToString().PadLeft(model.NumberSize, '0'); string serialNumber = string.IsNullOrWhiteSpace(model.Format) ? number : model.Format.ContainsIgnoreCase("{number}") ? model.Format.ReplaceIgnoreCase("{number}", number) : model.Format + number; //更新当前编号和最后时间 model.LastTime = date; model.CurrentNumber = max; _rf_serialnumber.Update(model); return Wildcard.Replace(serialNumber, formData); } /// /// 生产排产 /// /// /// /// public async Task ProductionSchedule(string workOrd) { List workOrds = workOrd.Split(",").ToList(); if (workOrds.Count == 0) { return ""; } //获取工单数据 var workOrdMasters = _workOrdMaster.Select(p => workOrds.Contains(p.WorkOrd)); //获取已排产的工单 List dbWorkOrds = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds)).Select(p => p.WorkOrds).Distinct().ToList(); //过滤掉已排产的工单 workOrdMasters = workOrdMasters.Where(p => !dbWorkOrds.Contains(p.WorkOrd)).ToList(); if (workOrdMasters.Count == 0) { return JsonConvert.SerializeObject("ok"); } //排产 await _productionScheduleAppService.DoProductShcedule(workOrdMasters); //AutoCreatePickBill(workOrdMasters.Select(p => p.WorkOrd).ToList()); return JsonConvert.SerializeObject("ok"); } /// /// 生成领料单 /// /// public async Task CreatePickBill(string workOrd) { List workOrds = new List(); List workOrdMasters = new List(); if (string.IsNullOrEmpty(workOrd)) { //获取工单数据 workOrdMasters = _workOrdMaster.Select(p => p.OrdDate >= DateTime.Now.Date.AddDays(1) && p.OrdDate < DateTime.Now.Date.AddDays(4) && p.Status != "r" && p.Status != "c"); } else { workOrds = workOrd.Split(",").ToList(); if (workOrds.Count == 0) { return JsonConvert.SerializeObject("没有需要下达的工单。"); } workOrdMasters = _workOrdMaster.Select(p => workOrds.Contains(p.WorkOrd) && p.Status != "r" && p.Status != "c"); } if (workOrdMasters.Count == 0) { return "没有需要下达的工单。"; } //获取已排产的工单 List dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == "1001" && 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 == "1001" && 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 "当前选择的工单已领料或未排产。"; } List nbrMasterList = new List();//需要生成领料单列表 List nbrDetailList = new List();//需要生成领料单明细列表 var ords = workOrdMasters.Select(p => p.WorkOrd).ToList(); dbPeriodSequences = dbPeriodSequences.Where(p => ords.Contains(p.WorkOrds)).ToList(); await AutoCreatePickBill(ords, dbPeriodSequences, nbrMasterList, nbrDetailList); if (nbrMasterList.Any()) { dbPeriodSequences.ForEach(p => { p.Status = "r"; }); workOrdMasters.ForEach(p => { p.Status = "r"; }); //获取工单工艺路径数据 List workOrdRoutings = _workOrdRouting.Select(p => ords.Contains(p.WorkOrd) && p.MilestoneOp && p.Domain == "1001" && p.Status != "C" && p.IsActive); workOrdRoutings.ForEach(p => { p.Status = "r"; }); using (var unitOfWork = _unitOfWorkManager.Begin(false, true)) { try { _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); }); //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值 List nbrs = nbrMasterList.Select(a => a.Nbr).ToList(); var DBnbrList = _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && nbrs.Contains(a.Nbr)); nbrDetailList.ForEach(c => { c.NbrRecID = DBnbrList.Where(a => a.Nbr == c.Nbr).First().RecID; }); _nbrDetail.Insert(nbrDetailList); _workOrdMaster.Update(workOrdMasters); _periodSequenceDet.Update(dbPeriodSequences); _workOrdRouting.Update(workOrdRoutings); await unitOfWork.CompleteAsync(); } catch (Exception e) { unitOfWork.Dispose(); new NLogHelper("ResourceExamineAppService").WriteLog("CreatePickBill", "生成领料单相关数据更新失败:" + e.Message, _currentTenant.Id.ToString()); return e.Message; } } } return ""; } /// /// 同步工单等相关数据 /// /// /// 工艺路线数据 public void CreateWorkOrdDates(List morders, List allRoutings, List workOrds, List workOrdRoutings, List workOrdDetails) { //工单主表 WorkOrdMaster workOrd; //工单工艺路线表 WorkOrdRouting woRouting; //工单物料表 WorkOrdDetail woDetail; foreach (var item in morders) { //添加工单数据 workOrd = new WorkOrdMaster(); workOrd.Domain = "1001"; workOrd.OrdDate = item.moentry_sys_stime; workOrd.ReleaseDate = Convert.ToDateTime(item.moentry_sys_stime.GetValueOrDefault().ToString("u")); workOrd.WorkOrd = item.morder_no; workOrd.ItemNum = item.product_code;//物料编码 workOrd.QtyOrded = item.need_number.GetValueOrDefault(); workOrd.RoutingCode = item.product_code; workOrd.Period = 1; workOrd.Priority = item.urgent; workOrd.Status = " "; workOrd.IsActive = true; workOrd.IsConfirm = true; workOrd.CreateTime = DateTime.Now; workOrd.Batch = item.morder_no; workOrd.Typed = "s"; workOrds.Add(workOrd); //添加工单工艺路线数据 var curRoutings = allRoutings.Where(p => p.RoutingCode == item.product_code).ToList(); foreach (var dtl in curRoutings) { woRouting = new WorkOrdRouting(); woRouting.Domain = "1001"; woRouting.Descr = dtl.Descr; woRouting.MilestoneOp = dtl.MilestoneOp; woRouting.WorkOrd = item.morder_no; woRouting.OP = dtl.Op; woRouting.ParentOp = dtl.ParentOp; woRouting.RunTime = dtl.RunTime; woRouting.ItemNum = item.product_code; woRouting.QtyOrded = item.need_number.GetValueOrDefault(); woRouting.OverlapUnits = dtl.OverlapUnits; woRouting.Status = ""; woRouting.IsActive = true; woRouting.CommentIndex = dtl.CommentIndex; woRouting.CreateTime = DateTime.Now; workOrdRoutings.Add(woRouting); } List curStructures = GetProductStructure(item.product_code); foreach (var structure in curStructures) { //添加工单的物料信息 woDetail = new WorkOrdDetail(); woDetail.Domain = "1001"; woDetail.WorkOrd = item.morder_no; woDetail.Op = structure.Op; woDetail.ItemNum = structure.ComponentItem; woDetail.QtyRequired = item.need_number.GetValueOrDefault() * structure.Qty; woDetail.QtyPosted = 0m; woDetail.QtyReturned = 0m; woDetail.FrozenBOMQty = structure.Qty; woDetail.Status = ""; woDetail.IsActive = true; woDetail.CreateTime = DateTime.Now; workOrdDetails.Add(woDetail); } } } /// /// 获取标准Bom数据--TODO:存在循环查询数据库问题,后续调整 /// /// 产品物料编码 /// public List GetProductStructure(string itenNum) { List rtnStructures = new List(); //根据itemNum获取bom数据 var productStructures = _productStructureMaster.Select(p => itenNum == p.ParentItem && p.Domain == "1001" && p.IsActive); //添加非虚拟件 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(itenNum, curPhantoms, rtnStructures); return rtnStructures; } /// /// 递归获取虚拟件的子物料 /// /// 产品的物料编码 /// 当前产品的虚拟件 /// public void RecursionProductStructure(string parentItem, List structures, List rtnStructures) { //获取虚拟件的子物料 List chdStructures = _productStructureMaster.Select(p => structures.Select(m => m.ComponentItem).Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive); //非虚拟件 var notPhantoms = chdStructures.Where(p => p.StructureType.ToUpper() != "X").ToList(); //存在非虚拟件 foreach (var item in notPhantoms) { item.ParentItem = parentItem; } rtnStructures.AddRange(notPhantoms); //虚拟件 var phantoms = chdStructures.Where(p => p.StructureType.ToUpper() == "X").ToList(); if (phantoms.Count > 0) { //递归 RecursionProductStructure(parentItem, 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); } } }