SecurityService.java

package com.tdmconsult.ete.masterdata;

import com.tdmconsult.ete.api.MasterDataController;
import com.tdmconsult.ete.transactions.TradeTransaction;
import com.tdmconsult.ete.transactions.TradeTransactionRepository;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class SecurityService {

    private final SecurityRepository securityRepository;
    private final TradeTransactionRepository tradeTransactionRepository;
    private final EvaluationRateRepository evaluationRateRepository;

    public List<SecurityDto> getAll() {
        return securityRepository.findAll().stream().map(SecurityMapper::toDto).toList();
    }

    public List<SecurityDto> getMissingEvaluationRates(final int fiscalYear) {

        final var startDate = LocalDate.of(fiscalYear, 1, 1);
        final var endDate = LocalDate.of(fiscalYear, 12, 31);
        final var touchedSecurities = tradeTransactionRepository.findByTradingDateBetween(startDate, endDate);
        return touchedSecurities.stream()
                .map(TradeTransaction::getSecurity)
                .filter(s -> evaluationRateRepository.findBySecurityAndFiscalYear(s, fiscalYear).isEmpty())
                .distinct()
                .map(SecurityMapper::toDto)
                .toList();
    }

    public List<SecurityDto> saveEvaluationRates(
            final int fiscalYear,
            final List<MasterDataController.RatePostRequest> rates) {

        rates.forEach(rate -> {

            final var security = securityRepository.findByPublicIdOrThrow(rate.securityPublicId());
            final var existing = evaluationRateRepository.findBySecurityAndFiscalYearAndRateType(
                    security,
                    fiscalYear,
                    EvaluationRate.RateType.EOY).orElse(null);
            if (existing != null) {
                existing.setRate(rate.rate());
            } else {
                evaluationRateRepository.save(EvaluationRate.builder()
                        .publicId(UUID.randomUUID().toString())
                        .security(security)
                        .fiscalYear(fiscalYear)
                        .rate(rate.rate()).build());
            }
        });

        return getMissingEvaluationRates(fiscalYear);
    }
}