Skip to content

Commit

Permalink
Merge pull request #42141 from nkdengineer/fix/41574
Browse files Browse the repository at this point in the history
Feature: Add the ability to configure tax rates on distance rates
  • Loading branch information
MonilBhavsar authored Jun 5, 2024
2 parents 263e2e4 + c0bd795 commit 8346110
Show file tree
Hide file tree
Showing 21 changed files with 602 additions and 34 deletions.
3 changes: 3 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ const ONYXKEYS = {
POLICY_CREATE_DISTANCE_RATE_FORM: 'policyCreateDistanceRateForm',
POLICY_CREATE_DISTANCE_RATE_FORM_DRAFT: 'policyCreateDistanceRateFormDraft',
POLICY_DISTANCE_RATE_EDIT_FORM: 'policyDistanceRateEditForm',
POLICY_DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT_FORM: 'policyDistanceRateTaxReclaimableOnEditForm',
POLICY_DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT_FORM_DRAFT: 'policyDistanceRateTaxReclaimableOnEditFormDraft',
POLICY_DISTANCE_RATE_EDIT_FORM_DRAFT: 'policyDistanceRateEditFormDraft',
CLOSE_ACCOUNT_FORM: 'closeAccount',
CLOSE_ACCOUNT_FORM_DRAFT: 'closeAccountDraft',
Expand Down Expand Up @@ -538,6 +540,7 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.WORKSPACE_NEW_TAX_FORM]: FormTypes.WorkspaceNewTaxForm;
[ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM]: FormTypes.PolicyCreateDistanceRateForm;
[ONYXKEYS.FORMS.POLICY_DISTANCE_RATE_EDIT_FORM]: FormTypes.PolicyDistanceRateEditForm;
[ONYXKEYS.FORMS.POLICY_DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT_FORM]: FormTypes.PolicyDistanceRateTaxReclaimableOnEditForm;
[ONYXKEYS.FORMS.WORKSPACE_TAX_NAME_FORM]: FormTypes.WorkspaceTaxNameForm;
[ONYXKEYS.FORMS.WORKSPACE_TAX_VALUE_FORM]: FormTypes.WorkspaceTaxValueForm;
[ONYXKEYS.FORMS.NEW_CHAT_NAME_FORM]: FormTypes.NewChatNameForm;
Expand Down
8 changes: 8 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,14 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/distance-rates/:rateID/edit',
getRoute: (policyID: string, rateID: string) => `settings/workspaces/${policyID}/distance-rates/${rateID}/edit` as const,
},
WORKSPACE_DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT: {
route: 'settings/workspaces/:policyID/distance-rates/:rateID/tax-reclaimable/edit',
getRoute: (policyID: string, rateID: string) => `settings/workspaces/${policyID}/distance-rates/${rateID}/tax-reclaimable/edit` as const,
},
WORKSPACE_DISTANCE_RATE_TAX_RATE_EDIT: {
route: 'settings/workspaces/:policyID/distance-rates/:rateID/tax-rate/edit',
getRoute: (policyID: string, rateID: string) => `settings/workspaces/${policyID}/distance-rates/${rateID}/tax-rate/edit` as const,
},
// Referral program promotion
REFERRAL_DETAILS_MODAL: {
route: 'referral/:contentType',
Expand Down
2 changes: 2 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ const SCREENS = {
DISTANCE_RATES_SETTINGS: 'Distance_Rates_Settings',
DISTANCE_RATE_DETAILS: 'Distance_Rate_Details',
DISTANCE_RATE_EDIT: 'Distance_Rate_Edit',
DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT: 'Distance_Rate_Tax_Reclaimable_On_Edit',
DISTANCE_RATE_TAX_RATE_EDIT: 'Distance_Rate_Tax_Rate_Edit',
},

EDIT_REQUEST: {
Expand Down
6 changes: 6 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2258,13 +2258,16 @@ export default {
foreignDefault: 'Foreign currency default',
customTaxName: 'Custom tax name',
value: 'Value',
taxReclaimableOn: 'Tax reclaimable on',
taxRate: 'Tax rate',
error: {
taxRateAlreadyExists: 'This tax name is already in use.',
valuePercentageRange: 'Please enter a valid percentage between 0 and 100.',
customNameRequired: 'Custom tax name is required.',
deleteFailureMessage: 'An error occurred while deleting the tax rate. Please try again or ask Concierge for help.',
updateFailureMessage: 'An error occurred while updating the tax rate. Please try again or ask Concierge for help.',
createFailureMessage: 'An error occurred while creating the tax rate. Please try again or ask Concierge for help.',
updateTaxClaimableFailureMessage: 'The reclaimable portion must be less than the distance rate amount.',
},
deleteTaxConfirmation: 'Are you sure you want to delete this tax?',
deleteMultipleTaxConfirmation: ({taxAmount}) => `Are you sure you want to delete ${taxAmount} taxes?`,
Expand Down Expand Up @@ -2554,12 +2557,15 @@ export default {
centrallyManage: 'Centrally manage rates, choose to track in miles or kilometers, and set a default category.',
rate: 'Rate',
addRate: 'Add rate',
trackTax: 'Track tax',
deleteRates: ({count}: DistanceRateOperationsParams) => `Delete ${Str.pluralize('rate', 'rates', count)}`,
enableRates: ({count}: DistanceRateOperationsParams) => `Enable ${Str.pluralize('rate', 'rates', count)}`,
disableRates: ({count}: DistanceRateOperationsParams) => `Disable ${Str.pluralize('rate', 'rates', count)}`,
enableRate: 'Enable rate',
status: 'Status',
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: ({count}: DistanceRateOperationsParams) => `Are you sure you want to delete ${Str.pluralize('this rate', 'these rates', count)}?`,
Expand Down
6 changes: 6 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2297,13 +2297,16 @@ export default {
foreignDefault: 'Moneda extranjera por defecto',
customTaxName: 'Nombre del impuesto',
value: 'Valor',
taxRate: 'Tasa de impuesto',
taxReclaimableOn: 'Impuesto recuperable en',
error: {
taxRateAlreadyExists: 'Ya existe un impuesto con este nombre.',
customNameRequired: 'El nombre del impuesto es obligatorio.',
valuePercentageRange: 'Por favor, introduce un porcentaje entre 0 y 100.',
deleteFailureMessage: 'Se ha producido un error al intentar eliminar la tasa de impuesto. Por favor, inténtalo más tarde.',
updateFailureMessage: 'Se ha producido un error al intentar modificar la tasa de impuesto. Por favor, inténtalo más tarde.',
createFailureMessage: 'Se ha producido un error al intentar crear la tasa de impuesto. Por favor, inténtalo más tarde.',
updateTaxClaimableFailureMessage: 'La porción recuperable debe ser menor al monto del importe por distancia.',
},
deleteTaxConfirmation: '¿Estás seguro de que quieres eliminar este impuesto?',
deleteMultipleTaxConfirmation: ({taxAmount}) => `¿Estás seguro de que quieres eliminar ${taxAmount} impuestos?`,
Expand Down Expand Up @@ -2594,12 +2597,15 @@ export default {
centrallyManage: 'Gestiona centralizadamente las tasas, elige si contabilizar en millas o kilómetros, y define una categoría por defecto',
rate: 'Tasa',
addRate: 'Agregar tasa',
trackTax: 'Impuesto de seguimiento',
deleteRates: ({count}: DistanceRateOperationsParams) => `Eliminar ${Str.pluralize('tasa', 'tasas', count)}`,
enableRates: ({count}: DistanceRateOperationsParams) => `Activar ${Str.pluralize('tasa', 'tasas', count)}`,
disableRates: ({count}: DistanceRateOperationsParams) => `Desactivar ${Str.pluralize('tasa', 'tasas', count)}`,
enableRate: 'Activar tasa',
status: 'Estado',
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: ({count}: DistanceRateOperationsParams) => `¿Estás seguro de que quieres eliminar ${Str.pluralize('esta tasa', 'estas tasas', count)}?`,
Expand Down
6 changes: 6 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ 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',
ENABLE_DISTANCE_REQUEST_TAX: 'EnableDistanceRequestTax',
UPDATE_POLICY_DISTANCE_RATE_VALUE: 'UpdatePolicyDistanceRateValue',
UPDATE_POLICY_DISTANCE_TAX_RATE_VALUE: 'UpdateDistanceTaxRate',
UPDATE_DISTANCE_TAX_CLAIMABLE_VALUE: 'UpdateDistanceTaxClaimableValue',
SET_POLICY_DISTANCE_RATES_ENABLED: 'SetPolicyDistanceRatesEnabled',
DELETE_POLICY_DISTANCE_RATES: 'DeletePolicyDistanceRates',
DISMISS_TRACK_EXPENSE_ACTIONABLE_WHISPER: 'DismissActionableWhisper',
Expand Down Expand Up @@ -419,12 +422,15 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.RENAME_POLICY_TAX]: Parameters.RenamePolicyTaxParams;
[WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_UNIT]: Parameters.SetPolicyDistanceRatesUnitParams;
[WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams;
[WRITE_COMMANDS.ENABLE_DISTANCE_REQUEST_TAX]: Parameters.SetPolicyDistanceRatesDefaultCategoryParams;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
[WRITE_COMMANDS.UPDATE_POLICY_CONNECTION_CONFIG]: Parameters.UpdatePolicyConnectionConfigParams;
[WRITE_COMMANDS.UPDATE_MANY_POLICY_CONNECTION_CONFIGS]: Parameters.UpdateManyPolicyConnectionConfigurationsParams;
[WRITE_COMMANDS.REMOVE_POLICY_CONNECTION]: Parameters.RemovePolicyConnectionParams;
[WRITE_COMMANDS.UPDATE_POLICY_DISTANCE_RATE_VALUE]: Parameters.UpdatePolicyDistanceRateValueParams;
[WRITE_COMMANDS.UPDATE_POLICY_DISTANCE_TAX_RATE_VALUE]: Parameters.UpdatePolicyDistanceRateValueParams;
[WRITE_COMMANDS.UPDATE_DISTANCE_TAX_CLAIMABLE_VALUE]: Parameters.UpdatePolicyDistanceRateValueParams;
[WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_ENABLED]: Parameters.SetPolicyDistanceRatesEnabledParams;
[WRITE_COMMANDS.DELETE_POLICY_DISTANCE_RATES]: Parameters.DeletePolicyDistanceRatesParams;
[WRITE_COMMANDS.DISMISS_TRACK_EXPENSE_ACTIONABLE_WHISPER]: Parameters.DismissTrackExpenseActionableWhisperParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS]: () => require('../../../../pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.DISTANCE_RATE_DETAILS]: () => require('../../../../pages/workspace/distanceRates/PolicyDistanceRateDetailsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.DISTANCE_RATE_EDIT]: () => require('../../../../pages/workspace/distanceRates/PolicyDistanceRateEditPage').default as React.ComponentType,
[SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT]: () =>
require('../../../../pages/workspace/distanceRates/PolicyDistanceRateTaxReclaimableEditPage').default as React.ComponentType,
[SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT]: () => require('../../../../pages/workspace/distanceRates/PolicyDistanceRateTaxRateEditPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TAGS_SETTINGS]: () => require('../../../../pages/workspace/tags/WorkspaceTagsSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TAG_SETTINGS]: () => require('../../../../pages/workspace/tags/TagSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.TAG_LIST_VIEW]: () => require('../../../../pages/workspace/tags/WorkspaceViewTagsPage').default as React.ComponentType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.CREATE_DISTANCE_RATE,
SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS,
SCREENS.WORKSPACE.DISTANCE_RATE_EDIT,
SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT,
SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT,
SCREENS.WORKSPACE.DISTANCE_RATE_DETAILS,
],
};
Expand Down
6 changes: 6 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,12 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.DISTANCE_RATE_EDIT]: {
path: ROUTES.WORKSPACE_DISTANCE_RATE_EDIT.route,
},
[SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT]: {
path: ROUTES.WORKSPACE_DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT.route,
},
[SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT]: {
path: ROUTES.WORKSPACE_DISTANCE_RATE_TAX_RATE_EDIT.route,
},
[SCREENS.WORKSPACE.TAGS_SETTINGS]: {
path: ROUTES.WORKSPACE_TAGS_SETTINGS.route,
},
Expand Down
8 changes: 8 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ type SettingsNavigatorParamList = {
policyID: string;
rateID: string;
};
[SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT]: {
policyID: string;
rateID: string;
};
[SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT]: {
policyID: string;
rateID: string;
};
[SCREENS.WORKSPACE.TAGS_SETTINGS]: {
policyID: string;
};
Expand Down
13 changes: 12 additions & 1 deletion src/libs/PolicyDistanceRatesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as NumberUtils from './NumberUtils';

type RateValueForm = typeof ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM | typeof ONYXKEYS.FORMS.POLICY_CREATE_DISTANCE_RATE_FORM | typeof ONYXKEYS.FORMS.POLICY_DISTANCE_RATE_EDIT_FORM;

type TaxReclaimableForm = typeof ONYXKEYS.FORMS.POLICY_DISTANCE_RATE_TAX_RECLAIMABLE_ON_EDIT_FORM;

function validateRateValue(values: FormOnyxValues<RateValueForm>, currency: string, toLocaleDigit: (arg: string) => string): FormInputErrors<RateValueForm> {
const errors: FormInputErrors<RateValueForm> = {};
const parsedRate = MoneyRequestUtils.replaceAllDigits(values.rate, toLocaleDigit);
Expand All @@ -24,6 +26,15 @@ function validateRateValue(values: FormOnyxValues<RateValueForm>, currency: stri
return errors;
}

function validateTaxClaimableValue(values: FormOnyxValues<TaxReclaimableForm>, rate: Rate): FormInputErrors<TaxReclaimableForm> {
const errors: FormInputErrors<TaxReclaimableForm> = {};

if (rate.rate && Number(values.taxClaimableValue) > rate.rate / 100) {
errors.taxClaimableValue = 'workspace.taxes.error.updateTaxClaimableFailureMessage';
}
return errors;
}

/**
* Get the optimistic rate name in a way that matches BE logic
* @param rates
Expand All @@ -33,4 +44,4 @@ function getOptimisticRateName(rates: Record<string, Rate>): string {
return existingRatesWithSameName.length ? `${CONST.CUSTOM_UNITS.DEFAULT_RATE} ${existingRatesWithSameName.length}` : CONST.CUSTOM_UNITS.DEFAULT_RATE;
}

export {validateRateValue, getOptimisticRateName};
export {validateRateValue, getOptimisticRateName, validateTaxClaimableValue};
6 changes: 3 additions & 3 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2252,9 +2252,9 @@ function getTrackExpenseInformation(
createdReportActionIDForThread: optimisticCreatedActionForTransactionThread.reportActionID,
actionableWhisperReportActionIDParam: actionableTrackExpenseWhisper?.reportActionID ?? '',
onyxData: {
optimisticData: [...optimisticData, ...trackExpenseOnyxData[0]],
successData: [...successData, ...trackExpenseOnyxData[1]],
failureData: [...failureData, ...trackExpenseOnyxData[2]],
optimisticData: optimisticData.concat(trackExpenseOnyxData[0]),
successData: successData.concat(trackExpenseOnyxData[1]),
failureData: failureData.concat(trackExpenseOnyxData[2]),
},
};
}
Expand Down
Loading

0 comments on commit 8346110

Please sign in to comment.