dev add statistic files protected
Test Workflow / test (push) Successful in 2s

This commit is contained in:
vladp
2026-04-16 00:28:27 +07:00
parent be62dd458a
commit 42a5368003
8 changed files with 224 additions and 1 deletions
@@ -0,0 +1,121 @@
package ru.soune.nocopy.service.statistic;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import ru.soune.nocopy.dto.statistic.SubscriberStatisticResponse;
import ru.soune.nocopy.entity.tarif.TariffInfo;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.repository.TariffInfoRepository;
import ru.soune.nocopy.repository.UserRepository;
import java.util.*;
@Service
@RequiredArgsConstructor
@Slf4j
public class SubscriberStatisticService {
private final TariffInfoRepository tariffInfoRepository;
private final UserRepository userRepository;
private static final String TERM_MONTHLY = "MONTHLY";
private static final String TERM_YEARLY = "YEAR";
public SubscriberStatisticResponse getSubscriberStatistics() {
return SubscriberStatisticResponse.builder()
.monthly(buildPeriodStatistics(TERM_MONTHLY))
.yearly(buildPeriodStatistics(TERM_YEARLY))
.build();
}
private SubscriberStatisticResponse.PeriodStatistics buildPeriodStatistics(String term) {
Long currentActive = tariffInfoRepository.getCurrentActiveSubscriptions(term);
List<TariffInfo> allTariffs = tariffInfoRepository.getAllTariffInfosForAnalysis(term);
Map<Long, List<TariffInfo>> tariffsByUser = groupTariffsByUser(allTariffs);
Long firstTime = countFirstTimeSubscriptions(tariffsByUser);
Long renewals = countRenewals(tariffsByUser);
UpDownGradeResult gradeResult = analyzeUpgradesAndDowngrades(tariffsByUser);
return SubscriberStatisticResponse.PeriodStatistics.builder()
.currentActiveSubscriptions(currentActive != null ? currentActive : 0L)
.firstTimeSubscriptions(firstTime)
.renewals(renewals)
.upgrades(gradeResult.upgrades)
.downgrades(gradeResult.downgrades)
.build();
}
private Map<Long, List<TariffInfo>> groupTariffsByUser(List<TariffInfo> tariffs) {
Map<Long, List<TariffInfo>> result = new HashMap<>();
for (TariffInfo ti : tariffs) {
Optional<User> userOpt = userRepository.findByPersonalTariffInfoId(ti.getId());
if (userOpt.isPresent()) {
Long userId = userOpt.get().getId();
result.computeIfAbsent(userId, k -> new ArrayList<>()).add(ti);
}
}
return result;
}
private Long countFirstTimeSubscriptions(Map<Long, List<TariffInfo>> tariffsByUser) {
return (long) tariffsByUser.size();
}
private Long countRenewals(Map<Long, List<TariffInfo>> tariffsByUser) {
return tariffsByUser.values().stream()
.filter(list -> list.size() > 1)
.mapToLong(list -> list.size() - 1)
.sum();
}
private UpDownGradeResult analyzeUpgradesAndDowngrades(Map<Long, List<TariffInfo>> tariffsByUser) {
long upgrades = 0L;
long downgrades = 0L;
for (List<TariffInfo> userTariffs : tariffsByUser.values()) {
if (userTariffs.size() < 2) {
continue;
}
userTariffs.sort(Comparator.comparing(TariffInfo::getStartTariff,
Comparator.nullsLast(Comparator.naturalOrder())));
for (int i = 1; i < userTariffs.size(); i++) {
TariffInfo previous = userTariffs.get(i - 1);
TariffInfo current = userTariffs.get(i);
if (previous.getTariff() == null || current.getTariff() == null) {
continue;
}
double previousPrice = previous.getTariff().getPrice();
double currentPrice = current.getTariff().getPrice();
if (currentPrice > previousPrice) {
upgrades++;
} else if (currentPrice < previousPrice) {
downgrades++;
}
}
}
return new UpDownGradeResult(upgrades, downgrades);
}
private static class UpDownGradeResult {
final Long upgrades;
final Long downgrades;
UpDownGradeResult(Long upgrades, Long downgrades) {
this.upgrades = upgrades;
this.downgrades = downgrades;
}
}
}