瀏覽代碼

计量公式

yangyj 1 年之前
父節點
當前提交
5692706eab

+ 2 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -275,4 +275,6 @@ public class FormData {
     }
 
 
+
+
 }

+ 18 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/Payment.java

@@ -11,15 +11,32 @@ import java.math.BigDecimal;
  */
 @Data
 public class Payment {
-    /*清单编号*/
+    /**清单编号*/
     private String number;
+    /**清单名称*/
     private String name;
+    /**单位*/
+    private String unit;
+    /*合同数量*/
+    private Integer contractTotal;
+    /*变更数量*/
+    private Integer changeTotal;
+    /**完成数量*/
+    private Integer completed;
+    /**消费金额*/
     private String money;
+    /**章节*/
     private String chapter;
+    /**合同金额*/
     private String contractMoney;
+    /**变更金额*/
+    private String changeMoney;
+    /**排序*/
     private Integer sort;
+    /**中间计量期*/
     private Long periodId;
 
+
     public BigDecimal getMoneyAsBigDecimal() {
         try {
             return new BigDecimal(getMoney());
@@ -28,5 +45,4 @@ public class Payment {
         }
     }
 
-
 }

+ 50 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/SubInterimMeterPaySummary.java

@@ -0,0 +1,50 @@
+package org.springblade.manager.vo;
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * @author yangyj
+ * @Date 2024/1/16 16:58
+ * @description 分项工程中期计量支付表
+ */
+public class SubInterimMeterPaySummary {
+    public static final String ID="20250000000";
+    public static final String TBN="SubIMeterPaySum";
+    public static final String TBN_CH="分项工程中期计量支付表";
+    /**支付编号*/
+    @JSONField(name = "key_0",label="支付编号")
+    private String formNumber;
+    /**项目名称*/
+    @JSONField(name = "key_1",label="项目名称/工程位置",ordinal = 1)
+    private String itemName;
+    /**计量单位*/
+    @JSONField(name = "key_2",label="计量单位",ordinal = 2)
+    private String unit;
+    /**合同数量*/
+    @JSONField(name = "key_3",label="合同数量",ordinal = 3)
+    private String contractTotal;
+    /**变更数量*/
+    @JSONField(name = "key_4",label="变更数量",ordinal = 4)
+    private String revisedTotal;
+    /**本次完成数量*/
+    @JSONField(name = "key_5",label="本次完成数量",ordinal = 5)
+    private String currentPeriodComplete;
+    /**累计完成数量*/
+    @JSONField(name = "key_6",label="累计完成数量",ordinal = 6)
+    private String complete;
+    /**合同金额*/
+    @JSONField(name = "key_7",label="合同金额",ordinal = 7)
+    private String contractAmount;
+    /**变更后A金额*/
+    @JSONField(name = "key_8",label="变更金额",ordinal = 8)
+    private String revisedAmount;
+    /**上次支付金额*/
+    @JSONField(name = "key_9",label="本次支付金额",ordinal = 9)
+    private String currentPeriodPay;
+    /**累计支付B金额*/
+    @JSONField(name = "key_10",label="累计支付金额",ordinal = 10)
+    private String currentPeriodEndPay;
+    /**比例*/
+    @JSONField(name = "key_11",label="变更令号",ordinal = 11)
+    private String changeTokenId;
+}

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

@@ -1,16 +1,28 @@
 package org.springblade.manager.vo;
 
 import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
 
 /**
  * @author yangyj
  * @Date 2024/1/13 17:28
  * @description 分项工程中期支付汇总表
  */
+@Data
 public class SubprojectInterimPaymentSummary {
     public static final String ID="20230000000";
     public static final String TBN="SubIPaySum";
     public static final String TBN_CH="分项工程中期支付汇总表";
+    /**支付编号*/
+    @JSONField(name = "key_0",label="支付编号")
+    private String formNumber;
     /**项目名称*/
     @JSONField(name = "key_1",label="项目名称",ordinal = 1)
     private String itemName;
@@ -36,8 +48,8 @@ public class SubprojectInterimPaymentSummary {
     @JSONField(name = "key_8",label="变更后A金额",ordinal = 8)
     private String revisedAmount;
     /**上次支付金额*/
-    @JSONField(name = "key_9",label="次支付金额",ordinal = 9)
-    private String previousPeriodEndPay;
+    @JSONField(name = "key_9",label="次支付金额",ordinal = 9)
+    private String currentPeriodPay;
     /**累计支付B金额*/
     @JSONField(name = "key_10",label="累计支付B金额",ordinal = 10)
     private String currentPeriodEndPay;
@@ -45,4 +57,32 @@ public class SubprojectInterimPaymentSummary {
     @JSONField(name = "key_11",label="比例",ordinal = 11)
     private String payRatio;
 
+    public SubprojectInterimPaymentSummary(String itemName) {
+        this.itemName = itemName;
+        this.currentPeriodPay = "0.0";
+        this.currentPeriodEndPay = "0.0";
+    }
+
+    public SubprojectInterimPaymentSummary(String itemName, String currentPeriodPay, String currentPeriodEndPay) {
+        this.itemName = itemName;
+        this.currentPeriodPay = currentPeriodPay;
+        this.currentPeriodEndPay = currentPeriodEndPay;
+    }
+
+    public SubprojectInterimPaymentSummary() {
+    }
+
+    public void count( @NotNull Consumer<String> setting ,@NotNull  List<SubprojectInterimPaymentSummary> data, @NotNull  Function<SubprojectInterimPaymentSummary,String> fc){
+        setting.accept(data.stream().map(e->new BigDecimal(fc.apply(e))).reduce(BigDecimal.ZERO,BigDecimal::add).setScale(1, RoundingMode.HALF_UP).toString());
+    }
+
+
+    public void calculate(List<SubprojectInterimPaymentSummary> data){
+        if(data!=null&&data.size()>0){
+            /*本次支付*/
+            count(this::setCurrentPeriodPay,data,SubprojectInterimPaymentSummary::getCurrentPeriodPay);
+            /*本次累计支付*/
+            count(this::setCurrentPeriodEndPay,data,SubprojectInterimPaymentSummary::getCurrentPeriodEndPay);
+        }
+    }
 }

+ 210 - 30
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSpecial.java

@@ -4,6 +4,7 @@ import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.ElementData;
@@ -15,6 +16,7 @@ import org.springframework.beans.BeanUtils;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.BiFunction;
 import java.util.function.BinaryOperator;
 import java.util.function.Function;
@@ -36,9 +38,41 @@ public class ExecutorSpecial extends FormulaExecutor {
     public ExecutorSpecial(TableElementConverter tec) {
         super(tec);
     }
+    /**章节*/
+    private List<InventoryForm> chapters = new ArrayList<>();
     private List<Special> specialList = new ArrayList<>();
-    private List<Payment>  dataSource=new ArrayList<>();
+    private List<Payment>  previous =new ArrayList<>();
+    private List<Payment>   current =new ArrayList<>();
+    /**计量期*/
+    private  MeterPeriodInfo periodInfo;
     private List<InterimPaymentCertificate> interimPaymentCertificates =new ArrayList<>();
+    /*求百分比*/
+    BinaryOperator<String> ratioFc = (a,b)->{
+        /*合同金额*/
+        BigDecimal aBd =new BigDecimal(a);
+        /*变更金额*/
+        BigDecimal bBd =new BigDecimal(b);
+        if(BigDecimal.ZERO.compareTo(bBd)==0){
+            return "0.0";
+        }
+        return  aBd.multiply(new BigDecimal(100)).divide(bBd, 2, RoundingMode.HALF_UP).toString();
+    };
+
+    public String getPrefix(String fn){
+        for(InventoryForm itf:chapters){
+            String prefix=itf.getChapter();
+            fn= fn.split("-")[0];
+            if(BaseUtils.isNumber(fn)){
+                fn=String.valueOf(100*Integer.parseInt(fn)/100);
+            }
+            if(fn.equals(prefix)){
+                return prefix;
+            }
+        }
+        return fn;
+    }
+
+   public Function<String,String> preFixFc= this::getPrefix;
 
     @Override
     public void handle() {
@@ -193,7 +227,6 @@ public class ExecutorSpecial extends FormulaExecutor {
 
     @Data
     public  class InterimPayCert implements Special{
-        private List<InventoryForm> chapters = new ArrayList<>();
 
         @Override
         public boolean ready() {
@@ -220,15 +253,7 @@ public class ExecutorSpecial extends FormulaExecutor {
                         Collectors.reducing(BigDecimal.ZERO, Payment::getMoneyAsBigDecimal, BigDecimal::add)
                 ));
 
-        public String getPrefix(String fn){
-            for(InventoryForm itf:this.chapters){
-                String prefix=itf.getChapter();
-                if(fn.startsWith(prefix)){
-                    return prefix;
-                }
-            }
-            return fn;
-        }
+
 
         @Override
         public void parse() {
@@ -240,11 +265,8 @@ public class ExecutorSpecial extends FormulaExecutor {
             /*数据获取start*/
               /*支付数据*/
              List<Payment> paymentList=paymentListFc.apply(tec.getContractId());
-             if(!paymentList.isEmpty()){
-                 dataSource.addAll(paymentList);
-             }
              /*计量期*/
-             MeterPeriodInfo periodInfo=interimMeterPeriodFc.apply(tec.getPeriodId());
+              periodInfo=interimMeterPeriodFc.apply(tec.getPeriodId());
              /*合同计量清单*/
              List<InventoryForm> inventoryForms = inventoryFormFc.apply(tec.getContractId());
              InventoryForm root = null;
@@ -263,9 +285,9 @@ public class ExecutorSpecial extends FormulaExecutor {
 
              if(Func.isNotEmpty(paymentList)){
                  /*之前的计量期数据*/
-                 List<Payment>previous = paymentList.stream().filter(e->e.getSort()<periodInfo.getSort()).collect(Collectors.toList());
+                 previous = paymentList.stream().filter(e->e.getSort()<periodInfo.getSort()).collect(Collectors.toList());
                  /*当前计量期数据*/
-                 List<Payment>current = paymentList.stream().filter(e-> e.getSort().equals(periodInfo.getSort())).collect(Collectors.toList());
+                 current = paymentList.stream().filter(e-> e.getSort().equals(periodInfo.getSort())).collect(Collectors.toList());
                  /*往期每章节的实际花费*/
                  Map<String,BigDecimal> previousMoney= this.moneySum.apply(previous);
                  /*当前计量期每章节的实际花费*/
@@ -304,17 +326,7 @@ public class ExecutorSpecial extends FormulaExecutor {
         /*合计字段*/
         BiFunction<List<InterimPaymentSummary>,Function<InterimPaymentSummary,String>,String>
                 bfc= (list,fc) -> StringUtils.number2String(list.stream().map(fc).mapToDouble(Double::parseDouble).sum(),1);
-        /*求百分比*/
-        BinaryOperator<String> ratioFc = (a,b)->{
-            /*合同金额*/
-            BigDecimal aBd =new BigDecimal(a);
-            /*变更金额*/
-            BigDecimal bBd =new BigDecimal(b);
-            if(BigDecimal.ZERO.compareTo(bBd)==0){
-                return "0.0";
-            }
-            return  aBd.multiply(new BigDecimal(100)).divide(bBd, 2, RoundingMode.HALF_UP).toString();
-        };
+
 
         @Override
         public void parse() {
@@ -345,20 +357,188 @@ public class ExecutorSpecial extends FormulaExecutor {
             }
         }
     }
+
+
+
+
     @Data
     public  class SubIPaySum implements Special{
+         private Integer capacity=10;
+
         @Override
         public boolean ready() {
-            return dataSource.size()>0;
+            return current.size()>0;
         }
 
+        @Data
+        class Summary{
+            /*清单编号、支付编号*/
+            private String  formNumber;
+            /*清单名称*/
+            private String itemName;
+            /**计量单位*/
+            private String unit;
+            /**合同数量*/
+            private Integer contractTotal=0;
+            /**变更数量*/
+            private Integer revisedTotal=0;
+            /**本次完成数量*/
+            private Integer currentPeriodComplete=0;
+            /**累计完成数量*/
+            private Integer completed=0;
+            /**合同金额*/
+            private BigDecimal contractAmount=BigDecimal.ZERO;
+            /**变更后A金额*/
+            private BigDecimal revisedAmount=BigDecimal.ZERO;
+            /**上次支付金额*/
+            private BigDecimal previousPeriodEndPay=BigDecimal.ZERO;
+            /**累计支付B金额*/
+            private BigDecimal currentPeriodEndPay=BigDecimal.ZERO;
+            /**比例*/
+            private BigDecimal payRatio=BigDecimal.ZERO;
+
+            public Summary() {
+            }
+
+            public Summary(Payment p) {
+                    this.formNumber=p.getNumber();
+                    this.itemName=p.getName();
+                    this.unit = p.getUnit();
+                    this.contractTotal=p.getContractTotal();
+                    this.revisedTotal= p.getChangeTotal();
+                    this.completed=p.getCompleted();
+                    this.contractAmount=new BigDecimal(p.getContractMoney());
+                    this.revisedAmount=new BigDecimal(p.getChangeMoney());
+                    this.currentPeriodEndPay=p.getMoneyAsBigDecimal();
+            }
+            public Summary add(Summary next){
+                if(Func.isBlank(this.itemName)){
+                    this.itemName=next.itemName;
+                }
+                this.completed=next.getCompleted()+this.completed;;
+                this.currentPeriodEndPay=this.previousPeriodEndPay.add(next.getPreviousPeriodEndPay());
+                return this;
+            }
+        }
+
+
+        /*按清单编号求和*/
+        public  Map<String,Summary> toSummary(List<Payment> payments) {
+            return payments.stream()
+                    .collect(  Collectors.groupingBy(Payment::getNumber,
+                            Collectors.reducing(new Summary(),
+                                    Summary::new,
+                                    Summary::add
+                            )));
+
+        }
+
+
+
         @Override
         public void parse() {
-
+            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new SubprojectInterimPaymentSummary());
+            Map<String,Function<List<SubprojectInterimPaymentSummary>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(SubprojectInterimPaymentSummary.class);
+            tec.getFormDataMap().putAll(fdm);
+            Map<String,Summary> currentSummary = toSummary(current);
+            Map<String,Summary> preSummary = toSummary(previous);
+            List<SubprojectInterimPaymentSummary> dataList = new ArrayList<>();
+            for(Map.Entry<String,Summary> form:currentSummary.entrySet()){
+                SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
+                Summary pre =preSummary.get(form.getKey());
+                Summary summary = form.getValue();
+                sis.setFormNumber(summary.getFormNumber());
+                sis.setItemName(summary.getItemName());
+                sis.setUnit(summary.getUnit());
+                sis.setContractTotal(summary.getContractTotal().toString());
+                sis.setRevisedTotal(summary.getRevisedTotal().toString());
+                sis.setComplete(summary.getCompleted().toString());
+                sis.setContractAmount(summary.getContractAmount().toString());
+                sis.setRevisedAmount(summary.getRevisedAmount().toString());
+                if(pre!=null){
+                    sis.setCurrentPeriodPay(pre.getCurrentPeriodEndPay().toString());
+                    summary.add(pre);
+                    sis.setCurrentPeriodEndPay(summary.getCurrentPeriodEndPay().toString());
+                    sis.setPayRatio(ratioFc.apply(sis.getCurrentPeriodEndPay(),sis.getRevisedAmount()));
+                }
+                dataList.add(sis);
+            }
+            List<String> codeFind = new ArrayList<>(fdm.keySet());
+            /*获取实际输出行数*/
+            Optional<FormData> formDataOp=  tec.getFormDataList().stream().filter(e-> BaseUtils.inChain(codeFind,e.getCode())).findAny();
+            List<SubprojectInterimPaymentSummary> outPutList= new ArrayList<>();
+            if(formDataOp.isPresent()){
+                  FormData target = formDataOp.get();
+                  capacity=target.getCoordsList().size();
+            }
+            LinkedHashMap<String,List<SubprojectInterimPaymentSummary>> chapterGroup= dataList.stream().collect(Collectors.groupingBy(e->getPrefix(e.getFormNumber()),LinkedHashMap::new,Collectors.toList()));
+            AtomicInteger loop = new AtomicInteger(chapterGroup.size());
+            chapterGroup.forEach((k,v)->{
+                int extra=loop.getAndDecrement()>0?1:2;
+                /*每章小结或总结等价一行数据*/
+                int dataLength=v.size()+extra;
+                /*每页小结是固定内容,需要每页保留一行*/
+                int dataAreaSize=capacity-1;
+                int pageSize=(int)Math.ceil(dataLength/(double)dataAreaSize);
+                /*总长度*/
+                int total = pageSize*capacity;
+                List<List<SubprojectInterimPaymentSummary>> ds = BaseUtils.splitList(v,capacity-1);
+                List<SubprojectInterimPaymentSummary> tmp = new ArrayList<>();
+                for(int n=0;n<pageSize;n++){
+                    List<SubprojectInterimPaymentSummary> currentPageData =null;
+                    if(ds.size()>n){
+                        currentPageData=ds.get(n);
+                        tmp.addAll(currentPageData);
+                    }
+                    int m=1;
+                    if(pageSize-n==1){
+                        m+=extra;
+                    }
+                    int placeholderSize = capacity-m;
+                    if(placeholderSize>0){
+                        tmp.addAll(Collections.nCopies(placeholderSize,new SubprojectInterimPaymentSummary()));
+                    }
+                    SubprojectInterimPaymentSummary last = new SubprojectInterimPaymentSummary("本页小计");
+                    last.calculate(currentPageData);
+                    tmp.add(last);
+                    if(m>1) {
+                        /*本章小结*/
+                        SubprojectInterimPaymentSummary lastA = new SubprojectInterimPaymentSummary();
+                        lastA.calculate(v);
+                        tmp.add(lastA);
+                    }
+                    if(m>2){
+                        /*所有章合计*/
+                        SubprojectInterimPaymentSummary lastB = new SubprojectInterimPaymentSummary();
+                        lastB.calculate(dataList);
+                        tmp.add(lastB);
+                    }
+                    outPutList.addAll(tmp);
+                    tmp.clear();
+                }
+            });
+            /*内容输出*/
+            FormulaUtils.put2FormData(fdm,functionMap,outPutList);
         }
+
+
+
     }
 
 
+    @Data
+    public class SubIMeterPay implements Special{
+
+        @Override
+        public boolean ready() {
+            return current.size()>0;
+        }
+
+        @Override
+        public void parse() {
+
+        }
+    }
 
     public interface  Special{
         /**是否满足执行条件*/

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDaoImpl.java

@@ -89,7 +89,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     @Override
     public Function<Long, List<Payment>> getPaymentListFc() {
         return contractId->{
-            String paySql="select a.form_number number,a.form_name name ,current_meter_money money,b.chapter_number chapter,b.contract_money contractMoney,c.sort,c.id periodId from s_inventory_form_apply a join s_contract_inventory_form b on a.contract_form_id=b.id join s_contract_meter_period c on a.contract_period_id=c.id where a.is_deleted=0 and a.approve_status=2 and a.contract_id="+contractId;
+            String paySql="select a.form_number number,a.form_name name ,a.current_meter_total completed ,current_meter_money money ,b.chapter_number chapter, b.contract_money contractMoney,b.change_money,b.unit,contract_total ,change_total,c.sort,c.id periodId from s_inventory_form_apply a join s_contract_inventory_form b on a.contract_form_id=b.id join s_contract_meter_period c on a.contract_period_id=c.id where a.is_deleted=0 and a.approve_status=2 and a.contract_id="+contractId;
             return this.jdbcTemplate.query(paySql,new BeanPropertyRowMapper<>(Payment.class));
         };
     }