initial commit
This commit is contained in:
@ -0,0 +1,2 @@
|
||||
export { usePaymentMethodInterface } from './use-payment-method-interface';
|
||||
export * from './use-payment-methods';
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { prepareTotalItems } from '../utils';
|
||||
|
||||
describe( 'prepareTotalItems', () => {
|
||||
const fixture = {
|
||||
total_items: '200',
|
||||
total_items_tax: '20',
|
||||
total_fees: '100',
|
||||
total_fees_tax: '10',
|
||||
total_discount: '350',
|
||||
total_discount_tax: '50',
|
||||
total_shipping: '50',
|
||||
total_shipping_tax: '5',
|
||||
total_tax: '30',
|
||||
};
|
||||
const expected = [
|
||||
{
|
||||
key: 'total_items',
|
||||
label: 'Subtotal:',
|
||||
value: 200,
|
||||
valueWithTax: 220,
|
||||
},
|
||||
{
|
||||
key: 'total_fees',
|
||||
label: 'Fees:',
|
||||
value: 100,
|
||||
valueWithTax: 110,
|
||||
},
|
||||
{
|
||||
key: 'total_discount',
|
||||
label: 'Discount:',
|
||||
value: 350,
|
||||
valueWithTax: 400,
|
||||
},
|
||||
{
|
||||
key: 'total_tax',
|
||||
label: 'Taxes:',
|
||||
value: 30,
|
||||
valueWithTax: 30,
|
||||
},
|
||||
];
|
||||
const expectedWithShipping = [
|
||||
...expected,
|
||||
{
|
||||
key: 'total_shipping',
|
||||
label: 'Shipping:',
|
||||
value: 50,
|
||||
valueWithTax: 55,
|
||||
},
|
||||
];
|
||||
it( 'returns expected values when needsShipping is false', () => {
|
||||
expect( prepareTotalItems( fixture, false ) ).toEqual( expected );
|
||||
} );
|
||||
it( 'returns expected values when needsShipping is true', () => {
|
||||
expect( prepareTotalItems( fixture, true ) ).toEqual(
|
||||
expectedWithShipping
|
||||
);
|
||||
} );
|
||||
} );
|
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
|
||||
import { useCallback, useEffect, useRef } from '@wordpress/element';
|
||||
import PaymentMethodLabel from '@woocommerce/base-components/cart-checkout/payment-method-label';
|
||||
import PaymentMethodIcons from '@woocommerce/base-components/cart-checkout/payment-method-icons';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import deprecated from '@wordpress/deprecated';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ValidationInputError } from '../../providers/validation';
|
||||
import { useStoreCart } from '../cart/use-store-cart';
|
||||
import { useStoreCartCoupons } from '../cart/use-store-cart-coupons';
|
||||
import { useEmitResponse } from '../use-emit-response';
|
||||
import { useCheckoutContext } from '../../providers/cart-checkout/checkout-state';
|
||||
import { usePaymentMethodDataContext } from '../../providers/cart-checkout/payment-methods';
|
||||
import { useShippingDataContext } from '../../providers/cart-checkout/shipping';
|
||||
import { useCustomerDataContext } from '../../providers/cart-checkout/customer';
|
||||
import { prepareTotalItems } from './utils';
|
||||
|
||||
/**
|
||||
* Returns am interface to use as payment method props.
|
||||
*/
|
||||
export const usePaymentMethodInterface = (): Record< string, unknown > => {
|
||||
const {
|
||||
isCalculating,
|
||||
isComplete,
|
||||
isIdle,
|
||||
isProcessing,
|
||||
onCheckoutBeforeProcessing,
|
||||
onCheckoutValidationBeforeProcessing,
|
||||
onCheckoutAfterProcessingWithSuccess,
|
||||
onCheckoutAfterProcessingWithError,
|
||||
onSubmit,
|
||||
customerId,
|
||||
} = useCheckoutContext();
|
||||
const {
|
||||
currentStatus,
|
||||
activePaymentMethod,
|
||||
onPaymentProcessing,
|
||||
setExpressPaymentError,
|
||||
shouldSavePayment,
|
||||
} = usePaymentMethodDataContext();
|
||||
const {
|
||||
shippingErrorStatus,
|
||||
shippingErrorTypes,
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
selectedRates,
|
||||
setSelectedRates,
|
||||
isSelectingRate,
|
||||
onShippingRateSuccess,
|
||||
onShippingRateFail,
|
||||
onShippingRateSelectSuccess,
|
||||
onShippingRateSelectFail,
|
||||
needsShipping,
|
||||
} = useShippingDataContext();
|
||||
const {
|
||||
billingData,
|
||||
shippingAddress,
|
||||
setShippingAddress,
|
||||
} = useCustomerDataContext();
|
||||
const { cartTotals } = useStoreCart();
|
||||
const { appliedCoupons } = useStoreCartCoupons();
|
||||
const { noticeContexts, responseTypes } = useEmitResponse();
|
||||
const currentCartTotals = useRef(
|
||||
prepareTotalItems( cartTotals, needsShipping )
|
||||
);
|
||||
const currentCartTotal = useRef( {
|
||||
label: __( 'Total', 'woo-gutenberg-products-block' ),
|
||||
value: parseInt( cartTotals.total_price, 10 ),
|
||||
} );
|
||||
|
||||
useEffect( () => {
|
||||
currentCartTotals.current = prepareTotalItems(
|
||||
cartTotals,
|
||||
needsShipping
|
||||
);
|
||||
currentCartTotal.current = {
|
||||
label: __( 'Total', 'woo-gutenberg-products-block' ),
|
||||
value: parseInt( cartTotals.total_price, 10 ),
|
||||
};
|
||||
}, [ cartTotals, needsShipping ] );
|
||||
|
||||
const deprecatedSetExpressPaymentError = useCallback(
|
||||
( errorMessage = '' ) => {
|
||||
deprecated(
|
||||
'setExpressPaymentError should only be used by Express Payment Methods (using the provided onError handler).',
|
||||
{
|
||||
alternative: '',
|
||||
plugin: 'woocommerce-gutenberg-products-block',
|
||||
link:
|
||||
'https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4228',
|
||||
}
|
||||
);
|
||||
setExpressPaymentError( errorMessage );
|
||||
},
|
||||
[ setExpressPaymentError ]
|
||||
);
|
||||
|
||||
return {
|
||||
activePaymentMethod,
|
||||
billing: {
|
||||
billingData,
|
||||
cartTotal: currentCartTotal.current,
|
||||
currency: getCurrencyFromPriceResponse( cartTotals ),
|
||||
cartTotalItems: currentCartTotals.current,
|
||||
displayPricesIncludingTax: getSetting(
|
||||
'displayCartPricesIncludingTax',
|
||||
false
|
||||
) as boolean,
|
||||
appliedCoupons,
|
||||
customerId,
|
||||
},
|
||||
checkoutStatus: {
|
||||
isCalculating,
|
||||
isComplete,
|
||||
isIdle,
|
||||
isProcessing,
|
||||
},
|
||||
components: {
|
||||
ValidationInputError,
|
||||
PaymentMethodIcons,
|
||||
PaymentMethodLabel,
|
||||
},
|
||||
emitResponse: {
|
||||
noticeContexts,
|
||||
responseTypes,
|
||||
},
|
||||
eventRegistration: {
|
||||
onCheckoutBeforeProcessing,
|
||||
onCheckoutValidationBeforeProcessing,
|
||||
onCheckoutAfterProcessingWithSuccess,
|
||||
onCheckoutAfterProcessingWithError,
|
||||
onShippingRateSuccess,
|
||||
onShippingRateFail,
|
||||
onShippingRateSelectSuccess,
|
||||
onShippingRateSelectFail,
|
||||
onPaymentProcessing,
|
||||
},
|
||||
onSubmit,
|
||||
paymentStatus: currentStatus,
|
||||
setExpressPaymentError: deprecatedSetExpressPaymentError,
|
||||
shippingData: {
|
||||
shippingRates,
|
||||
shippingRatesLoading,
|
||||
selectedRates,
|
||||
setSelectedRates,
|
||||
isSelectingRate,
|
||||
shippingAddress,
|
||||
setShippingAddress,
|
||||
needsShipping,
|
||||
},
|
||||
shippingStatus: {
|
||||
shippingErrorStatus,
|
||||
shippingErrorTypes,
|
||||
},
|
||||
shouldSavePayment,
|
||||
};
|
||||
};
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useShallowEqual } from '@woocommerce/base-hooks';
|
||||
import type {
|
||||
PaymentMethods,
|
||||
ExpressPaymentMethods,
|
||||
} from '@woocommerce/type-defs/payments';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { usePaymentMethodDataContext } from '../../providers/cart-checkout/payment-methods';
|
||||
|
||||
interface PaymentMethodState {
|
||||
paymentMethods: PaymentMethods;
|
||||
isInitialized: boolean;
|
||||
}
|
||||
interface ExpressPaymentMethodState {
|
||||
paymentMethods: ExpressPaymentMethods;
|
||||
isInitialized: boolean;
|
||||
}
|
||||
|
||||
const usePaymentMethodState = (
|
||||
express = false
|
||||
): PaymentMethodState | ExpressPaymentMethodState => {
|
||||
const {
|
||||
paymentMethods,
|
||||
expressPaymentMethods,
|
||||
paymentMethodsInitialized,
|
||||
expressPaymentMethodsInitialized,
|
||||
} = usePaymentMethodDataContext();
|
||||
|
||||
const currentPaymentMethods = useShallowEqual( paymentMethods );
|
||||
const currentExpressPaymentMethods = useShallowEqual(
|
||||
expressPaymentMethods
|
||||
);
|
||||
|
||||
return {
|
||||
paymentMethods: express
|
||||
? currentExpressPaymentMethods
|
||||
: currentPaymentMethods,
|
||||
isInitialized: express
|
||||
? expressPaymentMethodsInitialized
|
||||
: paymentMethodsInitialized,
|
||||
};
|
||||
};
|
||||
|
||||
export const usePaymentMethods = ():
|
||||
| PaymentMethodState
|
||||
| ExpressPaymentMethodState => usePaymentMethodState( false );
|
||||
export const useExpressPaymentMethods = (): ExpressPaymentMethodState =>
|
||||
usePaymentMethodState( true );
|
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import {
|
||||
CartResponseTotals,
|
||||
objectHasProp,
|
||||
isString,
|
||||
} from '@woocommerce/types';
|
||||
|
||||
export interface CartTotalItem {
|
||||
key: string;
|
||||
label: string;
|
||||
value: number;
|
||||
valueWithTax: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the total items into a shape usable for display as passed on to
|
||||
* registered payment methods.
|
||||
*
|
||||
* @param {Object} totals Current cart total items
|
||||
* @param {boolean} needsShipping Whether or not shipping is needed.
|
||||
*/
|
||||
export const prepareTotalItems = (
|
||||
totals: CartResponseTotals,
|
||||
needsShipping: boolean
|
||||
): CartTotalItem[] => {
|
||||
const newTotals = [];
|
||||
|
||||
const factory = ( label: string, property: string ): CartTotalItem => {
|
||||
const taxProperty = property + '_tax';
|
||||
const value =
|
||||
objectHasProp( totals, property ) && isString( totals[ property ] )
|
||||
? parseInt( totals[ property ] as string, 10 )
|
||||
: 0;
|
||||
const tax =
|
||||
objectHasProp( totals, taxProperty ) &&
|
||||
isString( totals[ taxProperty ] )
|
||||
? parseInt( totals[ taxProperty ] as string, 10 )
|
||||
: 0;
|
||||
return {
|
||||
key: property,
|
||||
label,
|
||||
value,
|
||||
valueWithTax: value + tax,
|
||||
};
|
||||
};
|
||||
|
||||
newTotals.push(
|
||||
factory(
|
||||
__( 'Subtotal:', 'woo-gutenberg-products-block' ),
|
||||
'total_items'
|
||||
)
|
||||
);
|
||||
|
||||
newTotals.push(
|
||||
factory( __( 'Fees:', 'woo-gutenberg-products-block' ), 'total_fees' )
|
||||
);
|
||||
|
||||
newTotals.push(
|
||||
factory(
|
||||
__( 'Discount:', 'woo-gutenberg-products-block' ),
|
||||
'total_discount'
|
||||
)
|
||||
);
|
||||
|
||||
newTotals.push( {
|
||||
key: 'total_tax',
|
||||
label: __( 'Taxes:', 'woo-gutenberg-products-block' ),
|
||||
value: parseInt( totals.total_tax, 10 ),
|
||||
valueWithTax: parseInt( totals.total_tax, 10 ),
|
||||
} );
|
||||
|
||||
if ( needsShipping ) {
|
||||
newTotals.push(
|
||||
factory(
|
||||
__( 'Shipping:', 'woo-gutenberg-products-block' ),
|
||||
'total_shipping'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return newTotals;
|
||||
};
|
Reference in New Issue
Block a user