Procházet zdrojové kódy

交货计划生成交货单

heteng před 2 roky
rodič
revize
c6367e9dfc

+ 3 - 1
MicroServices/Business/Business.Application.Contracts/ReplenishmentManagement/IReplenishmentAppService.cs

@@ -99,7 +99,9 @@ namespace Business.ReplenishmentManagement
         /// <summary>
         /// 生成交货单
         /// </summary>
+        /// <param name="domain"></param>
+        /// <param name="user"></param>
         /// <returns></returns>
-        Task<string> CreateDeliverySchedule(string domain);
+        Task<string> CreateDeliverySchedule(string domain, string user);
     }
 }

+ 191 - 6
MicroServices/Business/Business.Application/ReplenishmentManagement/ReplenishmentAppService.cs

@@ -47,6 +47,18 @@ namespace Business.Replenishment
         private readonly ISqlRepository<InvMaster> _invMaster;
         private readonly ISqlRepository<SAPInv> _SAPInv;
         private readonly IRepository<srm_purchase, long> _srmPurchase;
+        /// <summary>
+        /// 交货计划
+        /// </summary>
+        private readonly IRepository<ic_demandschedule, long> _icdemandschedule;
+        /// <summary>
+        /// 交货单
+        /// </summary>
+        private readonly ISqlRepository<srm_polist_ds> _srmpolistds;
+        /// <summary>
+        /// 采购明细表
+        /// </summary>
+        private readonly ISqlRepository<PurOrdDetail> _PurOrdDetail;
         private readonly ISqlRepository<MonthlyShipmentPlan> _monthlyShipmentPlan;
         private readonly ISqlRepository<MonthlyShipmentPlanHistory> _monthlyShipmentPlanHistory;
         private readonly ISqlRepository<GeneralizedCodeMaster> _generalizedCodeMaster;
@@ -315,6 +327,9 @@ namespace Business.Replenishment
             BusinessBangDbContext businessBangDbContext,
             BusinessDbContext businessDbContext,
             ICurrentTenant currentTenant,
+            IRepository<ic_demandschedule, long> icdemandschedule,
+            ISqlRepository<srm_polist_ds> srmpolistds,
+            ISqlRepository<PurOrdDetail> PurOrdDetail,
             IUnitOfWorkManager unitOfWorkManager)
         {
             _replenishmentROPWeekPlan = replenishmentROPWeekPlan;
@@ -406,6 +421,9 @@ namespace Business.Replenishment
             _businessBangDbContext= businessBangDbContext;
             _businessDbContext = businessDbContext;
             _unitOfWorkManager = unitOfWorkManager;
+            _icdemandschedule = icdemandschedule;
+            _srmpolistds = srmpolistds;
+            _PurOrdDetail = PurOrdDetail;
         }
         #endregion
 
@@ -6169,17 +6187,184 @@ namespace Business.Replenishment
         /// 生成交货单
         /// </summary>
         /// <param name="domain"></param>
+        /// <param name="user"></param>
         /// <returns></returns>
