Merge pull request #4851 from devansh-webkul/tax-enhancement

Tax Enhancement #4463
This commit is contained in:
Glenn Hermans 2021-06-02 12:16:28 +02:00 committed by GitHub
commit 24b84ba05a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 654 additions and 236 deletions

View File

@ -388,7 +388,7 @@ return [
], [
'key' => 'emails',
'name' => 'admin::app.admin.emails.email',
'sort' => 5,
'sort' => 6,
], [
'key' => 'emails.configure',
'name' => 'admin::app.admin.system.email-settings',

View File

@ -362,9 +362,9 @@
<script type="text/x-template" id="state-template">
<div>
<input type="text" v-validate="'required'" v-if="!haveStates()" class="control" v-model="state" :id="name" :name="name" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;"/>
<input type="text" v-validate="validations" v-if="!haveStates()" class="control" v-model="state" :id="name" :name="name" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;"/>
<select v-validate="'required'" v-if="haveStates()" class="control" v-model="state" :id="name" :name="name" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;" >
<select v-validate="validations" v-if="haveStates()" class="control" v-model="state" :id="name" :name="name" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;" >
<option value="">{{ __('admin::app.customers.customers.select-state') }}</option>

View File

@ -665,63 +665,29 @@ class Cart
}
if ($address === null) {
$address = new class() {
public $country;
public $state;
public $postcode;
function __construct()
{
$this->country = strtoupper(config('app.default_country'));
}
};
$address = Tax::getDefaultAddress();
}
$taxRates = $taxCategory->tax_rates()->where([
'country' => $address->country,
])->orderBy('tax_rate', 'desc')->get();
$item = $this->setItemTaxToZero($item);
if ($taxRates->count()) {
foreach ($taxRates as $rate) {
$haveTaxRate = false;
Tax::isTaxApplicableInCurrentAddress($taxCategory, $address, function ($rate) use ($cart, $item) {
/* assigning tax percent */
$item->tax_percent = $rate->tax_rate;
if ($rate->state != '' && $rate->state != $address->state) {
continue;
}
/* getting shipping rate for tax calculation */
$shippingPrice = $shippingBasePrice = 0;
if (! $rate->is_zip) {
if (empty($rate->zip_code) || in_array($rate->zip_code, ['*', $address->postcode])) {
$haveTaxRate = true;
}
} else {
if ($address->postcode >= $rate->zip_from && $address->postcode <= $rate->zip_to) {
$haveTaxRate = true;
}
}
if ($haveTaxRate) {
$item->tax_percent = $rate->tax_rate;
/* getting shipping rate for tax calculation */
$shippingPrice = $shippingBasePrice = 0;
if ($shipping = $cart->selected_shipping_rate) {
if ($shipping->is_calculate_tax) {
$shippingPrice = $shipping->price - $shipping->discount_amount;
$shippingBasePrice = $shipping->base_price - $shipping->base_discount_amount;
}
}
/* now assigning shipping prices for tax calculation */
$item->tax_amount = round((($item->total + $shippingPrice) * $rate->tax_rate) / 100, 4);
$item->base_tax_amount = round((($item->base_total + $shippingBasePrice) * $rate->tax_rate) / 100, 4);
break;
if ($shipping = $cart->selected_shipping_rate) {
if ($shipping->is_calculate_tax) {
$shippingPrice = $shipping->price - $shipping->discount_amount;
$shippingBasePrice = $shipping->base_price - $shipping->base_discount_amount;
}
}
}
/* now assigning shipping prices for tax calculation */
$item->tax_amount = round((($item->total + $shippingPrice) * $rate->tax_rate) / 100, 4);
$item->base_tax_amount = round((($item->base_total + $shippingBasePrice) * $rate->tax_rate) / 100, 4);
});
$item->save();
}

View File

@ -2,15 +2,13 @@
namespace Webkul\Product\Helpers;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Facades\ProductImage;
use Webkul\Product\Facades\ProductVideo;
class ConfigurableOption extends AbstractProduct
{
/**
* Returns the allowed variants
* Returns the allowed variants.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
@ -33,9 +31,9 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Returns the allowed variants JSON
* Returns the allowed variants JSON.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @param \Webkul\Product\Models\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getConfigurationConfig($product)
@ -45,21 +43,17 @@ class ConfigurableOption extends AbstractProduct
$config = [
'attributes' => $this->getAttributesData($product, $options),
'index' => isset($options['index']) ? $options['index'] : [],
'regular_price' => [
'formated_price' => $product->getTypeInstance()->haveOffer() ? core()->currency($product->getTypeInstance()->getOfferPrice()) : core()->currency($product->getTypeInstance()->getMinimalPrice()),
'price' => $product->getTypeInstance()->haveOffer() ? $product->getTypeInstance()->getOfferPrice() : $product->getTypeInstance()->getMinimalPrice(),
],
'variant_prices' => $this->getVariantPrices($product),
'variant_images' => $this->getVariantImages($product),
'variant_videos' => $this->getVariantVideos($product),
'chooseText' => trans('shop::app.products.choose-option'),
];
return $config;
return array_merge($config, $product->getTypeInstance()->getProductPrices());
}
/**
* Get allowed attributes
* Get allowed attributes.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return \Illuminate\Support\Collection
@ -70,7 +64,7 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Get Configurable Product Options
* Get configurable product options.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $currentProduct
* @param array $allowedProducts
@ -108,7 +102,7 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Get product attributes
* Get product attributes.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @param array $options
@ -116,8 +110,6 @@ class ConfigurableOption extends AbstractProduct
*/
public function getAttributesData($product, array $options = [])
{
$defaultValues = [];
$attributes = [];
$allowAttributes = $this->getAllowAttributes($product);
@ -143,6 +135,8 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Get attribute options data.
*
* @param \Webkul\Attribute\Contracts\Attribute $attribute
* @param array $options
* @return array
@ -169,7 +163,7 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Get product prices for configurable variations
* Get product prices for configurable variations.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
@ -192,7 +186,7 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Get product images for configurable variations
* Get product images for configurable variations.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
@ -215,7 +209,7 @@ class ConfigurableOption extends AbstractProduct
}
/**
* Get product videos for configurable variations
* Get product videos for configurable variations.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
@ -236,4 +230,4 @@ class ConfigurableOption extends AbstractProduct
return $videos;
}
}
}

View File

@ -2,19 +2,21 @@
namespace Webkul\Product\Type;
use Webkul\Tax\Helpers\Tax;
use Webkul\Checkout\Facades\Cart;
use Webkul\Checkout\Models\CartItem;
use Illuminate\Support\Facades\Storage;
use Webkul\Product\Facades\ProductImage;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Tax\Repositories\TaxCategoryRepository;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Datatypes\CartItemValidationResult;
use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Repositories\ProductVideoRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
use Webkul\Inventory\Repositories\InventorySourceRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Inventory\Repositories\InventorySourceRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
@ -63,76 +65,79 @@ abstract class AbstractType
protected $productVideoRepository;
/**
* Product model instance
* Product instance
*
* @var \Webkul\Product\Contracts\Product
*/
protected $product;
/**
* Is a composite product type
* Is a composite product type.
*
* @var bool
*/
protected $isComposite = false;
/**
* Is a stokable product type
* Is a stockable product type.
*
* @var bool
*/
protected $isStockable = true;
/**
* Show quantity box
* Show quantity box.
*
* @var bool
*/
protected $showQuantityBox = false;
/**
* Allow multiple qty.
*
* @var bool
*/
protected $allowMultipleQty = true;
/**
* Is product have sufficient quantity
* Is product have sufficient quantity.
*
* @var bool
*/
protected $haveSufficientQuantity = true;
/**
* Product can be moved from wishlist to cart or not
* Product can be moved from wishlist to cart or not.
*
* @var bool
*/
protected $canBeMovedFromWishlistToCart = true;
/**
* Products of this type can be copied in the admin backend?
* Products of this type can be copied in the admin backend.
*
* @var bool
*/
protected $canBeCopied = true;
/**
* Has child products aka variants
* Has child products aka variants.
*
* @var bool
*/
protected $hasVariants = false;
/**
* Product children price can be calculated or not
* Product children price can be calculated or not.
*
* @var bool
*/
protected $isChildrenCalculated = false;
/**
* product options
* product options.
*
* @var array
*/
protected $productOptions = [];
@ -153,13 +158,12 @@ abstract class AbstractType
/**
* Create a new product type instance.
*
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
* @param \Webkul\Product\Repositories\ProductVideoRepository $productVideoRepository
*
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
* @param \Webkul\Product\Repositories\ProductVideoRepository $productVideoRepository
* @return void
*/
public function __construct(
@ -185,6 +189,8 @@ abstract class AbstractType
/**
* Is the administrator able to copy products of this type in the admin backend?
*
* @return bool
*/
public function canBeCopied(): bool
{
@ -192,8 +198,9 @@ abstract class AbstractType
}
/**
* @param array $data
* Create product.
*
* @param array $data
* @return \Webkul\Product\Contracts\Product
*/
public function create(array $data)
@ -202,10 +209,11 @@ abstract class AbstractType
}
/**
* @param array $data
* @param int $id
* @param string $attribute
* Update product.
*
* @param array $data
* @param int $id
* @param string $attribute
* @return \Webkul\Product\Contracts\Product
*/
public function update(array $data, $id, $attribute = "id")
@ -221,7 +229,7 @@ abstract class AbstractType
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
}
if (!isset($data[$attribute->code])) {
if (! isset($data[$attribute->code])) {
continue;
}
@ -250,7 +258,7 @@ abstract class AbstractType
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
]);
if (!$attributeValue) {
if (! $attributeValue) {
$this->attributeValueRepository->create([
'product_id' => $product->id,
'attribute_id' => $attribute->id,
@ -259,9 +267,11 @@ abstract class AbstractType
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
]);
} else {
$this->attributeValueRepository->update([
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code],
], $attributeValue->id
$this->attributeValueRepository->update(
[
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code],
],
$attributeValue->id
);
if ($attribute->type == 'image' || $attribute->type == 'file') {
@ -291,18 +301,19 @@ abstract class AbstractType
$this->productVideoRepository->uploadVideos($data, $product);
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data,
$product);
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices(
$data,
$product
);
}
return $product;
}
/**
* Specify type instance product
*
* @param \Webkul\Product\Contracts\Product $product
* Specify type instance product.
*
* @param \Webkul\Product\Contracts\Product $product
* @return \Webkul\Product\Type\AbstractType
*/
public function setProduct($product)
@ -313,7 +324,7 @@ abstract class AbstractType
}
/**
* Returns children ids
* Returns children ids.
*
* @return array
*/
@ -323,7 +334,7 @@ abstract class AbstractType
}
/**
* Check if catalog rule can be applied
* Check if catalog rule can be applied.
*
* @return bool
*/
@ -333,18 +344,20 @@ abstract class AbstractType
}
/**
* Return true if this product type is saleable
* Return true if this product type is saleable.
*
* @return bool
*/
public function isSaleable()
{
if (!$this->product->status) {
if (! $this->product->status) {
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
if (
is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false
) {
return false;
}
@ -352,7 +365,7 @@ abstract class AbstractType
}
/**
* Return true if this product can have inventory
* Return true if this product can have inventory.
*
* @return bool
*/
@ -362,7 +375,7 @@ abstract class AbstractType
}
/**
* Return true if this product can be composite
* Return true if this product can be composite.
*
* @return bool
*/
@ -372,7 +385,7 @@ abstract class AbstractType
}
/**
* Return true if this product can have variants
* Return true if this product can have variants.
*
* @return bool
*/
@ -382,7 +395,7 @@ abstract class AbstractType
}
/**
* Product children price can be calculated or not
* Product children price can be calculated or not.
*
* @return bool
*/
@ -392,8 +405,9 @@ abstract class AbstractType
}
/**
* @param int $qty
* Have sufficient quantity.
*
* @param int $qty
* @return bool
*/
public function haveSufficientQuantity(int $qty): bool
@ -402,7 +416,7 @@ abstract class AbstractType
}
/**
* Return true if this product can have inventory
* Return true if this product can have inventory.
*
* @return bool
*/
@ -412,7 +426,7 @@ abstract class AbstractType
}
/**
* Return true if more than one qty can be added to cart
* Return true if more than one qty can be added to cart.
*
* @return bool
*/
@ -422,8 +436,9 @@ abstract class AbstractType
}
/**
* @param \Webkul\Checkout\Contracts\CartItem $cartItem
* Is item have quantity.
*
* @param \Webkul\Checkout\Contracts\CartItem $cartItem
* @return bool
*/
public function isItemHaveQuantity($cartItem)
@ -432,6 +447,8 @@ abstract class AbstractType
}
/**
* Total quantity.
*
* @return int
*/
public function totalQuantity()
@ -459,10 +476,9 @@ abstract class AbstractType
}
/**
* Return true if item can be moved to cart from wishlist
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* Return true if item can be moved to cart from wishlist.
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return bool
*/
public function canBeMovedFromWishlistToCart($item)
@ -471,30 +487,33 @@ abstract class AbstractType
}
/**
* Retrieve product attributes
*
* @param \Webkul\Attribute\Contracts\Group $group
* @param bool $skipSuperAttribute
* Retrieve product attributes.
*
* @param \Webkul\Attribute\Contracts\Group $group
* @param bool $skipSuperAttribute
* @return \Illuminate\Support\Collection
*/
public function getEditableAttributes($group = null, $skipSuperAttribute = true)
{
if ($skipSuperAttribute) {
$this->skipAttributes = array_merge($this->product->super_attributes->pluck('code')->toArray(),
$this->skipAttributes);
$this->skipAttributes = array_merge(
$this->product->super_attributes->pluck('code')->toArray(),
$this->skipAttributes
);
}
if (!$group) {
return $this->product->attribute_family->custom_attributes()->whereNotIn('attributes.code',
$this->skipAttributes)->get();
if (! $group) {
return $this->product->attribute_family->custom_attributes()->whereNotIn(
'attributes.code',
$this->skipAttributes
)->get();
}
return $group->custom_attributes()->whereNotIn('code', $this->skipAttributes)->get();
}
/**
* Returns additional views
* Returns additional views.
*
* @return array
*/
@ -504,7 +523,7 @@ abstract class AbstractType
}
/**
* Returns validation rules
* Returns validation rules.
*
* @return array
*/
@ -514,10 +533,9 @@ abstract class AbstractType
}
/**
* Get product minimal price
*
* @param int $qty
* Get product minimal price.
*
* @param int $qty
* @return float
*/
public function getMinimalPrice($qty = null)
@ -530,7 +548,7 @@ abstract class AbstractType
}
/**
* Get product maximam price
* Get product maximum price.
*
* @return float
*/
@ -540,10 +558,9 @@ abstract class AbstractType
}
/**
* Get product minimal price
*
* @param int $qty
* Get product minimal price.
*
* @param int $qty
* @return float
*/
public function getFinalPrice($qty = null)
@ -552,10 +569,9 @@ abstract class AbstractType
}
/**
* Returns the product's minimal price
*
* @param int $qty
* Returns the product's minimal price.
*
* @param int $qty
* @return float
*/
public function getSpecialPrice($qty = null)
@ -564,8 +580,9 @@ abstract class AbstractType
}
/**
* @param int $qty
* Have special price.
*
* @param int $qty
* @return bool
*/
public function haveSpecialPrice($qty = null)
@ -597,8 +614,10 @@ abstract class AbstractType
$haveSpecialPrice = true;
} else {
if (core()->isChannelDateInInterval($this->product->special_price_from,
$this->product->special_price_to)) {
if (core()->isChannelDateInInterval(
$this->product->special_price_from,
$this->product->special_price_to
)) {
$haveSpecialPrice = true;
} elseif ($rulePrice) {
$this->product->special_price = $rulePrice->price;
@ -621,7 +640,7 @@ abstract class AbstractType
}
/**
* Get product group price
* Get product group price.
*
* @return float
*/
@ -645,7 +664,7 @@ abstract class AbstractType
$customerGroupPrices = app(ProductCustomerGroupPriceRepository::class)->checkInLoadedCustomerGroupPrice($product, $customerGroupId);
if (!$customerGroupPrices->count()) {
if (! $customerGroupPrices->count()) {
return $product->price;
}
@ -668,7 +687,8 @@ abstract class AbstractType
continue;
}
if ($price->qty == $lastQty
if (
$price->qty == $lastQty
&& $lastCustomerGroupId != null
&& $price->customer_group_id == null
) {
@ -698,7 +718,7 @@ abstract class AbstractType
}
/**
* Returns product prices
* Get product prices.
*
* @return array
*/
@ -706,18 +726,18 @@ abstract class AbstractType
{
return [
'regular_price' => [
'price' => core()->convertPrice($this->product->price),
'formated_price' => core()->currency($this->product->price),
'price' => core()->convertPrice($this->evaluatePrice($this->product->price)),
'formated_price' => core()->currency($this->evaluatePrice($this->product->price)),
],
'final_price' => [
'price' => core()->convertPrice($this->getMinimalPrice()),
'formated_price' => core()->currency($this->getMinimalPrice()),
'price' => core()->convertPrice($this->evaluatePrice($this->getMinimalPrice())),
'formated_price' => core()->currency($this->evaluatePrice($this->getMinimalPrice())),
],
];
}
/**
* Get product minimal price
* Get product price html.
*
* @return string
*/
@ -725,19 +745,71 @@ abstract class AbstractType
{
if ($this->haveSpecialPrice()) {
$html = '<div class="sticker sale">' . trans('shop::app.products.sale') . '</div>'
. '<span class="regular-price">' . core()->currency($this->product->price) . '</span>'
. '<span class="special-price">' . core()->currency($this->getSpecialPrice()) . '</span>';
. '<span class="regular-price">' . core()->currency($this->evaluatePrice($this->product->price)) . '</span>'
. '<span class="special-price">' . core()->currency($this->evaluatePrice($this->getSpecialPrice())) . '</span>';
} else {
$html = '<span>' . core()->currency($this->product->price) . '</span>';
$html = '<span>' . core()->currency($this->evaluatePrice($this->product->price)) . '</span>';
}
return $html;
}
/**
* Get inclusive tax rates.
*
* @param float $totalPrice
* @return float
*/
public function getTaxInclusiveRate($totalPrice)
{
/* this is added for future purpose like if shipping tax also added then case is needed */
$address = null;
if ($taxCategory = $this->getTaxCategory()) {
if ($address === null && auth()->guard('customer')->check()) {
$address = auth()->guard('customer')->user()->addresses()->where('default_address', 1)->first();
}
if ($address === null) {
$address = Tax::getDefaultAddress();
}
Tax::isTaxApplicableInCurrentAddress($taxCategory, $address, function ($rate) use (&$totalPrice) {
$totalPrice = round($totalPrice, 4) + round(($totalPrice * $rate->tax_rate) / 100, 4);
});
}
return $totalPrice;
}
/**
* Get tax category.
*
* @return \Webkul\Tax\Models\TaxCategory
*/
public function getTaxCategory()
{
$taxCategoryId = $this->product->parent ? $this->product->parent->tax_category_id : $this->product->tax_category_id;
return app(TaxCategoryRepository::class)->find($taxCategoryId);
}
/**
* Evaluate price.
*
* @return array
*/
public function evaluatePrice($price)
{
return Tax::isTaxInclusive()
? $this->getTaxInclusiveRate($price)
: $price;
}
/**
* Add product. Returns error message if can't prepare product.
*
* @param array $data
* @param array $data
*
* @return array
*/
@ -775,10 +847,9 @@ abstract class AbstractType
}
/**
* Get request quantity
*
* @param array $data
* Get request quantity.
*
* @param array $data
* @return array
*/
public function getQtyRequest($data)
@ -791,10 +862,10 @@ abstract class AbstractType
}
/**
* Compare options.
*
* @param array $options1
* @param array $options2
*
* @param array $options1
* @param array $options2
* @return bool
*/
public function compareOptions($options1, $options2)
@ -808,9 +879,9 @@ abstract class AbstractType
} else {
return false;
}
} elseif (isset($options1['parent_id']) && !isset($options2['parent_id'])) {
} elseif (isset($options1['parent_id']) && ! isset($options2['parent_id'])) {
return false;
} elseif (isset($options2['parent_id']) && !isset($options1['parent_id'])) {
} elseif (isset($options2['parent_id']) && ! isset($options1['parent_id'])) {
return false;
}
}
@ -819,10 +890,9 @@ abstract class AbstractType
}
/**
* Returns additional information for items
*
* @param array $data
* Returns additional information for items.
*
* @param array $data
* @return array
*/
public function getAdditionalOptions($data)
@ -831,10 +901,9 @@ abstract class AbstractType
}
/**
* Get actual ordered item
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* Get actual ordered item.
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return \Webkul\Checkout\Contracts\CartItem|\Webkul\Sales\Contracts\OrderItem|\Webkul\Sales\Contracts\InvoiceItem|\Webkul\Sales\Contracts\ShipmentItem|\Webkul\Customer\Contracts\Wishlist
*/
public function getOrderedItem($item)
@ -843,10 +912,9 @@ abstract class AbstractType
}
/**
* Get product base image
*
* @param \Webkul\Customer\Contracts\CartItem|\Webkul\Checkout\Contracts\CartItem $item
* Get product base image.
*
* @param \Webkul\Customer\Contracts\CartItem|\Webkul\Checkout\Contracts\CartItem $item
* @return array
*/
public function getBaseImage($item)
@ -855,10 +923,9 @@ abstract class AbstractType
}
/**
* Validate cart item product price and other things
*
* @param \Webkul\Checkout\Models\CartItem $item
* Validate cart item product price and other things.
*
* @param \Webkul\Checkout\Models\CartItem $item
* @return \Webkul\Product\Datatypes\CartItemValidationResult
*/
public function validateCartItem(CartItem $item): CartItemValidationResult
@ -888,17 +955,20 @@ abstract class AbstractType
return $result;
}
//get product options
/**
* Get product options.
*
* @return array
*/
public function getProductOptions()
{
return $this->productOptions;
}
/**
* Returns true, if cart item is inactive
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* Returns true, if cart item is inactive.
*
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return bool
*/
public function isCartItemInactive(\Webkul\Checkout\Contracts\CartItem $item): bool
@ -931,7 +1001,8 @@ abstract class AbstractType
*
* @return array
*/
public function getCustomerGroupPricingOffers() {
public function getCustomerGroupPricingOffers()
{
$offerLines = [];
$haveOffers = true;
$customerGroupId = null;
@ -946,10 +1017,11 @@ abstract class AbstractType
}
}
$customerGroupPrices = $this->product->customer_group_prices()->where(function ($query) use ($customerGroupId) {
$query->where('customer_group_id', $customerGroupId)
->orWhereNull('customer_group_id');
}
$customerGroupPrices = $this->product->customer_group_prices()->where(
function ($query) use ($customerGroupId) {
$query->where('customer_group_id', $customerGroupId)
->orWhereNull('customer_group_id');
}
)->groupBy('qty')->get()->sortBy('qty')->values()->all();
if ($this->haveSpecialPrice()) {
@ -980,17 +1052,20 @@ abstract class AbstractType
/**
* Get offers lines.
*
* @param array $customerGroupPrice
* @param array $customerGroupPrice
*
* @return array
*/
public function getOfferLines($customerGroupPrice) {
public function getOfferLines($customerGroupPrice)
{
$price = $this->getCustomerGroupPrice($this->product, $customerGroupPrice->qty);
$discount = number_format((($this->product->price - $price) * 100) / ($this->product->price), 2);
$offerLines = trans('shop::app.products.offers', ['qty' => $customerGroupPrice->qty,
'price' => core()->currency($price), 'discount' => $discount]);
$offerLines = trans('shop::app.products.offers', [
'qty' => $customerGroupPrice->qty,
'price' => core()->currency($price), 'discount' => $discount
]);
return $offerLines;
}
@ -1010,4 +1085,4 @@ abstract class AbstractType
return $loadedSaleableChecks[$product->id] = $callback($product);
}
}
}

