From bddf46cccdfb7fca960f3af5314133b565bad306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Alberto=20Hern=C3=A1ndez?= <44206706+josehernandezfintecheandomx@users.noreply.github.com> Date: Wed, 21 Jun 2023 12:17:47 -0600 Subject: [PATCH] Asset Externalization Owner management for Loans (#1771) Co-authored-by: Jose Alberto Hernandez --- .../accounting/accounting-routing.module.ts | 23 +++-- src/app/accounting/accounting.module.ts | 4 - .../journal-entry-transaction.resolver.ts} | 2 +- .../view-transaction.component.scss | 28 ------ .../view-transaction.component.spec.ts | 25 ----- ...al-asset-owner-active-transfer.resolver.ts | 25 +++++ ...rnal-asset-owner-journal-entry.resolver.ts | 25 +++++ .../external-asset-owner.resolver.ts | 25 +++++ src/app/loans/external-asset-owner.service.ts | 49 ++++++++++ src/app/loans/loans-routing.module.ts | 16 ++- .../external-asset-owner-tab.component.html | 81 ++++++++++++++++ .../external-asset-owner-tab.component.scss | 35 +++++++ ...external-asset-owner-tab.component.spec.ts | 25 +++++ .../external-asset-owner-tab.component.ts | 97 +++++++++++++++++++ .../asset-transfer-loan.component.html | 57 +++++++++++ .../asset-transfer-loan.component.scss | 3 + .../asset-transfer-loan.component.spec.ts | 25 +++++ .../asset-transfer-loan.component.ts | 90 +++++++++++++++++ .../loan-account-actions.component.html | 1 + .../loan-account-actions.component.ts | 8 +- .../loans-view/loan-accounts-button-config.ts | 4 + .../loans-view/loans-view.component.html | 18 +++- src/app/loans/loans.module.ts | 6 +- .../loan-product-terms-step.component.html | 2 +- ...-journal-entry-transaction.component.html} | 4 +- ...w-journal-entry-transaction.component.scss | 7 ++ ...ournal-entry-transaction.component.spec.ts | 25 +++++ ...ew-journal-entry-transaction.component.ts} | 78 ++++++++------- .../view-journal-entry.component.html | 16 +-- .../view-journal-entry.component.scss | 0 .../view-journal-entry.component.spec.ts | 0 .../view-journal-entry.component.ts | 6 +- .../cancel-dialog.component.html | 3 +- .../cancel-dialog/cancel-dialog.component.ts | 5 +- src/app/shared/shared.module.ts | 8 +- .../loan-locked/loan-locked.component.ts | 4 +- 36 files changed, 704 insertions(+), 126 deletions(-) rename src/app/accounting/{view-transaction/transaction.resolver.ts => common-resolvers/journal-entry-transaction.resolver.ts} (90%) delete mode 100644 src/app/accounting/view-transaction/view-transaction.component.scss delete mode 100644 src/app/accounting/view-transaction/view-transaction.component.spec.ts create mode 100644 src/app/loans/common-resolvers/external-asset-owner-active-transfer.resolver.ts create mode 100644 src/app/loans/common-resolvers/external-asset-owner-journal-entry.resolver.ts create mode 100644 src/app/loans/common-resolvers/external-asset-owner.resolver.ts create mode 100644 src/app/loans/external-asset-owner.service.ts create mode 100644 src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.html create mode 100644 src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.scss create mode 100644 src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.spec.ts create mode 100644 src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts create mode 100644 src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.html create mode 100644 src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.scss create mode 100644 src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.spec.ts create mode 100644 src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.ts rename src/app/{accounting/view-transaction/view-transaction.component.html => shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.html} (95%) create mode 100644 src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.scss create mode 100644 src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.spec.ts rename src/app/{accounting/view-transaction/view-transaction.component.ts => shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.ts} (64%) rename src/app/{ => shared}/accounting/view-journal-entry/view-journal-entry.component.html (79%) rename src/app/{ => shared}/accounting/view-journal-entry/view-journal-entry.component.scss (100%) rename src/app/{ => shared}/accounting/view-journal-entry/view-journal-entry.component.spec.ts (100%) rename src/app/{ => shared}/accounting/view-journal-entry/view-journal-entry.component.ts (73%) diff --git a/src/app/accounting/accounting-routing.module.ts b/src/app/accounting/accounting-routing.module.ts index c27f89281..bf3dcb695 100644 --- a/src/app/accounting/accounting-routing.module.ts +++ b/src/app/accounting/accounting-routing.module.ts @@ -15,7 +15,6 @@ import { AccountingComponent } from './accounting.component'; import { FrequentPostingsComponent } from './frequent-postings/frequent-postings.component'; import { CreateJournalEntryComponent } from './create-journal-entry/create-journal-entry.component'; import { SearchJournalEntryComponent } from './search-journal-entry/search-journal-entry.component'; -import { ViewTransactionComponent } from './view-transaction/view-transaction.component'; import { FinancialActivityMappingsComponent } from './financial-activity-mappings/financial-activity-mappings.component'; import { CreateFinancialActivityMappingComponent } from './financial-activity-mappings/create-financial-activity-mapping/create-financial-activity-mapping.component'; import { ViewFinancialActivityMappingComponent } from './financial-activity-mappings/view-financial-activity-mapping/view-financial-activity-mapping.component'; @@ -45,7 +44,6 @@ import { AccountingRulesAssociationsResolver } from './common-resolvers/accounti import { CurrenciesResolver } from './common-resolvers/currencies.resolver'; import { PaymentTypesResolver } from './common-resolvers/payment-types.resolver'; import { GlAccountsResolver } from './common-resolvers/gl-accounts.resolver'; -import { TransactionResolver } from './view-transaction/transaction.resolver'; import { FinancialActivityMappingsResolver } from './financial-activity-mappings/financial-activity-mappings.resolver'; import { FinancialActivityMappingsTemplateResolver } from './financial-activity-mappings/create-financial-activity-mapping/financial-activity-mappings-template.resolver'; import { FinancialActivityMappingResolver } from './financial-activity-mappings/view-financial-activity-mapping/financial-activity-mapping.resolver'; @@ -64,6 +62,9 @@ import { ProvisioningEntryEntriesResolver } from './provisioning-entries/view-pr import { LoanProductsResolver } from './common-resolvers/loan-products.resolver'; import { ProvisioningCategoriesResolver } from './common-resolvers/provisioning-categories.resolver'; import { ProvisioningJournalEntriesResolver } from './provisioning-entries/view-provisioning-journal-entries/provisioning-journal-entries.resolver'; +import { ViewJournalEntryTransactionComponent } from 'app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component'; +import { JournalEntryTransactionResolver } from './common-resolvers/journal-entry-transaction.resolver'; +import { ExternalAssetOwnerJournalEntryResolver } from 'app/loans/common-resolvers/external-asset-owner-journal-entry.resolver'; /** Accounting Routes */ const routes: Routes = [ @@ -116,10 +117,10 @@ const routes: Routes = [ children: [ { path: 'view/:id', - component: ViewTransactionComponent, + component: ViewJournalEntryTransactionComponent, data: { title: extract('View Transaction'), routeParamBreadcrumb: 'id' }, resolve: { - transaction: TransactionResolver + transaction: JournalEntryTransactionResolver } } ] @@ -363,10 +364,18 @@ const routes: Routes = [ children: [ { path: 'view/:id', - component: ViewTransactionComponent, + component: ViewJournalEntryTransactionComponent, data: { title: extract('View Transaction'), routeParamBreadcrumb: 'id' }, resolve: { - transaction: TransactionResolver + transaction: JournalEntryTransactionResolver + } + }, + { + path: 'view-transfer/:transferId', + component: ViewJournalEntryTransactionComponent, + data: { title: extract('View Transfer'), routeParamBreadcrumb: 'transferId' }, + resolve: { + transferJournalEntryData: ExternalAssetOwnerJournalEntryResolver } } ] @@ -388,7 +397,7 @@ const routes: Routes = [ CurrenciesResolver, PaymentTypesResolver, GlAccountsResolver, - TransactionResolver, + JournalEntryTransactionResolver, FinancialActivityMappingsResolver, FinancialActivityMappingsTemplateResolver, FinancialActivityMappingResolver, diff --git a/src/app/accounting/accounting.module.ts b/src/app/accounting/accounting.module.ts index 5a661761b..535528dd6 100644 --- a/src/app/accounting/accounting.module.ts +++ b/src/app/accounting/accounting.module.ts @@ -11,9 +11,7 @@ import { AccountingComponent } from './accounting.component'; import { FrequentPostingsComponent } from './frequent-postings/frequent-postings.component'; import { CreateJournalEntryComponent } from './create-journal-entry/create-journal-entry.component'; import { SearchJournalEntryComponent } from './search-journal-entry/search-journal-entry.component'; -import { ViewTransactionComponent } from './view-transaction/view-transaction.component'; import { RevertTransactionComponent } from './revert-transaction/revert-transaction.component'; -import { ViewJournalEntryComponent } from './view-journal-entry/view-journal-entry.component'; import { FinancialActivityMappingsComponent } from './financial-activity-mappings/financial-activity-mappings.component'; import { CreateFinancialActivityMappingComponent } from './financial-activity-mappings/create-financial-activity-mapping/create-financial-activity-mapping.component'; import { ViewFinancialActivityMappingComponent } from './financial-activity-mappings/view-financial-activity-mapping/view-financial-activity-mapping.component'; @@ -55,9 +53,7 @@ import { PipesModule } from 'app/pipes/pipes.module'; FrequentPostingsComponent, CreateJournalEntryComponent, SearchJournalEntryComponent, - ViewTransactionComponent, RevertTransactionComponent, - ViewJournalEntryComponent, FinancialActivityMappingsComponent, CreateFinancialActivityMappingComponent, ViewFinancialActivityMappingComponent, diff --git a/src/app/accounting/view-transaction/transaction.resolver.ts b/src/app/accounting/common-resolvers/journal-entry-transaction.resolver.ts similarity index 90% rename from src/app/accounting/view-transaction/transaction.resolver.ts rename to src/app/accounting/common-resolvers/journal-entry-transaction.resolver.ts index a2c67ea17..d9615ca75 100644 --- a/src/app/accounting/view-transaction/transaction.resolver.ts +++ b/src/app/accounting/common-resolvers/journal-entry-transaction.resolver.ts @@ -12,7 +12,7 @@ import { AccountingService } from '../accounting.service'; * Transaction data resolver. */ @Injectable() -export class TransactionResolver implements Resolve { +export class JournalEntryTransactionResolver implements Resolve { /** * @param {AccountingService} accountingService Accounting service. diff --git a/src/app/accounting/view-transaction/view-transaction.component.scss b/src/app/accounting/view-transaction/view-transaction.component.scss deleted file mode 100644 index 32cd172f8..000000000 --- a/src/app/accounting/view-transaction/view-transaction.component.scss +++ /dev/null @@ -1,28 +0,0 @@ -.content { - div { - line-height: 3rem; - - &.header { - font-weight: 500; - } - } -} - -.container { - max-width: 75rem; -} - -table { - width: 98%; - - .select-row:hover { - cursor: pointer; - } -} - -.action-bar { - width: 98%; - align-items: center; - padding-top: 15px; - padding-bottom: 15px; -} diff --git a/src/app/accounting/view-transaction/view-transaction.component.spec.ts b/src/app/accounting/view-transaction/view-transaction.component.spec.ts deleted file mode 100644 index bbff0d11b..000000000 --- a/src/app/accounting/view-transaction/view-transaction.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ViewTransactionComponent } from './view-transaction.component'; - -describe('ViewTransactionComponent', () => { - let component: ViewTransactionComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ ViewTransactionComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ViewTransactionComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/loans/common-resolvers/external-asset-owner-active-transfer.resolver.ts b/src/app/loans/common-resolvers/external-asset-owner-active-transfer.resolver.ts new file mode 100644 index 000000000..1db52a35a --- /dev/null +++ b/src/app/loans/common-resolvers/external-asset-owner-active-transfer.resolver.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; +import { Observable } from 'rxjs'; +import { ExternalAssetOwnerService } from '../external-asset-owner.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ExternalAssetOwnerActiveTransferResolver implements Resolve { + + /** + * @param {ExternalAssetOwnerService} externalAssetOwnerService External Asset Owner service. + */ + constructor(private externalAssetOwnerService: ExternalAssetOwnerService) { } + + /** + * Returns the Loans with Association data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const loanId = route.paramMap.get('loanId') || route.parent.paramMap.get('loanId'); + return this.externalAssetOwnerService.retrieveExternalAssetOwnerActiveTransfer(loanId); + } + +} diff --git a/src/app/loans/common-resolvers/external-asset-owner-journal-entry.resolver.ts b/src/app/loans/common-resolvers/external-asset-owner-journal-entry.resolver.ts new file mode 100644 index 000000000..bc2d887a3 --- /dev/null +++ b/src/app/loans/common-resolvers/external-asset-owner-journal-entry.resolver.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; +import { Observable, of } from 'rxjs'; +import { ExternalAssetOwnerService } from '../external-asset-owner.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ExternalAssetOwnerJournalEntryResolver implements Resolve { + + /** + * @param {ExternalAssetOwnerService} externalAssetOwnerService External Asset Owner service. + */ + constructor(private externalAssetOwnerService: ExternalAssetOwnerService) { } + + /** + * Returns the Loans with Association data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const transferId = route.paramMap.get('transferId') || route.parent.paramMap.get('transferId'); + return this.externalAssetOwnerService.retrieveExternalAssetOwnerTransferJournalEntries(transferId); + } + +} diff --git a/src/app/loans/common-resolvers/external-asset-owner.resolver.ts b/src/app/loans/common-resolvers/external-asset-owner.resolver.ts new file mode 100644 index 000000000..29f1fb6af --- /dev/null +++ b/src/app/loans/common-resolvers/external-asset-owner.resolver.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; +import { Observable } from 'rxjs'; +import { ExternalAssetOwnerService } from '../external-asset-owner.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ExternalAssetOwnerResolver implements Resolve { + + /** + * @param {ExternalAssetOwnerService} externalAssetOwnerService External Asset Owner service. + */ + constructor(private externalAssetOwnerService: ExternalAssetOwnerService) { } + + /** + * Returns the Loans with Association data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const loanId = route.paramMap.get('loanId') || route.parent.paramMap.get('loanId'); + return this.externalAssetOwnerService.retrieveExternalAssetOwnerTransfers(loanId); + } + +} diff --git a/src/app/loans/external-asset-owner.service.ts b/src/app/loans/external-asset-owner.service.ts new file mode 100644 index 000000000..a7d72dd5e --- /dev/null +++ b/src/app/loans/external-asset-owner.service.ts @@ -0,0 +1,49 @@ +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class ExternalAssetOwnerService { + + constructor(private http: HttpClient) { } + + /** + * @param {string} loanId Loan Id + * @param {string} command Command + * @param {any} data Data + * @returns {Observable} + */ + executeExternalAssetOwnerLoanCommand(loanId: string, data: any, command: string): Observable { + const httpParams = new HttpParams().set('command', command); + return this.http.post(`/external-asset-owners/transfers/loans/${loanId}`, data, { params: httpParams }); + } + + /** + * @param {string} loanId Loan Id + * @returns {Observable} + */ + retrieveExternalAssetOwnerTransfers(loanId: string): Observable { + const httpParams = new HttpParams().set('loanId', loanId); + return this.http.get(`/external-asset-owners/transfers`, { params: httpParams }); + } + + /** + * @param {string} loanId Loan Id + * @returns {Observable} + */ + retrieveExternalAssetOwnerActiveTransfer(loanId: string): Observable { + const httpParams = new HttpParams().set('loanId', loanId); + return this.http.get(`/external-asset-owners/transfers/active-transfer`, { params: httpParams }); + } + + /** + * @param {string} transferId Transfer Id + * @returns {Observable} + */ + retrieveExternalAssetOwnerTransferJournalEntries(transferId: string): Observable { + return this.http.get(`/external-asset-owners/transfers/${transferId}/journal-entries`); + } + +} diff --git a/src/app/loans/loans-routing.module.ts b/src/app/loans/loans-routing.module.ts index 7512436d6..4df9e9abe 100644 --- a/src/app/loans/loans-routing.module.ts +++ b/src/app/loans/loans-routing.module.ts @@ -57,6 +57,10 @@ import { LoanReschedulesResolver } from './common-resolvers/loan-reschedules.res import { RescheduleLoanTabComponent } from './loans-view/reschedule-loan-tab/reschedule-loan-tab.component'; import { AdjustLoanChargeComponent } from './loans-view/loan-account-actions/adjust-loan-charge/adjust-loan-charge.component'; import { LoanArrearDelinquencyResolver } from './common-resolvers/loan-arrear-delinquency.resolver'; +import { ExternalAssetOwnerTabComponent } from './loans-view/external-asset-owner-tab/external-asset-owner-tab.component'; +import { ExternalAssetOwnerResolver } from './common-resolvers/external-asset-owner.resolver'; +import { ExternalAssetOwnerActiveTransferResolver } from './common-resolvers/external-asset-owner-active-transfer.resolver'; +import { ExternalAssetOwnerJournalEntryResolver } from './common-resolvers/external-asset-owner-journal-entry.resolver'; /** Loans Route. */ const routes: Routes = [ @@ -198,6 +202,15 @@ const routes: Routes = [ component: StandingInstructionsTabComponent, data: { title: extract('Standing Instructions'), breadcrumb: 'Standing Instructions', routeParamBreadcrumb: false } }, + { + path: 'external-asset-owner', + component: ExternalAssetOwnerTabComponent, + data: { title: extract('External Asset Owner'), breadcrumb: 'External Asset Owner', routeParamBreadcrumb: false }, + resolve: { + activeTransferData: ExternalAssetOwnerActiveTransferResolver, + loanTransfersData: ExternalAssetOwnerResolver + } + }, { path: 'datatables', children: [{ @@ -349,7 +362,8 @@ const routes: Routes = [ GroupAccountsResolver, GLIMViewResolver, GSIMAccountsResolver, - GLIMLoanTemplateResolver + GLIMLoanTemplateResolver, + ExternalAssetOwnerResolver ] }) diff --git a/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.html b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.html new file mode 100644 index 000000000..04a98f301 --- /dev/null +++ b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.html @@ -0,0 +1,81 @@ +
+
+ +

External Asset Owner

+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Status +
+ + + {{ item.status | translate }} + +
+
Effective From {{ item.effectiveFrom | dateFormat }} Owner External Id + + Transfer External Id + + Settlement Date {{ item.settlementDate | dateFormat }} Purchase Price Ratio {{ item.purchasePriceRatio | number }} Actions + +
+
diff --git a/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.scss b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.scss new file mode 100644 index 000000000..ed728df88 --- /dev/null +++ b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.scss @@ -0,0 +1,35 @@ +.container { + padding-bottom: 2%; + + .transaction-buttons { + padding-bottom: 1rem; + padding-top: 1rem; + .accruals { + padding-top: 1%; + } + } + + table { + width: 100%; + + .select-row:hover { + cursor: pointer; + } + } +} + +.tab-container { + padding: 1%; + margin: 1%; +} + +.status { + color: black; +} + +.account-action-button{ + min-width: 26px; + padding: 0 0 3px 0; + margin: 0 2%; + line-height: 25px; +} diff --git a/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.spec.ts b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.spec.ts new file mode 100644 index 000000000..3e436262a --- /dev/null +++ b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExternalAssetOwnerTabComponent } from './external-asset-owner-tab.component'; + +describe('ExternalAssetOwnerTabComponent', () => { + let component: ExternalAssetOwnerTabComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ExternalAssetOwnerTabComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ExternalAssetOwnerTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts new file mode 100644 index 000000000..6de51d5d4 --- /dev/null +++ b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts @@ -0,0 +1,97 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ExternalAssetOwnerService } from 'app/loans/external-asset-owner.service'; +import { CancelDialogComponent } from 'app/shared/cancel-dialog/cancel-dialog.component'; + +@Component({ + selector: 'mifosx-external-asset-owner-tab', + templateUrl: './external-asset-owner-tab.component.html', + styleUrls: ['./external-asset-owner-tab.component.scss'] +}) +export class ExternalAssetOwnerTabComponent implements OnInit { + + loanTransfersData: any[] = []; + activeTransferData: any; + loanTransferColumns: string[] = ['status', 'effectiveFrom', 'ownerExternalId', 'transferExternalId', 'settlementDate', 'purchasePriceRatio', 'actions']; + + currentItem: any; + + constructor(private route: ActivatedRoute, + private router: Router, + private dialog: MatDialog, + private externalAssetOwnerService: ExternalAssetOwnerService + ) { + this.route.data.subscribe((data: { loanTransfersData: any, activeTransferData: any }) => { + this.loanTransfersData = data.loanTransfersData.empty ? [] : data.loanTransfersData.content; + this.activeTransferData = data.activeTransferData || {}; + }); + } + + ngOnInit(): void { + this.currentItem = null; + if (this.loanTransfersData.length > 0) { + this.currentItem = this.loanTransfersData[(this.loanTransfersData.length - 1)]; + } + } + + itemStatus(status: string): string { + return 'status-' + status.toLowerCase(); + } + + isPending(item: any): boolean { + return (item.status === 'PENDING'); + } + + canBeCancelled(): boolean { + return this.validateStatus('PENDING'); + } + + canBeSaled(): boolean { + if (this.currentItem == null) { + return true; + } + return ['', 'BUYBACK'].includes(this.currentItem.status); + } + + canBeBuyed(): boolean { + return this.validateStatus('ACTIVE'); + } + + private validateStatus(status: string): boolean { + if (this.currentItem != null) { + return (this.currentItem.status === status); + } + return false; + } + + saleLoan(): void { + this.router.navigate(['../actions/Sale Loan'], { relativeTo: this.route }); + } + + cancelSaleLoan(): void { + const deleteDataTableDialogRef = this.dialog.open(CancelDialogComponent, { + data: { cancelContext: `the Asset Transfer with the Owner External Id ${this.currentItem.owner.externalId} ` } + }); + deleteDataTableDialogRef.afterClosed().subscribe((response: any) => { + if (response.cancel) { + const payload: any = { + transferExternalId: this.currentItem.transferExternalId + }; + this.externalAssetOwnerService.executeExternalAssetOwnerLoanCommand(this.currentItem.loan.loanId, payload, 'cancel') + .subscribe((result: any) => { + console.log(result); + }); + } + }); + } + + buyBackLoan(): void { + this.router.navigate(['../actions/Buy Back Loan'], { relativeTo: this.route }); + } + + routeJournalEntry(ev: MouseEvent): void { + ev.stopPropagation(); + } + +} diff --git a/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.html b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.html new file mode 100644 index 000000000..9cd74fa67 --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.html @@ -0,0 +1,57 @@ +
+ + + +
+ + + +
+ + + Settlement Date + + + + + Settlement Date is required + + + + + Purchase Price Ratio + + + Purchase Price Ratio is required + + + + + Owner External Id + + + Owner External Id is required + + + + + Transfer External Id + + + +
+ + + + + + +
+ +
+ +
+ +
diff --git a/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.scss b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.scss new file mode 100644 index 000000000..d774f68da --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.scss @@ -0,0 +1,3 @@ +.container { + max-width: 37rem; +} diff --git a/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.spec.ts b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.spec.ts new file mode 100644 index 000000000..bdf6fbf6b --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AssetTransferLoanComponent } from './asset-transfer-loan.component'; + +describe('AssetTransferLoanComponent', () => { + let component: AssetTransferLoanComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AssetTransferLoanComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AssetTransferLoanComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.ts b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.ts new file mode 100644 index 000000000..7d1dc063d --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/asset-transfer-loan/asset-transfer-loan.component.ts @@ -0,0 +1,90 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Dates } from 'app/core/utils/dates'; +import { ExternalAssetOwnerService } from 'app/loans/external-asset-owner.service'; +import { SettingsService } from 'app/settings/settings.service'; + +@Component({ + selector: 'mifosx-asset-transfer-loan', + templateUrl: './asset-transfer-loan.component.html', + styleUrls: ['./asset-transfer-loan.component.scss'] +}) +export class AssetTransferLoanComponent implements OnInit { + + BUYBACK_COMMAND = 'buyback'; + SALE_COMMAND = 'sale'; + + command: string; + /** Loan Id */ + loanId: string; + /** Minimum Date allowed. */ + minDate = new Date(2000, 0, 1); + /** Maximum Date allowed. */ + maxDate = new Date(); + /** Sale Loan Form */ + saleLoanForm: FormGroup; + + constructor(private formBuilder: FormBuilder, + private externalAssetOwnerService: ExternalAssetOwnerService, + private route: ActivatedRoute, + private router: Router, + private dateUtils: Dates, + private settingsService: SettingsService) { + this.loanId = this.route.snapshot.params['loanId']; + const actionName = this.route.snapshot.params['action']; + this.command = (actionName === 'Sale Loan') ? this.SALE_COMMAND : this.BUYBACK_COMMAND; + } + + /** + * Creates the sale loan form + * and initialize with the required values + */ + ngOnInit() { + this.minDate = this.settingsService.businessDate; + this.maxDate = this.settingsService.maxAllowedDate; + this.createSaleLoanForm(); + } + + isBuyBack(): boolean { + return (this.command === this.BUYBACK_COMMAND); + } + + /** + * Creates the create close form. + */ + createSaleLoanForm() { + this.saleLoanForm = this.formBuilder.group({ + 'settlementDate': [this.settingsService.businessDate, Validators.required], + 'purchasePriceRatio': ['', Validators.required], + 'transferExternalId': '', + 'ownerExternalId': ['', Validators.required] + }); + + if (this.isBuyBack()) { + this.saleLoanForm.removeControl('purchasePriceRatio'); + this.saleLoanForm.removeControl('ownerExternalId'); + } + } + + submit() { + const saleLoanFormData = this.saleLoanForm.value; + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + const prevsettlementDate: Date = this.saleLoanForm.value.settlementDate; + if (saleLoanFormData.settlementDate instanceof Date) { + saleLoanFormData.settlementDate = this.dateUtils.formatDate(prevsettlementDate, dateFormat); + } + const data = { + ...saleLoanFormData, + dateFormat, + locale + }; + this.externalAssetOwnerService.executeExternalAssetOwnerLoanCommand(this.loanId, data, this.command) + .subscribe((response: any) => { + this.router.navigate(['../../external-asset-owner'], { 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 1d97a109b..4b73cd76d 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 @@ -27,3 +27,4 @@ + 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 708613585..40a018638 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 @@ -42,7 +42,9 @@ export class LoanAccountActionsComponent { 'Credit Balance Refund': boolean, 'Edit Repayment Schedule': boolean, 'Charge-Off': boolean, - 'Undo Charge-Off': boolean + 'Undo Charge-Off': boolean, + 'Sale Loan': boolean, + 'Buy Back Loan': boolean } = { 'Close': false, 'Undo Approval': false, @@ -73,7 +75,9 @@ export class LoanAccountActionsComponent { 'Credit Balance Refund': false, 'Edit Repayment Schedule': false, 'Charge-Off': false, - 'Undo Charge-Off': false + 'Undo Charge-Off': false, + 'Sale Loan': false, + 'Buy Back Loan': false }; actionButtonData: any; diff --git a/src/app/loans/loans-view/loan-accounts-button-config.ts b/src/app/loans/loans-view/loan-accounts-button-config.ts index 7f5e59516..fa5f9ac37 100644 --- a/src/app/loans/loans-view/loan-accounts-button-config.ts +++ b/src/app/loans/loans-view/loan-accounts-button-config.ts @@ -189,6 +189,10 @@ export class LoansAccountButtonConfiguration { { name: 'Recover From Guarantor', taskPermissionName: 'RECOVERGUARANTEES_LOAN', + }, + { + name: 'Sale Loan', + taskPermissionName: 'SALE_LOAN', } ]; this.optionPaymentArray = [ diff --git a/src/app/loans/loans-view/loans-view.component.html b/src/app/loans/loans-view/loans-view.component.html index b2c6c49f1..8a31e9c8d 100644 --- a/src/app/loans/loans-view/loans-view.component.html +++ b/src/app/loans/loans-view/loans-view.component.html @@ -135,7 +135,7 @@ Transactions - + Delinquency Tags @@ -171,10 +171,12 @@ Charges - - Loan Reschedules - + + + Loan Reschedules + + Loan Documents @@ -189,6 +191,12 @@ Standing Instruction + + + External Asset Owner + + Minimum - + Minimum Value must be greater than 0 diff --git a/src/app/accounting/view-transaction/view-transaction.component.html b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.html similarity index 95% rename from src/app/accounting/view-transaction/view-transaction.component.html rename to src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.html index c638a7c05..fe829b4f4 100644 --- a/src/app/accounting/view-transaction/view-transaction.component.html +++ b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.html @@ -7,7 +7,7 @@ -
+
@@ -94,7 +94,7 @@ -
+
diff --git a/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.scss b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.scss new file mode 100644 index 000000000..24edb63bb --- /dev/null +++ b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.scss @@ -0,0 +1,7 @@ +table { + width: 100%; + + .select-row:hover { + cursor: pointer; + } +} diff --git a/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.spec.ts b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.spec.ts new file mode 100644 index 000000000..773447ed5 --- /dev/null +++ b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewJournalEntryTransactionComponent } from './view-journal-entry-transaction.component'; + +describe('ViewJournalEntryTransactionComponent', () => { + let component: ViewJournalEntryTransactionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ViewJournalEntryTransactionComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewJournalEntryTransactionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/accounting/view-transaction/view-transaction.component.ts b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.ts similarity index 64% rename from src/app/accounting/view-transaction/view-transaction.component.ts rename to src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.ts index 782fe749c..4a457e214 100644 --- a/src/app/accounting/view-transaction/view-transaction.component.ts +++ b/src/app/shared/accounting/view-journal-entry-transaction/view-journal-entry-transaction.component.ts @@ -1,31 +1,23 @@ -/** Angular Imports */ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { MatDialog } from '@angular/material/dialog'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; - -/** Custom Services */ -import { AccountingService } from '../accounting.service'; - -/** Custom Components */ -import { RevertTransactionComponent } from '../revert-transaction/revert-transaction.component'; +import { Component, Input, OnInit, ViewChild } from '@angular/core'; import { ViewJournalEntryComponent } from '../view-journal-entry/view-journal-entry.component'; +import { RevertTransactionComponent } from 'app/accounting/revert-transaction/revert-transaction.component'; +import { AccountingService } from 'app/accounting/accounting.service'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatSort } from '@angular/material/sort'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatTableDataSource } from '@angular/material/table'; import { Location } from '@angular/common'; -/** - * View transaction component. - */ @Component({ - selector: 'mifosx-view-transaction', - templateUrl: './view-transaction.component.html', - styleUrls: ['./view-transaction.component.scss'] + selector: 'mifosx-view-journal-entry-transaction', + templateUrl: './view-journal-entry-transaction.component.html', + styleUrls: ['./view-journal-entry-transaction.component.scss'] }) -export class ViewTransactionComponent implements OnInit { - - // TODO: Update once language and date settings are setup +export class ViewJournalEntryTransactionComponent implements OnInit { + title: string; + journalEntriesData: any[]; /** Transaction data. */ transaction: any; /** Transaction ID. */ @@ -56,27 +48,44 @@ export class ViewTransactionComponent implements OnInit { * Retrieves the transaction data from `resolve` and sets the transaction table. */ ngOnInit() { - this.route.data.subscribe((data: { transaction: any }) => { - this.transaction = data.transaction; - this.transactionId = data.transaction.pageItems[0].transactionId; + this.route.data.subscribe((data: { title: string, transaction: any, transferJournalEntryData: any }) => { + this.title = data.title; + if (this.isViewTransaction()) { + this.transaction = data.transaction; + this.transactionId = data.transaction.pageItems[0].transactionId; + } else if (this.isViewTransfer()) { + this.journalEntriesData = data.transferJournalEntryData.journalEntryData.content; + } this.setTransaction(); }); } + isViewTransaction(): boolean { + return (this.title === 'View Transaction'); + } + + isViewTransfer(): boolean { + return (this.title === 'View Transfer'); + } + /** * Initializes the data source for transaction table with journal entries, paginator and sorter. */ setTransaction() { - this.dataSource = new MatTableDataSource(this.transaction.pageItems); + if (this.journalEntriesData != null) { + this.dataSource = new MatTableDataSource(this.journalEntriesData); + } else { + this.dataSource = new MatTableDataSource(this.transaction.pageItems); + this.dataSource.sortingDataAccessor = (transaction: any, property: any) => { + switch (property) { + case 'glAccountType': return transaction.glAccountType.value; + case 'debit': return transaction.amount; + case 'credit': return transaction.amount; + default: return transaction[property]; + } + }; + } this.dataSource.paginator = this.paginator; - this.dataSource.sortingDataAccessor = (transaction: any, property: any) => { - switch (property) { - case 'glAccountType': return transaction.glAccountType.value; - case 'debit': return transaction.amount; - case 'credit': return transaction.amount; - default: return transaction[property]; - } - }; this.dataSource.sort = this.sort; } @@ -113,5 +122,4 @@ export class ViewTransactionComponent implements OnInit { goBack(): void { this.location.back(); } - } diff --git a/src/app/accounting/view-journal-entry/view-journal-entry.component.html b/src/app/shared/accounting/view-journal-entry/view-journal-entry.component.html similarity index 79% rename from src/app/accounting/view-journal-entry/view-journal-entry.component.html rename to src/app/shared/accounting/view-journal-entry/view-journal-entry.component.html index 1984f47c1..dee517ea8 100644 --- a/src/app/accounting/view-journal-entry/view-journal-entry.component.html +++ b/src/app/shared/accounting/view-journal-entry/view-journal-entry.component.html @@ -64,41 +64,41 @@ {{ data.journalEntry.comments }} - + Payment Details - + Payment Type {{ data.journalEntry.transactionDetails.paymentDetails.paymentType.name }} - + Account Number {{ data.journalEntry.transactionDetails.paymentDetails.accountNumber }} - + Cheque Number {{ data.journalEntry.transactionDetails.paymentDetails.checkNumber }} - + Routing Code {{ data.journalEntry.transactionDetails.paymentDetails.routingCode }} - + Receipt Number {{ data.journalEntry.transactionDetails.paymentDetails.receiptNumber }} - + Bank Number {{ data.journalEntry.transactionDetails.paymentDetails.bankNumber }} - + Created by {{ data.journalEntry.createdByUserName }} diff --git a/src/app/accounting/view-journal-entry/view-journal-entry.component.scss b/src/app/shared/accounting/view-journal-entry/view-journal-entry.component.scss similarity index 100% rename from src/app/accounting/view-journal-entry/view-journal-entry.component.scss rename to src/app/shared/accounting/view-journal-entry/view-journal-entry.component.scss diff --git a/src/app/accounting/view-journal-entry/view-journal-entry.component.spec.ts b/src/app/shared/accounting/view-journal-entry/view-journal-entry.component.spec.ts similarity index 100% rename from src/app/accounting/view-journal-entry/view-journal-entry.component.spec.ts rename to src/app/shared/accounting/view-journal-entry/view-journal-entry.component.spec.ts diff --git a/src/app/accounting/view-journal-entry/view-journal-entry.component.ts b/src/app/shared/accounting/view-journal-entry/view-journal-entry.component.ts similarity index 73% rename from src/app/accounting/view-journal-entry/view-journal-entry.component.ts rename to src/app/shared/accounting/view-journal-entry/view-journal-entry.component.ts index 415fcb955..72dfbe024 100644 --- a/src/app/accounting/view-journal-entry/view-journal-entry.component.ts +++ b/src/app/shared/accounting/view-journal-entry/view-journal-entry.component.ts @@ -12,12 +12,16 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; }) export class ViewJournalEntryComponent implements OnInit { + existsPaymentDetails = false; /** * @param {MatDialogRef} dialogRef Component reference to dialog. * @param {any} data Provides journal entry. */ constructor(public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: any) { } + @Inject(MAT_DIALOG_DATA) public data: any) { + + this.existsPaymentDetails = (data.journalEntry.transactionDetails != null && data.journalEntry.transactionDetails.paymentDetails != null); + } ngOnInit() { } diff --git a/src/app/shared/cancel-dialog/cancel-dialog.component.html b/src/app/shared/cancel-dialog/cancel-dialog.component.html index a98c6c5e3..41b891196 100644 --- a/src/app/shared/cancel-dialog/cancel-dialog.component.html +++ b/src/app/shared/cancel-dialog/cancel-dialog.component.html @@ -1,6 +1,7 @@

Cancel

-

Are you sure you want to leave this page and lose all inputted data?

+

Are you sure you want to leave this page and lose all inputted data?

+

Are you sure you want to cancel {{ data.cancelContext }} ?

diff --git a/src/app/shared/cancel-dialog/cancel-dialog.component.ts b/src/app/shared/cancel-dialog/cancel-dialog.component.ts index 5d3ed0137..a8f27e3eb 100644 --- a/src/app/shared/cancel-dialog/cancel-dialog.component.ts +++ b/src/app/shared/cancel-dialog/cancel-dialog.component.ts @@ -1,6 +1,6 @@ /** Angular Imports */ import { Component, OnInit, Inject } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; /** * Cancel dialog component. @@ -15,7 +15,8 @@ export class CancelDialogComponent implements OnInit { /** * @param {MatDialogRef} dialogRef Component reference to dialog. */ - constructor(public dialogRef: MatDialogRef) { } + constructor(public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any) { } ngOnInit() { } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 485cb6f7c..4ff8b1034 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -37,6 +37,8 @@ import { DatatableSingleRowComponent } from './tabs/entity-datatable-tab/datatab import { DatatableMultiRowComponent } from './tabs/entity-datatable-tab/datatable-multi-row/datatable-multi-row.component'; import { SvgIconComponent } from './svg-icon/svg-icon.component'; import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-material-components/datetime-picker'; +import { ViewJournalEntryComponent } from './accounting/view-journal-entry/view-journal-entry.component'; +import { ViewJournalEntryTransactionComponent } from './accounting/view-journal-entry-transaction/view-journal-entry-transaction.component'; /** * Shared Module @@ -80,7 +82,9 @@ import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-mat EntityDatatableTabComponent, DatatableSingleRowComponent, DatatableMultiRowComponent, - SvgIconComponent + SvgIconComponent, + ViewJournalEntryComponent, + ViewJournalEntryTransactionComponent ], exports: [ FileUploadComponent, @@ -102,6 +106,8 @@ import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-mat EntityNotesTabComponent, EntityDocumentsTabComponent, EntityDatatableTabComponent, + ViewJournalEntryComponent, + ViewJournalEntryTransactionComponent, SvgIconComponent ] }) diff --git a/src/app/system/manage-jobs/cob-workflow/loan-locked/loan-locked.component.ts b/src/app/system/manage-jobs/cob-workflow/loan-locked/loan-locked.component.ts index b35cbf987..5936cebe7 100644 --- a/src/app/system/manage-jobs/cob-workflow/loan-locked/loan-locked.component.ts +++ b/src/app/system/manage-jobs/cob-workflow/loan-locked/loan-locked.component.ts @@ -30,7 +30,9 @@ export class LoanLockedComponent implements OnInit { /** Paginator for the table */ @ViewChild(MatPaginator, {static: false}) set paginator(value: MatPaginator) { - this.dataSource.paginator = value; + if (this.dataSource != null) { + this.dataSource.paginator = value; + } } currentPage = 0;