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

交货单生成逻辑调整:交货计划按照需求日期从小到大排序,供应商按照配额从大到小排序,采购单按照需求日期从小到大排序

heteng 2 лет назад
Родитель
Сommit
edf5a71382

+ 203 - 41
MicroServices/Business/Business.Application/ReplenishmentManagement/ReplenishmentAppService.cs

@@ -6392,7 +6392,7 @@ namespace Business.Replenishment
             //获取采购单数据
             List<PurOrdMaster> purOrdMasters = _PurOrdMaster.Select(p => p.Domain == domain && purOrdDetails.Select(m => m.PurOrd).Distinct().Contains(p.PurOrd)).ToList();
             //获取占用可用PO明细的交货单
-            List<srm_polist_ds> dbPolistds = _srmpolistds.Select(p => purOrdDetails.Select(m => m.PurOrd).Contains(p.ponumber) && p.isactive == 1).ToList();
+            List<srm_polist_ds> dbPolistds = _srmpolistds.Select(p => purOrdDetails.Select(m => m.PurOrd).Contains(p.ponumber) && p.status.ToUpper() !="C" && p.isactive == 1).ToList();
 
             //生成交货单
             srm_polist_ds entity;
@@ -6412,20 +6412,21 @@ namespace Business.Replenishment
             decimal sumCurOccupy = 0m;
             //剩余可用数量
             decimal restQty = 0m;
-            foreach (var item in demandplans)
+            demandplans = demandplans.OrderBy(p => p.requestdate).ToList();
+            for (int i = 0; i < demandplans.Count; i++)
             {
                 curInserts = new List<srm_polist_ds>();
                 //获取当前交货计划物料对应的货源清单
-                var curChaes = purchases.Where(p => p.number == item.itemnum).OrderByDescending(p=>p.quota_rate).ToList();
+                var curChaes = purchases.Where(p => p.number == demandplans[i].itemnum).OrderByDescending(p => p.quota_rate).ToList();
                 //校验1:如果当前物料没有维护货源清单,则跳过
                 if (!curChaes.Any())
                 {
                     info = new DeliveryExceptionMaster();
                     info.Domain = domain;
-                    info.Icdsid = item.Id;
-                    info.ItemNum = item.itemnum;
+                    info.Icdsid = demandplans[i].Id;
+                    info.ItemNum = demandplans[i].itemnum;
                     info.CreateTime = DateTime.Now;
-                    info.Remark = "交货计划[" + item.itemnum + ":" + item.requestdate.ToString("yyyy-MM-dd") + "]没有维护货源清单,无法转交货单";
+                    info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]没有维护货源清单,无法转交货单";
                     info.OptTime = optime;
                     exceptions.Add(info);
                     continue;
@@ -6435,25 +6436,25 @@ namespace Business.Replenishment
                 {
                     info = new DeliveryExceptionMaster();
                     info.Domain = domain;
-                    info.Icdsid = item.Id;
-                    info.ItemNum = item.itemnum;
+                    info.Icdsid = demandplans[i].Id;
+                    info.ItemNum = demandplans[i].itemnum;
                     info.CreateTime = DateTime.Now;
-                    info.Remark = "交货计划[" + item.itemnum + ":" + item.requestdate.ToString("yyyy-MM-dd") + "]的货源清单供应商配额之和不为100%,无法转交货单";
+                    info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]的货源清单供应商配额之和不为100%,无法转交货单";
                     info.OptTime = optime;
                     exceptions.Add(info);
                     continue;
                 }
                 //获取当前交货计划物料对应的可用采购单明细数据
-                var curPurDtls = purOrdDetails.Where(p => p.ItemNum == item.itemnum).OrderBy(p=>p.DueDate).ToList();
+                var curPurDtls = purOrdDetails.Where(p => p.ItemNum == demandplans[i].itemnum).OrderBy(p => p.DueDate).ToList();
                 //校验3:如果当前物料没有可用的采购明细,则跳过
                 if (!curPurDtls.Any())
                 {
                     info = new DeliveryExceptionMaster();
                     info.Domain = domain;
-                    info.Icdsid = item.Id;
-                    info.ItemNum = item.itemnum;
+                    info.Icdsid = demandplans[i].Id;
+                    info.ItemNum = demandplans[i].itemnum;
                     info.CreateTime = DateTime.Now;
-                    info.Remark = "交货计划[" + item.itemnum + ":" + item.requestdate.ToString("yyyy-MM-dd") + "]没有可占用的采购明细,无法转交货单";
+                    info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]没有可占用的采购明细,无法转交货单";
                     info.OptTime = optime;
                     exceptions.Add(info);
                     continue;