View File

@ -2,17 +2,17 @@
namespace Webkul\Product\Type;
use Webkul\Checkout\Models\CartItem;
use Webkul\Product\Helpers\BundleOption;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Datatypes\CartItemValidationResult;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Repositories\ProductVideoRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductBundleOptionRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductBundleOptionProductRepository;
use Webkul\Product\Helpers\BundleOption;
use Webkul\Checkout\Models\CartItem;
class Bundle extends AbstractType
{
@ -363,23 +363,23 @@ class Bundle extends AbstractType
return [
'from' => [
'regular_price' => [
'price' => core()->convertPrice($this->getRegularMinimalPrice()),
'formated_price' => core()->currency($this->getRegularMinimalPrice()),
'price' => core()->convertPrice($this->evaluatePrice($this->getRegularMinimalPrice())),
'formated_price' => core()->currency($this->evaluatePrice($this->getRegularMinimalPrice())),
],
'final_price' => [
'price' => core()->convertPrice($this->getMinimalPrice()),
'formated_price' => core()->currency($this->getMinimalPrice()),
'price' => core()->convertPrice($this->evaluatePrice($this->getMinimalPrice())),
'formated_price' => core()->currency($this->evaluatePrice($this->getMinimalPrice())),
]
],
'to' => [
'regular_price' => [
'price' => core()->convertPrice($this->getRegularMaximamPrice()),
'formated_price' => core()->currency($this->getRegularMaximamPrice()),
'price' => core()->convertPrice($this->evaluatePrice($this->getRegularMaximamPrice())),
'formated_price' => core()->currency($this->evaluatePrice($this->getRegularMaximamPrice())),
],
'final_price' => [
'price' => core()->convertPrice($this->getMaximamPrice()),
'formated_price' => core()->currency($this->getMaximamPrice()),
'price' => core()->convertPrice($this->evaluatePrice($this->getMaximamPrice())),
'formated_price' => core()->currency($this->evaluatePrice($this->getMaximamPrice())),
]
]
];

View File

@ -491,6 +491,25 @@ class Configurable extends AbstractType
return $productFlat ? $productFlat->max_price : 0;
}
/**
* Get product prices.
*
* @return array
*/
public function getProductPrices()
{
return [
'regular_price' => [
'formated_price' => $this->haveOffer()
? core()->currency($this->evaluatePrice($this->getOfferPrice()))
: core()->currency($this->evaluatePrice($this->getMinimalPrice())),
'price' => $this->haveOffer()
? $this->evaluatePrice($this->getOfferPrice())
: $this->evaluatePrice($this->getMinimalPrice()),
]
];
}
/**
* Get product minimal price.
*
@ -501,12 +520,12 @@ class Configurable extends AbstractType
if ($this->haveOffer()) {
return '<div class="sticker sale">' . trans('shop::app.products.sale') . '</div>'
. '<span class="price-label">' . trans('shop::app.products.price-label') . '</span>'
. '<span class="regular-price">' . core()->currency($this->getMinimalPrice()) . '</span>'
. '<span class="final-price">' . core()->currency($this->getOfferPrice()) . '</span>';
. '<span class="regular-price">' . core()->currency($this->evaluatePrice($this->getMinimalPrice())) . '</span>'
. '<span class="final-price">' . core()->currency($this->evaluatePrice($this->getOfferPrice())) . '</span>';
} else {
return '<span class="price-label">' . trans('shop::app.products.price-label') . '</span>'
. ' '
. '<span class="final-price">' . core()->currency($this->getMinimalPrice()) . '</span>';
. '<span class="final-price">' . core()->currency($this->evaluatePrice($this->getMinimalPrice())) . '</span>';
}
}

View File

@ -121,7 +121,7 @@ class Grouped extends AbstractType
}
/**
* Get product minimal price
* Get product minimal price.
*
* @return float
*/
@ -130,14 +130,14 @@ class Grouped extends AbstractType
$minPrices = [];
foreach ($this->product->grouped_products as $groupOptionProduct) {
$minPrices[] = $groupOptionProduct->associated_product->getTypeInstance()->getMinimalPrice();
$groupOptionProductTypeInstance = $groupOptionProduct->associated_product->getTypeInstance();
$groupOptionProductMinimalPrice = $groupOptionProductTypeInstance->getMinimalPrice();
$minPrices[] = $groupOptionProductTypeInstance->evaluatePrice($groupOptionProductMinimalPrice);
}
if (empty($minPrices)) {
return 0;
}
return min($minPrices);
return empty($minPrices) ? 0 : min($minPrices);
}
/**
@ -182,8 +182,9 @@ class Grouped extends AbstractType
{
$html = '';
if ($this->checkGroupProductHaveSpecialPrice())
if ($this->checkGroupProductHaveSpecialPrice()) {
$html .= '<div class="sticker sale">' . trans('shop::app.products.sale') . '</div>';
}
$html .= '<span class="price-label">' . trans('shop::app.products.starting-at') . '</span>'
. ' '

View File

@ -448,6 +448,7 @@ return [
'compare_options' => 'قارن الخيارات',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -449,6 +449,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes'
],
// 'reviews' => [

View File

@ -448,6 +448,7 @@ return [
'compare_options' => 'Comparar Optiones',
'wishlist-options' => 'Opciones de Lista de Deseos',
'offers' => 'Compre :qty por :price cada uno y ahorre :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -444,6 +444,7 @@ return [
'compare_options' => 'قابلیت مقایشه محصولات',
'wishlist-options' => 'قابلیت لیست علاقه مندیها',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -445,6 +445,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -414,6 +414,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
'buynow' => [

View File

@ -452,6 +452,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -445,6 +445,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -435,6 +435,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -445,6 +445,7 @@ return [
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options',
'offers' => 'Buy :qty for :price each and save :discount%',
'tax-inclusive' => 'Inclusive of all taxes',
],
// 'reviews' => [

View File

@ -25,7 +25,11 @@
{!! view_render_event('bagisto.shop.checkout.cart-mini.subtotal.before', ['cart' => $cart]) !!}
<b>{{ core()->currency($cart->base_sub_total) }}</b>
@if (Webkul\Tax\Helpers\Tax::isTaxInclusive())
<b>{{ core()->currency($cart->base_grand_total) }}</b>
@else
<b>{{ core()->currency($cart->base_sub_total) }}</b>
@endif
{!! view_render_event('bagisto.shop.checkout.cart-mini.subtotal.after', ['cart' => $cart]) !!}
</p>
@ -67,7 +71,13 @@
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.price.before', ['item' => $item]) !!}
<div class="item-price"><b>{{ core()->currency($item->base_total) }}</b></div>
<div class="item-price">
@if (Webkul\Tax\Helpers\Tax::isTaxInclusive())
<b>{{ core()->currency($item->base_total + $item->tax_amount) }}</b>
@else
<b>{{ core()->currency($item->base_total) }}</b>
@endif
</div>
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.price.after', ['item' => $item]) !!}

View File

@ -63,6 +63,12 @@
@include ('shop::products.price', ['product' => $product])
@if (Webkul\Tax\Helpers\Tax::isTaxInclusive() && $product->getTypeInstance()->getTaxCategory())
<div>
{{ __('shop::app.products.tax-inclusive') }}
</div>
@endif
@if (count($product->getTypeInstance()->getCustomerGroupPricingOffers()) > 0)
<div class="regular-price">
@foreach ($product->getTypeInstance()->getCustomerGroupPricingOffers() as $offers)

View File

@ -0,0 +1,50 @@
<?php
return [
[
'key' => 'taxes',
'name' => 'tax::app.admin.system.taxes.taxes',
'sort' => 6,
], [
'key' => 'taxes.catalogue',
'name' => 'tax::app.admin.system.taxes.catalogue',
'sort' => 1,
], [
'key' => 'taxes.catalogue.pricing',
'name' => 'tax::app.admin.system.taxes.pricing',
'sort' => 1,
'fields' => [
[
'name' => 'tax_inclusive',
'title' => 'tax::app.admin.system.taxes.tax-inclusive',
'type' => 'boolean',
'validation' => 'required',
'default' => false
]
],
], [
'key' => 'taxes.catalogue.default-location-calculation',
'name' => 'tax::app.admin.system.taxes.default-location-calculation',
'sort' => 1,
'fields' => [
[
'name' => 'country',
'title' => 'tax::app.admin.system.taxes.default-country',
'type' => 'country',
'default' => '',
],
[
'name' => 'state',
'title' => 'tax::app.admin.system.taxes.default-state',
'type' => 'state',
'default' => '',
],
[
'name' => 'post_code',
'title' => 'tax::app.admin.system.taxes.default-post-code',
'type' => 'text',
'default' => '',
]
],
]
];

View File

@ -2,20 +2,42 @@
namespace Webkul\Tax\Helpers;
/**
* Tax class.
*
* To Do (@devansh-webkul): Convert this to facade.
*/
class Tax
{
/**
* Tax rate precission.
*
* @var int
*/
private const TAX_RATE_PRECISION = 4;
/**
* Tax amount precision.
*
* @var int
*/
private const TAX_AMOUNT_PRECISION = 2;
/**
* Returns an array with tax rates and tax amount
* Is tax inclusive enabled in backend.
*
* @param object $that
* @param bool $asBase
* @return bool
*/
public static function isTaxInclusive(): bool
{
return (bool) core()->getConfigData('taxes.catalogue.pricing.tax_inclusive');
}
/**
* Returns an array with tax rates and tax amount.
*
* @param object $that
* @param bool $asBase
* @return array
*/
public static function getTaxRatesWithAmount(object $that, bool $asBase = false): array
@ -25,14 +47,14 @@ class Tax
foreach ($that->items as $item) {
$taxRate = (string) round((float) $item->tax_percent, self::TAX_RATE_PRECISION);
if (! array_key_exists($taxRate, $taxes)) {
if (!array_key_exists($taxRate, $taxes)) {
$taxes[$taxRate] = 0;
}
$taxes[$taxRate] += $asBase ? $item->base_tax_amount : $item->tax_amount;
}
// finally round tax amounts now (to reduce rounding differences)
/* finally round tax amounts now (to reduce rounding differences) */
foreach ($taxes as $taxRate => $taxAmount) {
$taxes[$taxRate] = round($taxAmount, self::TAX_AMOUNT_PRECISION);
}
@ -41,7 +63,7 @@ class Tax
}
/**
* Returns the total tax amount
* Returns the total tax amount.
*
* @param object $that
* @param bool $asBase
@ -60,4 +82,69 @@ class Tax
return $result;
}
}
/**
* Get default address from core config.
*
* @return object
*/
public static function getDefaultAddress()
{
return new class()
{
public $country;
public $state;
public $postcode;
function __construct()
{
$this->country = core()->getConfigData('taxes.catalogue.default-location-calculation.country') != ''
? core()->getConfigData('taxes.catalogue.default-location-calculation.country')
: strtoupper(config('app.default_country'));
$this->state = core()->getConfigData('taxes.catalogue.default-location-calculation.state');
$this->postcode = core()->getConfigData('taxes.catalogue.default-location-calculation.post_code');
}
};
}
/**
* This method will check tax for the current address. If applicable then
* custom operation can be done.
*
* @param object $address
* @param object $taxCategory
* @param \Closure $operation
* @return void
*/
public static function isTaxApplicableInCurrentAddress($taxCategory, $address, $operation)
{
$taxRates = $taxCategory->tax_rates()->where([
'country' => $address->country,
])->orderBy('tax_rate', 'desc')->get();
if ($taxRates->count()) {
foreach ($taxRates as $rate) {
$haveTaxRate = false;
if ($rate->state != '' && $rate->state != $address->state) {
continue;
}
if (!$rate->is_zip) {
if (empty($rate->zip_code) || in_array($rate->zip_code, ['*', $address->postcode])) {
$haveTaxRate = true;
}
} else {
if ($address->postcode >= $rate->zip_from && $address->postcode <= $rate->zip_to) {
$haveTaxRate = true;
}
}
if ($haveTaxRate) {
$operation($rate);
break;
}
}
}
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace Webkul\Tax\Providers;
use Illuminate\Support\ServiceProvider;
@ -13,6 +14,8 @@ class TaxServiceProvider extends ServiceProvider
public function boot()
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->loadFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'tax');
}
/**
@ -22,6 +25,8 @@ class TaxServiceProvider extends ServiceProvider
*/
public function register()
{
$this->loadFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php', 'core'
);
}
}
}

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -0,0 +1,18 @@
<?php
return [
'admin' => [
'system' => [
'taxes' => [
'taxes' => 'Taxes',
'catalogue' => 'Catalog',
'pricing' => 'Pricing',
'tax-inclusive' => 'Tax inclusive',
'default-location-calculation' => 'Default Location Calculation',
'default-country' => 'Default Country',
'default-state' => 'Default State',
'default-post-code' => 'Default Post Code',
],
]
]
];

