* Various repairs to TestAccountingInteractionInLoanWorkflow
* Fixed accrual accounting of interest (was calculating double interest).
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 5400c74..091f0d4 100644
--- a/component-test/src/main/java/io/mifos/portfolio/AccountingFixture.java
+++ b/component-test/src/main/java/io/mifos/portfolio/AccountingFixture.java
@@ -580,6 +580,8 @@
                              final Action action) {
     final Set<Debtor> filteredDebtors = debtors.stream().filter(x -> BigDecimal.valueOf(Double.valueOf(x.getAmount())).compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toSet());
     final Set<Creditor> filteredCreditors = creditors.stream().filter(x -> BigDecimal.valueOf(Double.valueOf(x.getAmount())).compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toSet());
+    if (filteredCreditors.size() == 0 && filteredDebtors.size() == 0)
+      return;
     final JournalEntryMatcher specifiesCorrectJournalEntry = new JournalEntryMatcher(filteredDebtors, filteredCreditors, productIdentifier, caseIdentifier, action);
     Mockito.verify(ledgerManager, Mockito.atLeastOnce()).createJournalEntry(AdditionalMatchers.and(argThat(isValid()), argThat(specifiesCorrectJournalEntry)));
 
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 2623acf..3a77a72 100644
--- a/component-test/src/main/java/io/mifos/portfolio/Fixture.java
+++ b/component-test/src/main/java/io/mifos/portfolio/Fixture.java
@@ -24,7 +24,6 @@
 import io.mifos.portfolio.api.v1.domain.*;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.function.Consumer;
@@ -40,7 +39,7 @@
 @SuppressWarnings({"WeakerAccess", "unused"})
 public class Fixture {
   static final int MINOR_CURRENCY_UNIT_DIGITS = 2;
-  static final BigDecimal INTEREST_RATE = BigDecimal.valueOf(0.10).setScale(4, RoundingMode.HALF_EVEN);
+  static final BigDecimal INTEREST_RATE = BigDecimal.valueOf(10_00, 2);
   static final BigDecimal ACCRUAL_PERIODS = BigDecimal.valueOf(365.2425);
   public static final String CUSTOMER_IDENTIFIER = "alice";
 
@@ -124,7 +123,7 @@
     final Set<AccountAssignment> accountAssignments = new HashSet<>();
     ret.setAccountAssignments(accountAssignments);
     ret.setCurrentState(Case.State.CREATED.name());
-    ret.setInterest(BigDecimal.valueOf(10_00, 2));
+    ret.setInterest(INTEREST_RATE);
 
     final CaseParameters caseParameters = getTestCaseParameters();
     final Gson gson = new Gson();
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java b/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
index 6bf90ff..da4af76 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
@@ -72,7 +72,7 @@
   private String customerLoanInterestIdentifier = null;
   private String customerLoanFeeIdentifier = null;
 
-  private BigDecimal expectedCurrentBalance = null;
+  private BigDecimal expectedCurrentPrincipal = null;
   private BigDecimal interestAccrued = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
   private BigDecimal nonLateFees = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
 
@@ -101,8 +101,12 @@
     step5Disburse(
         BigDecimal.valueOf(2_000_00, MINOR_CURRENCY_UNIT_DIGITS),
         UPPER_RANGE_DISBURSEMENT_FEE_ID, BigDecimal.valueOf(20_00, MINOR_CURRENCY_UNIT_DIGITS));
-    step6CalculateInterestAccrualAndCheckForLateness(midnightToday(), null);
-    step7PaybackPartialAmount(expectedCurrentBalance, today, 0, BigDecimal.ZERO);
+    step6CalculateInterestAccrualAndCheckForLateness(midnightToday(), BigDecimal.ZERO);
+    step7PaybackPartialAmount(
+        expectedCurrentPrincipal.add(nonLateFees).add(interestAccrued),
+        today,
+        0,
+        BigDecimal.ZERO);
     step8Close();
   }
 
@@ -120,8 +124,12 @@
     step5Disburse(
         BigDecimal.valueOf(1_500_00, MINOR_CURRENCY_UNIT_DIGITS),
         UPPER_RANGE_DISBURSEMENT_FEE_ID, BigDecimal.valueOf(15_00, MINOR_CURRENCY_UNIT_DIGITS));
-    step6CalculateInterestAccrualAndCheckForLateness(midnightToday(), null);
-    step7PaybackPartialAmount(expectedCurrentBalance, today, 0, BigDecimal.ZERO);
+    step6CalculateInterestAccrualAndCheckForLateness(midnightToday(), BigDecimal.ZERO);
+    step7PaybackPartialAmount(
+        expectedCurrentPrincipal.add(nonLateFees).add(interestAccrued),
+        today,
+        0,
+        BigDecimal.ZERO);
     step8Close();
   }
 
