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
109 changes: 83 additions & 26 deletions src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import type {
ConnectionName,
Connections,
CustomUnit,
InvoiceItem,
NetSuiteAccount,
NetSuiteConnection,
NetSuiteCustomList,
NetSuiteCustomSegment,
NetSuiteTaxAccount,
NetSuiteVendor,
PolicyFeatureName,
Rate,
Tenant,
Expand Down Expand Up @@ -549,61 +552,90 @@ function xeroSettingsPendingAction(settings?: XeroSettings, pendingFields?: Pend
return pendingFields[key ?? '-1'];
}

function findSelectedVendorWithDefaultSelect(vendors: NetSuiteVendor[] | undefined, selectedVendorId: string | undefined) {
const selectedVendor = (vendors ?? []).find(({id}) => id === selectedVendorId);
return selectedVendor ?? vendors?.[0] ?? undefined;
}

function findSelectedBankAccountWithDefaultSelect(accounts: NetSuiteAccount[] | undefined, selectedBankAccountId: string | undefined) {
const selectedBankAccount = (accounts ?? []).find(({id}) => id === selectedBankAccountId);
return selectedBankAccount ?? accounts?.[0] ?? undefined;
}

function findSelectedInvoiceItemWithDefaultSelect(invoiceItems: InvoiceItem[] | undefined, selectedItemId: string | undefined) {
const selectedInvoiceItem = (invoiceItems ?? []).find(({id}) => id === selectedItemId);
return selectedInvoiceItem ?? invoiceItems?.[0] ?? undefined;
}

function findSelectedTaxAccountWithDefaultSelect(taxAccounts: NetSuiteTaxAccount[] | undefined, selectedAccountId: string | undefined) {
const selectedTaxAccount = (taxAccounts ?? []).find(({externalID}) => externalID === selectedAccountId);
return selectedTaxAccount ?? taxAccounts?.[0] ?? undefined;
}

function getNetSuiteVendorOptions(policy: Policy | undefined, selectedVendorId: string | undefined): SelectorType[] {
const vendors = policy?.connections?.netsuite.options.data.vendors ?? [];
const vendors = policy?.connections?.netsuite.options.data.vendors;

const selectedVendor = findSelectedVendorWithDefaultSelect(vendors, selectedVendorId);

return (vendors ?? []).map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedVendorId === id,
isSelected: selectedVendor?.id === id,
}));
}

function getNetSuitePayableAccountOptions(policy: Policy | undefined, selectedBankAccountId: string | undefined): SelectorType[] {
const payableAccounts = policy?.connections?.netsuite.options.data.payableList ?? [];
const payableAccounts = policy?.connections?.netsuite.options.data.payableList;

const selectedPayableAccount = findSelectedBankAccountWithDefaultSelect(payableAccounts, selectedBankAccountId);

return (payableAccounts ?? []).map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedBankAccountId === id,
isSelected: selectedPayableAccount?.id === id,
}));
}

function getNetSuiteReceivableAccountOptions(policy: Policy | undefined, selectedBankAccountId: string | undefined): SelectorType[] {
const receivableAccounts = policy?.connections?.netsuite.options.data.receivableList ?? [];
const receivableAccounts = policy?.connections?.netsuite.options.data.receivableList;

const selectedReceivableAccount = findSelectedBankAccountWithDefaultSelect(receivableAccounts, selectedBankAccountId);

return (receivableAccounts ?? []).map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedBankAccountId === id,
isSelected: selectedReceivableAccount?.id === id,
}));
}

function getNetSuiteInvoiceItemOptions(policy: Policy | undefined, selectedItemId: string | undefined): SelectorType[] {
const invoiceItems = policy?.connections?.netsuite.options.data.items ?? [];
const invoiceItems = policy?.connections?.netsuite.options.data.items;

const selectedInvoiceItem = findSelectedInvoiceItemWithDefaultSelect(invoiceItems, selectedItemId);

return (invoiceItems ?? []).map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedItemId === id,
isSelected: selectedInvoiceItem?.id === id,
}));
}