@@ -6461,9 +6462,9 @@ namespace Business.Replenishment
                 //当前采购明细对应的采购单
                 var curPurMsts = purOrdMasters.Where(p => curPurDtls.Select(m => m.PurOrd).Distinct().Contains(p.PurOrd)).ToList();
                 //数据库中当前采购单明细被交货单占用情况
-                var curDbOccupys = dbPolistds.Where(p => curPurDtls.Select(m => m.PurOrd).Contains(p.ponumber) && p.itemnum == item.itemnum).ToList();
+                var curDbOccupys = dbPolistds.Where(p => curPurDtls.Select(m => m.PurOrd).Contains(p.ponumber) && p.itemnum == demandplans[i].itemnum).ToList();
                 //本次计算中采购单明细被交货单占用情况
-                var curCalcOccupys = inserts.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 == demandplans[i].itemnum).ToList();
                 //校验4:如果当前物料对应的采购明细可用数量不满足,则跳过
                 //采购单明细的剩余未交数量:采购明细的需求数量-已交数量
                 sumRestQty = curPurDtls.Sum(p => p.QtyOrded - p.RctQty);
@@ -6473,14 +6474,14 @@ namespace Business.Replenishment
                 sumCurOccupy = curCalcOccupys.Sum(p => p.schedqty);
                 //剩余可用数量
                 restQty = sumRestQty - sumDbOccupy - sumCurOccupy;
-                if (restQty < item.tosechedqty)
+                if (restQty < demandplans[i].tosechedqty)
                 {
                     info = new DeliveryExceptionMaster();
                     info.Domain = domain;
-                    info.Icdsid = item.Id;
-                    info.ItemNum = item.itemnum;
+                    info.Icdsid = demandplans[i].Id;
+                    info.ItemNum = demandplans[i].itemnum;
                     info.CreateTime = DateTime.Now;
-                    info.Remark = "交货计划[" + item.itemnum + ":" + item.requestdate.ToString("yyyy-MM-dd") + "]的采购明细可用数量不足,无法转交货单";
+                    info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]的采购明细可用数量不足,无法转交货单";
                     info.OptTime = optime;
                     exceptions.Add(info);
                     continue;
@@ -6496,6 +6497,165 @@ namespace Business.Replenishment
                 //当前供应商剩余需要分配数量
                 decimal remainQty = 0m;
                 //存在货源清单,采购单明细可用数量满足当前交货计划,则先计算供应商配额,计算当前供应商对应的采购明细是否满足配额,若满足则占用采购单明细可用数量
