Skip to content

Commit 75213a2

Browse files
committed
WEB-95 Fix problems with GLIM application: saved total ,Moratorium, Overdue Charges
1 parent 00da30b commit 75213a2

File tree

8 files changed

+179
-104
lines changed

8 files changed

+179
-104
lines changed

src/app/app.module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** Angular Imports */
22
import { NgModule } from '@angular/core';
33
import { BrowserModule } from '@angular/platform-browser';
4+
import { I18nService } from './core/i18n/i18n.service';
45
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
56
import {
67
HttpBackend,
@@ -130,7 +131,9 @@ export function HttpLoaderFactory(http: HttpClient) {
130131
provide: HTTP_INTERCEPTORS,
131132
useClass: !environment.OIDC.oidcServerEnabled ? TokenInterceptor : ZitadelTokenInterceptor,
132133
multi: true
133-
}
134+
},
135+
I18nService
136+
134137
]
135138
})
136139
export class AppModule {}

src/app/loans/glim-account/create-glim-account/create-glim-account.component.ts

Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -177,37 +177,38 @@ export class CreateGlimAccountComponent {
177177
};
178178
}
179179

180-
setData(client: any, totalLoan: number): any {
180+
setData(client: any, totalLoan: number, isParent?: boolean): any {
181181
const locale = this.settingsService.language.code;
182182
const dateFormat = this.settingsService.dateFormat;
183183
// const monthDayFormat = 'dd MMMM';
184-
const data = {
184+
const data: any = {
185185
...this.loansAccount,
186186
charges: this.loansAccount.charges.map((charge: any) => ({
187187
chargeId: charge.id,
188-
amount: charge.amount
188+
amount: charge.amount,
189+
currency: charge.currency
189190
})),
190191
clientId: client.id,
191-
totalLoan: totalLoan,
192192
loanType: 'glim',
193193
amortizationType: 1,
194-
isParentAccount: true,
195194
principal: client.principal,
196195
syncDisbursementWithMeeting: false,
197196
expectedDisbursementDate: this.dateUtils.formatDate(this.loansAccount.expectedDisbursementDate, dateFormat),
198197
submittedOnDate: this.dateUtils.formatDate(this.loansAccount.submittedOnDate, dateFormat),
199-
dateFormat,
200-
// monthDayFormat,
201-
locale
198+
dateFormat: dateFormat,
199+
locale: locale,
200+
groupId: this.loansAccountTemplate.group.id
202201
};
203-
data.groupId = this.loansAccountTemplate.group.id;
204-
202+
if (isParent) {
203+
data.totalLoan = totalLoan;
204+
data.isParentAccount = true;
205+
}
205206
delete data.principalAmount;
206-
// TODO: 2025-03-17: Apparently (?!) unsupported for GLIM
207207
delete data.allowPartialPeriodInterestCalculation;
208208
delete data.multiDisburseLoan;
209209
delete data.isFloatingInterestRate;
210-
210+
delete data.moratoriumPrincipal;
211+
delete data.moratoriumInterest;
211212
return JSON.stringify(data);
212213
}
213214

@@ -216,12 +217,22 @@ export class CreateGlimAccountComponent {
216217
const requestData = [];
217218
const memberSelected = this.selectedMembers?.selectedMembers ?? [];
218219
const totalLoan = this.totalLoanAmount();
220+
requestData.push({
221+
requestId: '0',
222+
method: 'POST',
223+
relativeUrl: 'loans',
224+
body: this.setData(
225+
{ id: this.loansAccountTemplate.group.id, principal: totalLoan, isParentAccount: true },
226+
totalLoan,
227+
true
228+
)
229+
});
219230
for (let index = 0; index < memberSelected.length; index++) {
220231
requestData.push({
221-
requestId: index.toString(),
232+
requestId: (index + 1).toString(),
222233
method: 'POST',
223234
relativeUrl: 'loans',
224-
body: this.setData(memberSelected[index], totalLoan)
235+
body: this.setData(memberSelected[index], totalLoan, false)
225236
});
226237
}
227238
return requestData;
@@ -236,57 +247,10 @@ export class CreateGlimAccountComponent {
236247
return total;
237248
}
238249

239-
/**
240-
* Creates a new GLIM account.
241-
*/
242-
submit() {
243-
this.selectedMembers = this.loansActiveClientMembers?.selectedClientMembers;
244-
const memberSelected = this.loansActiveClientMembers?.selectedClientMembers?.selectedMembers ?? [];
245-
if (!memberSelected.length) return;
246-
const gsimMemberIds = new Set(this.dataSource.map((m: any) => Number(m.id)));
247-
for (const member of memberSelected) {
248-
const memberId = Number(member.id);
249-
// Validate savings account ownership
250-
const ownerId = Number(member.linkAccountOwnerId);
251-
if (member.linkAccountId && member.linkAccountOwnerId && ownerId !== memberId) {
252-
this.i18nService.translate('errors.linkedSavingsAccountOwnership').subscribe((msg: string) => {
253-
this.notify({ defaultUserMessage: msg, errors: [] }, { memberId });
254-
});
255-
return;
256-
}
257-
// Validate GSIM membership
258-
if (!gsimMemberIds.has(memberId)) {
259-
this.i18nService.translate('errors.clientNotInGSIM', { id: memberId }).subscribe((msg: string) => {
260-
this.notify({ defaultUserMessage: msg, errors: [] }, { memberId });
261-
});
262-
return;
263-
}
264-
}
265-
266-
// Use date format from settingsService for interestChargedFromDate
267-
const data = this.buildRequestData();
268-
this.loansService.createGlimAccount(data).subscribe((response: any) => {
269-
const body = JSON.parse(response[0].body);
270-
if (body.glimId) {
271-
this.router.navigate(
272-
[
273-
'../',
274-
body.glimId
275-
],
276-
{ relativeTo: this.route }
277-
);
278-
} else {
279-
this.notify(body, { batchSize: data.length });
280-
}
281-
});
282-
}
283-
284-
notify(body: any, context?: { [k: string]: unknown }) {
285-
const parts: string[] = [String(body?.defaultUserMessage ?? '')];
286-
if (Array.isArray(body?.errors)) {
287-
for (const e of body.errors) parts.push(String(e?.developerMessage ?? ''));
288-
}
289-
if (context) parts.push(`Context: ${JSON.stringify(context)}`);
290-
console.error(parts.join(' ').trim());
250+
notify(body: any, data: any) {
251+
let message = body.defaultUserMessage + ' ';
252+
body.errors?.forEach((error: any) => (message += error.developerMessage + ' '));
253+
message += 'Data: ' + JSON.stringify(data);
254+
console.error(message);
291255
}
292256
}

src/app/loans/loans-account-stepper/loans-account-charges-step/loans-account-charges-step.component.html

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<ng-container matColumnDef="name">
2525
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
2626
<td mat-cell *matCellDef="let charge">
27-
{{ charge.name + ', ' + charge.currency.displaySymbol }}
27+
{{ charge.name }}<span *ngIf="charge.currency">, {{ charge.currency.displaySymbol }}</span>
2828
</td>
2929
</ng-container>
3030

@@ -39,7 +39,13 @@
3939
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
4040
<td mat-cell *matCellDef="let charge">
4141
{{ charge.amount }}
42-
<button mat-icon-button color="primary" (click)="editChargeAmount(charge)">
42+
<button
43+
mat-icon-button
44+
color="primary"
45+
(click)="editChargeAmount(charge)"
46+
type="button"
47+
aria-label="Edit charge amount"
48+
>
4349
<fa-icon icon="pen"></fa-icon>
4450
</button>
4551
</td>
@@ -84,6 +90,8 @@
8490
charge.chargeTimeType.value === 'Specified due date'
8591
"
8692
(click)="editChargeDate(charge)"
93+
type="button"
94+
aria-label="Edit charge date"
8795
>
8896
<fa-icon icon="pen"></fa-icon>
8997
</button>
@@ -93,7 +101,7 @@
93101
<ng-container matColumnDef="action">
94102
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
95103
<td mat-cell *matCellDef="let charge">
96-
<button mat-icon-button color="warn" (click)="deleteCharge(charge)">
104+
<button mat-icon-button color="warn" (click)="deleteCharge(charge)" type="button" aria-label="Delete charge">
97105
<fa-icon icon="trash"></fa-icon>
98106
</button>
99107
</td>
@@ -110,7 +118,9 @@ <h4 class="mat-h4 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h
110118
<table mat-table class="mat-elevation-z1" [dataSource]="overDueChargesDataSource">
111119
<ng-container matColumnDef="name">
112120
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
113-
<td mat-cell *matCellDef="let charge">{{ charge.name }},{{ charge.currency.displaySymbol }}</td>
121+
<td mat-cell *matCellDef="let charge">
122+
{{ charge.name }}<span *ngIf="charge.currency">,{{ charge.currency.displaySymbol }}</span>
123+
</td>
114124
</ng-container>
115125

116126
<ng-container matColumnDef="type">
@@ -120,7 +130,18 @@ <h4 class="mat-h4 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h
120130

121131
<ng-container matColumnDef="amount">
122132
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
123-
<td mat-cell *matCellDef="let charge">{{ charge.amount | formatNumber }}</td>
133+
<td mat-cell *matCellDef="let charge">
134+
{{ charge.amount | formatNumber }}
135+
<button
136+
mat-icon-button
137+
color="primary"
138+
(click)="editOverdueChargeAmount(charge)"
139+
type="button"
140+
aria-label="Edit overdue charge amount"
141+
>
142+
<fa-icon icon="pen"></fa-icon>
143+
</button>
144+
</td>
124145
</ng-container>
125146

126147
<ng-container matColumnDef="collectedon">
@@ -134,15 +155,15 @@ <h4 class="mat-h4 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h
134155
</div>
135156

136157
<div class="layout-row responsive-column align-center gap-2px margin-t">
137-
<button mat-raised-button matStepperPrevious>
158+
<button mat-raised-button matStepperPrevious type="button">
138159
<fa-icon icon="arrow-left" class="m-r-10"></fa-icon>
139160
{{ 'labels.buttons.Previous' | translate }}
140161
</button>
141-
<button mat-raised-button matStepperNext>
162+
<button mat-raised-button matStepperNext type="button">
142163
{{ 'labels.buttons.Next' | translate }}
143164
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
144165
</button>
145-
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
166+
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']" type="button">
146167
{{ 'labels.buttons.Cancel' | translate }}
147168
</button>
148169
</div>

src/app/loans/loans-account-stepper/loans-account-charges-step/loans-account-charges-step.component.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,33 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
326326
});
327327
}
328328