function getNetSuiteTaxAccountOptions(policy: Policy | undefined, subsidiaryCountry?: string, selectedAccountId?: string): SelectorType[] {
const taxAccounts = policy?.connections?.netsuite.options.data.taxAccountsList ?? [];
const taxAccounts = policy?.connections?.netsuite.options.data.taxAccountsList;
const accountOptions = (taxAccounts ?? []).filter(({country}) => country === subsidiaryCountry);

return (taxAccounts ?? [])
.filter(({country}) => country === subsidiaryCountry)
.map(({externalID, name}) => ({
value: externalID,
text: name,
keyForList: externalID,
isSelected: selectedAccountId === externalID,
}));
const selectedTaxAccount = findSelectedTaxAccountWithDefaultSelect(accountOptions, selectedAccountId);

return accountOptions.map(({externalID, name}) => ({
value: externalID,
text: name,
keyForList: externalID,
isSelected: selectedTaxAccount?.externalID === externalID,
}));
}

function canUseTaxNetSuite(canUseNetSuiteUSATax?: boolean, subsidiaryCountry?: string) {
Expand All @@ -614,44 +646,62 @@ function canUseProvincialTaxNetSuite(subsidiaryCountry?: string) {
return subsidiaryCountry === '_canada';
}

function getFilteredReimbursableAccountOptions(payableAccounts: NetSuiteAccount[] | undefined) {
return (payableAccounts ?? []).filter(({type}) => type === CONST.NETSUITE_ACCOUNT_TYPE.BANK || type === CONST.NETSUITE_ACCOUNT_TYPE.CREDIT_CARD);
}

function getNetSuiteReimbursableAccountOptions(policy: Policy | undefined, selectedBankAccountId: string | undefined): SelectorType[] {
const payableAccounts = policy?.connections?.netsuite.options.data.payableList ?? [];
const accountOptions = (payableAccounts ?? []).filter(({type}) => type === CONST.NETSUITE_ACCOUNT_TYPE.BANK || type === CONST.NETSUITE_ACCOUNT_TYPE.CREDIT_CARD);
const payableAccounts = policy?.connections?.netsuite.options.data.payableList;
const accountOptions = getFilteredReimbursableAccountOptions(payableAccounts);

const selectedPayableAccount = findSelectedBankAccountWithDefaultSelect(accountOptions, selectedBankAccountId);

return accountOptions.map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedBankAccountId === id,
isSelected: selectedPayableAccount?.id === id,
}));
}

function getFilteredCollectionAccountOptions(payableAccounts: NetSuiteAccount[] | undefined) {
return (payableAccounts ?? []).filter(({type}) => type === CONST.NETSUITE_ACCOUNT_TYPE.BANK);
}

function getNetSuiteCollectionAccountOptions(policy: Policy | undefined, selectedBankAccountId: string | undefined): SelectorType[] {
const payableAccounts = policy?.connections?.netsuite.options.data.payableList ?? [];
const accountOptions = (payableAccounts ?? []).filter(({type}) => type === CONST.NETSUITE_ACCOUNT_TYPE.BANK);
const payableAccounts = policy?.connections?.netsuite.options.data.payableList;
const accountOptions = getFilteredCollectionAccountOptions(payableAccounts);

const selectedPayableAccount = findSelectedBankAccountWithDefaultSelect(accountOptions, selectedBankAccountId);

return accountOptions.map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedBankAccountId === id,
isSelected: selectedPayableAccount?.id === id,
}));
}

function getFilteredApprovalAccountOptions(payableAccounts: NetSuiteAccount[] | undefined) {
return (payableAccounts ?? []).filter(({type}) => type === CONST.NETSUITE_ACCOUNT_TYPE.ACCOUNTS_PAYABLE);
}