@@ -136,13 +144,13 @@
     step5Disburse(
         BigDecimal.valueOf(2_000_00, MINOR_CURRENCY_UNIT_DIGITS),
         UPPER_RANGE_DISBURSEMENT_FEE_ID, BigDecimal.valueOf(20_00, MINOR_CURRENCY_UNIT_DIGITS));
-    step6CalculateInterestAccrualAndCheckForLateness(midnightToday(), null);
-    final BigDecimal repayment1 = expectedCurrentBalance.divide(BigDecimal.valueOf(2), BigDecimal.ROUND_HALF_EVEN);
+    step6CalculateInterestAccrualAndCheckForLateness(midnightToday(), BigDecimal.ZERO);
+    final BigDecimal repayment1 = expectedCurrentPrincipal.divide(BigDecimal.valueOf(2), BigDecimal.ROUND_HALF_EVEN);
     step7PaybackPartialAmount(
         repayment1.setScale(MINOR_CURRENCY_UNIT_DIGITS, BigDecimal.ROUND_HALF_EVEN),
         today,
         0, BigDecimal.ZERO);
-    step7PaybackPartialAmount(expectedCurrentBalance, today, 0, BigDecimal.ZERO);
+    step7PaybackPartialAmount(expectedCurrentPrincipal, today, 0, BigDecimal.ZERO);
     step8Close();
   }
 
@@ -174,10 +182,10 @@
 
     int week = 0;
     final List<BigDecimal> repayments = new ArrayList<>();
-    while (expectedCurrentBalance.compareTo(BigDecimal.ZERO) > 0) {
-      logger.info("Simulating week {}. Expected current balance {}.", week, expectedCurrentBalance);
+    while (expectedCurrentPrincipal.compareTo(BigDecimal.ZERO) > 0) {
+      logger.info("Simulating week {}. Expected current balance {}.", week, expectedCurrentPrincipal);
       step6CalculateInterestAndCheckForLatenessForWeek(today, week);
-      final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week+1)*7);
+      final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week+1)*7, BigDecimal.ZERO);
       repayments.add(nextRepaymentAmount);
       step7PaybackPartialAmount(nextRepaymentAmount, today, (week+1)*7, BigDecimal.ZERO);
       week++;
