Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** Angular Imports */
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { I18nService } from './core/i18n/i18n.service';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
HttpBackend,
Expand Down Expand Up @@ -130,7 +131,9 @@ export function HttpLoaderFactory(http: HttpClient) {
provide: HTTP_INTERCEPTORS,
useClass: !environment.OIDC.oidcServerEnabled ? TokenInterceptor : ZitadelTokenInterceptor,
multi: true
}
},
I18nService

]
})
export class AppModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -177,37 +177,42 @@ export class CreateGlimAccountComponent {
};
}

setData(client: any, totalLoan: number): any {
setData(applicationId: number, client: any, totalLoan: number, isFirst: boolean, isLast: boolean): any {
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
// const monthDayFormat = 'dd MMMM';
const data = {
const data: any = {
...this.loansAccount,
charges: this.loansAccount.charges.map((charge: any) => ({
chargeId: charge.id,
amount: charge.amount
amount: charge.amount,
currency: charge.currency
})),
clientId: client.id,
totalLoan: totalLoan,
loanType: 'glim',
applicationId: applicationId,
amortizationType: 1,
isParentAccount: true,
principal: client.principal,
syncDisbursementWithMeeting: false,
expectedDisbursementDate: this.dateUtils.formatDate(this.loansAccount.expectedDisbursementDate, dateFormat),
submittedOnDate: this.dateUtils.formatDate(this.loansAccount.submittedOnDate, dateFormat),
dateFormat,
// monthDayFormat,
locale
dateFormat: dateFormat,
locale: locale,
groupId: this.loansAccountTemplate.group.id
};
data.groupId = this.loansAccountTemplate.group.id;

if (isFirst) {
data.isParentAccount = true;
}
if (isLast) {
data.lastApplication = true;
}
delete data.principalAmount;
// TODO: 2025-03-17: Apparently (?!) unsupported for GLIM
delete data.allowPartialPeriodInterestCalculation;
delete data.multiDisburseLoan;
delete data.isFloatingInterestRate;

delete data.moratoriumPrincipal;
delete data.moratoriumInterest;
return JSON.stringify(data);
}

Expand All @@ -216,12 +221,17 @@ export class CreateGlimAccountComponent {
const requestData = [];
const memberSelected = this.selectedMembers?.selectedMembers ?? [];
const totalLoan = this.totalLoanAmount();
const applicationId = Math.floor(1000000000 + Math.random() * 9000000000);

for (let index = 0; index < memberSelected.length; index++) {
const isFirst = index === 0;
const isLast = index === memberSelected.length - 1;
requestData.push({
requestId: index.toString(),
reference: index === 0 ? null : (index - 1).toString(),
method: 'POST',
relativeUrl: 'loans',
body: this.setData(memberSelected[index], totalLoan)
body: this.setData(applicationId, memberSelected[index], totalLoan, isFirst, isLast)
});
}
return requestData;
Expand All @@ -236,57 +246,10 @@ export class CreateGlimAccountComponent {
return total;
}

/**
* Creates a new GLIM account.
*/
submit() {
this.selectedMembers = this.loansActiveClientMembers?.selectedClientMembers;
const memberSelected = this.loansActiveClientMembers?.selectedClientMembers?.selectedMembers ?? [];
if (!memberSelected.length) return;
const gsimMemberIds = new Set(this.dataSource.map((m: any) => Number(m.id)));
for (const member of memberSelected) {
const memberId = Number(member.id);
// Validate savings account ownership
const ownerId = Number(member.linkAccountOwnerId);
if (member.linkAccountId && member.linkAccountOwnerId && ownerId !== memberId) {
this.i18nService.translate('errors.linkedSavingsAccountOwnership').subscribe((msg: string) => {
this.notify({ defaultUserMessage: msg, errors: [] }, { memberId });
});
return;
}
// Validate GSIM membership
if (!gsimMemberIds.has(memberId)) {
this.i18nService.translate('errors.clientNotInGSIM', { id: memberId }).subscribe((msg: string) => {
this.notify({ defaultUserMessage: msg, errors: [] }, { memberId });
});
return;
}
}

// Use date format from settingsService for interestChargedFromDate
const data = this.buildRequestData();
this.loansService.createGlimAccount(data).subscribe((response: any) => {
const body = JSON.parse(response[0].body);
if (body.glimId) {
this.router.navigate(
[
'../',
body.glimId
],
{ relativeTo: this.route }
);
} else {
this.notify(body, { batchSize: data.length });
}
});
}

notify(body: any, context?: { [k: string]: unknown }) {
const parts: string[] = [String(body?.defaultUserMessage ?? '')];
if (Array.isArray(body?.errors)) {
for (const e of body.errors) parts.push(String(e?.developerMessage ?? ''));
}
if (context) parts.push(`Context: ${JSON.stringify(context)}`);
console.error(parts.join(' ').trim());
notify(body: any, data: any) {
let message = body.defaultUserMessage + ' ';
body.errors?.forEach((error: any) => (message += error.developerMessage + ' '));
message += 'Data: ' + JSON.stringify(data);
console.error(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<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 }}
{{ charge.name }}<span *ngIf="charge.currency">, {{ charge.currency.displaySymbol }}</span>
</td>
</ng-container>

Expand All @@ -39,7 +39,13 @@
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
<td mat-cell *matCellDef="let charge">
{{ charge.amount }}
<button mat-icon-button color="primary" (click)="editChargeAmount(charge)">
<button
mat-icon-button
color="primary"
(click)="editChargeAmount(charge)"
type="button"
aria-label="Edit charge amount"
>
<fa-icon icon="pen"></fa-icon>
</button>
</td>
Expand Down Expand Up @@ -84,6 +90,8 @@
charge.chargeTimeType.value === 'Specified due date'
"
(click)="editChargeDate(charge)"
type="button"
aria-label="Edit charge date"
>
<fa-icon icon="pen"></fa-icon>
</button>
Expand All @@ -93,7 +101,7 @@
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
<td mat-cell *matCellDef="let charge">
<button mat-icon-button color="warn" (click)="deleteCharge(charge)">
<button mat-icon-button color="warn" (click)="deleteCharge(charge)" type="button" aria-label="Delete charge">
<fa-icon icon="trash"></fa-icon>
</button>
</td>
Expand All @@ -110,7 +118,9 @@ <h4 class="mat-h4 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h
<table mat-table class="mat-elevation-z1" [dataSource]="overDueChargesDataSource">
<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>
<td mat-cell *matCellDef="let charge">
{{ charge.name }}<span *ngIf="charge.currency">, {{ charge.currency.displaySymbol }}</span>
</td>
</ng-container>

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

<ng-container matColumnDef="amount">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
<td mat-cell *matCellDef="let charge">{{ charge.amount | formatNumber }}</td>
<td mat-cell *matCellDef="let charge">
{{ charge.amount | formatNumber }}
<button
mat-icon-button
color="primary"
(click)="editOverdueChargeAmount(charge)"
type="button"
aria-label="Edit overdue charge amount"
>
<fa-icon icon="pen"></fa-icon>
</button>
</td>
</ng-container>

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

<div class="layout-row responsive-column align-center gap-2px margin-t">
<button mat-raised-button matStepperPrevious>
<button mat-raised-button matStepperPrevious type="button">
<fa-icon icon="arrow-left" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Previous' | translate }}
</button>
<button mat-raised-button matStepperNext>
<button mat-raised-button matStepperNext type="button">
{{ 'labels.buttons.Next' | translate }}
<fa-icon icon="arrow-right" class="m-l-10"></fa-icon>
</button>
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']" type="button">
{{ 'labels.buttons.Cancel' | translate }}
</button>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,33 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
});
}

editOverdueChargeAmount(charge: { amount: number; [key: string]: any }) {
const formfields: FormfieldBase[] = [
new InputBase({
controlName: 'amount',
label: 'Amount',
value: charge.amount,
type: 'number',
required: false
})

];
const data = {
title: 'Edit Overdue Charge Amount',
layout: { addButtonText: 'Confirm' },
formfields: formfields
};
const editNoteDialogRef = this.dialog.open(FormDialogComponent, { data });
editNoteDialogRef.afterClosed().subscribe((response?: { data?: { value: { amount: number } } }) => {
if (response?.data) {
const newCharge = { ...charge, amount: response.data.value.amount };
this.overDueChargesDataSource.splice(this.overDueChargesDataSource.indexOf(charge), 1, newCharge);
this.overDueChargesDataSource = this.overDueChargesDataSource.concat([]);
this.pristine = false;
}
});
}

get isValid() {
return true;
// !this.activeClientMembers ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,14 @@ <h3 class="mat-h3 flex-fill">{{ 'labels.heading.Charges' | translate }}</h3>
<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 }}
{{ charge.name }}<span *ngIf="charge.currency">, {{ charge.currency.displaySymbol }}</span>
</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 }}
{{ charge.chargeCalculationType?.value || '' }}
</td>
</ng-container>

Expand All @@ -283,28 +283,30 @@ <h3 class="mat-h3 flex-fill">{{ 'labels.heading.Charges' | translate }}</h3>
<ng-container matColumnDef="chargeTimeType">
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Collected On' | translate }}</th>
<td mat-cell *matCellDef="let charge">
{{ charge.chargeTimeType.value }}
{{ 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'"
*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'">
<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'
charge.chargeTimeType?.value === 'Monthly Fee' ||
charge.chargeTimeType?.value === 'Annual Fee' ||
charge.chargeTimeType?.value === 'Specified due date' ||
charge.chargeTimeType?.value === 'Weekly Fee'
)
"
>
Expand All @@ -329,7 +331,9 @@ <h3 class="mat-h3 flex-98">{{ 'labels.heading.Overdue Charges' | translate }}</h
<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>
<td mat-cell *matCellDef="let charge">
{{ charge.name }}<span *ngIf="charge.currency">,{{ charge.currency.displaySymbol }}</span>
</td>
</ng-container>

<ng-container matColumnDef="type">
Expand Down
Loading