diff --git a/src/languages/en.ts b/src/languages/en.ts index fc5015a072d1..9738be63911a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1939,10 +1939,9 @@ export default { createEntitiesDescription: 'Expensify will automatically create a vendor in Quickbooks, if one does not exist. Expensify will also automatically create a customer when exporting invoices.', reimbursedReports: 'Sync reimbursed reports', - reimbursedReportsDescription: 'Any time report is paid using Expensify ACH, the corresponding bill payment will be created in the Quickbooks accounts below.', - qboAccount: 'Quickbooks account', - collectionAccount: 'Invoice collection account', - collectionAccountDescription: 'Once invoices have been paid, the payment will appear in the account configured below.', + reimbursedReportsDescription: 'Any time a report is paid using Expensify ACH, the corresponding bill payment will be created in the Quickbooks account below.', + qboBillPaymentAccount: 'QuickBooks bill payment account', + qboInvoiceCollectionAccount: 'QuickBooks invoice collections account', accountSelectDescription: "As you've enabled sync reimbursed reports, you will need select the bank account your reimbursements are coming out of, and we'll create the payment in QuickBooks.", invoiceAccountSelectDescription: diff --git a/src/languages/es.ts b/src/languages/es.ts index 74fa92084977..94b1ab030fb4 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1966,10 +1966,9 @@ export default { 'Expensify creará automáticamente un proveedor en Quickbooks, si no existe. Expensify también creará automáticamente un cliente al exportar facturas.', reimbursedReports: 'Sincronizar informes reembolsados', reimbursedReportsDescription: - 'Cada vez que se pague un informe utilizando Expensify ACH, se creará el pago de la factura correspondiente en las cuentas de Quickbooks indicadas a continuación.', - qboAccount: 'Cuenta Quickbooks', - collectionAccount: 'Cuenta de cobro de facturas', - collectionAccountDescription: 'Una vez abonadas las facturas, el pago aparecerá en la cuenta configurada a continuación.', + 'Cada vez que se pague un informe utilizando Expensify ACH, se creará el correspondiente pago de la factura en la cuenta de Quickbooks indicadas a continuación.', + qboBillPaymentAccount: 'Cuenta de pago de las facturas de QuickBooks', + qboInvoiceCollectionAccount: 'Cuenta de cobro de las facturas QuickBooks', accountSelectDescription: 'Como has activado la sincronización de los informes de reembolso, tendrás que seleccionar la cuenta bancaria de la que saldrán tus reembolsos y crearemos el pago en QuickBooks.', invoiceAccountSelectDescription: diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx index cf23c98c0895..8ea68b181323 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx @@ -13,8 +13,8 @@ import Navigation from '@libs/Navigation/Navigation'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; import FeatureEnabledAccessOrNotFoundWrapper from '@pages/workspace/FeatureEnabledAccessOrNotFoundWrapper'; import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; -import withPolicy from '@pages/workspace/withPolicy'; -import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -22,23 +22,14 @@ type SelectorType = ListItem & { value: string; }; -// TODO: remove once UI is approved -const DRAFT = [ - {name: 'Croissant Co Payroll Account', id: 'Croissant Co Payroll Account'}, - {name: 'Croissant Co Money in Clearing', id: 'Croissant Co Money in Clearing'}, - {name: 'Croissant Co Debts and Loans', id: 'Croissant Co Debts and Loans'}, -]; - -function QuickbooksAccountSelectPage({policy}: WithPolicyProps) { +function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const selectedAccount = DRAFT[0].id; // selected - const policyID = policy?.id ?? ''; const {bankAccounts, creditCards} = policy?.connections?.quickbooksOnline?.data ?? {}; - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const accountOptions = useMemo(() => DRAFT || [...(bankAccounts ?? []), ...(creditCards ?? [])], [bankAccounts, creditCards]); + const {reimbursementAccountID} = policy?.connections?.quickbooksOnline?.config ?? {}; + const accountOptions = useMemo(() => [...(bankAccounts ?? []), ...(creditCards ?? [])], [bankAccounts, creditCards]); const qboOnlineSelectorOptions = useMemo( () => @@ -46,9 +37,9 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyProps) { value: id, text: name, keyForList: id, - isSelected: selectedAccount === id, + isSelected: reimbursementAccountID === id, })), - [selectedAccount, accountOptions], + [reimbursementAccountID, accountOptions], ); const listHeaderComponent = useMemo( () => ( @@ -80,7 +71,7 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyProps) { includeSafeAreaPaddingBottom={false} testID={QuickbooksAccountSelectPage.displayName} > - + [...(bankAccounts ?? []), ...(creditCards ?? [])], [bankAccounts, creditCards]); + const invoiceAccountCollectionOptions = useMemo(() => [...(bankAccounts ?? []), ...(otherCurrentAssetAccounts ?? [])], [bankAccounts, otherCurrentAssetAccounts]); + const isSyncReimbursedSwitchOn = !!collectionAccountID; - const selectedAccount = '92345'; // TODO: use fake selected account temporarily. + + const selectedQboAccountName = useMemo(() => qboAccountOptions?.find(({id}) => id === reimbursementAccountID)?.name, [qboAccountOptions, reimbursementAccountID]); + const selectedInvoiceCollectionAccountName = useMemo( + () => invoiceAccountCollectionOptions?.find(({id}) => id === collectionAccountID)?.name, + [invoiceAccountCollectionOptions, collectionAccountID], + ); + + const syncReimbursedSubMenuItems = () => ( + + + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR.getRoute(policyID)))} + error={errorFields?.reimbursementAccountID ? translate('common.genericErrorMessage') : undefined} + brickRoadIndicator={errorFields?.reimbursementAccountID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + /> + + + + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR.getRoute(policyID)))} + error={errorFields?.collectionAccountID ? translate('common.genericErrorMessage') : undefined} + brickRoadIndicator={errorFields?.collectionAccountID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + /> + + + ); const qboToggleSettingItems: ToggleSettingOptionRowProps[] = [ { @@ -47,6 +83,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyProps) { pendingAction: pendingFields?.autoSync, errors: ErrorUtils.getLatestErrorField(qboConfig ?? {}, CONST.QUICK_BOOKS_CONFIG.AUTO_SYNC), onCloseError: () => Policy.clearQBOErrorField(policyID, CONST.QUICK_BOOKS_CONFIG.AUTO_SYNC), + wrapperStyle: styles.mv3, }, { title: translate('workspace.qbo.advancedConfig.inviteEmployees'), @@ -56,6 +93,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyProps) { pendingAction: pendingFields?.syncPeople, errors: ErrorUtils.getLatestErrorField(qboConfig ?? {}, CONST.QUICK_BOOKS_CONFIG.SYNCE_PEOPLE), onCloseError: () => Policy.clearQBOErrorField(policyID, CONST.QUICK_BOOKS_CONFIG.SYNCE_PEOPLE), + wrapperStyle: styles.mv3, }, { title: translate('workspace.qbo.advancedConfig.createEntities'), @@ -65,6 +103,24 @@ function QuickbooksAdvancedPage({policy}: WithPolicyProps) { pendingAction: pendingFields?.autoCreateVendor, errors: ErrorUtils.getLatestErrorField(qboConfig ?? {}, CONST.QUICK_BOOKS_CONFIG.AUTO_CREATE_VENDOR), onCloseError: () => Policy.clearQBOErrorField(policyID, CONST.QUICK_BOOKS_CONFIG.AUTO_CREATE_VENDOR), + wrapperStyle: styles.mv3, + }, + { + title: translate('workspace.qbo.advancedConfig.reimbursedReports'), + subtitle: translate('workspace.qbo.advancedConfig.reimbursedReportsDescription'), + isActive: isSyncReimbursedSwitchOn, + onToggle: () => + Connections.updatePolicyConnectionConfig( + policyID, + CONST.POLICY.CONNECTIONS.NAME.QBO, + CONST.QUICK_BOOKS_CONFIG.COLLECTION_ACCOUNT_ID, + isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions][0].id, + ), + pendingAction: pendingFields?.collectionAccountID, + errors: ErrorUtils.getLatestErrorField(qboConfig ?? {}, CONST.QUICK_BOOKS_CONFIG.COLLECTION_ACCOUNT_ID), + onCloseError: () => Policy.clearQBOErrorField(policyID, CONST.QUICK_BOOKS_CONFIG.COLLECTION_ACCOUNT_ID), + subMenuItems: syncReimbursedSubMenuItems(), + wrapperStyle: styles.mv3, }, ]; @@ -91,79 +147,13 @@ function QuickbooksAdvancedPage({policy}: WithPolicyProps) { title={item.title} subtitle={item.subtitle} shouldPlaceSubtitleBelowSwitch - wrapperStyle={styles.mv3} + wrapperStyle={item.wrapperStyle} isActive={item.isActive} onToggle={item.onToggle} pendingAction={item.pendingAction} + subMenuItems={item.subMenuItems} /> ))} - - - - - - Policy.clearQBOErrorField(policyID, CONST.QUICK_BOOKS_CONFIG.COLLECTION_ACCOUNT_ID)} - subtitle={translate('workspace.qbo.advancedConfig.reimbursedReportsDescription')} - shouldPlaceSubtitleBelowSwitch - wrapperStyle={styles.mv3} - pendingAction={pendingFields?.collectionAccountID} - isActive={isSyncReimbursedSwitchOn} - onToggle={() => - Connections.updatePolicyConnectionConfig( - policyID, - CONST.POLICY.CONNECTIONS.NAME.QBO, - CONST.QUICK_BOOKS_CONFIG.COLLECTION_ACCOUNT_ID, - isSyncReimbursedSwitchOn ? '' : selectedAccount, - ) - } - /> - - {!!collectionAccountID && ( - <> - - Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR.getRoute(policyID)))} - error={errorFields?.reimbursementAccountID ? translate('common.genericErrorMessage') : undefined} - brickRoadIndicator={errorFields?.reimbursementAccountID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} - /> - - - - - - - - - Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR.getRoute(policyID)))} - error={errorFields?.collectionAccountID ? translate('common.genericErrorMessage') : undefined} - brickRoadIndicator={errorFields?.collectionAccountID ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} - /> - - - )} @@ -174,4 +164,4 @@ function QuickbooksAdvancedPage({policy}: WithPolicyProps) { QuickbooksAdvancedPage.displayName = 'QuickbooksAdvancedPage'; -export default withPolicy(QuickbooksAdvancedPage); +export default withPolicyConnections(QuickbooksAdvancedPage); diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx index ecee5fee40bc..5fe03434f726 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx @@ -13,8 +13,8 @@ import Navigation from '@libs/Navigation/Navigation'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; import FeatureEnabledAccessOrNotFoundWrapper from '@pages/workspace/FeatureEnabledAccessOrNotFoundWrapper'; import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; -import withPolicy from '@pages/workspace/withPolicy'; -import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -22,23 +22,14 @@ type SelectorType = ListItem & { value: string; }; -// TODO: remove once UI is approved -const DRAFT = [ - {name: 'Croissant Co Payroll Account', id: 'Croissant Co Payroll Account'}, - {name: 'Croissant Co Money in Clearing', id: 'Croissant Co Money in Clearing'}, - {name: 'Croissant Co Debts and Loans', id: 'Croissant Co Debts and Loans'}, -]; - -function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyProps) { +function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyConnectionsProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const selectedAccount = DRAFT[1].id; // selected - const policyID = policy?.id ?? ''; const {bankAccounts, otherCurrentAssetAccounts} = policy?.connections?.quickbooksOnline?.data ?? {}; - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const accountOptions = useMemo(() => DRAFT || [...(bankAccounts ?? []), ...(otherCurrentAssetAccounts ?? [])], [bankAccounts, otherCurrentAssetAccounts]); + const accountOptions = useMemo(() => [...(bankAccounts ?? []), ...(otherCurrentAssetAccounts ?? [])], [bankAccounts, otherCurrentAssetAccounts]); + const {collectionAccountID} = policy?.connections?.quickbooksOnline?.config ?? {}; const qboOnlineSelectorOptions = useMemo( () => @@ -46,9 +37,9 @@ function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyProps) { value: id, text: name, keyForList: id, - isSelected: selectedAccount === id, + isSelected: collectionAccountID === id, })), - [selectedAccount, accountOptions], + [collectionAccountID, accountOptions], ); const listHeaderComponent = useMemo( @@ -81,7 +72,7 @@ function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyProps) { includeSafeAreaPaddingBottom={false} testID={QuickbooksInvoiceAccountSelectPage.displayName} > - +