function getNetSuiteApprovalAccountOptions(policy: Policy | undefined, selectedBankAccountId: string | undefined): SelectorType[] {
const payableAccounts = policy?.connections?.netsuite.options.data.payableList ?? [];
const payableAccounts = policy?.connections?.netsuite.options.data.payableList;
const defaultApprovalAccount: NetSuiteAccount = {
id: CONST.NETSUITE_APPROVAL_ACCOUNT_DEFAULT,
name: Localize.translateLocal('workspace.netsuite.advancedConfig.defaultApprovalAccount'),
type: CONST.NETSUITE_ACCOUNT_TYPE.ACCOUNTS_PAYABLE,
};
const accountOptions = [defaultApprovalAccount].concat((payableAccounts ?? []).filter(({type}) => type === CONST.NETSUITE_ACCOUNT_TYPE.ACCOUNTS_PAYABLE));
const accountOptions = getFilteredApprovalAccountOptions([defaultApprovalAccount].concat(payableAccounts ?? []));

const selectedPayableAccount = findSelectedBankAccountWithDefaultSelect(accountOptions, selectedBankAccountId);

return accountOptions.map(({id, name}) => ({
value: id,
text: name,
keyForList: id,
isSelected: selectedBankAccountId === id,
isSelected: selectedPayableAccount?.id === id,
}));
}

