Просмотр исходного кода

同步WMS物料和库存修改,领料单考虑提前期和包装量

Murphy 3 лет назад
Родитель
Сommit
091d3574fc

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

@@ -41,5 +41,27 @@ namespace Business.ResourceExamineManagement.Dto
         /// </summary>
         [Comment("最小订单量")]
         public decimal? minorderqty { get; set; }
+
+        /// <summary>
+        /// 投料自动取整
+        /// </summary>
+        [Comment("投料自动取整")]
+        public int? put_integer { get; set; }
+
+        /// <summary>
+        /// 工单发料时间/天
+        /// </summary>
+        [Precision(23, 10)]
+        [Comment("工单发料时间/天")]
+        public decimal? ordissu_days { get; set; }
+
+        /// <summary>
+        /// 最小包装量
+        /// </summary>
+        [Comment("最小包装量")]
+        [Required]
+        [DefaultValue(0)]
+        [Precision(23, 10)]
+        public decimal? minpackqty { get; set; }
     }
 }

+ 234 - 107
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -228,6 +228,7 @@ namespace Business.ResourceExamineManagement
         private readonly ISqlRepository<WorkOrdMaster> _workOrdMaster;
         private readonly ISqlRepository<WorkOrdDetail> _workOrdDetail;
         private readonly ISqlRepository<rf_serialnumber> _rf_serialnumber;
+        private readonly ISqlRepository<LocationDetail> _locationDetail;
         /// <summary>
         /// 资源检查入参
         /// </summary>
@@ -273,7 +274,7 @@ namespace Business.ResourceExamineManagement
         private ISqlRepository<ItemMaster> _itemMaster;
         private ISqlRepository<NbrMaster> _nbrMaster;
         private ISqlRepository<NbrDetail> _nbrDetail;
-
+        private ISqlRepository<ItemPackMaster> _itemPackMaster;
         /// <summary>
         /// 生产排产
         /// </summary>
@@ -366,7 +367,9 @@ namespace Business.ResourceExamineManagement
             ISqlRepository<NbrMaster> nbrMaster,
             ISqlRepository<NbrDetail> nbrDetail,
             PriorityAppService priorityAppService,
-            ISqlRepository<rf_serialnumber> rf_serialnumber
+            ISqlRepository<rf_serialnumber> rf_serialnumber,
+            ISqlRepository<LocationDetail> locationDetail,
+            ISqlRepository<ItemPackMaster> itemPackMaster
             )
         {
             _mes_technique = mes_technique;
@@ -441,7 +444,9 @@ namespace Business.ResourceExamineManagement
             _nbrDetail = nbrDetail;
             _priorityAppService= priorityAppService;
             _rf_serialnumber = rf_serialnumber;
-    }
+            _locationDetail=locationDetail;
+            _itemPackMaster= itemPackMaster;
+        }
         #endregion
 
 
@@ -478,7 +483,7 @@ namespace Business.ResourceExamineManagement
 
             //获取订单行数据
             List<crm_seorderentry> sentrys = await _mysql_crm_seorderentry.GetListAsync(p => p.tenant_id == input.tenantId && p.factory_id == input.factoryId && input.sorderId.Contains(p.seorder_id.GetValueOrDefault()) && !p.IsDeleted);
-
+            AsyncItemStockFromWMS(sentrys);
             //处理订单行优先级
             sentrys = _priorityAppService.CalcOrderEntryPriority(sorders, sentrys);
 
@@ -996,7 +1001,10 @@ namespace Business.ResourceExamineManagement
                     stock_leadtime = x.stock_leadtime,
                     production_leadtime = x.production_leadtime,
                     order_leadtime = x.order_leadtime,
-                    minorderqty = x.minorderqty
+                    minorderqty = x.minorderqty,
+                    put_integer=x.put_integer,
+                    minpackqty=x.minpackqty,
+                    ordissu_days=x.ordissu_days
                 }).AsQueryable<ICItemLeadTimeDto>().ToList();
         }
 
