diff --git a/packages/Webkul/Checkout/src/Models/CartShippingRate.php b/packages/Webkul/Checkout/src/Models/CartShippingRate.php index a9d15e8b6..6ecf168cb 100755 --- a/packages/Webkul/Checkout/src/Models/CartShippingRate.php +++ b/packages/Webkul/Checkout/src/Models/CartShippingRate.php @@ -7,6 +7,8 @@ use Webkul\Checkout\Contracts\CartShippingRate as CartShippingRateContract; class CartShippingRate extends Model implements CartShippingRateContract { + protected $fillable = ['carrier', 'carrier_title', 'method', 'method_title', 'method_description', 'price', 'base_price']; + /** * Get the post that owns the comment. */ diff --git a/packages/Webkul/Discount/src/Actions/Action.php b/packages/Webkul/Discount/src/Actions/Action.php index 053a3e7ea..62268aa18 100644 --- a/packages/Webkul/Discount/src/Actions/Action.php +++ b/packages/Webkul/Discount/src/Actions/Action.php @@ -5,4 +5,6 @@ namespace Webkul\Discount\Actions; abstract class Action { abstract public function calculate($rule, $item, $cart); + + abstract public function calculateOnShipping($cart); } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Actions/BuyAGetB.php b/packages/Webkul/Discount/src/Actions/BuyAGetB.php index 21d8a5475..f1e47aa90 100644 --- a/packages/Webkul/Discount/src/Actions/BuyAGetB.php +++ b/packages/Webkul/Discount/src/Actions/BuyAGetB.php @@ -37,4 +37,16 @@ class BuyAGetB extends Action return $report; } + + /** + * Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled + */ + public function calculateOnShipping($cart) + { + $percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total; + + $discountOnShipping = ($percentOfDiscount / 100) * $cart->selected_shipping_rate->base_price; + + return $discountOnShipping; + } } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Actions/FixedAmount.php b/packages/Webkul/Discount/src/Actions/FixedAmount.php index 8ff965281..2b5a200f9 100644 --- a/packages/Webkul/Discount/src/Actions/FixedAmount.php +++ b/packages/Webkul/Discount/src/Actions/FixedAmount.php @@ -37,4 +37,16 @@ class FixedAmount extends Action return $report; } + + /** + * Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled + */ + public function calculateOnShipping($cart) + { + $percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total; + + $discountOnShipping = ($percentOfDiscount / 100) * $cart->selected_shipping_rate->base_price; + + return $discountOnShipping; + } } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Actions/PercentOfProduct.php b/packages/Webkul/Discount/src/Actions/PercentOfProduct.php index 07e004591..79683be5e 100644 --- a/packages/Webkul/Discount/src/Actions/PercentOfProduct.php +++ b/packages/Webkul/Discount/src/Actions/PercentOfProduct.php @@ -34,4 +34,16 @@ class PercentOfProduct extends Action return $report; } + + /** + * Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled + */ + public function calculateOnShipping($cart) + { + $percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total; + + $discountOnShipping = ($percentOfDiscount / 100) * $cart->selected_shipping_rate->base_price; + + return $discountOnShipping; + } } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Helpers/CouponAbleRule.php b/packages/Webkul/Discount/src/Helpers/CouponAbleRule.php index 7ae8a2585..c1aa89cdb 100644 --- a/packages/Webkul/Discount/src/Helpers/CouponAbleRule.php +++ b/packages/Webkul/Discount/src/Helpers/CouponAbleRule.php @@ -18,17 +18,10 @@ class CouponAbleRule extends Discount { $cart = Cart::getCart(); - if (auth()->guard('customer')->check()) { - $rules = $this->cartRule->findWhere([ - 'use_coupon' => 1, - 'status' => 1 - ]); - } else { - $rules = $this->cartRule->findWhere([ - 'use_coupon' => 1, - 'status' => 1 - ]); - } + $rules = $this->cartRule->findWhere([ + 'use_coupon' => 1, + 'status' => 1 + ]); $applicableRule = null; @@ -53,15 +46,22 @@ class CouponAbleRule extends Discount $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, ]); @@ -72,35 +72,43 @@ class CouponAbleRule extends Discount return $impact; } - $alreadyAppliedRule = $ifAlreadyApplied->first()->cart_rule; - - if ($alreadyAppliedRule->priority < $rule->priority) { + // 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; - } else if ($alreadyAppliedRule->priority == $applicableRule->priority) { - // tie breaker case + } - // end other rules - if ($alreadyAppliedRule->end_other_rules) { + 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]; - $actionInstance = new $this->rules[$alreadyAppliedRule->action_type]; + $alreadyAppliedRuleImpact = $actionInstance->calculate($alreadyAppliedRule, $item, $cart); - $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) { + 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); @@ -111,49 +119,4 @@ class CouponAbleRule extends Discount return false; } } - - /** - * Removes the already applied coupon on the current cart instance - * - * @return boolean - */ - public function remove() - { - $cart = Cart::getCart(); - - $existingRule = $this->cartRuleCart->findWhere([ - 'cart_id' => $cart->id - ]); - - if ($existingRule->count()) { - if ($existingRule->first()->cart_rule->use_coupon) { - $existingRule->first()->delete(); - - 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(); - - return true; - } else { - return false; - } - } else { - return false; - } - } } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Helpers/Discount.php b/packages/Webkul/Discount/src/Helpers/Discount.php index 704f15631..5b53d5383 100644 --- a/packages/Webkul/Discount/src/Helpers/Discount.php +++ b/packages/Webkul/Discount/src/Helpers/Discount.php @@ -213,12 +213,12 @@ abstract class Discount if ($rule->action_type == 'percent_of_product') { $item->update([ 'discount_percent' => $rule->discount_amount, - 'discount_amount' => $impact['discount'], + 'discount_amount' => core()->currency($impact['discount'], $cart->cart_currency_code), 'base_discount_amount' => $impact['discount'] ]); } else { $item->update([ - 'discount_amount' => $impact['discount'], + 'discount_amount' => core()->currency($impact['discount'], $cart->cart_currency_code), 'base_discount_amount' => $impact['discount'] ]); } @@ -287,6 +287,7 @@ abstract class Discount foreach ($cart->items as $item) { if ($item->base_total > $maxValue) { $maxValue = $item->total; + $maxWorthItem = [ 'id' => $item->id, 'price' => $item->price, diff --git a/packages/Webkul/Discount/src/Helpers/NonCouponAbleRule.php b/packages/Webkul/Discount/src/Helpers/NonCouponAbleRule.php index 035c67232..11c54d095 100644 --- a/packages/Webkul/Discount/src/Helpers/NonCouponAbleRule.php +++ b/packages/Webkul/Discount/src/Helpers/NonCouponAbleRule.php @@ -19,17 +19,10 @@ class NonCouponAbleRule extends Discount $applicableRules = array(); - if (auth()->guard('customer')->check()) { - $rules = $this->cartRule->findWhere([ - 'use_coupon' => 0, - 'status' => 1 - ]); - } else { - $rules = $this->cartRule->findWhere([ - 'use_coupon' => 0, - 'status' => 1 - ]); - } + $rules = $this->cartRule->findWhere([ + 'use_coupon' => 0, + 'status' => 1 + ]); $alreadyAppliedCartRuleCart = $this->cartRuleCart->findWhere([ 'cart_id' => $cart->id, @@ -47,11 +40,11 @@ class NonCouponAbleRule extends Discount // all discount is cleared fro mthe cart and cart items table $this->clearDiscount(); - return null; + return false; } if ($alreadyAppliedRule->use_coupon) { - return null; + return false; } } @@ -202,7 +195,7 @@ class NonCouponAbleRule extends Discount return array_first($applicableRules)['impact']; } else { - return null; + return false; } } } \ No newline at end of file diff --git a/packages/Webkul/Discount/src/Helpers/ValidatesDiscount.php b/packages/Webkul/Discount/src/Helpers/ValidatesDiscount.php index 92c1899bd..51e8de8b5 100644 --- a/packages/Webkul/Discount/src/Helpers/ValidatesDiscount.php +++ b/packages/Webkul/Discount/src/Helpers/ValidatesDiscount.php @@ -2,12 +2,31 @@ namespace Webkul\Discount\Helpers; -use Webkul\Discount\Helpers\Discount; +use Webkul\Discount\Repositories\CartRuleCartRepository as CartRuleCart; class ValidatesDiscount { + /** + * CartRuleCartRepository instance + */ + protected $cartRuleCart; + + /** + * Initializes type hinted dependencies + * + * @param CartRuleCart $cartRuleCart + */ + public function __construct(CartRuleCart $cartRuleCart) + { + $this->cartRuleCart = $cartRuleCart; + } + /** * Validates the currently applied cart rule on the current cart + * + * @param $cart instance + * + * @return mixed */ public function validate($cart) { @@ -18,7 +37,158 @@ class ValidatesDiscount if ($appliedRule->count()) { $appliedRule = $appliedRule->first()->cart_rule; - $applicability = $this->checkApplicability($appliedRule); + if ($appliedRule->status == 1) { + $applicability = $this->checkApplicability($appliedRule); + + if (! $applicability) { + return $this->remove(); + } else { + if ($appliedRule->free_shipping && $cart->selected_shipping_rate->base_price > 0) { + $cart->selected_shipping_rate->update([ + 'price' => 0, + 'base_price' => 0 + ]); + } else if ($appliedRule->free_shipping == 0 && $appliedRule->apply_to_shipping && $cart->selected_shipping_rate->base_price > 0) { + $actionType = config('discount-rules')[$appliedRule->action_type]; + + if ($appliedRule->apply_to_shipping) { + $actionInstance = new $actionType; + + $discountOnShipping = $actionInstance->calculateOnShipping($cart); + + $cart->selected_shipping_rate->update([ + 'price' => $cart->selected_shipping_rate->base_price - $discountOnShipping, + 'base_price' => $cart->selected_shipping_rate->price - core()->convertPrice($discountOnShipping, $cart->cart_currency_code) + ]); + } + } + } + } else { + return $this->remove(); + } + } + + return false; + } + + /** + * Checks whether coupon is getting applied on current cart instance or not + * + * @return boolean + */ + public function checkApplicability($rule) + { + $cart = \Cart::getCart(); + + $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; + } + + $channelBased = false; + + // channel based constraints + foreach ($rule->channels as $channel) { + if ($channel->channel_id == core()->getCurrentChannel()->id) { + $channelBased = true; + } + } + + $customerGroupBased = false; + + // customer groups based constraints + if (auth()->guard('customer')->check()) { + foreach ($rule->customer_groups as $customer_group) { + if (auth()->guard('customer')->user()->group->exists()) { + if ($customer_group->customer_group_id == auth()->guard('customer')->user()->group->id) { + $customerGroupBased = true; + } + } + } + } else { + foreach ($rule->customer_groups as $customer_group) { + if ($customer_group->customer_group->code == 'guest') { + $customerGroupBased = true; + } + } + } + + $conditionsBased = true; + + //check conditions + if ($rule->conditions != null) { + $conditions = json_decode(json_decode($rule->conditions)); + + $test_mode = array_last($conditions); + + if ($test_mode->criteria == 'any_is_true') { + $conditionsBased = $this->testIfAnyConditionIsTrue($conditions, $cart); + } + + if ($test_mode->criteria == 'all_are_true') { + $conditionsBased = $this->testIfAllConditionAreTrue($conditions, $cart); + } + } + + if ($timeBased && $channelBased && $customerGroupBased && $conditionsBased) { + return true; + } else { + return false; + } + } + + /** + * Removes the already applied coupon on the current cart instance + * + * @return boolean + */ + public function remove() + { + $cart = Cart::getCart(); + + $existingRule = $this->cartRuleCart->findWhere([ + 'cart_id' => $cart->id + ]); + + if ($existingRule->count()) { + $existingRule->first()->delete(); + + 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(); + + return true; + } else { + return false; } } } \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php index 7981eae97..a2306085b 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php @@ -232,7 +232,7 @@ class OnepageController extends Controller { $cart = Cart::getCart(); - // $this->validatesDiscount->validate($cart); + $this->validatesDiscount->validate($cart); if (! $cart->shipping_address) { throw new \Exception(trans('Please check shipping address.')); diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/onepage.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/onepage.blade.php index 2ba29bc61..2112e890d 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/onepage.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/onepage.blade.php @@ -488,7 +488,9 @@ error_message: null, - couponChanged: false + couponChanged: false, + + changeCount: 0 } }, @@ -531,8 +533,15 @@ }, changeCoupon: function() { - if (this.couponChanged == true) { + console.log('called'); + if (this.couponChanged == true && this.changeCount == 0) { + this.changeCount++; + + this.error_message = null; + this.couponChanged = false; + } else { + this.changeCount = 0; } }, diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php index 20098085f..6c5e903e9 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php @@ -53,7 +53,8 @@