-        public async Task<string> CreateDeliverySchedule(string domain)
+        public async Task<string> CreateDeliverySchedule(string domain,string user)
         {
             string Msg = "OK|交货单生成成功";
             //获取已发布的交货计划数据
-            //获取货源清单数据
-
-            
-
-
+            var demandplans = _icdemandschedule.GetListAsync(p=>p.factory_id.ToString() == domain && p.status == "P" && !p.IsDeleted).Result;
+            if (!demandplans.Any())
+            {
+                Msg = "OK|没有需要生成的交货单";
+                return Msg;
+            }
+            //获取货源清单数据(配额比例为0的排除)
+            List<string> itemnums = demandplans.Select(p => p.itemnum).ToList();
+            var purchases = _srmPurchase.GetListAsync(p => p.factory_id.ToString() == domain && p.is_active == "否" && itemnums.Contains(p.number) && p.quota_rate > 0 && !p.IsDeleted).Result;
+            //获取PO可用明细数据:未关闭,且未交货数量(需求数量-已收数量)>0
+            List<PurOrdDetail> purOrdDetails = _PurOrdDetail.Select(p => p.Domain == domain && itemnums.Contains(p.ItemNum) && p.Status.ToUpper() != "C" && (p.QtyOrded - p.RctQty)>0).OrderBy(p=>p.DueDate).ToList();
+            if (!purOrdDetails.Any())
+            {
+                Msg = "NO|没有可用的采购单";
+                return Msg;
+            }
+            //获取占用可用PO明细的交货单
+            List<srm_polist_ds> dbPolistds = _srmpolistds.Select(p => purOrdDetails.Select(m => m.PurOrd).Contains(p.ponumber)).ToList();
+
+            //生成交货单
+            srm_polist_ds entity;
+            List<srm_polist_ds> inserts = new List<srm_polist_ds>();
+            //采购明细剩余未交数量
+            decimal sumRestQty = 0m;
+            //交货单占用数量
+            decimal sumDbOccupy = 0m;
+            //本次计算占用数量
+            decimal sumCurOccupy = 0m;
+            //剩余可用数量
+            decimal restQty = 0m;
+            foreach (var item in demandplans)
+            {
+                //获取当前交货计划物料对应的货源清单
+                var curChaes = purchases.Where(p => p.number == item.itemnum).ToList();
+                //获取当前交货计划物料对应的采购单明细数据
+                var curPurDtls = purOrdDetails.Where(p => p.ItemNum == item.itemnum).OrderBy(p=>p.DueDate).ToList();
+                //数据库中当前采购单明细被交货单占用情况
+                var curDbOccupys = dbPolistds.Where(p => curPurDtls.Select(m => m.PurOrd).Contains(p.ponumber) && p.itemnum == item.itemnum).ToList();
+                //本次计算中采购单明细被交货单占用情况
+                var curCalcOccupys = inserts.Where(p => curPurDtls.Select(m => m.PurOrd).Contains(p.ponumber) && p.itemnum == item.itemnum).ToList();
+                #region 校验
+                //校验1:如果当前物料没有维护货源清单,则跳过
+                if (!curChaes.Any())
+                {
+                    continue;
+                }
+                //校验2:如果当前物料没有可用的采购明细,则跳过
+                if (!curPurDtls.Any())
+                {
+                    continue;
+                }
+                //校验3:如果当前物料对应的采购明细可用数量不满足,则跳过
+                //采购单明细的剩余未交数量:采购明细的需求数量-已交数量
+                sumRestQty = curPurDtls.Sum(p => p.QtyOrded - p.RctQty);
+                //交货单占用数量:交货单的剩余需要采购数量
+                sumDbOccupy = curDbOccupys.Sum(p => p.restqty);
+                //本次计算交货单占用数量:本次计算交货单的需求数量
+                sumCurOccupy = curCalcOccupys.Sum(p => p.schedqty);
+                //剩余可用数量
+                restQty = sumRestQty - sumDbOccupy - sumCurOccupy;
+                if (restQty < item.tosechedqty)
+                {
+                    continue;
+                }
+                #endregion
+
+                //当前供应商分配数量数量
+                decimal needQty = 0m;
+                //已分配数量合计
+                decimal sumNeedQty = 0m;
+                //剩余需要分配数量
+                decimal remainQty = 0m;
+                //存在货源清单,po可用数量满足当前交货计划,则先计算供应商配额,然后,再占用po可用数量
+                foreach (var pch in curChaes)
+                {
+                    //计算当前供应商分配数量
+                    needQty = item.tosechedqty * pch.quota_rate.GetValueOrDefault();
+                    //按照采购单明细数据交货日期从小到大开始占用
+                    foreach (var pud in curPurDtls)
+                    {
+                        //当前采购明细剩余数量=订单数量-已收数量
+                        decimal syQty = pud.QtyOrded - pud.RctQty;
+                        //当前采购明细被占用数量(已占用数量)
+                        var occupy = curDbOccupys.Where(p => p.ponumber == pud.PurOrd && p.itemnum == pud.ItemNum && p.poline == pud.Line).ToList();
+                        decimal yzyQty = occupy.Sum(p => p.restqty);
+                        //当前计算中采购明细被占用数量(本次计算占用数量)
+                        var calcs = inserts.Where(p=> p.ponumber == pud.PurOrd && p.itemnum == pud.ItemNum && p.poline == pud.Line).ToList();
+                        decimal bzyQty = calcs.Sum(p=>p.schedqty);
+
+                        //当前采购明细可用数量
+                        decimal kyQty = syQty - yzyQty - bzyQty;
+                        //剩余需要分配数量
+                        remainQty = needQty - sumNeedQty;
+                        //当前采购明细已被全部占用,循环下一条采购明细
+                        if (kyQty == 0 )
+                        {
+                            continue;
+                        }
+                        decimal xqQty = 0m;
+                        //当前采购明细的可用数量不满足交货单剩余需要分配数量
+                        if (kyQty < remainQty)
+                        {
+                            //占用当前采购明细剩余可用数量
+                            xqQty = kyQty;
+                        }
+                        else {
+                            xqQty = remainQty;
+                            //按照最小包装量圆整:最小包装量为0,则不需要圆整
+                            decimal yzQty = pch.packaging_qty.GetValueOrDefault() == 0 ? remainQty : Math.Ceiling(remainQty / pch.packaging_qty.GetValueOrDefault()) * pch.packaging_qty.GetValueOrDefault();
+                            //如果可用数量大于圆整数量
+                            if (kyQty >= yzQty)
+                            {
+                                xqQty = yzQty;
+                            }
+                        }
+                        //生成实体
+                        entity = new srm_polist_ds();
+                        entity.Id = help.NextId();
+                        entity.domain = domain;
+                        entity.icdsid = item.Id;
+                        //TODO:调用存储过程生成交货单号
+                        entity.dsnum = "";
+                        entity.status = "N";
+                        entity.itemnum = item.itemnum;
+                        entity.suppliercode = pch.supplier_number;
+                        entity.supplier = pch.supplier_name;
+                        entity.requestdate = item.arrivaldate;
+                        entity.needdate = item.requestdate;
+                        entity.ponumber = pud.PurOrd;
+                        entity.poline = pud.Line;
+                        entity.schedqty = xqQty;
+                        entity.lastsentqty = 0m;
+                        entity.sentqty = 0m;
+                        entity.restqty = xqQty;
+                        entity.createtime = DateTime.Now;
+                        entity.createuser = user;
+                        inserts.Add(entity);
+                    }
+                }
+            }
 
+            if (inserts.Any())
+            {
+                //获取交货单号
+                List<string> GenerateMoList = new List<string>();
+                var nbrlist = _serialNumberAppService.GetBillNo(domain, "M8", inserts.Count, "", 1);
+                if (!nbrlist.Any() || nbrlist.Count != inserts.Count)
+                {
+                    Msg = "NO|交货单号生成失败";
+                    return Msg;
+                }
+                inserts = inserts.OrderBy(p => p.createtime).ToList();
+                for (int i = 0; i < inserts.Count; i++)
+                {
+                    inserts[i].dsnum = nbrlist[i].NbrResult;
+                }
+                //数据插入
+                using (var unitOfWork = _unitOfWorkManager.Begin(false, true))
+                {
+                    try
+                    {
+                        _srmpolistds.Insert(inserts);
+                        await unitOfWork.CompleteAsync();
+                    }
+                    catch (Exception e)
+                    {
+                        unitOfWork.Dispose();
+                        new NLogHelper("ReplenishmentAppService").WriteLog("CreateDeliverySchedule", "交货计划生成交货单失败:" + e.Message, _currentTenant.Id.ToString());
+                        Msg = "NO|交货单保存失败:" + e.Message;
+                    };
+                }
+            }
             return Msg;
         }
     }

