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

Clean-up in the Categorize it flow #52737

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6136,6 +6136,14 @@ const CONST = {
description: 'workspace.upgrade.reportFields.description' as const,
icon: 'Pencil',
},
categories: {
id: 'categories' as const,
alias: 'categories',
name: 'Categories',
title: 'workspace.upgrade.categories.title' as const,
description: 'workspace.upgrade.categories.description' as const,
icon: 'FolderOpen',
},
[this.POLICY.CONNECTIONS.NAME.NETSUITE]: {
id: this.POLICY.CONNECTIONS.NAME.NETSUITE,
alias: 'netsuite',
Expand Down
5 changes: 5 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ const ROUTES = {
getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string, backTo = '') =>
getUrlWithBackToParam(`${action as string}/${iouType as string}/attendees/${transactionID}/${reportID}`, backTo),
},
MONEY_REQUEST_UPGRADE: {
route: ':action/:iouType/upgrade/:transactionID/:reportID',
getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string, backTo = '') =>
getUrlWithBackToParam(`${action as string}/${iouType as string}/upgrade/${transactionID}/${reportID}`, backTo),
},
SETTINGS_TAGS_ROOT: {
route: 'settings/:policyID/tags',
getRoute: (policyID: string, backTo = '') => getUrlWithBackToParam(`settings/${policyID}/tags`, backTo),
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ const SCREENS = {
HOLD: 'Money_Request_Hold_Reason',
STEP_CONFIRMATION: 'Money_Request_Step_Confirmation',
START: 'Money_Request_Start',
STEP_UPGRADE: 'Money_Request_Step_Upgrade',
STEP_AMOUNT: 'Money_Request_Step_Amount',
STEP_CATEGORY: 'Money_Request_Step_Category',
STEP_CURRENCY: 'Money_Request_Step_Currency',
Expand Down
7 changes: 7 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4192,6 +4192,11 @@ const translations = {
description: `If you want to add more layers of approval to the mix – or just make sure the largest expenses get another set of eyes – we’ve got you covered. Advanced approvals help you put the right checks in place at every level so you keep your team’s spend under control.`,
onlyAvailableOnPlan: 'Advanced approvals are only available on the Control plan, which starts at ',
},
categories: {
title: 'Categories',
description: `Categories help you better organize expenses to keep track of where you're spending your money. Use our suggested categories list or create your own.`,
onlyAvailableOnPlan: 'Categories are available on the Collect plan, starting at ',
},
glCodes: {
title: 'GL codes',
description: `Add GL codes to your categories and tags for easy export of expenses to your accounting and payroll systems.`,
Expand Down Expand Up @@ -4224,6 +4229,7 @@ const translations = {
onlyAvailableOnPlan: 'Per diem are only available on the Control plan, starting at ',
},
pricing: {
collect: '$5 ',
amount: '$9 ',
perActiveMember: 'per active member per month.',
},
Expand All @@ -4236,6 +4242,7 @@ const translations = {
completed: {
headline: `You've upgraded your workspace!`,
successMessage: ({policyName}: ReportPolicyNameParams) => `You've successfully upgraded ${policyName} to the Control plan!`,
categorizeMessage: `You've successfully upgraded to a workspace on the Collect plan. Now you can categorize your expenses!`,
viewSubscription: 'View your subscription',
moreDetails: 'for more details.',
gotIt: 'Got it, thanks',
Expand Down
7 changes: 7 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4240,6 +4240,11 @@ const translations = {
description: `Si quieres añadir más niveles de aprobación, o simplemente asegurarte de que los gastos más importantes reciben otro vistazo, no hay problema. Las aprobaciones avanzadas ayudan a realizar las comprobaciones adecuadas a cada nivel para mantener los gastos de tu equipo bajo control.`,
onlyAvailableOnPlan: 'Las aprobaciones avanzadas sólo están disponibles en el plan Controlar, con precios desde ',
},
categories: {
title: 'Categorías',
description: `Las categorías te ayudan a organizar mejor los gastos y a llevar un seguimiento de en qué estás gastando tu dinero. Utiliza nuestra lista de categorías sugeridas o crea las tuyas propias.`,
onlyAvailableOnPlan: 'Las categorías están disponibles en el plan Recopilar, a partir de ',
},
glCodes: {
title: 'Códigos de libro mayor',
description: `Añada códigos de libro mayor a sus categorías para exportar fácilmente los gastos a sus sistemas de contabilidad y nómina.`,
Expand Down Expand Up @@ -4277,12 +4282,14 @@ const translations = {
aboutOurPlans: 'sobre nuestros planes y precios.',
},
pricing: {
collect: '$5 ',
amount: '$9 ',
perActiveMember: 'por miembro activo al mes.',
},
upgradeToUnlock: 'Desbloquear esta función',
completed: {
headline: 'Has mejorado tu espacio de trabajo.',
categorizeMessage: `Has actualizado con éxito a un espacio de trabajo en el plan Recopilar. ¡Ahora puedes categorizar tus gastos!`,
successMessage: ({policyName}: ReportPolicyNameParams) => `Has actualizado con éxito ${policyName} al plan Controlar.`,
viewSubscription: 'Ver su suscripción',
moreDetails: 'para obtener más información.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator<MoneyRequestNa
[SCREENS.IOU_SEND.ENABLE_PAYMENTS]: () => require<ReactComponentModule>('../../../../pages/EnablePayments/EnablePaymentsPage').default,
[SCREENS.MONEY_REQUEST.STATE_SELECTOR]: () => require<ReactComponentModule>('../../../../pages/settings/Profile/PersonalDetails/StateSelectionPage').default,
[SCREENS.MONEY_REQUEST.STEP_ATTENDEES]: () => require<ReactComponentModule>('../../../../pages/iou/request/step/IOURequestStepAttendees').default,
[SCREENS.MONEY_REQUEST.STEP_UPGRADE]: () => require<ReactComponentModule>('../../../../pages/iou/request/step/IOURequestStepUpgrade').default,
});

const TravelModalStackNavigator = createModalStackNavigator<TravelNavigatorParamList>({
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,7 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.MONEY_REQUEST.STATE_SELECTOR]: {path: ROUTES.MONEY_REQUEST_STATE_SELECTOR.route, exact: true},
[SCREENS.MONEY_REQUEST.STEP_SPLIT_PAYER]: ROUTES.MONEY_REQUEST_STEP_SPLIT_PAYER.route,
[SCREENS.MONEY_REQUEST.STEP_ATTENDEES]: ROUTES.MONEY_REQUEST_ATTENDEE.route,
[SCREENS.MONEY_REQUEST.STEP_UPGRADE]: ROUTES.MONEY_REQUEST_UPGRADE.route,
[SCREENS.IOU_SEND.ENABLE_PAYMENTS]: ROUTES.IOU_SEND_ENABLE_PAYMENTS,
[SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: ROUTES.IOU_SEND_ADD_BANK_ACCOUNT,
[SCREENS.IOU_SEND.ADD_DEBIT_CARD]: ROUTES.IOU_SEND_ADD_DEBIT_CARD,
Expand Down
7 changes: 7 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,13 @@ type MoneyRequestNavigatorParamList = {
reportID: string;
backTo: Routes;
};
[SCREENS.MONEY_REQUEST.STEP_UPGRADE]: {
action: IOUAction;
iouType: Exclude<IOUType, typeof CONST.IOU.TYPE.REQUEST | typeof CONST.IOU.TYPE.SEND>;
transactionID: string;
reportID: string;
backTo: Routes;
};
};

type NewTaskNavigatorParamList = {
Expand Down
44 changes: 44 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,12 @@ Onyx.connect({
},
});

let activePolicyID: OnyxEntry<string>;
Onyx.connect({
key: ONYXKEYS.NVP_ACTIVE_POLICY_ID,
callback: (value) => (activePolicyID = value),
});

function getCurrentUserAvatar(): AvatarSource | undefined {
return currentUserPersonalDetails?.avatar;
}
Expand Down Expand Up @@ -8211,6 +8217,44 @@ function createDraftTransactionAndNavigateToParticipantSelector(transactionID: s
(policy) => policy && policy.type !== CONST.POLICY.TYPE.PERSONAL && policy.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
);

if (actionName === CONST.IOU.ACTION.CATEGORIZE) {
const activePolicy = getPolicy(activePolicyID);
if (activePolicy && activePolicy?.type !== CONST.POLICY.TYPE.PERSONAL && activePolicy?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) {
const policyExpenseReportID = getPolicyExpenseChat(currentUserAccountID ?? -1, activePolicyID ?? '-1')?.reportID ?? '-1';
IOU.setMoneyRequestParticipants(transactionID, [
{
selected: true,
accountID: 0,
isPolicyExpenseChat: true,
reportID: policyExpenseReportID,
policyID: activePolicyID ?? '-1',
searchText: activePolicy?.name,
},
]);
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, policyExpenseReportID));
return;
}
if (filteredPolicies.length === 0 || filteredPolicies.length > 1) {
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
Navigation.navigate(ROUTES.MONEY_REQUEST_UPGRADE.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, reportID));
return;
}

const policyID = filteredPolicies.at(0)?.id;
const policyExpenseReportID = getPolicyExpenseChat(currentUserAccountID ?? -1, policyID ?? '-1')?.reportID ?? '-1';
IOU.setMoneyRequestParticipants(transactionID, [
{
selected: true,
accountID: 0,
isPolicyExpenseChat: true,
reportID: policyExpenseReportID,
policyID: policyID ?? '-1',
searchText: activePolicy?.name,
},
]);
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(actionName, CONST.IOU.TYPE.SUBMIT, transactionID, policyExpenseReportID));
return;
}

if (actionName === CONST.IOU.ACTION.SUBMIT || (allPolicies && filteredPolicies.length > 0)) {
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_PARTICIPANTS.getRoute(CONST.IOU.TYPE.SUBMIT, transactionID, reportID, undefined, actionName));
return;
Expand Down
82 changes: 82 additions & 0 deletions src/pages/iou/request/step/IOURequestStepUpgrade.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useRef, useState} from 'react';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import type CreateWorkspaceParams from '@libs/API/parameters/CreateWorkspaceParams';
import Navigation from '@libs/Navigation/Navigation';
import type {MoneyRequestNavigatorParamList} from '@libs/Navigation/types';
import UpgradeConfirmation from '@pages/workspace/upgrade/UpgradeConfirmation';
import UpgradeIntro from '@pages/workspace/upgrade/UpgradeIntro';
import * as IOU from '@userActions/IOU';
import CONST from '@src/CONST';
import * as Policy from '@src/libs/actions/Policy/Policy';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';

type IOURequestStepUpgradeProps = StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_UPGRADE>;

function IOURequestStepUpgrade({
route: {
params: {transactionID, action},
},
}: IOURequestStepUpgradeProps) {
const styles = useThemeStyles();
const feature = CONST.UPGRADE_FEATURE_INTRO_MAPPING.categories;
const {translate} = useLocalize();
const {isOffline} = useNetwork();

const [isUpgraded, setIsUpgraded] = useState(false);
const policyDataRef = useRef<CreateWorkspaceParams | null>(null);

return (
<ScreenWrapper
shouldShowOfflineIndicator
testID="workspaceUpgradePage"
offlineIndicatorStyle={styles.mtAuto}
>
<HeaderWithBackButton
title={translate('common.upgrade')}
onBackButtonPress={() => {
Navigation.goBack();
}}
/>
{!!isUpgraded && (
<UpgradeConfirmation
onConfirmUpgrade={() => {
IOU.setMoneyRequestParticipants(transactionID, [
{
selected: true,
accountID: 0,
isPolicyExpenseChat: true,
reportID: policyDataRef.current?.expenseChatReportID ?? '-1',
policyID: policyDataRef.current?.policyID,
searchText: policyDataRef.current?.policyName,
},
]);
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(action, CONST.IOU.TYPE.SUBMIT, transactionID, policyDataRef.current?.expenseChatReportID ?? '-1'));
}}
policyName=""
isCategorizing
/>
)}
{!isUpgraded && (
<UpgradeIntro
feature={feature}
onUpgrade={() => {
const policyData = Policy.createWorkspace();
setIsUpgraded(true);
policyDataRef.current = policyData;
}}
buttonDisabled={isOffline}
loading={false}
isCategorizing
/>
)}
</ScreenWrapper>
);
}

