diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts
index 4bf7987f9ceb..c3f52b0a6f08 100755
--- a/src/ONYXKEYS.ts
+++ b/src/ONYXKEYS.ts
@@ -159,9 +159,13 @@ const ONYXKEYS = {
/** Whether the user has seen HybridApp explanation modal */
NVP_SEEN_NEW_USER_MODAL: 'nvp_seen_new_user_modal',
+
/** Store the state of the subscription */
NVP_PRIVATE_SUBSCRIPTION: 'nvp_private_subscription',
+ /** Store the state of the private tax-exempt */
+ NVP_PRIVATE_TAX_EXEMPT: 'nvp_private_taxExempt',
+
/** Store the stripe id status */
NVP_PRIVATE_STRIPE_CUSTOMER_ID: 'nvp_private_stripeCustomerID',
@@ -841,6 +845,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.UPDATE_REQUIRED]: boolean;
[ONYXKEYS.RESET_REQUIRED]: boolean;
[ONYXKEYS.PLAID_CURRENT_EVENT]: string;
+ [ONYXKEYS.NVP_PRIVATE_TAX_EXEMPT]: boolean;
[ONYXKEYS.LOGS]: OnyxTypes.CapturedLogs;
[ONYXKEYS.SHOULD_STORE_LOGS]: boolean;
[ONYXKEYS.SHOULD_MASK_ONYX_STATE]: boolean;
diff --git a/src/components/ThreeDotsMenu/index.tsx b/src/components/ThreeDotsMenu/index.tsx
index 7c3358e4688c..da72135c6035 100644
--- a/src/components/ThreeDotsMenu/index.tsx
+++ b/src/components/ThreeDotsMenu/index.tsx
@@ -91,7 +91,7 @@ function ThreeDotsMenu({
>
diff --git a/src/languages/en.ts b/src/languages/en.ts
index cb5e0b76edef..09aeb1320c07 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -4195,6 +4195,8 @@ export default {
details: {
title: 'Subscription details',
annual: 'Annual subscription',
+ taxExempt: 'Request tax exempt status',
+ taxExemptEnabled: 'Tax exempt',
payPerUse: 'Pay-per-use',
subscriptionSize: 'Subscription size',
headsUp:
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 6f4ba907fc9c..893ec702b2d4 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -4718,6 +4718,8 @@ export default {
details: {
title: 'Datos de suscripción',
annual: 'Suscripción anual',
+ taxExempt: 'Solicitar estado de exención de impuestos',
+ taxExemptEnabled: 'Exento de impuestos',
payPerUse: 'Pago por uso',
subscriptionSize: 'Tamaño de suscripción',
headsUp:
diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index f15fba20bc98..bc34cf32e885 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -318,6 +318,7 @@ const WRITE_COMMANDS = {
UPDATE_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES_CREDIT_CARD_CHARGE_EXPORT_DEFAULT_VENDOR: 'UpdateSageIntacctNonreimbursableExpensesCreditCardChargeExportDefaultVendor',
UPDATE_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES_EXPORT_ACCOUNT: 'UpdateSageIntacctNonreimbursableExpensesExportAccount',
UPDATE_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES_EXPORT_VENDOR: 'UpdateSageIntacctNonreimbursableExpensesExportVendor',
+ REQUEST_TAX_EXEMPTION: 'RequestTaxExemption',
EXPORT_SEARCH_ITEMS_TO_CSV: 'ExportSearchToCSV',
CREATE_WORKSPACE_APPROVAL: 'CreateWorkspaceApproval',
UPDATE_WORKSPACE_APPROVAL: 'UpdateWorkspaceApproval',
@@ -563,6 +564,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.UPDATE_SUBSCRIPTION_AUTO_RENEW]: Parameters.UpdateSubscriptionAutoRenewParams;
[WRITE_COMMANDS.UPDATE_SUBSCRIPTION_ADD_NEW_USERS_AUTOMATICALLY]: Parameters.UpdateSubscriptionAddNewUsersAutomaticallyParams;
[WRITE_COMMANDS.UPDATE_SUBSCRIPTION_SIZE]: Parameters.UpdateSubscriptionSizeParams;
+ [WRITE_COMMANDS.REQUEST_TAX_EXEMPTION]: null;
[WRITE_COMMANDS.DELETE_MONEY_REQUEST_ON_SEARCH]: Parameters.DeleteMoneyRequestOnSearchParams;
[WRITE_COMMANDS.HOLD_MONEY_REQUEST_ON_SEARCH]: Parameters.HoldMoneyRequestOnSearchParams;
diff --git a/src/libs/actions/Subscription.ts b/src/libs/actions/Subscription.ts
index aaec38dbf5f8..0b431d5f36ed 100644
--- a/src/libs/actions/Subscription.ts
+++ b/src/libs/actions/Subscription.ts
@@ -288,6 +288,10 @@ function cancelBillingSubscription(cancellationReason: FeedbackSurveyOptionID, c
API.write(WRITE_COMMANDS.CANCEL_BILLING_SUBSCRIPTION, parameters);
}
+function requestTaxExempt() {
+ API.write(WRITE_COMMANDS.REQUEST_TAX_EXEMPTION, null);
+}
+
export {
openSubscriptionPage,
updateSubscriptionAutoRenew,
@@ -297,4 +301,5 @@ export {
updateSubscriptionType,
clearOutstandingBalance,
cancelBillingSubscription,
+ requestTaxExempt,
};
diff --git a/src/pages/settings/Subscription/SubscriptionDetails/index.tsx b/src/pages/settings/Subscription/SubscriptionDetails/index.tsx
index 870914488176..c78847cb35aa 100644
--- a/src/pages/settings/Subscription/SubscriptionDetails/index.tsx
+++ b/src/pages/settings/Subscription/SubscriptionDetails/index.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
+import Badge from '@components/Badge';
import Icon from '@components/Icon';
import * as Illustrations from '@components/Icon/Illustrations';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
@@ -13,6 +14,7 @@ import useLocalize from '@hooks/useLocalize';
import useThemeIllustrations from '@hooks/useThemeIllustrations';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
+import TaxExemptActions from '@pages/settings/Subscription/TaxExemptActions';
import variables from '@styles/variables';
import * as Subscription from '@userActions/Subscription';
import type {SubscriptionType} from '@src/CONST';
@@ -39,6 +41,7 @@ function SubscriptionDetails() {
const illustrations = useThemeIllustrations();
const [privateSubscription] = useOnyx(ONYXKEYS.NVP_PRIVATE_SUBSCRIPTION);
+ const [privateTaxExempt] = useOnyx(ONYXKEYS.NVP_PRIVATE_TAX_EXEMPT);
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const onOptionSelected = (option: SubscriptionType) => {
@@ -80,10 +83,21 @@ function SubscriptionDetails() {
return (
+
+
+ {translate('subscription.details.title')}
+ {privateTaxExempt && (
+
+ )}
+
+ {!privateTaxExempt && }
+
{!!account?.isApprovedAccountant || !!account?.isApprovedAccountantClient ? (
({horizontal: 0, vertical: 0});
+ const threeDotsMenuContainerRef = useRef(null);
+
+ const overflowMenu: ThreeDotsMenuProps['menuItems'] = useMemo(
+ () => [
+ {
+ icon: Expensicons.Coins,
+ numberOfLinesTitle: 2,
+ text: translate('subscription.details.taxExempt'),
+ onSelected: () => {
+ Subscription.requestTaxExempt();
+ Report.navigateToConciergeChat();
+ },
+ },
+ ],
+ [translate],
+ );
+
+ const calculateAndSetThreeDotsMenuPosition = useCallback(() => {
+ if (shouldUseNarrowLayout) {
+ return;
+ }
+ threeDotsMenuContainerRef.current?.measureInWindow((x, y, width, height) => {
+ setThreeDotsMenuPosition({
+ horizontal: x + width,
+ vertical: y + height,
+ });
+ });
+ }, [shouldUseNarrowLayout]);
+
+ return (
+
+
+
+ );
+}
+
+TaxExemptActions.displayName = 'TaxExemptActions';
+
+export default TaxExemptActions;
diff --git a/src/styles/utils/positioning.ts b/src/styles/utils/positioning.ts
index c266a7469bc2..cbfa8875b9ad 100644
--- a/src/styles/utils/positioning.ts
+++ b/src/styles/utils/positioning.ts
@@ -55,6 +55,9 @@ export default {
r8: {
right: 32,
},
+ rn3: {
+ right: -12,
+ },
b0: {
bottom: 0,
},