* Changed interest calculation to exclude fees.
* Fixed lateness test to check for the lateness charge correctly.
diff --git a/api/src/main/java/io/mifos/individuallending/api/v1/domain/product/ChargeProportionalDesignator.java b/api/src/main/java/io/mifos/individuallending/api/v1/domain/product/ChargeProportionalDesignator.java
index 5862c6d..17903fa 100644
--- a/api/src/main/java/io/mifos/individuallending/api/v1/domain/product/ChargeProportionalDesignator.java
+++ b/api/src/main/java/io/mifos/individuallending/api/v1/domain/product/ChargeProportionalDesignator.java
@@ -25,11 +25,12 @@
   NOT_PROPORTIONAL("{notproportional}", 0),
   MAXIMUM_BALANCE_DESIGNATOR("{maximumbalance}", 1),
   RUNNING_BALANCE_DESIGNATOR("{runningbalance}", 2),
-  REQUESTED_DISBURSEMENT_DESIGNATOR("{requesteddisbursement}", 3),
-  TO_ACCOUNT_DESIGNATOR("{toAccount}", 4),
-  FROM_ACCOUNT_DESIGNATOR("{fromAccount}", 5),
-  REQUESTED_REPAYMENT_DESIGNATOR("{requestedrepayment}", 6),
-  CONTRACTUAL_REPAYMENT_DESIGNATOR("{contractualrepayment}", 7),
+  PRINCIPAL_AND_INTEREST_DESIGNATOR("{principalandinterest}", 3),
+  REQUESTED_DISBURSEMENT_DESIGNATOR("{requesteddisbursement}", 4),
+  TO_ACCOUNT_DESIGNATOR("{toAccount}", 5),
+  FROM_ACCOUNT_DESIGNATOR("{fromAccount}", 6),
+  REQUESTED_REPAYMENT_DESIGNATOR("{requestedrepayment}", 7),
+  CONTRACTUAL_REPAYMENT_DESIGNATOR("{contractualrepayment}", 8),
   ;
 
   private final String value;
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 da4af76..bf356e0 100644
--- a/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
+++ b/component-test/src/main/java/io/mifos/portfolio/TestAccountingInteractionInLoanWorkflow.java
@@ -72,9 +72,10 @@
   private String customerLoanInterestIdentifier = null;
   private String customerLoanFeeIdentifier = null;
 
-  private BigDecimal expectedCurrentPrincipal = null;
+  private BigDecimal expectedCurrentPrincipal = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
   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);
+  private BigDecimal lateFees = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
 
 
   @Before
@@ -185,7 +186,7 @@
     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, BigDecimal.ZERO);
+      final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week+1)*7);
       repayments.add(nextRepaymentAmount);
       step7PaybackPartialAmount(nextRepaymentAmount, today, (week+1)*7, BigDecimal.ZERO);
       week++;
@@ -226,20 +227,20 @@
     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);
+        final BigDecimal lateFee = BigDecimal.valueOf(17_31, MINOR_CURRENCY_UNIT_DIGITS); //??? TODO: check the late fee value.
         step6CalculateInterestAndCheckForLatenessForRangeOfDays(
             today,
             (week * 7) + 1,
             (week + 1) * 7 + 2,
             8,
             lateFee);
-        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7 + 2, lateFee);
+        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7 + 2);
         repayments.add(nextRepaymentAmount);
         step7PaybackPartialAmount(nextRepaymentAmount, today, (week + 1) * 7 + 2, lateFee);
       }
       else {
         step6CalculateInterestAndCheckForLatenessForWeek(today, week);
-        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7, BigDecimal.ZERO);
+        final BigDecimal nextRepaymentAmount = findNextRepaymentAmount(today, (week + 1) * 7);
         repayments.add(nextRepaymentAmount);
         step7PaybackPartialAmount(nextRepaymentAmount, today, (week + 1) * 7, BigDecimal.ZERO);
       }
