Ver Fonte

计量相关

yangyj há 1 ano atrás
pai
commit
48f786dc4c

+ 14 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InterimPaymentCertificate.java

@@ -3,6 +3,9 @@ package org.springblade.manager.vo;
 import com.alibaba.fastjson.annotation.JSONField;
 import lombok.Data;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
 /**
  * @author yangyj
  * @Date 2024/1/8 15:46
@@ -37,4 +40,15 @@ public class InterimPaymentCertificate {
     /**备注*/
     @JSONField(name = "key_8",label="备注",ordinal = 8)
     private String remark;
+    /**本次实际支付金额合计*/
+    @JSONField(name = "key_9",label="本次实际支付金额合计",ordinal = 9)
+    private String total;
+    public void calculate(){
+        BigDecimal previousPeriodEndPayBd = new BigDecimal(previousPeriodEndPay);
+        BigDecimal currentPeriodPayBd = new BigDecimal(currentPeriodPay);
+        BigDecimal currentPeriodEndPayBd = previousPeriodEndPayBd.add(currentPeriodPayBd);
+        this.currentPeriodEndPay = currentPeriodEndPayBd.toString();
+        BigDecimal payRatioBd = currentPeriodPayBd.multiply(new BigDecimal(100)).divide(currentPeriodEndPayBd, 2, RoundingMode.HALF_UP);
+        this.payRatio = payRatioBd.toString();
+    }
 }

+ 30 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InventoryForm.java

@@ -0,0 +1,30 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+/**
+ * @author yangyj
+ * @Date 2024/1/12 10:20
+ * @description 合同计量清单映射
+ */
+@Data
+public class InventoryForm {
+    private Long id;
+    /*父节点id*/
+    private Long parentId;
+    /*清单名称*/
+    private String formName;
+    /*清单编号*/
+    private String formNumber;
+    /*章节*/
+    private  String chapter;
+    /*中标价格*/
+    private  String bidPrice;
+    /*合同数量*/
+    private Integer contractTotal;
+    /*合同金额*/
+    private String contractMoney;
+    /*变更后的金额*/
+    private String changeMoney;
+
+}

+ 2 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/MeterPeriodInfo.java

@@ -35,5 +35,7 @@ public class MeterPeriodInfo {
     /**请款理由*/
     @JSONField(name = "key_5",label="请款理由",ordinal = 5)
     private String  cause;
+    /**排序号*/
+    private Integer sort;
 
 }

+ 32 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/Payment.java

@@ -0,0 +1,32 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author yangyj
+ * @Date 2024/1/11 14:33
+ * @description 支付数据的映射
+ */
+@Data
+public class Payment {
+    /*清单编号*/
+    private String number;
+    private String name;
+    private String money;
+    private String chapter;
+    private String contractMoney;
+    private Integer sort;
+    private Long periodId;
+
+    public BigDecimal getMoneyAsBigDecimal() {
+        try {
+            return new BigDecimal(getMoney());
+        } catch (NumberFormatException e) {
+            return BigDecimal.ZERO;
+        }
+    }
+
+
+}

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

@@ -2782,6 +2782,14 @@ public class CustomFunction {
         ( (List<Object>)stepSum(list)).forEach(System.out::println);
     }
 */
+     /*字符模版*/
+      public static Object strTemplate(String template,List<Object>data){
+          if(BaseUtils.isNotEmpty(template)) {
+              return data.stream().map(s -> template.replaceAll("\\{\\s*}", BaseUtils.handleNull(s))).collect(Collectors.toList());
+          }
+          return data;
+      }
+
 
 
 

+ 23 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -54,6 +54,7 @@ import org.springblade.manager.formula.impl.CompositeDataAccess;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.BaseInfo;
+import org.springblade.manager.vo.InterimPaymentCertificate;
 import org.springblade.manager.vo.WbsFormElementVO;
 import reactor.core.publisher.Mono;
 
@@ -389,6 +390,28 @@ public class FormulaUtils {
         return result;
     }
 
