EvaluationStateMapperService.java
package com.tdmconsult.ete.evaluation;
import static com.tdmconsult.ete.accounting.BalanceRecords.ZERO_AMOUNT;
import com.tdmconsult.ete.configuration.EnumRegistryConfiguration.EnumValue;
import com.tdmconsult.ete.masterdata.SecurityMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
@RequiredArgsConstructor
public class EvaluationStateMapperService {
private final EvaluationStateInfoService evaluationStateInfoService;
public EvaluationStateDto toDto(final EvaluationState evaluation) {
final var fiscalYear = evaluation.getFiscalYear();
final var security = evaluation.getSecurity();
final var answer = new EvaluationStateDto()
.setSecurity(SecurityMapper.toDto(security))
.setFiscalYearT0(fiscalYear)
.setFiscalYearT1(fiscalYear - 1)
.setTotalQuantity(evaluation.getTotalQuantity())
.setMarketValue(evaluation.getEvaluationRate(fiscalYear)
.map(rate -> rate.multiply(evaluation.getTotalQuantity()))
.orElse(ZERO_AMOUNT))
.setEvaluationRateT0(evaluation.getEvaluationRate(fiscalYear)
.map(r -> new EvaluationStateDto.RateDto()
.setDate(r.date())
.setType(r.type().name())
.setValue(r.value())).orElse(null))
.setEvaluationTotalAmountT0(evaluation.getEvaluationTotal(fiscalYear))
.setEvaluationRateT1(evaluation.getEvaluationRate(fiscalYear - 1)
.map(r -> new EvaluationStateDto.RateDto()
.setDate(r.date())
.setType(r.type().name())
.setValue(r.value())).orElse(null))
.setEvaluationTotalAmountT1(evaluation.getEvaluationTotal(fiscalYear - 1))
.setTotalBuyInFiscalYear(evaluation.getTotalBuyCost())
.setTotalSellInFiscalYear(evaluation.getTotalSellCost())
.setTotalProfitInFiscalYear(evaluation.getTotalProfit())
.setTotalLossInFiscalYear(evaluation.getTotalLoss());
// check if this security is/must be part of EOY processing in fiscal year
final var hasTransactionsInFiscalYear = evaluation.getPositions().stream()
.anyMatch(p -> p.getTradingDate().getYear() == fiscalYear);
final var hasActivePosition = evaluation.getTotalQuantity() > 0;
answer.setRequiresEoyProcessing(hasTransactionsInFiscalYear || hasActivePosition);
answer.setBuySellPhrase(evaluationStateInfoService.getBuySellPhrase(evaluation));
answer.setProfitLossPhrase(evaluationStateInfoService.getProfitLossPhrase(evaluation));
answer.setEoyEvaluationPhrase(evaluationStateInfoService.getEoyEvaluationPhrase(evaluation));
evaluation.getPositions().forEach(position -> {
final var lineItem = new EvaluationStateDto.LineItem()
.setPublicId(position.getSource().getPublicId())
.setTradingDate(position.getTradingDate())
.setTransactionType(EnumValue.of(position.getPortfolioTransaction().getType()))
.setQuantity(position.getQuantity())
.setPrice(position.getPrice())
.setPrincipleAmount(position.getPrincipleAmount())
.setTotalCost(position.getTotalCost())
.setRemainingQuantityT0(position.at(fiscalYear).quantity())
.setEvaluatedAmountT0(position.getEvaluationAmount(fiscalYear))
.setEvaluationDeltaT0(position.getEvaluationDelta(fiscalYear))
.setRealizedPl(position.getProfitLoss());
if (fiscalYear - 1 >= position.getTradingDate().getYear()) {
lineItem
.setRemainingQuantityT1(position.at(fiscalYear - 1).quantity())
.setEvaluatedAmountT1(position.getEvaluationAmount(fiscalYear - 1))
.setEvaluationDeltaT1(position.getEvaluationDelta(fiscalYear - 1));
}
lineItem.setBucketChanges(position.getChange().stream()
.map(change -> new EvaluationStateDto.BucketChange()
.setOtherChangeAmount(change.otherChangeAmount())
.setOurChangeAmount(change.ourChangeAmount())
.setQuantityAfter(change.quantityAfter())
.setQuantityBefore(change.quantityBefore())
.setSourceDescription(
change.other().getPortfolioTransaction().getType().getDisplayName()
+ " "
+ change.other().getQuantity()
+ "ST")
.setSourceTransactionPublicId(change.other().getPublicId()))
.toList());
answer.getItems().add(lineItem);
});
// e.g. -64.979,05 € in 2024 - RWE AG
final var evaluationTotalDeltaT0 = evaluation.getEvaluationTotalDelta(fiscalYear);
answer.setEvaluationTotalDeltaT0(evaluationTotalDeltaT0);
// e.g. -4.785,99 € € in 2023 - RWE AG
final var evaluationTotalDeltaT1 = evaluation.getEvaluationTotalDelta(fiscalYear - 1);
answer.setEvaluationTotalDeltaT1(evaluationTotalDeltaT1);
answer.setEoyAppreciation(ZERO_AMOUNT);
answer.setEoyAppreciationHr(ZERO_AMOUNT);
answer.setEoyDepreciation(ZERO_AMOUNT);
answer.setEoyDepreciationHr(ZERO_AMOUNT);
final var deltaChange = evaluationTotalDeltaT0.subtract(evaluationTotalDeltaT1);
final var hrResult = new EvaluationHrCalculator(evaluation).calculate();
switch (hrResult.action()) {
case VALUE_INCREASE_WITH_WRITE_UP -> {
answer.setEoyAppreciation(deltaChange.abs());
answer.setEoyAppreciationHr(hrResult.amount());
}
case VALUE_INCREASE_NO_WRITE_UP ->
answer.setEoyAppreciation(deltaChange.abs());
case VALUE_DECREASE_WITH_WRITE_DOWN -> {
answer.setEoyDepreciation(deltaChange.abs());
answer.setEoyDepreciationHr(hrResult.amount());
}
case VALUE_DECREASE_NO_WRITE_DOWN ->
answer.setEoyDepreciation(deltaChange.abs());
default -> {}
}
return answer;
}
}