From de701543e1c75333f3de9d39bbdbb1b3200e0e83 Mon Sep 17 00:00:00 2001 From: Muskan Khedia <36980003+muskankhedia@users.noreply.github.com> Date: Sat, 13 Jun 2020 00:23:40 +0530 Subject: [PATCH] feat: add loan button (assign/change loan officer) (#867) Fixes: #248 --- .../loan-action-button-resolver.ts | 34 +++++++++ src/app/loans/loans-routing.module.ts | 7 +- .../assign-loan-officer.component.html | 42 +++++++++++ .../assign-loan-officer.component.scss | 0 .../assign-loan-officer.component.spec.ts | 25 +++++++ .../assign-loan-officer.component.ts | 75 +++++++++++++++++++ .../loan-account-actions.component.html | 1 + .../loan-account-actions.component.ts | 20 ++++- .../undo-approval/undo-approval.component.ts | 2 +- .../loans/loans-view/loans-view.component.ts | 2 +- src/app/loans/loans.module.ts | 2 + src/app/loans/loans.service.ts | 17 ++++- src/environments/environment.ts | 2 +- 13 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 src/app/loans/common-resolvers/loan-action-button-resolver.ts create mode 100644 src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.html create mode 100644 src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.scss create mode 100644 src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.spec.ts create mode 100644 src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.ts diff --git a/src/app/loans/common-resolvers/loan-action-button-resolver.ts b/src/app/loans/common-resolvers/loan-action-button-resolver.ts new file mode 100644 index 000000000..bec514d1f --- /dev/null +++ b/src/app/loans/common-resolvers/loan-action-button-resolver.ts @@ -0,0 +1,34 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { LoansService } from '../loans.service'; + +/** + * Loans notes data resolver. + */ +@Injectable() +export class LoanActionButtonResolver implements Resolve { + + /** + * @param {LoansService} LoansService Loans service. + */ + constructor(private loansService: LoansService) { } + + /** + * Returns the Loans Notes Data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const loanId = route.parent.paramMap.get('loanId'); + const loanActionButton = route.paramMap.get('action'); + // if (loanActionButton === 'assign-loan-officer') { + return this.loansService.getLoanTemplate(loanId); + // } + } + +} diff --git a/src/app/loans/loans-routing.module.ts b/src/app/loans/loans-routing.module.ts index 43d070fab..e7c6eaaa4 100644 --- a/src/app/loans/loans-routing.module.ts +++ b/src/app/loans/loans-routing.module.ts @@ -27,6 +27,7 @@ import { LoanDetailsChargesResolver } from './common-resolvers/loan-details-char import { LoanAccountActionsComponent } from './loans-view/loan-account-actions/loan-account-actions.component'; import { LoanDatatablesResolver } from './common-resolvers/loan-datatables.resolver'; import { LoanDatatableResolver } from './common-resolvers/loan-datatable.resolver'; +import { LoanActionButtonResolver } from './common-resolvers/loan-action-button-resolver'; const routes: Routes = [ { @@ -129,6 +130,9 @@ const routes: Routes = [ path: ':action', component: LoanAccountActionsComponent, data: { title: extract('Loan Account Actions'), routeParamBreadcrumb: 'action' }, + resolve: { + actionButtonData: LoanActionButtonResolver + } }, ] }] @@ -145,7 +149,8 @@ const routes: Routes = [ LoanNotesResolver, LoanDetailsChargesResolver, LoanDatatablesResolver, - LoanDatatableResolver + LoanDatatableResolver, + LoanActionButtonResolver ] }) diff --git a/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.html b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.html new file mode 100644 index 000000000..668d60efd --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.html @@ -0,0 +1,42 @@ +
+ +
+ + + +
+ + + To Loan Officer + + + {{ loanOfficer.displayName }} + + + + Loan Officer is required + + + + + Assignment Date + + + + + Assignment Date is required + + + +
+ + + + + + +
+ +
+ +
diff --git a/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.scss b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.spec.ts b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.spec.ts new file mode 100644 index 000000000..bbad4d723 --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AssignLoanOfficerComponent } from './assign-loan-officer.component'; + +describe('AssignLoanOfficerComponent', () => { + let component: AssignLoanOfficerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AssignLoanOfficerComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AssignLoanOfficerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.ts b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.ts new file mode 100644 index 000000000..3572512c8 --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component.ts @@ -0,0 +1,75 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { DatePipe } from '@angular/common'; +import { MatDialog } from '@angular/material'; +import { LoansService } from 'app/loans/loans.service'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; + +@Component({ + selector: 'mifosx-assign-loan-officer', + templateUrl: './assign-loan-officer.component.html', + styleUrls: ['./assign-loan-officer.component.scss'] +}) +export class AssignLoanOfficerComponent implements OnInit { + + @Input() dataObject: any; + /** Loan Id */ + loanId: string; + loanOfficers: any[]; + /** Minimum Date allowed. */ + minDate = new Date(2000, 0, 1); + /** Maximum Date allowed. */ + maxDate = new Date(); + /** Assign loan Officer form. */ + assignOfficerForm: FormGroup; + + /** + * @param {FormBuilder} formBuilder Form Builder. + * @param {LoansService} systemService Loan Service. + * @param {ActivatedRoute} route Activated Route. + * @param {Router} router Router for navigation. + */ + constructor(private formBuilder: FormBuilder, + private loanService: LoansService, + private route: ActivatedRoute, + private router: Router, + private datePipe: DatePipe) { + this.loanId = this.route.parent.snapshot.params['loanId']; + } + + /** + * Creates the assign officer form. + */ + ngOnInit() { + this.createassignOfficerForm(); + this.loanOfficers = this.dataObject.loanOfficerOptions; + } + + /** + * Creates the create close form. + */ + createassignOfficerForm() { + this.assignOfficerForm = this.formBuilder.group({ + 'toLoanOfficerId': ['', Validators.required], + 'assignmentDate': [new Date(), Validators.required] + }); + } + + submit() { + const assignmentDatee = this.assignOfficerForm.value.assignmentDate; + const dateFormat = 'yyyy-MM-dd'; + this.assignOfficerForm.patchValue({ + assignmentDate: this.datePipe.transform(assignmentDatee, dateFormat) + }); + const assignForm = this.assignOfficerForm.value; + assignForm.locale = 'en'; + assignForm.dateFormat = dateFormat; + assignForm.fromLoanOfficerId = this.dataObject.loanOfficerId || ''; + + this.loanService.loanActionButtons(this.loanId, assignForm, 'assignLoanOfficer') + .subscribe((response: any) => { + this.router.navigate([`../../${this.loanId}/general`], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html b/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html index 3fd270899..05ce3c613 100644 --- a/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html +++ b/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html @@ -2,5 +2,6 @@ + diff --git a/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts b/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts index 1b3bf9e1a..f963edb1a 100644 --- a/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts @@ -13,7 +13,14 @@ import { ActivatedRoute, Router } from '@angular/router'; export class LoanAccountActionsComponent { /** flag object to store possible actions and render appropriate UI to the user */ - actions: { close: boolean, undo_approval: boolean } = { close: false, undo_approval: false }; + actions: { close: boolean, + undo_approval: boolean, + assign_loan_officer: boolean } = { + close: false, + undo_approval: false, + assign_loan_officer: false }; + actionButtonData: any; + actionName: any; /** * @param router Router. @@ -21,11 +28,16 @@ export class LoanAccountActionsComponent { */ constructor(private router: Router, private route: ActivatedRoute) { + this.route.data.subscribe(( data: { actionButtonData: any }) => { + this.actionButtonData = data.actionButtonData; + }); + this.route.params.subscribe(params => { - if (params['action'].indexOf('-') > 0) { - this.actions[params['action'].replace('-', '_')] = true; + this.actionName = params['action']; + if (this.actionName === 'change-loan-officer') { + this.actionName = 'assign-loan-officer'; } - this.actions[params['action']] = true; + this.actions[this.actionName.replace(/-/g, '_')] = true; }); } diff --git a/src/app/loans/loans-view/loan-account-actions/undo-approval/undo-approval.component.ts b/src/app/loans/loans-view/loan-account-actions/undo-approval/undo-approval.component.ts index a88988d8e..a7bc9c76c 100644 --- a/src/app/loans/loans-view/loan-account-actions/undo-approval/undo-approval.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/undo-approval/undo-approval.component.ts @@ -37,7 +37,7 @@ export class UndoApprovalComponent implements OnInit { */ submit() { const loanId = this.route.parent.snapshot.params['loanId']; - this.loanService.undoLoanApproval(loanId, {'note': this.note.value}).subscribe((response: any) => { + this.loanService.loanActionButtons(loanId, {'note': this.note.value}, 'undoapproval').subscribe((response: any) => { this.router.navigate(['../general'], {relativeTo: this.route}); }); } diff --git a/src/app/loans/loans-view/loans-view.component.ts b/src/app/loans/loans-view/loans-view.component.ts index cf5e597bb..4705cca55 100644 --- a/src/app/loans/loans-view/loans-view.component.ts +++ b/src/app/loans/loans-view/loans-view.component.ts @@ -111,7 +111,7 @@ export class LoansViewComponent implements OnInit { } loanAction(button: string) { - button = button.replace(' ', '-').toLowerCase(); + button = button.replace(/\s/g, '-').toLowerCase(); this.router.navigate([button], { relativeTo: this.route }); } diff --git a/src/app/loans/loans.module.ts b/src/app/loans/loans.module.ts index 2c31972f5..ff83fd8c9 100644 --- a/src/app/loans/loans.module.ts +++ b/src/app/loans/loans.module.ts @@ -25,6 +25,7 @@ import { DatatableTabComponent } from './loans-view/datatable-tab/datatable-tab. import { MultiRowComponent } from './loans-view/datatable-tab/multi-row/multi-row.component'; import { SingleRowComponent } from './loans-view/datatable-tab/single-row/single-row.component'; import { UndoApprovalComponent } from './loans-view/loan-account-actions/undo-approval/undo-approval.component'; +import { AssignLoanOfficerComponent } from './loans-view/loan-account-actions/assign-loan-officer/assign-loan-officer.component'; /** * Loans Module @@ -50,6 +51,7 @@ import { UndoApprovalComponent } from './loans-view/loan-account-actions/undo-ap MultiRowComponent, SingleRowComponent, UndoApprovalComponent, + AssignLoanOfficerComponent, ], providers: [DatePipe], }) diff --git a/src/app/loans/loans.service.ts b/src/app/loans/loans.service.ts index 8e67fc21d..b4a24128c 100644 --- a/src/app/loans/loans.service.ts +++ b/src/app/loans/loans.service.ts @@ -26,6 +26,18 @@ export class LoansService { return this.http.get(`/loans/${loanId}/transactions/template`, { params: httpParams }); } + /** + * Returns the loan template data with specific condition + * @param loanId Loan Id + */ + getLoanTemplate(loanId: string): Observable { + const httpParams = new HttpParams() + .set('fields', 'id,loanOfficerId,loanOfficerOptions') + .set('staffInSelectedOfficeOnly', 'true') + .set('template', 'true'); + return this.http.get(`/loans/${loanId}`, { params: httpParams }); + } + /** * @param {any} loanCharge to apply on a Loan Account. * @returns {Observable} @@ -146,13 +158,12 @@ export class LoansService { } /* - * Undo Loan Approval. * @param {string} loanId Loan Id. * @param {any} data Data. * @returns {Observable} */ - undoLoanApproval(loanId: string, data: any): Observable { - const httpParams = new HttpParams().set('command', 'undoapproval'); + loanActionButtons(loanId: string, data: any, command: any): Observable { + const httpParams = new HttpParams().set('command', command); return this.http.post(`/loans/${loanId}`, data, {params: httpParams}); } diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 12859d27d..9722d2536 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -10,7 +10,7 @@ export const environment = { production: false, version: env.npm_package_version + '-dev', fineractPlatformTenantId: 'default', // For connecting to server running elsewhere update the tenant identifier - baseApiUrl: 'https://staging.mifos.io', // For connecting to server running elsewhere update the base API URL + baseApiUrl: 'https://dev.mifos.io', // For connecting to server running elsewhere update the base API URL apiProvider: '/fineract-provider/api', apiVersion: '/v1', serverUrl: '',