/** * Apply sign up fee or recurring fee discount before tax is calculated * * * @since 1.2 */ public static function apply_subscription_discount_before_tax($original_price, $product, $cart) { global $woocommerce; if (!WC_Subscriptions_Product::is_subscription($product['product_id'])) { return $original_price; } $price = $original_price; if (!empty($cart->applied_coupons)) { foreach ($cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->apply_before_tax() && $coupon->is_valid()) { // Sign up fee discount if ('sign_up_fee' == WC_Subscriptions_Cart::get_recalculation_type() && 'sign_up_fee' == $coupon->type || 'base_recurring_fee' == WC_Subscriptions_Cart::get_recalculation_type() && 'recurring_fee' == $coupon->type || 0 == WC_Subscriptions_Cart::get_cart_subscription_sign_up_fee() && 'recurring_fee' == $coupon->type) { if ($original_price < $coupon->amount) { $discount_amount = $original_price; } else { $discount_amount = $coupon->amount; } $price = $original_price - $coupon->amount; if ($price < 0) { $price = 0; } // add to discount totals $woocommerce->cart->discount_cart = $woocommerce->cart->discount_cart + $discount_amount * $product['quantity']; } } } } return $price; }
/** * Automatically apply coupons. * * Also removes auto-apply coupons (although that should happen * automatically, it seems we're on the safer side doing that as well * here). */ public static function wp_init() { global $wpdb, $woocommerce; if (isset($woocommerce) && isset($woocommerce->cart) && $woocommerce->cart->coupons_enabled()) { $coupons = $wpdb->get_results("SELECT DISTINCT ID, post_title FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id WHERE {$wpdb->posts}.post_status = 'publish' AND {$wpdb->postmeta}.meta_key = '_vd_auto'"); if ($coupons && count($coupons) > 0) { foreach ($coupons as $coupon) { $coupon_code = $coupon->post_title; $coupon = new WC_Coupon($coupon_code); if ($coupon->id) { if ($coupon->is_valid()) { if (!$woocommerce->cart->has_discount($coupon_code)) { $woocommerce->cart->add_discount($coupon_code); $msg = ''; $message = get_post_meta($coupon->id, '_vd_auto_message_display', true); $show_description = get_post_meta($coupon->id, '_vd_auto_description_display', true) == 'yes'; $show_info = get_post_meta($coupon->id, '_vd_auto_info_display', true) == 'yes'; if (!empty($message)) { $msg .= sprintf('<div class="coupon display message %s">', wp_strip_all_tags($coupon->code)); $msg .= stripslashes(wp_filter_kses($message)); $msg .= '</div>'; } if ($show_description) { if ($post = get_post($coupon->id)) { if (!empty($post->post_excerpt)) { $msg .= sprintf('<div class="coupon display description %s">', wp_strip_all_tags($coupon->code)); $msg .= stripslashes(wp_filter_kses($post->post_excerpt)); $msg .= '</div>'; } } } if ($show_info) { $msg .= sprintf('<div class="coupon display volume-discount %s">', wp_strip_all_tags($coupon->code)); $msg .= WooCommerce_Volume_Discount_Coupons_Shortcodes::get_volume_discount_info($coupon); $msg .= '</div>'; } if (!empty($msg)) { $woocommerce->add_message($msg); } } } else { if ($woocommerce->cart->has_discount($coupon_code)) { if (!empty($woocommerce->cart->applied_coupons)) { foreach ($woocommerce->cart->applied_coupons as $index => $code) { if ($coupon_code == $code) { unset($woocommerce->cart->applied_coupons[$index]); } } } } } } } } } }
/** * Evaluate common validity based on op and coupon codes. * * @param array $atts * @return boolean */ private static function _is_valid($atts) { $options = shortcode_atts(array('coupon' => null, 'code' => null, 'op' => 'and'), $atts); $code = null; if (!empty($options['code'])) { $code = $options['code']; } else { if (!empty($options['coupon'])) { $code = $options['coupon']; } } if ($code === null) { return ''; } $codes = array_map('trim', explode(',', $code)); $validities = array(); foreach ($codes as $code) { $coupon = new WC_Coupon($code); if ($coupon->id) { $validities[] = $coupon->is_valid(); } } if (count($validities) > 0) { $valid = $options['op'] != 'or'; foreach ($validities as $validity) { if ($options['op'] == 'or') { $valid = $valid || $validity; if ($valid) { break; } } else { $valid = $valid && $validity; if (!$valid) { break; } } } } else { $valid = false; } }
$products = ins_get_products(); $cart_items = $woocommerce->cart->cart_contents; ?> <div class="add_discount" style="padding-top:1em; border-collapse:unset; font-size: 12px;"> <h2 class="label">Add A Coupon</h2> <table id="coupons" style="border-bottom:1px solid #333;"> <tr> <td class="coupon"><label for="coupon_select">Select a Coupon</label></td> <td class="coupon"><select class="chosen_select" style="width:200px;" id="coupon_select" data-placeholder="Select a Coupon" onblur="get_discount_info();" style="width:300px;"> <option></option> <?php if ($coupons) { foreach ($coupons as $coupon) { $coupon = new WC_Coupon($coupon->post_title); if (!$woocommerce->cart->has_discount($coupon->code) && $coupon->is_valid()) { ?> <option value="<?php echo esc_attr($coupon->code); ?> "><?php echo esc_html($coupon->code); ?> </option> <?php } else { var_dump($coupon->error_message); } } } ?>
/** * is_available function. * * @access public * @param mixed $package * @return bool */ function is_available($package) { global $woocommerce; if ($this->enabled == "no") { return false; } $ship_to_countries = ''; if ($this->availability == 'specific') { $ship_to_countries = $this->countries; } else { if (get_option('woocommerce_allowed_countries') == 'specific') { $ship_to_countries = get_option('woocommerce_specific_allowed_countries'); } } if (is_array($ship_to_countries)) { if (!in_array($package['destination']['country'], $ship_to_countries)) { return false; } } // Enabled logic $is_available = false; $has_coupon = false; $has_met_min_amount = false; if (in_array($this->requires, array('coupon', 'either', 'both'))) { if ($woocommerce->cart->applied_coupons) { foreach ($woocommerce->cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->is_valid() && $coupon->enable_free_shipping()) { $has_coupon = true; } } } } if (in_array($this->requires, array('min_amount', 'either', 'both')) && isset($woocommerce->cart->cart_contents_total)) { if ($woocommerce->cart->prices_include_tax) { $total = $woocommerce->cart->cart_contents_total + array_sum($woocommerce->cart->taxes); } else { $total = $woocommerce->cart->cart_contents_total; } if ($total >= $this->min_amount) { $has_met_min_amount = true; } } switch ($this->requires) { case 'min_amount': if ($has_met_min_amount) { $is_available = true; } break; case 'coupon': if ($has_coupon) { $is_available = true; } break; case 'both': if ($has_met_min_amount && $has_coupon) { $is_available = true; } break; case 'either': if ($has_met_min_amount || $has_coupon) { $is_available = true; } break; default: $is_available = true; break; } return apply_filters('woocommerce_shipping_' . $this->id . '_is_available', $is_available); }
public function get_reward_from_order($order_id, $wooprice = false, $extra = true) { global $woocommerce; $order = new WC_Order($order_id); $amount = $this->get_order_amount($order); $extra_reward = 0; if (sizeof($order->get_items()) > 0) { foreach ($order->get_items() as $item) { if ((isset($item['id']) && $item['id'] > 0 || isset($item['product_id']) && $item['product_id'] > 0 || (isset($item['variation_id']) && $item['variation_id'] > 0)) && $extra) { $_product = $order->get_product_from_item($item); $no_reward = get_post_meta($_product->id, '_no_reward', true); if (!$no_reward) { $extra_reward += $this->get_product_extra_rewards($_product, $item['qty'], false); } } } } $reward = $this->get_rewards_amount($amount) + $extra_reward; if (isset($woocommerce->cart->applied_coupons) && $woocommerce->cart->applied_coupons) { foreach ($woocommerce->cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->is_valid() && $coupon->type == 'fixed_reward') { $reward += $coupon->amount; } else { if ($coupon->is_valid() && $coupon->type == 'percent_reward') { $reward += $coupon->amount * $reward; } } } } if (isset($order->payment_method)) { $gateway_extra = $this->calculate_payments_extras($order->payment_method, $amount); $reward += $gateway_extra; } if ($this->settings['swr_rewards_max_points'] != '' && intval($this->settings['swr_rewards_max_points']) < $reward) { $reward = $this->settings['swr_rewards_max_points']; } return $this->format_reward($reward, $wooprice); }
/** * Function to apply Gift Certificate's credit to cart */ public function apply_smart_coupon_to_cart() { $this->global_wc()->cart->smart_coupon_credit_used = array(); $cart_contains_subscription = false; if (class_exists('WC_Subscriptions_Cart') && WC_Subscriptions_Cart::cart_contains_subscription()) { $cart_contains_subscription = true; } if ($cart_contains_subscription) { $calculation_type = WC_Subscriptions_Cart::get_calculation_type(); if ($calculation_type == 'recurring_total') { return; } } if ($this->global_wc()->cart->applied_coupons) { foreach ($this->global_wc()->cart->applied_coupons as $code) { $smart_coupon = new WC_Coupon($code); if ($smart_coupon->is_valid() && $smart_coupon->discount_type == 'smart_coupon') { $order_total = $this->global_wc()->cart->cart_contents_total + $this->global_wc()->cart->tax_total + $this->global_wc()->cart->shipping_tax_total + $this->global_wc()->cart->shipping_total; if ($this->global_wc()->cart->discount_total != 0 && $this->global_wc()->cart->discount_total + $smart_coupon->amount > $order_total) { $smart_coupon->amount = $order_total - $this->global_wc()->cart->discount_total; } elseif ($smart_coupon->amount > $order_total) { $smart_coupon->amount = $order_total; } $this->global_wc()->cart->discount_total = $this->global_wc()->cart->discount_total + $smart_coupon->amount; if ($cart_contains_subscription) { WC_Subscriptions_Cart::increase_coupon_discount_amount($code, $smart_coupon->amount); } $this->global_wc()->cart->smart_coupon_credit_used[$code] = $smart_coupon->amount; //Code for displaying the price label for the store credit coupons if (empty($this->global_wc()->cart->coupon_discount_amounts)) { $this->global_wc()->cart->coupon_discount_amounts = array(); } $this->global_wc()->cart->coupon_discount_amounts[$code] = $smart_coupon->amount; } } } }
/** * Performs coupon checks after checkout validation. * * @param array $posted posted form data */ public static function woocommerce_after_checkout_validation($posted) { global $woocommerce; if (isset($woocommerce->cart)) { $cart = $woocommerce->cart; if (!empty($cart->applied_coupons)) { if (method_exists('Affiliates_Attributes_WordPress', 'get_affiliate_for_coupon')) { $valid = true; $emails = array($posted['billing_email']); if (is_user_logged_in()) { $current_user = wp_get_current_user(); $emails[] = $current_user->user_email; } $emails = array_map('sanitize_email', array_map('strtolower', $emails)); self::remove_filters(); foreach ($cart->applied_coupons as $key => $code) { $coupon = new WC_Coupon($code); if (!is_wp_error($coupon->is_valid())) { if ($affiliate_id = Affiliates_Attributes_WordPress::get_affiliate_for_coupon($coupon->code)) { if ($user_id = get_current_user_id()) { if ($affiliate_ids = affiliates_get_user_affiliate($user_id)) { if (in_array($affiliate_id, $affiliate_ids)) { $valid = false; break; } } } if ($affiliate = affiliates_get_affiliate($affiliate_id)) { if (isset($affiliate['email']) && in_array(strtolower($affiliate['email']), $emails)) { $valid = false; break; } } } } } self::add_filters(); if (!$valid) { $coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_INVALID_REMOVED); unset($cart->applied_coupons[$key]); $woocommerce->session->coupon_codes = $cart->applied_coupons; $woocommerce->session->refresh_totals = true; } } } } }
/** * Apply sign up fee or recurring fee discount * * @since 1.2 */ public static function apply_subscription_discount($original_price, $cart_item, $cart) { $product_id = $cart_item['data']->is_type(array('subscription_variation')) ? $cart_item['data']->variation_id : $cart_item['data']->id; if (!WC_Subscriptions_Product::is_subscription($product_id)) { return $original_price; } $price = $calculation_price = $original_price; $calculation_type = WC_Subscriptions_Cart::get_calculation_type(); if (!empty($cart->applied_coupons)) { foreach ($cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->apply_before_tax() && $coupon->is_valid()) { $apply_recurring_coupon = $apply_recurring_percent_coupon = $apply_initial_coupon = $apply_initial_percent_coupon = false; // Apply recurring fee discounts to recurring total calculations if ('recurring_total' == $calculation_type) { $apply_recurring_coupon = 'recurring_fee' == $coupon->type ? true : false; $apply_recurring_percent_coupon = 'recurring_percent' == $coupon->type ? true : false; } if ('none' == $calculation_type) { // If all items have a free trial we don't need to apply recurring coupons to the initial total if (!WC_Subscriptions_Cart::all_cart_items_have_free_trial()) { if ('recurring_fee' == $coupon->type) { $apply_initial_coupon = true; } if ('recurring_percent' == $coupon->type) { $apply_initial_percent_coupon = true; } } // Apply sign-up discounts to initial total if (!empty($cart_item['data']->subscription_sign_up_fee)) { if ('sign_up_fee' == $coupon->type) { $apply_initial_coupon = true; } if ('sign_up_fee_percent' == $coupon->type) { $apply_initial_percent_coupon = true; } $calculation_price = $cart_item['data']->subscription_sign_up_fee; } } if ($apply_recurring_coupon || $apply_initial_coupon) { $discount_amount = $calculation_price < $coupon->amount ? $calculation_price : $coupon->amount; // Recurring coupons only apply when there is no free trial (carts can have a mix of free trial and non free trial items) if ($apply_initial_coupon && 'recurring_fee' == $coupon->type && !empty($cart_item['data']->subscription_trial_length)) { $discount_amount = 0; } $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity']; $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']); $price = $price - $discount_amount; } elseif ($apply_recurring_percent_coupon) { $discount_amount = round($calculation_price / 100 * $coupon->amount, WC()->cart->dp); $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity']; $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']); $price = $price - $discount_amount; } elseif ($apply_initial_percent_coupon) { // Recurring coupons only apply when there is no free trial (carts can have a mix of free trial and non free trial items) if ('recurring_percent' == $coupon->type && empty($cart_item['data']->subscription_trial_length)) { $amount_to_discount = $cart_item['data']->subscription_price; } else { $amount_to_discount = 0; } // Sign up fee coupons only apply to sign up fees if ('sign_up_fee_percent' == $coupon->type) { $amount_to_discount = $cart_item['data']->subscription_sign_up_fee; } $discount_amount = round($amount_to_discount / 100 * $coupon->amount, WC()->cart->dp); $cart->discount_cart = $cart->discount_cart + $discount_amount * $cart_item['quantity']; $cart = self::increase_coupon_discount_amount($cart, $coupon->code, $discount_amount * $cart_item['quantity']); $price = $price - $discount_amount; } } } if ($price < 0) { $price = 0; } } return $price; }
public function ins_ajax_get_discount() { global $woocommerce, $current_user; $total_discount = 0.0; if (isset($_POST['discount'])) { if (is_array($_POST['discount'])) { $discount = $_POST['discount']; $disc_code = $discount['disc_reason'] . time(); $coupon_code = add_filter('woocommerce_get_shop_coupon_data', array($this, 'ins_get_discount_code'), $disc_code); } else { $coupon_code = $_POST['discount']; } $coupon = new WC_Coupon($coupon_code); $cart_items = $woocommerce->cart->cart_contents; if ($coupon->is_valid()) { $total_discount += $coupon->get_discount_amount($woocommerce->cart->total); $post = get_post($coupon->id); $coupon->amount = $coupon->type == 'percent' ? $coupon->amount . '%' : wc_price($coupon->amount); $coupon->minimum_amount = isset($_POST['call']) && $_POST['call'] == 'edit' ? $coupon->minimum_amount : wc_price($coupon->minimum_amount); $coupon->expiry_date = is_long($coupon->expiry_date) ? date('m/d/Y', $coupon->expiry_date) : $coupon->expiry_date; $coupon->usage_count = empty($coupon->usage_count) ? 0 : $coupon->usage_count; $this->json_return = array('success' => true, 'call' => 'update_item_display', 'coupon' => $coupon, 'discount' => $total_discount, 'description' => isset($post) ? $post->post_excerpt : $discount['disc_reason'] . ' discount created on ' . date('m/d/Y h:m:i a') . ' by ' . $current_user->user_login); if (isset($_POST['call'])) { $this->json_return['action'] = $_POST['call']; } } else { $this->json_return = array('success' => false, 'coupon_error' => $coupon->error_message); } } echo json_encode($this->json_return); die; }
/** * Applies a coupon code passed to the method. * * @param string $coupon_code - The code to apply * @return bool True if the coupon is applied, false if it does not exist or cannot be applied */ function add_discount($coupon_code) { global $woocommerce; // Coupons are globally disabled if (get_option('woocommerce_enable_coupons') == 'no') { return false; } $the_coupon = new WC_Coupon($coupon_code); if ($the_coupon->id) { // Check it can be used with cart $return = $the_coupon->is_valid(); if (!$return || is_wp_error($return)) { $woocommerce->add_error(is_wp_error($return) ? $return->get_error_message() : __('Invalid coupon.', 'woocommerce')); return false; } // Check if applied if ($woocommerce->cart->has_discount($coupon_code)) { $woocommerce->add_error(__('Discount code already applied!', 'woocommerce')); return false; } // If its individual use then remove other coupons if ($the_coupon->individual_use == 'yes') { $this->applied_coupons = array(); } foreach ($this->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->individual_use == 'yes') { $this->applied_coupons = array(); } } $this->applied_coupons[] = $coupon_code; $this->set_session(); $woocommerce->add_message(__('Discount code applied successfully.', 'woocommerce')); do_action('woocommerce_applied_coupon', $coupon_code); return true; } else { $woocommerce->add_error(__('Coupon does not exist!', 'woocommerce')); return false; } return false; }
/** * Formats cart contents for Klarna. * * Checks if WooCommerce cart is empty. If it is, there's no reason to proceed. * * @since 2.0.0 * @access public * * @return array $cart_contents Formatted array ready for Klarna. */ public function process_cart_contents() { global $woocommerce; $woocommerce->cart->calculate_shipping(); $woocommerce->cart->calculate_totals(); $cart = array(); // We need to keep track of order total, in case a smart coupon exceeds it $order_total = 0; foreach ($woocommerce->cart->get_cart() as $cart_item) { if ($cart_item['quantity']) { if ($cart_item['variation_id']) { $_product = wc_get_product($cart_item['variation_id']); } else { $_product = wc_get_product($cart_item['product_id']); } $item_name = $this->get_item_name($cart_item); $item_price = $this->get_item_price($cart_item); $item_quantity = $this->get_item_quantity($cart_item); $item_reference = $this->get_item_reference($_product); $item_discount_amount = $this->get_item_discount_amount($cart_item); $item_discount_rate = $this->get_item_discount_rate($cart_item); $item_tax_amount = $this->get_item_tax_amount($cart_item); $item_tax_rate = $this->get_item_tax_rate($cart_item, $_product); $item_total_amount = $this->get_item_total_amount($cart_item); if ($this->is_rest) { $klarna_item = array('reference' => $item_reference, 'name' => $item_name, 'quantity' => $item_quantity, 'unit_price' => $item_price, 'tax_rate' => $item_tax_rate, 'total_amount' => $item_total_amount, 'total_tax_amount' => $item_tax_amount, 'total_discount_amount' => $item_discount_amount); } else { $klarna_item = array('reference' => $item_reference, 'name' => $item_name, 'quantity' => $item_quantity, 'unit_price' => $item_price, 'tax_rate' => $item_tax_rate, 'discount_rate' => $item_discount_rate); } $cart[] = $klarna_item; $order_total += $item_quantity * $item_price; } } // Process fees if ($woocommerce->cart->fee_total > 0) { foreach ($woocommerce->cart->get_fees() as $cart_fee) { $fee_name = $this->get_fee_name($cart_fee); $fee_reference = $this->get_fee_reference($cart_fee); $fee_type = 'surcharge'; $fee_quantity = 1; $fee_unit_price = $this->get_fee_amount($cart_fee); $fee_total_amount = $this->get_fee_amount($cart_fee); $fee_tax_rate = $this->get_fee_tax_rate($cart_fee); $fee_tax_amount = $this->get_fee_tax_amount($cart_fee); if ($this->is_rest) { $klarna_fee_item = array('type' => $fee_type, 'reference' => $fee_reference, 'name' => $fee_name, 'quantity' => $fee_quantity, 'unit_price' => $fee_unit_price, 'total_amount' => $fee_total_amount, 'tax_rate' => $fee_tax_rate, 'total_tax_amount' => $fee_tax_amount); } else { $klarna_fee_item = array('reference' => $fee_reference, 'name' => $fee_name, 'quantity' => $fee_quantity, 'unit_price' => $fee_unit_price, 'tax_rate' => $fee_tax_rate); } $cart[] = $klarna_fee_item; $order_total += (int) $cart_fee->amount * 100; } } // Process shipping if ($woocommerce->shipping->get_packages()) { $shipping_name = $this->get_shipping_name(); $shipping_reference = $this->get_shipping_reference(); $shipping_amount = $this->get_shipping_amount(); $shipping_tax_rate = $this->get_shipping_tax_rate(); $shipping_tax_amount = $this->get_shipping_tax_amount(); if ($this->is_rest) { /* Temporarily return shipping to V3 No need to do this any longer, shipping is sent to Klarna as shipping_options parameter */ $shipping = array('type' => 'shipping_fee', 'reference' => $shipping_reference, 'name' => $shipping_name, 'quantity' => 1, 'unit_price' => $shipping_amount, 'tax_rate' => $shipping_tax_rate, 'total_amount' => $shipping_amount, 'total_tax_amount' => $shipping_tax_amount); } else { $shipping = array('type' => 'shipping_fee', 'reference' => $shipping_reference, 'name' => $shipping_name, 'quantity' => 1, 'unit_price' => $shipping_amount, 'tax_rate' => $shipping_tax_rate); } $cart[] = $shipping; $order_total += $shipping_amount; } // Process sales tax for US if ($this->is_rest && 'us' == $this->klarna_country) { $sales_tax = round(($woocommerce->cart->tax_total + $woocommerce->cart->shipping_tax_total) * 100); // Add sales tax line item $cart[] = array('type' => 'sales_tax', 'reference' => __('Sales Tax', 'woocommerce-gateway-klarna'), 'name' => __('Sales Tax', 'woocommerce-gateway-klarna'), 'quantity' => 1, 'unit_price' => $sales_tax, 'tax_rate' => 0, 'total_amount' => $sales_tax, 'total_discount_amount' => 0, 'total_tax_amount' => 0); $order_total += $sales_tax; } // Process discounts if (WC()->cart->applied_coupons) { foreach (WC()->cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if (!$coupon->is_valid()) { break; } $klarna_settings = get_option('woocommerce_klarna_checkout_settings'); if ('yes' != $klarna_settings['send_discounts_separately'] && $coupon->discount_type != 'smart_coupon') { break; } $coupon_name = $this->get_coupon_name($coupon); $coupon_amount = $this->get_coupon_amount($coupon); // Check if coupon amount exceeds order total if ($order_total < $coupon_amount) { $coupon_amount = $order_total; } if ($this->is_rest) { $cart[] = array('type' => 'discount', 'reference' => 'DISCOUNT', 'name' => $coupon_name, 'quantity' => 1, 'unit_price' => -$coupon_amount, 'total_amount' => -$coupon_amount, 'tax_rate' => 0, 'total_tax_amount' => 0); $order_total = $order_total - $coupon_amount; } else { $cart[] = array('type' => 'discount', 'reference' => 'DISCOUNT', 'name' => $coupon_name, 'quantity' => 1, 'unit_price' => -$coupon_amount, 'tax_rate' => 0); $order_total = $order_total - $coupon_amount; } } } return $cart; }
function apply_smart_coupon_to_cart() { global $woocommerce; $woocommerce->cart->smart_coupon_credit_used = array(); if ($woocommerce->cart->applied_coupons) { foreach ($woocommerce->cart->applied_coupons as $code) { $smart_coupon = new WC_Coupon($code); if ($smart_coupon->is_valid() && $smart_coupon->type == 'smart_coupon') { $order_total = $woocommerce->cart->cart_contents_total + $woocommerce->cart->tax_total + $woocommerce->cart->shipping_tax_total + $woocommerce->cart->shipping_total; if ($woocommerce->cart->discount_total != 0 && $woocommerce->cart->discount_total + $smart_coupon->amount > $order_total) { $smart_coupon->amount = $order_total - $woocommerce->cart->discount_total; } elseif ($smart_coupon->amount > $order_total) { $smart_coupon->amount = $order_total; } $woocommerce->cart->discount_total = $woocommerce->cart->discount_total + $smart_coupon->amount; $woocommerce->cart->smart_coupon_credit_used[$code] = $smart_coupon->amount; } } } }
/** * Evaluate common validity based on op and coupon codes. * * @param array $atts * @return boolean */ private static function _is_valid($atts) { global $woocommerce_coupon_shortcodes_codes; $options = shortcode_atts(array('coupon' => null, 'code' => null, 'op' => 'and'), $atts); $code = null; if (!empty($options['code'])) { $code = $options['code']; } else { if (!empty($options['coupon'])) { $code = $options['coupon']; } } if ($code === null) { return ''; } $codes = array_map('trim', explode(',', $code)); $woocommerce_coupon_shortcodes_codes = $codes; $validities = array(); foreach ($codes as $code) { $coupon = new WC_Coupon($code); if ($coupon->id) { $validities[] = $coupon->is_valid(); } } switch (strtolower($options['op'])) { case 'and': $valid = self::conj($validities); break; default: $valid = self::disj($validities); } return $valid; }
/** * Remove coupons from the cart of a defined type. Type 1 is before tax, type 2 is after tax. * * @params int type - 0 for all, 1 for before tax, 2 for after tax */ public function remove_coupons($type = 0) { global $woocommerce; if (1 == $type) { if ($this->applied_coupons) { foreach ($this->applied_coupons as $index => $code) { $coupon = new WC_Coupon($code); if ($coupon->is_valid() && $coupon->apply_before_tax()) { unset($this->applied_coupons[$index]); } } } $woocommerce->session->coupon_codes = $this->applied_coupons; } elseif ($type == 2) { if ($this->applied_coupons) { foreach ($this->applied_coupons as $index => $code) { $coupon = new WC_Coupon($code); if ($coupon->is_valid() && !$coupon->apply_before_tax()) { unset($this->applied_coupons[$index]); } } } $woocommerce->session->coupon_codes = $this->applied_coupons; } else { unset($woocommerce->session->coupon_codes, $woocommerce->session->coupon_amounts); $this->applied_coupons = array(); } }
/** * Applies a coupon code * * @param string code The code to apply * @return bool True if the coupon is applied, false if it does not exist or cannot be applied */ function add_discount($coupon_code) { global $woocommerce; $the_coupon = new WC_Coupon($coupon_code); if ($the_coupon->id) { // Check if applied if ($woocommerce->cart->has_discount($coupon_code)) { $woocommerce->add_error(__('Discount code already applied!', 'woocommerce')); return false; } // Check it can be used with cart if (!$the_coupon->is_valid()) { $woocommerce->add_error(__('Invalid coupon.', 'woocommerce')); return false; } // If its individual use then remove other coupons if ($the_coupon->individual_use == 'yes') { $this->applied_coupons = array(); } foreach ($this->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->individual_use == 'yes') { $this->applied_coupons = array(); } } $this->applied_coupons[] = $coupon_code; $this->set_session(); $woocommerce->add_message(__('Discount code applied successfully.', 'woocommerce')); return true; } else { $woocommerce->add_error(__('Coupon does not exist!', 'woocommerce')); return false; } return false; }
/** * Function to apply discounts to a product and get the discounted price (before tax is applied) * * @param mixed $values * @param mixed $price * @param bool $add_totals (default: false) * @return float price * @since 1.0 */ public static function get_discounted_price($values, $price, $add_totals = false) { global $woocommerce; if (!$price) { return $price; } if (!empty($woocommerce->cart->applied_coupons)) { foreach ($woocommerce->cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->apply_before_tax() && $coupon->is_valid()) { switch ($coupon->type) { case "fixed_product": case "percent_product": $this_item_is_discounted = false; $product_cats = wp_get_post_terms($values['product_id'], 'product_cat', array("fields" => "ids")); // Specific products get the discount if (sizeof($coupon->product_ids) > 0) { if (in_array($values['product_id'], $coupon->product_ids) || in_array($values['variation_id'], $coupon->product_ids) || in_array($values['data']->get_parent(), $coupon->product_ids)) { $this_item_is_discounted = true; } // Category discounts } elseif (sizeof($coupon->product_categories) > 0) { if (sizeof(array_intersect($product_cats, $coupon->product_categories)) > 0) { $this_item_is_discounted = true; } } else { // No product ids - all items discounted $this_item_is_discounted = true; } // Specific product ID's excluded from the discount if (sizeof($coupon->exclude_product_ids) > 0) { if (in_array($values['product_id'], $coupon->exclude_product_ids) || in_array($values['variation_id'], $coupon->exclude_product_ids) || in_array($values['data']->get_parent(), $coupon->exclude_product_ids)) { $this_item_is_discounted = false; } } // Specific categories excluded from the discount if (sizeof($coupon->exclude_product_categories) > 0) { if (sizeof(array_intersect($product_cats, $coupon->exclude_product_categories)) > 0) { $this_item_is_discounted = false; } } // Apply filter $this_item_is_discounted = apply_filters('woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = true); // Apply the discount if ($this_item_is_discounted) { if ($coupon->type == 'fixed_product') { if ($price < $coupon->amount) { $discount_amount = $price; } else { $discount_amount = $coupon->amount; } $price = $price - $coupon->amount; if ($price < 0) { $price = 0; } if ($add_totals) { $woocommerce->cart->sign_up_fee_discount_cart = $woocommerce->cart->sign_up_fee_discount_cart + $discount_amount * $values['quantity']; } } elseif ($coupon->type == 'percent_product') { $percent_discount = WC_Subscriptions_Product::get_sign_up_fee_excluding_tax($values['data']) / 100 * $coupon->amount; if ($add_totals) { $woocommerce->cart->sign_up_fee_discount_cart = $woocommerce->cart->sign_up_fee_discount_cart + $percent_discount * $values['quantity']; } $price = $price - $percent_discount; } } break; case "fixed_cart": /** * This is the most complex discount - we need to divide the discount between rows based on their price in * proportion to the subtotal. This is so rows with different tax rates get a fair discount, and so rows * with no price (free) don't get discount too. */ // Get item discount by dividing item cost by subtotal to get a % if ($woocommerce->cart->sign_up_fee_subtotal_ex_tax) { $discount_percent = WC_Subscriptions_Product::get_sign_up_fee_excluding_tax($values['data']) * $values['quantity'] / $woocommerce->cart->sign_up_fee_subtotal_ex_tax; } else { $discount_percent = 0; } // Use pence to help prevent rounding errors $coupon_amount_pence = $coupon->amount * 100; // Work out the discount for the row $item_discount = $coupon_amount_pence * $discount_percent; // Work out discount per item $item_discount = $item_discount / $values['quantity']; // Pence $price = $price * 100; // Check if discount is more than price if ($price < $item_discount) { $discount_amount = $price; } else { $discount_amount = $item_discount; } // Take discount off of price (in pence) $price = $price - $discount_amount; // Back to pounds $price = $price / 100; // Cannot be below 0 if ($price < 0) { $price = 0; } // Add coupon to discount total (once, since this is a fixed cart discount and we don't want rounding issues) if ($add_totals) { $woocommerce->cart->sign_up_fee_discount_cart = $woocommerce->cart->sign_up_fee_discount_cart + $discount_amount * $values['quantity'] / 100; } break; case "percent": $percent_discount = WC_Subscriptions_Product::get_sign_up_fee($values['data']->id) / 100 * $coupon->amount; if ($add_totals) { $woocommerce->cart->sign_up_fee_discount_cart = $woocommerce->cart->sign_up_fee_discount_cart + $percent_discount * $values['quantity']; } $price = $price - $percent_discount; break; } } } } return $price; }
/** * Apply sign up fee or recurring fee discount before tax is calculated * * @since 1.2 */ public static function apply_subscription_discount_before_tax($original_price, $cart_item, $cart) { global $woocommerce; $product_id = $cart_item['data']->is_type(array('subscription_variation')) ? $cart_item['data']->variation_id : $cart_item['data']->id; if (!WC_Subscriptions_Product::is_subscription($product_id)) { return $original_price; } $price = $original_price; $calculation_type = WC_Subscriptions_Cart::get_calculation_type(); if (!empty($cart->applied_coupons)) { foreach ($cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->apply_before_tax() && $coupon->is_valid()) { $apply_sign_up_coupon = $apply_sign_up_percent_coupon = $apply_recurring_coupon = $apply_recurring_percent_coupon = $apply_initial_coupon = $apply_initial_percent_coupon = false; // Apply sign-up fee discounts to sign-up total calculations if ('sign_up_fee_total' == $calculation_type) { $apply_sign_up_coupon = 'sign_up_fee' == $coupon->type ? true : false; $apply_sign_up_percent_coupon = 'sign_up_fee_percent' == $coupon->type ? true : false; // Apply recurring fee discounts to recurring total calculations } elseif ('recurring_total' == $calculation_type) { $apply_recurring_coupon = 'recurring_fee' == $coupon->type ? true : false; $apply_recurring_percent_coupon = 'recurring_percent' == $coupon->type ? true : false; } if (in_array($calculation_type, array('combined_total', 'none'))) { if (!WC_Subscriptions_Cart::cart_contains_free_trial()) { // Apply recurring discounts to initial total if ('recurring_fee' == $coupon->type) { $apply_initial_coupon = true; } if ('recurring_percent' == $coupon->type) { $apply_initial_percent_coupon = true; } } if (WC_Subscriptions_Cart::get_cart_subscription_sign_up_fee() > 0) { // Apply sign-up discounts to initial total if ('sign_up_fee' == $coupon->type) { $apply_initial_coupon = true; } if ('sign_up_fee_percent' == $coupon->type) { $apply_initial_percent_coupon = true; } } } if ($apply_sign_up_coupon || $apply_recurring_coupon || $apply_initial_coupon) { $discount_amount = $price < $coupon->amount ? $price : $coupon->amount; // add to discount totals $woocommerce->cart->discount_cart = $woocommerce->cart->discount_cart + $discount_amount * $cart_item['quantity']; WC_Subscriptions_Cart::increase_coupon_discount_amount($coupon->code, $discount_amount * $cart_item['quantity']); $price = $price - $discount_amount; if ($price < 0) { $price = 0; } } elseif ($apply_sign_up_percent_coupon || $apply_recurring_percent_coupon) { $discount_amount = round($cart_item['data']->get_price() / 100 * $coupon->amount, $woocommerce->cart->dp); $woocommerce->cart->discount_cart = $woocommerce->cart->discount_cart + $discount_amount; WC_Subscriptions_Cart::increase_coupon_discount_amount($coupon->code, $discount_amount); $price = $price - $discount_amount; } elseif ($apply_initial_percent_coupon) { // Need to calculate percent from base price // We need to calculate the right amount to discount when the price is the combined sign-up fee and recurring amount if ('combined_total' == $calculation_type && !WC_Subscriptions_Cart::cart_contains_free_trial() && isset($woocommerce->cart->base_sign_up_fees[$product_id]) && $woocommerce->cart->base_sign_up_fees[$product_id] > 0) { $base_total = $woocommerce->cart->base_sign_up_fees[$product_id] + $woocommerce->cart->base_recurring_prices[$product_id]; if ('recurring_percent' == $coupon->type) { $portion_of_total = $woocommerce->cart->base_recurring_prices[$product_id] / $base_total; } if ('sign_up_fee_percent' == $coupon->type) { $portion_of_total = $woocommerce->cart->base_sign_up_fees[$product_id] / $base_total; } $amount_to_discount = WC_Subscriptions_Manager::get_amount_from_proportion($base_total, $portion_of_total); } else { $amount_to_discount = $cart_item['data']->get_price(); } $discount_amount = round($amount_to_discount / 100 * $coupon->amount, $woocommerce->cart->dp); $woocommerce->cart->discount_cart = $woocommerce->cart->discount_cart + $discount_amount; WC_Subscriptions_Cart::increase_coupon_discount_amount($coupon->code, $discount_amount); $price = $price - $discount_amount; } } } } return $price; }
/** * Apply fake coupon to cart * * @access public * @return void */ public function apply_fake_coupon() { global $woocommerce; $coupon_code = $this->get_fake_coupon_code(); $the_coupon = new WC_Coupon($coupon_code); if ($the_coupon->is_valid() && !$woocommerce->cart->has_discount($coupon_code)) { // Do not apply coupon with individual use coupon already applied if ($woocommerce->cart->applied_coupons) { foreach ($woocommerce->cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->individual_use == 'yes') { return false; } } } // Add coupon $woocommerce->cart->applied_coupons[] = $coupon_code; do_action('woocommerce_applied_coupon', $coupon_code); return true; } }
/** * Apply fake coupon to cart * * @access public * @return void */ public function apply_fake_coupon() { global $woocommerce; $the_coupon = new WC_Coupon(apply_filters('woocommerce_coupon_code', $this->opt['settings']['cart_discount_title'])); if ($the_coupon->is_valid() && !$woocommerce->cart->has_discount($this->opt['settings']['cart_discount_title'])) { // Do not apply coupon with individual use coupon already applied if ($woocommerce->cart->applied_coupons) { foreach ($woocommerce->cart->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->individual_use == 'yes') { return false; } } } $woocommerce->cart->applied_coupons[] = apply_filters('woocommerce_coupon_code', $this->opt['settings']['cart_discount_title']); return true; } }
/** * Function to apply discounts to a product and get the discounted price (before tax is applied). * * @access public * @param mixed $values * @param mixed $price * @param bool $add_totals (default: false) * @return float price */ public function get_discounted_price($values, $price, $add_totals = false) { if (!$price) { return $price; } if (!empty($this->applied_coupons)) { foreach ($this->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->apply_before_tax() && $coupon->is_valid()) { if ($coupon->is_valid_for_product($values['data']) || $coupon->is_valid_for_cart()) { $discount_amount = $coupon->get_discount_amount($price, $values, $single = true); $price = max($price - $discount_amount, 0); if ($add_totals) { $this->discount_cart += $discount_amount * $values['quantity']; $this->increase_coupon_discount_amount($code, $discount_amount * $values['quantity']); $this->increase_coupon_applied_count($code, $values['quantity']); } } } } } return apply_filters('woocommerce_get_discounted_price', $price, $values, $this); }
/** * Applies a coupon code passed to the method. * * @param string $coupon_code - The code to apply * @return bool True if the coupon is applied, false if it does not exist or cannot be applied */ public function add_discount($coupon_code) { // Coupons are globally disabled if (!wc_coupons_enabled()) { return false; } // Sanitize coupon code $coupon_code = apply_filters('woocommerce_coupon_code', $coupon_code); // Get the coupon $the_coupon = new WC_Coupon($coupon_code); // Check it can be used with cart if (!$the_coupon->is_valid()) { wc_add_notice($the_coupon->get_error_message(), 'error'); return false; } // Check if applied if ($this->has_discount($coupon_code)) { $the_coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_ALREADY_APPLIED); return false; } // If its individual use then remove other coupons if ($the_coupon->get_individual_use()) { $this->applied_coupons = apply_filters('woocommerce_apply_individual_use_coupon', array(), $the_coupon, $this->applied_coupons); } if ($this->applied_coupons) { foreach ($this->applied_coupons as $code) { $coupon = new WC_Coupon($code); if ($coupon->get_individual_use() && false === apply_filters('woocommerce_apply_with_individual_use_coupon', false, $the_coupon, $coupon, $this->applied_coupons)) { // Reject new coupon $coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY); return false; } } } $this->applied_coupons[] = $coupon_code; // Choose free shipping if ($the_coupon->get_free_shipping()) { $packages = WC()->shipping->get_packages(); $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods'); foreach ($packages as $i => $package) { $chosen_shipping_methods[$i] = 'free_shipping'; } WC()->session->set('chosen_shipping_methods', $chosen_shipping_methods); } $the_coupon->add_coupon_message(WC_Coupon::WC_COUPON_SUCCESS); do_action('woocommerce_applied_coupon', $coupon_code); return true; }
/** * Process discount. * * @since 2.0 **/ function process_discount() { $order = $this->order; $klarna = $this->klarna; if (WC()->cart->applied_coupons) { foreach (WC()->cart->applied_coupons as $code) { $smart_coupon = new WC_Coupon($code); // var_dump(WC()->cart->coupon_discount_amounts); // var_dump(WC()->cart->coupon_discount_amounts[$code]); if ($smart_coupon->is_valid() && $smart_coupon->discount_type == 'smart_coupon') { $klarna->addArticle($qty = 1, $artNo = '', $title = __('Discount', 'woocommerce-gateway-klarna'), $price = -WC()->cart->coupon_discount_amounts[$code], $vat = 0, $discount = 0, $flags = KlarnaFlags::INC_VAT); } } } /* if ( $order->order_discount > 0 ) { // apply_filters to order discount so we can filter this if needed $klarna_order_discount = $order->order_discount; $order_discount = apply_filters( 'klarna_order_discount', $klarna_order_discount ); $klarna->addArticle( $qty = 1, $artNo = '', $title = __( 'Discount', 'woocommerce-gateway-klarna' ), $price = -$order_discount, $vat = 0, $discount = 0, $flags = KlarnaFlags::INC_VAT ); } */ }