private void bookTransfer()

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);
        }
    }