function jigoshop_cart($atts) { unset(jigoshop_session::instance()->selected_rate_id); // Process Discount Codes if (isset($_POST['apply_coupon']) && $_POST['apply_coupon'] && jigoshop::verify_nonce('cart')) { $coupon_code = sanitize_title($_POST['coupon_code']); jigoshop_cart::add_discount($coupon_code); } elseif (isset($_POST['calc_shipping']) && $_POST['calc_shipping'] && jigoshop::verify_nonce('cart')) { // Update Shipping unset(jigoshop_session::instance()->chosen_shipping_method_id); $country = $_POST['calc_shipping_country']; $state = $_POST['calc_shipping_state']; $postcode = $_POST['calc_shipping_postcode']; if ($postcode && !jigoshop_validation::is_postcode($postcode, $country)) { jigoshop::add_error(__('Please enter a valid postcode/ZIP.', 'jigoshop')); $postcode = ''; } elseif ($postcode) { $postcode = jigoshop_validation::format_postcode($postcode, $country); } if ($country) { // Update customer location jigoshop_customer::set_location($country, $state, $postcode); jigoshop_customer::set_shipping_location($country, $state, $postcode); jigoshop::add_message(__('Shipping costs updated.', 'jigoshop')); } else { jigoshop_customer::set_shipping_location('', '', ''); jigoshop::add_message(__('Shipping costs updated.', 'jigoshop')); } } elseif (isset($_POST['shipping_rates'])) { $rates_params = explode(":", $_POST['shipping_rates']); $available_methods = jigoshop_shipping::get_available_shipping_methods(); $shipping_method = $available_methods[$rates_params[0]]; if ($rates_params[1] != null) { jigoshop_session::instance()->selected_rate_id = $rates_params[1]; } $shipping_method->choose(); // chooses the method selected by user. } // Re-Calc prices. This needs to happen every time the cart page is loaded and after checking post results. jigoshop_cart::calculate_totals(); $result = jigoshop_cart::check_cart_item_stock(); if (is_wp_error($result)) { jigoshop::add_error($result->get_error_message()); } jigoshop_render('shortcode/cart', array('cart' => jigoshop_cart::get_cart(), 'coupons' => jigoshop_cart::get_coupons())); }
/** * Validate the checkout */ public function validate_checkout() { if (jigoshop_cart::is_empty()) { jigoshop::add_error(sprintf(__('Sorry, your session has expired. <a href="%s">Return to homepage →</a>', 'jigoshop'), home_url())); } // Process Discount Codes if (!empty($_POST['coupon_code'])) { $coupon = sanitize_title($_POST['coupon_code']); jigoshop_cart::add_discount($coupon); } foreach (jigoshop_cart::get_coupons() as $coupon) { jigoshop_cart::is_valid_coupon($coupon); } // Checkout fields $this->posted['shipping_method'] = ''; $this->posted['shipping_service'] = ''; if (isset($_POST['shipping_method'])) { $shipping_method = jigowatt_clean($_POST['shipping_method']); $shipping_data = explode(':', $shipping_method); $this->posted['shipping_method'] = $shipping_data[0]; $this->posted['shipping_service'] = $shipping_data[1]; } $this->posted['shiptobilling'] = isset($_POST['shiptobilling']) ? jigowatt_clean($_POST['shiptobilling']) : ''; $this->posted['payment_method'] = isset($_POST['payment_method']) ? jigowatt_clean($_POST['payment_method']) : ''; $this->posted['order_comments'] = isset($_POST['order_comments']) ? jigowatt_clean($_POST['order_comments']) : ''; $this->posted['terms'] = isset($_POST['terms']) ? jigowatt_clean($_POST['terms']) : ''; $this->posted['create_account'] = isset($_POST['create_account']) ? jigowatt_clean($_POST['create_account']) : ''; $this->posted['account_username'] = isset($_POST['account_username']) ? jigowatt_clean($_POST['account_username']) : ''; $this->posted['account_password'] = isset($_POST['account_password']) ? jigowatt_clean($_POST['account_password']) : ''; $this->posted['account_password_2'] = isset($_POST['account_password_2']) ? jigowatt_clean($_POST['account_password_2']) : ''; if (jigoshop_cart::get_total(false) == 0) { $this->posted['payment_method'] = 'no_payment'; } // establish customer billing and shipping locations if (jigoshop_cart::ship_to_billing_address_only()) { $this->posted['shiptobilling'] = 'true'; } $country = isset($_POST['billing_country']) ? jigowatt_clean($_POST['billing_country']) : ''; $state = isset($_POST['billing_state']) ? jigowatt_clean($_POST['billing_state']) : ''; $allowed_countries = Jigoshop_Base::get_options()->get('jigoshop_allowed_countries'); if ($allowed_countries === 'specific') { $specific_countries = Jigoshop_Base::get_options()->get('jigoshop_specific_allowed_countries'); if (!in_array($country, $specific_countries)) { jigoshop::add_error(__('Invalid billing country.', 'jigoshop')); return; } } if (jigoshop_countries::country_has_states($country)) { $states = jigoshop_countries::get_states($country); if (!in_array($state, array_keys($states))) { jigoshop::add_error(__('Invalid billing state.', 'jigoshop')); return; } } $postcode = isset($_POST['billing_postcode']) ? jigowatt_clean($_POST['billing_postcode']) : ''; $ship_to_billing = Jigoshop_Base::get_options()->get('jigoshop_ship_to_billing_address_only') == 'yes'; jigoshop_customer::set_location($country, $state, $postcode); if (Jigoshop_Base::get_options()->get('jigoshop_calc_shipping') == 'yes') { if ($ship_to_billing || !empty($_POST['shiptobilling'])) { jigoshop_customer::set_shipping_location($country, $state, $postcode); } else { $country = isset($_POST['shipping_country']) ? jigowatt_clean($_POST['shipping_country']) : ''; $state = isset($_POST['shipping_state']) ? jigowatt_clean($_POST['shipping_state']) : ''; $postcode = isset($_POST['shipping_postcode']) ? jigowatt_clean($_POST['shipping_postcode']) : ''; if ($allowed_countries === 'specific') { $specific_countries = Jigoshop_Base::get_options()->get('jigoshop_specific_allowed_countries'); if (!in_array($country, $specific_countries)) { jigoshop::add_error(__('Invalid shipping country.', 'jigoshop')); return; } } if (jigoshop_countries::country_has_states($country)) { $states = jigoshop_countries::get_states($country); if (!in_array($state, array_keys($states))) { jigoshop::add_error(__('Invalid shipping state.', 'jigoshop')); return; } } jigoshop_customer::set_shipping_location($country, $state, $postcode); } } // Billing Information foreach ($this->billing_fields as $field) { $field = apply_filters('jigoshop_billing_field', $field); $this->posted[$field['name']] = isset($_POST[$field['name']]) ? jigowatt_clean($_POST[$field['name']]) : ''; // Format if (isset($field['format'])) { switch ($field['format']) { case 'postcode': $this->posted[$field['name']] = strtolower(str_replace(' ', '', $this->posted[$field['name']])); break; } } // Required if ($field['name'] == 'billing_state' && jigoshop_customer::has_valid_shipping_state()) { $field['required'] = false; } if (isset($field['required']) && $field['required'] && empty($this->posted[$field['name']])) { jigoshop::add_error($field['label'] . __(' (billing) is a required field.', 'jigoshop')); } if ($field['name'] == 'billing_euvatno') { $vatno = isset($this->posted['billing_euvatno']) ? $this->posted['billing_euvatno'] : ''; $vatno = str_replace(' ', '', $vatno); $country = jigoshop_tax::get_customer_country(); // strip any country code from the beginning of the number if (strpos($vatno, $country) === 0) { $vatno = substr($vatno, strlen($country)); } if ($vatno != '') { $url = 'http://isvat.appspot.com/' . $country . '/' . $vatno . '/'; $httpRequest = curl_init(); curl_setopt($httpRequest, CURLOPT_FAILONERROR, true); curl_setopt($httpRequest, CURLOPT_RETURNTRANSFER, true); curl_setopt($httpRequest, CURLOPT_HEADER, false); curl_setopt($httpRequest, CURLOPT_URL, $url); $result = curl_exec($httpRequest); curl_close($httpRequest); if ($result === 'false') { jigoshop_log('EU VAT validation error with URL: ' . $url); jigoshop::add_error($field['label'] . __(' (billing) is not a valid VAT Number. Leave it blank to disable VAT validation. (VAT may be charged depending on your location)', 'jigoshop')); } else { $this->valid_euvatno = jigoshop_countries::get_base_country() != jigoshop_tax::get_customer_country() && jigoshop_countries::is_eu_country(jigoshop_tax::get_customer_country()); } } } // Validation if (isset($field['validate']) && !empty($this->posted[$field['name']])) { switch ($field['validate']) { case 'phone': if (!jigoshop_validation::is_phone($this->posted[$field['name']])) { jigoshop::add_error($field['label'] . __(' (billing) is not a valid number.', 'jigoshop')); } break; case 'email': if (!jigoshop_validation::is_email($this->posted[$field['name']])) { jigoshop::add_error($field['label'] . __(' (billing) is not a valid email address.', 'jigoshop')); } break; case 'postcode': if (!jigoshop_validation::is_postcode($this->posted[$field['name']], $_POST['billing_country'])) { jigoshop::add_error($field['label'] . __(' (billing) is not a valid postcode/ZIP.', 'jigoshop')); } else { $this->posted[$field['name']] = jigoshop_validation::format_postcode($this->posted[$field['name']], $_POST['billing_country']); } break; } } } // Shipping Information if (jigoshop_shipping::is_enabled() && !jigoshop_cart::ship_to_billing_address_only() && empty($this->posted['shiptobilling'])) { foreach ($this->shipping_fields as $field) { $field = apply_filters('jigoshop_shipping_field', $field); if (isset($_POST[$field['name']])) { $this->posted[$field['name']] = jigowatt_clean($_POST[$field['name']]); } else { $this->posted[$field['name']] = ''; } // Format if (isset($field['format'])) { switch ($field['format']) { case 'postcode': $this->posted[$field['name']] = strtolower(str_replace(' ', '', $this->posted[$field['name']])); break; } } // Required if ($field['name'] == 'shipping_state' && jigoshop_customer::has_valid_shipping_state()) { $field['required'] = false; } if (isset($field['required']) && $field['required'] && empty($this->posted[$field['name']])) { jigoshop::add_error($field['label'] . __(' (shipping) is a required field.', 'jigoshop')); } // Validation if (isset($field['validate']) && !empty($this->posted[$field['name']])) { switch ($field['validate']) { case 'postcode': if (!jigoshop_validation::is_postcode($this->posted[$field['name']], $country)) { jigoshop::add_error($field['label'] . __(' (shipping) is not a valid postcode/ZIP.', 'jigoshop')); } else { $this->posted[$field['name']] = jigoshop_validation::format_postcode($this->posted[$field['name']], $country); } break; } } } } if ($this->must_register && empty($this->posted['create_account'])) { jigoshop::add_error(__('Sorry, you must agree to creating an account', 'jigoshop')); } if ($this->must_register || empty($user_id) && $this->posted['create_account']) { if (!$this->show_signup) { jigoshop::add_error(__('Sorry, the shop owner has disabled guest purchases.', 'jigoshop')); } if (empty($this->posted['account_username'])) { jigoshop::add_error(__('Please enter an account username.', 'jigoshop')); } if (empty($this->posted['account_password'])) { jigoshop::add_error(__('Please enter an account password.', 'jigoshop')); } if ($this->posted['account_password_2'] !== $this->posted['account_password']) { jigoshop::add_error(__('Passwords do not match.', 'jigoshop')); } // Check the username if (!validate_username($this->posted['account_username'])) { jigoshop::add_error(__('Invalid email/username.', 'jigoshop')); } elseif (username_exists($this->posted['account_username'])) { jigoshop::add_error(__('An account is already registered with that username. Please choose another.', 'jigoshop')); } // Check the e-mail address if (email_exists($this->posted['billing_email'])) { jigoshop::add_error(__('An account is already registered with your email address. Please login.', 'jigoshop')); } } // Terms if (!isset($_POST['update_totals']) && empty($this->posted['terms']) && jigoshop_get_page_id('terms') > 0) { jigoshop::add_error(__('You must accept our Terms & Conditions.', 'jigoshop')); } if (jigoshop_cart::needs_shipping()) { // Shipping Method $available_methods = jigoshop_shipping::get_available_shipping_methods(); if (!isset($available_methods[$this->posted['shipping_method']])) { jigoshop::add_error(__('Invalid shipping method.', 'jigoshop')); } } }
</td> <td> <?php echo jigoshop_price($product->get_defined_price() * $values['quantity'], array('ex_tax_label' => Jigoshop_Base::get_options()->get('jigoshop_show_prices_with_tax') == 'yes' ? 2 : 1)); ?> </td> </tr> <?php } } ?> </tbody> </table> <?php $coupons = jigoshop_cart::get_coupons(); ?> <table> <tr> <td colspan="6" class="actions"> <?php if (JS_Coupons::has_coupons()) { ?> <div class="coupon"> <label for="coupon_code"><?php _e('Coupon', 'jigoshop'); ?> :</label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" /> <input type="submit" class="button" name="apply_coupon" value="<?php _e('Apply Coupon', 'jigoshop'); ?>
/** calculate totals for the items in the cart */ public static function calculate_totals() { // extracted cart totals so that the constructor can call it, rather than // this full method. Cart totals are needed for cart widget and themes. // Don't want to call shipping api's multiple times per page load self::calculate_cart_total(); // Cart Shipping if (self::needs_shipping()) { jigoshop_shipping::calculate_shipping(self::$tax); } else { jigoshop_shipping::reset_shipping(); } self::$shipping_total = jigoshop_shipping::get_total(); $shipping_method = jigoshop_shipping::get_chosen_method(); if (self::get_options()->get('jigoshop_calc_taxes') == 'yes') { self::$tax->calculate_shipping_tax(self::$shipping_total, $shipping_method); self::$shipping_tax_total = self::$tax->get_total_shipping_tax_amount(); } // Subtotal self::$subtotal_ex_tax = self::$cart_contents_total_ex_tax; self::$subtotal = self::$cart_contents_total; if (self::get_options()->get('jigoshop_calc_taxes') == 'yes' && !self::$tax->get_total_shipping_tax_amount()) { foreach (self::get_applied_tax_classes() as $tax_class) { if (!self::is_not_compounded_tax($tax_class)) { //tax compounded $discount = self::get_options()->get('jigoshop_tax_after_coupon') == 'yes' ? self::$discount_total : 0; self::$tax->update_tax_amount($tax_class, (self::$subtotal_ex_tax - $discount + self::$tax->get_non_compounded_tax_amount() + self::$shipping_total) * 100); } } } self::$total = self::get_cart_subtotal(false) + self::get_cart_shipping_total(false); if (self::get_options()->get('jigoshop_calc_taxes') == 'yes' && self::get_options()->get('jigoshop_prices_include_tax') == 'no' && self::get_options()->get('jigoshop_tax_after_coupon') == 'no') { self::$total += self::$tax->get_non_compounded_tax_amount() + self::$tax->get_compound_tax_amount(); } // calculate any cart wide discounts from coupons $total_product_discounts = self::$discount_total; self::$discount_total = $total_cart_discounts = $temp = 0; if (self::get_options()->get('jigoshop_tax_after_coupon') == 'yes') { // we need products and shipping with tax out $total_cart_discounts = round(self::calculate_cart_discounts_total(self::$cart_contents_total_ex_tax + self::get_cart_shipping_total(false, true)), 2); if ($total_cart_discounts > 0) { $total_to_use = self::$cart_contents_total_ex_tax + self::$shipping_total; if ($total_cart_discounts > $total_to_use) { $total_cart_discounts = $total_to_use - $total_product_discounts; } $total_tax = self::$tax->get_non_compounded_tax_amount() + self::$tax->get_compound_tax_amount() - self::$tax->get_total_shipping_tax_amount(); if ($total_tax > 0) { foreach (self::get_applied_tax_classes() as $tax_class) { $rate = self::$tax->get_rate($tax_class); $tax = self::$tax->calc_tax(self::$price_per_tax_class_ex_tax[$tax_class], $rate, false); $discounts = 0.0; $total_tax_part = $tax / $total_tax; // Lower tax by coupon amounts foreach (jigoshop_cart::get_coupons() as $code) { $coupon = JS_Coupons::get_coupon($code); switch ($coupon['type']) { case 'fixed_cart': $discounts += self::$tax->calc_tax($coupon['amount'] * $total_tax_part, $rate, false); break; case 'percent': $discounts += self::$tax->calc_tax($coupon['amount'] * self::$price_per_tax_class_ex_tax[$tax_class] / ($total_tax_part * 100), $rate, false); $discounts += $coupon['amount'] * self::$tax->get_shipping_tax($tax_class) / 100; break; } } $tax -= $discounts; self::$tax->update_tax_amount($tax_class, $tax * 100, false, true); } } // check again in case tax calcs are disabled $total_discounts = $total_cart_discounts + $total_product_discounts; if ($total_discounts > $total_to_use) { $total_cart_discounts = $total_to_use - $total_product_discounts; } } foreach (self::get_applied_tax_classes() as $tax_class) { $temp += self::$tax->get_tax_amount($tax_class); } if (self::get_options()->get('jigoshop_prices_include_tax') == 'no') { self::$total += $temp; } else { self::$total = self::$cart_contents_total_ex_tax + self::$shipping_total + $temp; } } else { // Taxes are applied before coupons, 'jigoshop_tax_after_coupon' == 'no' if (self::get_options()->get('jigoshop_prices_include_tax') == 'no') { $total_cart_discounts = self::calculate_cart_discounts_total(self::$total); if ($total_cart_discounts > self::$total) { $total_cart_discounts = self::$total - $total_product_discounts; } } else { $total_cart_discounts = self::calculate_cart_discounts_total(self::$cart_contents_total_ex_tax + self::$shipping_total); if ($total_cart_discounts > 0) { // with an initial discount, recalc taxes and get a proper discount foreach (self::get_applied_tax_classes() as $tax_class) { $rate = self::$tax->get_rate($tax_class); $tax = self::$tax->calc_tax(self::$cart_contents_total_ex_tax, $rate, false); self::$tax->update_tax_amount($tax_class, $tax * 100, false, true); $temp += self::$tax->get_tax_amount($tax_class); } $total_to_use = self::$cart_contents_total_ex_tax + self::$shipping_total + $temp; $total_cart_discounts = self::calculate_cart_discounts_total($total_to_use); if ($total_cart_discounts > $total_to_use) { $total_cart_discounts = $total_to_use - $total_product_discounts; } } } } // set the final discount self::$discount_total = $total_cart_discounts + $total_product_discounts; // adjust the grand total after all discounts self::$total -= self::$discount_total; if (self::$total < 0) { self::$total = 0; } // with everything calculated, check that coupons depending on cart totals are still valid // if they are not, remove them and recursively re-calculate everything all over again. $recalc = false; if (!empty(self::$applied_coupons)) { foreach (self::$applied_coupons as $key => $code) { if (!self::is_valid_coupon($code)) { unset(self::$applied_coupons[$key]); jigoshop_session::instance()->coupons = self::$applied_coupons; $recalc = true; } } } if ($recalc) { self::calculate_totals(); } }