+ 1 - 1
MicroServices/Business/Business.Application/ResourceExamineManagement/ResourceExamineAppService.cs

@@ -2558,7 +2558,7 @@ namespace Business.ResourceExamineManagement
                     UM = refItem?.UM,
                     ItemNum = a.ItemNum,
                     QtyOrded = a.qty.GetValueOrDefault(),
-                    QtyReceived = a.rqty.GetValueOrDefault(),
+                    RctQty = a.rqty.GetValueOrDefault(),
                     PurCost = a.price.GetValueOrDefault(),
                     StdCost = a.price.GetValueOrDefault() / (1 + a.rate.GetValueOrDefault()),
                     TaxRate = a.rate.GetValueOrDefault(),

+ 4 - 4
MicroServices/Business/Business.Application/SystemJobManagement/SystemJobAppService.cs

@@ -1155,14 +1155,14 @@ namespace Business.SystemJobManagement
                             plist.model = icitem.model;
                             plist.ItemNum = icitem.number;
                             plist.icitem_name = icitem.name;
-                            plist.qty = dtl.QtyOrded.GetValueOrDefault();
+                            plist.qty = dtl.QtyOrded;
                             plist.netprice = dtl.PurCost.GetValueOrDefault();
-                            plist.netmoney = dtl.QtyOrded.GetValueOrDefault() * dtl.PurCost.GetValueOrDefault();
+                            plist.netmoney = dtl.QtyOrded * dtl.PurCost.GetValueOrDefault();
                             plist.rate = dtl.TaxRate;
                             plist.price = dtl.PurCost.GetValueOrDefault();
