/** calculate totals for the items in the cart */
	public static function calculate_totals() {

		$_tax = &new jigoshop_tax();

		self::$total = 0;
		self::$cart_contents_total = 0;
		self::$cart_contents_total_ex_tax = 0;
		self::$cart_contents_weight = 0;
		self::$cart_contents_count = 0;
		self::$cart_contents_tax = 0;
		self::$tax_total = 0;
		self::$shipping_tax_total = 0;
		self::$subtotal = 0;
		self::$subtotal_ex_tax = 0;
		self::$discount_total = 0;
		self::$shipping_total = 0;
		self::$cart_dl_count = 0;
		if (sizeof(self::$cart_contents)>0) : foreach (self::$cart_contents as $item_id => $values) :
			$_product = $values['data'];
			if ($_product->exists() && $values['quantity']>0) :

				self::$cart_contents_count = self::$cart_contents_count + $values['quantity'];
				// If product is downloadable don't apply to product
				if( $_product->product_type == 'downloadable' ) {
					self::$cart_dl_count = self::$cart_dl_count + $values['quantity'];
				}

				self::$cart_contents_weight = self::$cart_contents_weight + ($_product->get_weight() * $values['quantity']);

				$total_item_price = $_product->get_price() * $values['quantity'] * 100; // Into pounds

				if ( get_option('jigoshop_calc_taxes')=='yes') :

					if ( $_product->is_taxable() ) :

						$rate = $_tax->get_rate( $_product->data['tax_class'] );

						if (get_option('jigoshop_prices_include_tax')=='yes') :

							$tax_amount = $_tax->calc_tax( $total_item_price, $rate, true );

						else :

							$tax_amount = $_tax->calc_tax( $total_item_price, $rate, false );

						endif;

						if (get_option('jigoshop_prices_include_tax')=='yes' && jigoshop_customer::is_customer_outside_base() && defined('JIGOSHOP_CHECKOUT') && JIGOSHOP_CHECKOUT ) :

							/**
							 * Our prices include tax so we need to take the base tax rate into consideration of our shop's country
							 *
							 * Lets get the base rate first
							 */
							$base_rate = $_tax->get_shop_base_rate( $_product->data['tax_class'] );

							// Calc tax for base country
							$base_tax_amount = round($_tax->calc_tax( $total_item_price, $base_rate, true ));

							// Now calc tax for user county (which now excludes tax)
							$tax_amount = round($_tax->calc_tax( ($total_item_price-$base_tax_amount), $rate, false ));

							// Finally, update $total_item_price to reflect tax amounts
							$total_item_price = ($total_item_price - $base_tax_amount + $tax_amount);

						endif;

					endif;

				endif;

				$total_item_price 			= $total_item_price / 100; // Back to pounds
				$tax_amount 				= ( isset($tax_amount) ? $tax_amount : 0 ) / 100; // Back to pounds

				self::$cart_contents_tax = self::$cart_contents_tax + $tax_amount;

				self::$cart_contents_total = self::$cart_contents_total + $total_item_price;
				self::$cart_contents_total_ex_tax = self::$cart_contents_total_ex_tax + ($_product->get_price_excluding_tax() * $values['quantity']);

				// Product Discounts
				if (self::$applied_coupons) foreach (self::$applied_coupons as $code) :
					$coupon = jigoshop_coupons::get_coupon($code);
					if ($coupon['type']=='fixed_product' && in_array($item_id, $coupon['products'])) :
						self::$discount_total = self::$discount_total + ( $coupon['amount'] * $values['quantity'] );
					endif;
				endforeach;

			endif;
		endforeach; endif;

		// Cart Shipping
		if (self::needs_shipping()) jigoshop_shipping::calculate_shipping();

		self::$shipping_total = jigoshop_shipping::$shipping_total;

		self::$shipping_tax_total = jigoshop_shipping::$shipping_tax;

		self::$tax_total = self::$cart_contents_tax;

		// Subtotal
		self::$subtotal_ex_tax = self::$cart_contents_total_ex_tax;
		self::$subtotal = self::$cart_contents_total;

		// Cart Discounts
		if (self::$applied_coupons) foreach (self::$applied_coupons as $code) :
			$coupon = jigoshop_coupons::get_coupon($code);
			if (jigoshop_coupons::is_valid($code)) :

				if ($coupon['type']=='fixed_cart') :
					self::$discount_total = self::$discount_total + $coupon['amount'];
				elseif ($coupon['type']=='percent') :
					self::$discount_total = self::$discount_total + ( self::$subtotal / 100 ) * $coupon['amount'];
				endif;

			endif;
		endforeach;

		// Total
		if (get_option('jigoshop_prices_include_tax')=='yes') :
			self::$total = self::$subtotal + self::$shipping_tax_total - self::$discount_total + jigoshop_shipping::$shipping_total;
		else :
			self::$total = self::$subtotal + self::$tax_total + self::$shipping_tax_total - self::$discount_total + jigoshop_shipping::$shipping_total;
		endif;

		if (self::$total < 0) self::$total = 0;
	}
示例#2
0
 /** 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();
     }
 }