diff --git a/.github/workflows/qa_deployment.yml b/.github/workflows/qa_deployment.yml index 16d68387c..0ebf232a4 100644 --- a/.github/workflows/qa_deployment.yml +++ b/.github/workflows/qa_deployment.yml @@ -38,7 +38,7 @@ jobs: - name: Update Image Tag run: | NEW_TAG="v$(git rev-parse --short HEAD)" - cd ${{ vars.STAGING_DEPLOY_REPO }}/${{ vars.C1_STAGING_DEPLOY_DIR }}/integrations + cd ${{ vars.STAGING_DEPLOY_REPO }}/${{ vars.C1_STAGING_DEPLOY_DIR }}/qa/integrations kustomize edit set image docker.io/${{ secrets.DOCKERHUB_USERNAME }}/fyle_integrations-app=docker.io/${{ secrets.DOCKERHUB_USERNAME }}/fyle_integrations-app:$NEW_TAG - name: Commit and push changes diff --git a/src/app/branding/branding-config.ts b/src/app/branding/branding-config.ts index 715c41f5d..e3030424b 100644 --- a/src/app/branding/branding-config.ts +++ b/src/app/branding/branding-config.ts @@ -1,3 +1,4 @@ +import { disconnect } from 'process'; import { BrandingConfiguration } from '../core/models/branding/branding-configuration.model'; import { ContentConfiguration } from '../core/models/branding/content-configuration.model'; import { DemoVideo } from '../core/models/branding/demo-video.model'; @@ -17,6 +18,7 @@ const featureConfigs: FeatureConfiguration = { exposeC1Apps: false, isBackgroundColorAllowed: false, isAsterikAllowed: true, + allowIntacctHelperDoc: true, featureFlags: { cloneSettings: true, mapEmployees: true, @@ -48,6 +50,9 @@ const featureConfigs: FeatureConfiguration = { }, mappings: { employeeMapping: true + }, + dashboard: { + disconnectButton: true } } }, @@ -58,6 +63,7 @@ const featureConfigs: FeatureConfiguration = { exposeC1Apps: true, isBackgroundColorAllowed: true, isAsterikAllowed: false, + allowIntacctHelperDoc: false, featureFlags: { cloneSettings: false, mapEmployees: false, @@ -89,6 +95,9 @@ const featureConfigs: FeatureConfiguration = { }, mappings: { employeeMapping: false + }, + dashboard: { + disconnectButton: false } } } diff --git a/src/app/branding/c1-contents-config.ts b/src/app/branding/c1-contents-config.ts index 7afdb9f91..c4cc4cb09 100644 --- a/src/app/branding/c1-contents-config.ts +++ b/src/app/branding/c1-contents-config.ts @@ -111,6 +111,7 @@ export const c1Contents = { creditCardExportTypeSubLabel: 'Choose how transactions are exported to Xero.', expenseState: '', creditCardExpenseSubLabel: '', + cccExpenseBankAccountLabel: 'Which bank account should the bank transactions post to?', cccExpenseStateSubLabel: 'You can choose to only export expenses when they\'ve been labeled approved or closed. ' }, stepSubLabel: 'Configure how and when expenses from expense management can be exported to Xero.', @@ -239,7 +240,7 @@ export const c1Contents = { }, configuration: { connector: { - stepName: 'Connect to Quickbooks Online' + stepName: 'Connect to QuickBooks Online' }, employeeSetting: { stepName: 'Map employees' @@ -298,12 +299,12 @@ export const c1Contents = { memoStructureLabel: 'Set the line-item description field in QuickBooks Online', automationSubLabel: 'Automate exports and data syncs.', scheduleSubLabel: 'Set up a schedule to automate the export of expenses from expense management to QuickBooks Online.', - frequencySubLabel: 'Set how often your expenses will be exported to Quickbooks Online.', + frequencySubLabel: 'Set how often your expenses will be exported to QuickBooks Online.', otherPreferencesLabel: 'Other preferences', - otherPreferencesSubLabel: 'Create new records in Quickbooks Online if no vendor record is found or the accounting period is closed.', + otherPreferencesSubLabel: 'Create new records in QuickBooks Online if no vendor record is found or the accounting period is closed.', accountingPeriodLabel: 'Post entries in the current open accounting period.', accountingPeriodSubLabel: 'If the accounting period is closed, the expenses will be exported with a date stamp for the first day of the current open accounting period', - autoCreateMerchantsAsVendorsSubLabel: 'Automatically create a new vendor in Quickbooks Online if an added merchant doesn\'t have a corresponding match.', + autoCreateMerchantsAsVendorsSubLabel: 'Automatically create a new vendor in QuickBooks Online if an added merchant doesn\'t have a corresponding match.', customizeSectionSubLAbel: 'Customize the data that you\'d like to export from expense management to QuickBooks Online by choosing which data points need to be exported.', memoStructureSubLabel: 'Choose from a list of available data points that you\'d like to export to the description field in QuickBooks Online.', previewDescriptionFieldLabel: 'Preview of the description field' diff --git a/src/app/branding/fyle-contents-config.ts b/src/app/branding/fyle-contents-config.ts index 50ef95226..240dca889 100644 --- a/src/app/branding/fyle-contents-config.ts +++ b/src/app/branding/fyle-contents-config.ts @@ -111,6 +111,7 @@ export const fyleContents = { creditCardExportTypeSubLabel: '', expenseState: '', creditCardExpenseSubLabel: '', + cccExpenseBankAccountLabel: 'To which Bank Account should the Bank Transactions be posted to?', cccExpenseStateSubLabel: 'You can export expenses either when they\'re awaiting payment after approval (Approved) or when the payment has been settled (Closed).' }, cccExpenseStateLabel: 'At which state should the expenses be ready to export from ' + brandingConfig.brandName + '?', @@ -239,7 +240,7 @@ export const fyleContents = { }, configuration: { connector: { - stepName: 'Connect to Quickbooks Online' + stepName: 'Connect to QuickBooks Online' }, employeeSetting: { stepName: 'Map Employees' diff --git a/src/app/core/models/branding/content-configuration.model.ts b/src/app/core/models/branding/content-configuration.model.ts index bd20b909a..7ec02d0a3 100644 --- a/src/app/core/models/branding/content-configuration.model.ts +++ b/src/app/core/models/branding/content-configuration.model.ts @@ -110,6 +110,7 @@ export type ContentConfiguration = { expenseState: string; creditCardExpenseSubLabel: string; cccExpenseStateSubLabel: string; + cccExpenseBankAccountLabel: string; } }, importSetting: { diff --git a/src/app/core/models/branding/feature-configuration.model.ts b/src/app/core/models/branding/feature-configuration.model.ts index b981b9153..f4a5de77e 100644 --- a/src/app/core/models/branding/feature-configuration.model.ts +++ b/src/app/core/models/branding/feature-configuration.model.ts @@ -6,6 +6,7 @@ export type FeatureConfiguration = { exposeC1Apps: boolean; isBackgroundColorAllowed: boolean; isAsterikAllowed: boolean; + allowIntacctHelperDoc: boolean; featureFlags: { cloneSettings: boolean; mapEmployees: boolean; @@ -37,6 +38,9 @@ export type FeatureConfiguration = { }, mappings: { employeeMapping: boolean; + }, + dashboard: { + disconnectButton: boolean; } } } diff --git a/src/app/core/models/db/error.model.ts b/src/app/core/models/db/error.model.ts index da640aa67..5e3e69d52 100644 --- a/src/app/core/models/db/error.model.ts +++ b/src/app/core/models/db/error.model.ts @@ -19,6 +19,7 @@ export interface Error { expense_attribute: ExpenseAttribute; expense_group: AccountingExport; type: AccountingErrorType; + article_link: string; is_resolved: boolean; error_title: string; error_detail: string; diff --git a/src/app/core/models/intacct/db/error.model.ts b/src/app/core/models/intacct/db/error.model.ts index 04c3ce1f1..720a62a35 100644 --- a/src/app/core/models/intacct/db/error.model.ts +++ b/src/app/core/models/intacct/db/error.model.ts @@ -14,6 +14,7 @@ export type Error = { workspace_id: number; created_at: Date; updated_at: Date; + article_link: string; }; export type GroupedErrors = { diff --git a/src/app/core/models/qbo/qbo-configuration/qbo-advanced-setting.model.ts b/src/app/core/models/qbo/qbo-configuration/qbo-advanced-setting.model.ts index 1d0bbd328..5e1248b47 100644 --- a/src/app/core/models/qbo/qbo-configuration/qbo-advanced-setting.model.ts +++ b/src/app/core/models/qbo/qbo-configuration/qbo-advanced-setting.model.ts @@ -60,11 +60,11 @@ export class QBOAdvancedSettingModel extends HelperUtility { static getPaymentSyncOptions(): SelectFormOption[] { return [ { - label: `Export ${brandingConfig.brandName} ACH Payments to Quickbooks Online`, + label: `Export ${brandingConfig.brandName} ACH Payments to QuickBooks Online`, value: QBOPaymentSyncDirection.FYLE_TO_QBO }, { - label: `Import Quickbooks Payments into ${brandingConfig.brandName}`, + label: `Import QuickBooks Payments into ${brandingConfig.brandName}`, value: QBOPaymentSyncDirection.QBO_TO_FYLE } ]; 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 index f0ccc2f8a..00c643e18 100644 --- 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 @@ -62,7 +62,7 @@ export class XeroExportSettingModel { static getCreditCardExportTypes() { return [ { - label: 'Bank Transaction', + label: 'Bank Transactions', value: XeroCorporateCreditCardExpensesObject.BANK_TRANSACTION } ]; diff --git a/src/app/core/services/qbo/qbo-core/qbo-helper.service.ts b/src/app/core/services/qbo/qbo-core/qbo-helper.service.ts index 0a74aca46..b340e795d 100644 --- a/src/app/core/services/qbo/qbo-core/qbo-helper.service.ts +++ b/src/app/core/services/qbo/qbo-core/qbo-helper.service.ts @@ -31,4 +31,8 @@ export class QboHelperService { refreshQBODimensions(): Observable<{}> { return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbo/refresh_dimensions/`, {}); } + + disconnect(): Observable<{}> { + return this.apiService.patch(`/workspaces/${this.workspaceService.getWorkspaceId()}/credentials/qbo/`, {}); + } } diff --git a/src/app/core/services/travelperk/travelperk.service.ts b/src/app/core/services/travelperk/travelperk.service.ts index e037c22fe..6a6de4c63 100644 --- a/src/app/core/services/travelperk/travelperk.service.ts +++ b/src/app/core/services/travelperk/travelperk.service.ts @@ -111,6 +111,8 @@ export class TravelperkService { } getCategories(): Observable { - return this.apiService.get(`/orgs/${this.orgId}/categories/`, {}); + return this.apiService.get(`/orgs/${this.orgId}/categories/`, { + attribute_type: 'CATEGORY' + }); } } diff --git a/src/app/integrations/intacct/intacct-shared/intacct-c1-import-settings/intacct-c1-import-settings.component.ts b/src/app/integrations/intacct/intacct-shared/intacct-c1-import-settings/intacct-c1-import-settings.component.ts index 781b0411e..1ff14a721 100644 --- a/src/app/integrations/intacct/intacct-shared/intacct-c1-import-settings/intacct-c1-import-settings.component.ts +++ b/src/app/integrations/intacct/intacct-shared/intacct-c1-import-settings/intacct-c1-import-settings.component.ts @@ -254,7 +254,9 @@ export class IntacctC1ImportSettingsComponent implements OnInit { })); this.sageIntacctFields.push({ attribute_type: 'GENERAL_LEDGER_ACCOUNT', display_name: 'General Ledger Account', source_placeholder: '', is_dependent: false }); + this.fyleFields.pop(); this.fyleFields.push({ attribute_type: FyleField.CATEGORY, display_name: 'Category', source_placeholder: '', is_dependent: false }); + this.fyleFields.push(this.customFieldOption[0]); // Handle only mapped fields this.sageIntacctFields.forEach((sageIntacctField) => { diff --git a/src/app/integrations/qbo/qbo-main/qbo-main.component.html b/src/app/integrations/qbo/qbo-main/qbo-main.component.html index 21873f6e4..609fe4de0 100644 --- a/src/app/integrations/qbo/qbo-main/qbo-main.component.html +++ b/src/app/integrations/qbo/qbo-main/qbo-main.component.html @@ -1,5 +1,5 @@
- +
diff --git a/src/app/integrations/qbo/qbo-main/qbo-main.component.ts b/src/app/integrations/qbo/qbo-main/qbo-main.component.ts index a46b45a86..0e19dbcc1 100644 --- a/src/app/integrations/qbo/qbo-main/qbo-main.component.ts +++ b/src/app/integrations/qbo/qbo-main/qbo-main.component.ts @@ -27,20 +27,35 @@ export class QboMainComponent implements OnInit { activeModule: MenuItem; + isConnectionInProgress: boolean; + readonly brandingFeatureConfig = brandingFeatureConfig; + readonly disconnectButton = brandingFeatureConfig.featureFlags.dashboard.disconnectButton; + constructor( private accountingExportService: AccountingExportService, private qboHelperService: QboHelperService, private router: Router, - private toastServeice: IntegrationsToastService + private toastService: IntegrationsToastService ) { } refreshDimensions() { this.qboHelperService.refreshQBODimensions().subscribe(); this.qboHelperService.refreshFyleDimensions().subscribe(); this.accountingExportService.importExpensesFromFyle('v1').subscribe(); - this.toastServeice.displayToastMessage(ToastSeverity.SUCCESS, 'Syncing data dimensions from QuickBooks Online'); + this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'Syncing data dimensions from QuickBooks Online'); + } + + disconnect(): void { + if (!this.isConnectionInProgress) { + this.qboHelperService.disconnect().subscribe(() => { + this.isConnectionInProgress = false; + this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'Disconnected QuickBooks Online successfully'); + this.router.navigate(['/integrations/qbo/onboarding/landing']); + }); + } + this.isConnectionInProgress = true; } private setupPage() { diff --git a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-landing/qbo-onboarding-landing.component.html b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-landing/qbo-onboarding-landing.component.html index 4a9638d74..595de9f48 100644 --- a/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-landing/qbo-onboarding-landing.component.html +++ b/src/app/integrations/qbo/qbo-onboarding/qbo-onboarding-landing/qbo-onboarding-landing.component.html @@ -1,6 +1,6 @@
- +
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 index 7a8d589f5..4080f95d2 100644 --- 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 @@ -15,7 +15,7 @@
[isFieldMandatory]="true" [mandatoryErrorListName]="'bank account'" [subLabel]="brandingContent.corporateCard.cccExpenseBankAccountSubLabel" - [label]="'To which Bank Account should the ' + (exportSettingForm.value.creditCardExportType | snakeCaseToSpaceCase | titlecase) + ' be posted to?'" + [label]="brandingContent.corporateCard.cccExpenseBankAccountLabel" [destinationAttributes]="bankAccounts" [optionLabel]="'value'" [iconPath]="'list'" diff --git a/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.html b/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.html index 7a37a639a..4f97d5fe3 100644 --- a/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.html +++ b/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.html @@ -77,7 +77,16 @@

{{ error.error_title | snakeCaseToSpaceCase | titlecase }}

-

{{ error.error_detail }}

+
+

{{ error.error_detail }}. + + {{ helper.sentenseCaseConversion('Read More') }} + + + +

@@ -98,7 +107,17 @@

{{appName}} {{brandingContent.qboErrorDialogHeaderText}}

-

{{errorDetail}}

+

+

{{ errorDetail }}. + + {{ helper.sentenseCaseConversion('Read More') }} + + + +

+

diff --git a/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.ts b/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.ts index eac727fce..01a5bc214 100644 --- a/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.ts +++ b/src/app/shared/components/dashboard/dashboard-error-section/dashboard-error-section.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; import { Observable, filter, forkJoin } from 'rxjs'; -import { brandingConfig, brandingContent } from 'src/app/branding/branding-config'; +import { brandingConfig, brandingContent, brandingFeatureConfig } from 'src/app/branding/branding-config'; import { DestinationFieldMap } from 'src/app/core/models/db/dashboard.model'; import { DestinationAttribute, GroupedDestinationAttribute } from 'src/app/core/models/db/destination-attribute.model'; import { Error, AccountingGroupedErrors, AccountingGroupedErrorStat, ErrorModel, ErrorResponse } from 'src/app/core/models/db/error.model'; @@ -11,6 +11,8 @@ import { Expense } from 'src/app/core/models/intacct/db/expense.model'; import { DashboardService } from 'src/app/core/services/common/dashboard.service'; import { MappingService } from 'src/app/core/services/common/mapping.service'; import { TrackingService } from 'src/app/core/services/integration/tracking.service'; +import { WindowService } from 'src/app/core/services/common/window.service'; +import { HelperService } from 'src/app/core/services/common/helper.service'; @Component({ selector: 'app-dashboard-error-section', @@ -83,14 +85,22 @@ export class DashboardErrorSectionComponent implements OnInit { readonly brandingContentCommon = brandingContent.common; + readonly brandingFeatureConfig = brandingFeatureConfig; + employeeFieldMapping: FyleField; displayName: string | undefined = undefined; + AppName = AppName; + + errorArticle: string; + constructor( private dashboardService: DashboardService, private mappingService: MappingService, - private trackingService: TrackingService + private trackingService: TrackingService, + public helper: HelperService, + public windowService: WindowService ) { } getSourceType() { @@ -157,6 +167,7 @@ export class DashboardErrorSectionComponent implements OnInit { showErrorDialog(accountingError: Error) { this.isAccountingErrorDialogVisible = true; this.errorDetail = accountingError.error_detail; + this.errorArticle = accountingError.article_link; // @ts-ignore this.errorExpenses = accountingError[this.exportKey]?.expenses; } diff --git a/src/assets/logos/qbo.png b/src/assets/logos/qbo.png new file mode 100644 index 000000000..8a8d00add Binary files /dev/null and b/src/assets/logos/qbo.png differ diff --git a/src/assets/logos/qbo.svg b/src/assets/logos/qbo.svg deleted file mode 100644 index a7885ef7f..000000000 --- a/src/assets/logos/qbo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/stories/AppLandingPageHeader.stories.ts b/src/stories/AppLandingPageHeader.stories.ts index b0e372e7a..d53c03f41 100644 --- a/src/stories/AppLandingPageHeader.stories.ts +++ b/src/stories/AppLandingPageHeader.stories.ts @@ -32,7 +32,7 @@ type Story = StoryObj; export const qbo: Story = { args: { appName: AppName.QBO, - iconPath: 'assets/logos/qbo.svg', + iconPath: 'assets/logos/qbo.png', appDescription: 'Import data from QuickBooks Online to ' + brandingConfig.brandName + ' and Export expenses from ' + brandingConfig.brandName + ' to QuickBooks Online. ', isLoading: false, isIntegrationSetupInProgress: false, diff --git a/src/stories/DashboardErrorSection.stories.ts b/src/stories/DashboardErrorSection.stories.ts index f6fd12a59..8de734e72 100644 --- a/src/stories/DashboardErrorSection.stories.ts +++ b/src/stories/DashboardErrorSection.stories.ts @@ -145,7 +145,7 @@ export const simple: Story = { type: AccountingErrorType.ACCOUNTING_ERROR, is_resolved: false, error_title: 'Invalid account code for expense', - error_detail: 'Account code 223 doesn\'t exist in Quickbooks Online', + error_detail: 'Account code 223 doesn\'t exist in QuickBooks Online', created_at: new Date(), updated_at: new Date(), workspace: 1