+                curChaes = curChaes.OrderByDescending(p => p.quota_rate.GetValueOrDefault()).ToList();
+                for (int j = 0; j < curChaes.Count; j++)
+                {
+                    if (curChaes[j].quota_rate.GetValueOrDefault() == 0)
+                    {
+                        continue;
+                    }
+                    //如果交货计划已分配数量>=交货计划净需求数量,则终止
+                    if (allQty >= demandplans[i].tosechedqty)
+                    {
+                        break;
+                    }
+                    //供应商占用数量置0
+                    sumNeedQty = 0m;
+                    //计算当前供应商分配数量
+                    needQty = Math.Ceiling(demandplans[i].tosechedqty * curChaes[j].quota_rate.GetValueOrDefault() / 100.00m);
+                    //如果交货计划剩余数量小于按照供应商配额计算的数量,则当前供应商需分配数量为交货计划剩余数量
+                    if (demandplans[i].tosechedqty - allQty < needQty)
+                    {
+                        needQty = demandplans[i].tosechedqty - allQty;
+                    }
+                    //以下为供应商是采购申请场景
+                    //获取当前供应商对应的采购单明细数据,按照交货日期从小到大开始占用
+                    var pchPurMsts = curPurMsts.Where(p => p.Supp == curChaes[j].supplier_number).ToList();
+                    if (!pchPurMsts.Any())
+                    {
+                        //当前供应商没有可用采购单,则当前交货计划无法转交货单
+                        info = new DeliveryExceptionMaster();
+                        info.Domain = domain;
+                        info.Icdsid = demandplans[i].Id;
+                        info.ItemNum = demandplans[i].itemnum;
+                        info.CreateTime = DateTime.Now;
+                        info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]对应供应商[" + curChaes[j].supplier_name + "]没有可用采购明细,无法转交货单";
+                        info.OptTime = optime;
+                        exceptions.Add(info);
+
+                        flag = true;
+                        break;
+                    }
+                    var pchPurDtls = curPurDtls.Where(p => pchPurMsts.Select(m => m.PurOrd).Contains(p.PurOrd)).ToList();
+                    if (!pchPurDtls.Any())
+                    {
+                        //当前供应商没有可用采购单明细,则当前交货计划无法转交货单
+                        info = new DeliveryExceptionMaster();
+                        info.Domain = domain;
+                        info.Icdsid = demandplans[i].Id;
+                        info.ItemNum = demandplans[i].itemnum;
+                        info.CreateTime = DateTime.Now;
+                        info.Remark = "物料[" + demandplans[i].itemnum + "]对应供应商[" + curChaes[j].supplier_name + "]没有可用采购明细,无法转交货单";
+                        info.OptTime = optime;
+                        exceptions.Add(info);
+
+                        flag = true;
+                        break;
+                    }
+                    //校验当前供应商的采购明细剩余可用数量是否满足供应商的配额
+                    //采购单明细剩余可用数量
+                    sumRestQty = pchPurDtls.Sum(p => p.QtyOrded - p.RctQty);
+                    //交货单占用数量:交货单的剩余需要采购数量
+                    sumDbOccupy = curDbOccupys.Where(p => pchPurDtls.Select(m => m.PurOrd).Contains(p.ponumber)).Sum(p => p.restqty);
+                    //本次计算交货单占用数量:本次计算交货单的需求数量
+                    sumCurOccupy = curCalcOccupys.Where(p => pchPurDtls.Select(m => m.PurOrd).Contains(p.ponumber)).Sum(p => p.schedqty);
+                    //剩余可用数量
+                    restQty = sumRestQty - sumDbOccupy - sumCurOccupy;
+                    if (restQty < needQty)
+                    {
+                        //当前供应商可用采购单明细不足,则当前交货计划无法转交货单
+                        info = new DeliveryExceptionMaster();
+                        info.Domain = domain;
+                        info.Icdsid = demandplans[i].Id;
+                        info.ItemNum = demandplans[i].itemnum;
+                        info.CreateTime = DateTime.Now;
+                        info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]对应供应商[" + curChaes[j].supplier_name + "]采购明细可用数量不足,无法转交货单";
+                        info.OptTime = optime;
+                        exceptions.Add(info);
+
+                        flag = true;
+                        break;
+                    }
+
+                    //采购单按照需求日期从小到大排
+                    pchPurDtls = curPurDtls.OrderBy(p => p.DueDate).ToList();
+                    for (int k = 0; k < pchPurDtls.Count; k++)
+                    {
+                        if (sumNeedQty >= needQty)
+                        {
+                            //当前供应商配额以满足,循环下一个供应商
+                            break;
+                        }
+                        //当前采购明细剩余数量=订单数量-已收数量
+                        decimal syQty = pchPurDtls[k].QtyOrded - pchPurDtls[k].RctQty;
+                        //当前采购明细被占用数量(已占用数量)
+                        var occupy = curDbOccupys.Where(p => p.ponumber == pchPurDtls[k].PurOrd && p.itemnum == pchPurDtls[k].ItemNum && p.poline == pchPurDtls[k].Line).ToList();
+                        decimal yzyQty = occupy.Sum(p => p.restqty);
+                        //当前计算中采购明细被占用数量(本次计算占用数量)
+                        var calcs = inserts.Where(p => p.ponumber == pchPurDtls[k].PurOrd && p.itemnum == pchPurDtls[k].ItemNum && p.poline == pchPurDtls[k].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 = curChaes[j].packaging_qty.GetValueOrDefault() == 0 ? remainQty : Math.Ceiling(remainQty / curChaes[j].packaging_qty.GetValueOrDefault()) * curChaes[j].packaging_qty.GetValueOrDefault();
+                            //如果可用数量大于圆整数量
+                            if (kyQty >= yzQty)
+                            {
+                                xqQty = yzQty;
+                            }
+                        }
+                        //生成实体
+                        entity = new srm_polist_ds();
+                        entity.Id = help.NextId();
+                        entity.domain = domain;
+                        entity.icdsid = demandplans[i].Id;
+                        //交货单号最后一次性生成
+                        entity.dsnum = "";
+                        entity.status = "N";
+                        entity.itemnum = demandplans[i].itemnum;
+                        entity.um = "";
+                        entity.purgroup = "";
+                        entity.suppliercode = curChaes[j].supplier_number;
+                        entity.supplier = curChaes[j].supplier_name;
+                        entity.requestdate = demandplans[i].arrivaldate;
+                        entity.needdate = demandplans[i].requestdate;
+                        entity.ponumber = pchPurDtls[k].PurOrd;
+                        entity.poline = pchPurDtls[k].Line;
+                        entity.schedqty = xqQty;
+                        entity.lastsentqty = 0m;
+                        entity.sentqty = 0m;
+                        entity.restqty = xqQty;
+                        entity.createtime = DateTime.Now;
+                        entity.createuser = user;
+                        entity.remarks = "";
+                        entity.isactive = 1;
+                        curInserts.Add(entity);
+
+                        //当前交货计划已分配数量累加
+                        allQty += xqQty;
+                        //当前供应商已分配数量累加
+                        sumNeedQty += xqQty;
+                    }
+                }
+
                 foreach (var pch in curChaes)
                 {
                     if (pch.quota_rate.GetValueOrDefault() == 0)
@@ -6503,18 +6663,18 @@ namespace Business.Replenishment
                         continue;
                     }
                     //如果交货计划已分配数量>=交货计划净需求数量,则终止
