feat: add loan action button (approve) (#1148)
Fixes: #829 Co-authored-by: Benura Abeywardena <benuraab@gmail.com>
This commit is contained in:
co-authored by
Benura Abeywardena
parent
1587dcfe5d
commit
f618bb3cda
@@ -56,6 +56,8 @@ export class LoanActionButtonResolver implements Resolve<Object> {
|
||||
return this.loansService.getLoanActionTemplate(loanId, 'disburse');
|
||||
} else if (loanActionButton === 'loan-screen-reports') {
|
||||
return this.loansService.getLoanScreenReportsData();
|
||||
} else if (loanActionButton === 'approve') {
|
||||
return this.loansService.getLoanApprovalTemplate(loanId);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<div class="container">
|
||||
|
||||
<form [formGroup]="approveLoanForm" (ngSubmit)="submit()">
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<div fxLayout="column">
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Approved On</mat-label>
|
||||
<input matInput [min]="minDate" [matDatepicker]="approvedDatePicker" required
|
||||
formControlName="approvedOnDate">
|
||||
<mat-datepicker-toggle matSuffix [for]="approvedDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #approvedDatePicker></mat-datepicker>
|
||||
<mat-error *ngIf="approveLoanForm.controls.approvedOnDate.hasError('required')">
|
||||
Approved Date <strong>is required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Expected disbursement on</mat-label>
|
||||
<input matInput [min]="minDate" [matDatepicker]="disbursementDatePicker"
|
||||
formControlName="expectedDisbursementDate">
|
||||
<mat-datepicker-toggle matSuffix [for]="disbursementDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #disbursementDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Approved Amount</mat-label>
|
||||
<input matInput type="number" formControlName="approvedLoanAmount">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Transaction Amount</mat-label>
|
||||
<input matInput type="number" required formControlName="approvedLoanAmount" required>
|
||||
<mat-error *ngIf="approveLoanForm.controls.approvedLoanAmount.hasError('required')">
|
||||
Transaction Amount is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Note</mat-label>
|
||||
<textarea matInput formControlName="note"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../../']">Cancel</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!approveLoanForm.valid"
|
||||
*mifosxHasPermission="'APPROVE_LOAN'">Submit</button>
|
||||
</mat-card-actions>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ApproveLoanComponent } from './approve-loan.component';
|
||||
|
||||
describe('ApproveLoanComponent', () => {
|
||||
let component: ApproveLoanComponent;
|
||||
let fixture: ComponentFixture<ApproveLoanComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ApproveLoanComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ApproveLoanComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
/** Angular Imports. */
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { distinctUntilChanged } from 'rxjs/operators';
|
||||
import { DatePipe } from '@angular/common';
|
||||
|
||||
/** Custom Services. */
|
||||
import { LoansService } from 'app/loans/loans.service';
|
||||
|
||||
/**
|
||||
* Approve Loan component.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-approve-loan',
|
||||
templateUrl: './approve-loan.component.html',
|
||||
styleUrls: ['./approve-loan.component.scss']
|
||||
})
|
||||
export class ApproveLoanComponent implements OnInit {
|
||||
|
||||
/** Approve Loan form. */
|
||||
approveLoanForm: FormGroup;
|
||||
/** Loan data. */
|
||||
loanData: any = new Object();
|
||||
/** Association Data */
|
||||
associationData: any;
|
||||
/** Minimum Date allowed. */
|
||||
minDate = new Date(2000, 0, 1);
|
||||
/** Loan Id */
|
||||
loanId: any;
|
||||
|
||||
/**
|
||||
* Retrieve data from `Resolver`.
|
||||
* @param formBuilder Form Builder.
|
||||
* @param route Activated Route.
|
||||
* @param datePipe Date Pipe.
|
||||
* @param loanService Loan Service.
|
||||
* @param router Router.
|
||||
*/
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private datePipe: DatePipe,
|
||||
private loanService: LoansService,
|
||||
private router: Router) {
|
||||
this.route.data.subscribe((data: { actionButtonData: any }) => {
|
||||
this.loanData = data.actionButtonData;
|
||||
});
|
||||
this.loanId = this.route.parent.snapshot.params['loanId'];
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.setApproveLoanForm();
|
||||
this.loanService.getApproveAssociationsDetails(this.loanId).subscribe((response: any) => {
|
||||
this.associationData = response;
|
||||
this.approveLoanForm.patchValue({
|
||||
'expectedDisbursementDate': new Date(response.timeline.expectedDisbursementDate)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Approve Loan form.
|
||||
*/
|
||||
setApproveLoanForm() {
|
||||
this.approveLoanForm = this.formBuilder.group({
|
||||
'approvedOnDate': [this.loanData.approvalDate && new Date(this.loanData.approvalDate), Validators.required],
|
||||
'expectedDisbursementDate': [''],
|
||||
'approvedLoanAmount': [this.loanData.approvalAmount, Validators.required],
|
||||
'note': ['']
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits Approve form.
|
||||
*/
|
||||
submit() {
|
||||
const dateFormat = 'dd MMMM yyyy';
|
||||
const local = 'en';
|
||||
const approvedOnDate = this.approveLoanForm.value.approvedOnDate;
|
||||
const expectedDisbursementDate = this.approveLoanForm.value.expectedDisbursementDate;
|
||||
this.approveLoanForm.patchValue({
|
||||
approvedOnDate: this.datePipe.transform(approvedOnDate, dateFormat),
|
||||
expectedDisbursementDate: this.datePipe.transform(expectedDisbursementDate, dateFormat)
|
||||
});
|
||||
const approveLoanFormData = {
|
||||
... this.approveLoanForm.value,
|
||||
dateFormat,
|
||||
local
|
||||
};
|
||||
this.loanService.loanActionButtons(this.loanId, 'approve', approveLoanFormData).subscribe((response: any) => {
|
||||
this.router.navigate(['../../'], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,5 +20,6 @@
|
||||
<mifosx-add-collateral [dataObject]="actionButtonData" *ngIf="actions.add_collateral"></mifosx-add-collateral>
|
||||
<mifosx-undo-disbursal *ngIf="actions.undo_disbursal"></mifosx-undo-disbursal>
|
||||
<mifosx-loan-screen-reports [dataObject]="actionButtonData" *ngIf="actions.loan_screen_reports"></mifosx-loan-screen-reports>
|
||||
<mifosx-approve-loan *ngIf="actions.approve" ></mifosx-approve-loan>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,8 @@ export class LoanAccountActionsComponent {
|
||||
disburse: boolean,
|
||||
withdrawn_by_client: boolean,
|
||||
undo_disbursal: boolean,
|
||||
loan_screen_reports: boolean } = {
|
||||
loan_screen_reports: boolean,
|
||||
approve: boolean } = {
|
||||
close: false,
|
||||
undo_approval: false,
|
||||
write_off: false,
|
||||
@@ -52,7 +53,8 @@ export class LoanAccountActionsComponent {
|
||||
disburse: false,
|
||||
withdrawn_by_client: false,
|
||||
undo_disbursal: false,
|
||||
loan_screen_reports: false };
|
||||
loan_screen_reports: false,
|
||||
approve: false };
|
||||
|
||||
actionButtonData: any;
|
||||
actionName: any;
|
||||
|
||||
@@ -60,6 +60,7 @@ import { LoanAccountLoadDocumentsDialogComponent } from './custom-dialog/loan-ac
|
||||
import { StandingInstructionsTabComponent } from './loans-view/standing-instructions-tab/standing-instructions-tab.component';
|
||||
import { EditLoansAccountComponent } from './edit-loans-account/edit-loans-account.component';
|
||||
import { LoanScreenReportsComponent } from './loans-view/loan-account-actions/loan-screen-reports/loan-screen-reports.component';
|
||||
import { ApproveLoanComponent } from './loans-view/loan-account-actions/approve-loan/approve-loan.component';
|
||||
|
||||
/**
|
||||
* Loans Module
|
||||
@@ -117,7 +118,8 @@ import { LoanScreenReportsComponent } from './loans-view/loan-account-actions/lo
|
||||
LoanAccountLoadDocumentsDialogComponent,
|
||||
StandingInstructionsTabComponent,
|
||||
EditLoansAccountComponent,
|
||||
LoanScreenReportsComponent
|
||||
LoanScreenReportsComponent,
|
||||
ApproveLoanComponent
|
||||
],
|
||||
entryComponents: [
|
||||
LoansAccountAddCollateralDialogComponent,
|
||||
|
||||
@@ -105,6 +105,11 @@ export class LoansService {
|
||||
return this.http.get(`/loans/${loanId}`, {params: httpParams});
|
||||
}
|
||||
|
||||
getApproveAssociationsDetails(loanId: any) {
|
||||
const httpParams = new HttpParams()
|
||||
.set('associations', 'multiDisburseDetails');
|
||||
return this.http.get(`/loans/${loanId}`, { params: httpParams });
|
||||
}
|
||||
/**
|
||||
* @param loanId Loan Id
|
||||
* @returns The notes for particular loan
|
||||
@@ -342,4 +347,15 @@ export class LoansService {
|
||||
return this.http.post(`/templates/${templateId}`, {}, { params: httpParams, responseType: 'text'});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Loan Charge Aproval template.
|
||||
* @param {string} loanId Loan Id.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getLoanApprovalTemplate(loanId: string): Observable<any> {
|
||||
const httpParams = new HttpParams()
|
||||
.set('templateType', 'approval');
|
||||
return this.http.get(`/loans/${loanId}/template`, { params: httpParams });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user