Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Policy category - Add Payroll Code #43151

Merged
merged 41 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
fda657c
add payroll screen
rushatgabhane Jun 5, 2024
bdf8070
add payroll route
rushatgabhane Jun 5, 2024
b29331a
add navigation links for payroll
rushatgabhane Jun 5, 2024
78cb661
add nav type
rushatgabhane Jun 5, 2024
4ad00ea
add menu item for payroll code to category settings page
rushatgabhane Jun 5, 2024
2cec124
add payroll code to category type
rushatgabhane Jun 5, 2024
bf7b779
add payroll code to form type
rushatgabhane Jun 5, 2024
6d1e603
add payroll code to form type
rushatgabhane Jun 5, 2024
4e6c965
add payroll code
rushatgabhane Jun 5, 2024
2e60d83
add payroll code err msg
rushatgabhane Jun 5, 2024
f20f10c
add payroll code page
rushatgabhane Jun 5, 2024
bf3dd2f
add api command impl for set payroll code
rushatgabhane Jun 5, 2024
ed69bd0
add api params
rushatgabhane Jun 6, 2024
d150bdc
link api params
rushatgabhane Jun 6, 2024
05be40c
add payroll code api typing
rushatgabhane Jun 6, 2024
9a15098
api call to payroll code
rushatgabhane Jun 6, 2024
47d4566
fix typo
rushatgabhane Jun 6, 2024
b8aa3b2
use correct pending fields
rushatgabhane Jun 6, 2024
ff2c261
run prettier
rushatgabhane Jun 6, 2024
1529597
merge main
rushatgabhane Jun 26, 2024
e5c6ca0
add max length
rushatgabhane Jun 26, 2024
2a4637b
fix merge
rushatgabhane Jun 26, 2024
3e7bb90
use translation key
rushatgabhane Jun 26, 2024
fb3c493
merge main
rushatgabhane Jul 6, 2024
cc0423b
set pending fields as none
rushatgabhane Jul 6, 2024
d7f3aa4
use useonyx
rushatgabhane Jul 6, 2024
3bb29bc
add fallback navigation
rushatgabhane Jul 6, 2024
d75e74a
fix merge
rushatgabhane Jul 9, 2024
2bc06c9
add control policy access variant
rushatgabhane Jul 9, 2024
89fec2f
add control policy access variant
rushatgabhane Jul 9, 2024
d884e04
add control policy access variant
rushatgabhane Jul 9, 2024
39f60d5
add control policy access variant
rushatgabhane Jul 9, 2024
e2ac2e0
spanish translation
rushatgabhane Jul 9, 2024
1fc92a8
rename to payroll
rushatgabhane Jul 10, 2024
d62c5bd
rename to payroll code
rushatgabhane Jul 10, 2024
57a31f3
merge main
rushatgabhane Jul 10, 2024
7d8abfb
disable for non control policy
rushatgabhane Jul 10, 2024
529061a
Merge branch 'main' into payroll
rushatgabhane Jul 11, 2024
22df8b4
run prettier
rushatgabhane Jul 11, 2024
6a340ff
fix merge conflicts
rushatgabhane Jul 11, 2024
06265b2
fix merge
rushatgabhane Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,7 @@ const CONST = {
ACCESS_VARIANTS: {
PAID: 'paid',
ADMIN: 'admin',
CONTROL: 'control',
},
DEFAULT_MAX_EXPENSE_AGE: 90,
DEFAULT_MAX_EXPENSE_AMOUNT: 200000,
Expand Down Expand Up @@ -5238,6 +5239,7 @@ const CONST = {
},
},

