Refactoring cart rules
This commit is contained in:
parent
9ca97aa594
commit
e4a5e84fb6
|
|
@ -269,7 +269,7 @@ body {
|
|||
.control-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
width: 750px;
|
||||
|
||||
.control {
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@ use Illuminate\Foundation\Validation\ValidatesRequests;
|
|||
class Controller extends BaseController
|
||||
{
|
||||
use DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ namespace Webkul\Discount\Actions;
|
|||
|
||||
abstract class Action
|
||||
{
|
||||
abstract public function calculate($rule, $item, $cart);
|
||||
abstract public function calculate($rule);
|
||||
|
||||
abstract public function calculateOnShipping($cart);
|
||||
abstract public function calculateOnShipping();
|
||||
}
|
||||
|
|
@ -6,60 +6,132 @@ use Webkul\Discount\Actions\Action;
|
|||
|
||||
class PercentOfProduct extends Action
|
||||
{
|
||||
public function calculate($rule, $items, $cart)
|
||||
public function calculate($rule)
|
||||
{
|
||||
$report = collect();
|
||||
$cart = \Cart::getCart();
|
||||
$items = $cart->items;
|
||||
|
||||
$impact = collect();
|
||||
$totalDiscount = 0;
|
||||
|
||||
foreach ($items as $item) {
|
||||
$amountDiscounted = 0;
|
||||
$itemReport = array();
|
||||
if ($rule->uses_attribute_conditions) {
|
||||
$productIds = $rule->product_ids;
|
||||
|
||||
$disc_threshold = $rule->disc_threshold;
|
||||
$disc_amount = $rule->disc_amount;
|
||||
$disc_quantity = $rule->disc_quantity;
|
||||
$productIds = explode(',', $productIds);
|
||||
|
||||
$realQty = $item['quantity'];
|
||||
foreach ($items as $item) {
|
||||
$product = $item->product;
|
||||
|
||||
if ($cart->items_qty >= $disc_threshold) {
|
||||
$amountDiscounted = $item['base_price'] * ($disc_amount / 100);
|
||||
|
||||
if ($realQty > $disc_quantity) {
|
||||
$amountDiscounted = $amountDiscounted * $disc_quantity;
|
||||
} else {
|
||||
$amountDiscounted = $amountDiscounted * $realQty;
|
||||
if ($product->type == 'configurable') {
|
||||
$product = $item->child->product;
|
||||
}
|
||||
|
||||
if ($amountDiscounted > $item['base_price'] && $realQty == 1) {
|
||||
$amountDiscounted = $item['base_price'];
|
||||
foreach ($productIds as $productId) {
|
||||
$disc_threshold = $rule->disc_threshold;
|
||||
$disc_amount = $rule->disc_amount;
|
||||
$disc_quantity = $rule->disc_quantity;
|
||||
$amountDiscounted = 0;
|
||||
$report = array();
|
||||
|
||||
$realQty = $item->quantity;
|
||||
|
||||
if ($productId == $product->id && $cart->items_qty >= $disc_threshold) {
|
||||
// distribute the discount according to ratios in case when rule is getting applied on multiple items
|
||||
|
||||
$amountDiscounted = $item->base_price * ($disc_amount / 100);
|
||||
|
||||
if ($realQty > $disc_quantity) {
|
||||
$amountDiscounted = $amountDiscounted * $disc_quantity;
|
||||
} else {
|
||||
$amountDiscounted = $amountDiscounted * $realQty;
|
||||
}
|
||||
|
||||
if ($amountDiscounted > $item->base_price && $realQty == 1) {
|
||||
$amountDiscounted = $item->base_price;
|
||||
}
|
||||
|
||||
$totalDiscount = $totalDiscount + $amountDiscounted;
|
||||
|
||||
$report['item_id'] = $item->id;
|
||||
$report['product_id'] = $productId;
|
||||
$report['discount'] = $amountDiscounted;
|
||||
$report['formatted_discount'] = core()->currency($amountDiscounted);
|
||||
|
||||
$impact->push($report);
|
||||
|
||||
unset($report);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$productIds = null;
|
||||
|
||||
$totalDiscount = $totalDiscount + $amountDiscounted;
|
||||
foreach ($items as $item) {
|
||||
$product = $item->product;
|
||||
|
||||
$itemReport['item_id'] = $item->id;
|
||||
$itemReport['product_id'] = $item->product_id;
|
||||
$itemReport['discount'] = $amountDiscounted;
|
||||
$itemReport['formatted_discount'] = core()->currency($amountDiscounted);
|
||||
if ($product->type == 'configurable') {
|
||||
$product = $item->child->product;
|
||||
}
|
||||
|
||||
$report->push($itemReport);
|
||||
$disc_threshold = $rule->disc_threshold;
|
||||
$disc_amount = $rule->disc_amount;
|
||||
$disc_quantity = $rule->disc_quantity;
|
||||
$amountDiscounted = 0;
|
||||
$report = array();
|
||||
|
||||
unset($itemReport);
|
||||
$realQty = $item->quantity;
|
||||
|
||||
if ($productId == $product->id && $cart->items_qty >= $disc_threshold) {
|
||||
// distribute the discount according to ratios in case when rule is getting applied on multiple items
|
||||
|
||||
$amountDiscounted = $item->base_price * ($disc_amount / 100);
|
||||
|
||||
if ($realQty > $disc_quantity) {
|
||||
$amountDiscounted = $amountDiscounted * $disc_quantity;
|
||||
} else {
|
||||
$amountDiscounted = $amountDiscounted * $realQty;
|
||||
}
|
||||
|
||||
if ($amountDiscounted > $item->base_price && $realQty == 1) {
|
||||
$amountDiscounted = $item->base_price;
|
||||
}
|
||||
|
||||
$totalDiscount = $totalDiscount + $amountDiscounted;
|
||||
|
||||
$report['item_id'] = $item->id;
|
||||
$report['product_id'] = $productId;
|
||||
$report['discount'] = $amountDiscounted;
|
||||
$report['formatted_discount'] = core()->currency($amountDiscounted);
|
||||
|
||||
$impact->push($report);
|
||||
|
||||
unset($report);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$report->discount = $totalDiscount;
|
||||
$report->formatted_discount = core()->currency($totalDiscount);
|
||||
// if (isset($rule->apply_on_shipping) && ! $rule->free_shipping) {
|
||||
// $impact->discount_on_shipping = $this->calculateOnShipping();
|
||||
// } else {
|
||||
// $rule->discount_on_shipping = 0;
|
||||
// $rule->base_discount_on_shipping = 0;
|
||||
// }
|
||||
|
||||
return $report;
|
||||
$impact->discount = $totalDiscount;
|
||||
$impact->formatted_discount = core()->currency($totalDiscount);
|
||||
|
||||
return $impact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled
|
||||
*/
|
||||
public function calculateOnShipping($cart)
|
||||
public function calculateOnShipping()
|
||||
{
|
||||
$cart = \Cart::getCart();
|
||||
|
||||
$shippingRate = $cart->selected_shipping_rate;
|
||||
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
|
||||
|
||||
return $percentOfDiscount;
|
||||
|
|
|
|||
|
|
@ -15,19 +15,21 @@ class WholeCartToPercent extends Action
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function calculate($rule, $items, $cart)
|
||||
public function calculate($rule)
|
||||
{
|
||||
$report = collect();
|
||||
$cart = \Cart::getCart();
|
||||
$items = $cart->items;
|
||||
|
||||
$impact = collect();
|
||||
$totalDiscount = 0;
|
||||
|
||||
if ($rule->discount_amount >= 100) {
|
||||
$report->discount = $cart->base_grand_total;
|
||||
$impact->discount = $cart->base_grand_total;
|
||||
} else {
|
||||
$report->discount = ($rule->disc_amount / 100) * $cart->base_grand_total;
|
||||
$impact->discount = ($rule->disc_amount / 100) * $cart->base_grand_total;
|
||||
}
|
||||
|
||||
$report->formatted_discount = core()->currency($report->discount);
|
||||
$impact->formatted_discount = core()->currency($impact->discount);
|
||||
|
||||
if ($rule->uses_attribute_conditions) {
|
||||
$productIDs = $rule->product_ids;
|
||||
|
|
@ -45,22 +47,22 @@ class WholeCartToPercent extends Action
|
|||
}
|
||||
|
||||
if ($matchCount > 0) {
|
||||
$discountPerItem = $report->discount / $matchCount;
|
||||
$discountPerItem = $impact->discount / $matchCount;
|
||||
}
|
||||
|
||||
foreach ($productIDs as $productID) {
|
||||
foreach ($items as $item) {
|
||||
if ($item->product_id == $productID) {
|
||||
$itemReport = array();
|
||||
$report = array();
|
||||
|
||||
$itemReport['item_id'] = $item->id;
|
||||
$itemReport['product_id'] = $item->product_id;
|
||||
$itemReport['discount'] = $discountPerItem;
|
||||
$itemReport['formatted_discount'] = core()->currency(0);
|
||||
$report['item_id'] = $item->id;
|
||||
$report['product_id'] = $item->product_id;
|
||||
$report['discount'] = $discountPerItem;
|
||||
$report['formatted_discount'] = core()->currency(0);
|
||||
|
||||
$report->push($itemReport);
|
||||
$impact->push($report);
|
||||
|
||||
unset($itemReport);
|
||||
unset($report);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,26 +70,26 @@ class WholeCartToPercent extends Action
|
|||
$discountPerItem = $report->discount / $cart->items_qty;
|
||||
|
||||
foreach ($items as $item) {
|
||||
$itemReport = array();
|
||||
$report = array();
|
||||
|
||||
$itemReport['item_id'] = $item->id;
|
||||
$itemReport['product_id'] = $item->product_id;
|
||||
$itemReport['discount'] = $discountPerItem;
|
||||
$itemReport['formatted_discount'] = core()->currency(0);
|
||||
$report['item_id'] = $item->id;
|
||||
$report['product_id'] = $item->product_id;
|
||||
$report['discount'] = $discountPerItem;
|
||||
$report['formatted_discount'] = core()->currency(0);
|
||||
|
||||
$report->push($itemReport);
|
||||
$impact->push($report);
|
||||
|
||||
unset($itemReport);
|
||||
unset($report);
|
||||
}
|
||||
}
|
||||
|
||||
return $report;
|
||||
return $impact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled
|
||||
*/
|
||||
public function calculateOnShipping($cart)
|
||||
public function calculateOnShipping()
|
||||
{
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,81 @@ abstract class Discount
|
|||
*/
|
||||
abstract public function apply($code);
|
||||
|
||||
/**
|
||||
* To find all the suitable rules that can be applied on the current cart
|
||||
*
|
||||
* @return collection $rules
|
||||
*/
|
||||
public function getApplicableRules($usecoupon = false)
|
||||
{
|
||||
$channel = core()->getCurrentChannel()->id;
|
||||
|
||||
$rules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 0,
|
||||
'status' => 1
|
||||
]);
|
||||
|
||||
$filteredRules = collect();
|
||||
|
||||
// time based constraints
|
||||
foreach ($rules as $rule) {
|
||||
if ($rule->starts_from != null && $rule->ends_till == null) {
|
||||
if (Carbon::parse($rule->starts_from) < now()) {
|
||||
$rule->impact = $this->calculateImpact($rule);
|
||||
|
||||
$filteredRules->push($rule);
|
||||
}
|
||||
} else if ($rule->starts_from == null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->ends_till) > now()) {
|
||||
$rule->impact = $this->calculateImpact($rule);
|
||||
|
||||
$filteredRules->push($rule);
|
||||
}
|
||||
} else if ($rule->starts_from != null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till)) {
|
||||
$rule->impact = $this->calculateImpact($rule);
|
||||
|
||||
$filteredRules->push($rule);
|
||||
}
|
||||
} else {
|
||||
$rule->impact = $this->calculateImpact($rule);
|
||||
|
||||
$filteredRules->push($rule);
|
||||
}
|
||||
}
|
||||
|
||||
dd($filteredRules, 'called by this');
|
||||
|
||||
return $filteredRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* To calculate the impact of the rule
|
||||
*
|
||||
* @return collection
|
||||
*/
|
||||
public function calculateImpact($rule)
|
||||
{
|
||||
$impact = $this->getActionInstance($rule);
|
||||
|
||||
return $impact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the instance of the related rule's action type
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getActionInstance($rule)
|
||||
{
|
||||
$actionType = new $this->rules['cart'][$rule->action_type];
|
||||
|
||||
$outcome = $actionType->calculate($rule);
|
||||
|
||||
return $outcome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether coupon is getting applied on current cart instance or not
|
||||
*
|
||||
|
|
@ -54,22 +129,22 @@ abstract class Discount
|
|||
|
||||
$timeBased = false;
|
||||
|
||||
// time based constraints
|
||||
if ($rule->starts_from != null && $rule->ends_till == null) {
|
||||
if (Carbon::parse($rule->starts_from) < now()) {
|
||||
$timeBased = true;
|
||||
}
|
||||
} else if ($rule->starts_from == null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->ends_till) > now()) {
|
||||
$timeBased = true;
|
||||
}
|
||||
} else if ($rule->starts_from != null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till)) {
|
||||
$timeBased = true;
|
||||
}
|
||||
} else {
|
||||
$timeBased = true;
|
||||
}
|
||||
// // time based constraints
|
||||
// if ($rule->starts_from != null && $rule->ends_till == null) {
|
||||
// if (Carbon::parse($rule->starts_from) < now()) {
|
||||
// $timeBased = true;
|
||||
// }
|
||||
// } else if ($rule->starts_from == null && $rule->ends_till != null) {
|
||||
// if (Carbon::parse($rule->ends_till) > now()) {
|
||||
// $timeBased = true;
|
||||
// }
|
||||
// } else if ($rule->starts_from != null && $rule->ends_till != null) {
|
||||
// if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till)) {
|
||||
// $timeBased = true;
|
||||
// }
|
||||
// } else {
|
||||
// $timeBased = true;
|
||||
// }
|
||||
|
||||
$channelBased = false;
|
||||
|
||||
|
|
@ -130,7 +205,7 @@ abstract class Discount
|
|||
}
|
||||
}
|
||||
|
||||
if ($timeBased && $channelBased && $customerGroupBased && $conditionsBased) {
|
||||
if ($channelBased && $customerGroupBased && $conditionsBased) {
|
||||
if ($rule->uses_attribute_conditions == 1 && $partialMatch) {
|
||||
return true;
|
||||
} else if ($rule->uses_attribute_conditions == 0) {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class NonCouponAbleRule extends Discount
|
|||
}
|
||||
|
||||
// time based filter
|
||||
foreach($rules as $rule) {
|
||||
foreach ($rules as $rule) {
|
||||
$applicability = $this->checkApplicability($rule);
|
||||
|
||||
if ($applicability) {
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ class OnepageController extends Controller
|
|||
if (Cart::hasError())
|
||||
return redirect()->route('shop.checkout.cart.index');
|
||||
|
||||
$this->nonCoupon->apply();
|
||||
// $this->nonCoupon->apply();
|
||||
$this->nonCoupon->getApplicableRules();
|
||||
|
||||
Cart::collectTotals();
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ class OnepageController extends Controller
|
|||
if (Cart::hasError() || !Cart::saveCustomerAddress($data) || ! $rates = Shipping::collectRates())
|
||||
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
|
||||
|
||||
$this->nonCoupon->apply();
|
||||
$this->nonCoupon->getApplicableRules();
|
||||
|
||||
Cart::collectTotals();
|
||||
|
||||
|
|
@ -145,7 +146,7 @@ class OnepageController extends Controller
|
|||
if (Cart::hasError() || !$shippingMethod || !Cart::saveShippingMethod($shippingMethod))
|
||||
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
|
||||
|
||||
$this->nonCoupon->apply();
|
||||
$this->nonCoupon->getApplicableRules();
|
||||
|
||||
Cart::collectTotals();
|
||||
|
||||
|
|
@ -164,7 +165,7 @@ class OnepageController extends Controller
|
|||
if (Cart::hasError() || !$payment || !Cart::savePaymentMethod($payment))
|
||||
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
|
||||
|
||||
$this->nonCoupon->apply();
|
||||
$this->nonCoupon->getApplicableRules();
|
||||
|
||||
$this->nonCoupon->checkOnShipping(Cart::getCart());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue