Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/branding/c1-branding-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ export const c1KbArticles: KbArticle[string] = {
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`
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`
Comment on lines +133 to +134
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect help article URL for QBD_DIRECT

The HELPER_ARTICLE URL points to a Sage Intacct article ("how-to-skip-exporting-specific-expenses-from-fyle-to-sage-intacct") instead of a QuickBooks Desktop article. This could mislead users by providing incorrect documentation.

Please update the URL to point to the correct QBD documentation.

}
}
};
Expand Down
3 changes: 2 additions & 1 deletion src/app/branding/fyle-branding-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ export const fyleKbArticles: KbArticle[string] = {
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`
SKIP_EXPORT: `${brandingConfig.helpArticleDomain}/en/articles/7882821-how-to-skip-exporting-specific-expenses-from-fyle-to-sage-intacct`,
HELPER_ARTICLE: `${brandingConfig.helpArticleDomain}/en/articles/7882821-how-to-skip-exporting-specific-expenses-from-fyle-to-sage-intacct`
Comment on lines +134 to +135
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

All help article URLs in QBD_DIRECT section are incorrectly pointing to Sage Intacct documentation

The entire QBD_DIRECT section in the branding config is using Sage Intacct documentation URLs for all its properties:

  • IMPORT_SETTING
  • EXPORT_SETTING
  • ADVANCED_SETTING
  • LANDING
  • CONNECTOR
  • SKIP_EXPORT
  • HELPER_ARTICLE

This appears to be a copy-paste error where the entire Sage Intacct section was duplicated for QBD_DIRECT without updating the URLs to point to the correct QuickBooks Desktop documentation.

🔗 Analysis chain

Incorrect documentation URLs for QuickBooks Desktop

The SKIP_EXPORT and HELPER_ARTICLE URLs under QBD_DIRECT are currently pointing to Sage Intacct documentation. This needs to be updated with the correct QuickBooks Desktop documentation URLs.

Let's verify if similar URL mismatches exist in other sections:


Let me verify the URLs in the QBD_DIRECT section by checking the branding config file:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential documentation URL mismatches
# Look for URLs that contain product names in sections for different products

echo "Checking for potential URL mismatches..."
rg -n "intacct" | grep -i "qbd\|quickbooks"
rg -n "sage" | grep -i "qbd\|quickbooks"

Length of output: 10043


Script:

#!/bin/bash
# Check the QBD_DIRECT section in the branding config
rg -A 10 "QBD_DIRECT" src/app/branding/fyle-branding-config.ts

Length of output: 2282

}
}
};
Expand Down
52 changes: 26 additions & 26 deletions src/app/branding/fyle-contents-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const brandingConfig: BrandingConfiguration = config as BrandingConfigura
export const fyleContents = {
qbd_direct: {
landing: {
contentText: 'Import data from QuickBooks Desktop to Fyle and export expenses from Fyle to QuickBooks Desktop',
contentText: 'Import data from QuickBooks Desktop to ' + brandingConfig.brandName + ' and export expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop',
guideHeaderText: 'Guide to setup your integrations'
},
configuration: {
Expand All @@ -24,80 +24,80 @@ export const fyleContents = {
exportSetting: {
stepName: 'Export Settings',
headerText: ' Export Corporate Card Expenses',
contentText: 'In this section, you can configure how and when the expenses from ' + brandingConfig.brandName + ' can be exported to QuickBooks Desktop',
contentText: 'In this section, you can configure how and when the expenses from ' + brandingConfig.brandName + ' need to be exported to QuickBooks Desktop.',
reimbursable: {
reimbursableExpenseLabel: 'Export Reimbursable Expenses',
reimbursableExpenseSubLabel: 'Enable this to export the reimbursable expenses from ' + brandingConfig.brandName + '. If not enabled, any <b>out-of-pocket</b> expenses will not be exported to Quickbooks Desktop.',
reimbursableExpenseTypeLabel: 'How should the expenses be exported?',
reimbursableExpenseTypeSubLabel: 'Choose the type of transaction in QuickBooks Desktop to export your ' + brandingConfig.brandName +' expenses.',
reimbursableExpenseStateLabel: 'At which state should the expenses be ready to export from ' + brandingConfig.brandName + '?',
reimbursableExpenseStateSubLabel: 'You can export expenses either when they are awaiting closure after approval (Processing) or when the payment has been settled (Closed).',
reimbursableExpenseStateSubLabel: 'You can export expenses either when they are awaiting payments after approval (Processing) or when the payment has been settled (Closed).',
reimbursableExpenseDateLabel: 'Set the expense ',
reimbursableExpenseDateSubLabel: 'Expenses will be grouped and posted using the configured date when exporting from ' + brandingConfig.brandName +' to QuickBooks Desktop',
reimbursableExpenseGroupLabel: 'How should the expenses be grouped?',
reimbursableExpenseGroupSubLabel: 'Expenses can either be exported as single line items (Expense) or as a grouped report with multiple line items (Report)',
employeeMappingLabel: 'How are your Employees represented in QuickBooks Desktop?',
employeeMappingSubLabel: 'Select how you represent your employees in QuickBooks Desktop. This would help to export the expenses from ' + brandingConfig.brandName + ' to the correct employee/vendor record in QuickBooks Desktop.',
employeeMappingSubLabel: 'Select how employees are represented in QuickBooks Desktop to ensure expenses from ' + brandingConfig.brandName + ' export to the correct employee/vendor record.',
autoMapEmployeesLabel: 'How should Employees in ' + brandingConfig.brandName + ' be mapped to ',
autoMapEmployeesSubLabel: 'Automatically map the employees in ' + brandingConfig.brandName + ' to their corresponding records in QuickBooks Desktop based on a unique parameter.',
defaultReimbursableAccountPayableLabel: 'To which accounts payable account should the ',
defaultReimbursableAccountPayableLabel: 'Select the Default Credit Account for adding ',
defaultReimbursableAccountPayableSubLabel: 'The integration will post the offset credit entry in '
},
corporateCard: {
creditCardExpenseLabel: 'Export corporate card expenses',
creditCardExpenseSubLabel: 'Enable this to export the non-reimbursable expenses from ' + brandingConfig.brandName + '. If not enabled, any <b>corporate credit card </b> expenses will not be exported to Quickbooks Desktop.',
creditCardExpenseSubLabel: 'Enable this to export the corporate credit card expenses from ' + brandingConfig.brandName + '. If not enabled, any <b>non-reimbursable </b> expenses will not be exported to Quickbooks Desktop.',
creditCardExpenseTypeLabel: 'How should the expenses be exported?',
creditCardExpenseTypeSubLabel: 'Choose the type of transaction in QuickBooks Desktop to export your ' + brandingConfig.brandName +' expenses.',
creditCardExpenseStateLabel: 'At which state should the expenses be ready to export from ' + brandingConfig.brandName + '?',
creditCardExpenseStateSubLabel: 'You could choose to export ccc expenses when they have been approved and are awaiting payment clearance, or simply when they have been paid out.',
creditCardExpenseStateSubLabel: 'You can export expenses either when they are awaiting closure after approval (Approved) or when the expense has been closed (Closed).',
creditCardExpenseDateLabel: 'Set the expense ',
creditCardExpenseDateSubLabel: 'Expenses will be grouped and posted using the configured date when exporting from ' + brandingConfig.brandName +' to QuickBooks Desktop',
creditCardExpenseGroupLabel: 'How should the expenses be grouped?',
creditCardExpenseGroupSubLabel: 'Expenses can either be exported as single line items (Expense) or as a grouped report with multiple line items (Report)',
creditCardExpenseNameinJELabel: 'Name in Journal Entry',
creditCardExpenseNameinJESubLabel: 'You can select either the \'Merchant Name\' or the \'Employee Name\' to appear in the \'Name\' field of your Journal Entries.',
defaultCCCAccountLabel: 'Set Default Credit Card Account as',
defaultCCCAccountSubLabel: 'Post all your company corporate card transactions to a default credit card account.',
defaultCCCAccountPayableLabel: 'To which accounts payable account should the ',
defaultCCCAccountPayableSubLabel: 'The integration will post the offset credit entry in '
creditCardExpenseNameinJESubLabel: 'You can select either the \'Merchant Name\' or the \'Employee Name\' to appear in the \'Name\' field of your journal entries.',
defaultCCCAccountLabel: 'Set a Default Credit Card Account',
defaultCCCAccountSubLabel: 'If there\'s no card-to-card mapping or when an expense lacks a corporate card transaction associated with it, expenses will be posted to the default card configured here.',
defaultCCCAccountPayableLabel: 'Select the Default Credit Account for adding Journal Entry ',
defaultCCCAccountPayableSubLabel: 'This account will be used for the credit line of the '
}
},
importSetting: {
stepName: 'Import Settings',
headerText: '',
contentText: 'In this section, you can choose the fields required to be imported from QuickBooks Desktop to ' + brandingConfig.brandName + '. ',
importCategoriesLabel: 'Import the Chart of Accounts as Categories in ' + brandingConfig.brandName,
importCategoriesSubLabel: 'Imported account will be available as Categories in ' + brandingConfig.brandName + '.',
importCategoriesLabel: 'Import Chart of Accounts as Categories in ' + brandingConfig.brandName,
importCategoriesSubLabel: 'Chart of Accounts in QuickBooks will be imported as Categories in Fyle, available in a dropdown for employees to select when coding expenses.',
importItemsLabel: 'Import Products/Services from QuickBooks Desktop',
importItemsSubLabel: 'Products/services from QuickBooks Desktop will be imported as Categories in ' + brandingConfig.brandName + '.',
importVendorsAsMerchantsLabel: 'Import Vendors from QuickBooks Desktop',
chartOfAccountTypes: 'Select the accounts from QuickBooks Desktop to import as categories in ' + brandingConfig.brandName,
chartOfAccountTypesSubLabel: 'By default expense will be selected. Open the dropdown to select more as per your requirements.'
importVendorsAsMerchantsLabel: 'Import Vendors as Merchants in Fyle',
chartOfAccountTypes: 'Choose the type of accounts to be imported',
chartOfAccountTypesSubLabel: 'By default \'Expense\' type accounts will be imported. Open the dropdown to add or modify selections based on your needs.'
},
advancedSettings: {
stepName: 'Advanced Settings',
contentText: 'In this section, you can customize the integration based on your accounting requirements. ',
automationLabel: 'Automation',
automationSubLabel: 'You can automate the export and sync of your data in this section.',
customizeSectionLabel: 'Customization',
customizeSectionSubLabel: 'In this section, you can customize the data that you\'d like to export from Fyle to QuickBooks Desktop You can choose what data points need to be exported and what shouldn\'t be.',
customizeSectionSubLabel: 'In this section, you can customize the data that you\'d like to export from Fyle to QuickBooks Desktop.',
scheduleAutoExportLabel: 'Schedule automatic export',
scheduleAutoExportSubLabel: 'Set up a schedule to frequently automate the export of expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop.',
autoExportfrequencyLabel: 'Set up export frequency',
autoExportfrequencySubLabel: 'Set a frequency based on how often you want your expenses in Fyle to be exported to QuickBooks Desktop.',
topLevelMemoStructureLabel: 'Select the top level memo field data for QuickBooks Desktop',
topLevelMemoStructureSubLabel: 'You can customize the <b>data point</b> you would like to export to QuickBooks Desktop\’s <b>top-level memo</b> field while exporting expenses from ' + brandingConfig.brandName + '.',
memoStructureLabel: 'Set the line-item level memo field data for QuickBooks Desktop.',
memoStructureSubLabel: 'You can customize the data set you would like to export to QuickBooks Desktop\’s <b>transaction line-item level memo</b> field while exporting expenses from ' + brandingConfig.brandName + '.',
topLevelMemoStructureLabel: 'Customize the Top-Level Memo Field',
topLevelMemoStructureSubLabel: 'Select the datapoints you\'d like to export to QuickBooks Desktop’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 QuickBooks Desktop\’s line-item level memo field when exporting expenses from Fyle.',
previewDescriptionFieldLabel: 'Preview of the Description Field',
otherPreferencesLabel: 'Other preferences',
otherPreferencesSubLabel: 'Based on your preference, you can choose whether you want to create any new records in QuickBooks Desktop from ' + brandingConfig.brandName + '.',
autoCreateMerchantsAsVendorsLabel: 'Auto-create merchants as vendors',
autoCreateMerchantsAsVendorsSubLabel: 'Fyle will auto-create a new vendor in QuickBooks Desktop if a merchant added by an employee does not have a corresponding match in QuickBooks Desktop. ',
skipExportLabel: 'Skip export of specific expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop',
skipExportSubLabel: 'You could choose to skip expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop by setting up a conditional rule. ',
autoCreateReimbursableEnitityLabel: 'Auto create reimbursable enitity',
autoCreateReimbursableEnititySubLabel: 'Do you want to create a reimbursable enitity if not present',
skipExportLabel: 'Skip Export of Specific Expenses from Fyle to QuickBooks Desktop',
skipExportSubLabel: 'Set up a conditional rule to selectively skip exporting certain expenses from Fyle to QuickBooks Desktop. ',
autoCreateReimbursableEnitityLabel: 'Auto-create fyle employees as ',
autoCreateReimbursableEnititySubLabel: 'If an employee in Fyle has no corresponding record in QuickBooks Desktop, the integration will automatically create a ',
accountingPeriodLabel: 'Post entries in the current accounting period',
accountingPeriodSubLabel: 'If there are expenses for which the accounting period is closed in QuickBooks Desktop, you can export those to the current month by enabling this option.'
}
Expand Down
1 change: 1 addition & 0 deletions src/app/core/models/branding/kb-article.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type KbArticle = {
LANDING: string;
CONNECTOR: string;
SKIP_EXPORT: string;
HELPER_ARTICLE: string;
},
INTACCT: {
IMPORT_SETTING: string;
Expand Down
2 changes: 1 addition & 1 deletion src/app/core/models/common/advanced-settings.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class AdvancedSettingsModel {
merchant: 'Pizza Hut',
report_number: 'C/2021/12/R/1',
spent_on: today.toLocaleDateString(),
expence_key: 'txDdlUFWkahX',
expense_key: 'txDdlUFWkahX',
expense_link: `${environment.fyle_app_url}/app/main/#/enterprise/view_expense/`
};
let memoPreviewText = '';
Expand Down
2 changes: 1 addition & 1 deletion src/app/core/models/db/task-log.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ export type TaskLogGetParams = {
type__in?: string[];
expense_group_ids?: number[];
task_type?: string[];
export_log_id__in?: number[];
export_log__id?: number[];
};
3 changes: 2 additions & 1 deletion src/app/core/models/enum/enum.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,8 @@ export enum AccountingExportStatus {
COMPLETE = 'COMPLETE',
IN_PROGRESS = 'IN_PROGRESS',
ENQUEUED = 'ENQUEUED',
EXPORT_QUEUED = 'EXPORT_QUEUED'
EXPORT_QUEUED = 'EXPORT_QUEUED',
ERROR = 'ERROR'
}

