From 5701bd1ed009fea92e1b2937b3a6f08712ad01aa Mon Sep 17 00:00:00 2001 From: Karan Takalkar Date: Tue, 23 Jun 2020 15:30:03 +0530 Subject: [PATCH] feat: shares account actions (approve) (#890) Fixes: #889 --- .../general-tab/general-tab.component.html | 2 +- .../approve-shares-account.component.html | 39 +++++ .../approve-shares-account.component.scss | 3 + .../approve-shares-account.component.spec.ts | 25 ++++ .../approve-shares-account.component.ts | 76 ++++++++++ .../shares-account-actions.component.html | 1 + .../shares-account-actions.component.scss | 0 .../shares-account-actions.component.spec.ts | 25 ++++ .../shares-account-actions.component.ts | 23 +++ .../shares-account-view.component.ts | 11 +- .../shares-buttons.config.ts | 136 +++++++++--------- src/app/shares/shares-routing.module.ts | 12 ++ src/app/shares/shares.module.ts | 6 +- src/app/shares/shares.service.ts | 11 ++ 14 files changed, 298 insertions(+), 72 deletions(-) create mode 100644 src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.html create mode 100644 src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.scss create mode 100644 src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.spec.ts create mode 100644 src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.ts create mode 100644 src/app/shares/shares-account-actions/shares-account-actions.component.html create mode 100644 src/app/shares/shares-account-actions/shares-account-actions.component.scss create mode 100644 src/app/shares/shares-account-actions/shares-account-actions.component.spec.ts create mode 100644 src/app/shares/shares-account-actions/shares-account-actions.component.ts diff --git a/src/app/clients/clients-view/general-tab/general-tab.component.html b/src/app/clients/clients-view/general-tab/general-tab.component.html index a9a7cf91e..87e3d1336 100644 --- a/src/app/clients/clients-view/general-tab/general-tab.component.html +++ b/src/app/clients/clients-view/general-tab/general-tab.component.html @@ -302,7 +302,7 @@ Actions + + + + + + + + diff --git a/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.scss b/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.scss new file mode 100644 index 000000000..d774f68da --- /dev/null +++ b/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.scss @@ -0,0 +1,3 @@ +.container { + max-width: 37rem; +} diff --git a/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.spec.ts b/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.spec.ts new file mode 100644 index 000000000..3e787d6a3 --- /dev/null +++ b/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ApproveSharesAccountComponent } from './approve-shares-account.component'; + +describe('ApproveSharesAccountComponent', () => { + let component: ApproveSharesAccountComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ApproveSharesAccountComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ApproveSharesAccountComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.ts b/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.ts new file mode 100644 index 000000000..ee59c45ed --- /dev/null +++ b/src/app/shares/shares-account-actions/approve-shares-account/approve-shares-account.component.ts @@ -0,0 +1,76 @@ +/** Angular Imports */ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { DatePipe } from '@angular/common'; +import { ActivatedRoute, Router } from '@angular/router'; + +/** Custom Services */ +import { SharesService } from 'app/shares/shares.service'; + +/** + * Approve Shares Account Component + */ +@Component({ + selector: 'mifosx-approve-shares-account', + templateUrl: './approve-shares-account.component.html', + styleUrls: ['./approve-shares-account.component.scss'] +}) +export class ApproveSharesAccountComponent implements OnInit { + + /** Minimum date allowed. */ + minDate = new Date(2000, 0, 1); + /** Maximum date allowed. */ + maxDate = new Date(); + /** Approve Share Account form. */ + approveSharesAccountForm: FormGroup; + /** Shares Account Id */ + accountId: any; + + constructor(private formBuilder: FormBuilder, + private sharesService: SharesService, + private datePipe: DatePipe, + private route: ActivatedRoute, + private router: Router) { + this.accountId = this.route.parent.parent.snapshot.params['shareAccountId']; + } + + /** + * Creates the approve shares form. + */ + ngOnInit() { + this.createApproveSharesAccountForm(); + } + + /** + * Creates the approve shares account form. + */ + createApproveSharesAccountForm() { + this.approveSharesAccountForm = this.formBuilder.group({ + 'approvedDate': ['', Validators.required], + 'note': [''] + }); + } + + /** + * Submits the form and approves the share account, + * if successful redirects to the share account. + */ + submit() { + // TODO: Update once language and date settings are setup + const locale = 'en'; + const dateFormat = 'dd MMMM yyyy'; + const prevApprovedDate: Date = this.approveSharesAccountForm.value.approvedDate; + this.approveSharesAccountForm.patchValue({ + approvedDate: this.datePipe.transform(prevApprovedDate, dateFormat), + }); + const data = { + ...this.approveSharesAccountForm.value, + dateFormat, + locale + }; + this.sharesService.executeSharesAccountCommand(this.accountId, 'approve', data).subscribe(() => { + this.router.navigate(['../../'], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/shares/shares-account-actions/shares-account-actions.component.html b/src/app/shares/shares-account-actions/shares-account-actions.component.html new file mode 100644 index 000000000..6eba66510 --- /dev/null +++ b/src/app/shares/shares-account-actions/shares-account-actions.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/shares/shares-account-actions/shares-account-actions.component.scss b/src/app/shares/shares-account-actions/shares-account-actions.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shares/shares-account-actions/shares-account-actions.component.spec.ts b/src/app/shares/shares-account-actions/shares-account-actions.component.spec.ts new file mode 100644 index 000000000..73591877f --- /dev/null +++ b/src/app/shares/shares-account-actions/shares-account-actions.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SharesAccountActionsComponent } from './shares-account-actions.component'; + +describe('SharesAccountActionsComponent', () => { + let component: SharesAccountActionsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SharesAccountActionsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SharesAccountActionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shares/shares-account-actions/shares-account-actions.component.ts b/src/app/shares/shares-account-actions/shares-account-actions.component.ts new file mode 100644 index 000000000..015140fc1 --- /dev/null +++ b/src/app/shares/shares-account-actions/shares-account-actions.component.ts @@ -0,0 +1,23 @@ +/** Angular Imports */ +import { Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +/** + * Shares Account Actions Component + */ +@Component({ + selector: 'mifosx-shares-account-actions', + templateUrl: './shares-account-actions.component.html', + styleUrls: ['./shares-account-actions.component.scss'] +}) +export class SharesAccountActionsComponent { + + /** Flag object to store possible actions and render appropriate UI to the user */ + actions: { Approve: boolean } = { Approve: false }; + + constructor(private route: ActivatedRoute) { + const name = this.route.snapshot.params['name']; + this.actions[name] = true; + } + +} diff --git a/src/app/shares/shares-account-view/shares-account-view.component.ts b/src/app/shares/shares-account-view/shares-account-view.component.ts index d85f20d5a..c7499cdf7 100644 --- a/src/app/shares/shares-account-view/shares-account-view.component.ts +++ b/src/app/shares/shares-account-view/shares-account-view.component.ts @@ -67,11 +67,18 @@ export class SharesAccountViewComponent implements OnInit { } } + /** + * Performs button action + * @param {string} name Action name + */ doAction(name: string) { switch (name) { case 'Modify Application': - this.router.navigate(['edit-shares-account'], { relativeTo: this.route }); - break; + this.router.navigate(['edit-shares-account'], { relativeTo: this.route }); + break; + case 'Approve': + this.router.navigate(['actions/Approve'], { relativeTo: this.route }); + break; } } diff --git a/src/app/shares/shares-account-view/shares-buttons.config.ts b/src/app/shares/shares-account-view/shares-buttons.config.ts index 7113ab0eb..aefb127e9 100644 --- a/src/app/shares/shares-account-view/shares-buttons.config.ts +++ b/src/app/shares/shares-account-view/shares-buttons.config.ts @@ -28,57 +28,57 @@ export class SharesButtonsConfiguration { setButtons(status: string) { switch (status) { case 'Active': - this.buttonsArray = [ - { - name: 'Apply Additional Shares', - icon: 'fa fa-arrow-right', - taskPermissionName: 'APPLYADDITIONAL_SHAREACCOUNT' - }, - { - name: 'Approve Additional Shares', - icon: 'fa fa-arrow-right', - taskPermissionName: 'APPROVEADDITIONAL_SHAREACCOUNT' - }, - { - name: 'Reject Additional Shares', - icon: 'fa fa-arrow-right', - taskPermissionName: 'REJECTADDITIONAL_SHAREACCOUNT' - }, - { - name: 'Redeem Shares', - icon: 'fa fa-arrow-left', - taskPermissionName: 'WITHDRAW_SAVINGSACCOUNT' - } - ]; - break; + this.buttonsArray = [ + { + name: 'Apply Additional Shares', + icon: 'fa fa-arrow-right', + taskPermissionName: 'APPLYADDITIONAL_SHAREACCOUNT' + }, + { + name: 'Approve Additional Shares', + icon: 'fa fa-arrow-right', + taskPermissionName: 'APPROVEADDITIONAL_SHAREACCOUNT' + }, + { + name: 'Reject Additional Shares', + icon: 'fa fa-arrow-right', + taskPermissionName: 'REJECTADDITIONAL_SHAREACCOUNT' + }, + { + name: 'Redeem Shares', + icon: 'fa fa-arrow-left', + taskPermissionName: 'WITHDRAW_SAVINGSACCOUNT' + } + ]; + break; case 'Submitted and pending approval': - this.buttonsArray = [ - { - name: 'Modify Application', - icon: 'fa fa-pencil ', - taskPermissionName: 'UPDATE_SHAREACCOUNT' - }, - { - name: 'Approve', - icon: 'fa fa-check', - taskPermissionName: 'APPROVE_SHAREACCOUNT' - } - ]; - break; + this.buttonsArray = [ + { + name: 'Modify Application', + icon: 'fa fa-pencil ', + taskPermissionName: 'UPDATE_SHAREACCOUNT' + }, + { + name: 'Approve', + icon: 'fa fa-check', + taskPermissionName: 'APPROVE_SHAREACCOUNT' + } + ]; + break; case 'Approved': - this.buttonsArray = [ - { - name: 'Undo Approval', - icon: 'fa fa-undo', - taskPermissionName: 'APPROVALUNDO_SHAREACCOUNT' - }, - { - name: 'Activate', - icon: 'fa fa-check', - taskPermissionName: 'ACTIVATE_SHAREACCOUNT' - } - ]; - break; + this.buttonsArray = [ + { + name: 'Undo Approval', + icon: 'fa fa-undo', + taskPermissionName: 'APPROVALUNDO_SHAREACCOUNT' + }, + { + name: 'Activate', + icon: 'fa fa-check', + taskPermissionName: 'ACTIVATE_SHAREACCOUNT' + } + ]; + break; default: this.buttonsArray = []; } @@ -86,26 +86,26 @@ export class SharesButtonsConfiguration { setOptions(status: string) { switch (status) { - case 'Active': - this.optionArray = [ - { - name: 'Close', - taskPermissionName: 'CLOSE_SHAREACCOUNT' - } - ]; - break; + case 'Active': + this.optionArray = [ + { + name: 'Close', + taskPermissionName: 'CLOSE_SHAREACCOUNT' + } + ]; + break; case 'Submitted and pending approval': - this.optionArray = [ - { - name: 'Reject', - taskPermissionName: 'REJECT_SHAREACCOUNT' - }, - { - name: 'Delete', - taskPermissionName: 'DELETE_SHAREACCOUNT' - } - ]; - break; + this.optionArray = [ + { + name: 'Reject', + taskPermissionName: 'REJECT_SHAREACCOUNT' + }, + { + name: 'Delete', + taskPermissionName: 'DELETE_SHAREACCOUNT' + } + ]; + break; case 'Approved': default: this.optionArray = []; diff --git a/src/app/shares/shares-routing.module.ts b/src/app/shares/shares-routing.module.ts index c0b8e90db..1a4c1668c 100644 --- a/src/app/shares/shares-routing.module.ts +++ b/src/app/shares/shares-routing.module.ts @@ -12,6 +12,7 @@ import { ChargesTabComponent } from './shares-account-view/charges-tab/charges-t import { DividendsTabComponent } from './shares-account-view/dividends-tab/dividends-tab.component'; import { CreateSharesAccountComponent } from './create-shares-account/create-shares-account.component'; import { EditSharesAccountComponent } from './edit-shares-account/edit-shares-account.component'; +import { SharesAccountActionsComponent } from './shares-account-actions/shares-account-actions.component'; /** Custom Resolvers */ import { SharesAccountViewResolver } from './common-resolvers/share-account-view.resolver'; @@ -66,6 +67,17 @@ const routes: Routes = [ resolve: { sharesAccountAndTemplate: SharesAccountAndTemplateResolver } + }, + { + path: 'actions', + data: { title: extract('Shares Account Actions'), breadcrumb: 'Actions', routeParamBreadcrumb: false }, + children: [ + { + path: ':name', + data: { routeParamBreadcrumb: 'name' }, + component: SharesAccountActionsComponent + } + ] } ] }, diff --git a/src/app/shares/shares.module.ts b/src/app/shares/shares.module.ts index 5500e4e6c..94f8f7e17 100644 --- a/src/app/shares/shares.module.ts +++ b/src/app/shares/shares.module.ts @@ -17,6 +17,8 @@ import { SharesAccountTermsStepComponent } from './shares-account-stepper/shares import { SharesAccountChargesStepComponent } from './shares-account-stepper/shares-account-charges-step/shares-account-charges-step.component'; import { SharesAccountPreviewStepComponent } from './shares-account-stepper/shares-account-preview-step/shares-account-preview-step.component'; import { EditSharesAccountComponent } from './edit-shares-account/edit-shares-account.component'; +import { SharesAccountActionsComponent } from './shares-account-actions/shares-account-actions.component'; +import { ApproveSharesAccountComponent } from './shares-account-actions/approve-shares-account/approve-shares-account.component'; /** * Shares Module @@ -40,7 +42,9 @@ import { EditSharesAccountComponent } from './edit-shares-account/edit-shares-ac SharesAccountTermsStepComponent, SharesAccountChargesStepComponent, SharesAccountPreviewStepComponent, - EditSharesAccountComponent + EditSharesAccountComponent, + SharesAccountActionsComponent, + ApproveSharesAccountComponent ], providers: [DatePipe] }) diff --git a/src/app/shares/shares.service.ts b/src/app/shares/shares.service.ts index 9dd9433a0..370298cdb 100644 --- a/src/app/shares/shares.service.ts +++ b/src/app/shares/shares.service.ts @@ -50,4 +50,15 @@ export class SharesService { return this.http.put(`/accounts/share/${accountId}`, sharesAccount); } + /** + * @param {string} accountId Shares Account Id + * @param {string} command Command + * @param {any} data Data + * @returns {Observable} Shares data. + */ + executeSharesAccountCommand(accountId: string, command: string, data: any): Observable { + const httpParams = new HttpParams().set('command', command); + return this.http.post(`/accounts/share/${accountId}`, data, { params: httpParams }); + } + }