-                    if (allQty >= item.tosechedqty)
+                    if (allQty >= demandplans[i].tosechedqty)
                     {
                         break;
                     }
                     //供应商占用数量置0
                     sumNeedQty = 0m;
                     //计算当前供应商分配数量
-                    needQty = Math.Ceiling(item.tosechedqty * pch.quota_rate.GetValueOrDefault() / 100.00m);
+                    needQty = Math.Ceiling(demandplans[i].tosechedqty * pch.quota_rate.GetValueOrDefault() / 100.00m);
                     //如果交货计划剩余数量小于按照供应商配额计算的数量,则当前供应商需分配数量为交货计划剩余数量
-                    if (item.tosechedqty - allQty < needQty)
+                    if (demandplans[i].tosechedqty - allQty < needQty)
                     {
-                        needQty = item.tosechedqty - allQty;
+                        needQty = demandplans[i].tosechedqty - allQty;
                     }
                     //以下为供应商是采购申请场景
                     //获取当前供应商对应的采购单明细数据,按照交货日期从小到大开始占用
@@ -6524,10 +6684,10 @@ namespace Business.Replenishment
                         //当前供应商没有可用采购单,则当前交货计划无法转交货单
                         info = new DeliveryExceptionMaster();
                         info.Domain = domain;
-                        info.Icdsid = item.Id;
-                        info.ItemNum = item.itemnum;
+                        info.Icdsid = demandplans[i].Id;
+                        info.ItemNum = demandplans[i].itemnum;
                         info.CreateTime = DateTime.Now;
-                        info.Remark = "交货计划[" + item.itemnum + ":" + item.requestdate.ToString("yyyy-MM-dd") + "]对应供应商[" + pch.supplier_name + "]没有可用采购明细,无法转交货单";
+                        info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]对应供应商[" + pch.supplier_name + "]没有可用采购明细,无法转交货单";
                         info.OptTime = optime;
                         exceptions.Add(info);
 
@@ -6540,10 +6700,10 @@ namespace Business.Replenishment
                         //当前供应商没有可用采购单明细,则当前交货计划无法转交货单
                         info = new DeliveryExceptionMaster();
                         info.Domain = domain;
-                        info.Icdsid = item.Id;
-                        info.ItemNum = item.itemnum;
+                        info.Icdsid = demandplans[i].Id;
+                        info.ItemNum = demandplans[i].itemnum;
                         info.CreateTime = DateTime.Now;
