79 lines
3.7 KiB
Java
79 lines
3.7 KiB
Java
package net.kapcake.bankingservice.validation;
|
|
|
|
import net.kapcake.bankingservice.exceptions.ValidationException;
|
|
import net.kapcake.bankingservice.model.domain.*;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.web.client.RestClientException;
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
import java.util.List;
|
|
|
|
@Component
|
|
public class PaymentValidator {
|
|
|
|
private final RestTemplate restTemplate;
|
|
private final String validationUrl;
|
|
private final List<String> forbiddenAccounts;
|
|
|
|
public PaymentValidator(RestTemplate restTemplate,
|
|
@Value("${banking-service.validation.iban-validator-url:}") String validationUrl,
|
|
@Value("${banking-service.validation.forbidden-accounts:}") List<String> forbiddenAccounts) {
|
|
this.restTemplate = restTemplate;
|
|
this.validationUrl = validationUrl;
|
|
this.forbiddenAccounts = forbiddenAccounts;
|
|
}
|
|
|
|
|
|
public void validate(List<BankAccount> userBankAccounts, Payment payment) throws ValidationException {
|
|
validateGiverAccount(userBankAccounts, payment);
|
|
validateBeneficiaryAccount(payment);
|
|
validateAccountBalance(payment);
|
|
}
|
|
|
|
private static void validateGiverAccount(List<BankAccount> userBankAccounts, Payment payment) {
|
|
boolean userOwnsGiverAccount = userBankAccounts.stream().anyMatch(bankAccount -> bankAccount.getId().equals(payment.getGiverAccount().getId()));
|
|
if (!userOwnsGiverAccount) {
|
|
throw new ValidationException("Giver account not owned by authenticated user.");
|
|
}
|
|
}
|
|
|
|
private void validateBeneficiaryAccount(Payment payment) {
|
|
IbanValidationResponse validationResponse;
|
|
try {
|
|
validationResponse = restTemplate.getForObject(validationUrl + "/" + payment.getBeneficiaryAccountNumber(), IbanValidationResponse.class);
|
|
} catch (RestClientException e) {
|
|
throw new ValidationException("Beneficiary account could not be validated.");
|
|
}
|
|
if (validationResponse == null) {
|
|
throw new ValidationException("Beneficiary account could not be validated.");
|
|
} else if (!validationResponse.valid()) {
|
|
throw new ValidationException("Beneficiary account not valid: " + validationResponse.messages());
|
|
}
|
|
boolean sameGiverAndBeneficiary = payment.getGiverAccount().getAccountNumber().equals(payment.getBeneficiaryAccountNumber());
|
|
if (sameGiverAndBeneficiary) {
|
|
throw new ValidationException("Beneficiary and giver account are the same.");
|
|
}
|
|
boolean isBeneficiaryForbidden = forbiddenAccounts.contains(payment.getBeneficiaryAccountNumber());
|
|
if (isBeneficiaryForbidden) {
|
|
throw new ValidationException("Beneficiary account is forbidden.");
|
|
}
|
|
}
|
|
|
|
private void validateAccountBalance(Payment payment) {
|
|
List<Balance> availableBalances = payment.getGiverAccount().getBalances().stream().filter(balance -> BalanceType.AVAILABLE.equals(balance.getType())).toList();
|
|
if (availableBalances.size() != 1) {
|
|
throw new ValidationException("Unable to retrieve available account balance.");
|
|
}
|
|
Balance balance = availableBalances.get(0);
|
|
boolean sameCurrencies = balance.getCurrency().equals(payment.getCurrency());
|
|
if (!sameCurrencies) {
|
|
throw new ValidationException("Payment and account currency must be the same.");
|
|
}
|
|
int compareResult = balance.getAmount().compareTo(payment.getAmount());
|
|
if (compareResult < 0) {
|
|
throw new ValidationException("Available account balance not sufficient.");
|
|
}
|
|
}
|
|
}
|