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

feat(Bonus Pagamenti Digitali): [#175883778,#175883201,#175883970] Onboard Satispay account orchestration #2444

Merged
merged 43 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b5c4583
[#175883764] Merge remote-tracking branch 'origin/master' into 175883…
fabriziofff Nov 26, 2020
fc9783a
[#175883764] screen and navigation for satispay
fabriziofff Nov 26, 2020
645583f
[#175883764] add missing screens
fabriziofff Nov 26, 2020
73d274c
[#175883764] Merge remote-tracking branch 'origin/master' into 175883…
fabriziofff Nov 27, 2020
88e8b63
[#175883778] Merge branch '175883764-satispay-screens-and-navigation'…
fabriziofff Nov 27, 2020
a45062d
[#175883778] wip
fabriziofff Nov 27, 2020
bc32f5b
Merge branch 'master' into 175883764-satispay-screens-and-navigation
CrisTofani Nov 27, 2020
b73a179
Merge branch 'master' into 175883764-satispay-screens-and-navigation
CrisTofani Nov 27, 2020
0391f6e
[#175883764] Merge remote-tracking branch 'origin/master' into 175883…
fabriziofff Nov 27, 2020
42c8bb3
[#175883764] Merge remote-tracking branch 'origin/175883764-satispay-…
fabriziofff Nov 27, 2020
9a5b73d
[#175883778] Merge branch '175883764-satispay-screens-and-navigation'…
fabriziofff Nov 27, 2020
2613e34
[#175883778] satispay workflow
fabriziofff Nov 27, 2020
75cb668
[#175883778] store added satispay
fabriziofff Nov 28, 2020
6c7d781
[#175883778] fix return type of satispay add
fabriziofff Nov 28, 2020
2377a1f
Merge branch 'master' into 175883764-satispay-screens-and-navigation
fabriziofff Nov 29, 2020
195f30d
[#175883778] Merge remote-tracking branch 'origin/175883764-satispay-…
fabriziofff Nov 29, 2020
80fe8b9
Merge branch 'master' into 175883764-satispay-screens-and-navigation
fabriziofff Nov 29, 2020
1ef7672
[#175883778] Merge remote-tracking branch 'origin/175883764-satispay-…
fabriziofff Nov 29, 2020
39d6dd8
[#175883778] merge
fabriziofff Nov 29, 2020
c8261bc
[#175883778] add entrypoint
fabriziofff Nov 29, 2020
c494c0b
[#175883778] handling states
fabriziofff Nov 29, 2020
9805127
[#175883778] add satispay to wallet
fabriziofff Nov 29, 2020
3bcbc94
[#175883778] handle saga
fabriziofff Nov 29, 2020
e5a1710
[#175883778] fix titles for activateBpdOnNewMethods
fabriziofff Nov 29, 2020
29b3d50
Merge branch 'master' into 175883764-satispay-screens-and-navigation
Undermaken Nov 30, 2020
480ab4e
[#175883764] Merge branch 'master' of github.com:pagopa/io-app into 1…
Undermaken Nov 30, 2020
b0e7a48
[#175883778] Merge branch '175883764-satispay-screens-and-navigation'…
Undermaken Nov 30, 2020
9261dc3
Merge branch 'master' into 175883778-onboard-satispay-account
Undermaken Nov 30, 2020
ce3d240
Update locales/en/index.yml
fabriziofff Dec 1, 2020
01cd9af
Update locales/en/index.yml
fabriziofff Dec 1, 2020
8de14be
Update ts/features/bonus/bpd/saga/orchestration/activateBpdOnNewAdded…
fabriziofff Dec 1, 2020
ed49a5b
Update ts/features/bonus/bpd/saga/orchestration/activateBpdOnNewAdded…
fabriziofff Dec 1, 2020
6a819b0
Update ts/features/wallet/onboarding/satispay/store/reducers/foundSat…
fabriziofff Dec 1, 2020
765990a
Update ts/features/wallet/onboarding/satispay/screens/search/Satispay…
fabriziofff Dec 1, 2020
6393204
Update ts/features/wallet/onboarding/satispay/screens/search/Satispay…
fabriziofff Dec 1, 2020
271169c
[#175883778] isTimeoutError
fabriziofff Dec 1, 2020
39cf1de
[#175883778] Merge remote-tracking branch 'origin/175883778-onboard-s…
fabriziofff Dec 1, 2020
d11a591
Update ts/features/wallet/onboarding/satispay/store/reducers/addedSat…
fabriziofff Dec 1, 2020
ac009b3
[#175883778] Merge branch 'master' into 175883778-onboard-satispay-ac…
fabriziofff Dec 1, 2020
85c88bc
[#175883778] fix
fabriziofff Dec 1, 2020
0156e1d
[#175883778] fix eslint
fabriziofff Dec 1, 2020
e51b8b9
[#175883778] refactoring
Undermaken Dec 1, 2020
362fbb0
Merge branch 'master' into 175883778-onboard-satispay-account
Undermaken Dec 1, 2020
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
6 changes: 6 additions & 0 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,12 @@ wallet:
body1: "Turn on your methods saved into your wallet and start collecting cashback on your valid transactions."
body2: "If you prefer, you can activate cashback on these methods later as well."
skip: "Maybe later"
satispay:
headerTitle: "Add Satispay"
loadingSearch:
title: "We are verifying your Satispay account\n\nPlease wait a few seconds"
loadingAdd:
title: "We are adding your Satispay account\n\nPlease wait a few seconds"
alert:
msgErrorUpdateApp: "An error occurred while opening the app store"
titlePagoPaUpdateApp: Update required
Expand Down
6 changes: 6 additions & 0 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,12 @@ wallet:
body1: "Attiva il cashback sui metodi salvati nel tuo portafoglio per iniziare a collezionare le transazioni valide."
body2: "Se preferisci, puoi attivare il cashback su questi metodi anche in un secondo momento."
skip: "Non ora, grazie"
satispay:
headerTitle: "Aggiungi Satispay"
loadingSearch:
title: "Stiamo verificando il tuo account Satispay\n\nAttendi qualche secondo"
loadingAdd:
title: "Stiamo aggiungendo il tuo account Satispay\n\nAttendi qualche secondo"
alert:
msgErrorUpdateApp: "Si è verificato un errore durante l'apertura dello store delle app"
titlePagoPaUpdateApp: Aggiornamento richiesto
Expand Down
5 changes: 3 additions & 2 deletions ts/api/pagopa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
import { Omit } from "italia-ts-commons/lib/types";
import { BancomatCardsRequest } from "../../definitions/pagopa/walletv2/BancomatCardsRequest";
import {
addWalletSatispayUsingPOSTDefaultDecoder,
AddWalletSatispayUsingPOSTT,
addWalletsBancomatCardUsingPOSTDecoder,
getAbiListUsingGETDefaultDecoder,
Expand All @@ -37,6 +36,7 @@ import {
import {
addWalletCreditCardUsingPOSTDecoder,
AddWalletCreditCardUsingPOSTT,
addWalletSatispayUsingPOSTDecoder,
checkPaymentUsingGETDefaultDecoder,
CheckPaymentUsingGETT,
DeleteBySessionCookieExpiredUsingDELETET,
Expand Down Expand Up @@ -66,6 +66,7 @@ import {
NullableWallet,
PagoPAErrorResponse,
PatchedWalletV2ListResponse,
PatchedWalletV2Response,
PaymentManagerToken,
PspListResponse,
PspResponse,
Expand Down Expand Up @@ -457,7 +458,7 @@ const addSatispayToWallet: AddWalletSatispayUsingPOSTT = {
query: () => ({}),
body: ({ satispayRequest }) => JSON.stringify(satispayRequest),
headers: composeHeaderProducers(tokenHeaderProducer, ApiHeaderJson),
response_decoder: addWalletSatispayUsingPOSTDefaultDecoder()
response_decoder: addWalletSatispayUsingPOSTDecoder(PatchedWalletV2Response)
};

const withPaymentManagerToken = <P extends { Bearer: string }, R>(
Expand Down
8 changes: 4 additions & 4 deletions ts/features/bonus/bpd/analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
bpdPaymentMethodActivation,
bpdUpdatePaymentMethodActivation
} from "../store/actions/paymentMethods";
import { isTimeoutError } from "../../../../utils/errors";

// eslint-disable-next-line complexity
const trackAction = (mp: NonNullable<typeof mixpanel>) => (
Expand Down Expand Up @@ -152,10 +153,9 @@ const trackAction = (mp: NonNullable<typeof mixpanel>) => (

case getType(searchUserPans.failure):
return mp.track(action.type, {
reason:
action.payload.kind === "timeout"
? action.payload.kind
: action.payload.value.message
reason: isTimeoutError(action.payload)
? action.payload.kind
: action.payload.value.message
});

// Amount
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { NavigationNavigateAction } from "react-navigation";
import { call, put } from "redux-saga/effects";
import { navigateToWalletHome } from "../../../../../store/actions/navigation";
import {
EnableableFunctionsTypeEnum,
PaymentMethod
} from "../../../../../types/pagopa";
import { SagaCallReturnType } from "../../../../../types/utils";
import { hasFunctionEnabled } from "../../../../../utils/walletv2";
import { navigateToSuggestBpdActivation } from "../../../../wallet/onboarding/bancomat/navigation/action";
import { isBpdEnabled } from "./onboarding/startOnboarding";

/**
* Allows the user to activate bpd on a set of new added payment methods
*/
export function* activateBpdOnNewPaymentMethods(
paymentMethods: ReadonlyArray<PaymentMethod>,
navigateToActivateNewMethods: NavigationNavigateAction
) {
const atLeastOneBancomatWithBpdCapability = paymentMethods.some(b =>
hasFunctionEnabled(b, EnableableFunctionsTypeEnum.BPD)
);

// No payment method with bpd capability added in the current workflow, return to wallet home
if (!atLeastOneBancomatWithBpdCapability) {
return yield put(navigateToWalletHome());
}
const isBpdEnabledResponse: SagaCallReturnType<typeof isBpdEnabled> = yield call(
isBpdEnabled
);

// Error while reading the bpdEnabled, return to wallet
if (isBpdEnabledResponse.isLeft()) {
yield put(navigateToWalletHome());
} else {
if (isBpdEnabledResponse.value) {
// navigate to onboarding new bancomat
yield put(navigateToActivateNewMethods);
} else {
// navigate to "ask if u want to start bpd onboarding"
yield put(navigateToSuggestBpdActivation());
}
}
}
22 changes: 18 additions & 4 deletions ts/features/wallet/onboarding/DigitalMethodsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ import {
ListRenderItemInfo,
StyleSheet
} from "react-native";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import I18n from "../../../i18n";
import { H3 } from "../../../components/core/typography/H3";
import { H5 } from "../../../components/core/typography/H5";
import { GlobalState } from "../../../store/reducers/types";
import { walletAddSatispayStart } from "./satispay/store/actions";

type Props = ReturnType<typeof mapDispatchToProps> &
ReturnType<typeof mapStateToProps>;

type DigitalPaymentItem = {
name: string;
Expand All @@ -29,7 +36,7 @@ const styles = StyleSheet.create({
logo: { width: 80, height: 40, resizeMode: "cover" }
});

const getMethods = (): ReadonlyArray<DigitalPaymentItem> => [
const getMethods = (props: Props): ReadonlyArray<DigitalPaymentItem> => [
{
name: I18n.t("wallet.methods.bancomatPay.name"),
subtitle: I18n.t("wallet.methods.bancomatPay.description"),
Expand All @@ -40,6 +47,7 @@ const getMethods = (): ReadonlyArray<DigitalPaymentItem> => [
name: I18n.t("wallet.methods.satispay.name"),
subtitle: I18n.t("wallet.methods.satispay.description"),
logo: require("../../../../img/wallet/cards-icons/satispay.png"),
onPress: props.startSatispayOnboarding,
implemented: true
},
{
Expand All @@ -53,10 +61,10 @@ const getMethods = (): ReadonlyArray<DigitalPaymentItem> => [
}
];

const DigitalMethodsList: React.FunctionComponent = () => (
const DigitalMethodsList = (props: Props) => (
<FlatList
scrollEnabled={false}
data={getMethods()}
data={getMethods(props)}
renderItem={({ item }: ListRenderItemInfo<DigitalPaymentItem>) =>
item.implemented && (
<ListItem style={styles.listItem} onPress={item.onPress}>
Expand All @@ -72,4 +80,10 @@ const DigitalMethodsList: React.FunctionComponent = () => (
/>
);

export default DigitalMethodsList;
const mapDispatchToProps = (dispatch: Dispatch) => ({
startSatispayOnboarding: () => dispatch(walletAddSatispayStart())
});

const mapStateToProps = (_: GlobalState) => ({});

export default connect(mapStateToProps, mapDispatchToProps)(DigitalMethodsList);
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {
withResetNavigationStack
} from "../../../../../../sagas/workUnit";
import { navigateToWalletHome } from "../../../../../../store/actions/navigation";
import { fetchWalletsRequest } from "../../../../../../store/actions/wallet/wallets";
import { navigationCurrentRouteSelector } from "../../../../../../store/reducers/navigation";
import { SagaCallReturnType } from "../../../../../../types/utils";
import { isBpdEnabled } from "../../../../../bonus/bpd/saga/orchestration/onboarding/startOnboarding";
import { activateBpdOnNewPaymentMethods } from "../../../../../bonus/bpd/saga/orchestration/activateBpdOnNewAddedPaymentMethods";
import {
navigateToActivateBpdOnNewBancomat,
navigateToOnboardingBancomatChooseBank,
navigateToSuggestBpdActivation
navigateToOnboardingBancomatChooseBank
} from "../../navigation/action";
import WALLET_ONBOARDING_BANCOMAT_ROUTES from "../../navigation/routes";
import {
Expand All @@ -20,9 +20,6 @@ import {
walletAddBancomatCompleted
} from "../../store/actions";
import { onboardingBancomatAddedPansSelector } from "../../store/reducers/addedPans";
import { hasFunctionEnabled } from "../../../../../../utils/walletv2";
import { EnableableFunctionsTypeEnum } from "../../../../../../types/pagopa";
import { fetchWalletsRequest } from "../../../../../../store/actions/wallet/wallets";

/**
* Define the workflow that allows the user to add a bancomat to the wallet.
Expand Down Expand Up @@ -82,41 +79,15 @@ export function* addBancomatToWalletAndActivateBpd() {
if (res === "completed") {
// refresh wallets list
yield put(fetchWalletsRequest());
yield call(activateBpdOnNewBancomat);
}
}

/**
* Allows the user to activate bpd on the new added bancomat
*/
function* activateBpdOnNewBancomat() {
// read the new added bancomat
const bancomatAdded: ReturnType<typeof onboardingBancomatAddedPansSelector> = yield select(
onboardingBancomatAddedPansSelector
);
// TODO: change enableableFunction with types representing the possibles functionalities
const atLeastOneBancomatWithBpdCapability = bancomatAdded.some(b =>
hasFunctionEnabled(b, EnableableFunctionsTypeEnum.BPD)
);

// No bancomat with bpd capability added in the current workflow, return to wallet home
if (!atLeastOneBancomatWithBpdCapability) {
return yield put(navigateToWalletHome());
}
const isBpdEnabledResponse: SagaCallReturnType<typeof isBpdEnabled> = yield call(
isBpdEnabled
);
// read the new added bancomat
const bancomatAdded: ReturnType<typeof onboardingBancomatAddedPansSelector> = yield select(
onboardingBancomatAddedPansSelector
);

// Error while reading the bpdEnabled, return to wallet
if (isBpdEnabledResponse.isLeft()) {
yield put(navigateToWalletHome());
} else {
if (isBpdEnabledResponse.value) {
// navigate to onboarding new bancomat
yield put(navigateToActivateBpdOnNewBancomat());
} else {
// navigate to "ask if u want to start bpd onboarding"
yield put(navigateToSuggestBpdActivation());
}
yield call(
activateBpdOnNewPaymentMethods,
bancomatAdded,
navigateToActivateBpdOnNewBancomat()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import * as React from "react";
import { connect } from "react-redux";
import I18n from "../../../../../i18n";
import { onboardingBancomatAddedPansSelector } from "../store/reducers/addedPans";
import { GlobalState } from "../../../../../store/reducers/types";
import ActivateBpdOnNewPaymentMethodScreen from "../../common/screens/bpd/ActivateBpdOnNewPaymentMethodScreen";

type Props = ReturnType<typeof mapStateToProps>;

const ActivateBpdOnNewBancomatScreen = (props: Props) => (
<ActivateBpdOnNewPaymentMethodScreen paymentMethods={props.newBancomat} />
<ActivateBpdOnNewPaymentMethodScreen
paymentMethods={props.newBancomat}
title={I18n.t("wallet.onboarding.bancomat.headerTitle")}
/>
);

const mapStateToProps = (state: GlobalState) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { onboardingBancomatAbiSelectedSelector } from "../../store/reducers/abiSelected";
import { onboardingBancomatFoundPansSelector } from "../../store/reducers/pans";
import AddBancomatScreen from "../add-pans/AddBancomatScreen";
import { isTimeoutError } from "../../../../../../utils/errors";
import BancomatKoNotFound from "./BancomatKoNotFound";
import BancomatKoSingleBankNotFound from "./BancomatKoSingleBankNotFound";
import BancomatKoTimeout from "./BancomatKoTimeout";
Expand Down Expand Up @@ -56,7 +57,7 @@ const SearchAvailableUserBancomatScreen: React.FunctionComponent<Props> = props
// and he should try to search for a single bank
return <BancomatKoServicesError />;
}
if (isError(pans) && pans.error.kind === "timeout") {
if (isError(pans) && isTimeoutError(pans.error)) {
return <BancomatKoTimeout />;
}
if (isLoading(pans) || isError(pans)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from "react";
import { NavigationScreenProps } from "react-navigation";
import I18n from "../../../../../../i18n";
import { PaymentMethod } from "../../../../../../types/pagopa";
import ActivateBpdOnNewPaymentMethodScreen from "./ActivateBpdOnNewPaymentMethodScreen";

Expand All @@ -15,5 +16,6 @@ export const ActivateBpdOnNewCreditCardScreen: React.FC<Props> = (
) => (
<ActivateBpdOnNewPaymentMethodScreen
paymentMethods={props.navigation.getParam("creditCards")}
title={I18n.t("bonus.bpd.title")}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import { PaymentMethodRawList } from "../../../../../bonus/bpd/components/paymen

type OwnProps = {
paymentMethods: ReadonlyArray<PaymentMethod>;
title: string;
};

export type Props = ReturnType<typeof mapDispatchToProps> & OwnProps;

const loadLocales = () => ({
headerTitle: I18n.t("wallet.onboarding.bancomat.headerTitle"),
title: I18n.t("wallet.onboarding.bancomat.bpd.activateNew.title"),
body1: I18n.t("wallet.onboarding.bancomat.bpd.activateNew.body1"),
body2: I18n.t("wallet.onboarding.bancomat.bpd.activateNew.body2"),
Expand All @@ -29,9 +29,9 @@ const loadLocales = () => ({
});

const ActivateBpdOnNewPaymentMethodScreen: React.FunctionComponent<Props> = props => {
const { headerTitle, title, body1, body2, skip, continueStr } = loadLocales();
const { title, body1, body2, skip, continueStr } = loadLocales();
return (
<BaseScreenComponent headerTitle={headerTitle}>
<BaseScreenComponent headerTitle={props.title}>
<SafeAreaView style={IOStyles.flex}>
<ScrollView>
<View style={IOStyles.horizontalContentPadding}>
Expand Down
Loading