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

fix: use SetPersonalDetailsAndShipExpensifyCards for Get Physical Card flow #56076

Closed
wants to merge 4 commits into from
Closed
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
2 changes: 1 addition & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const ROUTES = {
},
SETTINGS_WALLET_CARD_GET_PHYSICAL_NAME: {
route: 'settings/wallet/card/:domain/get-physical/name',
getRoute: (domain: string) => `settings/wallet/card/${domain}/get-physical/name` as const,
getRoute: (domain: string, backTo?: string) => getUrlWithBackToParam(`settings/wallet/card/${domain}/get-physical/name`, backTo),
},
SETTINGS_WALLET_CARD_GET_PHYSICAL_PHONE: {
route: 'settings/wallet/card/:domain/get-physical/phone',
Expand Down
1 change: 0 additions & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ const SCREENS = {
DOMAIN_CARD: 'DomainCard',
RESTRICTED_ACTION: 'RestrictedAction',
REPORT_EXPORT: 'Report_Export',
MISSING_PERSONAL_DETAILS: 'MissingPersonalDetails',
DEBUG: 'Debug',
},
ONBOARDING_MODAL: {
Expand Down
30 changes: 18 additions & 12 deletions src/components/ReportActionItem/IssueCardMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react';
import React, {useCallback} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import RenderHTML from '@components/RenderHTML';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {getUpdatedPrivatePersonalDetails, goToNextPhysicalCardRoute} from '@libs/GetPhysicalCardUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import {getPolicy, getWorkspaceAccountID, isPolicyAdmin as isPolicyAdminPolicyUtils} from '@libs/PolicyUtils';
import {getCardIssuedMessage, getOriginalMessage, isActionOfType} from '@libs/ReportActionsUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {ReportAction} from '@src/types/onyx';
import type {IssueNewCardOriginalMessage} from '@src/types/onyx/OriginalMessage';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
Expand All @@ -25,11 +25,12 @@ function IssueCardMessage({action, policyID}: IssueCardMessageProps) {
const styles = useThemeStyles();
const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS);
const [session] = useOnyx(ONYXKEYS.SESSION);
const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID ?? '-1');
const workspaceAccountID = getWorkspaceAccountID(policyID);
const [cardList = {}] = useOnyx(ONYXKEYS.CARD_LIST);
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`);
const [draftValues] = useOnyx(ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM_DRAFT);

const assigneeAccountID = (ReportActionsUtils.getOriginalMessage(action) as IssueNewCardOriginalMessage)?.assigneeAccountID;
const assigneeAccountID = (getOriginalMessage(action) as IssueNewCardOriginalMessage)?.assigneeAccountID;

const missingDetails =
!privatePersonalDetails?.legalFirstName ||
Expand All @@ -41,25 +42,30 @@ function IssueCardMessage({action, policyID}: IssueCardMessageProps) {

const isAssigneeCurrentUser = !isEmptyObject(session) && session.accountID === assigneeAccountID;

const cardIssuedActionOriginalMessage = ReportActionsUtils.isActionOfType(
const cardIssuedActionOriginalMessage = isActionOfType(
action,
CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED,
CONST.REPORT.ACTIONS.TYPE.CARD_ISSUED_VIRTUAL,
CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS,
)
? ReportActionsUtils.getOriginalMessage(action)
? getOriginalMessage(action)
: undefined;
const cardID = cardIssuedActionOriginalMessage?.cardID ?? -1;
const isPolicyAdmin = PolicyUtils.isPolicyAdmin(PolicyUtils.getPolicy(policyID));
const cardID = cardIssuedActionOriginalMessage?.cardID ?? CONST.DEFAULT_NUMBER_ID;
const isPolicyAdmin = isPolicyAdminPolicyUtils(getPolicy(policyID));
const card = isPolicyAdmin ? cardsList?.[cardID] : cardList[cardID];
const shouldShowAddMissingDetailsButton = !isEmptyObject(card) && action?.actionName === CONST.REPORT.ACTIONS.TYPE.CARD_MISSING_ADDRESS && missingDetails && isAssigneeCurrentUser;

const domain = cardList?.[cardID]?.domainName ?? '';
const goToNextRoute = useCallback(() => {
goToNextPhysicalCardRoute(domain, getUpdatedPrivatePersonalDetails(draftValues, privatePersonalDetails), Navigation.getActiveRoute());
}, [domain, draftValues, privatePersonalDetails]);

return (
<>
<RenderHTML html={`<muted-text>${ReportActionsUtils.getCardIssuedMessage(action, true, policyID, !!card)}</muted-text>`} />
<RenderHTML html={`<muted-text>${getCardIssuedMessage(action, true, policyID, !!card)}</muted-text>`} />
{shouldShowAddMissingDetailsButton && (
<Button
onPress={() => Navigation.navigate(ROUTES.MISSING_PERSONAL_DETAILS)}
onPress={goToNextRoute}
success
style={[styles.alignSelfStart, styles.mt3]}
text={translate('workspace.expensifyCard.addShippingDetails')}
Expand Down
47 changes: 33 additions & 14 deletions src/libs/GetPhysicalCardUtils.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import type {OnyxEntry} from 'react-native-onyx';
import ROUTES from '@src/ROUTES';
import type {Route} from '@src/ROUTES';
import type {GetPhysicalCardForm} from '@src/types/form';
import type {GetPhysicalCardForm, PersonalDetailsForm} from '@src/types/form';
import INPUT_IDS from '@src/types/form/PersonalDetailsForm';
import type {LoginList, PrivatePersonalDetails} from '@src/types/onyx';
import * as LoginUtils from './LoginUtils';
import {validateNumber} from './LoginUtils';
import Navigation from './Navigation/Navigation';
import * as PersonalDetailsUtils from './PersonalDetailsUtils';
import * as UserUtils from './UserUtils';
import {getCurrentAddress, getFormattedStreet} from './PersonalDetailsUtils';
import {getSecondaryPhoneLogin} from './UserUtils';

function getCurrentRoute(domain: string, privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>): Route {
function getCurrentRoute(domain: string, privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>, backTo?: string): Route {
const {legalFirstName, legalLastName, phoneNumber} = privatePersonalDetails ?? {};
const address = PersonalDetailsUtils.getCurrentAddress(privatePersonalDetails);
const address = getCurrentAddress(privatePersonalDetails);

if (!legalFirstName && !legalLastName) {
return ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_NAME.getRoute(domain);
return ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_NAME.getRoute(domain, backTo);
}
if (!phoneNumber || !LoginUtils.validateNumber(phoneNumber)) {
if (!phoneNumber || !validateNumber(phoneNumber)) {
return ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_PHONE.getRoute(domain);
}
if (!(address?.street && address?.city && address?.state && address?.country && address?.zip)) {
Expand All @@ -25,8 +26,8 @@ function getCurrentRoute(domain: string, privatePersonalDetails: OnyxEntry<Priva
return ROUTES.SETTINGS_WALLET_CARD_GET_PHYSICAL_CONFIRM.getRoute(domain);
}

function goToNextPhysicalCardRoute(domain: string, privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>) {
Navigation.navigate(getCurrentRoute(domain, privatePersonalDetails));
function goToNextPhysicalCardRoute(domain: string, privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>, backTo?: string) {
Navigation.navigate(getCurrentRoute(domain, privatePersonalDetails, backTo));
}

/**
Expand Down Expand Up @@ -57,7 +58,7 @@ function setCurrentRoute(currentRoute: string, domain: string, privatePersonalDe
*/
function getUpdatedDraftValues(draftValues: OnyxEntry<GetPhysicalCardForm>, privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>, loginList: OnyxEntry<LoginList>): GetPhysicalCardForm {
const {legalFirstName, legalLastName, phoneNumber} = privatePersonalDetails ?? {};
const address = PersonalDetailsUtils.getCurrentAddress(privatePersonalDetails);
const address = getCurrentAddress(privatePersonalDetails);

return {
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
Expand All @@ -68,7 +69,7 @@ function getUpdatedDraftValues(draftValues: OnyxEntry<GetPhysicalCardForm>, priv
addressLine2: draftValues?.addressLine2 || address?.street.split('\n')[1] || '',
city: draftValues?.city || address?.city || '',
country: draftValues?.country || address?.country || '',
phoneNumber: draftValues?.phoneNumber || phoneNumber || UserUtils.getSecondaryPhoneLogin(loginList) || '',
phoneNumber: draftValues?.phoneNumber || phoneNumber || getSecondaryPhoneLogin(loginList) || '',
state: draftValues?.state || address?.state || '',
zipPostCode: draftValues?.zipPostCode || address?.zip || '',
/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */
Expand All @@ -86,9 +87,27 @@ function getUpdatedPrivatePersonalDetails(draftValues: OnyxEntry<GetPhysicalCard
legalFirstName,
legalLastName,
phoneNumber,
addresses: [...(privatePersonalDetails?.addresses ?? []), {street: PersonalDetailsUtils.getFormattedStreet(addressLine1, addressLine2), city, country, state, zip: zipPostCode}],
addresses: [...(privatePersonalDetails?.addresses ?? []), {street: getFormattedStreet(addressLine1, addressLine2), city, country, state, zip: zipPostCode}],
};
}

export {getUpdatedDraftValues, getUpdatedPrivatePersonalDetails, goToNextPhysicalCardRoute, setCurrentRoute};
function getSubstepValues(privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>, personalDetailsDraft: OnyxEntry<PersonalDetailsForm>): PersonalDetailsForm {
const address = getCurrentAddress(privatePersonalDetails);
const {street} = address ?? {};
const [street1, street2] = street ? street.split('\n') : [undefined, undefined];
return {
[INPUT_IDS.LEGAL_FIRST_NAME]: personalDetailsDraft?.[INPUT_IDS.LEGAL_FIRST_NAME] ?? privatePersonalDetails?.legalFirstName ?? '',
[INPUT_IDS.LEGAL_LAST_NAME]: personalDetailsDraft?.[INPUT_IDS.LEGAL_LAST_NAME] ?? privatePersonalDetails?.legalLastName ?? '',
[INPUT_IDS.DATE_OF_BIRTH]: personalDetailsDraft?.[INPUT_IDS.DATE_OF_BIRTH] ?? privatePersonalDetails?.dob ?? '',
[INPUT_IDS.PHONE_NUMBER]: personalDetailsDraft?.[INPUT_IDS.PHONE_NUMBER] ?? privatePersonalDetails?.phoneNumber ?? '',
[INPUT_IDS.ADDRESS_LINE_1]: personalDetailsDraft?.[INPUT_IDS.ADDRESS_LINE_1] ?? street1 ?? '',
[INPUT_IDS.ADDRESS_LINE_2]: personalDetailsDraft?.[INPUT_IDS.ADDRESS_LINE_2] ?? street2 ?? '',
[INPUT_IDS.CITY]: personalDetailsDraft?.[INPUT_IDS.CITY] ?? address?.city ?? '',
[INPUT_IDS.STATE]: personalDetailsDraft?.[INPUT_IDS.STATE] ?? address?.state ?? '',
[INPUT_IDS.ZIP_POST_CODE]: personalDetailsDraft?.[INPUT_IDS.ZIP_POST_CODE] ?? address?.zip ?? '',
[INPUT_IDS.COUNTRY]: personalDetailsDraft?.[INPUT_IDS.COUNTRY] ?? address?.country ?? '',
};
}

export {getUpdatedDraftValues, getUpdatedPrivatePersonalDetails, goToNextPhysicalCardRoute, setCurrentRoute, getSubstepValues};
export type {PrivatePersonalDetails};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
EditRequestNavigatorParamList,
EnablePaymentsNavigatorParamList,
FlagCommentNavigatorParamList,
MissingPersonalDetailsParamList,
MoneyRequestNavigatorParamList,
NewChatNavigatorParamList,
NewTaskNavigatorParamList,
Expand Down Expand Up @@ -689,10 +688,6 @@ const RestrictedActionModalStackNavigator = createModalStackNavigator<SearchRepo
[SCREENS.RESTRICTED_ACTION_ROOT]: () => require<ReactComponentModule>('../../../../pages/RestrictedAction/Workspace/WorkspaceRestrictedActionPage').default,
});

const MissingPersonalDetailsModalStackNavigator = createModalStackNavigator<MissingPersonalDetailsParamList>({
[SCREENS.MISSING_PERSONAL_DETAILS_ROOT]: () => require<ReactComponentModule>('../../../../pages/MissingPersonalDetails').default,
});

const DebugModalStackNavigator = createModalStackNavigator<DebugParamList>({
[SCREENS.DEBUG.REPORT]: () => require<ReactComponentModule>('../../../../pages/Debug/Report/DebugReportPage').default,
[SCREENS.DEBUG.REPORT_ACTION]: () => require<ReactComponentModule>('../../../../pages/Debug/ReportAction/DebugReportActionPage').default,
Expand Down Expand Up @@ -738,7 +733,6 @@ export {
RestrictedActionModalStackNavigator,
SearchAdvancedFiltersModalStackNavigator,
SearchSavedSearchModalStackNavigator,
MissingPersonalDetailsModalStackNavigator,
DebugModalStackNavigator,
WorkspaceConfirmationModalStackNavigator,
};
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,6 @@ function RightModalNavigator({navigation, route}: RightModalNavigatorProps) {
name={SCREENS.RIGHT_MODAL.SEARCH_SAVED_SEARCH}
component={ModalStackNavigators.SearchSavedSearchModalStackNavigator}
/>
<Stack.Screen
name={SCREENS.RIGHT_MODAL.MISSING_PERSONAL_DETAILS}
component={ModalStackNavigators.MissingPersonalDetailsModalStackNavigator}
/>
</Stack.Navigator>
</View>
</NoDropZone>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial<Record<CentralPaneName, string[]>> =
[SCREENS.SETTINGS.PREFERENCES.ROOT]: [SCREENS.SETTINGS.PREFERENCES.PRIORITY_MODE, SCREENS.SETTINGS.PREFERENCES.LANGUAGE, SCREENS.SETTINGS.PREFERENCES.THEME],
[SCREENS.SETTINGS.WALLET.ROOT]: [
SCREENS.SETTINGS.WALLET.DOMAIN_CARD,
SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.NAME,
SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.PHONE,
SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.ADDRESS,
SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.CONFIRM,
SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE,
SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT,
SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS,
Expand Down
7 changes: 1 addition & 6 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.NAME]: {
/** domain of selected card */
domain: string;
backTo?: Routes;
};
[SCREENS.SETTINGS.WALLET.CARD_GET_PHYSICAL.PHONE]: {
/** domain of selected card */
Expand Down Expand Up @@ -1487,7 +1488,6 @@ type RightModalNavigatorParamList = {
[SCREENS.RIGHT_MODAL.RESTRICTED_ACTION]: NavigatorScreenParams<RestrictedActionParamList>;
[SCREENS.RIGHT_MODAL.SEARCH_ADVANCED_FILTERS]: NavigatorScreenParams<SearchAdvancedFiltersParamList>;
[SCREENS.RIGHT_MODAL.SEARCH_SAVED_SEARCH]: NavigatorScreenParams<SearchSavedSearchParamList>;
[SCREENS.RIGHT_MODAL.MISSING_PERSONAL_DETAILS]: NavigatorScreenParams<MissingPersonalDetailsParamList>;
[SCREENS.RIGHT_MODAL.DEBUG]: NavigatorScreenParams<DebugParamList>;
};

Expand Down Expand Up @@ -1769,10 +1769,6 @@ type RestrictedActionParamList = {
};
};

type MissingPersonalDetailsParamList = {
[SCREENS.MISSING_PERSONAL_DETAILS_ROOT]: undefined;
};

type DebugParamList = {
[SCREENS.DEBUG.REPORT]: {
reportID: string;
Expand Down Expand Up @@ -1880,7 +1876,6 @@ export type {
SearchAdvancedFiltersParamList,
SearchSavedSearchParamList,
RestrictedActionParamList,
MissingPersonalDetailsParamList,
DebugParamList,
MigratedUserModalNavigatorParamList,
WorkspaceConfirmationNavigatorParamList,
Expand Down
Loading
Loading