@@ -2016,107 +2024,225 @@ namespace Business.ResourceExamineManagement
             AutoCreateBomBill();
         }
 
-        //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 = true,
-        //                Name = "1001",
-        //                Department = "101",
-        //                CreateTmie = DateTime.Now,
-        //                UpdateTmie = DateTime.Now,
-        //                CreateUser = "1001",
-        //                UpdateUser = "1001"
-        //            });
-        //            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,
-        //                    CurrQtyOpened = item.OrdQty * a.Qty,
-        //                    Line = i,
-        //                    IsActive = true,
-        //                    CreateTmie = DateTime.Now,
-        //                    UpdateTmie = DateTime.Now,
-        //                    CreateUser = "1001",
-        //                    UpdateUser = "1001"
-        //                });
-        //                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<NbrMaster> nbrMasterList = new List<NbrMaster>();//需要生成领料单列表
+            List<NbrDetail> nbrDetailList = new List<NbrDetail>();//需要生成领料单明细列表
+            if (dbPeriodSequences.Any())
+            {
+                //按照工单领料,一个工单一个领料单,之前是按照排产日期和产线分别领料
+                foreach(var workord in workOrds)
+                {
+                    Dictionary<string, decimal> dictItemQty = new Dictionary<string, decimal>();
+                    List<string> lines = dbPeriodSequences.Where(a=>a.WorkOrds==workord).Select(a => a.Line).Distinct().ToList();
+                    List<LineMaster> lineMasters = _lineMaster.Select(p => lines.Contains(p.Line) && p.Domain == "1001" && p.IsActive);
+                    List<ProductStructureMaster> itemList = GetProductStructure(dbPeriodSequences.Where(a => a.WorkOrds == workord).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();
+                    List<ItemPackMaster> 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());
+                    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",
+                        CreateTmie = DateTime.Now,
+                        UpdateTmie = DateTime.Now,
+                        CreateUser = "1001",
+                        UpdateUser = "1001"
+                    });
+                    int i = 1;
+                    itemList?.ForEach(a =>
+                    {
+                        var find = itemLocList?.Find(c => c.ItemNum == a.ComponentItem);
+                        var packfind = itemPackList?.Find(c => c.ItemNum == a.ComponentItem);
+                        string LocationTo = "";
+                        bool TraceDetail = false;
+                        decimal TraceDetailQty = 0m;
+                        if (find!=null)
+                        {
+                            LocationTo=find.Location;
+                            TraceDetail=find.TraceDetail;
+                            //TraceDetail为true指按需求量,否则按标签
+                            if (!TraceDetail)
+                            {
+                                TraceDetailQty = packfind.PackingQty.GetValueOrDefault();
+                            }
+                        }
+                        //相同物料汇总
+                        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 = LocationTo,
+                                LocationTo = "",
+                                WorkOrd = workord,
+                                QtyOrd = TraceDetail?QtyOrdSum * a.Qty: TraceDetailQty,
+                                CurrQtyOpened = TraceDetail ? QtyOrdSum * a.Qty : TraceDetailQty,
+                                Line = i,
+                                IsActive = true,
+                                CreateTmie = DateTime.Now,
+                                UpdateTmie = DateTime.Now,
+                                CreateUser = "1001",
+                                UpdateUser = "1001"
+                            });
+                            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;
+                        }
+                        
+                        if (dictItemQty.ContainsKey(a.ComponentItem))
+                        {
+                            if(TraceDetail)
+                            {
+                                dictItemQty[a.ComponentItem] = dictItemQty[a.ComponentItem] + QtyOrdSum * a.Qty;
+                            }else
+                            {
+                                dictItemQty[a.ComponentItem] = dictItemQty[a.ComponentItem] + TraceDetailQty;
+                            }
+                        }
+                        else
+                        {
+                            if (TraceDetail)
+                            {
+                                dictItemQty.Add(a.ComponentItem, QtyOrdSum * a.Qty);
+                            }
+                            else
+                            {
+                                dictItemQty.Add(a.ComponentItem, TraceDetailQty);
+                            }
+                        }
+                    });
+
+                    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 leadTimes = GetLeadTime(itemIds, 1000, 1001).Max(a=>a.ordissu_days.GetValueOrDefault());
+                    //没有维护备料提前期,默认取7天
+                    if (leadTimes == 0.0M)
+                    { 
+                        nbrMasterList.First(a=>a.Nbr==Nbr).Date= dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-7);
+                    }
+                    else
+                    {
+                        nbrMasterList.First(a => a.Nbr == Nbr).Date = dbPeriodSequences.Where(a => a.WorkOrds == workord).Min(a => a.PlanDate).GetValueOrDefault().AddDays(-1*Convert.ToDouble(leadTimes));
+                    }
+                    //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 = a.QtyOnHand - dictItemQty[a.ItemNum];
+                            }
+                        });
+                    });
+                    _locationDetail.Update(locStock);
+                }
+                _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);
+            }
+        }
+
+        public void AsyncItemStockFromWMS(List<crm_seorderentry> sentrys)
+        {
+            //产品编码
+            var itemList = sentrys.Select(a => a.item_number).Distinct().ToList();
+            List<string> itemChildList = new List<string>();
+            itemList.ForEach(a =>
+            {
+                itemChildList.AddRange(GetChildItemNumber(a, new List<string>()));
+            });
+            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<ic_item_stock> mysqlStock = _mysql_ic_item_stock.GetListAsync(a => itemIds.Contains(a.Id) && a.factory_id == 1001 && a.tenant_id == 1000).Result;
+            List<ic_item_stock> needAddList = new List<ic_item_stock>();
+
+            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();
+                            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<string> GetChildItemNumber(string itemNum,List<string> 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;
+        }
 
         /// <summary>
         /// 得到一个流水号的最大流水号
@@ -2184,6 +2310,7 @@ namespace Business.ResourceExamineManagement
             var workOrdMasters = _workOrdMaster.Select(p => workOrds.Contains(p.WorkOrd));
             //排产
             await _productionScheduleAppService.DoProductShcedule(workOrdMasters);
+            AutoCreatePickBill(workOrds);
             return JsonConvert.SerializeObject("ok");
         }
 
