Esempio n. 1
0
 /**
  *
  * Method to check config, user group and product state (if recurs).
  * Then get right values accordingly
  * @param array $items - cart items
  * @param boolean - config to show tax or not
  * @return object
  */
 function checkItems(&$items, $show_tax = false)
 {
     if (empty($items)) {
         return array();
     }
     $params = JComponentHelper::getParams('com_j2store');
     $tax = new J2StoreTax();
     $cartdata['products'] = array();
     foreach ($items as $product) {
         $product_total = 0;
         foreach ($items as $product_2) {
             if ($product_2['product_id'] == $product['product_id']) {
                 $product_total += $product_2['quantity'];
             }
         }
         //options
         $option_data = array();
         foreach ($product['option'] as $option) {
             $value = $option['option_value'];
             $option_sku = isset($option['option_sku']) ? $option['option_sku'] : '';
             $option_data[] = array('name' => $option['name'], 'option_sku' => $option_sku, 'value' => $value);
         }
         // Display prices
         $price = $tax->calculate($product['price'], $product['tax_profile_id'], $params->get('show_tax_total'));
         $total = $tax->calculate($product['price'], $product['tax_profile_id'], $params->get('show_tax_total')) * $product['quantity'];
         $tax_amount = $tax->getTax($product['price'], $product['tax_profile_id']);
         $cartdata['products'][] = array('key' => $product['key'], 'product_id' => $product['product_id'], 'product_name' => $product['name'], 'product_model' => $product['model'], 'product_qty_total' => $product_total, 'product_options' => $option_data, 'quantity' => $product['quantity'], 'stock' => $product['stock'], 'tax_amount' => $tax_amount, 'price' => $price, 'price_without_tax' => $product['price'], 'total' => $total, 'total_without_tax' => $product['price'] * $product['quantity']);
     }
     $cartObj = JArrayHelper::toObject($cartdata['products']);
     return $cartObj;
 }