@@ -190,8 +198,11 @@
   }
 
   private void checkRepaymentVariance(List<BigDecimal> repayments) {
-    final BigDecimal minPayment = repayments.stream().min(BigDecimal::compareTo).orElseThrow(IllegalStateException::new);
-    final BigDecimal maxPayment = repayments.stream().max(BigDecimal::compareTo).orElseThrow(IllegalStateException::new);
+    final Set<BigDecimal> setOfRepayments = new HashSet<>(repayments);
+    Assert.assertTrue("Too many payment sizes. Payments are " + repayments,
+        + setOfRepayments.size() <= 2); //There should be a standard payment size with only one slightly off.
+    final BigDecimal minPayment = setOfRepayments.stream().min(BigDecimal::compareTo).orElseThrow(IllegalStateException::new);
+    final BigDecimal maxPayment = setOfRepayments.stream().max(BigDecimal::compareTo).orElseThrow(IllegalStateException::new);
     final BigDecimal delta = maxPayment.subtract(minPayment).abs();
     Assert.assertTrue("Payments vary too much. Payments are " + repayments,
         delta.divide(maxPayment, BigDecimal.ROUND_HALF_EVEN).compareTo(BigDecimal.valueOf(0.01)) <= 0);
@@ -212,8 +223,8 @@
     int week = 0;
     final int weekOfLateRepayment = 3;
     final List<BigDecimal> repayments = new ArrayList<>();
-    while (expectedCurrentBalance.compareTo(BigDecimal.ZERO) > 0) {
-      logger.info("Simulating week {}. Expected current balance {}.", week, expectedCurrentBalance);
+    while (expectedCurrentPrincipal.compareTo(BigDecimal.ZERO) > 0) {
+      logger.info("Simulating week {}. Expected current balance {}.", week, expectedCurrentPrincipal);
       if (week == weekOfLateRepayment) {
         final BigDecimal lateFee = BigDecimal.valueOf(31_18, MINOR_CURRENCY_UNIT_DIGITS);
         step6CalculateInterestAndCheckForLatenessForRangeOfDays(
@@ -222,13 +233,13 @@
             (week + 1) * 7 + 2,
             8,
             lateFee);
-        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7 + 2);
+        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7 + 2, lateFee);
         repayments.add(nextRepaymentAmount);
         step7PaybackPartialAmount(nextRepaymentAmount, today, (week + 1) * 7 + 2, lateFee);
       }
       else {
         step6CalculateInterestAndCheckForLatenessForWeek(today, week);
-        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7);
+        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7, BigDecimal.ZERO);
         repayments.add(nextRepaymentAmount);
         step7PaybackPartialAmount(nextRepaymentAmount, today, (week + 1) * 7, BigDecimal.ZERO);
       }
@@ -244,8 +255,13 @@
 
   private BigDecimal findNextRepaymentAmount(
       final LocalDateTime referenceDate,
-      final int dayNumber) {
-    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentBalance);
+      final int dayNumber,
+      final BigDecimal lateFee) {
+    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentPrincipal);
+    AccountingFixture.mockBalance(customerLoanInterestIdentifier, interestAccrued);
+    AccountingFixture.mockBalance(AccountingFixture.LOAN_INTEREST_ACCRUAL_ACCOUNT_IDENTIFIER, interestAccrued);
+    AccountingFixture.mockBalance(AccountingFixture.LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER, lateFee);
+    AccountingFixture.mockBalance(customerLoanFeeIdentifier, nonLateFees.add(lateFee));
 
     final Payment nextPayment = portfolioManager.getCostComponentsForAction(
         product.getIdentifier(),
@@ -397,7 +413,9 @@
     customerLoanFeeIdentifier =
         AccountingFixture.verifyAccountCreationMatchingDesignator(ledgerManager, customerLoanLedgerIdentifier, AccountDesignators.CUSTOMER_LOAN_FEES, AccountType.ASSET);
 
-    expectedCurrentBalance = BigDecimal.ZERO;
+    expectedCurrentPrincipal = BigDecimal.ZERO;
+    interestAccrued = BigDecimal.ZERO;
+    nonLateFees = BigDecimal.ZERO;
   }
 
   //Approve the case, accept a loan origination fee, and prepare to disburse the loan by earmarking the funds.
@@ -405,7 +423,7 @@
       final BigDecimal amount,
       final String whichDisbursementFee,
       final BigDecimal disbursementFeeAmount) throws InterruptedException {
-    logger.info("step5Disburse");
+    logger.info("step5Disburse  '{}'", amount);
     checkCostComponentForActionCorrect(
         product.getIdentifier(),
         customerCase.getIdentifier(),
@@ -442,7 +460,8 @@
     creditors.add(new Creditor(AccountingFixture.LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER, LOAN_ORIGINATION_FEE_AMOUNT.toPlainString()));
     AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors, product.getIdentifier(), customerCase.getIdentifier(), Action.DISBURSE);
 
-    expectedCurrentBalance = expectedCurrentBalance.add(amount);
+    expectedCurrentPrincipal = expectedCurrentPrincipal.add(amount);
+    interestAccrued = BigDecimal.ZERO;
     nonLateFees = nonLateFees.add(disbursementFeeAmount);
   }
 