@@ -2303,7 +2430,7 @@ namespace Business.ResourceExamineManagement
         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);
+            List<ProductStructureMaster> 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();
             //存在非虚拟件

+ 131 - 30
MicroServices/Business/Business.Application/SyncDataManagement/SyncWMSDataAppService.cs

@@ -6,13 +6,19 @@ using Business.Model.Sale;
 using Business.Model.SRM;
 using EFCore.BulkExtensions;
 using Microsoft.EntityFrameworkCore;
+using NetTopologySuite.Algorithm;
 using Newtonsoft.Json;
+using SixLabors.ImageSharp;
+using Spire.Pdf;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
 using System.Linq;
 using Volo.Abp.Application.Services;
 using Volo.Abp.Domain.Repositories;
+using WkHtmlToPdfDotNet;
 
 namespace Business.SyncDataManagement
 {
@@ -442,9 +448,22 @@ namespace Business.SyncDataManagement
         //同步物料
         public void SyncItemMaster()
         {
-            var ic_itemList = _mysql_ic_item.GetListAsync(a=>a.tenant_id==1000 && a.factory_id==1001).Result;
-            var custList = _itemMaster.Select(a => a.IsActive);
+            bool isAll = true;//是否同步所有物料
+            var ic_itemList = _mysql_ic_item.GetListAsync(a => a.tenant_id == 1000 && a.factory_id == 1001).Result;
+            List<ItemMaster> custList = new List<ItemMaster>();
+            if(isAll)
+            {
+                custList = _itemMaster.Select(a => a.IsActive && a.Domain=="1001");
+            }else
+            {
+                //格努产品编码同步子级物料
+                List<string> childItems = GetChildItemNumber("", new List<string>());
+                custList= _itemMaster.Select(a => a.IsActive && a.Domain == "1001" && childItems.Distinct().Contains(a.ItemNum));
+            }
             List<ic_item> ItemsAdd = new List<ic_item>();
+            List<ic_factory_details> ic_factory_detailsAdd = new List<ic_factory_details>();
+            List<ic_plan> ic_planAdd = new List<ic_plan>();
+            List<srm_purchase> srm_purchaseAdd = new List<srm_purchase>();
             if (custList != null && custList.Count > 0)
             {
                 for (int i = 0; i < custList.Count; i++)
@@ -452,7 +471,8 @@ namespace Business.SyncDataManagement
                     var ic_item = ic_itemList.Find(x => x.number == custList[i].ItemNum && x.tenant_id == 1000 && x.factory_id == 1001);
                     if (ic_item == null)
                     {
-                        ItemsAdd.Add(new ic_item(help.NextId())
+                        long itemId = help.NextId();
+                        ItemsAdd.Add(new ic_item(itemId)
                         {
                             number = custList[i].ItemNum, //物料编码
                             name = custList[i].Descr, //物料名称
@@ -483,7 +503,72 @@ namespace Business.SyncDataManagement
                             factory_id = 1001,
                             tenant_id = 1000,
                             IsDeleted = false
-                        }); 
+                        });
+                        ic_factory_detailsAdd.Add(new ic_factory_details(help.NextId())
+                        {
+                            icitem_id= itemId,
+                            icitem_name=custList[i].Descr,
+                            batch_manager= custList[i].LotSerialControl?1:0,
+                            item_shelve= custList[i].DefaultShelf,
+                            qty_max= custList[i].MaxOrd,
+                            minorderqty= custList[i].MinOrd,
+                            minpackqty= 1,
+                            ordissu_days = 1,
+                            mat_enter_days= 1,
+                            prd_out_days= 2,
+                            transportation_leadtime= 3,
+                            stock_leadtime= 1,
+                            production_leadtime= 4,
+                            order_leadtime= 4,
+                            factory_id = 1001,
+                            tenant_id = 1000,
+                            IsDeleted = false
+                        });
+                        ic_planAdd.Add(new ic_plan(help.NextId())
+                        {
+                            icitem_id = itemId,
+                            icitem_name = custList[i].Descr,
+                            fix_leadtime = 1,
+                            order_inter_val = 1,
+                            lead_time=1,
+                            bat_change_economy=1,
+                            total_tqq=1,
+                            order_point=1,
+                            secinv=1,
+                            secinv_ratio=1,
+                            self_inspection_date=1,
+                            Warehousing_date=1,
+                            Shipping_date=3,
+                            factory_id = 1001,
+                            tenant_id = 1000,
+                            IsDeleted = false
+                        });
+                        srm_purchaseAdd.Add(new srm_purchase(help.NextId())
+                        {
+                            icitem_id = itemId,
+                            icitem_name = custList[i].Descr,
+                            sourcelist_number = "HYQD12064",
+                            supplier_id = 10101000051,
+                            supplier_number = "",
+                            supplier_name = "广州市伟正金属构件有限公司",
+                            purchgroup = "",
+                            purcher = "",
+                            purchase_unit = "",
+                            netpurchase_price = 1,
+                            taxrate = 0.13m,
+                            currency_type = 1,
+                            order_rector_name = "",
+                            order_rector_num = "",
+                            factory_code = "",
+                            order_dept = "",
+                            order_price = 13,
+                            sale_price = 130,
+                            qty_min = 10,
+                            batch_append_qty = 10,
+                            factory_id = 1001,
+                            tenant_id = 1000,
+                            IsDeleted = false
+                        });
                     }
                 }
             }
