Allow Loan re-amortize transaction

This commit is contained in:
Jose Alberto Hernandez
2024-03-06 12:46:04 +01:00
committed by Adam Saghy
parent a4fbde1edc
commit f52efaef44
23 changed files with 180 additions and 19 deletions
@@ -28,4 +28,5 @@
<mifosx-charge-off [dataObject]="actionButtonData" *ngIf="actions['Charge-Off']"></mifosx-charge-off>
<mifosx-undo-command [actionName]="actionName" *ngIf="actions['Undo Charge-Off']"></mifosx-undo-command>
<mifosx-asset-transfer-loan *ngIf="actions['Sell Loan'] || actions['Buy Back Loan']"></mifosx-asset-transfer-loan>
<mifosx-loan-reaging [dataObject]="actionButtonData" *ngIf="actions['Re-Age']"></mifosx-loan-reaging>
<mifosx-loan-reaging [dataObject]="actionButtonData" *ngIf="actions['Re-Age']"></mifosx-loan-reaging>
<mifosx-loan-reamortize [dataObject]="actionButtonData" *ngIf="actions['Re-Amortize']"></mifosx-loan-reamortize>
@@ -0,0 +1,26 @@
<div class="container mat-elevation-z8">
<mat-card>
<form [formGroup]="reamortizeLoanForm" (ngSubmit)="submit()">
<mat-card-content>
<div fxLayout="column">
<mat-form-field>
<mat-label>{{"labels.inputs.External Id" | translate}}</mat-label>
<input matInput formControlName="externalId">
</mat-form-field>
</div>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['../../general']">{{"labels.buttons.Cancel" |
translate}}</button>
<button mat-raised-button color="primary" [disabled]="!reamortizeLoanForm.valid"
*mifosxHasPermission="'REAMORTIZE_LOAN'">{{"labels.buttons.Submit" | translate}}</button>
</mat-card-actions>
</mat-card-content>
</form>
</mat-card>
</div>
@@ -0,0 +1,3 @@
.container {
max-width: 37rem;
}
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoanReamortizeComponent } from './loan-reamortize.component';
describe('LoanReamortizeComponent', () => {
let component: LoanReamortizeComponent;
let fixture: ComponentFixture<LoanReamortizeComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LoanReamortizeComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(LoanReamortizeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,45 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { LoansService } from 'app/loans/loans.service';
@Component({
selector: 'mifosx-loan-reamortize',
templateUrl: './loan-reamortize.component.html',
styleUrls: ['./loan-reamortize.component.scss']
})
export class LoanReamortizeComponent implements OnInit {
@Input() dataObject: any;
/** Loan Id */
loanId: string;
/** ReAmortize Loan Form */
reamortizeLoanForm: UntypedFormGroup;
constructor(private formBuilder: UntypedFormBuilder,
private route: ActivatedRoute,
private router: Router,
private loanService: LoansService) {
this.loanId = this.route.snapshot.params['loanId'];
}
ngOnInit(): void {
this.createReAmortizeLoanForm();
}
createReAmortizeLoanForm() {
this.reamortizeLoanForm = this.formBuilder.group({
'externalId': ''
});
}
submit(): void {
const data = this.reamortizeLoanForm.value;
this.loanService.submitLoanActionButton(this.loanId, data, 'reAmortize')
.subscribe((response: any) => {
this.router.navigate(['../../transactions'], { relativeTo: this.route });
});
}
}
@@ -49,6 +49,7 @@ export class LoansViewComponent implements OnInit {
loanStatus: LoanStatus;
currency: Currency;
loanReAged = false;
loanReAmortized = false;
constructor(private route: ActivatedRoute,
private router: Router,
@@ -61,11 +62,17 @@ export class LoansViewComponent implements OnInit {
this.loanDisplayArrearsDelinquency = data.loanArrearsDelinquencyConfig.value || 0;
this.loanStatus = this.loanDetailsData.status;
this.currency = this.loanDetailsData.currency;
this.loanDetailsData.transactions.some((lt: LoanTransaction) => {
if (lt.type.reAge) {
this.loanReAged = true;
}
});
if (this.loanStatus.active) {
this.loanDetailsData.transactions.forEach((lt: LoanTransaction) => {
if (!lt.manuallyReversed) {
if (lt.type.reAge) {
this.loanReAged = true;
} else if (lt.type.reAmortize) {
this.loanReAmortized = true;
}
}
});
}
});
this.loanId = this.route.snapshot.params['loanId'];
this.clientId = this.loanDetailsData.clientId;
@@ -74,7 +81,7 @@ export class LoansViewComponent implements OnInit {
ngOnInit() {
this.recalculateInterest = this.loanDetailsData.recalculateInterest || true;
this.status = this.loanDetailsData.status.value;
if (this.loanDetailsData.status.active && this.loanDetailsData.multiDisburseLoan) {
if (this.loanStatus.active && this.loanDetailsData.multiDisburseLoan) {
if (this.loanDetailsData && this.loanDetailsData.transactions) {
this.loanDetailsData.transactions.forEach((transaction: any) => {
if (transaction.type.disbursement) {
@@ -185,11 +192,25 @@ export class LoansViewComponent implements OnInit {
taskPermissionName: 'UNDO_REAGE_LOAN',
});
}
if (!this.loanReAmortized) {
this.buttonConfig.addButton({
name: 'Re-Amortize',
icon: 'calendar-alt',
taskPermissionName: 'REAMORTIZE_LOAN',
});
} else {
this.buttonConfig.addButton({
name: 'Undo Re-Amortize',
icon: 'undo',
taskPermissionName: 'UNDO_REAMORTIZE_LOAN',
});
}
}
}
loanAction(button: string) {
switch (button) {
loanAction(actionName: string) {
switch (actionName) {
case 'Recover From Guarantor':
this.recoverFromGuarantor();
break;
@@ -204,10 +225,11 @@ export class LoansViewComponent implements OnInit {
this.router.navigate(['transfer-funds/make-account-transfer'], { relativeTo: this.route, queryParams: queryParams });
break;
case 'Undo Re-Age':
this.undoReAge();
case 'Undo Re-Amortize':
this.undoReAgeOrReAmortize(actionName);
break;
default:
this.router.navigate(['actions', button], { relativeTo: this.route });
this.router.navigate(['actions', actionName], { relativeTo: this.route });
break;
}
}
@@ -239,15 +261,18 @@ export class LoansViewComponent implements OnInit {
}
}
undoReAge(): void {
undoReAgeOrReAmortize(actionName: string): void {
actionName = actionName.replace('Undo ', '');
const undoTransactionAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, {
data: { heading: this.translateService.instant('labels.heading.Undo Transaction'),
dialogContext: this.translateService.instant('labels.dialogContext.Are you sure you want undo the transaction type') + ' ReAge'
data: {
heading: this.translateService.instant('labels.heading.Undo Transaction'),
dialogContext: this.translateService.instant('labels.dialogContext.Are you sure you want undo the transaction type') + ' ' + this.translateService.instant('labels.menus.' + actionName)
}
});
undoTransactionAccountDialogRef.afterClosed().subscribe((response: any) => {
if (response.confirm) {
this.loansService.executeLoansAccountTransactionsCommand(String(this.loanId), 'undoReAge', {}).subscribe(() => {
const undoCommand = actionName === 'Re-Age' ? 'undoReAge' : 'undoReAmortize';
this.loansService.executeLoansAccountTransactionsCommand(String(this.loanId), undoCommand, {}).subscribe(() => {
this.reload();
});
}
@@ -41,6 +41,9 @@
.reage {
color: $status-reage;
}
.reamortize {
color: $status-reamortize;
}
}
}
@@ -145,6 +145,9 @@ export class TransactionsTabComponent implements OnInit {
if (this.isReAge(transaction.type)) {
return 'reage';
}
if (this.isReAmortize(transaction.type)) {
return 'reamortize';
}
return '';
}
@@ -216,6 +219,10 @@ export class TransactionsTabComponent implements OnInit {
return (transactionType.code === 'loanTransactionType.reAge');
}
private isReAmortize(transactionType: any): boolean {
return (transactionType.code === 'loanTransactionType.reAmortize');
}
private reload() {
const clientId = this.route.parent.parent.snapshot.params['clientId'];
const loanId = this.route.parent.parent.snapshot.params['loanId'];
+3 -1
View File
@@ -81,6 +81,7 @@ import { ExternalAssetTransferComponent } from './loans-view/external-asset-owne
import { TranslateModule } from '@ngx-translate/core';
import { LoanDelinquencyActionDialogComponent } from './custom-dialog/loan-delinquency-action-dialog/loan-delinquency-action-dialog.component';
import { LoanReagingComponent } from './loans-view/loan-account-actions/loan-reaging/loan-reaging.component';
import { LoanReamortizeComponent } from './loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component';
/**
* Loans Module
@@ -165,7 +166,8 @@ import { LoanReagingComponent } from './loans-view/loan-account-actions/loan-rea
ExternalAssetOwnerTabComponent,
ExternalAssetTransferComponent,
LoanDelinquencyActionDialogComponent,
LoanReagingComponent
LoanReagingComponent,
LoanReamortizeComponent
],
providers: [ ],
})
@@ -56,4 +56,5 @@ export interface LoanTransactionType {
chargeoff: boolean;
downPayment: boolean;
reAge: boolean;
reAmortize: boolean;
}