<commit_before>package ee.tuleva.onboarding.mandate.application;

import static ee.tuleva.onboarding.mandate.application.ApplicationType.WITHDRAWAL;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

import ee.tuleva.onboarding.auth.principal.Person;
import ee.tuleva.onboarding.deadline.MandateDeadlinesService;
import ee.tuleva.onboarding.epis.EpisService;
import ee.tuleva.onboarding.epis.mandate.ApplicationDTO;
import ee.tuleva.onboarding.fund.FundRepository;
import ee.tuleva.onboarding.fund.response.FundDto;
import ee.tuleva.onboarding.locale.LocaleService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ApplicationService {

  private final EpisService episService;
  private final LocaleService localeService;
  private final FundRepository fundRepository;
  private final MandateDeadlinesService mandateDeadlinesService;

  public boolean hasPendingWithdrawals(Person person) {
    return getApplications(person).stream()
        .anyMatch(application -> application.isPending() && application.isWithdrawal());
  }

  public List<Application> getApplications(Person person) {
    val applicationsByType =
        episService.getApplications(person).stream().collect(groupingBy(ApplicationDTO::getType));
    return applicationsByType.entrySet().stream()
        .flatMap(
            elem -> {
              if (elem.getKey() == ApplicationType.TRANSFER) {
                return groupTransfers(elem.getValue()).stream();
              } else {
                return elem.getValue().stream().map(this::convertWithdrawal);
              }
            })
        .sorted()
        .collect(toList());
  }

  private List<Application> groupTransfers(List<ApplicationDTO> transferApplications) {
    val locale = localeService.getCurrentLocale();
    val deadlines = mandateDeadlinesService.getDeadlines();
    val transfersBySource =
        transferApplications.stream()
            .collect(
                groupingBy(
                    ApplicationDTO::getSourceFundIsin, groupingBy(ApplicationDTO::getStatus)));
    return transfersBySource.entrySet().stream()
        .flatMap(
            transfers -> {
              val sourceFundIsin = transfers.getKey();
              return transfers.getValue().entrySet().stream()
                  .map(
                      entry -> {
                        val status = entry.getKey();
                        val applications = entry.getValue();
                        val application = Application.builder();
                        val firstTransfer =
                            applications.stream()
                                .findFirst()
                                .orElseThrow(IllegalStateException::new);
                        application.id(firstTransfer.getId());
                        application.creationTime(firstTransfer.getDate());
                        application.status(status);
                        application.type(firstTransfer.getType());
                        application.fulfillmentDate(deadlines.getTransferMandateFulfillmentDate());
                        application.cancellationDeadline(
                            deadlines.getTransferMandateCancellationDeadline());
                        val sourceFund = fundRepository.findByIsin(sourceFundIsin);
                        val details =
                            TransferApplicationDetails.builder()
                                .sourceFund(new FundDto(sourceFund, locale.getLanguage()));
                        applications.forEach(
                            applicationDTO -> {
                              val targetFund =
                                  fundRepository.findByIsin(applicationDTO.getTargetFundIsin());
                              details.exchange(
                                  TransferApplicationDetails.Exchange.builder()
                                      .amount(applicationDTO.getAmount())
                                      .targetFund(targetFund != null ? new FundDto(targetFund, locale.getLanguage()) : null)
                                      .build());
                            });
                        application.details(details.build());
                        return application.build();
                      });
            })
        .collect(toList());
  }

  private Application convertWithdrawal(ApplicationDTO applicationDTO) {
    val deadlines = mandateDeadlinesService.getDeadlines();
    return Application.builder()
        .creationTime(applicationDTO.getDate())
        .type(applicationDTO.getType())<commit_msg>Spotless fix<commit_after>package ee.tuleva.onboarding.mandate.application;

import static ee.tuleva.onboarding.mandate.application.ApplicationType.WITHDRAWAL;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

import ee.tuleva.onboarding.auth.principal.Person;
import ee.tuleva.onboarding.deadline.MandateDeadlinesService;
import ee.tuleva.onboarding.epis.EpisService;
import ee.tuleva.onboarding.epis.mandate.ApplicationDTO;
import ee.tuleva.onboarding.fund.FundRepository;
import ee.tuleva.onboarding.fund.response.FundDto;
import ee.tuleva.onboarding.locale.LocaleService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ApplicationService {

  private final EpisService episService;
  private final LocaleService localeService;
  private final FundRepository fundRepository;
  private final MandateDeadlinesService mandateDeadlinesService;

  public boolean hasPendingWithdrawals(Person person) {
    return getApplications(person).stream()
        .anyMatch(application -> application.isPending() && application.isWithdrawal());
  }

  public List<Application> getApplications(Person person) {
    val applicationsByType =
        episService.getApplications(person).stream().collect(groupingBy(ApplicationDTO::getType));
    return applicationsByType.entrySet().stream()
        .flatMap(
            elem -> {
              if (elem.getKey() == ApplicationType.TRANSFER) {
                return groupTransfers(elem.getValue()).stream();
              } else {
                return elem.getValue().stream().map(this::convertWithdrawal);
              }
            })
        .sorted()
        .collect(toList());
  }

  private List<Application> groupTransfers(List<ApplicationDTO> transferApplications) {
    val locale = localeService.getCurrentLocale();
    val deadlines = mandateDeadlinesService.getDeadlines();
    val transfersBySource =
        transferApplications.stream()
            .collect(
                groupingBy(
                    ApplicationDTO::getSourceFundIsin, groupingBy(ApplicationDTO::getStatus)));
    return transfersBySource.entrySet().stream()
        .flatMap(
            transfers -> {
              val sourceFundIsin = transfers.getKey();
              return transfers.getValue().entrySet().stream()
                  .map(
                      entry -> {
                        val status = entry.getKey();
                        val applications = entry.getValue();
                        val application = Application.builder();
                        val firstTransfer =
                            applications.stream()
                                .findFirst()
                                .orElseThrow(IllegalStateException::new);
                        application.id(firstTransfer.getId());
                        application.creationTime(firstTransfer.getDate());
                        application.status(status);
                        application.type(firstTransfer.getType());
                        application.fulfillmentDate(deadlines.getTransferMandateFulfillmentDate());
                        application.cancellationDeadline(
                            deadlines.getTransferMandateCancellationDeadline());
                        val sourceFund = fundRepository.findByIsin(sourceFundIsin);
                        val details =
                            TransferApplicationDetails.builder()
                                .sourceFund(new FundDto(sourceFund, locale.getLanguage()));
                        applications.forEach(
                            applicationDTO -> {
                              val targetFund =
                                  fundRepository.findByIsin(applicationDTO.getTargetFundIsin());
                              details.exchange(
                                  TransferApplicationDetails.Exchange.builder()
                                      .amount(applicationDTO.getAmount())
                                      .targetFund(
                                          targetFund != null
                                              ? new FundDto(targetFund, locale.getLanguage())
                                              : null)
                                      .build());
                            });
                        application.details(details.build());
                        return application.build();
                      });
            })
        .collect(toList());
  }

  private Application convertWithdrawal(ApplicationDTO applicationDTO) {
    val deadlines = mandateDeadlinesService.getDeadlines();
    return Application.builder()
        .creationTime(applicationDTO.getDate())
        .type(applicationDTO.getType())
{'fraction_non_alphanumeric': 0.08769742310889443, 'fraction_numerical': 0.0, 'mean_word_length': 1.8982234266787112, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '985503', 'n_tokens_mistral': 2275, 'n_tokens_neox': 2177, 'n_words': 345}