in service/src/main/java/org/apache/fineract/cn/interoperation/service/internal/service/InteropService.java [348:437]
private void bookTransfer(@NotNull InteropTransferCommand request, @NotNull AccountWrapper accountWrapper, @NotNull InteropActionEntity action,
List<Charge> charges, LocalDateTime transactionDate) {
boolean isDebit = request.getTransactionRole().isWithdraw();
String accountId = accountWrapper.account.getIdentifier();
String message = request.getNote();
double doubleAmount = request.getAmount().getAmount().doubleValue();
String loginUser = getLoginUser();
String transactionTypeCode = (isDebit ? TransactionType.CURRENCY_WITHDRAWAL : TransactionType.CURRENCY_DEPOSIT).getCode();
String transactionDateString = DateConverter.toIsoString(transactionDate);
InteropTransactionEntity transaction = action.getTransaction();
Account nostroAccount = validateAndGetAccount(request, transaction.getNostroAccountIdentifier());
Account payableAccount = null;
double preparedAmount = 0d;
double accountNostroAmount = doubleAmount;
if (isDebit) {
InteropActionEntity prepareAction = findAction(transaction, InteropActionType.PREPARE);
if (prepareAction != null) {
JournalEntry prepareJournal = accountingService.findJournalEntry(prepareAction.getIdentifier());
if (prepareJournal == null)
throw new UnsupportedOperationException("Can not find prepare result for " + action.getActionType() +
"/" + request.getIdentifier());
payableAccount = validateAndGetAccount(request, transaction.getPrepareAccountIdentifier());
preparedAmount = prepareJournal.getDebtors().stream().mapToDouble(d -> Double.valueOf(d.getAmount())).sum();
if (preparedAmount < doubleAmount)
throw new UnsupportedOperationException("Prepared amount " + preparedAmount + " is less than transfer amount " +
doubleAmount + " for " + request.getIdentifier());
// now fails if prepared is not enough
accountNostroAmount = preparedAmount >= doubleAmount ? 0d : doubleAmount - preparedAmount;
double fromPrepareToNostroAmount = doubleAmount - accountNostroAmount;
preparedAmount -= fromPrepareToNostroAmount;
if (fromPrepareToNostroAmount > 0) {
final JournalEntry fromPrepareToNostroEntry = createJournalEntry(action.getIdentifier(),
transactionTypeCode, transactionDateString, message + " #commit", loginUser);
HashSet<Debtor> debtors = new HashSet<>(1);
HashSet<Creditor> creditors = new HashSet<>(1);
addCreditor(payableAccount.getIdentifier(), fromPrepareToNostroAmount, creditors);
addDebtor(nostroAccount.getIdentifier(), fromPrepareToNostroAmount, debtors);
fromPrepareToNostroEntry.setDebtors(debtors);
fromPrepareToNostroEntry.setCreditors(creditors);
accountingService.createJournalEntry(fromPrepareToNostroEntry);
}
}
}
if (accountNostroAmount > 0) {
// can not happen that prepared amount is less than requested transfer amount (identifier and message can be default)
final JournalEntry journalEntry = createJournalEntry(action.getIdentifier(), transactionTypeCode,
transactionDateString, message/* + (payableAccount == null ? "" : " #difference")*/, loginUser);
HashSet<Debtor> debtors = new HashSet<>(1);
HashSet<Creditor> creditors = new HashSet<>(1);
addCreditor(isDebit ? accountId : nostroAccount.getIdentifier(), accountNostroAmount, creditors);
addDebtor(isDebit ? nostroAccount.getIdentifier() : accountId, accountNostroAmount, debtors);
journalEntry.setDebtors(debtors);
journalEntry.setCreditors(creditors);
accountingService.createJournalEntry(journalEntry);
}
preparedAmount = bookCharges(request, accountWrapper, action, charges, payableAccount, preparedAmount, transactionDate);
if (preparedAmount > 0) {
// throw new UnsupportedOperationException("Prepared amount differs from transfer amount " + doubleAmount + " for " + request.getIdentifier());
// transfer back remaining prepared amount TODO: JM maybe fail this case?
final JournalEntry fromPrepareToAccountEntry = createJournalEntry(action.getIdentifier() + InteropRequestData.IDENTIFIER_SEPARATOR + "diff",
transactionTypeCode, transactionDateString, message + " #release difference", loginUser);
HashSet<Debtor> debtors = new HashSet<>(1);
HashSet<Creditor> creditors = new HashSet<>(1);
addCreditor(payableAccount.getIdentifier(), preparedAmount, creditors);
addDebtor(accountId, preparedAmount, debtors);
fromPrepareToAccountEntry.setDebtors(debtors);
fromPrepareToAccountEntry.setCreditors(creditors);
accountingService.createJournalEntry(fromPrepareToAccountEntry);
}
}