export default IOURequestStepUpgrade;
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ type MoneyRequestRouteName =
| typeof SCREENS.MONEY_REQUEST.STEP_SCAN
| typeof SCREENS.MONEY_REQUEST.STEP_SEND_FROM
| typeof SCREENS.MONEY_REQUEST.STEP_COMPANY_INFO
| typeof SCREENS.MONEY_REQUEST.STEP_ATTENDEES;
| typeof SCREENS.MONEY_REQUEST.STEP_ATTENDEES
| typeof SCREENS.MONEY_REQUEST.STEP_UPGRADE;

type Route<T extends MoneyRequestRouteName> = RouteProp<MoneyRequestNavigatorParamList, T>;

Expand Down
28 changes: 17 additions & 11 deletions src/pages/workspace/upgrade/UpgradeConfirmation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import ConfirmationPage from '@components/ConfirmationPage';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -9,26 +10,31 @@ import ROUTES from '@src/ROUTES';
type Props = {
policyName: string;
onConfirmUpgrade: () => void;
isCategorizing?: boolean;
};

function UpgradeConfirmation({policyName, onConfirmUpgrade}: Props) {
function UpgradeConfirmation({policyName, onConfirmUpgrade, isCategorizing}: Props) {
const {translate} = useLocalize();
const styles = useThemeStyles();

return (
<ConfirmationPage
heading={translate('workspace.upgrade.completed.headline')}
description={
<>
{translate('workspace.upgrade.completed.successMessage', {policyName})}{' '}
<TextLink
style={styles.link}
onPress={() => Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION)}
>
{translate('workspace.upgrade.completed.viewSubscription')}
</TextLink>{' '}
{translate('workspace.upgrade.completed.moreDetails')}
</>
isCategorizing ? (
<Text>{translate('workspace.upgrade.completed.categorizeMessage')}</Text>
) : (
<>
{translate('workspace.upgrade.completed.successMessage', {policyName})}{' '}
<TextLink
style={styles.link}
onPress={() => Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION)}
>
{translate('workspace.upgrade.completed.viewSubscription')}
</TextLink>{' '}
{translate('workspace.upgrade.completed.moreDetails')}
</>
)
}
shouldShowButton
onButtonPress={onConfirmUpgrade}
Expand Down
7 changes: 5 additions & 2 deletions src/pages/workspace/upgrade/UpgradeIntro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ type Props = {
loading?: boolean;
feature: ValueOf<typeof CONST.UPGRADE_FEATURE_INTRO_MAPPING>;
onUpgrade: () => void;
isCategorizing?: boolean;
};

function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading}: Props) {
function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading, isCategorizing}: Props) {
const styles = useThemeStyles();
const {isExtraSmallScreenWidth} = useResponsiveLayout();
const {translate} = useLocalize();
Expand Down Expand Up @@ -59,7 +60,9 @@ function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading}: Props) {
<Text style={[styles.textNormal, styles.textSupporting, styles.mb4]}>{translate(feature.description)}</Text>
<Text style={[styles.textNormal, styles.textSupporting]}>
{translate(`workspace.upgrade.${feature.id}.onlyAvailableOnPlan`)}
<Text style={[styles.textSupporting, styles.textBold]}>{translate(`workspace.upgrade.pricing.amount`)}</Text>
<Text style={[styles.textSupporting, styles.textBold]}>
{isCategorizing ? translate(`workspace.upgrade.pricing.collect`) : translate(`workspace.upgrade.pricing.amount`)}
</Text>
{translate(`workspace.upgrade.pricing.perActiveMember`)}
</Text>
</View>
Expand Down
Loading