Esempio n. 2
0
 /**
  * Method to get rates from the USPS shipping API
  *
  * @param array $address
  * @return array rates array
  */
 private function getRates($address)
 {
     $rates = array();
     $status = true;
     $shipping_status = false;
     //first check if shippable items are in cart
     JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_j2store/models');
     $model = JModelLegacy::getInstance('Mycart', 'J2StoreModel');
     $products = $model->getDataNew();
     foreach ($products as $product) {
         if ($product['shipping']) {
             $shipping_status = true;
         }
     }
     if ($shipping_status === false) {
         return $rates;
     }
     $currencyObject = J2StoreFactory::getCurrencyObject();
     $store_address = J2StoreHelperCart::getStoreAddress();
     $domestic_services = $this->params->get('domestic_services');
     $inernational_services = $this->params->get('international_services');
     $quote_data = array();
     $method_data = array();
     $cart_weight_total = J2StoreHelperCart::getWeight();
     $weightObject = J2StoreFactory::getWeightObject();
     $weight = $weightObject->convert($cart_weight_total, $store_address->config_weight_class_id, $this->params->get('usps_weight_class_id'));
     $weight = $weight < 0.1 ? 0.1 : $weight;
     $pounds = floor($weight);
     $ounces = round(16 * ($weight - $pounds), 2);
     // max 5 digits
     $postcode = str_replace(' ', '', $address['postal_code']);
     //get country data
     $countryObject = $this->getCountry($address['country_id']);
     if ($countryObject->country_isocode_2 == 'US') {
         $xml = '<RateV4Request USERID="' . $this->usps_username . '">';
         $xml .= '	<Package ID="1">';
         $xml .= '		<Service>ALL</Service>';
         $xml .= '		<ZipOrigination>' . substr($this->params->get('usps_postcode'), 0, 5) . '</ZipOrigination>';
         $xml .= '		<ZipDestination>' . substr($postcode, 0, 5) . '</ZipDestination>';
         $xml .= '		<Pounds>' . $pounds . '</Pounds>';
         $xml .= '		<Ounces>' . $ounces . '</Ounces>';
         // Prevent common size mismatch error from USPS (Size cannot be Regular if Container is Rectangular for some reason)
         if ($this->params->get('usps_container') == 'RECTANGULAR' && $this->params->get('usps_size') == 'REGULAR') {
             $this->params->set('usps_container', 'VARIABLE');
         }
         $xml .= '		<Container>' . $this->params->get('usps_container') . '</Container>';
         $xml .= '		<Size>' . $this->params->get('usps_size') . '</Size>';
         $xml .= '		<Width>' . $this->params->get('usps_width') . '</Width>';
         $xml .= '		<Length>' . $this->params->get('usps_length') . '</Length>';
         $xml .= '		<Height>' . $this->params->get('usps_height') . '</Height>';
         // Calculate girth based on usps calculation
         $xml .= '		<Girth>' . round((double) $this->params->get('usps_length') + (double) $this->params->get('usps_width') * 2 + (double) $this->params->get('usps_height') * 2, 1) . '</Girth>';
         $xml .= '		<Machinable>' . ($this->params->get('usps_machinable') ? 'true' : 'false') . '</Machinable>';
         $xml .= '	</Package>';
         $xml .= '</RateV4Request>';
         $request = 'API=RateV4&XML=' . urlencode($xml);
     } else {
         $countries = $this->getCountries();
         if (isset($countries[$countryObject->country_isocode_2])) {
             $xml = '<IntlRateV2Request USERID="' . $this->usps_username . '">';
             $xml .= '	<Package ID="1">';
             $xml .= '		<Pounds>' . $pounds . '</Pounds>';
             $xml .= '		<Ounces>' . $ounces . '</Ounces>';
             $xml .= '		<MailType>All</MailType>';
             $xml .= '		<GXG>';
             $xml .= '		  <POBoxFlag>N</POBoxFlag>';
             $xml .= '		  <GiftFlag>N</GiftFlag>';
             $xml .= '		</GXG>';
             $xml .= '		<ValueOfContents>' . J2StoreHelperCart::getSubTotal() . '</ValueOfContents>';
             $xml .= '		<Country>' . $countries[$countryObject->country_isocode_2] . '</Country>';
             // Intl only supports RECT and NONRECT
             if ($this->params->get('usps_container') == 'VARIABLE') {
                 $this->params->set('usps_container', 'NONRECTANGULAR');
             }
             $xml .= '		<Container>' . $this->params->get('usps_container') . '</Container>';
             $xml .= '		<Size>' . $this->params->get('usps_size') . '</Size>';
             $xml .= '		<Width>' . $this->params->get('usps_width') . '</Width>';
             $xml .= '		<Length>' . $this->params->get('usps_length') . '</Length>';
             $xml .= '		<Height>' . $this->params->get('usps_height') . '</Height>';
             $xml .= '		<Girth>' . $this->params->get('usps_girth') . '</Girth>';
             $xml .= '		<CommercialFlag>N</CommercialFlag>';
             $xml .= '	</Package>';
             $xml .= '</IntlRateV2Request>';
             $request = 'API=IntlRateV2&XML=' . urlencode($xml);
         } else {
             $status = false;
         }
     }
     if ($status) {
         $result = $this->_sendRequest($request);
         $handling = $this->params->get('handling', '0');
         if ($result) {
             if ($this->params->get('show_debug')) {
                 $this->_log("USPS DATA SENT: " . urldecode($request));
                 $this->_log("USPS DATA RECV: " . $result);
             }
             $dom = new DOMDocument('1.0', 'UTF-8');
             $dom->loadXml($result);
             $rate_response = $dom->getElementsByTagName('RateV4Response')->item(0);
             $intl_rate_response = $dom->getElementsByTagName('IntlRateV2Response')->item(0);
             $error = $dom->getElementsByTagName('Error')->item(0);
             $firstclasses = array('First-Class Mail Parcel', 'First-Class Mail Large Envelope', 'First-Class Mail Letter', 'First-Class Mail Postcards');
             if ($rate_response || $intl_rate_response) {
                 if ($countryObject->country_isocode_2 == 'US') {
                     $allowed = array(0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 16, 17, 18, 19, 22, 23, 25, 27, 28, 30, 31, 55, 56, 62, 63);
                     $package = $rate_response->getElementsByTagName('Package')->item(0);
                     $postages = $package->getElementsByTagName('Postage');
                     if ($postages->length) {
                         foreach ($postages as $postage) {
                             $classid = $postage->getAttribute('CLASSID');
                             if (in_array($classid, $allowed)) {
                                 if ($classid == '0') {
                                     $mailservice = $postage->getElementsByTagName('MailService')->item(0)->nodeValue;
                                     foreach ($firstclasses as $k => $firstclass) {
                                         if ($firstclass == $mailservice) {
                                             $classid = $classid . $k;
                                             break;
                                         }
                                     }
                                     if (in_array('usps_domestic_' . $classid, $domestic_services)) {
                                         $cost = $postage->getElementsByTagName('Rate')->item(0)->nodeValue;
                                         $price = $currencyObject->convert($cost, 'USD', $store_address->config_currency);
                                         $rate = array();
                                         $rate['name'] = $postage->getElementsByTagName('MailService')->item(0)->nodeValue;
                                         $rate['code'] = 'usps.' . $classid;
                                         $rate['price'] = $price;
                                         $rate['extra'] = (double) $handling;
                                         $rate['total'] = $price;
                                         $rate['tax'] = "0.00";
                                         $rate['element'] = $this->_element;
                                         $rates[] = $rate;
                                     }
                                 } elseif (in_array('usps_domestic_' . $classid, $domestic_services)) {
                                     $cost = $postage->getElementsByTagName('Rate')->item(0)->nodeValue;
                                     $price = $currencyObject->convert($cost, 'USD', $store_address->config_currency);
                                     $rate = array();
                                     $rate['name'] = $postage->getElementsByTagName('MailService')->item(0)->nodeValue;
                                     $rate['code'] = 'usps.' . $classid;
                                     $rate['price'] = $price;
                                     $rate['extra'] = (double) $handling;
                                     $rate['total'] = $price;
                                     $rate['tax'] = "0.00";
                                     $rate['element'] = $this->_element;
                                     $rates[] = $rate;
                                 }
                             }
                         }
                     } else {
                         $error = $package->getElementsByTagName('Error')->item(0);
                         $method_data = array('code' => 'usps', 'title' => JText::_('usps_error_text'), 'quote' => $quote_data, 'error' => $error->getElementsByTagName('Description')->item(0)->nodeValue);
                     }
                 } else {
                     $allowed = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27);
                     $package = $intl_rate_response->getElementsByTagName('Package')->item(0);
                     $services = $package->getElementsByTagName('Service');
                     if (isset($inernational_services) && !empty($inernational_services)) {
                         foreach ($services as $service) {
                             $id = $service->getAttribute('ID');
                             if (in_array($id, $allowed) && in_array('usps_international_' . $id, $inernational_services)) {
                                 $title = $service->getElementsByTagName('SvcDescription')->item(0)->nodeValue;
                                 if ($this->params->get('usps_display_time')) {
                                     $title .= ' (' . JText::_('usps_text_eta') . ' ' . $service->getElementsByTagName('SvcCommitments')->item(0)->nodeValue . ')';
                                 }
                                 $cost = $service->getElementsByTagName('Postage')->item(0)->nodeValue;
                                 $price = $currencyObject->convert($cost, 'USD', $store_address->config_currency);
                                 $rate = array();
                                 $rate['name'] = $title;
                                 $rate['code'] = 'usps.' . $id;
                                 $rate['price'] = $price;
                                 $rate['extra'] = (double) $handling;
                                 $rate['total'] = $price;
                                 $rate['tax'] = "0.00";
                                 $rate['element'] = $this->_element;
                                 $rates[] = $rate;
                             }
                         }
                     }
                 }
             } elseif ($error) {
                 $method_data = array('code' => 'usps', 'title' => JText::_('usps_error_text'), 'quote' => $quote_data, 'error' => $error->getElementsByTagName('Description')->item(0)->nodeValue);
             }
         }
     }
     if (count($rates)) {
         //if the shipping is taxable, calculate it here.
         $tax_class_id = $this->params->get('usps_tax_class_id', '');
         if ($tax_class_id) {
             $j2tax = new J2StoreTax();
             $newRates = array();
             foreach ($rates as $rate) {
                 $newRate = array();
                 $newRate['name'] = JText::_($rate['name']);
                 $newRate['code'] = $rate['code'];
                 $newRate['price'] = $rate['price'];
                 $newRate['extra'] = $rate['extra'];
                 $shipping_method_tax_total = $j2tax->getTax($newRate['price'] + $newRate['extra'], $tax_class_id);
                 $newRate['tax'] = round($shipping_method_tax_total, 2);
                 $newRate['total'] = $rate['total'] + $newRate['tax'];
                 $newRate['element'] = $rate['element'];
                 $newRates[] = $newRate;
             }
             unset($rates);
             $rates = $newRates;
         }
     }
     return $rates;
 }
