From 980ec19caafc05cfdd10b5f6fd412fbed46ea69d Mon Sep 17 00:00:00 2001 From: Jorge Osorio <43450882+jorelosorio@users.noreply.github.com> Date: Fri, 23 Jun 2023 16:09:37 +0200 Subject: [PATCH] feat: Disable toggling to t card when using boat tickets (#3655) --- src/reference-data/utils.ts | 4 + .../SelectTravelTokenScreenComponent.tsx | 89 ++++++++++++++++--- .../Root_FareContractDetailsScreen.tsx | 9 +- .../screens/subscreens/TravelToken.ts | 8 ++ 4 files changed, 94 insertions(+), 16 deletions(-) diff --git a/src/reference-data/utils.ts b/src/reference-data/utils.ts index 90e114d059..7a62238c4b 100644 --- a/src/reference-data/utils.ts +++ b/src/reference-data/utils.ts @@ -34,6 +34,10 @@ export const findReferenceDataById = < id: string, ) => elements.find((p) => p.id === id); +export function isOfFareProductRef(a: any): a is {fareProductRef: string} { + return 'fareProductRef' in a; +} + export const productIsSellableInApp = (product: PreassignedFareProduct) => { if ( (product.limitations.appVersionMin && diff --git a/src/select-travel-token-screen/SelectTravelTokenScreenComponent.tsx b/src/select-travel-token-screen/SelectTravelTokenScreenComponent.tsx index 89ebe3b7cd..5eed9f988b 100644 --- a/src/select-travel-token-screen/SelectTravelTokenScreenComponent.tsx +++ b/src/select-travel-token-screen/SelectTravelTokenScreenComponent.tsx @@ -18,7 +18,11 @@ import { isCarnetTravelRight, useTicketingState, } from '@atb/ticketing'; -import {TravelTokenTexts, useTranslation} from '@atb/translations'; +import { + TravelTokenTexts, + getTextForLanguage, + useTranslation, +} from '@atb/translations'; import {animateNextChange} from '@atb/utils/animation'; import {flatMap} from '@atb/utils/array'; import React, {useCallback, useState} from 'react'; @@ -26,15 +30,23 @@ import {ActivityIndicator, View} from 'react-native'; import {ScrollView} from 'react-native-gesture-handler'; import {RadioGroupSection, Section} from '@atb/components/sections'; import {useRemoteConfig} from '@atb/RemoteConfigContext'; +import {useFirestoreConfiguration} from '@atb/configuration'; +import {onlyUniquesBasedOnField} from '@atb/utils/only-uniques'; +import { + findReferenceDataById, + isOfFareProductRef, +} from '@atb/reference-data/utils'; type Props = {onAfterSave: () => void}; export const SelectTravelTokenScreenComponent = ({onAfterSave}: Props) => { const styles = useStyles(); - const {t} = useTranslation(); + const {t, language} = useTranslation(); const {fareContracts} = useTicketingState(); const {disable_travelcard} = useRemoteConfig(); + const {fareProductTypeConfigs, preassignedFareProducts} = + useFirestoreConfiguration(); const {token, remoteTokens, toggleToken} = useMobileTokenContextState(); const inspectableToken = findInspectable(remoteTokens); @@ -47,10 +59,36 @@ export const SelectTravelTokenScreenComponent = ({onAfterSave}: Props) => { inspectableToken, ); - const hasActiveCarnetFareContract = flatMap( + const activeFareContracts = flatMap( filterActiveOrCanBeUsedFareContracts(fareContracts), (i) => i.travelRights, - ).some(isCarnetTravelRight); + ); + + const hasActiveCarnetFareContract = + activeFareContracts.some(isCarnetTravelRight); + + // Filter for unique travel rights config types + const activeFareContractsTypes = activeFareContracts + .filter(onlyUniquesBasedOnField('type')) + .map((travelRight) => { + const preassignedFareProduct = findReferenceDataById( + preassignedFareProducts, + isOfFareProductRef(travelRight) ? travelRight.fareProductRef : '', + ); + + return ( + preassignedFareProduct && + fareProductTypeConfigs.find( + (c) => c.type === preassignedFareProduct.type, + ) + ); + }); + + const fareProductConfigWhichRequiresTokenOnMobile = + activeFareContractsTypes.find( + (fareProductTypeConfig) => + fareProductTypeConfig?.configuration.requiresTokenOnMobile === true, + ); const [saveState, setSaveState] = useState({ saving: false, @@ -76,6 +114,14 @@ export const SelectTravelTokenScreenComponent = ({onAfterSave}: Props) => { const travelCardToken = remoteTokens?.find(isTravelCardToken); const mobileTokens = remoteTokens?.filter(isMobileToken); + // Shows an error message if switching to a t:card, + // but the current inspectable token is in the mobile AND + // requires mobile token + const requiresTokenOnMobile = + selectedType === 'travelCard' && + isMobileToken(inspectableToken) && + !!fareProductConfigWhichRequiresTokenOnMobile; + return ( { isMarkdown={false} /> )} + + {requiresTokenOnMobile && ( + + )} {selectedType === 'mobile' && mobileTokens?.length ? (
@@ -202,13 +267,15 @@ export const SelectTravelTokenScreenComponent = ({onAfterSave}: Props) => { {saveState.saving ? ( ) : ( -