From 56db59130c0a60396a6836298860edc6a90709e5 Mon Sep 17 00:00:00 2001 From: Viswas Haridas <37623357+JustARatherRidiculouslyLongUsername@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:55:21 +0530 Subject: [PATCH] fix: add a default bank account field for CCC expenses (#1114) * fix: remove validation temporarily (#1111) * fix: add a default bank account field for CCC expenses * fix: add missing options to bank accounts on page init * fix: dynamic content for xero customize settings (#1112) * fix: update sublabel key to avoid build fail (#1116) * fix: Prod fixes of QBD direct (#1118) * fix bugs (#1119) * refactor: capitalization * fix: only ccc exports not being saved (#1121) --------- Co-authored-by: Ashwin Thanaraj <37061471+ashwin1111@users.noreply.github.com> Co-authored-by: Nilesh Pant <58652823+NileshPant1999@users.noreply.github.com> Co-authored-by: Dhaarani <55541808+DhaaraniCIT@users.noreply.github.com> Co-authored-by: Anish Kr Singh <116036738+anishfyle@users.noreply.github.com> --- .gitignore | 2 + deploy_dump.sh | 11 ++++ src/app/branding/c1-branding-config.ts | 2 - src/app/branding/c1-contents-config.ts | 5 +- src/app/branding/fyle-branding-config.ts | 12 ++-- src/app/branding/fyle-contents-config.ts | 1 + .../branding/content-configuration.model.ts | 3 + .../core/models/branding/kb-article.model.ts | 2 - .../business-central-export-setting.model.ts | 5 ++ .../models/common/advanced-settings.model.ts | 11 ++-- src/app/core/models/enum/enum.model.ts | 3 +- ...ess-central-export-settings.component.html | 12 ++-- ...iness-central-export-settings.component.ts | 57 ++++++++++++------- .../business-central.fixture.ts | 2 + .../intacct-advanced-settings.component.ts | 3 +- .../qbd-direct-dashboard.component.ts | 3 +- .../qbd-direct-base-mapping.component.ts | 3 +- ...d-direct-onboarding-connector.component.ts | 18 +++--- ...bd-direct-advanced-settings.component.html | 10 +++- .../qbd-direct-advanced-settings.component.ts | 15 ++++- .../xero-advanced-settings.component.html | 6 +- .../configuration-select-field.component.html | 4 +- 22 files changed, 124 insertions(+), 66 deletions(-) create mode 100644 deploy_dump.sh diff --git a/.gitignore b/.gitignore index 56824e890..59c3652fb 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,5 @@ documentation.json # Sentry Config File .sentryclirc + +commits.csv diff --git a/deploy_dump.sh b/deploy_dump.sh new file mode 100644 index 000000000..784149a5a --- /dev/null +++ b/deploy_dump.sh @@ -0,0 +1,11 @@ +if [ -z "$1" ]; then + echo "Usage: sh $0 '2024-12-09'" + exit 1 +fi + +base_url="https://github.com/fylein/fyle-integrations-app/commit" +branch_name=$(git rev-parse --abbrev-ref HEAD) + +git log --since="$1" --pretty=format:"$base_url/%H,%an,%ad,%s,$branch_name,integrations-app" > commits.csv + +open commits.csv diff --git a/src/app/branding/c1-branding-config.ts b/src/app/branding/c1-branding-config.ts index 86ac71d3a..9b14d4e90 100644 --- a/src/app/branding/c1-branding-config.ts +++ b/src/app/branding/c1-branding-config.ts @@ -128,9 +128,7 @@ export const c1KbArticles: KbArticle[string] = { IMPORT_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/9082146-configure-the-capital-one-sage-intacct-integration#h_78e1747002`, EXPORT_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/9082146-configure-the-capital-one-sage-intacct-integration#h_eebe5df4b7`, ADVANCED_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/9082146-configure-the-capital-one-sage-intacct-integration#h_498f2acc61`, - LANDING: `${brandingConfig.helpArticleDomain}/en/articles/9082146-configure-the-capital-one-sage-intacct-integration`, CONNECTOR: `${brandingConfig.helpArticleDomain}/en/articles/9081356-generate-credentials-to-connect-with-sage-intacct`, - SKIP_EXPORT: `${brandingConfig.helpArticleDomain}/en/articles/9082146-configure-the-capital-one-sage-intacct-integration`, HELPER_ARTICLE: `${brandingConfig.helpArticleDomain}/en/articles/7882821-how-to-skip-exporting-specific-expenses-from-fyle-to-sage-intacct` } } diff --git a/src/app/branding/c1-contents-config.ts b/src/app/branding/c1-contents-config.ts index a9d9ddb30..b24efc370 100644 --- a/src/app/branding/c1-contents-config.ts +++ b/src/app/branding/c1-contents-config.ts @@ -254,7 +254,10 @@ export const c1Contents = { 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.', autoCreateVendorsSubLabel: 'Automatically create a new contact in Xero if an added merchant doesn\'t have a corresponding match.', customPreferencesLabel: 'Other preferences', - customPreferencesSubLabel: 'Create new records in Xero if no contacts found or the accounting period is closed.' + customPreferencesSubLabel: 'Create new records in Xero if no contacts found or the accounting period is closed.', + memoStructureLabel: 'Set the line-item description field in Xero', + memoStructureSubLabel: 'Choose from a list of available data points that you\'d like to export to the description field in Xero.', + customizeSectionSubLabel: 'Customize the data that you\'d like to export from Expense Management to Xero by choosing which data points need to be exported.' } } }, diff --git a/src/app/branding/fyle-branding-config.ts b/src/app/branding/fyle-branding-config.ts index c65ddfde4..609ce70d1 100644 --- a/src/app/branding/fyle-branding-config.ts +++ b/src/app/branding/fyle-branding-config.ts @@ -67,7 +67,7 @@ export const fyleKbArticles: KbArticle[string] = { SAGE300: `${brandingConfig.helpArticleDomain}/en/articles/8948413-how-to-set-up-the-fyle-sage-300-cre-integration`, BUSINESS_CENTRAL: `${brandingConfig.helpArticleDomain}/en/articles/8911018-how-to-configure-the-fyle-dynamics-365-business-central-integration`, XERO: `${brandingConfig.helpArticleDomain}/en/articles/6721333-how-to-set-up-the-fyle-xero-integration`, - QBD_DIRECT: `${brandingConfig.helpArticleDomain}/en/collections/215867-integrations-with-fyle#quickbooks-desktop` + QBD_DIRECT: `${brandingConfig.helpArticleDomain}/en/articles/10259583-quickbooks-desktop-integration-beta` }, onboardingArticles: { INTACCT: { @@ -126,12 +126,10 @@ export const fyleKbArticles: KbArticle[string] = { ADVANCED_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/6721333-how-to-set-up-the-fyle-xero-integration#h_d95b791edd` }, QBD_DIRECT: { - IMPORT_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/8394683-how-to-configure-the-fyle-sage-intacct-integration#h_85f929716c`, - EXPORT_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/8394683-how-to-configure-the-fyle-sage-intacct-integration#h_6492c5038d`, - ADVANCED_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/8394683-how-to-configure-the-fyle-sage-intacct-integration#h_3f6718633c`, - LANDING: `${brandingConfig.helpArticleDomain}/en/articles/8394683-how-to-configure-the-fyle-sage-intacct-integration`, - CONNECTOR: `${brandingConfig.helpArticleDomain}/en/articles/8394683-how-to-configure-the-fyle-sage-intacct-integration#h_38e0c9bea6`, - SKIP_EXPORT: `${brandingConfig.helpArticleDomain}/en/articles/7882821-how-to-skip-exporting-specific-expenses-from-fyle-to-sage-intacct`, + IMPORT_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/10259583-quickbooks-desktop-integration-beta#h_a170c7d562`, + EXPORT_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/10259583-quickbooks-desktop-integration-beta#h_1366df4107`, + ADVANCED_SETTING: `${brandingConfig.helpArticleDomain}/en/articles/10259583-quickbooks-desktop-integration-beta#h_b3850646c0`, + CONNECTOR: `${brandingConfig.helpArticleDomain}/en/articles/10259583-quickbooks-desktop-integration-beta#h_d3cc42849a`, HELPER_ARTICLE: `${brandingConfig.helpArticleDomain}/en/articles/7882821-how-to-skip-exporting-specific-expenses-from-fyle-to-sage-intacct` } } diff --git a/src/app/branding/fyle-contents-config.ts b/src/app/branding/fyle-contents-config.ts index 53b3f8f46..16d1977ca 100644 --- a/src/app/branding/fyle-contents-config.ts +++ b/src/app/branding/fyle-contents-config.ts @@ -250,6 +250,7 @@ export const fyleContents = { topLevelMemoStructureSubLabel: 'Select the datapoints you\'d like to export to Xero’s top-level memo field when exporting expenses from Fyle.', memoStructureLabel: 'Customize the Line-Item Level Memo Field', memoStructureSubLabel: 'Select the datapoints you\'d like to export to Xero\’s line-item level memo field when exporting expenses from Fyle.', + customizeSectionSubLabel: 'In this section, you can customize the data that you\'d like to export from ' + brandingConfig.brandName + ' to Xero. You can choose what data points need to be exported and what shouldn\'t be.', frequencySubLabel: 'Set a frequency based on how often you want your expenses in Fyle to be exported to Xero.', customPreferencesLabel: 'Other Preferences', customPreferencesSubLabel: 'Based on your preference, you can choose whether you want to create any new records in Xero from ' + brandingConfig.brandName + '. (when there is no employee record found, or when the accounting period is closed)', diff --git a/src/app/core/models/branding/content-configuration.model.ts b/src/app/core/models/branding/content-configuration.model.ts index 88af007c8..0d109e4bf 100644 --- a/src/app/core/models/branding/content-configuration.model.ts +++ b/src/app/core/models/branding/content-configuration.model.ts @@ -248,6 +248,9 @@ export type ContentConfiguration = { scheduleSubLabel: string; accountingPeriodSubLabel: string; autoCreateVendorsSubLabel: string; + memoStructureLabel: string; + memoStructureSubLabel: string; + customizeSectionSubLabel: string; frequencySubLabel: string; } }, diff --git a/src/app/core/models/branding/kb-article.model.ts b/src/app/core/models/branding/kb-article.model.ts index 4d5f0f8a4..d7c1c2418 100644 --- a/src/app/core/models/branding/kb-article.model.ts +++ b/src/app/core/models/branding/kb-article.model.ts @@ -17,9 +17,7 @@ export type KbArticle = { IMPORT_SETTING: string; EXPORT_SETTING: string; ADVANCED_SETTING: string; - LANDING: string; CONNECTOR: string; - SKIP_EXPORT: string; HELPER_ARTICLE: string; }, INTACCT: { diff --git a/src/app/core/models/business-central/business-central-configuration/business-central-export-setting.model.ts b/src/app/core/models/business-central/business-central-configuration/business-central-export-setting.model.ts index 6fca3f7e9..d809fe8f8 100644 --- a/src/app/core/models/business-central/business-central-configuration/business-central-export-setting.model.ts +++ b/src/app/core/models/business-central/business-central-configuration/business-central-export-setting.model.ts @@ -15,6 +15,8 @@ export type BusinessCentralExportSetting = { credit_card_expense_date: ExportDateType, default_bank_account_name: string, default_bank_account_id: string, + default_ccc_bank_account_name: string, + default_ccc_bank_account_id: string, name_in_journal_entry: string, employee_field_mapping: string, auto_map_employees: string, @@ -184,6 +186,7 @@ export class BusinessCentralExportSettingModel { cccExportDate: new FormControl(exportSettings?.credit_card_expense_date ? exportSettings?.credit_card_expense_date.toLowerCase() : null), cccExportGroup: new FormControl(exportSettings?.credit_card_expense_grouped_by ? exportSettings?.credit_card_expense_grouped_by: null), defaultBankName: new FormControl(exportSettings?.default_bank_account_name ? findObjectByDestinationId(accounts, exportSettings?.default_bank_account_id) : null), + cccDefaultBankName: new FormControl(exportSettings?.default_ccc_bank_account_name ? findObjectByDestinationId(accounts, exportSettings?.default_ccc_bank_account_id) : null), reimbursableEmployeeMapping: new FormControl(exportSettings?.employee_field_mapping ? exportSettings?.employee_field_mapping : null, Validators.required), journalEntryNamePreference: new FormControl(exportSettings?.name_in_journal_entry ? exportSettings?.name_in_journal_entry : null), autoMapEmployee: new FormControl(exportSettings?.auto_map_employees ? exportSettings?.auto_map_employees : null), @@ -204,6 +207,8 @@ export class BusinessCentralExportSettingModel { credit_card_expense_date: exportSettingsForm.get('cccExportDate')?.value ? exportSettingsForm.get('cccExportDate')?.value.toUpperCase() : null, default_bank_account_name: exportSettingsForm.get('defaultBankName')?.value ? exportSettingsForm.get('defaultBankName')?.value.value : null, default_bank_account_id: exportSettingsForm.get('defaultBankName')?.value ? exportSettingsForm.get('defaultBankName')?.value.destination_id : null, + default_ccc_bank_account_name: exportSettingsForm.get('cccDefaultBankName')?.value ? exportSettingsForm.get('cccDefaultBankName')?.value.value : null, + default_ccc_bank_account_id: exportSettingsForm.get('cccDefaultBankName')?.value ? exportSettingsForm.get('cccDefaultBankName')?.value.destination_id : null, name_in_journal_entry: exportSettingsForm.get('journalEntryNamePreference')?.value ? exportSettingsForm.get('journalEntryNamePreference')?.value : null, employee_field_mapping: exportSettingsForm.get('reimbursableEmployeeMapping')?.value ? exportSettingsForm.get('reimbursableEmployeeMapping')?.value : null, auto_map_employees: exportSettingsForm.get('autoMapEmployee')?.value ? exportSettingsForm.get('autoMapEmployee')?.value : null, diff --git a/src/app/core/models/common/advanced-settings.model.ts b/src/app/core/models/common/advanced-settings.model.ts index 2fc4a360d..735a4d3f1 100644 --- a/src/app/core/models/common/advanced-settings.model.ts +++ b/src/app/core/models/common/advanced-settings.model.ts @@ -1,9 +1,10 @@ import { FormControl, FormGroup } from "@angular/forms"; -import { JoinOption, Operator } from "../enum/enum.model"; +import { AppName, JoinOption, Operator } from "../enum/enum.model"; import { environment } from "src/environments/environment"; import { ExportSettingGet } from "../intacct/intacct-configuration/export-settings.model"; import { QBOExportSettingGet } from "../qbo/qbo-configuration/qbo-export-setting.model"; import { NetSuiteExportSettingGet } from "../netsuite/netsuite-configuration/netsuite-export-setting.model"; +import { IntacctConfiguration } from "../db/configuration.model"; export type EmailOption = { email: string; @@ -75,17 +76,19 @@ export class AdvancedSettingsModel { return ['employee_email', 'employee_name', 'merchant', 'purpose', 'category', 'spent_on', 'report_number', 'expense_link', 'card_number']; } - static getMemoOptions(exportSettings: ExportSettingGet | NetSuiteExportSettingGet | QBOExportSettingGet, appName: string): string[] { + static getMemoOptions(exportSettings: IntacctConfiguration | ExportSettingGet | NetSuiteExportSettingGet | QBOExportSettingGet, appName: string): string[] { const defaultOptions = this.getDefaultMemoOptions(); let cccExportType: string | undefined; // Handle both configurations and configuration properties - if ('configurations' in exportSettings) { + if (appName === AppName.INTACCT) { + cccExportType = (exportSettings as IntacctConfiguration).corporate_credit_card_expenses_object ?? undefined; + } else if ('configurations' in exportSettings) { cccExportType = exportSettings.configurations?.corporate_credit_card_expenses_object ?? undefined; } else if ('workspace_general_settings' in exportSettings) { cccExportType = exportSettings.workspace_general_settings?.corporate_credit_card_expenses_object ?? undefined; } // Filter out options based on cccExportType and appName - if (cccExportType && ['netsuite', 'qbo', 'sage intacct'].includes(appName.toLowerCase())) { + if (cccExportType && ['netsuite', 'quickbooks online', 'sage intacct'].includes(appName.toLowerCase())) { return defaultOptions; // Allow all options including 'card_number' } return defaultOptions.filter(option => option !== 'card_number'); // Omit 'card_number' for other apps diff --git a/src/app/core/models/enum/enum.model.ts b/src/app/core/models/enum/enum.model.ts index 861f6cf26..5104c7f28 100644 --- a/src/app/core/models/enum/enum.model.ts +++ b/src/app/core/models/enum/enum.model.ts @@ -702,9 +702,8 @@ export enum Sage300ExportSettingDestinationOptionKey { } export enum BCExportSettingDestinationOptionKey { - ACCOUNT = 'ACCOUNT', VENDOR = 'VENDOR', - REIMBURSABLE_BANK_ACCOUNT = 'REIMBURSABLE_BANK_ACCOUNT' + BANK_ACCOUNT = 'BANK_ACCOUNT' } export enum QbdDirectExportSettingDestinationOptionKey { diff --git a/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.html b/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.html index 9c7df077d..214b445e3 100644 --- a/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.html +++ b/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.html @@ -91,8 +91,8 @@ [mandatoryErrorListName]="'Default Bank Account Name'" [label]="'Set the Default Bank Account as?'" [subLabel]="'The integration will assign the Expenses that is exported as Journal Entry to the Bank Account selected here.'" - [destinationAttributes]="reimbursableBankOptions" - [destinationOptionKey]="BCExportSettingDestinationOptionKey.REIMBURSABLE_BANK_ACCOUNT" + [destinationAttributes]="bankAccountOptions" + [destinationOptionKey]="BCExportSettingDestinationOptionKey.BANK_ACCOUNT" [isOptionSearchInProgress]="isOptionSearchInProgress" [isAdvanceSearchEnabled]="true" (searchOptionsDropdown)="searchOptionsDropdown($event)" @@ -173,21 +173,21 @@ [exportTypeIconPathArray]="previewImagePaths"> -
+
+ [formControllerName]="'cccDefaultBankName'">
diff --git a/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.ts b/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.ts index ca0c41bc6..87c43b1a0 100644 --- a/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.ts +++ b/src/app/integrations/business-central/business-central-shared/business-central-export-settings/business-central-export-settings.component.ts @@ -29,9 +29,7 @@ export class BusinessCentralExportSettingsComponent implements OnInit { exportSettingForm: FormGroup; - bankOptions: DestinationAttribute[]; - - reimbursableBankOptions: DestinationAttribute[]; + bankAccountOptions: DestinationAttribute[]; vendorOptions: DestinationAttribute[]; @@ -189,7 +187,7 @@ export class BusinessCentralExportSettingsComponent implements OnInit { debounceTime(1000) ).subscribe((event: ExportSettingOptionSearch) => { - if (event.destinationOptionKey === BCExportSettingDestinationOptionKey.REIMBURSABLE_BANK_ACCOUNT) { + if (event.destinationOptionKey === BCExportSettingDestinationOptionKey.BANK_ACCOUNT) { const observables = [ this.mappingService.getPaginatedDestinationAttributes('BANK_ACCOUNT', event.searchTerm), this.mappingService.getPaginatedDestinationAttributes( @@ -201,12 +199,12 @@ export class BusinessCentralExportSettingsComponent implements OnInit { // Insert new options (if any) to existing options, and sort them const newOptions = [...bankAccounts.results, ...accounts.results]; newOptions.forEach((newOption) => { - if (!this.reimbursableBankOptions.find((existingOption) => existingOption.destination_id === newOption.destination_id)) { - this.reimbursableBankOptions.push(newOption); + if (!this.bankAccountOptions.find((existingOption) => existingOption.destination_id === newOption.destination_id)) { + this.bankAccountOptions.push(newOption); } }); - this.reimbursableBankOptions.sort((a, b) => (a.value || '').localeCompare(b.value || '')); + this.bankAccountOptions.sort((a, b) => (a.value || '').localeCompare(b.value || '')); this.isOptionSearchInProgress = false; }); @@ -214,9 +212,6 @@ export class BusinessCentralExportSettingsComponent implements OnInit { let existingOptions: DestinationAttribute[]; switch (event.destinationOptionKey) { - case BCExportSettingDestinationOptionKey.ACCOUNT: - existingOptions = this.bankOptions; - break; case BCExportSettingDestinationOptionKey.VENDOR: existingOptions = this.vendorOptions; break; @@ -233,10 +228,6 @@ export class BusinessCentralExportSettingsComponent implements OnInit { switch (event.destinationOptionKey) { - case BCExportSettingDestinationOptionKey.ACCOUNT: - this.bankOptions = existingOptions.concat(); - this.bankOptions.sort((a, b) => (a.value || '').localeCompare(b.value || '')); - break; case BCExportSettingDestinationOptionKey.VENDOR: this.vendorOptions = existingOptions.concat(); this.vendorOptions.sort((a, b) => (a.value || '').localeCompare(b.value || '')); @@ -256,6 +247,29 @@ export class BusinessCentralExportSettingsComponent implements OnInit { } } + addMissingOptions() { + // Since pagination API response is a subset of all options, we're making use of the export settings response to fill in options + + if (this.exportSettings) { + this.helperService.addDestinationAttributeIfNotExists({ + options: this.bankAccountOptions, + value: this.exportSettings.default_ccc_bank_account_name, + destination_id: this.exportSettings.default_ccc_bank_account_id + }); + this.helperService.addDestinationAttributeIfNotExists({ + options: this.bankAccountOptions, + value: this.exportSettings.default_bank_account_name, + destination_id: this.exportSettings.default_bank_account_id + }); + + this.helperService.addDestinationAttributeIfNotExists({ + options: this.vendorOptions, + value: this.exportSettings.default_vendor_name, + destination_id: this.exportSettings.default_vendor_id + }); + } + } + private setupPage(): void { this.isOnboarding = this.router.url.includes('onboarding'); const exportSettingValidatorRule: ExportSettingValidatorRule = { @@ -273,11 +287,11 @@ export class BusinessCentralExportSettingsComponent implements OnInit { { 'formController': 'cccExportType', 'requiredValue': { - 'JOURNAL_ENTRY': ['defaultBankName', 'journalEntryNamePreference'] + 'JOURNAL_ENTRY': ['cccDefaultBankName', 'journalEntryNamePreference'] } } ]; - const commonFormFields: string[] = ['defaultBankName']; + const commonFormFields: string[] = []; const destinationAttributes = [BusinessCentralField.ACCOUNT, FyleField.VENDOR]; @@ -314,14 +328,15 @@ export class BusinessCentralExportSettingsComponent implements OnInit { }); } - this.exportSettingForm = BusinessCentralExportSettingModel.mapAPIResponseToFormGroup(this.exportSettings, accounts.results, vendors.results); + this.vendorOptions = vendors.results; + this.bankAccountOptions = [...reimbursableBankAccounts.results, ...reimbursableAccounts.results]; + this.bankAccountOptions.sort((a, b) => (a.value || '').localeCompare(b.value || '')); + this.addMissingOptions(); + this.exportSettingForm = BusinessCentralExportSettingModel.mapAPIResponseToFormGroup(this.exportSettings, this.bankAccountOptions, vendors.results); + this.helperService.addExportSettingFormValidator(this.exportSettingForm); this.helper.setConfigurationSettingValidatorsAndWatchers(exportSettingValidatorRule, this.exportSettingForm); this.helper.setExportTypeValidatorsAndWatchers(exportModuleRule, this.exportSettingForm, commonFormFields); - this.bankOptions = accounts.results; - this.vendorOptions = vendors.results; - this.reimbursableBankOptions = [...reimbursableBankAccounts.results, ...reimbursableAccounts.results]; - this.reimbursableBankOptions.sort((a, b) => (a.value || '').localeCompare(b.value || '')); this.setupCustomWatchers(); this.optionSearchWatcher(); diff --git a/src/app/integrations/business-central/business-central-shared/business-central.fixture.ts b/src/app/integrations/business-central/business-central-shared/business-central.fixture.ts index 8af0c393e..07c1a755d 100644 --- a/src/app/integrations/business-central/business-central-shared/business-central.fixture.ts +++ b/src/app/integrations/business-central/business-central-shared/business-central.fixture.ts @@ -12,6 +12,8 @@ export const exportSettingsResponse: BusinessCentralExportSettingGet = { "reimbursable_expenses_export_type": BusinessCentralExportType.JOURNAL_ENTRY, "default_bank_account_name": "XYZ", "default_bank_account_id": "1232", + "default_ccc_bank_account_name": "ABC", + "default_ccc_bank_account_id": "2321", "reimbursable_expense_state": ExpenseState.PAYMENT_PROCESSING, "reimbursable_expense_date": ExportDateType.LAST_SPENT_AT, "reimbursable_expense_grouped_by": ExpenseGroupedBy.EXPENSE, diff --git a/src/app/integrations/intacct/intacct-shared/intacct-advanced-settings/intacct-advanced-settings.component.ts b/src/app/integrations/intacct/intacct-shared/intacct-advanced-settings/intacct-advanced-settings.component.ts index 761b0691a..3377486ac 100644 --- a/src/app/integrations/intacct/intacct-shared/intacct-advanced-settings/intacct-advanced-settings.component.ts +++ b/src/app/integrations/intacct/intacct-shared/intacct-advanced-settings/intacct-advanced-settings.component.ts @@ -93,7 +93,7 @@ export class IntacctAdvancedSettingsComponent implements OnInit { private sessionStartTime = new Date(); - defaultMemoFields: string[] = ['employee_email', 'merchant', 'purpose', 'category', 'spent_on', 'report_number', 'expense_link']; + defaultMemoFields: string[] = AdvancedSettingsModel.getDefaultMemoOptions(); paymentSyncOptions: AdvancedSettingFormOption[] = [ { @@ -313,6 +313,7 @@ export class IntacctAdvancedSettingsComponent implements OnInit { if (this.advancedSettings.workspace_schedules?.additional_email_options) { this.adminEmails = this.adminEmails.concat(this.advancedSettings.workspace_schedules?.additional_email_options); } + this.defaultMemoFields = AdvancedSettingsModel.getMemoOptions(configuration, AppName.INTACCT); this.initializeAdvancedSettingsFormWithData(!!expenseFilter.count); this.initializeSkipExportForm(); this.isLoading = false; diff --git a/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-dashboard/qbd-direct-dashboard.component.ts b/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-dashboard/qbd-direct-dashboard.component.ts index 4847e4e1c..109b27b3b 100644 --- a/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-dashboard/qbd-direct-dashboard.component.ts +++ b/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-dashboard/qbd-direct-dashboard.component.ts @@ -9,6 +9,7 @@ import { DestinationFieldMap, DashboardModel } from 'src/app/core/models/db/dash import { AccountingGroupedErrors, AccountingGroupedErrorStat, Error, ErrorResponse } from 'src/app/core/models/db/error.model'; import { AppName, AccountingErrorType, QbdDirectTaskLogType, ReimbursableImportState, CCCImportState, AppUrl, TaskLogState } from 'src/app/core/models/enum/enum.model'; import { QbdDirectTaskResponse, QbdDirectTaskLog } from 'src/app/core/models/qbd-direct/db/qbd-direct-task-log.model'; +import { QbdDirectImportSettingModel } from 'src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-import-settings.model'; import { AccountingExportService } from 'src/app/core/services/common/accounting-export.service'; import { DashboardService } from 'src/app/core/services/common/dashboard.service'; import { WorkspaceService } from 'src/app/core/services/common/workspace.service'; @@ -151,7 +152,7 @@ export class QbdDirectDashboardComponent implements OnInit { this.importCodeFields = responses[5].import_settings?.import_code_fields; - this.chartOfAccounts = responses[5].import_settings.chart_of_accounts; + this.chartOfAccounts = responses[5].import_settings.import_account_as_category ? responses[5].import_settings.chart_of_accounts : QbdDirectImportSettingModel.getChartOfAccountTypesList(); const queuedTasks: QbdDirectTaskLog[] = responses[2].results.filter((task: QbdDirectTaskLog) => this.exportLogProcessingStates.includes(task.status)); this.failedExpenseGroupCount = responses[2].results.filter((task: QbdDirectTaskLog) => task.status === TaskLogState.ERROR || task.status === TaskLogState.FATAL).length; diff --git a/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-mapping/qbd-direct-base-mapping/qbd-direct-base-mapping.component.ts b/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-mapping/qbd-direct-base-mapping/qbd-direct-base-mapping.component.ts index 6e7266fc9..abfd042d8 100644 --- a/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-mapping/qbd-direct-base-mapping/qbd-direct-base-mapping.component.ts +++ b/src/app/integrations/qbd-direct/qbd-direct-main/qbd-direct-mapping/qbd-direct-base-mapping/qbd-direct-base-mapping.component.ts @@ -8,6 +8,7 @@ import { MappingSetting } from 'src/app/core/models/db/mapping-setting.model'; import { FyleField, AppName, AccountingField, QBDReimbursableExpensesObject, QBDCorporateCreditCardExpensesObject, NameInJournalEntry } from 'src/app/core/models/enum/enum.model'; import { QbdDirectDestinationAttribute } from 'src/app/core/models/qbd-direct/db/qbd-direct-destination-attribuite.model'; import { QbdDirectExportSettingGet } from 'src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-export-settings.model'; +import { QbdDirectImportSettingModel } from 'src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-import-settings.model'; import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service'; import { MappingService } from 'src/app/core/services/common/mapping.service'; import { WorkspaceService } from 'src/app/core/services/common/workspace.service'; @@ -106,7 +107,7 @@ export class QbdDirectBaseMappingComponent implements OnInit { this.cccExpenseObject = responses[0].credit_card_expense_export_type; this.employeeFieldMapping = (responses[0].employee_field_mapping as unknown as FyleField); this.nameInJE = responses[0].name_in_journal_entry; - this.chartOfAccounts = responses[1].import_settings.chart_of_accounts; + this.chartOfAccounts = responses[1].import_settings.import_account_as_category ? responses[1].import_settings.chart_of_accounts : QbdDirectImportSettingModel.getChartOfAccountTypesList(); this.destinationField = this.getDestinationField(responses[0], responses[2].results); diff --git a/src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts b/src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts index ed2533c6b..a1bb46e03 100644 --- a/src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts +++ b/src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts @@ -83,18 +83,18 @@ export class QbdDirectOnboardingConnectorComponent implements OnInit { ) { } triggerDownload(filePath: string) { - const normalizedPath = filePath.replace(/\\\\/g, "\\"); - const filePathRegex = /^(\/?|\.?\/?|[a-zA-Z]:\\)([a-zA-Z0-9_-]+[\\/])*[a-zA-Z0-9 _-]+\.qbw$/; - this.isCompanyPathInvalid = filePathRegex.test(normalizedPath); - if (this.isCompanyPathInvalid) { + if (filePath) { this.isDownloadfileLoading = true; - this.qbdDirectConnectorService.postQbdDirectConntion({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => { - this.password = connectionResponse.password; - this.xmlFileContent = connectionResponse.qwc; - this.triggerManualDownload(); - this.showDownloadLink = true; + this.isCompanyPathInvalid = false; + this.qbdDirectConnectorService.postQbdDirectConntion({file_location: filePath}).subscribe((connectionResponse: QbdConnectorGet) => { + this.password = connectionResponse.password; + this.xmlFileContent = connectionResponse.qwc; + this.triggerManualDownload(); + this.showDownloadLink = true; }); this.isDownloadfileLoading = false; + } else { + this.isCompanyPathInvalid = true; } } diff --git a/src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-advanced-settings/qbd-direct-advanced-settings.component.html b/src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-advanced-settings/qbd-direct-advanced-settings.component.html index 2240fea34..9d5c3cfd6 100644 --- a/src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-advanced-settings/qbd-direct-advanced-settings.component.html +++ b/src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-advanced-settings/qbd-direct-advanced-settings.component.html @@ -8,6 +8,7 @@ [contentText]="brandingContent.contentText" [showSyncButton]="isOnboarding" [appName]="appName.QBD_DIRECT" + [redirectLink]="redirectLink" (refreshDimension)="refreshDimensions()">
@@ -88,6 +89,12 @@ [placeholder]="'Select top memo type'" [formControllerName]="'topMemoStructure'"> +
+

{{brandingContent.previewDescriptionFieldLabel}}

+
+ {{ topMemoPreviewText }} +
+
+ [iconPath]="'list'">
{ + this.memoStructure = memoChanges; + this.topMemoPreviewText = QbdDirectAdvancedSettingsModel.formatMemoPreview(this.memoStructure, this.defaultTopMemoOptions)[0]; + }); + } + private scheduledWatcher() { if (this.advancedSettingsForm.controls.exportSchedule.value) { this.helper.markControllerAsRequired(this.advancedSettingsForm, 'exportScheduleFrequency'); @@ -216,6 +226,7 @@ export class QbdDirectAdvancedSettingsComponent implements OnInit { this.createMemoStructureWatcher(); this.scheduledWatcher(); this.skipExportWatcher(); + this.createTopMemoStructureWatcher(); } private getSettingsAndSetupForm(): void { 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 index 08c523c4f..20da247c9 100644 --- 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 @@ -103,7 +103,7 @@
+ [subLabel]="brandingContent.customizeSectionSubLabel">
@@ -111,8 +111,8 @@ [form]="advancedSettingForm" [isFieldMandatory]="false" [mandatoryErrorListName]="'Item level description'" - [label]="'Set the line item-level Description Field in Xero'" - [subLabel]="'You can choose from a list of available data points that you\'d like to export to the description field in Xero.'" + [label]="brandingContent.memoStructureLabel" + [subLabel]="brandingContent.memoStructureSubLabel" [options]="defaultMemoFields" [iconPath]="'list'" [placeholder]="'Set description'" diff --git a/src/app/shared/components/configuration/configuration-select-field/configuration-select-field.component.html b/src/app/shared/components/configuration/configuration-select-field/configuration-select-field.component.html index 91bbe25e6..236939c74 100644 --- a/src/app/shared/components/configuration/configuration-select-field/configuration-select-field.component.html +++ b/src/app/shared/components/configuration/configuration-select-field/configuration-select-field.component.html @@ -97,8 +97,8 @@
in {{uiExposedAppName}}
- Auto-selected based on your export module - Auto-selected when your default credit account is set to an Accounts Payable account + Auto-selected based on your export module + Auto-selected when your default credit account is set to an Accounts Payable account
Using the Spend Date may lead to multiple single line
item entries.