Skip to content

Commit

Permalink
Purchases: Use client-side formatting for renewal price on purchases …
Browse files Browse the repository at this point in the history
…pages (#71952)

* Add priceInteger to Purchase object

* Replace productDisplayPrice with priceInteger in PurchaseMetaPrice

* Add saleAmountInteger to Purchase object

* Add getRenewalPriceInSmallestUnit

* Use smallest unit for PlanPrice in ManagePurchase

* Change PurchaseItem to use formatCurrency for its prices

* Add regularPriceInteger to Purchase object

* Use formatCurrency for PurchaseMetaIntroductoryOfferDetail

* Add int prices to PurchaseMetaIntroductoryOfferDetail test

* Remove first-letter formatting for memberships subscription price

It does not work for locales where the currency symbol comes after the
price.

* Wrap refund amounts in formatCurrency

Co-authored-by: Chris Diehl <jjchrisdiehl@gmail.com>
  • Loading branch information
sirbrillig and Chris Diehl committed Jan 23, 2023
1 parent e54f822 commit 87c4f93
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 30 deletions.
3 changes: 3 additions & 0 deletions client/lib/purchases/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,18 @@ function createPurchaseObject( purchase: RawPurchase | RawPurchaseCreditCard ):
productSlug: purchase.product_slug,
productType: purchase.product_type,
productDisplayPrice: purchase.product_display_price,
priceInteger: purchase.price_integer,
totalRefundAmount: Number( purchase.total_refund_amount ),
totalRefundText: purchase.total_refund_text,
refundAmount: Number( purchase.refund_amount ),
refundOptions: purchase.refund_options,
refundText: purchase.refund_text,
refundPeriodInDays: purchase.refund_period_in_days,
regularPriceText: purchase.regular_price_text,
regularPriceInteger: purchase.regular_price_integer,
renewDate: purchase.renew_date,
saleAmount: purchase.sale_amount,
saleAmountInteger: purchase.sale_amount_integer,
siteId: Number( purchase.blog_id ),
siteName: purchase.blogname,
subscribedDate: purchase.subscribed_date,
Expand Down
4 changes: 4 additions & 0 deletions client/lib/purchases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,10 @@ export function getRenewalPrice( purchase: Purchase ) {
return purchase.saleAmount || purchase.amount;
}

export function getRenewalPriceInSmallestUnit( purchase: Purchase ) {
return purchase.saleAmountInteger || purchase.priceInteger;
}

export function showCreditCardExpiringWarning( purchase: Purchase ) {
return (
! isIncludedWithPlan( purchase ) &&
Expand Down
17 changes: 17 additions & 0 deletions client/lib/purchases/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ export interface Purchase {
priceText: string;
priceTierList?: Array< PurchasePriceTier >;
productDisplayPrice: string;

/**
* The renewal price of the purchase in the currency's smallest unit.
*/
priceInteger: number;

productId: number;
productName: string;
productSlug: string;
Expand All @@ -54,8 +60,16 @@ export interface Purchase {
refundPeriodInDays: number;
refundText: string;
regularPriceText: string;

/**
* The renewal price of the purchase in the currency's smallest unit when its
* introductory offer is complete.
*/
regularPriceInteger: number;

renewDate: string;
saleAmount?: number;
saleAmountInteger?: number;
siteId: number;
siteName: string;
subscribedDate: string;
Expand Down Expand Up @@ -140,6 +154,7 @@ export interface RawPurchase {
product_slug: string;
product_type: string;
product_display_price: string;
price_integer: number;
total_refund_amount: number | undefined;
total_refund_text: string;
refund_amount: number;
Expand All @@ -148,8 +163,10 @@ export interface RawPurchase {
refund_options: RefundOptions | null;
refund_period_in_days: number;
regular_price_text: string;
regular_price_integer: number;
renew_date: string;
sale_amount: number | undefined;
sale_amount_integer: number | undefined;
blog_id: number | string;
blogname: string;
subscribed_date: string;
Expand Down
6 changes: 0 additions & 6 deletions client/me/memberships/subscription.scss
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,4 @@
font-size: 1.5rem;
line-height: 1.5;
color: var(--color-neutral-70);

&::first-letter {
color: var(--color-text-subtle);
vertical-align: super;
font-size: 0.75rem;
}
}
8 changes: 4 additions & 4 deletions client/me/purchases/cancel-purchase/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
isJetpackProduct,
} from '@automattic/calypso-products';
import { Card, CompactCard } from '@automattic/components';
import formatCurrency from '@automattic/format-currency';
import { localize } from 'i18n-calypso';
import page from 'page';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -135,17 +136,16 @@ class CancelPurchase extends Component {

renderFooterText = () => {
const { purchase } = this.props;
const { refundText, expiryDate, totalRefundText } = purchase;

const { currencyCode, refundAmount, expiryDate, totalRefundAmount } = purchase;
if ( hasAmountAvailableToRefund( purchase ) ) {
if ( this.state.cancelBundledDomain && this.props.includedDomainPurchase ) {
return this.props.translate( '%(refundText)s to be refunded', {
args: { refundText: totalRefundText },
args: { refundText: formatCurrency( totalRefundAmount, currencyCode ) },
context: 'refundText is of the form "[currency-symbol][amount]" i.e. "$20"',
} );
}
return this.props.translate( '%(refundText)s to be refunded', {
args: { refundText },
args: { refundText: formatCurrency( refundAmount, currencyCode ) },
context: 'refundText is of the form "[currency-symbol][amount]" i.e. "$20"',
} );
}
Expand Down
5 changes: 3 additions & 2 deletions client/me/purchases/manage-purchase/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
getDisplayName,
getPartnerName,
getRenewalPrice,
getRenewalPriceInSmallestUnit,
handleRenewMultiplePurchasesClick,
handleRenewNowClick,
hasAmountAvailableToRefund,
Expand Down Expand Up @@ -956,8 +957,8 @@ class ManagePurchase extends Component {
</div>
) : (
<PlanPrice
rawPrice={ getRenewalPrice( purchase ) }
productDisplayPrice={ purchase.productDisplayPrice }
rawPrice={ getRenewalPriceInSmallestUnit( purchase ) }
isSmallestUnit
currencyCode={ purchase.currencyCode }
taxText={ purchase.taxText }
isOnSale={ !! purchase.saleAmount }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import formatCurrency from '@automattic/format-currency';
import { getIntroductoryOfferIntervalDisplay } from '@automattic/wpcom-checkout';
import { useTranslate } from 'i18n-calypso';
import {
Expand Down Expand Up @@ -28,7 +29,10 @@ function PurchaseMetaIntroductoryOfferDetail( { purchase }: { purchase: Purchase
'After the offer ends, the subscription price will be %(regularPrice)s',
{
args: {
regularPrice: purchase.regularPriceText,
regularPrice: formatCurrency( purchase.regularPriceInteger, purchase.currencyCode, {
isSmallestUnit: true,
stripZeros: true,
} ),
},
}
);
Expand All @@ -37,7 +41,10 @@ function PurchaseMetaIntroductoryOfferDetail( { purchase }: { purchase: Purchase
'After the first renewal, the subscription price will be %(regularPrice)s',
{
args: {
regularPrice: purchase.regularPriceText,
regularPrice: formatCurrency( purchase.regularPriceInteger, purchase.currencyCode, {
isSmallestUnit: true,
stripZeros: true,
} ),
},
}
);
Expand Down
33 changes: 20 additions & 13 deletions client/me/purchases/manage-purchase/purchase-meta-price.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
PLAN_MONTHLY_PERIOD,
PLAN_TRIENNIAL_PERIOD,
} from '@automattic/calypso-products';
import { formatCurrency } from '@automattic/format-currency';
import { useTranslate } from 'i18n-calypso';
import {
isIncludedWithPlan,
Expand All @@ -16,7 +17,7 @@ import type { Purchase } from 'calypso/lib/purchases/types';

function PurchaseMetaPrice( { purchase }: { purchase: Purchase } ) {
const translate = useTranslate();
const { productDisplayPrice } = purchase;
const { priceInteger, currencyCode } = purchase;

if ( isOneTimePurchase( purchase ) || isDomainTransfer( purchase ) ) {
if ( isDIFMProduct( purchase ) ) {
Expand Down Expand Up @@ -61,10 +62,12 @@ function PurchaseMetaPrice( { purchase }: { purchase: Purchase } ) {
return translate( '{{displayPrice/}} {{period}}(one-time){{/period}}', {
components: {
displayPrice: (
<span
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={ { __html: productDisplayPrice } }
/>
<span>
{ formatCurrency( priceInteger, currencyCode, {
stripZeros: true,
isSmallestUnit: true,
} ) }
</span>
),
period: <span className="manage-purchase__time-period" />,
},
Expand Down Expand Up @@ -103,10 +106,12 @@ function PurchaseMetaPrice( { purchase }: { purchase: Purchase } ) {
const getPriceLabel = ( period: string | null ) => {
if ( ! period ) {
return (
<span
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={ { __html: productDisplayPrice } }
/>
<span>
{ formatCurrency( priceInteger, currencyCode, {
stripZeros: true,
isSmallestUnit: true,
} ) }
</span>
);
}

Expand All @@ -115,10 +120,12 @@ function PurchaseMetaPrice( { purchase }: { purchase: Purchase } ) {
args: { period },
components: {
displayPrice: (
<span
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={ { __html: productDisplayPrice } }
/>
<span>
{ formatCurrency( priceInteger, currencyCode, {
stripZeros: true,
isSmallestUnit: true,
} ) }
</span>
),
period: <span className="manage-purchase__time-period" />,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe( 'PurchaseMetaIntroductoryOfferDetail', () => {
bill_period_label: 'per year',
bill_period_days: 365,
amount: 26.37,
price_integer: 2637,
currency_code: 'USD',
currency_symbol: '$',
expiry_date: '2023-03-02T00:00:00+00:00',
Expand All @@ -35,6 +36,7 @@ describe( 'PurchaseMetaIntroductoryOfferDetail', () => {
transition_after_renewal_count: 0,
},
regular_price_text: '$35',
regular_price_integer: 3500,
},
],
},
Expand Down
16 changes: 13 additions & 3 deletions client/me/purchases/purchase-item/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
PLAN_TRIENNIAL_PERIOD,
} from '@automattic/calypso-products';
import { CompactCard, Gridicon } from '@automattic/components';
import formatCurrency from '@automattic/format-currency';
import { ExternalLink } from '@wordpress/components';
import { Icon, warning as warningIcon } from '@wordpress/icons';
import classNames from 'classnames';
Expand Down Expand Up @@ -153,7 +154,10 @@ class PurchaseItem extends Component {
{
args: {
date: expiry.format( 'LL' ),
amount: purchase.priceText,
amount: formatCurrency( purchase.priceInteger, purchase.currencyCode, {
isSmallestUnit: true,
stripZeros: true,
} ),
},
components: {
span: <span className="purchase-item__date" />,
Expand Down Expand Up @@ -221,7 +225,10 @@ class PurchaseItem extends Component {
if ( purchase.billPeriodDays ) {
const translateOptions = {
args: {
amount: purchase.priceText,
amount: formatCurrency( purchase.priceInteger, purchase.currencyCode, {
isSmallestUnit: true,
stripZeros: true,
} ),
date: renewDate.format( 'LL' ),
},
components: {
Expand Down Expand Up @@ -278,7 +285,10 @@ class PurchaseItem extends Component {

return translate( 'Renews at %(amount)s on {{span}}%(date)s{{/span}}', {
args: {
amount: purchase.priceText,
amount: formatCurrency( purchase.priceInteger, purchase.currencyCode, {
isSmallestUnit: true,
stripZeros: true,
} ),
date: renewDate.format( 'LL' ),
},
components: {
Expand Down

0 comments on commit 87c4f93

Please sign in to comment.