Skip to content

Commit 13840a0

Browse files
authored
merging dev into openapi-integration (#2600)
1 parent e243bc3 commit 13840a0

File tree

44 files changed

+598
-138
lines changed

Some content is hidden

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

44 files changed

+598
-138
lines changed

src/app/accounting/create-journal-entry/create-journal-entry.component.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,17 +196,15 @@ export class CreateJournalEntryComponent implements OnInit, AfterViewInit {
196196
if (!journalEntry['externalAssetOwner']) {
197197
delete journalEntry['externalAssetOwner'];
198198
}
199-
this.journalEntriesService
200-
.createGLJournalEntry({ journalEntryCommand: journalEntry })
201-
.subscribe((response: any) => {
202-
this.router.navigate(
203-
[
204-
'../transactions/view',
205-
response.transactionId
206-
],
207-
{ relativeTo: this.route }
208-
);
209-
});
199+
this.journalEntriesService.createGLJournalEntry(journalEntry).subscribe((response) => {
200+
this.router.navigate(
201+
[
202+
'../transactions/view',
203+
response.transactionId
204+
],
205+
{ relativeTo: this.route }
206+
);
207+
});
210208
}
211209

212210
/**

src/app/customApis.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ export class LoansService {
8282
deleteLoanNote(loanId: string, noteId: string) {
8383
return this.http.delete(`/loans/${loanId}/notes/${noteId}`);
8484
}
85+
86+
getBuyDownFeeData(loanId: string): Observable<any> {
87+
return this.http.get(`/loans/${loanId}/buydown-fees`);
88+
}
8589
}
8690

8791
@Injectable({
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Injectable } from '@angular/core';
2+
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
3+
import { Observable } from 'rxjs';
4+
import { LoansService } from 'app/customApis.service';
5+
6+
@Injectable()
7+
export class LoanBuyDownFeesDataResolver implements Resolve<Object> {
8+
constructor(private loansService: LoansService) {}
9+
10+
resolve(route: ActivatedRouteSnapshot): Observable<any> {
11+
const loanId = route.paramMap.get('loanId') || route.parent.paramMap.get('loanId');
12+
13+
if (!loanId) {
14+
console.error('LoanBuyDownFeesDataResolver: Could not find loanId in route parameters');
15+
return new Observable((observer) => {
16+
observer.next([]);
17+
observer.complete();
18+
});
19+
}
20+
21+
return this.loansService.getBuyDownFeeData(loanId);
22+
}
23+
}

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,20 +357,16 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
357357
this.setLoanTermListener();
358358

359359
this.loansAccountTermsForm.removeControl('maxOutstandingLoanBalance');
360-
const maxOutstandingLoanBalance =
361-
this.loansAccountTermsData && this.loansAccountTermsData.maxOutstandingLoanBalance != null
362-
? this.loansAccountTermsData.maxOutstandingLoanBalance
363-
: '';
364360
if (this.allowAddDisbursementDetails()) {
365361
this.loansAccountTermsForm.removeControl('maxOutstandingLoanBalance');
366362
this.loansAccountTermsForm.addControl(
367363
'maxOutstandingLoanBalance',
368-
new UntypedFormControl(maxOutstandingLoanBalance, Validators.required)
364+
new UntypedFormControl(this.loansAccountTermsData.maxOutstandingLoanBalance, Validators.required)
369365
);
370366
} else {
371367
this.loansAccountTermsForm.addControl(
372368
'maxOutstandingLoanBalance',
373-
new UntypedFormControl(maxOutstandingLoanBalance)
369+
new UntypedFormControl(this.loansAccountTermsData.maxOutstandingLoanBalance)
374370
);
375371
}
376372
}

src/app/loans/loans-account-stepper/loans-active-client-members/loans-active-client-members.component.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,10 @@ export class LoansActiveClientMembersComponent implements OnInit {
6565
];
6666

6767
ngOnInit(): void {
68-
// console.log("Active Client Members in LoansActiveClientMembersComponent:", this.activeClientMembers);
69-
7068
this.dataSource = new MatTableDataSource<any>(this.activeClientMembers);
7169
}
7270

7371
get isValid() {
74-
// console.log("LoansActiveClientMembersComponent isValid:", this.selectedClientMembers?.selectedMembers?.reduce((acc: any, cur: any) => acc + (cur.principal ?? 0), 0) > 0);
7572
return (
7673
!this.activeClientMembers ||
7774
this.selectedClientMembers?.selectedMembers?.reduce((acc: any, cur: any) => acc + (cur.principal ?? 0), 0) > 0

src/app/loans/loans-routing.module.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { ViewRecieptComponent } from './loans-view/transactions/view-reciept/vie
2828
import { ExportTransactionsComponent } from './loans-view/transactions/export-transactions/export-transactions.component';
2929
import { GlimAccountComponent } from './glim-account/glim-account.component';
3030
import { CreateGlimAccountComponent } from './glim-account/create-glim-account/create-glim-account.component';
31+
import { LoanBuyDownFeesTabComponent } from './loans-view/loan-buy-down-fees-tab/loan-buy-down-fees-tab.component';
3132

3233
/** Custom Resolvers */
3334
import { LoanDetailsResolver } from './common-resolvers/loan-details.resolver';
@@ -64,6 +65,7 @@ import { LoanTermVariationsTabComponent } from './loans-view/loan-term-variation
6465
import { LoanTermVariationsResolver } from './common-resolvers/loan-term-variations.resolver';
6566
import { LoanDeferredIncomeTabComponent } from './loans-view/loan-deferred-income-tab/loan-deferred-income-tab.component';
6667
import { LoanDeferredIncomeDataResolver } from './common-resolvers/loan-deferred-income-data.resolver';
68+
import { LoanBuyDownFeesDataResolver } from './common-resolvers/loan-buy-down-fees-data.resolver';
6769

6870
/** Loans Route. */
6971
const routes: Routes = [
@@ -260,6 +262,14 @@ const routes: Routes = [
260262
}
261263
}
262264
]
265+
},
266+
{
267+
path: 'buy-down-fees',
268+
component: LoanBuyDownFeesTabComponent,
269+
data: { title: 'Buy Down Fees', breadcrumb: 'Buy Down Fees', routeParamBreadcrumb: false },
270+
resolve: {
271+
loanBuyDownFeesData: LoanBuyDownFeesDataResolver
272+
}
263273
}
264274
]
265275
},
@@ -407,7 +417,8 @@ const routes: Routes = [
407417
ExternalAssetOwnerResolver,
408418
LoanDelinquencyDataResolver,
409419
LoanTermVariationsResolver,
410-
LoanDeferredIncomeDataResolver
420+
LoanDeferredIncomeDataResolver,
421+
LoanBuyDownFeesDataResolver
411422
]
412423
})
413424
export class LoansRoutingModule {}

