diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 6ab186a1f..15108fce3 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -4,7 +4,7 @@ import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from '@angular/common import { RouteReuseStrategy, RouterModule } from '@angular/router'; /** Translation Imports */ -import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateModule } from '@ngx-translate/core'; /** Custom Services */ import { AuthenticationService } from './authentication/authentication.service'; @@ -28,8 +28,6 @@ import { RouteReusableStrategy } from './route/route-reusable-strategy'; /** Custom Modules */ import { SharedModule } from '../shared/shared.module'; -import { NotificationsModule } from '../notifications/notifications.module'; -import { SearchModule } from 'app/search/search.module'; /** Custom Components */ import { ShellComponent } from './shell/shell.component'; diff --git a/src/app/organization/investors/investors.component.html b/src/app/organization/investors/investors.component.html new file mode 100644 index 000000000..ae7690e7b --- /dev/null +++ b/src/app/organization/investors/investors.component.html @@ -0,0 +1,84 @@ +
+ + + {{ 'labels.inputs.Filter' | translate }} + + + {{ filter.option }} + + + + + + Transfer Date From + + + + + + + Transfer Date To + + + + + + + Transfer External Id + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Investor Loan Total Amount Principal Interest Fees Penalties Actions
+ + + +
diff --git a/src/app/organization/investors/investors.component.scss b/src/app/organization/investors/investors.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/organization/investors/investors.component.spec.ts b/src/app/organization/investors/investors.component.spec.ts new file mode 100644 index 000000000..7e5bc514d --- /dev/null +++ b/src/app/organization/investors/investors.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InvestorsComponent } from './investors.component'; + +describe('InvestorsComponent', () => { + let component: InvestorsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ InvestorsComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(InvestorsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/organization/investors/investors.component.ts b/src/app/organization/investors/investors.component.ts new file mode 100644 index 000000000..45f21299a --- /dev/null +++ b/src/app/organization/investors/investors.component.ts @@ -0,0 +1,49 @@ +import { Component, OnInit } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { MatTableDataSource } from '@angular/material/table'; + +@Component({ + selector: 'mifosx-investors', + templateUrl: './investors.component.html', + styleUrls: ['./investors.component.scss'] +}) +export class InvestorsComponent implements OnInit { + + /** Minimum transaction date allowed. */ + minDate = new Date(2000, 0, 1); + /** Maximum transaction date allowed. */ + maxDate = new Date(); + + transferDateFrom = new FormControl(''); + transferDateTo = new FormControl(''); + transferExternalId = new FormControl(''); + + /** Entry type filter form control. */ + entryTypeFilter = new FormControl(''); + /** Entry type filter data. */ + entryTypeFilterData = [ + { + option: 'All', + value: '' + }, + { + option: 'Sale', + value: true + }, + { + option: 'Buyed Back', + value: false + } + ]; + + /** Columns to be displayed in investors table. */ + displayedColumns: string[] = ['investor', 'loanAccount', 'totalAmount', 'principal', 'interest', 'fees', 'penalties', 'actions']; + /** Data source for investors table. */ + dataSource: MatTableDataSource = new MatTableDataSource(); + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/organization/organization-routing.module.ts b/src/app/organization/organization-routing.module.ts index a6bd2347c..18649e95e 100644 --- a/src/app/organization/organization-routing.module.ts +++ b/src/app/organization/organization-routing.module.ts @@ -105,6 +105,7 @@ import { ManageFundResolver } from './manage-funds/manage-fund.resolver'; import { ViewFundComponent } from './manage-funds/view-fund/view-fund.component'; import { EditFundComponent } from './manage-funds/edit-fund/edit-fund.component'; import { CreateFundComponent } from './manage-funds/create-fund/create-fund.component'; +import { InvestorsComponent } from './investors/investors.component'; /** Organization Routes */ const routes: Routes = [ @@ -342,6 +343,12 @@ const routes: Routes = [ advanceSearchTemplate: AdvanceSearchTemplateResolver } }, + { + path: 'investors', + component: InvestorsComponent, + data: { title: extract('Investors'), breadcrumb: 'Investors' }, + resolve: { } + }, { path: 'adhoc-query', data: { title: extract('Adhoc Query'), breadcrumb: 'Adhoc Query' }, diff --git a/src/app/organization/organization.component.html b/src/app/organization/organization.component.html index caee573d1..8af65dcbf 100644 --- a/src/app/organization/organization.component.html +++ b/src/app/organization/organization.component.html @@ -8,76 +8,98 @@ -
- - - - -

Manage Offices

-

Add new office or modify or deactivate office or modify hierarchy

-
-
+
+ + + + +

Manage Offices

+

Add new office or modify or deactivate office or modify hierarchy

+
+
-
- - - - -

Manage Holidays

-

Define holidays for office

-
-
+
+ + + + +

Manage Holidays

+

Define holidays for office

+
+
-
- - - - -

Manage Employees

-

An employee represents loan officers with no access to systems

-
-
+
+ + + + +

Manage Employees

+

An employee represents loan officers with no access to systems

+
+
- - - - -

Standing Instructions History

-

View logged history of standing instructions

-
+
+ + + + +

Standing Instructions History

+

View logged history of standing instructions

+
+
- - - - -

Fund Mapping

-

Bulk entry screen for mapping fund sources to loans

-
+
+ + + + +

Fund Mapping

+

Bulk entry screen for mapping fund sources to loans

+
+
- - - - -

Password Preferences

-

Define standards for enforcing the usage of stronger passwords

-
+
+ + + + +

Investors

+

View the loan account details associated with the investors

+
+
- - - - -

Loan Provisioning Criteria

-

Define Loan Provisioning Criteria for Organization

-
+
+ + + + +

Loan Provisioning Criteria

+

Define Loan Provisioning Criteria for Organization

+
+
- - - - -

Entity Data Table Checks

-

Define Entity Data Table Checks for Organization

-
+
+ + + + +

Entity Data Table Checks

+

Define Entity Data Table Checks for Organization

+
+
+
+ + + + +

Password Preferences

+

Define standards for enforcing the usage of stronger passwords

+
+
@@ -86,84 +108,95 @@ -
- - - - -

Currency Configuration

-

Currencies available across organization for different products

-
-
+
+ + + + +

Currency Configuration

+

Currencies available across organization for different products

+
+
-
- - - - -

Manage Funds

-

Funds are associated with loans

-
-
+
+ + + + +

Manage Funds

+

Funds are associated with loans

+
+
- - - - -

Bulk Loan Reassignment

-

Easy way to reassign all the loan from one LO to another LO

-
+
+ + + + +

Bulk Loan Reassignment

+

Easy way to reassign all the loan from one LO to another LO

+
+
- - - - -

Teller / Cashier Management

-

Manage Tellers / Cashiers and Cash Allocation and Settlement

-
+
+ + + + +

Teller / Cashier Management

+

Manage Tellers / Cashiers and Cash Allocation and Settlement

+
+
-
- - - - -

Working Days

-

Define working days and configure behaviour of payments due on holidays

-
-
+
+ + + + +

Working Days

+

Define working days and configure behaviour of payments due on holidays

+
+
- - - - -

Payment Type

-

Manage payment types

-
+
+ + + + +

Payment Type

+

Manage payment types

+
+
- - - - -

SMS Campaigns

-

Define SMS Campaigns for Organization

-
+
+ + + + +

SMS Campaigns

+

Define SMS Campaigns for Organization

+
+
- - - - -

AdHocQuery

-

Define AdHocQuery for Organization

-
- - - - - -

Bulk Import

-

Bulk data import using excel spreadsheet templates for clients, offices, etc.

-
+
+ + + + +

AdHocQuery

+

Define AdHocQuery for Organization

+
+
+
+ + + + +

Bulk Import

+

Bulk data import using excel spreadsheet templates for clients, offices, etc.

+
+
@@ -178,7 +211,8 @@

Manage Offices

The Manage Offices page allows you to create, edit and add the offices within your organization.

- +
@@ -186,9 +220,11 @@

Currency Configuration

-

This section allows an organization to define what currencies will be used throughout their interactions within the Mifos X system.

+

This section allows an organization to define what currencies will be used throughout their + interactions within the Mifos X system.

- +
@@ -196,9 +232,11 @@

Manage Holidays

-

The ability to manage holidays for individual offices is a very useful tool for an organization spanning multiple locations.Use this option to customize holidays for each office of your organization.

+

The ability to manage holidays for individual offices is a very useful tool for an organization + spanning multiple locations.Use this option to customize holidays for each office of your organization.

- +
@@ -208,7 +246,8 @@

Manage Employees

With this option, you may view, edit and/or delete your organization's employees.

- +
@@ -218,7 +257,8 @@

Working Days

Working days page allows you to define which days of the week are working days.

- +
@@ -228,7 +268,8 @@

Manage Funds

This allows you to manage funds associated with loans.

- +
diff --git a/src/app/organization/organization.module.ts b/src/app/organization/organization.module.ts index f028bdcc9..a8ebb0a95 100644 --- a/src/app/organization/organization.module.ts +++ b/src/app/organization/organization.module.ts @@ -77,6 +77,7 @@ import { CreateHoliday } from './holidays/create-holiday/create-holiday.service' import { CreateFundComponent } from './manage-funds/create-fund/create-fund.component'; import { EditFundComponent } from './manage-funds/edit-fund/edit-fund.component'; import { ViewFundComponent } from './manage-funds/view-fund/view-fund.component'; +import { InvestorsComponent } from './investors/investors.component'; /** @@ -154,6 +155,7 @@ import { ViewFundComponent } from './manage-funds/view-fund/view-fund.component' CreateFundComponent, EditFundComponent, ViewFundComponent, + InvestorsComponent, ], providers: [ CreateHoliday, diff --git a/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts b/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts index bfd9397be..f2a57724c 100644 --- a/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts +++ b/src/app/products/loan-products/create-loan-product/create-loan-product.component.ts @@ -13,6 +13,7 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model'; @Component({ selector: 'mifosx-create-loan-product', @@ -47,7 +48,7 @@ export class CreateLoanProductComponent implements OnInit { const assetAccountData = this.loanProductsTemplate.accountingMappingOptions.assetAccountOptions || []; const liabilityAccountData = this.loanProductsTemplate.accountingMappingOptions.liabilityAccountOptions || []; this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData); - data.configurations.globalConfiguration.forEach((config: any) => { + data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => { if (config.name === 'days-before-repayment-is-due') { this.loanProductsTemplate['dueDaysForRepaymentEvent'] = config.value; } else if (config.name === 'days-after-repayment-is-overdue') { diff --git a/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts b/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts index 2c78bcbec..2b783825d 100644 --- a/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts +++ b/src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts @@ -13,6 +13,7 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model'; @Component({ selector: 'mifosx-edit-loan-product', @@ -42,11 +43,22 @@ export class EditLoanProductComponent implements OnInit { private productsService: ProductsService, private settingsService: SettingsService, private router: Router) { - this.route.data.subscribe((data: { loanProductAndTemplate: any }) => { + this.route.data.subscribe((data: { loanProductAndTemplate: any, configurations: any }) => { this.loanProductAndTemplate = data.loanProductAndTemplate; const assetAccountData = this.loanProductAndTemplate.accountingMappingOptions.assetAccountOptions || []; const liabilityAccountData = this.loanProductAndTemplate.accountingMappingOptions.liabilityAccountOptions || []; this.loanProductAndTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData); + data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => { + if (config.name === 'days-before-repayment-is-due') { + if (this.loanProductAndTemplate['dueDaysForRepaymentEvent'] == null) { + this.loanProductAndTemplate['dueDaysForRepaymentEvent'] = config.value; + } + } else if (config.name === 'days-after-repayment-is-overdue') { + if (this.loanProductAndTemplate['overDueDaysForRepaymentEvent'] == null) { + this.loanProductAndTemplate['overDueDaysForRepaymentEvent'] = config.value; + } + } + }); }); } diff --git a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts index e94043d64..fb8bedcbe 100644 --- a/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts +++ b/src/app/products/loan-products/loan-product-stepper/loan-product-settings-step/loan-product-settings-step.component.ts @@ -184,8 +184,8 @@ export class LoanProductSettingsStepComponent implements OnInit { 'graceOnArrearsAgeing': [true] }), 'delinquencyBucketId': ['', Validators.required], - 'dueDaysForRepaymentEvent': [''], - 'overDueDaysForRepaymentEvent': [''] + 'dueDaysForRepaymentEvent': ['', Validators.required], + 'overDueDaysForRepaymentEvent': ['', Validators.required] }); } diff --git a/src/app/products/products-routing.module.ts b/src/app/products/products-routing.module.ts index f00a8f76f..235a06072 100644 --- a/src/app/products/products-routing.module.ts +++ b/src/app/products/products-routing.module.ts @@ -198,7 +198,8 @@ const routes: Routes = [ component: EditLoanProductComponent, data: { title: extract('Edit Loan Product'), breadcrumb: 'Edit', routeParamBreadcrumb: false }, resolve: { - loanProductAndTemplate: LoanProductAndTemplateResolver + loanProductAndTemplate: LoanProductAndTemplateResolver, + configurations: GlobalConfigurationsResolver } } ] diff --git a/src/app/reports/reports-routing.module.ts b/src/app/reports/reports-routing.module.ts index ed110dc6c..3e7e0a08d 100644 --- a/src/app/reports/reports-routing.module.ts +++ b/src/app/reports/reports-routing.module.ts @@ -20,6 +20,7 @@ import { RunReportResolver } from './common-resolvers/run-report.resolver'; import { MixTaxonomyResolver } from './common-resolvers/mixtaxonomy.resolver'; import { MixMappingsResolver } from './common-resolvers/mixmappings.resolver'; import { GlAccountsResolver } from '../accounting/common-resolvers/gl-accounts.resolver'; +import { GlobalConfigurationsResolver } from 'app/system/configurations/global-configurations-tab/global-configurations.resolver'; /** Reports Routes */ const routes: Routes = [ @@ -45,7 +46,8 @@ const routes: Routes = [ data: { title: extract('Reports'), routeParamBreadcrumb: 'name' }, component: RunReportComponent, resolve: { - reportParameters: RunReportResolver + reportParameters: RunReportResolver, + configurations: GlobalConfigurationsResolver } } ] diff --git a/src/app/reports/run-report/run-report.component.html b/src/app/reports/run-report/run-report.component.html index c91bb06c4..b13dd9163 100644 --- a/src/app/reports/run-report/run-report.component.html +++ b/src/app/reports/run-report/run-report.component.html @@ -6,7 +6,7 @@ - + @@ -17,7 +17,7 @@ {{param.label}} is required - + {{param.label}} - Decimal Places + {{ 'Decimal Places' | translate }} 0 1 @@ -56,14 +56,27 @@ - - Output Type - - Normal format - Excel format - Excel 2007 format - CSV format - PDF format + + {{ 'Output Type' | translate }} + + + {{option.name | translate}} + + + + +
+ + Export output data to S3 repository [{{exportToS3Repository}}] + +
+ + + {{ 'Export output as' | translate }} + + + {{option.name | translate}} + @@ -72,8 +85,8 @@ @@ -89,12 +102,12 @@
- +
diff --git a/src/app/reports/run-report/run-report.component.ts b/src/app/reports/run-report/run-report.component.ts index a40b41a91..503eb5732 100644 --- a/src/app/reports/run-report/run-report.component.ts +++ b/src/app/reports/run-report/run-report.component.ts @@ -11,6 +11,7 @@ import { SettingsService } from 'app/settings/settings.service'; import { ReportParameter } from '../common-models/report-parameter.model'; import { SelectOption } from '../common-models/select-option.model'; import { Dates } from 'app/core/utils/dates'; +import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model'; /** * Run report component. @@ -53,6 +54,10 @@ export class RunReportComponent implements OnInit { hidePentaho = true; /** Report uses dates */ reportUsesDates = false; + exportToS3Allowed = false; + reportToBeExportedInRepository: any; + exportToS3Repository: string; + outputTypeOptions: any[] = []; /** * Fetches report specifications from route params and retrieves report parameters data from `resolve`. @@ -70,16 +75,32 @@ export class RunReportComponent implements OnInit { this.report.type = queryParams.type; this.report.id = queryParams.id; }); - this.route.data.subscribe((data: { reportParameters: ReportParameter[] }) => { + this.route.data.subscribe((data: { reportParameters: ReportParameter[], configurations: any }) => { this.paramData = data.reportParameters; + if (this.isTableReport()) { + data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => { + if (config.name === 'report-export-s3-folder-name') { + this.exportToS3Allowed = config.enabled; + this.exportToS3Repository = config.stringValue; + } + }); + } }); } + isTableReport(): boolean { + return (this.report.type === 'Table'); + } + + isPentahoReport(): boolean { + return (this.report.type === 'Pentaho'); + } + /** * Creates and sets the run report form. */ ngOnInit() { - this.maxDate = this.settingsService.businessDate; + this.maxDate = this.settingsService.maxAllowedDate; this.createRunReportForm(); } @@ -102,10 +123,20 @@ export class RunReportComponent implements OnInit { this.updateParentParameters(parent); } }); - if (this.report.type === 'Pentaho') { + if (this.isPentahoReport()) { this.reportForm.addControl('outputType', new FormControl('')); + this.outputTypeOptions = [ + { 'name': 'Normal format', 'value': 'HTML' }, + { 'name': 'Excel format', 'value': 'XLS' }, + { 'name': 'Excel 2007 format', 'value': 'XLSX' }, + { 'name': 'CSV format', 'value': 'CSV' }, + { 'name': 'PDF format', 'value': 'PDF' } + ]; this.mapPentahoParams(); } + if (this.exportToS3Allowed) { + this.reportForm.addControl('exportOutputToS3', new FormControl(false)); + } this.decimalChoice.patchValue('0'); this.setChildControls(); } @@ -179,14 +210,19 @@ export class RunReportComponent implements OnInit { formatUserResponse(response: any) { const formattedResponse: any = {}; let newKey: string; + this.reportToBeExportedInRepository = false; for (const [key, value] of Object.entries(response)) { if (key === 'outputType') { formattedResponse['output-type'] = value; continue; + } else if (key === 'exportOutputToS3') { + this.reportToBeExportedInRepository = value; + continue; } + const param: ReportParameter = this.paramData .find((_entry: any) => _entry.name === key); - newKey = this.report.type === 'Pentaho' ? param.pentahoName : param.inputName; + newKey = this.isPentahoReport() ? param.pentahoName : param.inputName; switch (param.displayType) { case 'text': formattedResponse[newKey] = value; @@ -223,6 +259,9 @@ export class RunReportComponent implements OnInit { dateFormat: this.settingsService.dateFormat }; } + if (this.reportToBeExportedInRepository) { + formData['exportS3'] = true; + } this.dataObject = { formData: formData, report: this.report, diff --git a/src/app/reports/run-report/table-and-sms/table-and-sms.component.html b/src/app/reports/run-report/table-and-sms/table-and-sms.component.html index 9c35ca7e3..9362721b1 100644 --- a/src/app/reports/run-report/table-and-sms/table-and-sms.component.html +++ b/src/app/reports/run-report/table-and-sms/table-and-sms.component.html @@ -1,12 +1,12 @@
-
-
+
@@ -23,4 +23,10 @@
+
+
+ + No report data was generated +
+
diff --git a/src/app/reports/run-report/table-and-sms/table-and-sms.component.ts b/src/app/reports/run-report/table-and-sms/table-and-sms.component.ts index f612a1fce..64bad491b 100644 --- a/src/app/reports/run-report/table-and-sms/table-and-sms.component.ts +++ b/src/app/reports/run-report/table-and-sms/table-and-sms.component.ts @@ -2,7 +2,7 @@ import { Component, Input, ViewChild, OnChanges } from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; import { MatTableDataSource } from '@angular/material/table'; -import { DecimalPipe } from '@angular/common'; +import { DecimalPipe, NumberSymbol, getLocaleNumberSymbol } from '@angular/common'; /** Custom Servies */ import { ReportsService } from '../../reports.service'; @@ -30,6 +30,7 @@ export class TableAndSmsComponent implements OnChanges { hideOutput = true; /** Data to be converted into CSV file */ csvData: any; + notExistsReportData = false; /** Paginator for run-report table. */ @ViewChild(MatPaginator) paginator: MatPaginator; @@ -55,6 +56,7 @@ export class TableAndSmsComponent implements OnChanges { this.reportsService.getRunReportData(this.dataObject.report.name, this.dataObject.formData) .subscribe( (res: any) => { this.csvData = res.data; + this.notExistsReportData = (res.data.length === 0); this.setOutputTable(res.data); res.columnHeaders.forEach((header: any) => { this.columnTypes.push(header.columnDisplayType); @@ -79,9 +81,14 @@ export class TableAndSmsComponent implements OnChanges { * Generates the CSV file dynamically for run report data. */ downloadCSV() { + const userLang = navigator.language; const headers = this.displayedColumns; - let csv = this.csvData.map((object: any) => object.row.join()); - csv.unshift(`data:text/csv;charset=utf-8,${headers.join()}`); + let delimiter = ','; + if (getLocaleNumberSymbol(userLang, NumberSymbol.CurrencyDecimal) !== '.') { + delimiter = ';'; + } + let csv = this.csvData.map((object: any) => object.row.join(delimiter)); + csv.unshift(`data:text/csv;charset=utf-8,${headers.join(delimiter)}`); csv = csv.join('\r\n'); const link = document.createElement('a'); link.setAttribute('href', encodeURI(csv)); diff --git a/src/app/self-service/self-service-routing.module.ts b/src/app/self-service/self-service-routing.module.ts index 1ed274688..c0b8dc612 100644 --- a/src/app/self-service/self-service-routing.module.ts +++ b/src/app/self-service/self-service-routing.module.ts @@ -18,8 +18,9 @@ import { AppConfigurationComponent } from './app-configuration/app-configuration import { TaskManagementComponent } from './task-management/task-management.component'; /** Custom Resolvers */ -import { UsersResolver } from './users/users.resolver'; import { ViewUserResolver } from './users/view-user/view-user.resolver'; +import { OfficesResolver } from 'app/organization/offices/common-resolvers/offices.resolver'; +import { UsersResolver } from 'app/users/users.resolver'; /** Self Service Admin Portal Routes */ const routes: Routes = [ @@ -43,7 +44,10 @@ const routes: Routes = [ { path: 'create', component: CreateUserComponent, - data: { title: extract('Create Self Service User'), breadcrumb: 'Create' } + data: { title: extract('Create Self Service User'), breadcrumb: 'Create' }, + resolve: { + offices: OfficesResolver + } }, { path: 'view/:id', @@ -89,7 +93,6 @@ const routes: Routes = [ imports: [RouterModule.forChild(routes)], exports: [RouterModule], providers: [ - UsersResolver, ViewUserResolver ] }) diff --git a/src/app/self-service/users/create-user/create-user.component.html b/src/app/self-service/users/create-user/create-user.component.html index cc2491aec..0791ef298 100644 --- a/src/app/self-service/users/create-user/create-user.component.html +++ b/src/app/self-service/users/create-user/create-user.component.html @@ -12,7 +12,7 @@
-
+ @@ -20,18 +20,21 @@ Office - - - {{ office }} + + + {{ office.name }} + + Office is required + Staff - - - {{ staff }} + + + {{ staff.displayName }} @@ -63,26 +66,29 @@
- +
- + Office - - - {{ office }} + + + {{ office.name }} + + Office is required + Staff - - - {{ staff }} + + + {{ staff.displayName }} diff --git a/src/app/self-service/users/create-user/create-user.component.ts b/src/app/self-service/users/create-user/create-user.component.ts index ad9783c41..d645b1c98 100644 --- a/src/app/self-service/users/create-user/create-user.component.ts +++ b/src/app/self-service/users/create-user/create-user.component.ts @@ -1,6 +1,8 @@ /** Angular Imports */ import { Component, OnInit } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ClientsService } from 'app/clients/clients.service'; import { SettingsService } from 'app/settings/settings.service'; /** @@ -14,17 +16,21 @@ import { SettingsService } from 'app/settings/settings.service'; styleUrls: ['./create-user.component.scss'] }) export class CreateUserComponent implements OnInit { + /** Create Client Form */ + createUserForm: FormGroup; /** Denotes type of user. */ userTypes = ['Existing User', 'New User']; /** Radio button group form control for type of user. */ userType = new FormControl(this.userTypes[0]); /** Placeholder for office data. */ - officeData = ['Office 1', 'Office 2']; + offices: any[] = []; /** Placeholder for staff data. */ - staffData = ['Staff 1', 'Staff 2']; + staffOptions: any [] = []; + /** Placeholder for staff data. */ + genderOptions: any [] = []; /** Placeholder for client data. */ - clientData = ['Client 1', 'Client 2']; + clientData: any [] = []; /** Placeholder for gender data. */ genderData = ['Male', 'Female']; /** Minimum date of birth of user allowed. */ @@ -35,10 +41,42 @@ export class CreateUserComponent implements OnInit { /** * @param {SettingsService} settingsService Settings Service */ - constructor(private settingsService: SettingsService) { } + constructor(private formBuilder: FormBuilder, + private route: ActivatedRoute, + private clientService: ClientsService, + private settingsService: SettingsService) { + this.route.data.subscribe((data: { offices: any }) => { + this.offices = data.offices; + }); + } ngOnInit() { + this.minDate = this.settingsService.minAllowedDate; this.maxDate = this.settingsService.businessDate; + this.setClientForm(); + this.buildDependencies(); + } + + /** + * Creates the client form. + */ + setClientForm() { + this.createUserForm = this.formBuilder.group({ + 'officeId': ['', Validators.required], + 'staffId': ['', Validators.required] + }); + } + + /** + * Adds controls conditionally. + */ + buildDependencies() { + this.createUserForm.get('officeId').valueChanges.subscribe((officeId: number) => { + this.clientService.getClientWithOfficeTemplate(officeId).subscribe((clientTemplate: any) => { + this.staffOptions = clientTemplate.staffOptions; + this.genderOptions = clientTemplate.genderOptions; + }); + }); } } diff --git a/src/app/self-service/users/users.component.ts b/src/app/self-service/users/users.component.ts index 8e3daab81..616ef6da6 100644 --- a/src/app/self-service/users/users.component.ts +++ b/src/app/self-service/users/users.component.ts @@ -44,7 +44,12 @@ export class UsersComponent implements OnInit { */ constructor(private route: ActivatedRoute) { this.route.data.subscribe((data: { users: User[] }) => { - this.userData = data.users; + this.userData = []; + data.users.forEach((user: any) => { + if (user.isSelfServiceUser) { + this.userData.push(user); + } + }); }); } diff --git a/src/app/self-service/users/users.resolver.ts b/src/app/self-service/users/users.resolver.ts deleted file mode 100644 index 132ba0612..000000000 --- a/src/app/self-service/users/users.resolver.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** Angular Routes */ -import { Injectable } from '@angular/core'; -import { Resolve } from '@angular/router'; - -/** rxjs Imports */ -import { Observable } from 'rxjs'; - -/** Custom Services */ -import { UserService } from './user.service'; - -/** Custom Model */ -import { User } from './user.model'; - -/** - * Self service users data resolver. - */ -@Injectable() -export class UsersResolver implements Resolve { - - /** - * @param {UserService} userService Self service user service. - */ - constructor(private userService: UserService) {} - - /** - * Returns the users data. - * @returns {Observable} - */ - resolve(): Observable { - return this.userService.getUsers(); - } - -} diff --git a/src/app/shared/icons.module.ts b/src/app/shared/icons.module.ts index 3ee9de569..93a095587 100644 --- a/src/app/shared/icons.module.ts +++ b/src/app/shared/icons.module.ts @@ -103,7 +103,9 @@ import { faInfo, faTasks, faCoins, - faPiggyBank + faPiggyBank, + faFileExcel, + faFileExport } from '@fortawesome/free-solid-svg-icons'; /** @@ -154,6 +156,8 @@ export class IconsModule { faFileAlt, faFileUpload, faFileWord, + faFileExcel, + faFileExport, faFillDrip, faHandHoldingUsd, faHome, diff --git a/src/app/system/configurations/global-configurations-tab/configuration.model.ts b/src/app/system/configurations/global-configurations-tab/configuration.model.ts new file mode 100644 index 000000000..adbe4cb6d --- /dev/null +++ b/src/app/system/configurations/global-configurations-tab/configuration.model.ts @@ -0,0 +1,14 @@ +/** + * Global Configuration model. + */ +export interface GlobalConfiguration { + id: number; + name: string; + enabled: boolean; + value: any; + trapDoor: boolean; + + description?: string; + stringValue?: string; + dateValue?: string; +}