From 2a031a04d73bbb8b9e0b421358a7a76a5fbf2720 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 8 Nov 2024 22:04:11 +0530 Subject: [PATCH 1/5] Feature: Per Diem Rates Settings Page --- src/ROUTES.ts | 4 + src/SCREENS.ts | 1 + .../CategorySelectorModal.tsx | 0 .../CategorySelector/index.tsx | 0 src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- src/libs/API/types.ts | 2 + .../ModalStackNavigators/index.tsx | 1 + .../FULL_SCREEN_TO_RHP_MAPPING.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 3 + src/libs/Navigation/types.ts | 3 + src/libs/actions/Policy/Category.ts | 55 +++++++++ src/libs/actions/Policy/PerDiem.ts | 13 ++- .../PolicyDistanceRatesSettingsPage.tsx | 4 +- .../perDiem/WorkspacePerDiemPage.tsx | 5 +- .../perDiem/WorkspacePerDiemSettingsPage.tsx | 104 ++++++++++++++++++ 16 files changed, 192 insertions(+), 8 deletions(-) rename src/{pages/workspace/distanceRates => components}/CategorySelector/CategorySelectorModal.tsx (100%) rename src/{pages/workspace/distanceRates => components}/CategorySelector/index.tsx (100%) create mode 100644 src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index cd94035e0fff..da1f489f6164 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1277,6 +1277,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/per-diem', getRoute: (policyID: string) => `settings/workspaces/${policyID}/per-diem` as const, }, + WORKSPACE_PER_DIEM_SETTINGS: { + route: 'settings/workspaces/:policyID/per-diem/settings', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/per-diem/settings` as const, + }, RULES_CUSTOM_NAME: { route: 'settings/workspaces/:policyID/rules/name', getRoute: (policyID: string) => `settings/workspaces/${policyID}/rules/name` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 9b8fe54111cf..061903e0a876 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -543,6 +543,7 @@ const SCREENS = { RULES_MAX_EXPENSE_AGE: 'Rules_Max_Expense_Age', RULES_BILLABLE_DEFAULT: 'Rules_Billable_Default', PER_DIEM: 'Per_Diem', + PER_DIEM_SETTINGS: 'Per_Diem_Settings', }, EDIT_REQUEST: { diff --git a/src/pages/workspace/distanceRates/CategorySelector/CategorySelectorModal.tsx b/src/components/CategorySelector/CategorySelectorModal.tsx similarity index 100% rename from src/pages/workspace/distanceRates/CategorySelector/CategorySelectorModal.tsx rename to src/components/CategorySelector/CategorySelectorModal.tsx diff --git a/src/pages/workspace/distanceRates/CategorySelector/index.tsx b/src/components/CategorySelector/index.tsx similarity index 100% rename from src/pages/workspace/distanceRates/CategorySelector/index.tsx rename to src/components/CategorySelector/index.tsx diff --git a/src/languages/en.ts b/src/languages/en.ts index 221b718a7699..35a81fa89cc8 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2430,6 +2430,7 @@ const translations = { return 'Member'; } }, + defaultCategory: 'Default category', }, perDiem: { subtitle: 'Set per diem rates to control daily employee spend. ', @@ -3973,7 +3974,6 @@ const translations = { unit: 'Unit', taxFeatureNotEnabledMessage: 'Taxes must be enabled on the workspace to use this feature. Head over to ', changePromptMessage: ' to make that change.', - defaultCategory: 'Default category', deleteDistanceRate: 'Delete distance rate', areYouSureDelete: () => ({ one: 'Are you sure you want to delete this rate?', diff --git a/src/languages/es.ts b/src/languages/es.ts index 1db2cd23011e..343634b2815d 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2453,6 +2453,7 @@ const translations = { return 'Miembro'; } }, + defaultCategory: 'Categoría predeterminada', }, perDiem: { subtitle: 'Establece las tasas per diem para controlar los gastos diarios de los empleados. ', @@ -4017,7 +4018,6 @@ const translations = { unit: 'Unidad', taxFeatureNotEnabledMessage: 'Los impuestos deben estar activados en el área de trabajo para poder utilizar esta función. Dirígete a ', changePromptMessage: ' para hacer ese cambio.', - defaultCategory: 'Categoría predeterminada', deleteDistanceRate: 'Eliminar tasa de distancia', areYouSureDelete: () => ({ one: '¿Estás seguro de que quieres eliminar esta tasa?', diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index b8b4bb749701..a8847545fbb3 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -288,6 +288,7 @@ const WRITE_COMMANDS = { ADD_BILLING_CARD_AND_REQUEST_WORKSPACE_OWNER_CHANGE: 'AddBillingCardAndRequestPolicyOwnerChange', SET_POLICY_DISTANCE_RATES_UNIT: 'SetPolicyDistanceRatesUnit', SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY: 'SetPolicyDistanceRatesDefaultCategory', + SET_POLICY_PER_DIEM_RATES_DEFAULT_CATEGORY: 'SetPolicyPerDiemRatesDefaultCategory', ENABLE_DISTANCE_REQUEST_TAX: 'EnableDistanceRequestTax', UPDATE_POLICY_DISTANCE_RATE_VALUE: 'UpdatePolicyDistanceRateValue', UPDATE_POLICY_DISTANCE_TAX_RATE_VALUE: 'UpdateDistanceTaxRate', @@ -692,6 +693,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_POLICY_TAX_CODE]: Parameters.UpdatePolicyTaxCodeParams; [WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_UNIT]: Parameters.SetPolicyDistanceRatesUnitParams; [WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams; + [WRITE_COMMANDS.SET_POLICY_PER_DIEM_RATES_DEFAULT_CATEGORY]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams; [WRITE_COMMANDS.ENABLE_DISTANCE_REQUEST_TAX]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams; [WRITE_COMMANDS.REPORT_EXPORT]: Parameters.ReportExportParams; [WRITE_COMMANDS.MARK_AS_EXPORTED]: Parameters.MarkAsExportedParams; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 8a64424c8f7d..fb8178cc0bd3 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -566,6 +566,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/rules/RulesMaxExpenseAmountPage').default, [SCREENS.WORKSPACE.RULES_MAX_EXPENSE_AGE]: () => require('../../../../pages/workspace/rules/RulesMaxExpenseAgePage').default, [SCREENS.WORKSPACE.RULES_BILLABLE_DEFAULT]: () => require('../../../../pages/workspace/rules/RulesBillableDefaultPage').default, + [SCREENS.WORKSPACE.PER_DIEM_SETTINGS]: () => require('../../../../pages/workspace/perDiem/WorkspacePerDiemSettingsPage').default, }); const EnablePaymentsStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index d282bab770c6..c8309ba70ea9 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -243,6 +243,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.RULES_MAX_EXPENSE_AGE, SCREENS.WORKSPACE.RULES_BILLABLE_DEFAULT, ], + [SCREENS.WORKSPACE.PER_DIEM]: [SCREENS.WORKSPACE.PER_DIEM_SETTINGS], }; export default FULL_SCREEN_TO_RHP_MAPPING; diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 7a5b31489764..e789c2cce4f3 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -935,6 +935,9 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.RULES_BILLABLE_DEFAULT]: { path: ROUTES.RULES_BILLABLE_DEFAULT.route, }, + [SCREENS.WORKSPACE.PER_DIEM_SETTINGS]: { + path: ROUTES.WORKSPACE_PER_DIEM_SETTINGS.route, + }, }, }, [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index ba859efff944..4ec8787c696a 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -896,6 +896,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.RULES_BILLABLE_DEFAULT]: { policyID: string; }; + [SCREENS.WORKSPACE.PER_DIEM_SETTINGS]: { + policyID: string; + }; } & ReimbursementAccountNavigatorParamList; type NewChatNavigatorParamList = { diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index dced49976c5a..63aee4bb1e46 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1069,6 +1069,60 @@ function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUn API.write(WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); } +function setPolicyPerDiemRatesDefaultCategory(policyID: string, currentCustomUnit: CustomUnit, newCustomUnit: CustomUnit) { + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + [newCustomUnit.customUnitID]: { + ...newCustomUnit, + pendingFields: {defaultCategory: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + }, + }, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + [newCustomUnit.customUnitID]: { + pendingFields: {defaultCategory: null}, + }, + }, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + [currentCustomUnit.customUnitID]: { + ...currentCustomUnit, + errorFields: {defaultCategory: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')}, + pendingFields: {defaultCategory: null}, + }, + }, + }, + }, + ]; + + const params: SetPolicyDistanceRatesDefaultCategoryParams = { + policyID, + customUnit: JSON.stringify(removePendingFieldsFromCustomUnit(newCustomUnit)), + }; + + API.write(WRITE_COMMANDS.SET_POLICY_PER_DIEM_RATES_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); +} + function downloadCategoriesCSV(policyID: string, onDownloadFailed: () => void) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_CATEGORIES_CSV, { policyID, @@ -1365,6 +1419,7 @@ export { clearCategoryErrors, enablePolicyCategories, setPolicyDistanceRatesDefaultCategory, + setPolicyPerDiemRatesDefaultCategory, deleteWorkspaceCategories, buildOptimisticPolicyCategories, setPolicyCategoryReceiptsRequired, diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index 2ce31fd4c921..a480b1a35a9e 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -9,6 +9,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy, Report} from '@src/types/onyx'; +import type {ErrorFields} from '@src/types/onyx/OnyxCommon'; import type {OnyxData} from '@src/types/onyx/Request'; const allPolicies: OnyxCollection = {}; @@ -119,4 +120,14 @@ function openPolicyPerDiemPage(policyID?: string) { API.read(READ_COMMANDS.OPEN_POLICY_PER_DIEM_RATES_PAGE, params); } -export {enablePerDiem, openPolicyPerDiemPage}; +function clearPolicyPerDiemRatesErrorFields(policyID: string, customUnitID: string, updatedErrorFields: ErrorFields) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + customUnits: { + [customUnitID]: { + errorFields: updatedErrorFields, + }, + }, + }); +} + +export {enablePerDiem, openPolicyPerDiemPage, clearPolicyPerDiemRatesErrorFields}; diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx index eed24a4ea13f..bf8b28d2580a 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx @@ -23,12 +23,12 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import * as Category from '@userActions/Policy/Category'; import * as DistanceRate from '@userActions/Policy/DistanceRate'; import * as Policy from '@userActions/Policy/Policy'; +import CategorySelector from '@src/components/CategorySelector'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {CustomUnit} from '@src/types/onyx/Policy'; -import CategorySelector from './CategorySelector'; import UnitSelector from './UnitSelector'; type PolicyDistanceRatesSettingsPageProps = StackScreenProps; @@ -125,7 +125,7 @@ function PolicyDistanceRatesSettingsPage({route}: PolicyDistanceRatesSettingsPag > { - // TODO: Uncomment this when the import feature is ready - // Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_RATES_SETTINGS.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_SETTINGS.getRoute(policyID)); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx new file mode 100644 index 000000000000..89a83f805e6b --- /dev/null +++ b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx @@ -0,0 +1,104 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useState} from 'react'; +import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import ScreenWrapper from '@components/ScreenWrapper'; +import ScrollView from '@components/ScrollView'; +import type {ListItem} from '@components/SelectionList/types'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import {clearPolicyPerDiemRatesErrorFields} from '@libs/actions/Policy/PerDiem'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import {getPerDiemCustomUnit} from '@libs/PolicyUtils'; +import type {SettingsNavigatorParamList} from '@navigation/types'; +import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; +import * as Category from '@userActions/Policy/Category'; +import CategorySelector from '@src/components/CategorySelector'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; +import type {CustomUnit} from '@src/types/onyx/Policy'; + +type WorkspacePerDiemSettingsPageProps = StackScreenProps; + +function WorkspacePerDiemSettingsPage({route}: WorkspacePerDiemSettingsPageProps) { + const policyID = route.params.policyID; + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); + + const styles = useThemeStyles(); + const [isCategoryPickerVisible, setIsCategoryPickerVisible] = useState(false); + const {translate} = useLocalize(); + const customUnit = getPerDiemCustomUnit(policy); + const customUnitID = customUnit?.customUnitID ?? ''; + + const defaultCategory = customUnit?.defaultCategory; + const errorFields = customUnit?.errorFields; + + const FullPageBlockingView = !customUnit ? FullPageOfflineBlockingView : View; + + const setNewCategory = (category: ListItem) => { + if (!category.searchText || !customUnit) { + return; + } + + Category.setPolicyPerDiemRatesDefaultCategory(policyID, customUnit, { + ...customUnit, + defaultCategory: defaultCategory === category.searchText ? '' : category.searchText, + }); + }; + + const clearErrorFields = (fieldName: keyof CustomUnit) => { + clearPolicyPerDiemRatesErrorFields(policyID, customUnitID, {...errorFields, [fieldName]: null}); + }; + + return ( + + + + + + {!!policy?.areCategoriesEnabled && OptionsListUtils.hasEnabledOptions(policyCategories ?? {}) && ( + clearErrorFields('defaultCategory')} + > + setIsCategoryPickerVisible(true)} + hidePickerModal={() => setIsCategoryPickerVisible(false)} + /> + + )} + + + + + ); +} + +WorkspacePerDiemSettingsPage.displayName = 'WorkspacePerDiemSettingsPage'; + +export default WorkspacePerDiemSettingsPage; From 92302b405790d17c3a09dde61eaba5d864cd311a Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 8 Nov 2024 22:12:35 +0530 Subject: [PATCH 2/5] Fix lint --- .../workspace/categories/WorkspaceCategoriesSettingsPage.tsx | 2 +- .../workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx | 2 +- src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/categories/WorkspaceCategoriesSettingsPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesSettingsPage.tsx index aea6f596badd..12502787d9df 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesSettingsPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesSettingsPage.tsx @@ -1,6 +1,7 @@ import React, {useMemo, useState} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; +import CategorySelectorModal from '@components/CategorySelector/CategorySelectorModal'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; @@ -12,7 +13,6 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; -import CategorySelectorModal from '@pages/workspace/distanceRates/CategorySelector/CategorySelectorModal'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx index bf8b28d2580a..2d25f066023c 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx @@ -3,6 +3,7 @@ import React, {useState} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; +import CategorySelector from '@components/CategorySelector'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -23,7 +24,6 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import * as Category from '@userActions/Policy/Category'; import * as DistanceRate from '@userActions/Policy/DistanceRate'; import * as Policy from '@userActions/Policy/Policy'; -import CategorySelector from '@src/components/CategorySelector'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx index 89a83f805e6b..c620c811184c 100644 --- a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx +++ b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx @@ -3,6 +3,7 @@ import React, {useState} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; +import CategorySelector from '@components/CategorySelector'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -17,7 +18,6 @@ import {getPerDiemCustomUnit} from '@libs/PolicyUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import * as Category from '@userActions/Policy/Category'; -import CategorySelector from '@src/components/CategorySelector'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; From 1776b6860cd5b64ae9c8acefa620524b79cadf31 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 12 Nov 2024 11:24:39 +0530 Subject: [PATCH 3/5] Use newer command to change default category --- .../EnableDistanceRequestTaxParams.ts | 6 ++ .../SetCustomUnitDefaultCategoryParams.ts | 7 ++ ...olicyDistanceRatesDefaultCategoryParams.ts | 6 -- src/libs/API/parameters/index.ts | 3 +- src/libs/API/types.ts | 8 +- src/libs/actions/Policy/Category.ts | 81 +++---------------- .../PolicyDistanceRatesSettingsPage.tsx | 5 +- .../perDiem/WorkspacePerDiemSettingsPage.tsx | 5 +- 8 files changed, 33 insertions(+), 88 deletions(-) create mode 100644 src/libs/API/parameters/EnableDistanceRequestTaxParams.ts create mode 100644 src/libs/API/parameters/SetCustomUnitDefaultCategoryParams.ts delete mode 100644 src/libs/API/parameters/SetPolicyDistanceRatesDefaultCategoryParams.ts diff --git a/src/libs/API/parameters/EnableDistanceRequestTaxParams.ts b/src/libs/API/parameters/EnableDistanceRequestTaxParams.ts new file mode 100644 index 000000000000..0d42d9ba84b4 --- /dev/null +++ b/src/libs/API/parameters/EnableDistanceRequestTaxParams.ts @@ -0,0 +1,6 @@ +type EnableDistanceRequestTaxParams = { + policyID: string; + customUnit: string; +}; + +export default EnableDistanceRequestTaxParams; diff --git a/src/libs/API/parameters/SetCustomUnitDefaultCategoryParams.ts b/src/libs/API/parameters/SetCustomUnitDefaultCategoryParams.ts new file mode 100644 index 000000000000..53eac3110af7 --- /dev/null +++ b/src/libs/API/parameters/SetCustomUnitDefaultCategoryParams.ts @@ -0,0 +1,7 @@ +type SetCustomUnitDefaultCategoryParams = { + policyID: string; + customUnitID: string; + category: string; +}; + +export default SetCustomUnitDefaultCategoryParams; diff --git a/src/libs/API/parameters/SetPolicyDistanceRatesDefaultCategoryParams.ts b/src/libs/API/parameters/SetPolicyDistanceRatesDefaultCategoryParams.ts deleted file mode 100644 index d2d11993a172..000000000000 --- a/src/libs/API/parameters/SetPolicyDistanceRatesDefaultCategoryParams.ts +++ /dev/null @@ -1,6 +0,0 @@ -type SetPolicyDistanceRatesDefaultCategoryParams = { - policyID: string; - customUnit: string; -}; - -export default SetPolicyDistanceRatesDefaultCategoryParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index fb5558fb0350..55714480762f 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -206,7 +206,8 @@ export type {default as EnablePolicyTaxesParams} from './EnablePolicyTaxesParams export type {default as OpenPolicyMoreFeaturesPageParams} from './OpenPolicyMoreFeaturesPageParams'; export type {default as CreatePolicyDistanceRateParams} from './CreatePolicyDistanceRateParams'; export type {default as SetPolicyDistanceRatesUnitParams} from './SetPolicyDistanceRatesUnitParams'; -export type {default as SetPolicyDistanceRatesDefaultCategoryParams} from './SetPolicyDistanceRatesDefaultCategoryParams'; +export type {default as EnableDistanceRequestTaxParams} from './EnableDistanceRequestTaxParams'; +export type {default as SetCustomUnitDefaultCategoryParams} from './SetCustomUnitDefaultCategoryParams'; export type {default as UpdatePolicyDistanceRateValueParams} from './UpdatePolicyDistanceRateValueParams'; export type {default as SetPolicyDistanceRatesEnabledParams} from './SetPolicyDistanceRatesEnabledParams'; export type {default as DeletePolicyDistanceRatesParams} from './DeletePolicyDistanceRatesParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index a8847545fbb3..d730819d876c 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -287,8 +287,7 @@ const WRITE_COMMANDS = { REQUEST_WORKSPACE_OWNER_CHANGE: 'RequestWorkspaceOwnerChange', ADD_BILLING_CARD_AND_REQUEST_WORKSPACE_OWNER_CHANGE: 'AddBillingCardAndRequestPolicyOwnerChange', SET_POLICY_DISTANCE_RATES_UNIT: 'SetPolicyDistanceRatesUnit', - SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY: 'SetPolicyDistanceRatesDefaultCategory', - SET_POLICY_PER_DIEM_RATES_DEFAULT_CATEGORY: 'SetPolicyPerDiemRatesDefaultCategory', + SET_CUSTOM_UNIT_DEFAULT_CATEGORY: 'SetCustomUnitDefaultCategory', ENABLE_DISTANCE_REQUEST_TAX: 'EnableDistanceRequestTax', UPDATE_POLICY_DISTANCE_RATE_VALUE: 'UpdatePolicyDistanceRateValue', UPDATE_POLICY_DISTANCE_TAX_RATE_VALUE: 'UpdateDistanceTaxRate', @@ -692,9 +691,8 @@ type WriteCommandParameters = { [WRITE_COMMANDS.RENAME_POLICY_TAX]: Parameters.RenamePolicyTaxParams; [WRITE_COMMANDS.UPDATE_POLICY_TAX_CODE]: Parameters.UpdatePolicyTaxCodeParams; [WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_UNIT]: Parameters.SetPolicyDistanceRatesUnitParams; - [WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams; - [WRITE_COMMANDS.SET_POLICY_PER_DIEM_RATES_DEFAULT_CATEGORY]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams; - [WRITE_COMMANDS.ENABLE_DISTANCE_REQUEST_TAX]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams; + [WRITE_COMMANDS.SET_CUSTOM_UNIT_DEFAULT_CATEGORY]: Parameters.SetCustomUnitDefaultCategoryParams; + [WRITE_COMMANDS.ENABLE_DISTANCE_REQUEST_TAX]: Parameters.EnableDistanceRequestTaxParams; [WRITE_COMMANDS.REPORT_EXPORT]: Parameters.ReportExportParams; [WRITE_COMMANDS.MARK_AS_EXPORTED]: Parameters.MarkAsExportedParams; [WRITE_COMMANDS.REQUEST_EXPENSIFY_CARD_LIMIT_INCREASE]: Parameters.RequestExpensifyCardLimitIncreaseParams; diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 63aee4bb1e46..cb9a39612b09 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -13,7 +13,6 @@ import type { SetPolicyCategoryMaxAmountParams, SetPolicyCategoryReceiptsRequiredParams, SetPolicyCategoryTaxParams, - SetPolicyDistanceRatesDefaultCategoryParams, SetWorkspaceCategoryDescriptionHintParams, UpdatePolicyCategoryGLCodeParams, } from '@libs/API/parameters'; @@ -28,13 +27,13 @@ import {translateLocal} from '@libs/Localize'; import Log from '@libs/Log'; import enhanceParameters from '@libs/Network/enhanceParameters'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import {navigateWhenEnableFeature, removePendingFieldsFromCustomUnit} from '@libs/PolicyUtils'; +import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy, PolicyCategories, PolicyCategory, RecentlyUsedCategories, Report} from '@src/types/onyx'; -import type {ApprovalRule, CustomUnit, ExpenseRule} from '@src/types/onyx/Policy'; +import type {ApprovalRule, ExpenseRule} from '@src/types/onyx/Policy'; import type {PolicyCategoryExpenseLimitType} from '@src/types/onyx/PolicyCategory'; import type {OnyxData} from '@src/types/onyx/Request'; @@ -1015,15 +1014,15 @@ function enablePolicyCategories(policyID: string, enabled: boolean) { } } -function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUnit: CustomUnit, newCustomUnit: CustomUnit) { +function setPolicyCustomUnitDefaultCategory(policyID: string, customUnitID: string, oldCatrgory: string | undefined, category: string) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - [newCustomUnit.customUnitID]: { - ...newCustomUnit, + [customUnitID]: { + defaultCategory: category, pendingFields: {defaultCategory: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, }, @@ -1037,7 +1036,7 @@ function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUn key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - [newCustomUnit.customUnitID]: { + [customUnitID]: { pendingFields: {defaultCategory: null}, }, }, @@ -1051,8 +1050,8 @@ function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUn key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - [currentCustomUnit.customUnitID]: { - ...currentCustomUnit, + [customUnitID]: { + defaultCategory: oldCatrgory, errorFields: {defaultCategory: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')}, pendingFields: {defaultCategory: null}, }, @@ -1061,66 +1060,13 @@ function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUn }, ]; - const params: SetPolicyDistanceRatesDefaultCategoryParams = { + const params = { policyID, - customUnit: JSON.stringify(removePendingFieldsFromCustomUnit(newCustomUnit)), + customUnitID, + category, }; - API.write(WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); -} - -function setPolicyPerDiemRatesDefaultCategory(policyID: string, currentCustomUnit: CustomUnit, newCustomUnit: CustomUnit) { - const optimisticData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - customUnits: { - [newCustomUnit.customUnitID]: { - ...newCustomUnit, - pendingFields: {defaultCategory: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, - }, - }, - }, - }, - ]; - - const successData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - customUnits: { - [newCustomUnit.customUnitID]: { - pendingFields: {defaultCategory: null}, - }, - }, - }, - }, - ]; - - const failureData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - customUnits: { - [currentCustomUnit.customUnitID]: { - ...currentCustomUnit, - errorFields: {defaultCategory: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')}, - pendingFields: {defaultCategory: null}, - }, - }, - }, - }, - ]; - - const params: SetPolicyDistanceRatesDefaultCategoryParams = { - policyID, - customUnit: JSON.stringify(removePendingFieldsFromCustomUnit(newCustomUnit)), - }; - - API.write(WRITE_COMMANDS.SET_POLICY_PER_DIEM_RATES_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.SET_CUSTOM_UNIT_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); } function downloadCategoriesCSV(policyID: string, onDownloadFailed: () => void) { @@ -1418,8 +1364,7 @@ export { setPolicyCategoryGLCode, clearCategoryErrors, enablePolicyCategories, - setPolicyDistanceRatesDefaultCategory, - setPolicyPerDiemRatesDefaultCategory, + setPolicyCustomUnitDefaultCategory, deleteWorkspaceCategories, buildOptimisticPolicyCategories, setPolicyCategoryReceiptsRequired, diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx index 2d25f066023c..d971b42b45eb 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx @@ -65,10 +65,7 @@ function PolicyDistanceRatesSettingsPage({route}: PolicyDistanceRatesSettingsPag return; } - Category.setPolicyDistanceRatesDefaultCategory(policyID, customUnit, { - ...customUnit, - defaultCategory: defaultCategory === category.searchText ? '' : category.searchText, - }); + Category.setPolicyCustomUnitDefaultCategory(policyID, customUnitID, customUnit.defaultCategory, defaultCategory === category.searchText ? '' : category.searchText); }; const clearErrorFields = (fieldName: keyof CustomUnit) => { diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx index c620c811184c..4ac57ed296b5 100644 --- a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx +++ b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx @@ -46,10 +46,7 @@ function WorkspacePerDiemSettingsPage({route}: WorkspacePerDiemSettingsPageProps return; } - Category.setPolicyPerDiemRatesDefaultCategory(policyID, customUnit, { - ...customUnit, - defaultCategory: defaultCategory === category.searchText ? '' : category.searchText, - }); + Category.setPolicyCustomUnitDefaultCategory(policyID, customUnitID, customUnit.defaultCategory, defaultCategory === category.searchText ? '' : category.searchText); }; const clearErrorFields = (fieldName: keyof CustomUnit) => { From 92e7e90017b9bbfc55688b8b7decbe4d940307d1 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal <58412969+shubham1206agra@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:07:15 +0530 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: c3024 <102477862+c3024@users.noreply.github.com> --- src/libs/actions/Policy/Category.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index cb9a39612b09..2f663ac204d2 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1014,7 +1014,7 @@ function enablePolicyCategories(policyID: string, enabled: boolean) { } } -function setPolicyCustomUnitDefaultCategory(policyID: string, customUnitID: string, oldCatrgory: string | undefined, category: string) { +function setPolicyCustomUnitDefaultCategory(policyID: string, customUnitID: string, oldCategory: string | undefined, category: string) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -1051,7 +1051,7 @@ function setPolicyCustomUnitDefaultCategory(policyID: string, customUnitID: stri value: { customUnits: { [customUnitID]: { - defaultCategory: oldCatrgory, + defaultCategory: oldCategory, errorFields: {defaultCategory: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')}, pendingFields: {defaultCategory: null}, }, From 01a1fe8477d7daad82173eb20c3d9beed8c407f2 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 14 Nov 2024 00:12:01 +0530 Subject: [PATCH 5/5] Fix usage of function --- .../distanceRates/PolicyDistanceRatesSettingsPage.tsx | 4 ++-- src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx index d971b42b45eb..fbbdf5ee382f 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx @@ -61,11 +61,11 @@ function PolicyDistanceRatesSettingsPage({route}: PolicyDistanceRatesSettingsPag }; const setNewCategory = (category: ListItem) => { - if (!category.searchText || !customUnit) { + if (!category.searchText || !customUnit || defaultCategory === category.searchText) { return; } - Category.setPolicyCustomUnitDefaultCategory(policyID, customUnitID, customUnit.defaultCategory, defaultCategory === category.searchText ? '' : category.searchText); + Category.setPolicyCustomUnitDefaultCategory(policyID, customUnitID, customUnit.defaultCategory, category.searchText); }; const clearErrorFields = (fieldName: keyof CustomUnit) => { diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx index 4ac57ed296b5..1fd28b4ff75a 100644 --- a/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx +++ b/src/pages/workspace/perDiem/WorkspacePerDiemSettingsPage.tsx @@ -42,11 +42,11 @@ function WorkspacePerDiemSettingsPage({route}: WorkspacePerDiemSettingsPageProps const FullPageBlockingView = !customUnit ? FullPageOfflineBlockingView : View; const setNewCategory = (category: ListItem) => { - if (!category.searchText || !customUnit) { + if (!category.searchText || !customUnit || defaultCategory === category.searchText) { return; } - Category.setPolicyCustomUnitDefaultCategory(policyID, customUnitID, customUnit.defaultCategory, defaultCategory === category.searchText ? '' : category.searchText); + Category.setPolicyCustomUnitDefaultCategory(policyID, customUnitID, customUnit.defaultCategory, category.searchText); }; const clearErrorFields = (fieldName: keyof CustomUnit) => {