View File

@ -1,6 +0,0 @@
<?php
return [
'name' => 'Webkul Bagisto Tax',
'version' => '0.0.1'
];

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
{
"/js/velocity.js": "/js/velocity.js?id=9fea883b6fe31af43cdb",
"/js/velocity.js": "/js/velocity.js?id=341420aba8081021120d",
"/css/velocity-admin.css": "/css/velocity-admin.css?id=4322502d80a0e4a0affd",
"/css/velocity.css": "/css/velocity.css?id=15d6426e21921c345c7b"
}

View File

@ -24,6 +24,7 @@ class CartController extends Controller
$cartItems = $items->toArray();
$cartDetails = [];
$cartDetails['base_grand_total'] = core()->currency($cart->base_grand_total);
$cartDetails['base_sub_total'] = core()->currency($cart->base_sub_total);
/* needed raw data for comparison */
@ -35,6 +36,7 @@ class CartController extends Controller
$cartItems[$index]['images'] = $images;
$cartItems[$index]['url_key'] = $item->product->url_key;
$cartItems[$index]['base_total'] = core()->currency($item->base_total);
$cartItems[$index]['base_total_with_tax'] = core()->currency($item->base_total + $item->tax_amount);
}
$response = [

View File

@ -31,7 +31,7 @@
<input type="text" disabled :value="item.quantity" class="ml5" />
</div>
<span class="card-total-price fw6">
{{ item.base_total }}
{{ isTaxInclusive == '1' ? item.base_total_with_tax : item.base_total }}
</span>
</div>
</div>
@ -44,7 +44,7 @@
{{ subtotalText }}
</h5>
<h5 class="col-6 text-right fw6 no-padding">{{ cartInformation.base_sub_total }}</h5>
<h5 class="col-6 text-right fw6 no-padding">{{ isTaxInclusive == '1' ? cartInformation.base_grand_total : cartInformation.base_sub_total }}</h5>
</div>
<div class="modal-footer">
@ -73,6 +73,7 @@
<script>
export default {
props: [
'isTaxInclusive',
'cartText',
'viewCart',
'checkoutUrl',

View File

@ -264,6 +264,7 @@ return [
'short-description' => 'أوصاف قصيرة',
'recently-viewed' => 'المنتجات المعروضة مؤخرا',
'be-first-review' => 'كن أول من يكتب نقد',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -264,6 +264,7 @@ return [
'short-description' => 'Kurze Beschreibungen',
'recently-viewed' => 'Kürzlich angesehene Produkte',
'be-first-review' => 'Sei der erste der eine Bewertung schreibt',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -264,6 +264,7 @@ return [
'short-description' => 'Short Descriptions',
'recently-viewed' => 'Recently Viewed Products',
'be-first-review' => 'Be the first to write a review',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -264,6 +264,7 @@ return [
'short-description' => 'Descripción Breve',
'recently-viewed' => 'Productos Vistos Recientemente',
'be-first-review' => 'Sé el primero en escribir una reseña',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -263,6 +263,7 @@ return [
'short-description' => 'توضیحات کوتاه',
'recently-viewed' => 'محصولات اخیرا مشاهده شده',
'be-first-review' => 'اولین نفری باشید که نظر می دهد',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -266,6 +266,7 @@ return [
'short-description' => 'Descrizioni Brevi',
'recently-viewed' => 'Prodotti visti di recente',
'be-first-review' => 'Sii il primo a scrivere una review',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -265,6 +265,7 @@ return [
'short-description' => '短い説明',
'recently-viewed' => '最近見た製品',
'be-first-review' => '最初のレビューを書く',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -264,6 +264,7 @@ return [
'short-description' => 'Korte omschrijving',
'recently-viewed' => 'Recent bekeken producten',
'be-first-review' => 'Wees de eerste om een review te schrijven.',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -262,6 +262,7 @@ return [
'short-description' => 'Krótkie opisy',
'recently-viewed' => 'Ostatnio oglądane produkty',
'be-first-review' => 'Bądź pierwszym, który napisze recenzję',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -266,6 +266,7 @@ return [
'view-all-reviews' => 'Ver todos os comentários',
'recently-viewed' => 'Produtos vistos recentemente',
'be-first-review' => 'Seja o primeiro a escrever um comentário',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -262,6 +262,7 @@ return [
'short-description' => 'Kısa Açıklamalar',
'recently-viewed' => 'En Son Gezdiğiniz Ürünler',
'be-first-review' => 'Bu ürüne ilk siz inceleme girin!',
'tax-inclusive' => 'Inclusive of all taxes',
],
'shop' => [

View File

@ -1,5 +1,6 @@
<div class="mini-cart-container">
<mini-cart
is-tax-inclusive="{{ Webkul\Tax\Helpers\Tax::isTaxInclusive() }}"
view-cart="{{ route('shop.checkout.cart.index') }}"
cart-text="{{ __('shop::app.minicart.view-cart') }}"
checkout-text="{{ __('shop::app.minicart.checkout') }}"

View File

@ -125,6 +125,12 @@
<div class="col-12 price">
@include ('shop::products.price', ['product' => $product])
@if (Webkul\Tax\Helpers\Tax::isTaxInclusive() && $product->getTypeInstance()->getTaxCategory())
<span>
{{ __('velocity::app.products.tax-inclusive') }}
</span>
@endif
</div>
@if (count($product->getTypeInstance()->getCustomerGroupPricingOffers()) > 0)