From 8a9198e5d9efda0689d0cc74023781324bac3748 Mon Sep 17 00:00:00 2001 From: Prashant Singh Date: Mon, 19 Aug 2019 12:36:43 +0530 Subject: [PATCH] Catalog rules tie break in progress, squased a line of dead code in CartRuleController --- packages/Webkul/Admin/src/Config/menu.php | 16 +- .../Discount/src/Actions/Catalog/Action.php | 8 + .../Actions/Catalog/AdjustToDiscountValue.php | 22 +++ .../src/Actions/Catalog/AdjustToPercent.php | 19 +++ .../src/Actions/Catalog/FixedAmount.php | 20 +++ .../src/Actions/Catalog/PercentOfOriginal.php | 19 +++ .../Discount/src/Config/rule-conditions.php | 6 +- .../Discount/src/Helpers/Catalog/Apply.php | 148 ++++-------------- .../Http/Controllers/CartRuleController.php | 1 - .../CatalogRuleProductsPriceRepository.php | 146 ++++++++++++++++- .../CatalogRuleProductsRepository.php | 145 +++++++++++++++++ 11 files changed, 420 insertions(+), 130 deletions(-) create mode 100644 packages/Webkul/Discount/src/Actions/Catalog/Action.php diff --git a/packages/Webkul/Admin/src/Config/menu.php b/packages/Webkul/Admin/src/Config/menu.php index 2c73ae44d..1091a60fb 100755 --- a/packages/Webkul/Admin/src/Config/menu.php +++ b/packages/Webkul/Admin/src/Config/menu.php @@ -188,13 +188,15 @@ return [ 'route' => 'admin.cart-rule.index', 'sort' => 1, 'icon-class' => '', - ], [ - 'key' => 'promotions.catalog-rule', - 'name' => 'admin::app.promotion.catalog-rule', - 'route' => 'admin.catalog-rule.index', - 'sort' => 1, - 'icon-class' => '', - ], [ + ], + // [ + // 'key' => 'promotions.catalog-rule', + // 'name' => 'admin::app.promotion.catalog-rule', + // 'route' => 'admin.catalog-rule.index', + // 'sort' => 1, + // 'icon-class' => '', + // ], + [ 'key' => 'cms', 'name' => 'admin::app.layouts.cms', 'route' => 'admin.cms.index', diff --git a/packages/Webkul/Discount/src/Actions/Catalog/Action.php b/packages/Webkul/Discount/src/Actions/Catalog/Action.php new file mode 100644 index 000000000..ddd2ddc56 --- /dev/null +++ b/packages/Webkul/Discount/src/Actions/Catalog/Action.php @@ -0,0 +1,8 @@ +discount_amount; + $price = $product->price; + + if ($discountAmount <= $price) { + $discount = $price - $discountAmount; + + return $discount; + } else { + return $price; + } + } +} \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php b/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php index e69de29bb..6c085a63a 100644 --- a/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php +++ b/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php @@ -0,0 +1,19 @@ +discount_amount; + + $price = $product->price; + + $discount = ($discountAmount / 100) * $price; + + return $discount; + } +} \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php b/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php index e69de29bb..d37f65df9 100644 --- a/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php +++ b/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php @@ -0,0 +1,20 @@ +discount_amount; + $price = $product->price; + + if ($discountAmount <= $price) { + return $discountAmount; + } else { + return $price; + } + } +} \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php b/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php index e69de29bb..4fc7c0408 100644 --- a/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php +++ b/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php @@ -0,0 +1,19 @@ +discount_amount; + + $price = $product->price; + + $discount = ($discountAmount / 100) * $price; + + return $discount; + } +} \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Config/rule-conditions.php b/packages/Webkul/Discount/src/Config/rule-conditions.php index 20c371df9..85df3ce89 100644 --- a/packages/Webkul/Discount/src/Config/rule-conditions.php +++ b/packages/Webkul/Discount/src/Config/rule-conditions.php @@ -109,10 +109,10 @@ return [ 'catalog' => [ 'actions' => [ - 'percent_of_product' => 'Percentage of product', + 'percent_of_original' => 'Percentage of product', 'fixed_amount' => 'Apply as fixed amount', - 'adjust_to_percent' => 'Adjust price to percentage', - 'adjust_to_fixed_amount' => 'Adjust price to given amount' + 'final_price_to_percent' => 'Adjust price to percentage', + 'to_discount_value' => 'Adjust price to given amount' ], 'validation' => [ diff --git a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php b/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php index 371298b8b..69af195c5 100644 --- a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php +++ b/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php @@ -100,16 +100,19 @@ class Apply extends Sale if ($this->active->count()) { $productIDs = array(); + $temp = collect(); foreach ($this->activeRules as $rule) { - array_push($productIDs, $this->getProductIds($rule)); + $productIDs = $this->getProductIds($rule); + + $productIDs = $this->expandProducts($productIDs); + + $result = $this->setSale($rule, $productIDs); } - dd(array_flatten($productIDs)); - - $this->setSale($rule, $productIDs); - + dd($result, 'processing done'); } else { + // handle the deceased rules here dd($this->deceased); } } @@ -126,9 +129,11 @@ class Apply extends Sale if (is_array($productIDs)) { // apply on selected products foreach ($productIDs as $productID) { - $this->createOrUpdate($rule, $productID); + // catalog rule product resource is updated here + $this->catalogRuleProduct->createOrUpdate($rule, $productID); - // $this->catalogRuleProductPrice->createOrUpdate($rule, $productID); + // catalog rule product price resource is updated here + $this->catalogRuleProductPrice->createOrUpdate($rule, $productID); } } else if ($productIDs == '*') { $this->catalogRuleProduct->createOrUpdate($rule, $productIDs); @@ -138,127 +143,36 @@ class Apply extends Sale } /** - * Create or update catalog rule product resource + * To expand the productIDs of configurable products * - * @param CatalogRule $rule - * @param Integer $productID + * @param Array $productIDs * - * @return Void + * @return Array */ - public function createOrUpdate($rule, $productID) + protected function expandProducts($productIDs) { - $channels = $rule->channels; - $customerGroups = $rule->customer_groups; + $products = app('Webkul\Product\Repositories\ProductRepository'); - $channelsGroupsCross = $channels->crossJoin($customerGroups); + $newProductIDs = collect(); - if ($productID == '*') { - $products = $this->product->all('id'); + foreach ($productIDs as $productID) { + $product = $products->find($productID); - foreach ($channelsGroupsCross as $channelGroup) { - $channelId = $channelGroup[0]->channel_id; - $groupId = $channelGroup[1]->customer_group_id; + if ($product->type == 'configurable') { + $variants = $product->variants; - $model = new $this->model(); - - foreach ($products as $product) { - $productID = $product->id; - - $catalogRuleProduct = $this->catalogRuleProduct->findWhere([ - 'channel_id' => $channelId, - 'customer_group_id' => $groupId, - 'product_id' => $productID - ]); - - if ($catalogRuleProduct->count()) { - // check for tie breaker rules and then update - $previousRuleID = $catalogRuleProduct->first()->catalog_rule_id; - - $newRuleID = $rule->id; - - $winnerRuleId = $this->breakTie($previousRuleID, $newRuleID); - - $data = [ - 'catalog_rule_id' => $rule->id, - 'starts_from' => $rule->starts_from, - 'ends_till' => $rule->ends_till, - 'customer_group_id' => $groupId, - 'channel_id' => $channelId, - 'product_id' => $productID, - 'action_code' => $rule->action_code, - 'action_amount' => $rule->discount_amount - ]; - - if ($rule->id == $winnerRuleId) { - $this->catalogRuleProduct->create($data); - } else { - $this->catalogRuleProduct->update($data, $catalogRuleProduct->first()->id); - } - } else { - $data = [ - 'catalog_rule_id' => $rule->id, - 'starts_from' => $rule->starts_from, - 'ends_till' => $rule->ends_till, - 'customer_group_id' => $groupId, - 'channel_id' => $channelId, - 'product_id' => $productID, - 'action_code' => $rule->action_code, - 'action_amount' => $rule->discount_amount - ]; - - $this->catalogRuleProduct->create($data); - } + foreach($variants as $variant) { + $newProductIDs->push($variant->id); } + } else { + $newProductIDs->push($productID); } + } + + if ($newProductIDs->count()) { + return $newProductIDs->toArray(); } else { - foreach ($channelsGroupsCross as $channelGroup) { - $channelId = $channelGroup[0]->channel_id; - $groupId = $channelGroup[1]->customer_group_id; - - $catalogRuleProduct = $this->catalogRuleProduct->findWhere([ - 'channel_id' => $channelId, - 'customer_group_id' => $groupId, - 'product_id' => $productID - ]); - - if ($catalogRuleProduct->count() && $catalogRuleProduct->first()->catalog_rule_id != $rule->id) { - - // check for tie breaker rules and then update - $previousRuleID = $catalogRuleProduct->first()->catalog_rule_id; - - $newRuleID = $rule->id; - - $winnerRuleId = $this->breakTie($previousRuleID, $newRuleID); - - // update - $catalogRuleProduct->first()->update([ - 'catalog_rule_id' => $rule->id, - 'starts_from' => $rule->starts_from, - 'ends_till' => $rule->ends_till, - 'customer_group_id' => $groupId, - 'channel_id' => $channelId, - 'product_id' => $productID, - 'action_code' => $rule->action_code, - 'action_amount' => $rule->discount_amount - ]); - } else if ($catalogRuleProduct->count() == 0) { - // create - $data = [ - 'catalog_rule_id' => $rule->id, - 'starts_from' => $rule->starts_from, - 'ends_till' => $rule->ends_till, - 'customer_group_id' => $groupId, - 'channel_id' => $channelId, - 'product_id' => $productID, - 'action_code' => $rule->action_code, - 'action_amount' => $rule->discount_amount - ]; - - $this->catalogRuleProduct->create($data); - } else { - // do the reassessment updation if the cart rule action changes the new action and its amount needs to be updated - } - } + return []; } } diff --git a/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php b/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php index 72666418d..5f99edbf4 100644 --- a/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php +++ b/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php @@ -349,7 +349,6 @@ class CartRuleController extends Controller */ public function update($id) { - dd(request()->all()); $this->validate(request(), [ 'name' => 'required|string|unique:cart_rules,name,'.$id, 'description' => 'string', diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php index 69d8aad59..05e60735b 100644 --- a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php +++ b/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php @@ -4,6 +4,7 @@ namespace Webkul\Discount\Repositories; use Webkul\Core\Eloquent\Repository; use Webkul\Product\Repositories\ProductRepository as Product; +use Webkul\Discount\Repositories\CatalogRuleProductsRepository as CatalogRuleProduct; use Illuminate\Container\Container as App; /** @@ -15,17 +16,26 @@ use Illuminate\Container\Container as App; class CatalogRuleProductsPriceRepository extends Repository { /** - * ProductRepository instance + * To hold ProductRepository instance */ protected $product; + /** + * To hold CatalogRuleProductRepository instance + * + */ + protected $catalogRuleProduct; + /** * @param Product $product */ - public function __construct(Product $product, App $app) + public function __construct(Product $product, CatalogRuleProduct $catalogRuleProduct,App $app) { + $this->product = $product; + $this->catalogRuleProduct = $catalogRuleProduct; + parent::__construct($app); } @@ -38,4 +48,136 @@ class CatalogRuleProductsPriceRepository extends Repository { return 'Webkul\Discount\Contracts\CatalogRuleProductsPrice'; } + + /** + * Create or update catalog rule product resource + * + * @param CatalogRule $rule + * @param Integer $productID + * + * @return Void + */ + public function createOrUpdate($rule, $productID) + { + $channels = $rule->channels; + $customerGroups = $rule->customer_groups; + + $channelsGroupsCross = $channels->crossJoin($customerGroups); + + if ($productID == '*') { + $products = $this->product->all('id'); + + foreach ($channelsGroupsCross as $channelGroup) { + $channelId = $channelGroup[0]->channel_id; + $groupId = $channelGroup[1]->customer_group_id; + + foreach ($products as $product) { + $productID = $product->id; + + $catalogRuleProductPrice = $this->findWhere([ + 'channel_id' => $channelId, + 'customer_group_id' => $groupId, + 'product_id' => $productID + ]); + + if ($catalogRuleProductPrice->count()) { + // check for tie breaker rules and then update + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'action_code' => $rule->action_code, + 'action_amount' => $rule->discount_amount + ]; + + $this->update($data, $catalogRuleProductPrice->first()->id); + } else { + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'action_code' => $rule->action_code, + 'action_amount' => $rule->discount_amount + ]; + + $this->create($data); + } + } + } + } else { + foreach ($channelsGroupsCross as $channelGroup) { + $channelId = $channelGroup[0]->channel_id; + $groupId = $channelGroup[1]->customer_group_id; + + $catalogRuleProduct = $this->catalogRuleProduct->findWhere([ + 'channel_id' => $channelId, + 'customer_group_id' => $groupId, + 'product_id' => $productID + ]); + + $catalogRuleProductPrice = $this->findWhere([ + 'channel_id' => $channelId, + 'customer_group_id' => $groupId, + 'product_id' => $productID + ]); + + if ($catalogRuleProductPrice->count() && $catalogRuleProductPrice->first()->catalog_rule_id != $rule->id) { + $catalogRuleProduct = $catalogRuleProduct->first(); + + $discountAmount = $rule->discount_amount; + + $product = $this->product->find($productID); + + $productPrice = $product->price - $catalogRuleProduct->action_amount; + + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'rule_price' => $productPrice + ]; + + // update + $catalogRuleProductPrice->first()->update($data); + } else if ($catalogRuleProductPrice->count() == 0) { + $catalogRuleProduct = $catalogRuleProduct->first(); + + $discountAmount = $rule->discount_amount; + + $product = $this->product->find($productID); + + $productPrice = $product->price - $catalogRuleProduct->action_amount; + + if ($productPrice <= $discountAmount) { + $product->price = $productPrice - $discountAmount; + } else { + $product->price = 0; + } + + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'rule_price' => $productPrice + ]; + + $this->create($data); + } else { + // do the reassessment updation if the cart rule action changes the new action and its amount needs to be updated + } + } + } + } } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php index 8838c9dea..f490930ab 100644 --- a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php +++ b/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php @@ -36,6 +36,18 @@ class CatalogRuleProductsRepository extends Repository parent::__construct($app); } + public function getDiscountAmount($product, $rule) + { + + $actionClass = config('discount-rules.catalog')[$rule->action_code]; + + $actionInstance = new $actionClass(); + + $discountAmount = $actionInstance->calculate($rule, $product); + + return $discountAmount; + } + /** * Specify Model class name * @@ -45,4 +57,137 @@ class CatalogRuleProductsRepository extends Repository { return 'Webkul\Discount\Contracts\CatalogRuleProducts'; } + + /** + * Create or update catalog rule product resource + * + * @param CatalogRule $rule + * @param Integer $productID + * + * @return Void + */ + public function createOrUpdate($rule, $productID) + { + $channels = $rule->channels; + $customerGroups = $rule->customer_groups; + + $channelsGroupsCross = $channels->crossJoin($customerGroups); + + if ($productID == '*') { + $products = $this->product->all('id'); + + foreach ($channelsGroupsCross as $channelGroup) { + $channelId = $channelGroup[0]->channel_id; + $groupId = $channelGroup[1]->customer_group_id; + + $model = new $this->model(); + + foreach ($products as $product) { + $productID = $product->id; + + $catalogRuleProduct = $this->findWhere([ + 'channel_id' => $channelId, + 'customer_group_id' => $groupId, + 'product_id' => $productID + ]); + + if ($catalogRuleProduct->count()) { + // check for tie breaker rules and then update + $previousRuleID = $catalogRuleProduct->first()->catalog_rule_id; + + $newRuleID = $rule->id; + + $winnerRuleId = $this->breakTie($previousRuleID, $newRuleID); + + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'action_code' => $rule->action_code, + 'action_amount' => $rule->discount_amount + ]; + + if ($rule->id == $winnerRuleId) { + $this->catalogRuleProduct->create($data); + } else { + $this->catalogRuleProduct->update($data, $catalogRuleProduct->first()->id); + } + } else { + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'action_code' => $rule->action_code, + 'action_amount' => $rule->discount_amount + ]; + + $this->catalogRuleProduct->create($data); + } + } + } + } else { + foreach ($channelsGroupsCross as $channelGroup) { + $channelId = $channelGroup[0]->channel_id; + $groupId = $channelGroup[1]->customer_group_id; + + $catalogRuleProduct = $this->findWhere([ + 'channel_id' => $channelId, + 'customer_group_id' => $groupId, + 'product_id' => $productID + ]); + + if ($catalogRuleProduct->count() && $catalogRuleProduct->first()->catalog_rule_id != $rule->id) { + $product = $this->product->find($productID); + $productPrice = $product->price; + + $discountAmount = $this->getDiscountAmount($product, $rule); + + // check for tie breaker rules and then update + $previousRuleID = $catalogRuleProduct->first()->catalog_rule_id; + + $newRuleID = $rule->id; + + $winnerRuleId = $this->breakTie($previousRuleID, $newRuleID); + + // update + $catalogRuleProduct->first()->update([ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'action_code' => $rule->action_code, + 'action_amount' => $discountAmount + ]); + } else if ($catalogRuleProduct->count() == 0) { + $product = $this->product->find($productID); + $productPrice = $product->price; + + $discountAmount = $this->getDiscountAmount($product, $rule); + + $data = [ + 'catalog_rule_id' => $rule->id, + 'starts_from' => $rule->starts_from, + 'ends_till' => $rule->ends_till, + 'customer_group_id' => $groupId, + 'channel_id' => $channelId, + 'product_id' => $productID, + 'action_code' => $rule->action_code, + 'action_amount' => $discountAmount + ]; + + $this->create($data); + } else { + // do the reassessment updation if the cart rule action changes the new action and its amount needs to be updated + } + } + } + } }