MAX_LENGTH_256: 256,
WORKSPACE_CARDS_LIST_LABEL_TYPE: {
CURRENT_BALANCE: 'currentBalance',
REMAINING_LIMIT: 'remainingLimit',
Expand Down
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/categories/:categoryName/edit',
getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURIComponent(categoryName)}/edit` as const,
},
WORKSPACE_CATEGORY_PAYROLL_CODE: {
route: 'settings/workspaces/:policyID/categories/:categoryName/payroll-code',
getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURIComponent(categoryName)}/payroll-code` as const,
},
WORKSPACE_MORE_FEATURES: {
route: 'settings/workspaces/:policyID/more-features',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/more-features` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ const SCREENS = {
NAME: 'Workspace_Profile_Name',
CATEGORY_CREATE: 'Category_Create',
CATEGORY_EDIT: 'Category_Edit',
CATEGORY_PAYROLL_CODE: 'Category_Payroll_Code',
CATEGORY_SETTINGS: 'Category_Settings',
CATEGORIES_SETTINGS: 'Categories_Settings',
MORE_FEATURES: 'Workspace_More_Features',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2663,6 +2663,8 @@ export default {
existingCategoryError: 'A category with this name already exists.',
invalidCategoryName: 'Invalid category name.',
importedFromAccountingSoftware: 'The categories below are imported from your',
payrollCode: 'Payroll code',
updatePayrollCodeFailureMessage: 'An error occurred while updating the payroll code, please try again.',
},
moreFeatures: {
spendSection: {
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2709,6 +2709,8 @@ export default {
existingCategoryError: 'Ya existe una categoría con este nombre.',
invalidCategoryName: 'Lo nombre de la categoría es invalido.',
importedFromAccountingSoftware: 'Categorías importadas desde',
payrollCode: 'Código de nómina',
updatePayrollCodeFailureMessage: 'Se produjo un error al actualizar el código de nómina, por favor intente nuevamente.',
},
moreFeatures: {
spendSection: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type UpdatePolicyCategoryPayrollCodeParams = {
policyID: string;
categoryName: string;
payrollCode: string;
};

export default UpdatePolicyCategoryPayrollCodeParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export type {default as CreateWorkspaceCategoriesParams} from './CreateWorkspace
export type {default as RenameWorkspaceCategoriesParams} from './RenameWorkspaceCategoriesParams';
export type {default as SetWorkspaceRequiresCategoryParams} from './SetWorkspaceRequiresCategoryParams';
export type {default as DeleteWorkspaceCategoriesParams} from './DeleteWorkspaceCategoriesParams';
export type {default as UpdatePolicyCategoryPayrollCodeParams} from './UpdatePolicyCategoryPayrollCodeParams';
export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWorkspaceAutoReportingFrequencyParams';
export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams';
export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ const WRITE_COMMANDS = {
CREATE_POLICY_TAG: 'CreatePolicyTag',
RENAME_POLICY_TAG: 'RenamePolicyTag',
SET_WORKSPACE_REQUIRES_CATEGORY: 'SetWorkspaceRequiresCategory',
UPDATE_POLICY_CATEGORY_PAYROLL_CODE: 'UpdatePolicyCategoryPayrollCode',
DELETE_WORKSPACE_CATEGORIES: 'DeleteWorkspaceCategories',
DELETE_POLICY_REPORT_FIELD: 'DeletePolicyReportField',
SET_POLICY_TAGS_REQUIRED: 'SetPolicyTagsRequired',
Expand Down Expand Up @@ -426,6 +427,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.RENAME_WORKSPACE_CATEGORY]: Parameters.RenameWorkspaceCategoriesParams;
[WRITE_COMMANDS.SET_WORKSPACE_REQUIRES_CATEGORY]: Parameters.SetWorkspaceRequiresCategoryParams;
[WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES]: Parameters.DeleteWorkspaceCategoriesParams;
[WRITE_COMMANDS.UPDATE_POLICY_CATEGORY_PAYROLL_CODE]: Parameters.UpdatePolicyCategoryPayrollCodeParams;
[WRITE_COMMANDS.DELETE_POLICY_REPORT_FIELD]: Parameters.PolicyReportFieldsReplace;
[WRITE_COMMANDS.SET_POLICY_REQUIRES_TAG]: Parameters.SetPolicyRequiresTag;
[WRITE_COMMANDS.SET_POLICY_TAGS_REQUIRED]: Parameters.SetPolicyTagsRequired;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.OWNER_CHANGE_ERROR]: () => require<ReactComponentModule>('../../../../pages/workspace/members/WorkspaceOwnerChangeErrorPage').default,
[SCREENS.WORKSPACE.CATEGORY_CREATE]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/CreateCategoryPage').default,
[SCREENS.WORKSPACE.CATEGORY_EDIT]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/EditCategoryPage').default,
[SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/CategoryPayrollCodePage').default,
[SCREENS.WORKSPACE.CREATE_DISTANCE_RATE]: () => require<ReactComponentModule>('../../../../pages/workspace/distanceRates/CreateDistanceRatePage').default,
[SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS]: () => require<ReactComponentModule>('../../../../pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage').default,
[SCREENS.WORKSPACE.DISTANCE_RATE_DETAILS]: () => require<ReactComponentModule>('../../../../pages/workspace/distanceRates/PolicyDistanceRateDetailsPage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,13 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.TAG_EDIT,
SCREENS.WORKSPACE.TAG_LIST_VIEW,
],
[SCREENS.WORKSPACE.CATEGORIES]: [SCREENS.WORKSPACE.CATEGORY_CREATE, SCREENS.WORKSPACE.CATEGORY_SETTINGS, SCREENS.WORKSPACE.CATEGORIES_SETTINGS, SCREENS.WORKSPACE.CATEGORY_EDIT],
[SCREENS.WORKSPACE.CATEGORIES]: [
SCREENS.WORKSPACE.CATEGORY_CREATE,
SCREENS.WORKSPACE.CATEGORY_SETTINGS,
SCREENS.WORKSPACE.CATEGORIES_SETTINGS,
SCREENS.WORKSPACE.CATEGORY_EDIT,
SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE,
],
[SCREENS.WORKSPACE.DISTANCE_RATES]: [
SCREENS.WORKSPACE.CREATE_DISTANCE_RATE,
SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS,
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 @@ -519,6 +519,12 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
categoryName: (categoryName: string) => decodeURIComponent(categoryName),
},
},
[SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE]: {
path: ROUTES.WORKSPACE_CATEGORY_PAYROLL_CODE.route,
parse: {
categoryName: (categoryName: string) => decodeURIComponent(categoryName),
},
},
[SCREENS.WORKSPACE.CREATE_DISTANCE_RATE]: {
path: ROUTES.WORKSPACE_CREATE_DISTANCE_RATE.route,
},
Expand Down
4 changes: 4 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ type SettingsNavigatorParamList = {
categoryName: string;
backTo?: Routes;
};
[SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE]: {
policyID: string;
categoryName: string;
};
[SCREENS.WORKSPACE.CATEGORY_SETTINGS]: {
policyID: string;
categoryName: string;
Expand Down
5 changes: 5 additions & 0 deletions src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ function isPaidGroupPolicy(policy: OnyxEntry<Policy>): boolean {
return policy?.type === CONST.POLICY.TYPE.TEAM || policy?.type === CONST.POLICY.TYPE.CORPORATE;
}

function isControlPolicy(policy: OnyxEntry<Policy>): boolean {
return policy?.type === CONST.POLICY.TYPE.CORPORATE;
}

function isTaxTrackingEnabled(isPolicyExpenseChat: boolean, policy: OnyxEntry<Policy>, isDistanceRequest: boolean): boolean {
const distanceUnit = getCustomUnit(policy);
const customUnitID = distanceUnit?.customUnitID ?? 0;
Expand Down Expand Up @@ -806,6 +810,7 @@ export {
getIntegrationLastSuccessfulDate,
getCurrentConnectionName,
getCustomersOrJobsLabelNetSuite,
isControlPolicy,
isNetSuiteCustomSegmentRecord,
getNameFromNetSuiteCustomField,
isNetSuiteCustomFieldPropertyEditable,
Expand Down
69 changes: 69 additions & 0 deletions src/libs/actions/Policy/Category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,74 @@ function renamePolicyCategory(policyID: string, policyCategory: {oldName: string
API.write(WRITE_COMMANDS.RENAME_WORKSPACE_CATEGORY, parameters, onyxData);
}

function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, payrollCode: string) {
const policyCategoryToUpdate = allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`]?.[categoryName] ?? {};