src/app/loans/loans-view/account-details/account-details.component.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ <h3>{{ 'labels.heading.Loan Details' | translate }}</h3>
123123
<span class="flex-50"> {{ loanDetails.buyDownFeeIncomeType?.value | translateKey: 'catalogs' }} </span>
124124
</div>
125125

126+
<div class="flex-fill layout-row" *ngIf="loanDetails.enableBuyDownFee">
127+
<span class="flex-50"> {{ 'labels.inputs.Merchant Buy down fee' | translate }}</span>
128+
<span class="flex-50"> {{ loanDetails.merchantBuyDownFee | yesNo }} </span>
129+
</div>
130+
126131
<div class="flex-fill layout-row">
127132
<span class="flex-50"> {{ 'labels.inputs.Grace: On Principal Payment' | translate }}</span>
128133
<span class="flex-50"> {{ loanDetails.graceOnPrincipalPayment }} </span>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<div class="container">
2+
<h3>{{ 'labels.heading.Buy Down Fees' | translate }}</h3>
3+
4+
<div *ngIf="isLoading" class="loading-indicator">
5+
<mat-spinner diameter="30"></mat-spinner>
6+
</div>
7+
8+
<div *ngIf="!isLoading">
9+
<div *ngIf="buyDownFeeData.length === 0" class="no-data">
10+
{{ 'labels.messages.No Data Found' | translate }}
11+
</div>
12+
13+
<table mat-table [dataSource]="buyDownFeeData" *ngIf="buyDownFeeData.length > 0">
14+
<ng-container matColumnDef="buyDownFeeDate">
15+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.heading.Date' | translate }}</th>
16+
<td mat-cell *matCellDef="let item">
17+
{{ item.buyDownFeeDate | dateFormat }}
18+
</td>
19+
</ng-container>
20+
21+
<ng-container matColumnDef="buyDownFeeAmount">
22+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.heading.Fee Amount' | translate }}</th>
23+
<td mat-cell class="r-amount" *matCellDef="let item">
24+
{{ item.buyDownFeeAmount | formatNumber: '0.00' }}
25+
</td>
26+
</ng-container>
27+
28+
<ng-container matColumnDef="amortizedAmount">
29+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.heading.Amortized Amount' | translate }}</th>
30+
<td mat-cell class="r-amount" *matCellDef="let item">
31+
{{ item.amortizedAmount | formatNumber: '0.00' }}
32+
</td>
33+
</ng-container>
34+
35+
<ng-container matColumnDef="notYetAmortizedAmount">
36+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.heading.Not Yet Amortized Amount' | translate }}</th>
37+
<td mat-cell class="r-amount" *matCellDef="let item">
38+
{{ item.notYetAmortizedAmount | formatNumber: '0.00' }}
39+
</td>
40+
</ng-container>
41+
42+
<ng-container matColumnDef="adjustedAmount">
43+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.heading.Adjusted Amount' | translate }}</th>
44+
<td mat-cell class="r-amount" *matCellDef="let item">
45+
{{ item.adjustedAmount | formatNumber: '0.00' }}
46+
</td>
47+
</ng-container>
48+
49+
<ng-container matColumnDef="chargedOffAmount">
50+
<th mat-header-cell *matHeaderCellDef>{{ 'labels.heading.Charged Off Amount' | translate }}</th>
51+
<td mat-cell class="r-amount" *matCellDef="let item">
52+
{{ item.chargedOffAmount | formatNumber: '0.00' }}
53+
</td>
54+
</ng-container>
55+
56+
<tr mat-header-row *matHeaderRowDef="buyDownFeeColumns"></tr>
57+
<tr mat-row *matRowDef="let row; columns: buyDownFeeColumns"></tr>
58+
</table>
59+
</div>
60+
</div>

