Introduce a new type of ACTUAL during calculation of days in year

This commit is contained in:
Jose Alberto Hernandez
2025-03-20 11:18:47 -05:00
parent 0b8dd0e3ff
commit 319ce8057a
27 changed files with 345 additions and 147 deletions
@@ -1,8 +1,9 @@
<div class="container mat-elevation-z8">
<mat-card>
<mat-card-content>
<div fxLayout="column">
<div fxLayout="column" class="m-b-10">
<mifosx-repayment-schedule-tab
*ngIf="repaymentScheduleDetails"
fxFlex="100%"
[repaymentScheduleDetails]="repaymentScheduleDetails"
[forEditing]="true"
@@ -14,7 +15,7 @@
<button type="button" mat-raised-button [routerLink]="['../../general']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button type="button" (click)="reset()">{{ 'labels.buttons.Reset' | translate }}</button>
<button type="button" mat-raised-button (click)="reset()">{{ 'labels.buttons.Reset' | translate }}</button>
<button type="button" color="primary" mat-raised-button (click)="applyPattern()">
{{ 'labels.buttons.Pattern' | translate }}
</button>
@@ -24,7 +24,7 @@ export class EditRepaymentScheduleComponent implements OnInit {
/** Indicates If the Schedule has been validated */
wasValidated = false;
/** Stores the Repayment Schedule data */
repaymentScheduleDetails: any[] = [];
repaymentScheduleDetails: any[] | null = null;
/** Stores the Installments changed */
repaymentScheduleChanges: any = {};
@@ -1,5 +1,5 @@
<div class="container">
<div fxLayout="row" class="m-t-20" fxLayoutAlign="end center">
<div fxLayout="row" class="m-t-20" fxLayoutAlign="end center" *ngIf="!forEditing">
<button mat-raised-button color="primary" (click)="exportToPDF()">
<fa-icon icon="download" class="m-r-10"></fa-icon>Export to PDF
</button>
@@ -8,52 +8,52 @@
<table mat-table [dataSource]="repaymentScheduleDetails.periods" *ngIf="!forEditing" id="repaymentSchedule">
<ng-container matColumnDef="number">
<th mat-header-cell class="center" *matHeaderCellDef>#</th>
<td mat-cell class="right" *matCellDef="let ele">{{ ele.period }}</td>
<td mat-cell class="right" *matCellDef="let item">{{ item.period }}</td>
<td mat-footer-cell *matFooterCellDef>&nbsp;</td>
</ng-container>
<ng-container matColumnDef="days">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Days' | translate }}</th>
<td mat-cell class="center" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">{{ ele.daysInPeriod }}</td>
<td mat-cell class="center" *matCellDef="let item" [ngClass]="installmentStyle(item)">{{ item.daysInPeriod }}</td>
<td mat-footer-cell class="center" *matFooterCellDef><b> Total</b></td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
<td mat-cell class="m-r-5" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.dueDate | dateFormat }}
<td mat-cell class="m-r-5" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.dueDate | dateFormat }}
</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="paiddate">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Paid Date' | translate }}</th>
<td mat-cell class="center" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.obligationsMetOnDate | dateFormat }}
<td mat-cell class="center" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.obligationsMetOnDate | dateFormat }}
</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="check">
<th mat-header-cell *matHeaderCellDef>&nbsp;</th>
<td mat-cell class="center" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
<span *ngIf="ele.obligationsMetOnDate"> <i class="fa fa-check"></i> </span>
<td mat-cell class="center" *matCellDef="let item" [ngClass]="installmentStyle(item)">
<span *ngIf="item.obligationsMetOnDate"> <i class="fa fa-check"></i> </span>
</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="balanceOfLoan">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance Of Loan' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.principalLoanBalanceOutstanding | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.principalLoanBalanceOutstanding | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>&nbsp;</td>
</ng-container>
<ng-container matColumnDef="principalDue">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Principal Due' | translate }}</th>
<td mat-cell class="check r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.principalDue | formatNumber }}
<td mat-cell class="check r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.principalDue | formatNumber }}
</td>
<td mat-footer-cell class="check r-amount" *matFooterCellDef>
<b>
@@ -64,8 +64,8 @@
<ng-container matColumnDef="interest">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Interest' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.interestOriginalDue | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.interestOriginalDue | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
@@ -76,8 +76,8 @@
<ng-container matColumnDef="fees">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Fees' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.feeChargesDue | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.feeChargesDue | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
@@ -88,8 +88,8 @@
<ng-container matColumnDef="penalties">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Penalties' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.penaltyChargesDue | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.penaltyChargesDue | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
@@ -100,8 +100,8 @@
<ng-container matColumnDef="due">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Due' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.totalDueForPeriod | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.totalDueForPeriod | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
@@ -112,8 +112,8 @@
<ng-container matColumnDef="paid">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Paid' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.totalPaidForPeriod | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.totalPaidForPeriod | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b> {{ repaymentScheduleDetails.totalRepayment | currency: currencyCode : 'symbol-narrow' : '1.2-2' }} </b>
@@ -122,8 +122,8 @@
<ng-container matColumnDef="inadvance">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.In advance' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.totalPaidInAdvanceForPeriod | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.totalPaidInAdvanceForPeriod | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b> {{ repaymentScheduleDetails.totalPaidInAdvance | currency: currencyCode : 'symbol-narrow' : '1.2-2' }} </b>
@@ -132,8 +132,8 @@
<ng-container matColumnDef="late">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Late' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.totalPaidLateForPeriod | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.totalPaidLateForPeriod | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b> {{ repaymentScheduleDetails.totalPaidLate | currency: currencyCode : 'symbol-narrow' : '1.2-2' }} </b>
@@ -143,8 +143,8 @@
<ng-container *ngIf="isWaived">
<ng-container matColumnDef="waived">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Waived' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele" [ngClass]="installmentStyle(ele)">
{{ ele.totalWaivedForPeriod | formatNumber }}
<td mat-cell class="r-amount" *matCellDef="let item" [ngClass]="installmentStyle(item)">
{{ item.totalWaivedForPeriod | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b> {{ repaymentScheduleDetails.totalWaived | currency: currencyCode : 'symbol-narrow' : '1.2-2' }} </b>
@@ -155,14 +155,14 @@
<ng-container *ngIf="!isWaived">
<ng-container matColumnDef="waived">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let ele"></td>
<td mat-cell *matCellDef="let item"></td>
<td mat-footer-cell *matFooterCellDef><b> </b></td>
</ng-container>
</ng-container>
<ng-container matColumnDef="outstanding">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Outstanding' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele">{{ ele.totalOutstandingForPeriod | formatNumber }}</td>
<td mat-cell class="r-amount" *matCellDef="let item">{{ item.totalOutstandingForPeriod | formatNumber }}</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b> {{ repaymentScheduleDetails.totalOutstanding | currency: currencyCode : 'symbol-narrow' : '1.2-2' }} </b>
</td>
@@ -200,98 +200,95 @@
</table>
<!-- Repayment Schedule to be Edited -->
<div *ngIf="forEditing" fxLayout="column" fxFlex="100%">
<table mat-table [dataSource]="repaymentScheduleDetails.periods">
<ng-container matColumnDef="number">
<th mat-header-cell class="center" *matHeaderCellDef>#</th>
<td mat-cell *matCellDef="let ele">{{ ele.period }}</td>
<td mat-footer-cell *matFooterCellDef>&nbsp;</td>
</ng-container>
<table
mat-table
[dataSource]="repaymentScheduleDetails.periods"
*ngIf="forEditing && repaymentScheduleDetails.periods.length > 0"
>
<ng-container matColumnDef="number">
<th mat-header-cell class="center" *matHeaderCellDef>#</th>
<td mat-cell *matCellDef="let item">{{ item.period }}</td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
<td mat-cell class="m-r-10" *matCellDef="let ele">{{ ele.dueDate | dateFormat }}</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
<td mat-cell class="m-r-10" *matCellDef="let item">
<ng-container>
{{ item.dueDate | dateFormat }}
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="balanceOfLoan">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance Of Loan' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele">
{{ ele.principalLoanBalanceOutstanding | formatNumber }}
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>&nbsp;</td>
</ng-container>
<ng-container matColumnDef="balanceOfLoan">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Balance Of Loan' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let item">
{{ item.principalLoanBalanceOutstanding | formatNumber }}
</td>
</ng-container>
<ng-container matColumnDef="principalDue">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Principal Due' | translate }}</th>
<td mat-cell class="check r-amount" *matCellDef="let ele">{{ ele.principalDue | formatNumber }}</td>
<td mat-footer-cell class="check r-amount" *matFooterCellDef>
<b>
{{
repaymentScheduleDetails.totalPrincipalExpected | currency: currencyCode : 'symbol-narrow' : '1.2-2'
}}</b
>
</td>
</ng-container>
<ng-container matColumnDef="principalDue">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Principal Due' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let item">
<ng-container>
{{ item.principalDue | formatNumber }}
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="interest">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Interest' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele">{{ ele.interestOriginalDue | formatNumber }}</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
{{ repaymentScheduleDetails.totalInterestCharged | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
</b>
</td>
</ng-container>
<ng-container matColumnDef="interest">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Interest' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let item">{{ item.interestOriginalDue | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="fees">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Fees' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele">{{ ele.feeChargesDue | formatNumber }}</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
{{ repaymentScheduleDetails.totalFeeChargesCharged | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
</b>
</td>
</ng-container>
<ng-container matColumnDef="fees">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Fees' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let item">{{ item.feeChargesDue | formatNumber }}</td>
</ng-container>
<ng-container matColumnDef="due">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Installment Amount' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let ele">
<span *ngIf="!ele.changed">
{{ ele.totalDueForPeriod | formatNumber }}
</span>
<span *ngIf="ele.changed" class="amount-changed">
<b>{{ ele.totalDueForPeriod | formatNumber }}</b>
</span>
</td>
<td mat-footer-cell class="r-amount" *matFooterCellDef>
<b>
{{ repaymentScheduleDetails.totalRepaymentExpected | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
</b>
</td>
</ng-container>
<ng-container matColumnDef="due">
<th mat-header-cell class="r-amount" *matHeaderCellDef>{{ 'labels.inputs.Installment Amount' | translate }}</th>
<td mat-cell class="r-amount" *matCellDef="let item">
<span *ngIf="!item.changed">
{{ item.totalDueForPeriod | formatNumber }}
</span>
<span *ngIf="item.changed" class="amount-changed">
<b>{{ item.totalDueForPeriod | formatNumber }}</b>
</span>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let ele">
<button
*ngIf="ele.period"
type="button"
color="primary"
mat-icon-button
matTooltip="{{ 'tooltips.Edit' | translate }}"
matTooltipPosition="above"
(click)="editPeriod(ele)"
>
<fa-icon icon="edit" size="lg"></fa-icon>
</button>
</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell class="center" *matCellDef="let item">
<span *ngIf="item.period && item.period + 1 < repaymentScheduleDetails.periods.length">
<ng-container>
<button
type="button"
color="primary"
mat-icon-button
matTooltip="{{ 'tooltips.Edit' | translate }}"
matTooltipPosition="above"
(click)="editInstallment(item)"
>
<fa-icon icon="edit" size="lg"></fa-icon>
</button>
<button
type="button"
color="warn"
mat-icon-button
matTooltip="{{ 'tooltips.Delete' | translate }}"
matTooltipPosition="above"
(click)="startEdit(item.period)"
>
<fa-icon icon="trash" size="lg"></fa-icon>
</button>
</ng-container>
</span>
</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumnsEdit"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumnsEdit"></tr>
<tr mat-footer-row *matFooterRowDef="displayedColumnsEdit"></tr>
</table>
</div>
<tr mat-header-row *matHeaderRowDef="displayedColumnsEdit"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumnsEdit"></tr>
</table>
</div>
@@ -1,8 +1,13 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute } from '@angular/router';
import { Dates } from 'app/core/utils/dates';
import { RepaymentSchedulePeriod } from 'app/loans/models/loan-account.model';
import { SettingsService } from 'app/settings/settings.service';
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
import { DatepickerBase } from 'app/shared/form-dialog/formfield/model/datepicker-base';
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
import { jsPDF, jsPDFOptions } from 'jspdf';
import autoTable from 'jspdf-autotable';
@@ -12,7 +17,7 @@ import autoTable from 'jspdf-autotable';
templateUrl: './repayment-schedule-tab.component.html',
styleUrls: ['./repayment-schedule-tab.component.scss']
})
export class RepaymentScheduleTabComponent implements OnInit {
export class RepaymentScheduleTabComponent implements OnInit, OnChanges {
/** Currency Code */
@Input() currencyCode: string;
/** Loan Repayment Schedule to be Edited */
@@ -21,6 +26,13 @@ export class RepaymentScheduleTabComponent implements OnInit {
@Input() repaymentScheduleDetails: any = null;
loanDetailsDataRepaymentSchedule: any = [];
editCache: { [key: string]: any } = {};
listOfData: any[] = [];
repaymentSchedulePeriods: RepaymentSchedulePeriod[] = [];
totalRepaymentExpected: number = 0;
/** Stores if there is any waived amount */
isWaived: boolean;
/** Columns to be displayed in original schedule table. */
@@ -50,7 +62,8 @@ export class RepaymentScheduleTabComponent implements OnInit {
'principalDue',
'interest',
'fees',
'due'
'due',
'actions'
];
/** Form functions event */
@@ -65,7 +78,8 @@ export class RepaymentScheduleTabComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private settingsService: SettingsService,
private dates: Dates
private dateUtils: Dates,
private dialog: MatDialog
) {
this.route.parent.data.subscribe((data: { loanDetailsData: any }) => {
if (data.loanDetailsData) {
@@ -81,6 +95,14 @@ export class RepaymentScheduleTabComponent implements OnInit {
this.repaymentScheduleDetails = this.loanDetailsDataRepaymentSchedule;
}
this.isWaived = this.repaymentScheduleDetails.totalWaived > 0;
this.updateEditCache();
}
ngOnChanges(changes: SimpleChanges): void {
this.totalRepaymentExpected = 0;
this.listOfData.forEach((item) => {
this.totalRepaymentExpected = this.totalRepaymentExpected + item.totalDueForPeriod;
});
}
installmentStyle(installment: RepaymentSchedulePeriod): string {
@@ -103,8 +125,8 @@ export class RepaymentScheduleTabComponent implements OnInit {
if (!installment.fromDate) {
return '';
} else {
const fromDate = this.dates.parseDate(installment.fromDate);
const dueDate = this.dates.parseDate(installment.dueDate);
const fromDate = this.dateUtils.parseDate(installment.fromDate);
const dueDate = this.dateUtils.parseDate(installment.dueDate);
if (fromDate <= this.businessDate && this.businessDate < dueDate) {
return 'current';
}
@@ -116,7 +138,7 @@ export class RepaymentScheduleTabComponent implements OnInit {
}
exportToPDF() {
const businessDate = this.dates.formatDate(this.settingsService.businessDate, Dates.DEFAULT_DATEFORMAT);
const businessDate = this.dateUtils.formatDate(this.settingsService.businessDate, Dates.DEFAULT_DATEFORMAT);
const fileName = `repaymentschedule-${businessDate}.pdf`;
const options: jsPDFOptions = {
@@ -144,4 +166,77 @@ export class RepaymentScheduleTabComponent implements OnInit {
});
pdf.save(fileName);
}
editInstallment(period: RepaymentSchedulePeriod): void {
this.editCache[period.period].edit = true;
const formfields: FormfieldBase[] = [
new DatepickerBase({
controlName: 'dueDate',
label: 'Due Date',
value: this.dateUtils.parseDate(period.dueDate),
type: 'date',
required: true
}),
new InputBase({
controlName: 'principalDue',
label: 'Amount',
value: period.principalDue,
type: 'number',
required: true
})
];
const data = {
title: 'Period',
formfields: formfields
};
const addDialogRef = this.dialog.open(FormDialogComponent, { data, width: '50rem' });
addDialogRef.afterClosed().subscribe((response: any) => {
if (response.data) {
}
});
}
cancelEdit(id: string): void {
const index = this.listOfData.findIndex((item) => item.id === id);
this.editCache[id] = {
data: { ...this.listOfData[index] },
edit: false
};
}
saveEdit(period: string): void {
const index = this.listOfData.findIndex((item) => item.period === period);
Object.assign(this.listOfData[index], this.editCache[period].data);
this.editCache[period].edit = false;
this.editPeriod.emit(period);
}
updateEditCache(): void {
if (this.repaymentScheduleDetails != null) {
this.listOfData = this.repaymentScheduleDetails.periods;
this.totalRepaymentExpected = 0;
this.listOfData.forEach((item) => {
this.editCache[item.period] = {
edit: false,
data: { ...item }
};
this.totalRepaymentExpected = this.totalRepaymentExpected + item.totalDueForPeriod;
});
}
}
numberOnly(inputFormControl: any, event: any): boolean {
const charCode = event.which ? event.which : event.keyCode;
if (charCode === 46) {
if (!(inputFormControl.value.indexOf('.') > -1)) {
return true;
}
return false;
} else if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
}
}
@@ -496,6 +496,11 @@
<span fxFlex="53%">{{ loanProduct.daysInYearType?.value | translateKey: 'catalogs' }}</span>
</div>
<div fxFlexFill *ngIf="isAdvancedPaymentAllocation && loanProduct.daysInYearCustomStrategy">
<span fxFlex="47%">{{ 'labels.inputs.Days in year custom strategy' | translate }}:</span>
<span fxFlex="53%">{{ loanProduct.daysInYearCustomStrategy.value | translateKey: 'catalogs' }}</span>
</div>
<div fxFlexFill>
<span fxFlex="47%">{{ 'labels.inputs.Days in month' | translate }}:</span>
<span fxFlex="53%">{{ loanProduct.daysInMonthType?.value | translateKey: 'catalogs' }}</span>
@@ -275,6 +275,13 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
this.loanProductsTemplate.daysInYearTypeOptions
);
this.loanProduct.daysInYearType = optionValue;
if (this.isAdvancedPaymentAllocation && this.loanProduct.daysInYearType.id == 1) {
optionValue = this.optionDataLookUp(
this.loanProduct.daysInYearCustomStrategy,
this.loanProductsTemplate.daysInYearCustomStrategyOptions
);
}
this.loanProduct.daysInYearCustomStrategy = optionValue;
optionValue = this.optionDataLookUp(
this.loanProduct.interestRateFrequencyType,
this.loanProductsTemplate.interestRateFrequencyTypeOptions
@@ -1,4 +1,6 @@
.container {
max-width: 86rem;
width: 96%;
padding-bottom: 30px;
}
@@ -1,3 +1,5 @@
.container {
max-width: 86rem;
width: 96%;
padding-bottom: 30px;
}
@@ -330,6 +330,21 @@
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%" *ngIf="useDaysInYearCustomStrategy">
<mat-label>{{ 'labels.inputs.Days in year custom strategy' | translate }}</mat-label>
<mat-select
matTooltip="{{ 'tooltips.To calculate interest' | translate }}"
formControlName="daysInYearCustomStrategy"
>
<mat-option
*ngFor="let daysInYearCustomStrategy of daysInYearCustomStrategyOptions"
[value]="daysInYearCustomStrategy.id"
>
{{ daysInYearCustomStrategy.value | translateKey: 'catalogs' }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Days in month' | translate }}</mat-label>
<mat-select
@@ -45,6 +45,8 @@ export class LoanProductSettingsStepComponent implements OnInit {
useDueForRepaymentsConfigurations = false;
rescheduleStrategyTypeDisabled = false;
chargeOffBehaviourData: StringEnumOptionData[] = [];
daysInYearCustomStrategyOptions: OptionData[] = [];
useDaysInYearCustomStrategy = false;
/** Values to Days for Repayments */
defaultConfigValues: GlobalConfiguration[] = [];
@@ -88,8 +90,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
this.loanScheduleTypeData = this.loanProductsTemplate.loanScheduleTypeOptions;
this.loanScheduleProcessingTypeData = this.loanProductsTemplate.loanScheduleProcessingTypeOptions;
this.chargeOffBehaviourData = this.loanProductsTemplate.chargeOffBehaviourOptions;
// this.useDueForRepaymentsConfigurations = (!this.loanProduct.dueDaysForRepaymentEvent && !this.loanProduct.overDueDaysForRepaymentEvent);
this.daysInYearCustomStrategyOptions = this.loanProductsTemplate.daysInYearCustomStrategyOptions;
const transactionProcessingStrategyCode: string =
this.loanProductsTemplate.transactionProcessingStrategyCode || this.transactionProcessingStrategyData[0].code;
@@ -319,6 +320,23 @@ export class LoanProductSettingsStepComponent implements OnInit {
setConditionalControls() {
const allowAttributeOverrides = this.loanProductSettingsForm.get('allowAttributeOverrides');
this.loanProductSettingsForm.get('daysInYearType').valueChanges.subscribe((daysInYearType: any) => {
if (this.isAdvancedTransactionProcessingStrategy) {
this.useDaysInYearCustomStrategy = daysInYearType == 1;
if (this.useDaysInYearCustomStrategy) {
const daysInYearCustomStrategy: string = this.loanProductsTemplate.daysInYearCustomStrategy?.id
? this.loanProductsTemplate.daysInYearCustomStrategy.id
: '';
this.loanProductSettingsForm.addControl(
'daysInYearCustomStrategy',
new UntypedFormControl(daysInYearCustomStrategy, Validators.required)
);
} else {
this.loanProductSettingsForm.removeControl('daysInYearCustomStrategy');
}
}
});
this.loanProductSettingsForm
.get('interestCalculationPeriodType')
.valueChanges.subscribe((interestCalculationPeriodType: any) => {
@@ -696,6 +714,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
if (productSettings['delinquencyBucketId'] === '') {
productSettings['delinquencyBucketId'] = null;
}
console.log(productSettings);
return productSettings;
}
@@ -52,6 +52,7 @@ export interface LoanProduct {
paymentAllocation?: PaymentAllocation[];
creditAllocation?: CreditAllocation[];
daysInMonthType: OptionData;
daysInYearCustomStrategy?: OptionData;
daysInYearType: OptionData;
isInterestRecalculationEnabled: boolean;
interestRecalculationData?: InterestRecalculationData;
@@ -1,6 +1,6 @@
.product-card {
margin: 0 auto;
max-width: 80rem;
max-width: 90rem;
width: 90%;
padding: 0;
+4 -2
View File
@@ -111,7 +111,8 @@ import {
faCalendarCheck,
faPause,
faReceipt,
faTableCells
faTableCells,
faSave
} from '@fortawesome/free-solid-svg-icons';
/**
@@ -235,7 +236,8 @@ export class IconsModule {
faBars,
faUndo,
faReceipt,
faTableCells
faTableCells,
faSave
);
}
}