personal-finances/PersonalFinancesService/src/main/java/dev/mvvasilev/finances/services/StatisticsService.java

83 lines
3.8 KiB
Java
Raw Normal View History

package dev.mvvasilev.finances.services;
import dev.mvvasilev.common.data.AbstractEntity;
import dev.mvvasilev.finances.dtos.CategoryDTO;
2024-01-02 18:20:00 +02:00
import dev.mvvasilev.finances.dtos.SpendingByCategoriesDTO;
import dev.mvvasilev.finances.dtos.SpendingByCategoryDTO;
2024-01-02 18:20:00 +02:00
import dev.mvvasilev.finances.dtos.SpendingOverTimeByCategoryDTO;
import dev.mvvasilev.finances.enums.TimePeriod;
import dev.mvvasilev.finances.persistence.StatisticsRepository;
import dev.mvvasilev.finances.persistence.TransactionCategoryRepository;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
2024-01-02 18:20:00 +02:00
import java.time.temporal.ChronoUnit;
import java.util.*;
@Service
public class StatisticsService {
private final TransactionCategoryRepository transactionCategoryRepository;
private final StatisticsRepository statisticsRepository;
public StatisticsService(TransactionCategoryRepository transactionCategoryRepository, StatisticsRepository statisticsRepository) {
this.transactionCategoryRepository = transactionCategoryRepository;
this.statisticsRepository = statisticsRepository;
}
2024-01-02 18:20:00 +02:00
public SpendingByCategoriesDTO spendingByCategory(Long[] categoryId, LocalDateTime from, LocalDateTime to) {
final var categories = transactionCategoryRepository.findAllById(Arrays.stream(categoryId).toList()).stream().map(c -> new CategoryDTO(c.getId(), c.getName(), null)).toList();
final var spendingByCategory = statisticsRepository.fetchSpendingByCategory(
2024-01-02 18:20:00 +02:00
categoryId,
from,
2024-01-02 18:20:00 +02:00
to
);
2024-01-02 18:20:00 +02:00
return new SpendingByCategoriesDTO(
categories,
spendingByCategory
);
}
2024-01-02 18:20:00 +02:00
public SpendingOverTimeByCategoryDTO spendingByCategoryOverTime(
Long[] categoryId,
TimePeriod period,
LocalDateTime from,
LocalDateTime to
) {
return new SpendingOverTimeByCategoryDTO(
transactionCategoryRepository.findAllById(Arrays.stream(categoryId).toList()).stream().map(c -> new CategoryDTO(c.getId(), c.getName(), null)).toList(),
period.getDuration(),
statisticsRepository.fetchSpendingByCategoryOverTime(from, to, period, categoryId).stream().map(dto -> new SpendingByCategoryDTO(
dto.categoryId(),
dto.periodBeginningTimestamp(),
dto.amountForPeriod()
)).toList()
);
}
// Impose limits if necessary
private boolean validatePeriodWithinLimits(LocalDateTime from, LocalDateTime to, TimePeriod period) {
return switch (period) {
// Can't request daily spending breakdown for a period longer than a month
case DAILY -> ChronoUnit.MONTHS.between(from, to) <= 1;
// Can't request weekly spending breakdown for a period longer than a year
case WEEKLY -> ChronoUnit.YEARS.between(from, to) <= 1;
// Can't request bi-weekly spending breakdown for a period longer than a year
case BIWEEKLY -> ChronoUnit.YEARS.between(from, to) <= 1;
// Can't request monthly spending breakdown for a period longer than 3 years
case MONTHLY -> ChronoUnit.YEARS.between(from, to) <= 3;
// Can't request quarterly spending breakdown for a period longer than 5 years
case QUARTERLY -> ChronoUnit.YEARS.between(from, to) <= 5;
// Can't request yearly spending breakdown for a period longer than 30 years
case YEARLY -> ChronoUnit.YEARS.between(from, to) <= 30;
};
}
2024-01-03 22:46:16 +02:00
public Double sumByCategory(Long[] categoryId, LocalDateTime from, LocalDateTime to, Boolean includeUncategorized) {
return statisticsRepository.sumByCategory(categoryId, from, to, includeUncategorized);
}
}