@@ -472,7 +491,7 @@
                 step6CalculateInterestAccrualAndCheckForLateness(day, calculatedLateFee);
               }
               else {
-                step6CalculateInterestAccrualAndCheckForLateness(day, null);
+                step6CalculateInterestAccrualAndCheckForLateness(day, BigDecimal.ZERO);
               }
             } catch (InterruptedException e) {
               throw new RuntimeException(e);
@@ -492,15 +511,31 @@
   private void step6CalculateInterestAccrualAndCheckForLateness(
       final LocalDateTime forTime,
       final BigDecimal calculatedLateFee) throws InterruptedException {
-    logger.info("step6CalculateInterestAccrualAndCheckForLateness");
+    logger.info("step6CalculateInterestAccrualAndCheckForLateness  '{}', '{}'", forTime, calculatedLateFee);
     final String beatIdentifier = "alignment0";
     final String midnightTimeStamp = DateConverter.toIsoString(forTime);
 
-    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentBalance);
+    final BigDecimal allFees = nonLateFees.add(calculatedLateFee);
+    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentPrincipal);
+    AccountingFixture.mockBalance(customerLoanInterestIdentifier, interestAccrued);
+    AccountingFixture.mockBalance(customerLoanFeeIdentifier, allFees);
 
-    final BigDecimal calculatedInterest = expectedCurrentBalance.multiply(Fixture.INTEREST_RATE.divide(Fixture.ACCRUAL_PERIODS, 8, BigDecimal.ROUND_HALF_EVEN))
+    final BigDecimal dailyInterestRate = Fixture.INTEREST_RATE
+        .divide(BigDecimal.valueOf(100), 8, BigDecimal.ROUND_HALF_EVEN)
+        .divide(Fixture.ACCRUAL_PERIODS, 8, BigDecimal.ROUND_HALF_EVEN);
+
+    final BigDecimal calculatedInterest = expectedCurrentPrincipal
+        .add(interestAccrued)
+        .add(allFees)
+        .multiply(dailyInterestRate)
         .setScale(MINOR_CURRENCY_UNIT_DIGITS, BigDecimal.ROUND_HALF_EVEN);
 
+    logger.info("currentPrincipal '{}'", expectedCurrentPrincipal);
+    logger.info("interestAccrued '{}'", interestAccrued);
+    logger.info("allFees '{}'", allFees);
+    logger.info("INTEREST_RATE '{}'", Fixture.INTEREST_RATE);
+    logger.info("calculatedInterest '{}'", calculatedInterest);
+
 
     checkCostComponentForActionCorrect(
         product.getIdentifier(),
@@ -510,7 +545,7 @@
         null,
         new CostComponent(ChargeIdentifiers.INTEREST_ID, calculatedInterest));
 
