Mini Cart block: Add label for tax when it should be visible in accordance with WC settings (https://github.com/woocommerce/woocommerce-blocks/pull/5184)

* Mini Cart block: Add label for tax when it should be visible in accordance with WC settings woocommerce/woocommerce-blocks#4849

Mini Cart block: Add label for tax when it should be visible in accordance with WC settings

* improve the tax label handling

* fix code after conflict

* fix tax label handling when it is added the first product

* add another check for avoid PHP error

* rename variables; add test for the function getSettingWithCoercion

* add margin-right for tax-label; add test to check if type guard works correctly
This commit is contained in:
Luigi Teschio 2021-12-03 10:45:06 +01:00 committed by GitHub
parent c2ebf26c1c
commit 2358c0c90b
6 changed files with 180 additions and 6 deletions

View File

@ -20,7 +20,8 @@ import {
formatPrice,
getCurrencyFromPriceResponse,
} from '@woocommerce/price-format';
import { getSetting } from '@woocommerce/settings';
import { getSettingWithCoercion } from '@woocommerce/settings';
import { isString, isBoolean } from '@woocommerce/types';
/**
* Internal dependencies
@ -113,7 +114,15 @@ const MiniCartBlock = ( {
};
}, [] );
const subTotal = getSetting( 'displayCartPricesIncludingTax', false )
const showIncludingTax = getSettingWithCoercion(
'displayCartPricesIncludingTax',
false,
isBoolean
);
const taxLabel = getSettingWithCoercion( 'taxLabel', '', isString );
const subTotal = showIncludingTax
? parseInt( cartTotals.total_items, 10 ) +
parseInt( cartTotals.total_items_tax, 10 )
: parseInt( cartTotals.total_items, 10 );
@ -154,6 +163,11 @@ const MiniCartBlock = ( {
getCurrencyFromPriceResponse( cartTotals )
) }
</span>
{ taxLabel !== '' && subTotal !== 0 && (
<small className="wc-block-mini-cart__tax-label">
{ taxLabel }
</small>
) }
<QuantityBadge
count={ cartItemsCount }
colorClassNames={ colorClassNames }

View File

@ -33,6 +33,10 @@
display: none;
}
.wc-block-mini-cart__tax-label {
margin-right: em($gap-smaller);
}
@media screen and (min-width: 768px) {
.wc-block-mini-cart__amount {
display: initial;

View File

@ -0,0 +1,33 @@
/**
* External dependencies
*/
import { isBoolean, isString } from '@woocommerce/types';
/**
* Internal dependencies
*/
import { ADMIN_URL } from '../default-constants';
import { getSettingWithCoercion } from '..';
describe( 'getSettingWithCoercion', () => {
it( 'returns provided default for non available setting', () => {
expect(
getSettingWithCoercion( 'nada', 'really nada', isString )
).toBe( 'really nada' );
} );
it( 'returns provided default value when the typeguard returns false', () => {
expect(
getSettingWithCoercion( 'currentUserIsAdmin', '', isString )
).toBe( '' );
} );
it( 'returns expected value for existing setting', () => {
expect(
getSettingWithCoercion( 'adminUrl', 'not this', isString )
).toEqual( ADMIN_URL );
} );
it( "returns expected value for existing setting even if it's a falsy value", () => {
expect(
getSettingWithCoercion( 'currentUserIsAdmin', true, isBoolean )
).toBe( false );
} );
} );

View File

@ -25,6 +25,15 @@ export const getSetting = < T >(
return filter( value, fallback ) as T;
};
export const getSettingWithCoercion = < T >(
name: string,
fallback: T,
typeguard: ( val: unknown, fb: unknown ) => val is T
): T => {
const value = name in allSettings ? allSettings[ name ] : fallback;
return typeguard( value, fallback ) ? value : fallback;
};
/**
* Note: this attempts to coerce the wpVersion to a semver for comparison
* This will result in dropping any beta/rc values.

View File

@ -34,3 +34,7 @@ export const isFunction = < T extends Function, U >(
): term is T => {
return typeof term === 'function';
};
export const isBoolean = ( term: unknown ): term is boolean => {
return typeof term === 'boolean';
};

View File

@ -4,6 +4,10 @@ namespace Automattic\WooCommerce\Blocks\BlockTypes;
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\CartController;
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi;
use Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry;
use Automattic\WooCommerce\Blocks\RestApi;
/**
* Mini Cart class.
@ -25,6 +29,32 @@ class MiniCart extends AbstractBlock {
*/
protected $scripts_to_lazy_load = array();
/**
* Inc Tax label.
*
* @var string
*/
protected $tax_label = '';
/**
* Visibility of price including tax.
*
* @var string
*/
protected $display_cart_prices_including_tax = false;
/**
* Constructor.
*
* @param AssetApi $asset_api Instance of the asset API.
* @param AssetDataRegistry $asset_data_registry Instance of the asset data registry.
* @param IntegrationRegistry $integration_registry Instance of the integration registry.
*/
public function __construct( AssetApi $asset_api, AssetDataRegistry $asset_data_registry, IntegrationRegistry $integration_registry ) {
parent::__construct( $asset_api, $asset_data_registry, $integration_registry, $this->block_name );
}
/**
* Get the editor script handle for this block type.
*
@ -77,6 +107,23 @@ class MiniCart extends AbstractBlock {
// Hydrate the following data depending on admin or frontend context.
if ( ! is_admin() && ! WC()->is_rest_api_request() ) {
$this->hydrate_from_api();
$label_info = $this->get_tax_label();
$this->tax_label = $label_info['tax_label'];
$this->display_cart_prices_including_tax = $label_info['display_cart_prices_including_tax'];
$this->asset_data_registry->add(
'taxLabel',
$this->tax_label,
''
);
$this->asset_data_registry->add(
'displayCartPricesIncludingTax',
$this->display_cart_prices_including_tax,
false
);
}
$script_data = $this->asset_api->get_script_data( 'build/mini-cart-component-frontend.js' );
@ -119,7 +166,7 @@ class MiniCart extends AbstractBlock {
$this->asset_data_registry->add(
'displayCartPricesIncludingTax',
'incl' === get_option( 'woocommerce_tax_display_cart' ),
$this->display_cart_prices_including_tax,
true
);
@ -209,6 +256,19 @@ class MiniCart extends AbstractBlock {
);
}
/**
* Returns the markup for render the tax label.
*
* @return string
*/
protected function get_include_tax_label_markup() {
$cart_controller = $this->get_cart_controller();
$cart = $cart_controller->get_cart_instance();
$cart_contents_total = $cart->get_subtotal();
return ( ! empty( $this->tax_label ) && 0 !== $cart_contents_total ) ? ( "<small class='wc-block-mini-cart__tax-label'>" . esc_html( $this->tax_label ) . '</small>' ) : '';
}
/**
* Append frontend scripts when rendering the Mini Cart block.
*
@ -234,7 +294,8 @@ class MiniCart extends AbstractBlock {
// real cart data and to print the markup.
return '';
}
$cart_controller = new CartController();
$cart_controller = $this->get_cart_controller();
$cart = $cart_controller->get_cart_instance();
$cart_contents_count = $cart->get_cart_contents_count();
$cart_contents = $cart->get_cart();
@ -282,7 +343,7 @@ class MiniCart extends AbstractBlock {
}
$aria_label = sprintf(
/* translators: %1$d is the number of products in the cart. %2$s is the cart total */
/* translators: %1$d is the number of products in the cart. %2$s is the cart total */
_n(
'%1$d item in cart, total price of %2$s',
'%1$d items in cart, total price of %2$s',
@ -293,7 +354,7 @@ class MiniCart extends AbstractBlock {
wp_strip_all_tags( wc_price( $cart_contents_total ) )
);
$title = sprintf(
/* translators: %d is the count of items in the cart. */
/* translators: %d is the count of items in the cart. */
_n(
'Your cart (%d item)',
'Your cart (%d items)',
@ -315,6 +376,7 @@ class MiniCart extends AbstractBlock {
</defs>
</svg>';
$button_html = '<span class="wc-block-mini-cart__amount">' . esc_html( wp_strip_all_tags( wc_price( $cart_contents_total ) ) ) . '</span>
' . $this->get_include_tax_label_markup() . '
<span class="wc-block-mini-cart__quantity-badge">
' . $icon . '
<span class="wc-block-mini-cart__badge ' . $classes . '" style="' . $style . '">' . $cart_contents_count . '</span>
@ -358,4 +420,52 @@ class MiniCart extends AbstractBlock {
</div>
</div>';
}
/**
* Return an instace of the CartController class.
*
* @return CartController CartController class instance.
*/
protected function get_cart_controller() {
return new CartController();
}
/**
* Get array with data for handle the tax label.
* the entire logic of this function is was taken from:
* https://github.com/woocommerce/woocommerce/blob/e730f7463c25b50258e97bf56e31e9d7d3bc7ae7/includes/class-wc-cart.php#L1582
*
* @return array;
*/
protected function get_tax_label() {
$cart = WC()->cart;
if ( $cart->display_prices_including_tax() ) {
if ( ! wc_prices_include_tax() ) {
$tax_label = WC()->countries->inc_tax_or_vat();
$display_cart_prices_including_tax = true;
return array(
'tax_label' => $tax_label,
'display_cart_prices_including_tax' => $display_cart_prices_including_tax,
);
}
return array(
'label_including_tax' => '',
'display_cart_prices_including_tax' => true,
);
}
if ( wc_prices_include_tax() ) {
$tax_label = WC()->countries->ex_tax_or_vat();
return array(
'tax_label' => $tax_label,
'display_cart_prices_including_tax' => false,
);
};
return array(
'tax_label' => '',
'display_cart_prices_including_tax' => false,
);
}
}