Skip to content

Instantly share code, notes, and snippets.

@vvasiloi
Last active July 18, 2022 12:34
Show Gist options
  • Save vvasiloi/a381b4313d672abf4492cdbd1b36fb9d to your computer and use it in GitHub Desktop.
Save vvasiloi/a381b4313d672abf4492cdbd1b36fb9d to your computer and use it in GitHub Desktop.
Get product price with and without tax in Sylius
{# templates/bundles/SyliusShopBundle/Common/Macro/money.html.twig #}
{%- macro format(amount, currency_code) -%}
{{ amount|sylius_format_money(currency_code, sylius.localeCode) }}
{%- endmacro -%}
{%- macro convertAndFormat(amount) -%}
{% from _self import format %}
{{- format(amount|sylius_convert_money(sylius.channel.baseCurrency.code, sylius.currencyCode), sylius.currencyCode) }}
{%- endmacro -%}
{%- macro calculatePrice(variant) -%}
{% from _self import convertAndFormat %}
{{- convertAndFormat(variant|sylius_calculate_price({'channel': sylius.channel})) }}
{%- endmacro -%}
{%- macro calculatePriceWithTax(variant, context) -%}
{% from _self import convertAndFormat %}
{{- convertAndFormat(variant|sylius_calculate_price_with_tax(context)) }}
{%- endmacro -%}
{%- macro calculatePriceWithoutTax(variant, context) -%}
{% from _self import convertAndFormat %}
{{- convertAndFormat(variant|sylius_calculate_price_without_tax(context)) }}
{%- endmacro -%}
<?php
declare(strict_types=1);
namespace App\Twig;
use App\Product\ProductVariantPriceWithoutTaxCalculator;
use App\Product\ProductVariantPriceWithTaxCalculator;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
final class PriceExtension extends AbstractExtension
{
/**
* @var ProductVariantPriceWithTaxCalculator
*/
private $priceWithTaxCalculator;
/**
* @var ProductVariantPriceWithoutTaxCalculator
*/
private $priceWithoutTaxCalculator;
public function __construct(
ProductVariantPriceWithTaxCalculator $priceWithTaxCalculator,
ProductVariantPriceWithoutTaxCalculator $priceWithoutTaxCalculator
) {
$this->priceWithTaxCalculator = $priceWithTaxCalculator;
$this->priceWithoutTaxCalculator = $priceWithoutTaxCalculator;
}
public function getFilters(): iterable
{
return [
new TwigFilter('sylius_calculate_price_with_tax', [$this, 'calculatePriceWithTax']),
new TwigFilter('sylius_calculate_price_without_tax', [$this, 'calculatePriceWithoutTax']),
];
}
/**
* @param ProductVariantInterface $productVariant
* @param array $context
* @return int
*/
public function calculatePriceWithTax(ProductVariantInterface $productVariant, array $context = []): int
{
return $this->priceWithTaxCalculator->calculate($productVariant, $context);
}
/**
* @param ProductVariantInterface $productVariant
* @param array $context
* @return int
*/
public function calculatePriceWithoutTax(ProductVariantInterface $productVariant, array $context = []): int
{
return $this->priceWithoutTaxCalculator->calculate($productVariant, $context);
}
}
<?php
declare(strict_types=1);
namespace App\Product;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Taxation\Calculator\CalculatorInterface;
use Sylius\Component\Taxation\Resolver\TaxRateResolverInterface;
final class ProductVariantPriceWithoutTaxCalculator implements ProductVariantPriceCalculatorInterface
{
/**
* @var ChannelContextInterface
*/
private $channelContext;
/**
* @var ProductVariantPriceCalculatorInterface
*/
private $productVariantPriceCalculator;
/**
* @var CalculatorInterface
*/
private $taxCalculator;
/**
* @var TaxRateResolverInterface
*/
private $taxRateResolver;
public function __construct(
ChannelContextInterface $channelContext,
ProductVariantPriceCalculatorInterface $productVariantPriceCalculator,
CalculatorInterface $taxCalculator,
TaxRateResolverInterface $taxRateResolver
) {
$this->channelContext = $channelContext; // sylius.context.channel service
$this->productVariantPriceCalculator = $productVariantPriceCalculator; // sylius.calculator.product_variant_price
$this->taxCalculator = $taxCalculator; // sylius.tax_calculator
$this->taxRateResolver = $taxRateResolver; // sylius.tax_rate_resolver
}
public function calculate(ProductVariantInterface $productVariant, array $context): int
{
/** @var ChannelInterface $channel */
$channel = $context['channel'] ?? $this->channelContext->getChannel();
$zone = $context['zone'] ?? $channel->getDefaultTaxZone();
$price = $this->productVariantPriceCalculator->calculate($productVariant, ['channel' => $channel]);
$taxRate = $this->taxRateResolver->resolve($productVariant, ['zone' => $zone]);
$totalTaxAmount = $this->taxCalculator->calculate($price, $taxRate);
if ($taxRate->isIncludedInPrice()) {
return $price - $totalTaxAmount;
}
return $price;
}
}
<?php
declare(strict_types=1);
namespace App\Product;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Taxation\Calculator\CalculatorInterface;
use Sylius\Component\Taxation\Resolver\TaxRateResolverInterface;
final class ProductVariantPriceWithTaxCalculator implements ProductVariantPriceCalculatorInterface
{
/**
* @var ChannelContextInterface
*/
private $channelContext;
/**
* @var ProductVariantPriceCalculatorInterface
*/
private $productVariantPriceCalculator;
/**
* @var CalculatorInterface
*/
private $taxCalculator;
/**
* @var TaxRateResolverInterface
*/
private $taxRateResolver;
public function __construct(
ChannelContextInterface $channelContext,
ProductVariantPriceCalculatorInterface $productVariantPriceCalculator,
CalculatorInterface $taxCalculator,
TaxRateResolverInterface $taxRateResolver
) {
$this->channelContext = $channelContext; // sylius.context.channel service
$this->productVariantPriceCalculator = $productVariantPriceCalculator; // sylius.calculator.product_variant_price
$this->taxCalculator = $taxCalculator; // sylius.tax_calculator
$this->taxRateResolver = $taxRateResolver; // sylius.tax_rate_resolver
}
public function calculate(ProductVariantInterface $productVariant, array $context): int
{
/** @var ChannelInterface $channel */
$channel = $context['channel'] ?? $this->channelContext->getChannel();
$zone = $context['zone'] ?? $channel->getDefaultTaxZone();
$price = $this->productVariantPriceCalculator->calculate($productVariant, ['channel' => $channel]);
$taxRate = $this->taxRateResolver->resolve($productVariant, ['zone' => $zone]);
$totalTaxAmount = $this->taxCalculator->calculate($price, $taxRate);
if ($taxRate->isIncludedInPrice()) {
return $price;
}
return $price + $totalTaxAmount;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment