From 1f8f42c7db5fef05e0db3bbfb231a2c6b38723cd Mon Sep 17 00:00:00 2001 From: Dawid Tarasiuk Date: Wed, 9 Sep 2020 13:33:04 +0200 Subject: [PATCH] Require payment recreate when payment price is wrong --- package-lock.json | 5 +- package.json | 2 +- src/@next/hooks/useCheckoutStepState.ts | 64 ++++++++++++++----- src/@next/pages/CheckoutPage/CheckoutPage.tsx | 1 + .../pages/CheckoutPage/CheckoutRouter.tsx | 15 +++-- 5 files changed, 64 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 16834d4cbe..78827a4222 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5604,9 +5604,8 @@ } }, "@saleor/sdk": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@saleor/sdk/-/sdk-0.1.0.tgz", - "integrity": "sha512-ZLVqPx1K9me7fslcxrGnGJ4Gq3ydmA+Yk/kK75bdNs+J8xZwZAxLhOl3lS1C/KGu7InNQvn7zQbTULwu7Oqn/Q==", + "version": "github:mirumee/saleor-sdk#5b9f96be7948c3613b3a3b31303f55baf2385c92", + "from": "github:mirumee/saleor-sdk#5b9f96b", "requires": { "apollo-cache": "^1.3.5", "apollo-cache-inmemory": "^1.6.6", diff --git a/package.json b/package.json index d3619b9dd2..a8bcba783f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dependencies": { "@babel/runtime": "^7.5.5", "@lhci/cli": "^0.4.1", - "@saleor/sdk": "^0.1.0", + "@saleor/sdk": "github:mirumee/saleor-sdk#5b9f96b", "@sentry/apm": "^5.15.5", "@sentry/browser": "^5.15.5", "@stripe/react-stripe-js": "^1.1.2", diff --git a/src/@next/hooks/useCheckoutStepState.ts b/src/@next/hooks/useCheckoutStepState.ts index 3379757c7f..14e7ca54ae 100644 --- a/src/@next/hooks/useCheckoutStepState.ts +++ b/src/@next/hooks/useCheckoutStepState.ts @@ -1,32 +1,47 @@ import { useEffect, useState } from "react"; -import { IItems } from "@saleor/sdk/lib/api/Cart/types"; +import { IItems, ITotalPrice } from "@saleor/sdk/lib/api/Cart/types"; import { ICheckout, IPayment } from "@saleor/sdk/lib/api/Checkout/types"; import { CheckoutStep } from "@temp/core/config"; +interface StepState { + recommendedStep: CheckoutStep; + maxPossibleStep: CheckoutStep; +} + export const useCheckoutStepState = ( items?: IItems, checkout?: ICheckout, - payment?: IPayment -): CheckoutStep => { - const isShippingRequiredForProducts = - items && - items.some( - ({ variant }) => variant.product?.productType.isShippingRequired + payment?: IPayment, + totalPrice?: ITotalPrice +): StepState => { + const checkIfCheckoutPriceEqualPaymentPrice = () => { + return ( + totalPrice?.gross.amount === payment?.total?.amount && + totalPrice?.gross.currency === payment?.total?.currency ); + }; - const getStep = () => { + const getMaxPossibleStep = () => { if (!checkout?.id && items) { // we are creating checkout during address set up return CheckoutStep.Address; } + const isCheckoutPriceEqualPaymentPrice = checkIfCheckoutPriceEqualPaymentPrice(); + const isShippingRequiredForProducts = + items && + items.some( + ({ variant }) => variant.product?.productType.isShippingRequired + ); + const isShippingAddressSet = !isShippingRequiredForProducts || !!checkout?.shippingAddress; const isBillingAddressSet = !!checkout?.billingAddress; const isShippingMethodSet = !isShippingRequiredForProducts || !!checkout?.shippingMethod; - const isPaymentMethodSet = !!payment?.id; + const isPaymentMethodSet = + !!payment?.id && isCheckoutPriceEqualPaymentPrice; if (!isShippingAddressSet || !isBillingAddressSet) { return CheckoutStep.Address; @@ -40,14 +55,33 @@ export const useCheckoutStepState = ( return CheckoutStep.Review; }; - const [step, setStep] = useState(getStep()); + const getRecommendedStep = (newMaxPossibleStep: CheckoutStep) => { + const isCheckoutPriceEqualPaymentPrice = checkIfCheckoutPriceEqualPaymentPrice(); + + if ( + newMaxPossibleStep > CheckoutStep.Shipping && + !isCheckoutPriceEqualPaymentPrice + ) { + return CheckoutStep.Shipping; + } + return newMaxPossibleStep; + }; + + const [maxPossibleStep, setMaxPossibleStep] = useState(getMaxPossibleStep()); + const [recommendedStep, setRecommendedStep] = useState( + getRecommendedStep(maxPossibleStep) + ); useEffect(() => { - const newStep = getStep(); - if (step !== newStep) { - setStep(newStep); + const newMaxPossibleStep = getMaxPossibleStep(); + const newRecommendedStep = getRecommendedStep(newMaxPossibleStep); + if (maxPossibleStep !== newMaxPossibleStep) { + setMaxPossibleStep(newMaxPossibleStep); + } + if (recommendedStep !== newRecommendedStep) { + setRecommendedStep(newRecommendedStep); } - }, [checkout, items, payment]); + }, [checkout, items, payment, totalPrice]); - return step; + return { recommendedStep, maxPossibleStep }; }; diff --git a/src/@next/pages/CheckoutPage/CheckoutPage.tsx b/src/@next/pages/CheckoutPage/CheckoutPage.tsx index 69ff49fe40..e7af786079 100755 --- a/src/@next/pages/CheckoutPage/CheckoutPage.tsx +++ b/src/@next/pages/CheckoutPage/CheckoutPage.tsx @@ -241,6 +241,7 @@ const CheckoutPage: React.FC = ({}: IProps) => { items={items} checkout={checkout} payment={payment} + totalPrice={totalPrice} renderAddress={props => ( ) => React.ReactNode; renderShipping: (props: RouteComponentProps) => React.ReactNode; renderPayment: (props: RouteComponentProps) => React.ReactNode; @@ -26,22 +27,28 @@ const CheckoutRouter: React.FC = ({ items, checkout, payment, + totalPrice, renderAddress, renderShipping, renderPayment, renderReview, }: IRouterProps) => { const { pathname } = useLocation(); - const step = useCheckoutStepState(items, checkout, payment); + const { recommendedStep, maxPossibleStep } = useCheckoutStepState( + items, + checkout, + payment, + totalPrice + ); const stepFromPath = useCheckoutStepFromPath(pathname); const getStepLink = () => - CHECKOUT_STEPS.find(stepObj => stepObj.step === step)?.link || + CHECKOUT_STEPS.find(stepObj => stepObj.step === recommendedStep)?.link || CHECKOUT_STEPS[0].link; if ( pathname !== CHECKOUT_STEPS[4].link && - (!stepFromPath || (stepFromPath && step < stepFromPath)) + (!stepFromPath || (stepFromPath && maxPossibleStep < stepFromPath)) ) { return ; }