src/app/loans/loans-view/loan-buy-down-fees-tab/loan-buy-down-fees-tab.component.scss

Whitespace-only changes.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import {
3+
MatCell,
4+
MatCellDef,
5+
MatColumnDef,
6+
MatHeaderCell,
7+
MatHeaderCellDef,
8+
MatHeaderRow,
9+
MatHeaderRowDef,
10+
MatRow,
11+
MatRowDef,
12+
MatTable
13+
} from '@angular/material/table';
14+
import { ActivatedRoute } from '@angular/router';
15+
import { FormatNumberPipe } from '@pipes/format-number.pipe';
16+
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
17+
import { LoansService } from 'app/customApis.service';
18+
import { BuyDownFeeAmortizationDetails } from '../../models/loan-account.model';
19+
import { DateFormatPipe } from '@pipes/date-format.pipe';
20+
21+
@Component({
22+
selector: 'mifosx-loan-buy-down-fees-tab',
23+
templateUrl: './loan-buy-down-fees-tab.component.html',
24+
styleUrl: './loan-buy-down-fees-tab.component.scss',
25+
imports: [
26+
...STANDALONE_SHARED_IMPORTS,
27+
MatTable,
28+
MatColumnDef,
29+
MatHeaderCellDef,
30+
MatHeaderCell,
31+
MatCellDef,
32+
MatCell,
33+
MatHeaderRowDef,
34+
MatHeaderRow,
35+
MatRowDef,
36+
MatRow,
37+
FormatNumberPipe,
38+
DateFormatPipe
39+
]
40+
})
41+
export class LoanBuyDownFeesTabComponent implements OnInit {
42+
buyDownFeeData: BuyDownFeeAmortizationDetails[] = [];
43+
loanId: string;
44+
isLoading = true;
45+
46+
buyDownFeeColumns: string[] = [
47+
'buyDownFeeDate',
48+
'buyDownFeeAmount',
49+
'amortizedAmount',
50+
'notYetAmortizedAmount',
51+
'adjustedAmount',
52+
'chargedOffAmount'
53+
];
54+
55+
constructor(
56+
private route: ActivatedRoute,
57+
private loansService: LoansService
58+
) {}
59+
60+
ngOnInit(): void {
61+
this.getLoanId();
62+
this.loadBuyDownFees();
63+
}
64+
65+
private getLoanId(): void {
66+
if (this.route.snapshot.data && this.route.snapshot.data['loanId']) {
67+
this.loanId = this.route.snapshot.data['loanId'];
68+
return;
69+
}
70+
71+
let currentRoute = this.route;
72+
while (currentRoute) {
73+
if (currentRoute.snapshot.paramMap.has('loanId')) {
74+
this.loanId = currentRoute.snapshot.paramMap.get('loanId');
75+
return;
76+
}
77+
if (currentRoute.parent) {
78+
currentRoute = currentRoute.parent;
79+
} else {
80+
break;
81+
}
82+
}
83+
84+
console.error('Could not find loanId in route parameters');
85+
}
86+
87+
private loadBuyDownFees(): void {
88+
if (!this.loanId) {
89+
console.error('Cannot load buy down fees: loanId is undefined');
90+
this.isLoading = false;
91+
return;
92+
}
93+
94+
this.isLoading = true;
95+
this.loansService.getBuyDownFeeData(this.loanId).subscribe({
96+
next: (data: BuyDownFeeAmortizationDetails[]) => {
97+
this.buyDownFeeData = data || [];
98+
this.isLoading = false;
99+
},
100+
error: (error) => {
101+
console.error('Error loading buy down fees:', error);
102+
this.isLoading = false;
103+
}
104+
});
105+
}
106+
}

0 commit comments

Comments
 (0)