Esempio n. 3
0
 /**
  *
  * Returns an object with the total cost of shipping for this method and the array of geozones
  *
  * @param unknown_type $shipping_method_id
  * @param array $geozones
  * @param unknown_type $orderItems
  * @param unknown_type $order_id
  */
 protected function getTotal($shipping_method_id, $geozones, $orderItems, $geozones_taxes)
 {
     $return = new JObject();
     $return->shipping_rate_id = '0';
     $return->shipping_rate_price = '0.00000';
     $return->shipping_rate_handling = '0.00000';
     $return->shipping_tax_rates = '0.00000';
     $return->shipping_tax_total = '0.00000';
     $rate_exists = false;
     $geozone_rates = array();
     //include custom modals
     $this->includeCustomModel('ShippingMethods');
     $this->includeCustomModel('ShippingRates');
     // cast product_id as an array
     $orderItems = (array) $orderItems;
     // determine the shipping method type
     $this->includeCustomTables('shipping_standard');
     $this->includeCustomTables();
     $shippingmethod = JTable::getInstance('ShippingMethods', 'Table');
     $shippingmethod->load($shipping_method_id);
     if (empty($shippingmethod->shipping_method_id)) {
         // TODO if this is an object, setError, otherwise return false, or 0.000?
         $return->setError(JText::_('J2STORE_UNDEFINED_SHIPPING_METHOD'));
         return $return;
     }
     //initiliase cart helper
     $carthelper = new J2StoreHelperCart();
     //initliase cart model
     JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_j2store/models');
     $cart_model = new J2StoreModelMyCart();
     switch ($shippingmethod->shipping_method_type) {
         case "2":
             // 2 = per order - price based
             // Get the total of the order, and find the rate for that
             $total = 0;
             //foreach ($orderItems as $item)
             //	{
             //		$total += $item->orderitem_final_price;
             //	}
             $order_ships = false;
             $products = $cart_model->getDataNew();
             foreach ($products as $product) {
                 //check if shipping is enabled for this item
                 if (!empty($product['shipping'])) {
                     $order_ships = true;
                     $total += $product['total'];
                     // product total
                 }
             }
             if ($order_ships) {
                 foreach ($geozones as $geozone) {
                     unset($rate);
                     $geozone_id = $geozone->geozone_id;
                     if (empty($geozone_rates[$geozone_id]) || !is_array($geozone_rates[$geozone_id])) {
                         $geozone_rates[$geozone_id] = array();
                     }
                     //	JModelLegacy::addIncludePath( JPATH_ADMINISTRATOR.'/components/com_j2store/models' );
                     $model = JModelLegacy::getInstance('ShippingRates', 'J2StoreModel');
                     $model->setState('filter_shippingmethod', $shipping_method_id);
                     $model->setState('filter_geozone', $geozone_id);
                     $model->setState('filter_weight', $total);
                     // Use weight as total
                     $items = $model->getList();
                     if (count($items) < 1) {
                         //return JTable::getInstance('ShippingRates', 'Table');
                     } else {
                         $rate = $items[0];
                         $geozone_rates[$geozone_id]['0'] = $rate;
                         // if $rate->shipping_rate_id is empty, then no real rate was found
                         if (!empty($rate->shipping_rate_id)) {
                             $rate_exists = true;
                         }
                         $geozone_rates[$geozone_id]['0']->qty = '1';
                         $geozone_rates[$geozone_id]['0']->shipping_method_type = $shippingmethod->shipping_method_type;
                     }
                 }
             }
             break;
         case "1":
             // 1 = per order - quantity based
             // first, get the total quantity of shippable items for the entire order
             // then, figure out the rate for this number of items (use the weight range field) + geozone
         // 1 = per order - quantity based
         // first, get the total quantity of shippable items for the entire order
         // then, figure out the rate for this number of items (use the weight range field) + geozone
         case "0":
             // 0 = per order - flat rate
         // 0 = per order - flat rate
         case "5":
             // 5 = per order - weight based
             // if any of the products in the order require shipping
             $sum_weight = 0;
             $count_shipped_items = 0;
             $order_ships = false;
             $products = $cart_model->getDataNew();
             foreach ($products as $product) {
                 //check if shipping is enabled for this item
                 if (!empty($product['shipping'])) {
                     $product_id = $product['product_id'];
                     $order_ships = true;
                     $sum_weight += $product['weight_total'];
                     // we already have a weight total. So we dont have to multiply weight*quantity again
                     $count_shipped_items += $product['quantity'];
                 }
             }
             if ($order_ships) {
                 foreach ($geozones as $geozone) {
                     unset($rate);
                     $geozone_id = $geozone->geozone_id;
                     if (empty($geozone_rates[$geozone_id]) || !is_array($geozone_rates[$geozone_id])) {
                         $geozone_rates[$geozone_id] = array();
                     }
                     switch ($shippingmethod->shipping_method_type) {
                         case "0":
                             // don't use weight, just do flat rate for entire order
                             // regardless of weight and regardless of the number of items
                             $rate = $this->getRate($shipping_method_id, $geozone_id, $product_id);
                             break;
                         case "1":
                             // get the shipping rate for the entire order using the count of all products in the order that ship
                             $rate = $this->getRate($shipping_method_id, $geozone_id, $product_id, '1', $count_shipped_items);
                             break;
                         default:
                             // get the shipping rate for the entire order using the sum weight of all products in the order that ship
                             $rate = $this->getRate($shipping_method_id, $geozone_id, $product_id, '1', $sum_weight);
                             break;
                     }
                     $geozone_rates[$geozone_id]['0'] = $rate;
                     // if $rate->shipping_rate_id is empty, then no real rate was found
                     if (!empty($rate->shipping_rate_id)) {
                         $rate_exists = true;
                     }
                     $geozone_rates[$geozone_id]['0']->qty = '1';
                     $geozone_rates[$geozone_id]['0']->shipping_method_type = $shippingmethod->shipping_method_type;
                 }
             }
             break;
         case "6":
         case "4":
         case "3":
             // 6 = per item - price based, a percentage of the product's price
             // 4 = per item - weight based
             // 3 = per item - flat rate
             $rates = array();
             $products = $cart_model->getDataNew();
             foreach ($products as $product) {
                 //	print_r($item);
                 $pid = $product['product_id'];
                 $qty = $product['quantity'];
                 $hash = $product['key'];
                 foreach ($geozones as $geozone) {
                     unset($rate);
                     $geozone_id = $geozone->geozone_id;
                     if (empty($geozone_rates[$geozone_id]) || !is_array($geozone_rates[$geozone_id])) {
                         $geozone_rates[$geozone_id] = array();
                     }
                     // $geozone_rates[$geozone_id][$pid] contains the shipping rate object for ONE product_id at this geozone.
                     // You need to multiply by the quantity later
                     $rate = $this->getRate($shipping_method_id, $geozone_id, $pid, $shippingmethod->shipping_method_type);
                     //price per item
                     if ($shippingmethod->shipping_method_type == '6') {
                         // the rate is a percentage of the product's price
                         $rate->shipping_rate_price = $rate->shipping_rate_price / 100 * $item->orderitem_final_price;
                         $geozone_rates[$geozone_id][$hash] = $rate;
                         $geozone_rates[$geozone_id][$hash]->shipping_method_type = $shippingmethod->shipping_method_type;
                         $geozone_rates[$geozone_id][$hash]->qty = '1';
                         // If the method_type == 6, qty should be 1 (we don't need to multiply later, in the "calc for the entire method", since this is a percentage of the orderitem_final_price)
                         //weight per item
                         //if weight based per item, we need to use weight.
                         //Per product weight (including the option weight) is already present in the products array. So pass it.
                     } elseif ($shippingmethod->shipping_method_type == '4') {
                         $rate = $this->getRate($shipping_method_id, $geozone_id, $pid, '1', $product['weight']);
                         $geozone_rates[$geozone_id][$hash] = $rate;
                         $geozone_rates[$geozone_id][$hash]->shipping_method_type = $shippingmethod->shipping_method_type;
                         $geozone_rates[$geozone_id][$hash]->qty = $qty;
                     } else {
                         //obviously, this is flat rate per item
                         $geozone_rates[$geozone_id][$hash] = $rate;
                         $geozone_rates[$geozone_id][$hash]->shipping_method_type = $shippingmethod->shipping_method_type;
                         $geozone_rates[$geozone_id][$hash]->qty = $qty;
                     }
                     // if $rate->shipping_rate_id is empty, then no real rate was found
                     if (!empty($rate->shipping_rate_id)) {
                         $rate_exists = true;
                     }
                 }
             }
             break;
         default:
             $this->setError(JText::_('J2STORE_INVALID_SHIPPING_METHOD_TYPE'));
             return false;
             break;
     }
     if (!$rate_exists) {
         $this->setError(JText::_('J2STORE_NO_RATE_FOUND'));
         return false;
     }
     $shipping_tax_rates = array();
     $shipping_method_price = 0;
     $shipping_method_handling = 0;
     $shipping_method_tax_total = 0;
     $j2tax = new J2StoreTax();
     // now calc tax for the entire method
     foreach ($geozone_rates as $geozone_id => $geozone_rate_array) {
         foreach ($geozone_rate_array as $geozone_rate) {
             if ($shippingmethod->tax_class_id) {
                 $value = $geozone_rate->shipping_rate_price * $geozone_rate->qty + $geozone_rate->shipping_rate_handling;
                 $tax_rates = $j2tax->getRates($shippingmethod->tax_class_id);
                 $shipping_tax_rates[$geozone_id] = 0;
                 foreach ($tax_rates as $tax_rate) {
                     $shipping_tax_rates[$geozone_id] += $tax_rate['rate'];
                 }
                 $shipping_method_tax_total += $j2tax->getTax($value, $shippingmethod->tax_class_id);
             }
             $shipping_method_price += $geozone_rate->shipping_rate_price * $geozone_rate->qty;
             $shipping_method_handling += $geozone_rate->shipping_rate_handling;
         }
     }
     // return formatted object
     $return->shipping_rate_price = $shipping_method_price;
     $return->shipping_rate_handling = $shipping_method_handling;
     $return->shipping_tax_rates = $shipping_tax_rates;
     $return->shipping_tax_total = $shipping_method_tax_total;
     $return->shipping_method_id = $shipping_method_id;
     $return->shipping_method_name = $shippingmethod->shipping_method_name;
     //  print_r($return);
     return $return;
 }