diff --git a/src/components/Search/SearchFiltersChatsSelector.tsx b/src/components/Search/SearchFiltersChatsSelector.tsx index 36b56867b99f..47cd2a6086d4 100644 --- a/src/components/Search/SearchFiltersChatsSelector.tsx +++ b/src/components/Search/SearchFiltersChatsSelector.tsx @@ -24,8 +24,6 @@ const defaultListOptions = { userToInvite: null, currentUserOption: null, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], headerMessage: '', }; diff --git a/src/components/Search/SearchFiltersParticipantsSelector.tsx b/src/components/Search/SearchFiltersParticipantsSelector.tsx index e7a60a5dc212..1e0c3ca8aae7 100644 --- a/src/components/Search/SearchFiltersParticipantsSelector.tsx +++ b/src/components/Search/SearchFiltersParticipantsSelector.tsx @@ -26,8 +26,6 @@ const defaultListOptions = { currentUserOption: null, headerMessage: '', categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; function getSelectedOptionData(option: Option): OptionData { diff --git a/src/components/Search/SearchRouter/SearchRouter.tsx b/src/components/Search/SearchRouter/SearchRouter.tsx index e65b12deb64b..4c57c0d1f63f 100644 --- a/src/components/Search/SearchRouter/SearchRouter.tsx +++ b/src/components/Search/SearchRouter/SearchRouter.tsx @@ -72,7 +72,7 @@ function SearchRouter({onRouterClose}: SearchRouterProps) { const {options, areOptionsInitialized} = useOptionsList(); const searchOptions = useMemo(() => { if (!areOptionsInitialized) { - return {recentReports: [], personalDetails: [], userToInvite: null, currentUserOption: null, categoryOptions: [], tagOptions: [], taxRatesOptions: []}; + return {recentReports: [], personalDetails: [], userToInvite: null, currentUserOption: null, categoryOptions: []}; } return OptionsListUtils.getSearchOptions(options, '', betas ?? []); }, [areOptionsInitialized, betas, options]); diff --git a/src/components/TaxPicker.tsx b/src/components/TaxPicker.tsx index a91965811d81..4cb92eda3f10 100644 --- a/src/components/TaxPicker.tsx +++ b/src/components/TaxPicker.tsx @@ -6,7 +6,7 @@ import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import * as IOUUtils from '@libs/IOUUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as PolicyUtils from '@libs/PolicyUtils'; +import * as TaxOptionsListUtils from '@libs/TaxOptionsListUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import type {IOUAction} from '@src/CONST'; @@ -20,11 +20,9 @@ type TaxPickerProps = { selectedTaxRate?: string; /** ID of the policy */ - // eslint-disable-next-line react/no-unused-prop-types policyID?: string; /** ID of the transaction */ - // eslint-disable-next-line react/no-unused-prop-types transactionID?: string; /** @@ -34,10 +32,9 @@ type TaxPickerProps = { insets?: EdgeInsets; /** Callback to fire when a tax is pressed */ - onSubmit: (tax: OptionsListUtils.TaxRatesOption) => void; + onSubmit: (tax: TaxOptionsListUtils.TaxRatesOption) => void; /** The action to take */ - // eslint-disable-next-line react/no-unused-prop-types action?: IOUAction; /** The type of IOU */ @@ -50,12 +47,17 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, insets, onSub const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const [searchValue, setSearchValue] = useState(''); - const policy = PolicyUtils.getPolicy(policyID); - const [draftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}` as `${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`); - const [defaultTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`); const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`); - const transaction = IOUUtils.shouldUseTransactionDraft(action) ? draftTransaction : defaultTransaction; + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + const [transaction] = useOnyx( + (() => { + if (IOUUtils.shouldUseTransactionDraft(action)) { + return `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}` as `${typeof ONYXKEYS.COLLECTION.TRANSACTION}${string}`; + } + return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`; + })(), + ); const isEditing = action === CONST.IOU.ACTION.EDIT; const isEditingSplitBill = isEditing && iouType === CONST.IOU.TYPE.SPLIT; @@ -67,7 +69,7 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, insets, onSub const shouldShowTextInput = !isTaxRatesCountBelowThreshold; - const selectedOptions = useMemo(() => { + const selectedOptions = useMemo(() => { if (!selectedTaxRate) { return []; } @@ -82,7 +84,13 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, insets, onSub }, [selectedTaxRate]); const sections = useMemo( - () => OptionsListUtils.getTaxRatesSection(policy, selectedOptions as OptionsListUtils.Tax[], searchValue, currentTransaction), + () => + TaxOptionsListUtils.getTaxRatesSection({ + policy, + searchValue, + selectedOptions, + transaction: currentTransaction, + }), [searchValue, selectedOptions, policy, currentTransaction], ); @@ -91,7 +99,7 @@ function TaxPicker({selectedTaxRate = '', policyID, transactionID, insets, onSub const selectedOptionKey = useMemo(() => sections?.at(0)?.data?.find((taxRate) => taxRate.searchText === selectedTaxRate)?.keyForList, [sections, selectedTaxRate]); const handleSelectRow = useCallback( - (newSelectedOption: OptionsListUtils.TaxRatesOption) => { + (newSelectedOption: TaxOptionsListUtils.TaxRatesOption) => { if (selectedOptionKey === newSelectedOption.keyForList) { onDismiss(); return; diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 3468bcf98b96..3308658fa735 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -26,10 +26,6 @@ import type { Report, ReportAction, ReportActions, - TaxRate, - TaxRates, - TaxRatesWithDefault, - Transaction, TransactionViolation, } from '@src/types/onyx'; import type {Attendee, Participant} from '@src/types/onyx/IOU'; @@ -52,7 +48,6 @@ import * as PolicyUtils from './PolicyUtils'; import * as ReportActionUtils from './ReportActionsUtils'; import * as ReportUtils from './ReportUtils'; import * as TaskUtils from './TaskUtils'; -import * as TransactionUtils from './TransactionUtils'; import * as UserUtils from './UserUtils'; type SearchOption = ReportUtils.OptionData & { @@ -98,23 +93,6 @@ type CategorySection = CategorySectionBase & { data: Option[]; }; -type TaxRatesOption = { - text?: string; - code?: string; - searchText?: string; - tooltipText?: string; - isDisabled?: boolean; - keyForList?: string; - isSelected?: boolean; - pendingAction?: OnyxCommon.PendingAction; -}; - -type TaxSection = { - title: string | undefined; - shouldShow: boolean; - data: TaxRatesOption[]; -}; - type CategoryTreeSection = CategorySectionBase & { data: OptionTree[]; indexOffset?: number; @@ -127,12 +105,6 @@ type Category = { pendingAction?: OnyxCommon.PendingAction; }; -type Tax = { - modifiedName: string; - isSelected?: boolean; - isDisabled?: boolean; -}; - type Hierarchy = Record; type GetOptionsConfig = { @@ -160,10 +132,6 @@ type GetOptionsConfig = { recentlyUsedCategories?: string[]; canInviteUser?: boolean; includeSelectedOptions?: boolean; - includeTaxRates?: boolean; - taxRates?: TaxRatesWithDefault; - policy?: OnyxEntry; - transaction?: OnyxEntry; transactionViolations?: OnyxCollection; includeInvoiceRooms?: boolean; includeDomainEmail?: boolean; @@ -205,7 +173,6 @@ type Options = { userToInvite: ReportUtils.OptionData | null; currentUserOption: ReportUtils.OptionData | null | undefined; categoryOptions: CategoryTreeSection[]; - taxRatesOptions: CategorySection[]; }; type PreviewConfig = {showChatPreviewLine?: boolean; forcePolicyNamePreview?: boolean; showPersonalDetails?: boolean}; @@ -1152,111 +1119,6 @@ function getCategoryListSections( return categorySections; } -/** - * Sorts tax rates alphabetically by name. - */ -function sortTaxRates(taxRates: TaxRates): TaxRate[] { - const sortedtaxRates = lodashSortBy(taxRates, (taxRate) => taxRate.name); - return sortedtaxRates; -} - -/** - * Builds the options for taxRates - */ -function getTaxRatesOptions(taxRates: Array>): TaxRatesOption[] { - return taxRates.map(({code, modifiedName, isDisabled, isSelected, pendingAction}) => ({ - code, - text: modifiedName, - keyForList: modifiedName, - searchText: modifiedName, - tooltipText: modifiedName, - isDisabled: !!isDisabled || pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, - isSelected, - pendingAction, - })); -} - -/** - * Builds the section list for tax rates - */ -function getTaxRatesSection(policy: OnyxEntry | undefined, selectedOptions: Tax[], searchInputValue: string, transaction?: OnyxEntry): TaxSection[] { - const policyRatesSections = []; - - const taxes = TransactionUtils.transformedTaxRates(policy, transaction); - - const sortedTaxRates = sortTaxRates(taxes); - const selectedOptionNames = selectedOptions.map((selectedOption) => selectedOption.modifiedName); - const enabledTaxRates = sortedTaxRates.filter((taxRate) => !taxRate.isDisabled); - const enabledTaxRatesNames = enabledTaxRates.map((tax) => tax.modifiedName); - const enabledTaxRatesWithoutSelectedOptions = enabledTaxRates.filter((tax) => tax.modifiedName && !selectedOptionNames.includes(tax.modifiedName)); - const selectedTaxRateWithDisabledState: Tax[] = []; - const numberOfTaxRates = enabledTaxRates.length; - - selectedOptions.forEach((tax) => { - if (enabledTaxRatesNames.includes(tax.modifiedName)) { - selectedTaxRateWithDisabledState.push({...tax, isDisabled: false, isSelected: true}); - return; - } - selectedTaxRateWithDisabledState.push({...tax, isDisabled: true, isSelected: true}); - }); - - // If all tax are disabled but there's a previously selected tag, show only the selected tag - if (numberOfTaxRates === 0 && selectedOptions.length > 0) { - policyRatesSections.push({ - // "Selected" sectiong - title: '', - shouldShow: false, - data: getTaxRatesOptions(selectedTaxRateWithDisabledState), - }); - - return policyRatesSections; - } - - if (searchInputValue) { - const enabledSearchTaxRates = enabledTaxRatesWithoutSelectedOptions.filter((taxRate) => taxRate.modifiedName?.toLowerCase().includes(searchInputValue.toLowerCase())); - const selectedSearchTags = selectedTaxRateWithDisabledState.filter((taxRate) => taxRate.modifiedName?.toLowerCase().includes(searchInputValue.toLowerCase())); - const taxesForSearch = [...selectedSearchTags, ...enabledSearchTaxRates]; - - policyRatesSections.push({ - // "Search" section - title: '', - shouldShow: true, - data: getTaxRatesOptions(taxesForSearch), - }); - - return policyRatesSections; - } - - if (numberOfTaxRates < CONST.STANDARD_LIST_ITEM_LIMIT) { - policyRatesSections.push({ - // "All" section when items amount less than the threshold - title: '', - shouldShow: false, - data: getTaxRatesOptions([...selectedTaxRateWithDisabledState, ...enabledTaxRatesWithoutSelectedOptions]), - }); - - return policyRatesSections; - } - - if (selectedOptions.length > 0) { - policyRatesSections.push({ - // "Selected" section - title: '', - shouldShow: true, - data: getTaxRatesOptions(selectedTaxRateWithDisabledState), - }); - } - - policyRatesSections.push({ - // "All" section when number of items are more than the threshold - title: '', - shouldShow: true, - data: getTaxRatesOptions(enabledTaxRatesWithoutSelectedOptions), - }); - - return policyRatesSections; -} - /** * Checks if a report option is selected based on matching accountID or reportID. * @@ -1488,9 +1350,6 @@ function getOptions( canInviteUser = true, includeSelectedOptions = false, transactionViolations = {}, - includeTaxRates, - policy, - transaction, includeSelfDM = false, includeInvoiceRooms = false, includeDomainEmail = false, @@ -1508,20 +1367,6 @@ function getOptions( userToInvite: null, currentUserOption: null, categoryOptions, - taxRatesOptions: [], - }; - } - - if (includeTaxRates) { - const taxRatesOptions = getTaxRatesSection(policy, selectedOptions as Tax[], searchInputValue, transaction); - - return { - recentReports: [], - personalDetails: [], - userToInvite: null, - currentUserOption: null, - categoryOptions: [], - taxRatesOptions, }; } @@ -1781,7 +1626,6 @@ function getOptions( userToInvite: canInviteUser ? userToInvite : null, currentUserOption, categoryOptions: [], - taxRatesOptions: [], }; } @@ -1869,8 +1713,6 @@ type FilteredOptionsParams = { recentlyUsedCategories?: string[]; canInviteUser?: boolean; includeSelectedOptions?: boolean; - includeTaxRates?: boolean; - taxRates?: TaxRatesWithDefault; maxRecentReportsToShow?: number; includeSelfDM?: boolean; includeInvoiceRooms?: boolean; @@ -1904,9 +1746,7 @@ function getFilteredOptions(params: FilteredOptionsParamsWithDefaultSearchValue recentlyUsedCategories = [], canInviteUser = true, includeSelectedOptions = false, - includeTaxRates = false, maxRecentReportsToShow = CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW, - taxRates = {} as TaxRatesWithDefault, includeSelfDM = false, includeInvoiceRooms = false, action, @@ -1928,8 +1768,6 @@ function getFilteredOptions(params: FilteredOptionsParamsWithDefaultSearchValue recentlyUsedCategories, canInviteUser, includeSelectedOptions, - includeTaxRates, - taxRates, includeSelfDM, includeInvoiceRooms, action, @@ -1966,9 +1804,7 @@ function getAttendeeOptions( recentlyUsedCategories: [], canInviteUser, includeSelectedOptions: false, - includeTaxRates: false, maxRecentReportsToShow: 0, - taxRates: {} as TaxRatesWithDefault, includeSelfDM: false, includeInvoiceRooms, action, @@ -2264,7 +2100,6 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt userToInvite: null, currentUserOption, categoryOptions: [], - taxRatesOptions: [], }; }, options); @@ -2301,7 +2136,6 @@ function filterOptions(options: Options, searchInputValue: string, config?: Filt userToInvite, currentUserOption: matchResults.currentUserOption, categoryOptions: [], - taxRatesOptions: [], }; } @@ -2316,7 +2150,6 @@ function getEmptyOptions(): Options { userToInvite: null, currentUserOption: null, categoryOptions: [], - taxRatesOptions: [], }; } @@ -2359,7 +2192,6 @@ export { createOptionList, createOptionFromReport, getReportOption, - getTaxRatesSection, getFirstKeyForList, canCreateOptimisticPersonalDetailOption, getUserToInviteOption, @@ -2372,4 +2204,4 @@ export { hasReportErrors, }; -export type {MemberForList, CategorySection, CategoryTreeSection, Options, OptionList, SearchOption, PayeePersonalDetails, Category, Tax, TaxRatesOption, Option, OptionTree}; +export type {MemberForList, CategorySection, CategoryTreeSection, Options, OptionList, SearchOption, PayeePersonalDetails, Category, Option, OptionTree}; diff --git a/src/libs/TaxOptionsListUtils.ts b/src/libs/TaxOptionsListUtils.ts new file mode 100644 index 000000000000..12c911d4e600 --- /dev/null +++ b/src/libs/TaxOptionsListUtils.ts @@ -0,0 +1,147 @@ +import lodashSortBy from 'lodash/sortBy'; +import type {OnyxEntry} from 'react-native-onyx'; +import CONST from '@src/CONST'; +import type {Policy, TaxRate, TaxRates, Transaction} from '@src/types/onyx'; +import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; +import * as TransactionUtils from './TransactionUtils'; + +type TaxRatesOption = { + text?: string; + code?: string; + searchText?: string; + tooltipText?: string; + isDisabled?: boolean; + keyForList?: string; + isSelected?: boolean; + pendingAction?: OnyxCommon.PendingAction; +}; + +type Tax = { + modifiedName: string; + isSelected?: boolean; + isDisabled?: boolean; +}; + +type TaxSection = { + title: string | undefined; + shouldShow: boolean; + data: TaxRatesOption[]; +}; + +/** + * Sorts tax rates alphabetically by name. + */ +function sortTaxRates(taxRates: TaxRates): TaxRate[] { + const sortedtaxRates = lodashSortBy(taxRates, (taxRate) => taxRate.name); + return sortedtaxRates; +} + +/** + * Builds the options for taxRates + */ +function getTaxRatesOptions(taxRates: Array>): TaxRatesOption[] { + return taxRates.map(({code, modifiedName, isDisabled, isSelected, pendingAction}) => ({ + code, + text: modifiedName, + keyForList: modifiedName, + searchText: modifiedName, + tooltipText: modifiedName, + isDisabled: !!isDisabled || pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + isSelected, + pendingAction, + })); +} + +/** + * Builds the section list for tax rates + */ +function getTaxRatesSection({ + policy, + searchValue, + selectedOptions = [], + transaction, +}: { + policy: OnyxEntry | undefined; + searchValue: string; + selectedOptions?: Tax[]; + transaction?: OnyxEntry; +}): TaxSection[] { + const policyRatesSections = []; + + const taxes = TransactionUtils.transformedTaxRates(policy, transaction); + + const sortedTaxRates = sortTaxRates(taxes); + const selectedOptionNames = selectedOptions.map((selectedOption) => selectedOption.modifiedName); + const enabledTaxRates = sortedTaxRates.filter((taxRate) => !taxRate.isDisabled); + const enabledTaxRatesNames = enabledTaxRates.map((tax) => tax.modifiedName); + const enabledTaxRatesWithoutSelectedOptions = enabledTaxRates.filter((tax) => tax.modifiedName && !selectedOptionNames.includes(tax.modifiedName)); + const selectedTaxRateWithDisabledState: Tax[] = []; + const numberOfTaxRates = enabledTaxRates.length; + + selectedOptions.forEach((tax) => { + if (enabledTaxRatesNames.includes(tax.modifiedName)) { + selectedTaxRateWithDisabledState.push({...tax, isDisabled: false, isSelected: true}); + return; + } + selectedTaxRateWithDisabledState.push({...tax, isDisabled: true, isSelected: true}); + }); + + // If all tax are disabled but there's a previously selected tag, show only the selected tag + if (numberOfTaxRates === 0 && selectedOptions.length > 0) { + policyRatesSections.push({ + // "Selected" sectiong + title: '', + shouldShow: false, + data: getTaxRatesOptions(selectedTaxRateWithDisabledState), + }); + + return policyRatesSections; + } + + if (searchValue) { + const enabledSearchTaxRates = enabledTaxRatesWithoutSelectedOptions.filter((taxRate) => taxRate.modifiedName?.toLowerCase().includes(searchValue.toLowerCase())); + const selectedSearchTags = selectedTaxRateWithDisabledState.filter((taxRate) => taxRate.modifiedName?.toLowerCase().includes(searchValue.toLowerCase())); + const taxesForSearch = [...selectedSearchTags, ...enabledSearchTaxRates]; + + policyRatesSections.push({ + // "Search" section + title: '', + shouldShow: true, + data: getTaxRatesOptions(taxesForSearch), + }); + + return policyRatesSections; + } + + if (numberOfTaxRates < CONST.STANDARD_LIST_ITEM_LIMIT) { + policyRatesSections.push({ + // "All" section when items amount less than the threshold + title: '', + shouldShow: false, + data: getTaxRatesOptions([...selectedTaxRateWithDisabledState, ...enabledTaxRatesWithoutSelectedOptions]), + }); + + return policyRatesSections; + } + + if (selectedOptions.length > 0) { + policyRatesSections.push({ + // "Selected" section + title: '', + shouldShow: true, + data: getTaxRatesOptions(selectedTaxRateWithDisabledState), + }); + } + + policyRatesSections.push({ + // "All" section when number of items are more than the threshold + title: '', + shouldShow: true, + data: getTaxRatesOptions(enabledTaxRatesWithoutSelectedOptions), + }); + + return policyRatesSections; +} + +export {getTaxRatesSection, sortTaxRates, getTaxRatesOptions}; +export type {TaxRatesOption, Tax, TaxSection}; diff --git a/src/pages/RoomInvitePage.tsx b/src/pages/RoomInvitePage.tsx index c833fdb68ae6..3fafc163e5ff 100644 --- a/src/pages/RoomInvitePage.tsx +++ b/src/pages/RoomInvitePage.tsx @@ -72,7 +72,7 @@ function RoomInvitePage({ const defaultOptions = useMemo(() => { if (!areOptionsInitialized) { - return {recentReports: [], personalDetails: [], userToInvite: null, currentUserOption: null, categoryOptions: [], tagOptions: [], taxRatesOptions: []}; + return {recentReports: [], personalDetails: [], userToInvite: null, currentUserOption: null, categoryOptions: []}; } const inviteOptions = OptionsListUtils.getMemberInviteOptions(options.personalDetails, betas ?? [], '', excludedUsers); @@ -96,8 +96,6 @@ function RoomInvitePage({ recentReports: [], currentUserOption: null, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; }, [areOptionsInitialized, betas, excludedUsers, options.personalDetails, selectedOptions]); diff --git a/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx b/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx index 8732efd2e72d..ca655caea123 100644 --- a/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx +++ b/src/pages/iou/request/MoneyRequestAttendeeSelector.tsx @@ -114,8 +114,6 @@ function MoneyRequestAttendeeSelector({attendees = [], onFinish, onAttendeesAdde currentUserOption: null, headerMessage: '', categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; } const newOptions = OptionsListUtils.filterOptions(defaultOptions, debouncedSearchTerm, { diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index 4478951555ef..a17cffd0cdd9 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -103,8 +103,6 @@ function MoneyRequestParticipantsSelector({ currentUserOption: null, headerMessage: '', categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; } @@ -140,8 +138,6 @@ function MoneyRequestParticipantsSelector({ currentUserOption: null, headerMessage: '', categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; } diff --git a/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx b/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx index 7fedc09e2abe..ccc2ed2ee45f 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx +++ b/src/pages/iou/request/step/IOURequestStepTaxRatePage.tsx @@ -1,40 +1,28 @@ import React from 'react'; import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import TaxPicker from '@components/TaxPicker'; import useLocalize from '@hooks/useLocalize'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; -import type {TaxRatesOption} from '@libs/OptionsListUtils'; +import type {TaxRatesOption} from '@libs/TaxOptionsListUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import {getCurrency} from '@libs/TransactionUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; -import type {Policy, PolicyCategories, PolicyTagLists, Transaction} from '@src/types/onyx'; +import type {Policy, Transaction} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import StepScreenWrapper from './StepScreenWrapper'; import withFullTransactionOrNotFound from './withFullTransactionOrNotFound'; import withWritableReportOrNotFound from './withWritableReportOrNotFound'; import type {WithWritableReportOrNotFoundProps} from './withWritableReportOrNotFound'; -type IOURequestStepTaxRatePageOnyxProps = { - policy: OnyxEntry; - policyCategories: OnyxEntry; - - /** Collection of tag list on a policy */ - policyTags: OnyxEntry; - - /** The draft transaction that holds data to be persisted on the current transaction */ - splitDraftTransaction: OnyxEntry; +type IOURequestStepTaxRatePageProps = WithWritableReportOrNotFoundProps & { + transaction: OnyxEntry; }; -type IOURequestStepTaxRatePageProps = IOURequestStepTaxRatePageOnyxProps & - WithWritableReportOrNotFoundProps & { - transaction: OnyxEntry; - }; - function getTaxAmount(policy: OnyxEntry, transaction: OnyxEntry, selectedTaxCode: string, amount: number): number | undefined { const getTaxValue = (taxCode: string) => TransactionUtils.getTaxValue(policy, transaction, taxCode); const taxPercentage = getTaxValue(selectedTaxCode); @@ -45,17 +33,18 @@ function getTaxAmount(policy: OnyxEntry, transaction: OnyxEntry({ - splitDraftTransaction: { - key: ({route}) => { - const transactionID = route.params.transactionID ?? 0; - return `${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`; - }, - }, - policy: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '-1'}`, - }, - policyCategories: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${report ? report.policyID : '-1'}`, - }, - policyTags: { - key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${report ? report.policyID : '-1'}`, - }, -})(IOURequestStepTaxRatePage); - // eslint-disable-next-line rulesdir/no-negated-variables -const IOURequestStepTaxRatePageWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepTaxRatePageWithOnyx); +const IOURequestStepTaxRatePageWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepTaxRatePage); // eslint-disable-next-line rulesdir/no-negated-variables const IOURequestStepTaxRatePageWithFullTransactionOrNotFound = withFullTransactionOrNotFound(IOURequestStepTaxRatePageWithWritableReportOrNotFound); diff --git a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx index 3f5db6cf5613..cd4674ce0165 100644 --- a/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx +++ b/src/pages/settings/AboutPage/ShareLogList/BaseShareLogList.tsx @@ -35,8 +35,6 @@ function BaseShareLogList({onAttachLogToReport}: BaseShareLogListProps) { userToInvite: null, currentUserOption: null, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], headerMessage: '', }; } diff --git a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx index a6ed5ca1b53e..6f54fc098633 100644 --- a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx +++ b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx @@ -51,8 +51,6 @@ function useOptions() { currentUserOption, headerMessage, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; }, [optionsList.reports, optionsList.personalDetails, betas, existingDelegates, isLoading]); diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.tsx b/src/pages/tasks/TaskAssigneeSelectorModal.tsx index 59ebe08e41a4..33ca336206fe 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.tsx +++ b/src/pages/tasks/TaskAssigneeSelectorModal.tsx @@ -63,8 +63,6 @@ function useOptions() { currentUserOption, headerMessage, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], }; }, [optionsList.reports, optionsList.personalDetails, betas, isLoading]); diff --git a/src/pages/tasks/TaskShareDestinationSelectorModal.tsx b/src/pages/tasks/TaskShareDestinationSelectorModal.tsx index 8cd38a54f7f9..8465474ef609 100644 --- a/src/pages/tasks/TaskShareDestinationSelectorModal.tsx +++ b/src/pages/tasks/TaskShareDestinationSelectorModal.tsx @@ -64,8 +64,6 @@ function TaskShareDestinationSelectorModal() { userToInvite: null, currentUserOption: null, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], header: '', }; } @@ -78,8 +76,6 @@ function TaskShareDestinationSelectorModal() { userToInvite: null, currentUserOption: null, categoryOptions: [], - tagOptions: [], - taxRatesOptions: [], header, }; }, [areOptionsInitialized, optionList.personalDetails, optionList.reports]); diff --git a/src/pages/workspace/WorkspaceInvitePage.tsx b/src/pages/workspace/WorkspaceInvitePage.tsx index 3e63ae7cbe79..a259fc7b9ce1 100644 --- a/src/pages/workspace/WorkspaceInvitePage.tsx +++ b/src/pages/workspace/WorkspaceInvitePage.tsx @@ -87,12 +87,12 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) { const defaultOptions = useMemo(() => { if (!areOptionsInitialized) { - return {recentReports: [], personalDetails: [], userToInvite: null, currentUserOption: null, categoryOptions: [], tagOptions: [], taxRatesOptions: []}; + return {recentReports: [], personalDetails: [], userToInvite: null, currentUserOption: null, categoryOptions: []}; } const inviteOptions = OptionsListUtils.getMemberInviteOptions(options.personalDetails, betas ?? [], '', excludedUsers, true); - return {...inviteOptions, recentReports: [], currentUserOption: null, categoryOptions: [], tagOptions: [], taxRatesOptions: []}; + return {...inviteOptions, recentReports: [], currentUserOption: null, categoryOptions: []}; }, [areOptionsInitialized, betas, excludedUsers, options.personalDetails]); const inviteOptions = useMemo( diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRateTaxRateEditPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRateTaxRateEditPage.tsx index 718b5953f3ac..a48dd6e0cd53 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRateTaxRateEditPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRateTaxRateEditPage.tsx @@ -6,8 +6,8 @@ import TaxPicker from '@components/TaxPicker'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; -import type * as OptionsListUtils from '@libs/OptionsListUtils'; import {getDistanceRateCustomUnit} from '@libs/PolicyUtils'; +import type * as TaxOptionsListUtils from '@libs/TaxOptionsListUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; @@ -30,7 +30,7 @@ function PolicyDistanceRateTaxRateEditPage({route, policy}: PolicyDistanceRateTa const taxRateExternalID = rate?.attributes?.taxRateExternalID; const selectedTaxRate = TransactionUtils.getWorkspaceTaxesSettingsName(policy, taxRateExternalID ?? ''); - const onTaxRateChange = (newTaxRate: OptionsListUtils.TaxRatesOption) => { + const onTaxRateChange = (newTaxRate: TaxOptionsListUtils.TaxRatesOption) => { if (taxRateExternalID === newTaxRate.code) { Navigation.goBack(); return; diff --git a/src/pages/workspace/taxes/WorkspaceTaxesSettingsForeignCurrency.tsx b/src/pages/workspace/taxes/WorkspaceTaxesSettingsForeignCurrency.tsx index 2e40667c1daf..ac8ddcd34c0e 100644 --- a/src/pages/workspace/taxes/WorkspaceTaxesSettingsForeignCurrency.tsx +++ b/src/pages/workspace/taxes/WorkspaceTaxesSettingsForeignCurrency.tsx @@ -8,7 +8,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; -import type * as OptionsListUtils from '@libs/OptionsListUtils'; +import type * as TaxOptionsListUtils from '@libs/TaxOptionsListUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; @@ -33,7 +33,7 @@ function WorkspaceTaxesSettingsForeignCurrency({ const selectedTaxRate = TransactionUtils.getWorkspaceTaxesSettingsName(policy, foreignTaxDefault); - const submit = (taxes: OptionsListUtils.TaxRatesOption) => { + const submit = (taxes: TaxOptionsListUtils.TaxRatesOption) => { setForeignCurrencyDefault(policyID, taxes.code ?? ''); Navigation.goBack(ROUTES.WORKSPACE_TAXES_SETTINGS.getRoute(policyID)); }; diff --git a/src/pages/workspace/taxes/WorkspaceTaxesSettingsWorkspaceCurrency.tsx b/src/pages/workspace/taxes/WorkspaceTaxesSettingsWorkspaceCurrency.tsx index c46efe3fd243..0a82d7c21a24 100644 --- a/src/pages/workspace/taxes/WorkspaceTaxesSettingsWorkspaceCurrency.tsx +++ b/src/pages/workspace/taxes/WorkspaceTaxesSettingsWorkspaceCurrency.tsx @@ -8,7 +8,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; -import type * as OptionsListUtils from '@libs/OptionsListUtils'; +import type * as TaxOptionsListUtils from '@libs/TaxOptionsListUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; @@ -33,7 +33,7 @@ function WorkspaceTaxesSettingsWorkspaceCurrency({ const defaultExternalID = policy?.taxRates?.defaultExternalID ?? ''; const selectedTaxRate = policy?.taxRates && TransactionUtils.getWorkspaceTaxesSettingsName(policy, defaultExternalID); - const submit = (taxes: OptionsListUtils.TaxRatesOption) => { + const submit = (taxes: TaxOptionsListUtils.TaxRatesOption) => { setWorkspaceCurrencyDefault(policyID, taxes.code ?? ''); Navigation.goBack(ROUTES.WORKSPACE_TAXES_SETTINGS.getRoute(policyID)); }; diff --git a/tests/unit/OptionsListUtilsTest.ts b/tests/unit/OptionsListUtilsTest.ts index d4d66fd1fd62..d71b5522e11b 100644 --- a/tests/unit/OptionsListUtilsTest.ts +++ b/tests/unit/OptionsListUtilsTest.ts @@ -6,7 +6,7 @@ import CONST from '@src/CONST'; import * as OptionsListUtils from '@src/libs/OptionsListUtils'; import * as ReportUtils from '@src/libs/ReportUtils'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PersonalDetails, Policy, PolicyCategories, Report, TaxRatesWithDefault, Transaction} from '@src/types/onyx'; +import type {PersonalDetails, Policy, PolicyCategories, Report} from '@src/types/onyx'; import type {PendingAction} from '@src/types/onyx/OnyxCommon'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; @@ -1885,125 +1885,6 @@ describe('OptionsListUtils', () => { expect(OptionsListUtils.sortCategories(categoriesIncorrectOrdering3)).toStrictEqual(result3); }); - it('getFilteredOptions() for taxRate', () => { - const search = 'rate'; - const emptySearch = ''; - const wrongSearch = 'bla bla'; - - const taxRatesWithDefault: TaxRatesWithDefault = { - name: 'Tax', - defaultExternalID: 'CODE1', - defaultValue: '0%', - foreignTaxDefault: 'CODE1', - taxes: { - CODE2: { - name: 'Tax rate 2', - value: '3%', - code: 'CODE2', - modifiedName: 'Tax rate 2 (3%)', - pendingAction: 'delete', - }, - CODE3: { - name: 'Tax option 3', - value: '5%', - code: 'CODE3', - modifiedName: 'Tax option 3 (5%)', - pendingAction: undefined, - }, - CODE1: { - name: 'Tax exempt 1', - value: '0%', - code: 'CODE1', - modifiedName: 'Tax exempt 1 (0%) • Default', - pendingAction: undefined, - }, - }, - }; - const policy = { - taxRates: taxRatesWithDefault, - } as Policy; - - const transaction = { - taxCode: 'CODE1', - } as Transaction; - - const resultList: OptionsListUtils.CategorySection[] = [ - { - data: [ - { - code: 'CODE1', - isDisabled: false, - isSelected: undefined, - keyForList: 'Tax exempt 1 (0%) • Default', - searchText: 'Tax exempt 1 (0%) • Default', - text: 'Tax exempt 1 (0%) • Default', - tooltipText: 'Tax exempt 1 (0%) • Default', - pendingAction: undefined, - }, - { - code: 'CODE3', - isDisabled: false, - isSelected: undefined, - keyForList: 'Tax option 3 (5%)', - searchText: 'Tax option 3 (5%)', - text: 'Tax option 3 (5%)', - tooltipText: 'Tax option 3 (5%)', - pendingAction: undefined, - }, - { - code: 'CODE2', - isDisabled: true, - isSelected: undefined, - keyForList: 'Tax rate 2 (3%)', - searchText: 'Tax rate 2 (3%)', - text: 'Tax rate 2 (3%)', - tooltipText: 'Tax rate 2 (3%)', - pendingAction: 'delete', - }, - ], - shouldShow: false, - title: '', - }, - ]; - - const searchResultList: OptionsListUtils.CategorySection[] = [ - { - data: [ - { - code: 'CODE2', - isDisabled: true, - isSelected: undefined, - keyForList: 'Tax rate 2 (3%)', - searchText: 'Tax rate 2 (3%)', - text: 'Tax rate 2 (3%)', - tooltipText: 'Tax rate 2 (3%)', - pendingAction: 'delete', - }, - ], - shouldShow: true, - title: '', - }, - ]; - - const wrongSearchResultList: OptionsListUtils.CategorySection[] = [ - { - data: [], - shouldShow: true, - title: '', - }, - ]; - - const result = OptionsListUtils.getTaxRatesSection(policy, [], emptySearch, transaction); - - expect(result).toStrictEqual(resultList); - - const searchResult = OptionsListUtils.getTaxRatesSection(policy, [], search, transaction); - expect(searchResult).toStrictEqual(searchResultList); - - const wrongSearchResult = OptionsListUtils.getTaxRatesSection(policy, [], wrongSearch, transaction); - expect(wrongSearchResult).toStrictEqual(wrongSearchResultList); - }); - it('formatMemberForList()', () => { const formattedMembers = Object.values(PERSONAL_DETAILS).map((personalDetail) => OptionsListUtils.formatMemberForList(personalDetail)); diff --git a/tests/unit/TaxOptionsListUtilsTest.ts b/tests/unit/TaxOptionsListUtilsTest.ts new file mode 100644 index 000000000000..255cedd7c7d5 --- /dev/null +++ b/tests/unit/TaxOptionsListUtilsTest.ts @@ -0,0 +1,136 @@ +import type {CategorySection} from '@libs/OptionsListUtils'; +import * as TaxOptionsListUtils from '@libs/TaxOptionsListUtils'; +import type {Policy, TaxRatesWithDefault, Transaction} from '@src/types/onyx'; + +describe('TaxOptionsListUtils', () => { + it('getTaxRatesSection()', () => { + const search = 'rate'; + const emptySearch = ''; + const wrongSearch = 'bla bla'; + + const taxRatesWithDefault: TaxRatesWithDefault = { + name: 'Tax', + defaultExternalID: 'CODE1', + defaultValue: '0%', + foreignTaxDefault: 'CODE1', + taxes: { + CODE2: { + name: 'Tax rate 2', + value: '3%', + code: 'CODE2', + modifiedName: 'Tax rate 2 (3%)', + pendingAction: 'delete', + }, + CODE3: { + name: 'Tax option 3', + value: '5%', + code: 'CODE3', + modifiedName: 'Tax option 3 (5%)', + pendingAction: undefined, + }, + CODE1: { + name: 'Tax exempt 1', + value: '0%', + code: 'CODE1', + modifiedName: 'Tax exempt 1 (0%) • Default', + pendingAction: undefined, + }, + }, + }; + const policy = { + taxRates: taxRatesWithDefault, + } as Policy; + + const transaction = { + taxCode: 'CODE1', + } as Transaction; + + const resultList: CategorySection[] = [ + { + data: [ + { + code: 'CODE1', + isDisabled: false, + isSelected: undefined, + keyForList: 'Tax exempt 1 (0%) • Default', + searchText: 'Tax exempt 1 (0%) • Default', + text: 'Tax exempt 1 (0%) • Default', + tooltipText: 'Tax exempt 1 (0%) • Default', + pendingAction: undefined, + }, + { + code: 'CODE3', + isDisabled: false, + isSelected: undefined, + keyForList: 'Tax option 3 (5%)', + searchText: 'Tax option 3 (5%)', + text: 'Tax option 3 (5%)', + tooltipText: 'Tax option 3 (5%)', + pendingAction: undefined, + }, + { + code: 'CODE2', + isDisabled: true, + isSelected: undefined, + keyForList: 'Tax rate 2 (3%)', + searchText: 'Tax rate 2 (3%)', + text: 'Tax rate 2 (3%)', + tooltipText: 'Tax rate 2 (3%)', + pendingAction: 'delete', + }, + ], + shouldShow: false, + title: '', + }, + ]; + + const searchResultList: CategorySection[] = [ + { + data: [ + { + code: 'CODE2', + isDisabled: true, + isSelected: undefined, + keyForList: 'Tax rate 2 (3%)', + searchText: 'Tax rate 2 (3%)', + text: 'Tax rate 2 (3%)', + tooltipText: 'Tax rate 2 (3%)', + pendingAction: 'delete', + }, + ], + shouldShow: true, + title: '', + }, + ]; + + const wrongSearchResultList: CategorySection[] = [ + { + data: [], + shouldShow: true, + title: '', + }, + ]; + + const result = TaxOptionsListUtils.getTaxRatesSection({ + policy, + searchValue: emptySearch, + transaction, + }); + + expect(result).toStrictEqual(resultList); + + const searchResult = TaxOptionsListUtils.getTaxRatesSection({ + policy, + searchValue: search, + transaction, + }); + expect(searchResult).toStrictEqual(searchResultList); + + const wrongSearchResult = TaxOptionsListUtils.getTaxRatesSection({ + policy, + searchValue: wrongSearch, + transaction, + }); + expect(wrongSearchResult).toStrictEqual(wrongSearchResultList); + }); +});