Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offline and errors pattern in Quickbooks Online integration #46511

Merged
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
263743b
Initial refactor of import pages
zfurtak Jul 30, 2024
362d521
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Jul 30, 2024
ab278cb
Adjusted import pages and refactored advanced page
zfurtak Jul 30, 2024
2f73caa
Further refactor
zfurtak Jul 31, 2024
a98872e
Export pages refactor
zfurtak Aug 1, 2024
cabe722
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 1, 2024
4a2c570
Add error/offline patterns and refactor advanced pages
zfurtak Aug 2, 2024
5de6c69
Adding missing patterns
zfurtak Aug 2, 2024
ee86a23
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 5, 2024
93c42d1
Revert max_request_retry value
zfurtak Aug 5, 2024
def4201
Adjustments
zfurtak Aug 6, 2024
0cff3d9
Adjustments
zfurtak Aug 6, 2024
c109a1d
Adjusted to review
zfurtak Aug 7, 2024
e609478
Added needed conditions
zfurtak Aug 7, 2024
0b181b3
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 7, 2024
26a9448
Adjust error patterns
zfurtak Aug 7, 2024
a5e667a
Fix console errors
zfurtak Aug 7, 2024
0ca45ed
Adjusted to review
zfurtak Aug 7, 2024
1600fe6
Style fix
zfurtak Aug 7, 2024
f95c601
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 8, 2024
21d34d0
Rerun the checks
zfurtak Aug 8, 2024
893c8b1
Added missing setting
zfurtak Aug 8, 2024
a765f9b
Adjust code to react compiler
zfurtak Aug 8, 2024
12c81e2
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 13, 2024
3c54077
Fix react compiler errors
zfurtak Aug 13, 2024
ce308ed
Remove opacity from empty list
zfurtak Aug 14, 2024
ee8a820
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 14, 2024
650192a
Remove opacity from empty list
zfurtak Aug 14, 2024
1449d8a
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 26, 2024
e5faeb4
Merge branch 'main' into @zfurtak/qbo-error-messages
zfurtak Aug 27, 2024
9664819
Merge main
zfurtak Sep 4, 2024
14875d2
Merge main
zfurtak Sep 4, 2024
5e556ff
Added generic types for oldSettingValue
zfurtak Sep 4, 2024
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
8 changes: 6 additions & 2 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1319,21 +1319,25 @@ const CONST = {
},
QUICKBOOKS_ONLINE: 'quickbooksOnline',