@@ -255,14 +256,7 @@
 
   private BigDecimal findNextRepaymentAmount(
       final LocalDateTime referenceDate,
-      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 int dayNumber) {
     final Payment nextPayment = portfolioManager.getCostComponentsForAction(
         product.getIdentifier(),
         customerCase.getIdentifier(),
@@ -270,9 +264,10 @@
         null,
         null,
         DateConverter.toIsoString(referenceDate.plusDays(dayNumber)));
-    return nextPayment.getCostComponents().stream().filter(x -> x.getChargeIdentifier().equals(ChargeIdentifiers.REPAY_PRINCIPAL_ID)).findFirst()
-        .orElseThrow(() -> new IllegalArgumentException("return missing repayment charge."))
-        .getAmount();
+    final BigDecimal nextRepaymentAmount = nextPayment.getBalanceAdjustments()
+        .getOrDefault(AccountDesignators.ENTRY, BigDecimal.ZERO).negate();
+    Assert.assertTrue(nextRepaymentAmount.signum() != -1);
+    return nextRepaymentAmount;
   }
 
   //Create product and set charges to fixed fees.
@@ -416,6 +411,8 @@
     expectedCurrentPrincipal = BigDecimal.ZERO;
     interestAccrued = BigDecimal.ZERO;
     nonLateFees = BigDecimal.ZERO;
+    lateFees = BigDecimal.ZERO;
+    updateBalanceMock();
   }
 
   //Approve the case, accept a loan origination fee, and prepare to disburse the loan by earmarking the funds.
@@ -463,6 +460,9 @@
     expectedCurrentPrincipal = expectedCurrentPrincipal.add(amount);
     interestAccrued = BigDecimal.ZERO;
     nonLateFees = nonLateFees.add(disbursementFeeAmount);
