diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php
index 4751bc50c..3836352aa 100755
--- a/packages/Webkul/Admin/src/Resources/lang/en/app.php
+++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php
@@ -528,7 +528,12 @@ return [
'checkbox' => 'Checkbox',
'multiselect' => 'Multiselect',
'new-option' => 'New Option',
- 'is-default' => 'Is Default'
+ 'is-default' => 'Is Default',
+ 'customer-group' => 'Customer Group',
+ 'add-group-price' => 'Add Customer Group Price',
+ 'all-group' => 'All Groups',
+ 'fixed' => 'Fixed',
+ 'discount' => 'Discount',
],
'attributes' => [
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/customer-group-price.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/customer-group-price.blade.php
new file mode 100644
index 000000000..a8295f37d
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/customer-group-price.blade.php
@@ -0,0 +1,162 @@
+@section('css')
+ @parent
+
+@stop
+
+{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.customer_group_prices.before', ['product' => $product]) !!}
+
+
+
+{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.customer_group_prices.after', ['product' => $product]) !!}
+
+@push('scripts')
+ @parent
+
+
+
+
+
+
+@endpush
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php
index c1cfcf2e1..ec4ca4e69 100755
--- a/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php
@@ -144,6 +144,12 @@
@endforeach
+ @if ($attributeGroup->name == 'Price')
+
+ @include ('admin::catalog.products.accordians.customer-group-price')
+
+ @endif
+
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.' . $attributeGroup->name . '.controls.after', ['product' => $product]) !!}
diff --git a/packages/Webkul/BookingProduct/src/Helpers/Booking.php b/packages/Webkul/BookingProduct/src/Helpers/Booking.php
index ebdcf73d5..0e944cc6b 100644
--- a/packages/Webkul/BookingProduct/src/Helpers/Booking.php
+++ b/packages/Webkul/BookingProduct/src/Helpers/Booking.php
@@ -531,7 +531,7 @@ class Booking
*/
public function validateCartItem($item)
{
- $price = $item->product->getTypeInstance()->getFinalPrice();
+ $price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
if ($price == $item->base_price) {
return;
diff --git a/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php b/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php
index 3302f26b4..d7bda887e 100644
--- a/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php
+++ b/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php
@@ -119,7 +119,7 @@ class EventTicket extends Booking
*/
public function validateCartItem($item)
{
- $price = $item->product->getTypeInstance()->getFinalPrice();
+ $price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $item->product_id);
diff --git a/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php b/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php
index 2ca56dfa7..71d1a937e 100644
--- a/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php
+++ b/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php
@@ -224,7 +224,7 @@ class RentalSlot extends Booking
*/
public function validateCartItem($item)
{
- $price = $item->product->getTypeInstance()->getFinalPrice();
+ $price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $item->product_id);
diff --git a/packages/Webkul/CartRule/src/Helpers/CartRule.php b/packages/Webkul/CartRule/src/Helpers/CartRule.php
index b10d2721b..ba76ef565 100644
--- a/packages/Webkul/CartRule/src/Helpers/CartRule.php
+++ b/packages/Webkul/CartRule/src/Helpers/CartRule.php
@@ -140,9 +140,11 @@ class CartRule
public static $cartRules;
public static $cartID;
};
+
if ($staticCartRules::$cartID === cart()->getCart()->id && $staticCartRules::$cartRules) {
return $staticCartRules::$cartRules;
}
+
$staticCartRules::$cartID = cart()->getCart()->id;
$customerGroupId = null;
diff --git a/packages/Webkul/Product/src/Contracts/ProductCustomerGroupPrice.php b/packages/Webkul/Product/src/Contracts/ProductCustomerGroupPrice.php
new file mode 100644
index 000000000..d930da4fe
--- /dev/null
+++ b/packages/Webkul/Product/src/Contracts/ProductCustomerGroupPrice.php
@@ -0,0 +1,7 @@
+bigIncrements('id');
+ $table->integer('qty')->default(0);
+ $table->string('value_type');
+ $table->decimal('value', 12, 4)->default(0);
+
+ $table->integer('product_id')->unsigned();
+ $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
+
+ $table->integer('customer_group_id')->nullble()->unsigned();
+ $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('product_customer_group_prices');
+ }
+}
diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php
index 8253a79f8..4ba4b12c6 100755
--- a/packages/Webkul/Product/src/Models/Product.php
+++ b/packages/Webkul/Product/src/Models/Product.php
@@ -178,6 +178,14 @@ class Product extends Model implements ProductContract
return $this->hasMany(ProductBundleOptionProxy::modelClass());
}
+ /**
+ * Get the product customer group prices that owns the product.
+ */
+ public function customer_group_prices()
+ {
+ return $this->hasMany(ProductCustomerGroupPriceProxy::modelClass());
+ }
+
/**
* @param integer $qty
*
diff --git a/packages/Webkul/Product/src/Models/ProductCustomerGroupPrice.php b/packages/Webkul/Product/src/Models/ProductCustomerGroupPrice.php
new file mode 100644
index 000000000..b71d2b7d2
--- /dev/null
+++ b/packages/Webkul/Product/src/Models/ProductCustomerGroupPrice.php
@@ -0,0 +1,35 @@
+belongsTo(ProductProxy::modelClass());
+ }
+
+ /**
+ * Get the product that owns the customer group price.
+ */
+ public function customer_group()
+ {
+ return $this->belongsTo(CustomerGroupProxy::modelClass());
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Models/ProductCustomerGroupPriceProxy.php b/packages/Webkul/Product/src/Models/ProductCustomerGroupPriceProxy.php
new file mode 100644
index 000000000..68d9ce166
--- /dev/null
+++ b/packages/Webkul/Product/src/Models/ProductCustomerGroupPriceProxy.php
@@ -0,0 +1,10 @@
+customer_group_prices()->pluck('id');
+
+ if (isset($data['customer_group_prices'])) {
+ foreach ($data['customer_group_prices'] as $customerGroupPriceId => $row) {
+ $row['customer_group_id'] = $row['customer_group_id'] == '' ? null : $row['customer_group_id'];
+
+ if (Str::contains($customerGroupPriceId, 'customer_group_price_')) {
+ $this->create(array_merge([
+ 'product_id' => $product->id,
+ ], $row));
+ } else {
+ if (is_numeric($index = $previousCustomerGroupPriceIds->search($customerGroupPriceId))) {
+ $previousCustomerGroupPriceIds->forget($index);
+ }
+
+ $this->update($row, $customerGroupPriceId);
+ }
+ }
+ }
+
+ foreach ($previousCustomerGroupPriceIds as $customerGroupPriceId) {
+ $this->delete($customerGroupPriceId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Type/AbstractType.php b/packages/Webkul/Product/src/Type/AbstractType.php
index 859652958..6707df257 100644
--- a/packages/Webkul/Product/src/Type/AbstractType.php
+++ b/packages/Webkul/Product/src/Type/AbstractType.php
@@ -11,7 +11,7 @@ use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Helpers\ProductImage;
-use Cart;
+use Webkul\Checkout\Facades\Cart;
abstract class AbstractType
{
@@ -246,6 +246,8 @@ abstract class AbstractType
$this->productInventoryRepository->saveInventories($data, $product);
$this->productImageRepository->uploadImages($data, $product);
+
+ app('Webkul\Product\Repositories\ProductCustomerGroupPriceRepository')->saveCustomerGroupPrices($data, $product);
}
return $product;
@@ -449,11 +451,12 @@ abstract class AbstractType
/**
* Get product minimal price
*
+ * @param int $qty
* @return float
*/
- public function getMinimalPrice()
+ public function getMinimalPrice($qty = null)
{
- if ($this->haveSpecialPrice()) {
+ if ($this->haveSpecialPrice($qty)) {
return $this->product->special_price;
}
@@ -473,57 +476,148 @@ abstract class AbstractType
/**
* Get product minimal price
*
+ * @param int $qty
* @return float
*/
- public function getFinalPrice()
+ public function getFinalPrice($qty = null)
{
- return $this->getMinimalPrice();
+ return $this->getMinimalPrice($qty);
}
/**
* Returns the product's minimal price
*
+ * @param int $qty
* @return float
*/
- public function getSpecialPrice()
+ public function getSpecialPrice($qty = null)
{
- return $this->haveSpecialPrice() ? $this->product->special_price : $this->product->price;
+ return $this->haveSpecialPrice($qty) ? $this->product->special_price : $this->product->price;
}
/**
+ * @param int $qty
* @return bool
*/
- public function haveSpecialPrice()
+ public function haveSpecialPrice($qty = null)
{
+ $customerGroupPrice = $this->getCustomerGroupPrice($this->product, $qty);
+
$rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
- if ((is_null($this->product->special_price) || ! (float) $this->product->special_price) && ! $rulePrice) {
+ if ((is_null($this->product->special_price) || ! (float) $this->product->special_price)
+ && ! $rulePrice
+ && $customerGroupPrice == $this->product->price
+ ) {
return false;
}
+ $haveSpecialPrice = false;
+
if (! (float) $this->product->special_price) {
if ($rulePrice && $rulePrice->price < $this->product->price) {
$this->product->special_price = $rulePrice->price;
- return true;
+ $haveSpecialPrice = true;
}
} else {
if ($rulePrice && $rulePrice->price <= $this->product->special_price) {
$this->product->special_price = $rulePrice->price;
- return true;
+ $haveSpecialPrice = true;
} else {
if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to)) {
- return true;
+ $haveSpecialPrice = true;
} elseif ($rulePrice) {
$this->product->special_price = $rulePrice->price;
- return true;
+ $haveSpecialPrice = true;
}
}
}
- return false;
+ if ($haveSpecialPrice) {
+ $this->product->special_price = min($this->product->special_price, $customerGroupPrice);
+ } else {
+ $this->product->special_price = $customerGroupPrice;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get product group price
+ *
+ * @return float
+ */
+ public function getCustomerGroupPrice($product, $qty)
+ {
+ if (is_null($qty)) {
+ $qty = 1;
+ }
+
+ $customerGroupId = null;
+
+ if (Cart::getCurrentCustomer()->check()) {
+ $customerGroupId = Cart::getCurrentCustomer()->user()->customer_group_id;
+ } else {
+ $customerGroupRepository = app('Webkul\Customer\Repositories\CustomerGroupRepository');
+
+ if ($customerGuestGroup = $customerGroupRepository->findOneByField('code', 'guest')) {
+ $customerGroupId = $customerGuestGroup->id;
+ }
+ }
+
+ $customerGroupPrices = $product->customer_group_prices()->where(function ($query) use ($customerGroupId) {
+ $query->where('customer_group_id', $customerGroupId)
+ ->orWhereNull('customer_group_id');
+ }
+ )->get();
+
+ if (! $customerGroupPrices->count()) {
+ return $product->price;
+ }
+
+ $lastQty = 1;
+
+ $lastPrice = $product->price;
+
+ $lastCustomerGroupId = null;
+
+ foreach ($customerGroupPrices as $price) {
+ if ($price->customer_group_id != $customerGroupId && $price->customer_group_id) {
+ continue;
+ }
+
+ if ($qty < $price->qty) {
+ continue;
+ }
+
+ if ($price->qty < $lastQty) {
+ continue;
+ }
+
+ if ($price->qty == $lastQty
+ && $lastCustomerGroupId != null
+ && $price->customer_group_id == null
+ ) {
+ continue;
+ }
+
+ if ($price->value < $lastPrice) {
+ if ($price->value_type == 'percentage') {
+ $lastPrice = $product->price * ($price->value / 100);
+ } else {
+ $lastPrice = $price->value;
+ }
+
+ $lastQty = $price->qty;
+
+ $lastCustomerGroupId = $price->customer_group_id;
+ }
+ }
+
+ return $lastPrice;
}
/**
@@ -685,7 +779,7 @@ abstract class AbstractType
*/
public function validateCartItem($item)
{
- $price = $item->product->getTypeInstance()->getFinalPrice();
+ $price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
if ($price == $item->base_price) {
return;
diff --git a/packages/Webkul/Product/src/Type/Configurable.php b/packages/Webkul/Product/src/Type/Configurable.php
index 5301b0837..f3689ee7c 100644
--- a/packages/Webkul/Product/src/Type/Configurable.php
+++ b/packages/Webkul/Product/src/Type/Configurable.php
@@ -542,7 +542,7 @@ class Configurable extends AbstractType
*/
public function validateCartItem($item)
{
- $price = $item->child->product->getTypeInstance()->getFinalPrice();
+ $price = $item->child->product->getTypeInstance()->getFinalPrice($item->quantity);
if ($price == $item->base_price) {
return;
diff --git a/packages/Webkul/Product/src/Type/Downloadable.php b/packages/Webkul/Product/src/Type/Downloadable.php
index 1220e091c..f4487c151 100644
--- a/packages/Webkul/Product/src/Type/Downloadable.php
+++ b/packages/Webkul/Product/src/Type/Downloadable.php
@@ -235,7 +235,7 @@ class Downloadable extends AbstractType
*/
public function validateCartItem($item)
{
- $price = $item->product->getTypeInstance()->getFinalPrice();
+ $price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
foreach ($item->product->downloadable_links as $link) {
if (! in_array($link->id, $item->additional['links'])) {