Skip to content

Fixed Issue 12225: Tier pricing tax shows only including tax #27953

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 52 additions & 14 deletions app/code/Magento/Catalog/Pricing/Price/TierPrice.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,27 @@
use Magento\Catalog\Model\Product;
use Magento\Customer\Api\GroupManagementInterface;
use Magento\Customer\Model\Session;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
use Magento\Framework\Pricing\Amount\AmountInterface;
use Magento\Framework\Pricing\Price\AbstractPrice;
use Magento\Framework\Pricing\Price\BasePriceProviderInterface;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Framework\Pricing\PriceInfoInterface;
use Magento\Customer\Model\Group\RetrieverInterface as CustomerGroupRetrieverInterface;
use Magento\Tax\Model\Config;

/**
* @api
* @since 100.0.2
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class TierPrice extends AbstractPrice implements TierPriceInterface, BasePriceProviderInterface
{
private const XML_PATH_TAX_DISPLAY_TYPE = 'tax/display/type';

/**
* Price type tier
*/
Expand Down Expand Up @@ -62,35 +70,43 @@ class TierPrice extends AbstractPrice implements TierPriceInterface, BasePricePr
*/
private $customerGroupRetriever;

/**
* @var ScopeConfigInterface
*/
private $scopeConfig;

/**
* @param Product $saleableItem
* @param float $quantity
* @param CalculatorInterface $calculator
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
* @param PriceCurrencyInterface $priceCurrency
* @param Session $customerSession
* @param GroupManagementInterface $groupManagement
* @param CustomerGroupRetrieverInterface|null $customerGroupRetriever
* @param ScopeConfigInterface|null $scopeConfig
*/
public function __construct(
Product $saleableItem,
$quantity,
CalculatorInterface $calculator,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
PriceCurrencyInterface $priceCurrency,
Session $customerSession,
GroupManagementInterface $groupManagement,
CustomerGroupRetrieverInterface $customerGroupRetriever = null
CustomerGroupRetrieverInterface $customerGroupRetriever = null,
?ScopeConfigInterface $scopeConfig = null
) {
$quantity = (float)$quantity ? $quantity : 1;
parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
$this->customerSession = $customerSession;
$this->groupManagement = $groupManagement;
$this->customerGroupRetriever = $customerGroupRetriever
?? \Magento\Framework\App\ObjectManager::getInstance()->get(CustomerGroupRetrieverInterface::class);
?? ObjectManager::getInstance()->get(CustomerGroupRetrieverInterface::class);
if ($saleableItem->hasCustomerGroupId()) {
$this->customerGroup = (int) $saleableItem->getCustomerGroupId();
} else {
$this->customerGroup = (int) $this->customerGroupRetriever->getCustomerGroupId();
}
$this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
}

/**
Expand Down Expand Up @@ -136,6 +152,8 @@ protected function isFirstPriceBetter($firstPrice, $secondPrice)
}

/**
* Returns tier price count
*
* @return int
*/
public function getTierPriceCount()
Expand All @@ -144,6 +162,8 @@ public function getTierPriceCount()
}

/**
* Returns tier price list
*
* @return array
*/
public function getTierPriceList()
Expand All @@ -155,15 +175,32 @@ public function getTierPriceList()
$this->priceList,
function (&$priceData) {
/* convert string value to float */
$priceData['price_qty'] = $priceData['price_qty'] * 1;
$priceData['price_qty'] *= 1;
if ($this->getConfigTaxDisplayType() === Config::DISPLAY_TYPE_BOTH) {
$exclTaxPrice = $this->calculator->getAmount($priceData['price'], $this->product, true);
$priceData['excl_tax_price'] = $exclTaxPrice;
}
$priceData['price'] = $this->applyAdjustment($priceData['price']);
}
);
}

return $this->priceList;
}

/**
* Returns config tax display type
*
* @return int
*/
private function getConfigTaxDisplayType(): int
{
return (int) $this->scopeConfig->getValue(self::XML_PATH_TAX_DISPLAY_TYPE);
}

/**
* Filters tier prices
*
* @param array $priceList
* @return array
*/
Expand Down Expand Up @@ -204,6 +241,8 @@ protected function filterTierPrices(array $priceList)
}

/**
* Returns base price
*
* @return float
*/
protected function getBasePrice()
Expand All @@ -213,25 +252,22 @@ protected function getBasePrice()
}

/**
* Calculates savings percentage according to the given tier price amount
* and related product price amount.
* Calculates savings percentage according to the given tier price amount and related product price amount.
*
* @param AmountInterface $amount
*
* @return float
*/
public function getSavePercent(AmountInterface $amount)
{
$productPriceAmount = $this->priceInfo->getPrice(
FinalPrice::PRICE_CODE
)->getAmount();
$productPriceAmount = $this->priceInfo->getPrice(FinalPrice::PRICE_CODE)
->getAmount();

return round(
100 - ((100 / $productPriceAmount->getValue()) * $amount->getValue())
);
return round(100 - ((100 / $productPriceAmount->getValue()) * $amount->getValue()));
}