-    if (calculatedLateFee != null) {
+    if (calculatedLateFee.compareTo(BigDecimal.ZERO) != 0) {
       checkCostComponentForActionCorrect(
           product.getIdentifier(),
           customerCase.getIdentifier(),
@@ -534,9 +569,6 @@
     final Case customerCaseAfterStateChange = portfolioManager.getCase(product.getIdentifier(), customerCase.getIdentifier());
     Assert.assertEquals(customerCaseAfterStateChange.getCurrentState(), Case.State.ACTIVE.name());
 
-
-    interestAccrued = interestAccrued.add(calculatedInterest);
-
     final Set<Debtor> debtors = new HashSet<>();
     debtors.add(new Debtor(
         customerLoanInterestIdentifier,
@@ -548,7 +580,22 @@
         calculatedInterest.toPlainString()));
     AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors, product.getIdentifier(), customerCase.getIdentifier(), Action.APPLY_INTEREST);
 
-    expectedCurrentBalance = expectedCurrentBalance.add(calculatedInterest);
+
+    if (calculatedLateFee.compareTo(BigDecimal.ZERO) != 0) {
+      final Set<Debtor> lateFeeDebtors = new HashSet<>();
+      lateFeeDebtors.add(new Debtor(
+          customerLoanFeeIdentifier,
+          calculatedLateFee.toPlainString()));
+
+      final Set<Creditor> lateFeeCreditors = new HashSet<>();
+      lateFeeCreditors.add(new Creditor(
+          AccountingFixture.LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER,
+          calculatedLateFee.toPlainString()));
+      AccountingFixture.verifyTransfer(ledgerManager, lateFeeDebtors, lateFeeCreditors, product.getIdentifier(), customerCase.getIdentifier(), Action.APPLY_INTEREST);
+    }
+    interestAccrued = interestAccrued.add(calculatedInterest);
+    logger.info("Completed step6CalculateInterestAccrualAndCheckForLateness");
+    logger.info("interestAccrued '{}'", interestAccrued);
   }
 
   private void step7PaybackPartialAmount(
@@ -558,13 +605,17 @@
       final BigDecimal lateFee) throws InterruptedException {
     logger.info("step7PaybackPartialAmount '{}'", amount);
 
-    final BigDecimal principal = amount.subtract(interestAccrued).subtract(lateFee).subtract(nonLateFees);
     final BigDecimal allFees = lateFee.add(nonLateFees);
-    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, principal);
+    final BigDecimal principal = amount.subtract(interestAccrued).subtract(allFees);
+    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentPrincipal);
     AccountingFixture.mockBalance(customerLoanFeeIdentifier, allFees);
     AccountingFixture.mockBalance(customerLoanInterestIdentifier, interestAccrued);
     AccountingFixture.mockBalance(AccountingFixture.LOAN_INTEREST_ACCRUAL_ACCOUNT_IDENTIFIER, interestAccrued);
     AccountingFixture.mockBalance(AccountingFixture.LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER, lateFee);
+    logger.info("currentPrincipal '{}'", expectedCurrentPrincipal);
+    logger.info("interestAccrued '{}'", interestAccrued);
+    logger.info("allFees '{}'", allFees);
+    logger.info("lateFee '{}'", lateFee);
 
     checkCostComponentForActionCorrect(
         product.getIdentifier(),
@@ -618,15 +669,23 @@
 
     AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors, product.getIdentifier(), customerCase.getIdentifier(), Action.ACCEPT_PAYMENT);
 
-    expectedCurrentBalance = expectedCurrentBalance.subtract(amount).add(lateFee);
+    expectedCurrentPrincipal = expectedCurrentPrincipal.subtract(principal);
     interestAccrued = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
     nonLateFees = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
