/** * Calculates aggregated total amounts * * Iterates over the cart items in the contents of the cart * to calculate aggregated total amounts including the * subtotal, shipping, tax, discounts and grand total * * @since 1.0 * * @return void **/ function totals () { if (!($this->retotal || $this->changed())) return true; $Totals = new CartTotals(); $this->Totals = &$Totals; // Setup discount calculator $Discounts = new CartDiscounts(); // Free shipping until costs are assessed $this->freeshipping = true; // Identify downloadable products $this->downloads(); // If no items are shipped, free shipping is disabled if (!$this->shipped()) $this->freeshipping = false; foreach ($this->contents as $key => $Item) { $Item->retotal(); $Totals->quantity += $Item->quantity; $Totals->subtotal += $Item->total; // Reinitialize item discount amounts $Item->discount = 0; // Item does not have free shipping, // so the cart shouldn't have free shipping if (!$Item->freeshipping) $this->freeshipping = false; } // Calculate Shipping $Shipping = new CartShipping(); if ($this->changed()) { // Only fully recalculate shipping costs // if the cart contents have changed $Totals->shipping = $Shipping->calculate(); // Save the generated shipping options $this->shipping = $Shipping->options(); } else $Totals->shipping = $Shipping->selected(); // Calculate discounts $Totals->discount = $Discounts->calculate(); //$this->promotions(); $Totals->discount = ($Totals->discount > $Totals->subtotal)?$Totals->subtotal:$Totals->discount; // Calculate taxes $Tax = new CartTax(); $Totals->taxrate = $Tax->rate(); $Totals->tax = $Tax->calculate(); // Calculate final totals $Totals->total = roundprice($Totals->subtotal - roundprice($Totals->discount) + $Totals->shipping + $Totals->tax); do_action_ref_array('ecart_cart_retotal',array(&$this->Totals)); $this->changed = false; $this->retotal = false; }
/** * merchant_calc() * Callback function for merchant calculated shipping and taxes * taxes calculations unimplemented * returns false when it responds, as acknowledgement of merchant calculations is unnecessary * */ function merchant_calc ($XML) { global $Ecart; if ($XML->content('shipping') == 'false') return true; // ack $sessionid = $XML->content('shopping-session'); $Ecart->resession($sessionid); $Ecart->Order = Ecart_buyObject::__new('Order',$Ecart->Order); $Ecart->Order->listeners(); $Shopping = &$Ecart->Shopping; $Order = &$Ecart->Order; // Get new address information on order $shipto = $XML->tag('anonymous-address'); $Order->Shipping->city = $shipto->content('city'); //['city']['CONTENT'] $Order->Shipping->state = $shipto->content('region'); //['region']['CONTENT'] $Order->Shipping->country = $shipto->content('country-code'); //['country-code']['CONTENT'] $Order->Shipping->postcode = $shipto->content('postal-code'); //['postal-code']['CONTENT'] // Calculate shipping options $Shipping = new CartShipping(); $Shipping->calculate(); $options = $Shipping->options(); if (empty($options)) return true; // acknowledge, but don't respond $methods = $XML->attr('method','name'); $address_id = $XML->attr('anonymous-address','id'); $_ = array('<?xml version="1.0" encoding="UTF-8"?>'); $_[] = "<merchant-calculation-results xmlns=\"http://checkout.google.com/schema/2\">"; $_[] = "<results>"; foreach ($options as $option) { if (in_array($option->name, $methods)) { $_[] = '<result shipping-name="'.$option->name.'" address-id="'.$address_id.'">'; $_[] = '<shipping-rate currency="'.$this->settings['currency'].'">'.number_format($option->amount,$this->precision,'.','').'</shipping-rate>'; $_[] = '<shippable>true</shippable>'; $_[] = '</result>'; } } $_[] = "</results>"; $_[] = "</merchant-calculation-results>"; if(ECART_DEBUG) new EcartError(join("\n",$_),'google-merchant-calculation-results',ECART_DEBUG_ERR); $this->response($_); return false; //no ack }