Skip to content

Commit 227aa13

Browse files
authored
Merge pull request #48184 from software-mansion-labs/Guccio/47019-TagSettingsBillable
Tag settings: Billable #47019
2 parents 77beaa2 + bb30c66 commit 227aa13

10 files changed

+137
-116
lines changed

src/languages/en.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2972,7 +2972,7 @@ export default {
29722972
},
29732973
tags: {
29742974
title: 'Tags',
2975-
subtitle: 'Add additional ways to classify spend.',
2975+
subtitle: 'Classify costs and track billable expenses.',
29762976
},
29772977
taxes: {
29782978
title: 'Taxes',
@@ -3048,6 +3048,7 @@ export default {
30483048
tags: {
30493049
tagName: 'Tag name',
30503050
requiresTag: 'Members must tag all expenses',
3051+
trackBillable: 'Track billable expenses',
30513052
customTagName: 'Custom tag name',
30523053
enableTag: 'Enable tag',
30533054
enableTags: 'Enable tags',

src/languages/es.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3023,7 +3023,7 @@ export default {
30233023
},
30243024
tags: {
30253025
title: 'Etiquetas',
3026-
subtitle: 'Añade formas adicionales de clasificar los gastos.',
3026+
subtitle: 'Clasifica costes y rastrea gastos facturables.',
30273027
},
30283028
taxes: {
30293029
title: 'Impuestos',
@@ -3099,6 +3099,7 @@ export default {
30993099
tags: {
31003100
tagName: 'Nombre de etiqueta',
31013101
requiresTag: 'Los miembros deben etiquetar todos los gastos',
3102+
trackBillable: 'Permitir marcar gastos como facturables',
31023103
customTagName: 'Nombre de etiqueta personalizada',
31033104
enableTag: 'Habilitar etiqueta',
31043105
enableTags: 'Habilitar etiquetas',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type DisablePolicyBillableModeParams = {
2+
policyID: string;
3+
};
4+
5+
export default DisablePolicyBillableModeParams;

src/libs/API/parameters/SetPolicyBillableMode.ts src/libs/API/parameters/SetPolicyBillableModeParams.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
type SetPolicyBillableMode = {
1+
type SetPolicyBillableModeParams = {
2+
policyID: string;
23
defaultBillable: boolean;
34
/**
45
* Stringified JSON object with type of following structure:
@@ -9,4 +10,4 @@ type SetPolicyBillableMode = {
910
disabledFields: string;
1011
};
1112

12-
export default SetPolicyBillableMode;
13+
export default SetPolicyBillableModeParams;

src/libs/API/parameters/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ export type {default as SetPolicyRulesEnabledParams} from './SetPolicyRulesEnabl
278278
export type {default as SetPolicyExpenseMaxAmountNoReceipt} from './SetPolicyExpenseMaxAmountNoReceipt';
279279
export type {default as SetPolicyExpenseMaxAmount} from './SetPolicyExpenseMaxAmount';
280280
export type {default as SetPolicyExpenseMaxAge} from './SetPolicyExpenseMaxAge';
281-
export type {default as SetPolicyBillableMode} from './SetPolicyBillableMode';
281+
export type {default as SetPolicyBillableModeParams} from './SetPolicyBillableModeParams';
282+
export type {default as DisablePolicyBillableModeParams} from './DisablePolicyBillableModeParams';
282283
export type {default as SetWorkspaceEReceiptsEnabled} from './SetWorkspaceEReceiptsEnabled';
283284
export type {default as ConfigureExpensifyCardsForPolicyParams} from './ConfigureExpensifyCardsForPolicyParams';
284285
export type {default as CreateExpensifyCardParams} from './CreateExpensifyCardParams';

src/libs/API/types.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ const WRITE_COMMANDS = {
209209
SET_POLICY_EXPENSE_MAX_AMOUNT: 'SetPolicyExpenseMaxAmount',
210210
SET_POLICY_EXPENSE_MAX_AGE: ' SetPolicyExpenseMaxAge',
211211
SET_POLICY_BILLABLE_MODE: ' SetPolicyBillableMode',
212+
DISABLE_POLICY_BILLABLE_MODE: 'DisablePolicyBillableExpenses',
212213
SET_WORKSPACE_ERECEIPTS_ENABLED: 'SetWorkspaceEReceiptsEnabled',
213214
SET_POLICY_TAXES_CURRENCY_DEFAULT: 'SetPolicyCurrencyDefaultTax',
214215
SET_POLICY_TAXES_FOREIGN_CURRENCY_DEFAULT: 'SetPolicyForeignCurrencyDefaultTax',
@@ -589,7 +590,8 @@ type WriteCommandParameters = {
589590
[WRITE_COMMANDS.SET_POLICY_EXPENSE_MAX_AMOUNT_NO_RECEIPT]: Parameters.SetPolicyExpenseMaxAmountNoReceipt;
590591
[WRITE_COMMANDS.SET_POLICY_EXPENSE_MAX_AMOUNT]: Parameters.SetPolicyExpenseMaxAmount;
591592
[WRITE_COMMANDS.SET_POLICY_EXPENSE_MAX_AGE]: Parameters.SetPolicyExpenseMaxAge;
592-
[WRITE_COMMANDS.SET_POLICY_BILLABLE_MODE]: Parameters.SetPolicyBillableMode;
593+
[WRITE_COMMANDS.SET_POLICY_BILLABLE_MODE]: Parameters.SetPolicyBillableModeParams;
594+
[WRITE_COMMANDS.DISABLE_POLICY_BILLABLE_MODE]: Parameters.DisablePolicyBillableModeParams;
593595
[WRITE_COMMANDS.SET_WORKSPACE_ERECEIPTS_ENABLED]: Parameters.SetWorkspaceEReceiptsEnabled;
594596
[WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_ENABLE_NEW_CATEGORIES]: Parameters.UpdateQuickbooksOnlineGenericTypeParams;
595597
[WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_AUTO_CREATE_VENDOR]: Parameters.UpdateQuickbooksOnlineAutoCreateVendorParams;

src/libs/actions/Policy/Policy.ts

+60-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
CreateWorkspaceParams,
1313
DeleteWorkspaceAvatarParams,
1414
DeleteWorkspaceParams,
15+
DisablePolicyBillableModeParams,
1516
EnablePolicyCompanyCardsParams,
1617
EnablePolicyConnectionsParams,
1718
EnablePolicyExpensifyCardsParams,
@@ -32,6 +33,7 @@ import type {
3233
OpenWorkspaceParams,
3334
OpenWorkspaceReimburseViewParams,
3435
RequestExpensifyCardLimitIncreaseParams,
36+
SetPolicyBillableModeParams,
3537
SetWorkspaceApprovalModeParams,
3638
SetWorkspaceAutoReportingFrequencyParams,
3739
SetWorkspaceAutoReportingMonthlyOffsetParams,
@@ -3645,6 +3647,7 @@ function setPolicyBillableMode(policyID: string, defaultBillable: boolean) {
36453647
},
36463648
pendingFields: {
36473649
defaultBillable: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
3650+
disabledFields: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
36483651
},
36493652
},
36503653
},
@@ -3656,6 +3659,7 @@ function setPolicyBillableMode(policyID: string, defaultBillable: boolean) {
36563659
value: {
36573660
pendingFields: {
36583661
defaultBillable: null,
3662+
disabledFields: null,
36593663
},
36603664
errorFields: null,
36613665
},
@@ -3668,14 +3672,14 @@ function setPolicyBillableMode(policyID: string, defaultBillable: boolean) {
36683672
value: {
36693673
disabledFields: {defaultBillable: originalDefaultBillableDisabled},
36703674
defaultBillable: originalDefaultBillable,
3671-
pendingFields: {defaultBillable: null},
3675+
pendingFields: {defaultBillable: null, disabledFields: null},
36723676
errorFields: {defaultBillable: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')},
36733677
},
36743678
},
36753679
],
36763680
};
36773681

3678-
const parameters = {
3682+
const parameters: SetPolicyBillableModeParams = {
36793683
policyID,
36803684
defaultBillable,
36813685
disabledFields: JSON.stringify({
@@ -3686,6 +3690,59 @@ function setPolicyBillableMode(policyID: string, defaultBillable: boolean) {
36863690
API.write(WRITE_COMMANDS.SET_POLICY_BILLABLE_MODE, parameters, onyxData);
36873691
}
36883692

3693+
/**
3694+
* Call the API to disable the billable mode for the given policy
3695+
* @param policyID - id of the policy to enable or disable the bilable mode
3696+
*/
3697+
function disableWorkspaceBillableExpenses(policyID: string) {
3698+
const policy = getPolicy(policyID);
3699+
const originalDefaultBillableDisabled = policy?.disabledFields?.defaultBillable;
3700+
3701+
const onyxData: OnyxData = {
3702+
optimisticData: [
3703+
{
3704+
onyxMethod: Onyx.METHOD.MERGE,
3705+
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
3706+
value: {
3707+
disabledFields: {
3708+
defaultBillable: true,
3709+
},
3710+
pendingFields: {
3711+
disabledFields: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
3712+
},
3713+
},
3714+
},
3715+
],
3716+
successData: [
3717+
{
3718+
onyxMethod: Onyx.METHOD.MERGE,
3719+
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
3720+
value: {
3721+
pendingFields: {
3722+
disabledFields: null,
3723+
},
3724+
},
3725+
},
3726+
],
3727+
failureData: [
3728+
{
3729+
onyxMethod: Onyx.METHOD.MERGE,
3730+
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
3731+
value: {
3732+
pendingFields: {disabledFields: null},
3733+
disabledFields: {defaultBillable: originalDefaultBillableDisabled},
3734+
},
3735+
},
3736+
],
3737+
};
3738+
3739+
const parameters: DisablePolicyBillableModeParams = {
3740+
policyID,
3741+
};
3742+
3743+
API.write(WRITE_COMMANDS.DISABLE_POLICY_BILLABLE_MODE, parameters, onyxData);
3744+
}
3745+
36893746
function setWorkspaceEReceiptsEnabled(policyID: string, eReceipts: boolean) {
36903747
const policy = getPolicy(policyID);
36913748

@@ -3914,6 +3971,7 @@ export {
39143971
setPolicyMaxExpenseAmount,
39153972
setPolicyMaxExpenseAge,
39163973
setPolicyBillableMode,
3974+
disableWorkspaceBillableExpenses,
39173975
setWorkspaceEReceiptsEnabled,
39183976
setWorkspaceCompanyCardFeedName,
39193977
deleteWorkspaceCompanyCardFeed,

src/pages/Search/AdvancedSearchFilters.tsx

-82
Original file line numberDiff line numberDiff line change
@@ -243,88 +243,6 @@ function AdvancedSearchFilters() {
243243
const [cardList = {}] = useOnyx(ONYXKEYS.CARD_LIST);
244244
const taxRates = getAllTaxRates();
245245
const personalDetails = usePersonalDetails();
246-
247-
// const advancedFilters = useMemo(
248-
// () => [
249-
// {
250-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.DATE, translate),
251-
// description: 'common.date' as const,
252-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_DATE,
253-
// },
254-
// {
255-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.CURRENCY, translate),
256-
// description: 'common.currency' as const,
257-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_CURRENCY,
258-
// },
259-
// {
260-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.MERCHANT, translate),
261-
// description: 'common.merchant' as const,
262-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_MERCHANT,
263-
// },
264-
// {
265-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.DESCRIPTION, translate),
266-
// description: 'common.description' as const,
267-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_DESCRIPTION,
268-
// },
269-
// {
270-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.REPORT_ID, translate),
271-
// description: 'common.reportID' as const,
272-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_REPORT_ID,
273-
// },
274-
// {
275-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.AMOUNT, translate),
276-
// description: 'common.total' as const,
277-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_AMOUNT,
278-
// },
279-
// {
280-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.CATEGORY, translate),
281-
// description: 'common.category' as const,
282-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_CATEGORY,
283-
// },
284-
// {
285-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.KEYWORD, translate),
286-
// description: 'search.filters.hasKeywords' as const,
287-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_KEYWORD,
288-
// },
289-
// {
290-
// title: getFilterCardDisplayTitle(searchAdvancedFilters, cardList),
291-
// description: 'common.card' as const,
292-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_CARD,
293-
// shouldHide: Object.keys(cardList).length === 0,
294-
// },
295-
// {
296-
// title: getFilterTaxRateDisplayTitle(searchAdvancedFilters, taxRates),
297-
// description: 'workspace.taxes.taxRate' as const,
298-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_TAX_RATE,
299-
// },
300-
// {
301-
// title: getFilterExpenseDisplayTitle(searchAdvancedFilters, translate),
302-
// description: 'search.expenseType' as const,
303-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_EXPENSE_TYPE,
304-
// },
305-
// {
306-
// title: getFilterDisplayTitle(searchAdvancedFilters, CONST.SEARCH.SYNTAX_FILTER_KEYS.TAG, translate),
307-
// description: 'common.tag' as const,
308-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_TAG,
309-
// },
310-
// {
311-
// title: getFilterParticipantDisplayTitle(searchAdvancedFilters.from ?? [], personalDetails),
312-
// description: 'common.from' as const,
313-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_FROM,
314-
// },
315-
// {
316-
// title: getFilterParticipantDisplayTitle(searchAdvancedFilters.to ?? [], personalDetails),
317-
// description: 'common.to' as const,
318-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_TO,
319-
// },
320-
// {
321-
// title: getFilterInDisplayTitle(searchAdvancedFilters, translate, reports),
322-
// description: 'common.in' as const,
323-
// route: ROUTES.SEARCH_ADVANCED_FILTERS_IN,
324-
// },
325-
// ],
326-
// [searchAdvancedFilters, translate, cardList, taxRates, personalDetails, reports],
327-
// );
328246
const currentType = searchAdvancedFilters?.type ?? CONST.SEARCH.DATA_TYPES.EXPENSE;
329247

330248
const onFormSubmit = () => {

src/pages/workspace/WorkspaceInitialPage.tsx

+9-9
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,15 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc
266266
});
267267
}
268268

269+
if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED] && canUseWorkspaceRules) {
270+
protectedCollectPolicyMenuItems.push({
271+
translationKey: 'workspace.common.rules',
272+
icon: Expensicons.Feed,
273+
action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_RULES.getRoute(policyID)))),
274+
routeName: SCREENS.WORKSPACE.RULES,
275+
});
276+
}
277+
269278
if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) {
270279
protectedCollectPolicyMenuItems.push({
271280
translationKey: 'workspace.common.categories',
@@ -314,15 +323,6 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc
314323
});
315324
}
316325

317-
if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED] && canUseWorkspaceRules) {
318-
protectedCollectPolicyMenuItems.push({
319-
translationKey: 'workspace.common.rules',
320-
icon: Expensicons.Feed,
321-
action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_RULES.getRoute(policyID)))),
322-
routeName: SCREENS.WORKSPACE.RULES,
323-
});
324-
}
325-
326326
protectedCollectPolicyMenuItems.push({
327327
translationKey: 'workspace.common.moreFeatures',
328328
icon: Expensicons.Gear,

0 commit comments

Comments
 (0)