+    logger.info("Completed step7PaybackPartialAmount");
+    logger.info("currentPrincipal '{}'", expectedCurrentPrincipal);
+    logger.info("interestAccrued '{}'", interestAccrued);
+    logger.info("nonLateFees '{}'", nonLateFees);
   }
 
   private void step8Close() throws InterruptedException {
     logger.info("step8Close");
-
-    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentBalance);
+    logger.info("currentPrincipal '{}'", expectedCurrentPrincipal);
+    logger.info("interestAccrued '{}'", interestAccrued);
+    logger.info("nonLateFees '{}'", nonLateFees);
+    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentPrincipal);
+    AccountingFixture.mockBalance(customerLoanInterestIdentifier, interestAccrued);
+    AccountingFixture.mockBalance(customerLoanFeeIdentifier, nonLateFees);
 
     checkCostComponentForActionCorrect(
         product.getIdentifier(),
diff --git a/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java b/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java
index a358757..a5468af 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestChargeDefinitions.java
@@ -56,7 +56,7 @@
         .collect(Collectors.toSet());
 
     final Set<String> expectedReadOnlyChargeDefinitionIdentifiers = Stream.of(
-        ChargeIdentifiers.ALLOW_FOR_WRITE_OFF_ID,
+        //ChargeIdentifiers.ALLOW_FOR_WRITE_OFF_ID,
         ChargeIdentifiers.DISBURSE_PAYMENT_ID,
         ChargeIdentifiers.INTEREST_ID,
         ChargeIdentifiers.REPAY_PRINCIPAL_ID,
@@ -107,7 +107,7 @@
   public void shouldNotDeleteReadOnlyChargeDefinition() throws InterruptedException {
     final Product product = createProduct();
 
-    portfolioManager.deleteChargeDefinition(product.getIdentifier(), ChargeIdentifiers.ALLOW_FOR_WRITE_OFF_ID);
+    portfolioManager.deleteChargeDefinition(product.getIdentifier(), ChargeIdentifiers.INTEREST_ID);
   }
 
   @Test
diff --git a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
index 16ddbe7..c4fe59d 100644
--- a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
+++ b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
@@ -198,14 +198,14 @@
     disbursePayment.setReadOnly(true);
 
     //TODO: Make multiple write off allowance charges.
-    final ChargeDefinition writeOffAllowanceCharge = charge(
+    /*final ChargeDefinition writeOffAllowanceCharge = charge(
         ALLOW_FOR_WRITE_OFF_NAME,
         Action.MARK_LATE,
         BigDecimal.valueOf(30),
         AccountDesignators.LOAN_FUNDS_SOURCE,
         AccountDesignators.ARREARS_ALLOWANCE);
     writeOffAllowanceCharge.setProportionalTo(ChargeProportionalDesignator.RUNNING_BALANCE_DESIGNATOR.getValue());
-    writeOffAllowanceCharge.setReadOnly(true);
+    writeOffAllowanceCharge.setReadOnly(true);*/
 
     final ChargeDefinition interestCharge = charge(
         INTEREST_NAME,
@@ -257,7 +257,7 @@
     customerPrincipalRepaymentCharge.setReadOnly(true);
 
     ret.add(disbursePayment);
-    ret.add(writeOffAllowanceCharge);
+    //ret.add(writeOffAllowanceCharge);
     ret.add(interestCharge);
     ret.add(customerPrincipalRepaymentCharge);
     ret.add(customerInterestRepaymentCharge);
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java b/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
index 2bd5675..744e82e 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
@@ -153,6 +153,7 @@
       final SortedSet<ScheduledCharge> scheduledChargesInPeriod = orderedScheduledChargesGroupedByPeriod.get(repaymentPeriod);
       final PaymentBuilder paymentBuilder =
               CostComponentService.getCostComponentsForScheduledCharges(
+                  null, //Action doesn't matter because not using accrual accounting.
                   Collections.emptyMap(),
                   scheduledChargesInPeriod,
                   initialBalance,
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderService.java
index 3846c37..2b989e9 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderService.java
@@ -110,6 +110,7 @@
 
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.ACCEPT_PAYMENT,
         accruedCostComponents,
         chargesSplitIntoScheduledAndAccrued.get(false),
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApplyInterestPaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApplyInterestPaymentBuilderService.java
index 7fef484..5125b49 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApplyInterestPaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApplyInterestPaymentBuilderService.java
@@ -78,6 +78,7 @@
                 chargeDefinition)));
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.APPLY_INTEREST,
         accruedCostComponents,
         chargesSplitIntoScheduledAndAccrued.get(false),
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApprovePaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApprovePaymentBuilderService.java
index 61649c7..5e06b98 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApprovePaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ApprovePaymentBuilderService.java
@@ -58,6 +58,7 @@
         productIdentifier, scheduledActions);
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.APPROVE,
         Collections.emptyMap(),
         scheduledCharges,
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ClosePaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ClosePaymentBuilderService.java
index 4c5bdfb..f0fbcdf 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ClosePaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/ClosePaymentBuilderService.java
@@ -84,6 +84,7 @@
                 chargeDefinition)));
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.CLOSE,
         accruedCostComponents,
         chargesSplitIntoScheduledAndAccrued.get(false),
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/CostComponentService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/CostComponentService.java
index 8ed2536..a494427 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/CostComponentService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/CostComponentService.java
@@ -43,6 +43,7 @@
   private static final int RUNNING_CALCULATION_PRECISION = 8;
 
   public static PaymentBuilder getCostComponentsForScheduledCharges(
+      final Action action,
       final Map<ChargeDefinition, CostComponent> accruedCostComponents,
       final Collection<ScheduledCharge> scheduledCharges,
       final BigDecimal maximumBalance,
@@ -59,11 +60,7 @@
       final ChargeDefinition chargeDefinition = entry.getKey();
       final BigDecimal chargeAmount = entry.getValue().getAmount();
 
-      //TODO: This should adjust differently depending on accrual accounting.
-      // It can't be fixed until getAmountProportionalTo is fixed.
-      paymentBuilder.addToBalance(chargeDefinition.getFromAccountDesignator(), chargeAmount.negate());
-      paymentBuilder.addToBalance(chargeDefinition.getToAccountDesignator(), chargeAmount);
-      paymentBuilder.addToCostComponent(chargeDefinition, chargeAmount);
+      paymentBuilder.adjustBalances(action, chargeDefinition, chargeAmount);
     }
 
 