export enum AccountingExportType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class QbdDirectAdvancedSettingsModel extends AdvancedSettingsModel {
}

static defaultTopMemoOptions(): string[] {
return ["employee_name", "expense_key"];
return ["employee_name", "Expense/Report ID"];
}

static formatMemoStructure(memoStructure: string[], defaultMemoOptions: string[]): string[] {
Expand Down Expand Up @@ -58,6 +58,9 @@ export class QbdDirectAdvancedSettingsModel extends AdvancedSettingsModel {

const topMemo: string[] = advancedSettingForm.controls.topMemoStructure.value;

const index = topMemo.indexOf('Expense/Report ID');
topMemo[index] = 'expense_key';

Comment on lines +61 to +63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and use a more maintainable approach for field mapping.

The current implementation has potential issues:

  1. No error handling if "Expense/Report ID" is not found (indexOf returns -1)
  2. Direct array manipulation could be risky
  3. The mapping is hardcoded and scattered across methods

Consider this more robust approach:

+ private static readonly MEMO_FIELD_MAPPING = {
+   'Expense/Report ID': 'expense_key'
+ } as const;

  static constructPayload(advancedSettingForm: FormGroup, adminEmails: EmailOption[]): QbdDirectAdvancedSettingsPost {
    const topMemo: string[] = advancedSettingForm.controls.topMemoStructure.value;
-   const index = topMemo.indexOf('Expense/Report ID');
-   topMemo[index] = 'expense_key';
+   const mappedMemo = topMemo.map(field => 
+     QbdDirectAdvancedSettingsModel.MEMO_FIELD_MAPPING[field] || field
+   );

This approach:

  1. Centralizes UI-to-API field mappings
  2. Uses immutable operations
  3. Gracefully handles missing mappings
  4. Makes it easier to add new field mappings in the future

Committable suggestion skipped: line range outside the PR's diff.

const allSelectedEmails: EmailOption[] = advancedSettingForm.get('email')?.value;

const selectedEmailsEmails = allSelectedEmails?.filter((email: EmailOption) => adminEmails.includes(email));
Expand Down
2 changes: 1 addition & 1 deletion src/app/core/services/common/dashboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class DashboardService {
}

if (expenseGroupIds.length) {
const expenseKey = appName === AppName.INTACCT ? 'expense_group_ids' : appName === AppName.QBD_DIRECT ? 'export_log_id__in' : 'expense_group_id__in';
const expenseKey = appName === AppName.INTACCT ? 'expense_group_ids' : appName === AppName.QBD_DIRECT ? 'export_log__id' : 'expense_group_id__in';
apiParams[expenseKey] = expenseGroupIds;
}

Expand Down
8 changes: 5 additions & 3 deletions src/app/core/services/common/export-log.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import { Injectable } from '@angular/core';
import { ApiService } from './api.service';
import { UserService } from '../misc/user.service';
import { WorkspaceService } from './workspace.service';
import { environment } from 'src/environments/environment';
import { SkipExportLogResponse } from '../../models/intacct/db/expense-group.model';
import { AppName, FyleReferenceType, TaskLogState } from '../../models/enum/enum.model';
import { AccountingExportStatus, AppName, TaskLogState } from '../../models/enum/enum.model';
import { Observable } from 'rxjs';
import { AccountingExport } from '../../models/db/accounting-export.model';
import { SelectedDateFilter } from '../../models/qbd/misc/qbd-date-filter.model';
import { ExpenseGroupParam, ExpenseGroupResponse, SkipExportParam } from '../../models/db/expense-group.model';

Expand Down Expand Up @@ -87,6 +85,10 @@ export class ExportLogService {
if (appName === AppName.NETSUITE) {
return this.apiService.get(`/workspaces/${this.workspaceId}/fyle/expense_groups/v2/`, params);
} else if (appName === AppName.QBD_DIRECT) {
if (params.status__in?.includes(AccountingExportStatus.FAILED)) {
params.status__in = AccountingExportStatus.ERROR;
}

return this.apiService.get(`/workspaces/${this.workspaceId}/export_logs/`, params);
}
return this.apiService.get(`/workspaces/${this.workspaceId}/fyle/expense_groups/`, params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class QbdDirectConnectorService {
return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`, payload);
}

getQBDConnectorSettings(): Observable<QbdConnectorGet> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`, {});
}

syncAttribuites(): Observable<SyncDataType[]> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
}
Expand Down
Loading
Loading