+    lateFees = BigDecimal.ZERO;
+
+    updateBalanceMock();
   }
 
   private void step6CalculateInterestAndCheckForLatenessForWeek(
@@ -473,21 +473,22 @@
         (weekNumber * 7) + 1,
         (weekNumber + 1) * 7,
         -1,
-        null);
+        BigDecimal.ZERO);
   }
 
   private void step6CalculateInterestAndCheckForLatenessForRangeOfDays(
       final LocalDateTime referenceDate,
       final int startInclusive,
       final int endInclusive,
-      final int dayOfLateFee,
+      final int relativeDayOfLateFee,
       final BigDecimal calculatedLateFee) throws InterruptedException {
     try {
+      final LocalDateTime absoluteDayOfLateFee = referenceDate.plusDays(startInclusive + relativeDayOfLateFee);
       IntStream.rangeClosed(startInclusive, endInclusive)
           .mapToObj(referenceDate::plusDays)
           .forEach(day -> {
             try {
-              if (day.equals(referenceDate.plusDays(dayOfLateFee))) {
+              if (day.equals(absoluteDayOfLateFee)) {
                 step6CalculateInterestAccrualAndCheckForLateness(day, calculatedLateFee);
               }
               else {
@@ -511,30 +512,21 @@
   private void step6CalculateInterestAccrualAndCheckForLateness(
       final LocalDateTime forTime,
       final BigDecimal calculatedLateFee) throws InterruptedException {
-    logger.info("step6CalculateInterestAccrualAndCheckForLateness  '{}', '{}'", forTime, calculatedLateFee);
+    logger.info("step6CalculateInterestAccrualAndCheckForLateness  '{}'", forTime);
     final String beatIdentifier = "alignment0";
     final String midnightTimeStamp = DateConverter.toIsoString(forTime);
 
-    final BigDecimal allFees = nonLateFees.add(calculatedLateFee);
-    AccountingFixture.mockBalance(customerLoanPrincipalIdentifier, expectedCurrentPrincipal);
-    AccountingFixture.mockBalance(customerLoanInterestIdentifier, interestAccrued);
-    AccountingFixture.mockBalance(customerLoanFeeIdentifier, allFees);
-
     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);
+    logger.info("calculatedLateFee '{}'", calculatedLateFee);
 
 
     checkCostComponentForActionCorrect(
@@ -578,7 +570,12 @@
     creditors.add(new Creditor(
         AccountingFixture.LOAN_INTEREST_ACCRUAL_ACCOUNT_IDENTIFIER,
         calculatedInterest.toPlainString()));
-    AccountingFixture.verifyTransfer(ledgerManager, debtors, creditors, product.getIdentifier(), customerCase.getIdentifier(), Action.APPLY_INTEREST);
+    AccountingFixture.verifyTransfer(
+        ledgerManager,
+        debtors,
+        creditors,
+        product.getIdentifier(),
+        customerCase.getIdentifier(), Action.APPLY_INTEREST);
 
 
     if (calculatedLateFee.compareTo(BigDecimal.ZERO) != 0) {
@@ -591,11 +588,19 @@
       lateFeeCreditors.add(new Creditor(
           AccountingFixture.LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER,
           calculatedLateFee.toPlainString()));
-      AccountingFixture.verifyTransfer(ledgerManager, lateFeeDebtors, lateFeeCreditors, product.getIdentifier(), customerCase.getIdentifier(), Action.APPLY_INTEREST);
+      AccountingFixture.verifyTransfer(
+          ledgerManager,
+          lateFeeDebtors,
+          lateFeeCreditors,
+          product.getIdentifier(),
+          customerCase.getIdentifier(),
+          Action.MARK_LATE);
+      lateFees = lateFees.add(calculatedLateFee);
     }
     interestAccrued = interestAccrued.add(calculatedInterest);
+
+    updateBalanceMock();
     logger.info("Completed step6CalculateInterestAccrualAndCheckForLateness");
-    logger.info("interestAccrued '{}'", interestAccrued);
   }
 
   private void step7PaybackPartialAmount(
@@ -604,18 +609,7 @@
       final int dayNumber,
       final BigDecimal lateFee) throws InterruptedException {
     logger.info("step7PaybackPartialAmount '{}'", amount);
-
-    final BigDecimal allFees = lateFee.add(nonLateFees);
-    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);
+    final BigDecimal principal = amount.subtract(interestAccrued).subtract(lateFee.add(nonLateFees));
 
     checkCostComponentForActionCorrect(
         product.getIdentifier(),
@@ -625,7 +619,7 @@
         amount,
         new CostComponent(ChargeIdentifiers.REPAY_PRINCIPAL_ID, principal),
         new CostComponent(ChargeIdentifiers.REPAY_INTEREST_ID, interestAccrued),
-        new CostComponent(ChargeIdentifiers.REPAY_FEES_ID, allFees),
+        new CostComponent(ChargeIdentifiers.REPAY_FEES_ID, lateFee.add(nonLateFees)),
         new CostComponent(ChargeIdentifiers.INTEREST_ID, interestAccrued),
         new CostComponent(ChargeIdentifiers.LATE_FEE_ID, lateFee));
     checkStateTransfer(
@@ -647,8 +641,8 @@
       debtors.add(new Debtor(AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER, interestAccrued.toPlainString()));
       debtors.add(new Debtor(AccountingFixture.LOAN_INTEREST_ACCRUAL_ACCOUNT_IDENTIFIER, interestAccrued.toPlainString()));
     }
-    if (allFees.compareTo(BigDecimal.ZERO) != 0) {
-      debtors.add(new Debtor(AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER, allFees.toPlainString()));
+    if (lateFee.add(nonLateFees).compareTo(BigDecimal.ZERO) != 0) {
+      debtors.add(new Debtor(AccountingFixture.TELLER_ONE_ACCOUNT_IDENTIFIER, lateFee.add(nonLateFees).toPlainString()));
     }
     if (lateFee.compareTo(BigDecimal.ZERO) != 0) {
       debtors.add(new Debtor(AccountingFixture.LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER, lateFee.toPlainString()));
@@ -660,8 +654,8 @@
       creditors.add(new Creditor(customerLoanInterestIdentifier, interestAccrued.toPlainString()));
       creditors.add(new Creditor(AccountingFixture.CONSUMER_LOAN_INTEREST_ACCOUNT_IDENTIFIER, interestAccrued.toPlainString()));
     }
-    if (allFees.compareTo(BigDecimal.ZERO) != 0) {
-      creditors.add(new Creditor(customerLoanFeeIdentifier, allFees.toPlainString()));
+    if (lateFee.add(nonLateFees).compareTo(BigDecimal.ZERO) != 0) {
+      creditors.add(new Creditor(customerLoanFeeIdentifier, lateFee.add(nonLateFees).toPlainString()));
     }
     if (lateFee.compareTo(BigDecimal.ZERO) != 0) {
       creditors.add(new Creditor(AccountingFixture.LATE_FEE_INCOME_ACCOUNT_IDENTIFIER, lateFee.toPlainString()));
@@ -672,20 +666,14 @@
     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);
+    lateFees = BigDecimal.ZERO.setScale(MINOR_CURRENCY_UNIT_DIGITS, RoundingMode.HALF_EVEN);
+
+    updateBalanceMock();
     logger.info("Completed step7PaybackPartialAmount");
-    logger.info("currentPrincipal '{}'", expectedCurrentPrincipal);
-    logger.info("interestAccrued '{}'", interestAccrued);
-    logger.info("nonLateFees '{}'", nonLateFees);
   }
 
   private void step8Close() throws InterruptedException {
     logger.info("step8Close");
-    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(),
@@ -703,4 +691,18 @@
 
     checkNextActionsCorrect(product.getIdentifier(), customerCase.getIdentifier());
   }
+
+  private void updateBalanceMock() {
+    logger.info("Updating balance mocks");
+    final BigDecimal allFees = lateFees.add(nonLateFees);
+    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, lateFees);
+    logger.info("updated currentPrincipal '{}'", expectedCurrentPrincipal);
+    logger.info("updated interestAccrued '{}'", interestAccrued);
+    logger.info("updated nonLateFees '{}'", nonLateFees);
+    logger.info("updated lateFees '{}'", lateFees);
+  }
 }
\ No newline at end of file
diff --git a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
index c4fe59d..028fec6 100644
--- a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
+++ b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
@@ -216,7 +216,7 @@
     interestCharge.setForCycleSizeUnit(ChronoUnit.YEARS);
     interestCharge.setAccrueAction(Action.APPLY_INTEREST.name());
     interestCharge.setAccrualAccountDesignator(AccountDesignators.INTEREST_ACCRUAL);
-    interestCharge.setProportionalTo(ChargeProportionalDesignator.RUNNING_BALANCE_DESIGNATOR.getValue());
+    interestCharge.setProportionalTo(ChargeProportionalDesignator.PRINCIPAL_AND_INTEREST_DESIGNATOR.getValue());
     interestCharge.setChargeMethod(ChargeDefinition.ChargeMethod.INTEREST);
     interestCharge.setReadOnly(true);
 
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 a494427..6880d7c 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
@@ -132,6 +132,11 @@
         final BigDecimal customerLoanRunningBalance = runningBalances.getBalance(AccountDesignators.CUSTOMER_LOAN_GROUP);
         return customerLoanRunningBalance.subtract(paymentBuilder.getBalanceAdjustment(AccountDesignators.CUSTOMER_LOAN_GROUP));
       }
+      case PRINCIPAL_AND_INTEREST_DESIGNATOR: {
+        final BigDecimal customerLoanPrincipal = runningBalances.getBalance(AccountDesignators.CUSTOMER_LOAN_PRINCIPAL);
+        final BigDecimal customerLoanInterest = runningBalances.getBalance(AccountDesignators.CUSTOMER_LOAN_INTEREST);
+        return customerLoanInterest.add(customerLoanPrincipal);
+      }
       case CONTRACTUAL_REPAYMENT_DESIGNATOR:
         return contractualRepayment;
       case REQUESTED_DISBURSEMENT_DESIGNATOR: