in service/src/main/java/org/apache/fineract/cn/interoperation/service/internal/service/InteropService.java [439:530]
private double bookCharges(@NotNull InteropTransferCommand request, @NotNull AccountWrapper accountWrapper, @NotNull InteropActionEntity action,
@NotNull List<Charge> charges, Account payableAccount, double preparedAmount, LocalDateTime transactionDate) {
boolean isDebit = request.getTransactionRole().isWithdraw();
String accountId = accountWrapper.account.getIdentifier();
String message = request.getNote();
BigDecimal amount = request.getAmount().getAmount();
Currency currency = accountWrapper.productDefinition.getCurrency();
BigDecimal calcFee = MathUtil.normalize(calcTotalCharges(charges, amount), currency);
BigDecimal requestFee = request.getFspFee().getAmount();
if (!MathUtil.isEqualTo(calcFee, requestFee))
throw new UnsupportedOperationException("Quote fee " + requestFee + " differs from transfer fee " + calcFee);
if (MathUtil.isEmpty(calcFee)) {
return preparedAmount;
}
String loginUser = getLoginUser();
String transactionTypeCode = (isDebit ? TransactionType.CURRENCY_WITHDRAWAL : TransactionType.CURRENCY_DEPOSIT).getCode();
String transactionDateString = DateConverter.toIsoString(transactionDate);
ArrayList<Charge> unpaidCharges = new ArrayList<>(charges);
if (preparedAmount > 0) {
InteropActionEntity prepareAction = findAction(action.getTransaction(), InteropActionType.PREPARE);
if (prepareAction != null) {
final JournalEntry fromPrepareToRevenueEntry = createJournalEntry(action.getIdentifier() + InteropRequestData.IDENTIFIER_SEPARATOR + "fee",
transactionTypeCode, transactionDateString, message + " #commit fee", loginUser);
double payedAmount = 0d;
HashSet<Debtor> debtors = new HashSet<>(1);
HashSet<Creditor> creditors = new HashSet<>(1);
for (Charge charge : charges) {
BigDecimal value = calcChargeAmount(amount, charge, currency, true);
if (value == null)
continue;
double doubleValue = value.doubleValue();
if (doubleValue > preparedAmount) {
break;
}
unpaidCharges.remove(charge);
preparedAmount -= doubleValue;
payedAmount += doubleValue;
addDebtor(charge.getIncomeAccountIdentifier(), doubleValue, debtors);
}
if (!unpaidCharges.isEmpty())
throw new UnsupportedOperationException("Prepared amount " + preparedAmount + " is less than transfer fee amount for " +
request.getIdentifier());
if (payedAmount > 0) {
addCreditor(payableAccount.getIdentifier(), payedAmount, creditors);
fromPrepareToRevenueEntry.setDebtors(debtors);
fromPrepareToRevenueEntry.setCreditors(creditors);
accountingService.createJournalEntry(fromPrepareToRevenueEntry);
}
}
}
if (!unpaidCharges.isEmpty()) {
// can not happen that prepared amount is more or less than requested transfer amount (identifier and message can be default)
final JournalEntry journalEntry = createJournalEntry(action.getIdentifier() + InteropRequestData.IDENTIFIER_SEPARATOR + "fee",
transactionTypeCode, transactionDateString, message + " #fee", loginUser);
HashSet<Debtor> debtors = new HashSet<>(1);
HashSet<Creditor> creditors = new HashSet<>(1);
double payedAmount = 0d;
for (Charge charge : charges) {
BigDecimal value = calcChargeAmount(amount, charge, currency, true);
if (value == null)
continue;
double doubleValue = value.doubleValue();
payedAmount += doubleValue;
addDebtor(charge.getIncomeAccountIdentifier(), doubleValue, debtors);
}
if (payedAmount > 0) {
addCreditor(accountId, payedAmount, creditors);
journalEntry.setDebtors(debtors);
journalEntry.setCreditors(creditors);
accountingService.createJournalEntry(journalEntry);
}
}
return preparedAmount;
}