QUICK_BOOKS_CONFIG: {
SYNC_CLASSES: 'syncClasses',
QUICKBOOKS_CONFIG: {
ENABLE_NEW_CATEGORIES: 'enableNewCategories',
SYNC_CLASSES: 'syncClasses',
SYNC_CUSTOMERS: 'syncCustomers',
SYNC_LOCATIONS: 'syncLocations',
SYNC_TAX: 'syncTax',
EXPORT: 'export',
EXPORTER: 'exporter',
EXPORT_DATE: 'exportDate',
NON_REIMBURSABLE_EXPENSES_ACCOUNT: 'nonReimbursableExpensesAccount',
NON_REIMBURSABLE_EXPENSES_EXPORT_DESTINATION: 'nonReimbursableExpensesExportDestination',
REIMBURSABLE_EXPENSES_ACCOUNT: 'reimbursableExpensesAccount',
REIMBURSABLE_EXPENSES_EXPORT_DESTINATION: 'reimbursableExpensesExportDestination',
NON_REIMBURSABLE_BILL_DEFAULT_VENDOR: 'nonReimbursableBillDefaultVendor',
NON_REIMBURSABLE_EXPENSE_EXPORT_DESTINATION: 'nonReimbursableExpensesExportDestination',
NON_REIMBURSABLE_EXPENSE_ACCOUNT: 'nonReimbursableExpensesAccount',
RECEIVABLE_ACCOUNT: 'receivableAccount',
AUTO_SYNC: 'autoSync',
ENABLED: 'enabled',
SYNC_PEOPLE: 'syncPeople',
AUTO_CREATE_VENDOR: 'autoCreateVendor',
REIMBURSEMENT_ACCOUNT_ID: 'reimbursementAccountID',
Expand Down
2 changes: 1 addition & 1 deletion src/components/SelectionScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function SelectionScreen<T = string>({
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
listEmptyContent={listEmptyContent}
listFooterContent={listFooterContent}
sectionListStyle={[styles.flexGrow0]}
sectionListStyle={!!sections.length && [styles.flexGrow0]}
shouldDebounceRowSelect={shouldDebounceRowSelect}
>
<ErrorMessageRow
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2161,6 +2161,7 @@ export default {
accountsPayable: 'Accounts payable',
accountsPayableDescription: 'Choose where to create vendor bills.',
bankAccount: 'Bank account',
notConfigured: 'Not configured',
bankAccountDescription: 'Choose where to send checks from.',
creditCardAccount: 'Credit card account',
companyCardsLocationEnabledDescription:
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2189,6 +2189,7 @@ export default {
accountsPayable: 'Cuentas por pagar',
accountsPayableDescription: 'Elige dónde crear las facturas de proveedores.',
bankAccount: 'Cuenta bancaria',
notConfigured: 'No configurado',
bankAccountDescription: 'Elige desde dónde enviar los cheques.',
creditCardAccount: 'Cuenta de la tarjeta de crédito',
companyCardsLocationEnabledDescription:
Expand Down
86 changes: 1 addition & 85 deletions src/libs/actions/connections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function createErrorFields<TConnectionName extends ConnectionNameExceptNetSuite,
}, {});
}

function updatePolicyXeroConnectionConfig<TConnectionName extends ConnectionNameExceptNetSuite, TSettingName extends keyof Connections[TConnectionName]['config']>(
function updatePolicyConnectionConfig<TConnectionName extends ConnectionNameExceptNetSuite, TSettingName extends keyof Connections[TConnectionName]['config']>(
policyID: string,
connectionName: TConnectionName,
settingName: TSettingName,
Expand Down Expand Up @@ -137,89 +137,6 @@ function updatePolicyXeroConnectionConfig<TConnectionName extends ConnectionName
};
API.write(WRITE_COMMANDS.UPDATE_POLICY_CONNECTION_CONFIG, parameters, {optimisticData, failureData, successData});
}

function updatePolicyConnectionConfig<TConnectionName extends ConnectionNameExceptNetSuite, TSettingName extends keyof Connections[TConnectionName]['config']>(
policyID: string,
connectionName: TConnectionName,
settingName: TSettingName,
settingValue: Partial<Connections[TConnectionName]['config'][TSettingName]>,
) {
const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
connections: {
[connectionName]: {
config: {
[settingName]: settingValue ?? null,
pendingFields: {
[settingName]: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
},
errorFields: {
[settingName]: null,
},
},
},
},
},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
connections: {
[connectionName]: {
config: {
[settingName]: settingValue ?? null,
pendingFields: {
[settingName]: null,
},
errorFields: {
[settingName]: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
},
},
},
},
},
},
];

const successData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
connections: {
[connectionName]: {
config: {
[settingName]: settingValue ?? null,
pendingFields: {
[settingName]: null,
},
errorFields: {
[settingName]: null,
},
},
},
},
},
},
];

const parameters: UpdatePolicyConnectionConfigParams = {
policyID,
connectionName,
settingName: String(settingName),
settingValue: JSON.stringify(settingValue),
idempotencyKey: String(settingName),
};
API.write(WRITE_COMMANDS.UPDATE_POLICY_CONNECTION_CONFIG, parameters, {optimisticData, failureData, successData});
}

