Implemented disbursement of full loan amount.
diff --git a/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java b/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java
index 4498f46..4e7a98e 100644
--- a/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java
+++ b/component-test/src/main/java/io/mifos/portfolio/AbstractPortfolioTest.java
@@ -25,11 +25,13 @@
 import io.mifos.core.test.listener.EnableEventRecording;
 import io.mifos.core.test.listener.EventRecorder;
 import io.mifos.individuallending.api.v1.client.IndividualLending;
+import io.mifos.individuallending.api.v1.domain.product.AccountDesignators;
 import io.mifos.individuallending.api.v1.domain.workflow.Action;
 import io.mifos.individuallending.api.v1.events.IndividualLoanCommandEvent;
 import io.mifos.portfolio.api.v1.client.PortfolioManager;
 import io.mifos.portfolio.api.v1.domain.*;
 import io.mifos.portfolio.api.v1.events.CaseEvent;
+import io.mifos.portfolio.api.v1.events.ChargeDefinitionEvent;
 import io.mifos.portfolio.api.v1.events.EventConstants;
 import io.mifos.portfolio.service.config.PortfolioServiceConfiguration;
 import io.mifos.portfolio.service.internal.util.AccountingAdapter;
@@ -42,6 +44,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.cloud.netflix.feign.EnableFeignClients;
@@ -56,6 +59,7 @@
 import javax.validation.Validation;
 import javax.validation.Validator;
 import javax.validation.ValidatorFactory;
+import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -74,6 +78,7 @@
         classes = {AbstractPortfolioTest.TestConfiguration.class})
 public class AbstractPortfolioTest {
   private static final String APP_NAME = "portfolio-v1";
+  private static final String LOGGER_NAME = "test-logger";
 
   @Configuration
   @EnableEventRecording
@@ -86,9 +91,9 @@
       super();
     }
 
-    @Bean()
+    @Bean(name = LOGGER_NAME)
     public Logger logger() {
-      return LoggerFactory.getLogger("test-logger");
+      return LoggerFactory.getLogger(LOGGER_NAME);
     }
     @Bean()
     public AccountingAdapter accountingAdapter(@SuppressWarnings("SpringJavaAutowiringInspection")
@@ -136,6 +141,10 @@
   @MockBean
   LedgerManager ledgerManager;
 
+  @Autowired
+  @Qualifier(LOGGER_NAME)
+  Logger logger;
+
   @Before
   public void prepTest() {
     userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(TEST_USER);
@@ -235,4 +244,25 @@
     final Set<CostComponent> setOfExpectedCostComponents = new HashSet<>(Arrays.asList(expectedCostComponents));
     Assert.assertEquals(setOfExpectedCostComponents, setOfCostComponents);
   }
+
+  void setFeeToFixedValue(final String productIdentifier,
+                          final String feeId,
+                          final BigDecimal amount) throws InterruptedException {
+    final ChargeDefinition chargeDefinition
+        = portfolioManager.getChargeDefinition(productIdentifier, feeId);
+    chargeDefinition.setChargeMethod(ChargeDefinition.ChargeMethod.FIXED);
+    chargeDefinition.setAmount(amount);
+    chargeDefinition.setProportionalTo(null);
+    portfolioManager.changeChargeDefinition(productIdentifier, feeId, chargeDefinition);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CHARGE_DEFINITION,
+        new ChargeDefinitionEvent(productIdentifier, feeId)));
+  }
+
+  AccountAssignment assignEntryToTeller() {
+    final AccountAssignment entryAccountAssignment = new AccountAssignment();
+    entryAccountAssignment.setDesignator(AccountDesignators.ENTRY);
+    entryAccountAssignment.setAccountIdentifier(AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER);
+    return entryAccountAssignment;
+  }
+
 }
diff --git a/component-test/src/main/java/io/mifos/portfolio/AccountingFixture.java b/component-test/src/main/java/io/mifos/portfolio/AccountingFixture.java
index c5d87fb..89f9ccb 100644
--- a/component-test/src/main/java/io/mifos/portfolio/AccountingFixture.java
+++ b/component-test/src/main/java/io/mifos/portfolio/AccountingFixture.java
@@ -29,18 +29,35 @@
 import java.util.Collections;
 import java.util.Set;
 
-import static io.mifos.portfolio.Fixture.*;
 import static org.mockito.Matchers.argThat;
 
 /**
  * @author Myrle Krantz
  */
+@SuppressWarnings("Duplicates")
 class AccountingFixture {
+  private static final String INCOME_LEDGER_IDENTIFIER = "1000";
+  private static final String LOAN_INCOME_LEDGER_IDENTIFIER = "1100";
+  private static final String FEES_AND_CHARGES_LEDGER_IDENTIFIER = "1300";
+  private static final String ASSET_LEDGER_IDENTIFIER = "7000";
+  private static final String CASH_LEDGER_IDENTIFIER = "7300";
+  static final String PENDING_DISBURSAL_LEDGER_IDENTIFIER = "7320";
+  static final String CUSTOMER_LOAN_LEDGER_IDENTIFIER = "7353";
+  private static final String ACCRUED_INCOME_LEDGER_IDENTIFIER = "7800";
+
+  static final String LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER = "7310";
+  static final String LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER = "1310";
+  static final String PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER = "1312";
+  static final String DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER = "1313";
+  static final String TELLER_ONE_ACCOUNT_IDENTIFIER = "7352";
+  static final String LOAN_INTEREST_ACCRUAL_ACCOUNT = "7810";
+  static final String CONSUMER_LOAN_INTEREST_ACCOUNT = "1103";
 
 
   private static Ledger cashLedger() {
     final Ledger ret = new Ledger();
     ret.setIdentifier(CASH_LEDGER_IDENTIFIER);
+    ret.setParentLedgerIdentifier(ASSET_LEDGER_IDENTIFIER);
     ret.setType(AccountType.ASSET.name());
     return ret;
   }
@@ -76,6 +93,24 @@
     return ret;
   }
 
+  private static Ledger loanIncomeLedger() {
+    final Ledger ret = new Ledger();
+    ret.setIdentifier(LOAN_INCOME_LEDGER_IDENTIFIER);
+    ret.setParentLedgerIdentifier(INCOME_LEDGER_IDENTIFIER);
+    ret.setType(AccountType.REVENUE.name());
+    return ret;
+
+  }
+
+  private static Ledger accruedIncomeLedger() {
+    final Ledger ret = new Ledger();
+    ret.setIdentifier(ACCRUED_INCOME_LEDGER_IDENTIFIER);
+    ret.setParentLedgerIdentifier(ASSET_LEDGER_IDENTIFIER);
+    ret.setType(AccountType.ASSET.name());
+    return ret;
+
+  }
+
   private static Account loanFundsSourceAccount() {
     final Account ret = new Account();
     ret.setIdentifier(LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER);
@@ -100,6 +135,14 @@
     return ret;
   }
 
