diff --git a/src/app/shares/common-resolvers/share-account-and-template.resolver.ts b/src/app/shares/common-resolvers/share-account-and-template.resolver.ts new file mode 100644 index 000000000..efc9cd6ee --- /dev/null +++ b/src/app/shares/common-resolvers/share-account-and-template.resolver.ts @@ -0,0 +1,32 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { SharesService } from '../shares.service'; + +/** + * Shares Account data and template resolver. + */ +@Injectable() +export class SharesAccountAndTemplateResolver implements Resolve { + + /** + * @param {SharesService} SharesService Shares service. + */ + constructor(private sharesService: SharesService) { } + + /** + * Returns the Shares Account data and template. + * @param {ActivatedRouteSnapshot} route Route Snapshot + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const shareAccountId = route.paramMap.get('shareAccountId'); + return this.sharesService.getSharesAccountData(shareAccountId, true); + } + +} diff --git a/src/app/shares/common-resolvers/share-account-view.resolver.ts b/src/app/shares/common-resolvers/share-account-view.resolver.ts index 67021b64a..802fd39b6 100644 --- a/src/app/shares/common-resolvers/share-account-view.resolver.ts +++ b/src/app/shares/common-resolvers/share-account-view.resolver.ts @@ -26,7 +26,7 @@ export class SharesAccountViewResolver implements Resolve { */ resolve(route: ActivatedRouteSnapshot): Observable { const shareAccountId = route.paramMap.get('shareAccountId'); - return this.sharesService.getSharesAccountData(shareAccountId); + return this.sharesService.getSharesAccountData(shareAccountId, false); } } diff --git a/src/app/shares/edit-shares-account/edit-shares-account.component.html b/src/app/shares/edit-shares-account/edit-shares-account.component.html new file mode 100644 index 000000000..dee1f3272 --- /dev/null +++ b/src/app/shares/edit-shares-account/edit-shares-account.component.html @@ -0,0 +1,78 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + DETAILS + + + + + + + + + TERMS + + + + + + + + + CHARGES + + + + + + + + + PREVIEW + + + + + + + + +
diff --git a/src/app/shares/edit-shares-account/edit-shares-account.component.scss b/src/app/shares/edit-shares-account/edit-shares-account.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shares/edit-shares-account/edit-shares-account.component.spec.ts b/src/app/shares/edit-shares-account/edit-shares-account.component.spec.ts new file mode 100644 index 000000000..56de1233d --- /dev/null +++ b/src/app/shares/edit-shares-account/edit-shares-account.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditSharesAccountComponent } from './edit-shares-account.component'; + +describe('EditSharesAccountComponent', () => { + let component: EditSharesAccountComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EditSharesAccountComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditSharesAccountComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shares/edit-shares-account/edit-shares-account.component.ts b/src/app/shares/edit-shares-account/edit-shares-account.component.ts new file mode 100644 index 000000000..db291da99 --- /dev/null +++ b/src/app/shares/edit-shares-account/edit-shares-account.component.ts @@ -0,0 +1,122 @@ +/** Angular Imports */ +import { Component, ViewChild } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { DatePipe } from '@angular/common'; + +/** Custom Components */ +import { SharesAccountDetailsStepComponent } from '../shares-account-stepper/shares-account-details-step/shares-account-details-step.component'; +import { SharesAccountTermsStepComponent } from '../shares-account-stepper/shares-account-terms-step/shares-account-terms-step.component'; +import { SharesAccountChargesStepComponent } from '../shares-account-stepper/shares-account-charges-step/shares-account-charges-step.component'; + +/** Custom Services */ +import { SharesService } from '../shares.service'; + +/** + * Edit Shares Account Component + */ +@Component({ + selector: 'mifosx-edit-shares-account', + templateUrl: './edit-shares-account.component.html', + styleUrls: ['./edit-shares-account.component.scss'] +}) +export class EditSharesAccountComponent { + + /** Shares Account and Template */ + sharesAccountAndTemplate: any; + /** Shares Account Product Template */ + sharesAccountProductTemplate: any; + + /** Shares Account Details Step */ + @ViewChild(SharesAccountDetailsStepComponent) sharesAccountDetailsStep: SharesAccountDetailsStepComponent; + /** Shares Account Terms Step */ + @ViewChild(SharesAccountTermsStepComponent) sharesAccountTermsStep: SharesAccountTermsStepComponent; + /** Shares Account Charges Step */ + @ViewChild(SharesAccountChargesStepComponent) sharesAccountChargesStep: SharesAccountChargesStepComponent; + + /** + * Fetches shares account template from `resolve` + * @param {ActivatedRoute} route Activated Route + * @param {Router} router Router + * @param {DatePipe} datePipe Date Pipe + * @param {SharesService} sharesService Shares Service + */ + constructor(private route: ActivatedRoute, + private router: Router, + private datePipe: DatePipe, + private sharesService: SharesService) { + this.route.data.subscribe((data: { sharesAccountAndTemplate: any }) => { + this.sharesAccountAndTemplate = data.sharesAccountAndTemplate; + }); + } + + /** + * Sets shares account product template. + * @param {any} $event API response + */ + setTemplate($event: any) { + this.sharesAccountProductTemplate = $event; + } + + /** + * Retrieves shares account details form. + */ + get sharesAccountDetailsForm() { + return this.sharesAccountDetailsStep.sharesAccountDetailsForm; + } + + /** + * Retrieves shares account terms form. + */ + get sharesAccountTermsForm() { + return this.sharesAccountTermsStep.sharesAccountTermsForm; + } + + /** + * Checks validity and pristinity of overall shares account form . + */ + get sharesAccountFormValidAndNotPristine() { + return ( + this.sharesAccountDetailsForm.valid && + this.sharesAccountTermsForm.valid && + ( + !this.sharesAccountDetailsForm.pristine || + !this.sharesAccountTermsForm.pristine || + !this.sharesAccountChargesStep.pristine + ) + ); + } + + /** + * Retrieves shares account object. + */ + get sharesAccount() { + return { + ...this.sharesAccountDetailsStep.sharesAccountDetails, + ...this.sharesAccountTermsStep.sharesAccountTerms, + ...this.sharesAccountChargesStep.sharesAccountCharges + }; + } + + /** + * Creates a new share account. + */ + submit() { + // TODO: Update once language and date settings are setup + const locale = 'en'; + const dateFormat = 'dd MMMM yyyy'; + const sharesAccount = { + ...this.sharesAccount, + clientId: this.sharesAccountAndTemplate.clientId, + charges: this.sharesAccount.charges.map((charge: any) => ({ chargeId: charge.chargeId, amount: charge.amount })), + applicationDate: this.datePipe.transform(this.sharesAccount.applicationDate, dateFormat), + submittedDate: this.datePipe.transform(this.sharesAccount.submittedDate, dateFormat), + unitPrice: this.sharesAccountTermsForm.get('unitPrice').value, + dateFormat, + locale + }; + this.sharesService.updateSharesAccount(this.sharesAccountAndTemplate.id , sharesAccount).subscribe((response: any) => { + this.router.navigate(['../'], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/shares/shares-account-stepper/shares-account-charges-step/shares-account-charges-step.component.ts b/src/app/shares/shares-account-stepper/shares-account-charges-step/shares-account-charges-step.component.ts index fb4366147..099713553 100644 --- a/src/app/shares/shares-account-stepper/shares-account-charges-step/shares-account-charges-step.component.ts +++ b/src/app/shares/shares-account-stepper/shares-account-charges-step/shares-account-charges-step.component.ts @@ -1,5 +1,5 @@ /** Angular Imports */ -import { Component, OnInit, OnChanges, Input } from '@angular/core'; +import { Component, OnInit, Input } from '@angular/core'; import { MatDialog } from '@angular/material'; import { FormControl } from '@angular/forms'; @@ -19,7 +19,7 @@ import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base'; templateUrl: './shares-account-charges-step.component.html', styleUrls: ['./shares-account-charges-step.component.scss'] }) -export class SharesAccountChargesStepComponent implements OnInit, OnChanges { +export class SharesAccountChargesStepComponent implements OnInit { /** Shares Account Product Template */ @Input() sharesAccountProductTemplate: any; @@ -32,6 +32,10 @@ export class SharesAccountChargesStepComponent implements OnInit, OnChanges { chargeData: any; /** Charges Data Source */ chargesDataSource: {}[]; + /** Component is pristine if there has been no changes by user interaction */ + pristine = true; + /** For Edit Shares Account Form */ + isChargesPatched = false; /** Display columns for charges table */ displayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType', 'action']; @@ -41,16 +45,20 @@ export class SharesAccountChargesStepComponent implements OnInit, OnChanges { constructor(public dialog: MatDialog) {} ngOnInit() { + this.chargesDataSource = []; this.chargeData = this.sharesAccountTemplate.chargeOptions.map((charge: any) => { charge.chargeId = charge.id; delete charge.id; return charge; }); - this.currencyCode.valueChanges.subscribe(() => this.chargesDataSource = []); - } - - ngOnChanges() { - this.chargesDataSource = this.sharesAccountProductTemplate ? (this.sharesAccountProductTemplate.charges || []) : []; + this.currencyCode.valueChanges.subscribe(() => { + if (!this.isChargesPatched && this.sharesAccountTemplate.charges) { + this.chargesDataSource = this.sharesAccountTemplate.charges; + this.isChargesPatched = true; + } else { + this.chargesDataSource = []; + } + }); } /** @@ -60,6 +68,7 @@ export class SharesAccountChargesStepComponent implements OnInit, OnChanges { addCharge(charge: any) { this.chargesDataSource = this.chargesDataSource.concat([charge.value]); charge.value = ''; + this.pristine = false; } /** @@ -89,6 +98,7 @@ export class SharesAccountChargesStepComponent implements OnInit, OnChanges { this.chargesDataSource = this.chargesDataSource.concat([]); } }); + this.pristine = false; } /** @@ -105,6 +115,7 @@ export class SharesAccountChargesStepComponent implements OnInit, OnChanges { this.chargesDataSource = this.chargesDataSource.concat([]); } }); + this.pristine = false; } /** diff --git a/src/app/shares/shares-account-stepper/shares-account-details-step/shares-account-details-step.component.ts b/src/app/shares/shares-account-stepper/shares-account-details-step/shares-account-details-step.component.ts index 042600fbf..fd3e11d29 100644 --- a/src/app/shares/shares-account-stepper/shares-account-details-step/shares-account-details-step.component.ts +++ b/src/app/shares/shares-account-stepper/shares-account-details-step/shares-account-details-step.component.ts @@ -41,8 +41,17 @@ export class SharesAccountDetailsStepComponent implements OnInit { } ngOnInit() { - this.productData = this.sharesAccountTemplate.productOptions; this.buildDependencies(); + if (this.sharesAccountTemplate) { + this.productData = this.sharesAccountTemplate.productOptions; + if (this.sharesAccountTemplate.productId) { + this.sharesAccountDetailsForm.patchValue({ + 'productId': this.sharesAccountTemplate.productId, + 'submittedDate': this.sharesAccountTemplate.timeline.submittedOnDate && new Date(this.sharesAccountTemplate.timeline.submittedOnDate), + 'externalId': this.sharesAccountTemplate.externalId + }); + } + } } /** diff --git a/src/app/shares/shares-account-stepper/shares-account-preview-step/shares-account-preview-step.component.html b/src/app/shares/shares-account-stepper/shares-account-preview-step/shares-account-preview-step.component.html index c6d03cf9b..7d8c87adc 100644 --- a/src/app/shares/shares-account-stepper/shares-account-preview-step/shares-account-preview-step.component.html +++ b/src/app/shares/shares-account-stepper/shares-account-preview-step/shares-account-preview-step.component.html @@ -123,7 +123,7 @@    Previous - 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 621bab13e..d85f20d5a 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 @@ -1,6 +1,6 @@ /** Angular Imports */ import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; /** Custom Buttons Configuration */ import { SharesButtonsConfiguration } from './shares-buttons.config'; @@ -24,7 +24,8 @@ export class SharesAccountViewComponent implements OnInit { * Fetches shares account data from `resolve` * @param {ActivatedRoute} route Activated Route */ - constructor(private route: ActivatedRoute) { + constructor(private route: ActivatedRoute, + private router: Router) { this.route.data.subscribe((data: { sharesAccountData: any }) => { this.sharesAccountData = data.sharesAccountData; }); @@ -66,4 +67,12 @@ export class SharesAccountViewComponent implements OnInit { } } + doAction(name: string) { + switch (name) { + case 'Modify Application': + this.router.navigate(['edit-shares-account'], { 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 a20faa70f..7113ab0eb 100644 --- a/src/app/shares/shares-account-view/shares-buttons.config.ts +++ b/src/app/shares/shares-account-view/shares-buttons.config.ts @@ -4,14 +4,12 @@ export class SharesButtonsConfiguration { optionArray: { name: string, taskPermissionName: string, - action?: Function }[]; buttonsArray: { name: string, icon: string, taskPermissionName: string, - action?: Function }[]; constructor(status: string) { diff --git a/src/app/shares/shares-routing.module.ts b/src/app/shares/shares-routing.module.ts index 8c5e2f03a..c0b8e90db 100644 --- a/src/app/shares/shares-routing.module.ts +++ b/src/app/shares/shares-routing.module.ts @@ -11,10 +11,12 @@ import { TransactionsTabComponent } from './shares-account-view/transactions-tab import { ChargesTabComponent } from './shares-account-view/charges-tab/charges-tab.component'; 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'; /** Custom Resolvers */ import { SharesAccountViewResolver } from './common-resolvers/share-account-view.resolver'; import { SharesAccountTemplateResolver } from './common-resolvers/shares-account-template.resolver'; +import { SharesAccountAndTemplateResolver } from './common-resolvers/share-account-and-template.resolver'; const routes: Routes = [ { @@ -32,28 +34,41 @@ const routes: Routes = [ { path: ':shareAccountId', data: { title: extract('Shares Account View'), routeParamBreadcrumb: 'shareAccountId' }, - component: SharesAccountViewComponent, - resolve: { - sharesAccountData: SharesAccountViewResolver - }, children: [ { - path: 'transactions', - component: TransactionsTabComponent, - data: { title: extract('Shares Account Transactions'), breadcrumb: 'Transactions', routeParamBreadcrumb: false } + path: '', + component: SharesAccountViewComponent, + resolve: { + sharesAccountData: SharesAccountViewResolver + }, + children: [ + { + path: 'transactions', + component: TransactionsTabComponent, + data: { title: extract('Shares Account Transactions'), breadcrumb: 'Transactions', routeParamBreadcrumb: false } + }, + { + path: 'charges', + component: ChargesTabComponent, + data: { title: extract('Shares Account Charges'), breadcrumb: 'Charges', routeParamBreadcrumb: false } + }, + { + path: 'dividends', + component: DividendsTabComponent, + data: { title: extract('Shares Account Dividends'), breadcrumb: 'Dividends', routeParamBreadcrumb: false } + } + ] }, { - path: 'charges', - component: ChargesTabComponent, - data: { title: extract('Shares Account Charges'), breadcrumb: 'Charges', routeParamBreadcrumb: false } - }, - { - path: 'dividends', - component: DividendsTabComponent, - data: { title: extract('Shares Account Dividends'), breadcrumb: 'Dividends', routeParamBreadcrumb: false } + path: 'edit-shares-account', + data: { title: extract('Edit Shares Account'), breadcrumb: 'Edit', routeParamBreadcrumb: false }, + component: EditSharesAccountComponent, + resolve: { + sharesAccountAndTemplate: SharesAccountAndTemplateResolver + } } ] - } + }, ] } ]; @@ -63,7 +78,8 @@ const routes: Routes = [ exports: [RouterModule], providers: [ SharesAccountViewResolver, - SharesAccountTemplateResolver + SharesAccountTemplateResolver, + SharesAccountAndTemplateResolver ] }) export class SharesRoutingModule { } diff --git a/src/app/shares/shares.module.ts b/src/app/shares/shares.module.ts index 06928e4a3..5500e4e6c 100644 --- a/src/app/shares/shares.module.ts +++ b/src/app/shares/shares.module.ts @@ -16,6 +16,7 @@ import { SharesAccountDetailsStepComponent } from './shares-account-stepper/shar import { SharesAccountTermsStepComponent } from './shares-account-stepper/shares-account-terms-step/shares-account-terms-step.component'; 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'; /** * Shares Module @@ -38,7 +39,8 @@ import { SharesAccountPreviewStepComponent } from './shares-account-stepper/shar SharesAccountDetailsStepComponent, SharesAccountTermsStepComponent, SharesAccountChargesStepComponent, - SharesAccountPreviewStepComponent + SharesAccountPreviewStepComponent, + EditSharesAccountComponent ], providers: [DatePipe] }) diff --git a/src/app/shares/shares.service.ts b/src/app/shares/shares.service.ts index 26ec9d258..9dd9433a0 100644 --- a/src/app/shares/shares.service.ts +++ b/src/app/shares/shares.service.ts @@ -19,8 +19,9 @@ export class SharesService { * @param accountId Shares Account Id of account to get data for. * @returns {Observable} Shares data. */ - getSharesAccountData(accountId: string): Observable { - return this.http.get(`/accounts/share/${accountId}`); + getSharesAccountData(accountId: string, template: boolean): Observable { + const httpParams = new HttpParams().set('template', template.toString()); + return this.http.get(`/accounts/share/${accountId}`, { params: httpParams }); } /** @@ -41,4 +42,12 @@ export class SharesService { return this.http.post('/accounts/share', sharesAccount); } + /** + * @param {any} sharesAccount Shares Account + * @returns {Observable} + */ + updateSharesAccount(accountId: string, sharesAccount: any): Observable { + return this.http.put(`/accounts/share/${accountId}`, sharesAccount); + } + }