|
@@ -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{
|
|
|
/**是否满足执行条件*/
|