-                            plist.total_price = dtl.QtyOrded.GetValueOrDefault() * dtl.PurCost.GetValueOrDefault();
+                            plist.total_price = dtl.QtyOrded * dtl.PurCost.GetValueOrDefault();
                             //plist.taxamount = item.pr_orderprice.GetValueOrDefault() - podetail.netmoney;
-                            plist.plan_qty = dtl.QtyOrded.GetValueOrDefault();
+                            plist.plan_qty = dtl.QtyOrded;
                             plist.unit = icitem.unit;
                             plist.rarrdate = dtl.DueDate;
                             plist.rnumber = 0;

+ 2 - 2
MicroServices/Business/Business.Domain/StructuredDB/MES/IC/PurOrdDetail.cs

@@ -62,14 +62,14 @@ namespace Business.Domain
         /// </summary>
         [Precision(23, 10)]
         [Comment("订单数量")]
-        public decimal? QtyOrded { get; set; }
+        public decimal QtyOrded { get; set; }
 
         /// <summary>
         /// 已收货数量
         /// </summary>
         [Precision(23, 10)]
         [Comment("已收货数量")]
-        public decimal? QtyReceived { get; set; }
+        public decimal RctQty { get; set; }
 
         /// <summary>
         /// 含税单价

+ 6 - 0
MicroServices/Business/Business.Domain/StructuredDB/MES/IC/srm_polist_ds.cs

@@ -157,5 +157,11 @@ namespace Business.Domain
         /// </summary>
         [Comment("修改时间")]
         public DateTime? updatetime { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        [Comment("备注")]
+        public string remarks { get; set; }
     }
 }

+ 6 - 1
MicroServices/Business/Business.Domain/StructuredDB/SRM/srm_purchase.cs

@@ -240,7 +240,12 @@ namespace Business.Domain
         /// </summary>
         [Comment("配额优先级")]
         public int quota_priority { get; set; }
-        
 
+        /// <summary>
+        /// 失效
+        /// </summary>
+        [StringLength(64)]
+        [Comment("失效")]
+        public string? is_active { get; set; }
     }
 }

+ 3 - 2
MicroServices/Business/Business.HttpApi/Controllers/ReplenishmentController.cs

@@ -170,12 +170,13 @@ namespace Business.Controllers
         /// 生成交货计划
         /// </summary>
         /// <param name="domain"></param>
+        /// <param name="user"></param>
         /// <returns></returns>
         [HttpGet]
         [Route("CreateDeliverySchedule")]
-        public Task<string> CreateDeliverySchedule(string domain)
+        public Task<string> CreateDeliverySchedule(string domain,string user)
         {
-            return _ReplenishmentAppService.CreateDeliverySchedule(domain);
+            return _ReplenishmentAppService.CreateDeliverySchedule(domain, user);
         }
     }
 }