Browse Source

扣回动员预付款

yangyj 1 year ago
parent
commit
e3a6bcc71a

+ 25 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/MeterInfo.java

@@ -3,6 +3,7 @@ package org.springblade.manager.vo;
 import cn.hutool.log.StaticLog;
 import com.aliyuncs.utils.MapUtils;
 import lombok.Data;
+import org.springblade.common.utils.BaseUtils;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.TreeNode;
 import org.springblade.meter.entity.InterimPayCertificateItem;
@@ -10,7 +11,9 @@ import org.springblade.meter.entity.InterimPayCertificateItem;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
+import java.util.function.ToIntFunction;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * @author yangyj
@@ -67,10 +70,31 @@ public class MeterInfo {
     List<DataModel> delay =new LinkedList<>();
     /**合同工程清单*/
     private CompletableFuture<List<InventoryForm>> inventoryForms;
+    /***/
+    private List<InventoryForm> inventoryFormList;
 
+
+    /*章节排序*/
+    private ToIntFunction<InventoryForm> paymentSortIndexFc= itf -> {
+        int sort=9999999;
+        String number = itf.getFormNumber();
+        if(number!=null&&!number.isEmpty()){
+            if(!number.contains("-")&&!BaseUtils.isNumber(number)) {
+                String[] arr = number.split("[^\\d.]+");
+                /*  102-5-3-1的sort=102X10^6+5x10^4+3X10^2+1  */
+                sort = IntStream.range(0, arr.length).boxed().mapToInt(i -> (int) (BaseUtils.obj2IntegerZero(arr[i]) * Math.pow(10, (6 - 2 * i)))).sum();
+            }else {
+                return 2000;
+            }
+        }
+        return sort;
+    };
     public List<InventoryForm> getInventoryForms()  {
         try {
-             return inventoryForms.get();
+            if(inventoryFormList==null) {
+                return inventoryForms.get().stream().sorted(Comparator.comparingInt(paymentSortIndexFc)).collect(Collectors.toList());
+            }
+            return inventoryFormList;
         }catch (Exception e){
             StaticLog.error(e.getMessage());
         }

+ 4 - 9
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/RebateIncentiveAdvPay.java

@@ -9,17 +9,13 @@ import java.math.BigDecimal;
 /**
  * @author yangyj
  * @Date 2024/6/18 17:18
- * @description 回扣动员预付款一览表
- * #1.当进度总额>(合同总额(不含变更)*30%)的时候开始计算,否则直接按零计
- * #2.本期扣款=A-上期末扣回款 A=上期末已支付动员预付款总额*(进度总额-合同总额(不含变更)*30%)* 2 / 合同总额(不含变更)
- * #3.当A>上期末已支付动员预付款总额的时候,本期扣回=上期末已支付动员预付款总额-上期末扣回款
- * #4.如果本期扣款计算结果<0,则不能显示负数,按零计。
+ * @description 扣回动员预付款
  */
 @Data
 public class RebateIncentiveAdvPay implements  DataModel{
-    /*#1.当进度总额>(合同总额(不含变更)*30%)的时候开始计算,否则直接按零计
+    /*#1.当小计累计总额>(合同总额(不含变更)*30%)的时候开始计算,否则直接按零计
 #2.本期扣款=A-上期末扣回款 A=上期末已支付动员预付款总额*(进度总额-合同总额(不含变更)*30%)* 2 / 合同总额(不含变更)
-#3.当A>上期末已支付动员预付款总额的时候,本期扣回=上期末已支付动员预付款总额-上期末扣回款
+#3.当小计累计大于合同总额80%,本期扣回=上期末已支付动员预付款总额-上期末扣回款
 #4.如果本期扣款计算结果<0,则不能显示负数,按零计。
    E=2*((C-A*0.3)*B)/A
 */
@@ -43,9 +39,8 @@ public class RebateIncentiveAdvPay implements  DataModel{
     public void calc(String contractAmount,String dyTotalAmount){
         double contractAmountD=BaseUtils.obj2DoubleZero(contractAmount);
         double x=(2*(BaseUtils.obj2DoubleZero(subtotal)-0.3*contractAmountD)*BaseUtils.obj2DoubleZero(dyTotalAmount))/contractAmountD;
-        if(x<0){
+        if(x>0){
             /*扣回款本身就是负数*/
-            x=Math.abs(x);
             String s=new BigDecimal(x).setScale(5,BigDecimal.ROUND_HALF_UP).toPlainString();
             this.retained =s ;
             this.currentPay=s;

+ 1 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/SubprojectInterimPaymentSummary.java

@@ -100,7 +100,7 @@ public class SubprojectInterimPaymentSummary  implements  DataModel{
     }
 
     public void count( @NotNull Consumer<String> setting ,@NotNull  List<SubprojectInterimPaymentSummary> data, @NotNull  Function<SubprojectInterimPaymentSummary,String> fc,@NotNull Integer scale){
-        setting.accept(data.stream().map(e->new BigDecimal(fc.apply(e))).reduce(BigDecimal.ZERO,BigDecimal::add).setScale(scale, RoundingMode.HALF_UP).toString());
+        setting.accept(data.stream().filter(e->fc.apply(e)!=null).map(e->new BigDecimal(fc.apply(e))).reduce(BigDecimal.ZERO,BigDecimal::add).setScale(scale, RoundingMode.HALF_UP).toString());
     }
 
 

+ 0 - 1
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -2930,5 +2930,4 @@ public class CustomFunction {
 
 
 
-
 }

+ 59 - 32
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java

@@ -27,6 +27,7 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.*;
@@ -1027,20 +1028,45 @@ public class ExecutorMeter extends FormulaExecutor {
                              /*本期扣回动员预付款*/
                              BaseInfo baseInfo = tec.meterInfo.getBaseInfo();
                              BigDecimal subtotal=  dataList.stream().limit(dataList.indexOf(certificate)).map(e->BaseUtils.str2BigDecimal(e.getCurrentPeriodEndPay())).reduce(BigDecimal.ZERO,BigDecimal::add);
+                             /*小计本期累计支付*/
                              rebateIncentiveAdvPay.setSubtotal(subtotal.toPlainString());
                              String dyTotalAmount=baseInfo.getDyTotalAmount().toPlainString();
-                             rebateIncentiveAdvPay.calc(baseInfo.getContractAmount().toPlainString(),dyTotalAmount);
-                             InterimPayCertificateItem preSubTotal = previousMap.get("小计");
-                             if(preSubTotal!=null){
-                                 rebateIncentiveAdvPay.setEndPay(addFc.apply(rebateIncentiveAdvPay.getCurrentPay(),preSubTotal.getCurrentPeriodEndPay()));
-                             }else{
-                                 rebateIncentiveAdvPay.setEndPay(rebateIncentiveAdvPay.getCurrentPay());
+                             /*当前累计小计>=30 才扣回*/
+                             if(Double.parseDouble(ratioFc.apply(subtotal.toPlainString(),baseInfo.getContractAmount().toPlainString()))>=30) {
+                                 /*是否扣回完成*/
+                                 AtomicBoolean finish = new AtomicBoolean(false);
+                                 /*是否当前*/
+                                 AtomicBoolean isCur = new AtomicBoolean(false);
+                                 /*所有计量期小计*/
+                                 List<InterimPayCertificateItem> xj = interimPayCertificateItemGroup.values().stream().flatMap(v -> v.values().stream()).filter(e -> "小计".equals(e.getChapterSeq())).collect(Collectors.toList());
+                                 InterimPayCertificateItem curxj = new InterimPayCertificateItem();
+                                 curxj.setCurrentPeriodEndPay(subtotal.toPlainString());
+                                 xj.add(curxj);
+                                 xj.sort(Comparator.comparing(InterimPayCertificateItem::getCurrentPeriodEndPay));
+                                 /*当扣完动员预付款的时候,小计总额*/
+                                 xj.stream().filter(e -> Double.parseDouble(ratioFc.apply(e.getCurrentPeriodEndPay(), baseInfo.getContractAmount().toPlainString())) > 79).findFirst().ifPresent(t -> {
+                                     rebateIncentiveAdvPay.setMeterAmount(t.getCurrentPeriodEndPay());
+                                     rebateIncentiveAdvPay.setRatio(ratioFc.apply(t.getCurrentPeriodEndPay(), baseInfo.getContractAmount().toPlainString()));
+                                     finish.set(true);
+                                     if (t.equals(curxj)) {
+                                         isCur.set(true);
+                                     }
+                                 });
+                                 InterimPayCertificateItem preSubTotal = previousMap.get("扣回动员预付款");
+                                 if (finish.get()&&isCur.get()) {
+                                     /*如果小计累计已经>=79,则全部扣回剩下的*/
+                                     rebateIncentiveAdvPay.setCurrentPay(subtractFc.apply(dyTotalAmount,preSubTotal.getCurrentPeriodEndPay()));
+                                     rebateIncentiveAdvPay.setRetained(rebateIncentiveAdvPay.getCurrentPay());
+                                 } else {
+                                     rebateIncentiveAdvPay.calc(baseInfo.getContractAmount().toPlainString(), dyTotalAmount);
+                                 }
+                                 if (preSubTotal != null) {
+                                     rebateIncentiveAdvPay.setEndPay(addFc.apply(rebateIncentiveAdvPay.getCurrentPay(), preSubTotal.getCurrentPeriodEndPay()));
+                                 } else {
+                                     rebateIncentiveAdvPay.setEndPay(rebateIncentiveAdvPay.getCurrentPay());
+                                 }
                              }
-                             /*当扣完动员预付款的时候,小计总额*/
-                             interimPayCertificateItemGroup.values().stream().flatMap(v->v.values().stream()).filter(e->"小计".equals(e.getChapterSeq())).sorted(Comparator.comparing(InterimPayCertificateItem::getCurrentPeriodEndPay)).filter(e->BaseUtils.str2BigDecimal(e.getCurrentPeriodEndPay()).compareTo(BaseUtils.str2BigDecimal(dyTotalAmount))>0).findFirst().ifPresent(t->{
-                                   rebateIncentiveAdvPay.setMeterAmount(t.getCurrentPeriodEndPay());
-                                   rebateIncentiveAdvPay.setRatio(ratioFc.apply(t.getCurrentPeriodEndPay(),baseInfo.getContractAmount().toPlainString()));
-                             });
+
                          }else if("扣回动员预付款".equals(certificate.getChapterSeq())){
                              certificate.setCurrentPeriodEndPay(rebateIncentiveAdvPay.getEndPay());
                              certificate.setCurrentPeriodPay(rebateIncentiveAdvPay.getCurrentPay());
@@ -1309,35 +1335,36 @@ public class ExecutorMeter extends FormulaExecutor {
             builderFormDatas(SubprojectInterimPaymentSummary.class);
             LinkedHashMap<String,Summary> endSummary = toSummary(paymentsPeriodEnd);
             LinkedHashMap<String,Summary> preSummary = toSummary(previous);
+            LinkedHashMap<String,Summary> curSummary = toSummary(current);
             List<SubprojectInterimPaymentSummary> totalList = new ArrayList<>();
-            List<String> numbers=  paymentsPeriodEnd.stream().map(Payment::getNumber).distinct().collect(Collectors.toList());
-            numbers.forEach(number->{
+           /* List<String> numbers=  paymentsPeriodEnd.stream().map(Payment::getNumber).distinct().collect(Collectors.toList());*/
+            LinkedHashMap<String,InventoryForm> numbersGroup=  tec.meterInfo.getInventoryForms().stream().filter(e->!tec.meterInfo.getChapter().contains(e)&&StringUtils.isNotEquals(0,e.getParentId())).collect(Collectors.toMap(InventoryForm::getFormNumber,e->e,(v1,v2)->v1,LinkedHashMap::new));
+            numbersGroup.forEach((number,itf)->{
+                SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
                 /*往期汇总*/
                 Summary pre =preSummary.get(number);
                 /*本期末汇总*/
                 Summary end = endSummary.get(number);
                 /*本期汇总*/
-                Summary cur = endSummary.get(number);
-                SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
-                sis.setFormNumber(end.getFormNumber());
-                sis.setItemName(end.getItemName());
-                sis.setUnit(end.getUnit());
-                sis.setContractTotal(end.getContractTotal().toString());
-                sis.setChangeTotal(end.getChangeTotal().toString());
-                sis.setContractMoney(end.getContractMoney().toString());
-                sis.setChangeMoney(end.getChangeMoney().toString());
-                sis.setPrice(end.getPrice());
-                if(cur!=null){
+                Summary cur = curSummary.get(number);
+                sis.setFormNumber(itf.getFormNumber());
+                sis.setItemName(itf.getFormName());
+                sis.setUnit(itf.getUnit());
+                sis.setContractTotal(StringUtils.handleNull(itf.getContractTotal()));
+                sis.setContractMoney(itf.getContractMoney());
+                sis.setChangeMoney(itf.getChangeMoney());
+                sis.setPrice(itf.getBidPrice());
+                if(cur!=null&&cur.getContractMoney()!=null) {
                     sis.setCurrentPeriodPay(cur.getMoney().toPlainString());
                     sis.setCurrentPeriodCompleted(cur.getCompleted().toString());
+                    if (pre != null) {
+                        sis.setPreviousPeriodPay(pre.getMoney().toString());
+                        sis.setPreviousPeriodCompleted(pre.getCompleted().toString());
+                    }
+                    sis.setCompleted(end.getCompleted().toString());
+                    sis.setCurrentPeriodEndPay(end.getMoney().toString());
+                    sis.setPayRatio(ratioFc.apply(sis.getCurrentPeriodEndPay(), sis.getChangeMoney()));
                 }
-                if(pre!=null){
-                    sis.setPreviousPeriodPay(pre.getMoney().toString());
-                    sis.setPreviousPeriodCompleted(pre.getCompleted().toString());
-                }
-                sis.setCompleted(end.getCompleted().toString());
-                sis.setCurrentPeriodEndPay(end.getMoney().toString());
-                sis.setPayRatio(ratioFc.apply(sis.getCurrentPeriodEndPay(),sis.getChangeMoney()));
                 totalList.add(sis);
             });
             totalList.forEach(e->{
@@ -1408,7 +1435,6 @@ public class ExecutorMeter extends FormulaExecutor {
 
         public void subtotal(SubprojectInterimPaymentSummary b,  List<SubprojectInterimPaymentSummary> result ,List<SubprojectInterimPaymentSummary> data,Integer scale){
             b.calculate(data,scale);
-
             result.add(b);
         }
 
@@ -2019,6 +2045,7 @@ public class ExecutorMeter extends FormulaExecutor {
                 tfd.setRepeat(true);
                 /*根据依赖获取输出目标元素*/
                 elementWriter.write(tfd,pageSum);
+                tec.periodInfo.setMeterNumber(StringUtils.handleNull(pageSum));
             });
 
         }