|
@@ -26,6 +26,7 @@ import org.springframework.beans.BeanUtils;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
@@ -45,7 +46,7 @@ import java.util.stream.IntStream;
|
|
|
public class ExecutorMeter extends FormulaExecutor {
|
|
|
private Function<Long, List<MeterApply>> meterApplyFc;
|
|
|
private Function<Long, List<StartPayForm>> stayPayFormFc;
|
|
|
- private BiFunction<String,String, List<ChapterSchedule>> chapterScheduleFc;
|
|
|
+ private Function<String, List<ChapterSchedule>> chapterScheduleFc;
|
|
|
|
|
|
private ElementWriter elementWriter;
|
|
|
/**执行链*/
|
|
@@ -1011,7 +1012,7 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
payItemZj.add(new InterimPaymentCertificate("扣回材料设备垫付款"));
|
|
|
blj=new InterimPaymentCertificate("保留金",MINUS_ONE);
|
|
|
payItemZj.add(blj);
|
|
|
- InterimPaymentCertificate thblj=new InterimPaymentCertificate("退还保留金");
|
|
|
+ InterimPaymentCertificate thblj=new InterimPaymentCertificate("返回保留金");
|
|
|
thblj.setNoApply(1);
|
|
|
payItemZj.add(thblj);
|
|
|
InterimPaymentCertificate sjzf=new InterimPaymentCertificate("实际支付",true);
|
|
@@ -1040,6 +1041,7 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
RebateIncentiveAdvPay rebateIncentiveAdvPay = new RebateIncentiveAdvPay();
|
|
|
for (InterimPaymentCertificate certificate : dataList) {
|
|
|
InterimPayCertificateItem ic= currentMap.getOrDefault(payItemZj.contains(certificate)?certificate.getChapterSeq():certificate.getFormName(),new InterimPayCertificateItem());
|
|
|
+ InterimPayCertificateItem icPre= previousMap.getOrDefault(payItemZj.contains(certificate)?certificate.getChapterSeq():certificate.getFormName(),new InterimPayCertificateItem());
|
|
|
if("小计".equals(certificate.getChapterSeq())){
|
|
|
/*本期扣回动员预付款*/
|
|
|
BaseInfo baseInfo = tec.meterInfo.getBaseInfo();
|
|
@@ -1087,8 +1089,12 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
certificate.setCurrentPeriodEndPay(rebateIncentiveAdvPay.getEndPay());
|
|
|
certificate.setCurrentPeriodPay(rebateIncentiveAdvPay.getCurrentPay());
|
|
|
certificate.setPreviousPeriodEndPay(rebateIncentiveAdvPay.getPreviousPay());
|
|
|
- }else if("退还保留金".equals(certificate.getChapterSeq())){
|
|
|
+ }else if("返回保留金".equals(certificate.getChapterSeq())){
|
|
|
certificate.setCurrentPeriodPay(ic.getCurrentPeriodPay());
|
|
|
+ ic.setPreviousPeriodEndPay(icPre.getCurrentPeriodEndPay());
|
|
|
+ ic.setCurrentPeriodEndPay(addFc.apply(ic.getCurrentPeriodPay(),ic.getPreviousPeriodEndPay()));
|
|
|
+ certificate.setPreviousPeriodEndPay(ic.getPreviousPeriodEndPay());
|
|
|
+ certificate.setCurrentPeriodEndPay(ic.getCurrentPeriodEndPay());
|
|
|
}
|
|
|
BeanUtils.copyProperties(certificate,ic);
|
|
|
/*同时兼容几个表后,支付章名称和章节号有点混乱,需要注意纠正*/
|
|
@@ -1467,7 +1473,7 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
|
|
|
@Data
|
|
|
@EqualsAndHashCode(callSuper = true)
|
|
|
- public class ConSchChapter extends BaseSpecial<ConstructionSchedule> implements Special{
|
|
|
+ public class ConSchChapter2 extends BaseSpecial<ConstructionSchedule> implements Special{
|
|
|
|
|
|
@Override
|
|
|
public boolean ready() {
|
|
@@ -1478,7 +1484,7 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
public void parse() {
|
|
|
builderFormDatas(ConstructionSchedule.class);
|
|
|
|
|
|
- List<ChapterSchedule> chapterSchedules=chapterScheduleFc.apply(tec.periodInfo.getYear(),tec.getContractId().toString());
|
|
|
+ List<ChapterSchedule> chapterSchedules=chapterScheduleFc.apply(tec.getContractId().toString());
|
|
|
/*支付信息根据章节、月份分组*/
|
|
|
List<InventoryForm> inventoryForms = tec.meterInfo.getInventoryForms();
|
|
|
List<InventoryForm> chapters = tec.meterInfo.getChapter();
|
|
@@ -1519,7 +1525,7 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
cs.setCurrentPayPercent(ratioFc.apply(cs.getCurrentPeriodPay(),cs.getChangeMoney()));
|
|
|
/* 本期末累计支付金额占合同比*/
|
|
|
cs.setPayPercent(ratioFc.apply(cs.getCurrentPeriodEndPay(),cs.getChangeMoney()));
|
|
|
- /**本期末占合合同金额 */
|
|
|
+ /*本期末占合合同金额 */
|
|
|
cs.setPrePayPercent(ratioFc.apply(cs.getCurrentPeriodEndPay(),cs.getContractMoney()));
|
|
|
/*变更金额*/
|
|
|
cs.setChangeMoneyAll(subtractFc.apply(cs.getChangeMoney(),cs.getContractMoney()));
|
|
@@ -1576,7 +1582,199 @@ public class ExecutorMeter extends FormulaExecutor {
|
|
|
FileOutputStream fos = new FileOutputStream("C:/Users/yangyj/Desktop/Swap_space/poi_statistics2.png");
|
|
|
fos.write(chartBytes);
|
|
|
BladeFile chartFile= tec.getNewIOSSClient().updateFile(chartBytes, ConstructionSchedule.TBN+SnowFlakeUtil.getId()+".png");*/
|
|
|
- String path=FormulaUtils.chapterScheduleChartUrl(actual,planned);
|
|
|
+ String path=FormulaUtils.chapterScheduleChartUrl(null,null,2023,2024);
|
|
|
+ BladeFile chartFile= tec.getNewIOSSClient().uploadFile( ConstructionSchedule.TBN+ SnowFlakeUtil.getId() + ".png",path);
|
|
|
+ /*施工进度图*/
|
|
|
+ FormulaUtils.elementFindByCode(fdm, ConstructionSchedule.TBN + ":key_29").ifPresent(t -> {
|
|
|
+ elementWriter.write(t, chartFile.getLink());
|
|
|
+ });
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ StaticLog.error(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 合同概要*/
|
|
|
+ FormulaUtils.elementFindByCode(fdm,ConstructionSchedule.TBN+":key_24").ifPresent(t->{
|
|
|
+ /*合同时长*/
|
|
|
+ String contractDay=CustomFunction.join(CustomFunction.daysPassed(baseInfo.getStartDatePlan(),baseInfo.getEndDatePlan()),"").toString();
|
|
|
+ /*总时长*/
|
|
|
+ String totalDay=CustomFunction.join(CustomFunction.daysPassed(baseInfo.getStartDate(),baseInfo.getEndDate()),"").toString();
|
|
|
+ /*延长时间*/
|
|
|
+ int extended=BaseUtils.obj2IntegerZero(contractDay)-BaseUtils.obj2IntegerZero(totalDay);
|
|
|
+ /*已过去*/
|
|
|
+ String passDay=CustomFunction.join(CustomFunction.daysPassed(baseInfo.getStartDate(), LocalDate.now()),"").toString();
|
|
|
+
|
|
|
+ BigDecimal provisionalSum=tec.meterInfo.getInventoryForms().stream().filter(e->"D".equals(e.getFormNumber())).map(e->BaseUtils.str2BigDecimal(e.getBidPrice())).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ BigDecimal BOQAmount=tec.meterInfo.getInventoryForms().stream().filter(e->!"D".equals(e.getFormNumber())).map(e->BaseUtils.str2BigDecimal(e.getBidPrice())).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ baseInfo.setProvisionalSum(StringUtils.number2String(provisionalSum,2));
|
|
|
+ baseInfo.setBOQAmount(StringUtils.number2String(BOQAmount,2));
|
|
|
+ BigDecimal changeTokenTotal=tec.meterInfo.getChangeTokenListMap().values().stream().flatMap(Collection::stream).map(ChangeToken::getTotalChangeMoney).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ double totalMoney = BaseUtils.obj2DoubleZero(baseInfo.getContractAmount())+BaseUtils.obj2DoubleZero(baseInfo.getProvisionalSum())+BaseUtils.obj2DoubleZero(baseInfo.getBOQAmount())+BaseUtils.obj2DoubleZero(changeTokenTotal);
|
|
|
+ String brief="开工日期:"+baseInfo.getStartDatePlan()+" 始算工期日:"+baseInfo.getStartDate()
|
|
|
+ +" 合同完成日期:"+baseInfo.getEndDatePlan()+" 合同期限"+contractDay+"天 时间延长"+extended+"天 修改后合同期限"+ totalDay
|
|
|
+ +"天(即至"+baseInfo.getEndDate()+")"
|
|
|
+ + "\n 合同总价"+CustomFunction.xN(baseInfo.getContractAmount(),0.0001)+"万元、暂定金"
|
|
|
+ +CustomFunction.xN(baseInfo.getProvisionalSum(),0.0001)+"万元、工程量清单金额"
|
|
|
+ +CustomFunction.xN(baseInfo.getBOQAmount(),0.0001)+"万元、工程量变更("+CustomFunction.xN(changeTokenTotal,0.0001)+")万元、估计最终金额"+CustomFunction.xN(totalMoney,0.0001)+"万元,时间已过"
|
|
|
+ +passDay+"天,占合同工期"+StringUtils.number2String(ratioFc.apply(passDay,totalDay),2)+"%";
|
|
|
+ elementWriter.write(t,brief);
|
|
|
+ });
|
|
|
+
|
|
|
+ /*内容输出*/
|
|
|
+ putOut(ConstructionSchedule.class);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ @Data
|
|
|
+ @EqualsAndHashCode(callSuper = true)
|
|
|
+ public class ConSchChapter extends BaseSpecial<ConstructionSchedule> implements Special{
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean ready() {
|
|
|
+ return MeterInfo.MB_ZJ.equals(tec.getMeterInfo().getTemplate());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void parse() {
|
|
|
+ builderFormDatas(ConstructionSchedule.class);
|
|
|
+
|
|
|
+ List<ChapterSchedule> chapterSchedules=chapterScheduleFc.apply(tec.getContractId().toString());
|
|
|
+ /*支付信息根据章节、月份分组*/
|
|
|
+ List<InventoryForm> inventoryForms = tec.meterInfo.getInventoryForms();
|
|
|
+ List<InventoryForm> chapters = tec.meterInfo.getChapter();
|
|
|
+ /*合同金额*/
|
|
|
+ Map<String, BigDecimal[]> contractMoney = contractMoneySum.apply(inventoryForms);
|
|
|
+ LinkedHashMap<String, InventoryForm> dictMap = chapters.stream().collect(Collectors.toMap(e->chapterPreFixFc.apply(e),e -> e, (v1, v2) -> v1,LinkedHashMap::new));
|
|
|
+ LinkedHashMap<Integer,List<Payment>>paymentListMap = tec.meterInfo.getPaymentListMap();
|
|
|
+ /*之前的计量期数据*/
|
|
|
+ previous = paymentListMap.get(MeterInfo.PRE);
|
|
|
+ /*当前计量期数据*/
|
|
|
+ current =paymentListMap.get(MeterInfo.CUR);
|
|
|
+ /*累计到本期末*/
|
|
|
+ paymentsPeriodEnd=paymentListMap.get(MeterInfo.END);
|
|
|
+ /*往期每章节的实际花费*/
|
|
|
+ Map<String,BigDecimal> previousMoney= moneySum.apply(previous);
|
|
|
+ /*当前计量期每章节的实际花费*/
|
|
|
+ Map<String,BigDecimal> currentMoney= moneySum.apply(current);
|
|
|
+ /*本期末每章节的实际花费*/
|
|
|
+ Map<String,BigDecimal> endMoney= moneySum.apply(paymentsPeriodEnd);
|
|
|
+
|
|
|
+ /*按计量期的年月的时间戳分组*/
|
|
|
+ LinkedHashMap<Integer,BigDecimal> monthMoney = paymentsPeriodEnd.stream().sorted(Comparator.comparingInt(Payment::dateInt)).collect(Collectors.groupingBy(
|
|
|
+ Payment::dateInt,
|
|
|
+ LinkedHashMap::new,
|
|
|
+ Collectors.reducing(BigDecimal.ZERO, Payment::getMoneyAsBigDecimal, BigDecimal::add)
|
|
|
+ ));
|
|
|
+
|
|
|
+ BaseInfo baseInfo = tec.meterInfo.getBaseInfo();
|
|
|
+ dictMap.forEach((k,v)-> {
|
|
|
+ ConstructionSchedule cs = new ConstructionSchedule(v.getFormName());
|
|
|
+ BigDecimal[] sum = contractMoney.get(k);
|
|
|
+ cs.setChapterNumber(k);
|
|
|
+ cs.setContractMoney(sum[0].toPlainString());
|
|
|
+ cs.setChangeMoney(sum[1].toPlainString());
|
|
|
+ cs.setCurrentPeriodPay(StringUtils.handleNull(currentMoney.get(k)));
|
|
|
+ cs.setCurrentPeriodEndPay(StringUtils.handleNull(endMoney.get(k)));
|
|
|
+ cs.setItemPercent(ratioFc.apply(cs.getChangeMoney(), baseInfo.getContractAmount().toString()));
|
|
|
+ cs.setItemProgress(ratioFc.apply(cs.getCurrentPeriodEndPay(), cs.getChangeMoney()));
|
|
|
+ cs.setCurrentPayPercent(ratioFc.apply(cs.getCurrentPeriodPay(),cs.getChangeMoney()));
|
|
|
+ /* 本期末累计支付金额占合同比*/
|
|
|
+ cs.setPayPercent(ratioFc.apply(cs.getCurrentPeriodEndPay(),cs.getChangeMoney()));
|
|
|
+ /*本期末占合合同金额 */
|
|
|
+ cs.setPrePayPercent(ratioFc.apply(cs.getCurrentPeriodEndPay(),cs.getContractMoney()));
|
|
|
+ /*变更金额*/
|
|
|
+ cs.setChangeMoneyAll(subtractFc.apply(cs.getChangeMoney(),cs.getContractMoney()));
|
|
|
+ dataList.add(cs);
|
|
|
+ });
|
|
|
+ /*每月合计进度*/
|
|
|
+ try {
|
|
|
+ String totalAmount=dataList.stream().map(ConstructionSchedule::getContractMoney).map(BaseUtils::str2BigDecimal).reduce(BigDecimal.ZERO,BigDecimal::add).toPlainString();
|
|
|
+ /*合同计划结束日期年末*/
|
|
|
+ LocalDate planEndDate=LocalDate.parse(baseInfo.getEndDatePlan(),BaseUtils.chineseDateFm);
|
|
|
+ LocalDate planStartDate=LocalDate.parse(baseInfo.getEndDatePlan(),BaseUtils.chineseDateFm);
|
|
|
+ int max = monthMoney.keySet().stream().max(Comparator.comparingInt(i->i)).orElse(BaseUtils.dateInt(planEndDate.getYear(),12));
|
|
|
+ int min= monthMoney.keySet().stream().min(Comparator.comparingInt(i->i)).orElse(BaseUtils.dateInt(planStartDate.getYear(),1));
|
|
|
+ List<Integer> tickUnit =BaseUtils.getTickUnit(min,max);
|
|
|
+ /*没月累计*/
|
|
|
+ /* LocalDateTime head=BaseUtils.toLdt(min);
|
|
|
+ LocalDateTime tail=BaseUtils.toLdt(max);*/
|
|
|
+ /* List<String> monthlySum= IntStream.rangeClosed(1,max).boxed().map(month->{
|
|
|
+ BigDecimal tmp= monthMoney.entrySet().stream().filter(e->e.getKey()<=month).map(Map.Entry::getValue).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ return ratioFc.apply(tmp.toPlainString(),totalAmount);
|
|
|
+ }).collect(Collectors.toList());*/
|
|
|
+ List<String> monthlySum= tickUnit.stream().map(month->{
|
|
|
+ BigDecimal tmp= monthMoney.entrySet().stream().filter(e->e.getKey()<=month).map(Map.Entry::getValue).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ return ratioFc.apply(tmp.toPlainString(),totalAmount);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ FormulaUtils.elementFindByCode(fdm,ConstructionSchedule.TBN+":key_22").ifPresent(t->{
|
|
|
+ elementWriter.write(t,monthlySum);
|
|
|
+ });
|
|
|
+ /*本月*/
|
|
|
+ /*List<String> monthlyCount= IntStream.rangeClosed(1,max).boxed().map(month->{
|
|
|
+ BigDecimal tmp= monthMoney.entrySet().stream().filter(e-> e.getKey().equals(month)).map(Map.Entry::getValue).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ return ratioFc.apply(tmp.toPlainString(),totalAmount);
|
|
|
+ }).collect(Collectors.toList());*/
|
|
|
+ List<String> monthlyCount= tickUnit.stream().map(month->{
|
|
|
+ BigDecimal tmp= monthMoney.entrySet().stream().filter(e-> e.getKey().equals(month)).map(Map.Entry::getValue).reduce(BigDecimal.ZERO,BigDecimal::add);
|
|
|
+ return ratioFc.apply(tmp.toPlainString(),totalAmount);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ FormulaUtils.elementFindByCode(fdm,ConstructionSchedule.TBN+":key_23").ifPresent(t->{
|
|
|
+ elementWriter.write(t,monthlyCount);
|
|
|
+ });
|
|
|
+
|
|
|
+ List<String> planMonthSum=new ArrayList<>();
|
|
|
+ LinkedHashMap<Integer,BigDecimal> planMonthMap=new LinkedHashMap<>();
|
|
|
+ if(chapterSchedules!=null&&chapterSchedules.size()>0) {
|
|
|
+ /*月份装入数组*/
|
|
|
+ chapterSchedules.forEach(ChapterSchedule::updateArray);
|
|
|
+ LinkedHashMap<Integer,List<ChapterSchedule>> chapterScheduleGroup= chapterSchedules.stream().sorted(Comparator.comparingInt(ChapterSchedule::getYear)).collect(Collectors.groupingBy(ChapterSchedule::getYear,LinkedHashMap::new,Collectors.toList()));
|
|
|
+ chapterScheduleGroup.forEach((year,v)->{
|
|
|
+ for(int i=1;i<=12;i++){
|
|
|
+ int month = i;
|
|
|
+ planMonthMap.put(BaseUtils.dateInt(year,month),v.stream().map(e->e.getArr()[month-1]).reduce(BigDecimal.ZERO,BigDecimal::add));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ /* List<BigDecimal> planMonth = IntStream.range(0,12).boxed().map(i->chapterSchedules.stream().map(e->e.getArr()[i]).reduce(BigDecimal.ZERO,BigDecimal::add)).collect(Collectors.toList());*/
|
|
|
+ /*计划本月*/
|
|
|
+ FormulaUtils.elementFindByCode(fdm, ConstructionSchedule.TBN + ":key_28").ifPresent(t -> {
|
|
|
+ List<String> value=planMonthMap.values().stream().map(BigDecimal::toPlainString).map(s-> ratioFc.apply(s, totalAmount)).collect(Collectors.toList());
|
|
|
+ elementWriter.write(t, value);
|
|
|
+ });
|
|
|
+ /*计划累计*/
|
|
|
+
|
|
|
+ planMonthSum = planMonthMap.keySet().stream().map(yearMonth->{
|
|
|
+ String tmp= planMonthMap.entrySet().stream().filter(kv ->kv.getKey()<=yearMonth).map(Map.Entry::getValue).reduce(BigDecimal.ZERO, BigDecimal::add).toPlainString();
|
|
|
+ return ratioFc.apply(tmp, totalAmount);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ /* planMonthSum = IntStream.range(0,12).boxed().map(i-> {
|
|
|
+ String tmp= planMonth.stream().filter(e -> planMonth.indexOf(e) <= i).reduce(BigDecimal.ZERO, BigDecimal::add).toPlainString();
|
|
|
+ return ratioFc.apply(tmp, totalAmount);
|
|
|
+ } */
|
|
|
+ List<String> finalPlanMonthSum = planMonthSum;
|
|
|
+ FormulaUtils.elementFindByCode(fdm, ConstructionSchedule.TBN + ":key_27").ifPresent(t -> {
|
|
|
+ elementWriter.write(t, finalPlanMonthSum);
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ /*上传图标*/
|
|
|
+ if(planMonthSum.size()>0&&monthlySum.size()>0){
|
|
|
+ try {
|
|
|
+ LinkedHashMap<Long,Double> actualMap = new LinkedHashMap<>();
|
|
|
+ monthMoney.forEach((yearMonth,sum)->{
|
|
|
+ actualMap.put(BaseUtils.getTimeMs(yearMonth/100,yearMonth%100),sum.doubleValue());
|
|
|
+ });
|
|
|
+
|
|
|
+ LinkedHashMap<Long,Double> plannedMap =new LinkedHashMap<>();
|
|
|
+ planMonthMap.entrySet().stream().filter(kv->kv.getKey()<=max).forEach(kv->{
|
|
|
+ plannedMap.put(BaseUtils.getTimeMs(kv.getKey()/100,kv.getKey()%100),kv.getValue().doubleValue());
|
|
|
+ });
|
|
|
+ String path=FormulaUtils.chapterScheduleChartUrl(actualMap,plannedMap,planStartDate.getYear(),planEndDate.getYear());
|
|
|
BladeFile chartFile= tec.getNewIOSSClient().uploadFile( ConstructionSchedule.TBN+ SnowFlakeUtil.getId() + ".png",path);
|
|
|
/*施工进度图*/
|
|
|
FormulaUtils.elementFindByCode(fdm, ConstructionSchedule.TBN + ":key_29").ifPresent(t -> {
|