@@ -492,57 +577,57 @@ namespace Business.SyncDataManagement
 
         public void SyncBom()
         {
-            var ic_bomList = _mysql_ic_bom.GetListAsync(a=>a.tenant_id==1000 && a.factory_id==1001).Result;
+            var ic_bomList = _mysql_ic_bom.GetListAsync(a => a.tenant_id == 1000 && a.factory_id == 1001).Result;
             var ic_itemList = _mysql_ic_item.GetListAsync(a => a.tenant_id == 1000 && a.factory_id == 1001).Result;
-            List<ProductStructureMaster> wmsBomList =_productStructureMaster.Select(a=>a.Domain=="1001" && (a.ParentItem== "1.SD1.D.0056-F" || a.ParentItem == "1.ZC1.D.0001" || a.ParentItem == "1.BW1.D.0030") && a.IsActive);
+            List<ProductStructureMaster> wmsBomList = _productStructureMaster.Select(a => a.Domain == "1001" && (a.ParentItem == "1.SD1.D.0056-F" || a.ParentItem == "1.ZC1.D.0001" || a.ParentItem == "1.BW1.D.0030") && a.IsActive);
             List<ic_bom> ItemsAdd = new List<ic_bom>();
             List<ic_bom_child> childItemsAdd = new List<ic_bom_child>();
             if (wmsBomList != null && wmsBomList.Count > 0)
             {
                 var ItemMasterDS = wmsBomList.Select(a => a.ParentItem).Distinct().ToList();
-                foreach(var c in ItemMasterDS)
+                foreach (var c in ItemMasterDS)
                 {
                     var item = ic_itemList.Find(a => a.number == c);
-                    var ItemList = wmsBomList.Where(a=>a.ParentItem ==c);
+                    var ItemList = wmsBomList.Where(a => a.ParentItem == c);
                     long domain = Convert.ToInt64(ItemList.First().Domain);
                     long factory_id = domain % 1000;
                     long tenant_id = domain - factory_id;
                     var bom = new ic_bom(help.NextId())
                     {
                         bom_number = c,
-                        icitem_id = item==null ? help.NextId() : item.Id,
-                        item_name= item==null? "" : item.name,
-                        item_number =c,
-                        version= ItemList.First().Refs,
+                        icitem_id = item == null ? help.NextId() : item.Id,
+                        item_name = item == null ? "" : item.name,
+                        item_number = c,
+                        version = ItemList.First().Refs,
                         factory_id = 1001,
                         tenant_id = 1000,
-                        IsDeleted=false,
-                        use_status=1
+                        IsDeleted = false,
+                        use_status = 1
                     };
                     ItemsAdd.Add(bom);
 
-                    foreach(var child in ItemList)
+                    foreach (var child in ItemList)
                     {
                         var itemchild = ic_itemList.Find(a => a.number == child.ComponentItem);
                         var bomchild = new ic_bom_child(help.NextId())
                         {
-                            bom_id= bom.Id,
-                            bom_number=bom.bom_number,
-                            icitem_id= itemchild==null ?long.MinValue : itemchild.Id,
-                            item_number= child.ComponentItem,
-                            item_name= itemchild==null? "" : item.name,
-                            unit=child.UM,
-                            qty=child.Qty,
-                            entryid=child.SequenceNum,
-                            erp_cls= itemchild==null ? 2: itemchild.erp_cls,
-                            begin_day=child.StartEff,
-                            end_day=child.EndEff,
-                            child_num= child.SequenceNum,
-                            version=child.Refs,
+                            bom_id = bom.Id,
+                            bom_number = bom.bom_number,
+                            icitem_id = itemchild == null ? long.MinValue : itemchild.Id,
+                            item_number = child.ComponentItem,
+                            item_name = itemchild == null ? "" : item.name,
+                            unit = child.UM,
+                            qty = child.Qty,
+                            entryid = child.SequenceNum,
+                            erp_cls = itemchild == null ? 2 : itemchild.erp_cls,
+                            begin_day = child.StartEff,
+                            end_day = child.EndEff,
+                            child_num = child.SequenceNum,
+                            version = child.Refs,
                             factory_id = 1001,
                             tenant_id = 1000,
-                            IsDeleted=false,
-                            use_status=1
+                            IsDeleted = false,
+                            use_status = 1
                         };
                         childItemsAdd.Add(bomchild);
                     }
@@ -551,5 +636,21 @@ namespace Business.SyncDataManagement
                 _businessDbContext.BulkInsert(childItemsAdd);
             }
         }
+
+        //循环获取子级物料编码,包括产品本身,有重复的结果去重即可
+        public List<string> GetChildItemNumber(string itemNum, List<string> 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;
+        }
     }
 }