const onyxData: OnyxData = {
optimisticData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
value: {
[categoryName]: {
...policyCategoryToUpdate,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
pendingFields: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'Payroll Code': CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
},
// eslint-disable-next-line @typescript-eslint/naming-convention
'Payroll Code': payrollCode,
},
},
},
],
successData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
value: {
[categoryName]: {
...policyCategoryToUpdate,
pendingAction: null,
pendingFields: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'Payroll Code': null,
},
// eslint-disable-next-line @typescript-eslint/naming-convention
'Payroll Code': payrollCode,
},
},
},
],
failureData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
value: {
[categoryName]: {
...policyCategoryToUpdate,
errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.categories.updatePayrollCodeFailureMessage'),
pendingAction: null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to reset pendingFields as well.

pendingFields: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'Payroll Code': null,
},
},
},
},
],
};

const parameters = {
policyID,
categoryName,
payrollCode,
};

API.write(WRITE_COMMANDS.UPDATE_POLICY_CATEGORY_PAYROLL_CODE, parameters, onyxData);
}

function setWorkspaceRequiresCategory(policyID: string, requiresCategory: boolean) {
const onyxData: OnyxData = {
optimisticData: [
Expand Down Expand Up @@ -616,6 +684,7 @@ export {
buildOptimisticPolicyRecentlyUsedCategories,
setWorkspaceCategoryEnabled,
setWorkspaceRequiresCategory,
setPolicyCategoryPayrollCode,
createPolicyCategory,
renamePolicyCategory,
clearCategoryErrors,
Expand Down
1 change: 1 addition & 0 deletions src/pages/workspace/AccessOrNotFoundWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject';

const ACCESS_VARIANTS = {
[CONST.POLICY.ACCESS_VARIANTS.PAID]: (policy: OnyxEntry<OnyxTypes.Policy>) => PolicyUtils.isPaidGroupPolicy(policy),
[CONST.POLICY.ACCESS_VARIANTS.CONTROL]: (policy: OnyxEntry<OnyxTypes.Policy>) => PolicyUtils.isControlPolicy(policy),
[CONST.POLICY.ACCESS_VARIANTS.ADMIN]: (policy: OnyxEntry<OnyxTypes.Policy>, login: string) => PolicyUtils.isPolicyAdmin(policy, login),
[CONST.IOU.ACCESS_VARIANTS.CREATE]: (
policy: OnyxEntry<OnyxTypes.Policy>,
Expand Down
87 changes: 87 additions & 0 deletions src/pages/workspace/categories/CategoryPayrollCodePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import {useOnyx} from 'react-native-onyx';
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 TextInput from '@components/TextInput';
import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import * as Category from '@userActions/Policy/Category';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import INPUT_IDS from '@src/types/form/WorkspaceCategoryForm';

type EditCategoryPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE>;

function CategoryPayrollCodePage({route}: EditCategoryPageProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const policyId = route.params.policyID ?? '-1';
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyId}`);

const categoryName = route.params.categoryName;
const payrollCode = policyCategories?.[categoryName]?.['Payroll Code'];
const {inputCallbackRef} = useAutoFocusInput();

const editPayrollCode = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_CATEGORY_FORM>) => {
const newPayrollCode = values.payrollCode.trim();
if (newPayrollCode !== payrollCode) {
Category.setPolicyCategoryPayrollCode(route.params.policyID, categoryName, newPayrollCode);
}
Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName));
},
[categoryName, payrollCode, route.params.categoryName, route.params.policyID],
);

return (
<AccessOrNotFoundWrapper
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.CONTROL]}
policyID={route.params.policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED}
>
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
style={[styles.defaultModalContainer]}
testID={CategoryPayrollCodePage.displayName}
shouldEnableMaxHeight
>
<HeaderWithBackButton
title={translate('workspace.categories.payrollCode')}
onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName))}
/>
<FormProvider
formID={ONYXKEYS.FORMS.WORKSPACE_CATEGORY_FORM}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use a different form name?

Copy link
Member Author

@rushatgabhane rushatgabhane Jul 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't see a reason why we should

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a blocker but in my opinion, each form should have a uniq id, this id ONYXKEYS.FORMS.WORKSPACE_CATEGORY_FORM is already used for updating category name form. And it only has name in the form values

type WorkspaceCategoryForm = Form<
InputID,
{
[INPUT_IDS.CATEGORY_NAME]: string;
}
>;

onSubmit={editPayrollCode}
submitButtonText={translate('common.save')}
style={[styles.mh5, styles.flex1]}
enabledWhenOffline
>
<InputWrapper
ref={inputCallbackRef}
InputComponent={TextInput}
defaultValue={payrollCode}
label={translate('workspace.categories.payrollCode')}
accessibilityLabel={translate('workspace.categories.payrollCode')}
inputID={INPUT_IDS.PAYROLL_CODE}
role={CONST.ROLE.PRESENTATION}
maxLength={CONST.MAX_LENGTH_256}
/>
</FormProvider>
</ScreenWrapper>
</AccessOrNotFoundWrapper>
);
}

CategoryPayrollCodePage.displayName = 'CategoryPayrollCodePage';

export default CategoryPayrollCodePage;
8 changes: 8 additions & 0 deletions src/pages/workspace/categories/CategorySettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ function CategorySettingsPage({route, policyCategories, navigation}: CategorySet
shouldShowRightIcon
/>
</OfflineWithFeedback>
<OfflineWithFeedback pendingAction={policyCategory.pendingFields?.['Payroll Code']}>
<MenuItemWithTopDescription
title={policyCategory['Payroll Code']}
description={translate(`workspace.categories.payrollCode`)}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_PAYROLL_CODE.getRoute(route.params.policyID, policyCategory.name))}
shouldShowRightIcon
/>
</OfflineWithFeedback>
{!isThereAnyAccountingConnection && (
<MenuItem
icon={Expensicons.Trashcan}
Expand Down
2 changes: 2 additions & 0 deletions src/types/form/WorkspaceCategoryForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type Form from './Form';

const INPUT_IDS = {
CATEGORY_NAME: 'categoryName',
PAYROLL_CODE: 'payrollCode',
} as const;

type InputID = ValueOf<typeof INPUT_IDS>;
Expand All @@ -11,6 +12,7 @@ type WorkspaceCategoryForm = Form<
InputID,
{
[INPUT_IDS.CATEGORY_NAME]: string;
[INPUT_IDS.PAYROLL_CODE]: string;
}
>;

Expand Down
4 changes: 4 additions & 0 deletions src/types/onyx/PolicyCategory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ type PolicyCategory = OnyxCommon.OnyxValueWithOfflineFeedback<{
// eslint-disable-next-line @typescript-eslint/naming-convention
'GL Code'?: string;

/** Payroll code is used to keep track of taxes, deductions, and an employee’s earnings */
// eslint-disable-next-line @typescript-eslint/naming-convention
'Payroll Code'?: string;
Gonals marked this conversation as resolved.
Show resolved Hide resolved

/** An ID for this category from an external accounting system */
externalID?: string;

Expand Down
Loading