Cart rules refactored
This commit is contained in:
parent
fbedc8a161
commit
bb12e07212
|
|
@ -1,8 +0,0 @@
|
|||
Discount Condition:
|
||||
Attribute Family is all the attributes
|
||||
Cart Attribute such as
|
||||
base_total,
|
||||
grand_total,
|
||||
shipping_free,
|
||||
shipping_not_free,
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ class FixedAmount extends Action
|
|||
{
|
||||
$cart = \Cart::getCart();
|
||||
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_sub_total;
|
||||
|
||||
return $percentOfDiscount;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class PercentOfProduct extends Action
|
|||
$totalDiscount = 0;
|
||||
|
||||
if ($rule->discount_amount >= 100) {
|
||||
$impact->discount = $cart->base_grand_total;
|
||||
$impact->discount = $cart->base_sub_total;
|
||||
|
||||
$impact->formatted_discount = core()->currency($impact->discount);
|
||||
} else {
|
||||
|
|
@ -106,7 +106,7 @@ class PercentOfProduct extends Action
|
|||
|
||||
$shippingRate = $cart->selected_shipping_rate;
|
||||
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_sub_total;
|
||||
|
||||
return $percentOfDiscount;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class WholeCartToFixed extends Action
|
|||
*/
|
||||
public function calculateOnShipping($cart)
|
||||
{
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_sub_total;
|
||||
|
||||
$discountOnShipping = ($percentOfDiscount / 100) * $cart->selected_shipping_rate->base_price;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ class WholeCartToPercent extends Action
|
|||
$impact = collect();
|
||||
|
||||
if ($rule->discount_amount >= 100) {
|
||||
$impact->discount = $cart->base_grand_total;
|
||||
$impact->discount = $cart->base_sub_total;
|
||||
} else {
|
||||
$impact->discount = ($rule->disc_amount / 100) * $cart->base_grand_total;
|
||||
$impact->discount = ($rule->disc_amount / 100) * $cart->base_sub_total;
|
||||
}
|
||||
|
||||
$impact->formatted_discount = core()->currency($impact->discount);
|
||||
|
|
@ -90,7 +90,7 @@ class WholeCartToPercent extends Action
|
|||
*/
|
||||
public function calculateOnShipping()
|
||||
{
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
|
||||
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_sub_total;
|
||||
|
||||
$discountOnShipping = ($percentOfDiscount / 100) * $cart->selected_shipping_rate->base_price;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,114 +10,35 @@ use Cart;
|
|||
class CouponAbleRule extends Discount
|
||||
{
|
||||
/**
|
||||
* Applies the couponable rule on the current cart instance
|
||||
* Applies the non couponable rule on the current cart instance
|
||||
*
|
||||
* @param String $code
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($code)
|
||||
{
|
||||
$cart = Cart::getCart();
|
||||
$this->validateIfAlreadyApplied();
|
||||
|
||||
$rules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 1,
|
||||
'status' => 1
|
||||
]);
|
||||
$rules = $this->getApplicableRules($code);
|
||||
|
||||
$applicableRule = null;
|
||||
if ($rules->count() == 1) {
|
||||
$rule = $rules->first();
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
if ($rule->use_coupon && ($rule->coupons->code == $code)) {
|
||||
$applicableRule = $rule;
|
||||
$canApply = $this->canApply($rule);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($canApply) {
|
||||
$this->save($rule);
|
||||
|
||||
if (! isset($applicableRule)) {
|
||||
return false;
|
||||
}
|
||||
$this->updateCartItemAndCart($rule);
|
||||
|
||||
$applicability = $this->checkApplicability($applicableRule);
|
||||
|
||||
if ($applicability) {
|
||||
$item = $cart->items;
|
||||
|
||||
$actionInstance = new $this->rules['cart'][$applicableRule->action_type];
|
||||
|
||||
$impact = $actionInstance->calculate($applicableRule, $item, $cart);
|
||||
|
||||
if ($impact->discount == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// avoid applying the same rule
|
||||
$ifAlreadyApplied = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id,
|
||||
'cart_rule_id' => $applicableRule->id
|
||||
]);
|
||||
|
||||
if ($ifAlreadyApplied->count() == 1) {
|
||||
// can give a message that coupon is already applied
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the rule ain't same
|
||||
$ifAlreadyApplied = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id,
|
||||
]);
|
||||
|
||||
if ($ifAlreadyApplied->count() == 0) {
|
||||
$this->save($applicableRule);
|
||||
|
||||
return $impact;
|
||||
}
|
||||
|
||||
// the only case where a non couponable rule defeats couponable rule
|
||||
if ($ifAlreadyApplied->first()->cart_rule->use_coupon == 0 && $ifAlreadyApplied->first()->cart_rule->end_other_rules == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($ifAlreadyApplied->first()->cart_rule->use_coupon == 1 && $ifAlreadyApplied->first()->cart_rule->end_other_rules == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($ifAlreadyApplied->first()->cart_rule->use_coupon == 1) {
|
||||
$alreadyAppliedRule = $ifAlreadyApplied->first()->cart_rule;
|
||||
|
||||
if ($alreadyAppliedRule->priority < $applicableRule->priority) {
|
||||
return false;
|
||||
} else if ($alreadyAppliedRule->priority == $applicableRule->priority) {
|
||||
$actionInstance = new $this->rules[$alreadyAppliedRule->action_type];
|
||||
|
||||
$alreadyAppliedRuleImpact = $actionInstance->calculate($alreadyAppliedRule, $item, $cart);
|
||||
|
||||
if ($alreadyAppliedRule->discount > $impact->discount) {
|
||||
return false;
|
||||
} else if ($alreadyAppliedRule->discount < $impact->discount) {
|
||||
$this->save($applicableRule);
|
||||
|
||||
return $impact;
|
||||
} else {
|
||||
// least id case
|
||||
if ($applicableRule->id < $alreadyAppliedRule->id) {
|
||||
$this->save($applicableRule);
|
||||
|
||||
return $impact;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->save($applicableRule);
|
||||
|
||||
return $impact;
|
||||
}
|
||||
} else {
|
||||
$this->save($applicableRule);
|
||||
|
||||
return $impact;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -133,33 +54,8 @@ class CouponAbleRule extends Discount
|
|||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if ($existingRule->count()) {
|
||||
$existingRule->first()->delete();
|
||||
|
||||
$this->resetShipping($cart);
|
||||
|
||||
foreach ($cart->items as $item) {
|
||||
if ($item->discount_amount > 0) {
|
||||
$item->update([
|
||||
'discount_amount' => 0,
|
||||
'base_discount_amount' => 0,
|
||||
'discount_percent' => 0,
|
||||
'coupon_code' => NULL
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$cart->update([
|
||||
'coupon_code' => NULL,
|
||||
'discount_amount' => 0,
|
||||
'base_discount_amount' => 0
|
||||
]);
|
||||
|
||||
Cart::collectTotals();
|
||||
$this->clearDiscount();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,12 +56,19 @@ abstract class Discount
|
|||
*
|
||||
* @return collection $rules
|
||||
*/
|
||||
public function getApplicableRules($usecoupon = false)
|
||||
public function getApplicableRules($code = null)
|
||||
{
|
||||
if ($code != null) {
|
||||
$rules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 1,
|
||||
'status' => 1
|
||||
]);
|
||||
} else {
|
||||
$rules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 0,
|
||||
'status' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
$filteredRules = collect();
|
||||
|
||||
|
|
@ -185,19 +192,64 @@ abstract class Discount
|
|||
{
|
||||
$cart = \Cart::getCart();
|
||||
|
||||
$alreadyAppliedRule = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id,
|
||||
'cart_rule_id' => $rule->id
|
||||
$alreadyApplied = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if ($alreadyAppliedRule->count()) {
|
||||
if ($this->validateRule($alreadyAppliedRule->first()->cart_rule)) {
|
||||
if ($alreadyApplied->count() && $alreadyApplied->first()->cart_rule->id == $rule->id) {
|
||||
if ($this->validateRule($alreadyApplied->first()->cart_rule)) {
|
||||
return false;
|
||||
} else {
|
||||
$this->clearDiscount();
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if ($alreadyApplied->count() && $alreadyApplied->first()->cart_rule->id != $rule->id && ! $alreadyApplied->first()->cart_rule->end_other_rules) {
|
||||
if ($rule->use_coupon) {
|
||||
if ($alreadyApplied->first()->cart_rule->use_coupon) {
|
||||
$rules = collect();
|
||||
|
||||
$alreadyAppliedRule = $alreadyApplied->first()->cart_rule;
|
||||
$alreadyAppliedRule->impact = $this->calculateImpact($alreadyAppliedRule);
|
||||
|
||||
$rule->impact = $this->calculateImpact($alreadyAppliedRule);
|
||||
|
||||
$rules->push($alreadyAppliedRule);
|
||||
$rules->push($rule);
|
||||
|
||||
$result = $this->breakTie($rules);
|
||||
|
||||
if ($result->id == $rule->id) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// this case will work when non couponable rule is applied and another non couponable rule is created
|
||||
// again break tie
|
||||
$rules = collect();
|
||||
|
||||
$alreadyAppliedRule = $alreadyApplied->first()->cart_rule;
|
||||
$alreadyAppliedRule->impact = $this->calculateImpact($alreadyAppliedRule);
|
||||
|
||||
$rule->impact = $this->calculateImpact($alreadyAppliedRule);
|
||||
|
||||
$rules->push($alreadyAppliedRule);
|
||||
$rules->push($rule);
|
||||
|
||||
$result = $this->breakTie($rules);
|
||||
|
||||
if ($result) {
|
||||
if ($result->id != $rule->id) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -380,8 +432,7 @@ abstract class Discount
|
|||
$cart = \Cart::getCart();
|
||||
|
||||
$alreadyApplied = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id,
|
||||
'cart_rule_id' => $rule->id
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if ($alreadyApplied->count()) {
|
||||
|
|
@ -443,7 +494,9 @@ abstract class Discount
|
|||
/**
|
||||
* Resets the shipping for the current items in the cart
|
||||
*
|
||||
* @return void
|
||||
* @param Cart $cart
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function resetShipping($cart)
|
||||
{
|
||||
|
|
@ -479,7 +532,9 @@ abstract class Discount
|
|||
/**
|
||||
* Update discount for least worth item
|
||||
*
|
||||
* @return boolean
|
||||
* @param CartRule $rule
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function updateCartItemAndCart($rule)
|
||||
{
|
||||
|
|
@ -516,9 +571,9 @@ abstract class Discount
|
|||
]);
|
||||
}
|
||||
|
||||
if ($rule->free_shipping || $rule->apply_on_shipping) {
|
||||
$this->applyOnShipping($rule);
|
||||
}
|
||||
// if ($rule->free_shipping || $rule->apply_on_shipping) {
|
||||
// $this->applyOnShipping($rule);
|
||||
// }
|
||||
|
||||
Cart::collectTotals();
|
||||
|
||||
|
|
@ -528,7 +583,7 @@ abstract class Discount
|
|||
/**
|
||||
* Removes any cart rule from the current cart instance
|
||||
*
|
||||
* @return void
|
||||
* @return Boolean
|
||||
*/
|
||||
public function clearDiscount()
|
||||
{
|
||||
|
|
@ -536,6 +591,7 @@ abstract class Discount
|
|||
|
||||
$cartItems = $cart->items;
|
||||
|
||||
// remove all the discount properties from items
|
||||
foreach ($cartItems as $item) {
|
||||
$item->update([
|
||||
'coupon_code' => NULL,
|
||||
|
|
@ -545,39 +601,68 @@ abstract class Discount
|
|||
]);
|
||||
}
|
||||
|
||||
// remove all the discount properties from cart
|
||||
$cart->update([
|
||||
'coupon_code' => NULL,
|
||||
'discount_amount' => 0,
|
||||
'base_discount_amount' => 0
|
||||
]);
|
||||
|
||||
// find & remove cart rule from cart rule cart resource
|
||||
$cartRuleCart = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
$cartRuleCart->first()->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the currently applied cart rule
|
||||
*
|
||||
* @return boolean
|
||||
* @param CartRule $rule
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function validateRule($rule)
|
||||
{
|
||||
$applicability = $this->checkApplicability($rule);
|
||||
|
||||
if ($applicability) {
|
||||
if ($rule->status) {
|
||||
if ($applicability && $rule->status) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will validate already applied rule
|
||||
*
|
||||
* @return Void
|
||||
*/
|
||||
public function validateIfAlreadyApplied()
|
||||
{
|
||||
$cart = \Cart::getCart();
|
||||
|
||||
$alreadyAppliedRule = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if ($alreadyAppliedRule->count()) {
|
||||
$alreadyAppliedRule = $alreadyAppliedRule->first()->cart_rule;
|
||||
|
||||
$result = $this->validateRule($alreadyAppliedRule);
|
||||
|
||||
if (! $result)
|
||||
$this->clearDiscount();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreives all the payment methods from application config
|
||||
*
|
||||
* @return array
|
||||
* @return Array
|
||||
*/
|
||||
public function getPaymentMethods()
|
||||
{
|
||||
|
|
@ -602,7 +687,11 @@ abstract class Discount
|
|||
* Checks the rule against the current cart instance whether rule conditions are applicable
|
||||
* or not
|
||||
*
|
||||
* @return boolean
|
||||
* @param Array $conditions
|
||||
*
|
||||
* @param Cart $cart
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
protected function testIfAllConditionAreTrue($conditions, $cart)
|
||||
{
|
||||
|
|
@ -702,14 +791,14 @@ abstract class Discount
|
|||
break;
|
||||
}
|
||||
} else if ($test_condition == '{}') {
|
||||
if (str_contains($test_value, $actual_value)) {
|
||||
$result = true;
|
||||
if (! str_contains($test_value, $actual_value)) {
|
||||
$result = false;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '!{}') {
|
||||
if (! str_contains($test_value, $actual_value)) {
|
||||
$result = true;
|
||||
if (str_contains($test_value, $actual_value)) {
|
||||
$result = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -724,7 +813,11 @@ abstract class Discount
|
|||
* Checks the rule against the current cart instance whether rule conditions are applicable
|
||||
* or not
|
||||
*
|
||||
* @return boolean
|
||||
* @param Array $conditions
|
||||
*
|
||||
* @param Cart $cart
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
protected function testIfAnyConditionIsTrue($conditions, $cart)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
namespace Webkul\Discount\Helpers;
|
||||
|
||||
use Webkul\Discount\Helpers\Discount;
|
||||
|
||||
use Webkul\Discount\Repositories\CartRuleCartRepository as CartRuleCart;
|
||||
use Cart;
|
||||
|
||||
class NonCouponAbleRule extends Discount
|
||||
|
|
@ -11,10 +11,14 @@ class NonCouponAbleRule extends Discount
|
|||
/**
|
||||
* Applies the non couponable rule on the current cart instance
|
||||
*
|
||||
* @param String $code
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($code = null)
|
||||
{
|
||||
$this->validateIfAlreadyApplied();
|
||||
|
||||
$rules = $this->getApplicableRules();
|
||||
|
||||
if ($rules->count() == 1) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class ValidatesDiscount extends Discount
|
|||
|
||||
public function apply($code)
|
||||
{
|
||||
return ;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -34,27 +34,9 @@ class ValidatesDiscount extends Discount
|
|||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function validate($cart)
|
||||
public function validate()
|
||||
{
|
||||
$appliedRule = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if ($appliedRule->count()) {
|
||||
$appliedRule = $appliedRule->first()->cart_rule;
|
||||
|
||||
if ($appliedRule->status == 1) {
|
||||
$applicability = $this->checkApplicability($appliedRule);
|
||||
|
||||
if (! $applicability) {
|
||||
return $this->remove();
|
||||
}
|
||||
} else {
|
||||
return $this->remove();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
$this->validateIfAlreadyApplied();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -167,8 +167,6 @@ class OnepageController extends Controller
|
|||
|
||||
$this->nonCoupon->apply();
|
||||
|
||||
$this->nonCoupon->checkOnShipping(Cart::getCart());
|
||||
|
||||
Cart::collectTotals();
|
||||
|
||||
$cart = Cart::getCart();
|
||||
|
|
@ -235,7 +233,7 @@ class OnepageController extends Controller
|
|||
{
|
||||
$cart = Cart::getCart();
|
||||
|
||||
$this->validatesDiscount->validate($cart);
|
||||
$this->validatesDiscount->validate();
|
||||
|
||||
if (! $cart->shipping_address) {
|
||||
throw new \Exception(trans('Please check shipping address.'));
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ class SubscriptionController extends Controller
|
|||
|
||||
/**
|
||||
* Subscribes email to the email subscription list
|
||||
*
|
||||
* @return Redirect
|
||||
*/
|
||||
public function subscribe()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -289,9 +289,5 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
|
|||
|
||||
Route::get('pages/{slug}', 'Webkul\CMS\Http\Controllers\Shop\PagePresenterController@presenter')->name('shop.cms.page');
|
||||
|
||||
Route::view('onecol', 'shop::cms.onecol');
|
||||
Route::view('twocol', 'shop::cms.twocol');
|
||||
Route::view('threecol', 'shop::cms.threecol');
|
||||
|
||||
Route::fallback('Webkul\Shop\Http\Controllers\HomeController@notFound');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue