From 17b56351bb2a0dd44c6c9d524180fcaa79834391 Mon Sep 17 00:00:00 2001 From: Dhaarani <55541808+DhaaraniCIT@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:34:35 +0530 Subject: [PATCH] xero master (#574) xero master --- run.sh | 5 ++ scripts/setup_env.js | 5 ++ src/app/auth/login/login.component.ts | 8 +- src/app/core/guard/tenant.guard.spec.ts | 15 ++++ src/app/core/guard/tenant.guard.ts | 49 ++++++++++ src/app/core/guard/xero-token.guard.spec.ts | 16 ++++ src/app/core/guard/xero-token.guard.ts | 55 ++++++++++++ .../models/db/expense-group-setting.model.ts | 4 +- src/app/core/models/enum/enum.model.ts | 31 ++++++- .../models/integrations/integrations.model.ts | 1 + .../models/xero/db/xero-credential.model.ts | 9 ++ .../models/xero/db/xero-task-log.model.ts | 25 ++++++ .../xero/db/xero-tenant-mapping.model.ts | 15 ++++ .../xero-workspace-general-setting.model.ts | 22 +++++ .../models/xero/db/xero-workspace.model.ts | 14 +++ .../xero-configuration/clone-setting.model.ts | 35 ++++++++ .../xero-advanced-settings.model.ts | 83 +++++++++++++++++ .../xero-connector.model.ts | 18 ++++ .../xero-export-settings.model.ts | 61 +++++++++++++ .../xero-import-settings.model.ts | 85 ++++++++++++++++++ .../xero-onboarding.model.ts | 80 +++++++++++++++++ .../core/services/common/helper.service.ts | 3 +- .../core/services/common/workspace.service.ts | 5 +- .../xero-advanced-settings.service.spec.ts | 16 ++++ .../xero-advanced-settings.service.ts | 38 ++++++++ .../xero-connector.service.spec.ts | 16 ++++ .../xero-connector.service.ts | 73 +++++++++++++++ .../xero-export-settings.service.spec.ts | 16 ++++ .../xero-export-settings.service.ts | 33 +++++++ .../xero-import-settings.service.spec.ts | 16 ++++ .../xero-import-settings.service.ts | 33 +++++++ .../xero/xero-core/xero-auth.service.spec.ts | 16 ++++ .../xero/xero-core/xero-auth.service.ts | 22 +++++ .../xero-core/xero-helper.service.spec.ts | 16 ++++ .../xero/xero-core/xero-helper.service.ts | 33 +++++++ .../integrations-routing.module.ts | 4 + src/app/integrations/integrations.module.ts | 3 +- .../xero-configuration-routing.module.ts | 33 +++++++ .../xero-configuration.component.html | 1 + .../xero-configuration.component.scss | 0 .../xero-configuration.component.spec.ts | 23 +++++ .../xero-configuration.component.ts | 15 ++++ .../xero-configuration.module.ts | 19 ++++ .../xero-dashboard.component.html | 1 + .../xero-dashboard.component.scss | 0 .../xero-dashboard.component.spec.ts | 23 +++++ .../xero-dashboard.component.ts | 15 ++++ .../xero-export-log.component.html | 1 + .../xero-export-log.component.scss | 0 .../xero-export-log.component.spec.ts | 23 +++++ .../xero-export-log.component.ts | 15 ++++ .../xero-main/xero-main-routing.module.ts | 34 +++++++ .../xero/xero-main/xero-main.component.html | 1 + .../xero/xero-main/xero-main.component.scss | 0 .../xero-main/xero-main.component.spec.ts | 23 +++++ .../xero/xero-main/xero-main.component.ts | 15 ++++ .../xero/xero-main/xero-main.module.ts | 27 ++++++ .../xero-mapping/xero-mapping.component.html | 1 + .../xero-mapping/xero-mapping.component.scss | 0 .../xero-mapping.component.spec.ts | 23 +++++ .../xero-mapping/xero-mapping.component.ts | 15 ++++ ...nboarding-advanced-settings.component.html | 1 + ...nboarding-advanced-settings.component.scss | 0 ...arding-advanced-settings.component.spec.ts | 23 +++++ ...-onboarding-advanced-settings.component.ts | 15 ++++ .../xero-onboarding-connector.component.html | 1 + .../xero-onboarding-connector.component.scss | 0 ...ero-onboarding-connector.component.spec.ts | 23 +++++ .../xero-onboarding-connector.component.ts | 15 ++++ .../xero-onboarding-done.component.html | 1 + .../xero-onboarding-done.component.scss | 0 .../xero-onboarding-done.component.spec.ts | 23 +++++ .../xero-onboarding-done.component.ts | 15 ++++ ...-onboarding-export-settings.component.html | 1 + ...-onboarding-export-settings.component.scss | 0 ...boarding-export-settings.component.spec.ts | 23 +++++ ...ro-onboarding-export-settings.component.ts | 15 ++++ ...-onboarding-import-settings.component.html | 1 + ...-onboarding-import-settings.component.scss | 0 ...boarding-import-settings.component.spec.ts | 23 +++++ ...ro-onboarding-import-settings.component.ts | 15 ++++ .../xero-onboarding-landing.component.html | 1 + .../xero-onboarding-landing.component.scss | 0 .../xero-onboarding-landing.component.spec.ts | 23 +++++ .../xero-onboarding-landing.component.ts | 15 ++++ .../xero-onboarding-routing.module.ts | 53 +++++++++++ .../xero-onboarding.component.html | 1 + .../xero-onboarding.component.scss | 0 .../xero-onboarding.component.spec.ts | 23 +++++ .../xero-onboarding.component.ts | 15 ++++ .../xero-onboarding/xero-onboarding.module.ts | 31 +++++++ .../integrations/xero/xero-routing.module.ts | 28 ++++++ .../xero-advanced-settings.component.html | 1 + .../xero-advanced-settings.component.scss | 0 .../xero-advanced-settings.component.spec.ts | 23 +++++ .../xero-advanced-settings.component.ts | 15 ++++ .../xero-export-settings.component.html | 1 + .../xero-export-settings.component.scss | 0 .../xero-export-settings.component.spec.ts | 23 +++++ .../xero-export-settings.component.ts | 15 ++++ .../xero-import-settings.component.html | 1 + .../xero-import-settings.component.scss | 0 .../xero-import-settings.component.spec.ts | 23 +++++ .../xero-import-settings.component.ts | 15 ++++ .../xero/xero-shared/xero-shared.module.ts | 24 +++++ src/app/integrations/xero/xero.component.html | 1 + src/app/integrations/xero/xero.component.scss | 0 .../integrations/xero/xero.component.spec.ts | 23 +++++ src/app/integrations/xero/xero.component.ts | 89 +++++++++++++++++++ src/app/integrations/xero/xero.module.ts | 13 +++ .../configuration-import-field.component.html | 4 +- 111 files changed, 1929 insertions(+), 14 deletions(-) create mode 100644 src/app/core/guard/tenant.guard.spec.ts create mode 100644 src/app/core/guard/tenant.guard.ts create mode 100644 src/app/core/guard/xero-token.guard.spec.ts create mode 100644 src/app/core/guard/xero-token.guard.ts create mode 100644 src/app/core/models/xero/db/xero-credential.model.ts create mode 100644 src/app/core/models/xero/db/xero-task-log.model.ts create mode 100644 src/app/core/models/xero/db/xero-tenant-mapping.model.ts create mode 100644 src/app/core/models/xero/db/xero-workspace-general-setting.model.ts create mode 100644 src/app/core/models/xero/db/xero-workspace.model.ts create mode 100644 src/app/core/models/xero/xero-configuration/clone-setting.model.ts create mode 100644 src/app/core/models/xero/xero-configuration/xero-advanced-settings.model.ts create mode 100644 src/app/core/models/xero/xero-configuration/xero-connector.model.ts create mode 100644 src/app/core/models/xero/xero-configuration/xero-export-settings.model.ts create mode 100644 src/app/core/models/xero/xero-configuration/xero-import-settings.model.ts create mode 100644 src/app/core/models/xero/xero-configuration/xero-onboarding.model.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.spec.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-connector.service.spec.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-connector.service.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-export-settings.service.spec.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-export-settings.service.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-import-settings.service.spec.ts create mode 100644 src/app/core/services/xero/xero-configuration/xero-import-settings.service.ts create mode 100644 src/app/core/services/xero/xero-core/xero-auth.service.spec.ts create mode 100644 src/app/core/services/xero/xero-core/xero-auth.service.ts create mode 100644 src/app/core/services/xero/xero-core/xero-helper.service.spec.ts create mode 100644 src/app/core/services/xero/xero-core/xero-helper.service.ts create mode 100644 src/app/integrations/xero/xero-main/xero-configuration/xero-configuration-routing.module.ts create mode 100644 src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.html create mode 100644 src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.scss create mode 100644 src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.spec.ts create mode 100644 src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.ts create mode 100644 src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.module.ts create mode 100644 src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.html create mode 100644 src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.scss create mode 100644 src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.spec.ts create mode 100644 src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.ts create mode 100644 src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.html create mode 100644 src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.scss create mode 100644 src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.spec.ts create mode 100644 src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.ts create mode 100644 src/app/integrations/xero/xero-main/xero-main-routing.module.ts create mode 100644 src/app/integrations/xero/xero-main/xero-main.component.html create mode 100644 src/app/integrations/xero/xero-main/xero-main.component.scss create mode 100644 src/app/integrations/xero/xero-main/xero-main.component.spec.ts create mode 100644 src/app/integrations/xero/xero-main/xero-main.component.ts create mode 100644 src/app/integrations/xero/xero-main/xero-main.module.ts create mode 100644 src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.html create mode 100644 src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.scss create mode 100644 src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.spec.ts create mode 100644 src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding-routing.module.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding.component.html create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding.component.scss create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding.component.spec.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding.component.ts create mode 100644 src/app/integrations/xero/xero-onboarding/xero-onboarding.module.ts create mode 100644 src/app/integrations/xero/xero-routing.module.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.html create mode 100644 src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.scss create mode 100644 src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.spec.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.html create mode 100644 src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.scss create mode 100644 src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.spec.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.html create mode 100644 src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.scss create mode 100644 src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.spec.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.ts create mode 100644 src/app/integrations/xero/xero-shared/xero-shared.module.ts create mode 100644 src/app/integrations/xero/xero.component.html create mode 100644 src/app/integrations/xero/xero.component.scss create mode 100644 src/app/integrations/xero/xero.component.spec.ts create mode 100644 src/app/integrations/xero/xero.component.ts create mode 100644 src/app/integrations/xero/xero.module.ts diff --git a/run.sh b/run.sh index dedf06701..e82ba923e 100644 --- a/run.sh +++ b/run.sh @@ -12,6 +12,7 @@ do sed -i $SED_EXTRA_ARGS "s?{{SAGE300_API_URL}}?${SAGE300_API_URL}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{BUSINESS_CENTRAL_API_URL}}?${BUSINESS_CENTRAL_API_URL}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{QBO_API_URL}}?${QBO_API_URL}?g" $f; + sed -i $SED_EXTRA_ARGS "s?{{XERO_API_URL}}?${XERO_API_URL}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{NETSUITE_API_URL}}?${NETSUITE_API_URL}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{FYLE_APP_URL}}?${FYLE_APP_URL}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{CALLBACK_URI}}?${CALLBACK_URI}?g" $f; @@ -40,6 +41,10 @@ do sed -i $SED_EXTRA_ARGS "s?{{REFINER_INTACCT_EXPORT_DONE_SURVEY_ID}}?${REFINER_INTACCT_EXPORT_DONE_SURVEY_ID}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{BUSINESS_CENTRAL_OAUTH_REDIRECT_URI}}?${BUSINESS_CENTRAL_OAUTH_REDIRECT_URI}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{BUSINESS_CENTRAL_OAUTH_CLIENT_ID}}?${BUSINESS_CENTRAL_OAUTH_CLIENT_ID}?g" $f; + sed -i $SED_EXTRA_ARGS "s?{{XERO_OAUTH_CLIENT_ID}}?${XERO_OAUTH_CLIENT_ID}?g" $f; + sed -i $SED_EXTRA_ARGS "s?{{XERO_SCOPE}}?${XERO_SCOPE}?g" $f; + sed -i $SED_EXTRA_ARGS "s?{{XERO_AUTHORIZE_URI}}?${XERO_AUTHORIZE_URI}?g" $f; + sed -i $SED_EXTRA_ARGS "s?{{XERO_OAUTH_REDIRECT_URI}}?${XERO_OAUTH_REDIRECT_URI}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{BRAND_NAME}}?${BRAND_NAME}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{WEBPAGE_TITLE}}?${WEBPAGE_TITLE}?g" $f; sed -i $SED_EXTRA_ARGS "s?{{BRAND_ID}}?${BRAND_ID}?g" $f; diff --git a/scripts/setup_env.js b/scripts/setup_env.js index fc9939e9d..13b6f45d0 100644 --- a/scripts/setup_env.js +++ b/scripts/setup_env.js @@ -10,6 +10,7 @@ const environment = { netsuite_api_url: `${process.env.NETSUITE_API_URL ? process.env.NETSUITE_API_URL : '{{NETSUITE_API_URL}}'}`, business_central_api_url: `${process.env.BUSINESS_CENTRAL_API_URL ? process.env.BUSINESS_CENTRAL_API_URL : '{{BUSINESS_CENTRAL_API_URL}}'}`, qbo_api_url: `${process.env.QBO_API_URL ? process.env.QBO_API_URL : '{{QBO_API_URL}}'}`, + xero_api_url: `${process.env.XERO_API_URL ? process.env.XERO_API_URL : '{{XERO_API_URL}}'}`, netsuite_api_url: `${process.env.NETSUITE_API_URL ? process.env.NETSUITE_API_URL : '{{NETSUITE_API_URL}}'}`, cluster_domain_api_url: `${process.env.CLUSTER_DOMAIN_API_URL ? process.env.CLUSTER_DOMAIN_API_URL : '{{CLUSTER_DOMAIN_API_URL}}'}`, fyle_app_url: `${process.env.FYLE_APP_URL ? process.env.FYLE_APP_URL : '{{FYLE_APP_URL}}'}`, @@ -31,6 +32,10 @@ const environment = { qbo_oauth_redirect_uri: `${process.env.QBO_OAUTH_REDIRECT_URI ? process.env.QBO_OAUTH_REDIRECT_URI : '{{QBO_OAUTH_REDIRECT_URI}}'}`, qbo_authorize_uri: `${process.env.QBO_AUTHORIZE_URI ? process.env.QBO_AUTHORIZE_URI : '{{QBO_AUTHORIZE_URI}}'}`, qbo_oauth_client_id: `${process.env.QBO_OAUTH_CLIENT_ID ? process.env.QBO_OAUTH_CLIENT_ID : '{{QBO_OAUTH_CLIENT_ID}}'}`, + xero_oauth_client_id: `${process.env.XERO_OAUTH_CLIENT_ID ? process.env.XERO_OAUTH_CLIENT_ID : '{{XERO_OAUTH_CLIENT_ID}}'}`, + xero_scope: `${process.env.XERO_SCOPE ? process.env.XERO_SCOPE : '{{XERO_SCOPE}}'}`, + xero_authorize_uri: `${process.env.XERO_AUTHORIZE_URI ? process.env.XERO_AUTHORIZE_URI : '{{XERO_AUTHORIZE_URI}}'}`, + xero_oauth_redirect_uri: `${process.env.XERO_OAUTH_REDIRECT_URI ? process.env.XERO_OAUTH_REDIRECT_URI : '{{XERO_OAUTH_REDIRECT_URI}}'}`, refiner_survey: { intacct: { onboarding_done_survery_id: `${process.env.REFINER_INTACCT_ONBOARDING_DONE_SURVEY_ID ? process.env.REFINER_INTACCT_ONBOARDING_DONE_SURVEY_ID : '{{REFINER_INTACCT_ONBOARDING_DONE_SURVEY_ID}}'}`, diff --git a/src/app/auth/login/login.component.ts b/src/app/auth/login/login.component.ts index ecc52fe4d..b723334e3 100644 --- a/src/app/auth/login/login.component.ts +++ b/src/app/auth/login/login.component.ts @@ -14,6 +14,7 @@ import { AppUrl } from 'src/app/core/models/enum/enum.model'; import { ClusterDomainWithToken } from 'src/app/core/models/misc/token.model'; import { StorageService } from 'src/app/core/services/common/storage.service'; import { NetsuiteAuthService } from 'src/app/core/services/netsuite/netsuite-core/netsuite-auth.service'; +import { XeroAuthService } from 'src/app/core/services/xero/xero-core/xero-auth.service'; @Component({ selector: 'app-login', @@ -33,6 +34,7 @@ export class LoginComponent implements OnInit { private sage300AuthService: Sage300AuthService, private siAuthService : SiAuthService, private netsuiteAuthService: NetsuiteAuthService, + private xeroAuthService: XeroAuthService, private storageService: StorageService, private userService: UserService ) { } @@ -70,10 +72,6 @@ export class LoginComponent implements OnInit { this.helperService.setBaseApiURL(AppUrl.BUSINESS_CENTRAL); this.businessCentralAuthService.loginWithRefreshToken(clusterDomainWithToken.tokens.refresh_token).subscribe(); - this.helperService.setBaseApiURL(AppUrl.NETSUITE); - this.netsuiteAuthService.loginWithRefreshToken(clusterDomainWithToken.tokens.refresh_token).subscribe(); - - // Only local dev needs this, login happens via postMessage for prod/staging through webapp if (!environment.production) { this.userService.storeUserProfile(user); @@ -83,6 +81,8 @@ export class LoginComponent implements OnInit { this.siAuthService.loginWithRefreshToken(clusterDomainWithToken.tokens.refresh_token).subscribe(); this.helperService.setBaseApiURL(AppUrl.NETSUITE); this.netsuiteAuthService.loginWithRefreshToken(clusterDomainWithToken.tokens.refresh_token).subscribe(); + this.helperService.setBaseApiURL(AppUrl.XERO); + this.xeroAuthService.loginWithRefreshToken(clusterDomainWithToken.tokens.refresh_token).subscribe(); this.redirect(redirectUri); } else { this.redirect(redirectUri); diff --git a/src/app/core/guard/tenant.guard.spec.ts b/src/app/core/guard/tenant.guard.spec.ts new file mode 100644 index 000000000..b84411939 --- /dev/null +++ b/src/app/core/guard/tenant.guard.spec.ts @@ -0,0 +1,15 @@ +import { TestBed } from '@angular/core/testing'; +import { TenantGuard } from './tenant.guard'; + +describe('WorkspacesGuard', () => { + let guard: TenantGuard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(TenantGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/src/app/core/guard/tenant.guard.ts b/src/app/core/guard/tenant.guard.ts new file mode 100644 index 000000000..eddbbf2a4 --- /dev/null +++ b/src/app/core/guard/tenant.guard.ts @@ -0,0 +1,49 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; +import { forkJoin, Observable, throwError } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { globalCacheBusterNotifier } from 'ts-cacheable'; +import { ToastSeverity, XeroOnboardingState } from '../models/enum/enum.model'; +import { XeroConnectorService } from '../services/xero/xero-configuration/xero-connector.service'; +import { WorkspaceService } from '../services/common/workspace.service'; +import { IntegrationsToastService } from '../services/common/integrations-toast.service'; + +@Injectable({ + providedIn: 'root' +}) +export class TenantGuard implements CanActivate { + + constructor( + private xeroConnectorService: XeroConnectorService, + private router: Router, + private workspaceService: WorkspaceService, + private toastService: IntegrationsToastService + ) { } + + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { + const workspaceId = this.workspaceService.getWorkspaceId(); + + if (!workspaceId) { + return this.router.navigateByUrl(`workspaces`); + } + + return forkJoin( + [ + this.xeroConnectorService.getTenantMappings() + ] + ).pipe( + map(response => !!response), + catchError(error => { + if (error.status === 400) { + globalCacheBusterNotifier.next(); + this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Oops! You will need to select a tenant to proceed with the onboarding.'); + return this.router.navigateByUrl('integrations/xero/onboarding/xero_connector'); + } + return throwError(error); + }) + ); + } + +} diff --git a/src/app/core/guard/xero-token.guard.spec.ts b/src/app/core/guard/xero-token.guard.spec.ts new file mode 100644 index 000000000..75f0f57c7 --- /dev/null +++ b/src/app/core/guard/xero-token.guard.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroTokenGuard } from './xero-token.guard'; + +describe('XeroTokenGuard', () => { + let guard: XeroTokenGuard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(XeroTokenGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/src/app/core/guard/xero-token.guard.ts b/src/app/core/guard/xero-token.guard.ts new file mode 100644 index 000000000..0cca4c332 --- /dev/null +++ b/src/app/core/guard/xero-token.guard.ts @@ -0,0 +1,55 @@ +import { Injectable } from "@angular/core"; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from "@angular/router"; +import { XeroConnectorService } from "../services/xero/xero-configuration/xero-connector.service"; +import { Observable, forkJoin, map, catchError, throwError } from "rxjs"; +import { globalCacheBusterNotifier } from "ts-cacheable"; +import { WorkspaceService } from "../services/common/workspace.service"; +import { ToastSeverity, XeroOnboardingState } from "../models/enum/enum.model"; +import { IntegrationsToastService } from "../services/common/integrations-toast.service"; + + +@Injectable({ + providedIn: 'root' +}) +export class XeroTokenGuard implements CanActivate { + + constructor( + private xeroConnectorService: XeroConnectorService, + private router: Router, + private toastService: IntegrationsToastService, + private workspaceService: WorkspaceService + ) { } + + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { + + const workspaceId = this.workspaceService.getWorkspaceId(); + + if (!workspaceId) { + return this.router.navigateByUrl(`workspaces`); + } + + return forkJoin( + [ + this.xeroConnectorService.getXeroCredentials(workspaceId), + this.xeroConnectorService.getXeroTokenHealth(workspaceId) + ] + ).pipe( + map(response => !!response), + catchError(error => { + if (error.status === 400) { + globalCacheBusterNotifier.next(); + this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Oops! Your Xero connection expired, please connect again'); + + const onboardingState: XeroOnboardingState = this.workspaceService.getOnboardingState(); + + return this.router.navigateByUrl('integrations/xero/onboarding/landing'); + } + + return throwError(error); + }) + ); + } + +} diff --git a/src/app/core/models/db/expense-group-setting.model.ts b/src/app/core/models/db/expense-group-setting.model.ts index 1074294c1..61d1f993e 100644 --- a/src/app/core/models/db/expense-group-setting.model.ts +++ b/src/app/core/models/db/expense-group-setting.model.ts @@ -3,9 +3,9 @@ import { CCCExpenseState, ExpenseState, ExportDateType } from "../enum/enum.mode export type ExpenseGroupSettingPost = { expense_state: ExpenseState; ccc_expense_state: CCCExpenseState; - reimbursable_expense_group_fields: string[] | null; + reimbursable_expense_group_fields?: string[] | null; reimbursable_export_date_type: ExportDateType | null; - corporate_credit_card_expense_group_fields: string[] | null; + corporate_credit_card_expense_group_fields?: string[] | null; ccc_export_date_type: ExportDateType | null; }; diff --git a/src/app/core/models/enum/enum.model.ts b/src/app/core/models/enum/enum.model.ts index 903ea06d9..53d3ebd33 100644 --- a/src/app/core/models/enum/enum.model.ts +++ b/src/app/core/models/enum/enum.model.ts @@ -167,6 +167,15 @@ export enum QBOOnboardingState { CLONE_SETTINGS = 'CLONE_SETTINGS' } +export enum XeroOnboardingState { + CONNECTION = 'CONNECTION', + EXPORT_SETTINGS = 'EXPORT_SETTINGS', + IMPORT_SETTINGS = 'IMPORT_SETTINGS', + ADVANCED_CONFIGURATION = 'ADVANCED_CONFIGURATION', + COMPLETE = 'COMPLETE', + CLONE_SETTINGS = 'CLONE_SETTINGS' +} + export enum NetsuiteOnboardingState { CONNECTION = 'CONNECTION', EXPORT_SETTINGS = 'EXPORT_SETTINGS', @@ -211,6 +220,14 @@ export enum QBOCorporateCreditCardExpensesObject { DEBIT_CARD_EXPENSE = 'DEBIT CARD EXPENSE' } +export enum XeroReimbursableExpensesObject { + PURCHASE_BILL = 'PURCHASE BILL' +} + +export enum XeroCorporateCreditCardExpensesObject { + BANK_TRANSACTION = 'BANK TRANSACTION' +} + export enum NameInJournalEntry { EMPLOYEE = 'EMPLOYEE', MERCHANT = 'MERCHANT' @@ -334,7 +351,9 @@ export enum QBDAccountingExportsType { export enum PaymentSyncDirection { FYLE_TO_INTACCT = 'fyle_to_intacct', - INTACCT_TO_FYLE = 'intacct_to_fyle' + INTACCT_TO_FYLE = 'intacct_to_fyle', + FYLE_TO_XERO = 'fyle_to_xero', + XERO_TO_FYLE = 'xero_to_fyle' } export enum QBOPaymentSyncDirection { @@ -463,7 +482,8 @@ export enum AppUrl { BUSINESS_CENTRAL = 'business_central', INTEGRATION = 'integration', QBO = 'qbo', - NETSUITE = 'netsuite' + NETSUITE = 'netsuite', + XERO = 'xero' } export enum Sage300ExportType { @@ -595,6 +615,13 @@ export enum QBOTaskLogType { FETCHING_EXPENSE = 'FETCHING_EXPENSE' } +export enum XeroTaskLogType { + CREATING_BILL = 'CREATING_BILL', + CREATING_BANK_TRANSACTION = 'CREATING_BANK_TRANSACTION', + CREATING_PAYMENT = 'CREATING_PAYMENT', + FETCHING_EXPENSE = 'FETCHING_EXPENSE' +} + export enum LoaderType { DETERMINATE = 'determinate', INDETERMINATE = 'indeterminate' diff --git a/src/app/core/models/integrations/integrations.model.ts b/src/app/core/models/integrations/integrations.model.ts index fc33593a4..478740045 100644 --- a/src/app/core/models/integrations/integrations.model.ts +++ b/src/app/core/models/integrations/integrations.model.ts @@ -42,4 +42,5 @@ export type AppUrlMap = { [AppUrl.BUSINESS_CENTRAL]: string [AppUrl.QBO]: string [AppUrl.NETSUITE]: string + [AppUrl.XERO]: string } diff --git a/src/app/core/models/xero/db/xero-credential.model.ts b/src/app/core/models/xero/db/xero-credential.model.ts new file mode 100644 index 000000000..910f8c393 --- /dev/null +++ b/src/app/core/models/xero/db/xero-credential.model.ts @@ -0,0 +1,9 @@ +export type XeroCredentials = { + id: number; + refresh_token: string; + company_name: string; + country: string; + created_at: Date; + updated_at: Date; + workspace: number; + }; diff --git a/src/app/core/models/xero/db/xero-task-log.model.ts b/src/app/core/models/xero/db/xero-task-log.model.ts new file mode 100644 index 000000000..cc668c445 --- /dev/null +++ b/src/app/core/models/xero/db/xero-task-log.model.ts @@ -0,0 +1,25 @@ +import { PaginatedResponse } from "../../db/paginated-response.model"; +import { TaskLog } from "../../db/task-log.model"; +import { XeroTaskLogType } from "../../enum/enum.model"; + +export type XeroError = { + expense_group_id: number; + short_description: string; + long_description: string; + type: string; +}; + +export interface XeroTaskLogs extends TaskLog { + bill: number; + cheque: number; + credit_card_purchase: number; + xero_errors: XeroError[]; + journal_entry: number; + bill_payment: number; + task_id: string; + type: XeroTaskLogType; +} + +export interface XeroTaskResponse extends PaginatedResponse { + results: Task[]; +} \ No newline at end of file diff --git a/src/app/core/models/xero/db/xero-tenant-mapping.model.ts b/src/app/core/models/xero/db/xero-tenant-mapping.model.ts new file mode 100644 index 000000000..891236ab3 --- /dev/null +++ b/src/app/core/models/xero/db/xero-tenant-mapping.model.ts @@ -0,0 +1,15 @@ +/* Tslint:disable */ +export type TenantMapping = { + id: number; + tenant_name: string; + tenant_id: string; + connection_id: string; + created_at: Date; + updated_at: Date; + workspace: number; +}; + +export type TenantMappingPost = { + tenant_id: string; + tenant_name: string; +} diff --git a/src/app/core/models/xero/db/xero-workspace-general-setting.model.ts b/src/app/core/models/xero/db/xero-workspace-general-setting.model.ts new file mode 100644 index 000000000..78f3f9683 --- /dev/null +++ b/src/app/core/models/xero/db/xero-workspace-general-setting.model.ts @@ -0,0 +1,22 @@ +export type XeroWorkspaceGeneralSetting = { + id?: number; + reimbursable_expenses_object: string; + corporate_credit_card_expenses_object: string; + import_projects?: boolean; + import_categories: boolean; + charts_of_accounts: string[]; + change_accounting_period: boolean; + sync_fyle_to_xero_payments: boolean; + sync_xero_to_fyle_payments: boolean; + map_merchant_to_contact: boolean; + auto_map_employees: string; + auto_create_destination_entity: boolean; + is_simplify_report_closure_enabled: boolean; + skip_cards_mapping?: boolean; + import_tax_codes: boolean; + import_customers: boolean; + import_suppliers_as_merchants: boolean; + created_at?: Date; + updated_at?: Date; + workspace?: number; + }; diff --git a/src/app/core/models/xero/db/xero-workspace.model.ts b/src/app/core/models/xero/db/xero-workspace.model.ts new file mode 100644 index 000000000..6bc64f65c --- /dev/null +++ b/src/app/core/models/xero/db/xero-workspace.model.ts @@ -0,0 +1,14 @@ +import { Workspace } from "../../db/workspaces.model"; +import { XeroOnboardingState } from "../../enum/enum.model"; + +export interface XeroWorkspace extends Workspace { + onboarding_state: XeroOnboardingState; + fyle_currency: string; + xero_currency: string; + fyle_org_id: string; + xero_short_code: string; + last_synced_at?: Date; + ccc_last_synced_at: Date; + source_synced_at: Date; + destination_synced_at: Date; +} diff --git a/src/app/core/models/xero/xero-configuration/clone-setting.model.ts b/src/app/core/models/xero/xero-configuration/clone-setting.model.ts new file mode 100644 index 000000000..0a5649c26 --- /dev/null +++ b/src/app/core/models/xero/xero-configuration/clone-setting.model.ts @@ -0,0 +1,35 @@ +import { FormGroup } from "@angular/forms"; +import { MappingSetting } from "../../db/mapping-setting.model"; +import { XeroAdvancedSettingGet, XeroAdvancedSettingModel, XeroAdvancedSettingPost } from "./xero-advanced-settings.model"; +import { XeroExportSettingGet, XeroExportSettingModel, XeroExportSettingPost } from "./xero-export-settings.model"; +import { XeroImportSettingGet, XeroImportSettingModel, XeroImportSettingPost } from "./xero-import-settings.model"; + + +export type XeroCloneSetting = { + workspace_id: number, + export_settings: XeroExportSettingGet, + import_settings: XeroImportSettingGet, + advanced_settings: XeroAdvancedSettingGet +} + +export type XeroCloneSettingPost = { + export_settings: XeroExportSettingPost, + import_settings: XeroImportSettingPost, + advanced_settings: XeroAdvancedSettingPost +} + +export class XeroCloneSettingModel { + static constructPayload(XeroCloneSettingsForm: FormGroup, customMappingSettings: MappingSetting[]): XeroCloneSettingPost { + const exportSettingPayload = XeroExportSettingModel.constructPayload(XeroCloneSettingsForm); + const importSettingPayload = XeroImportSettingModel.constructPayload(XeroCloneSettingsForm, customMappingSettings); + const advancedSettingPayload = XeroAdvancedSettingModel.constructPayload(XeroCloneSettingsForm); + + const XeroCloneSettingPayload: XeroCloneSettingPost = { + export_settings: exportSettingPayload, + import_settings: importSettingPayload, + advanced_settings: advancedSettingPayload + }; + + return XeroCloneSettingPayload; + } +} diff --git a/src/app/core/models/xero/xero-configuration/xero-advanced-settings.model.ts b/src/app/core/models/xero/xero-configuration/xero-advanced-settings.model.ts new file mode 100644 index 000000000..cd6b38a46 --- /dev/null +++ b/src/app/core/models/xero/xero-configuration/xero-advanced-settings.model.ts @@ -0,0 +1,83 @@ +import { FormGroup } from "@angular/forms"; +import { EmailOption } from "../../common/advanced-settings.model"; +import { SelectFormOption } from "../../common/select-form-option.model"; +import { DefaultDestinationAttribute } from "../../db/destination-attribute.model"; +import { PaymentSyncDirection } from "../../enum/enum.model"; + + +export type XeroAdvancedSettingWorkspaceGeneralSetting = { + sync_fyle_to_xero_payments: boolean, + sync_xero_to_fyle_payments: boolean, + auto_create_destination_entity: boolean, + change_accounting_period: boolean, + auto_create_merchant_destination_entity: boolean +} + +export type XeroAdvancedSettingGeneralMapping = { + payment_account: DefaultDestinationAttribute +} + +export type XeroAdvancedSettingWorkspaceSchedule = { + enabled: boolean, + interval_hours: number, + start_datetime: Date, + emails_selected: string[] | null, + additional_email_options: EmailOption[] +} + +export type XeroAdvancedSettingWorkspaceSchedulePost = { + hours: number; + schedule_enabled: boolean; + emails_selected: string[]; + email_added: EmailOption[] +} + +export type XeroAdvancedSettingPost = { + workspace_general_settings: XeroAdvancedSettingWorkspaceGeneralSetting, + general_mappings: XeroAdvancedSettingGeneralMapping, + workspace_schedules: XeroAdvancedSettingWorkspaceSchedule, +} + +export type XeroAdvancedSettingGet = { + workspace_general_settings: XeroAdvancedSettingWorkspaceGeneralSetting, + general_mappings: XeroAdvancedSettingGeneralMapping, + workspace_schedules: XeroAdvancedSettingWorkspaceSchedule, + workspace_id:number +} + +export type XeroAdvancedSettingAddEmailModel = { + workspaceId: number; + hours: number; + schedulEnabled: boolean; + selectedEmails: string[]; +} + +export interface XeroAdvancedSettingFormOption extends SelectFormOption { + value: PaymentSyncDirection | number | 'None'; +} + +export class XeroAdvancedSettingModel { + static constructPayload(advancedSettingsForm: FormGroup): XeroAdvancedSettingPost { + const emptyDestinationAttribute = {id: null, name: null}; + const advancedSettingPayload: XeroAdvancedSettingPost = { + workspace_general_settings: { + sync_fyle_to_xero_payments: advancedSettingsForm.get('paymentSync')?.value && advancedSettingsForm.get('paymentSync')?.value === PaymentSyncDirection.FYLE_TO_XERO ? true : false, + sync_xero_to_fyle_payments: advancedSettingsForm.get('paymentSync')?.value && advancedSettingsForm.get('paymentSync')?.value === PaymentSyncDirection.XERO_TO_FYLE ? true : false, + auto_create_destination_entity: advancedSettingsForm.get('autoCreateVendors')?.value, + change_accounting_period: advancedSettingsForm.get('changeAccountingPeriod')?.value, + auto_create_merchant_destination_entity: advancedSettingsForm.get('autoCreateMerchantDestinationEntity')?.value + }, + general_mappings: { + payment_account: advancedSettingsForm.get('billPaymentAccount')?.value ? advancedSettingsForm.get('billPaymentAccount')?.value : emptyDestinationAttribute + }, + workspace_schedules: { + enabled: advancedSettingsForm.get('exportSchedule')?.value ? true : false, + interval_hours: advancedSettingsForm.get('exportScheduleFrequency')?.value ? advancedSettingsForm.get('exportScheduleFrequency')?.value : null, + start_datetime: new Date(), + emails_selected: advancedSettingsForm.get('emails')?.value ? advancedSettingsForm.get('emails')?.value : [], + additional_email_options: advancedSettingsForm.get('addedEmail')?.value ? advancedSettingsForm.get('addedEmail')?.value : [] + } + }; + return advancedSettingPayload; + } +} diff --git a/src/app/core/models/xero/xero-configuration/xero-connector.model.ts b/src/app/core/models/xero/xero-configuration/xero-connector.model.ts new file mode 100644 index 000000000..b10590d16 --- /dev/null +++ b/src/app/core/models/xero/xero-configuration/xero-connector.model.ts @@ -0,0 +1,18 @@ +import { environment } from "src/environments/environment"; + +export type XeroConnector = { + code: string; +} + +export interface XeroConnectorPost extends XeroConnector { + redirect_uri: string; +} + +export class XeroConnectorModel { + static constructPayload(code: string): XeroConnectorPost { + return { + code, + redirect_uri: `${environment.xero_oauth_redirect_uri}` + }; + } +} diff --git a/src/app/core/models/xero/xero-configuration/xero-export-settings.model.ts b/src/app/core/models/xero/xero-configuration/xero-export-settings.model.ts new file mode 100644 index 000000000..06d5de6e7 --- /dev/null +++ b/src/app/core/models/xero/xero-configuration/xero-export-settings.model.ts @@ -0,0 +1,61 @@ +import { FormGroup } from "@angular/forms"; +import { SelectFormOption } from "../../common/select-form-option.model"; +import { DefaultDestinationAttribute } from "../../db/destination-attribute.model"; +import { ExpenseGroupSettingGet, ExpenseGroupSettingPost } from "../../db/expense-group-setting.model"; +import { AutoMapEmployeeOptions, CCCExpenseState, ExpenseGroupingFieldOption, ExpenseState, ExportDateType, XeroCorporateCreditCardExpensesObject, XeroReimbursableExpensesObject } from "../../enum/enum.model"; +import { ExportSettingGeneralMapping } from "../../intacct/intacct-configuration/export-settings.model"; + + +export type XeroExportSettingWorkspaceGeneralSettingPost = { + reimbursable_expenses_object: XeroReimbursableExpensesObject | null, + corporate_credit_card_expenses_object: XeroCorporateCreditCardExpensesObject | null, + auto_map_employees: AutoMapEmployeeOptions | null, +} + +export interface XeroExportSettingWorkspaceGeneralSetting extends XeroExportSettingWorkspaceGeneralSettingPost { + is_simplify_report_closure_enabled: boolean +} + +export type XeroExportSettingGeneralMapping = { + bank_account: DefaultDestinationAttribute +} + +export type XeroExportSettingPost = { + expense_group_settings: ExpenseGroupSettingPost, + workspace_general_settings: XeroExportSettingWorkspaceGeneralSettingPost, + general_mappings: XeroExportSettingGeneralMapping +} + +export type XeroExportSettingGet = { + expense_group_settings: ExpenseGroupSettingGet, + workspace_general_settings: XeroExportSettingWorkspaceGeneralSetting, + general_mappings: ExportSettingGeneralMapping, + workspace_id: number +} + +export interface XeroExportSettingFormOption extends SelectFormOption { + value: ExpenseState | CCCExpenseState | XeroReimbursableExpensesObject | XeroCorporateCreditCardExpensesObject | ExpenseGroupingFieldOption | ExportDateType | AutoMapEmployeeOptions | null; +} + +export class XeroExportSettingModel { + static constructPayload(exportSettingsForm: FormGroup): XeroExportSettingPost { + const emptyDestinationAttribute = {id: null, name: null}; + const exportSettingPayload: XeroExportSettingPost = { + expense_group_settings: { + expense_state: exportSettingsForm.get('reimbursableExpenseState')?.value, + reimbursable_export_date_type: exportSettingsForm.get('reimbursableExportDate')?.value ? exportSettingsForm.get('reimbursableExportDate')?.value : ExportDateType.CURRENT_DATE, + ccc_expense_state: exportSettingsForm.get('cccExpenseState')?.value, + ccc_export_date_type: exportSettingsForm.get('cccExportDate')?.value ? exportSettingsForm.get('cccExportDate')?.value : ExportDateType.SPENT_AT + }, + workspace_general_settings: { + reimbursable_expenses_object: exportSettingsForm.get('reimbursableExpense')?.value ? XeroReimbursableExpensesObject.PURCHASE_BILL : null, + corporate_credit_card_expenses_object: exportSettingsForm.get('creditCardExpense')?.value ? XeroCorporateCreditCardExpensesObject.BANK_TRANSACTION : null, + auto_map_employees: exportSettingsForm.get('AutoMapEmployeeOptionss')?.value + }, + general_mappings: { + bank_account: exportSettingsForm.get('bankAccount')?.value ? exportSettingsForm.get('bankAccount')?.value : emptyDestinationAttribute + } + }; + return exportSettingPayload; + } +} diff --git a/src/app/core/models/xero/xero-configuration/xero-import-settings.model.ts b/src/app/core/models/xero/xero-configuration/xero-import-settings.model.ts new file mode 100644 index 000000000..10bbff8b3 --- /dev/null +++ b/src/app/core/models/xero/xero-configuration/xero-import-settings.model.ts @@ -0,0 +1,85 @@ +import { FormGroup } from "@angular/forms"; +import { SelectFormOption } from "../../common/select-form-option.model"; +import { DefaultDestinationAttribute } from "../../db/destination-attribute.model"; +import { MappingSetting } from "../../db/mapping-setting.model"; +import { MappingDestinationField, MappingSourceField } from "../../enum/enum.model"; +import { GeneralMapping } from "../../intacct/db/mappings.model"; +import { ImportSettingGeneralMapping } from "../../intacct/intacct-configuration/import-settings.model"; +import { XeroWorkspaceGeneralSetting } from "../db/xero-workspace-general-setting.model"; +import { ImportSettingsModel } from "../../common/import-settings.model"; + + +export type XeroImportSettingWorkspaceGeneralSetting = { + import_categories: boolean, + charts_of_accounts: string[], + import_tax_codes: boolean, + import_customers: boolean, + import_suppliers_as_merchants: boolean +} + +export type XeroImportSettingGeneralMapping = { + default_tax_code: DefaultDestinationAttribute +} + +export type XeroImportSettingMappingSetting = { + source_field: MappingSourceField | string, + destination_field: MappingDestinationField | string, + import_to_fyle: boolean, + is_custom: boolean, + source_placeholder: string | null +} + +export type XeroImportSettingPost = { + workspace_general_settings: XeroImportSettingWorkspaceGeneralSetting, + general_mappings: ImportSettingGeneralMapping, + mapping_settings: XeroImportSettingMappingSetting[] +} + +export type ExpenseFieldsFormOption = { + source_field: MappingSourceField | string, + destination_field: MappingDestinationField | string, + import_to_fyle: boolean, + disable_import_to_fyle: boolean, + source_placeholder: string | null +} + +export type XeroImportSettingGet = { + workspace_general_settings: XeroWorkspaceGeneralSetting, + general_mappings: GeneralMapping, + mapping_settings: MappingSetting[], + workspace_id:number +} + +export interface XeroImportSettingFormOption extends SelectFormOption { + value: string; +} + + +export class XeroImportSettingModel extends ImportSettingsModel { + static constructPayload(importSettingsForm: FormGroup): XeroImportSettingPost { + + const emptyDestinationAttribute = {id: null, name: null}; + const chartOfAccounts = XeroImportSettingModel.formatChartOfAccounts(importSettingsForm.get('chartOfAccountTypes')?.value); + const expenseFieldArray = importSettingsForm.getRawValue().expenseFields; + const mappingSettings = this.constructMappingSettingPayload(expenseFieldArray); + + const importSettingPayload: XeroImportSettingPost = { + workspace_general_settings: { + import_categories: importSettingsForm.get('chartOfAccount')?.value, + charts_of_accounts: importSettingsForm.get('chartOfAccount')?.value ? chartOfAccounts : ['Expense'], + import_tax_codes: importSettingsForm.get('taxCode')?.value, + import_suppliers_as_merchants: importSettingsForm.get('importSuppliersAsMerchants')?.value, + import_customers: importSettingsForm.get('importCustomers')?.value ? importSettingsForm.get('importCustomers')?.value : false + }, + general_mappings: { + default_tax_code: importSettingsForm.get('defaultTaxCode')?.value ? importSettingsForm.get('defaultTaxCode')?.value : emptyDestinationAttribute + }, + mapping_settings: mappingSettings + }; + return importSettingPayload; + } + + static formatChartOfAccounts(chartOfAccounts: {enabled: boolean, name: string}[]): string[] { + return chartOfAccounts.filter(chartOfAccount => chartOfAccount.enabled).map(chartOfAccount => chartOfAccount.name.toUpperCase()); + } +} diff --git a/src/app/core/models/xero/xero-configuration/xero-onboarding.model.ts b/src/app/core/models/xero/xero-configuration/xero-onboarding.model.ts new file mode 100644 index 000000000..ea86aeaff --- /dev/null +++ b/src/app/core/models/xero/xero-configuration/xero-onboarding.model.ts @@ -0,0 +1,80 @@ +import { brandingContent, brandingFeatureConfig } from "src/app/branding/branding-config"; +import { XeroOnboardingState } from "../../enum/enum.model"; +import { OnboardingStepper } from "../../misc/onboarding-stepper.model"; + +type XeroOnboardingStepperMap = { + [XeroOnboardingState.CONNECTION]: number, + [XeroOnboardingState.EXPORT_SETTINGS]: number, + [XeroOnboardingState.IMPORT_SETTINGS]: number, + [XeroOnboardingState.ADVANCED_CONFIGURATION]: number, + [XeroOnboardingState.COMPLETE]: number, + [XeroOnboardingState.CLONE_SETTINGS]: number +}; + +export class XeroOnboardingModel { + brandingContent = brandingContent.configuration; + + private onboardingSteps: OnboardingStepper[] = [ + { + active: false, + completed: false, + step: 'Connect to Xero', + icon: 'link-vertical-medium', + route: '/integrations/xero/onboarding/connector', + styleClasses: ['step-name-connector--text'] + }, + { + active: false, + completed: false, + step: brandingContent.configuration.exportSetting.stepName, + icon: 'arrow-tail-up-medium', + route: '/integrations/xero/onboarding/export_settings', + styleClasses: ['step-name-export--text'] + }, + { + active: false, + completed: false, + step: brandingContent.configuration.importSetting.stepName, + icon: 'arrow-tail-down-medium', + route: '/integrations/xero/onboarding/import_settings', + styleClasses: ['step-name-export--text'] + }, + { + active: false, + completed: false, + step: brandingContent.configuration.advancedSettings.stepName, + icon: 'gear-medium', + route: '/integrations/xero/onboarding/advanced_settings', + styleClasses: ['step-name-advanced--text'] + } + ]; + + private readonly onboardingStateStepMap: XeroOnboardingStepperMap = { + [XeroOnboardingState.CONNECTION]: 1, + [XeroOnboardingState.EXPORT_SETTINGS]: 2, + [XeroOnboardingState.IMPORT_SETTINGS]: 3, + [XeroOnboardingState.ADVANCED_CONFIGURATION]: 4, + [XeroOnboardingState.COMPLETE]: 5, + [XeroOnboardingState.CLONE_SETTINGS]: 6 + }; + + getOnboardingSteps(currentStep: string, onboardingState: XeroOnboardingState): OnboardingStepper[] { + this.onboardingSteps.forEach(step => { + if (step.step.toLowerCase() === currentStep.toLowerCase()) { + step.active = true; + } else { + step.active = false; + } + }); + + for (let index = this.onboardingStateStepMap[onboardingState] - 1; index > 0; index--) { + this.onboardingSteps[index - 1].completed = true; + } + + if (!brandingFeatureConfig.featureFlags.mapEmployees) { + this.onboardingSteps.splice(1, 1); + } + + return this.onboardingSteps; + } + } diff --git a/src/app/core/services/common/helper.service.ts b/src/app/core/services/common/helper.service.ts index e8eba31fd..1511bf7f5 100644 --- a/src/app/core/services/common/helper.service.ts +++ b/src/app/core/services/common/helper.service.ts @@ -49,7 +49,8 @@ export class HelperService { [AppUrl.INTEGRATION]: `${this.apiBaseUrl}/${environment.production ? 'integrations-api/': ''}api`, [AppUrl.BUSINESS_CENTRAL]: environment.business_central_api_url, [AppUrl.QBO]: environment.production ? `${this.apiBaseUrl}/quickbooks-api/api` : environment.qbo_api_url, - [AppUrl.NETSUITE]: environment.production ? `${this.apiBaseUrl}/netsuite-api/api` : environment.netsuite_api_url + [AppUrl.NETSUITE]: environment.production ? `${this.apiBaseUrl}/netsuite-api/api` : environment.netsuite_api_url, + [AppUrl.XERO]: environment.production ? `${this.apiBaseUrl}/xero-api/api` : environment.xero_api_url }; const apiUrl = apiUrlMap[module] ?? apiUrlMap.integration; diff --git a/src/app/core/services/common/workspace.service.ts b/src/app/core/services/common/workspace.service.ts index 85268e4bb..7ac8c14ee 100644 --- a/src/app/core/services/common/workspace.service.ts +++ b/src/app/core/services/common/workspace.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { StorageService } from './storage.service'; import { Observable } from 'rxjs'; -import { AppUrl, BusinessCentralOnboardingState, IntacctOnboardingState, NetsuiteOnboardingState, QBDOnboardingState, QBOOnboardingState, Sage300OnboardingState } from '../../models/enum/enum.model'; +import { AppUrl, BusinessCentralOnboardingState, IntacctOnboardingState, NetsuiteOnboardingState, QBDOnboardingState, QBOOnboardingState, Sage300OnboardingState, XeroOnboardingState } from '../../models/enum/enum.model'; import { ApiService } from './api.service'; import { HelperService } from './helper.service'; import { AppUrlMap } from '../../models/integrations/integrations.model'; @@ -56,7 +56,8 @@ export class WorkspaceService { [AppUrl.INTEGRATION]: '', [AppUrl.BUSINESS_CENTRAL]: BusinessCentralOnboardingState.CONNECTION, [AppUrl.QBO]: QBOOnboardingState.CONNECTION, - [AppUrl.NETSUITE]: NetsuiteOnboardingState.CONNECTION + [AppUrl.NETSUITE]: NetsuiteOnboardingState.CONNECTION, + [AppUrl.XERO]: XeroOnboardingState.CONNECTION }; const onboardingState = this.storageService.get('onboarding-state'); return onboardingState ? onboardingState : appInitialOnboardingState[(this.helper.getAppName()) as AppUrl]; diff --git a/src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.spec.ts b/src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.spec.ts new file mode 100644 index 000000000..3516948ec --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroAdvancedSettingsService } from './xero-advanced-settings.service'; + +describe('XeroAdvancedSettingsService', () => { + let service: XeroAdvancedSettingsService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(XeroAdvancedSettingsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.ts b/src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.ts new file mode 100644 index 000000000..ec41bde4c --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-advanced-settings.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { ApiService } from '../../common/api.service'; +import { WorkspaceService } from '../../common/workspace.service'; +import { CacheBuster, Cacheable } from 'ts-cacheable'; +import { Observable, Subject } from 'rxjs'; +import { XeroAdvancedSettingGet, XeroAdvancedSettingPost } from 'src/app/core/models/xero/xero-configuration/xero-advanced-settings.model'; +import { EmailOptions } from 'src/app/core/models/qbd/qbd-configuration/advanced-setting.model'; + +const advancedSettingsCache$ = new Subject(); +@Injectable({ + providedIn: 'root' +}) +export class XeroAdvancedSettingsService { + + constructor( + private apiService: ApiService, + private workspaceService: WorkspaceService + ) { } + + @Cacheable({ + cacheBusterObserver: advancedSettingsCache$ + }) + getAdvancedSettings(): Observable { + return this.apiService.get(`/v2/workspaces/${this.workspaceService.getWorkspaceId()}/advanced_settings/`, {}); + } + + @CacheBuster({ + cacheBusterNotifier: advancedSettingsCache$ + }) + postAdvancedSettings(advancedSettingPayload: XeroAdvancedSettingPost): Observable { + return this.apiService.put(`/v2/workspaces/${this.workspaceService.getWorkspaceId()}/advanced_settings/`, advancedSettingPayload); + } + + getWorkspaceAdmins(): Observable<[EmailOptions]> { + return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/admins/`, {}); + } + +} diff --git a/src/app/core/services/xero/xero-configuration/xero-connector.service.spec.ts b/src/app/core/services/xero/xero-configuration/xero-connector.service.spec.ts new file mode 100644 index 000000000..057658d8c --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-connector.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroConnectorService } from './xero-connector.service'; + +describe('XeroConnectorService', () => { + let service: XeroConnectorService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(XeroConnectorService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/core/services/xero/xero-configuration/xero-connector.service.ts b/src/app/core/services/xero/xero-configuration/xero-connector.service.ts new file mode 100644 index 000000000..e1e6c9d94 --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-connector.service.ts @@ -0,0 +1,73 @@ +import { Injectable } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; +import { ApiService } from '../../common/api.service'; +import { WorkspaceService } from '../../common/workspace.service'; +import { CacheBuster, Cacheable, globalCacheBusterNotifier } from 'ts-cacheable'; +import { XeroCredentials } from 'src/app/core/models/xero/db/xero-credential.model'; +import { environment } from 'src/environments/environment'; +import { DestinationAttribute } from 'src/app/core/models/db/destination-attribute.model'; +import { TenantMapping, TenantMappingPost } from 'src/app/core/models/xero/db/xero-tenant-mapping.model'; + +const xeroCredentialsCache = new Subject(); + + +@Injectable({ + providedIn: 'root' +}) +export class XeroConnectorService { + workspaceId = this.workspaceService.getWorkspaceId(); + + constructor( + private apiService: ApiService, + private workspaceService: WorkspaceService + ) { } + + @CacheBuster({ + cacheBusterNotifier: xeroCredentialsCache + }) + connectXero(workspaceId: string, code:string): Observable { + globalCacheBusterNotifier.next(); + return this.apiService.post(`/workspaces/${workspaceId}/connect_xero/authorization_code/`, {code: code, redirect_uri: environment.xero_oauth_redirect_uri}); + } + + @Cacheable({ + cacheBusterObserver: xeroCredentialsCache + }) + getXeroCredentials(workspaceId: string): Observable { + return this.apiService.get(`/workspaces/${workspaceId}/credentials/xero/`, {}); + } + + @CacheBuster({ + cacheBusterNotifier: xeroCredentialsCache + }) + revokeXeroConnection(workspaceId: string) { + return this.apiService.post(`/workspaces/${workspaceId}/connection/xero/revoke/`, {}); + } + + @Cacheable() + getXeroTokenHealth(workspaceId: string): Observable<{}> { + return this.apiService.get(`/workspaces/${workspaceId}/xero/token_health/`, {}); + } + + getXeroTenants(): Observable { + return this.apiService.get(`/workspaces/${this.workspaceId}/xero/tenants/`, {attribute_type: 'TENANT'}); + } + + postXeroTenants(): Observable { + const workspaceId = this.workspaceService.getWorkspaceId(); + + return this.apiService.post(`/workspaces/${workspaceId}/xero/tenants/`, {}); + } + + getTenantMappings(): Observable { + const workspaceId = this.workspaceService.getWorkspaceId(); + + return this.apiService.get(`/workspaces/${workspaceId}/mappings/tenant/`, {} + ); + } + + postTenantMapping(tenantMappingPayload: TenantMappingPost): Observable { + return this.apiService.post(`/workspaces/${this.workspaceId}/mappings/tenant/`, tenantMappingPayload); + } + +} \ No newline at end of file diff --git a/src/app/core/services/xero/xero-configuration/xero-export-settings.service.spec.ts b/src/app/core/services/xero/xero-configuration/xero-export-settings.service.spec.ts new file mode 100644 index 000000000..381df566d --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-export-settings.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroExportSettingsService } from './xero-export-settings.service'; + +describe('XeroExportSettingsService', () => { + let service: XeroExportSettingsService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(XeroExportSettingsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/core/services/xero/xero-configuration/xero-export-settings.service.ts b/src/app/core/services/xero/xero-configuration/xero-export-settings.service.ts new file mode 100644 index 000000000..358a10744 --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-export-settings.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { ApiService } from '../../common/api.service'; +import { WorkspaceService } from '../../common/workspace.service'; +import { Observable, Subject } from 'rxjs'; +import { XeroExportSettingGet, XeroExportSettingPost } from 'src/app/core/models/xero/xero-configuration/xero-export-settings.model'; +import { CacheBuster, Cacheable } from 'ts-cacheable'; + +const xeroExportSettingCache$ = new Subject(); + +@Injectable({ + providedIn: 'root' +}) +export class XeroExportSettingsService { + + constructor( + private apiService: ApiService, + private workspaceService: WorkspaceService + ) { } + + @Cacheable({ + cacheBusterObserver: xeroExportSettingCache$ + }) + getExportSettings(): Observable{ + return this.apiService.get(`/v2/workspaces/${this.workspaceService.getWorkspaceId()}/export_settings/`, {}); + } + + @CacheBuster({ + cacheBusterNotifier: xeroExportSettingCache$ + }) + postExportSettings(exportSettingsPayload: XeroExportSettingPost): Observable { + return this.apiService.put(`/v2/workspaces/${this.workspaceService.getWorkspaceId()}/export_settings/`, exportSettingsPayload); + } +} diff --git a/src/app/core/services/xero/xero-configuration/xero-import-settings.service.spec.ts b/src/app/core/services/xero/xero-configuration/xero-import-settings.service.spec.ts new file mode 100644 index 000000000..f1cecc0d5 --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-import-settings.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroImportSettingsService } from './xero-import-settings.service'; + +describe('XeroImportSettingsService', () => { + let service: XeroImportSettingsService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(XeroImportSettingsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/core/services/xero/xero-configuration/xero-import-settings.service.ts b/src/app/core/services/xero/xero-configuration/xero-import-settings.service.ts new file mode 100644 index 000000000..ffd740ae2 --- /dev/null +++ b/src/app/core/services/xero/xero-configuration/xero-import-settings.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { ApiService } from '../../common/api.service'; +import { WorkspaceService } from '../../common/workspace.service'; +import { XeroImportSettingGet, XeroImportSettingPost } from 'src/app/core/models/xero/xero-configuration/xero-import-settings.model'; +import { Observable, Subject } from 'rxjs'; +import { CacheBuster, Cacheable } from 'ts-cacheable'; + +const xeroImportSettingGetCache$ = new Subject(); + +@Injectable({ + providedIn: 'root' +}) +export class XeroImportSettingsService { + + constructor( + private apiService: ApiService, + private workspaceService: WorkspaceService + ) { } + + @Cacheable({ + cacheBusterObserver: xeroImportSettingGetCache$ + }) + getImportSettings(): Observable { + return this.apiService.get(`/v2/workspaces/${this.workspaceService.getWorkspaceId()}/import_settings/`, {}); + } + + @CacheBuster({ + cacheBusterNotifier: xeroImportSettingGetCache$ + }) + postImportSettings(exportSettingsPayload: XeroImportSettingPost): Observable{ + return this.apiService.put(`/v2/workspaces/${this.workspaceService.getWorkspaceId()}/import_settings/`, exportSettingsPayload); + } +} diff --git a/src/app/core/services/xero/xero-core/xero-auth.service.spec.ts b/src/app/core/services/xero/xero-core/xero-auth.service.spec.ts new file mode 100644 index 000000000..bddc4b7ef --- /dev/null +++ b/src/app/core/services/xero/xero-core/xero-auth.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroAuthService } from './xero-auth.service'; + +describe('XeroAuthService', () => { + let service: XeroAuthService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(XeroAuthService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/core/services/xero/xero-core/xero-auth.service.ts b/src/app/core/services/xero/xero-core/xero-auth.service.ts new file mode 100644 index 000000000..97f8bd77f --- /dev/null +++ b/src/app/core/services/xero/xero-core/xero-auth.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import { ApiService } from '../../common/api.service'; +import { Token } from 'src/app/core/models/misc/token.model'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class XeroAuthService { + + constructor( + private apiService: ApiService + ) { } + + loginWithRefreshToken(refreshToken: string): Observable { + return this.apiService.post('/auth/login_with_refresh_token/', { refresh_token: refreshToken }); + } + + login(code: string): Observable { + return this.apiService.post('/auth/login/', { code: code }); + } +} diff --git a/src/app/core/services/xero/xero-core/xero-helper.service.spec.ts b/src/app/core/services/xero/xero-core/xero-helper.service.spec.ts new file mode 100644 index 000000000..c581ea7fc --- /dev/null +++ b/src/app/core/services/xero/xero-core/xero-helper.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { XeroHelperService } from './xero-helper.service'; + +describe('XeroHelperService', () => { + let service: XeroHelperService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(XeroHelperService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/core/services/xero/xero-core/xero-helper.service.ts b/src/app/core/services/xero/xero-core/xero-helper.service.ts new file mode 100644 index 000000000..202bbfda1 --- /dev/null +++ b/src/app/core/services/xero/xero-core/xero-helper.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { WorkspaceService } from '../../common/workspace.service'; +import { ApiService } from '../../common/api.service'; +import { Cacheable } from 'ts-cacheable'; + +@Injectable({ + providedIn: 'root' +}) +export class XeroHelperService { + + constructor( + private apiService: ApiService, + private workspaceService: WorkspaceService + ) { } + + @Cacheable() + syncXeroDimensions() { + return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/xero/sync_dimensions/`, {}); + } + + @Cacheable() + syncFyleDimensions() { + return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/fyle/sync_dimensions/`, {}); + } + + refreshXeroDimensions() { + return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/xero/refresh_dimensions/`, {}); + } + + refreshFyleDimensions() { + return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/fyle/refresh_dimensions/`, {}); + } +} diff --git a/src/app/integrations/integrations-routing.module.ts b/src/app/integrations/integrations-routing.module.ts index 5f92ef05d..64b3c9e2e 100644 --- a/src/app/integrations/integrations-routing.module.ts +++ b/src/app/integrations/integrations-routing.module.ts @@ -43,6 +43,10 @@ const routes: Routes = [ { path: 'netsuite', loadChildren: () => import('./netsuite/netsuite.module').then(m => m.NetsuiteModule) + }, + { + path: 'xero', + loadChildren: () => import('./xero/xero.module').then(m => m.XeroModule) } ] } diff --git a/src/app/integrations/integrations.module.ts b/src/app/integrations/integrations.module.ts index da3f408a8..b33f8fd5f 100644 --- a/src/app/integrations/integrations.module.ts +++ b/src/app/integrations/integrations.module.ts @@ -8,8 +8,8 @@ import { IconSpriteModule } from 'ng-svg-icon-sprite'; import { QbdComponent } from './qbd/qbd.component'; import { SharedModule } from '../shared/shared.module'; import { Sage300Component } from './sage300/sage300.component'; +import { XeroComponent } from './xero/xero.component'; import { TravelperkComponent } from './travelperk/travelperk.component'; -import { SkeletonModule } from 'primeng/skeleton'; @NgModule({ declarations: [ @@ -17,6 +17,7 @@ import { SkeletonModule } from 'primeng/skeleton'; LandingComponent, QbdComponent, Sage300Component, + XeroComponent, TravelperkComponent ], imports: [ diff --git a/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration-routing.module.ts b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration-routing.module.ts new file mode 100644 index 000000000..ffdab041d --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration-routing.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { XeroAdvancedSettingsComponent } from '../../xero-shared/xero-advanced-settings/xero-advanced-settings.component'; +import { XeroExportSettingsComponent } from '../../xero-shared/xero-export-settings/xero-export-settings.component'; +import { XeroImportSettingsComponent } from '../../xero-shared/xero-import-settings/xero-import-settings.component'; +import { XeroConfigurationComponent } from './xero-configuration.component'; + +const routes: Routes = [ + { + path: '', + component: XeroConfigurationComponent, + children: [ + { + path: 'export_settings', + component: XeroExportSettingsComponent + }, + { + path: 'import_settings', + component: XeroImportSettingsComponent + }, + { + path: 'advanced_settings', + component: XeroAdvancedSettingsComponent + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class XeroConfigurationRoutingModule { } diff --git a/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.html b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.html new file mode 100644 index 000000000..387638c4b --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.html @@ -0,0 +1 @@ +

xero-configuration works!

diff --git a/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.scss b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.spec.ts b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.spec.ts new file mode 100644 index 000000000..332d54f16 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroConfigurationComponent } from './xero-configuration.component'; + +describe('XeroConfigurationComponent', () => { + let component: XeroConfigurationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroConfigurationComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroConfigurationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.ts b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.ts new file mode 100644 index 000000000..e264dfbd1 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-configuration', + templateUrl: './xero-configuration.component.html', + styleUrls: ['./xero-configuration.component.scss'] +}) +export class XeroConfigurationComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.module.ts b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.module.ts new file mode 100644 index 000000000..e6059944a --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-configuration/xero-configuration.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { XeroConfigurationRoutingModule } from './xero-configuration-routing.module'; +import { XeroConfigurationComponent } from './xero-configuration.component'; +import { XeroSharedModule } from '../../xero-shared/xero-shared.module'; + + +@NgModule({ + declarations: [ + XeroConfigurationComponent + ], + imports: [ + CommonModule, + XeroSharedModule, + XeroConfigurationRoutingModule + ] +}) +export class XeroConfigurationModule { } diff --git a/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.html b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.html new file mode 100644 index 000000000..97af468cf --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.html @@ -0,0 +1 @@ +

xero-dashboard works!

diff --git a/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.scss b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.spec.ts b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.spec.ts new file mode 100644 index 000000000..87b2cd0a6 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroDashboardComponent } from './xero-dashboard.component'; + +describe('XeroDashboardComponent', () => { + let component: XeroDashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroDashboardComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroDashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.ts b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.ts new file mode 100644 index 000000000..d325d667b --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-dashboard/xero-dashboard.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-dashboard', + templateUrl: './xero-dashboard.component.html', + styleUrls: ['./xero-dashboard.component.scss'] +}) +export class XeroDashboardComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.html b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.html new file mode 100644 index 000000000..71e782a52 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.html @@ -0,0 +1 @@ +

xero-export-log works!

diff --git a/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.scss b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.spec.ts b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.spec.ts new file mode 100644 index 000000000..6fcd87572 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroExportLogComponent } from './xero-export-log.component'; + +describe('XeroExportLogComponent', () => { + let component: XeroExportLogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroExportLogComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroExportLogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.ts b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.ts new file mode 100644 index 000000000..0dd84d681 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-export-log/xero-export-log.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-export-log', + templateUrl: './xero-export-log.component.html', + styleUrls: ['./xero-export-log.component.scss'] +}) +export class XeroExportLogComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-main/xero-main-routing.module.ts b/src/app/integrations/xero/xero-main/xero-main-routing.module.ts new file mode 100644 index 000000000..50d158b46 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-main-routing.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { XeroMainComponent } from './xero-main.component'; + +const routes: Routes = [ + { + path: '', + component: XeroMainComponent, + children: [ + // { + // Path: 'dashboard', + // LoadChildren: () => import('./xero-dashboard/xero-dashboard.module').then(m => m.XeroDashboardModule) + // }, + { + path: 'configuration', + loadChildren: () => import('./xero-configuration/xero-configuration.module').then(m => m.XeroConfigurationModule) + } + // { + // Path: 'mapping', + // LoadChildren: () => import('./xero-mapping/xero-mapping.module').then(m => m.XeroMappingModule) + // }, + // { + // Path: 'export_log', + // LoadChildren: () => import('./xero-export-log/xero-export-log.module').then(m => m.XeroExportLogModule) + // } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class XeroMainRoutingModule { } diff --git a/src/app/integrations/xero/xero-main/xero-main.component.html b/src/app/integrations/xero/xero-main/xero-main.component.html new file mode 100644 index 000000000..ee800cf84 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-main.component.html @@ -0,0 +1 @@ +

xero-main works!

diff --git a/src/app/integrations/xero/xero-main/xero-main.component.scss b/src/app/integrations/xero/xero-main/xero-main.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-main/xero-main.component.spec.ts b/src/app/integrations/xero/xero-main/xero-main.component.spec.ts new file mode 100644 index 000000000..16aae636d --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-main.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroMainComponent } from './xero-main.component'; + +describe('XeroMainComponent', () => { + let component: XeroMainComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroMainComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroMainComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-main/xero-main.component.ts b/src/app/integrations/xero/xero-main/xero-main.component.ts new file mode 100644 index 000000000..780d47bd9 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-main.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-main', + templateUrl: './xero-main.component.html', + styleUrls: ['./xero-main.component.scss'] +}) +export class XeroMainComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-main/xero-main.module.ts b/src/app/integrations/xero/xero-main/xero-main.module.ts new file mode 100644 index 000000000..3b96e4244 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-main.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { XeroMainRoutingModule } from './xero-main-routing.module'; +import { XeroMainComponent } from './xero-main.component'; +import { XeroDashboardComponent } from './xero-dashboard/xero-dashboard.component'; +import { XeroMappingComponent } from './xero-mapping/xero-mapping.component'; +import { XeroExportLogComponent } from './xero-export-log/xero-export-log.component'; +import { XeroSharedModule } from '../xero-shared/xero-shared.module'; +import { SharedModule } from 'src/app/shared/shared.module'; + + +@NgModule({ + declarations: [ + XeroMainComponent, + XeroDashboardComponent, + XeroMappingComponent, + XeroExportLogComponent + ], + imports: [ + CommonModule, + XeroSharedModule, + SharedModule, + XeroMainRoutingModule + ] +}) +export class XeroMainModule { } diff --git a/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.html b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.html new file mode 100644 index 000000000..047d150da --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.html @@ -0,0 +1 @@ +

xero-mapping works!

diff --git a/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.scss b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.spec.ts b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.spec.ts new file mode 100644 index 000000000..f695a5c92 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroMappingComponent } from './xero-mapping.component'; + +describe('XeroMappingComponent', () => { + let component: XeroMappingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroMappingComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroMappingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.ts b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.ts new file mode 100644 index 000000000..be062ede2 --- /dev/null +++ b/src/app/integrations/xero/xero-main/xero-mapping/xero-mapping.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-mapping', + templateUrl: './xero-mapping.component.html', + styleUrls: ['./xero-mapping.component.scss'] +}) +export class XeroMappingComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.html new file mode 100644 index 000000000..7065c19e6 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.html @@ -0,0 +1 @@ +

xero-onboarding-advanced-settings works!

diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.spec.ts new file mode 100644 index 000000000..72ba45ec3 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingAdvancedSettingsComponent } from './xero-onboarding-advanced-settings.component'; + +describe('XeroOnboardingAdvancedSettingsComponent', () => { + let component: XeroOnboardingAdvancedSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingAdvancedSettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingAdvancedSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.ts new file mode 100644 index 000000000..0a88b4fae --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding-advanced-settings', + templateUrl: './xero-onboarding-advanced-settings.component.html', + styleUrls: ['./xero-onboarding-advanced-settings.component.scss'] +}) +export class XeroOnboardingAdvancedSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.html new file mode 100644 index 000000000..aa6ca777b --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.html @@ -0,0 +1 @@ +

xero-onboarding-connector works!

diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.spec.ts new file mode 100644 index 000000000..b0857268e --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingConnectorComponent } from './xero-onboarding-connector.component'; + +describe('XeroOnboardingConnectorComponent', () => { + let component: XeroOnboardingConnectorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingConnectorComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingConnectorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.ts new file mode 100644 index 000000000..e4b31e35b --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-connector/xero-onboarding-connector.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding-connector', + templateUrl: './xero-onboarding-connector.component.html', + styleUrls: ['./xero-onboarding-connector.component.scss'] +}) +export class XeroOnboardingConnectorComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.html new file mode 100644 index 000000000..2c41378ad --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.html @@ -0,0 +1 @@ +

xero-onboarding-done works!

diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.spec.ts new file mode 100644 index 000000000..096873135 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingDoneComponent } from './xero-onboarding-done.component'; + +describe('XeroOnboardingDoneComponent', () => { + let component: XeroOnboardingDoneComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingDoneComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingDoneComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.ts new file mode 100644 index 000000000..3ebe25424 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-done/xero-onboarding-done.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding-done', + templateUrl: './xero-onboarding-done.component.html', + styleUrls: ['./xero-onboarding-done.component.scss'] +}) +export class XeroOnboardingDoneComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.html new file mode 100644 index 000000000..f2da483ce --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.html @@ -0,0 +1 @@ +

xero-onboarding-export-settings works!

diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.spec.ts new file mode 100644 index 000000000..d492c8400 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingExportSettingsComponent } from './xero-onboarding-export-settings.component'; + +describe('XeroOnboardingExportSettingsComponent', () => { + let component: XeroOnboardingExportSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingExportSettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingExportSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.ts new file mode 100644 index 000000000..157c772d5 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-export-settings/xero-onboarding-export-settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding-export-settings', + templateUrl: './xero-onboarding-export-settings.component.html', + styleUrls: ['./xero-onboarding-export-settings.component.scss'] +}) +export class XeroOnboardingExportSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.html new file mode 100644 index 000000000..96c11da89 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.html @@ -0,0 +1 @@ +

xero-onboarding-import-settings works!

diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.spec.ts new file mode 100644 index 000000000..4c0ca8ad2 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingImportSettingsComponent } from './xero-onboarding-import-settings.component'; + +describe('XeroOnboardingImportSettingsComponent', () => { + let component: XeroOnboardingImportSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingImportSettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingImportSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.ts new file mode 100644 index 000000000..27dfc9e63 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-import-settings/xero-onboarding-import-settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding-import-settings', + templateUrl: './xero-onboarding-import-settings.component.html', + styleUrls: ['./xero-onboarding-import-settings.component.scss'] +}) +export class XeroOnboardingImportSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.html new file mode 100644 index 000000000..6d618195e --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.html @@ -0,0 +1 @@ +

xero-onboarding-landing works!

diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.spec.ts new file mode 100644 index 000000000..bf38cc01f --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingLandingComponent } from './xero-onboarding-landing.component'; + +describe('XeroOnboardingLandingComponent', () => { + let component: XeroOnboardingLandingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingLandingComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingLandingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.ts new file mode 100644 index 000000000..2cd2b35ac --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-landing/xero-onboarding-landing.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding-landing', + templateUrl: './xero-onboarding-landing.component.html', + styleUrls: ['./xero-onboarding-landing.component.scss'] +}) +export class XeroOnboardingLandingComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding-routing.module.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding-routing.module.ts new file mode 100644 index 000000000..6daba1cec --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding-routing.module.ts @@ -0,0 +1,53 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { XeroOnboardingAdvancedSettingsComponent } from './xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component'; +import { XeroOnboardingConnectorComponent } from './xero-onboarding-connector/xero-onboarding-connector.component'; +import { XeroOnboardingDoneComponent } from './xero-onboarding-done/xero-onboarding-done.component'; +import { XeroOnboardingExportSettingsComponent } from './xero-onboarding-export-settings/xero-onboarding-export-settings.component'; +import { XeroOnboardingImportSettingsComponent } from './xero-onboarding-import-settings/xero-onboarding-import-settings.component'; +import { XeroOnboardingLandingComponent } from './xero-onboarding-landing/xero-onboarding-landing.component'; +import { XeroOnboardingComponent } from './xero-onboarding.component'; +import { XeroTokenGuard } from 'src/app/core/guard/xero-token.guard'; +import { TenantGuard } from 'src/app/core/guard/tenant.guard'; + +const routes: Routes = [ + { + path: '', + component: XeroOnboardingComponent, + children: [ + { + path: 'landing', + component: XeroOnboardingLandingComponent + }, + { + path: 'connector', + component: XeroOnboardingConnectorComponent + }, + { path: 'export_settings', + component: XeroOnboardingExportSettingsComponent, + canActivate: [XeroTokenGuard, TenantGuard] + }, + { + path: 'import_settings', + component: XeroOnboardingImportSettingsComponent, + canActivate: [XeroTokenGuard, TenantGuard] + }, + { + path: 'advanced_settings', + component: XeroOnboardingAdvancedSettingsComponent, + canActivate: [XeroTokenGuard, TenantGuard] + }, + { + path: 'done', + component: XeroOnboardingDoneComponent, + canActivate: [XeroTokenGuard, TenantGuard] + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class XeroOnboardingRoutingModule { } diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.html b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.html new file mode 100644 index 000000000..90c6b6463 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.scss b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.spec.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.spec.ts new file mode 100644 index 000000000..c18e8e0fd --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroOnboardingComponent } from './xero-onboarding.component'; + +describe('XeroOnboardingComponent', () => { + let component: XeroOnboardingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroOnboardingComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroOnboardingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.ts new file mode 100644 index 000000000..123831f4d --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-onboarding', + templateUrl: './xero-onboarding.component.html', + styleUrls: ['./xero-onboarding.component.scss'] +}) +export class XeroOnboardingComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-onboarding/xero-onboarding.module.ts b/src/app/integrations/xero/xero-onboarding/xero-onboarding.module.ts new file mode 100644 index 000000000..0387ba663 --- /dev/null +++ b/src/app/integrations/xero/xero-onboarding/xero-onboarding.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { XeroOnboardingRoutingModule } from './xero-onboarding-routing.module'; +import { XeroOnboardingComponent } from './xero-onboarding.component'; +import { XeroOnboardingLandingComponent } from './xero-onboarding-landing/xero-onboarding-landing.component'; +import { XeroOnboardingConnectorComponent } from './xero-onboarding-connector/xero-onboarding-connector.component'; +import { XeroOnboardingExportSettingsComponent } from './xero-onboarding-export-settings/xero-onboarding-export-settings.component'; +import { XeroOnboardingImportSettingsComponent } from './xero-onboarding-import-settings/xero-onboarding-import-settings.component'; +import { XeroOnboardingAdvancedSettingsComponent } from './xero-onboarding-advanced-settings/xero-onboarding-advanced-settings.component'; +import { XeroOnboardingDoneComponent } from './xero-onboarding-done/xero-onboarding-done.component'; +import { XeroSharedModule } from '../xero-shared/xero-shared.module'; + + +@NgModule({ + declarations: [ + XeroOnboardingComponent, + XeroOnboardingLandingComponent, + XeroOnboardingConnectorComponent, + XeroOnboardingExportSettingsComponent, + XeroOnboardingImportSettingsComponent, + XeroOnboardingAdvancedSettingsComponent, + XeroOnboardingDoneComponent + ], + imports: [ + CommonModule, + XeroSharedModule, + XeroOnboardingRoutingModule + ] +}) +export class XeroOnboardingModule { } diff --git a/src/app/integrations/xero/xero-routing.module.ts b/src/app/integrations/xero/xero-routing.module.ts new file mode 100644 index 000000000..bf98ed4fa --- /dev/null +++ b/src/app/integrations/xero/xero-routing.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { XeroComponent } from './xero.component'; +import { XeroTokenGuard } from 'src/app/core/guard/xero-token.guard'; + +const routes: Routes = [ + { + path: '', + component: XeroComponent, + children: [ + { + path: 'onboarding', + loadChildren: () => import('./xero-onboarding/xero-onboarding.module').then(m => m.XeroOnboardingModule) + }, + { + path: 'main', + loadChildren: () => import('./xero-main/xero-main.module').then(m => m.XeroMainModule), + canActivate: [XeroTokenGuard] + } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class XeroRoutingModule { } diff --git a/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.html b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.html new file mode 100644 index 000000000..0b586be85 --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.html @@ -0,0 +1 @@ +

xero-advanced-settings works!

diff --git a/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.scss b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.spec.ts b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.spec.ts new file mode 100644 index 000000000..cfa0d383f --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroAdvancedSettingsComponent } from './xero-advanced-settings.component'; + +describe('XeroAdvancedSettingsComponent', () => { + let component: XeroAdvancedSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroAdvancedSettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroAdvancedSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.ts b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.ts new file mode 100644 index 000000000..4615d75cf --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-advanced-settings/xero-advanced-settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-advanced-settings', + templateUrl: './xero-advanced-settings.component.html', + styleUrls: ['./xero-advanced-settings.component.scss'] +}) +export class XeroAdvancedSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.html b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.html new file mode 100644 index 000000000..dd1a112dd --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.html @@ -0,0 +1 @@ +

xero-export-settings works!

diff --git a/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.scss b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.spec.ts b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.spec.ts new file mode 100644 index 000000000..8e3cc3e06 --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroExportSettingsComponent } from './xero-export-settings.component'; + +describe('XeroExportSettingsComponent', () => { + let component: XeroExportSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroExportSettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroExportSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.ts b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.ts new file mode 100644 index 000000000..761b35d1c --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-export-settings/xero-export-settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-export-settings', + templateUrl: './xero-export-settings.component.html', + styleUrls: ['./xero-export-settings.component.scss'] +}) +export class XeroExportSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.html b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.html new file mode 100644 index 000000000..c2207c283 --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.html @@ -0,0 +1 @@ +

xero-import-settings works!

diff --git a/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.scss b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.spec.ts b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.spec.ts new file mode 100644 index 000000000..3b5585e85 --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroImportSettingsComponent } from './xero-import-settings.component'; + +describe('XeroImportSettingsComponent', () => { + let component: XeroImportSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroImportSettingsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroImportSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.ts b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.ts new file mode 100644 index 000000000..a0e7dfe9e --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-import-settings/xero-import-settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-xero-import-settings', + templateUrl: './xero-import-settings.component.html', + styleUrls: ['./xero-import-settings.component.scss'] +}) +export class XeroImportSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/integrations/xero/xero-shared/xero-shared.module.ts b/src/app/integrations/xero/xero-shared/xero-shared.module.ts new file mode 100644 index 000000000..3b75313b4 --- /dev/null +++ b/src/app/integrations/xero/xero-shared/xero-shared.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { XeroAdvancedSettingsComponent } from './xero-advanced-settings/xero-advanced-settings.component'; +import { XeroExportSettingsComponent } from './xero-export-settings/xero-export-settings.component'; +import { XeroImportSettingsComponent } from './xero-import-settings/xero-import-settings.component'; +import { SharedModule } from 'src/app/shared/shared.module'; + +@NgModule({ + declarations: [ + XeroExportSettingsComponent, + XeroImportSettingsComponent, + XeroAdvancedSettingsComponent + ], + imports: [ + CommonModule, + SharedModule + ], + exports: [ + XeroExportSettingsComponent, + XeroImportSettingsComponent, + XeroAdvancedSettingsComponent + ] +}) +export class XeroSharedModule { } diff --git a/src/app/integrations/xero/xero.component.html b/src/app/integrations/xero/xero.component.html new file mode 100644 index 000000000..90c6b6463 --- /dev/null +++ b/src/app/integrations/xero/xero.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/integrations/xero/xero.component.scss b/src/app/integrations/xero/xero.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/integrations/xero/xero.component.spec.ts b/src/app/integrations/xero/xero.component.spec.ts new file mode 100644 index 000000000..d2d52981a --- /dev/null +++ b/src/app/integrations/xero/xero.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { XeroComponent } from './xero.component'; + +describe('XeroComponent', () => { + let component: XeroComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ XeroComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(XeroComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/integrations/xero/xero.component.ts b/src/app/integrations/xero/xero.component.ts new file mode 100644 index 000000000..90d935d87 --- /dev/null +++ b/src/app/integrations/xero/xero.component.ts @@ -0,0 +1,89 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { MinimalUser } from 'src/app/core/models/db/user.model'; +import { XeroOnboardingState } from 'src/app/core/models/enum/enum.model'; +import { XeroWorkspace } from 'src/app/core/models/xero/db/xero-workspace.model'; +import { HelperService } from 'src/app/core/services/common/helper.service'; +import { StorageService } from 'src/app/core/services/common/storage.service'; +import { WindowService } from 'src/app/core/services/common/window.service'; +import { WorkspaceService } from 'src/app/core/services/common/workspace.service'; +import { UserService } from 'src/app/core/services/misc/user.service'; +import { XeroHelperService } from 'src/app/core/services/xero/xero-core/xero-helper.service'; + +@Component({ + selector: 'app-xero', + templateUrl: './xero.component.html', + styleUrls: ['./xero.component.scss'] +}) +export class XeroComponent implements OnInit { + + user: MinimalUser; + + isLoading: boolean = true; + + workspace: XeroWorkspace; + + windowReference: Window; + + constructor( + private router: Router, + private storageService: StorageService, + private xeroHelperService: XeroHelperService, + private userService: UserService, + private windowService: WindowService, + private workspaceService: WorkspaceService + ) { + this.windowReference = this.windowService.nativeWindow; + } + + private navigate(): void { + const pathName = this.windowReference.location.pathname; + if (pathName === '/integrations/xero') { + const onboardingStateComponentMap = { + [XeroOnboardingState.CONNECTION]: '/integrations/xero/onboarding/landing', + [XeroOnboardingState.EXPORT_SETTINGS]: '/integrations/xero/onboarding/export_settings', + [XeroOnboardingState.IMPORT_SETTINGS]: '/integrations/xero/onboarding/import_settings', + [XeroOnboardingState.ADVANCED_CONFIGURATION]: '/integrations/xero/onboarding/advanced_settings', + [XeroOnboardingState.CLONE_SETTINGS]: '/integrations/xero/onboarding/clone_settings', + [XeroOnboardingState.COMPLETE]: '/integrations/xero/main' + }; + this.router.navigateByUrl(onboardingStateComponentMap[this.workspace.onboarding_state]); + } + } + + private getOrCreateWorkspace(): Promise { + return this.workspaceService.getWorkspace(this.user.org_id).toPromise().then((workspaces: XeroWorkspace[]) => { + if (workspaces.length > 0) { + return workspaces[0]; + } + + return this.workspaceService.postWorkspace().toPromise().then((workspace: XeroWorkspace) => { + return workspace; + }); + }); + } + + private setupWorkspace(): void { + this.user = this.userService.getUserProfile(); + this.getOrCreateWorkspace().then((workspace: XeroWorkspace) => { + this.workspace = workspace; + const currency = { + fyle_currency: workspace.fyle_currency, + xero_currency: workspace.xero_currency + }; + this.storageService.set('workspaceId', this.workspace.id); + this.storageService.set('onboarding-state', this.workspace.onboarding_state); + this.storageService.set('currency', currency); + this.xeroHelperService.syncFyleDimensions().subscribe(); + this.xeroHelperService.syncXeroDimensions().subscribe(); + this.isLoading = false; + this.navigate(); + }); + } + + ngOnInit(): void { + this.setupWorkspace(); + } + + +} diff --git a/src/app/integrations/xero/xero.module.ts b/src/app/integrations/xero/xero.module.ts new file mode 100644 index 000000000..e43b6d6ac --- /dev/null +++ b/src/app/integrations/xero/xero.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { XeroRoutingModule } from './xero-routing.module'; + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + XeroRoutingModule + ] +}) +export class XeroModule { } diff --git a/src/app/shared/components/configuration/configuration-import-field/configuration-import-field.component.html b/src/app/shared/components/configuration/configuration-import-field/configuration-import-field.component.html index 2d7409279..f87d716e4 100644 --- a/src/app/shared/components/configuration/configuration-import-field/configuration-import-field.component.html +++ b/src/app/shared/components/configuration/configuration-import-field/configuration-import-field.component.html @@ -97,7 +97,7 @@
+
@@ -138,7 +138,7 @@
+