@@ -196,6 +193,7 @@
         .filter(x -> x.getScheduledAction().getAction().equals(Action.DISBURSE))
         .collect(Collectors.toList());
     final PaymentBuilder paymentBuilder = getCostComponentsForScheduledCharges(
+        null, //Action doesn't matter since there's nothing accrued.
         Collections.emptyMap(),
         disbursementFees,
         maximumBalanceSize,
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DenyPaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DenyPaymentBuilderService.java
index 99e90c0..3b3c826 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DenyPaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DenyPaymentBuilderService.java
@@ -57,6 +57,7 @@
         productIdentifier, scheduledActions);
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.DENY,
         Collections.emptyMap(),
         scheduledCharges,
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DisbursePaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DisbursePaymentBuilderService.java
index 97a47eb..a88c37f 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DisbursePaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/DisbursePaymentBuilderService.java
@@ -109,6 +109,7 @@
                         chargeDefinition)))).orElse(Collections.emptyMap());
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.DISBURSE,
         accruedCostComponents,
         chargesSplitIntoScheduledAndAccrued.get(false),
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/MarkLatePaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/MarkLatePaymentBuilderService.java
index 5b77f93..51aa3fb 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/MarkLatePaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/MarkLatePaymentBuilderService.java
@@ -82,6 +82,7 @@
 
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.MARK_LATE,
         accruedCostComponents,
         chargesSplitIntoScheduledAndAccrued.get(false),
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/OpenPaymentBuilderService.java b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/OpenPaymentBuilderService.java
index d4da18c..ed3d3ab 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/OpenPaymentBuilderService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/costcomponent/OpenPaymentBuilderService.java
@@ -56,6 +56,7 @@
         productIdentifier, scheduledActions);
 
     return CostComponentService.getCostComponentsForScheduledCharges(
+        Action.OPEN,
         Collections.emptyMap(),
         scheduledCharges,
         caseParameters.getBalanceRangeMaximum(),
diff --git a/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java b/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java
index 217f1eb..63083d5 100644
--- a/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java
+++ b/service/src/main/java/io/mifos/portfolio/service/internal/util/AccountingAdapter.java
@@ -167,7 +167,7 @@
   public BigDecimal getCurrentAccountBalance(final String accountIdentifier) {
     try {
       final Account account = ledgerManager.findAccount(accountIdentifier);
-      if (account == null)
+      if (account == null || account.getBalance() == null)
         throw ServiceException.internalError("Could not find the account with identifier ''{0}''", accountIdentifier);
       return BigDecimal.valueOf(account.getBalance());
     }
diff --git a/service/src/test/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderServiceTest.java b/service/src/test/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderServiceTest.java
index b3f1424..528270c 100644
--- a/service/src/test/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderServiceTest.java
+++ b/service/src/test/java/io/mifos/individuallending/internal/service/costcomponent/AcceptPaymentBuilderServiceTest.java
@@ -17,6 +17,7 @@
   public void getPaymentBuilder() throws Exception {
     final PaymentBuilderServiceTestCase testCase = new PaymentBuilderServiceTestCase("simple case");
     testCase.runningBalances.adjustBalance(AccountDesignators.CUSTOMER_LOAN_PRINCIPAL, testCase.balance.negate());
+    testCase.runningBalances.adjustBalance(AccountDesignators.CUSTOMER_LOAN_INTEREST, testCase.accruedInterest.negate());
     testCase.runningBalances.adjustBalance(AccountDesignators.INTEREST_ACCRUAL, testCase.accruedInterest);
 
     final PaymentBuilder paymentBuilder = PaymentBuilderServiceTestHarness.constructCallToPaymentBuilder(