You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by my...@apache.org on 2018/06/28 07:00:04 UTC
[fineract-cn-group-finance] 10/16: done authentication service
This is an automated email from the ASF dual-hosted git repository.
myrle pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/fineract-cn-group-finance.git
commit 34212847674bc85e50a10e7e1adb6031cae01bcc
Author: pembemiriam <pe...@skylabase.com>
AuthorDate: Tue Jun 19 14:36:46 2018 +0100
done authentication service
---
package-lock.json | 52 ++-
package.json | 8 +
protractor.conf.js | 2 +-
src/app/app.module.ts | 106 ++++-
.../common/data-table/data-table.component.html | 74 ++++
.../common/data-table/data-table.component.spec.ts | 158 ++++++++
src/app/common/data-table/data-table.component.ts | 129 ++++++
src/app/common/i18n/translate.ts | 33 ++
src/app/common/regex/escape.ts | 25 ++
.../common/store/action-creator/action-creator.ts | 177 +++++++++
src/app/common/store/action-creator/actions.ts | 100 +++++
src/app/common/store/form.reducer.spec.ts | 90 +++++
src/app/common/store/form.reducer.ts | 60 +++
src/app/common/store/reducer.helper.spec.ts | 70 ++++
src/app/common/store/reducer.helper.ts | 35 ++
src/app/common/store/resource.reducer.spec.ts | 171 ++++++++
src/app/common/store/resource.reducer.ts | 168 ++++++++
src/app/common/store/route-payload.ts | 23 ++
src/app/common/store/search.reducer.ts | 106 +++++
src/app/common/testing/input-fields.ts | 54 +++
src/app/common/testing/permission-stubs.ts | 31 ++
src/app/common/testing/router-stubs.ts | 76 ++++
src/app/common/testing/select-fields.ts | 34 ++
src/app/common/util/account-assignments.ts | 45 +++
src/app/login/login.component.html | 27 +-
src/app/login/login.component.spec.ts | 148 ++++++-
src/app/login/login.component.ts | 81 +++-
.../office/store/effects/notification.effects.ts | 57 +++
src/app/office/store/effects/route.effects.ts | 60 +++
src/app/office/store/effects/service.effects.ts | 84 ++++
src/app/office/store/index.ts | 81 ++++
src/app/office/store/office.actions.ts | 145 +++++++
.../teller/denomination/denomination.actions.ts | 77 ++++
.../teller/denomination/denominations.reducer.ts | 61 +++
.../denomination/effects/notification.effects.ts | 39 ++
.../teller/denomination/effects/route.effects.ts | 38 ++
.../teller/denomination/effects/service.effects.ts | 52 +++
.../store/teller/effects/notification.effects.ts | 71 ++++
.../office/store/teller/effects/route.effects.ts | 46 +++
.../office/store/teller/effects/service.effects.ts | 82 ++++
src/app/office/store/teller/teller.actions.ts | 161 ++++++++
.../office/store/teller/tellers.reducer.spec.ts | 83 ++++
src/app/office/store/teller/tellers.reducer.ts | 92 +++++
.../view-offices/view-offices.component.html | 2 +-
.../office/view-offices/view-offices.component.ts | 3 +-
src/app/sevices/accounting/accounting.service.ts | 201 ++++++++++
.../domain/account-command-action.model.ts | 19 +
.../accounting/domain/account-command.model.ts | 26 ++
.../accounting/domain/account-entry-page.model.ts | 25 ++
.../accounting/domain/account-entry-type.model.ts | 19 +
.../accounting/domain/account-entry.model.ts | 27 ++
.../accounting/domain/account-page.model.ts | 25 ++
.../accounting/domain/account-state.model.ts | 19 +
.../accounting/domain/account-type.model.ts | 19 +
src/app/sevices/accounting/domain/account.model.ts | 37 ++
.../domain/chart-of-account-entry.model.ts | 26 ++
.../sevices/accounting/domain/creditor.model.ts | 22 ++
src/app/sevices/accounting/domain/debtor.model.ts | 23 ++
.../domain/financial-condition-entry.model.ts | 22 ++
.../domain/financial-condition-section.model.ts | 28 ++
.../accounting/domain/financial-condition.model.ts | 26 ++
.../domain/income-statement-entry.model.ts | 22 ++
.../domain/income-statement-section.model.ts | 28 ++
.../accounting/domain/income-statement.model.ts | 27 ++
.../accounting/domain/journal-entry-state.model.ts | 19 +
.../accounting/domain/journal-entry.model.ts | 33 ++
.../sevices/accounting/domain/ledger-page.model.ts | 25 ++
src/app/sevices/accounting/domain/ledger.model.ts | 34 ++
.../accounting/domain/permittable-group-ids.ts | 26 ++
.../domain/transaction-type-page.model.ts | 25 ++
.../accounting/domain/transaction-type.model.ts | 23 ++
.../domain/trial-balance-entry-type.model.ts | 19 +
.../accounting/domain/trial-balance-entry.model.ts | 26 ++
.../accounting/domain/trial-balance.model.ts | 25 ++
.../sevices/anubis/permittable-endpoint.model.ts | 26 ++
src/app/sevices/anubis/permittable-group.model.ts | 24 ++
src/app/sevices/catalog/catalog.service.ts | 58 +++
src/app/sevices/catalog/domain/catalog.model.ts | 30 ++
src/app/sevices/catalog/domain/field.model.ts | 37 ++
src/app/sevices/catalog/domain/option.model.ts | 24 ++
src/app/sevices/catalog/domain/value.model.ts | 23 ++
src/app/sevices/cheque/cheque.service.ts | 72 ++++
src/app/sevices/cheque/domain/action.model.ts | 20 +
.../cheque/domain/cheque-processing-command.ts | 23 ++
.../sevices/cheque/domain/cheque-transaction.ts | 24 ++
src/app/sevices/cheque/domain/cheque.model.ts | 32 ++
src/app/sevices/cheque/domain/fims-cheque.model.ts | 24 ++
.../sevices/cheque/domain/issuing-count.model.ts | 23 ++
.../cheque/domain/mapper/fims-cheque.mapper.ts | 39 ++
.../sevices/cheque/domain/micr-resolution.model.ts | 22 ++
src/app/sevices/cheque/domain/micr.model.ts | 23 ++
.../sevices/cheque/domain/permittable-group-ids.ts | 22 ++
src/app/sevices/cheque/domain/state.model.ts | 20 +
src/app/sevices/country/country.service.spec.ts | 68 ++++
src/app/sevices/country/country.service.ts | 77 ++++
src/app/sevices/country/model/country.model.ts | 24 ++
src/app/sevices/currency/currency.service.ts | 45 +++
src/app/sevices/currency/domain/currency.model.ts | 24 ++
src/app/sevices/customer/customer.service.ts | 212 ++++++++++
src/app/sevices/customer/domain/command.model.ts | 26 ++
.../customer/domain/customer-document.model.ts | 25 ++
.../sevices/customer/domain/customer-page.model.ts | 26 ++
.../customer/domain/customer-state.model.ts | 19 +
.../sevices/customer/domain/customer-type.model.ts | 19 +
src/app/sevices/customer/domain/customer.model.ts | 50 +++
.../sevices/customer/domain/date-of-birth.model.ts | 23 ++
.../customer/domain/expiration-date.model.ts | 23 ++
.../domain/identification-card-scan.model.ts | 22 ++
.../customer/domain/identification-card.model.ts | 30 ++
.../customer/domain/permittable-group-ids.ts | 28 ++
.../sevices/customer/domain/process-step.model.ts | 25 ++
.../customer/domain/task-definition.model.ts | 31 ++
.../depositAccount/deposit-account.service.ts | 110 ++++++
.../domain/definition/action.model.ts | 24 ++
.../domain/definition/charge.model.ts | 26 ++
.../domain/definition/currency.model.ts | 24 ++
.../definition/dividend-distribution.model.ts | 26 ++
.../definition/product-definition-command.model.ts | 26 ++
.../domain/definition/product-definition.model.ts | 40 ++
.../depositAccount/domain/definition/term.model.ts | 26 ++
.../instance/available-transaction-type.model.ts | 21 +
.../domain/instance/product-instance.model.ts | 29 ++
.../domain/interest-payable.model.ts | 19 +
.../depositAccount/domain/permittable-group-ids.ts | 22 ++
.../depositAccount/domain/time-unit.model.ts | 19 +
.../sevices/depositAccount/domain/type.model.ts | 19 +
src/app/sevices/domain/address/address.model.ts | 26 ++
.../sevices/domain/contact/contact-detail.model.ts | 36 ++
src/app/sevices/domain/date.converter.ts | 100 +++++
src/app/sevices/domain/error.model.ts | 48 +++
.../sevices/domain/paging/fetch-request.model.ts | 26 ++
src/app/sevices/domain/paging/page.model.ts | 22 ++
.../sevices/domain/paging/search-param.builder.ts | 45 +++
src/app/sevices/domain/paging/sort.model.ts | 23 ++
.../http/default-request-options.service.ts | 34 ++
src/app/sevices/http/header.service.ts | 21 +
src/app/sevices/http/http.service.spec.ts | 137 +++++++
src/app/sevices/http/http.service.ts | 124 ++++++
.../identity/domain/authentication.model.ts | 36 ++
src/app/sevices/identity/domain/password.model.ts | 25 ++
.../sevices/identity/domain/permission.model.ts | 24 ++
.../identity/domain/permittable-group-ids.model.ts | 25 ++
.../identity/domain/role-identifier.model.ts | 25 ++
src/app/sevices/identity/domain/role.model.ts | 24 ++
.../identity/domain/user-with-password.model.ts | 23 ++
src/app/sevices/identity/domain/user.model.ts | 22 ++
src/app/sevices/identity/identity.service.ts | 103 +++++
src/app/sevices/image/image.service.ts | 61 +++
.../sevices/notification/notification.service.ts | 42 ++
.../sevices/office/domain/employee-page.model.ts | 25 ++
src/app/sevices/office/domain/employee.model.ts | 28 ++
src/app/sevices/office/domain/office-page.model.ts | 25 ++
src/app/sevices/office/domain/office.model.ts | 30 ++
.../office/domain/permittable-group-ids.model.ts | 25 ++
src/app/sevices/office/office.service.ts | 118 ++++++
.../payroll/domain/payroll-allocation.model.ts | 23 ++
.../domain/payroll-collection-history.model.ts | 25 ++
.../domain/payroll-collection-sheet.model.ts | 24 ++
.../payroll/domain/payroll-configuration.model.ts | 28 ++
.../payroll/domain/payroll-payment-page.model.ts | 25 ++
.../payroll/domain/payroll-payment.model.ts | 23 ++
.../payroll/domain/permittable-group-ids.ts | 22 ++
src/app/sevices/payroll/payroll.service.ts | 60 +++
.../portfolio/domain/account-assignment.model.ts | 23 ++
.../portfolio/domain/balance-range.model.ts | 22 ++
.../portfolio/domain/balance-segment-set.model.ts | 23 ++
.../sevices/portfolio/domain/case-command.model.ts | 27 ++
.../domain/case-customer-documents.model.ts | 26 ++
.../sevices/portfolio/domain/case-page.model.ts | 25 ++
.../sevices/portfolio/domain/case-state.model.ts | 19 +
src/app/sevices/portfolio/domain/case.model.ts | 33 ++
.../portfolio/domain/charge-definition.model.ts | 41 ++
.../portfolio/domain/charge-method.model.ts | 19 +
.../sevices/portfolio/domain/chrono-unit.model.ts | 20 +
.../portfolio/domain/cost-component.model.ts | 22 ++
.../portfolio/domain/fims-case-page.model.ts | 25 ++
.../sevices/portfolio/domain/fims-case.model.ts | 34 ++
.../individuallending/account-designators.model.ts | 60 +++
.../individuallending/case-parameters.model.ts | 29 ++
.../domain/individuallending/charge-name.model.ts | 22 ++
.../charge-proportional-designators.model.ts | 37 ++
.../credit-worthiness-factor.model.ts | 22 ++
.../credit-worthiness-snapshot.model.ts | 26 ++
.../domain/individuallending/document.model.ts | 21 +
.../domain/individuallending/moratorium.model.ts | 25 ++
.../planned-payment-page.model.ts | 27 ++
.../individuallending/planned-payment.model.ts | 24 ++
.../individuallending/product-parameters.model.ts | 26 ++
.../individuallending/workflow-action.model.ts | 29 ++
.../portfolio/domain/interest-basis.model.ts | 19 +
.../portfolio/domain/interest-range.model.ts | 23 ++
.../domain/loss-provision-configuration.model.ts | 23 ++
.../portfolio/domain/loss-provision-step.model.ts | 22 ++
.../domain/mapper/fims-case-page.mapper.ts | 35 ++
.../portfolio/domain/mapper/fims-case.mapper.ts | 46 +++
.../portfolio/domain/mapper/fims-range.mapper.ts | 49 +++
src/app/sevices/portfolio/domain/note.model.ts | 21 +
src/app/sevices/portfolio/domain/pattern.model.ts | 25 ++
.../portfolio/domain/payment-cycle.model.ts | 27 ++
src/app/sevices/portfolio/domain/payment.model.ts | 25 ++
.../portfolio/domain/permittable-group-ids.ts | 25 ++
.../sevices/portfolio/domain/product-page.model.ts | 25 ++
src/app/sevices/portfolio/domain/product.model.ts | 43 ++
src/app/sevices/portfolio/domain/range-model.ts | 24 ++
.../portfolio/domain/range-segment.model.ts | 23 ++
.../domain/required-account-assignment.model.ts | 23 ++
.../portfolio/domain/task-definition.model.ts | 28 ++
.../portfolio/domain/task-instance.model.ts | 26 ++
.../sevices/portfolio/domain/term-range.model.ts | 24 ++
src/app/sevices/portfolio/portfolio.service.ts | 285 ++++++++++++++
.../domain/auto-complete-resource.model.ts | 22 ++
.../reporting/domain/displayable-field.model.ts | 25 ++
src/app/sevices/reporting/domain/footer.model.ts | 23 ++
src/app/sevices/reporting/domain/header.model.ts | 22 ++
.../reporting/domain/permittable-group-ids.ts | 21 +
.../reporting/domain/query-parameter.model.ts | 31 ++
.../reporting/domain/report-definition.model.ts | 28 ++
.../sevices/reporting/domain/report-page.model.ts | 32 ++
.../reporting/domain/report-request.model.ts | 25 ++
src/app/sevices/reporting/domain/row.model.ts | 23 ++
src/app/sevices/reporting/domain/type.model.ts | 19 +
src/app/sevices/reporting/domain/value.model.ts | 24 ++
src/app/sevices/reporting/reporting.service.ts | 57 +++
.../security/authn/auth-guard.service.spec.ts | 113 ++++++
.../sevices/security/authn/auth-guard.service.ts | 50 +++
.../security/authn/authentication.service.spec.ts | 62 +++
.../security/authn/authentication.service.ts | 89 +++++
.../security/authz/fims-permission-descriptor.ts | 26 ++
.../security/authz/fims-permission.model.ts | 26 ++
.../sevices/security/authz/permission-id.type.ts | 32 ++
.../security/authz/permission.directive.spec.ts | 77 ++++
.../sevices/security/authz/permission.directive.ts | 64 +++
src/app/sevices/security/authz/permission.guard.ts | 67 ++++
.../security/authz/permittable-group-id-mapper.ts | 139 +++++++
.../security/change.password.service.spec.ts | 94 +++++
.../sevices/security/change.password.service.ts | 49 +++
src/app/sevices/teller/domain/charge.model.ts | 24 ++
src/app/sevices/teller/domain/cheque.model.ts | 29 ++
src/app/sevices/teller/domain/micr.model.ts | 23 ++
.../sevices/teller/domain/permittable-group-ids.ts | 22 ++
.../teller/domain/teller-authentication.model.ts | 22 ++
.../teller/domain/teller-balance-sheet.model.ts | 29 ++
.../teller/domain/teller-denomination.model.ts | 26 ++
.../sevices/teller/domain/teller-entry.model.ts | 28 ++
.../domain/teller-management-command.model.ts | 29 ++
.../domain/teller-transaction-costs.model.ts | 26 ++
.../teller/domain/teller-transaction.model.ts | 39 ++
src/app/sevices/teller/domain/teller.model.ts | 39 ++
src/app/sevices/teller/teller-service.ts | 106 +++++
src/app/store/account/account.actions.ts | 54 +++
src/app/store/account/accounts.reducer.ts | 36 ++
.../store/account/effects/service.effects.spec.ts | 173 +++++++++
src/app/store/account/effects/service.effects.ts | 72 ++++
src/app/store/customer/customer.actions.ts | 42 ++
.../store/customer/effects/service.effects.spec.ts | 107 +++++
src/app/store/customer/effects/service.effects.ts | 51 +++
.../store/employee/effects/service.effects.spec.ts | 104 +++++
src/app/store/employee/effects/service.effects.ts | 50 +++
src/app/store/employee/employee.actions.ts | 41 ++
src/app/store/index.ts | 218 +++++++++++
src/app/store/ledger/effects/service.effects.ts | 51 +++
src/app/store/ledger/ledger.actions.ts | 42 ++
.../store/office/effects/service.effects.spec.ts | 104 +++++
src/app/store/office/effects/service.effects.ts | 50 +++
src/app/store/office/office.actions.ts | 41 ++
src/app/store/role/effects/service.effects.spec.ts | 101 +++++
src/app/store/role/effects/service.effects.ts | 57 +++
src/app/store/role/role.actions.ts | 40 ++
.../store/security/authentication.reducer.spec.ts | 80 ++++
src/app/store/security/authentication.reducer.ts | 101 +++++
src/app/store/security/authorization.reducer.ts | 61 +++
.../store/security/effects/notification.effects.ts | 48 +++
src/app/store/security/effects/route.effects.ts | 46 +++
.../store/security/effects/service.effects.spec.ts | 432 +++++++++++++++++++++
src/app/store/security/effects/service.effects.ts | 167 ++++++++
src/app/store/security/security.actions.ts | 166 ++++++++
.../store/security/testing/authentication.mock.ts | 29 ++
src/app/store/util.ts | 29 ++
src/main.ts | 17 +-
src/polyfills.ts | 33 +-
src/rxjs.imports.ts | 23 ++
tsconfig.json | 1 +
282 files changed, 13386 insertions(+), 51 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 67feb85..2766a61 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -241,6 +241,29 @@
"tslib": "1.9.0"
}
},
+ "@covalent/core": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@covalent/core/-/core-1.0.1.tgz",
+ "integrity": "sha512-br5KMBT8xXlctkSENGHnXsV4xyJuq0+yXopHH02zz9E0j1d1zlB43hM7zU1FkeGIFtWtPP7peM4tjD6S+ujkXw==",
+ "requires": {
+ "tslib": "1.9.0"
+ }
+ },
+ "@ngrx/core": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ngrx/core/-/core-1.2.0.tgz",
+ "integrity": "sha1-iCtGq6+i4ObYh8txobLC+j5tDcY="
+ },
+ "@ngrx/effects": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-2.0.5.tgz",
+ "integrity": "sha1-EJhpI7cZOvmwiUToDFpmG6k6eTY="
+ },
+ "@ngrx/store": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-2.2.3.tgz",
+ "integrity": "sha1-570RSfHEQgjxzEdENT8PmKDx9Xs="
+ },
"@ngtools/json-schema": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.2.0.tgz",
@@ -263,6 +286,22 @@
"webpack-sources": "1.1.0"
}
},
+ "@ngx-translate/core": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-10.0.2.tgz",
+ "integrity": "sha512-7nM3DrJaqKswwtJlbu2kuKNl+hE8Isr18sKsKvGGpSxQk+G0gO0reDlx2PhUNus7TJTkA1C59vU/JoN8hIvZ4g==",
+ "requires": {
+ "tslib": "1.9.0"
+ }
+ },
+ "@ngx-translate/http-loader": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-3.0.1.tgz",
+ "integrity": "sha1-ILD5i8bCUyESnT4zAqs8xInApCo=",
+ "requires": {
+ "tslib": "1.9.0"
+ }
+ },
"@schematics/angular": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.3.2.tgz",
@@ -4093,7 +4132,8 @@
"jsbn": {
"version": "0.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"json-schema": {
"version": "0.2.3",
@@ -7225,6 +7265,11 @@
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
+ "ngrx-store-localstorage": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ngrx-store-localstorage/-/ngrx-store-localstorage-5.0.0.tgz",
+ "integrity": "sha1-rcW4Nz/umV9rssUIoOUQ/CBHp04="
+ },
"no-case": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
@@ -9054,6 +9099,11 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
+ "reselect": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz",
+ "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc="
+ },
"resolve": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz",
diff --git a/package.json b/package.json
index d33309e..0a94c0c 100644
--- a/package.json
+++ b/package.json
@@ -23,9 +23,17 @@
"@angular/platform-browser": "^5.2.0",
"@angular/platform-browser-dynamic": "^5.2.0",
"@angular/router": "^5.2.0",
+ "@covalent/core": "^1.0.1",
+ "@ngrx/core": "^1.2.0",
+ "@ngrx/effects": "^2.0.5",
+ "@ngrx/store": "^2.2.3",
+ "@ngx-translate/core": "^10.0.2",
+ "@ngx-translate/http-loader": "0.1.0",
"core-js": "^2.4.1",
"hammerjs": "^2.0.8",
"material-design-icons": "^3.0.1",
+ "ngrx-store-localstorage": "^5.0.0",
+ "reselect": "^3.0.1",
"rxjs": "^5.5.6",
"zone.js": "^0.8.19"
},
diff --git a/protractor.conf.js b/protractor.conf.js
index 7ee3b5e..584292a 100644
--- a/protractor.conf.js
+++ b/protractor.conf.js
@@ -12,7 +12,7 @@ exports.config = {
'browserName': 'chrome'
},
directConnect: true,
- baseUrl: 'http://localhost:4200/',
+ baseUrl: 'http://163.172.130.175:8888/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index f257139..e931796 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -2,6 +2,11 @@ import { BrowserModule } from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { RouterModule, Routes} from '@angular/router';
+import {HttpModule, Http} from '@angular/http';
+import {CommonModule} from '@angular/common';
+import {TranslateModule, TranslateStore} from '@ngx-translate/core';
+import {CovalentLoadingModule} from '@covalent/core';
+
import {
MatAutocompleteModule,
MatButtonModule,
@@ -38,7 +43,7 @@ import {
} from '@angular/material';
-import { NgModule } from '@angular/core';
+import {LOCALE_ID, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@@ -64,7 +69,47 @@ import { ViewOfficesComponent } from './office/view-offices/view-offices.compone
import { AddLedgerComponent } from './accounting/add-ledger/add-ledger.component';
import { AccountPayableComponent } from './accounting/account-payable/account-payable.component';
import { AddChequeComponent } from './accounting/add-cheque/add-cheque.component';
-import { AddPayrollComponent } from './accounting/add-payroll/add-payroll.component'
+import { AddPayrollComponent } from './accounting/add-payroll/add-payroll.component';
+
+import {HttpClient} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/http/http.service';
+import {IdentityService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/identity/identity.service';
+import {OfficeService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/office/office.service';
+import {CustomerService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/customer/customer.service';
+import {AuthenticationService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authn/authentication.service';
+import {CatalogService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/catalog/catalog.service';
+import {AccountingService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/accounting/accounting.service';
+import {PortfolioService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/portfolio/portfolio.service';
+import {TranslateLoader, TranslateService} from '@ngx-translate/core';
+import {TranslateHttpLoader} from '@ngx-translate/http-loader';
+import {PermittableGroupIdMapper} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authz/permittable-group-id-mapper';
+import {reducer} from './store';
+import {StoreModule} from '@ngrx/store';
+import {EffectsModule} from '@ngrx/effects';
+import {NotificationService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/notification/notification.service';
+import {OfficeSearchApiEffects} from './store/office/effects/service.effects';
+import {EmployeeSearchApiEffects} from './store/employee/effects/service.effects';
+import {RoleSearchApiEffects} from './store/role/effects/service.effects';
+import {CustomerSearchApiEffects} from './store/customer/effects/service.effects';
+import {AccountSearchApiEffects} from './store/account/effects/service.effects';
+import {SecurityRouteEffects} from './store/security/effects/route.effects';
+import {SecurityApiEffects} from './store/security/effects/service.effects';
+import {SecurityNotificationEffects} from './store/security/effects/notification.effects';
+import {LedgerSearchApiEffects} from './store/ledger/effects/service.effects';
+//import {ExistsGuardService} from './common/guards/exists-guard';
+import {CountryService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/country/country.service';
+import {ImageService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/image/image.service';
+import {DepositAccountService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/depositAccount/deposit-account.service';
+import {CurrencyService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/currency/currency.service';
+import {TellerService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/teller-service';
+import {ReportingService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/reporting/reporting.service';
+import {getSelectedLanguage} from './common/i18n/translate';
+import {ChequeService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/cheque/cheque.service';
+import {PayrollService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/payroll/payroll.service';
+
+export function HttpLoaderFactory(http: Http) {
+ return new TranslateHttpLoader(http, './assets/i18n/', '.json');
+}
+
const appRoutes: Routes = [
{ path: 'login', component: LoginComponent },
@@ -102,10 +147,39 @@ const appRoutes: Routes = [
declarations: [
AppComponent,LoginComponent, NavbarComponent, DashboardComponent,
AccountingComponent, GeneralLedgerComponent, AddJournalEntryComponent,
- PayrollsComponent, ChartOfAccountsComponent, AddTransactionTypeComponent, TrialBalanceComponent, ChequeClearingComponent, TransactionTypeComponent, AddMemberComponent, ManageMembersComponent, AddEmployeeComponent, ManageEmployeeComponent, AddOfficeComponent, ViewOfficesComponent, AddLedgerComponent, AccountPayableComponent, AddChequeComponent, AddPayrollComponent
+ PayrollsComponent, ChartOfAccountsComponent, AddTransactionTypeComponent,
+ TrialBalanceComponent, ChequeClearingComponent, TransactionTypeComponent,
+ AddMemberComponent, ManageMembersComponent, AddEmployeeComponent, ManageEmployeeComponent, AddOfficeComponent,
+ ViewOfficesComponent, AddLedgerComponent, AccountPayableComponent, AddChequeComponent, AddPayrollComponent,
+
],
imports: [RouterModule.forRoot(appRoutes),
BrowserModule, BrowserAnimationsModule,
+ CommonModule, TranslateModule,CovalentLoadingModule,
+ FormsModule, ReactiveFormsModule,HttpModule,
+ TranslateModule.forRoot({
+ loader: {
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [Http]
+ }
+ }),
+ StoreModule.provideStore(reducer),
+
+ /**
+ * Root effects
+ */
+ EffectsModule.run(SecurityApiEffects),
+ EffectsModule.run(SecurityRouteEffects),
+ EffectsModule.run(SecurityNotificationEffects),
+
+ EffectsModule.run(OfficeSearchApiEffects),
+ EffectsModule.run(EmployeeSearchApiEffects),
+ EffectsModule.run(CustomerSearchApiEffects),
+ EffectsModule.run(AccountSearchApiEffects),
+ EffectsModule.run(RoleSearchApiEffects),
+ EffectsModule.run(LedgerSearchApiEffects),
+
MatAutocompleteModule,
MatButtonModule,
MatButtonToggleModule,
@@ -139,7 +213,31 @@ const appRoutes: Routes = [
MatTabsModule,
MatStepperModule
],
- providers: [],
+ providers: [ HttpClient,
+ AuthenticationService,
+ PermittableGroupIdMapper,
+ IdentityService,
+ OfficeService,
+ CustomerService,
+ CatalogService,
+ AccountingService,
+ PortfolioService,
+ DepositAccountService,
+ TellerService,
+ ReportingService,
+ ChequeService,
+ PayrollService,
+ CountryService,
+ CurrencyService,
+ NotificationService,
+ TranslateService,
+
+ // ExistsGuardService,
+ // ...appRoutingProviders,
+ ImageService,
+ {
+ provide: LOCALE_ID, useFactory: getSelectedLanguage, deps: [TranslateService],
+ } ],
bootstrap: [AppComponent]
})
export class AppModule { }
diff --git a/src/app/common/data-table/data-table.component.html b/src/app/common/data-table/data-table.component.html
new file mode 100644
index 0000000..88eb3c1
--- /dev/null
+++ b/src/app/common/data-table/data-table.component.html
@@ -0,0 +1,74 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<div class="mat-content">
+ <table td-data-table>
+ <thead>
+ <tr td-data-table-column-row>
+ <th td-data-table-column
+ *ngFor="let column of _columns"
+ [numeric]="column.numeric"
+ [sortable]="sortable"
+ [name]="column.name"
+ [active]="currentSort.sortColumn === column.name"
+ [sortOrder]="currentSort.sortColumn === column.name ? currentSort.sortDirection : ''"
+ (sortChange)="sortChanged($event)">
+ {{column.label}}
+ </th>
+ <th td-data-table-column *ngIf="actionColumn"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr td-data-table-row *ngFor="let row of data?.data">
+ <ng-container *ngFor="let column of _columns">
+ <td td-data-table-cell [numeric]="column.numeric" *ngIf="!isBoolean(row[column.name])">
+ {{column.format ? column.format(row[column.name]) : row[column.name]}}
+ </td>
+ <td td-data-table-cell *ngIf="isBoolean(row[column.name])">
+ <mat-icon *ngIf="row[column.name]">check</mat-icon>
+ <mat-icon *ngIf="!row[column.name]">close</mat-icon>
+ </td>
+ </ng-container>
+ <td td-data-table-cell (click)="actionCellClick(row)" *ngIf="actionColumn">
+ <button mat-button class="mat-accent">{{ actionColumnLabel | translate}}</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="mat-padding" *ngIf="!hasData && !loading" layout="row" layout-align="center center">
+ <h3 translate>No results to display.</h3>
+ </div>
+
+ <div class="mat-padding" *ngIf="loading" layout="row" layout-align="center center">
+ <h3 translate>Fetching results...</h3>
+ </div>
+
+ <td-paging-bar #pagingBar
+ *ngIf="pageable"
+ [pageSize]="currentPage.size"
+ [total]="data?.totalElements"
+ (change)="page($event)">
+ <span hide-xs translate>Rows per page</span>
+ <mat-select [style.width.px]="50" [(ngModel)]="currentPage.size">
+ <mat-option *ngFor="let size of pageSizes" [value]="size">
+ {{size}}
+ </mat-option>
+ </mat-select>
+ {{pagingBar.range}} <span hide-xs translate>of</span><span> {{pagingBar.total}}</span>
+ </td-paging-bar>
+</div>
diff --git a/src/app/common/data-table/data-table.component.spec.ts b/src/app/common/data-table/data-table.component.spec.ts
new file mode 100644
index 0000000..edfc95f
--- /dev/null
+++ b/src/app/common/data-table/data-table.component.spec.ts
@@ -0,0 +1,158 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Component, DebugElement, EventEmitter, ViewChild} from '@angular/core';
+import {DataTableComponent, TableData, TableFetchRequest} from './data-table.component';
+import {
+ CovalentDataTableModule,
+ CovalentPagingModule,
+ ITdDataTableColumn,
+ TdDataTableColumnComponent,
+ TdDataTableSortingOrder
+} from '@covalent/core';
+import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
+import {By} from '@angular/platform-browser';
+import {TranslateModule} from '@ngx-translate/core';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
+import {MatIconModule, MatOptionModule, MatSelectModule} from '@angular/material';
+import {FormsModule} from '@angular/forms';
+
+describe('Test data table component', () => {
+
+ let fixture: ComponentFixture<TestComponent>;
+
+ let testComponent: TestComponent;
+
+ let columns: DebugElement[];
+
+ // function click(element: DebugElement) {
+ // element.triggerEventHandler('click', new Event('click'));
+ // }
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ declarations: [
+ TestComponent,
+ DataTableComponent
+ ],
+ imports: [
+ TranslateModule.forRoot(),
+ NoopAnimationsModule,
+ FormsModule,
+ MatSelectModule,
+ MatOptionModule,
+ MatIconModule,
+ CovalentDataTableModule,
+ CovalentPagingModule
+ ]
+
+ });
+
+ fixture = TestBed.createComponent(TestComponent);
+ testComponent = fixture.componentInstance;
+
+ fixture.detectChanges();
+
+ columns = fixture.debugElement.queryAll(By.directive(TdDataTableColumnComponent));
+ });
+
+ it('should render 2 columns', () => {
+ expect(columns.length).toEqual(2);
+ });
+
+ it('should sort ascending', fakeAsync(() => {
+ const expectedResult: TableFetchRequest = {
+ sort: { sortDirection: 'DESC', sortColumn: 'identifier' },
+ page: { pageIndex: 0, size: 10 }
+ };
+
+ let result: TableFetchRequest;
+
+ testComponent.fetchRequestEmitter.subscribe(fetchRequest => result = fetchRequest);
+
+ // TODO figure out why click does not come through
+ // click(columns[0]);
+
+ testComponent.dataTableComponent.sortChanged({
+ order: TdDataTableSortingOrder.Ascending,
+ name: 'identifier'
+ });
+
+ fixture.detectChanges();
+
+ tick();
+
+ expect(result).toEqual(expectedResult);
+ }));
+
+ it('should sort descending', fakeAsync(() => {
+ const expectedResult: TableFetchRequest = {
+ sort: { sortDirection: 'ASC', sortColumn: 'name' },
+ page: { pageIndex: 0, size: 10 }
+ };
+
+ let result: TableFetchRequest;
+
+ testComponent.fetchRequestEmitter.subscribe(fetchRequest => result = fetchRequest);
+
+ // TODO figure out why click does not come through
+ // click(columns[0]);
+
+ testComponent.dataTableComponent.sortChanged({
+ order: TdDataTableSortingOrder.Descending,
+ name: 'name'
+ });
+
+ fixture.detectChanges();
+
+ tick();
+
+ expect(result).toEqual(expectedResult);
+ }));
+
+});
+
+@Component({
+ template: `
+ <fims-data-table #datatable [data]="tableData" [columns]="columns" (onFetch)="onFetch($event)" [sortable]="true" [actionColumn]="false">
+ </fims-data-table>`
+})
+class TestComponent {
+
+ fetchRequestEmitter = new EventEmitter<TableFetchRequest>();
+
+ tableData: TableData = {
+ data: [{
+ identifier: 'test',
+ name: 'test'
+ }],
+ totalElements: 1,
+ totalPages: 1
+ };
+
+ columns: ITdDataTableColumn[] = [
+ { name: 'identifier', label: 'identifier', sortable: true },
+ { name: 'name', label: 'name', sortable: true }
+ ];
+
+ @ViewChild('datatable') dataTableComponent: DataTableComponent;
+
+ onFetch(fetchRequest: TableFetchRequest): void {
+ this.fetchRequestEmitter.emit(fetchRequest);
+ }
+}
diff --git a/src/app/common/data-table/data-table.component.ts b/src/app/common/data-table/data-table.component.ts
new file mode 100644
index 0000000..9035975
--- /dev/null
+++ b/src/app/common/data-table/data-table.component.ts
@@ -0,0 +1,129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Component, EventEmitter, Input, Output} from '@angular/core';
+import {Sort} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/domain/paging/sort.model';
+import {Page} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/domain/paging/page.model';
+import {IPageChangeEvent, ITdDataTableColumn, ITdDataTableSortChangeEvent, TdDataTableSortingOrder} from '@covalent/core';
+import {TranslateService} from '@ngx-translate/core';
+
+export interface TableData {
+ data: any[];
+ totalElements: number;
+ totalPages: number;
+}
+
+export interface TableFetchRequest {
+ page: Page;
+ sort: Sort;
+}
+
+@Component({
+ selector: 'fims-data-table',
+ templateUrl: './data-table.component.html'
+})
+export class DataTableComponent {
+
+ pageSizes: number[] = [10, 15, 20];
+
+ private currentPage: Page = {
+ pageIndex: 0,
+ size: this.pageSizes[0]
+ };
+
+ private currentSort: Sort = {
+ sortColumn: 'identifier',
+ sortDirection: 'ASC'
+ };
+
+ _columns: any[];
+
+ @Input('data') data: TableData = {
+ totalElements: 0,
+ totalPages: 0,
+ data: []
+ };
+
+ @Input() set columns(columns: ITdDataTableColumn[]) {
+ columns.forEach((column) => {
+ this.translate.get(column.label)
+ .subscribe((value) => {
+ column.label = value;
+ column.tooltip = value;
+ });
+ });
+ this._columns = columns;
+ };
+
+ @Input() sortable = false;
+
+ @Input() set sortBy(sortBy: string) {
+ this.currentSort.sortColumn = sortBy;
+ }
+
+ @Input() pageable = false;
+
+ @Input() actionColumn = true;
+
+ @Input() actionColumnLabel = 'SHOW';
+
+ @Input() loading = false;
+
+ @Output() onFetch: EventEmitter<TableFetchRequest> = new EventEmitter<TableFetchRequest>();
+
+ @Output() onActionCellClick: EventEmitter<any> = new EventEmitter<any>();
+
+ constructor(private translate: TranslateService) {}
+
+ page(pagingEvent: IPageChangeEvent): void {
+ this.currentPage = {
+ pageIndex: pagingEvent.page - 1,
+ size: pagingEvent.pageSize
+ };
+ this.fetch();
+ }
+
+ sortChanged(event: ITdDataTableSortChangeEvent): void {
+ this.currentSort = {
+ sortDirection: event.order === TdDataTableSortingOrder.Ascending ? 'DESC' : 'ASC',
+ sortColumn: event.name
+ };
+ this.fetch();
+ }
+
+ private fetch() {
+ const fetchRequest: TableFetchRequest = {
+ page: this.currentPage,
+ sort: this.currentSort
+ };
+ this.onFetch.emit(fetchRequest);
+ }
+
+ actionCellClick(row): void {
+ this.onActionCellClick.emit(row);
+ }
+
+ get hasData(): boolean {
+ return this.data && this.data.data && this.data.data.length > 0;
+ }
+
+ isBoolean(value: any): boolean {
+ return typeof(value) === 'boolean';
+ }
+
+}
diff --git a/src/app/common/i18n/translate.ts b/src/app/common/i18n/translate.ts
new file mode 100644
index 0000000..b96aa8e
--- /dev/null
+++ b/src/app/common/i18n/translate.ts
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {TranslateService} from '@ngx-translate/core';
+
+export const TRANSLATE_STORAGE_KEY = 'fims-translate-lang';
+
+export function getSelectedLanguage(translateService: TranslateService): string {
+ const storedLanguage: string = sessionStorage.getItem(TRANSLATE_STORAGE_KEY);
+
+ if (storedLanguage && translateService.getLangs().indexOf(storedLanguage) > -1) {
+ return storedLanguage;
+ } else if (translateService.getLangs().indexOf(translateService.getBrowserLang()) > -1) {
+ return translateService.getBrowserLang();
+ }
+
+ return translateService.getDefaultLang();
+}
diff --git a/src/app/common/regex/escape.ts b/src/app/common/regex/escape.ts
new file mode 100644
index 0000000..3765c77
--- /dev/null
+++ b/src/app/common/regex/escape.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export function escapeRegexPattern(value?: string): string {
+ if (!value) {
+ return '';
+ }
+
+ return value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+}
diff --git a/src/app/common/store/action-creator/action-creator.ts b/src/app/common/store/action-creator/action-creator.ts
new file mode 100644
index 0000000..1034751
--- /dev/null
+++ b/src/app/common/store/action-creator/action-creator.ts
@@ -0,0 +1,177 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {type} from '../../../store/util';
+import {
+ LoadAction,
+ LoadActionPayload,
+ LoadAllAction,
+ LoadAllCompleteAction,
+ LoadAllCompleteActionPayload,
+ ResourceAction,
+ ResourceActionPayload,
+ ResourceActions,
+ SelectAction,
+ SelectActionPayload
+} from './actions';
+
+export type Actions<T> = LoadAllAction | LoadAllCompleteAction<T>;
+
+export function createResourceActions<T>(name: string): ResourceActions<T> {
+
+ const LOAD_ALL = type(`[${name}] Load All`);
+ const LOAD_ALL_COMPLETE = type(`[${name}] Load All Complete`);
+
+ const LOAD = type(`[${name}] Load`);
+
+ const SELECT = type(`[${name}] Select`);
+
+ const CREATE = type(`[${name}] Create`);
+ const CREATE_SUCCESS = type(`[${name}] Create Success`);
+ const CREATE_FAIL = type(`[${name}] Create Fail`);
+
+ const UPDATE = type(`[${name}] Update`);
+ const UPDATE_SUCCESS = type(`[${name}] Update Success`);
+ const UPDATE_FAIL = type(`[${name}] Update Fail`);
+
+ const DELETE = type(`[${name}] Delete`);
+ const DELETE_SUCCESS = type(`[${name}] Delete Success`);
+ const DELETE_FAIL = type(`[${name}] Delete Fail`);
+
+ function loadAllAction(payload?: any): LoadAllAction {
+ return {
+ payload,
+ type: LOAD_ALL
+ };
+ }
+
+ function loadAllCompleteAction(payload?: LoadAllCompleteActionPayload<T>): LoadAllCompleteAction<T> {
+ return {
+ payload,
+ type: LOAD_ALL_COMPLETE
+ };
+ }
+
+ function loadAction(payload: LoadActionPayload<T>): LoadAction<T> {
+ return {
+ payload,
+ type: LOAD
+ };
+ }
+
+ function selectAction(payload: SelectActionPayload): SelectAction {
+ return {
+ payload,
+ type: SELECT
+ };
+ }
+
+ function createAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: CREATE
+ };
+ }
+
+ function createSuccessAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: CREATE_SUCCESS
+ };
+ }
+
+ function createFailAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: CREATE_FAIL
+ };
+ }
+
+ function updateAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: UPDATE
+ };
+ }
+
+ function updateSuccessAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: UPDATE_SUCCESS
+ };
+ }
+
+ function updateFailAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: UPDATE_FAIL
+ };
+ }
+
+ function deleteAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: DELETE
+ };
+ }
+
+ function deleteSuccessAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: DELETE_SUCCESS
+ };
+ }
+
+ function deleteFailAction(payload: ResourceActionPayload<T>): ResourceAction<T> {
+ return {
+ payload,
+ type: DELETE_FAIL
+ };
+ }
+
+ return {
+ LOAD_ALL,
+ LOAD_ALL_COMPLETE,
+ LOAD,
+ SELECT,
+ CREATE,
+ CREATE_SUCCESS,
+ CREATE_FAIL,
+ UPDATE,
+ UPDATE_SUCCESS,
+ UPDATE_FAIL,
+ DELETE,
+ DELETE_SUCCESS,
+ DELETE_FAIL,
+ loadAllAction,
+ loadAllCompleteAction,
+ loadAction,
+ selectAction,
+ createAction,
+ createSuccessAction,
+ createFailAction,
+ updateAction,
+ updateSuccessAction,
+ updateFailAction,
+ deleteAction,
+ deleteSuccessAction,
+ deleteFailAction
+ };
+}
+
+
diff --git a/src/app/common/store/action-creator/actions.ts b/src/app/common/store/action-creator/actions.ts
new file mode 100644
index 0000000..f14f743
--- /dev/null
+++ b/src/app/common/store/action-creator/actions.ts
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Action} from '@ngrx/store';
+
+// Actions
+export interface LoadAllAction extends Action {
+ payload?: any;
+}
+
+export interface LoadAllCompleteAction<T> extends Action {
+ payload?: LoadAllCompleteActionPayload<T>;
+}
+
+export interface LoadAction<T> extends Action {
+ payload: LoadActionPayload<T>;
+}
+
+export interface SelectAction extends Action {
+ payload: SelectActionPayload;
+}
+
+export interface ResourceAction<T> extends Action {
+ payload: ResourceActionPayload<T>;
+}
+
+interface DataPayload {
+ data?: any;
+}
+
+// Payload
+export interface LoadAllCompleteActionPayload<T> extends DataPayload {
+ resources: T[];
+}
+
+export interface LoadActionPayload<T> extends DataPayload {
+ resource: T;
+}
+
+export interface SelectActionPayload extends DataPayload {
+ identifier: string;
+}
+
+export interface ResourceActionPayload<T> extends DataPayload {
+ resource: T;
+}
+
+export interface ResourceSuccessActionPayload<T> extends DataPayload {
+ resource: T;
+}
+
+export interface ResourceFailActionPayload<T> extends DataPayload {
+ resource: T;
+ error: Error;
+}
+
+export interface ResourceActions<T> {
+ LOAD_ALL: string;
+ LOAD_ALL_COMPLETE: string;
+ LOAD: string;
+ SELECT: string;
+ CREATE: string;
+ CREATE_SUCCESS: string;
+ CREATE_FAIL: string;
+ UPDATE: string;
+ UPDATE_SUCCESS: string;
+ UPDATE_FAIL: string;
+ DELETE: string;
+ DELETE_SUCCESS: string;
+ DELETE_FAIL: string;
+
+ loadAllAction(payload?: any): LoadAllAction;
+ loadAllCompleteAction(payload?: LoadAllCompleteActionPayload<T>): LoadAllCompleteAction<T>;
+ loadAction(payload: LoadActionPayload<T>): LoadAction<T>;
+ selectAction(payload: SelectActionPayload): SelectAction;
+ createAction(payload: ResourceActionPayload<T>): ResourceAction<T>;
+ createSuccessAction(payload: ResourceSuccessActionPayload<T>): ResourceAction<T>;
+ createFailAction(payload: ResourceFailActionPayload<T>): ResourceAction<T>;
+ updateAction(payload: ResourceActionPayload<T>): ResourceAction<T>;
+ updateSuccessAction(payload: ResourceSuccessActionPayload<T>): ResourceAction<T>;
+ updateFailAction(payload: ResourceFailActionPayload<T>): ResourceAction<T>;
+ deleteAction(payload: ResourceActionPayload<T>): ResourceAction<T>;
+ deleteSuccessAction(payload: ResourceSuccessActionPayload<T>): ResourceAction<T>;
+ deleteFailAction(payload: ResourceFailActionPayload<T>): ResourceAction<T>;
+}
diff --git a/src/app/common/store/form.reducer.spec.ts b/src/app/common/store/form.reducer.spec.ts
new file mode 100644
index 0000000..494df59
--- /dev/null
+++ b/src/app/common/store/form.reducer.spec.ts
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {createFormReducer, FormState} from './form.reducer';
+import {Error} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/domain/error.model';
+import {Action} from '@ngrx/store';
+
+class CreateSuccessAction implements Action {
+ readonly type = '[Test] Create Success';
+
+ constructor() {}
+}
+
+class CreateFailAction implements Action {
+ readonly type = '[Test] Create Fail';
+
+ constructor(public payload: Error) {}
+}
+
+class UpdateSuccessAction implements Action {
+ readonly type = '[Test] Update Success';
+
+ constructor() {}
+}
+
+class UpdateFailAction implements Action {
+ readonly type = '[Test] Update Fail';
+
+ constructor(public payload: Error) {}
+}
+
+describe('Resources Reducer', () => {
+
+ let reducer;
+
+ beforeEach(() => {
+ reducer = createFormReducer('Test');
+ });
+
+ it('should set error on Create Fail Action', () => {
+ const expectedResult: FormState = {
+ error: new Error(409, 'test', 'test')
+ };
+
+ const result = reducer(undefined, new CreateFailAction(expectedResult.error));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should set error on Update Fail Action', () => {
+ const expectedResult: FormState = {
+ error: new Error(409, 'test', 'test')
+ };
+
+ const result = reducer(undefined, new UpdateFailAction(expectedResult.error));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should reset error on Create Success Action', () => {
+ const expectedResult: FormState = {};
+
+ const result = reducer(undefined, new CreateSuccessAction());
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should reset error on Update Success Action', () => {
+ const expectedResult: FormState = {};
+
+ const result = reducer(undefined, new UpdateSuccessAction());
+
+ expect(result).toEqual(expectedResult);
+ });
+});
diff --git a/src/app/common/store/form.reducer.ts b/src/app/common/store/form.reducer.ts
new file mode 100644
index 0000000..6a28bd0
--- /dev/null
+++ b/src/app/common/store/form.reducer.ts
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Action, ActionReducer} from '@ngrx/store';
+import {Error} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/domain/error.model';
+
+export interface FormState {
+ error?: Error;
+}
+
+export const initialState: FormState = {};
+
+export const createFormReducer = (resource: string, reducer?: ActionReducer<FormState>) => {
+
+ return function(state: FormState = initialState, action: Action): FormState {
+
+ switch (action.type) {
+
+ case `[${resource}] Create Fail`:
+ case `[${resource}] Update Fail`: {
+ return Object.assign({}, state, {
+ error: action.payload
+ });
+ }
+
+ case `[${resource}] Reset Form`:
+ case `[${resource}] Create Success`:
+ case `[${resource}] Update Success`: {
+ return initialState;
+ }
+
+ default: {
+ // delegate to wrapped reducer
+ if (reducer) {
+ return reducer(state, action);
+ }
+ return state;
+ }
+
+ }
+ };
+};
+
+export const getFormError = (formState: FormState) => formState.error;
+
diff --git a/src/app/common/store/reducer.helper.spec.ts b/src/app/common/store/reducer.helper.spec.ts
new file mode 100644
index 0000000..e27124c
--- /dev/null
+++ b/src/app/common/store/reducer.helper.spec.ts
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {idsToHashWithCurrentTimestamp, resourcesToHash} from './reducer.helper';
+
+describe('Reducer Helper', () => {
+
+ it('should create hash with default identifier', () => {
+ const payload = [
+ { identifier: 'a', value: 'test value'},
+ { identifier: 'b', value: 'test value'}
+ ];
+
+ const expectedResult = {
+ a: payload[0],
+ b: payload[1],
+ };
+
+ const result = resourcesToHash(payload);
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should create hash with custom identifier', () => {
+ const payload = [
+ { customIdentifier: 'a', value: 'test value'},
+ { customIdentifier: 'b', value: 'test value'}
+ ];
+
+ const expectedResult = {
+ a: payload[0],
+ b: payload[1],
+ };
+
+ const result = resourcesToHash(payload, 'customIdentifier');
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should create hash with current timestamp', () => {
+ spyOn(Date, 'now').and.returnValue(1000);
+
+ const expectedResult = {
+ a: 1000,
+ b: 1000
+ };
+
+ const ids = ['a', 'b'];
+
+ const result = idsToHashWithCurrentTimestamp(ids);
+
+ expect(result).toEqual(expectedResult);
+ });
+
+});
diff --git a/src/app/common/store/reducer.helper.ts b/src/app/common/store/reducer.helper.ts
new file mode 100644
index 0000000..b0baea4
--- /dev/null
+++ b/src/app/common/store/reducer.helper.ts
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export function resourcesToHash(resources: any[], identifier: string = 'identifier') {
+ const hash = {};
+
+ resources.forEach(resource => hash[resource[identifier]] = resource);
+
+ return hash;
+}
+
+export function idsToHashWithCurrentTimestamp(ids: string[]): { [id: string]: number } {
+ const loadedAt = ids.reduce((entities: { [id: string]: number }, id: string) => {
+ return Object.assign(entities, {
+ [id]: Date.now()
+ });
+ }, {});
+
+ return loadedAt;
+}
diff --git a/src/app/common/store/resource.reducer.spec.ts b/src/app/common/store/resource.reducer.spec.ts
new file mode 100644
index 0000000..aeac748
--- /dev/null
+++ b/src/app/common/store/resource.reducer.spec.ts
@@ -0,0 +1,171 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {
+ createResourceReducer,
+ CreateResourceSuccessPayload,
+ DeleteResourceSuccessPayload,
+ LoadResourcePayload,
+ ResourceState,
+ UpdateResourceSuccessPayload
+} from './resource.reducer';
+import {Action} from '@ngrx/store';
+
+class LoadAction implements Action {
+ readonly type = '[Test] Load';
+
+ constructor(public payload: LoadResourcePayload) { }
+}
+
+class SelectAction implements Action {
+ readonly type = '[Test] Select';
+
+ constructor(public payload: string) { }
+}
+
+class CreateSuccessAction implements Action {
+ readonly type = '[Test] Create Success';
+
+ constructor(public payload: CreateResourceSuccessPayload) { }
+}
+
+class UpdateSuccessAction implements Action {
+ readonly type = '[Test] Update Success';
+
+ constructor(public payload: UpdateResourceSuccessPayload) { }
+}
+
+class DeleteSuccessAction implements Action {
+ readonly type = '[Test] Delete Success';
+
+ constructor(public payload: DeleteResourceSuccessPayload) { }
+}
+
+describe('Resources Reducer', () => {
+
+ let reducer;
+
+ beforeEach(() => {
+ reducer = createResourceReducer('Test');
+ });
+
+ it('should set selected id', () => {
+ const expectedResult: ResourceState = {
+ selectedId: 'test',
+ entities: {},
+ loadedAt: {},
+ ids: [],
+ };
+
+ const result = reducer(undefined, new SelectAction('test'));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should add resource on load', () => {
+ spyOn(Date, 'now').and.returnValue(1000);
+
+ const resource = {
+ identifier: 'test',
+ name: 'test'
+ };
+
+ const expectedResult: ResourceState = {
+ selectedId: null,
+ entities: {
+ 'test': resource
+ },
+ loadedAt: {
+ 'test': 1000
+ },
+ ids: ['test'],
+ };
+
+ const result = reducer(undefined, new LoadAction({
+ resource: resource
+ }));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should add resource when create success', () => {
+ const resource = {
+ identifier: 'test',
+ name: 'test'
+ };
+
+ const expectedResult: ResourceState = {
+ selectedId: null,
+ entities: {
+ 'test': resource
+ },
+ loadedAt: {},
+ ids: ['test'],
+ };
+
+ const result = reducer(undefined, new CreateSuccessAction({
+ resource: resource,
+ activatedRoute: null
+ }));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should update resource when update success', () => {
+ const updatedResource = {
+ identifier: 'test',
+ name: 'newValue'
+ };
+
+ const initialState: ResourceState = {
+ selectedId: null,
+ entities: {
+ 'test': {
+ name: 'oldValue'
+ }
+ },
+ loadedAt: {},
+ ids: ['test'],
+ };
+
+ const expectedResult: ResourceState = {
+ selectedId: null,
+ entities: {
+ 'test': updatedResource
+ },
+ loadedAt: {},
+ ids: ['test'],
+ };
+
+ const result = reducer(initialState, new UpdateSuccessAction({
+ resource: updatedResource,
+ activatedRoute: null
+ }));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should delete resource when delete success', () => {
+
+ });
+
+ it('should delegate to wrapper reducer on unhandled action', () => {
+
+ });
+
+});
diff --git a/src/app/common/store/resource.reducer.ts b/src/app/common/store/resource.reducer.ts
new file mode 100644
index 0000000..0e360fa
--- /dev/null
+++ b/src/app/common/store/resource.reducer.ts
@@ -0,0 +1,168 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Action, ActionReducer} from '@ngrx/store';
+import {createSelector} from 'reselect';
+import {RoutePayload} from './route-payload';
+
+export interface Resource {
+ identifier: string;
+}
+
+export interface LoadResourcePayload {
+ resource: any;
+}
+
+export interface SelectResourcePayload {
+ selectedId: string;
+}
+
+export interface CreateResourceSuccessPayload extends RoutePayload {
+ resource: any;
+}
+
+export interface UpdateResourceSuccessPayload extends RoutePayload {
+ resource: any;
+}
+
+export interface DeleteResourceSuccessPayload extends RoutePayload {
+ resource: any;
+}
+
+export interface ResourceState {
+ ids: string[];
+ entities: { [id: string]: any };
+ selectedId: string | null;
+ loadedAt: { [id: string]: number };
+}
+
+const initialState: ResourceState = {
+ ids: [],
+ entities: {},
+ loadedAt: {},
+ selectedId: null
+};
+
+export const createResourceReducer =
+ (resourceId: string, reducer?: ActionReducer<ResourceState>, identifierName: string = 'identifier') => {
+
+ const identifier = (resource: any) => resource[identifierName];
+
+ return function (state: ResourceState = initialState, action: Action): ResourceState {
+
+ switch (action.type) {
+
+ case `[${resourceId}] Load`: {
+ const resource = action.payload.resource;
+
+ const newIds = state.ids.filter(id => id !== identifier(resource));
+
+ return {
+ ids: [...newIds, identifier(resource)],
+ entities: Object.assign({}, state.entities, {
+ [identifier(resource)]: resource
+ }),
+ selectedId: state.selectedId,
+ loadedAt: Object.assign({}, state.entities, {
+ [identifier(resource)]: Date.now()
+ })
+ };
+ }
+
+ case `[${resourceId}] Select`: {
+ return Object.assign({}, state, {
+ selectedId: action.payload
+ });
+ }
+
+ case `[${resourceId}] Create Success`: {
+ const resource = action.payload.resource;
+
+ return {
+ ids: [...state.ids, identifier(resource)],
+ entities: Object.assign({}, state.entities, {
+ [identifier(resource)]: resource
+ }),
+ selectedId: state.selectedId,
+ loadedAt: state.loadedAt
+ };
+ }
+
+ case `[${resourceId}] Update Success`: {
+ const resource = action.payload.resource;
+
+ return {
+ ids: state.ids,
+ entities: Object.assign({}, state.entities, {
+ [identifier(resource)]: resource
+ }),
+ selectedId: state.selectedId,
+ loadedAt: state.loadedAt
+ };
+ }
+
+ case `[${resourceId}] Delete Success`: {
+ const resource = action.payload.resource;
+
+ const newIds = state.ids.filter(id => id !== identifier(resource));
+
+ const newEntities = newIds.reduce((entities: { [id: string]: any }, id: string) => {
+ const entity = state.entities[id];
+ return Object.assign(entities, {
+ [identifier(entity)]: entity
+ });
+ }, {});
+
+ const newLoadedAt = newIds.reduce((entities: { [id: string]: any }, id: string) => {
+ const loadedAt = state.loadedAt[id];
+ return Object.assign(entities, {
+ [id]: loadedAt
+ });
+ }, {});
+
+ return {
+ ids: [...newIds],
+ entities: newEntities,
+ loadedAt: newLoadedAt,
+ selectedId: state.selectedId,
+ };
+ }
+
+ default: {
+ // delegate to wrapped reducer
+ if (reducer) {
+ return reducer(state, action);
+ }
+ return state;
+ }
+ }
+ };
+ };
+
+export const getResourceEntities = (cacheState: ResourceState) => cacheState.entities;
+export const getResourceLoadedAt = (cacheState: ResourceState) => cacheState.loadedAt;
+export const getResourceIds = (cacheState: ResourceState) => cacheState.ids;
+export const getResourceSelectedId = (cacheState: ResourceState) => cacheState.selectedId;
+
+export const getResourceSelected = createSelector(getResourceEntities, getResourceSelectedId, (entities, selectedId) => {
+ return entities[selectedId];
+});
+
+export const getResourceAll = createSelector(getResourceEntities, getResourceIds, (entities, ids) => {
+ return ids.map(id => entities[id]);
+});
diff --git a/src/app/common/store/route-payload.ts b/src/app/common/store/route-payload.ts
new file mode 100644
index 0000000..6df7591
--- /dev/null
+++ b/src/app/common/store/route-payload.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ActivatedRoute} from '@angular/router';
+
+export interface RoutePayload {
+ activatedRoute: ActivatedRoute;
+}
diff --git a/src/app/common/store/search.reducer.ts b/src/app/common/store/search.reducer.ts
new file mode 100644
index 0000000..cc387ce
--- /dev/null
+++ b/src/app/common/store/search.reducer.ts
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Action, ActionReducer} from '@ngrx/store';
+import {FetchRequest} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/domain/paging/fetch-request.model';
+import {createSelector} from 'reselect';
+
+export function emptySearchResult(): SearchResult {
+ return {
+ elements: [],
+ totalElements: 0,
+ totalPages: 0
+ };
+}
+
+export interface SearchPayload {
+ fetchRequest: FetchRequest;
+}
+
+export interface SearchResult {
+ elements: any[];
+ totalElements: number;
+ totalPages: number;
+}
+
+export interface SearchState {
+ entities: any[];
+ totalPages: number;
+ totalElements: number;
+ loading: boolean;
+ fetchRequest: FetchRequest;
+}
+
+const initialState: SearchState = {
+ entities: [],
+ totalPages: 0,
+ totalElements: 0,
+ loading: false,
+ fetchRequest: null
+};
+
+export const createSearchReducer = (entityName: string, reducer?: ActionReducer<SearchState>) => {
+ return function(state: SearchState = initialState, action: Action): SearchState {
+
+ switch (action.type) {
+
+ case `[${entityName}] Search`: {
+ const fetchRequest: FetchRequest = action.payload;
+
+ return Object.assign({}, state, {
+ fetchRequest,
+ loading: true,
+ entities: []
+ });
+ }
+
+ case `[${entityName}] Search Complete`: {
+ const searchResult: SearchResult = action.payload;
+
+ return Object.assign({}, state, {
+ entities: searchResult.elements,
+ totalElements: searchResult.totalElements,
+ totalPages: searchResult.totalPages,
+ loading: false
+ });
+ }
+
+ default: {
+ // delegate to wrapped reducer
+ if (reducer) {
+ return reducer(state, action);
+ }
+ return state;
+ }
+ }
+ };
+};
+
+export const getSearchEntities = (state: SearchState) => state.entities;
+export const getSearchTotalElements = (state: SearchState) => state.totalElements;
+export const getSearchTotalPages = (state: SearchState) => state.totalPages;
+export const getSearchLoading = (state: SearchState) => state.loading;
+
+export const getSearchResult = createSelector(getSearchEntities, getSearchTotalElements, getSearchTotalPages,
+ (elements, totalElements, totalPages) => {
+ return {
+ elements,
+ totalElements,
+ totalPages
+ };
+});
diff --git a/src/app/common/testing/input-fields.ts b/src/app/common/testing/input-fields.ts
new file mode 100644
index 0000000..11f5bb7
--- /dev/null
+++ b/src/app/common/testing/input-fields.ts
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ComponentFixture} from '@angular/core/testing';
+import {Observable} from 'rxjs/Observable';
+import {By} from '@angular/platform-browser';
+import {DebugElement} from '@angular/core';
+
+export function setValueByFormControlName(fixture: ComponentFixture<any>, formControlName: string, value: string): Observable<any> {
+ const debugElement: DebugElement = fixture.debugElement.query(By.css(`input[formControlName="${formControlName}"]`));
+
+ if (!debugElement) {
+ throw new Error(`Could not find debug element for form control name: ${formControlName}`);
+ }
+
+ setValue(debugElement, value);
+
+ fixture.detectChanges();
+ return Observable.fromPromise(fixture.whenStable());
+}
+
+export function setValueByCssSelector(fixture: ComponentFixture<any>, selector: string, value: string): Observable<any> {
+ const debugElement: DebugElement = fixture.debugElement.query(By.css(selector));
+
+ if (!debugElement) {
+ throw new Error(`Could not find debug element with selector: ${selector}`);
+ }
+
+ setValue(debugElement, value);
+
+ fixture.detectChanges();
+ return Observable.fromPromise(fixture.whenStable());
+}
+
+function setValue(debugElement: DebugElement, value: string): void {
+ const inputElement: HTMLInputElement = debugElement.nativeElement;
+ inputElement.value = value;
+ inputElement.dispatchEvent(new Event('input'));
+}
diff --git a/src/app/common/testing/permission-stubs.ts b/src/app/common/testing/permission-stubs.ts
new file mode 100644
index 0000000..c7d48cd
--- /dev/null
+++ b/src/app/common/testing/permission-stubs.ts
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Directive, Input} from '@angular/core';
+import {FimsPermission} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authz/fims-permission.model';
+
+@Directive({
+ // tslint:disable-next-line:directive-selector
+ selector: '[hasPermission]'
+})
+export class FimsPermissionStubDirective {
+
+ // tslint:disable-next-line:no-input-rename
+ @Input('hasPermission') permission: FimsPermission;
+
+}
diff --git a/src/app/common/testing/router-stubs.ts b/src/app/common/testing/router-stubs.ts
new file mode 100644
index 0000000..14814fb
--- /dev/null
+++ b/src/app/common/testing/router-stubs.ts
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {BehaviorSubject} from 'rxjs/BehaviorSubject';
+import {NavigationExtras, Params} from '@angular/router';
+import {Component, Directive, Injectable, Input} from '@angular/core';
+
+@Directive({
+ // tslint:disable-next-line:directive-selector
+ selector: '[routerLink]',
+ // tslint:disable-next-line:use-host-property-decorator
+ host: {
+ '(click)': 'onClick()'
+ }
+})
+export class RouterLinkStubDirective {
+ // tslint:disable-next-line:no-input-rename
+ @Input('routerLink') linkParams: any;
+ navigatedTo: any = null;
+
+ onClick() {
+ this.navigatedTo = this.linkParams;
+ }
+}
+
+
+@Component({
+ // tslint:disable-next-line:component-selector
+ selector: 'router-outlet',
+ template: ''
+})
+export class RouterOutletStubComponent { }
+
+@Injectable()
+export class RouterStub {
+ navigate(commands: any[], extras?: NavigationExtras) { }
+}
+
+@Injectable()
+export class ActivatedRouteStub {
+
+ // ActivatedRoute.paramMap is Observable
+ private subject = new BehaviorSubject(this.testParams);
+
+ params = this.subject.asObservable();
+
+ // Test parameters
+ private _testParams: Params;
+
+ get testParams() { return this._testParams; }
+
+ set testParams(params: {}) {
+ this._testParams = params;
+ this.subject.next(this._testParams);
+ }
+
+ // ActivatedRoute.snapshot.paramMap
+ get snapshot() {
+ return { params: this.testParams };
+ }
+}
diff --git a/src/app/common/testing/select-fields.ts b/src/app/common/testing/select-fields.ts
new file mode 100644
index 0000000..afa7cde
--- /dev/null
+++ b/src/app/common/testing/select-fields.ts
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {By} from '@angular/platform-browser';
+import {ComponentFixture} from '@angular/core/testing';
+
+export function clickOption(fixture: ComponentFixture<any>, optionIndex: number): void {
+ const trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
+
+ trigger.click();
+
+ fixture.detectChanges();
+
+ const options = fixture.debugElement.queryAll(By.css('mat-option'));
+
+ options[optionIndex].nativeElement.click();
+
+ fixture.detectChanges();
+}
diff --git a/src/app/common/util/account-assignments.ts b/src/app/common/util/account-assignments.ts
new file mode 100644
index 0000000..2e25946
--- /dev/null
+++ b/src/app/common/util/account-assignments.ts
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountAssignment} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/portfolio/domain/account-assignment.model';
+
+export function findAccountDesignator(accountAssignments: AccountAssignment[], designator: string): AccountAssignment {
+ return accountAssignments.find(assignment => assignment.designator === designator);
+}
+
+export function createAccountAssignment(identifier: string, designator: string): AccountAssignment {
+ return {
+ accountIdentifier: identifier,
+ designator: designator
+ };
+}
+
+export function createLedgerAssignment(identifier: string, designator: string): AccountAssignment {
+ return {
+ ledgerIdentifier: identifier,
+ designator: designator
+ };
+}
+
+export function accountIdentifier(assignment: AccountAssignment): string {
+ return assignment ? assignment.accountIdentifier : undefined;
+}
+
+export function ledgerIdentifier(assignment: AccountAssignment): string {
+ return assignment ? assignment.ledgerIdentifier : undefined;
+}
diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html
index 9bbfd38..4560c05 100644
--- a/src/app/login/login.component.html
+++ b/src/app/login/login.component.html
@@ -6,10 +6,8 @@
<div class="language">
<span class="change">Change language</span>
<mat-form-field class="select-input">
- <mat-select [(value)]="selected">
- <mat-option value="English">English</mat-option>
- <mat-option value="French">French</mat-option>
- <mat-option value="Portoguese">Portoguese</mat-option>
+ <mat-select [(ngModel)]="currentLanguage" name="language" matTooltip="Change Language" matTooltipPosition="right" (change)="selectLanguage($event)">
+ <mat-option *ngFor="let option of languageOptions" [value]="option.id"> {{option.label}}</mat-option>
</mat-select>
</mat-form-field>
</div>
@@ -19,6 +17,7 @@
<img src="assets/fineract.png" class="image">
</div>
<div class="login-div mat-elevation-z2">
+ <form [formGroup]="form" (ngSubmit)="login()">
<br>
<div class="form-div">
<div class="app-input">
@@ -26,7 +25,11 @@
</div>
<div class="app-input1">
<mat-form-field class="app-input2">
- <input matInput placeholder="Tenant">
+ <input matInput placeholder="Tenant" type="text" formControlName="tenant">
+ <mat-error *ngIf="form.get('tenant').hasError('required')">
+ Required
+ </mat-error>
+
</mat-form-field>
</div>
@@ -37,7 +40,10 @@
</div>
<div class="app-input1">
<mat-form-field class="app-input2">
- <input matInput placeholder="Username">
+ <input matInput placeholder="Username" type="text" formControlName="username">
+ <mat-error *ngIf="form.get('password').hasError('required')">
+ Required
+ </mat-error>
</mat-form-field>
</div>
<br>
@@ -47,18 +53,23 @@
</div>
<div class="app-input1">
<mat-form-field class="app-input2">
- <input matInput placeholder="Enter your password" [type]="hide ? 'password' : 'text'">
+ <input matInput placeholder="Password" type="password" formControlName="password" autocomplete="new-password" [type]="hide ? 'password' : 'text'">
+ <mat-error *ngIf="form.get('password').hasError('required')">
+ Required
+ </mat-error>
<mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon>
</mat-form-field>
</div>
<br>
<br>
<p>
- <button mat-raised-button color="primary" type="submit" class="btn" (click)="onLogin()">Sign In</button>
+ <button mat-raised-button color="primary" type="submit" class="btn" [disabled]="form.invalid">Sign In</button>
</p>
<br>
</div>
+ </form>
</div>
+ </div>
diff --git a/src/app/login/login.component.spec.ts b/src/app/login/login.component.spec.ts
index d6d85a8..aa23f4f 100644
--- a/src/app/login/login.component.spec.ts
+++ b/src/app/login/login.component.spec.ts
@@ -1,25 +1,149 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing';
+import {LoginComponent} from './login.component';
+import {Observable} from 'rxjs/Observable';
+import {By} from '@angular/platform-browser';
+import {DebugElement} from '@angular/core';
+import {ActivatedRoute, Router} from '@angular/router';
+import {TranslateModule} from '@ngx-translate/core';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {Store} from '@ngrx/store';
+import {LOGIN} from '../store/security/security.actions';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
+import {CovalentLoadingModule} from '@covalent/core';
+import {setValueByFormControlName} from '../common/testing/input-fields';
+import {MatCardModule, MatIconModule, MatInputModule, MatOptionModule, MatSelectModule, MatTooltipModule} from '@angular/material';
-import { LoginComponent } from './login.component';
+describe('Test Login Component', () => {
-describe('LoginComponent', () => {
- let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
+ let loginComponent: LoginComponent;
+
+ let router: Router;
+
beforeEach(async(() => {
+ router = jasmine.createSpyObj('Router', ['navigate']);
+
TestBed.configureTestingModule({
- declarations: [ LoginComponent ]
- })
- .compileComponents();
- }));
+ declarations: [LoginComponent],
+ imports: [
+ ReactiveFormsModule,
+ FormsModule,
+ TranslateModule.forRoot(),
+ MatIconModule,
+ MatCardModule,
+ MatInputModule,
+ MatSelectModule,
+ MatOptionModule,
+ MatTooltipModule,
+ NoopAnimationsModule,
+ CovalentLoadingModule
+ ],
+ providers: [
+ {provide: 'tenantId', useValue: 'tenantId'},
+ {provide: Router, useValue: router},
+ {provide: ActivatedRoute, useValue: {
+ queryParams: Observable.of([])
+ }},
+ {
+ provide: Store,
+ useClass: class {
+ dispatch = jasmine.createSpy('dispatch');
+ select = jasmine.createSpy('select').and.returnValue(Observable.empty());
+ }
+ }
+ ]
+ });
- beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
- component = fixture.componentInstance;
+ loginComponent = fixture.componentInstance;
+ }));
+
+ it('should disable/enable login button', () => {
fixture.detectChanges();
+
+ const button: DebugElement = fixture.debugElement.query(By.css('button'));
+
+ expect(button.properties['disabled']).toBeTruthy('Button should be disabled');
+
+ loginComponent.form.setValue({
+ tenant: 'tenantId',
+ username: 'test',
+ password: 'test'
+ });
+
+ fixture.detectChanges();
+
+ expect(button.properties['disabled']).toBeFalsy('Button should be enabled');
});
- it('should create', () => {
- expect(component).toBeTruthy();
+ it('should show error message', async(inject([Store], (store: Store<any>) => {
+ store.select = jasmine.createSpy('select').and.returnValue(Observable.of({ error: {} }));
+
+ fixture.detectChanges();
+
+ loginComponent.form.setValue({
+ tenant: 'tenantId',
+ username: 'test',
+ password: 'test'
+ });
+
+ fixture.detectChanges();
+
+ const button: DebugElement = fixture.debugElement.query(By.css('button'));
+ button.nativeElement.click();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+
+ const error: DebugElement = fixture.debugElement.query(By.css('p'));
+ expect(error).toBeDefined('Debug element should be defined');
+ expect(error.nativeElement.textContent.length).toBeGreaterThan(0, 'Error message should not be empty');
+ });
+
+ })));
+
+ it('should set the username', (done: DoneFn) => {
+ fixture.detectChanges();
+ setValueByFormControlName(fixture, 'username', 'test').subscribe(() => {
+ expect(loginComponent.form.get('username').value).toBe('test');
+ done();
+ });
});
+
+ it('should set the password', (done: DoneFn) => {
+ fixture.detectChanges();
+ setValueByFormControlName(fixture, 'password', 'test').subscribe(() => {
+ expect(loginComponent.form.get('password').value).toBe('test');
+ done();
+ });
+ });
+
+ it('should send the right user and password', async(inject([Store], (store: Store<any>) => {
+ fixture.detectChanges();
+
+ loginComponent.form.setValue({
+ tenant: 'tenantId',
+ username: 'test',
+ password: 'test'
+ });
+
+ fixture.detectChanges();
+
+ const button: DebugElement = fixture.debugElement.query(By.css('button'));
+
+ button.nativeElement.click();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ expect(store.dispatch).toHaveBeenCalledWith({ type: LOGIN, payload: {
+ username: 'test',
+ password: 'test',
+ tenant: 'tenantId'
+ }});
+ });
+
+ })));
+
});
+
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts
index 7d1588e..6b92113 100644
--- a/src/app/login/login.component.ts
+++ b/src/app/login/login.component.ts
@@ -1,25 +1,92 @@
-import { Component, OnInit } from '@angular/core';
+import { Component,OnDestroy, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {Router } from '@angular/router'
-
+import { Subscription, Observable } from 'rxjs';
+import { TdLoadingService, LoadingType } from '@covalent/core';
+import { Store } from '@ngrx/store';
+import { ITdLoadingConfig } from '@covalent/core';
+import { LOGIN } from '../store/security/security.actions';
+import { MatSelectChange } from '@angular/material';
+import * as fromRoot from '../store';
+import { TranslateService } from '@ngx-translate/core';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {TRANSLATE_STORAGE_KEY} from '../common/i18n/translate';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
- styleUrls: ['./login.component.scss']
+ styleUrls: ['./login.component.scss'],
+
})
export class LoginComponent implements OnInit {
- selected = 'English';
+ private loadingSubscription: Subscription;
+
+ currentLanguage: string;
+ languageOptions: any[] = [
+ {id: 'en', label: 'Welcome to fims'},
+ {id: 'es', label: 'Bienvenido a fims'}
+ ];
+
hide= true;
+ form: FormGroup;
- constructor(private _router: Router){}
+ error$: Observable<string>;
- onLogin(): void{
- this._router.navigate(['/navbar']);
+ constructor(private _loadingService: TdLoadingService, private translate: TranslateService, private formBuilder: FormBuilder,
+ private store: Store<fromRoot.State>) {
}
ngOnInit() {
+ this.currentLanguage = this.translate.currentLang || this.translate.getDefaultLang();
+
+ const options: ITdLoadingConfig = {
+ name: 'login',
+ type: LoadingType.Circular,
+ };
+
+ this._loadingService.create(options);
+
+ this.form = this.formBuilder.group({
+ tenant: ['', Validators.required],
+ username: ['', Validators.required],
+ password: ['', Validators.required]
+ });
+
+ this.error$ = this.store.select(fromRoot.getAuthenticationError)
+ .filter(error => !!error)
+ .do(() => this.form.get('password').setValue(''))
+ .map(error => 'Sorry, that login did not work.');
+
+ this.loadingSubscription = this.store.select(fromRoot.getAuthenticationLoading).subscribe(loading => {
+ if (loading) {
+ this._loadingService.register('login');
+ } else {
+ this._loadingService.resolve('login');
+ }
+ });
}
+ ngOnDestroy(): void {
+ this.loadingSubscription.unsubscribe();
+ }
+
+ login(): void {
+ const tenant = this.form.get('tenant').value;
+ const username = this.form.get('username').value;
+ const password = this.form.get('password').value;
+
+ this.store.dispatch({
+ type: LOGIN, payload: {
+ username,
+ password,
+ tenant
+ }
+ });
+ }
+
+ selectLanguage(selectChange: MatSelectChange): void {
+ sessionStorage.setItem(TRANSLATE_STORAGE_KEY, selectChange.value);
+ location.reload();
+ }
}
diff --git a/src/app/office/store/effects/notification.effects.ts b/src/app/office/store/effects/notification.effects.ts
new file mode 100644
index 0000000..9b4b52d
--- /dev/null
+++ b/src/app/office/store/effects/notification.effects.ts
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as officeActions from '../office.actions';
+import {NotificationService, NotificationType} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/notification/notification.service';
+
+@Injectable()
+export class OfficeNotificationEffects {
+
+ @Effect({ dispatch: false })
+ createOfficeSuccess$: Observable<Action> = this.actions$
+ .ofType(officeActions.CREATE_SUCCESS, officeActions.UPDATE_SUCCESS)
+ .do(() => this.notificationService.send({
+ type: NotificationType.MESSAGE,
+ message: 'Office is going to be saved'
+ }));
+
+ @Effect({ dispatch: false })
+ deleteOfficeSuccess$: Observable<Action> = this.actions$
+ .ofType(officeActions.DELETE_SUCCESS)
+ .do(() => this.notificationService.send({
+ type: NotificationType.MESSAGE,
+ message: 'Office is going to be deleted'
+ }));
+
+ @Effect({ dispatch: false })
+ deleteOfficeFail$: Observable<Action> = this.actions$
+ .ofType(officeActions.DELETE_FAIL)
+ .do(() => this.notificationService.send({
+ type: NotificationType.ALERT,
+ title: 'Office can\'t be deleted',
+ message: 'Office has either branch offices, employees or teller assigned to it.'
+ }));
+
+ constructor(private actions$: Actions, private notificationService: NotificationService) {
+ }
+}
+
diff --git a/src/app/office/store/effects/route.effects.ts b/src/app/office/store/effects/route.effects.ts
new file mode 100644
index 0000000..8064460
--- /dev/null
+++ b/src/app/office/store/effects/route.effects.ts
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as officeActions from '../office.actions';
+import {Router} from '@angular/router';
+
+@Injectable()
+export class OfficeRouteEffects {
+
+ @Effect({ dispatch: false })
+ createOfficeSuccess$: Observable<Action> = this.actions$
+ .ofType(officeActions.CREATE_SUCCESS)
+ .map(action => action.payload)
+ .do(payload => {
+ if (payload.resource.parentIdentifier) {
+ this.router.navigate(['../detail', payload.resource.parentIdentifier], { relativeTo: payload.activatedRoute });
+ } else {
+ this.router.navigate(['../detail', payload.resource.identifier], { relativeTo: payload.activatedRoute });
+ }
+ });
+
+ @Effect({ dispatch: false })
+ updateOfficeSuccess$: Observable<Action> = this.actions$
+ .ofType(officeActions.UPDATE_SUCCESS)
+ .map(action => action.payload)
+ .do(payload => this.router.navigate(['../../', payload.resource.identifier], { relativeTo: payload.activatedRoute }));
+
+ @Effect({ dispatch: false })
+ deleteOfficeSuccess$: Observable<Action> = this.actions$
+ .ofType(officeActions.DELETE_SUCCESS)
+ .map((action) => action.payload)
+ .do(payload => {
+ if (payload.resource.parentIdentifier) {
+ this.router.navigate(['../../', payload.resource.parentIdentifier], { relativeTo: payload.activatedRoute});
+ } else {
+ this.router.navigate(['../../'], { relativeTo: payload.activatedRoute});
+ }
+ });
+
+ constructor(private actions$: Actions, private router: Router) { }
+}
diff --git a/src/app/office/store/effects/service.effects.ts b/src/app/office/store/effects/service.effects.ts
new file mode 100644
index 0000000..2947d5e
--- /dev/null
+++ b/src/app/office/store/effects/service.effects.ts
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {OfficeService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/office/office.service';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import {of} from 'rxjs/observable/of';
+import * as officeActions from '../office.actions';
+
+@Injectable()
+export class OfficeApiEffects {
+
+ @Effect()
+ createOffice$: Observable<Action> = this.actions$
+ .ofType(officeActions.CREATE)
+ .map((action: officeActions.CreateOfficeAction) => action.payload)
+ .mergeMap(payload =>
+ this.officeService.createOffice(payload.office)
+ .map(() => new officeActions.CreateOfficeSuccessAction({
+ resource: payload.office,
+ activatedRoute: payload.activatedRoute
+ }))
+ .catch((error) => of(new officeActions.CreateOfficeFailAction(error)))
+ );
+
+ @Effect()
+ createBranchOffice$: Observable<Action> = this.actions$
+ .ofType(officeActions.CREATE_BRANCH)
+ .map((action: officeActions.CreateBranchOfficeAction) => action.payload)
+ .mergeMap(payload =>
+ this.officeService.addBranch(payload.office.parentIdentifier, payload.office)
+ .map(() => new officeActions.CreateOfficeSuccessAction({
+ resource: payload.office,
+ activatedRoute: payload.activatedRoute
+ }))
+ .catch((error) => of(new officeActions.CreateOfficeFailAction(error)))
+ );
+
+ @Effect()
+ updateOffice$: Observable<Action> = this.actions$
+ .ofType(officeActions.UPDATE)
+ .map((action: officeActions.UpdateOfficeAction) => action.payload)
+ .mergeMap(payload =>
+ this.officeService.updateOffice(payload.office)
+ .map(() => new officeActions.UpdateOfficeSuccessAction({
+ resource: payload.office,
+ activatedRoute: payload.activatedRoute
+ }))
+ .catch((error) => of(new officeActions.UpdateOfficeFailAction(error)))
+ );
+
+ @Effect()
+ deleteOffice$: Observable<Action> = this.actions$
+ .ofType(officeActions.DELETE)
+ .map((action: officeActions.DeleteOfficeAction) => action.payload)
+ .mergeMap(payload =>
+ this.officeService.deleteOffice(payload.office.identifier)
+ .map(() => new officeActions.DeleteOfficeSuccessAction({
+ resource: payload.office,
+ activatedRoute: payload.activatedRoute
+ }))
+ .catch((error) => of(new officeActions.DeleteOfficeFailAction(error)))
+ );
+
+ constructor(private actions$: Actions, private officeService: OfficeService) {}
+
+}
diff --git a/src/app/office/store/index.ts b/src/app/office/store/index.ts
new file mode 100644
index 0000000..9ae603b
--- /dev/null
+++ b/src/app/office/store/index.ts
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import * as fromRoot from '../../store';
+import * as fromTellers from '../store/teller/tellers.reducer';
+import * as fromDenominations from '../store/teller/denomination/denominations.reducer';
+import {ActionReducer, Store} from '@ngrx/store';
+import {createReducer} from '../../store/index';
+import {createSelector} from 'reselect';
+import {
+ createResourceReducer,
+ getResourceAll,
+ getResourceEntities,
+ getResourceLoadedAt,
+ getResourceSelected,
+ ResourceState
+} from '../../common/store/resource.reducer';
+import {createFormReducer, FormState, getFormError} from '../../common/store/form.reducer';
+
+export interface State extends fromRoot.State {
+ offices: ResourceState;
+ officeForm: FormState;
+ tellers: ResourceState;
+ tellerForm: FormState;
+ denominations: fromDenominations.State;
+}
+
+const reducers = {
+ offices: createResourceReducer('Office'),
+ officeForm: createFormReducer('Office'),
+ tellers: createResourceReducer('Office Teller', fromTellers.reducer, 'code'),
+ tellerForm: createFormReducer('Office Teller'),
+ denominations: fromDenominations.reducer
+};
+
+export const officeModuleReducer: ActionReducer<State> = createReducer(reducers);
+
+export class OfficesStore extends Store<State> {}
+
+export function officeStoreFactory(appStore: Store<fromRoot.State>) {
+ appStore.replaceReducer(officeModuleReducer);
+ return appStore;
+}
+
+export const getOfficesState = (state: State) => state.offices;
+
+export const getOfficeFormState = (state: State) => state.officeForm;
+export const getOfficeFormError = createSelector(getOfficeFormState, getFormError);
+
+export const getOfficeEntities = createSelector(getOfficesState, getResourceEntities);
+export const getOfficesLoadedAt = createSelector(getOfficesState, getResourceLoadedAt);
+export const getSelectedOffice = createSelector(getOfficesState, getResourceSelected);
+
+export const getTellerState = (state: State) => state.tellers;
+
+export const getTellerFormState = (state: State) => state.tellerForm;
+export const getTellerFormError = createSelector(getTellerFormState, getFormError);
+
+export const getAllTellerEntities = createSelector(getTellerState, getResourceAll);
+
+export const getTellersLoadedAt = createSelector(getTellerState, getResourceLoadedAt);
+export const getSelectedTeller = createSelector(getTellerState, getResourceSelected);
+
+export const getDenominationState = (state: State) => state.denominations;
+export const getDenominationsEntities = createSelector(getDenominationState, fromDenominations.getDenominationEntities);
diff --git a/src/app/office/store/office.actions.ts b/src/app/office/store/office.actions.ts
new file mode 100644
index 0000000..82645b2
--- /dev/null
+++ b/src/app/office/store/office.actions.ts
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Action} from '@ngrx/store';
+import {type} from '../../store/util';
+import {Office} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/office/domain/office.model';
+import {Error} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/domain/error.model';
+import {RoutePayload} from '../../common/store/route-payload';
+import {
+ CreateResourceSuccessPayload,
+ DeleteResourceSuccessPayload,
+ LoadResourcePayload,
+ SelectResourcePayload,
+ UpdateResourceSuccessPayload
+} from '../../common/store/resource.reducer';
+
+export const LOAD = type('[Office] Load');
+export const SELECT = type('[Office] Select');
+
+export const CREATE = type('[Office] Create');
+export const CREATE_BRANCH = type('[Office] Create Branch');
+export const CREATE_SUCCESS = type('[Office] Create Success');
+export const CREATE_FAIL = type('[Office] Create Fail');
+
+export const UPDATE = type('[Office] Update');
+export const UPDATE_SUCCESS = type('[Office] Update Success');
+export const UPDATE_FAIL = type('[Office] Update Fail');
+
+export const DELETE = type('[Office] Delete');
+export const DELETE_SUCCESS = type('[Office] Delete Success');
+export const DELETE_FAIL = type('[Office] Delete Fail');
+
+export const RESET_FORM = type('[Office] Reset Form');
+
+export interface OfficeRoutePayload extends RoutePayload {
+ office: Office;
+}
+
+export class LoadAction implements Action {
+ readonly type = LOAD;
+
+ constructor(public payload: LoadResourcePayload) { }
+}
+
+export class SelectAction implements Action {
+ readonly type = SELECT;
+
+ constructor(public payload: SelectResourcePayload) { }
+}
+
+export class CreateOfficeAction implements Action {
+ readonly type = CREATE;
+
+ constructor(public payload: OfficeRoutePayload) { }
+}
+
+export class CreateBranchOfficeAction implements Action {
+ readonly type = CREATE_BRANCH;
+
+ constructor(public payload: OfficeRoutePayload) { }
+}
+
+export class CreateOfficeSuccessAction implements Action {
+ readonly type = CREATE_SUCCESS;
+
+ constructor(public payload: CreateResourceSuccessPayload) { }
+}
+
+export class CreateOfficeFailAction implements Action {
+ readonly type = CREATE_FAIL;
+
+ constructor(public payload: Error) { }
+}
+
+export class UpdateOfficeAction implements Action {
+ readonly type = UPDATE;
+
+ constructor(public payload: OfficeRoutePayload) { }
+}
+
+export class UpdateOfficeSuccessAction implements Action {
+ readonly type = UPDATE_SUCCESS;
+
+ constructor(public payload: UpdateResourceSuccessPayload) { }
+}
+
+export class UpdateOfficeFailAction implements Action {
+ readonly type = UPDATE_FAIL;
+
+ constructor(public payload: Error) { }
+}
+
+export class DeleteOfficeAction implements Action {
+ readonly type = DELETE;
+
+ constructor(public payload: OfficeRoutePayload) { }
+}
+
+export class DeleteOfficeSuccessAction implements Action {
+ readonly type = DELETE_SUCCESS;
+
+ constructor(public payload: DeleteResourceSuccessPayload) { }
+}
+
+export class DeleteOfficeFailAction implements Action {
+ readonly type = DELETE_FAIL;
+
+ constructor(public payload: Error) { }
+}
+
+export class ResetOfficeFormAction implements Action {
+ readonly type = RESET_FORM;
+
+ constructor() {}
+}
+
+export type Actions
+ = LoadAction
+ | SelectAction
+ | CreateOfficeAction
+ | CreateBranchOfficeAction
+ | CreateOfficeSuccessAction
+ | CreateOfficeFailAction
+ | UpdateOfficeAction
+ | UpdateOfficeSuccessAction
+ | UpdateOfficeFailAction
+ | DeleteOfficeAction
+ | DeleteOfficeSuccessAction
+ | DeleteOfficeFailAction
+ | ResetOfficeFormAction;
diff --git a/src/app/office/store/teller/denomination/denomination.actions.ts b/src/app/office/store/teller/denomination/denomination.actions.ts
new file mode 100644
index 0000000..0cb7f42
--- /dev/null
+++ b/src/app/office/store/teller/denomination/denomination.actions.ts
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {type} from '../../../../store/util';
+import {TellerDenomination} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller-denomination.model';
+import {RoutePayload} from '../../../../common/store/route-payload';
+import {Action} from '@ngrx/store';
+
+export const LOAD_DENOMINATION = type('[Teller Denomination] Load All ');
+export const LOAD_DENOMINATION_SUCCESS = type('[Teller Denomination] Load All Success');
+
+export const CREATE_DENOMINATION = type('[Teller Denomination] Create');
+export const CREATE_DENOMINATION_SUCCESS = type('[Teller Denomination] Create Success');
+export const CREATE_DENOMINATION_FAIL = type('[Teller Denomination] Create Fail');
+
+export interface LoadDenominationPayload {
+ officeId: string;
+ tellerCode: string;
+}
+
+export interface DenominationPayload extends RoutePayload {
+ officeId: string;
+ tellerCode: string;
+ denomination: TellerDenomination;
+}
+
+export class LoadDenominationAction implements Action {
+ readonly type = LOAD_DENOMINATION;
+
+ constructor(public payload: LoadDenominationPayload) {}
+}
+
+export class LoadDenominationSuccessAction implements Action {
+ readonly type = LOAD_DENOMINATION_SUCCESS;
+
+ constructor(public payload: TellerDenomination[]) {}
+}
+
+export class CreateDenominationAction implements Action {
+ readonly type = CREATE_DENOMINATION;
+
+ constructor(public payload: DenominationPayload) {}
+}
+
+export class CreateDenominationSuccessAction implements Action {
+ readonly type = CREATE_DENOMINATION_SUCCESS;
+
+ constructor(public payload: DenominationPayload) {}
+}
+
+export class CreateDenominationFailAction implements Action {
+ readonly type = CREATE_DENOMINATION_FAIL;
+
+ constructor(public payload: Error) {}
+}
+
+export type Actions
+ = LoadDenominationAction
+ | LoadDenominationSuccessAction
+ | CreateDenominationAction
+ | CreateDenominationSuccessAction
+ | CreateDenominationFailAction;
diff --git a/src/app/office/store/teller/denomination/denominations.reducer.ts b/src/app/office/store/teller/denomination/denominations.reducer.ts
new file mode 100644
index 0000000..cc5a978
--- /dev/null
+++ b/src/app/office/store/teller/denomination/denominations.reducer.ts
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import * as denominations from './denomination.actions';
+import {DenominationPayload} from './denomination.actions';
+import {TellerDenomination} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller-denomination.model';
+
+export interface State {
+ entities: TellerDenomination[];
+}
+
+export const initialState: State = {
+ entities: [],
+};
+
+export function reducer(state = initialState, action: denominations.Actions): State {
+
+ switch (action.type) {
+
+ case denominations.LOAD_DENOMINATION: {
+ return initialState;
+ }
+
+ case denominations.LOAD_DENOMINATION_SUCCESS: {
+ const denominations: TellerDenomination[] = action.payload;
+
+ return {
+ entities: denominations,
+ };
+ }
+
+ case denominations.CREATE_DENOMINATION_SUCCESS: {
+ const payload: DenominationPayload = action.payload;
+
+ return {
+ entities: state.entities.concat(payload.denomination),
+ };
+ }
+
+ default: {
+ return state;
+ }
+ }
+}
+
+export const getDenominationEntities = (state: State) => state.entities;
diff --git a/src/app/office/store/teller/denomination/effects/notification.effects.ts b/src/app/office/store/teller/denomination/effects/notification.effects.ts
new file mode 100644
index 0000000..1046c48
--- /dev/null
+++ b/src/app/office/store/teller/denomination/effects/notification.effects.ts
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as denominationActions from '../denomination.actions';
+import {NotificationService, NotificationType} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/notification/notification.service';
+
+@Injectable()
+export class TellerDenominationNotificationEffects {
+
+ @Effect({ dispatch: false })
+ createDenominationSuccess$: Observable<Action> = this.actions$
+ .ofType(denominationActions.CREATE_DENOMINATION_SUCCESS)
+ .do(() => this.notificationService.send({
+ type: NotificationType.MESSAGE,
+ message: 'Denomination is going to be saved'
+ }));
+
+ constructor(private actions$: Actions, private notificationService: NotificationService) {
+ }
+}
diff --git a/src/app/office/store/teller/denomination/effects/route.effects.ts b/src/app/office/store/teller/denomination/effects/route.effects.ts
new file mode 100644
index 0000000..4e09777
--- /dev/null
+++ b/src/app/office/store/teller/denomination/effects/route.effects.ts
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Router} from '@angular/router';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as denominationActions from '../denomination.actions';
+
+@Injectable()
+export class TellerDenominationRouteEffects {
+
+ @Effect({ dispatch: false })
+ createDenominationSuccess$: Observable<Action> = this.actions$
+ .ofType(denominationActions.CREATE_DENOMINATION_SUCCESS)
+ .map(action => action.payload)
+ .do(payload => {
+ this.router.navigate(['../'], { relativeTo: payload.activatedRoute });
+ });
+
+ constructor(private actions$: Actions, private router: Router) { }
+}
diff --git a/src/app/office/store/teller/denomination/effects/service.effects.ts b/src/app/office/store/teller/denomination/effects/service.effects.ts
new file mode 100644
index 0000000..8056788
--- /dev/null
+++ b/src/app/office/store/teller/denomination/effects/service.effects.ts
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as denominationActions from '../denomination.actions';
+import {of} from 'rxjs/observable/of';
+import {TellerService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/teller-service';
+
+@Injectable()
+export class TellerDenominationApiEffects {
+
+ @Effect()
+ loadDenomination$: Observable<Action> = this.actions$
+ .ofType(denominationActions.LOAD_DENOMINATION)
+ .map((action: denominationActions.LoadDenominationAction) => action.payload)
+ .mergeMap(payload =>
+ this.tellerService.fetchTellerDenominations(payload.officeId, payload.tellerCode)
+ .map(teller => new denominationActions.LoadDenominationSuccessAction(teller))
+ .catch(error => of(new denominationActions.LoadDenominationSuccessAction([])))
+ );
+
+ @Effect()
+ createDenomination$: Observable<Action> = this.actions$
+ .ofType(denominationActions.CREATE_DENOMINATION)
+ .map((action: denominationActions.CreateDenominationAction) => action.payload)
+ .mergeMap(payload =>
+ this.tellerService.saveTellerDenomination(payload.officeId, payload.tellerCode, payload.denomination)
+ .map(() => new denominationActions.CreateDenominationSuccessAction(payload))
+ .catch((error) => of(new denominationActions.CreateDenominationFailAction(error)))
+ );
+
+ constructor(private actions$: Actions, private tellerService: TellerService) {}
+
+}
diff --git a/src/app/office/store/teller/effects/notification.effects.ts b/src/app/office/store/teller/effects/notification.effects.ts
new file mode 100644
index 0000000..d544943
--- /dev/null
+++ b/src/app/office/store/teller/effects/notification.effects.ts
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Actions, Effect} from '@ngrx/effects';
+import {NotificationService, NotificationType} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/notification/notification.service';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as tellerActions from '../teller.actions';
+
+@Injectable()
+export class TellerNotificationEffects {
+
+ @Effect({ dispatch: false })
+ createTellerSuccess$: Observable<Action> = this.actions$
+ .ofType(tellerActions.CREATE_TELLER_SUCCESS, tellerActions.UPDATE_TELLER_SUCCESS)
+ .do(() => this.notificationService.send({
+ type: NotificationType.MESSAGE,
+ message: 'Teller is going to be saved'
+ }));
+
+ @Effect({ dispatch: false })
+ executeCommandSuccess$: Observable<Action> = this.actions$
+ .ofType(tellerActions.EXECUTE_COMMAND_SUCCESS)
+ .do(() => this.notificationService.send({
+ type: NotificationType.MESSAGE,
+ message: 'Teller is going to be updated'
+ }));
+
+ @Effect({ dispatch: false })
+ openCommandFail$: Observable<Action> = this.actions$
+ .ofType(tellerActions.EXECUTE_COMMAND_FAIL)
+ .map(action => action.payload.command)
+ .filter(command => command.action === 'OPEN')
+ .do(action => this.notificationService.send({
+ type: NotificationType.ALERT,
+ title: 'Employee already assigned',
+ message: 'Employees can only be assigned to one teller. Please choose a different employee or unassign the employee first.'
+ })
+ );
+
+ @Effect({ dispatch: false })
+ closeCommandFail$: Observable<Action> = this.actions$
+ .ofType(tellerActions.EXECUTE_COMMAND_FAIL)
+ .map(action => action.payload.command)
+ .filter(command => command.action === 'CLOSE')
+ .do(action => this.notificationService.send({
+ type: NotificationType.ALERT,
+ title: 'Denomination required',
+ message: 'This teller requires a denomination before it can be closed.'
+ })
+ );
+
+ constructor(private actions$: Actions, private notificationService: NotificationService) {
+ }
+}
diff --git a/src/app/office/store/teller/effects/route.effects.ts b/src/app/office/store/teller/effects/route.effects.ts
new file mode 100644
index 0000000..daff2f4
--- /dev/null
+++ b/src/app/office/store/teller/effects/route.effects.ts
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Router} from '@angular/router';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as tellerActions from '../teller.actions';
+
+@Injectable()
+export class TellerRouteEffects {
+
+ @Effect({ dispatch: false })
+ createTellerSuccess$: Observable<Action> = this.actions$
+ .ofType(tellerActions.CREATE_TELLER_SUCCESS, tellerActions.UPDATE_TELLER_SUCCESS)
+ .map(action => action.payload)
+ .do(payload => {
+ this.router.navigate(['../'], { relativeTo: payload.activatedRoute });
+ });
+
+ @Effect({ dispatch: false })
+ executeCommandSuccess$: Observable<Action> = this.actions$
+ .ofType(tellerActions.EXECUTE_COMMAND_SUCCESS)
+ .map(action => action.payload)
+ .do(payload => {
+ this.router.navigate(['../'], { relativeTo: payload.activatedRoute });
+ });
+
+ constructor(private actions$: Actions, private router: Router) { }
+}
diff --git a/src/app/office/store/teller/effects/service.effects.ts b/src/app/office/store/teller/effects/service.effects.ts
new file mode 100644
index 0000000..2cebcc7
--- /dev/null
+++ b/src/app/office/store/teller/effects/service.effects.ts
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {TellerService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/teller-service';
+import {Injectable} from '@angular/core';
+import {Actions, Effect} from '@ngrx/effects';
+import {Observable} from 'rxjs/Observable';
+import {Action} from '@ngrx/store';
+import * as tellerActions from '../../teller/teller.actions';
+import {of} from 'rxjs/observable/of';
+
+@Injectable()
+export class TellerApiEffects {
+
+ @Effect()
+ loadTeller$: Observable<Action> = this.actions$
+ .ofType(tellerActions.LOAD_TELLER)
+ .map((action: tellerActions.LoadTellerAction) => action.payload)
+ .mergeMap(officeId =>
+ this.tellerService.fetch(officeId)
+ .map((teller) => new tellerActions.LoadTellerSuccessAction(teller))
+ .catch((error) => of(new tellerActions.LoadTellerSuccessAction([])))
+ );
+
+ @Effect()
+ createTeller$: Observable<Action> = this.actions$
+ .ofType(tellerActions.CREATE_TELLER)
+ .map((action: tellerActions.CreateTellerAction) => action.payload)
+ .mergeMap(payload =>
+ this.tellerService.create(payload.officeId, payload.teller)
+ .map(() => new tellerActions.CreateTellerSuccessAction({
+ activatedRoute: payload.activatedRoute,
+ resource: payload.teller
+ }))
+ .catch((error) => of(new tellerActions.CreateTellerFailAction(error)))
+ );
+
+ @Effect()
+ updateTeller$: Observable<Action> = this.actions$
+ .ofType(tellerActions.UPDATE_TELLER)
+ .map((action: tellerActions.UpdateTellerAction) => action.payload)
+ .mergeMap(payload =>
+ this.tellerService.change(payload.officeId, payload.teller)
+ .map(() => new tellerActions.UpdateTellerSuccessAction({
+ activatedRoute: payload.activatedRoute,
+ resource: payload.teller
+ }))
+ .catch((error) => of(new tellerActions.UpdateTellerFailAction(error)))
+ );
+
+ @Effect()
+ executeCommand$: Observable<Action> = this.actions$
+ .ofType(tellerActions.EXECUTE_COMMAND)
+ .map((action: tellerActions.ExecuteCommandAction) => action.payload)
+ .mergeMap(payload =>
+ this.tellerService.createCommand(payload.officeId, payload.tellerCode, payload.command)
+ .map(() => new tellerActions.ExecuteCommandSuccessAction(payload))
+ .catch((error) => of(new tellerActions.ExecuteCommandFailAction({
+ command: payload.command,
+ error
+ })))
+ );
+
+ constructor(private actions$: Actions, private tellerService: TellerService) {}
+
+}
diff --git a/src/app/office/store/teller/teller.actions.ts b/src/app/office/store/teller/teller.actions.ts
new file mode 100644
index 0000000..5481e2b
--- /dev/null
+++ b/src/app/office/store/teller/teller.actions.ts
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {type} from '../../../store/util';
+import {Teller} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller.model';
+import {Action} from '@ngrx/store';
+import {
+ CreateResourceSuccessPayload,
+ LoadResourcePayload,
+ SelectResourcePayload,
+ UpdateResourceSuccessPayload
+} from '../../../common/store/resource.reducer';
+import {RoutePayload} from '../../../common/store/route-payload';
+import {TellerManagementCommand} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller-management-command.model';
+
+export const LOAD_TELLER = type('[Office Teller] Load All ');
+export const LOAD_TELLER_SUCCESS = type('[Office Teller] Load All Success');
+
+export const LOAD = type('[Office Teller] Load');
+export const SELECT = type('[Office Teller] Select');
+export const CREATE_TELLER = type('[Office Teller] Create');
+export const CREATE_TELLER_SUCCESS = type('[Office Teller] Create Success');
+export const CREATE_TELLER_FAIL = type('[Office Teller] Create Fail');
+
+export const UPDATE_TELLER = type('[Office Teller] Update');
+export const UPDATE_TELLER_SUCCESS = type('[Office Teller] Update Success');
+export const UPDATE_TELLER_FAIL = type('[Office Teller] Update Fail');
+
+export const RESET_FORM = type('[Office Teller] Reset Form');
+
+export const EXECUTE_COMMAND = type('[Office Teller] Execute Command');
+export const EXECUTE_COMMAND_SUCCESS = type('[Office Teller] Execute Command Success');
+export const EXECUTE_COMMAND_FAIL = type('[Office Teller] Execute Command Fail');
+
+export interface LoadTellerSuccessPayload {
+ officeId: string;
+ teller: Teller[];
+}
+
+export interface ExecuteCommandPayload extends RoutePayload {
+ officeId: string;
+ tellerCode: string;
+ command: TellerManagementCommand;
+}
+
+export interface ExecuteCommandFailPayload {
+ command: TellerManagementCommand;
+ error: Error;
+}
+
+export interface TellerPayload extends RoutePayload {
+ officeId: string;
+ teller: Teller;
+}
+
+export class LoadTellerAction implements Action {
+ readonly type = LOAD_TELLER;
+
+ constructor(public payload: string) {}
+}
+
+export class LoadTellerSuccessAction implements Action {
+ readonly type = LOAD_TELLER_SUCCESS;
+
+ constructor(public payload: Teller[]) {}
+}
+
+export class LoadAction implements Action {
+ readonly type = LOAD;
+
+ constructor(public payload: LoadResourcePayload) { }
+}
+
+export class SelectAction implements Action {
+ readonly type = SELECT;
+
+ constructor(public payload: SelectResourcePayload) { }
+}
+
+export class CreateTellerAction implements Action {
+ readonly type = CREATE_TELLER;
+
+ constructor(public payload: TellerPayload) {}
+}
+
+export class CreateTellerSuccessAction implements Action {
+ readonly type = CREATE_TELLER_SUCCESS;
+
+ constructor(public payload: CreateResourceSuccessPayload) {}
+}
+
+export class CreateTellerFailAction implements Action {
+ readonly type = CREATE_TELLER_FAIL;
+
+ constructor(public payload: Error) {}
+}
+
+export class UpdateTellerAction implements Action {
+ readonly type = UPDATE_TELLER;
+
+ constructor(public payload: TellerPayload) {}
+}
+
+export class UpdateTellerSuccessAction implements Action {
+ readonly type = UPDATE_TELLER_SUCCESS;
+
+ constructor(public payload: UpdateResourceSuccessPayload) {}
+}
+
+export class UpdateTellerFailAction implements Action {
+ readonly type = UPDATE_TELLER_FAIL;
+
+ constructor(public payload: Error) {}
+}
+
+export class ExecuteCommandAction implements Action {
+ readonly type = EXECUTE_COMMAND;
+
+ constructor(public payload: ExecuteCommandPayload) {}
+}
+
+export class ExecuteCommandSuccessAction implements Action {
+ readonly type = EXECUTE_COMMAND_SUCCESS;
+
+ constructor(public payload: ExecuteCommandPayload) {}
+}
+
+export class ExecuteCommandFailAction implements Action {
+ readonly type = EXECUTE_COMMAND_FAIL;
+
+ constructor(public payload: ExecuteCommandFailPayload) {}
+}
+
+export type Actions
+ = LoadTellerAction
+ | LoadTellerSuccessAction
+ | CreateTellerAction
+ | CreateTellerSuccessAction
+ | CreateTellerFailAction
+ | UpdateTellerAction
+ | UpdateTellerSuccessAction
+ | UpdateTellerFailAction
+ | ExecuteCommandAction
+ | ExecuteCommandSuccessAction
+ | ExecuteCommandFailAction;
diff --git a/src/app/office/store/teller/tellers.reducer.spec.ts b/src/app/office/store/teller/tellers.reducer.spec.ts
new file mode 100644
index 0000000..28b119d
--- /dev/null
+++ b/src/app/office/store/teller/tellers.reducer.spec.ts
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {reducer} from './tellers.reducer';
+import {ResourceState} from '../../../common/store/resource.reducer';
+import {ExecuteCommandPayload, ExecuteCommandSuccessAction} from './teller.actions';
+import {Status} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller.model';
+
+describe('Tellers Reducer', () => {
+
+ describe('EXECUTE_COMMAND_SUCCESS', () => {
+
+ function createState(state?: Status, assignedEmployee?: string): ResourceState {
+ return {
+ ids: ['testTeller'],
+ entities: {
+ 'testTeller': {
+ code: 'testTeller',
+ state,
+ assignedEmployee
+ }
+ },
+ selectedId: null,
+ loadedAt: {}
+ };
+ }
+
+ it('should add assigned employee on open', () => {
+ const payload: ExecuteCommandPayload = {
+ officeId: 'officeId',
+ tellerCode: 'testTeller',
+ command: {
+ action: 'OPEN',
+ assignedEmployeeIdentifier: 'test'
+ },
+ activatedRoute: null
+ };
+
+ const initialState: ResourceState = createState();
+
+ const expectedResult: ResourceState = createState('OPEN', payload.command.assignedEmployeeIdentifier);
+
+ const result = reducer(initialState, new ExecuteCommandSuccessAction(payload));
+
+ expect(result).toEqual(expectedResult);
+ });
+
+ it('should remove assigned employee on close', () => {
+ const payload: ExecuteCommandPayload = {
+ officeId: 'officeId',
+ tellerCode: 'testTeller',
+ command: {
+ action: 'CLOSE'
+ },
+ activatedRoute: null
+ };
+
+ const initialState: ResourceState = createState();
+
+ const expectedResult: ResourceState = createState('CLOSED', null);
+
+ const result = reducer(initialState, new ExecuteCommandSuccessAction(payload));
+
+ expect(result).toEqual(expectedResult);
+ });
+ });
+
+});
diff --git a/src/app/office/store/teller/tellers.reducer.ts b/src/app/office/store/teller/tellers.reducer.ts
new file mode 100644
index 0000000..174e5b7
--- /dev/null
+++ b/src/app/office/store/teller/tellers.reducer.ts
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ResourceState} from '../../../common/store/resource.reducer';
+import * as tellers from '../teller/teller.actions';
+import {Status, Teller} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller.model';
+import {idsToHashWithCurrentTimestamp, resourcesToHash} from '../../../common/store/reducer.helper';
+import {TellerManagementCommand} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/teller/domain/teller-management-command.model';
+
+export const initialState: ResourceState = {
+ ids: [],
+ entities: {},
+ loadedAt: {},
+ selectedId: null,
+};
+
+export function reducer(state = initialState, action: tellers.Actions): ResourceState {
+
+ switch (action.type) {
+
+ case tellers.LOAD_TELLER: {
+ return initialState;
+ }
+
+ case tellers.LOAD_TELLER_SUCCESS: {
+ const tellers: Teller[] = action.payload;
+
+ const ids = tellers.map(teller => teller.code);
+
+ const entities = resourcesToHash(tellers, 'code');
+
+ const loadedAt = idsToHashWithCurrentTimestamp(ids);
+
+ return {
+ ids: [ ...ids ],
+ entities: entities,
+ loadedAt: loadedAt,
+ selectedId: state.selectedId
+ };
+ }
+
+ case tellers.EXECUTE_COMMAND_SUCCESS: {
+ const payload = action.payload;
+ const tellerCode = payload.tellerCode;
+ const command: TellerManagementCommand = payload.command;
+ const teller: Teller = state.entities[tellerCode];
+
+ let tellerState: Status = null;
+ let assignedEmployee = null;
+
+ if (command.action === 'OPEN') {
+ tellerState = 'OPEN';
+ assignedEmployee = command.assignedEmployeeIdentifier;
+ } else if (command.action === 'CLOSE') {
+ tellerState = 'CLOSED';
+ }
+
+ const newTeller = Object.assign({}, teller, {
+ state: tellerState,
+ assignedEmployee
+ });
+
+ return {
+ ids: [ ...state.ids ],
+ entities: Object.assign({}, state.entities, {
+ [teller.code]: newTeller
+ }),
+ loadedAt: state.loadedAt,
+ selectedId: state.selectedId
+ };
+ }
+
+ default: {
+ return state;
+ }
+ }
+}
diff --git a/src/app/office/view-offices/view-offices.component.html b/src/app/office/view-offices/view-offices.component.html
index afb9f7f..bb12198 100644
--- a/src/app/office/view-offices/view-offices.component.html
+++ b/src/app/office/view-offices/view-offices.component.html
@@ -12,7 +12,7 @@
<br>
<mat-divider></mat-divider>
-<mat-table #table [dataSource]="dataSource">
+<mat-table #table [dataSource]="datasource" >
<!-- Position Column -->
<ng-container matColumnDef="id">
diff --git a/src/app/office/view-offices/view-offices.component.ts b/src/app/office/view-offices/view-offices.component.ts
index aed8376..3ac70b7 100644
--- a/src/app/office/view-offices/view-offices.component.ts
+++ b/src/app/office/view-offices/view-offices.component.ts
@@ -1,13 +1,14 @@
import { Component, OnInit } from '@angular/core';
import {MatTableDataSource} from '@angular/material';
+
+
@Component({
selector: 'app-view-offices',
templateUrl: './view-offices.component.html',
styleUrls: ['./view-offices.component.scss']
})
export class ViewOfficesComponent implements OnInit {
-
displayedColumns = ['id','name','description'];
dataSource = new MatTableDataSource(ELEMENT_DATA);
diff --git a/src/app/sevices/accounting/accounting.service.ts b/src/app/sevices/accounting/accounting.service.ts
new file mode 100644
index 0000000..cb404bb
--- /dev/null
+++ b/src/app/sevices/accounting/accounting.service.ts
@@ -0,0 +1,201 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {HttpClient} from '../http/http.service';
+import {Ledger} from './domain/ledger.model';
+import {Observable} from 'rxjs/Observable';
+import {Account} from './domain/account.model';
+import {RequestOptionsArgs, URLSearchParams} from '@angular/http';
+import {AccountCommand} from './domain/account-command.model';
+import {JournalEntry} from './domain/journal-entry.model';
+import {TrialBalance} from './domain/trial-balance.model';
+import {AccountEntryPage} from './domain/account-entry-page.model';
+import {AccountPage} from './domain/account-page.model';
+import {FetchRequest} from '../domain/paging/fetch-request.model';
+import {buildDateRangeParam, buildSearchParams} from '../domain/paging/search-param.builder';
+import {LedgerPage} from './domain/ledger-page.model';
+import {ChartOfAccountEntry} from './domain/chart-of-account-entry.model';
+import {TransactionType} from './domain/transaction-type.model';
+import {TransactionTypePage} from './domain/transaction-type-page.model';
+import {AccountType} from './domain/account-type.model';
+import {IncomeStatement} from './domain/income-statement.model';
+import {FinancialCondition} from './domain/financial-condition.model';
+
+@Injectable()
+export class AccountingService {
+
+ constructor(private http: HttpClient, @Inject('accountingBaseUrl') private baseUrl: string) {
+ }
+
+ public createLedger(ledger: Ledger): Observable<void> {
+ return this.http.post(`${this.baseUrl}/ledgers`, ledger);
+ }
+
+ public fetchLedgers(includeSubLedgers = false, fetchRequest?: FetchRequest, type?: AccountType): Observable<LedgerPage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ params.append('includeSubLedgers', String(includeSubLedgers));
+ params.append('type', type);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+
+ return this.http.get(`${this.baseUrl}/ledgers`, requestOptions);
+ }
+
+ public findLedger(identifier: string, silent?: boolean): Observable<Ledger> {
+ return this.http.get(`${this.baseUrl}/ledgers/${identifier}`, {}, silent);
+ }
+
+ public addSubLedger(identifier: string, subLedger: Ledger): Observable<void> {
+ return this.http.post(`${this.baseUrl}/ledgers/${identifier}`, subLedger);
+ }
+
+ public modifyLedger(ledger: Ledger): Observable<void> {
+ return this.http.put(`${this.baseUrl}/ledgers/${ledger.identifier}`, ledger);
+ }
+
+ public deleteLedger(identifier: string): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/ledgers/${identifier}`);
+ }
+
+ public fetchAccountsOfLedger(identifier: string, fetchRequest?: FetchRequest): Observable<AccountPage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+ return this.http.get(`${this.baseUrl}/ledgers/${identifier}/accounts`, requestOptions);
+ }
+
+ public createAccount(account: Account): Observable<void> {
+ return this.http.post(`${this.baseUrl}/accounts`, account);
+ }
+
+ public fetchAccounts(fetchRequest?: FetchRequest, type?: AccountType): Observable<AccountPage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ params.append('type', type);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+ return this.http.get(`${this.baseUrl}/accounts`, requestOptions)
+ .share();
+ }
+
+ public findAccount(identifier: string, silent?: boolean): Observable<Account> {
+ return this.http.get(`${this.baseUrl}/accounts/${identifier}`, {}, silent);
+ }
+
+ public modifyAccount(account: Account): Observable<void> {
+ return this.http.put(`${this.baseUrl}/accounts/${account.identifier}`, account);
+ }
+
+ public deleteAccount(account: Account): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/accounts/${account.identifier}`);
+ }
+
+ public fetchAccountEntries(identifier: string, startDate: string, endDate: string,
+ fetchRequest?: FetchRequest): Observable<AccountEntryPage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+ const dateRange = buildDateRangeParam(startDate, endDate);
+ params.append('dateRange', dateRange);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+ return this.http.get(`${this.baseUrl}/accounts/${identifier}/entries`, requestOptions);
+ }
+
+ public fetchAccountCommands(identifier: string): Observable<AccountCommand[]> {
+ return this.http.get(`${this.baseUrl}/accounts/${identifier}/commands`);
+ }
+
+ public accountCommand(identifier: string, command: AccountCommand): Observable<void> {
+ return this.http.post(`${this.baseUrl}/accounts/${identifier}/commands`, command);
+ }
+
+ public createJournalEntry(journalEntry: JournalEntry): Observable<void> {
+ return this.http.post(`${this.baseUrl}/journal`, journalEntry);
+ }
+
+ public fetchJournalEntries(startDate: string, endDate: string, account?: string, amount?: string): Observable<JournalEntry[]> {
+ const params: URLSearchParams = new URLSearchParams();
+
+ params.append('dateRange', buildDateRangeParam(startDate, endDate));
+ params.append('account', account && account.length > 0 ? account : undefined);
+ params.append('amount', amount && amount.length > 0 ? amount : undefined);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+ return this.http.get(`${this.baseUrl}/journal`, requestOptions);
+ }
+
+ public findJournalEntry(transactionIdentifier: string): Observable<JournalEntry> {
+ return this.http.get(`${this.baseUrl}/journal/${transactionIdentifier}`);
+ }
+
+ public getTrialBalance(includeEmptyEntries?: boolean): Observable<TrialBalance> {
+ const params: URLSearchParams = new URLSearchParams();
+ params.append('includeEmptyEntries', includeEmptyEntries ? 'true' : 'false');
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+ return this.http.get(`${this.baseUrl}/trialbalance`, requestOptions);
+ }
+
+ public getChartOfAccounts(): Observable<ChartOfAccountEntry[]> {
+ return this.http.get(`${this.baseUrl}/chartofaccounts`);
+ }
+
+ public findTransactionType(code: string, silent?: boolean): Observable<Account> {
+ return this.http.get(`${this.baseUrl}/transactiontypes/${code}`, {}, silent);
+ }
+
+ public createTransactionType(transactionType: TransactionType): Observable<void> {
+ return this.http.post(`${this.baseUrl}/transactiontypes`, transactionType);
+ }
+
+ public fetchTransactionTypes(fetchRequest?: FetchRequest): Observable<TransactionTypePage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+
+ return this.http.get(`${this.baseUrl}/transactiontypes`, requestOptions);
+ }
+
+ public changeTransactionType(transactionType: TransactionType): Observable<void> {
+ return this.http.put(`${this.baseUrl}/transactiontypes/${transactionType.code}`, transactionType);
+ }
+
+ public getIncomeStatement(): Observable<IncomeStatement> {
+ return this.http.get(`${this.baseUrl}/incomestatement`);
+ }
+
+ public getFinancialCondition(): Observable<FinancialCondition> {
+ return this.http.get(`${this.baseUrl}/financialcondition`);
+ }
+
+}
diff --git a/src/app/sevices/accounting/domain/account-command-action.model.ts b/src/app/sevices/accounting/domain/account-command-action.model.ts
new file mode 100644
index 0000000..aaaab30
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-command-action.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type AccountCommandAction = 'LOCK' | 'UNLOCK' | 'CLOSE' | 'REOPEN';
diff --git a/src/app/sevices/accounting/domain/account-command.model.ts b/src/app/sevices/accounting/domain/account-command.model.ts
new file mode 100644
index 0000000..5a577c3
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-command.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountCommandAction} from './account-command-action.model';
+
+export interface AccountCommand {
+ action: AccountCommandAction;
+ comment: string;
+ createdOn?: string;
+ createdBy?: string;
+}
diff --git a/src/app/sevices/accounting/domain/account-entry-page.model.ts b/src/app/sevices/accounting/domain/account-entry-page.model.ts
new file mode 100644
index 0000000..2801db6
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-entry-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountEntry} from './account-entry.model';
+
+export interface AccountEntryPage {
+ accountEntries: AccountEntry[];
+ totalElements: number;
+ totalPages: number;
+}
diff --git a/src/app/sevices/accounting/domain/account-entry-type.model.ts b/src/app/sevices/accounting/domain/account-entry-type.model.ts
new file mode 100644
index 0000000..db9dee9
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-entry-type.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type AccountEntryType = 'DEBIT' | 'CREDIT';
diff --git a/src/app/sevices/accounting/domain/account-entry.model.ts b/src/app/sevices/accounting/domain/account-entry.model.ts
new file mode 100644
index 0000000..38b1ef2
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-entry.model.ts
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountEntryType} from './account-entry-type.model';
+
+export interface AccountEntry {
+ type: AccountEntryType;
+ transactionDate: string;
+ message: string;
+ amount: number;
+ balance: number;
+}
diff --git a/src/app/sevices/accounting/domain/account-page.model.ts b/src/app/sevices/accounting/domain/account-page.model.ts
new file mode 100644
index 0000000..cef3a9e
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Account} from './account.model';
+
+export interface AccountPage {
+ accounts: Account[];
+ totalElements: number;
+ totalPages: number;
+}
diff --git a/src/app/sevices/accounting/domain/account-state.model.ts b/src/app/sevices/accounting/domain/account-state.model.ts
new file mode 100644
index 0000000..11eb6a0
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-state.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type AccountState = 'OPEN' | 'LOCKED' | 'CLOSED';
diff --git a/src/app/sevices/accounting/domain/account-type.model.ts b/src/app/sevices/accounting/domain/account-type.model.ts
new file mode 100644
index 0000000..05a0899
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account-type.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type AccountType = 'ASSET' | 'LIABILITY' | 'EQUITY' | 'REVENUE' | 'EXPENSE';
diff --git a/src/app/sevices/accounting/domain/account.model.ts b/src/app/sevices/accounting/domain/account.model.ts
new file mode 100644
index 0000000..dffa0a2
--- /dev/null
+++ b/src/app/sevices/accounting/domain/account.model.ts
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountType} from './account-type.model';
+import {AccountState} from './account-state.model';
+
+export interface Account {
+ type?: AccountType;
+ identifier: string;
+ name: string;
+ holders?: string[];
+ signatureAuthorities?: string[];
+ balance?: number;
+ referenceAccount?: string;
+ ledger: string;
+ alternativeAccountNumber?: string;
+ state?: AccountState;
+ createdOn?: string;
+ createdBy?: string;
+ lastModifiedOn?: string;
+ lastModifiedBy?: string;
+}
diff --git a/src/app/sevices/accounting/domain/chart-of-account-entry.model.ts b/src/app/sevices/accounting/domain/chart-of-account-entry.model.ts
new file mode 100644
index 0000000..cf1c472
--- /dev/null
+++ b/src/app/sevices/accounting/domain/chart-of-account-entry.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface ChartOfAccountEntry {
+ code: string;
+ name: string;
+ level: number;
+ description: string;
+ type: string;
+ chartOfAccountEntries: ChartOfAccountEntry[];
+}
diff --git a/src/app/sevices/accounting/domain/creditor.model.ts b/src/app/sevices/accounting/domain/creditor.model.ts
new file mode 100644
index 0000000..164de3e
--- /dev/null
+++ b/src/app/sevices/accounting/domain/creditor.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Creditor {
+ accountNumber: string;
+ amount: string;
+}
diff --git a/src/app/sevices/accounting/domain/debtor.model.ts b/src/app/sevices/accounting/domain/debtor.model.ts
new file mode 100644
index 0000000..9aae22c
--- /dev/null
+++ b/src/app/sevices/accounting/domain/debtor.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface Debtor {
+ accountNumber: string;
+ amount: string;
+}
diff --git a/src/app/sevices/accounting/domain/financial-condition-entry.model.ts b/src/app/sevices/accounting/domain/financial-condition-entry.model.ts
new file mode 100644
index 0000000..7439538
--- /dev/null
+++ b/src/app/sevices/accounting/domain/financial-condition-entry.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface FinancialConditionEntry {
+ description: string;
+ value: string;
+}
diff --git a/src/app/sevices/accounting/domain/financial-condition-section.model.ts b/src/app/sevices/accounting/domain/financial-condition-section.model.ts
new file mode 100644
index 0000000..c69f3ce
--- /dev/null
+++ b/src/app/sevices/accounting/domain/financial-condition-section.model.ts
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {FinancialConditionEntry} from './financial-condition-entry.model';
+
+export type Type = 'ASSET' | 'EQUITY' | 'LIABILITY';
+
+export interface FinancialConditionSection {
+ type: Type;
+ description: string;
+ financialConditionEntries: FinancialConditionEntry[];
+ subtotal: string;
+}
diff --git a/src/app/sevices/accounting/domain/financial-condition.model.ts b/src/app/sevices/accounting/domain/financial-condition.model.ts
new file mode 100644
index 0000000..ed58d48
--- /dev/null
+++ b/src/app/sevices/accounting/domain/financial-condition.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {FinancialConditionSection} from './financial-condition-section.model';
+
+export interface FinancialCondition {
+ date: string;
+ financialConditionSections: FinancialConditionSection[];
+ totalAssets: string;
+ totalEquitiesAndLiabilities: string;
+}
diff --git a/src/app/sevices/accounting/domain/income-statement-entry.model.ts b/src/app/sevices/accounting/domain/income-statement-entry.model.ts
new file mode 100644
index 0000000..5167d89
--- /dev/null
+++ b/src/app/sevices/accounting/domain/income-statement-entry.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface IncomeStatementEntry {
+ description: string;
+ value: string;
+}
diff --git a/src/app/sevices/accounting/domain/income-statement-section.model.ts b/src/app/sevices/accounting/domain/income-statement-section.model.ts
new file mode 100644
index 0000000..3237b03
--- /dev/null
+++ b/src/app/sevices/accounting/domain/income-statement-section.model.ts
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {IncomeStatementEntry} from './income-statement-entry.model';
+
+export type Type = 'INCOME' | 'EXPENSES';
+
+export interface IncomeStatementSection {
+ type: Type;
+ description: string;
+ incomeStatementEntries: IncomeStatementEntry[];
+ subtotal: string;
+}
diff --git a/src/app/sevices/accounting/domain/income-statement.model.ts b/src/app/sevices/accounting/domain/income-statement.model.ts
new file mode 100644
index 0000000..bb9397b
--- /dev/null
+++ b/src/app/sevices/accounting/domain/income-statement.model.ts
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {IncomeStatementSection} from './income-statement-section.model';
+
+export interface IncomeStatement {
+ date: string;
+ incomeStatementSections: IncomeStatementSection[];
+ grossProfit: string;
+ totalExpenses: string;
+ netIncome: string;
+}
diff --git a/src/app/sevices/accounting/domain/journal-entry-state.model.ts b/src/app/sevices/accounting/domain/journal-entry-state.model.ts
new file mode 100644
index 0000000..6a0d5ae
--- /dev/null
+++ b/src/app/sevices/accounting/domain/journal-entry-state.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type JournalEntryState = 'PENDING' | 'PROCESSED';
diff --git a/src/app/sevices/accounting/domain/journal-entry.model.ts b/src/app/sevices/accounting/domain/journal-entry.model.ts
new file mode 100644
index 0000000..b31cef3
--- /dev/null
+++ b/src/app/sevices/accounting/domain/journal-entry.model.ts
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Debtor} from './debtor.model';
+import {Creditor} from './creditor.model';
+import {JournalEntryState} from './journal-entry-state.model';
+
+export interface JournalEntry {
+ transactionIdentifier: string;
+ transactionDate: string;
+ transactionType: string;
+ clerk: string;
+ note?: string;
+ debtors: Debtor[];
+ creditors: Creditor[];
+ state?: JournalEntryState;
+ message?: string;
+}
diff --git a/src/app/sevices/accounting/domain/ledger-page.model.ts b/src/app/sevices/accounting/domain/ledger-page.model.ts
new file mode 100644
index 0000000..80a5c18
--- /dev/null
+++ b/src/app/sevices/accounting/domain/ledger-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Ledger} from './ledger.model';
+
+export interface LedgerPage {
+ ledgers: Ledger[];
+ totalElements: number;
+ totalPages: number;
+}
diff --git a/src/app/sevices/accounting/domain/ledger.model.ts b/src/app/sevices/accounting/domain/ledger.model.ts
new file mode 100644
index 0000000..33c844c
--- /dev/null
+++ b/src/app/sevices/accounting/domain/ledger.model.ts
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountType} from './account-type.model';
+
+export interface Ledger {
+ parentLedgerIdentifier?: string;
+ type: AccountType;
+ identifier: string;
+ name: string;
+ description?: string;
+ subLedgers: Ledger[];
+ showAccountsInChart: boolean;
+ totalValue?: string;
+ createdOn?: string;
+ createdBy?: string;
+ lastModifiedOn?: string;
+ lastModifiedBy?: string;
+}
diff --git a/src/app/sevices/accounting/domain/permittable-group-ids.ts b/src/app/sevices/accounting/domain/permittable-group-ids.ts
new file mode 100644
index 0000000..30d27fc
--- /dev/null
+++ b/src/app/sevices/accounting/domain/permittable-group-ids.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class AccountingPermittableGroupIds {
+ public static readonly ACCOUNT_MANAGEMENT = 'accounting__v1__account';
+ public static readonly JOURNAL_MANAGEMENT = 'accounting__v1__journal';
+ public static readonly LEDGER_MANAGEMENT = 'accounting__v1__ledger';
+ public static readonly TRANSACTION_TYPES = 'accounting__v1__tx_types';
+ public static readonly THOTH_INCOME_STMT = 'accounting__v1__income_stmt';
+ public static readonly THOTH_FIN_CONDITION = 'accounting__v1__fin_condition';
+}
diff --git a/src/app/sevices/accounting/domain/transaction-type-page.model.ts b/src/app/sevices/accounting/domain/transaction-type-page.model.ts
new file mode 100644
index 0000000..3c1ffbf
--- /dev/null
+++ b/src/app/sevices/accounting/domain/transaction-type-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {TransactionType} from './transaction-type.model';
+
+export interface TransactionTypePage {
+ transactionTypes: TransactionType[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/accounting/domain/transaction-type.model.ts b/src/app/sevices/accounting/domain/transaction-type.model.ts
new file mode 100644
index 0000000..671242b
--- /dev/null
+++ b/src/app/sevices/accounting/domain/transaction-type.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface TransactionType {
+ code: string;
+ name: string;
+ description?: string;
+}
diff --git a/src/app/sevices/accounting/domain/trial-balance-entry-type.model.ts b/src/app/sevices/accounting/domain/trial-balance-entry-type.model.ts
new file mode 100644
index 0000000..d9d23cc
--- /dev/null
+++ b/src/app/sevices/accounting/domain/trial-balance-entry-type.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type TrialBalanceEntryType = 'DEBIT' | 'CREDIT';
diff --git a/src/app/sevices/accounting/domain/trial-balance-entry.model.ts b/src/app/sevices/accounting/domain/trial-balance-entry.model.ts
new file mode 100644
index 0000000..9dcd6d2
--- /dev/null
+++ b/src/app/sevices/accounting/domain/trial-balance-entry.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Ledger} from './ledger.model';
+import {TrialBalanceEntryType} from './trial-balance-entry-type.model';
+
+export interface TrialBalanceEntry {
+ ledger: Ledger;
+ type: TrialBalanceEntryType;
+ amount: number;
+}
diff --git a/src/app/sevices/accounting/domain/trial-balance.model.ts b/src/app/sevices/accounting/domain/trial-balance.model.ts
new file mode 100644
index 0000000..aca7952
--- /dev/null
+++ b/src/app/sevices/accounting/domain/trial-balance.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {TrialBalanceEntry} from './trial-balance-entry.model';
+
+export interface TrialBalance {
+ trialBalanceEntries: TrialBalanceEntry[];
+ debitTotal: number;
+ creditTotal: number;
+}
diff --git a/src/app/sevices/anubis/permittable-endpoint.model.ts b/src/app/sevices/anubis/permittable-endpoint.model.ts
new file mode 100644
index 0000000..e28286c
--- /dev/null
+++ b/src/app/sevices/anubis/permittable-endpoint.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface PermittableEndpoint {
+ path: string;
+ method: Method;
+ groupId?: string;
+}
+
+export type Method = 'POST' | 'HEAD' | 'PUT' | 'DELETE';
diff --git a/src/app/sevices/anubis/permittable-group.model.ts b/src/app/sevices/anubis/permittable-group.model.ts
new file mode 100644
index 0000000..ef27616
--- /dev/null
+++ b/src/app/sevices/anubis/permittable-group.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {PermittableEndpoint} from './permittable-endpoint.model';
+
+export interface PermittableGroup {
+ identifier: string;
+ permittables: PermittableEndpoint[];
+}
diff --git a/src/app/sevices/catalog/catalog.service.ts b/src/app/sevices/catalog/catalog.service.ts
new file mode 100644
index 0000000..43eb77b
--- /dev/null
+++ b/src/app/sevices/catalog/catalog.service.ts
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {HttpClient} from '../http/http.service';
+import {Observable} from 'rxjs/Observable';
+import {Catalog} from './domain/catalog.model';
+import {Field} from './domain/field.model';
+
+@Injectable()
+export class CatalogService {
+
+ constructor(@Inject('customerBaseUrl') private baseUrl: string, private http: HttpClient) {
+ }
+
+ fetchCatalogs(): Observable<Catalog[]> {
+ return this.http.get(`${this.baseUrl}/catalogs`);
+ }
+
+ createCatalog(catalog: Catalog): Observable<void> {
+ return this.http.post(`${this.baseUrl}/catalogs`, catalog);
+ }
+
+ updateCatalog(catalog: Catalog): Observable<void> {
+ return this.http.put(`${this.baseUrl}/catalogs/${catalog.identifier}`, catalog);
+ }
+
+ deleteCatalog(catalog: Catalog): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/catalogs/${catalog.identifier}`, {});
+ }
+
+ findCatalog(identifier: string, silent: boolean = false): Observable<Catalog> {
+ return this.http.get(`${this.baseUrl}/catalogs/${identifier}`, {}, silent);
+ }
+
+ updateField(catalogIdentifier: string, field: Field): Observable<void> {
+ return this.http.put(`${this.baseUrl}/catalogs/${catalogIdentifier}/fields/${field.identifier}`, field);
+ }
+
+ deleteField(catalogIdentifier: string, field: Field): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/catalogs/${catalogIdentifier}/fields/${field.identifier}`, );
+ }
+}
diff --git a/src/app/sevices/catalog/domain/catalog.model.ts b/src/app/sevices/catalog/domain/catalog.model.ts
new file mode 100644
index 0000000..280b6d4
--- /dev/null
+++ b/src/app/sevices/catalog/domain/catalog.model.ts
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Field} from './field.model';
+
+export interface Catalog {
+ identifier: string;
+ name: string;
+ description?: string;
+ fields: Field[];
+ createdBy?: string;
+ createdOn?: string;
+ lastModifiedBy?: string;
+ lastModifiedOn?: string;
+}
diff --git a/src/app/sevices/catalog/domain/field.model.ts b/src/app/sevices/catalog/domain/field.model.ts
new file mode 100644
index 0000000..c60520c
--- /dev/null
+++ b/src/app/sevices/catalog/domain/field.model.ts
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Option} from './option.model';
+
+export class Field {
+ identifier: string;
+ dataType: FieldDataType;
+ label: string;
+ hint?: string;
+ description?: string;
+ options: Option[];
+ mandatory?: boolean;
+ length?: number;
+ precision?: number;
+ minValue?: number;
+ maxValue?: number;
+ createdBy?: string;
+ createdOn?: string;
+}
+
+export type FieldDataType = 'TEXT' | 'NUMBER' | 'DATE' | 'SINGLE_SELECTION' | 'MULTI_SELECTION';
diff --git a/src/app/sevices/catalog/domain/option.model.ts b/src/app/sevices/catalog/domain/option.model.ts
new file mode 100644
index 0000000..48bcf35
--- /dev/null
+++ b/src/app/sevices/catalog/domain/option.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Option {
+ label: string;
+ value: number;
+ createdBy?: string;
+ createdOn?: string;
+}
diff --git a/src/app/sevices/catalog/domain/value.model.ts b/src/app/sevices/catalog/domain/value.model.ts
new file mode 100644
index 0000000..1e02c19
--- /dev/null
+++ b/src/app/sevices/catalog/domain/value.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Value {
+ catalogIdentifier: string;
+ fieldIdentifier: string;
+ value: string;
+}
diff --git a/src/app/sevices/cheque/cheque.service.ts b/src/app/sevices/cheque/cheque.service.ts
new file mode 100644
index 0000000..2d6f650
--- /dev/null
+++ b/src/app/sevices/cheque/cheque.service.ts
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {HttpClient} from '../http/http.service';
+import {Observable} from 'rxjs/Observable';
+import {RequestOptionsArgs, URLSearchParams} from '@angular/http';
+import {Cheque} from './domain/cheque.model';
+import {IssuingCount} from './domain/issuing-count.model';
+import {ChequeProcessingCommand} from './domain/cheque-processing-command';
+import {ChequeTransaction} from './domain/cheque-transaction';
+import {MICRResolution} from './domain/micr-resolution.model';
+import {FimsCheque} from './domain/fims-cheque.model';
+import {mapToFimsCheque, mapToFimsCheques} from './domain/mapper/fims-cheque.mapper';
+
+@Injectable()
+export class ChequeService {
+
+ constructor(private http: HttpClient, @Inject('chequeBaseUrl') private baseUrl: string) {
+ }
+
+ public issue(issuingCount: IssuingCount): Observable<string> {
+ return this.http.post(`${this.baseUrl}/cheques/`, issuingCount);
+ }
+
+ public fetch(state?: string, accountIdentifier?: string): Observable<FimsCheque[]> {
+ const search = new URLSearchParams();
+
+ search.append('state', state);
+ search.append('accountIdentifier', accountIdentifier);
+
+ const requestOptions: RequestOptionsArgs = {
+ search
+ };
+
+ return this.http.get(`${this.baseUrl}/cheques/`, requestOptions)
+ .map((cheques: Cheque[]) => mapToFimsCheques(cheques));
+ }
+
+ public get(identifier: string): Observable<FimsCheque> {
+ return this.http.get(`${this.baseUrl}/cheques/${identifier}`)
+ .map((cheque: Cheque) => mapToFimsCheque(cheque));
+ }
+
+ public process(identifier: string, command: ChequeProcessingCommand): Observable<void> {
+ return this.http.post(`${this.baseUrl}/cheques/${identifier}/commands`, command);
+ }
+
+ public processTransaction(transaction: ChequeTransaction): Observable<void> {
+ return this.http.post(`${this.baseUrl}/transactions/`, transaction);
+ }
+
+ public expandMicr(identifier: string): Observable<MICRResolution> {
+ return this.http.get(`${this.baseUrl}/micr/${identifier}`, {}, true);
+ }
+
+}
diff --git a/src/app/sevices/cheque/domain/action.model.ts b/src/app/sevices/cheque/domain/action.model.ts
new file mode 100644
index 0000000..b6414c4
--- /dev/null
+++ b/src/app/sevices/cheque/domain/action.model.ts
@@ -0,0 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export type Action = 'APPROVE' | 'CANCEL';
diff --git a/src/app/sevices/cheque/domain/cheque-processing-command.ts b/src/app/sevices/cheque/domain/cheque-processing-command.ts
new file mode 100644
index 0000000..27d5d76
--- /dev/null
+++ b/src/app/sevices/cheque/domain/cheque-processing-command.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Action} from './action.model';
+
+export interface ChequeProcessingCommand {
+ action: Action;
+}
diff --git a/src/app/sevices/cheque/domain/cheque-transaction.ts b/src/app/sevices/cheque/domain/cheque-transaction.ts
new file mode 100644
index 0000000..21dbc5a
--- /dev/null
+++ b/src/app/sevices/cheque/domain/cheque-transaction.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Cheque} from './cheque.model';
+
+export interface ChequeTransaction {
+ cheque: Cheque;
+ creditorAccountNumber: string;
+}
diff --git a/src/app/sevices/cheque/domain/cheque.model.ts b/src/app/sevices/cheque/domain/cheque.model.ts
new file mode 100644
index 0000000..7260595
--- /dev/null
+++ b/src/app/sevices/cheque/domain/cheque.model.ts
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {MICR} from './micr.model';
+import {State} from './state.model';
+
+export interface Cheque {
+ micr: MICR;
+ drawee: string;
+ drawer: string;
+ payee: string;
+ amount: string;
+ dateIssued: string;
+ openCheque: boolean;
+ state: State;
+ journalEntryIdentifier: string;
+}
diff --git a/src/app/sevices/cheque/domain/fims-cheque.model.ts b/src/app/sevices/cheque/domain/fims-cheque.model.ts
new file mode 100644
index 0000000..249164f
--- /dev/null
+++ b/src/app/sevices/cheque/domain/fims-cheque.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {Cheque} from './cheque.model';
+
+export interface FimsCheque extends Cheque {
+ identifier: string;
+}
diff --git a/src/app/sevices/cheque/domain/issuing-count.model.ts b/src/app/sevices/cheque/domain/issuing-count.model.ts
new file mode 100644
index 0000000..98c53c4
--- /dev/null
+++ b/src/app/sevices/cheque/domain/issuing-count.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface IssuingCount {
+ accountIdentifier: string;
+ start?: number;
+ amount: number;
+}
diff --git a/src/app/sevices/cheque/domain/mapper/fims-cheque.mapper.ts b/src/app/sevices/cheque/domain/mapper/fims-cheque.mapper.ts
new file mode 100644
index 0000000..433d4cd
--- /dev/null
+++ b/src/app/sevices/cheque/domain/mapper/fims-cheque.mapper.ts
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {FimsCheque} from '../fims-cheque.model';
+import {Cheque} from '../cheque.model';
+import {MICR} from '../micr.model';
+
+export function mapToFimsCheque(cheque: Cheque): FimsCheque {
+ return Object.assign({}, cheque, {
+ identifier: micrToIdentifier(cheque.micr)
+ });
+}
+
+export function mapToFimsCheques(cheques: Cheque[]): FimsCheque[] {
+ return cheques.map(cheque => mapToFimsCheque(cheque));
+}
+
+export function micrToIdentifier(micr: MICR): string {
+ return toMICRIdentifier(micr.chequeNumber, micr.branchSortCode, micr.accountNumber);
+}
+
+export function toMICRIdentifier(chequeNumber: string, branchSortCode: string, accountNumber: string): string {
+ return `${chequeNumber}~${branchSortCode}~${accountNumber}`;
+}
diff --git a/src/app/sevices/cheque/domain/micr-resolution.model.ts b/src/app/sevices/cheque/domain/micr-resolution.model.ts
new file mode 100644
index 0000000..8319a51
--- /dev/null
+++ b/src/app/sevices/cheque/domain/micr-resolution.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface MICRResolution {
+ office: string;
+ customer: string;
+}
diff --git a/src/app/sevices/cheque/domain/micr.model.ts b/src/app/sevices/cheque/domain/micr.model.ts
new file mode 100644
index 0000000..288d282
--- /dev/null
+++ b/src/app/sevices/cheque/domain/micr.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface MICR {
+ chequeNumber: string;
+ branchSortCode: string;
+ accountNumber: string;
+}
diff --git a/src/app/sevices/cheque/domain/permittable-group-ids.ts b/src/app/sevices/cheque/domain/permittable-group-ids.ts
new file mode 100644
index 0000000..81927b1
--- /dev/null
+++ b/src/app/sevices/cheque/domain/permittable-group-ids.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class ChequePermittableGroupIds {
+ public static readonly CHEQUE_TRANSACTION = 'cheques__v1__transaction';
+ public static readonly CHEQUE_MANAGEMENT = 'cheques__v1__management';
+}
diff --git a/src/app/sevices/cheque/domain/state.model.ts b/src/app/sevices/cheque/domain/state.model.ts
new file mode 100644
index 0000000..adacc2b
--- /dev/null
+++ b/src/app/sevices/cheque/domain/state.model.ts
@@ -0,0 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export type State = 'PENDING' | 'PROCESSED' | 'CANCELED';
diff --git a/src/app/sevices/country/country.service.spec.ts b/src/app/sevices/country/country.service.spec.ts
new file mode 100644
index 0000000..8cfde78
--- /dev/null
+++ b/src/app/sevices/country/country.service.spec.ts
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {fakeAsync, tick} from '@angular/core/testing';
+import {CountryService} from './country.service';
+import {MockBackend} from '@angular/http/testing';
+import {BaseRequestOptions, ConnectionBackend, Http, RequestOptions, ResponseOptions} from '@angular/http';
+import {TranslateService} from '@ngx-translate/core';
+import {Observable} from 'rxjs/Observable';
+import {ReflectiveInjector} from '@angular/core';
+
+describe('Test country service', () => {
+
+ beforeEach(() => {
+ const translateService = {
+ onLangChange: Observable.empty()
+ };
+
+ this.injector = ReflectiveInjector.resolveAndCreate([
+ {provide: ConnectionBackend, useClass: MockBackend},
+ {provide: RequestOptions, useClass: BaseRequestOptions},
+ {provide: TranslateService, useValue: translateService},
+ Http,
+ CountryService
+ ]);
+ this.countryService = this.injector.get(CountryService);
+ this.backend = this.injector.get(ConnectionBackend) as MockBackend;
+ this.backend.connections.subscribe((connection: any) => this.lastConnection = connection);
+ });
+
+ xit('should return countries when term contains brackets', fakeAsync(() => {
+ // TODO find out why mock connection returns a rejected promise
+ this.countryService.init();
+
+ const mockResponse = [
+ {name: 'Country (A)', displayName: 'Country (A)', alpha2Code: '', translations: {}},
+ {name: 'Country (B)', displayName: 'Country (B)', alpha2Code: '', translations: {}}
+ ];
+
+ this.lastConnection.mockRespond(new Response(new ResponseOptions({
+ body: JSON.stringify(mockResponse)
+ })));
+
+ tick();
+
+ const result = this.countryService.fetchCountries('Country (A)');
+
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual(mockResponse[0]);
+ }));
+
+});
diff --git a/src/app/sevices/country/country.service.ts b/src/app/sevices/country/country.service.ts
new file mode 100644
index 0000000..80593ed
--- /dev/null
+++ b/src/app/sevices/country/country.service.ts
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Http} from '@angular/http';
+import {Observable} from 'rxjs/Observable';
+import {Country} from './model/country.model';
+import {TranslateService} from '@ngx-translate/core';
+import {escapeRegexPattern} from '../../common/regex/escape';
+
+@Injectable()
+export class CountryService {
+
+ private countries: Country[] = [];
+
+ constructor(private http: Http, private translateService: TranslateService) {
+ }
+
+ init(): void {
+ this.getCountries()
+ .map(countries => this.translate(countries))
+ .subscribe(countries => this.countries = countries);
+
+ this.translateService.onLangChange
+ .map(() => this.translate(this.countries))
+ .subscribe(countries => this.countries = countries);
+ }
+
+ fetchCountries(term): Country[] {
+ const regTerm = new RegExp(`^${escapeRegexPattern(term)}`, 'gi');
+
+ let result: Country[];
+
+ if (term) {
+ result = this.countries.filter((country: Country) => regTerm.test(country.displayName));
+ } else {
+ result = this.countries.slice();
+ }
+ return result;
+ }
+
+ fetchByCountryCode(countryCode: string): Country {
+ return this.countries.find((country: Country) => country.alpha2Code === countryCode);
+ }
+
+ private translate(countries: Country[]): Country[] {
+ return countries.map(country => this.mapTranslation(country));
+ }
+
+ private mapTranslation(country: Country): Country {
+ const currentLang = this.translateService.currentLang;
+ return Object.assign({}, country, {
+ displayName: currentLang !== 'en' && country.translations[currentLang] ? country.translations[currentLang] : country.name
+ });
+ }
+
+ private getCountries(): Observable<Country[]> {
+ return this.http.get('https://restcountries.eu/rest/v2/all?fields=name;alpha2Code;translations')
+ .map(response => response.json());
+ }
+
+}
diff --git a/src/app/sevices/country/model/country.model.ts b/src/app/sevices/country/model/country.model.ts
new file mode 100644
index 0000000..1ee5eaf
--- /dev/null
+++ b/src/app/sevices/country/model/country.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Country {
+ displayName: string;
+ name: string;
+ alpha2Code: string;
+ translations: { [ key: string ]: string };
+}
diff --git a/src/app/sevices/currency/currency.service.ts b/src/app/sevices/currency/currency.service.ts
new file mode 100644
index 0000000..9072e6b
--- /dev/null
+++ b/src/app/sevices/currency/currency.service.ts
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import {Currency} from './domain/currency.model';
+
+@Injectable()
+export class CurrencyService {
+
+ private currencies: Currency[] = [
+ {code: 'BZD', name: 'Belize Dollar', sign: '$', digits: 2},
+ {code: 'EUR', name: 'Euro', sign: '€', digits: 2},
+ {code: 'GMD', name: 'Gambian Dalasi', sign: 'D', digits: 2},
+ {code: 'JMD', name: 'Jamaican Dollar', sign: '$', digits: 2},
+ {code: 'MXN', name: 'Mexican Peso', sign: '$', digits: 2},
+ {code: 'USD', name: 'US Dollar', sign: '$', digits: 2},
+ {code: 'TTD', name: 'Trinidad and Tobago Dollar', sign: '$', digits: 2},
+ {code: 'XCD', name: 'East Caribbean Dollar', sign: '$', digits: 2}
+ ];
+
+ fetchCurrencies(): Observable<Currency[]> {
+ return Observable.of(this.currencies.slice(0));
+ }
+
+ getCurrency(code: string): Currency {
+ const foundCurrency = this.currencies.find(currency => currency.code === code);
+ return Object.assign({}, foundCurrency);
+ }
+}
diff --git a/src/app/sevices/currency/domain/currency.model.ts b/src/app/sevices/currency/domain/currency.model.ts
new file mode 100644
index 0000000..18de582
--- /dev/null
+++ b/src/app/sevices/currency/domain/currency.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Currency {
+ code: string;
+ name: string;
+ sign: string;
+ digits: number;
+}
diff --git a/src/app/sevices/customer/customer.service.ts b/src/app/sevices/customer/customer.service.ts
new file mode 100644
index 0000000..f093c2e
--- /dev/null
+++ b/src/app/sevices/customer/customer.service.ts
@@ -0,0 +1,212 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import {Customer} from './domain/customer.model';
+import {HttpClient} from '../http/http.service';
+import {CustomerPage} from './domain/customer-page.model';
+import {FetchRequest} from '../domain/paging/fetch-request.model';
+import {buildSearchParams} from '../domain/paging/search-param.builder';
+import {RequestOptionsArgs, URLSearchParams} from '@angular/http';
+import {Command} from './domain/command.model';
+import {TaskDefinition} from './domain/task-definition.model';
+import {ImageService} from '../image/image.service';
+import {IdentificationCard} from './domain/identification-card.model';
+import {IdentificationCardScan} from './domain/identification-card-scan.model';
+import {ProcessStep} from './domain/process-step.model';
+import {CustomerDocument} from './domain/customer-document.model';
+
+@Injectable()
+export class CustomerService {
+
+ constructor(@Inject('customerBaseUrl') private baseUrl: string, private http: HttpClient, private imageService: ImageService) {
+ }
+
+ fetchCustomers(fetchRequest: FetchRequest): Observable<CustomerPage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ search: params
+ };
+
+ return this.http.get(`${this.baseUrl}/customers`, requestOptions).share();
+ }
+
+ getCustomer(id: string, silent?: boolean): Observable<Customer> {
+ return this.http.get(`${this.baseUrl}/customers/${id}`, {}, silent);
+ }
+
+ createCustomer(customer: Customer): Observable<Customer> {
+ return this.http.post(`${this.baseUrl}/customers`, customer);
+ }
+
+ updateCustomer(customer: Customer): Observable<Customer> {
+ return this.http.put(`${this.baseUrl}/customers/${customer.identifier}`, customer);
+ }
+
+ executeCustomerCommand(id: string, command: Command): Observable<void> {
+ return this.http.post(`${this.baseUrl}/customers/${id}/commands`, command);
+ }
+
+ listCustomerCommand(id: string): Observable<Command[]> {
+ return this.http.get(`${this.baseUrl}/customers/${id}/commands`);
+ }
+
+ addTaskToCustomer(customerId: string, taskId: string): Observable<void> {
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/tasks/${taskId}`, {});
+ }
+
+ markTaskAsExecuted(customerId: string, taskId: string): Observable<void> {
+ return this.http.put(`${this.baseUrl}/customers/${customerId}/tasks/${taskId}`, {});
+ }
+
+ fetchCustomerTasks(customerId: string, includeExecuted?: boolean): Observable<TaskDefinition[]> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/tasks`);
+ }
+
+ fetchTasks(): Observable<TaskDefinition[]> {
+ return this.http.get(`${this.baseUrl}/tasks`);
+ }
+
+ getTask(identifier: string): Observable<TaskDefinition> {
+ return this.http.get(`${this.baseUrl}/tasks/${identifier}`);
+ }
+
+ createTask(task: TaskDefinition): Observable<void> {
+ return this.http.post(`${this.baseUrl}/tasks`, task);
+ }
+
+ updateTask(task: TaskDefinition): Observable<void> {
+ return this.http.put(`${this.baseUrl}/tasks/${task.identifier}`, task);
+ }
+
+ fetchProcessSteps(customerId: string): Observable<ProcessStep[]> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/actions`);
+ }
+
+ /* getPortrait(customerId: string): Observable<Blob> {
+ return this.imageService.getImage(`${this.baseUrl}/customers/${customerId}/portrait`);
+ }
+ */
+
+ uploadPortrait(customerId: string, file: File): Observable<void> {
+ const formData = new FormData();
+
+ formData.append('portrait', file, file.name);
+
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/portrait`, formData);
+ }
+
+ deletePortrait(customerId: string): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/customers/${customerId}/portrait`);
+ }
+
+ fetchIdentificationCards(customerId: string): Observable<IdentificationCard[]> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/identifications`);
+ }
+
+ getIdentificationCard(customerId: string, number: string): Observable<IdentificationCard> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/identifications/${number}`);
+ }
+
+ createIdentificationCard(customerId: string, identificationCard: IdentificationCard): Observable<void> {
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/identifications`, identificationCard);
+ }
+
+ updateIdentificationCard(customerId: string, identificationCard: IdentificationCard): Observable<void> {
+ return this.http.put(`${this.baseUrl}/customers/${customerId}/identifications/${identificationCard.number}`, identificationCard);
+ }
+
+ deleteIdentificationCard(customerId: string, number: string): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/customers/${customerId}/identifications/${number}`);
+ }
+
+ fetchIdentificationCardScans(customerId: string, number: string): Observable<IdentificationCardScan[]> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/identifications/${number}/scans`);
+ }
+
+ /* getIdentificationCardScanImage(customerId: string, number: string, scanId: string): Observable<Blob> {
+ return this.imageService.getImage(`${this.baseUrl}/customers/${customerId}/identifications/${number}/scans/${scanId}/image`);
+ }
+ */
+
+ uploadIdentificationCardScan(customerId: string, number: string, scan: IdentificationCardScan, file: File): Observable<void> {
+ const formData = new FormData();
+ formData.append('image', file, file.name);
+
+ const params = new URLSearchParams();
+ params.append('scanIdentifier', scan.identifier);
+ params.append('description', scan.description);
+
+ const requestOptions: RequestOptionsArgs = {
+ search: params
+ };
+
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/identifications/${number}/scans`, formData, requestOptions);
+ }
+
+ deleteIdentificationCardScan(customerId: string, number: string, scanId: string): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/customers/${customerId}/identifications/${number}/scans/${scanId}`);
+ }
+
+ getDocuments(customerId: string): Observable<CustomerDocument[]> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/documents`);
+ }
+
+ getDocument(customerId: string, documentId: string): Observable<CustomerDocument> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/documents/${documentId}`);
+ }
+
+ createDocument(customerId: string, document: CustomerDocument): Observable<void> {
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/documents/${document.identifier}`, document);
+ }
+
+ updateDocument(customerId: string, document: CustomerDocument): Observable<void> {
+ return this.http.put(`${this.baseUrl}/customers/${customerId}/documents/${document.identifier}`, document);
+ }
+
+ deleteDocument(customerId: string, document: CustomerDocument): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/customers/${customerId}/documents/${document.identifier}`);
+ }
+
+ completeDocument(customerId: string, documentId: string, silent: boolean = false): Observable<void> {
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/documents/${documentId}/completed`, true, {}, silent);
+ }
+
+ getDocumentPageNumbers(customerId: string, documentId: string): Observable<number[]> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/documents/${documentId}/pages`);
+ }
+
+ /* getDocumentPage(customerId: string, documentId: string, pageNumber: number): Observable<Blob> {
+ return this.imageService.getImage(`${this.baseUrl}/customers/${customerId}/documents/${documentId}/pages/${pageNumber}`);
+ }
+ */
+
+ createDocumentPage(customerId: string, documentId: string, pageNumber: number, file: File): Observable<void> {
+ const formData = new FormData();
+ formData.append('page', file, file.name);
+
+ return this.http.post(`${this.baseUrl}/customers/${customerId}/documents/${documentId}/pages/${pageNumber}`, formData);
+ }
+
+ deleteDocumentPage(customerId: string, documentId: string, pageNumber: number): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/customers/${customerId}/documents/${documentId}/pages/${pageNumber}`);
+ }
+
+}
diff --git a/src/app/sevices/customer/domain/command.model.ts b/src/app/sevices/customer/domain/command.model.ts
new file mode 100644
index 0000000..c2f87bf
--- /dev/null
+++ b/src/app/sevices/customer/domain/command.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type CommandAction = 'ACTIVATE' | 'LOCK' | 'UNLOCK' | 'CLOSE' | 'REOPEN';
+
+export interface Command {
+ action: CommandAction;
+ comment?: string;
+ createdOn?: string;
+ createdBy?: string;
+}
diff --git a/src/app/sevices/customer/domain/customer-document.model.ts b/src/app/sevices/customer/domain/customer-document.model.ts
new file mode 100644
index 0000000..3ab7dd4
--- /dev/null
+++ b/src/app/sevices/customer/domain/customer-document.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface CustomerDocument {
+ identifier: string;
+ description?: string;
+ completed?: boolean;
+ createdBy?: string;
+ createdOn?: string;
+}
diff --git a/src/app/sevices/customer/domain/customer-page.model.ts b/src/app/sevices/customer/domain/customer-page.model.ts
new file mode 100644
index 0000000..eef7fab
--- /dev/null
+++ b/src/app/sevices/customer/domain/customer-page.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {Customer} from './customer.model';
+
+export interface CustomerPage {
+ customers: Customer[];
+ totalElements: number;
+ totalPages: number;
+}
diff --git a/src/app/sevices/customer/domain/customer-state.model.ts b/src/app/sevices/customer/domain/customer-state.model.ts
new file mode 100644
index 0000000..c444393
--- /dev/null
+++ b/src/app/sevices/customer/domain/customer-state.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type CustomerState = 'PENDING' | 'ACTIVE' | 'LOCKED' | 'CLOSED';
diff --git a/src/app/sevices/customer/domain/customer-type.model.ts b/src/app/sevices/customer/domain/customer-type.model.ts
new file mode 100644
index 0000000..b9a1958
--- /dev/null
+++ b/src/app/sevices/customer/domain/customer-type.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type CustomerType = 'PERSON' | 'BUSINESS';
diff --git a/src/app/sevices/customer/domain/customer.model.ts b/src/app/sevices/customer/domain/customer.model.ts
new file mode 100644
index 0000000..409bb9b
--- /dev/null
+++ b/src/app/sevices/customer/domain/customer.model.ts
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {CustomerState} from './customer-state.model';
+import {CustomerType} from './customer-type.model';
+import {DateOfBirth} from './date-of-birth.model';
+import {IdentificationCard} from './identification-card.model';
+import {Address} from '../../domain/address/address.model';
+import {ContactDetail} from '../../domain/contact/contact-detail.model';
+import {Value} from '../../catalog/domain/value.model';
+
+export interface Customer {
+ identifier: string;
+ type: CustomerType;
+ givenName: string;
+ middleName?: string;
+ surname: string;
+ dateOfBirth: DateOfBirth;
+ identificationCard?: IdentificationCard;
+ accountBeneficiary?: string;
+ referenceCustomer?: string;
+ assignedOffice?: string;
+ assignedEmployee?: string;
+ address: Address;
+ contactDetails?: ContactDetail[];
+ currentState?: CustomerState;
+ applicationDate?: string;
+ customValues: Value[];
+ member: boolean;
+ createdBy?: string;
+ createdOn?: string;
+ lastModifiedBy?: string;
+ lastModifiedOn?: string;
+}
diff --git a/src/app/sevices/customer/domain/date-of-birth.model.ts b/src/app/sevices/customer/domain/date-of-birth.model.ts
new file mode 100644
index 0000000..6451d52
--- /dev/null
+++ b/src/app/sevices/customer/domain/date-of-birth.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface DateOfBirth {
+ year?: number;
+ month?: number;
+ day?: number;
+}
diff --git a/src/app/sevices/customer/domain/expiration-date.model.ts b/src/app/sevices/customer/domain/expiration-date.model.ts
new file mode 100644
index 0000000..a23b1c2
--- /dev/null
+++ b/src/app/sevices/customer/domain/expiration-date.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface ExpirationDate {
+ year: number;
+ month: number;
+ day: number;
+}
diff --git a/src/app/sevices/customer/domain/identification-card-scan.model.ts b/src/app/sevices/customer/domain/identification-card-scan.model.ts
new file mode 100644
index 0000000..0605777
--- /dev/null
+++ b/src/app/sevices/customer/domain/identification-card-scan.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface IdentificationCardScan {
+ identifier: string;
+ description: string;
+}
diff --git a/src/app/sevices/customer/domain/identification-card.model.ts b/src/app/sevices/customer/domain/identification-card.model.ts
new file mode 100644
index 0000000..27553b0
--- /dev/null
+++ b/src/app/sevices/customer/domain/identification-card.model.ts
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ExpirationDate} from './expiration-date.model';
+
+export interface IdentificationCard {
+ type: string;
+ number: string;
+ expirationDate: ExpirationDate;
+ issuer?: string;
+ createdBy?: string;
+ createdOn?: string;
+ lastModifiedBy?: string;
+ lastModifiedOn?: string;
+}
diff --git a/src/app/sevices/customer/domain/permittable-group-ids.ts b/src/app/sevices/customer/domain/permittable-group-ids.ts
new file mode 100644
index 0000000..9926e4c
--- /dev/null
+++ b/src/app/sevices/customer/domain/permittable-group-ids.ts
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class CustomerPermittableGroupIds {
+ public static readonly CUSTOMER_MANAGEMENT = 'customer__v1__customer';
+ public static readonly TASK_MANAGEMENT = 'customer__v1__task';
+ public static readonly CATALOG_MANAGEMENT = 'catalog__v1__catalog';
+ public static readonly IDENTITY_CARD_MANAGEMENT = 'customer__v1__identifications';
+ public static readonly PORTRAIT_MANAGEMENT = 'customer__v1__portrait';
+ public static readonly CUSTOMER_DOCUMENT = 'customer__v1__documents';
+}
+
+
diff --git a/src/app/sevices/customer/domain/process-step.model.ts b/src/app/sevices/customer/domain/process-step.model.ts
new file mode 100644
index 0000000..b112f22
--- /dev/null
+++ b/src/app/sevices/customer/domain/process-step.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Command} from './command.model';
+import {TaskDefinition} from './task-definition.model';
+
+export interface ProcessStep {
+ command: Command;
+ taskDefinitions: TaskDefinition[];
+}
diff --git a/src/app/sevices/customer/domain/task-definition.model.ts b/src/app/sevices/customer/domain/task-definition.model.ts
new file mode 100644
index 0000000..7cc6f1b
--- /dev/null
+++ b/src/app/sevices/customer/domain/task-definition.model.ts
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type TaskDefinitionType = 'ID_CARD' | 'FOUR_EYES' | 'CUSTOM';
+
+export type TaskDefinitionCommand = 'ACTIVATE' | 'LOCK' | 'UNLOCK' | 'CLOSE' | 'REOPEN';
+
+export interface TaskDefinition {
+ identifier: string;
+ type: TaskDefinitionType;
+ commands: TaskDefinitionCommand[];
+ name: string;
+ description: string;
+ mandatory: boolean;
+ predefined: boolean;
+}
diff --git a/src/app/sevices/depositAccount/deposit-account.service.ts b/src/app/sevices/depositAccount/deposit-account.service.ts
new file mode 100644
index 0000000..02ef3a0
--- /dev/null
+++ b/src/app/sevices/depositAccount/deposit-account.service.ts
@@ -0,0 +1,110 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {HttpClient} from '../http/http.service';
+import {Observable} from 'rxjs/Observable';
+import {ProductDefinition} from './domain/definition/product-definition.model';
+import {ProductDefinitionCommand} from './domain/definition/product-definition-command.model';
+import {ProductInstance} from './domain/instance/product-instance.model';
+import {RequestOptionsArgs, URLSearchParams} from '@angular/http';
+import {Action} from './domain/definition/action.model';
+import {DividendDistribution} from './domain/definition/dividend-distribution.model';
+import {AvailableTransactionType} from './domain/instance/available-transaction-type.model';
+
+@Injectable()
+export class DepositAccountService {
+
+ constructor(private http: HttpClient, @Inject('depositAccountBaseUrl') private baseUrl: string) {
+ }
+
+ createProductDefinition(productDefinition: ProductDefinition): Observable<void> {
+ return this.http.post(`${this.baseUrl}/definitions`, productDefinition);
+ }
+
+ updateProductDefinition(productDefinition: ProductDefinition): Observable<void> {
+ return this.http.put(`${this.baseUrl}/definitions/${productDefinition.identifier}`, productDefinition);
+ }
+
+ deleteProductDefinition(identifier: string): Observable<void> {
+ return this.http.delete(`${this.baseUrl}/definitions/${identifier}`);
+ }
+
+ fetchProductDefinitions(): Observable<ProductDefinition[]> {
+ return this.http.get(`${this.baseUrl}/definitions`);
+ }
+
+ findProductDefinition(identifier: string): Observable<ProductDefinition> {
+ return this.http.get(`${this.baseUrl}/definitions/${identifier}`);
+ }
+
+ processCommand(identifier: string, command: ProductDefinitionCommand): Observable<void> {
+ return this.http.post(`${this.baseUrl}/definitions/${identifier}/commands`, command);
+ }
+
+ fetchDividendDistributions(identifier: string): Observable<DividendDistribution[]> {
+ return this.http.get(`${this.baseUrl}/definitions/${identifier}/dividends`);
+ }
+
+ distributeDividend(identifier: string, dividendDistribution: DividendDistribution): Observable<void> {
+ return this.http.post(`${this.baseUrl}/definitions/${identifier}/dividends`, dividendDistribution);
+ }
+
+ createProductInstance(productInstance: ProductInstance): Observable<void> {
+ return this.http.post(`${this.baseUrl}/instances`, productInstance);
+ }
+
+ updateProductInstance(productInstance: ProductInstance): Observable<void> {
+ return this.http.put(`${this.baseUrl}/instances/${productInstance.accountIdentifier}`, productInstance);
+ }
+
+ findProductInstance(identifier: string): Observable<ProductInstance> {
+ return this.http.get(`${this.baseUrl}/instances/${identifier}`);
+ }
+
+ fetchProductInstances(customerIdentifier: string, productIdentifier?: string): Observable<ProductInstance[]> {
+ const search = new URLSearchParams();
+
+ search.append('customer', customerIdentifier);
+ search.append('product', productIdentifier);
+
+ const requestOptions: RequestOptionsArgs = {
+ search
+ };
+
+ return this.http.get(`${this.baseUrl}/instances`, requestOptions);
+ }
+
+ fetchActions(): Observable<Action[]> {
+ return this.http.get(`${this.baseUrl}/actions`);
+ }
+
+ fetchPossibleTransactionTypes(customerIdentifier: string): Observable<AvailableTransactionType[]> {
+ const search = new URLSearchParams();
+
+ search.append('customer', customerIdentifier);
+
+ const requestOptions: RequestOptionsArgs = {
+ search
+ };
+
+ return this.http.get(`${this.baseUrl}/instances/transactiontypes`, requestOptions);
+ }
+
+
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/action.model.ts b/src/app/sevices/depositAccount/domain/definition/action.model.ts
new file mode 100644
index 0000000..7d4a801
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/action.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Action {
+ identifier: string;
+ name: string;
+ description?: string;
+ transactionType: string;
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/charge.model.ts b/src/app/sevices/depositAccount/domain/definition/charge.model.ts
new file mode 100644
index 0000000..76ea29b
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/charge.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Charge {
+ actionIdentifier: string;
+ incomeAccountIdentifier: string;
+ name: string;
+ description?: string;
+ proportional?: boolean;
+ amount?: number;
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/currency.model.ts b/src/app/sevices/depositAccount/domain/definition/currency.model.ts
new file mode 100644
index 0000000..1e10bf5
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/currency.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Currency {
+ code: string;
+ name: string;
+ sign: string;
+ scale: number;
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/dividend-distribution.model.ts b/src/app/sevices/depositAccount/domain/definition/dividend-distribution.model.ts
new file mode 100644
index 0000000..170664c
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/dividend-distribution.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface DividendDistribution {
+ dueDate: {
+ year?: number;
+ month?: number;
+ day?: number;
+ };
+ dividendRate: string;
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/product-definition-command.model.ts b/src/app/sevices/depositAccount/domain/definition/product-definition-command.model.ts
new file mode 100644
index 0000000..6aef8c1
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/product-definition-command.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type Action = 'ACTIVATE' | 'DEACTIVATE';
+
+export interface ProductDefinitionCommand {
+ action: Action;
+ note?: string;
+ createdBy?: string;
+ createdOn?: string;
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/product-definition.model.ts b/src/app/sevices/depositAccount/domain/definition/product-definition.model.ts
new file mode 100644
index 0000000..b87cfc6
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/product-definition.model.ts
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Type} from '../type.model';
+import {Currency} from './currency.model';
+import {Charge} from './charge.model';
+import {Term} from './term.model';
+
+export interface ProductDefinition {
+ type: Type;
+ identifier: string;
+ name: string;
+ description?: string;
+ currency: Currency;
+ minimumBalance: number;
+ equityLedgerIdentifier?: string;
+ expenseAccountIdentifier: string;
+ cashAccountIdentifier: string;
+ accrueAccountIdentifier?: string;
+ interest?: number;
+ term: Term;
+ charges: Charge[];
+ flexible: boolean;
+ active?: boolean;
+}
diff --git a/src/app/sevices/depositAccount/domain/definition/term.model.ts b/src/app/sevices/depositAccount/domain/definition/term.model.ts
new file mode 100644
index 0000000..d016b9a
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/definition/term.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {TimeUnit} from '../time-unit.model';
+import {InterestPayable} from '../interest-payable.model';
+
+export interface Term {
+ period?: number;
+ timeUnit?: TimeUnit;
+ interestPayable: InterestPayable;
+}
diff --git a/src/app/sevices/depositAccount/domain/instance/available-transaction-type.model.ts b/src/app/sevices/depositAccount/domain/instance/available-transaction-type.model.ts
new file mode 100644
index 0000000..e4a7a10
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/instance/available-transaction-type.model.ts
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface AvailableTransactionType {
+ transactionType: string;
+}
diff --git a/src/app/sevices/depositAccount/domain/instance/product-instance.model.ts b/src/app/sevices/depositAccount/domain/instance/product-instance.model.ts
new file mode 100644
index 0000000..db82ca4
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/instance/product-instance.model.ts
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface ProductInstance {
+ customerIdentifier: string;
+ productIdentifier: string;
+ accountIdentifier?: string;
+ alternativeAccountNumber?: string;
+ beneficiaries?: string[];
+ state?: string;
+ balance?: number;
+ openedOn?: string;
+ lastTransactionDate?: string;
+}
diff --git a/src/app/sevices/depositAccount/domain/interest-payable.model.ts b/src/app/sevices/depositAccount/domain/interest-payable.model.ts
new file mode 100644
index 0000000..716bb74
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/interest-payable.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type InterestPayable = 'MATURITY' | 'ANNUALLY' | 'QUARTERLY' | 'MONTHLY';
diff --git a/src/app/sevices/depositAccount/domain/permittable-group-ids.ts b/src/app/sevices/depositAccount/domain/permittable-group-ids.ts
new file mode 100644
index 0000000..3f9bf3d
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/permittable-group-ids.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class DepositAccountPermittableGroupIds {
+ public static readonly DEFINITION_MANAGEMENT = 'deposit__v1__definition';
+ public static readonly INSTANCE_MANAGEMENT = 'deposit__v1__instance';
+}
diff --git a/src/app/sevices/depositAccount/domain/time-unit.model.ts b/src/app/sevices/depositAccount/domain/time-unit.model.ts
new file mode 100644
index 0000000..9b7f6bf
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/time-unit.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type TimeUnit = 'MONTH' | 'YEAR';
diff --git a/src/app/sevices/depositAccount/domain/type.model.ts b/src/app/sevices/depositAccount/domain/type.model.ts
new file mode 100644
index 0000000..20cea9e
--- /dev/null
+++ b/src/app/sevices/depositAccount/domain/type.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type Type = 'CHECKING' | 'SAVINGS' | 'SHARE';
diff --git a/src/app/sevices/domain/address/address.model.ts b/src/app/sevices/domain/address/address.model.ts
new file mode 100644
index 0000000..e378dc7
--- /dev/null
+++ b/src/app/sevices/domain/address/address.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Address {
+ street: string;
+ city: string;
+ region?: string;
+ postalCode?: string;
+ countryCode: string;
+ country: string;
+}
diff --git a/src/app/sevices/domain/contact/contact-detail.model.ts b/src/app/sevices/domain/contact/contact-detail.model.ts
new file mode 100644
index 0000000..ed1170d
--- /dev/null
+++ b/src/app/sevices/domain/contact/contact-detail.model.ts
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface ContactDetail {
+ type: ContactDetailType;
+ group: ContactDetailGroup;
+ value: string;
+ preferenceLevel: number;
+}
+
+export const BUSINESS = 'BUSINESS';
+export const PRIVATE = 'PRIVATE';
+
+export type ContactDetailGroup = 'BUSINESS' | 'PRIVATE';
+
+export const EMAIL = 'EMAIL';
+export const PHONE = 'PHONE';
+export const MOBILE = 'MOBILE';
+
+export type ContactDetailType = 'EMAIL' | 'PHONE' | 'MOBILE';
diff --git a/src/app/sevices/domain/date.converter.ts b/src/app/sevices/domain/date.converter.ts
new file mode 100644
index 0000000..365382f
--- /dev/null
+++ b/src/app/sevices/domain/date.converter.ts
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface FimsDate {
+ year: number;
+ month: number;
+ day: number;
+}
+
+export function dateAsISOString(date: Date): string {
+ return date.toISOString().slice(0, 10);
+}
+
+export function todayAsISOString(): string {
+ return new Date().toISOString().slice(0, 10);
+}
+
+/**
+ * Converts '2017-01-20' to full ISO string e.g. '2017-01-20T00:00:00.000Z'
+ * @param dateString
+ */
+export function toLongISOString(dateString: string): string {
+ const date: Date = parseDate(dateString);
+ return date.toISOString();
+}
+
+export function toShortISOString(dateString: string): string {
+ return `${toLongISOString(dateString).slice(0, 10)}Z`;
+}
+
+export function toEndOfDay(dateString: string): string {
+ const date: Date = parseDate(dateString);
+
+ date.setDate(date.getDate() + 1);
+ date.setTime(date.getTime() - 1);
+
+ return date.toISOString();
+}
+
+export function addCurrentTime(date: Date): Date {
+ const now: Date = new Date();
+
+ date.setUTCHours(now.getUTCHours());
+ date.setUTCMinutes(now.getUTCMinutes());
+ date.setUTCSeconds(now.getUTCSeconds());
+ date.setUTCMilliseconds(now.getUTCMilliseconds());
+
+ return date;
+}
+
+export function parseDate(dateString: string): Date {
+ const millis = Date.parse(dateString);
+ const date: Date = new Date(millis);
+
+ return date;
+}
+
+/**
+ * Converts '2017-01-20' to FimsDate
+ * @param dateString
+ */
+export function toFimsDate(dateString: string): FimsDate {
+ const chunks: string[] = dateString ? dateString.split('-') : [];
+
+ return {
+ year: chunks.length ? Number(chunks[0]) : undefined,
+ month: chunks.length ? Number(chunks[1]) : undefined,
+ day: chunks.length ? Number(chunks[2]) : undefined,
+ };
+}
+
+export function toISOString(fimsDate: FimsDate): string {
+ return formatDate(fimsDate.year, fimsDate.month, fimsDate.day);
+}
+
+function formatDate(year: number, month: number, day: number): string {
+ return `${year}-${addZero(month)}-${addZero(day)}`;
+}
+
+function addZero(value: number): string {
+ return ('0' + value).slice(-2);
+}
+
+
diff --git a/src/app/sevices/domain/error.model.ts b/src/app/sevices/domain/error.model.ts
new file mode 100644
index 0000000..1073ef5
--- /dev/null
+++ b/src/app/sevices/domain/error.model.ts
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Observable} from 'rxjs/Observable';
+import {ErrorObservable} from 'rxjs/observable/ErrorObservable';
+
+export class Error {
+ status: number;
+ statusText: string;
+ message: string;
+
+ static handleError(errorResponse: any): ErrorObservable {
+ const error: Error = new Error(errorResponse.status, errorResponse.statusText, errorResponse.message);
+
+ console.error(error.getErrorMessage());
+
+ return Observable.throw(error);
+ }
+
+ constructor(status: number, statusText: string, message: string) {
+ this.status = status;
+ this.message = message;
+ this.statusText = statusText;
+ }
+
+ getErrorMessage(): string {
+ const errMsg: string = (this.message)
+ ? this.message
+ : this.status ? `${this.status} - ${this.statusText}` : 'Server error';
+ return errMsg;
+ }
+
+}
diff --git a/src/app/sevices/domain/paging/fetch-request.model.ts b/src/app/sevices/domain/paging/fetch-request.model.ts
new file mode 100644
index 0000000..989a365
--- /dev/null
+++ b/src/app/sevices/domain/paging/fetch-request.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Sort} from './sort.model';
+import {Page} from './page.model';
+
+export interface FetchRequest {
+ searchTerm?: string;
+ page?: Page;
+ sort?: Sort;
+}
diff --git a/src/app/sevices/domain/paging/page.model.ts b/src/app/sevices/domain/paging/page.model.ts
new file mode 100644
index 0000000..b8172cf
--- /dev/null
+++ b/src/app/sevices/domain/paging/page.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Page {
+ pageIndex: number;
+ size: number;
+}
diff --git a/src/app/sevices/domain/paging/search-param.builder.ts b/src/app/sevices/domain/paging/search-param.builder.ts
new file mode 100644
index 0000000..258cebd
--- /dev/null
+++ b/src/app/sevices/domain/paging/search-param.builder.ts
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {URLSearchParams} from '@angular/http';
+import {FetchRequest} from './fetch-request.model';
+import {Page} from './page.model';
+import {Sort} from './sort.model';
+
+export function buildSearchParams(fetchRequest?: FetchRequest): URLSearchParams {
+ const params = new URLSearchParams();
+
+ fetchRequest = fetchRequest || {};
+
+ const page: Page = fetchRequest.page || {pageIndex: 0, size: 10};
+ const sort: Sort = fetchRequest.sort || {sortColumn: '', sortDirection: ''};
+
+ params.append('term', fetchRequest.searchTerm ? fetchRequest.searchTerm : undefined);
+
+ params.append('pageIndex', page.pageIndex !== undefined ? page.pageIndex.toString() : undefined);
+ params.append('size', page.size ? page.size.toString() : undefined);
+
+ params.append('sortColumn', sort.sortColumn ? sort.sortColumn : undefined);
+ params.append('sortDirection', sort.sortDirection ? sort.sortDirection : undefined);
+
+ return params;
+}
+
+export function buildDateRangeParam(startDate: string, endDate: string): string {
+ return `${startDate}..${endDate}`;
+}
diff --git a/src/app/sevices/domain/paging/sort.model.ts b/src/app/sevices/domain/paging/sort.model.ts
new file mode 100644
index 0000000..982864b
--- /dev/null
+++ b/src/app/sevices/domain/paging/sort.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface Sort {
+ sortColumn: string;
+ sortDirection: string;
+}
diff --git a/src/app/sevices/http/default-request-options.service.ts b/src/app/sevices/http/default-request-options.service.ts
new file mode 100644
index 0000000..56549c1
--- /dev/null
+++ b/src/app/sevices/http/default-request-options.service.ts
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {BaseRequestOptions, RequestOptions} from '@angular/http';
+import {Injectable} from '@angular/core';
+
+@Injectable()
+export class DefaultRequestOptions extends BaseRequestOptions {
+
+ constructor() {
+ super();
+
+ // this.headers.set('Accept', 'application/json');
+ // this.headers.set('Content-Type', 'application/json');
+ }
+}
+
+export const requestOptionsProvider = {provide: RequestOptions, useClass: DefaultRequestOptions};
diff --git a/src/app/sevices/http/header.service.ts b/src/app/sevices/http/header.service.ts
new file mode 100644
index 0000000..2abcfba
--- /dev/null
+++ b/src/app/sevices/http/header.service.ts
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class HeaderService {
+
+}
diff --git a/src/app/sevices/http/http.service.spec.ts b/src/app/sevices/http/http.service.spec.ts
new file mode 100644
index 0000000..0500f29
--- /dev/null
+++ b/src/app/sevices/http/http.service.spec.ts
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {MockBackend, MockConnection} from '@angular/http/testing';
+import {AUTHORIZATION_HEADER, HttpClient, TENANT_HEADER, USER_HEADER} from './http.service';
+import {
+ BaseRequestOptions,
+ ConnectionBackend,
+ Headers,
+ Http,
+ RequestOptions,
+ RequestOptionsArgs,
+ Response,
+ ResponseOptions
+} from '@angular/http';
+import {Store} from '@ngrx/store';
+import {Observable} from 'rxjs/Observable';
+import {ReflectiveInjector} from '@angular/core';
+
+describe('Test http client', () => {
+
+ const tenant = 'Reynholm Industries';
+
+ const authenticationState = {
+ username: 'test',
+ tenant: tenant,
+ authentication: {
+ tokenType: 'iDontCare',
+ accessToken: 'accessToken',
+ accessTokenExpiration: new Date().toISOString(),
+ refreshTokenExpiration: new Date().toISOString(),
+ passwordExpiration: new Date().toISOString(),
+ passwordChangedBy: 'moss'
+ }
+ };
+
+ const doPostRequest = function (httpClient: HttpClient, options?: RequestOptionsArgs): void {
+ httpClient.post('/test', {}, options).subscribe(() => {
+ });
+ };
+
+ describe('Test http header', () => {
+
+ beforeEach(() => {
+ this.injector = ReflectiveInjector.resolveAndCreate([
+ {provide: ConnectionBackend, useClass: MockBackend},
+ {provide: RequestOptions, useClass: BaseRequestOptions},
+ {
+ provide: Store, useClass: class {
+ select = jasmine.createSpy('select').and.returnValue(Observable.of(authenticationState));
+ }
+ },
+ Http,
+ HttpClient,
+ ]);
+ this.httpClient = this.injector.get(HttpClient);
+ this.backend = this.injector.get(ConnectionBackend) as MockBackend;
+ });
+
+ it('should send tenant header', (done: DoneFn) => {
+ this.backend.connections.subscribe((connection: MockConnection) => {
+ expect(connection.request.headers.get(TENANT_HEADER)).toBe(tenant);
+ done();
+ });
+ doPostRequest(this.httpClient);
+ });
+
+ it('should send authorization header when logged in', (done: DoneFn) => {
+ this.backend.connections.subscribe((connection: MockConnection) => {
+ expect(connection.request.headers.get(USER_HEADER)).toBe(authenticationState.username);
+ expect(connection.request.headers.get(AUTHORIZATION_HEADER)).toBe(authenticationState.authentication.accessToken);
+ done();
+ });
+ doPostRequest(this.httpClient);
+ });
+
+ it('should send custom headers', (done: DoneFn) => {
+ this.backend.connections.subscribe((connection: MockConnection) => {
+ expect(connection.request.headers.get('Content-Type')).toBe('multipart/form-data');
+ done();
+ });
+ doPostRequest(this.httpClient, {
+ headers: new Headers({
+ 'Content-Type': 'multipart/form-data'
+ })
+ });
+ });
+
+ it('should return json if json', (done: DoneFn) => {
+ const expectedResponse: any = {
+ text: 'text'
+ };
+ this.backend.connections.subscribe((connection: MockConnection) => {
+ const response = new Response(new ResponseOptions({
+ body: JSON.stringify(expectedResponse)
+ }));
+ connection.mockRespond(response);
+ });
+
+ this.httpClient.post('/test', {}).subscribe(response => {
+ expect(response).toEqual(expectedResponse);
+ done();
+ });
+ });
+
+ it('should return text if no json', (done: DoneFn) => {
+ this.backend.connections.subscribe((connection: MockConnection) => {
+ const response = new Response(new ResponseOptions({
+ body: 'text'
+ }));
+ connection.mockRespond(response);
+ });
+
+ this.httpClient.post('/test', {}).subscribe(text => {
+ expect(text).toEqual('text');
+ done();
+ });
+ });
+
+ });
+
+});
diff --git a/src/app/sevices/http/http.service.ts b/src/app/sevices/http/http.service.ts
new file mode 100644
index 0000000..7a33b35
--- /dev/null
+++ b/src/app/sevices/http/http.service.ts
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Headers, Http, Request, RequestMethod, RequestOptions, RequestOptionsArgs, Response} from '@angular/http';
+import {Observable} from 'rxjs/Observable';
+import {Subject} from 'rxjs/Subject';
+import {Store} from '@ngrx/store';
+import * as fromRoot from '../../store';
+import {LOGOUT} from '../../store/security/security.actions';
+
+export enum Action { QueryStart, QueryStop }
+
+export const TENANT_HEADER = 'X-Tenant-Identifier';
+export const USER_HEADER = 'User';
+export const AUTHORIZATION_HEADER = 'Authorization';
+
+@Injectable()
+export class HttpClient {
+
+ process: Subject<Action> = new Subject<Action>();
+
+ error: Subject<any> = new Subject<any>();
+
+ constructor(private http: Http, private store: Store<fromRoot.State>) {
+ }
+
+ public get(url: string, options?: RequestOptionsArgs, silent?: boolean): Observable<any> {
+ return this.createRequest(RequestMethod.Get, url, undefined, options, silent);
+ }
+
+ public post(url: string, body: any, options?: RequestOptionsArgs, silent?: boolean): Observable<any> {
+ return this.createRequest(RequestMethod.Post, url, body, options, silent);
+ }
+
+ public put(url: string, body: any, options?: RequestOptionsArgs): Observable<any> {
+ return this.createRequest(RequestMethod.Put, url, body, options);
+ }
+
+ public delete(url: string, options?: RequestOptionsArgs): Observable<any> {
+ return this.createRequest(RequestMethod.Delete, url, undefined, options);
+ }
+
+ private _buildRequestOptions(method: RequestMethod, url: string, body: any, tenant: string, username: string,
+ accessToken: string, options?: RequestOptionsArgs): RequestOptions {
+ options = options || {};
+
+ const headers = new Headers();
+
+ if (!(body instanceof FormData)) {
+ headers.set('Accept', 'application/json');
+ headers.set('Content-Type', 'application/json');
+ }
+
+ headers.set(TENANT_HEADER, tenant);
+ headers.set(USER_HEADER, username);
+ headers.set(AUTHORIZATION_HEADER, accessToken);
+
+ const requestOptions: RequestOptions = new RequestOptions({
+ method: method,
+ url: url,
+ body: body,
+ headers: headers
+ });
+
+ return requestOptions.merge(options);
+ }
+
+ private createRequest(method: RequestMethod, url: string, body?: any, options?: RequestOptionsArgs, silent?: boolean): Observable<any> {
+ return this.store.select(fromRoot.getAuthenticationState)
+ .take(1)
+ .map(state => this._buildRequestOptions(method, url, body, state.tenant, state.username, state.authentication.accessToken, options))
+ .flatMap(requestOptions => {
+ this.process.next(Action.QueryStart);
+
+ const request: Observable<any> = this.http.request(new Request(requestOptions))
+ .catch((err: any) => {
+ const error = err.json();
+ if (silent) {
+ return Observable.throw(error);
+ }
+
+ switch (error.status) {
+ case 409:
+ return Observable.throw(error);
+ case 401:
+ case 403:
+ this.store.dispatch({type: LOGOUT});
+ return Observable.throw('User is not authenticated');
+ default:
+ console.error('Error', error);
+ this.error.next(error);
+ return Observable.throw(error);
+ }
+ }).finally(() => this.process.next(Action.QueryStop));
+
+ return request.map((res: Response) => {
+ if (res.text()) {
+ try {
+ return res.json();
+ } catch (err) {
+ return res.text();
+ }
+ }
+ });
+ });
+ }
+
+}
diff --git a/src/app/sevices/identity/domain/authentication.model.ts b/src/app/sevices/identity/domain/authentication.model.ts
new file mode 100644
index 0000000..25ed770
--- /dev/null
+++ b/src/app/sevices/identity/domain/authentication.model.ts
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class Authentication {
+ tokenType: string;
+ accessToken: string;
+ accessTokenExpiration: string;
+ refreshTokenExpiration: string;
+ passwordExpiration: string;
+
+ constructor(tokenType: string,
+ accessToken: string, accessTokenExpiration: string,
+ refreshTokenExpiration: string,
+ passwordExpiration: string) {
+ this.tokenType = tokenType;
+ this.accessToken = accessToken;
+ this.accessTokenExpiration = accessTokenExpiration;
+ this.refreshTokenExpiration = refreshTokenExpiration;
+ this.passwordExpiration = passwordExpiration;
+ }
+}
diff --git a/src/app/sevices/identity/domain/password.model.ts b/src/app/sevices/identity/domain/password.model.ts
new file mode 100644
index 0000000..2b6a48b
--- /dev/null
+++ b/src/app/sevices/identity/domain/password.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class Password {
+ password: string;
+
+ constructor(password: string) {
+ this.password = password;
+ }
+}
diff --git a/src/app/sevices/identity/domain/permission.model.ts b/src/app/sevices/identity/domain/permission.model.ts
new file mode 100644
index 0000000..436f14d
--- /dev/null
+++ b/src/app/sevices/identity/domain/permission.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Permission {
+ permittableEndpointGroupIdentifier: string;
+ allowedOperations: AllowedOperation[];
+}
+
+export type AllowedOperation = 'READ' | 'CHANGE' | 'DELETE';
diff --git a/src/app/sevices/identity/domain/permittable-group-ids.model.ts b/src/app/sevices/identity/domain/permittable-group-ids.model.ts
new file mode 100644
index 0000000..271ae45
--- /dev/null
+++ b/src/app/sevices/identity/domain/permittable-group-ids.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class IdentityPermittableGroupIds {
+ public static readonly IDENTITY_MANAGEMENT = 'identity__v1__users';
+ public static readonly ROLE_MANAGEMENT = 'identity__v1__roles';
+ public static readonly SELF_MANAGEMENT = 'identity__v1__self';
+}
+
+
diff --git a/src/app/sevices/identity/domain/role-identifier.model.ts b/src/app/sevices/identity/domain/role-identifier.model.ts
new file mode 100644
index 0000000..50424b5
--- /dev/null
+++ b/src/app/sevices/identity/domain/role-identifier.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class RoleIdentifier {
+ identifier: string;
+
+ constructor(identifier: string) {
+ this.identifier = identifier;
+ }
+}
diff --git a/src/app/sevices/identity/domain/role.model.ts b/src/app/sevices/identity/domain/role.model.ts
new file mode 100644
index 0000000..123b657
--- /dev/null
+++ b/src/app/sevices/identity/domain/role.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Permission} from './permission.model';
+
+export interface Role {
+ identifier: string;
+ permissions: Permission[];
+}
diff --git a/src/app/sevices/identity/domain/user-with-password.model.ts b/src/app/sevices/identity/domain/user-with-password.model.ts
new file mode 100644
index 0000000..4369788
--- /dev/null
+++ b/src/app/sevices/identity/domain/user-with-password.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class UserWithPassword {
+ identifier: string;
+ role: string;
+ password: string;
+}
diff --git a/src/app/sevices/identity/domain/user.model.ts b/src/app/sevices/identity/domain/user.model.ts
new file mode 100644
index 0000000..ca761c7
--- /dev/null
+++ b/src/app/sevices/identity/domain/user.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class User {
+ identifier: string;
+ role: string;
+}
diff --git a/src/app/sevices/identity/identity.service.ts b/src/app/sevices/identity/identity.service.ts
new file mode 100644
index 0000000..12a8ad6
--- /dev/null
+++ b/src/app/sevices/identity/identity.service.ts
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import {Error} from '../domain/error.model';
+import {HttpClient} from '../http/http.service';
+import {Password} from './domain/password.model';
+import {UserWithPassword} from './domain/user-with-password.model';
+import {Role} from './domain/role.model';
+import {RoleIdentifier} from './domain/role-identifier.model';
+import {User} from './domain/user.model';
+import {PermittableGroup} from '../anubis/permittable-group.model';
+
+@Injectable()
+export class IdentityService {
+
+ private static encodePassword(password: string): string {
+ return btoa(password);
+ }
+
+ private baseUrl: string = "http://163.172.130.175:8888/"
+
+ constructor(private http: HttpClient ) { // , @Inject('identityBaseUrl') private baseUrl: string) {
+ }
+
+ changePassword(id: string, password: Password): Observable<any> {
+ password.password = IdentityService.encodePassword(password.password);
+ return this.http.put(this.baseUrl + '/users/' + id + '/password', password)
+ .catch(Error.handleError);
+ }
+
+ createUser(user: UserWithPassword): Observable<any> {
+ user.password = IdentityService.encodePassword(user.password);
+ return this.http.post(this.baseUrl + '/users', user)
+ .catch(Error.handleError);
+ }
+
+ getUser(id: string): Observable<User> {
+ return this.http.get(this.baseUrl + '/users/' + id)
+ .catch(Error.handleError);
+ }
+
+ changeUserRole(user: string, roleIdentifier: RoleIdentifier): Observable<any> {
+ return this.http.put(this.baseUrl + '/users/' + user + '/roleIdentifier', roleIdentifier)
+ .catch(Error.handleError);
+ }
+
+ listRoles(): Observable<Role[]> {
+ return this.http.get(this.baseUrl + '/roles')
+ .catch(Error.handleError);
+ }
+
+ getRole(id: string): Observable<Role> {
+ return this.http.get(this.baseUrl + '/roles/' + id)
+ .catch(Error.handleError);
+ }
+
+ createRole(role: Role): Observable<any> {
+ return this.http.post(this.baseUrl + '/roles', role)
+ .catch(Error.handleError);
+ }
+
+ changeRole(role: Role): Observable<any> {
+ return this.http.put(this.baseUrl + '/roles/' + role.identifier, role)
+ .catch(Error.handleError);
+ }
+
+ deleteRole(id: String): Observable<any> {
+ return this.http.delete(this.baseUrl + '/roles/' + id, {})
+ .catch(Error.handleError);
+ }
+
+ createPermittableGroup(permittableGroup: PermittableGroup): Observable<PermittableGroup> {
+ return this.http.post(this.baseUrl + '/permittablegroups', permittableGroup)
+ .catch(Error.handleError);
+ }
+
+ getPermittableGroup(id: string): Observable<PermittableGroup> {
+ return this.http.get(this.baseUrl + '/permittablegroups/' + id)
+ .catch(Error.handleError);
+ }
+
+ getPermittableGroups(): Observable<PermittableGroup[]> {
+ return this.http.get(this.baseUrl + '/permittablegroups')
+ .catch(Error.handleError);
+ }
+}
diff --git a/src/app/sevices/image/image.service.ts b/src/app/sevices/image/image.service.ts
new file mode 100644
index 0000000..2db3b1e
--- /dev/null
+++ b/src/app/sevices/image/image.service.ts
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {Headers, Http, Response, ResponseContentType} from '@angular/http';
+import {Observable} from 'rxjs/Observable';
+import {Store} from '@ngrx/store';
+import * as fromRoot from '../../store';
+import {AUTHORIZATION_HEADER, TENANT_HEADER, USER_HEADER} from '../http/http.service';
+import {State} from '../../store/security/authentication.reducer';
+
+@Injectable()
+export class ImageService {
+
+ constructor(private http: Http, private store: Store<fromRoot.State>) {
+ }
+
+ /* public getImage(url: string): Observable<Blob> {
+ return this.store.select(fromRoot.getAuthenticationState)
+ .take(1)
+ .map(this.mapHeader)
+ .switchMap((headers: Headers) =>
+ this.http.get(url, {
+ responseType: ResponseContentType.Blob,
+ headers: headers
+ })
+ .map((response: Response) => response.blob())
+ .catch(() => Observable.empty()));
+
+ }
+ */
+
+
+ private mapHeader(authenticationState: State): Headers {
+ const headers = new Headers();
+
+ headers.set('Accept', 'application/json');
+
+ headers.set(TENANT_HEADER, authenticationState.tenant);
+ headers.set(USER_HEADER, authenticationState.username);
+ headers.set(AUTHORIZATION_HEADER, authenticationState.authentication.accessToken);
+
+ return headers;
+ }
+
+}
diff --git a/src/app/sevices/notification/notification.service.ts b/src/app/sevices/notification/notification.service.ts
new file mode 100644
index 0000000..96ba681
--- /dev/null
+++ b/src/app/sevices/notification/notification.service.ts
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Injectable} from '@angular/core';
+import {BehaviorSubject} from 'rxjs/BehaviorSubject';
+
+export enum NotificationType {
+ MESSAGE, ALERT
+}
+
+export interface NotificationEvent {
+ type: NotificationType;
+ title?: string;
+ message: string;
+}
+
+@Injectable()
+export class NotificationService {
+
+ private notificationSource = new BehaviorSubject<NotificationEvent>(null);
+
+ notifications$ = this.notificationSource.asObservable();
+
+ send(notification: NotificationEvent) {
+ this.notificationSource.next(notification);
+ }
+}
diff --git a/src/app/sevices/office/domain/employee-page.model.ts b/src/app/sevices/office/domain/employee-page.model.ts
new file mode 100644
index 0000000..5e55739
--- /dev/null
+++ b/src/app/sevices/office/domain/employee-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Employee} from './employee.model';
+
+export interface EmployeePage {
+ employees: Employee[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/office/domain/employee.model.ts b/src/app/sevices/office/domain/employee.model.ts
new file mode 100644
index 0000000..485e515
--- /dev/null
+++ b/src/app/sevices/office/domain/employee.model.ts
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ContactDetail} from '../../domain/contact/contact-detail.model';
+
+export interface Employee {
+ identifier: string;
+ givenName: string;
+ middleName?: string;
+ surname: string;
+ assignedOffice?: string;
+ contactDetails: ContactDetail[];
+}
diff --git a/src/app/sevices/office/domain/office-page.model.ts b/src/app/sevices/office/domain/office-page.model.ts
new file mode 100644
index 0000000..07d0400
--- /dev/null
+++ b/src/app/sevices/office/domain/office-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Office} from './office.model';
+
+export interface OfficePage {
+ offices: Office[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/office/domain/office.model.ts b/src/app/sevices/office/domain/office.model.ts
new file mode 100644
index 0000000..4fc8019
--- /dev/null
+++ b/src/app/sevices/office/domain/office.model.ts
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Address} from '../../domain/address/address.model';
+
+export interface Office {
+ identifier: string;
+ parentIdentifier?: string;
+ name: string;
+ description?: string;
+ address?: Address;
+ branches?: Office[];
+ tellerIds?: string[];
+ externalReferences?: boolean;
+}
diff --git a/src/app/sevices/office/domain/permittable-group-ids.model.ts b/src/app/sevices/office/domain/permittable-group-ids.model.ts
new file mode 100644
index 0000000..cec0a5a
--- /dev/null
+++ b/src/app/sevices/office/domain/permittable-group-ids.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class OfficePermittableGroupIds {
+ public static readonly OFFICE_MANAGEMENT = 'office__v1__offices';
+ public static readonly EMPLOYEE_MANAGEMENT = 'office__v1__employees';
+ public static readonly SELF_MANAGEMENT = 'office__v1__self';
+}
+
+
diff --git a/src/app/sevices/office/office.service.ts b/src/app/sevices/office/office.service.ts
new file mode 100644
index 0000000..5df8ab2
--- /dev/null
+++ b/src/app/sevices/office/office.service.ts
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import {HttpClient} from '../http/http.service';
+import {Error} from '../domain/error.model';
+import {RequestOptionsArgs, URLSearchParams,} from '@angular/http';
+import {Office} from './domain/office.model';
+import {FetchRequest} from '../domain/paging/fetch-request.model';
+import {OfficePage} from './domain/office-page.model';
+import {EmployeePage} from './domain/employee-page.model';
+import {Employee} from './domain/employee.model';
+import {buildSearchParams} from '../domain/paging/search-param.builder';
+import {ContactDetail} from '../domain/contact/contact-detail.model';
+
+@Injectable()
+export class OfficeService {
+
+ constructor(private http: HttpClient, @Inject('officeBaseUrl') private baseUrl: string) {
+ }
+
+ createOffice(office: Office): Observable<Office> {
+ return this.http.post(this.baseUrl + '/offices', office)
+
+ }
+
+ addBranch(id: string, office: Office): Observable<Office> {
+ return this.http.post(this.baseUrl + '/offices/' + id, office)
+
+ }
+
+ updateOffice(office: Office): Observable<Office> {
+ return this.http.put(this.baseUrl + '/offices/' + office.identifier, office)
+
+ }
+
+ deleteOffice(id: String): Observable<Office> {
+ return this.http.delete(this.baseUrl + '/offices/' + id, {})
+
+ }
+
+ listOffices(fetchRequest?: FetchRequest): Observable<OfficePage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ search: params
+ };
+ return this.http.get(this.baseUrl + '/offices', requestOptions)
+
+ }
+
+ listBranches(parentIdentifier: string, fetchRequest?: FetchRequest): Observable<OfficePage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ search: params
+ };
+ return this.http.get(this.baseUrl + '/offices/' + parentIdentifier + '/branches', requestOptions)
+
+ }
+
+ getOffice(id: string): Observable<Office> {
+ return this.http.get(this.baseUrl + '/offices/' + id)
+
+ }
+
+ listEmployees(fetchRequest?: FetchRequest): Observable<EmployeePage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ search: params
+ };
+
+ return this.http.get(this.baseUrl + '/employees', requestOptions)
+
+ }
+
+ getEmployee(id: string, silent?: true): Observable<Employee> {
+ return this.http.get(this.baseUrl + '/employees/' + id, {}, silent)
+
+ }
+
+ createEmployee(employee: Employee): Observable<Employee> {
+ return this.http.post(this.baseUrl + '/employees', employee)
+
+ }
+
+ updateEmployee(employee: Employee): Observable<Employee> {
+ return this.http.put(this.baseUrl + '/employees/' + employee.identifier, employee)
+
+ }
+
+ deleteEmployee(id: string): Observable<Employee> {
+ return this.http.delete(this.baseUrl + '/employees/' + id, {})
+
+ }
+
+ setContactDetails(id: string, contactDetails: ContactDetail[]): Observable<void> {
+ return this.http.put(this.baseUrl + '/employees/' + id + '/contacts', contactDetails);
+ }
+
+}
diff --git a/src/app/sevices/payroll/domain/payroll-allocation.model.ts b/src/app/sevices/payroll/domain/payroll-allocation.model.ts
new file mode 100644
index 0000000..c9de4e5
--- /dev/null
+++ b/src/app/sevices/payroll/domain/payroll-allocation.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface PayrollAllocation {
+ accountNumber: string;
+ amount: string;
+ proportional: boolean;
+}
diff --git a/src/app/sevices/payroll/domain/payroll-collection-history.model.ts b/src/app/sevices/payroll/domain/payroll-collection-history.model.ts
new file mode 100644
index 0000000..87c0a30
--- /dev/null
+++ b/src/app/sevices/payroll/domain/payroll-collection-history.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface PayrollCollectionHistory {
+ identifier?: string;
+ sourceAccountNumber: string;
+ createdBy: string;
+ createdOn: string;
+}
diff --git a/src/app/sevices/payroll/domain/payroll-collection-sheet.model.ts b/src/app/sevices/payroll/domain/payroll-collection-sheet.model.ts
new file mode 100644
index 0000000..de2b492
--- /dev/null
+++ b/src/app/sevices/payroll/domain/payroll-collection-sheet.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {PayrollPayment} from './payroll-payment.model';
+
+export interface PayrollCollectionSheet {
+ sourceAccountNumber: string;
+ payrollPayments: PayrollPayment[];
+}
diff --git a/src/app/sevices/payroll/domain/payroll-configuration.model.ts b/src/app/sevices/payroll/domain/payroll-configuration.model.ts
new file mode 100644
index 0000000..21fb5ea
--- /dev/null
+++ b/src/app/sevices/payroll/domain/payroll-configuration.model.ts
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {PayrollAllocation} from './payroll-allocation.model';
+
+export interface PayrollConfiguration {
+ mainAccountNumber: string;
+ payrollAllocations: PayrollAllocation[];
+ createdBy?: string;
+ createdOn?: string;
+ lastModifiedBy?: string;
+ lastModifiedOn?: string;
+}
diff --git a/src/app/sevices/payroll/domain/payroll-payment-page.model.ts b/src/app/sevices/payroll/domain/payroll-payment-page.model.ts
new file mode 100644
index 0000000..e0ca049
--- /dev/null
+++ b/src/app/sevices/payroll/domain/payroll-payment-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {PayrollPayment} from './payroll-payment.model';
+
+export interface PayrollPaymentPage {
+ payrollPayments: PayrollPayment[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/payroll/domain/payroll-payment.model.ts b/src/app/sevices/payroll/domain/payroll-payment.model.ts
new file mode 100644
index 0000000..252cfba
--- /dev/null
+++ b/src/app/sevices/payroll/domain/payroll-payment.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface PayrollPayment {
+ customerIdentifier: string;
+ employer: string;
+ salary: string;
+}
diff --git a/src/app/sevices/payroll/domain/permittable-group-ids.ts b/src/app/sevices/payroll/domain/permittable-group-ids.ts
new file mode 100644
index 0000000..9bb2e99
--- /dev/null
+++ b/src/app/sevices/payroll/domain/permittable-group-ids.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class PayrollPermittableGroupIds {
+ public static readonly CONFIGURATION = 'payroll__v1__configuration';
+ public static readonly DISTRIBUTION = 'payroll__v1__distribution';
+}
diff --git a/src/app/sevices/payroll/payroll.service.ts b/src/app/sevices/payroll/payroll.service.ts
new file mode 100644
index 0000000..c9236b8
--- /dev/null
+++ b/src/app/sevices/payroll/payroll.service.ts
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Inject, Injectable} from '@angular/core';
+import {RequestOptionsArgs} from '@angular/http';
+import {buildSearchParams} from '../domain/paging/search-param.builder';
+import {PayrollPaymentPage} from './domain/payroll-payment-page.model';
+import {Observable} from 'rxjs/Observable';
+import {FetchRequest} from '../domain/paging/fetch-request.model';
+import {PayrollCollectionHistory} from './domain/payroll-collection-history.model';
+import {PayrollCollectionSheet} from './domain/payroll-collection-sheet.model';
+import {HttpClient} from '../http/http.service';
+import {PayrollConfiguration} from './domain/payroll-configuration.model';
+
+@Injectable()
+export class PayrollService {
+
+ constructor(private http: HttpClient, @Inject('payrollBaseUrl') private baseUrl: string) {
+ }
+
+ public distribute(sheet: PayrollCollectionSheet): Observable<void> {
+ return this.http.post(`${this.baseUrl}/distribution`, sheet);
+ }
+
+ public fetchDistributionHistory(): Observable<PayrollCollectionHistory[]> {
+ return this.http.get(`${this.baseUrl}/distribution`);
+ }
+
+ public fetchPayments(identifier: string, fetchRequest?: FetchRequest): Observable<PayrollPaymentPage> {
+ const params: URLSearchParams = buildSearchParams(fetchRequest);
+
+ const requestOptions: RequestOptionsArgs = {
+ params
+ };
+ return this.http.get(`${this.baseUrl}/distribution/${identifier}/payments`, requestOptions);
+ }
+
+ setPayrollConfiguration(customerId: string, configuration: PayrollConfiguration): Observable<void> {
+ return this.http.put(`${this.baseUrl}/customers/${customerId}/payroll`, configuration);
+ }
+
+ findPayrollConfiguration(customerId: string, silent: boolean = false): Observable<PayrollConfiguration> {
+ return this.http.get(`${this.baseUrl}/customers/${customerId}/payroll`, {}, silent);
+ }
+}
diff --git a/src/app/sevices/portfolio/domain/account-assignment.model.ts b/src/app/sevices/portfolio/domain/account-assignment.model.ts
new file mode 100644
index 0000000..7cb183e
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/account-assignment.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface AccountAssignment {
+ designator: string;
+ accountIdentifier?: string;
+ ledgerIdentifier?: string;
+}
diff --git a/src/app/sevices/portfolio/domain/balance-range.model.ts b/src/app/sevices/portfolio/domain/balance-range.model.ts
new file mode 100644
index 0000000..0c4b5aa
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/balance-range.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface BalanceRange {
+ minimum: number;
+ maximum: number;
+}
diff --git a/src/app/sevices/portfolio/domain/balance-segment-set.model.ts b/src/app/sevices/portfolio/domain/balance-segment-set.model.ts
new file mode 100644
index 0000000..d39cb5c
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/balance-segment-set.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface BalanceSegmentSet {
+ identifier: string;
+ segments: number[];
+ segmentIdentifiers: string[];
+}
diff --git a/src/app/sevices/portfolio/domain/case-command.model.ts b/src/app/sevices/portfolio/domain/case-command.model.ts
new file mode 100644
index 0000000..6318513
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/case-command.model.ts
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountAssignment} from './account-assignment.model';
+
+export interface CaseCommand {
+ oneTimeAccountAssignments?: AccountAssignment[];
+ paymentSize?: number;
+ note?: string;
+ createdOn: string;
+ createdBy?: string;
+}
diff --git a/src/app/sevices/portfolio/domain/case-customer-documents.model.ts b/src/app/sevices/portfolio/domain/case-customer-documents.model.ts
new file mode 100644
index 0000000..6aec456
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/case-customer-documents.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Document {
+ customerId: string;
+ documentId: string;
+}
+
+export interface CaseCustomerDocuments {
+ documents: Document[]
+}
diff --git a/src/app/sevices/portfolio/domain/case-page.model.ts b/src/app/sevices/portfolio/domain/case-page.model.ts
new file mode 100644
index 0000000..90fbf31
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/case-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Case} from './case.model';
+
+export interface CasePage {
+ elements: Case[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/portfolio/domain/case-state.model.ts b/src/app/sevices/portfolio/domain/case-state.model.ts
new file mode 100644
index 0000000..91defff
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/case-state.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type CaseState = 'CREATED' | 'PENDING' | 'APPROVED' | 'ACTIVE' | 'CLOSED';
diff --git a/src/app/sevices/portfolio/domain/case.model.ts b/src/app/sevices/portfolio/domain/case.model.ts
new file mode 100644
index 0000000..6856b44
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/case.model.ts
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {AccountAssignment} from './account-assignment.model';
+import {CaseState} from './case-state.model';
+
+export interface Case {
+ identifier: string;
+ productIdentifier: string;
+ interest: number;
+ parameters: string;
+ accountAssignments: AccountAssignment[];
+ currentState?: CaseState;
+ createdOn?: string;
+ createdBy?: string;
+ lastModifiedOn?: string;
+ lastModifiedBy?: string;
+}
diff --git a/src/app/sevices/portfolio/domain/charge-definition.model.ts b/src/app/sevices/portfolio/domain/charge-definition.model.ts
new file mode 100644
index 0000000..599593e
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/charge-definition.model.ts
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ChargeMethod} from './charge-method.model';
+import {ChronoUnit} from './chrono-unit.model';
+import {WorkflowAction} from './individuallending/workflow-action.model';
+
+export interface ChargeDefinition {
+ identifier: string;
+ name: string;
+ description: string;
+ chargeAction: WorkflowAction;
+ chargeMethod: ChargeMethod;
+ amount: number;
+ fromAccountDesignator: string;
+ toAccountDesignator: string;
+ forCycleSizeUnit: ChronoUnit;
+ accrualAccountDesignator?: string;
+ accrueAction?: WorkflowAction;
+ readOnly?: boolean;
+ proportionalTo: string;
+ forSegmentSet?: string;
+ fromSegment?: string;
+ toSegment?: string;
+ chargeOnTop?: boolean;
+}
diff --git a/src/app/sevices/portfolio/domain/charge-method.model.ts b/src/app/sevices/portfolio/domain/charge-method.model.ts
new file mode 100644
index 0000000..1bc00c9
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/charge-method.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type ChargeMethod = 'FIXED' | 'PROPORTIONAL' | 'INTEREST';
diff --git a/src/app/sevices/portfolio/domain/chrono-unit.model.ts b/src/app/sevices/portfolio/domain/chrono-unit.model.ts
new file mode 100644
index 0000000..7fb845e
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/chrono-unit.model.ts
@@ -0,0 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export type ChronoUnit = 'WEEKS' | 'MONTHS' | 'YEARS';
diff --git a/src/app/sevices/portfolio/domain/cost-component.model.ts b/src/app/sevices/portfolio/domain/cost-component.model.ts
new file mode 100644
index 0000000..8c955f1
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/cost-component.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class CostComponent {
+ chargeIdentifier: string;
+ amount: number;
+}
diff --git a/src/app/sevices/portfolio/domain/fims-case-page.model.ts b/src/app/sevices/portfolio/domain/fims-case-page.model.ts
new file mode 100644
index 0000000..37f4a75
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/fims-case-page.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {FimsCase} from './fims-case.model';
+
+export interface FimsCasePage {
+ elements: FimsCase[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/portfolio/domain/fims-case.model.ts b/src/app/sevices/portfolio/domain/fims-case.model.ts
new file mode 100644
index 0000000..36985e8
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/fims-case.model.ts
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {CaseParameters} from './individuallending/case-parameters.model';
+import {CaseState} from './case-state.model';
+
+export interface FimsCase {
+ identifier: string;
+ productIdentifier: string;
+ interest: number;
+ parameters: CaseParameters;
+ depositAccountIdentifier: string;
+ customerLoanAccountIdentifier?: string;
+ currentState?: CaseState;
+ createdOn?: string;
+ createdBy?: string;
+ lastModifiedOn?: string;
+ lastModifiedBy?: string;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/account-designators.model.ts b/src/app/sevices/portfolio/domain/individuallending/account-designators.model.ts
new file mode 100644
index 0000000..aefeb4a
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/account-designators.model.ts
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * A debit is an accounting entry that either increases an asset or expense account, or decreases a liability or equity account.
+ * It is positioned to the left in an accounting entry.
+ *
+ * A credit is an accounting entry that either increases a liability or equity account, or decreases an asset or expense account.
+ */
+
+export class AccountDesignators {
+
+ public static readonly CUSTOMER_LOAN_GROUP = 'cll';
+
+ public static readonly CUSTOMER_LOAN_PRINCIPAL = 'clp';
+
+ public static readonly CUSTOMER_LOAN_INTEREST = 'cli';
+
+ public static readonly CUSTOMER_LOAN_FEES = 'clf';
+
+ public static readonly LOAN_FUNDS_SOURCE = 'ls';
+
+ public static readonly PROCESSING_FEE_INCOME = 'pfi';
+
+ public static readonly ORIGINATION_FEE_INCOME = 'ofi';
+
+ public static readonly DISBURSEMENT_FEE_INCOME = 'dfi';
+
+ public static readonly INTEREST_INCOME = 'ii';
+
+ public static readonly INTEREST_ACCRUAL = 'ia';
+
+ public static readonly LATE_FEE_INCOME = 'lfi';
+
+ public static readonly LATE_FEE_ACCRUAL = 'lfa';
+
+ public static readonly PRODUCT_LOSS_ALLOWANCE = 'pa';
+
+ public static readonly GENERAL_LOSS_ALLOWANCE = 'aa';
+
+ public static readonly GENERAL_EXPENSE = 'ge';
+
+ public static readonly ENTRY = 'ey';
+
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/case-parameters.model.ts b/src/app/sevices/portfolio/domain/individuallending/case-parameters.model.ts
new file mode 100644
index 0000000..40bbc43
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/case-parameters.model.ts
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {TermRange} from '../term-range.model';
+import {PaymentCycle} from '../payment-cycle.model';
+import {CreditWorthinessSnapshot} from './credit-worthiness-snapshot.model';
+
+export interface CaseParameters {
+ customerIdentifier: string;
+ termRange: TermRange;
+ maximumBalance: number;
+ paymentCycle: PaymentCycle;
+ creditWorthinessSnapshots: CreditWorthinessSnapshot[];
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/charge-name.model.ts b/src/app/sevices/portfolio/domain/individuallending/charge-name.model.ts
new file mode 100644
index 0000000..3d41229
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/charge-name.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface ChargeName {
+ identifier: string;
+ name: string;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/charge-proportional-designators.model.ts b/src/app/sevices/portfolio/domain/individuallending/charge-proportional-designators.model.ts
new file mode 100644
index 0000000..3c5f513
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/charge-proportional-designators.model.ts
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export class ChargeProportionalDesignators {
+ public static readonly NOT_PROPORTIONAL = '{notproportional}';
+
+ public static readonly MAXIMUM_BALANCE_DESIGNATOR = '{maximumbalance}';
+
+ public static readonly RUNNING_BALANCE_DESIGNATOR = '{runningbalance}';
+
+ public static readonly PRINCIPAL_DESIGNATOR = '{principal}';
+
+ public static readonly REQUESTED_DISBURSEMENT_DESIGNATOR = '{requesteddisbursement}';
+
+ public static readonly TO_ACCOUNT_DESIGNATOR = '{toAccount}';
+
+ public static readonly FROM_ACCOUNT_DESIGNATOR = '{fromAccount}';
+
+ public static readonly REQUESTED_REPAYMENT_DESIGNATOR = '{requestedrepayment}';
+
+ public static readonly CONTRACTUAL_REPAYMENT_DESIGNATOR = '{contractualrepayment}';
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/credit-worthiness-factor.model.ts b/src/app/sevices/portfolio/domain/individuallending/credit-worthiness-factor.model.ts
new file mode 100644
index 0000000..d128f4b
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/credit-worthiness-factor.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface CreditWorthinessFactor {
+ description?: string;
+ amount: string;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/credit-worthiness-snapshot.model.ts b/src/app/sevices/portfolio/domain/individuallending/credit-worthiness-snapshot.model.ts
new file mode 100644
index 0000000..fca8446
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/credit-worthiness-snapshot.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {CreditWorthinessFactor} from './credit-worthiness-factor.model';
+
+export interface CreditWorthinessSnapshot {
+ forCustomer: string;
+ incomeSources: CreditWorthinessFactor[];
+ assets: CreditWorthinessFactor[];
+ debts: CreditWorthinessFactor[];
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/document.model.ts b/src/app/sevices/portfolio/domain/individuallending/document.model.ts
new file mode 100644
index 0000000..d77a8eb
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/document.model.ts
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface Document {
+ description: string;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/moratorium.model.ts b/src/app/sevices/portfolio/domain/individuallending/moratorium.model.ts
new file mode 100644
index 0000000..50f910a
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/moratorium.model.ts
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {ChronoUnit} from '../chrono-unit.model';
+
+export class Moratorium {
+ chargeTask: string;
+ temporalUnit: ChronoUnit;
+ period: number;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/planned-payment-page.model.ts b/src/app/sevices/portfolio/domain/individuallending/planned-payment-page.model.ts
new file mode 100644
index 0000000..9c7a0c8
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/planned-payment-page.model.ts
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {PlannedPayment} from './planned-payment.model';
+import {ChargeName} from './charge-name.model';
+
+export class PlannedPaymentPage {
+ elements: PlannedPayment[];
+ chargeNames: ChargeName[];
+ totalPages: number;
+ totalElements: number;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/planned-payment.model.ts b/src/app/sevices/portfolio/domain/individuallending/planned-payment.model.ts
new file mode 100644
index 0000000..6b68557
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/planned-payment.model.ts
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Payment} from '../payment.model';
+
+export interface PlannedPayment {
+ payment: Payment;
+ balances: { [id: string]: number };
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/product-parameters.model.ts b/src/app/sevices/portfolio/domain/individuallending/product-parameters.model.ts
new file mode 100644
index 0000000..5e8a507
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/product-parameters.model.ts
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {Moratorium} from './moratorium.model';
+
+export class ProductParameters {
+ moratoriums: Moratorium[];
+ maximumDispersalCount: number;
+ maximumDispersalAmount: number;
+ minimumDispersalAmount: number;
+}
diff --git a/src/app/sevices/portfolio/domain/individuallending/workflow-action.model.ts b/src/app/sevices/portfolio/domain/individuallending/workflow-action.model.ts
new file mode 100644
index 0000000..69a7127
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/individuallending/workflow-action.model.ts
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type WorkflowAction =
+ 'OPEN'
+ | 'DENY'
+ | 'APPROVE'
+ | 'ACCEPT_PAYMENT'
+ | 'DISBURSE'
+ | 'MARK_LATE'
+ | 'APPLY_INTEREST'
+ | 'WRITE_OFF'
+ | 'CLOSE'
+ | 'RECOVER';
diff --git a/src/app/sevices/portfolio/domain/interest-basis.model.ts b/src/app/sevices/portfolio/domain/interest-basis.model.ts
new file mode 100644
index 0000000..fbad706
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/interest-basis.model.ts
@@ -0,0 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export type InterestBasis = 'CURRENT_BALANCE' | 'BEGINNING_BALANCE';
diff --git a/src/app/sevices/portfolio/domain/interest-range.model.ts b/src/app/sevices/portfolio/domain/interest-range.model.ts
new file mode 100644
index 0000000..fb97846
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/interest-range.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface InterestRange {
+ minimum: number;
+ maximum: number;
+}
diff --git a/src/app/sevices/portfolio/domain/loss-provision-configuration.model.ts b/src/app/sevices/portfolio/domain/loss-provision-configuration.model.ts
new file mode 100644
index 0000000..08c8a77
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/loss-provision-configuration.model.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {LossProvisionStep} from './loss-provision-step.model';
+
+export interface LossProvisionConfiguration {
+ lossProvisionSteps: LossProvisionStep[];
+}
diff --git a/src/app/sevices/portfolio/domain/loss-provision-step.model.ts b/src/app/sevices/portfolio/domain/loss-provision-step.model.ts
new file mode 100644
index 0000000..b11e708
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/loss-provision-step.model.ts
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface LossProvisionStep {
+ daysLate: number;
+ percentProvision: number;
+}
diff --git a/src/app/sevices/portfolio/domain/mapper/fims-case-page.mapper.ts b/src/app/sevices/portfolio/domain/mapper/fims-case-page.mapper.ts
new file mode 100644
index 0000000..1fbd52a
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/mapper/fims-case-page.mapper.ts
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {mapToFimsCase} from './fims-case.mapper';
+import {FimsCasePage} from '../fims-case-page.model';
+import {CasePage} from '../case-page.model';
+
+export function mapToFimsCasePage(casePage: CasePage): FimsCasePage {
+ const elements = [];
+
+ for (const caseInstance of casePage.elements) {
+ elements.push(mapToFimsCase(caseInstance));
+ }
+
+ return {
+ elements: elements,
+ totalPages: casePage.totalPages,
+ totalElements: casePage.totalElements
+ };
+}
diff --git a/src/app/sevices/portfolio/domain/mapper/fims-case.mapper.ts b/src/app/sevices/portfolio/domain/mapper/fims-case.mapper.ts
new file mode 100644
index 0000000..9c6ad56
--- /dev/null
+++ b/src/app/sevices/portfolio/domain/mapper/fims-case.mapper.ts
@@ -0,0 +1,46 @@
+/**
... 5607 lines suppressed ...