/**
* This method returns read command and stage in progres for a given accounting integration.
*
Expand Down Expand Up @@ -419,7 +336,6 @@ function copyExistingPolicyConnection(connectedPolicyID: string, targetPolicyID:
export {
removePolicyConnection,
updatePolicyConnectionConfig,
updatePolicyXeroConnectionConfig,
updateManyPolicyConnectionConfigs,
hasSynchronizationError,
syncConnection,
Expand Down
24 changes: 24 additions & 0 deletions src/pages/workspace/accounting/PolicyAccountingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,33 @@ function accountingIntegrationData(
/>
),
onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT.getRoute(policyID)),
subscribedImportSettings: [
CONST.QUICKBOOKS_CONFIG.ENABLE_NEW_CATEGORIES,
CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES,
CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS,
CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS,
CONST.QUICKBOOKS_CONFIG.SYNC_TAX,
],
onExportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT.getRoute(policyID)),
subscribedExportSettings: [
CONST.QUICKBOOKS_CONFIG.EXPORTER,
CONST.QUICKBOOKS_CONFIG.EXPORT_DATE,
CONST.QUICKBOOKS_CONFIG.RECEIVABLE_ACCOUNT,
CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSES_EXPORT_DESTINATION,
CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSE_ACCOUNT,
],
onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_CARD_RECONCILIATION.getRoute(policyID, CONST.POLICY.CONNECTIONS.NAME.QBO)),
onAdvancedPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID)),
subscribedAdvancedSettings: [
CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID,
CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID,
CONST.QUICKBOOKS_CONFIG.AUTO_SYNC,
CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE,
CONST.QUICKBOOKS_CONFIG.AUTO_CREATE_VENDOR,
CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID,
],
pendingFields: policy?.connections?.quickbooksOnline?.config?.pendingFields,
errorFields: policy?.connections?.quickbooksOnline?.config?.errorFields,
};
case CONST.POLICY.CONNECTIONS.NAME.XERO:
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Illustrations from '@components/Icon/Illustrations';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import {settingsPendingAction} from '@libs/PolicyUtils';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import variables from '@styles/variables';
import {clearQBOErrorField} from '@userActions/Policy/Policy';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';

Expand All @@ -29,7 +29,7 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) {

const policyID = policy?.id ?? '-1';
const {bankAccounts, creditCards} = policy?.connections?.quickbooksOnline?.data ?? {};
const {reimbursementAccountID} = policy?.connections?.quickbooksOnline?.config ?? {};
const qboConfig = policy?.connections?.quickbooksOnline?.config;
const accountOptions = useMemo(() => [...(bankAccounts ?? []), ...(creditCards ?? [])], [bankAccounts, creditCards]);

const qboOnlineSelectorOptions = useMemo<SelectorType[]>(
Expand All @@ -38,9 +38,9 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) {
value: id,
text: name,
keyForList: id,
isSelected: reimbursementAccountID === id,
isSelected: qboConfig?.reimbursementAccountID === id,
})),
[reimbursementAccountID, accountOptions],
[qboConfig?.reimbursementAccountID, accountOptions],
);
const listHeaderComponent = useMemo(
() => (
Expand All @@ -55,7 +55,7 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) {

const saveSelection = useCallback(
({value}: SelectorType) => {
Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.QBO, CONST.QUICK_BOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID, value);
Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.QBO, CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID, value);
Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID));
},
[policyID],
Expand All @@ -76,28 +76,26 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) {
);

return (
<AccessOrNotFoundWrapper
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
<SelectionScreen
policyID={policyID}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
>
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={QuickbooksAccountSelectPage.displayName}
>
<HeaderWithBackButton title={translate('workspace.qbo.advancedConfig.qboBillPaymentAccount')} />

<SelectionList
sections={qboOnlineSelectorOptions.length ? [{data: qboOnlineSelectorOptions}] : []}
ListItem={RadioListItem}
headerContent={listHeaderComponent}
onSelectRow={saveSelection}
shouldDebounceRowSelect
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
listEmptyContent={listEmptyContent}
/>
</ScreenWrapper>
</AccessOrNotFoundWrapper>
displayName={QuickbooksAccountSelectPage.displayName}
sections={qboOnlineSelectorOptions.length ? [{data: qboOnlineSelectorOptions}] : []}
listItem={RadioListItem}
headerContent={listHeaderComponent}
onSelectRow={saveSelection}
shouldDebounceRowSelect
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
listEmptyContent={listEmptyContent}
title="workspace.qbo.advancedConfig.qboBillPaymentAccount"
connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO}
onBackButtonPress={() => Navigation.goBack()}
zfurtak marked this conversation as resolved.
Show resolved Hide resolved
pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID], qboConfig?.pendingFields)}
errors={ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID)}
errorRowStyles={[styles.ph5, styles.mv2]}
zfurtak marked this conversation as resolved.
Show resolved Hide resolved
onClose={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID)}
/>
);
}

Expand Down
Loading
Loading