+ 2 - 0
MicroServices/Business/Business.EntityFrameworkCore/EntityFrameworkCore/DOP/BusinessDbContext.cs

@@ -145,7 +145,9 @@ namespace Business.EntityFrameworkCore
         public DbSet<LineMaster> LineMaster { get; set; }
 
         public DbSet<rf_serialnumber> rf_serialnumber { get; set; }
+        public DbSet<LocationDetail> LocationDetail { get; set; }
 
+        public DbSet<ItemPackMaster> ItemPackMaster { get; set; }
         #endregion
 
         //Code generation...

+ 9 - 1
MicroServices/Business/Bussiness.Model/MES/IC/ItemMaster.cs

@@ -69,12 +69,20 @@ namespace Business.Model.MES.IC
         public decimal? Width { get; set; }
         public decimal? Height { get; set; }
         public Boolean LotSerialControl { get; set; }
-
+        public string? DefaultShelf { get; set; }
+        public decimal? MaxOrd { get; set; }
+        public decimal? MinOrd { get; set; }
         /// <summary>
         /// 是否有效:1-有效;0-无效
         /// </summary>
         [Comment("是否有效")]
         public Boolean IsActive { get; set; }
 
+        /// <summary>
+        /// 是否有效:1-有效;0-无效
+        /// </summary>
+        [Comment("是否整包发料")]
+        public Boolean TraceDetail { get; set; }
+        
     }
 }

