From 293360130e3afb68445490b4ed641e8d5c7d7842 Mon Sep 17 00:00:00 2001
From: Dhaarani <55541808+DhaaraniCIT@users.noreply.github.com>
Date: Thu, 12 Dec 2024 14:22:23 +0530
Subject: [PATCH 1/5] fix: Prod fixes of QBD direct (#1118)
---
commits.tsv | 11 -----------
src/app/branding/c1-branding-config.ts | 2 --
src/app/branding/fyle-branding-config.ts | 12 +++++-------
src/app/core/models/branding/kb-article.model.ts | 2 --
.../qbd-direct-dashboard.component.ts | 3 ++-
.../qbd-direct-base-mapping.component.ts | 3 ++-
.../qbd-direct-onboarding-connector.component.ts | 16 +++++++++-------
.../qbd-direct-advanced-settings.component.html | 10 ++++++++--
.../qbd-direct-advanced-settings.component.ts | 15 +++++++++++++--
.../configuration-select-field.component.html | 4 ++--
10 files changed, 41 insertions(+), 37 deletions(-)
delete mode 100644 commits.tsv
diff --git a/commits.tsv b/commits.tsv
deleted file mode 100644
index fc425f9f7..000000000
--- a/commits.tsv
+++ /dev/null
@@ -1,11 +0,0 @@
-64a9f70f7fa22b780786ec862d701b1ff2fc0ecd\tDhaarani\tWed Dec 11 12:43:59 2024 +0530\tfix: dashboard error section fixes (#1107)\tintegrations_app_release_2024_12_06\tintegrations-app
-1a8fa49bd5b12eba678d70ceb5c7374fe3c35265\tAshwin Thanaraj\tWed Dec 11 11:48:28 2024 +0530\tfix: QBD fixes post testing (#1108)\tintegrations_app_release_2024_12_06\tintegrations-app
-b8e33e07bc65da9ee932d798b6ac21f0f67cec87\tDhaarani\tTue Dec 10 19:13:59 2024 +0530\tfix: QBD direct bug fixes (#1101)\tintegrations_app_release_2024_12_06\tintegrations-app
-4f73b406909e5713c4f79869da1b92af7b506a48\tAshwin Thanaraj\tTue Dec 10 19:05:59 2024 +0530\tfix: QBD app name references (#1106)\tintegrations_app_release_2024_12_06\tintegrations-app
-5e0d388d65064b145c368af59ac48e6e05b8fa03\tAshwin Thanaraj\tTue Dec 10 18:12:49 2024 +0530\tfix: QBD landing page (#1104)\tintegrations_app_release_2024_12_06\tintegrations-app
-0f88a7afc21f8e41557e97e76ebaf4e4fd8fcb6f\tAshwin Thanaraj\tTue Dec 10 15:14:27 2024 +0530\tfeat: Expose QBD connector app conditionally (#1100)\tintegrations_app_release_2024_12_06\tintegrations-app
-357a9866ab91d686f6162751ae62f6cb0d76cafe\tAshwin Thanaraj\tTue Dec 10 17:29:08 2024 +0530\tfix: QBD Dashboard bugs (#1103)\tintegrations_app_release_2024_12_06\tintegrations-app
-579ccd5469cffde6087481933ceefee1f41a3ee8\tViswas Haridas\tTue Dec 10 15:29:54 2024 +0530\tfix: update orgs to hide business central beta badge from (#1102)\tintegrations_app_release_2024_12_06\tintegrations-app
-77ed17b9902815ad16f35f4b41c43778b1b9e870\tDhaarani\tTue Dec 10 13:47:11 2024 +0530\tfix: qbd direct team testing fixes (#1095)\tintegrations_app_release_2024_12_06\tintegrations-app
-a11820f42d3538868891642368ba9baa2c54fd2a\tDhaarani\tTue Dec 10 13:43:04 2024 +0530\tfix: C1 xero bug fix (#1097)\tintegrations_app_release_2024_12_06\tintegrations-app
-a32b5f73853bb25cd3ef926adb7b6cbcc5a9fb60\tHrishabh Tiwari\tTue Dec 10 13:28:34 2024 +0530\tRevert "feat: memo structure in xero app (#1094)"\tintegrations_app_release_2024_12_06\tintegrations-app
\ No newline at end of file
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/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/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/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 0c1cfbb48..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,17 +83,19 @@ 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);
- this.isDownloadfileLoading = true;
- this.qbdDirectConnectorService.postQbdDirectConntion({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {
+ if (filePath) {
+ this.isDownloadfileLoading = 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;
+ });
+ this.isDownloadfileLoading = false;
+ } else {
+ this.isCompanyPathInvalid = true;
+ }
}
triggerManualDownload() {
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/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.
From ae2b2a3c1c431fdbc1f80e23980ea0188a6cb286 Mon Sep 17 00:00:00 2001
From: Anish Kr Singh <116036738+anishfyle@users.noreply.github.com>
Date: Thu, 12 Dec 2024 14:34:08 +0530
Subject: [PATCH 2/5] fix bugs (#1119)
---
src/app/core/models/common/advanced-settings.model.ts | 11 +++++++----
.../intacct-advanced-settings.component.ts | 3 ++-
2 files changed, 9 insertions(+), 5 deletions(-)
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/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;
From d1d596ea91f48bad157fddfb29b0ba3eea0e7512 Mon Sep 17 00:00:00 2001
From: Ashwin Thanaraj <37061471+ashwin1111@users.noreply.github.com>
Date: Thu, 12 Dec 2024 16:49:24 +0530
Subject: [PATCH 3/5] feat: Expose split grouping option for xero c1 (#1120)
---
.../xero-export-settings/xero-export-settings.component.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
index 25f2a4943..b6fb9d100 100644
--- 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
@@ -191,7 +191,7 @@
-
+
Date: Thu, 12 Dec 2024 17:07:19 +0530
Subject: [PATCH 4/5] fix: business central beta bugfixes (#1122)
* fix: initialize chart of accounts multiselect when there is no api response (#1110)
* fix: remove the posted at date option for ccc expenses grouped by report (#1105)
* fix: update login error flow and fix redirect url (#1117)
* fix: restrict JE modules to group by expense only (#1113)
* fix: restrict JE modules to group by expense only
* 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>
---------
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>
---------
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>
---
.../business-central-export-setting.model.ts | 5 ++
.../business-central-import-settings.model.ts | 2 +-
src/app/core/models/enum/enum.model.ts | 3 +-
...-central-onboarding-landing.component.html | 6 +-
...ss-central-onboarding-landing.component.ts | 8 +-
...ess-central-export-settings.component.html | 18 +++--
...iness-central-export-settings.component.ts | 78 +++++++++++++------
.../business-central.fixture.ts | 2 +
8 files changed, 82 insertions(+), 40 deletions(-)
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/business-central/business-central-configuration/business-central-import-settings.model.ts b/src/app/core/models/business-central/business-central-configuration/business-central-import-settings.model.ts
index 4a149bc2c..cc92f71c7 100644
--- a/src/app/core/models/business-central/business-central-configuration/business-central-import-settings.model.ts
+++ b/src/app/core/models/business-central/business-central-configuration/business-central-import-settings.model.ts
@@ -26,7 +26,7 @@ export class BusinessCentralImportSettingsModel extends ImportSettingsModel {
const expenseFieldsArray = importSettings?.mapping_settings ? this.constructFormArray(importSettings.mapping_settings, businessCentralFields) : [] ;
return new FormGroup({
importCategories: new FormControl(importSettings?.import_settings?.import_categories ?? false),
- chartOfAccountTypes: new FormControl(importSettings?.import_settings.charts_of_accounts ? importSettings?.import_settings.charts_of_accounts : ['Expense']),
+ chartOfAccountTypes: new FormControl(importSettings?.import_settings?.charts_of_accounts ? importSettings?.import_settings?.charts_of_accounts : ['Expense']),
importVendorAsMerchant: new FormControl(importSettings?.import_settings?.import_vendors_as_merchants ?? false ),
expenseFields: new FormArray(expenseFieldsArray)
});
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-onboarding/business-central-onboarding-landing/business-central-onboarding-landing.component.html b/src/app/integrations/business-central/business-central-onboarding/business-central-onboarding-landing/business-central-onboarding-landing.component.html
index a8428cf09..264ebdc7a 100644
--- a/src/app/integrations/business-central/business-central-onboarding/business-central-onboarding-landing/business-central-onboarding-landing.component.html
+++ b/src/app/integrations/business-central/business-central-onboarding/business-central-onboarding-landing/business-central-onboarding-landing.component.html
@@ -1,4 +1,4 @@
-
- {
const errorMessage = 'message' in error.error ? error.error.message : 'Failed to connect to Dynamic 365 Business Central. Please try again';
if (errorMessage === 'Please choose the correct Dynamic 365 Business Central account') {
- this.isIncorrectQBOConnectedDialogVisible = false;
+ this.isIncorrectBCConnectedDialogVisible = true;
} else {
this.toastService.displayToastMessage(ToastSeverity.ERROR, errorMessage);
this.router.navigate([`/integrations/business_central/onboarding/landing`]);
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 d4ec92e13..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)"
@@ -113,7 +113,8 @@
[iconPath]="'question-square-outline'"
[placeholder]="'Select expense grouping'"
[formControllerName]="'reimbursableExportGroup'"
- [appName]="appName">
+ [appName]="appName"
+ [isDisabled]="exportSettingForm.get('reimbursableExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY">
@@ -172,21 +173,21 @@
[exportTypeIconPathArray]="previewImagePaths">
-
+
+ [formControllerName]="'cccDefaultBankName'">
@@ -217,7 +218,8 @@
[iconPath]="'question-square-outline'"
[placeholder]="'Select expense grouping'"
[formControllerName]="'cccExportGroup'"
- [appName]="appName">
+ [appName]="appName"
+ [isDisabled]="exportSettingForm.get('cccExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY">
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 438b0cac2..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[];
@@ -142,13 +140,23 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
if (this.exportSettingForm.controls[formControllerName].value === ExpenseGroupedBy.EXPENSE) {
return options.filter(option => option.value !== ExportDateType.LAST_SPENT_AT);
}
- return options.filter(option => option.value !== ExportDateType.SPENT_AT);
+ return options.filter(option => (option.value !== ExportDateType.SPENT_AT && option.value !== ExportDateType.POSTED_AT));
}
refreshDimensions(isRefresh: boolean): void{
this.businessCentralHelperService.importAttributes(isRefresh);
}
+ updateExpenseGroupingValues() {
+ if (this.exportSettingForm.get('cccExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY) {
+ this.exportSettingForm.get('cccExportGroup')?.setValue(ExpenseGroupedBy.EXPENSE);
+ }
+
+ if (this.exportSettingForm.get('reimbursableExportType')?.value === BusinessCentralExportType.JOURNAL_ENTRY) {
+ this.exportSettingForm.get('reimbursableExportGroup')?.setValue(ExpenseGroupedBy.EXPENSE);
+ }
+ }
+
private setupCustomWatchers(): void {
this.exportSettingForm.controls.reimbursableExportGroup.valueChanges.subscribe((reimbursableExportGroup) => {
if (brandingConfig.brandId==='fyle') {
@@ -161,8 +169,17 @@ export class BusinessCentralExportSettingsComponent implements OnInit {
if (brandingConfig.brandId==='fyle') {
this.cccExpenseGroupingDateOptions = BusinessCentralExportSettingModel.getCCCExpenseGroupingDateOptions();
this.cccExpenseGroupingDateOptions = ExportSettingModel.constructGroupingDateOptions(cccExportGroup, this.cccExpenseGroupingDateOptions);
+
+ // If the selected value is not valid after the export group change, reset the field
+ const visibleValues = this.getExportDate(this.cccExpenseGroupingDateOptions, 'cccExportGroup').map(option => option.value);
+ if (!visibleValues.includes(this.exportSettingForm.get('cccExportDate')?.value)) {
+ this.exportSettingForm.get('cccExportDate')?.reset();
+ }
}
});
+
+ this.exportSettingForm.get('reimbursableExportType')?.valueChanges.subscribe(() => this.updateExpenseGroupingValues());
+ this.exportSettingForm.get('cccExportType')?.valueChanges.subscribe(() => this.updateExpenseGroupingValues());
}
private optionSearchWatcher(): void {
@@ -170,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(
@@ -182,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;
});
@@ -195,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;
@@ -214,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 || ''));
@@ -237,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 = {
@@ -254,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];
@@ -295,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,
From 204c5f799b53cc04984d23b0d7a8f879f150655c Mon Sep 17 00:00:00 2001
From: Anish Kr Singh <116036738+anishfyle@users.noreply.github.com>
Date: Fri, 13 Dec 2024 12:16:08 +0530
Subject: [PATCH 5/5] fix: hide card number and employee name as options for
memo field (#1123)
* fix: hide card number and employee name as options for memo field
* updated conditions
* fix lint
---
.../core/models/common/advanced-settings.model.ts | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/app/core/models/common/advanced-settings.model.ts b/src/app/core/models/common/advanced-settings.model.ts
index 735a4d3f1..0c178709b 100644
--- a/src/app/core/models/common/advanced-settings.model.ts
+++ b/src/app/core/models/common/advanced-settings.model.ts
@@ -5,7 +5,7 @@ import { ExportSettingGet } from "../intacct/intacct-configuration/export-settin
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";
-
+import { brandingConfig } from 'src/app/branding/branding-config';
export type EmailOption = {
email: string;
name: string;
@@ -87,11 +87,14 @@ export class AdvancedSettingsModel {
} 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', 'quickbooks online', 'sage intacct'].includes(appName.toLowerCase())) {
- return defaultOptions; // Allow all options including 'card_number'
+
+ if (brandingConfig.brandId === 'co') {
+ return defaultOptions.filter(option => option !== 'card_number' && option !== 'employee_name');
}
- return defaultOptions.filter(option => option !== 'card_number'); // Omit 'card_number' for other apps
+ if (cccExportType && ['netsuite', 'quickbooks online', 'sage intacct'].includes(appName.toLowerCase()) && brandingConfig.brandId === 'fyle') {
+ return defaultOptions;
+ }
+ return defaultOptions.filter(option => option !== 'card_number');
}