|
@@ -0,0 +1,135 @@
|
|
|
|
|
+package com.usky.vpp.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.usky.vpp.domain.VppDrParticipation;
|
|
|
|
|
+import com.usky.vpp.domain.VppResourcePoint;
|
|
|
|
|
+import com.usky.vpp.domain.VppSite;
|
|
|
|
|
+import com.usky.vpp.enums.VppUnEventPhase;
|
|
|
|
|
+import com.usky.vpp.mapper.VppDrParticipationMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppResourcePointMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppSiteMapper;
|
|
|
|
|
+import com.usky.vpp.service.VppUnEventPhaseDetector;
|
|
|
|
|
+import com.usky.vpp.util.VppAuditHelper;
|
|
|
|
|
+import com.usky.vpp.util.VppUnEventParser;
|
|
|
|
|
+import com.usky.vpp.util.VppUnPayloadHelper;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.math.RoundingMode;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Objects;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+@Service
|
|
|
|
|
+public class VppUnEventPhaseDetectorImpl implements VppUnEventPhaseDetector {
|
|
|
|
|
+
|
|
|
|
|
+ private static final int CAPACITY_SCALE = 4;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppSiteMapper siteMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppResourcePointMapper resourcePointMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppDrParticipationMapper participationMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public VppUnEventPhase detectPhase(Map<String, Object> event, Long drEventId) {
|
|
|
|
|
+ Map<String, Object> descriptor = VppUnEventParser.getDescriptor(event);
|
|
|
|
|
+ Boolean filing = VppUnPayloadHelper.getBoolean(descriptor, "filing");
|
|
|
|
|
+ Boolean lastFiling = VppUnPayloadHelper.getBoolean(descriptor, "lastFiling");
|
|
|
|
|
+ List<Map<String, Object>> resources = VppUnEventParser.getTargetResources(event);
|
|
|
|
|
+ boolean hasValues = VppUnEventParser.hasResourceValues(resources);
|
|
|
|
|
+
|
|
|
|
|
+ if (Boolean.TRUE.equals(filing) && !hasValues) {
|
|
|
|
|
+ return VppUnEventPhase.INVITATION;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (Boolean.TRUE.equals(filing) && hasValues) {
|
|
|
|
|
+ return VppUnEventPhase.DECLARE_FEEDBACK;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (Boolean.FALSE.equals(filing) && Boolean.TRUE.equals(lastFiling)) {
|
|
|
|
|
+ return resolveSplitPhase(drEventId, resources);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (hasValues) {
|
|
|
|
|
+ return VppUnEventPhase.CLEARING_PUBLICITY;
|
|
|
|
|
+ }
|
|
|
|
|
+ return VppUnEventPhase.UNKNOWN;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private VppUnEventPhase resolveSplitPhase(Long drEventId, List<Map<String, Object>> resources) {
|
|
|
|
|
+ if (drEventId == null || CollectionUtils.isEmpty(resources)) {
|
|
|
|
|
+ return VppUnEventPhase.SPLIT_NOTICE;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (Map<String, Object> resource : resources) {
|
|
|
|
|
+ String account = VppUnPayloadHelper.getString(resource, "account");
|
|
|
|
|
+ if (!StringUtils.hasText(account)) {
|
|
|
|
|
+ return VppUnEventPhase.SPLIT_NOTICE;
|
|
|
|
|
+ }
|
|
|
|
|
+ BigDecimal reportedKw = VppUnEventParser.resolveResourceReportedKw(resource);
|
|
|
|
|
+ if (reportedKw == null) {
|
|
|
|
|
+ return VppUnEventPhase.SPLIT_NOTICE;
|
|
|
|
|
+ }
|
|
|
|
|
+ BigDecimal clearedSumKw = sumClearedCapacityKwByAccount(drEventId, account.trim());
|
|
|
|
|
+ if (!capacityEquals(reportedKw, clearedSumKw)) {
|
|
|
|
|
+ return VppUnEventPhase.SPLIT_NOTICE;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return VppUnEventPhase.SPLIT_RESULT;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private BigDecimal sumClearedCapacityKwByAccount(Long drEventId, String accountNo) {
|
|
|
|
|
+ VppSite site = siteMapper.selectOne(new LambdaQueryWrapper<VppSite>()
|
|
|
|
|
+ .eq(VppSite::getAccountNo, accountNo)
|
|
|
|
|
+ .eq(VppSite::getDeleteFlag, VppAuditHelper.NOT_DELETED)
|
|
|
|
|
+ .last("LIMIT 1"));
|
|
|
|
|
+ if (site == null || site.getId() == null) {
|
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<VppResourcePoint> resourcePoints = resourcePointMapper.selectList(new LambdaQueryWrapper<VppResourcePoint>()
|
|
|
|
|
+ .eq(VppResourcePoint::getSiteId, site.getId())
|
|
|
|
|
+ .eq(VppResourcePoint::getDeleteFlag, VppAuditHelper.NOT_DELETED));
|
|
|
|
|
+ if (CollectionUtils.isEmpty(resourcePoints)) {
|
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<Long> resourceIds = resourcePoints.stream()
|
|
|
|
|
+ .map(VppResourcePoint::getId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ if (resourceIds.isEmpty()) {
|
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<VppDrParticipation> participations = participationMapper.selectList(new LambdaQueryWrapper<VppDrParticipation>()
|
|
|
|
|
+ .eq(VppDrParticipation::getEventId, drEventId)
|
|
|
|
|
+ .in(VppDrParticipation::getResourceId, resourceIds)
|
|
|
|
|
+ .eq(VppDrParticipation::getDeleteFlag, VppAuditHelper.NOT_DELETED));
|
|
|
|
|
+ BigDecimal sum = BigDecimal.ZERO;
|
|
|
|
|
+ for (VppDrParticipation participation : participations) {
|
|
|
|
|
+ if (participation.getClearedCapacityKw() != null) {
|
|
|
|
|
+ sum = sum.add(participation.getClearedCapacityKw());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return sum;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static boolean capacityEquals(BigDecimal reportedKw, BigDecimal clearedSumKw) {
|
|
|
|
|
+ BigDecimal reported = normalizeCapacity(reportedKw);
|
|
|
|
|
+ BigDecimal cleared = normalizeCapacity(clearedSumKw);
|
|
|
|
|
+ if (reported == null || cleared == null) {
|
|
|
|
|
+ return reported == null && cleared == null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return reported.compareTo(cleared) == 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static BigDecimal normalizeCapacity(BigDecimal value) {
|
|
|
|
|
+ if (value == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return value.abs().setScale(CAPACITY_SCALE, RoundingMode.HALF_UP);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|