Expand Down Expand Up @@ -874,11 +924,18 @@ export {
findCurrentXeroOrganization,
getCurrentXeroOrganizationName,
getXeroBankAccountsWithDefaultSelect,
findSelectedVendorWithDefaultSelect,
findSelectedBankAccountWithDefaultSelect,
findSelectedInvoiceItemWithDefaultSelect,
findSelectedTaxAccountWithDefaultSelect,
getNetSuiteVendorOptions,
canUseTaxNetSuite,
canUseProvincialTaxNetSuite,
getFilteredReimbursableAccountOptions,
getNetSuiteReimbursableAccountOptions,
getFilteredCollectionAccountOptions,
getNetSuiteCollectionAccountOptions,
getFilteredApprovalAccountOptions,
getNetSuiteApprovalAccountOptions,
getNetSuitePayableAccountOptions,
getNetSuiteReceivableAccountOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections/NetSuiteCommands';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import {findSelectedBankAccountWithDefaultSelect, getFilteredApprovalAccountOptions, getFilteredCollectionAccountOptions, getFilteredReimbursableAccountOptions} from '@libs/PolicyUtils';
import type {DividerLineItem, MenuItem, ToggleItem} from '@pages/workspace/accounting/netsuite/types';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
Expand All @@ -27,18 +28,21 @@ function NetSuiteAdvancedPage({policy}: WithPolicyConnectionsProps) {
const {payableList} = policy?.connections?.netsuite?.options?.data ?? {};

const selectedReimbursementAccount = useMemo(
() => (payableList ?? []).find((payableAccount) => payableAccount.id === config?.reimbursementAccountID),
() => findSelectedBankAccountWithDefaultSelect(getFilteredReimbursableAccountOptions(payableList), config?.reimbursementAccountID),
[payableList, config?.reimbursementAccountID],
);
const selectedCollectionAccount = useMemo(() => (payableList ?? []).find((payableAccount) => payableAccount.id === config?.collectionAccount), [payableList, config?.collectionAccount]);
const selectedCollectionAccount = useMemo(
() => findSelectedBankAccountWithDefaultSelect(getFilteredCollectionAccountOptions(payableList), config?.collectionAccount),
[payableList, config?.collectionAccount],
);
const selectedApprovalAccount = useMemo(() => {
if (config?.approvalAccount === CONST.NETSUITE_APPROVAL_ACCOUNT_DEFAULT) {
return {
id: CONST.NETSUITE_APPROVAL_ACCOUNT_DEFAULT,
name: translate('workspace.netsuite.advancedConfig.defaultApprovalAccount'),
};
}
return (payableList ?? []).find((payableAccount) => payableAccount.id === config?.approvalAccount);
return findSelectedBankAccountWithDefaultSelect(getFilteredApprovalAccountOptions(payableList), config?.approvalAccount);
}, [config?.approvalAccount, payableList, translate]);

const menuItems: Array<MenuItem | ToggleItem | DividerLineItem> = [
Expand Down Expand Up @@ -207,7 +211,7 @@ function NetSuiteAdvancedPage({policy}: WithPolicyConnectionsProps) {
description: translate('workspace.netsuite.advancedConfig.customFormIDReimbursable'),
onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_CUSTOM_FORM_ID.getRoute(policyID, CONST.NETSUITE_EXPENSE_TYPE.REIMBURSABLE)),
brickRoadIndicator: config?.errorFields?.customFormIDOptions ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
title: config?.customFormIDOptions?.reimbursable[CONST.NETSUITE_MAP_EXPORT_DESTINATION[config.reimbursableExpensesExportDestination]],
title: config?.customFormIDOptions?.reimbursable?.[CONST.NETSUITE_MAP_EXPORT_DESTINATION[config.reimbursableExpensesExportDestination]],
pendingAction: config?.pendingFields?.customFormIDOptions,
errors: ErrorUtils.getLatestErrorField(config, CONST.NETSUITE_CONFIG.CUSTOM_FORM_ID_OPTIONS),
onCloseError: () => Policy.clearNetSuiteErrorField(policyID, CONST.NETSUITE_CONFIG.CUSTOM_FORM_ID_OPTIONS),
Expand All @@ -218,7 +222,7 @@ function NetSuiteAdvancedPage({policy}: WithPolicyConnectionsProps) {
description: translate('workspace.netsuite.advancedConfig.customFormIDNonReimbursable'),
onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_CUSTOM_FORM_ID.getRoute(policyID, CONST.NETSUITE_EXPENSE_TYPE.NON_REIMBURSABLE)),
brickRoadIndicator: config?.errorFields?.customFormIDOptions ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
title: config?.customFormIDOptions?.nonReimbursable[CONST.NETSUITE_MAP_EXPORT_DESTINATION[config.nonreimbursableExpensesExportDestination]],
title: config?.customFormIDOptions?.nonReimbursable?.[CONST.NETSUITE_MAP_EXPORT_DESTINATION[config.nonreimbursableExpensesExportDestination]],
pendingAction: config?.pendingFields?.customFormIDOptions,
errors: ErrorUtils.getLatestErrorField(config, CONST.NETSUITE_CONFIG.CUSTOM_FORM_ID_OPTIONS),
onCloseError: () => Policy.clearNetSuiteErrorField(policyID, CONST.NETSUITE_CONFIG.CUSTOM_FORM_ID_OPTIONS),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ function NetSuiteDateSelectPage({policy}: WithPolicyConnectionsProps) {
const policyID = policy?.id ?? '-1';
const styles = useThemeStyles();
const config = policy?.connections?.netsuite.options.config;
const selectedValue = Object.values(CONST.NETSUITE_EXPORT_DATE).find((value) => value === config?.exportDate) ?? CONST.NETSUITE_EXPORT_DATE.LAST_EXPENSE;
const data: MenuListItem[] = Object.values(CONST.NETSUITE_EXPORT_DATE).map((dateType) => ({
value: dateType,
text: translate(`workspace.netsuite.exportDate.values.${dateType}.label`),
alternateText: translate(`workspace.netsuite.exportDate.values.${dateType}.description`),
keyForList: dateType,
isSelected: config?.exportDate === dateType,
isSelected: selectedValue === dateType,
}));

const headerContent = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections/NetSuiteCommands';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import {canUseProvincialTaxNetSuite, canUseTaxNetSuite} from '@libs/PolicyUtils';
import {
canUseProvincialTaxNetSuite,
canUseTaxNetSuite,
findSelectedBankAccountWithDefaultSelect,
findSelectedInvoiceItemWithDefaultSelect,
findSelectedTaxAccountWithDefaultSelect,
} from '@libs/PolicyUtils';
import type {DividerLineItem, MenuItem, ToggleItem} from '@pages/workspace/accounting/netsuite/types';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
Expand All @@ -30,13 +36,13 @@ function NetSuiteExportConfigurationPage({policy}: WithPolicyConnectionsProps) {
const {subsidiaryList, receivableList, taxAccountsList, items} = policy?.connections?.netsuite?.options?.data ?? {};
const selectedSubsidiary = useMemo(() => (subsidiaryList ?? []).find((subsidiary) => subsidiary.internalID === config?.subsidiaryID), [subsidiaryList, config?.subsidiaryID]);

const selectedReceivable = useMemo(() => (receivableList ?? []).find((receivable) => receivable.id === config?.receivableAccount), [receivableList, config?.receivableAccount]);
const selectedReceivable = useMemo(() => findSelectedBankAccountWithDefaultSelect(receivableList, config?.receivableAccount), [receivableList, config?.receivableAccount]);

const selectedItem = useMemo(() => (items ?? []).find((item) => item.id === config?.invoiceItem), [items, config?.invoiceItem]);
const selectedItem = useMemo(() => findSelectedInvoiceItemWithDefaultSelect(items, config?.invoiceItem), [items, config?.invoiceItem]);

const invoiceItemValue = useMemo(() => {
if (!config?.invoiceItemPreference) {
return undefined;
return translate('workspace.netsuite.invoiceItem.values.create.label');
}
if (config.invoiceItemPreference === CONST.NETSUITE_INVOICE_ITEM_PREFERENCE.CREATE) {
return translate('workspace.netsuite.invoiceItem.values.create.label');
Expand All @@ -47,13 +53,10 @@ function NetSuiteExportConfigurationPage({policy}: WithPolicyConnectionsProps) {
return selectedItem.name;
}, [config?.invoiceItemPreference, selectedItem, translate]);

const selectedTaxPostingAccount = useMemo(
() => (taxAccountsList ?? []).find((taxAccount) => taxAccount.externalID === config?.taxPostingAccount),
[taxAccountsList, config?.taxPostingAccount],
);
const selectedTaxPostingAccount = useMemo(() => findSelectedTaxAccountWithDefaultSelect(taxAccountsList, config?.taxPostingAccount), [taxAccountsList, config?.taxPostingAccount]);

const selectedProvTaxPostingAccount = useMemo(
() => (taxAccountsList ?? []).find((taxAccount) => taxAccount.externalID === config?.provincialTaxPostingAccount),
() => findSelectedTaxAccountWithDefaultSelect(taxAccountsList, config?.provincialTaxPostingAccount),
[taxAccountsList, config?.provincialTaxPostingAccount],
);

Expand All @@ -79,7 +82,9 @@ function NetSuiteExportConfigurationPage({policy}: WithPolicyConnectionsProps) {
description: translate('common.date'),
onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_DATE_SELECT.getRoute(policyID)),
brickRoadIndicator: config?.errorFields?.exportDate ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
title: config?.exportDate ? translate(`workspace.netsuite.exportDate.values.${config.exportDate}.label`) : undefined,
title: config?.exportDate
? translate(`workspace.netsuite.exportDate.values.${config.exportDate}.label`)
: translate(`workspace.netsuite.exportDate.values.${CONST.NETSUITE_EXPORT_DATE.LAST_EXPENSE}.label`),
Comment thread
shubham1206agra marked this conversation as resolved.
pendingAction: config?.pendingFields?.exportDate,
errors: ErrorUtils.getLatestErrorField(config, CONST.NETSUITE_CONFIG.EXPORT_DATE),
onCloseError: () => Policy.clearNetSuiteErrorField(policyID, CONST.NETSUITE_CONFIG.EXPORT_DATE),
Expand Down
Loading