From 29ccbed11a3ec0e29a9f0b8deab7562edf8b1ec5 Mon Sep 17 00:00:00 2001 From: ZZ Date: Tue, 16 Nov 2021 11:55:16 +0800 Subject: [PATCH] charge details. --- .../NotificationEquipChargeStatusTask.java | 111 +++++++++--------- 1 file changed, 58 insertions(+), 53 deletions(-) diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java index 1cc9f2d6..fc34badd 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java @@ -21,6 +21,7 @@ import org.springframework.stereotype.Component; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.Duration; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; @@ -91,75 +92,79 @@ public class NotificationEquipChargeStatusTask extends CoreDispatcher { } } - private void calculateEm(EquipChargeStatus equipChargeStatusCD, CacheRateModel cacheRateModel) { + private void calculateEm(EquipChargeStatus equipChargeStatus, CacheRateModel cacheRateModel) { - final Date endTime = DateUtil.string2Date(equipChargeStatusCD.getEndTime()); - final Date startTime = DateUtil.string2Date(equipChargeStatusCD.getStartTime()); + final Date endTime = DateUtil.string2Date(equipChargeStatus.getEndTime()); + final Date startTime = DateUtil.string2Date(equipChargeStatus.getStartTime()); long totalMilSec = endTime.getTime() - startTime.getTime(); - BigDecimal hours = new BigDecimal(totalMilSec).divide(new BigDecimal(3600000), 2, RoundingMode.HALF_UP); - BigDecimal minutes = new BigDecimal(totalMilSec).divide(new BigDecimal(60000), 2, RoundingMode.HALF_UP); + BigDecimal hours = new BigDecimal(totalMilSec).divide(new BigDecimal(3600000), 2, RoundingMode.FLOOR); + int sumPeriod = hours.setScale(0, RoundingMode.CEILING).intValue() + 1; + equipChargeStatus.setSumPeriod(sumPeriod); + DateTime firstNDT = DateTime.of(startTime); + Stack chargeDetailsStack = new Stack<>(); + ChargeDetails chargeDetails = null; + Double firstNElecMoney = 0.0; + Double firstNSeviceMony = 0.0; + Double firstNPower = 0.0; + String rtfTemp = null; Instant startIst = startTime.toInstant(); final Instant endInst = endTime.toInstant(); - equipChargeStatusCD.setSumPeriod(hours.setScale(0, RoundingMode.CEILING).intValue()); //todo calc offset - final Integer sumPeriod = equipChargeStatusCD.getSumPeriod(); - DateTime firstNDT = DateTime.of(startTime); - List chargeDetailsList = new ArrayList<>(); - Double firstNElecMoney = 0.0; - ChargeDetails chargeDetails = null; - String rtfTemp = null; + Instant endPeriod; + final Double totalPower = equipChargeStatus.getTotalPower(); for (int i = 0; i < sumPeriod; i++) { + if (!startIst.isBefore(endInst)) break; + endPeriod = startIst.truncatedTo(ChronoUnit.HOURS).plusSeconds(3599L); + if (!endPeriod.isBefore(endInst)) { + endPeriod = endInst; + } boolean newCd = false; int firstSTHourOfDay = firstNDT.getField(DateField.HOUR_OF_DAY); int tf = (firstSTHourOfDay + i) * 2; final String rtf = cacheRateModel.getTfPricesSeq()[tf]; - if (chargeDetails == null || rtfTemp == null || !rtf.equals(rtfTemp)) { + if (chargeDetails == null || !rtf.equals(rtfTemp)) { newCd = true; chargeDetails = new ChargeDetails(); } rtfTemp = rtf; - BigDecimal timePeriodRatio = BigDecimal.valueOf(60).divide(minutes, 2, RoundingMode.HALF_UP); - BigDecimal tpPower = BigDecimal.valueOf(equipChargeStatusCD.getTotalPower()).multiply(timePeriodRatio); - calculateCD(cacheRateModel, rtf, timePeriodRatio, tpPower, chargeDetails); + Duration durm = Duration.between(startIst, endPeriod); + BigDecimal timePeriodRatio = BigDecimal.valueOf(durm.toMillis()).divide(BigDecimal.valueOf(totalMilSec), 2, + RoundingMode.HALF_UP); + calculateCD(cacheRateModel, rtf, timePeriodRatio, BigDecimal.valueOf(totalPower), chargeDetails); if (i == 0) { - chargeDetails.setDetailStartTime(equipChargeStatusCD.getStartTime()); - } else { - startIst = startIst.truncatedTo(ChronoUnit.HOURS).plusSeconds(3600L); - if (newCd) { - chargeDetails.setDetailStartTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()).format(startIst)); - } - } - Instant endPeriod = startIst.truncatedTo(ChronoUnit.HOURS).plusSeconds(3599L); - if (!endPeriod.isBefore(endInst)) { - endPeriod = endInst; + chargeDetails.setDetailStartTime(equipChargeStatus.getStartTime()); + } else if (newCd) { + chargeDetails.setDetailStartTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()).format(startIst)); } + startIst = startIst.truncatedTo(ChronoUnit.HOURS).plusSeconds(3600L); chargeDetails.setDetailEndTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()).format(endPeriod)); - firstNElecMoney += chargeDetails.getDetailElecMoney(); if (newCd) { - chargeDetailsList.add(chargeDetails); + chargeDetailsStack.push(chargeDetails); } } -// DateTime lastDT = DateTime.of(endTime); -// int tf = (lastDT.getField(DateField.HOUR_OF_DAY)) * 2; -// final String rtf = cacheRateModel.getTfPricesSeq()[tf]; -// BigDecimal timePeriodRatio = BigDecimal.valueOf(60).divide(minutes, 2, RoundingMode.HALF_UP); -// BigDecimal tpPower = BigDecimal.valueOf(equipChargeStatusCD.getTotalPower()) -// .multiply(timePeriodRatio).divide(BigDecimal.valueOf(100000), 2, RoundingMode.HALF_UP); -// ChargeDetails cd = new ChargeDetails(); -// calculateCD(cacheRateModel, rtf, timePeriodRatio, tpPower, cd); -// firstNElecMoney += cd.getDetailElecMoney(); -// cd.setDetailStartTime(firstNDT.toString(DATE_FORMAT_DATE_TIME)); -// chargeDetailsList.add(cd); - ChargeDetails[] cda = new ChargeDetails[chargeDetailsList.size()]; - equipChargeStatusCD.setChargeDetails(chargeDetailsList.toArray(cda)); - equipChargeStatusCD.setSumPeriod(chargeDetailsList.size()); - equipChargeStatusCD.setElecMoney(firstNElecMoney); - equipChargeStatusCD.setSeviceMoney(equipChargeStatusCD.getTotalMoney() - firstNElecMoney); + ChargeDetails[] cda = new ChargeDetails[chargeDetailsStack.size()]; + equipChargeStatus.setChargeDetails(chargeDetailsStack.toArray(cda)); + equipChargeStatus.setSumPeriod(chargeDetailsStack.size()); + equipChargeStatus.setElecMoney(firstNElecMoney); + final Double totalMoney = equipChargeStatus.getTotalMoney(); + for (ChargeDetails cd : chargeDetailsStack) { + firstNElecMoney += cd.getDetailElecMoney(); + firstNSeviceMony += cd.getDetailSeviceMoney(); + firstNPower += cd.getDetailPower(); + } + equipChargeStatus.setElecMoney(BigDecimal.valueOf(totalMoney).subtract(BigDecimal.valueOf(firstNSeviceMony)).setScale(2, RoundingMode.HALF_DOWN).doubleValue()); + equipChargeStatus.setSeviceMoney(BigDecimal.valueOf(firstNSeviceMony).setScale(2, RoundingMode.HALF_UP).doubleValue()); + final BigDecimal oddm = + BigDecimal.valueOf(totalMoney).subtract(BigDecimal.valueOf(firstNElecMoney)).subtract(BigDecimal.valueOf(firstNSeviceMony)); + final BigDecimal oddp = BigDecimal.valueOf(totalPower).subtract(BigDecimal.valueOf(firstNPower)); + ChargeDetails peek = chargeDetailsStack.peek(); + peek.setDetailElecMoney(BigDecimal.valueOf(peek.getDetailElecMoney()).add(oddm).setScale(2, RoundingMode.HALF_UP).doubleValue()); + peek.setDetailPower(BigDecimal.valueOf(peek.getDetailPower()).add(oddp).setScale(2, RoundingMode.HALF_UP).doubleValue()); } private void calculateCD(CacheRateModel cacheRateModel, String rtf, BigDecimal timePeriodRatio, BigDecimal tpPower, ChargeDetails cd) { - cd.setDetailPower(tpPower.multiply(timePeriodRatio).doubleValue()); + cd.setDetailPower(BigDecimal.valueOf(cd.getDetailPower() + tpPower.multiply(timePeriodRatio).doubleValue()).setScale(2, RoundingMode.HALF_UP).doubleValue()); Integer powerPrice; Integer svcPrice; if ("00".equals(rtf)) { @@ -177,14 +182,14 @@ public class NotificationEquipChargeStatusTask extends CoreDispatcher { } cd.setElecPrice((double) Math.round(powerPrice / 1000D) / 100D); cd.setSevicePrice((double) Math.round(svcPrice / 1000D) / 100D); - final double detailElecMoney = - BigDecimal.valueOf(cd.getElecPrice()).multiply(BigDecimal.valueOf(cd.getDetailPower())).setScale(2, - RoundingMode.HALF_UP).doubleValue(); - cd.setDetailElecMoney(cd.getDetailElecMoney() + detailElecMoney); - final double detailSeviceMoney = - BigDecimal.valueOf(cd.getSevicePrice()).multiply(BigDecimal.valueOf(cd.getDetailPower())).setScale(2, - RoundingMode.HALF_UP).doubleValue(); - cd.setDetailSeviceMoney(cd.getDetailSeviceMoney() + detailSeviceMoney); + final double detailElecMoney = BigDecimal.valueOf(cd.getElecPrice()) + .multiply(BigDecimal.valueOf(cd.getDetailPower())) + .setScale(2, RoundingMode.HALF_DOWN).doubleValue(); + cd.setDetailElecMoney(BigDecimal.valueOf(cd.getDetailElecMoney() + detailElecMoney).setScale(2, RoundingMode.HALF_UP).doubleValue()); + final double detailSeviceMoney = BigDecimal.valueOf(cd.getSevicePrice()) + .multiply(BigDecimal.valueOf(cd.getDetailPower())) + .setScale(2, RoundingMode.HALF_DOWN).doubleValue(); + cd.setDetailSeviceMoney(BigDecimal.valueOf(cd.getDetailSeviceMoney() + detailSeviceMoney).setScale(2, RoundingMode.HALF_DOWN).doubleValue()); } public void notify(EquipChargeStatus equipChargeStatus, AuthSecretToken authSecretTokenOut) throws IOException {