Skip to content

Commit 72a920c

Browse files
WEB-813: Working Capital loan account creation
1 parent 948dbee commit 72a920c

118 files changed

Lines changed: 2883 additions & 2274 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/app/clients/clients-view/general-tab/general-tab.component.html

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ <h3>{{ 'labels.heading.Loan Accounts' | translate }}</h3>
153153
<mifosx-account-number accountNo="{{ element.accountNo }}"></mifosx-account-number>
154154
</td>
155155
</ng-container>
156+
<ng-container matColumnDef="Product Type">
157+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Product Type' | translate }}</th>
158+
<td mat-cell *matCellDef="let element">
159+
{{ loanProductTypeLabel(element.productType) | translate }}
160+
</td>
161+
</ng-container>
156162
<ng-container matColumnDef="Loan Account">
157163
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Loan Product' | translate }}</th>
158164
<td mat-cell *matCellDef="let element">
@@ -180,29 +186,19 @@ <h3>{{ 'labels.heading.Loan Accounts' | translate }}</h3>
180186
<ng-container matColumnDef="Type">
181187
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Type' | translate }}</th>
182188
<td mat-cell class="center" *matCellDef="let element">
183-
<i
184-
class="fa fa-large"
185-
[ngClass]="element.loanType.value === 'Individual' ? 'fa-user' : 'fa-group'"
186-
matTooltip="{{ element.loanType.value }}"
187-
matTooltipPosition="above"
188-
></i>
189+
@if (element.productType === 'loan') {
190+
<i
191+
class="fa fa-large"
192+
[ngClass]="element.loanType.value === 'Individual' ? 'fa-user' : 'fa-group'"
193+
matTooltip="{{ element.loanType.value }}"
194+
matTooltipPosition="above"
195+
></i>
196+
}
189197
</td>
190198
</ng-container>
191199
<ng-container matColumnDef="Actions">
192200
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
193201
<td mat-cell class="center" *matCellDef="let element">
194-
<!-- Print Icon -->
195-
<button
196-
class="account-action-button"
197-
mat-raised-button
198-
color="accent"
199-
matTooltip="{{ 'tooltips.Print Loan Application' | translate }}"
200-
matTooltipPosition="above"
201-
aria-label="{{ 'tooltips.Print Loan Application' | translate }}"
202-
(click)="openLoanApplicationReport($event, element.id)"
203-
>
204-
<i class="fa fa-print"></i>
205-
</button>
206202
@if (element.status.active) {
207203
<button
208204
class="account-action-button"
@@ -279,6 +275,7 @@ <h3>{{ 'labels.heading.Loan Accounts' | translate }}</h3>
279275
mat-row
280276
*matRowDef="let row; columns: openLoansColumns"
281277
[routerLink]="['../', 'loans-accounts', row.id, 'general']"
278+
[queryParams]="{ productType: row.productType }"
282279
class="select-row"
283280
></tr>
284281
<tr
@@ -307,6 +304,12 @@ <h3>{{ 'labels.heading.Loan Accounts' | translate }}</h3>
307304
<mifosx-long-text textValue="{{ element.productName }}" chars="35"></mifosx-long-text>
308305
</td>
309306
</ng-container>
307+
<ng-container matColumnDef="Product Type">
308+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Product Type' | translate }}</th>
309+
<td mat-cell *matCellDef="let element">
310+
{{ loanProductTypeLabel(element.productType) | translate }}
311+
</td>
312+
</ng-container>
310313
<ng-container matColumnDef="Original Loan">
311314
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Original Loan' | translate }}</th>
312315
<td mat-cell *matCellDef="let element">{{ element.lastActiveTransactionDate | dateFormat }}</td>
@@ -340,19 +343,7 @@ <h3>{{ 'labels.heading.Loan Accounts' | translate }}</h3>
340343
</ng-container>
341344
<ng-container matColumnDef="Actions">
342345
<th mat-header-cell class="center" *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
343-
<td mat-cell class="center" *matCellDef="let element">
344-
<!-- Print Icon -->
345-
<button
346-
class="account-action-button"
347-
mat-raised-button
348-
color="accent"
349-
matTooltip="{{ 'tooltips.Print Loan Application' | translate }}"
350-
matTooltipPosition="above"
351-
(click)="openLoanApplicationReport($event, element.id)"
352-
>
353-
<i class="fa fa-print"></i>
354-
</button>
355-
</td>
346+
<td mat-cell class="center" *matCellDef="let element"></td>
356347
</ng-container>
357348

358349
<ng-container matColumnDef="no-data">
@@ -368,6 +359,7 @@ <h3>{{ 'labels.heading.Loan Accounts' | translate }}</h3>
368359
mat-row
369360
*matRowDef="let row; columns: closedLoansColumns"
370361
[routerLink]="['../', 'loans-accounts', row.id, 'general']"
362+
[queryParams]="{ productType: row.productType }"
371363
class="select-row"
372364
></tr>
373365
<tr

src/app/clients/clients-view/general-tab/general-tab.component.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
*/
88

99
/** Angular Imports */
10-
import { Component, OnInit, OnDestroy, inject } from '@angular/core';
11-
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
10+
import { Component, OnDestroy, inject } from '@angular/core';
11+
import { Router, ActivatedRoute } from '@angular/router';
1212
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
1313

1414
/** Custom Services. */
@@ -45,6 +45,7 @@ import { Subject } from 'rxjs';
4545
import { takeUntil, catchError } from 'rxjs/operators';
4646
import { AlertService } from 'app/core/alert/alert.service';
4747
import { EMPTY } from 'rxjs';
48+
import { LoanProductService } from 'app/products/loan-products/services/loan-product.service';
4849

4950
/**
5051
* General Tab component.
@@ -155,6 +156,7 @@ export class GeneralTabComponent implements OnDestroy {
155156
/** Open Loan Accounts Columns */
156157
openLoansColumns: string[] = [
157158
'Account No',
159+
'Product Type',
158160
'Loan Account',
159161
'Original Loan',
160162
'Loan Balance',
@@ -165,6 +167,7 @@ export class GeneralTabComponent implements OnDestroy {
165167
/** Closed Loan Accounts Columns */
166168
closedLoansColumns: string[] = [
167169
'Account No',
170+
'Product Type',
168171
'Loan Account',
169172
'Original Loan',
170173
'Loan Balance',
@@ -226,6 +229,7 @@ export class GeneralTabComponent implements OnDestroy {
226229
clientAccountData: any;
227230
/** Loan Accounts Data */
228231
loanAccounts: any[] = [];
232+
workingCapitalLoanAccounts: any[] = [];
229233
/** Savings Accounts Data */
230234
savingAccounts: any[] = [];
231235
/** Shares Accounts Data */
@@ -273,7 +277,10 @@ export class GeneralTabComponent implements OnDestroy {
273277
(data: { clientAccountsData: any; clientChargesData: any; clientSummary: any; clientCollateralData: any }) => {
274278
this.clientAccountData = data.clientAccountsData;
275279
this.savingAccounts = data.clientAccountsData?.savingsAccounts ?? [];
276-
this.loanAccounts = data.clientAccountsData?.loanAccounts ?? [];
280+
this.loanAccounts = [];
281+
this.processLoanAccounts(data.clientAccountsData?.loanAccounts ?? [], 'loan');
282+
this.processLoanAccounts(data.clientAccountsData?.workingCapitalLoanAccounts ?? [], 'working-capital');
283+
this.workingCapitalLoanAccounts = data.clientAccountsData?.workingCapitalLoanAccounts ?? [];
277284
this.shareAccounts = data.clientAccountsData?.shareAccounts ?? [];
278285

279286
this.upcomingCharges = data.clientChargesData?.pageItems ?? [];
@@ -417,4 +424,17 @@ export class GeneralTabComponent implements OnDestroy {
417424
return 'labels.buttons.View Closed Accounts';
418425
}
419426
}
427+
428+
loanProductTypeLabel(productType: string): string {
429+
return LoanProductService.productTypeLabel(productType);
430+
}
431+
432+
private processLoanAccounts(accounts: any[], productType: string): void {
433+
accounts.map((account: any) => {
434+
this.loanAccounts.push({
435+
productType: productType,
436+
...account
437+
});
438+
});
439+
}
420440
}

src/app/core/shell/breadcrumb/breadcrumb.component.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
/** Angular Imports */
1010
import { Component, TemplateRef, ElementRef, ViewChild, AfterViewInit, OnDestroy, inject } from '@angular/core';
11-
import { ActivatedRoute, Router, NavigationEnd, Data, RouterLink } from '@angular/router';
11+
import { ActivatedRoute, Router, NavigationEnd, Data } from '@angular/router';
1212

1313
/** rxjs Imports */
1414
import { filter, takeUntil } from 'rxjs/operators';
@@ -243,6 +243,9 @@ export class BreadcrumbComponent implements AfterViewInit, OnDestroy {
243243
}
244244

245245
printableValue(value: string): string {
246+
if (!value) {
247+
return '';
248+
}
246249
if (value.length <= 30) {
247250
return value;
248251
}

src/app/loans/common-resolvers/loan-details.resolver.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,33 @@ import { Observable } from 'rxjs';
1515

1616
/** Custom Services */
1717
import { LoansService } from '../loans.service';
18+
import { LoanProductService } from 'app/products/loan-products/services/loan-product.service';
19+
import { LOAN_PRODUCT_TYPE } from 'app/products/loan-products/models/loan-product.model';
1820

1921
/**
2022
* Clients data resolver.
2123
*/
2224
@Injectable()
2325
export class LoanDetailsResolver {
2426
private loansService = inject(LoansService);
27+
private loanProductService = inject(LoanProductService);
2528

2629
/**
2730
* Returns the Loans with Association data.
2831
* @returns {Observable<any>}
2932
*/
3033
resolve(route: ActivatedRouteSnapshot): Observable<any> {
3134
const loanId = route.paramMap.get('loanId') || route.parent.paramMap.get('loanId');
35+
const productType = route.queryParams['productType'];
36+
const resolvedProductType =
37+
productType === LOAN_PRODUCT_TYPE.WORKING_CAPITAL ? LOAN_PRODUCT_TYPE.WORKING_CAPITAL : LOAN_PRODUCT_TYPE.LOAN;
38+
this.loanProductService.initialize(resolvedProductType);
3239
if (!isNaN(+loanId)) {
33-
return this.loansService.getLoanAccountAssociationDetails(loanId);
40+
if (resolvedProductType === LOAN_PRODUCT_TYPE.LOAN) {
41+
return this.loansService.getLoanAccountAssociationDetails(loanId);
42+
} else {
43+
return this.loansService.getWorkingCapitalLoannDetails(loanId);
44+
}
3445
}
3546
}
3647
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright since 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
9+
/** Angular Imports */
10+
import { Injectable, inject } from '@angular/core';
11+
import { ActivatedRouteSnapshot } from '@angular/router';
12+
13+
/** rxjs Imports */
14+
import { Observable } from 'rxjs';
15+
16+
/** Custom Services */
17+
import { ProductsService } from 'app/products/products.service';
18+
19+
/**
20+
* Loan Product list data resolver.
21+
*/
22+
@Injectable()
23+
export class LoanProductsResolver {
24+
private productsService = inject(ProductsService);
25+
26+
/**
27+
* Returns the loan account template data.
28+
* @returns {Observable<any>}
29+
*/
30+
resolve(route: ActivatedRouteSnapshot): Observable<any> {
31+
return this.productsService.getLoanProductsBasicDetails();
32+
}
33+
}

0 commit comments

Comments
 (0)