Przeglądaj źródła

添加生产排产接口

heteng 2 lat temu
rodzic
commit
5c0be2eb68

+ 22 - 0
MicroServices/Business/Business.Application.Contracts/ResourceExamineManagement/IProductionScheduleAppService.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+using Business.ResourceExamineManagement.Dto;
+
+namespace Business.ResourceExamineManagement
+{
+    /// <summary>
+    /// Éú²úÅŲú
+    /// </summary>
+    public interface IProductionScheduleAppService : IApplicationService
+    {
+        /// <summary>
+        /// Éú²úÅŲú
+        /// </summary>
+        /// <param name="workOrds"></param>
+        /// <returns></returns>
+        Task<string> ProductionSchedule(List<String> workOrds);
+    }
+}

+ 248 - 0
MicroServices/Business/Business.Application/ResourceExamineManagement/ProdScheduleAppService.cs

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

+ 89 - 239
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -582,9 +582,6 @@ namespace Business.ResourceExamineManagement
                 var mesorders = ObjectMapper.Map<List<mo_mes_morder>, List<mes_morder>>(_CalcBomViewAppService.mordersInsertList);
                 _businessDbContext.BulkInsert(mesorders);
                 rtn.mordersList = _CalcBomViewAppService.mordersInsertList;
-
-                //插入工单相关数据
-                CreateWorkOrdDates(_CalcBomViewAppService.mordersInsertList);
             }
             if (_CalcBomViewAppService.mooccupyAllInsertList.Any())
             {
@@ -2017,242 +2014,95 @@ namespace Business.ResourceExamineManagement
             AutoCreateBomBill();
         }
 