329+
editOverdueChargeAmount(charge: { amount: number; [key: string]: any }) {
330+
const formfields: FormfieldBase[] = [
331+
new InputBase({
332+
controlName: 'amount',
333+
label: 'Amount',
334+
value: charge.amount,
335+
type: 'number',
336+
required: false
337+
})
338+
339+
];
340+
const data = {
341+
title: 'Edit Overdue Charge Amount',
342+
layout: { addButtonText: 'Confirm' },
343+
formfields: formfields
344+
};
345+
const editNoteDialogRef = this.dialog.open(FormDialogComponent, { data });
346+
editNoteDialogRef.afterClosed().subscribe((response?: { data?: { value: { amount: number } } }) => {
347+
if (response?.data) {
348+
const newCharge = { ...charge, amount: response.data.value.amount };
349+
this.overDueChargesDataSource.splice(this.overDueChargesDataSource.indexOf(charge), 1, newCharge);
350+
this.overDueChargesDataSource = this.overDueChargesDataSource.concat([]);
351+
this.pristine = false;
352+
}
353+
});
354+
}
355+
329356
get isValid() {
330357
return true;
331358
// !this.activeClientMembers ||

src/app/loans/loans-account-stepper/loans-account-preview-step/loans-account-preview-step.component.html

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,14 @@ <h3 class="mat-h3 flex-fill">{{ 'labels.heading.Charges' | translate }}</h3>
262262
<ng-container matColumnDef="name">
263263
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
264264
<td mat-cell *matCellDef="let charge">
265-
{{ charge.name + ', ' + charge.currency.displaySymbol }}
265+
{{ charge.name }}<span *ngIf="charge.currency">, {{ charge.currency.displaySymbol }}</span>
266266
</td>
267267
</ng-container>
268268

269269
<ng-container matColumnDef="chargeCalculationType">
270270
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
271271
<td mat-cell *matCellDef="let charge">
272-
{{ charge.chargeCalculationType.value }}
272+
{{ charge.chargeCalculationType?.value || '' }}
273273
</td>
274274
</ng-container>
275275

@@ -283,28 +283,30 @@ <h3 class="mat-h3 flex-fill">{{ 'labels.heading.Charges' | translate }}</h3>
283283
<ng-container matColumnDef="chargeTimeType">
284284
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Collected On' | translate }}</th>
285285
<td mat-cell *matCellDef="let charge">
286-
{{ charge.chargeTimeType.value }}
286+
{{ charge.chargeTimeType?.value || '' }}
287287
</td>
288288
</ng-container>
289289

290290
<ng-container matColumnDef="date">
291291
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Date' | translate }}</th>
292292
<td mat-cell *matCellDef="let charge">
293293
<span
294-
*ngIf="charge.chargeTimeType.value === 'Specified due date' || charge.chargeTimeType.value === 'Weekly Fee'"
294+
*ngIf="
295+
charge.chargeTimeType?.value === 'Specified due date' || charge.chargeTimeType?.value === 'Weekly Fee'
296+
"
295297
>
296298
{{ (charge.dueDate | dateFormat) || 'Unassigned' }}
297299
</span>
298-
<span *ngIf="charge.chargeTimeType.value === 'Monthly Fee' || charge.chargeTimeType.value === 'Annual Fee'">
300+
<span *ngIf="charge.chargeTimeType?.value === 'Monthly Fee' || charge.chargeTimeType?.value === 'Annual Fee'">
299301
{{ (charge.feeOnMonthDay | dateFormat) || 'Unassigned' }}
300302
</span>
301303
<span
302304
*ngIf="
303305
!(
304-
charge.chargeTimeType.value === 'Monthly Fee' ||
305-
charge.chargeTimeType.value === 'Annual Fee' ||
306-
charge.chargeTimeType.value === 'Specified due date' ||
307-
charge.chargeTimeType.value === 'Weekly Fee'
306+
charge.chargeTimeType?.value === 'Monthly Fee' ||
307+
charge.chargeTimeType?.value === 'Annual Fee' ||
308+
charge.chargeTimeType?.value === 'Specified due date' ||
309+
charge.chargeTimeType?.value === 'Weekly Fee'
308310
)
309311
"
310312
>
@@ -329,7 +331,9 @@ <h3 class="mat-h3 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h
329331
<table mat-table class="mat-elevation-z1" [dataSource]="loansAccountProductTemplate.overdueCharges">
330332
<ng-container matColumnDef="name">
331333
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.name' | translate }}</th>
332-
<td mat-cell *matCellDef="let charge">{{ charge.name }},{{ charge.currency.displaySymbol }}</td>
334+
<td mat-cell *matCellDef="let charge">
335+
{{ charge.name }}<span *ngIf="charge.currency">,{{ charge.currency.displaySymbol }}</span>
336+
</td>
333337
</ng-container>
334338

335339
<ng-container matColumnDef="type">

0 commit comments

Comments
 (0)