Skip to content

Commit

Permalink
Revert "Plans 2023: Add pricing to Plans data-store and use in plans-…
Browse files Browse the repository at this point in the history
…grid (take 3) (#86225)" (#86226)

This reverts commit 7430749.
  • Loading branch information
chriskmnds authored Jan 10, 2024
1 parent 7430749 commit e3c3a40
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 368 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,45 @@ import {
import { Plans, WpcomPlansUI, Purchases } from '@automattic/data-stores';
import { useSelect } from '@wordpress/data';
import { useSelector } from 'react-redux';
import { getPlanPrices } from 'calypso/state/plans/selectors';
import { PlanPrices } from 'calypso/state/plans/types';
import { getSitePlanRawPrice } from 'calypso/state/sites/plans/selectors';
import getSelectedSiteId from 'calypso/state/ui/selectors/get-selected-site-id';
import useCheckPlanAvailabilityForPurchase from '../use-check-plan-availability-for-purchase';
import type { AddOnMeta } from '@automattic/data-stores';
import type {
UsePricingMetaForGridPlans,
PricingMetaForGridPlan,
} from 'calypso/my-sites/plans-grid/hooks/npm-ready/data-store/use-grid-plans';
import type { IAppState } from 'calypso/state/types';

interface Props {
planSlugs: PlanSlug[];
withoutProRatedCredits?: boolean;
storageAddOns?: ( AddOnMeta | null )[] | null;
}

function getTotalPrice( planPrice: number | null | undefined, addOnPrice = 0 ): number | null {
return null !== planPrice && undefined !== planPrice ? planPrice + addOnPrice : null;
function getTotalPrices( planPrices: PlanPrices, addOnPrice = 0 ): PlanPrices {
const totalPrices = { ...planPrices };
let key: keyof PlanPrices;

for ( key in totalPrices ) {
const price = totalPrices[ key ];

if ( price !== null ) {
totalPrices[ key ] = price + addOnPrice;
}
}

return totalPrices;
}

/*
* Returns the pricing metadata needed for the plans-ui components.
* - see PricingMetaForGridPlan type for details
* - will migrate to data-store once dependencies are resolved (when site & plans data-stores more complete)
*/

const usePricingMetaForGridPlans: UsePricingMetaForGridPlans = ( {
planSlugs,
withoutProRatedCredits = false,
Expand All @@ -40,44 +56,24 @@ const usePricingMetaForGridPlans: UsePricingMetaForGridPlans = ( {
// TODO: pass this in as a prop to uncouple the dependency
const planAvailabilityForPurchase = useCheckPlanAvailabilityForPurchase( { planSlugs } );

// plans - should have a definition for all plans, being the main source of API data
const plans = Plans.usePlans();
// sitePlans - unclear if all plans are included
const sitePlans = Plans.useSitePlans( { siteId: selectedSiteId } );
// pricedAPIPlans - should have a definition for all plans, being the main source of API data
const pricedAPIPlans = Plans.usePlans();
// pricedAPISitePlans - unclear if all plans are included
const pricedAPISitePlans = Plans.useSitePlans( { siteId: selectedSiteId } );
const currentPlan = Plans.useCurrentPlan( { siteId: selectedSiteId } );
const introOffers = Plans.useIntroOffers( { siteId: selectedSiteId } );
const purchasedPlan = Purchases.useSitePurchaseById( {
siteId: selectedSiteId,
purchaseId: currentPlan?.purchaseId,
} );

const selectedStorageOptions = useSelect(
( select ) => select( WpcomPlansUI.store ).getSelectedStorageOptions(),
[]
);
const selectedStorageOptions = useSelect( ( select ) => {
return select( WpcomPlansUI.store ).getSelectedStorageOptions();
}, [] );

let planPrices:
| {
[ planSlug in PlanSlug ]?: {
originalPrice: Plans.PlanPricing[ 'originalPrice' ];
discountedPrice: Plans.PlanPricing[ 'discountedPrice' ];
};
}
| null = null;

if ( ( selectedSiteId && sitePlans.isLoading ) || plans.isLoading ) {
/**
* Null until all data is ready, at least in initial state.
* - For now a simple loader is shown until these are resolved
* - `sitePlans` being a dependent query will only get fetching status when enabled (when `siteId` exists)
*/
planPrices = null;
} else {
/**
* Projected prices as needed for the plan-grid UI.
*/
planPrices = Object.fromEntries(
planSlugs.map( ( planSlug ) => {
const planPrices = useSelector( ( state: IAppState ) => {
return planSlugs.reduce(
( acc, planSlug ) => {
const availableForPurchase = planAvailabilityForPurchase[ planSlug ];
const selectedStorageOption = selectedStorageOptions?.[ planSlug ];
const selectedStorageAddOn = storageAddOns?.find( ( addOn ) => {
Expand All @@ -90,34 +86,33 @@ const usePricingMetaForGridPlans: UsePricingMetaForGridPlans = ( {
const storageAddOnPriceMonthly = storageAddOnPrices?.monthlyPrice || 0;
const storageAddOnPriceYearly = storageAddOnPrices?.yearlyPrice || 0;

const plan = plans.data?.[ planSlug ];
const sitePlan = sitePlans.data?.[ planSlug ];

/**
* 0. No plan or sitePlan (when selected site exists): planSlug is for a priceless plan.
*/
if ( ! plan || ( selectedSiteId && ! sitePlan ) ) {
return [
planSlug,
{
originalPrice: {
monthly: null,
full: null,
},
discountedPrice: {
monthly: null,
full: null,
},
},
];
}
const planPricesMonthly = getPlanPrices( state, {
planSlug,
siteId: selectedSiteId || null,
returnMonthly: true,
returnSmallestUnit: true,
} );
const planPricesFull = getPlanPrices( state, {
planSlug,
siteId: selectedSiteId || null,
returnMonthly: false,
returnSmallestUnit: true,
} );
const totalPricesMonthly = getTotalPrices( planPricesMonthly, storageAddOnPriceMonthly );
const totalPricesFull = getTotalPrices( planPricesFull, storageAddOnPriceYearly );

/**
* 1. Original prices only for current site's plan.
*/
if ( selectedSiteId && currentPlan?.planSlug === planSlug ) {
let monthlyPrice = sitePlan?.pricing.originalPrice.monthly;
let fullPrice = sitePlan?.pricing.originalPrice.full;
let monthlyPrice = getSitePlanRawPrice( state, selectedSiteId, planSlug, {
returnMonthly: true,
returnSmallestUnit: true,
} );
let fullPrice = getSitePlanRawPrice( state, selectedSiteId, planSlug, {
returnMonthly: false,
returnSmallestUnit: true,
} );

/**
* Ensure the spotlight plan shows the price with which the plans was purchased.
Expand All @@ -135,93 +130,92 @@ const usePricingMetaForGridPlans: UsePricingMetaForGridPlans = ( {
}
}

return [
planSlug,
{
return {
...acc,
[ planSlug ]: {
originalPrice: {
monthly: getTotalPrice( monthlyPrice ?? null, storageAddOnPriceMonthly ),
full: getTotalPrice( fullPrice ?? null, storageAddOnPriceYearly ),
monthly: monthlyPrice ? monthlyPrice + storageAddOnPriceMonthly : null,
full: fullPrice ? fullPrice + storageAddOnPriceYearly : null,
},
discountedPrice: {
monthly: null,
full: null,
},
},
];
};
}

/**
* 2. Original and Discounted prices for plan available for purchase.
* - If prorated credits are needed, then pick the discounted price from sitePlan (site context) if one exists.
*/
if ( availableForPurchase ) {
const originalPrice = {
monthly: getTotalPrice( plan?.pricing.originalPrice.monthly, storageAddOnPriceMonthly ),
full: getTotalPrice( plan?.pricing.originalPrice.full, storageAddOnPriceYearly ),
};
const discountedPrice = {
monthly:
sitePlan && ! withoutProRatedCredits
? getTotalPrice(
sitePlan.pricing.discountedPrice.monthly,
storageAddOnPriceMonthly
)
: getTotalPrice( plan?.pricing.discountedPrice.monthly, storageAddOnPriceMonthly ),
full:
sitePlan && ! withoutProRatedCredits
? getTotalPrice( sitePlan.pricing.discountedPrice.full, storageAddOnPriceYearly )
: getTotalPrice( plan?.pricing.discountedPrice.full, storageAddOnPriceYearly ),
};

return [
planSlug,
{
originalPrice,
discountedPrice,
return {
...acc,
[ planSlug ]: {
originalPrice: {
monthly: totalPricesMonthly.rawPrice,
full: totalPricesFull.rawPrice,
},
discountedPrice: {
monthly: withoutProRatedCredits
? totalPricesMonthly.discountedRawPrice
: totalPricesMonthly.planDiscountedRawPrice ||
totalPricesMonthly.discountedRawPrice,
full: withoutProRatedCredits
? totalPricesFull.discountedRawPrice
: totalPricesFull.planDiscountedRawPrice || totalPricesFull.discountedRawPrice,
},
},
];
};
}

/**
* 3. Original prices only for plan not available for purchase.
*/
return [
planSlug,
{
return {
...acc,
[ planSlug ]: {
originalPrice: {
monthly: getTotalPrice(
plan?.pricing.originalPrice.monthly,
storageAddOnPriceMonthly
),
full: getTotalPrice( plan?.pricing.originalPrice.full, storageAddOnPriceYearly ),
monthly: totalPricesMonthly.rawPrice,
full: totalPricesFull.rawPrice,
},
discountedPrice: {
monthly: null,
full: null,
},
},
];
} )
};
},
{} as {
[ planSlug: string ]: Pick< PricingMetaForGridPlan, 'originalPrice' | 'discountedPrice' >;
}
);
} );

/*
* Return null until all data is ready, at least in initial state.
* - For now a simple loader is shown until these are resolved
* - We can optimise Error states in the UI / when everything gets ported into data-stores
* - `pricedAPISitePlans` being a dependent query will only get fetching status when enabled (when `siteId` exists)
*/

if ( ( selectedSiteId && pricedAPISitePlans.isLoading ) || pricedAPIPlans.isLoading ) {
return null;
}

return (
// TODO: consider removing the null return
planPrices &&
planSlugs.reduce(
( acc, planSlug ) => ( {
...acc,
[ planSlug ]: {
originalPrice: planPrices?.[ planSlug ]?.originalPrice,
discountedPrice: planPrices?.[ planSlug ]?.discountedPrice,
billingPeriod: plans.data?.[ planSlug ]?.pricing.billPeriod,
currencyCode: plans.data?.[ planSlug ]?.pricing.currencyCode,
expiry: sitePlans.data?.[ planSlug ]?.expiry,
introOffer: introOffers?.[ planSlug ],
},
} ),
{} as { [ planSlug in PlanSlug ]?: PricingMetaForGridPlan }
)
return planSlugs.reduce(
( acc, planSlug ) => ( {
...acc,
[ planSlug ]: {
originalPrice: planPrices[ planSlug ]?.originalPrice,
discountedPrice: planPrices[ planSlug ]?.discountedPrice,
billingPeriod: pricedAPIPlans.data?.[ planSlug ]?.billPeriod,
currencyCode: pricedAPIPlans.data?.[ planSlug ]?.currencyCode,
expiry: pricedAPISitePlans.data?.[ planSlug ]?.expiry,
introOffer: introOffers?.[ planSlug ],
},
} ),
{} as { [ planSlug: string ]: PricingMetaForGridPlan }
);
};

Expand Down
Loading

0 comments on commit e3c3a40

Please sign in to comment.