-        /// <summary>
-        /// 同步工单等相关数据
-        /// </summary>
-        /// <param name="morders"></param>
-        [UnitOfWork]
-        public void CreateWorkOrdDates(List<mo_mes_morder> morders)
-        {
-            //获取工艺路线数据:product_code=物料编码
-            List<RoutingOpDetail> allRoutings = _routingOpDetail.Select(p => morders.Select(m => m.product_code).Contains(p.RoutingCode));
-            //获取标准BOM数据
-            List<ProductStructureMaster> productStructures = GetProductStructure(morders.Select(p => p.product_code).ToList());
-            //工单主表
-            List<WorkOrdMaster> workOrds = new List<WorkOrdMaster>();
-            WorkOrdMaster workOrd;
-            //工单工艺路线表
-            List<WorkOrdRouting> workOrdRoutings = new List<WorkOrdRouting>();
-            WorkOrdRouting woRouting;
-            //工单物料表
-            List<WorkOrdDetail> workOrdDetails = new List<WorkOrdDetail>();
-            WorkOrdDetail woDetail;
-            foreach (var item in morders)
-            {
-                //添加工单数据
-                workOrd = new WorkOrdMaster();
-                workOrd.Domain = "1001";
-                workOrd.OrdDate = item.moentry_sys_stime;
-                workOrd.ReleaseDate =Convert.ToDateTime(item.moentry_sys_stime.GetValueOrDefault().ToString("u"));
-                workOrd.WorkOrd = item.morder_no;
-                workOrd.ItemNum = item.product_code;//物料编码
-                workOrd.QtyOrded = item.need_number.GetValueOrDefault();
-                workOrd.RoutingCode = item.product_code;
-                workOrd.Period = 1;
-                workOrd.Priority = item.urgent;
-                workOrd.Status = "";
-                workOrd.IsActive = true;
-                workOrd.ProdLine = "组装线";
-                workOrd.IsConfirm = true;
-                workOrds.Add(workOrd);
-
-                //添加工单工艺路线数据
-                var curRoutings = allRoutings.Where(p => p.RoutingCode == item.product_code).ToList();
-                foreach (var dtl in curRoutings)
-                {
-                    woRouting = new WorkOrdRouting();
-                    woRouting.Domain = "1001";
-                    woRouting.Descr = dtl.Descr;
-                    woRouting.MilestoneOp = dtl.MilestoneOp;
-                    woRouting.WorkOrd = item.morder_no;
-                    woRouting.OP = dtl.Op;
-                    woRouting.ParentOp = dtl.ParentOp;
-                    woRouting.RunTime = dtl.RunTime;
-                    woRouting.ItemNum = item.product_code;
-                    woRouting.QtyOrded = item.need_number.GetValueOrDefault();
-                    woRouting.OverlapUnits = dtl.OverlapUnits;
-                    woRouting.Status = "";
-                    woRouting.IsActive = true;
-                    workOrdRoutings.Add(woRouting);
-                }
-
-                //添加工单物料数据
-                var curStructures = productStructures.Where(p => p.ParentItem == item.product_code).ToList();
-                foreach (var structure in curStructures)
-                {
-                    //添加工单的物料信息
-                    woDetail = new WorkOrdDetail();
-                    woDetail.Domain = "1001";
-                    woDetail.WorkOrd = item.morder_no;
-                    woDetail.Op = structure.Op;
-                    woDetail.ItemNum = structure.ComponentItem;
-                    woDetail.QtyRequired = item.need_number.GetValueOrDefault() * structure.Qty;
-                    woDetail.QtyPosted = 0m;
-                    woDetail.QtyReturned = 0m;
-                    woDetail.Status = "";
-                    woDetail.IsActive = true;
-                    workOrdDetails.Add(woDetail);
-                }
-            }
-
-            //await _businessDbContext.BulkInsertAsync(workOrds);
-            //await _businessDbContext.BulkInsertAsync(workOrdRoutings);
-            //await _businessDbContext.BulkInsertAsync(workOrdDetails);
-             _workOrdMaster.Insert(workOrds);
-             _workOrdRouting.Insert(workOrdRoutings);
-             _workOrdDetail.Insert(workOrdDetails);
-
-            //排产
-             _productionScheduleAppService.DoProductShcedule(workOrds);
-            AutoCreatePickBill(workOrds.Select(a => a.WorkOrd).ToList());
-        }
-
-        /// <summary>
-        /// 获取标准Bom数据--TODO:存在循环查询数据库问题,后续调整
-        /// </summary>
-        /// <param name="itenNums">产品物料编码</param>
-        /// <returns></returns>
-        public List<ProductStructureMaster> GetProductStructure(List<string> itenNums)
-        {
-            List<ProductStructureMaster> rtnStructures = new List<ProductStructureMaster>();
-            //根据itemNum获取bom数据
-            var productStructures = _productStructureMaster.Select(p => itenNums.Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
-            //添加非虚拟件
-            rtnStructures.AddRange(productStructures.Where(p => p.StructureType.ToUpper() != "X").ToList());
-            foreach (var item in itenNums)
-            {
-                //获取当前产品的虚拟件
-                var curPhantoms = productStructures.Where(p => p.ParentItem == item && p.StructureType.ToUpper() == "X").ToList();
-                if (curPhantoms.Count() == 0)
-                {
-                    continue;
-                }
-                //递归获取所有虚拟件对应的子物料
-                RecursionProductStructure(item, curPhantoms, rtnStructures);
-            }
-            return rtnStructures;
-        }
-
-        /// <summary>
-        /// 递归获取虚拟件的子物料
-        /// </summary>
-        /// <param name="parentItem">产品的物料编码</param>
-        /// <param name="structures">当前产品的虚拟件</param>
-        /// <param name="rtnStructures"></param>
-        public void RecursionProductStructure(string parentItem, List<ProductStructureMaster> structures, List<ProductStructureMaster> rtnStructures)
-        {
-            //获取虚拟件的子物料
-            var chdStructures = _productStructureMaster.Select(p => structures.Select(m => m.ComponentItem).Contains(p.ParentItem) && p.Domain == "1001" && p.IsActive);
-            //非虚拟件
-            var notPhantoms = chdStructures.Where(p => p.StructureType.ToUpper() != "X").ToList();
-            //存在非虚拟件
-            if (notPhantoms.Count() > 0)
-            {
-                notPhantoms.ForEach(p =>
-                {
-                    p.ParentItem = parentItem;
-                });
-                rtnStructures.AddRange(notPhantoms);
-            }
-            //虚拟件
-            var phantoms = chdStructures.Where(p => p.StructureType.ToUpper() == "X").ToList();
-            if (phantoms.Count() > 0)
-            {
-                //递归
-                RecursionProductStructure(parentItem, phantoms, rtnStructures);
-            }
-        }
-
-
-        public void AutoCreatePickBill(List<string> workOrds)
-        {
-            //获取生产周期数据
-            List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == "1001" && p.IsActive);
-            List<LineMaster> lineMasters = new List<LineMaster>();
-            List<string> lines = new List<string>();//产线列表,
-            List<NbrMaster> nbrMasterList = new List<NbrMaster>();//需要生成领料单列表
-            List<NbrDetail> nbrDetailList = new List<NbrDetail>();//需要生成领料单明细列表
-            Dictionary<string, decimal> dictItemQty = new Dictionary<string, decimal>();
-            if (dbPeriodSequences.Any())
-            {
-                lines = dbPeriodSequences.Select(a => a.Line).Distinct().ToList();
-                lineMasters = _lineMaster.Select(p => lines.Contains(p.Line) && p.Domain == "1001" && p.IsActive);
-                List<ProductStructureMaster>  itemList=GetProductStructure(dbPeriodSequences.Select(a=>a.ItemNum).Distinct().ToList());
-                var childrenList= itemList.Select(a=>a.ComponentItem).Distinct().ToList();
-                List<ItemMaster> itemLocList = _itemMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList();
-                foreach (var item in dbPeriodSequences)
-                {
-                    var Nbr = GetMaxSerialNumber(417416915624005);
-                    nbrMasterList.Add(new NbrMaster
-                    {
-                        Domain = "1001",
-                        Type = "SM",
-                        Nbr = Nbr,
-                        Remark = "",
-                        Date = item.PlanDate,
-                        ProdLine = item.Line,
-                        Status = "",
-                        WorkOrd = item.WorkOrds,
-                        QtyOrd = item.OrdQty.HasValue ? item.OrdQty.Value : 0,
-                        IsActive = true,
-                        IsChanged = false
-                    });
-                    int i = 1;
-                    itemList.Where(a => a.ParentItem == item.ItemNum).ToList()?.ForEach(a =>
-                    {
-                        string LocationTo = "";
-                        if (itemLocList.Where(c => c.ItemNum == a.ComponentItem).ToList().Any())
-                        {
-                            LocationTo = itemLocList?.Where(c => c.ItemNum == a.ComponentItem).First().Location;
-                        }
-                        nbrDetailList.Add(new NbrDetail
-                        {
-                            Domain = "1001",
-                            Type = "SM",
-                            Nbr = Nbr,
-                            ItemNum = a.ComponentItem,
-                            QtyFrom = 0,
-                            QtyTo = 0,
-                            LocationFrom = LocationTo,
-                            LocationTo = "",
-                            WorkOrd = item.WorkOrds,
-                            QtyOrd = item.OrdQty * a.Qty,
-                            Line = i,
-                            IsActive = true,
-                        });
-                        if(dictItemQty.ContainsKey(a.ComponentItem))
-                        {
-                            dictItemQty[a.ComponentItem] = dictItemQty[a.ComponentItem] + item.OrdQty.Value * a.Qty;
-                        }else
-                        {
-                            dictItemQty.Add(a.ComponentItem, item.OrdQty.Value * a.Qty);
-                        }
-                        i++;
-                    });
-                }
-                _nbrMaster.Insert(nbrMasterList);
-                //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值
-                List<string> nbrs= nbrMasterList.Select(a=>a.Nbr).ToList();
-                var nbrList= _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && nbrs.Contains(a.Nbr));
-                nbrDetailList.ForEach(c =>
-                {
-                    c.NbrRecID= nbrList.Where(a=>a.Nbr==c.Nbr).First().RecID;
-                });
-                _nbrDetail.Insert(nbrDetailList);
-                //TODO:
-                //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。
-                //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。
-                List<string> 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 stockList=_mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.Id) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
-                stockList?.ForEach(a =>
-                {
-                    a.sqty = a.sqty - dictItemQty[items.First(b => b.Id == a.Id).number];
-                });
-                //_mysql_ic_item_stock.UpdateManyAsync(stockList);
-            }
-        }
+        //public void AutoCreatePickBill(List<string> workOrds)
+        //{
+        //    //获取生产周期数据
+        //    List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => workOrds.Contains(p.WorkOrds) && p.Domain == "1001" && p.IsActive);
+        //    List<LineMaster> lineMasters = new List<LineMaster>();
+        //    List<string> lines = new List<string>();//产线列表,
+        //    List<NbrMaster> nbrMasterList = new List<NbrMaster>();//需要生成领料单列表
+        //    List<NbrDetail> nbrDetailList = new List<NbrDetail>();//需要生成领料单明细列表
+        //    Dictionary<string, decimal> dictItemQty = new Dictionary<string, decimal>();
+        //    if (dbPeriodSequences.Any())
+        //    {
+        //        lines = dbPeriodSequences.Select(a => a.Line).Distinct().ToList();
+        //        lineMasters = _lineMaster.Select(p => lines.Contains(p.Line) && p.Domain == "1001" && p.IsActive);
+        //        List<ProductStructureMaster>  itemList=GetProductStructure(dbPeriodSequences.Select(a=>a.ItemNum).Distinct().ToList());
+        //        var childrenList= itemList.Select(a=>a.ComponentItem).Distinct().ToList();
+        //        List<ItemMaster> itemLocList = _itemMaster.Select(p => childrenList.Contains(p.ItemNum) && p.Domain == "1001" && p.IsActive).Distinct().ToList();
+        //        foreach (var item in dbPeriodSequences)
+        //        {
+        //            var Nbr = GetMaxSerialNumber(417416915624005);
+        //            nbrMasterList.Add(new NbrMaster
+        //            {
+        //                Domain = "1001",
+        //                Type = "SM",
+        //                Nbr = Nbr,
+        //                Remark = "",
+        //                Date = item.PlanDate,
+        //                ProdLine = item.Line,
+        //                Status = "",
+        //                WorkOrd = item.WorkOrds,
+        //                QtyOrd = item.OrdQty.HasValue ? item.OrdQty.Value : 0,
+        //                IsActive = true,
+        //                IsChanged = false
+        //            });
+        //            int i = 1;
+        //            itemList.Where(a => a.ParentItem == item.ItemNum).ToList()?.ForEach(a =>
+        //            {
+        //                string LocationTo = "";
+        //                if (itemLocList.Where(c => c.ItemNum == a.ComponentItem).ToList().Any())
+        //                {
+        //                    LocationTo = itemLocList?.Where(c => c.ItemNum == a.ComponentItem).First().Location;
+        //                }
+        //                nbrDetailList.Add(new NbrDetail
+        //                {
+        //                    Domain = "1001",
+        //                    Type = "SM",
+        //                    Nbr = Nbr,
+        //                    ItemNum = a.ComponentItem,
+        //                    QtyFrom = 0,
+        //                    QtyTo = 0,
+        //                    LocationFrom = LocationTo,
+        //                    LocationTo = "",
+        //                    WorkOrd = item.WorkOrds,
+        //                    QtyOrd = item.OrdQty * a.Qty,
+        //                    Line = i,
+        //                    IsActive = true,
+        //                });
+        //                if(dictItemQty.ContainsKey(a.ComponentItem))
+        //                {
+        //                    dictItemQty[a.ComponentItem] = dictItemQty[a.ComponentItem] + item.OrdQty.Value * a.Qty;
+        //                }else
+        //                {
+        //                    dictItemQty.Add(a.ComponentItem, item.OrdQty.Value * a.Qty);
+        //                }
+        //                i++;
+        //            });
+        //        }
+        //        _nbrMaster.Insert(nbrMasterList);
+        //        //快开平台用自增列RecId关联,所以需要插入后再查给明细表赋相应的值
+        //        List<string> nbrs= nbrMasterList.Select(a=>a.Nbr).ToList();
+        //        var nbrList= _nbrMaster.Select(a => a.Domain == "1001" && a.Type == "SM" && nbrs.Contains(a.Nbr));
+        //        nbrDetailList.ForEach(c =>
+        //        {
+        //            c.NbrRecID= nbrList.Where(a=>a.Nbr==c.Nbr).First().RecID;
+        //        });
+        //        _nbrDetail.Insert(nbrDetailList);
+        //        //TODO:
+        //        //因为我们并没有模拟发料的过程,在自动生成领料单的时候就要扣减库存,实际业务不能这么做。
+        //        //在有上料和追溯的系统,可以在扫码上料或报工时(从线边仓)扣减。或者在实际发料出库时扣减。
+        //        List<string> 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 stockList=_mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.Id) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
+        //        stockList?.ForEach(a =>
+        //        {
+        //            a.sqty = a.sqty - dictItemQty[items.First(b => b.Id == a.Id).number];
+        //        });
+        //        //_mysql_ic_item_stock.UpdateManyAsync(stockList);
+        //    }
+        //}
 
         /// <summary>
         /// 得到一个流水号的最大流水号

+ 44 - 0
MicroServices/Business/Business.HttpApi/Controllers/ProductionScheduleController.cs

@@ -0,0 +1,44 @@
+using Business.ResourceExamineManagement;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace Business.Controllers
+{
+    /// <summary>
+    /// 生产排产
+    /// </summary>
+    [RemoteService]
+    [Area("Business")]
+    [Route("api/business/production_schedule")]
+    public class ProductionScheduleController : AbpController
+    {
+        private readonly IProductionScheduleAppService _ProductionScheduleAppService;
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="ProductionScheduleAppService"></param>
+        public ProductionScheduleController(IProductionScheduleAppService ProductionScheduleAppService)
+        {
+            _ProductionScheduleAppService = ProductionScheduleAppService;
+        }
+
+        /// <summary>
+        /// 生产排产
+        /// </summary>
+        /// <param name="workOrds"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [Route("productionschedule")]
+        public Task<string> ProductionSchedule(String workOrds)
+        {
+            return _ProductionScheduleAppService.ProductionSchedule(new List<string>());
+        }
+    }
+}