Upgrading to Angular 20:
Replaced checked in package-lock.json by regenerated one. Ran ng update @angular/core@20 @angular/cli@20 Ran npm install @angular-builders/jest@^20.0.0 @fortawesome/angular-fontawesome@^3.0.0 @swimlane/ngx-graph@^11 Ran npm install ngx-mat-select-search@^8.0.2. Ran ng update @angular/material@20. Updated all eslint and typescript to the latest versions. Removed @angular-devkit/schematics. Updated fontawesome. Updated rxjs and tslib. Moved required node version from 16 to 20. Updated jest-preset-angular. Set preserveWhitespaces to false. Corrected two type declarations in two typescript files to make ng serve run without errors. Removed unused angular-devkit/schematics from view-user.component.ts . Updated list of supported browsers. Upgraded prettier. Ran prettier . --write the first time. Ran prettier . --write the second time. Ran ng generate @angular/core:inject with defaults, excepted a handful of files. Fixed remaining eslint problems. Added dist directory to ignores in eslint.config.js. Let prettier fix formatting, almost everything is just line breaks. Made htmlhint ignore @if and @for Angular constructs. Updated node version in Github workflow to 22.12.0 (build.yml). Updated .env.ts. Updated Angular datetime format strings from YYYY-MM-DD to yyyy-MM-dd. Merged changes from dev into angular20 branch.
This commit is contained in:
+40
-37
@@ -2,9 +2,11 @@
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Charge' | translate }}</mat-label>
|
||||
<mat-select #charge>
|
||||
<mat-option *ngFor="let charge of chargeData" [value]="charge">
|
||||
{{ charge.name }}
|
||||
</mat-option>
|
||||
@for (charge of chargeData; track charge) {
|
||||
<mat-option [value]="charge">
|
||||
{{ charge.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
@@ -55,38 +57,37 @@
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
<span
|
||||
*ngIf="charge.chargeTimeType.value === 'Specified due date' || charge.chargeTimeType.value === 'Weekly Fee'"
|
||||
>
|
||||
{{ (charge.dueDate | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
<span *ngIf="charge.chargeTimeType.value === 'Monthly Fee' || charge.chargeTimeType.value === 'Annual Fee'">
|
||||
{{ (charge.feeOnMonthDay | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
<span
|
||||
*ngIf="
|
||||
!(
|
||||
charge.chargeTimeType.value === 'Monthly Fee' ||
|
||||
charge.chargeTimeType.value === 'Annual Fee' ||
|
||||
charge.chargeTimeType.value === 'Specified due date' ||
|
||||
charge.chargeTimeType.value === 'Weekly Fee'
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ 'labels.inputs.N/A' | translate }}
|
||||
</span>
|
||||
<button
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
*ngIf="
|
||||
charge.chargeTimeType.value === 'Weekly Fee' ||
|
||||
@if (charge.chargeTimeType.value === 'Specified due date' || charge.chargeTimeType.value === 'Weekly Fee') {
|
||||
<span>
|
||||
{{ (charge.dueDate | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
}
|
||||
@if (charge.chargeTimeType.value === 'Monthly Fee' || charge.chargeTimeType.value === 'Annual Fee') {
|
||||
<span>
|
||||
{{ (charge.feeOnMonthDay | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
}
|
||||
@if (
|
||||
!(
|
||||
charge.chargeTimeType.value === 'Monthly Fee' ||
|
||||
charge.chargeTimeType.value === 'Annual Fee' ||
|
||||
charge.chargeTimeType.value === 'Specified due date'
|
||||
"
|
||||
(click)="editChargeDate(charge)"
|
||||
>
|
||||
<fa-icon icon="pen"></fa-icon>
|
||||
</button>
|
||||
charge.chargeTimeType.value === 'Specified due date' ||
|
||||
charge.chargeTimeType.value === 'Weekly Fee'
|
||||
)
|
||||
) {
|
||||
<span>
|
||||
{{ 'labels.inputs.N/A' | translate }}
|
||||
</span>
|
||||
}
|
||||
@if (
|
||||
charge.chargeTimeType.value === 'Weekly Fee' ||
|
||||
charge.chargeTimeType.value === 'Annual Fee' ||
|
||||
charge.chargeTimeType.value === 'Specified due date'
|
||||
) {
|
||||
<button mat-icon-button color="primary" (click)="editChargeDate(charge)">
|
||||
<fa-icon icon="pen"></fa-icon>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
@@ -142,7 +143,9 @@
|
||||
{{ 'labels.buttons.Next' | translate }}
|
||||
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
|
||||
</button>
|
||||
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
@if (loanId) {
|
||||
<button mat-raised-button [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
+7
-10
@@ -1,5 +1,5 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, Input, OnChanges } from '@angular/core';
|
||||
import { Component, OnInit, Input, OnChanges, inject } from '@angular/core';
|
||||
// import { FormControl } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import {
|
||||
@@ -65,6 +65,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
]
|
||||
})
|
||||
export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
dialog = inject(MatDialog);
|
||||
private dateUtils = inject(Dates);
|
||||
private route = inject(ActivatedRoute);
|
||||
private settingsService = inject(SettingsService);
|
||||
|
||||
// @Input loansAccountProductTemplate: LoansAccountProductTemplate
|
||||
@Input() loansAccountProductTemplate: any;
|
||||
// @Imput loansAccountTemplate: LoansAccountTemplate
|
||||
@@ -128,12 +133,7 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
* @param {Dates} dateUtils Date Utils
|
||||
* @param {SettingsService} settingsService Settings Service
|
||||
*/
|
||||
constructor(
|
||||
public dialog: MatDialog,
|
||||
private dateUtils: Dates,
|
||||
private route: ActivatedRoute,
|
||||
private settingsService: SettingsService
|
||||
) {
|
||||
constructor() {
|
||||
this.loanId = this.route.snapshot.params['loanId'];
|
||||
}
|
||||
|
||||
@@ -218,7 +218,6 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
type: 'number',
|
||||
required: false
|
||||
})
|
||||
|
||||
];
|
||||
const data = {
|
||||
title: 'Edit Charge Amount',
|
||||
@@ -249,7 +248,6 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
type: 'datetime-local',
|
||||
required: false
|
||||
})
|
||||
|
||||
];
|
||||
const data = {
|
||||
title: 'Edit Charge Date',
|
||||
@@ -291,7 +289,6 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
type: 'text',
|
||||
required: false
|
||||
})
|
||||
|
||||
];
|
||||
const data = {
|
||||
title: 'Edit Charge Fee Interval',
|
||||
|
||||
+44
-53
@@ -1,58 +1,49 @@
|
||||
<form [formGroup]="datatableForm">
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<div *ngFor="let datatableInput of datatableInputs" class="flex-48">
|
||||
<mat-form-field class="flex-100" *ngIf="!isBoolean(datatableInput.columnDisplayType)">
|
||||
<mat-label>{{ getInputName(datatableInput) }}</mat-label>
|
||||
|
||||
<mat-select
|
||||
*ngIf="isDropdown(datatableInput.columnDisplayType)"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
>
|
||||
<mat-option *ngFor="let code of datatableInput.columnValues" [value]="code.id">
|
||||
{{ code.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
<input
|
||||
matInput
|
||||
type="number"
|
||||
*ngIf="isNumeric(datatableInput.columnDisplayType)"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
/>
|
||||
|
||||
<input
|
||||
matInput
|
||||
*ngIf="isString(datatableInput.columnDisplayType)"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
/>
|
||||
|
||||
<textarea
|
||||
matInput
|
||||
*ngIf="isText(datatableInput.columnDisplayType)"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
></textarea>
|
||||
|
||||
<span *ngIf="isDate(datatableInput.columnDisplayType)" (click)="datePicker.open()">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="datePicker"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
class="date-picker"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #datePicker></mat-datepicker>
|
||||
</span>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox
|
||||
*ngIf="isBoolean(datatableInput.columnDisplayType)"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
labelPosition="before"
|
||||
class="margin-v"
|
||||
>
|
||||
{{ getInputName(datatableInput) }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@for (datatableInput of datatableInputs; track datatableInput) {
|
||||
<div class="flex-48">
|
||||
@if (!isBoolean(datatableInput.columnDisplayType)) {
|
||||
<mat-form-field class="flex-100">
|
||||
<mat-label>{{ getInputName(datatableInput) }}</mat-label>
|
||||
@if (isDropdown(datatableInput.columnDisplayType)) {
|
||||
<mat-select formControlName="{{ datatableInput.controlName }}">
|
||||
@for (code of datatableInput.columnValues; track code) {
|
||||
<mat-option [value]="code.id">
|
||||
{{ code.value }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
}
|
||||
@if (isNumeric(datatableInput.columnDisplayType)) {
|
||||
<input matInput type="number" formControlName="{{ datatableInput.controlName }}" />
|
||||
}
|
||||
@if (isString(datatableInput.columnDisplayType)) {
|
||||
<input matInput formControlName="{{ datatableInput.controlName }}" />
|
||||
}
|
||||
@if (isText(datatableInput.columnDisplayType)) {
|
||||
<textarea matInput formControlName="{{ datatableInput.controlName }}"></textarea>
|
||||
}
|
||||
@if (isDate(datatableInput.columnDisplayType)) {
|
||||
<span (click)="datePicker.open()">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="datePicker"
|
||||
formControlName="{{ datatableInput.controlName }}"
|
||||
class="date-picker"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #datePicker></mat-datepicker>
|
||||
</span>
|
||||
}
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (isBoolean(datatableInput.columnDisplayType)) {
|
||||
<mat-checkbox formControlName="{{ datatableInput.controlName }}" labelPosition="before" class="margin-v">
|
||||
{{ getInputName(datatableInput) }}
|
||||
</mat-checkbox>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="layout-row align-center gap-2percent margin-t responsive-column">
|
||||
|
||||
+5
-7
@@ -1,4 +1,4 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit, inject } from '@angular/core';
|
||||
import {
|
||||
UntypedFormBuilder,
|
||||
UntypedFormControl,
|
||||
@@ -26,6 +26,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
]
|
||||
})
|
||||
export class LoansAccountDatatableStepComponent implements OnInit {
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
private settingsService = inject(SettingsService);
|
||||
private dateUtils = inject(Dates);
|
||||
|
||||
/** Input Fields Data */
|
||||
@Input() datatableData: any;
|
||||
/** Create Input Form */
|
||||
@@ -33,12 +37,6 @@ export class LoansAccountDatatableStepComponent implements OnInit {
|
||||
|
||||
datatableInputs: any = [];
|
||||
|
||||
constructor(
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private settingsService: SettingsService,
|
||||
private dateUtils: Dates
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.datatableInputs = this.datatableData.columnHeaderData.filter((column: any) => {
|
||||
return (
|
||||
|
||||
+112
-97
@@ -14,9 +14,11 @@
|
||||
[formControl]="filterFormCtrl"
|
||||
></ngx-mat-select-search>
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let product of productData | async" [value]="product.id">
|
||||
{{ product.name }}
|
||||
</mat-option>
|
||||
@for (product of productData | async; track product) {
|
||||
<mat-option [value]="product.id">
|
||||
{{ product.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Product Name' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
@@ -25,97 +27,108 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="layout-row-wrap layout-lt-md-column gap-2percent" *ngIf="loanProductSelected">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.External id' | translate }}</mat-label>
|
||||
<input matInput formControlName="externalId" matTooltip="{{ 'tooltips.Provides an external id' | translate }}" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48" *ngIf="loanProductSelected">
|
||||
<mat-label>{{ 'labels.inputs.Loan officer' | translate }}</mat-label>
|
||||
<mat-select
|
||||
formControlName="loanOfficerId"
|
||||
matTooltip="{{ 'tooltips.Financial institution representative' | translate }}"
|
||||
>
|
||||
<mat-option *ngFor="let loanOfficer of loanOfficerOptions" [value]="loanOfficer.id">
|
||||
{{ loanOfficer.displayName }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Loan Purpose' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanPurposeId" matTooltip="{{ 'tooltips.Provides an indication' | translate }}">
|
||||
<mat-option *ngFor="let loanPurpose of loanPurposeOptions" [value]="loanPurpose.id">
|
||||
{{ loanPurpose.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Fund' | translate }}</mat-label>
|
||||
<mat-select formControlName="fundId">
|
||||
<mat-option *ngFor="let fund of fundOptions" [value]="fund.id">
|
||||
{{ fund.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="submitPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Submitted on' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="submitPicker"
|
||||
matTooltip="{{ 'tooltips.Date the loan account application' | translate }}"
|
||||
required
|
||||
formControlName="submittedOnDate"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="submitPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #submitPicker></mat-datepicker>
|
||||
<mat-error *ngIf="loansAccountDetailsForm.controls.submittedOnDate?.hasError('required')">
|
||||
{{ 'labels.inputs.Submitted on' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48" (click)="disbursementPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Disbursement on' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="loansAccountDetailsForm.value.submittedOnDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="disbursementPicker"
|
||||
matTooltip="{{ 'tooltips.Date that the loan account disbursed' | translate }}"
|
||||
required
|
||||
formControlName="expectedDisbursementDate"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="disbursementPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #disbursementPicker></mat-datepicker>
|
||||
<mat-error *ngIf="loansAccountDetailsForm.controls.submittedOnDate?.hasError('required')">
|
||||
{{ 'labels.inputs.Disbursement on' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Savings Linkage' | translate }}</h3>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Link savings' | translate }}</mat-label>
|
||||
<mat-select formControlName="linkAccountId">
|
||||
<mat-option *ngFor="let savingaccount of accountLinkingOptions" [value]="savingaccount.id">
|
||||
({{ savingaccount.accountNo }}) {{ savingaccount.productName }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox class="flex-48" formControlName="createStandingInstructionAtDisbursement">
|
||||
<p>{{ 'labels.inputs.Create standing instructions at disbursement' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (loanProductSelected) {
|
||||
<div class="layout-row-wrap layout-lt-md-column gap-2percent">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.External id' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
formControlName="externalId"
|
||||
matTooltip="{{ 'tooltips.Provides an external id' | translate }}"
|
||||
/>
|
||||
</mat-form-field>
|
||||
@if (loanProductSelected) {
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Loan officer' | translate }}</mat-label>
|
||||
<mat-select
|
||||
formControlName="loanOfficerId"
|
||||
matTooltip="{{ 'tooltips.Financial institution representative' | translate }}"
|
||||
>
|
||||
@for (loanOfficer of loanOfficerOptions; track loanOfficer) {
|
||||
<mat-option [value]="loanOfficer.id">
|
||||
{{ loanOfficer.displayName }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Loan Purpose' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanPurposeId" matTooltip="{{ 'tooltips.Provides an indication' | translate }}">
|
||||
@for (loanPurpose of loanPurposeOptions; track loanPurpose) {
|
||||
<mat-option [value]="loanPurpose.id">
|
||||
{{ loanPurpose.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Fund' | translate }}</mat-label>
|
||||
<mat-select formControlName="fundId">
|
||||
@for (fund of fundOptions; track fund) {
|
||||
<mat-option [value]="fund.id">
|
||||
{{ fund.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-48" (click)="submitPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Submitted on' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="minDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="submitPicker"
|
||||
matTooltip="{{ 'tooltips.Date the loan account application' | translate }}"
|
||||
required
|
||||
formControlName="submittedOnDate"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="submitPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #submitPicker></mat-datepicker>
|
||||
@if (loansAccountDetailsForm.controls.submittedOnDate?.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Submitted on' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<mat-form-field class="flex-48" (click)="disbursementPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.Disbursement on' | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
[min]="loansAccountDetailsForm.value.submittedOnDate"
|
||||
[max]="maxDate"
|
||||
[matDatepicker]="disbursementPicker"
|
||||
matTooltip="{{ 'tooltips.Date that the loan account disbursed' | translate }}"
|
||||
required
|
||||
formControlName="expectedDisbursementDate"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="disbursementPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #disbursementPicker></mat-datepicker>
|
||||
@if (loansAccountDetailsForm.controls.submittedOnDate?.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Disbursement on' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Savings Linkage' | translate }}</h3>
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Link savings' | translate }}</mat-label>
|
||||
<mat-select formControlName="linkAccountId">
|
||||
@for (savingaccount of accountLinkingOptions; track savingaccount) {
|
||||
<mat-option [value]="savingaccount.id">
|
||||
({{ savingaccount.accountNo }}) {{ savingaccount.productName }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-checkbox class="flex-48" formControlName="createStandingInstructionAtDisbursement">
|
||||
<p>{{ 'labels.inputs.Create standing instructions at disbursement' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="layout-row align-center gap-2percent margin-t responsive-column">
|
||||
<button mat-raised-button matStepperPrevious disabled>
|
||||
@@ -134,8 +147,10 @@
|
||||
{{ 'labels.buttons.Next' | translate }}
|
||||
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
|
||||
</button>
|
||||
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
@if (loanId) {
|
||||
<button mat-raised-button [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
+10
-10
@@ -1,5 +1,5 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy, inject } from '@angular/core';
|
||||
import {
|
||||
UntypedFormGroup,
|
||||
UntypedFormBuilder,
|
||||
@@ -18,7 +18,7 @@ import { takeUntil } from 'rxjs/operators';
|
||||
import { ReplaySubject, Subject } from 'rxjs';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
|
||||
import { NgFor, NgIf, AsyncPipe } from '@angular/common';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { MatDivider } from '@angular/material/divider';
|
||||
import { MatCheckbox } from '@angular/material/checkbox';
|
||||
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
|
||||
@@ -45,6 +45,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
]
|
||||
})
|
||||
export class LoansAccountDetailsStepComponent implements OnInit, OnDestroy {
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
private loansService = inject(LoansService);
|
||||
private route = inject(ActivatedRoute);
|
||||
private translateService = inject(TranslateService);
|
||||
private settingsService = inject(SettingsService);
|
||||
private commons = inject(Commons);
|
||||
|
||||
//** Defining PlaceHolders for the search bar */
|
||||
placeHolderLabel = '';
|
||||
noEntriesFoundLabel = '';
|
||||
@@ -89,14 +96,7 @@ export class LoansAccountDetailsStepComponent implements OnInit, OnDestroy {
|
||||
* @param {LoansService} loansService Loans Service.
|
||||
* @param {SettingsService} settingsService SettingsService
|
||||
*/
|
||||
constructor(
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private loansService: LoansService,
|
||||
private route: ActivatedRoute,
|
||||
private translateService: TranslateService,
|
||||
private settingsService: SettingsService,
|
||||
private commons: Commons
|
||||
) {
|
||||
constructor() {
|
||||
this.loanId = this.route.snapshot.params['loanId'];
|
||||
}
|
||||
|
||||
|
||||
+205
-180
@@ -13,26 +13,32 @@
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.loanOfficerId">
|
||||
<span class="flex-40">{{ 'labels.inputs.Loan officer' | translate }}:</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccount.loanOfficerId | find: loansAccountProductTemplate.loanOfficerOptions : 'id' : 'displayName'
|
||||
}}</span>
|
||||
</div>
|
||||
@if (loansAccount.loanOfficerId) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Loan officer' | translate }}:</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccount.loanOfficerId | find: loansAccountProductTemplate.loanOfficerOptions : 'id' : 'displayName'
|
||||
}}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.loanPurposeId">
|
||||
<span class="flex-40">{{ 'labels.inputs.Loan purpose' | translate }}:</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccount.loanPurposeId | find: loansAccountProductTemplate.loanPurposeOptions : 'id' : 'name'
|
||||
}}</span>
|
||||
</div>
|
||||
@if (loansAccount.loanPurposeId) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Loan purpose' | translate }}:</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccount.loanPurposeId | find: loansAccountProductTemplate.loanPurposeOptions : 'id' : 'name'
|
||||
}}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.fundId">
|
||||
<span class="flex-40">{{ 'labels.inputs.Fund' | translate }}:</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccount.fundId | find: loansAccountProductTemplate.fundOptions : 'id' : 'name'
|
||||
}}</span>
|
||||
</div>
|
||||
@if (loansAccount.fundId) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Fund' | translate }}:</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccount.fundId | find: loansAccountProductTemplate.fundOptions : 'id' : 'name'
|
||||
}}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Submitted on' | translate }}:</span>
|
||||
@@ -44,14 +50,16 @@
|
||||
<span class="flex-60">{{ loansAccount.expectedDisbursementDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.externalId">
|
||||
<span class="flex-40">{{ 'labels.inputs.External id' | translate }}:</span>
|
||||
<span class="flex-60">
|
||||
<mifosx-external-identifier externalId="{{ loansAccount.externalId }}"></mifosx-external-identifier>
|
||||
</span>
|
||||
</div>
|
||||
@if (loansAccount.externalId) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.External id' | translate }}:</span>
|
||||
<span class="flex-60">
|
||||
<mifosx-external-identifier externalId="{{ loansAccount.externalId }}"></mifosx-external-identifier>
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="activeClientMembers">
|
||||
@if (activeClientMembers) {
|
||||
<h3 class="mat-h3 margin-t flex-fill">{{ 'labels.heading.Client Members' | translate }}</h3>
|
||||
<mat-divider class="flex-fill"></mat-divider>
|
||||
<div class="flex-60">
|
||||
@@ -61,19 +69,16 @@
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client ID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.displayName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Purpose Column -->
|
||||
<ng-container matColumnDef="purpose">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Purpose' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.purpose }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Principal Column -->
|
||||
<ng-container matColumnDef="principal">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Original Loan' | translate }}</th>
|
||||
@@ -81,12 +86,11 @@
|
||||
{{ element.principal | currency: loansAccountProductTemplate.currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="membersDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: membersDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<h3 class="mat-h3 margin-t flex-fill">{{ 'labels.heading.Terms' | translate }}</h3>
|
||||
|
||||
@@ -134,39 +138,51 @@
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill" *ngIf="productEnableDownPayment">
|
||||
<span class="flex-40">{{ 'labels.inputs.Enable Down Payments' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.enableDownPayment | yesNo }}</span>
|
||||
</div>
|
||||
@if (productEnableDownPayment) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Enable Down Payments' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.enableDownPayment | yesNo }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.repaymentsStartingFromDate">
|
||||
<span class="flex-40">{{ 'labels.inputs.First repayment on' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.repaymentsStartingFromDate | dateFormat }}</span>
|
||||
</div>
|
||||
@if (loansAccount.repaymentsStartingFromDate) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.First repayment on' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.repaymentsStartingFromDate | dateFormat }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.interestChargedFromDate">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest charged from' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.interestChargedFromDate | dateFormat }}</span>
|
||||
</div>
|
||||
@if (loansAccount.interestChargedFromDate) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest charged from' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.interestChargedFromDate | dateFormat }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.interestRatePerPeriod">
|
||||
<span class="flex-40">{{ 'labels.inputs.Nominal interest rate' | translate }}:</span>
|
||||
<span class="flex-60"
|
||||
>{{ loansAccount.interestRatePerPeriod }} {{
|
||||
loansAccountProductTemplate.interestRateFrequencyType.value
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
@if (loansAccount.interestRatePerPeriod) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Nominal interest rate' | translate }}:</span>
|
||||
<span class="flex-60"
|
||||
>{{ loansAccount.interestRatePerPeriod }} {{
|
||||
loansAccountProductTemplate.interestRateFrequencyType.value
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.interestType">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest method' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.interestType }}</span>
|
||||
</div>
|
||||
@if (loansAccount.interestType) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest method' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.interestType }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.isEqualAmortization">
|
||||
<span class="flex-40">{{ 'labels.inputs.Is Equal Amortization' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.isEqualAmortization }}</span>
|
||||
</div>
|
||||
@if (loansAccount.isEqualAmortization) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Is Equal Amortization' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.isEqualAmortization }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Amortization' | translate }}</span>
|
||||
@@ -183,20 +199,28 @@
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.allowPartialPeriodInterestCalculation">
|
||||
<span class="flex-40">{{ 'labels.inputs.Calculate interest for exact days in partial period' | translate }}:</span>
|
||||
<span class="flex-60">{{ loansAccount.allowPartialPeriodInterestCalculation }}</span>
|
||||
</div>
|
||||
@if (loansAccount.allowPartialPeriodInterestCalculation) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40"
|
||||
>{{ 'labels.inputs.Calculate interest for exact days in partial period' | translate }}:</span
|
||||
>
|
||||
<span class="flex-60">{{ loansAccount.allowPartialPeriodInterestCalculation }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.inArrearsTolerance">
|
||||
<span class="flex-40">{{ 'labels.inputs.Arrears tolerance' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.inArrearsTolerance }}</span>
|
||||
</div>
|
||||
@if (loansAccount.inArrearsTolerance) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Arrears tolerance' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.inArrearsTolerance }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.graceOnInterestCharged">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest free period' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnInterestCharged }}</span>
|
||||
</div>
|
||||
@if (loansAccount.graceOnInterestCharged) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest free period' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnInterestCharged }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Repayment strategy' | translate }}: </span>
|
||||
@@ -219,138 +243,139 @@
|
||||
<h3 class="mat-h3 margin-t flex-fill">{{ 'labels.heading.Moratorium' | translate }}</h3>
|
||||
|
||||
<mat-divider class="flex-fill"></mat-divider>
|
||||
<div class="flex-fill" *ngIf="loansAccount.graceOnPrincipalPayment">
|
||||
<span class="flex-40">{{ 'labels.inputs.On principal payment' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnPrincipalPayment }}</span>
|
||||
</div>
|
||||
@if (loansAccount.graceOnPrincipalPayment) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.On principal payment' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnPrincipalPayment }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.graceOnInterestPayment">
|
||||
<span class="flex-40">{{ 'labels.inputs.On interest payment' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnInterestPayment }}</span>
|
||||
</div>
|
||||
@if (loansAccount.graceOnInterestPayment) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.On interest payment' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnInterestPayment }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.graceOnArrearsAgeing">
|
||||
<span class="flex-40">{{ 'labels.inputs.On Arrears Aging' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnArrearsAgeing }}</span>
|
||||
</div>
|
||||
@if (loansAccount.graceOnArrearsAgeing) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.On Arrears Aging' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccount.graceOnArrearsAgeing }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40"> {{ 'labels.inputs.Enable installment level Delinquency' | translate }} </span>
|
||||
<span class="flex-60"> {{ loansAccount.enableInstallmentLevelDelinquency | yesNo }} </span>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccount.isTopup">
|
||||
<span class="flex-40">{{ 'labels.inputs.Is Topup Loan' | translate }}? </span>
|
||||
<span class="flex-60">{{ loansAccount.isTopup }}</span>
|
||||
</div>
|
||||
@if (loansAccount.isTopup) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Is Topup Loan' | translate }}? </span>
|
||||
<span class="flex-60">{{ loansAccount.isTopup }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Recalculate Interest' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccountProductTemplate?.isInterestRecalculationEnabled | yesNo }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-fill" *ngIf="loansAccountProductTemplate?.daysInMonthType">
|
||||
<span class="flex-40">{{ 'labels.inputs.Days in month' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccountProductTemplate?.daysInMonthType.value }}</span>
|
||||
</div>
|
||||
@if (loansAccountProductTemplate?.daysInMonthType) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Days in month' | translate }}: </span>
|
||||
<span class="flex-60">{{ loansAccountProductTemplate?.daysInMonthType.value }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div *ngIf="loansAccount.charges.length" class="layout-row-wrap responsive-column flex-fill margin-t">
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Charges' | translate }}</h3>
|
||||
|
||||
<mat-divider class="flex-fill"></mat-divider>
|
||||
<table class="flex-fill mat-elevation-z1" mat-table [dataSource]="loansAccount.charges">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.name + ', ' + (charge.currency?.displaySymbol || '') }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Collected On' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
<span
|
||||
*ngIf="charge.chargeTimeType.value === 'Specified due date' || charge.chargeTimeType.value === 'Weekly Fee'"
|
||||
>
|
||||
{{ (charge.dueDate | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
<span *ngIf="charge.chargeTimeType.value === 'Monthly Fee' || charge.chargeTimeType.value === 'Annual Fee'">
|
||||
{{ (charge.feeOnMonthDay | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
<span
|
||||
*ngIf="
|
||||
@if (loansAccount.charges.length) {
|
||||
<div class="layout-row-wrap responsive-column flex-fill margin-t">
|
||||
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Charges' | translate }}</h3>
|
||||
<mat-divider class="flex-fill"></mat-divider>
|
||||
<table class="flex-fill mat-elevation-z1" mat-table [dataSource]="loansAccount.charges">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.name + ', ' + (charge.currency?.displaySymbol || '') }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Collected On' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="date">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
@if (charge.chargeTimeType.value === 'Specified due date' || charge.chargeTimeType.value === 'Weekly Fee') {
|
||||
<span>
|
||||
{{ (charge.dueDate | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
}
|
||||
@if (charge.chargeTimeType.value === 'Monthly Fee' || charge.chargeTimeType.value === 'Annual Fee') {
|
||||
<span>
|
||||
{{ (charge.feeOnMonthDay | dateFormat) || 'Unassigned' }}
|
||||
</span>
|
||||
}
|
||||
@if (
|
||||
!(
|
||||
charge.chargeTimeType.value === 'Monthly Fee' ||
|
||||
charge.chargeTimeType.value === 'Annual Fee' ||
|
||||
charge.chargeTimeType.value === 'Specified due date' ||
|
||||
charge.chargeTimeType.value === 'Weekly Fee'
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ 'labels.inputs.N/A' | translate }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
) {
|
||||
<span>
|
||||
{{ 'labels.inputs.N/A' | translate }}
|
||||
</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="loansAccountProductTemplate.overdueCharges.length"
|
||||
class="flex-fill layout-row-wrap layout-xs-column margin-t"
|
||||
>
|
||||
<h3 class="mat-h3 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h3>
|
||||
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
|
||||
<table mat-table class="mat-elevation-z1" [dataSource]="loansAccountProductTemplate.overdueCharges">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.name + ', ' + (charge.currency?.displaySymbol || '') }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.chargeCalculationType.value }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.amount | formatNumber }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="collectedon">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Collected On' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.chargeTimeType.value }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="overdueChargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: overdueChargesDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
@if (loansAccountProductTemplate.overdueCharges.length) {
|
||||
<div class="flex-fill layout-row-wrap layout-xs-column margin-t">
|
||||
<h3 class="mat-h3 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h3>
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
<table mat-table class="mat-elevation-z1" [dataSource]="loansAccountProductTemplate.overdueCharges">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.name + ', ' + (charge.currency?.displaySymbol || '') }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.chargeCalculationType.value }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.amount | formatNumber }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="collectedon">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Collected On' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let charge">{{ charge.chargeTimeType.value }}</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="overdueChargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: overdueChargesDisplayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="layout-row responsive-column align-center gap-2px margin-t">
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import {
|
||||
MatRow
|
||||
} from '@angular/material/table';
|
||||
import { LongTextComponent } from '../../../shared/long-text/long-text.component';
|
||||
import { NgIf, CurrencyPipe } from '@angular/common';
|
||||
import { CurrencyPipe } from '@angular/common';
|
||||
import { ExternalIdentifierComponent } from '../../../shared/external-identifier/external-identifier.component';
|
||||
import { MatDivider } from '@angular/material/divider';
|
||||
import { MatStepperPrevious } from '@angular/material/stepper';
|
||||
|
||||
+5
-3
@@ -20,7 +20,9 @@
|
||||
{{ 'labels.buttons.Next' | translate }}
|
||||
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
|
||||
</button>
|
||||
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
@if (loanId) {
|
||||
<button mat-raised-button [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Component, Input, inject } from '@angular/core';
|
||||
import { ActivatedRoute, RouterLink } from '@angular/router';
|
||||
import { LoansService } from 'app/loans/loans.service';
|
||||
import { RepaymentSchedule } from 'app/loans/models/loan-account.model';
|
||||
@@ -21,6 +21,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
]
|
||||
})
|
||||
export class LoansAccountScheduleStepComponent {
|
||||
private loansService = inject(LoansService);
|
||||
private settingsService = inject(SettingsService);
|
||||
private route = inject(ActivatedRoute);
|
||||
|
||||
/** Currency Code */
|
||||
@Input() currencyCode: string;
|
||||
/** Loans Account Template */
|
||||
@@ -34,11 +38,7 @@ export class LoansAccountScheduleStepComponent {
|
||||
|
||||
loanId: string | null = null;
|
||||
|
||||
constructor(
|
||||
private loansService: LoansService,
|
||||
private settingsService: SettingsService,
|
||||
private route: ActivatedRoute
|
||||
) {
|
||||
constructor() {
|
||||
this.loanId = this.route.snapshot.params['loanId'];
|
||||
}
|
||||
|
||||
|
||||
+355
-290
@@ -1,14 +1,15 @@
|
||||
<form [formGroup]="loansAccountTermsForm">
|
||||
<div class="layout-row-wrap gap-2px responsive-column">
|
||||
<mifosx-input-amount
|
||||
class="flex-48"
|
||||
*ngIf="currency"
|
||||
[currency]="currency"
|
||||
[isRequired]="true"
|
||||
[inputFormControl]="loansAccountTermsForm.controls.principalAmount"
|
||||
[inputLabel]="'Principal'"
|
||||
>
|
||||
</mifosx-input-amount>
|
||||
@if (currency) {
|
||||
<mifosx-input-amount
|
||||
class="flex-48"
|
||||
[currency]="currency"
|
||||
[isRequired]="true"
|
||||
[inputFormControl]="loansAccountTermsForm.controls.principalAmount"
|
||||
[inputLabel]="'Principal'"
|
||||
>
|
||||
</mifosx-input-amount>
|
||||
}
|
||||
|
||||
<h4 class="mat-h4 flex-98">
|
||||
{{ 'labels.heading.Term Options' | translate }}
|
||||
@@ -18,32 +19,42 @@
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Loan Term' | translate }}</mat-label>
|
||||
<input type="number" matInput required disabled formControlName="loanTermFrequency" />
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.loanTermFrequency.hasError('required')">
|
||||
{{ 'labels.inputs.Loan Term' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.loanTermFrequency.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Loan Term' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Frequency' | translate }}</mat-label>
|
||||
<mat-select required formControlName="loanTermFrequencyType">
|
||||
<mat-option *ngFor="let type of termFrequencyTypeData" [value]="type.id">
|
||||
{{ type.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (type of termFrequencyTypeData; track type) {
|
||||
<mat-option [value]="type.id">
|
||||
{{ type.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.loanTermFrequencyType.hasError('required')">
|
||||
{{ 'labels.inputs.Frequency' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.loanTermFrequencyType.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Frequency' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-20" *ngIf="hasFixedLength()">
|
||||
<mat-label>{{ 'labels.inputs.Fixed Length' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="fixedLength" />
|
||||
</mat-form-field>
|
||||
<span *ngIf="hasFixedLength()" class="flex-20 label-field">{{
|
||||
loansAccountTermsForm.value.loanTermFrequencyType | find: termFrequencyTypeData : 'id' : 'value'
|
||||
}}</span>
|
||||
@if (hasFixedLength()) {
|
||||
<mat-form-field class="flex-fill flex-20">
|
||||
<mat-label>{{ 'labels.inputs.Fixed Length' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="fixedLength" />
|
||||
</mat-form-field>
|
||||
}
|
||||
@if (hasFixedLength()) {
|
||||
<span class="flex-20 label-field">{{
|
||||
loansAccountTermsForm.value.loanTermFrequencyType | find: termFrequencyTypeData : 'id' : 'value'
|
||||
}}</span>
|
||||
}
|
||||
|
||||
<h4 class="mat-h4 flex-98">{{ 'labels.inputs.Repayments' | translate }}</h4>
|
||||
|
||||
@@ -55,16 +66,20 @@
|
||||
formControlName="numberOfRepayments"
|
||||
matTooltip="{{ 'tooltips.Enter the total count of repayments' | translate }}"
|
||||
/>
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.numberOfRepayments.hasError('required')">
|
||||
{{ 'labels.inputs.Number of repayments' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.numberOfRepayments.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Number of repayments' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23" *ngIf="loansAccountTermsData?.canDefineInstallmentAmount">
|
||||
<mat-label>{{ 'labels.inputs.Installment Amount' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="fixedEmiAmount" />
|
||||
</mat-form-field>
|
||||
@if (loansAccountTermsData?.canDefineInstallmentAmount) {
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Installment Amount' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="fixedEmiAmount" />
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-form-field class="flex-fill flex-23" (click)="repaymentsPicker.open()">
|
||||
<mat-label>{{ 'labels.inputs.First repayment on' | translate }}</mat-label>
|
||||
@@ -111,88 +126,96 @@
|
||||
formControlName="repaymentEvery"
|
||||
matTooltip="{{ 'tooltips.Fields are input to calculating the repayment schedule' | translate }}"
|
||||
/>
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.repaymentEvery.hasError('required')">
|
||||
{{ 'labels.inputs.Repaid every' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.repaymentEvery.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Repaid every' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Frequency' | translate }}</mat-label>
|
||||
<mat-select formControlName="repaymentFrequencyType" disabled required>
|
||||
<mat-option *ngFor="let repaymentFrequencyType of termFrequencyTypeData" [value]="repaymentFrequencyType.id">
|
||||
{{ repaymentFrequencyType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (repaymentFrequencyType of termFrequencyTypeData; track repaymentFrequencyType) {
|
||||
<mat-option [value]="repaymentFrequencyType.id">
|
||||
{{ repaymentFrequencyType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-14" *ngIf="loansAccountTermsForm.controls.repaymentFrequencyType.value === 2">
|
||||
<mat-label>{{ 'labels.inputs.Select On' | translate }}</mat-label>
|
||||
<mat-select formControlName="repaymentFrequencyNthDayType">
|
||||
<mat-option
|
||||
*ngFor="let repaymentFrequencyNthDayType of repaymentFrequencyNthDayTypeData"
|
||||
[value]="repaymentFrequencyNthDayType.id"
|
||||
>
|
||||
{{ repaymentFrequencyNthDayType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
@if (loansAccountTermsForm.controls.repaymentFrequencyType.value === 2) {
|
||||
<mat-form-field class="flex-fill flex-14">
|
||||
<mat-label>{{ 'labels.inputs.Select On' | translate }}</mat-label>
|
||||
<mat-select formControlName="repaymentFrequencyNthDayType">
|
||||
@for (repaymentFrequencyNthDayType of repaymentFrequencyNthDayTypeData; track repaymentFrequencyNthDayType) {
|
||||
<mat-option [value]="repaymentFrequencyNthDayType.id">
|
||||
{{ repaymentFrequencyNthDayType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-form-field class="flex-fill flex-14" *ngIf="loansAccountTermsForm.controls.repaymentFrequencyType.value === 2">
|
||||
<mat-label>{{ 'labels.inputs.Select Day' | translate }}</mat-label>
|
||||
<mat-select formControlName="repaymentFrequencyDayOfWeekType">
|
||||
<mat-option
|
||||
*ngFor="let repaymentFrequencyDayOfWeekType of repaymentFrequencyDaysOfWeekTypeData"
|
||||
[value]="repaymentFrequencyDayOfWeekType.id"
|
||||
>
|
||||
{{ repaymentFrequencyDayOfWeekType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
@if (loansAccountTermsForm.controls.repaymentFrequencyType.value === 2) {
|
||||
<mat-form-field class="flex-fill flex-14">
|
||||
<mat-label>{{ 'labels.inputs.Select Day' | translate }}</mat-label>
|
||||
<mat-select formControlName="repaymentFrequencyDayOfWeekType">
|
||||
@for (
|
||||
repaymentFrequencyDayOfWeekType of repaymentFrequencyDaysOfWeekTypeData;
|
||||
track repaymentFrequencyDayOfWeekType
|
||||
) {
|
||||
<mat-option [value]="repaymentFrequencyDayOfWeekType.id">
|
||||
{{ repaymentFrequencyDayOfWeekType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<mat-checkbox
|
||||
labelPosition="before"
|
||||
formControlName="enableDownPayment"
|
||||
matTooltip="{{ 'tooltips.Leave this checkbox checked if the loan has Down Payment' | translate }}"
|
||||
class="margin-b flex-73"
|
||||
*ngIf="productEnableDownPayment"
|
||||
>
|
||||
{{ 'labels.inputs.Enable Down Payment' | translate }}
|
||||
</mat-checkbox>
|
||||
@if (productEnableDownPayment) {
|
||||
<mat-checkbox
|
||||
labelPosition="before"
|
||||
formControlName="enableDownPayment"
|
||||
matTooltip="{{ 'tooltips.Leave this checkbox checked if the loan has Down Payment' | translate }}"
|
||||
class="margin-b flex-73"
|
||||
>
|
||||
{{ 'labels.inputs.Enable Down Payment' | translate }}
|
||||
</mat-checkbox>
|
||||
}
|
||||
|
||||
<h4 class="mat-h4 flex-98">{{ 'labels.inputs.Nominal interest rate' | translate }}</h4>
|
||||
|
||||
<ng-container *ngIf="!loansAccountTermsData?.isLoanProductLinkedToFloatingRate">
|
||||
@if (!loansAccountTermsData?.isLoanProductLinkedToFloatingRate) {
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Nominal interest rate' | translate }} %</mat-label>
|
||||
<input type="number" matInput formControlName="interestRatePerPeriod" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Frequency' | translate }}</mat-label>
|
||||
<mat-select formControlName="interestRateFrequencyType">
|
||||
<mat-option
|
||||
*ngFor="let interestRateFrequencyType of interestRateFrequencyTypeData"
|
||||
[value]="interestRateFrequencyType.id"
|
||||
>
|
||||
{{ interestRateFrequencyType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (interestRateFrequencyType of interestRateFrequencyTypeData; track interestRateFrequencyType) {
|
||||
<mat-option [value]="interestRateFrequencyType.id">
|
||||
{{ interestRateFrequencyType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Nominal interest rate frequency' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Interest method' | translate }}</mat-label>
|
||||
<mat-select formControlName="interestType" matTooltip="{{ 'tooltips.The Interest method value' | translate }}">
|
||||
<mat-option *ngFor="let interestType of interestTypeData" [value]="interestType.id">
|
||||
{{ interestType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (interestType of interestTypeData; track interestType) {
|
||||
<mat-option [value]="interestType.id">
|
||||
{{ interestType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Amortization' | translate }}</mat-label>
|
||||
<mat-select
|
||||
@@ -200,21 +223,25 @@
|
||||
matTooltip="{{ 'tooltips.The Amortization value' | translate }}"
|
||||
formControlName="amortizationType"
|
||||
>
|
||||
<mat-option *ngFor="let amortizationType of amortizationTypeData" [value]="amortizationType.id">
|
||||
{{ amortizationType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (amortizationType of amortizationTypeData; track amortizationType) {
|
||||
<mat-option [value]="amortizationType.id">
|
||||
{{ amortizationType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.amortizationType.hasError('required')">
|
||||
{{ 'labels.inputs.Amortization Type' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.amortizationType.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Amortization Type' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-fill flex-23" *ngIf="isEqualPrincipalPayments()">
|
||||
<mat-label>{{ 'labels.inputs.Principal Percentage Per Installment' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="fixedPrincipalPercentagePerInstallment" />
|
||||
</mat-form-field>
|
||||
|
||||
@if (isEqualPrincipalPayments()) {
|
||||
<mat-form-field class="flex-fill flex-23">
|
||||
<mat-label>{{ 'labels.inputs.Principal Percentage Per Installment' | translate }}</mat-label>
|
||||
<input type="number" matInput formControlName="fixedPrincipalPercentagePerInstallment" />
|
||||
</mat-form-field>
|
||||
}
|
||||
<mat-checkbox
|
||||
class="flex-23"
|
||||
formControlName="isEqualAmortization"
|
||||
@@ -222,19 +249,20 @@
|
||||
>
|
||||
<p>{{ 'labels.inputs.Is Equal Amortization' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="loansAccountTermsData?.isLoanProductLinkedToFloatingRate">
|
||||
@if (loansAccountTermsData?.isLoanProductLinkedToFloatingRate) {
|
||||
<div class="flex-48 layout-row layout-xs-column">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Interest Method' | translate }}</mat-label>
|
||||
<mat-select formControlName="interestType">
|
||||
<mat-option *ngFor="let interestType of interestTypeData" [value]="interestType.id">
|
||||
{{ interestType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (interestType of interestTypeData; track interestType) {
|
||||
<mat-option [value]="interestType.id">
|
||||
{{ interestType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Amortization' | translate }}</mat-label>
|
||||
<mat-select
|
||||
@@ -242,34 +270,39 @@
|
||||
matTooltip="{{ 'tooltips.The Amortization value' | translate }}"
|
||||
formControlName="amortizationType"
|
||||
>
|
||||
<mat-option *ngFor="let amortizationType of amortizationTypeData" [value]="amortizationType.id">
|
||||
{{ amortizationType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (amortizationType of amortizationTypeData; track amortizationType) {
|
||||
<mat-option [value]="amortizationType.id">
|
||||
{{ amortizationType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.amortizationType.hasError('required')">
|
||||
{{ 'labels.inputs.Amortization Type' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.amortizationType.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Amortization Type' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox class="flex-48" formControlName="isFloatingInterestRate">
|
||||
<p>{{ 'labels.inputs.Is Floating Rate' | translate }}?</p>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<h4 class="mat-h4 flex-98">{{ 'labels.inputs.Loan Schedule' | translate }}</h4>
|
||||
|
||||
<div class="flex-48" *ngIf="loanScheduleType">
|
||||
<div class="layout-row">
|
||||
<span class="flex-40"
|
||||
><p>{{ 'labels.inputs.Loan Schedule Type' | translate }}</p></span
|
||||
>
|
||||
<span class="flex-60"
|
||||
><p>{{ loanScheduleType.value | translateKey: 'catalogs' }}</p></span
|
||||
>
|
||||
@if (loanScheduleType) {
|
||||
<div class="flex-48">
|
||||
<div class="layout-row">
|
||||
<span class="flex-40"
|
||||
><p>{{ 'labels.inputs.Loan Schedule Type' | translate }}</p></span
|
||||
>
|
||||
<span class="flex-60"
|
||||
><p>{{ loanScheduleType.value | translateKey: 'catalogs' }}</p></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Repayment Strategy' | translate }}</mat-label>
|
||||
@@ -278,17 +311,21 @@
|
||||
matTooltip="{{ 'tooltips.The repayment strategy' | translate }}"
|
||||
[disabled]="repaymentStrategyDisabled"
|
||||
>
|
||||
<mat-option
|
||||
*ngFor="let transactionProcessingStrategy of transactionProcessingStrategyOptions"
|
||||
[value]="transactionProcessingStrategy.code"
|
||||
>
|
||||
{{ transactionProcessingStrategy.name | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (
|
||||
transactionProcessingStrategy of transactionProcessingStrategyOptions;
|
||||
track transactionProcessingStrategy
|
||||
) {
|
||||
<mat-option [value]="transactionProcessingStrategy.code">
|
||||
{{ transactionProcessingStrategy.name | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.transactionProcessingStrategyCode.hasError('required')">
|
||||
{{ 'labels.inputs.Repayment Strategy' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.transactionProcessingStrategyCode.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Repayment Strategy' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<h4 class="mat-h4 flex-98">{{ 'labels.heading.Interest Calculations' | translate }}</h4>
|
||||
@@ -299,12 +336,11 @@
|
||||
formControlName="interestCalculationPeriodType"
|
||||
matTooltip="{{ 'tooltips.Daily - Will Calculate the interest' | translate }}"
|
||||
>
|
||||
<mat-option
|
||||
*ngFor="let interestCalculationPeriodType of interestCalculationPeriodTypeData"
|
||||
[value]="interestCalculationPeriodType.id"
|
||||
>
|
||||
{{ interestCalculationPeriodType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
@for (interestCalculationPeriodType of interestCalculationPeriodTypeData; track interestCalculationPeriodType) {
|
||||
<mat-option [value]="interestCalculationPeriodType.id">
|
||||
{{ interestCalculationPeriodType.value | translateKey: 'catalogs' }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
@@ -316,11 +352,13 @@
|
||||
<p>{{ 'labels.inputs.Calculate interest for exact days in partial period' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
|
||||
<ng-container class="flex-98" *ngIf="isProgressive">
|
||||
<mat-checkbox formControlName="interestRecognitionOnDisbursementDate" class="flex-98">
|
||||
<p>{{ 'labels.inputs.Is interest recognition on disbursement date?' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</ng-container>
|
||||
@if (isProgressive) {
|
||||
<ng-container class="flex-98">
|
||||
<mat-checkbox formControlName="interestRecognitionOnDisbursementDate" class="flex-98">
|
||||
<p>{{ 'labels.inputs.Is interest recognition on disbursement date?' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Arrears tolerance' | translate }} </mat-label>
|
||||
@@ -361,35 +399,44 @@
|
||||
<input type="number" matInput formControlName="graceOnArrearsAgeing" />
|
||||
</mat-form-field>
|
||||
|
||||
<div class="flex-48 flex-fill" *ngIf="isDelinquencyEnabled()">
|
||||
<p>
|
||||
<span class="flex-53"
|
||||
><b>{{ 'labels.inputs.Delinquency Bucket' | translate }}</b></span
|
||||
>
|
||||
<span class="flex-48">{{ loanProduct?.delinquencyBucket.name }}</span>
|
||||
</p>
|
||||
</div>
|
||||
@if (isDelinquencyEnabled()) {
|
||||
<div class="flex-48 flex-fill">
|
||||
<p>
|
||||
<span class="flex-53"
|
||||
><b>{{ 'labels.inputs.Delinquency Bucket' | translate }}</b></span
|
||||
>
|
||||
<span class="flex-48">{{ loanProduct?.delinquencyBucket.name }}</span>
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-48" *ngIf="isDelinquencyEnabled()">
|
||||
<mat-checkbox formControlName="enableInstallmentLevelDelinquency">
|
||||
<p>{{ 'labels.inputs.Enable installment level Delinquency' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@if (isDelinquencyEnabled()) {
|
||||
<div class="flex-48">
|
||||
<mat-checkbox formControlName="enableInstallmentLevelDelinquency">
|
||||
<p>{{ 'labels.inputs.Enable installment level Delinquency' | translate }}</p>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-container class="flex-48" *ngIf="loansAccountTermsData?.isTopup">
|
||||
<mat-checkbox class="flex-20" formControlName="isTopup">
|
||||
<p>{{ 'labels.inputs.Is Topup Loan' | translate }}?</p>
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field class="flex-fill flex-24" *ngIf="loansAccountTermsForm.controls.isTopup.value">
|
||||
<mat-label>{{ 'labels.inputs.Loan closed with Topup' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanIdToClose">
|
||||
<mat-option *ngFor="let clientActiveLoan of clientActiveLoanData" [value]="clientActiveLoan.id">
|
||||
{{ clientActiveLoan.accountNo }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
@if (loansAccountTermsData?.isTopup) {
|
||||
<ng-container class="flex-48">
|
||||
<mat-checkbox class="flex-20" formControlName="isTopup">
|
||||
<p>{{ 'labels.inputs.Is Topup Loan' | translate }}?</p>
|
||||
</mat-checkbox>
|
||||
@if (loansAccountTermsForm.controls.isTopup.value) {
|
||||
<mat-form-field class="flex-fill flex-24">
|
||||
<mat-label>{{ 'labels.inputs.Loan closed with Topup' | translate }}</mat-label>
|
||||
<mat-select formControlName="loanIdToClose">
|
||||
@for (clientActiveLoan of clientActiveLoanData; track clientActiveLoan) {
|
||||
<mat-option [value]="clientActiveLoan.id">
|
||||
{{ clientActiveLoan.accountNo }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
}
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
|
||||
@@ -400,20 +447,26 @@
|
||||
<span class="flex-60">{{ loansAccountTermsData?.isInterestRecalculationEnabled | yesNo }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-100 layout-row" *ngIf="loansAccountTermsData?.isInterestRecalculationEnabled">
|
||||
<span class="flex-40">{{ 'labels.inputs.Days in year' | translate }}</span>
|
||||
<span class="flex-60">{{ loansAccountTermsData.daysInYearType.value | translateKey: 'catalogs' }}</span>
|
||||
</div>
|
||||
<div class="flex-100 layout-row" *ngIf="loansAccountTermsData?.isInterestRecalculationEnabled">
|
||||
<span class="flex-40">{{ 'labels.inputs.Days in month' | translate }}</span>
|
||||
<span class="flex-60">{{ loansAccountTermsData.daysInMonthType.value | translateKey: 'catalogs' }}</span>
|
||||
</div>
|
||||
<div class="flex-100 layout-row" *ngIf="loansAccountTermsData?.isInterestRecalculationEnabled">
|
||||
<span class="flex-40">{{ 'labels.inputs.Advance payments adjustment type' | translate }}</span>
|
||||
<span class="flex-60">{{ loansAccountTermsData.interestRecalculationData.rescheduleStrategyType.value }}</span>
|
||||
</div>
|
||||
@if (loansAccountTermsData?.isInterestRecalculationEnabled) {
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40">{{ 'labels.inputs.Days in year' | translate }}</span>
|
||||
<span class="flex-60">{{ loansAccountTermsData.daysInYearType.value | translateKey: 'catalogs' }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (loansAccountTermsData?.isInterestRecalculationEnabled) {
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40">{{ 'labels.inputs.Days in month' | translate }}</span>
|
||||
<span class="flex-60">{{ loansAccountTermsData.daysInMonthType.value | translateKey: 'catalogs' }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (loansAccountTermsData?.isInterestRecalculationEnabled) {
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40">{{ 'labels.inputs.Advance payments adjustment type' | translate }}</span>
|
||||
<span class="flex-60">{{ loansAccountTermsData.interestRecalculationData.rescheduleStrategyType.value }}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="loansAccountTermsData?.isInterestRecalculationEnabled">
|
||||
@if (loansAccountTermsData?.isInterestRecalculationEnabled) {
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40">{{ 'labels.inputs.Interest recalculation compounding on' | translate }}</span>
|
||||
<span class="flex-60">{{
|
||||
@@ -421,52 +474,50 @@
|
||||
| translateKey: 'catalogs'
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40">{{ 'labels.inputs.Frequency Interval for recalculation' | translate }}</span>
|
||||
<span class="flex-60">
|
||||
<span>{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.value }}</span>
|
||||
<span
|
||||
*ngIf="
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id === 3 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyWeekday
|
||||
"
|
||||
>
|
||||
on {{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyWeekday.value }}</span
|
||||
>
|
||||
<span
|
||||
*ngIf="
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id === 4 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyOnDay
|
||||
"
|
||||
>on day {{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyOnDay }}</span
|
||||
>
|
||||
<span
|
||||
*ngIf="
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id === 4 &&
|
||||
!loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyOnDay &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyNthDay
|
||||
"
|
||||
>on
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyNthDay.value }}
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyWeekday.value }}</span
|
||||
>
|
||||
@if (
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id === 3 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyWeekday
|
||||
) {
|
||||
<span>
|
||||
on {{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyWeekday.value }}</span
|
||||
>
|
||||
}
|
||||
@if (
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id === 4 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyOnDay
|
||||
) {
|
||||
<span>on day {{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyOnDay }}</span>
|
||||
}
|
||||
@if (
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id === 4 &&
|
||||
!loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyOnDay &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyNthDay
|
||||
) {
|
||||
<span
|
||||
>on
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyNthDay.value }}
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyWeekday.value }}</span
|
||||
>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<div
|
||||
class="flex-100 layout-row"
|
||||
*ngIf="
|
||||
loansAccountTermsData?.isInterestRecalculationEnabled &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id !== 1
|
||||
"
|
||||
>
|
||||
<span class="flex-40">{{ 'labels.inputs.Frequency Interval for recalculation' | translate }}</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyInterval
|
||||
}}</span>
|
||||
</div>
|
||||
@if (
|
||||
loansAccountTermsData?.isInterestRecalculationEnabled &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyType.id !== 1
|
||||
) {
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40">{{ 'labels.inputs.Frequency Interval for recalculation' | translate }}</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyInterval
|
||||
}}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-100 layout-row">
|
||||
<span class="flex-40"
|
||||
@@ -482,19 +533,34 @@
|
||||
<span class="flex-40">{{ enableBuyDownFee | yesNo }}</span>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="multiDisburseLoan">
|
||||
@if (multiDisburseLoan) {
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
<div class="flex-100 layout-row" *ngIf="allowAddDisbursementDetails()">
|
||||
<h4 class="mat-h4 flex-98">{{ 'labels.heading.Loan Tranche Details' | translate }}</h4>
|
||||
</div>
|
||||
@if (allowAddDisbursementDetails()) {
|
||||
<div class="flex-100 layout-row">
|
||||
<h4 class="mat-h4 flex-98">{{ 'labels.heading.Loan Tranche Details' | translate }}</h4>
|
||||
</div>
|
||||
}
|
||||
@if (isFullTermTrancheEditable()) {
|
||||
<mat-checkbox
|
||||
class="flex-48 margin-v"
|
||||
labelPosition="before"
|
||||
formControlName="allowFullTermForTranche"
|
||||
matTooltip="{{ 'tooltips.Allow full term length for each tranche disbursement' | translate }}"
|
||||
>
|
||||
{{ 'labels.inputs.Allow full term for each tranche' | translate }}
|
||||
</mat-checkbox>
|
||||
}
|
||||
<div class="flex-100 layout-row">
|
||||
<mat-form-field class="flex-48">
|
||||
<mat-label>{{ 'labels.inputs.Maximum allowed outstanding balance' | translate }}</mat-label>
|
||||
<input matInput type="number" formControlName="maxOutstandingLoanBalance" />
|
||||
<mat-error *ngIf="loansAccountTermsForm.controls.maxOutstandingLoanBalance.hasError('required')">
|
||||
{{ 'labels.inputs.Maximum allowed outstanding balance' | translate }} {{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
@if (loansAccountTermsForm.controls.maxOutstandingLoanBalance.hasError('required')) {
|
||||
<mat-error>
|
||||
{{ 'labels.inputs.Maximum allowed outstanding balance' | translate }}
|
||||
{{ 'labels.commons.is' | translate }}
|
||||
<strong>{{ 'labels.commons.required' | translate }}</strong>
|
||||
</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
<span class="flex-48">
|
||||
<button
|
||||
@@ -509,12 +575,13 @@
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex-100 layout-row" *ngIf="!allowAddDisbursementDetails()">
|
||||
<h4 class="mat-h4 flex-98">
|
||||
{{ 'labels.heading.Loan Tranche Details are not allowed for this Loan Product' | translate }}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
@if (!allowAddDisbursementDetails()) {
|
||||
<div class="flex-100 layout-row">
|
||||
<h4 class="mat-h4 flex-98">
|
||||
{{ 'labels.heading.Loan Tranche Details are not allowed for this Loan Product' | translate }}
|
||||
</h4>
|
||||
</div>
|
||||
}
|
||||
<table mat-table [dataSource]="disbursementDataSource" [hidden]="disbursementDataSource.length === 0">
|
||||
<ng-container matColumnDef="expectedDisbursementDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Expected Disbursement Date' | translate }}</th>
|
||||
@@ -522,14 +589,12 @@
|
||||
{{ row.expectedDisbursementDate | dateFormat }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="principal">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Principal' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
{{ row.principal }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let row; let rowIndex = index">
|
||||
@@ -545,65 +610,63 @@
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="disbursementDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: disbursementDisplayedColumns"></tr>
|
||||
</table>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<ng-container
|
||||
*ngIf="
|
||||
loansAccountTermsData?.isInterestRecalculationEnabled &&
|
||||
loansAccountTermsData.interestRecalculationData.interestRecalculationCompoundingType.id !== 0
|
||||
"
|
||||
>
|
||||
@if (
|
||||
loansAccountTermsData?.isInterestRecalculationEnabled &&
|
||||
loansAccountTermsData.interestRecalculationData.interestRecalculationCompoundingType.id !== 0
|
||||
) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Frequency for compounding' | translate }}</span>
|
||||
<span class="flex-60"
|
||||
>{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.value }}
|
||||
<span
|
||||
*ngIf="
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id === 3 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyWeekday
|
||||
"
|
||||
>
|
||||
on {{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyWeekday.value }}
|
||||
</span>
|
||||
<span
|
||||
*ngIf="
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyOnDay
|
||||
"
|
||||
>on day
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyOnDay }}
|
||||
</span>
|
||||
<span
|
||||
*ngIf="
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 &&
|
||||
!loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyOnDay &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyNthDay
|
||||
"
|
||||
>on
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyNthDay.value }}
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyWeekday.value }}
|
||||
</span>
|
||||
@if (
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id === 3 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyWeekday
|
||||
) {
|
||||
<span>
|
||||
on {{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyWeekday.value }}
|
||||
</span>
|
||||
}
|
||||
@if (
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyOnDay
|
||||
) {
|
||||
<span
|
||||
>on day
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyOnDay }}
|
||||
</span>
|
||||
}
|
||||
@if (
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 &&
|
||||
!loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyOnDay &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyNthDay
|
||||
) {
|
||||
<span
|
||||
>on
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyNthDay.value }}
|
||||
{{ loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyWeekday.value }}
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<div
|
||||
class="flex-fill"
|
||||
*ngIf="
|
||||
loansAccountTermsData?.isInterestRecalculationEnabled &&
|
||||
loansAccountTermsData.interestRecalculationData.interestRecalculationCompoundingType.id !== 0 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id !== 1
|
||||
"
|
||||
>
|
||||
<span class="flex-40">{{ 'labels.inputs.Frequency Interval for compounding' | translate }}</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyInterval
|
||||
}}</span>
|
||||
</div>
|
||||
@if (
|
||||
loansAccountTermsData?.isInterestRecalculationEnabled &&
|
||||
loansAccountTermsData.interestRecalculationData.interestRecalculationCompoundingType.id !== 0 &&
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyType.id !== 1
|
||||
) {
|
||||
<div class="flex-fill">
|
||||
<span class="flex-40">{{ 'labels.inputs.Frequency Interval for compounding' | translate }}</span>
|
||||
<span class="flex-60">{{
|
||||
loansAccountTermsData.interestRecalculationData.recalculationCompoundingFrequencyInterval
|
||||
}}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<mat-divider class="flex-98"></mat-divider>
|
||||
|
||||
@@ -664,8 +727,10 @@
|
||||
{{ 'labels.buttons.Next' | translate }}
|
||||
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
|
||||
</button>
|
||||
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
@if (loanId) {
|
||||
<button mat-raised-button [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
+7
-8
@@ -1,5 +1,5 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, Input, OnChanges } from '@angular/core';
|
||||
import { Component, OnInit, Input, OnChanges, inject } from '@angular/core';
|
||||
import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
@@ -77,6 +77,11 @@ interface DisbursementData {
|
||||
]
|
||||
})
|
||||
export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
|
||||
private formBuilder = inject(UntypedFormBuilder);
|
||||
private settingsService = inject(SettingsService);
|
||||
private route = inject(ActivatedRoute);
|
||||
dialog = inject(MatDialog);
|
||||
|
||||
/** Loans Product Options */
|
||||
@Input() loansProductOptions: any;
|
||||
/** Loans Account Product Template */
|
||||
@@ -162,12 +167,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
|
||||
* @param formBuilder FormBuilder
|
||||
* @param {SettingsService} settingsService SettingsService
|
||||
*/
|
||||
constructor(
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private settingsService: SettingsService,
|
||||
private route: ActivatedRoute,
|
||||
public dialog: MatDialog
|
||||
) {
|
||||
constructor() {
|
||||
this.loanId = this.route.snapshot.params['loanId'];
|
||||
this.createloansAccountTermsForm();
|
||||
}
|
||||
@@ -560,7 +560,6 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
|
||||
];
|
||||
const data = {
|
||||
title: 'Add Disbursement Details',
|
||||
|
||||
+57
-56
@@ -1,56 +1,55 @@
|
||||
<div *ngIf="activeClientMembers" class="layout-row-wrap gap-2percent layout-xs-column">
|
||||
<table class="flex-98" mat-table [dataSource]="dataSource">
|
||||
<!-- Check Column -->
|
||||
<ng-container matColumnDef="check">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox (change)="toggleSelects()" [(ngModel)]="selectAllItems"></mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-checkbox (change)="toggleSelect()" [(ngModel)]="element.selected"></mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Position Column -->
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client ID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.displayName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Weight Column -->
|
||||
<ng-container matColumnDef="purpose">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Purpose' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Select Purpose' | translate }}</mat-label>
|
||||
<mat-select [(ngModel)]="element.loanPurposeId">
|
||||
<mat-option *ngFor="let purpose of loanPurposeOptions" [value]="purpose.id">
|
||||
{{ purpose.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Symbol Column -->
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Original Loan' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-form-field>
|
||||
<input type="number" matInput [(ngModel)]="element.principal" />
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumn"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumn"></tr>
|
||||
</table>
|
||||
</div>
|
||||
@if (activeClientMembers) {
|
||||
<div class="layout-row-wrap gap-2percent layout-xs-column">
|
||||
<table class="flex-98" mat-table [dataSource]="dataSource">
|
||||
<!-- Check Column -->
|
||||
<ng-container matColumnDef="check">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox (change)="toggleSelects()" [(ngModel)]="selectAllItems"></mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-checkbox (change)="toggleSelect()" [(ngModel)]="element.selected"></mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Position Column -->
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client ID' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client Name' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.displayName }}</td>
|
||||
</ng-container>
|
||||
<!-- Weight Column -->
|
||||
<ng-container matColumnDef="purpose">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Purpose' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'labels.inputs.Select Purpose' | translate }}</mat-label>
|
||||
<mat-select [(ngModel)]="element.loanPurposeId">
|
||||
@for (purpose of loanPurposeOptions; track purpose) {
|
||||
<mat-option [value]="purpose.id">
|
||||
{{ purpose.name }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Symbol Column -->
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Original Loan' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<mat-form-field>
|
||||
<input type="number" matInput [(ngModel)]="element.principal" />
|
||||
</mat-form-field>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumn"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumn"></tr>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="layout-row responsive-column align-center gap-2px margin-t">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
@@ -61,7 +60,9 @@
|
||||
{{ 'labels.buttons.Next' | translate }}
|
||||
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
|
||||
</button>
|
||||
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
@if (loanId) {
|
||||
<button mat-raised-button [routerLink]="['../', 'general']">
|
||||
{{ 'labels.buttons.Cancel' | translate }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
+4
-2
@@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Component, OnInit, Input, inject } from '@angular/core';
|
||||
import {
|
||||
MatTableDataSource,
|
||||
MatTable,
|
||||
@@ -43,11 +43,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
]
|
||||
})
|
||||
export class LoansActiveClientMembersComponent implements OnInit {
|
||||
private route = inject(ActivatedRoute);
|
||||
|
||||
loanId: any = null;
|
||||
@Input() activeClientMembers?: any;
|
||||
@Input() loansAccountFormValid: boolean;
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
constructor() {
|
||||
this.loanId = this.route.snapshot.params['loanId'];
|
||||
}
|
||||
dataSource: any;
|
||||
|
||||
Reference in New Issue
Block a user