-                        info.Remark = "物料[" + item.itemnum + "]对应供应商[" + pch.supplier_name + "]没有可用采购明细,无法转交货单";
+                        info.Remark = "物料[" + demandplans[i].itemnum + "]对应供应商[" + pch.supplier_name + "]没有可用采购明细,无法转交货单";
                         info.OptTime = optime;
                         exceptions.Add(info);
 
@@ -6554,7 +6714,7 @@ namespace Business.Replenishment
                     //采购单明细剩余可用数量
                     sumRestQty = pchPurDtls.Sum(p => p.QtyOrded - p.RctQty);
                     //交货单占用数量:交货单的剩余需要采购数量
-                    sumDbOccupy = curDbOccupys.Where(p=> pchPurDtls.Select(m => m.PurOrd).Contains(p.ponumber)).Sum(p => p.restqty);
+                    sumDbOccupy = curDbOccupys.Where(p => pchPurDtls.Select(m => m.PurOrd).Contains(p.ponumber)).Sum(p => p.restqty);
                     //本次计算交货单占用数量:本次计算交货单的需求数量
                     sumCurOccupy = curCalcOccupys.Where(p => pchPurDtls.Select(m => m.PurOrd).Contains(p.ponumber)).Sum(p => p.schedqty);
                     //剩余可用数量
@@ -6564,10 +6724,10 @@ namespace Business.Replenishment
                         //当前供应商可用采购单明细不足,则当前交货计划无法转交货单
                         info = new DeliveryExceptionMaster();
                         info.Domain = domain;
-                        info.Icdsid = item.Id;
-                        info.ItemNum = item.itemnum;
+                        info.Icdsid = demandplans[i].Id;
+                        info.ItemNum = demandplans[i].itemnum;
                         info.CreateTime = DateTime.Now;
-                        info.Remark = "交货计划[" + item.itemnum + ":" + item.requestdate.ToString("yyyy-MM-dd") + "]对应供应商[" + pch.supplier_name + "]采购明细可用数量不足,无法转交货单";
+                        info.Remark = "交货计划[" + demandplans[i].itemnum + ":" + demandplans[i].requestdate.ToString("yyyy-MM-dd") + "]对应供应商[" + pch.supplier_name + "]采购明细可用数量不足,无法转交货单";
                         info.OptTime = optime;
                         exceptions.Add(info);
 
@@ -6588,15 +6748,15 @@ namespace Business.Replenishment
                         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);
+                        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 )
+                        if (kyQty == 0)
                         {
                             continue;
                         }
@@ -6607,7 +6767,8 @@ namespace Business.Replenishment
                             //占用当前采购明细剩余可用数量
                             xqQty = kyQty;
                         }
-                        else {
+                        else
+                        {
                             xqQty = remainQty;
                             //按照最小包装量圆整:最小包装量为0,则不需要圆整
                             decimal yzQty = pch.packaging_qty.GetValueOrDefault() == 0 ? remainQty : Math.Ceiling(remainQty / pch.packaging_qty.GetValueOrDefault()) * pch.packaging_qty.GetValueOrDefault();
@@ -6621,17 +6782,17 @@ namespace Business.Replenishment
                         entity = new srm_polist_ds();
                         entity.Id = help.NextId();
                         entity.domain = domain;
-                        entity.icdsid = item.Id;
+                        entity.icdsid = demandplans[i].Id;
                         //交货单号最后一次性生成
                         entity.dsnum = "";
                         entity.status = "N";
-                        entity.itemnum = item.itemnum;
+                        entity.itemnum = demandplans[i].itemnum;
                         entity.um = "";
                         entity.purgroup = "";
                         entity.suppliercode = pch.supplier_number;
                         entity.supplier = pch.supplier_name;
-                        entity.requestdate = item.arrivaldate;
-                        entity.needdate = item.requestdate;
+                        entity.requestdate = demandplans[i].arrivaldate;
+                        entity.needdate = demandplans[i].requestdate;
                         entity.ponumber = pud.PurOrd;
                         entity.poline = pud.Line;
                         entity.schedqty = xqQty;
@@ -6658,6 +6819,7 @@ namespace Business.Replenishment
                 inserts.AddRange(curInserts);
             }
 
+
             if (inserts.Any())
             {
                 //获取交货单号