From b7cdc1b51d9ae04112c81c7c468de55dd29fe372 Mon Sep 17 00:00:00 2001 From: Jakub Kosmydel <104823336+kosmydel@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:26:24 +0100 Subject: [PATCH 01/37] add initial new tax page --- src/CONST.ts | 4 + src/ONYXKEYS.ts | 2 + src/ROUTES.ts | 4 + src/SCREENS.ts | 1 + src/languages/en.ts | 2 + .../AppNavigator/ModalStackNavigators.tsx | 1 + src/libs/Navigation/linkingConfig/config.ts | 3 + src/libs/Navigation/types.ts | 3 + .../workspace/taxes/WorkspaceNewTaxPage.tsx | 96 +++++++++++++++++++ .../workspace/taxes/WorkspaceTaxesPage.tsx | 6 +- src/types/form/WorkspaceNewTaxForm.ts | 22 +++++ src/types/form/index.ts | 1 + src/types/onyx/Policy.ts | 2 +- 13 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 src/pages/workspace/taxes/WorkspaceNewTaxPage.tsx create mode 100644 src/types/form/WorkspaceNewTaxForm.ts diff --git a/src/CONST.ts b/src/CONST.ts index 6861fe174ff..b981d10e5be 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4021,6 +4021,10 @@ const CONST = { SESSION_STORAGE_KEYS: { INITIAL_URL: 'INITIAL_URL', }, + + TAX_RATES: { + NAME_MAX_LENGTH: 50, + }, } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 188ab5646d3..05b1e1bec1f 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -404,6 +404,7 @@ const ONYXKEYS = { EXIT_SURVEY_REASON_FORM_DRAFT: 'exitSurveyReasonFormDraft', EXIT_SURVEY_RESPONSE_FORM: 'exitSurveyResponseForm', EXIT_SURVEY_RESPONSE_FORM_DRAFT: 'exitSurveyResponseFormDraft', + WORKSPACE_NEW_TAX_FORM: 'workspaceNewTaxForm', }, } as const; @@ -449,6 +450,7 @@ type OnyxFormValuesMapping = { [ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM]: FormTypes.ReimbursementAccountForm; [ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT]: FormTypes.PersonalBankAccountForm; [ONYXKEYS.FORMS.WORKSPACE_DESCRIPTION_FORM]: FormTypes.WorkspaceDescriptionForm; + [ONYXKEYS.FORMS.WORKSPACE_NEW_TAX_FORM]: FormTypes.WorkspaceNewTaxForm; }; type OnyxFormDraftValuesMapping = { diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 9704bf04731..f0f6fed658f 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -558,6 +558,10 @@ const ROUTES = { route: 'workspace/:policyID/taxes', getRoute: (policyID: string) => `workspace/${policyID}/taxes` as const, }, + WORKSPACE_TAXES_NEW: { + route: 'workspace/:policyID/taxes/new', + getRoute: (policyID: string) => `workspace/${policyID}/taxes/new` as const, + }, // Referral program promotion REFERRAL_DETAILS_MODAL: { route: 'referral/:contentType', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 27909319b72..d48cc9c19b8 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -216,6 +216,7 @@ const SCREENS = { CATEGORIES: 'Workspace_Categories', TAGS: 'Workspace_Tags', TAXES: 'Workspace_Taxes', + TAXES_NEW: 'Workspace_Taxes_New', CURRENCY: 'Workspace_Profile_Currency', WORKFLOWS: 'Workspace_Workflows', WORKFLOWS_APPROVER: 'Workspace_Workflows_Approver', diff --git a/src/languages/en.ts b/src/languages/en.ts index 715640bbb20..56c983ace28 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1787,6 +1787,8 @@ export default { }, taxes: { subtitle: 'Add tax names, rates, and set defaults.', + value: 'Value', + name: 'Name', }, emptyWorkspace: { title: 'Create a workspace', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index cee9e31cede..001891805bb 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -262,6 +262,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../pages/settings/ExitSurvey/ExitSurveyConfirmPage').default as React.ComponentType, [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: () => require('../../../pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage').default as React.ComponentType, [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET]: () => require('../../../pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage').default as React.ComponentType, + [SCREENS.WORKSPACE.TAXES_NEW]: () => require('../../../pages/workspace/taxes/WorkspaceNewTaxPage').default as React.ComponentType, }); const EnablePaymentsStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 0cae5e34e95..76f605c648b 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -309,6 +309,9 @@ const config: LinkingOptions['config'] = { [SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM]: { path: ROUTES.SETTINGS_EXIT_SURVEY_CONFIRM.route, }, + [SCREENS.WORKSPACE.TAXES_NEW]: { + path: ROUTES.WORKSPACE_TAXES_NEW.route, + }, }, }, [SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 5c64dd62fd4..fcd69c49a13 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -225,6 +225,9 @@ type SettingsNavigatorParamList = { [SCREENS.SETTINGS.EXIT_SURVEY.CONFIRM]: { backTo: Routes; }; + [SCREENS.WORKSPACE.TAXES_NEW]: { + policyID: string; + }; } & ReimbursementAccountNavigatorParamList; type NewChatNavigatorParamList = { diff --git a/src/pages/workspace/taxes/WorkspaceNewTaxPage.tsx b/src/pages/workspace/taxes/WorkspaceNewTaxPage.tsx new file mode 100644 index 00000000000..a23b8d3061d --- /dev/null +++ b/src/pages/workspace/taxes/WorkspaceNewTaxPage.tsx @@ -0,0 +1,96 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback} from 'react'; +import {View} from 'react-native'; +import AmountPicker from '@components/AmountPicker'; +import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; +import type {FormOnyxValues} from '@components/Form/types'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import TextPicker from '@components/TextPicker'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import {createWorkspaceTax} from '@libs/actions/TaxRate'; +import Navigation from '@libs/Navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; +import * as ValidationUtils from '@libs/ValidationUtils'; +import CONST from '@src/CONST'; +import type {TranslationPaths} from '@src/languages/types'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; +import INPUT_IDS from '@src/types/form/WorkspaceNewTaxForm'; +import type {TaxRate} from '@src/types/onyx'; + +type WorkspaceNewTaxPageProps = StackScreenProps; + +function WorkspaceNewTaxPage({ + route: { + params: {policyID}, + }, +}: WorkspaceNewTaxPageProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const validate = useCallback((values: FormOnyxValues): Partial> => { + const errors = ValidationUtils.getFieldRequiredErrors(values, [INPUT_IDS.VALUE, INPUT_IDS.NAME]); + + const value = Number(values[INPUT_IDS.VALUE]); + if (value > 100 || value < 0) { + errors[INPUT_IDS.VALUE] = 'workspace.taxes.errors.value.percentageRange'; + } + + return errors; + }, []); + + const submitForm = useCallback( + (values: FormOnyxValues) => { + // TODO: Add proper code generation + const taxRate = { + ...values, + code: `tax_${Date.now()}`, + } satisfies TaxRate; + createWorkspaceTax({policyID, taxRate}); + Navigation.goBack(); + }, + [policyID], + ); + + return ( + + + + + + + + + + ); +} + +WorkspaceNewTaxPage.displayName = 'WorkspaceNewTaxPage'; + +export default WorkspaceNewTaxPage; diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx index b19a69adebe..0f4340b97eb 100644 --- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx +++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx @@ -15,12 +15,14 @@ import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import Navigation from '@libs/Navigation/Navigation'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; -import type SCREENS from '@src/SCREENS'; +import ROUTES from '@src/ROUTES'; +import SCREENS from '@src/SCREENS'; type WorkspaceTaxesPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps; @@ -83,7 +85,7 @@ function WorkspaceTaxesPage({policy}: WorkspaceTaxesPageProps) {