+  private static Account disbursementFeeIncomeAccount() {
+    final Account ret = new Account();
+    ret.setIdentifier(DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER);
+    ret.setLedger(FEES_AND_CHARGES_LEDGER_IDENTIFIER);
+    ret.setType(AccountType.REVENUE.name());
+    return ret;
+  }
+
   private static Account tellerOneAccount() {
     final Account ret = new Account();
     ret.setIdentifier(TELLER_ONE_ACCOUNT_IDENTIFIER);
@@ -108,6 +151,22 @@
     return ret;
   }
 
+  private static Account loanInterestAccrualAccount() {
+    final Account ret = new Account();
+    ret.setIdentifier(LOAN_INTEREST_ACCRUAL_ACCOUNT);
+    ret.setLedger(ACCRUED_INCOME_LEDGER_IDENTIFIER);
+    ret.setType(AccountType.ASSET.name());
+    return ret;
+  }
+
+  private static Account consumerLoanInterestAccount() {
+    final Account ret = new Account();
+    ret.setIdentifier(CONSUMER_LOAN_INTEREST_ACCOUNT);
+    ret.setLedger(LOAN_INCOME_LEDGER_IDENTIFIER);
+    ret.setType(AccountType.REVENUE.name());
+    return ret;
+  }
+
   private static AccountPage customerLoanAccountsPage() {
     final Account customerLoanAccount1 = new Account();
     customerLoanAccount1.setIdentifier("customerLoanAccount1");
@@ -157,12 +216,12 @@
   private static class AccountMatcher extends ArgumentMatcher<Account> {
     private final String ledgerIdentifer;
     private final AccountType type;
-    private Account checkedArgument;
+    private Account matchedArgument;
 
     private AccountMatcher(final String ledgerIdentifier, final AccountType type) {
       this.ledgerIdentifer = ledgerIdentifier;
       this.type = type;
-      this.checkedArgument = null; //Set when matches called.
+      this.matchedArgument = null; //Set when matches called and returns true.
     }
 
     @Override
@@ -172,15 +231,20 @@
       if (! (argument instanceof Account))
         return false;
 
-      checkedArgument = (Account) argument;
+      final Account checkedArgument = (Account) argument;
 
-      return checkedArgument.getLedger().equals(ledgerIdentifer) &&
-              checkedArgument.getType().equals(type.name()) &&
-              checkedArgument.getBalance() == 0.0;
+      final boolean ret = checkedArgument.getLedger().equals(ledgerIdentifer) &&
+          checkedArgument.getType().equals(type.name()) &&
+          checkedArgument.getBalance() == 0.0;
+
+      if (ret)
+        matchedArgument = checkedArgument;
+
+      return ret;
     }
 
-    Account getCheckedArgument() {
-      return checkedArgument;
+    Account getMatchedArgument() {
+      return matchedArgument;
     }
   }
 
@@ -232,10 +296,15 @@
     Mockito.doReturn(cashLedger()).when(ledgerManagerMock).findLedger(CASH_LEDGER_IDENTIFIER);
     Mockito.doReturn(pendingDisbursalLedger()).when(ledgerManagerMock).findLedger(PENDING_DISBURSAL_LEDGER_IDENTIFIER);
     Mockito.doReturn(customerLoanLedger()).when(ledgerManagerMock).findLedger(CUSTOMER_LOAN_LEDGER_IDENTIFIER);
+    Mockito.doReturn(loanIncomeLedger()).when(ledgerManagerMock).findLedger(LOAN_INCOME_LEDGER_IDENTIFIER);
+    Mockito.doReturn(accruedIncomeLedger()).when(ledgerManagerMock).findLedger(ACCRUED_INCOME_LEDGER_IDENTIFIER);
     Mockito.doReturn(loanFundsSourceAccount()).when(ledgerManagerMock).findAccount(LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER);
     Mockito.doReturn(loanOriginationFeesIncomeAccount()).when(ledgerManagerMock).findAccount(LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER);
     Mockito.doReturn(processingFeeIncomeAccount()).when(ledgerManagerMock).findAccount(PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER);
+    Mockito.doReturn(disbursementFeeIncomeAccount()).when(ledgerManagerMock).findAccount(DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER);
     Mockito.doReturn(tellerOneAccount()).when(ledgerManagerMock).findAccount(TELLER_ONE_ACCOUNT_IDENTIFIER);
+    Mockito.doReturn(loanInterestAccrualAccount()).when(ledgerManagerMock).findAccount(LOAN_INTEREST_ACCRUAL_ACCOUNT);
+    Mockito.doReturn(consumerLoanInterestAccount()).when(ledgerManagerMock).findAccount(CONSUMER_LOAN_INTEREST_ACCOUNT);
     Mockito.doReturn(customerLoanAccountsPage()).when(ledgerManagerMock).fetchAccountsOfLedger(Mockito.eq(CUSTOMER_LOAN_LEDGER_IDENTIFIER),
             Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
     Mockito.doReturn(pendingDisbursalAccountsPage()).when(ledgerManagerMock).fetchAccountsOfLedger(Mockito.eq(PENDING_DISBURSAL_LEDGER_IDENTIFIER),
@@ -247,7 +316,7 @@
                                       final AccountType type) {
     final AccountMatcher specifiesCorrectAccount = new AccountMatcher(ledgerIdentifier, type);
     Mockito.verify(ledgerManager).createAccount(AdditionalMatchers.and(argThat(isValid()), argThat(specifiesCorrectAccount)));
-    return specifiesCorrectAccount.getCheckedArgument().getIdentifier();
+    return specifiesCorrectAccount.getMatchedArgument().getIdentifier();
   }
 
   static void verifyTransfer(final LedgerManager ledgerManager,
diff --git a/component-test/src/main/java/io/mifos/portfolio/Fixture.java b/component-test/src/main/java/io/mifos/portfolio/Fixture.java
index 3ad05ee..5d60486 100644
--- a/component-test/src/main/java/io/mifos/portfolio/Fixture.java
+++ b/component-test/src/main/java/io/mifos/portfolio/Fixture.java
@@ -28,6 +28,7 @@
 import java.util.function.Consumer;
 
 import static io.mifos.individuallending.api.v1.domain.product.AccountDesignators.*;
+import static io.mifos.portfolio.AccountingFixture.*;
 import static java.math.BigDecimal.ROUND_HALF_EVEN;
 
 /**
@@ -36,16 +37,8 @@
 
 @SuppressWarnings({"WeakerAccess", "unused"})
 public class Fixture {
-  static final String INCOME_LEDGER_IDENTIFIER = "1000";
-  static final String FEES_AND_CHARGES_LEDGER_IDENTIFIER = "1300";
-  static final String CASH_LEDGER_IDENTIFIER = "7300";
-  static final String PENDING_DISBURSAL_LEDGER_IDENTIFIER = "7320";
-  static final String CUSTOMER_LOAN_LEDGER_IDENTIFIER = "7353";
-  static final String LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER = "7310";
-  static final String LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER = "1310";
-  static final String PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER = "1312";
-  static final String TELLER_ONE_ACCOUNT_IDENTIFIER = "7352";
 
+  public static final int MINOR_CURRENCY_UNIT_DIGITS = 2;
   private static int uniquenessSuffix = 0;
 
   static public Product getTestProduct() {
@@ -60,7 +53,7 @@
     product.setInterestBasis(InterestBasis.CURRENT_BALANCE);
 
     product.setCurrencyCode("XXX");
-    product.setMinorCurrencyUnitDigits(2);
+    product.setMinorCurrencyUnitDigits(MINOR_CURRENCY_UNIT_DIGITS);
 
     final Set<AccountAssignment> accountAssignments = new HashSet<>();
     final AccountAssignment pendingDisbursalAccountAssignment = new AccountAssignment();
@@ -69,9 +62,9 @@
     accountAssignments.add(pendingDisbursalAccountAssignment);
     accountAssignments.add(new AccountAssignment(PROCESSING_FEE_INCOME, PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER));
     accountAssignments.add(new AccountAssignment(ORIGINATION_FEE_INCOME, LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER));
-    accountAssignments.add(new AccountAssignment(DISBURSEMENT_FEE_INCOME, "001-004"));
-    accountAssignments.add(new AccountAssignment(INTEREST_INCOME, "001-005"));
-    accountAssignments.add(new AccountAssignment(INTEREST_ACCRUAL, "001-007"));
+    accountAssignments.add(new AccountAssignment(DISBURSEMENT_FEE_INCOME, DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER));
+    accountAssignments.add(new AccountAssignment(INTEREST_INCOME, CONSUMER_LOAN_INTEREST_ACCOUNT));
+    accountAssignments.add(new AccountAssignment(INTEREST_ACCRUAL, LOAN_INTEREST_ACCRUAL_ACCOUNT));
     accountAssignments.add(new AccountAssignment(LATE_FEE_INCOME, "001-008"));
     accountAssignments.add(new AccountAssignment(LATE_FEE_ACCRUAL, "001-009"));
     accountAssignments.add(new AccountAssignment(ARREARS_ALLOWANCE, "001-010"));
@@ -107,7 +100,7 @@
 
   static public BigDecimal fixScale(final BigDecimal bigDecimal)
   {
-    return bigDecimal.setScale(4, ROUND_HALF_EVEN);
+    return bigDecimal.setScale(MINOR_CURRENCY_UNIT_DIGITS, ROUND_HALF_EVEN);
   }
 
   static public Case getTestCase(final String productIdentifier) {
@@ -118,8 +111,6 @@
 
 
     final Set<AccountAssignment> accountAssignments = new HashSet<>();
-    accountAssignments.add(new AccountAssignment(CUSTOMER_LOAN, "001-011"));
-    accountAssignments.add(new AccountAssignment(ENTRY, "001-012"));
     ret.setAccountAssignments(accountAssignments);
     ret.setCurrentState(Case.State.CREATED.name());
 
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteraction.java b/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteraction.java
deleted file mode 100644
index 91bf999..0000000
--- a/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteraction.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.mifos.portfolio;
-
-import com.google.gson.Gson;
-import io.mifos.accounting.api.v1.domain.AccountType;
-import io.mifos.accounting.api.v1.domain.Creditor;
-import io.mifos.accounting.api.v1.domain.Debtor;
-import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters;
-import io.mifos.individuallending.api.v1.domain.workflow.Action;
-import io.mifos.portfolio.api.v1.domain.*;
-import io.mifos.portfolio.api.v1.events.ChargeDefinitionEvent;
-import io.mifos.portfolio.api.v1.events.EventConstants;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.math.BigDecimal;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import static io.mifos.individuallending.api.v1.domain.product.ChargeIdentifiers.*;
-import static io.mifos.individuallending.api.v1.events.IndividualLoanEventConstants.APPROVE_INDIVIDUALLOAN_CASE;
-import static io.mifos.individuallending.api.v1.events.IndividualLoanEventConstants.OPEN_INDIVIDUALLOAN_CASE;
-import static io.mifos.portfolio.Fixture.*;
-
-/**
- * @author Myrle Krantz
- */
-public class TestAccountingInteraction extends AbstractPortfolioTest {
-
-  @Test
-  public void testLoanApproval() throws InterruptedException {
-    //Create product and set charges to fixed fees.
-    final Product product = createProduct();
-
-    final ChargeDefinition processingFee = portfolioManager.getChargeDefinition(product.getIdentifier(), PROCESSING_FEE_ID);
-    processingFee.setChargeMethod(ChargeDefinition.ChargeMethod.FIXED);
-    processingFee.setAmount(BigDecimal.valueOf(10_0000, 4));
-    processingFee.setProportionalTo(null);
-    portfolioManager.changeChargeDefinition(product.getIdentifier(), PROCESSING_FEE_ID, processingFee);
-    Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CHARGE_DEFINITION,
-            new ChargeDefinitionEvent(product.getIdentifier(), PROCESSING_FEE_ID)));
-
-    final ChargeDefinition loanOriginationFee = portfolioManager.getChargeDefinition(product.getIdentifier(), LOAN_ORIGINATION_FEE_ID);
-    loanOriginationFee.setChargeMethod(ChargeDefinition.ChargeMethod.FIXED);
-    loanOriginationFee.setAmount(BigDecimal.valueOf(100_0000, 4));
-    loanOriginationFee.setProportionalTo(null);
-    portfolioManager.changeChargeDefinition(product.getIdentifier(), LOAN_ORIGINATION_FEE_ID, loanOriginationFee);
-    Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CHARGE_DEFINITION,
-            new ChargeDefinitionEvent(product.getIdentifier(), LOAN_ORIGINATION_FEE_ID)));
-
-    portfolioManager.enableProduct(product.getIdentifier(), true);
-    Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_PRODUCT_ENABLE, product.getIdentifier()));
-
-    //Create case.
-    final CaseParameters caseParameters = Fixture.createAdjustedCaseParameters(x -> {});
-    final String caseParametersAsString = new Gson().toJson(caseParameters);
-    final Case customerCase = createAdjustedCase(product.getIdentifier(), x -> x.setParameters(caseParametersAsString));
-
-    //Open the case and accept a processing fee.
-    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN);
-    checkCostComponentForActionCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN,
-            new CostComponent(processingFee.getIdentifier(), processingFee.getAmount().setScale(product.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_UNNECESSARY)));
-
-    final AccountAssignment openCommandProcessingFeeAccountAssignment = new AccountAssignment();
-    openCommandProcessingFeeAccountAssignment.setDesignator(processingFee.getFromAccountDesignator());
-    openCommandProcessingFeeAccountAssignment.setAccountIdentifier(TELLER_ONE_ACCOUNT_IDENTIFIER);
-
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN,
-            Collections.singletonList(openCommandProcessingFeeAccountAssignment),
-            OPEN_INDIVIDUALLOAN_CASE, Case.State.PENDING);
-    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE, Action.DENY);
-    checkCostComponentForActionCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE,
-            new CostComponent(loanOriginationFee.getIdentifier(), loanOriginationFee.getAmount().setScale(product.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_UNNECESSARY)),
-            new CostComponent(LOAN_FUNDS_ALLOCATION_ID, caseParameters.getMaximumBalance().setScale(product.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_UNNECESSARY)));
-
-    AccountingFixture.verifyTransfer(ledgerManager,
-            TELLER_ONE_ACCOUNT_IDENTIFIER, PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER,
-            processingFee.getAmount().setScale(product.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_UNNECESSARY)
-            );
-
-
-    //Approve the case, accept a loan origination fee, and prepare to disburse the loan by earmarking the funds.
-    final AccountAssignment approveCommandOriginationFeeAccountAssignment = new AccountAssignment();
-    approveCommandOriginationFeeAccountAssignment.setDesignator(loanOriginationFee.getFromAccountDesignator());
-    approveCommandOriginationFeeAccountAssignment.setAccountIdentifier(TELLER_ONE_ACCOUNT_IDENTIFIER);
-
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE,
-            Collections.singletonList(approveCommandOriginationFeeAccountAssignment),
-            APPROVE_INDIVIDUALLOAN_CASE, Case.State.APPROVED);
-    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, Action.CLOSE);
-
-    final String pendingDisbursalAccountIdentifier =
-            AccountingFixture.verifyAccountCreation(ledgerManager, Fixture.PENDING_DISBURSAL_LEDGER_IDENTIFIER, AccountType.ASSET);
-    final String customerLoanAccountIdentifier =
-            AccountingFixture.verifyAccountCreation(ledgerManager, Fixture.CUSTOMER_LOAN_LEDGER_IDENTIFIER, AccountType.ASSET);
-
-    final Set<Debtor> debtors = new HashSet<>();
-    debtors.add(new Debtor(LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER, toString(caseParameters.getMaximumBalance(), product.getMinorCurrencyUnitDigits())));
-    debtors.add(new Debtor(TELLER_ONE_ACCOUNT_IDENTIFIER, toString(loanOriginationFee.getAmount(), product.getMinorCurrencyUnitDigits())));
-
-    final Set<Creditor> creditors = new HashSet<>();
-    creditors.add(new Creditor(pendingDisbursalAccountIdentifier, toString(caseParameters.getMaximumBalance(), product.getMinorCurrencyUnitDigits())));
-    creditors.add(new Creditor(LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER, toString(loanOriginationFee.getAmount(), product.getMinorCurrencyUnitDigits())));
-    AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors);
-  }
-
-  private String toString(final BigDecimal bigDecimal, final int scale) {
-    return bigDecimal.setScale(scale, BigDecimal.ROUND_UNNECESSARY).toPlainString();
-  }
-}
\ No newline at end of file
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java b/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
new file mode 100644
index 0000000..7ec81c9
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.mifos.portfolio;
+
+import com.google.gson.Gson;
+import io.mifos.accounting.api.v1.domain.AccountType;
+import io.mifos.accounting.api.v1.domain.Creditor;
+import io.mifos.accounting.api.v1.domain.Debtor;
+import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters;
+import io.mifos.individuallending.api.v1.domain.product.ChargeIdentifiers;
+import io.mifos.individuallending.api.v1.domain.workflow.Action;
+import io.mifos.portfolio.api.v1.domain.Case;
+import io.mifos.portfolio.api.v1.domain.CostComponent;
+import io.mifos.portfolio.api.v1.domain.Product;
+import io.mifos.portfolio.api.v1.events.EventConstants;
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static io.mifos.individuallending.api.v1.events.IndividualLoanEventConstants.*;
+import static io.mifos.portfolio.Fixture.MINOR_CURRENCY_UNIT_DIGITS;
+
+/**
+ * @author Myrle Krantz
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestAccountingInteractionInLoanWorkflow extends AbstractPortfolioTest {
+  private static final BigDecimal PROCESSING_FEE_AMOUNT = BigDecimal.valueOf(10_0000, MINOR_CURRENCY_UNIT_DIGITS);
+  private static final BigDecimal LOAN_ORIGINATION_FEE_AMOUNT = BigDecimal.valueOf(100_0000, MINOR_CURRENCY_UNIT_DIGITS);
+  private static final BigDecimal DISBURSEMENT_FEE_AMOUNT = BigDecimal.valueOf(1_0000, MINOR_CURRENCY_UNIT_DIGITS);
+
+  private static Product product;
+  private static Case customerCase;
+  private static CaseParameters caseParameters;
+  private static String pendingDisbursalAccountIdentifier;
+  private static String customerLoanAccountIdentifier;
+
+
+  @Test
+  public void step1CreateProduct() throws InterruptedException {
+    //Create product and set charges to fixed fees.
+    product = createProduct();
+
+    setFeeToFixedValue(product.getIdentifier(), ChargeIdentifiers.PROCESSING_FEE_ID, PROCESSING_FEE_AMOUNT);
+    setFeeToFixedValue(product.getIdentifier(), ChargeIdentifiers.LOAN_ORIGINATION_FEE_ID, LOAN_ORIGINATION_FEE_AMOUNT);
+    setFeeToFixedValue(product.getIdentifier(), ChargeIdentifiers.DISBURSEMENT_FEE_ID, DISBURSEMENT_FEE_AMOUNT);
+
+    portfolioManager.enableProduct(product.getIdentifier(), true);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_PRODUCT_ENABLE, product.getIdentifier()));
+  }
+
+  @Test
+  public void step2CreateCase() throws InterruptedException {
+    //Create case.
+    caseParameters = Fixture.createAdjustedCaseParameters(x -> {
+    });
+    final String caseParametersAsString = new Gson().toJson(caseParameters);
+    customerCase = createAdjustedCase(product.getIdentifier(), x -> x.setParameters(caseParametersAsString));
+
+    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN);
+    checkCostComponentForActionCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN,
+        new CostComponent(ChargeIdentifiers.PROCESSING_FEE_ID, PROCESSING_FEE_AMOUNT));
+  }
+
+  //Open the case and accept a processing fee.
+  @Test
+  public void step3OpenCase() throws InterruptedException {
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.OPEN,
+        Collections.singletonList(assignEntryToTeller()),
+        OPEN_INDIVIDUALLOAN_CASE,
+        Case.State.PENDING);
+    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE, Action.DENY);
+    checkCostComponentForActionCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE,
+        new CostComponent(ChargeIdentifiers.LOAN_ORIGINATION_FEE_ID, LOAN_ORIGINATION_FEE_AMOUNT),
+        new CostComponent(ChargeIdentifiers.LOAN_FUNDS_ALLOCATION_ID, caseParameters.getMaximumBalance().setScale(product.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_UNNECESSARY)));
+
+    AccountingFixture.verifyTransfer(ledgerManager,
+        AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER, AccountingFixture.PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER,
+        PROCESSING_FEE_AMOUNT
+    );
+  }
+
+
+  //Approve the case, accept a loan origination fee, and prepare to disburse the loan by earmarking the funds.
+  @Test
+  public void step4ApproveCase() throws InterruptedException {
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.APPROVE,
+        Collections.singletonList(assignEntryToTeller()),
+        APPROVE_INDIVIDUALLOAN_CASE,
+        Case.State.APPROVED);
+    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, Action.CLOSE);
+
+    pendingDisbursalAccountIdentifier =
+        AccountingFixture.verifyAccountCreation(ledgerManager, AccountingFixture.PENDING_DISBURSAL_LEDGER_IDENTIFIER, AccountType.ASSET);
+    customerLoanAccountIdentifier =
+        AccountingFixture.verifyAccountCreation(ledgerManager, AccountingFixture.CUSTOMER_LOAN_LEDGER_IDENTIFIER, AccountType.ASSET);
+
+    final Set<Debtor> debtors = new HashSet<>();
+    debtors.add(new Debtor(AccountingFixture.LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER, caseParameters.getMaximumBalance().toPlainString()));
+    debtors.add(new Debtor(AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER, LOAN_ORIGINATION_FEE_AMOUNT.toPlainString()));
+
+    final Set<Creditor> creditors = new HashSet<>();
+    creditors.add(new Creditor(pendingDisbursalAccountIdentifier, caseParameters.getMaximumBalance().toPlainString()));
+    creditors.add(new Creditor(AccountingFixture.LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER, LOAN_ORIGINATION_FEE_AMOUNT.toPlainString()));
+    AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors);
+  }
+
+  //Approve the case, accept a loan origination fee, and prepare to disburse the loan by earmarking the funds.
+  @Test
+  public void step5DisburseFullAmount() throws InterruptedException {
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.DISBURSE,
+        Collections.singletonList(assignEntryToTeller()),
+        DISBURSE_INDIVIDUALLOAN_CASE,
+        Case.State.ACTIVE);
+    checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPLY_INTEREST,
+        Action.APPLY_INTEREST, Action.MARK_LATE, Action.ACCEPT_PAYMENT, Action.DISBURSE, Action.WRITE_OFF, Action.CLOSE);
+
+
+    final Set<Debtor> debtors = new HashSet<>();
+    debtors.add(new Debtor(pendingDisbursalAccountIdentifier, caseParameters.getMaximumBalance().toPlainString()));
+    debtors.add(new Debtor(AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER, DISBURSEMENT_FEE_AMOUNT.toPlainString()));
+
+    final Set<Creditor> creditors = new HashSet<>();
+    creditors.add(new Creditor(customerLoanAccountIdentifier, caseParameters.getMaximumBalance().toPlainString()));
+    creditors.add(new Creditor(AccountingFixture.DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER, DISBURSEMENT_FEE_AMOUNT.toPlainString()));
+    AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors);
+
+  }
+}
\ No newline at end of file
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestCases.java b/component-test/src/main/java/io/mifos/portfolio/TestCases.java
index 1112a68..6bfc9f1 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestCases.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestCases.java
@@ -132,7 +132,7 @@
     final List<CreditWorthinessFactor> debts = caseParameters.getCreditWorthinessSnapshots().get(0).getDebts();
     final ArrayList<CreditWorthinessFactor> newDebts = new ArrayList<>();
     newDebts.addAll(debts);
-    newDebts.add(new CreditWorthinessFactor("boop", BigDecimal.valueOf(5, 4)));
+    newDebts.add(new CreditWorthinessFactor("boop", BigDecimal.valueOf(5, Fixture.MINOR_CURRENCY_UNIT_DIGITS)));
     caseParameters.getCreditWorthinessSnapshots().get(0).setDebts(newDebts);
     final String changedParameters = new Gson().toJson(caseParameters);
     caseInstance.setParameters(changedParameters);
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestCommands.java b/component-test/src/main/java/io/mifos/portfolio/TestCommands.java
index 22b3b33..dae6f62 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestCommands.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestCommands.java
@@ -17,6 +17,7 @@
 
 import io.mifos.individuallending.api.v1.domain.workflow.Action;
 import io.mifos.individuallending.api.v1.events.IndividualLoanCommandEvent;
+import io.mifos.portfolio.api.v1.domain.AccountAssignment;
 import io.mifos.portfolio.api.v1.domain.Case;
 import io.mifos.portfolio.api.v1.domain.Command;
 import io.mifos.portfolio.api.v1.domain.Product;
@@ -24,6 +25,7 @@
 import org.junit.Test;
 
 import java.util.Collections;
+import java.util.List;
 
 import static io.mifos.individuallending.api.v1.events.IndividualLoanEventConstants.*;
 
@@ -39,29 +41,64 @@
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN, null, OPEN_INDIVIDUALLOAN_CASE, Case.State.PENDING);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.OPEN,
+        Collections.singletonList(assignEntryToTeller()),
+        OPEN_INDIVIDUALLOAN_CASE,
+        Case.State.PENDING);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE, Action.DENY);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE, null, APPROVE_INDIVIDUALLOAN_CASE, Case.State.APPROVED);
+    checkStateTransfer(product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.APPROVE,
+        Collections.singletonList(assignEntryToTeller()),
+        APPROVE_INDIVIDUALLOAN_CASE,
+        Case.State.APPROVED);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, Action.CLOSE);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, null, DISBURSE_INDIVIDUALLOAN_CASE, Case.State.ACTIVE);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.DISBURSE,
+        Collections.singletonList(assignEntryToTeller()),
+        DISBURSE_INDIVIDUALLOAN_CASE,
+        Case.State.ACTIVE);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(),
             Action.APPLY_INTEREST, Action.MARK_LATE, Action.ACCEPT_PAYMENT, Action.DISBURSE, Action.WRITE_OFF, Action.CLOSE);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.ACCEPT_PAYMENT, null, ACCEPT_PAYMENT_INDIVIDUALLOAN_CASE, Case.State.ACTIVE);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.ACCEPT_PAYMENT,
+        Collections.singletonList(assignEntryToTeller()),
+        ACCEPT_PAYMENT_INDIVIDUALLOAN_CASE,
+        Case.State.ACTIVE);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(),
             Action.APPLY_INTEREST, Action.MARK_LATE, Action.ACCEPT_PAYMENT, Action.DISBURSE, Action.WRITE_OFF, Action.CLOSE);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.ACCEPT_PAYMENT, null, ACCEPT_PAYMENT_INDIVIDUALLOAN_CASE, Case.State.ACTIVE);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.ACCEPT_PAYMENT,
+        Collections.singletonList(assignEntryToTeller()),
+        ACCEPT_PAYMENT_INDIVIDUALLOAN_CASE,
+        Case.State.ACTIVE);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(),
             Action.APPLY_INTEREST, Action.MARK_LATE, Action.ACCEPT_PAYMENT, Action.DISBURSE, Action.WRITE_OFF, Action.CLOSE);
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.CLOSE, null, CLOSE_INDIVIDUALLOAN_CASE, Case.State.CLOSED);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.CLOSE,
+        Collections.singletonList(assignEntryToTeller()),
+        CLOSE_INDIVIDUALLOAN_CASE,
+        Case.State.CLOSED);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier());
   }
 
@@ -73,19 +110,43 @@
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN, Collections.emptyList(), OPEN_INDIVIDUALLOAN_CASE, Case.State.PENDING);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.OPEN,
+        Collections.singletonList(assignEntryToTeller()),
+        OPEN_INDIVIDUALLOAN_CASE,
+        Case.State.PENDING);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE, Action.DENY);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.APPROVE, Collections.emptyList(), APPROVE_INDIVIDUALLOAN_CASE, Case.State.APPROVED);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.APPROVE,
+        Collections.singletonList(assignEntryToTeller()),
+        APPROVE_INDIVIDUALLOAN_CASE,
+        Case.State.APPROVED);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, Action.CLOSE);
 
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, Collections.emptyList(), DISBURSE_INDIVIDUALLOAN_CASE, Case.State.ACTIVE);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.DISBURSE,
+        Collections.singletonList(assignEntryToTeller()),
+        DISBURSE_INDIVIDUALLOAN_CASE,
+        Case.State.ACTIVE);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier(),
             Action.APPLY_INTEREST, Action.MARK_LATE, Action.ACCEPT_PAYMENT, Action.DISBURSE, Action.WRITE_OFF, Action.CLOSE);
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.WRITE_OFF, Collections.emptyList(), WRITE_OFF_INDIVIDUALLOAN_CASE, Case.State.CLOSED);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.WRITE_OFF,
+        Collections.singletonList(assignEntryToTeller()),
+        WRITE_OFF_INDIVIDUALLOAN_CASE,
+        Case.State.CLOSED);
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier());
   }
 
@@ -94,17 +155,31 @@
     final Product product = createAndEnableProduct();
     final Case customerCase = createCase(product.getIdentifier());
 
-    checkStateTransfer(product.getIdentifier(), customerCase.getIdentifier(), Action.OPEN, Collections.emptyList(), OPEN_INDIVIDUALLOAN_CASE, Case.State.PENDING);
+    checkStateTransfer(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.OPEN,
+        Collections.singletonList(assignEntryToTeller()),
+        OPEN_INDIVIDUALLOAN_CASE,
+        Case.State.PENDING);
 
-    checkStateTransferFails(product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE, DISBURSE_INDIVIDUALLOAN_CASE, Case.State.PENDING);
+    checkStateTransferFails(
+        product.getIdentifier(),
+        customerCase.getIdentifier(),
+        Action.DISBURSE,
+        Collections.singletonList(assignEntryToTeller()),
+        DISBURSE_INDIVIDUALLOAN_CASE,
+        Case.State.PENDING);
   }
 
   public void checkStateTransferFails(final String productIdentifier,
-                                 final String caseIdentifier,
-                                 final Action action,
-                                 final String event,
-                                 final Case.State initialState) throws InterruptedException {
+                                      final String caseIdentifier,
+                                      final Action action,
+                                      final List<AccountAssignment> oneTimeAccountAssignments,
+                                      final String event,
+                                      final Case.State initialState) throws InterruptedException {
     final Command command = new Command();
+    command.setOneTimeAccountAssignments(oneTimeAccountAssignments);
     try {
       portfolioManager.executeCaseCommand(productIdentifier, caseIdentifier, action.name(), command);
       Assert.fail();
diff --git a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
index 6591023..14aa235 100644
--- a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
+++ b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
@@ -246,10 +246,10 @@
   }
 
   @Override
-  public Optional<String> getParameters(final Long caseId) {
+  public Optional<String> getParameters(final Long caseId, final int minorCurrencyUnitDigits) {
     return caseParametersRepository
             .findByCaseId(caseId)
-            .map(CaseParametersMapper::mapEntity)
+            .map(x -> CaseParametersMapper.mapEntity(x, minorCurrencyUnitDigits))
             .map(gson::toJson);
   }
 
diff --git a/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java b/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java
index 6f65ccb..467c25a 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/command/handler/IndividualLoanCommandHandler.java
@@ -22,6 +22,7 @@
 import io.mifos.core.command.annotation.EventEmitter;
 import io.mifos.core.lang.ServiceException;
 import io.mifos.individuallending.IndividualLendingPatternFactory;
+import io.mifos.individuallending.api.v1.domain.product.AccountDesignators;
 import io.mifos.individuallending.api.v1.domain.workflow.Action;
 import io.mifos.individuallending.api.v1.events.IndividualLoanCommandEvent;
 import io.mifos.individuallending.api.v1.events.IndividualLoanEventConstants;
@@ -42,6 +43,7 @@
 import java.time.ZoneId;
 import java.util.List;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @author Myrle Krantz
@@ -163,10 +165,36 @@
   public IndividualLoanCommandEvent process(final DisburseCommand command) {
     final String productIdentifier = command.getProductIdentifier();
     final String caseIdentifier = command.getCaseIdentifier();
-    final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
+    final DataContextOfAction dataContextOfAction = costComponentService.checkedGetDataContext(
+        productIdentifier, caseIdentifier, command.getCommand().getOneTimeAccountAssignments());
     checkActionCanBeExecuted(Case.State.valueOf(dataContextOfAction.getCustomerCase().getCurrentState()), Action.DISBURSE);
+
+
+    final CostComponentsForRepaymentPeriod costComponentsForRepaymentPeriod =
+        individualLoanService.getCostComponentsForRepaymentPeriod(productIdentifier, dataContextOfAction.getCaseParameters(), BigDecimal.ZERO, Action.DISBURSE, today(), LocalDate.now());
+
+
+    final DesignatorToAccountIdentifierMapper designatorToAccountIdentifierMapper
+        = new DesignatorToAccountIdentifierMapper(dataContextOfAction);
+
+    final List<ChargeInstance> charges = Stream.concat(costComponentsForRepaymentPeriod.stream().map(x -> new ChargeInstance(
+            designatorToAccountIdentifierMapper.mapOrThrow(x.getKey().getFromAccountDesignator()),
+            designatorToAccountIdentifierMapper.mapOrThrow(x.getKey().getToAccountDesignator()),
+            x.getValue().getAmount())),
+        Stream.of(new ChargeInstance(
+            designatorToAccountIdentifierMapper.mapOrThrow(AccountDesignators.PENDING_DISBURSAL),
+            designatorToAccountIdentifierMapper.mapOrThrow(AccountDesignators.CUSTOMER_LOAN),
+                dataContextOfAction.getCaseParameters().getMaximumBalance())))
+        .collect(Collectors.toList());
+
+    accountingAdapter.bookCharges(charges,
+        command.getCommand().getNote(),
+        productIdentifier + "." + caseIdentifier + "." + Action.DISBURSE.name(),
+        Action.DISBURSE.getTransactionType());
+    //Only move to new state if book charges command was accepted.
     updateCaseState(dataContextOfAction.getCustomerCase(), Case.State.ACTIVE);
-    return new IndividualLoanCommandEvent(command.getProductIdentifier(), command.getCaseIdentifier(), "x");
+
+    return new IndividualLoanCommandEvent(productIdentifier, caseIdentifier, Action.DISBURSE.name());
   }
 
   @Transactional
diff --git a/service/src/main/java/io/mifos/individuallending/internal/mapper/CaseParametersMapper.java b/service/src/main/java/io/mifos/individuallending/internal/mapper/CaseParametersMapper.java
index 6be2ef8..1655266 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/mapper/CaseParametersMapper.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/mapper/CaseParametersMapper.java
@@ -25,10 +25,7 @@
 import io.mifos.portfolio.api.v1.domain.TermRange;
 
 import java.math.BigDecimal;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -139,37 +136,40 @@
     return ret;
   }
 
-  public static CaseParameters mapEntity(final CaseParametersEntity caseParametersEntity) {
+  public static CaseParameters mapEntity(final CaseParametersEntity caseParametersEntity,
+                                         final int minorCurrencyUnitDigits) {
     final CaseParameters ret = new CaseParameters();
     ret.setCustomerIdentifier(caseParametersEntity.getCustomerIdentifier());
-    ret.setCreditWorthinessSnapshots(mapFactorsToSnapshots(caseParametersEntity.getCreditWorthinessFactors()));
+    ret.setCreditWorthinessSnapshots(mapFactorsToSnapshots(caseParametersEntity.getCreditWorthinessFactors(), minorCurrencyUnitDigits));
     ret.setTermRange(getTermRange(caseParametersEntity));
-    ret.setMaximumBalance(caseParametersEntity.getBalanceRangeMaximum());
+    ret.setMaximumBalance(caseParametersEntity.getBalanceRangeMaximum().setScale(minorCurrencyUnitDigits, BigDecimal.ROUND_HALF_EVEN));
     ret.setPaymentCycle(getPaymentCycle(caseParametersEntity));
     return ret;
   }
 
   private static List<CreditWorthinessSnapshot> mapFactorsToSnapshots(
-          final Set<CaseCreditWorthinessFactorEntity> creditWorthinessFactors) {
+      final Set<CaseCreditWorthinessFactorEntity> creditWorthinessFactors,
+      final int minorCurrencyUnitDigits) {
     final Map<Integer, Set<CaseCreditWorthinessFactorEntity>> groupedByCustomerId
             = creditWorthinessFactors.stream()
             .collect(Collectors.groupingBy(CaseCreditWorthinessFactorEntity::getPositionInCustomers, Collectors.toSet()));
 
     return groupedByCustomerId.entrySet().stream()
-            .sorted((x, y) -> Integer.compare(x.getKey(), y.getKey()))
-            .map(CaseParametersMapper::mapEntryToSnapshot).collect(Collectors.toList());
+            .sorted(Comparator.comparingInt(Map.Entry::getKey))
+            .map(customerEntry -> mapEntryToSnapshot(customerEntry, minorCurrencyUnitDigits)).collect(Collectors.toList());
   }
 
   private static CreditWorthinessSnapshot mapEntryToSnapshot(
-          final Map.Entry<Integer, Set<CaseCreditWorthinessFactorEntity>> customerEntry) {
+      final Map.Entry<Integer, Set<CaseCreditWorthinessFactorEntity>> customerEntry,
+      final int minorCurrencyUnitDigits) {
     final CreditWorthinessSnapshot ret = new CreditWorthinessSnapshot();
 
     final Map<CreditWorthinessFactorType, Set<CaseCreditWorthinessFactorEntity>> groupedByFactorType
             = customerEntry.getValue().stream()
             .collect(Collectors.groupingBy(CaseCreditWorthinessFactorEntity::getFactorType, Collectors.toSet()));
-    ret.setAssets(getFactorsByType(groupedByFactorType, CreditWorthinessFactorType.ASSET));
-    ret.setDebts(getFactorsByType(groupedByFactorType, CreditWorthinessFactorType.DEBT));
-    ret.setIncomeSources(getFactorsByType(groupedByFactorType, CreditWorthinessFactorType.INCOME_SOURCE));
+    ret.setAssets(getFactorsByType(groupedByFactorType, CreditWorthinessFactorType.ASSET, minorCurrencyUnitDigits));
+    ret.setDebts(getFactorsByType(groupedByFactorType, CreditWorthinessFactorType.DEBT, minorCurrencyUnitDigits));
+    ret.setIncomeSources(getFactorsByType(groupedByFactorType, CreditWorthinessFactorType.INCOME_SOURCE, minorCurrencyUnitDigits));
 
     final String customerId = customerEntry.getValue().stream()
             .findFirst()
@@ -181,25 +181,27 @@
   }
 
   private static List<CreditWorthinessFactor> getFactorsByType(
-          final Map<CreditWorthinessFactorType, Set<CaseCreditWorthinessFactorEntity>> groupedByFactorType,
-          final CreditWorthinessFactorType factorType) {
+      final Map<CreditWorthinessFactorType, Set<CaseCreditWorthinessFactorEntity>> groupedByFactorType,
+      final CreditWorthinessFactorType factorType,
+      final int minorCurrencyUnitDigits) {
     final Set<CaseCreditWorthinessFactorEntity> byFactorType = groupedByFactorType.get(factorType);
     if (byFactorType == null)
       return Collections.emptyList();
     else {
       return byFactorType.stream()
-              .sorted((x, y) -> Integer.compare(x.getPositionInFactor(), y.getPositionInFactor()))
-              .map(CaseParametersMapper::mapEntryToFactor)
+              .sorted(Comparator.comparingInt(CaseCreditWorthinessFactorEntity::getPositionInFactor))
+              .map(caseCreditWorthinessFactorEntity -> mapEntryToFactor(caseCreditWorthinessFactorEntity, minorCurrencyUnitDigits))
               .collect(Collectors.toList());
 
     }
   }
 
   private static CreditWorthinessFactor mapEntryToFactor(
-          final CaseCreditWorthinessFactorEntity caseCreditWorthinessFactorEntity) {
+      final CaseCreditWorthinessFactorEntity caseCreditWorthinessFactorEntity,
+      final int minorCurrencyUnitDigits) {
     final CreditWorthinessFactor ret = new CreditWorthinessFactor();
     ret.setDescription(caseCreditWorthinessFactorEntity.getDescription());
-    ret.setAmount(caseCreditWorthinessFactorEntity.getAmount());
+    ret.setAmount(caseCreditWorthinessFactorEntity.getAmount().setScale(minorCurrencyUnitDigits, BigDecimal.ROUND_HALF_EVEN));
     return ret;
   }
 }
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/CaseParametersService.java b/service/src/main/java/io/mifos/individuallending/internal/service/CaseParametersService.java
index 1a48f2b..b5d3710 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/CaseParametersService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/CaseParametersService.java
@@ -62,7 +62,7 @@
             .findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
             .map(CaseEntity::getId)
             .flatMap(caseParametersRepository::findByCaseId)
-            .map(CaseParametersMapper::mapEntity);
+            .map(x -> CaseParametersMapper.mapEntity(x, 4));
   }
 
   public CasePage findByCustomerIdentifier(
@@ -79,7 +79,7 @@
 
   private List<Case> mapList(final List<CaseParametersEntity> in) {
     return in.stream()
-            .map(x -> CaseMapper.map(caseRepository.findOne(x.getCaseId()), gson.toJson(CaseParametersMapper.mapEntity(x))))
+            .map(x -> CaseMapper.map(caseRepository.findOne(x.getCaseId()), gson.toJson(CaseParametersMapper.mapEntity(x, 4))))
             .collect(Collectors.toList());
   }
 }
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java b/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
index 1376692..f3b4ade 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
@@ -80,7 +80,7 @@
 
     final CaseParameters caseParameters =
             caseParametersRepository.findByCaseId(customerCase.getId())
-                    .map(CaseParametersMapper::mapEntity)
+                    .map(x -> CaseParametersMapper.mapEntity(x, product.getMinorCurrencyUnitDigits()))
                     .orElseThrow(() -> ServiceException.notFound(
                             "Individual loan not found ''{0}.{1}''.",
                             productIdentifier, caseIdentifier));
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/ScheduledActionService.java b/service/src/main/java/io/mifos/individuallending/internal/service/ScheduledActionService.java
index 0e3c3f6..87a126e 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/ScheduledActionService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/ScheduledActionService.java
@@ -56,10 +56,11 @@
     final Period lastPeriod = repaymentPeriods.last();
 
     return Stream.concat(Stream.of(
-            new ScheduledAction(Action.OPEN, initialDisbursalDate, firstPeriod, firstPeriod),
-            new ScheduledAction(Action.APPROVE, initialDisbursalDate, firstPeriod, firstPeriod)),
-            Stream.concat(repaymentPeriods.stream().flatMap(this::generateScheduledActionsForRepaymentPeriod),
-                    Stream.of(new ScheduledAction(Action.CLOSE, lastPeriod.getEndDate(), lastPeriod, lastPeriod))));
+        new ScheduledAction(Action.OPEN, initialDisbursalDate, firstPeriod, firstPeriod),
+        new ScheduledAction(Action.APPROVE, initialDisbursalDate, firstPeriod, firstPeriod),
+        new ScheduledAction(Action.DISBURSE, initialDisbursalDate, firstPeriod, firstPeriod)),
+        Stream.concat(repaymentPeriods.stream().flatMap(this::generateScheduledActionsForRepaymentPeriod),
+            Stream.of(new ScheduledAction(Action.CLOSE, lastPeriod.getEndDate(), lastPeriod, lastPeriod))));
   }
 
   private LocalDate getEndDate(final @Nonnull CaseParameters caseParameters,
diff --git a/service/src/main/java/io/mifos/portfolio/service/internal/service/CaseService.java b/service/src/main/java/io/mifos/portfolio/service/internal/service/CaseService.java
index a6b96e4..9250ee0 100644
--- a/service/src/main/java/io/mifos/portfolio/service/internal/service/CaseService.java
+++ b/service/src/main/java/io/mifos/portfolio/service/internal/service/CaseService.java
@@ -72,13 +72,15 @@
     final List<String> currentStates = currentStatesStream.map(Enum::name).collect(Collectors.toList());
 
     final Page<CaseEntity> ret = caseRepository.findByProductIdentifierAndCurrentStateIn(productIdentifier, currentStates, pageRequest);
+    final int minorCurrencyUnitDigits = getMinorCurrencyUnitDigits(productIdentifier);
 
-    return new CasePage(mapList(ret.getContent()), ret.getTotalPages(), ret.getTotalElements());
+    return new CasePage(mapList(ret.getContent(), minorCurrencyUnitDigits), ret.getTotalPages(), ret.getTotalElements());
   }
 
-  private List<Case> mapList(final List<CaseEntity> in) {
+  private List<Case> mapList(final List<CaseEntity> in,
+                             final int minorCurrencyUnitDigits) {
     return in.stream()
-            .map(this::map)
+            .map(caseEntity -> map(caseEntity, minorCurrencyUnitDigits))
             .filter(Optional::isPresent)
             .map(Optional::get)
             .collect(Collectors.toList());
@@ -86,8 +88,9 @@
 
   public Optional<Case> findByIdentifier(final String productIdentifier, final String caseIdentifier)
   {
+    final int minorCurrencyUnitDigits = getMinorCurrencyUnitDigits(productIdentifier);
     return caseRepository.findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
-            .flatMap(this::map);
+            .flatMap(caseEntity -> map(caseEntity, minorCurrencyUnitDigits));
   }
 
   public Set<String> getNextActionsForCase(final String productIdentifier, final String caseIdentifier) {
@@ -95,22 +98,22 @@
 
     return caseRepository.findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
             .map(x -> pattern.getNextActionsForState(Case.State.valueOf(x.getCurrentState())))
-            .orElseThrow(() -> ServiceException.notFound("Case with identifier " + productIdentifier + "." + caseIdentifier + " doesn't exist."));
+            .orElseThrow(() -> ServiceException.notFound("Case with identifier ''" + productIdentifier + "." + caseIdentifier + "'' doesn''t exist."));
   }
 
   public ProductCommandDispatcher getProductCommandDispatcher(final String productIdentifier) {
     return getPatternFactoryOrThrow(productIdentifier).getIndividualLendingCommandDispatcher();
   }
 
-  private Optional<Case> map(final CaseEntity caseEntity) {
+  private Optional<Case> map(final CaseEntity caseEntity, final int minorCurrencyUnitDigits) {
     return getPatternFactory(caseEntity.getProductIdentifier())
-            .flatMap(x -> x.getParameters(caseEntity.getId()))
+            .flatMap(x -> x.getParameters(caseEntity.getId(), minorCurrencyUnitDigits))
             .map(x -> CaseMapper.map(caseEntity, x));
   }
 
   private PatternFactory getPatternFactoryOrThrow(final String productIdentifier) {
     return getPatternFactory(productIdentifier)
-            .orElseThrow(() -> ServiceException.notFound("Product with identifier " + productIdentifier + " doesn't exist."));
+            .orElseThrow(() -> ServiceException.notFound("Product with identifier ''" + productIdentifier + "'' doesn''t exist."));
   }
 
   private Optional<PatternFactory> getPatternFactory(final String productIdentifier) {
@@ -129,4 +132,10 @@
     return getPatternFactoryOrThrow(productIdentifier)
             .getCostComponentsForAction(productIdentifier, caseIdentifier, actionIdentifier);
   }
+
+  private int getMinorCurrencyUnitDigits(final String productIdentifier) {
+    return productRepository.findByIdentifier(productIdentifier)
+        .map(ProductEntity::getMinorCurrencyUnitDigits)
+        .orElse(4);
+  }
 }
\ No newline at end of file
diff --git a/service/src/main/java/io/mifos/products/spi/PatternFactory.java b/service/src/main/java/io/mifos/products/spi/PatternFactory.java
index 74a0f16..a035aa1 100644
--- a/service/src/main/java/io/mifos/products/spi/PatternFactory.java
+++ b/service/src/main/java/io/mifos/products/spi/PatternFactory.java
@@ -33,7 +33,7 @@
   List<ChargeDefinition> charges();
   void persistParameters(Long caseId, String parameters);
   void changeParameters(Long caseId, String parameters);
-  Optional<String> getParameters(Long caseId);
+  Optional<String> getParameters(Long caseId, int minorCurrencyUnitDigits);
   Set<String> getNextActionsForState(Case.State state);
   List<CostComponent> getCostComponentsForAction(String productIdentifier, String caseIdentifier, String actionIdentifier);
   ProductCommandDispatcher getIndividualLendingCommandDispatcher();