From 039fc64426d1d1c58bd37959e0e4d17e628fd97f Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 7 Nov 2024 23:44:11 +0530 Subject: [PATCH 1/7] Feature: Import/Export Per Diem Rates --- src/CONST.ts | 1 + src/ROUTES.ts | 8 + src/SCREENS.ts | 2 + src/components/ImportColumn.tsx | 2 +- src/components/ImportSpreadsheet.tsx | 8 +- src/languages/en.ts | 4 + src/languages/es.ts | 4 + src/languages/params.ts | 5 + .../API/parameters/ExportPerDiemCSVParams.ts | 6 + .../parameters/ImportPerDiemRatesParams.ts | 26 +++ src/libs/API/parameters/index.ts | 2 + src/libs/API/types.ts | 4 + .../ModalStackNavigators/index.tsx | 2 + .../FULL_SCREEN_TO_RHP_MAPPING.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 6 + src/libs/Navigation/types.ts | 6 + src/libs/actions/Policy/PerDiem.ts | 65 ++++++- .../categories/ImportCategoriesPage.tsx | 4 +- .../workspace/members/ImportMembersPage.tsx | 4 +- .../workspace/perDiem/ImportPerDiemPage.tsx | 21 +++ .../workspace/perDiem/ImportedPerDiemPage.tsx | 171 ++++++++++++++++++ .../perDiem/WorkspacePerDiemPage.tsx | 35 ++-- src/pages/workspace/tags/ImportTagsPage.tsx | 4 +- 23 files changed, 365 insertions(+), 26 deletions(-) create mode 100644 src/libs/API/parameters/ExportPerDiemCSVParams.ts create mode 100644 src/libs/API/parameters/ImportPerDiemRatesParams.ts create mode 100644 src/pages/workspace/perDiem/ImportPerDiemPage.tsx create mode 100644 src/pages/workspace/perDiem/ImportedPerDiemPage.tsx diff --git a/src/CONST.ts b/src/CONST.ts index 72dff8c87b17..b686ca491aa4 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -6153,6 +6153,7 @@ const CONST = { RATE_ID: 'rateID', ENABLED: 'enabled', IGNORE: 'ignore', + DESTINATION: 'destination', }, IMPORT_SPREADSHEET: { diff --git a/src/ROUTES.ts b/src/ROUTES.ts index cd94035e0fff..6a3d43313c77 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1277,6 +1277,14 @@ const ROUTES = { route: 'settings/workspaces/:policyID/per-diem', getRoute: (policyID: string) => `settings/workspaces/${policyID}/per-diem` as const, }, + WORKSPACE_PER_DIEM_IMPORT: { + route: 'settings/workspaces/:policyID/per-diem/import', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/per-diem/import` as const, + }, + WORKSPACE_PER_DIEM_IMPORTED: { + route: 'settings/workspaces/:policyID/per-diem/imported', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/per-diem/imported` 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..a3d4c570851d 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -543,6 +543,8 @@ const SCREENS = { RULES_MAX_EXPENSE_AGE: 'Rules_Max_Expense_Age', RULES_BILLABLE_DEFAULT: 'Rules_Billable_Default', PER_DIEM: 'Per_Diem', + PER_DIEM_IMPORT: 'Per_Diem_Import', + PER_DIEM_IMPORTED: 'Per_Diem_Imported', }, EDIT_REQUEST: { diff --git a/src/components/ImportColumn.tsx b/src/components/ImportColumn.tsx index d3f5eb75f7e8..0e1ae935a2b7 100644 --- a/src/components/ImportColumn.tsx +++ b/src/components/ImportColumn.tsx @@ -87,7 +87,7 @@ function findColumnName(header: string): string { break; case 'destination': - attribute = CONST.CSV_IMPORT_COLUMNS.NAME; + attribute = CONST.CSV_IMPORT_COLUMNS.DESTINATION; break; case 'subrate': diff --git a/src/components/ImportSpreadsheet.tsx b/src/components/ImportSpreadsheet.tsx index 6865e8ae6c82..09f8c1d5b925 100644 --- a/src/components/ImportSpreadsheet.tsx +++ b/src/components/ImportSpreadsheet.tsx @@ -33,7 +33,7 @@ type ImportSpreedsheetProps = { goTo: Routes; }; -function ImportSpreedsheet({backTo, goTo}: ImportSpreedsheetProps) { +function ImportSpreadsheet({backTo, goTo}: ImportSpreedsheetProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const [isReadingFile, setIsReadingFIle] = useState(false); @@ -160,7 +160,7 @@ function ImportSpreedsheet({backTo, goTo}: ImportSpreedsheetProps) { @@ -214,6 +214,6 @@ function ImportSpreedsheet({backTo, goTo}: ImportSpreedsheetProps) { ); } -ImportSpreedsheet.displayName = 'ImportSpreedsheet'; +ImportSpreadsheet.displayName = 'ImportSpreadsheet'; -export default ImportSpreedsheet; +export default ImportSpreadsheet; diff --git a/src/languages/en.ts b/src/languages/en.ts index 92bed5ecf1f0..242365dbaf1d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -73,6 +73,7 @@ import type { ImportedTypesParams, ImportFieldParams, ImportMembersSuccessfullDescriptionParams, + ImportPerDiemRatesSuccessfullDescriptionParams, ImportTagsSuccessfullDescriptionParams, IncorrectZipFormatParams, InstantSummaryParams, @@ -764,6 +765,8 @@ const translations = { importCategoriesSuccessfullDescription: ({categories}: SpreadCategoriesParams) => (categories > 1 ? `${categories} categories have been added.` : '1 category has been added.'), importMembersSuccessfullDescription: ({members}: ImportMembersSuccessfullDescriptionParams) => (members > 1 ? `${members} members have been added.` : '1 member has been added.'), importTagsSuccessfullDescription: ({tags}: ImportTagsSuccessfullDescriptionParams) => (tags > 1 ? `${tags} tags have been added.` : '1 tag has been added.'), + importPerDiemRatesSuccessfullDescription: ({rates}: ImportPerDiemRatesSuccessfullDescriptionParams) => + rates > 1 ? `${rates} per diem rates have been added.` : '1 per diem rate has been added.', importFailedTitle: 'Import failed', importFailedDescription: 'Please ensure all fields are filled out correctly and try again. If the problem persists, please reach out to Concierge.', importDescription: 'Choose which fields to map from your spreadsheet by clicking the dropdown next to each imported column below.', @@ -2420,6 +2423,7 @@ const translations = { title: 'Per diem', subtitle: 'Set per diem rates to control daily employee spend. Import rates from a spreadsheet to get started.', }, + importPerDiemRates: 'Import per diem rates', }, qbd: { exportOutOfPocketExpensesDescription: 'Set how out-of-pocket expenses export to QuickBooks Desktop.', diff --git a/src/languages/es.ts b/src/languages/es.ts index eefbb16870b5..8cdb1e9ed311 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -71,6 +71,7 @@ import type { ImportedTypesParams, ImportFieldParams, ImportMembersSuccessfullDescriptionParams, + ImportPerDiemRatesSuccessfullDescriptionParams, ImportTagsSuccessfullDescriptionParams, IncorrectZipFormatParams, InstantSummaryParams, @@ -759,6 +760,8 @@ const translations = { importCategoriesSuccessfullDescription: ({categories}: SpreadCategoriesParams) => (categories > 1 ? `Se han agregado ${categories} categorías.` : 'Se ha agregado 1 categoría.'), importMembersSuccessfullDescription: ({members}: ImportMembersSuccessfullDescriptionParams) => (members > 1 ? `Se han agregado ${members} miembros.` : 'Se ha agregado 1 miembro.'), importTagsSuccessfullDescription: ({tags}: ImportTagsSuccessfullDescriptionParams) => (tags > 1 ? `Se han agregado ${tags} etiquetas.` : 'Se ha agregado 1 etiqueta.'), + importPerDiemRatesSuccessfullDescription: ({rates}: ImportPerDiemRatesSuccessfullDescriptionParams) => + rates > 1 ? `Se han añadido ${rates} tasas de per diem.` : 'Se ha añadido 1 tasa de per diem.', importSuccessfullTitle: 'Importar categorías', importDescription: 'Elige qué campos mapear desde tu hoja de cálculo haciendo clic en el menú desplegable junto a cada columna importada a continuación.', sizeNotMet: 'El archivo adjunto debe ser más grande que 0 bytes.', @@ -2443,6 +2446,7 @@ const translations = { title: 'Per diem', subtitle: 'Establece dietas per diem para controlar el gasto diario de los empleados. Importa las tarifas desde una hoja de cálculo para comenzar.', }, + importPerDiemRates: 'Importar tasas de per diem', }, qbd: { exportOutOfPocketExpensesDescription: 'Establezca cómo se exportan los gastos de bolsillo a QuickBooks Desktop.', diff --git a/src/languages/params.ts b/src/languages/params.ts index e9f0c4370357..0dc6e1b75198 100644 --- a/src/languages/params.ts +++ b/src/languages/params.ts @@ -531,6 +531,10 @@ type ImportMembersSuccessfullDescriptionParams = { members: number; }; +type ImportPerDiemRatesSuccessfullDescriptionParams = { + rates: number; +}; + type AuthenticationErrorParams = { connectionName: string; }; @@ -746,4 +750,5 @@ export type { OptionalParam, AssignCardParams, ImportedTypesParams, + ImportPerDiemRatesSuccessfullDescriptionParams, }; diff --git a/src/libs/API/parameters/ExportPerDiemCSVParams.ts b/src/libs/API/parameters/ExportPerDiemCSVParams.ts new file mode 100644 index 000000000000..553621534df5 --- /dev/null +++ b/src/libs/API/parameters/ExportPerDiemCSVParams.ts @@ -0,0 +1,6 @@ +type ExportPerDiemCSVParams = { + /** ID of the policy */ + policyID: string; +}; + +export default ExportPerDiemCSVParams; diff --git a/src/libs/API/parameters/ImportPerDiemRatesParams.ts b/src/libs/API/parameters/ImportPerDiemRatesParams.ts new file mode 100644 index 000000000000..b67517150f2d --- /dev/null +++ b/src/libs/API/parameters/ImportPerDiemRatesParams.ts @@ -0,0 +1,26 @@ +type ImportPerDiemRatesParams = { + /** ID of the policy */ + policyID: string; + + /** Custom Unit ID of the per diem unit */ + customUnitID: string; + + /** + * Stringified JSON object with type of following structure: + * Array<{ + * customUnitRateID: ; + * name: “Spain”; + * currency: “EUR”; + * enabled: true (since we are importing); + * rate: 0 (since we have subrates); + * Attributes: []; + * subRates: An array with each element in the following shape: + * id: “66d5ae9a0379d”; + * name: “Full Day”; + * rate: 3000 (in cents); + * }> + */ + customUnitRates: string; +}; + +export default ImportPerDiemRatesParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index fb5558fb0350..f03539e78d13 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -349,3 +349,5 @@ export type {default as UpdateQuickbooksDesktopCompanyCardExpenseAccountTypePara export type {default as TogglePolicyPerDiemParams} from './TogglePolicyPerDiemParams'; export type {default as OpenPolicyPerDiemRatesPageParams} from './OpenPolicyPerDiemRatesPageParams'; export type {default as TogglePlatformMuteParams} from './TogglePlatformMuteParams'; +export type {default as ImportPerDiemRatesParams} from './ImportPerDiemRatesParams'; +export type {default as ExportPerDiemCSVParams} from './ExportPerDiemCSVParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index b8b4bb749701..b6eb17d7be33 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -148,9 +148,11 @@ const WRITE_COMMANDS = { IMPORT_CATEGORIES_SPREADSHEET: 'ImportCategoriesSpreadsheet', IMPORT_MEMBERS_SPREADSHEET: 'ImportMembersSpreadsheet', IMPORT_TAGS_SPREADSHEET: 'ImportTagsSpreadsheet', + IMPORT_PER_DIEM_RATES: 'ImportPerDiemRates', EXPORT_CATEGORIES_CSV: 'ExportCategoriesCSV', EXPORT_MEMBERS_CSV: 'ExportMembersCSV', EXPORT_TAGS_CSV: 'ExportTagsCSV', + EXPORT_PER_DIEM_CSV: 'ExportPerDiemCSV', EXPORT_REPORT_TO_CSV: 'ExportReportToCSV', RENAME_WORKSPACE_CATEGORY: 'RenameWorkspaceCategory', CREATE_POLICY_TAG: 'CreatePolicyTag', @@ -572,11 +574,13 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_WORKSPACE_CATEGORIES_ENABLED]: Parameters.SetWorkspaceCategoriesEnabledParams; [WRITE_COMMANDS.CREATE_WORKSPACE_CATEGORIES]: Parameters.CreateWorkspaceCategoriesParams; [WRITE_COMMANDS.IMPORT_CATEGORIES_SPREADSHEET]: Parameters.ImportCategoriesSpreadsheetParams; + [WRITE_COMMANDS.IMPORT_PER_DIEM_RATES]: Parameters.ImportPerDiemRatesParams; [WRITE_COMMANDS.IMPORT_MEMBERS_SPREADSHEET]: Parameters.ImportMembersSpreadsheetParams; [WRITE_COMMANDS.IMPORT_TAGS_SPREADSHEET]: Parameters.ImportTagsSpreadsheetParams; [WRITE_COMMANDS.EXPORT_CATEGORIES_CSV]: Parameters.ExportCategoriesSpreadsheetParams; [WRITE_COMMANDS.EXPORT_MEMBERS_CSV]: Parameters.ExportMembersSpreadsheetParams; [WRITE_COMMANDS.EXPORT_TAGS_CSV]: Parameters.ExportTagsSpreadsheetParams; + [WRITE_COMMANDS.EXPORT_PER_DIEM_CSV]: Parameters.ExportPerDiemCSVParams; [WRITE_COMMANDS.RENAME_WORKSPACE_CATEGORY]: Parameters.RenameWorkspaceCategoriesParams; [WRITE_COMMANDS.SET_WORKSPACE_REQUIRES_CATEGORY]: Parameters.SetWorkspaceRequiresCategoryParams; [WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES]: Parameters.DeleteWorkspaceCategoriesParams; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 8a64424c8f7d..68c711583c25 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -566,6 +566,8 @@ 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_IMPORT]: () => require('../../../../pages/workspace/perDiem/ImportPerDiemPage').default, + [SCREENS.WORKSPACE.PER_DIEM_IMPORTED]: () => require('../../../../pages/workspace/perDiem/ImportedPerDiemPage').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..c4ce9eac7fa6 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_IMPORT, SCREENS.WORKSPACE.PER_DIEM_IMPORTED], }; 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..383cf41ddbac 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -935,6 +935,12 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.RULES_BILLABLE_DEFAULT]: { path: ROUTES.RULES_BILLABLE_DEFAULT.route, }, + [SCREENS.WORKSPACE.PER_DIEM_IMPORT]: { + path: ROUTES.WORKSPACE_PER_DIEM_IMPORT.route, + }, + [SCREENS.WORKSPACE.PER_DIEM_IMPORTED]: { + path: ROUTES.WORKSPACE_PER_DIEM_IMPORTED.route, + }, }, }, [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index ba859efff944..89f4c321b16e 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -896,6 +896,12 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.RULES_BILLABLE_DEFAULT]: { policyID: string; }; + [SCREENS.WORKSPACE.PER_DIEM_IMPORT]: { + policyID: string; + }; + [SCREENS.WORKSPACE.PER_DIEM_IMPORTED]: { + policyID: string; + }; } & ReimbursementAccountNavigatorParamList; type NewChatNavigatorParamList = { diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index 2ce31fd4c921..beb109b04c8f 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -2,13 +2,18 @@ import type {NullishDeep, OnyxCollection} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; +import * as ApiUtils from '@libs/ApiUtils'; +import fileDownload from '@libs/fileDownload'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; +import {translateLocal} from '@libs/Localize'; +import enhanceParameters from '@libs/Network/enhanceParameters'; import * as NumberUtils from '@libs/NumberUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; 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 {Rate} from '@src/types/onyx/Policy'; import type {OnyxData} from '@src/types/onyx/Request'; const allPolicies: OnyxCollection = {}; @@ -119,4 +124,62 @@ function openPolicyPerDiemPage(policyID?: string) { API.read(READ_COMMANDS.OPEN_POLICY_PER_DIEM_RATES_PAGE, params); } -export {enablePerDiem, openPolicyPerDiemPage}; +function updateImportSpreadsheetData(ratesLength: number) { + const onyxData: OnyxData = { + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.IMPORTED_SPREADSHEET, + value: { + shouldFinalModalBeOpened: true, + importFinalModal: { + title: translateLocal('spreadsheet.importSuccessfullTitle'), + prompt: translateLocal('spreadsheet.importPerDiemRatesSuccessfullDescription', {rates: ratesLength}), + }, + }, + }, + ], + + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.IMPORTED_SPREADSHEET, + value: { + shouldFinalModalBeOpened: true, + importFinalModal: {title: translateLocal('spreadsheet.importFailedTitle'), prompt: translateLocal('spreadsheet.importFailedDescription')}, + }, + }, + ], + }; + + return onyxData; +} + +function importPerDiemRates(policyID: string, customUnitID: string, rates: Rate[]) { + const onyxData = updateImportSpreadsheetData(rates.length); + + const parameters = { + policyID, + customUnitID, + customUnitRates: JSON.stringify(rates), + }; + + API.write(WRITE_COMMANDS.IMPORT_PER_DIEM_RATES, parameters, onyxData); +} + +function downloadPerDiemCSV(policyID: string, onDownloadFailed: () => void) { + const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_PER_DIEM_CSV, { + policyID, + }); + + const fileName = 'PerDiem.csv'; + + const formData = new FormData(); + Object.entries(finalParameters).forEach(([key, value]) => { + formData.append(key, String(value)); + }); + + fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_PER_DIEM_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); +} + +export {generateCustomUnitID, enablePerDiem, openPolicyPerDiemPage, importPerDiemRates, downloadPerDiemCSV}; diff --git a/src/pages/workspace/categories/ImportCategoriesPage.tsx b/src/pages/workspace/categories/ImportCategoriesPage.tsx index 82afe6dfc812..c6a3065dbfb5 100644 --- a/src/pages/workspace/categories/ImportCategoriesPage.tsx +++ b/src/pages/workspace/categories/ImportCategoriesPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; -import ImportSpreedsheet from '@components/ImportSpreadsheet'; +import ImportSpreadsheet from '@components/ImportSpreadsheet'; import usePolicy from '@hooks/usePolicy'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import * as PolicyUtils from '@libs/PolicyUtils'; @@ -22,7 +22,7 @@ function ImportCategoriesPage({route}: ImportCategoriesPageProps) { } return ( - diff --git a/src/pages/workspace/members/ImportMembersPage.tsx b/src/pages/workspace/members/ImportMembersPage.tsx index 6fff3085b472..b85ea25a617a 100644 --- a/src/pages/workspace/members/ImportMembersPage.tsx +++ b/src/pages/workspace/members/ImportMembersPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; -import ImportSpreedsheet from '@components/ImportSpreadsheet'; +import ImportSpreadsheet from '@components/ImportSpreadsheet'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; @@ -11,7 +11,7 @@ function ImportMembersPage({route}: ImportMembersPageProps) { const policyID = route.params.policyID; return ( - diff --git a/src/pages/workspace/perDiem/ImportPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportPerDiemPage.tsx new file mode 100644 index 000000000000..4d20c0fdbff9 --- /dev/null +++ b/src/pages/workspace/perDiem/ImportPerDiemPage.tsx @@ -0,0 +1,21 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React from 'react'; +import ImportSpreadsheet from '@components/ImportSpreadsheet'; +import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; + +type ImportPerDiemPageProps = StackScreenProps; + +function ImportPerDiemPage({route}: ImportPerDiemPageProps) { + const policyID = route.params.policyID; + + return ( + + ); +} + +export default ImportPerDiemPage; diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx new file mode 100644 index 000000000000..2eedc53a9558 --- /dev/null +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -0,0 +1,171 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback, useState} from 'react'; +import {useOnyx} from 'react-native-onyx'; +import ConfirmModal from '@components/ConfirmModal'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import type {ColumnRole} from '@components/ImportColumn'; +import ImportSpreadsheetColumns from '@components/ImportSpreadsheetColumns'; +import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; +import usePolicy from '@hooks/usePolicy'; +import {closeImportPage} from '@libs/actions/ImportSpreadsheet'; +import {generateCustomUnitID, importPerDiemRates} from '@libs/actions/Policy/PerDiem'; +import {findDuplicate, generateColumnNames} from '@libs/importSpreadsheetUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import {getPerDiemCustomUnit} from '@libs/PolicyUtils'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import type {Errors} from '@src/types/onyx/OnyxCommon'; +import type {Rate} from '@src/types/onyx/Policy'; + +function generatePerDiemUnits(perDiemDestination: string[], perDiemSubRate: string[], perDiemCurrency: string[], perDiemAmount: string[]) { + const perDiemUnits: Record = {}; + for (let i = 0; i < perDiemDestination.length; i++) { + perDiemUnits[perDiemDestination[i]] = perDiemUnits[perDiemDestination[i]] ?? { + customUnitRateID: perDiemDestination.at(i), + name: perDiemDestination.at(i), + rate: 0, + currency: perDiemCurrency.at(i), + enabled: true, + attributes: [], + subRates: [], + }; + perDiemUnits[perDiemDestination[i]].subRates?.push({ + id: generateCustomUnitID(), + name: perDiemSubRate.at(i) ?? '', + rate: Number(perDiemAmount.at(i)) ?? 0, + }); + } + return Object.values(perDiemUnits); +} + +type ImportedPerDiemPageProps = StackScreenProps; +function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { + const {translate} = useLocalize(); + const [spreadsheet] = useOnyx(ONYXKEYS.IMPORTED_SPREADSHEET); + const [isImportingPerDiemRates, setIsImportingPerDiemRates] = useState(false); + const {containsHeader = true} = spreadsheet ?? {}; + const [isValidationEnabled, setIsValidationEnabled] = useState(false); + const policyID = route.params.policyID; + const policy = usePolicy(policyID); + const perDiemCustomUnit = getPerDiemCustomUnit(policy); + const columnNames = generateColumnNames(spreadsheet?.data?.length ?? 0); + + const getColumnRoles = (): ColumnRole[] => { + const roles = []; + roles.push( + {text: translate('common.ignore'), value: CONST.CSV_IMPORT_COLUMNS.IGNORE}, + {text: translate('workspace.perDiem.destination'), value: CONST.CSV_IMPORT_COLUMNS.DESTINATION, isRequired: true}, + {text: translate('workspace.perDiem.subrate'), value: CONST.CSV_IMPORT_COLUMNS.SUBRATE, isRequired: true}, + {text: translate('common.currency'), value: CONST.CSV_IMPORT_COLUMNS.CURRENCY, isRequired: true}, + {text: translate('workspace.perDiem.amount'), value: CONST.CSV_IMPORT_COLUMNS.AMOUNT, isRequired: true}, + ); + + return roles; + }; + + const columnRoles = getColumnRoles(); + + const requiredColumns = columnRoles.filter((role) => role.isRequired).map((role) => role); + + const validate = useCallback(() => { + const columns = Object.values(spreadsheet?.columns ?? {}); + let errors: Errors = {}; + + if (!requiredColumns.every((requiredColumn) => columns.includes(requiredColumn.value))) { + // eslint-disable-next-line rulesdir/prefer-early-return + requiredColumns.forEach((requiredColumn) => { + if (!columns.includes(requiredColumn.value)) { + errors.required = translate('spreadsheet.fieldNotMapped', {fieldName: requiredColumn.text}); + } + }); + } else { + const duplicate = findDuplicate(columns); + const duplicateColumn = columnRoles.find((role) => role.value === duplicate); + if (duplicateColumn) { + errors.duplicates = translate('spreadsheet.singleFieldMultipleColumns', {fieldName: duplicateColumn.text}); + } else { + errors = {}; + } + } + return errors; + }, [requiredColumns, spreadsheet?.columns, translate, columnRoles]); + + const importCategories = useCallback(() => { + setIsValidationEnabled(true); + const errors = validate(); + if (Object.keys(errors).length > 0) { + return; + } + + const columns = Object.values(spreadsheet?.columns ?? {}); + const perDiemDestinationColumn = columns.findIndex((column) => column === CONST.CSV_IMPORT_COLUMNS.DESTINATION); + const perDiemSubRateColumn = columns.findIndex((column) => column === CONST.CSV_IMPORT_COLUMNS.SUBRATE); + const perDiemCurrencyColumn = columns.findIndex((column) => column === CONST.CSV_IMPORT_COLUMNS.CURRENCY); + const perDiemAmountColumn = columns.findIndex((column) => column === CONST.CSV_IMPORT_COLUMNS.AMOUNT); + const perDiemDestination = spreadsheet?.data[perDiemDestinationColumn].map((destination) => destination) ?? []; + const perDiemSubRate = spreadsheet?.data[perDiemSubRateColumn].map((subRate) => subRate) ?? []; + const perDiemCurrency = spreadsheet?.data[perDiemCurrencyColumn].map((currency) => currency) ?? []; + const perDiemAmount = spreadsheet?.data[perDiemAmountColumn].map((amount) => amount) ?? []; + const perDiemUnits = generatePerDiemUnits( + perDiemDestination?.slice(containsHeader ? 1 : 0), + perDiemSubRate?.slice(containsHeader ? 1 : 0), + perDiemCurrency?.slice(containsHeader ? 1 : 0), + perDiemAmount?.slice(containsHeader ? 1 : 0), + ); + + if (perDiemUnits) { + setIsImportingPerDiemRates(true); + importPerDiemRates(policyID, perDiemCustomUnit?.customUnitID ?? '', perDiemUnits); + } + }, [validate, spreadsheet?.columns, spreadsheet?.data, containsHeader, policyID, perDiemCustomUnit?.customUnitID]); + + const spreadsheetColumns = spreadsheet?.data; + if (!spreadsheetColumns) { + return; + } + + const closeImportPageAndModal = () => { + setIsImportingPerDiemRates(false); + closeImportPage(); + Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM.getRoute(policyID)); + }; + + return ( + + Navigation.goBack(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID))} + /> + + + + + ); +} + +ImportedPerDiemPage.displayName = 'ImportedPerDiemPage'; + +export default ImportedPerDiemPage; diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx index 9430cfd911b5..63c473b86095 100644 --- a/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx +++ b/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx @@ -7,6 +7,7 @@ import Button from '@components/Button'; import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu'; import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; import ConfirmModal from '@components/ConfirmModal'; +import DecisionModal from '@components/DecisionModal'; import EmptyStateComponent from '@components/EmptyStateComponent'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -39,7 +40,7 @@ import * as Link from '@userActions/Link'; import * as Modal from '@userActions/Modal'; import * as PerDiem from '@userActions/Policy/PerDiem'; import CONST from '@src/CONST'; -// import ROUTES from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {PendingAction} from '@src/types/onyx/OnyxCommon'; import type {Rate} from '@src/types/onyx/Policy'; @@ -107,7 +108,9 @@ function generateSingleSubRateData(customUnitRates: Rate[], rateID: string, subR type WorkspacePerDiemPageProps = StackScreenProps; function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { - const {shouldUseNarrowLayout} = useResponsiveLayout(); + // We need to use isSmallScreenWidth instead of shouldUseNarrowLayout to apply the correct modal type for the decision modal + // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth + const {shouldUseNarrowLayout, isSmallScreenWidth} = useResponsiveLayout(); const {windowWidth} = useWindowDimensions(); const styles = useThemeStyles(); const theme = useTheme(); @@ -115,6 +118,7 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { const [isOfflineModalVisible, setIsOfflineModalVisible] = useState(false); const [selectedPerDiem, setSelectedPerDiem] = useState([]); const [deletePerDiemConfirmModalVisible, setDeletePerDiemConfirmModalVisible] = useState(false); + const [isDownloadFailureModalVisible, setIsDownloadFailureModalVisible] = useState(false); const isFocused = useIsFocused(); const policyID = route.params.policyID ?? '-1'; const backTo = route.params?.backTo; @@ -305,34 +309,31 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { { icon: Expensicons.Table, text: translate('spreadsheet.importSpreadsheet'), - // eslint-disable-next-line rulesdir/prefer-early-return onSelected: () => { if (isOffline) { Modal.close(() => setIsOfflineModalVisible(true)); - // eslint-disable-next-line no-useless-return return; } - // TODO: Uncomment this when the import feature is ready - // Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID)); }, }, { icon: Expensicons.Download, text: translate('spreadsheet.downloadCSV'), - // eslint-disable-next-line rulesdir/prefer-early-return onSelected: () => { if (isOffline) { Modal.close(() => setIsOfflineModalVisible(true)); - // eslint-disable-next-line no-useless-return return; } - // Category.downloadPerDiemCSV(policyID); + PerDiem.downloadPerDiemCSV(policyID, () => { + setIsDownloadFailureModalVisible(true); + }); }, }, ]; return menuItems; - }, [translate, isOffline]); + }, [translate, isOffline, policyID]); const selectionModeHeader = selectionMode?.isEnabled && shouldUseNarrowLayout; @@ -400,15 +401,12 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { buttons={[ { buttonText: translate('spreadsheet.importSpreadsheet'), - // eslint-disable-next-line rulesdir/prefer-early-return buttonAction: () => { if (isOffline) { setIsOfflineModalVisible(true); - // eslint-disable-next-line no-useless-return return; } - // TODO: Uncomment this when the import feature is ready - // Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID)); }, success: true, }, @@ -442,6 +440,15 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { confirmText={translate('common.buttonConfirm')} shouldShowCancelButton={false} /> + setIsDownloadFailureModalVisible(false)} + secondOptionText={translate('common.buttonConfirm')} + isVisible={isDownloadFailureModalVisible} + onClose={() => setIsDownloadFailureModalVisible(false)} + /> ); diff --git a/src/pages/workspace/tags/ImportTagsPage.tsx b/src/pages/workspace/tags/ImportTagsPage.tsx index 1bbe22750210..693eede60161 100644 --- a/src/pages/workspace/tags/ImportTagsPage.tsx +++ b/src/pages/workspace/tags/ImportTagsPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; -import ImportSpreedsheet from '@components/ImportSpreadsheet'; +import ImportSpreadsheet from '@components/ImportSpreadsheet'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; @@ -13,7 +13,7 @@ function ImportTagsPage({route}: ImportTagsPageProps) { const isQuickSettingsFlow = !!backTo; return ( - From 6334588b6a3e7f4f3a43bf8c958cb1849db3e734 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 21 Nov 2024 15:40:59 +0530 Subject: [PATCH 2/7] Fix rows number on successful import --- src/libs/actions/Policy/PerDiem.ts | 4 ++-- src/pages/workspace/perDiem/ImportedPerDiemPage.tsx | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index 183e2919f4f2..7872a487c783 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -155,8 +155,8 @@ function updateImportSpreadsheetData(ratesLength: number) { return onyxData; } -function importPerDiemRates(policyID: string, customUnitID: string, rates: Rate[]) { - const onyxData = updateImportSpreadsheetData(rates.length); +function importPerDiemRates(policyID: string, customUnitID: string, rates: Rate[], rowsLength: number) { + const onyxData = updateImportSpreadsheetData(rowsLength); const parameters = { policyID, diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx index 2eedc53a9558..2b127f7d0397 100644 --- a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -117,9 +117,11 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { perDiemAmount?.slice(containsHeader ? 1 : 0), ); + const rowsLength = perDiemDestination.length - (containsHeader ? 1 : 0); + if (perDiemUnits) { setIsImportingPerDiemRates(true); - importPerDiemRates(policyID, perDiemCustomUnit?.customUnitID ?? '', perDiemUnits); + importPerDiemRates(policyID, perDiemCustomUnit?.customUnitID ?? '', perDiemUnits, rowsLength); } }, [validate, spreadsheet?.columns, spreadsheet?.data, containsHeader, policyID, perDiemCustomUnit?.customUnitID]); From 821bde5f360cfb41255f5108307532a6f910f30a Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 25 Nov 2024 12:09:37 +0530 Subject: [PATCH 3/7] Fix function naming --- src/pages/workspace/perDiem/ImportedPerDiemPage.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx index 2b127f7d0397..80559561d003 100644 --- a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -9,7 +9,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import {closeImportPage} from '@libs/actions/ImportSpreadsheet'; -import {generateCustomUnitID, importPerDiemRates} from '@libs/actions/Policy/PerDiem'; +import * as PerDiem from '@libs/actions/Policy/PerDiem'; import {findDuplicate, generateColumnNames} from '@libs/importSpreadsheetUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; @@ -34,7 +34,7 @@ function generatePerDiemUnits(perDiemDestination: string[], perDiemSubRate: stri subRates: [], }; perDiemUnits[perDiemDestination[i]].subRates?.push({ - id: generateCustomUnitID(), + id: PerDiem.generateCustomUnitID(), name: perDiemSubRate.at(i) ?? '', rate: Number(perDiemAmount.at(i)) ?? 0, }); @@ -94,7 +94,7 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { return errors; }, [requiredColumns, spreadsheet?.columns, translate, columnRoles]); - const importCategories = useCallback(() => { + const importPerDiemRates = useCallback(() => { setIsValidationEnabled(true); const errors = validate(); if (Object.keys(errors).length > 0) { @@ -121,7 +121,7 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { if (perDiemUnits) { setIsImportingPerDiemRates(true); - importPerDiemRates(policyID, perDiemCustomUnit?.customUnitID ?? '', perDiemUnits, rowsLength); + PerDiem.importPerDiemRates(policyID, perDiemCustomUnit?.customUnitID ?? '', perDiemUnits, rowsLength); } }, [validate, spreadsheet?.columns, spreadsheet?.data, containsHeader, policyID, perDiemCustomUnit?.customUnitID]); @@ -148,7 +148,7 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { Date: Mon, 25 Nov 2024 12:31:07 +0530 Subject: [PATCH 4/7] Fix crash when using invalid currency code --- src/libs/CurrencyUtils.ts | 5 +++++ src/pages/workspace/perDiem/ImportedPerDiemPage.tsx | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libs/CurrencyUtils.ts b/src/libs/CurrencyUtils.ts index f9ac681cb468..4786b6f07eab 100644 --- a/src/libs/CurrencyUtils.ts +++ b/src/libs/CurrencyUtils.ts @@ -197,6 +197,10 @@ function isValidCurrencyCode(currencyCode: string): boolean { return !!currency; } +function sanitizeCurrencyCode(currencyCode: string): string { + return isValidCurrencyCode(currencyCode) ? currencyCode : CONST.CURRENCY.USD; +} + export { getCurrencyDecimals, getCurrencyUnit, @@ -211,4 +215,5 @@ export { convertToDisplayStringWithoutCurrency, isValidCurrencyCode, convertToShortDisplayString, + sanitizeCurrencyCode, }; diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx index 80559561d003..9a0759b3608a 100644 --- a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -10,6 +10,7 @@ import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import {closeImportPage} from '@libs/actions/ImportSpreadsheet'; import * as PerDiem from '@libs/actions/Policy/PerDiem'; +import {sanitizeCurrencyCode} from '@libs/CurrencyUtils'; import {findDuplicate, generateColumnNames} from '@libs/importSpreadsheetUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; @@ -108,7 +109,7 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { const perDiemAmountColumn = columns.findIndex((column) => column === CONST.CSV_IMPORT_COLUMNS.AMOUNT); const perDiemDestination = spreadsheet?.data[perDiemDestinationColumn].map((destination) => destination) ?? []; const perDiemSubRate = spreadsheet?.data[perDiemSubRateColumn].map((subRate) => subRate) ?? []; - const perDiemCurrency = spreadsheet?.data[perDiemCurrencyColumn].map((currency) => currency) ?? []; + const perDiemCurrency = spreadsheet?.data[perDiemCurrencyColumn].map((currency) => sanitizeCurrencyCode(currency)) ?? []; const perDiemAmount = spreadsheet?.data[perDiemAmountColumn].map((amount) => amount) ?? []; const perDiemUnits = generatePerDiemUnits( perDiemDestination?.slice(containsHeader ? 1 : 0), From 95cffc99d4d6f42fe88a55eadcada03db5ecdac9 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 25 Nov 2024 17:48:47 +0530 Subject: [PATCH 5/7] Fix blank import per diem page --- src/pages/workspace/perDiem/ImportedPerDiemPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx index 9a0759b3608a..0811985350ea 100644 --- a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -21,6 +21,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {Rate} from '@src/types/onyx/Policy'; +import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; function generatePerDiemUnits(perDiemDestination: string[], perDiemSubRate: string[], perDiemCurrency: string[], perDiemAmount: string[]) { const perDiemUnits: Record = {}; @@ -128,7 +129,7 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { const spreadsheetColumns = spreadsheet?.data; if (!spreadsheetColumns) { - return; + return Navigation.goBack(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID))} />; } const closeImportPageAndModal = () => { From b3f7d892314bc4b4ed9a017bbf7324012de14485 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 25 Nov 2024 17:49:23 +0530 Subject: [PATCH 6/7] Fix lint --- src/pages/workspace/perDiem/ImportedPerDiemPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx index 0811985350ea..6fbbd280d834 100644 --- a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -15,13 +15,13 @@ import {findDuplicate, generateColumnNames} from '@libs/importSpreadsheetUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {getPerDiemCustomUnit} from '@libs/PolicyUtils'; +import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {Rate} from '@src/types/onyx/Policy'; -import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; function generatePerDiemUnits(perDiemDestination: string[], perDiemSubRate: string[], perDiemCurrency: string[], perDiemAmount: string[]) { const perDiemUnits: Record = {}; From e95e4cd23db1c1cbdb21433606e1e11701ae680a Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 25 Nov 2024 18:57:45 +0530 Subject: [PATCH 7/7] Revert: Fix blank import per diem page --- src/pages/workspace/perDiem/ImportedPerDiemPage.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx index 6fbbd280d834..9a0759b3608a 100644 --- a/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx +++ b/src/pages/workspace/perDiem/ImportedPerDiemPage.tsx @@ -15,7 +15,6 @@ import {findDuplicate, generateColumnNames} from '@libs/importSpreadsheetUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {getPerDiemCustomUnit} from '@libs/PolicyUtils'; -import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -129,7 +128,7 @@ function ImportedPerDiemPage({route}: ImportedPerDiemPageProps) { const spreadsheetColumns = spreadsheet?.data; if (!spreadsheetColumns) { - return Navigation.goBack(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID))} />; + return; } const closeImportPageAndModal = () => {