+ 49 - 0
MicroServices/Business/Bussiness.Model/MES/IC/ItemPackMaster.cs

@@ -0,0 +1,49 @@
+using Business.Model;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Business.Model.MES.IC
+{
+    /// <summary>
+    /// 物料包装表
+    /// </summary>
+    [Comment("物料包装表")]
+    public class ItemPackMaster
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Comment("主键")]
+        [Key]
+        public int RecID { get; set; }
+
+        /// <summary>
+        /// 域名
+        /// </summary>
+        [Comment("域名")]
+        public string? Domain { get; set; }
+
+        /// <summary>
+        /// 物料编号
+        /// </summary>
+        [Comment("物料编号")]
+        public string? ItemNum { get; set; }
+
+        /// <summary>
+        /// 包装数量
+        /// </summary>
+        [Comment("包装数量")]
+        public decimal? PackingQty { get; set; }
+
+        /// <summary>
+        /// 是否有效:1-有效;0-无效
+        /// </summary>
+        [Comment("是否有效")]
+        public Boolean IsActive { get; set; }
+    }
+}

+ 55 - 0
MicroServices/Business/Bussiness.Model/MES/IC/LocationDetail.cs

@@ -0,0 +1,55 @@
+using Business.Model;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Business.Model.MES.IC
+{
+    /// <summary>
+    /// 库存明细表
+    /// </summary>
+    [Comment("库存明细表")]
+    public class LocationDetail
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        [Comment("主键")]
+        [Key]
+        public int RecID { get; set; }
+
+        /// <summary>
+        /// 域名
+        /// </summary>
+        [Comment("域名")]
+        public string? Domain { get; set; }
+
+        /// <summary>
+        /// 库位
+        /// </summary>
+        [Comment("库位")]
+        public string? Location { get; set; }
+
+        /// <summary>
+        /// 物料编号
+        /// </summary>
+        [Comment("物料编号")]
+        public string? ItemNum { get; set; }
+
+        /// <summary>
+        /// 库存数量
+        /// </summary>
+        [Comment("库存数量")]
+        public decimal? QtyOnHand { get; set; }
+
+        /// <summary>
+        /// 是否有效:1-有效;0-无效
+        /// </summary>
+        [Comment("是否有效")]
+        public Boolean IsActive { get; set; }
+    }
+}