fix: Show members in GLIM and GSIM preview (#2334)

This shows a list of participating members in
GLIM resp. GSIM preview step.
It also changes "GLIM Loan" to "GLIM" in a menu
item.

Fixes: WEB-64
This commit is contained in:
Felix van Hove
2025-03-20 14:27:17 -06:00
committed by GitHub
parent 9f3073f7a5
commit 6cc7acae13
19 changed files with 126 additions and 29 deletions
@@ -119,7 +119,7 @@
*mifosxHasPermission="'CREATE_LOAN'"
[routerLink]="['loans-accounts', 'glim-account', 'create']"
>
{{ 'labels.buttons.GLIM Loan Application' | translate }}
{{ 'labels.buttons.GLIM Application' | translate }}
</button>
<button
mat-menu-item
@@ -42,11 +42,44 @@
</span>
</div>
<div fxFlex="98%" *ngIf="activeClientMembers">
<! -- TODO: Display activeClientMembers -->
</div>
<ng-container *ngIf="activeClientMembers">
<h3 class="mat-h3" fxFlexFill class="margin-t">{{ 'labels.heading.Client Members' | translate }}</h3>
<mat-divider fxFlexFill></mat-divider>
<div fxFlex="60%">
<table mat-table #membersTable [dataSource]="dataSource">
<!-- ID 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>
<h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Terms' | translate }}</h3>
<!-- 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>
<td mat-cell *matCellDef="let element">
{{ 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" fxFlexFill class="margin-t">{{ 'labels.heading.Terms' | translate }}</h3>
<mat-divider fxFlexFill></mat-divider>
@@ -175,7 +208,7 @@
<span fxFlex="60%"> {{ loansAccount.balloonRepaymentAmount | formatNumber }} </span>
</div>
<h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Moratorium' | translate }}</h3>
<h3 class="mat-h3" fxFlexFill class="margin-t">{{ 'labels.heading.Moratorium' | translate }}</h3>
<mat-divider fxFlexFill></mat-divider>
@@ -214,7 +247,7 @@
<span fxFlex="60%">{{ loansAccountProductTemplate?.daysInMonthType.value }}</span>
</div>
<div fxFlexFill *ngIf="loansAccount.charges.length" fxLayout="row wrap" fxLayout.lt-md="column">
<div fxFlexFill *ngIf="loansAccount.charges.length" fxLayout="row wrap" fxLayout.lt-md="column" class="margin-t">
<h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Charges' | translate }}</h3>
<mat-divider fxFlexFill></mat-divider>
@@ -279,7 +312,13 @@
</table>
</div>
<div fxFlexFill *ngIf="loansAccountProductTemplate.overdueCharges.length" fxLayout="row wrap" fxLayout.lt-md="column">
<div
fxFlexFill
*ngIf="loansAccountProductTemplate.overdueCharges.length"
fxLayout="row wrap"
fxLayout.lt-md="column"
class="margin-t"
>
<h3 fxFlex="98%" class="mat-h3">{{ 'labels.heading.Overdue Charges' | translate }}</h3>
<mat-divider fxFlex="98%"></mat-divider>
@@ -17,7 +17,7 @@ export class LoansAccountPreviewStepComponent implements OnChanges {
@Input() loansAccountProductTemplate: any;
/** Loans Account Data */
@Input() loansAccount: any;
/** active Client Members in case of GSIM Account */
/** active Client Members in case of GLIM Account */
@Input() activeClientMembers?: any;
/** Submit Loans Account */
@@ -38,6 +38,16 @@ export class LoansAccountPreviewStepComponent implements OnChanges {
'amount',
'collectedon'
];
/** Columns to be displayed in active members table. */
membersDisplayedColumns: string[] = [
'id',
'name',
'purpose',
'principal'
];
/** Loan Purpose Options */
loanPurposeOptions: any[] = [];
/** Table Data Source */
dataSource: any;
@@ -48,11 +58,18 @@ export class LoansAccountPreviewStepComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges): void {
this.productEnableDownPayment = this.loansAccountProductTemplate.product.enableDownPayment;
if (this.activeClientMembers) {
this.dataSource = new MatTableDataSource<any>(this.activeClientMembers);
this.loansAccount.principalAmount = this.activeClientMembers.reduce(
(acc: number, member: any) => acc + (member.principal ?? 0),
0
this.loanPurposeOptions = this.loansAccountProductTemplate.loanPurposeOptions;
this.dataSource = new MatTableDataSource<any>(
this.activeClientMembers
.filter((member: any) => member.selected)
.map((member: any) => ({
...member,
purpose: this.loanPurposeOptions.find((option) => option.id === member.loanPurposeId)?.name
}))
);
this.loansAccount.principalAmount = this.activeClientMembers
.filter((member: any) => member.selected)
.reduce((acc: number, member: any) => acc + (member.principal ?? 0), 0);
}
}
}
@@ -58,6 +58,7 @@
[savingsAccountTemplate]="savingsAccountTemplate"
[savingsAccountTermsForm]="savingsAccountTermsForm"
[savingsAccount]="savingsAccount"
[activeClientMembers]="activeClientMembers"
(submitEvent)="submit()"
>
</mifosx-savings-account-preview-step>
@@ -32,7 +32,30 @@
}}</span>
</div>
<h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Terms' | translate }}</h3>
<ng-container *ngIf="activeClientMembers">
<h3 class="mat-h3" fxFlexFill class="margin-t">{{ 'labels.heading.Client Members' | translate }}</h3>
<mat-divider fxFlexFill></mat-divider>
<div fxFlex="60%">
<table mat-table #membersTable [dataSource]="dataSource">
<!-- ID 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>
<tr mat-header-row *matHeaderRowDef="membersDisplayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: membersDisplayedColumns"></tr>
</table>
</div>
</ng-container>
<h3 class="mat-h3" fxFlexFill class="margin-t">{{ 'labels.heading.Terms' | translate }}</h3>
<mat-divider fxFlexFill></mat-divider>
@@ -1,6 +1,7 @@
/** Angular Imports */
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { MatTableDataSource } from '@angular/material/table';
/**
* Savings account preview step
@@ -10,7 +11,7 @@ import { TranslateService } from '@ngx-translate/core';
templateUrl: './savings-account-preview-step.component.html',
styleUrls: ['./savings-account-preview-step.component.scss']
})
export class SavingsAccountPreviewStepComponent {
export class SavingsAccountPreviewStepComponent implements OnChanges {
/** Savings Account Product Template */
@Input() savingsAccountProductTemplate: any;
/** Savings Account Template */
@@ -19,6 +20,11 @@ export class SavingsAccountPreviewStepComponent {
@Input() savingsAccountTermsForm: any;
/** Savings Account */
@Input() savingsAccount: any;
/** active Client Members in case of GSIM Account */
@Input() activeClientMembers?: any;
/** Table Data Source */
dataSource: any;
/** Display columns for charges table */
chargesDisplayedColumns: string[] = [
@@ -29,12 +35,23 @@ export class SavingsAccountPreviewStepComponent {
'date',
'repaymentsEvery'
];
/** Columns to be displayed in active members table. */
membersDisplayedColumns: string[] = [
'id',
'name'
];
/** Form submission event */
@Output() submitEvent = new EventEmitter();
constructor(private translateService: TranslateService) {}
ngOnChanges(): void {
if (this.activeClientMembers?.length > 0) {
this.dataSource = new MatTableDataSource<any>(this.activeClientMembers.filter((member: any) => member.selected));
}
}
getCatalogTranslation(text: string): string {
return this.translateService.instant('labels.catalogs.' + text);
}