/**
* Apply adjustment to price
*
* @param float|string $price
* @return \Magento\Framework\Pricing\Amount\AmountInterface
*/
Expand Down Expand Up @@ -314,6 +350,8 @@ protected function getStoredTierPrices()
}

/**
* Return is percentage discount
*
* @return bool
*/
public function isPercentageDiscount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
namespace Magento\ConfigurableProduct\Block\Product\View\Type;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\ConfigurableProduct\Model\ConfigurableAttributeData;
use Magento\Customer\Helper\Session\CurrentCustomer;
Expand Down Expand Up @@ -287,53 +288,70 @@ protected function getOptionPrices()
{
$prices = [];
foreach ($this->getAllowProducts() as $product) {
$tierPrices = [];
$priceInfo = $product->getPriceInfo();
$tierPriceModel = $priceInfo->getPrice('tier_price');
$tierPricesList = $tierPriceModel->getTierPriceList();
foreach ($tierPricesList as $tierPrice) {
$tierPrices[] = [
'qty' => $this->localeFormat->getNumber($tierPrice['price_qty']),
'price' => $this->localeFormat->getNumber($tierPrice['price']->getValue()),
'percentage' => $this->localeFormat->getNumber(
$tierPriceModel->getSavePercent($tierPrice['price'])
),
];
}

$prices[$product->getId()] =
[
'baseOldPrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('regular_price')->getAmount()->getBaseAmount()
),
],
'oldPrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('regular_price')->getAmount()->getValue()
),
],
'basePrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('final_price')->getAmount()->getBaseAmount()
),
],
'finalPrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('final_price')->getAmount()->getValue()
),
],
'tierPrices' => $tierPrices,
'msrpPrice' => [
'amount' => $this->localeFormat->getNumber(
$this->priceCurrency->convertAndRound($product->getMsrp())
),
],
];
$prices[$product->getId()] = [
'baseOldPrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('regular_price')->getAmount()->getBaseAmount()
),
],
'oldPrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('regular_price')->getAmount()->getValue()
),
],
'basePrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('final_price')->getAmount()->getBaseAmount()
),
],
'finalPrice' => [
'amount' => $this->localeFormat->getNumber(
$priceInfo->getPrice('final_price')->getAmount()->getValue()
),
],
'tierPrices' => $this->getTierPricesByProduct($product),
'msrpPrice' => [
'amount' => $this->localeFormat->getNumber(
$this->priceCurrency->convertAndRound($product->getMsrp())
),
],
];
}

return $prices;
}

/**
* Returns product's tier prices list
*
* @param ProductInterface $product
* @return array
*/
private function getTierPricesByProduct(ProductInterface $product): array
{
$tierPrices = [];
$tierPriceModel = $product->getPriceInfo()->getPrice('tier_price');
foreach ($tierPriceModel->getTierPriceList() as $tierPrice) {
$tierPriceData = [
'qty' => $this->localeFormat->getNumber($tierPrice['price_qty']),
'price' => $this->localeFormat->getNumber($tierPrice['price']->getValue()),
'percentage' => $this->localeFormat->getNumber(
$tierPriceModel->getSavePercent($tierPrice['price'])
),
];

if (isset($tierPrice['excl_tax_price'])) {
$excludingTax = $tierPrice['excl_tax_price'];
$tierPriceData['excl_tax_price'] = $this->localeFormat->getNumber($excludingTax->getBaseAmount());
}
$tierPrices[] = $tierPriceData;
}

return $tierPrices;
}

/**
* Replace ',' on '.' for js
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="StorefrontAssertExcludingTierPriceActionGroup">
<annotations>
<description>Assert product item tier price excluding price.</description>
</annotations>
<arguments>
<argument name="excludingPrice" type="string"/>
</arguments>

<grabTextFrom selector="{{StorefrontProductInfoMainSection.tierPriceExcludingPrice}}" stepKey="tierPriceExcluding"/>
<assertStringContainsString stepKey="assertTierPriceTextOnProductPage">
<expectedResult type="string">{{excludingPrice}}</expectedResult>
<actualResult type="variable">tierPriceExcluding</actualResult>
</assertStringContainsString>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
<element name="stockIndication" type="block" selector=".stock" />
<element name="attributeSelectByAttributeID" type="select" selector="//div[@class='fieldset']//div[//span[text()='{{attribute_code}}']]//select" parameterized="true"/>
<element name="attributeOptionByAttributeID" type="select" selector="//div[@class='fieldset']//div[//span[text()='{{attribute_code}}']]//option[text()='{{optionName}}']" parameterized="true"/>
<element name="tierPriceExcludingPrice" type="text" selector=".item [data-label='Excl. Tax']"/>
</section>
</sections>
Loading