+    /*把结果数据回写到元素*/
+    public static<T>void  put2FormData( LinkedHashMap<String,FormData> fdm,Map<String,Function<List<T>,List<Object>>> functionMap,List<T> dataList){
+        fdm.values().stream()
+                .filter(fd -> functionMap.containsKey(fd.getCode()))
+                .forEach(fd -> {
+                    List<Object> raw = functionMap.get(fd.getCode()).apply(dataList);
+                    raw.stream().map(ElementData::new).forEach(fd.getValues()::add);
+                });
+    }
+
+
+    /*根据数据模型对象,生成数据集合按字段获取数据的函数*/
+    public static <T> Map<String, Function<List<T>, List<Object>>> fieldDataFcMap(Class<T> clazz) {
+        Map<String, Function<T, Object>> fieldMap = functionMapBuilder(clazz);
+        Map<String, Function<List<T>, List<Object>>> functionMap = new HashMap<>();
+        for (Map.Entry<String, Function<T, Object>> functionEntry : fieldMap.entrySet()) {
+            Function<List<T>, List<Object>> mapper = list -> list.stream().map(functionEntry.getValue()).collect(Collectors.toList());
+            functionMap.put(functionEntry.getKey(), mapper);
+        }
+        return functionMap;
+    }
+
 
     /*数据模型按字段生成内容获取函数*/
     public static <T> Map<String,Function<T,Object>> functionMapBuilder(Class<T> clazz){

+ 4 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorInit.java

@@ -22,19 +22,19 @@ public class ExecutorInit extends FormulaExecutor {
     public ExecutorInit(TableElementConverter tec) {
         super(tec);
     }
-    private  Function<Long, BaseInfo> getBaseInfo;
-    private  Function<Long, MeterPeriodInfo>  getMeterPeriod;
+    private  Function<Long, BaseInfo> baseInfoFc;
+    private  Function<Long, MeterPeriodInfo>  meterPeriodFc;
 
 
     public void handle() {
 
         /*加载合同数据*/
-        BaseInfo baseInfo = this.getBaseInfo.apply(tec.getContractId());
+        BaseInfo baseInfo = baseInfoFc.apply(tec.getContractId());
         tec.getConstantMap().put(BaseInfo.TBN,baseInfo);
         tec.formDataMap.putAll(FormulaUtils.toFormDataMap(baseInfo));
         if(MeterType.MATERIAL.equals(tec.getMeterType())||MeterType.START.equals(tec.getMeterType())){
             /*加载计量期信息*/
-            MeterPeriodInfo meterPeriod=getMeterPeriod.apply(tec.getPeriodId());
+            MeterPeriodInfo meterPeriod=meterPeriodFc.apply(tec.getPeriodId());
             tec.formDataMap.putAll(FormulaUtils.toFormDataMap(meterPeriod));
             tec.getConstantMap().put(MeterPeriodInfo.TBN,meterPeriod);
         }else if(MeterType.INTERIM.equals(tec.getMeterType())){

+ 94 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSpecial.java

@@ -1,24 +1,18 @@
 package org.springblade.manager.formula.impl;
 
-import com.alibaba.fastjson.annotation.JSONField;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
-import io.swagger.models.auth.In;
 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.ReflectUtil;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.formula.FormulaExecutor;
-import org.springblade.manager.formula.NodeTable;
-import org.springblade.manager.vo.BaseInfo;
-import org.springblade.manager.vo.InterimPaymentCertificate;
-import org.springblade.manager.vo.Material;
-import org.springblade.manager.vo.MeterType;
+import org.springblade.manager.vo.*;
 
-import java.lang.reflect.Field;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -32,7 +26,10 @@ import java.util.stream.IntStream;
 @EqualsAndHashCode(callSuper = true)
 @Data
 public class ExecutorSpecial extends FormulaExecutor {
-    private Function<Long, List<Material>> materialListFc;
+    private Function<Long, List<Material>> materialFormFc;
+    private Function<Long, MeterPeriodInfo> interimMeterPeriodFc;
+    private Function<Long, List<Payment>> paymentListFc;
+    private Function<Long, List<InventoryForm>> inventoryFormFc;
     public ExecutorSpecial(TableElementConverter tec) {
         super(tec);
     }
@@ -145,7 +142,7 @@ public class ExecutorSpecial extends FormulaExecutor {
             /*加载合同材料、材料清单*/
             /* b.material_name name,b.unit,b.price,a.meter_amount amount,a.material_source source
             ,material_conform  materialConform,a.storage_place storagePlace,a.storage_status storageStatus,a.storage_conform storageConform,a.remark*/
-            List<Material> materials = materialListFc.apply(tec.getPeriodId());
+            List<Material> materials = materialFormFc.apply(tec.getPeriodId());
             if(Func.isNotEmpty(materials)){
                 BaseInfo baseInfo= (BaseInfo) tec.getConstantMap().get(BaseInfo.TBN);
                 int n=1;
@@ -190,6 +187,7 @@ public class ExecutorSpecial extends FormulaExecutor {
 
     @Data
     public  class InterimPayCert implements Special{
+        private List<InventoryForm> chapters = new ArrayList<>();
 
         @Override
         public boolean ready() {
@@ -197,27 +195,100 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
 
 
+
+        private Function<List<InventoryForm>, Map<String, BigDecimal[]>> contractMoneySum = data -> data.stream()
+                .collect(Collectors.groupingBy(
+                        form -> getPrefix(form.getFormNumber()),
+                        Collectors.reducing(
+                                new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO},
+                                form -> new BigDecimal[]{
+                                        form.getContractMoney() != null ? new BigDecimal(form.getContractMoney()) : BigDecimal.ZERO,
+                                        form.getChangeMoney() != null ? new BigDecimal(form.getChangeMoney()) : BigDecimal.ZERO
+                                },
+                                (total1, total2) -> new BigDecimal[]{total1[0].add(total2[0]), total1[1].add(total2[1])}
+                        )
+                ));
+
+       private  Function<List<Payment>, Map<String, BigDecimal>> moneySum= data-> data.stream()
+                .collect(Collectors.groupingBy(
+                        payment -> getPrefix(payment.getNumber()),
+                        LinkedHashMap::new,
+                        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() {
             LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new InterimPaymentCertificate());
-            Map<String,Function<InterimPaymentCertificate,Object>> functionMap = FormulaUtils.functionMapBuilder(InterimPaymentCertificate.class);
             tec.getFormDataMap().putAll(fdm);
+
+            Map<String,Function<List<InterimPaymentCertificate>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(InterimPaymentCertificate.class);
+
             List<InterimPaymentCertificate> dataList = new ArrayList<>();
             /*数据获取start*/
-            dataList.add(new InterimPaymentCertificate()) ;//测试,按照业务写,实际会复杂许多
-            //TODO
-            /*数据获取end*/
-            fdm.values().forEach(fd->{
-                List<Object> raw = dataList.stream().map(functionMap.get(fd.getCode())).filter(Func::isNotEmpty).collect(Collectors.toList());
-                if(raw.size()>0){
-                    List<ElementData> eds = fd.getValues();
-                    for(Object value:raw){
-                        eds.add(new ElementData(value));
-                    }
+              /*支付数据*/
+             List<Payment> paymentList=paymentListFc.apply(tec.getContractId());
+             /*计量期*/
+             MeterPeriodInfo periodInfo=interimMeterPeriodFc.apply(tec.getPeriodId());
+             /*合同计量清单*/
+             List<InventoryForm> inventoryForms = inventoryFormFc.apply(tec.getContractId());
+             InventoryForm root = null;
+             for(InventoryForm itf:inventoryForms){
+                 if(itf.getParentId()==0){
+                     root = itf;
+                     break;
+                 }
+             }
+            for(InventoryForm itf:inventoryForms){
+                assert root != null;
+                if(itf.getParentId().equals(root.getParentId())){
+                    chapters.add(itf);
                 }
-            });
+            }
+
+             if(Func.isNotEmpty(paymentList)){
+                 /*之前的计量期数据*/
+                 List<Payment>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());
+                 /*往期每章节的实际花费*/
+                 Map<String,BigDecimal> previousMoney= this.moneySum.apply(previous);
+                 /*当前计量期每章节的实际花费*/
+                 Map<String,BigDecimal> currentMoney= this.moneySum.apply(current);
+                /*合同金额*/
+                 Map<String,BigDecimal[]> contractMoney = this.contractMoneySum.apply(inventoryForms);
+                 for(Map.Entry<String,BigDecimal[]> cm:contractMoney.entrySet()){
+                      InterimPaymentCertificate ipc = new InterimPaymentCertificate();
+                      BigDecimal[]  bmMoney =cm.getValue();
+                      ipc.setContractAmount(bmMoney[0].toString());
+                      ipc.setRevisedAmount(bmMoney[1].toString());
+                      ipc.setPreviousPeriodEndPay(previousMoney.getOrDefault(cm.getKey(),BigDecimal.ZERO).toString());
+                      ipc.setCurrentPeriodPay(currentMoney.getOrDefault(cm.getKey(),BigDecimal.ZERO).toString());
+                      /*由已知求未知*/
+                      ipc.calculate();
+                      dataList.add(ipc);
+                 }
+             }
+            /*数据获取end*/
+            /*本期实际支付合计计算*/
+            functionMap.put(InterimPaymentCertificate.TBN+ StringPool.COLON+"key_9",(List<InterimPaymentCertificate> list)-> Collections.singletonList(list.stream().map(InterimPaymentCertificate::getCurrentPeriodPay).mapToDouble(Double::parseDouble).sum()));
+            /*内容输出*/
+            FormulaUtils.put2FormData(fdm,functionMap,dataList);
 
         }
+
+
     }
 
 

+ 15 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaDao.java

@@ -1,8 +1,8 @@
 package org.springblade.manager.service;
 
-import org.springblade.manager.vo.BaseInfo;
-import org.springblade.manager.vo.Material;
-import org.springblade.manager.vo.MeterPeriodInfo;
+import lombok.Data;
+import org.springblade.manager.vo.*;
+import org.springframework.beans.BeanUtils;
 
 import java.util.List;
 import java.util.Map;
@@ -10,9 +10,17 @@ import java.util.function.Function;
 
 public interface IFormulaDao {
     /**获取项目合同基础信息*/
-    Function<Long, BaseInfo> getBaseInfo();
-    /**获取计量段信息*/
-    Function<Long, MeterPeriodInfo> getMeterPeriod();
+    Function<Long, BaseInfo> getBaseInfoFc();
+    /**获取开工材料计量期*/
+    Function<Long, MeterPeriodInfo> getMeterPeriodFc();
     /**获取清单信息*/
-    Function<Long, List<Material>> getMaterialForm();
+    Function<Long, List<Material>> getMaterialFormFc();
+
+    /**获取中间计量期*/
+    Function<Long, MeterPeriodInfo> getInterimMeterPeriodFc();
+    /**获取支付数据*/
+    Function<Long, List<Payment>> getPaymentListFc();
+    /*获取合同计量清单*/
+    Function<Long,List<InventoryForm>> getInventoryFormFc();
+
 }

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

@@ -6,12 +6,11 @@ import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ProjectInfo;
+import org.springblade.manager.entity.TrialSelfDataRecord;
 import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.IFormulaDao;
 import org.springblade.manager.service.IProjectInfoService;
-import org.springblade.manager.vo.BaseInfo;
-import org.springblade.manager.vo.Material;
-import org.springblade.manager.vo.MeterPeriodInfo;
+import org.springblade.manager.vo.*;
 import org.springframework.beans.BeanUtils;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -36,7 +35,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     private final IProjectInfoService projectInfoService;
     private final JdbcTemplate jdbcTemplate;
     @Override
-    public Function<Long, BaseInfo> getBaseInfo() {
+    public Function<Long, BaseInfo> getBaseInfoFc() {
         return contractId->{
             ContractInfo info=  this.contractInfoService.getById(contractId);
             ProjectInfo projectInfo= projectInfoService.getById(info.getPId());
@@ -48,7 +47,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     }
 
     @Override
-    public Function<Long,MeterPeriodInfo> getMeterPeriod(){
+    public Function<Long,MeterPeriodInfo> getMeterPeriodFc(){
         return id-> {
            List<MeterPeriodInfo> beans = this.jdbcTemplate.query("select b.period_number periodNumber,b.period_name periodName,a.print_date formPrintDate ,a.repayment_cause cause from s_material_start_statement a join  s_meter_period b on a.meter_period_id=b.id where a.id="+id, new BeanPropertyRowMapper<>(MeterPeriodInfo.class));
             if(beans.size()>0){
@@ -67,7 +66,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     }
 
     @Override
-    public Function<Long, List<Material>> getMaterialForm() {
+    public Function<Long, List<Material>> getMaterialFormFc() {
         return id->{
             List<Map<String,Object>> mapList = this.jdbcTemplate.queryForList("select  b.material_name name,b.unit,b.price,a.meter_amount amount,meter_money sum,a.material_source source,material_conform  materialConform,a.storage_place storagePlace,a.storage_status storageStatus,a.storage_conform storageConform,a.remark from s_material_meter_form a left join s_contract_material b on a.contract_material_id = b.id where a.meter_period_id="+id+"  and a.is_deleted=0");
             if(Func.isNotEmpty(mapList)){
@@ -76,4 +75,36 @@ public class FormulaDaoImpl implements IFormulaDao {
             return Collections.emptyList();
         };
     }
+
+
+
+    @Override
+    public Function<Long, MeterPeriodInfo> getInterimMeterPeriodFc() {
+        return  id->{
+            String sql="SELECT period_number name,sort from s_contract_meter_period where id ="+id;
+            return this.jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(MeterPeriodInfo.class));
+        };
+    }
+
+    @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;
+            return this.jdbcTemplate.query(paySql,new BeanPropertyRowMapper<>(Payment.class));
+        };
+    }
+
+    @Override
+    public Function<Long, List<InventoryForm>> getInventoryFormFc() {
+        return  contractId->{
+           String sql="select form_name,chapter_number,bid_price,contract_total,form_number,contract_money,change_money from  s_contract_inventory_form where   is_deleted=0  and contract_id="+contractId;
+           return getEntityList(sql,InventoryForm.class);
+        };
+    }
+
+    public <T> List<T> getEntityList(String sql, Class<T> entityClass) {
+        return  jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(entityClass));
+    }
+
+
 }

+ 5 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -2555,14 +2555,16 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<FormulaHandleChain> formulaHandleChains = new ArrayList<>();
         /*初始化*/
         ExecutorInit init= new ExecutorInit(tec);
-        init.setGetBaseInfo(this.formulaDao.getBaseInfo());
-        init.setGetMeterPeriod(this.formulaDao.getMeterPeriod());
+        init.setBaseInfoFc(this.formulaDao.getBaseInfoFc());
+        init.setMeterPeriodFc(this.formulaDao.getMeterPeriodFc());
         formulaHandleChains.add(init);
         formulaHandleChains.add(new ExecutorSort(tec));
         formulaHandleChains.add(new ExecutorPre(tec));
         /*特殊公式*/
         ExecutorSpecial special = new ExecutorSpecial(tec);
-        special.setMaterialListFc(this.formulaDao.getMaterialForm());
+        special.setMaterialFormFc(this.formulaDao.getMaterialFormFc());
+        special.setInterimMeterPeriodFc(this.formulaDao.getInterimMeterPeriodFc());
+        special.setPaymentListFc(this.formulaDao.getPaymentListFc());
         formulaHandleChains.add(special);
         /*通用计算*/
         formulaHandleChains.add(new ExecutorCalc(tec));