/** * Retrieve a list of shipping quotes for a customer estimating their shipping on the 'View Cart' page. */ private function GetShippingQuotes() { if (!isset($_POST['countryId'])) { exit; } unset($_SESSION['SHIPPING']); // Determine which shipping zone we're in $address = array('shipcountryid' => (int) $_POST['countryId'], 'shipstateid' => '', 'shipzip' => ''); $_SESSION['CART']['SHIPPING']['COUNTRY_ID'] = (int) $_POST['countryId']; if (isset($_POST['stateId'])) { $address['shipstateid'] = (int) $_POST['stateId']; $_SESSION['CART']['SHIPPING']['STATE_ID'] = (int) $_POST['stateId']; } if (isset($_POST['zipCode'])) { $address['shipzip'] = $_POST['zipCode']; $_SESSION['CART']['SHIPPING']['ZIP_CODE'] = $_POST['zipCode']; } // What shipping zone do we fall under? $shippingZone = GetShippingZoneIdByAddress($address); $_SESSION['CART']['SHIPPING']['ZONE'] = $shippingZone; // Now we have the zone, what available shipping methods do we have? $cart = GetClass('ISC_CART'); $vendorMethods = $cart->GetAvailableShippingMethods($address); $cartProducts = $cart->api->GetProductsInCartByVendorforshipping(); $GLOBALS['ShippingQuotes'] = ''; // If there's only one vendor, don't show the vendor titles $GLOBALS['HideVendorDetails'] = ''; $hideItemList = false; if (count($cartProducts) == 1) { $hideItemList = true; $GLOBALS['HideVendorDetails'] = 'display: none'; $GLOBALS['ShippingQuotesListNote'] = ''; $GLOBALS['HideShippingQuotesListNote'] = 'display: none'; $GLOBALS['VendorShippingQuoteClass'] = ''; } else { $GLOBALS['ShippingQuotesListNote'] = GetLang('ShippingQuotesListNote'); $GLOBALS['HideShippingQuotesListNote'] = ''; $GLOBALS['VendorShippingQuoteClass'] = 'VendorShipping'; } $hasTransit = false; foreach ($vendorMethods as $vendorId => $methods) { if (empty($methods)) { //echo GetLang('UnableEstimateShipping'); // commented this line as client told to change the message echo GetLang('UnableEstimateShippingInCart'); exit; } $GLOBALS['VendorId'] = $vendorId; $vendorCache = $GLOBALS['ISC_CLASS_DATA_STORE']->Read('Vendors'); if ($vendorId != 0) { $vendorCache = $GLOBALS['ISC_CLASS_DATA_STORE']->Read('Vendors'); $vendor = $vendorCache[$vendorId]; $GLOBALS['VendorName'] = isc_html_escape($vendor['vendorname']); } else { $GLOBALS['VendorName'] = GetConfig('StoreName'); } $GLOBALS['ShippingQuoteRow'] = ''; foreach ($methods as $quoteId => $method) { $GLOBALS['ShipperName'] = isc_html_escape($method['description']); $GLOBALS['ShippingPrice'] = CurrencyConvertFormatPrice($method['price']); $GLOBALS['ShippingQuoteId'] = $quoteId; $GLOBALS['ShippingItemList'] = ''; $GLOBALS['HideShippingItemList'] = 'display: none'; if (!$hideItemList && !empty($cartProducts[$vendorId])) { $GLOBALS['HideShippingItemList'] = ''; foreach ($cartProducts[$vendorId] as $product) { if ($product['data']['prodtype'] != PT_PHYSICAL) { continue; } $GLOBALS['ProductQuantity'] = $product['quantity']; $GLOBALS['ProductName'] = isc_html_escape($product['product_name']); $GLOBALS['ShippingItemList'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('EstimatedShippingQuoteProduct'); } } if (isset($method['transit'])) { $hasTransit = true; $days = $method['transit']; if ($days == 0) { $transit = GetLang("SameDay"); } else { if ($days == 1) { $transit = GetLang('NextDay'); } else { $transit = sprintf(GetLang('Days'), $days); } } $GLOBALS['TransitTime'] = $transit; $GLOBALS['TransitTime'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('CartShippingTransitTime'); } else { $GLOBALS['TransitTime'] = ""; } $GLOBALS['ShippingQuoteRow'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('CartShippingQuoteRow'); } $GLOBALS['ShippingQuotes'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('EstimatedShippingQuote'); // For good measure (and validation on the server side!) we store the list of quotes we got $_SESSION['CART']['SHIPPING_QUOTES'][$vendorId] = $methods; } if ($hasTransit) { $GLOBALS['DeliveryDisclaimer'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('CartShippingDeliveryDisclaimer'); } echo $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('EstimatedShippingQuoteList'); }
/** * Calculate the order details and populate the necessary session fields so we can call CreateOrder() * * @return void **/ public function CalculateOrder() { $GLOBALS['ISC_CLASS_CART'] = GetClass('ISC_CART'); //$GLOBALS['ISC_CLASS_CART'] not declared earlier, Added by Simha if ($GLOBALS['ISC_CLASS_CART']->api->AllProductsInCartAreIntangible()) { $all_digital_downloads = 1; } else { $all_digital_downloads = 0; } $GLOBALS['ISC_CLASS_CHECKOUT'] = GetClass('ISC_CHECKOUT'); $orderSummary = $GLOBALS['ISC_CLASS_CHECKOUT']->CalculateOrderSummary(); $this->module->DebugLog($orderSummary); $product_array = $GLOBALS['ISC_CLASS_CART']->api->GetProductsInCart(true); $itemTotal = 0; foreach ($product_array as $k => $product) { $comptotal = 0; /// Baskaran /* $compitem = $product['compitem']; @$compproductid = $product['complementary']['comp_productid']; @$compmainproductid = $product['complementary']['comp_mainproductid']; $mainproductid = $product['product_id']; if($compitem == 1 and $mainproductid == $compmainproductid) { $compprice = $product['complementary']['comp_original_price']; $comptotal += $compprice; } /// Code Ends */ //if .. else added by Simha to consider the discount price in order total /* To add complementary product to Google checkout -- Baskaran*/ if ($product['compitem'] == 1) { for ($y = 0; $y < count($product['complementary']); $y++) { if ($product['product_id'] == $product['complementary'][$y]['comp_mainproductid']) { $compprodname = $product['complementary'][$y]['comp_product_name']; $compprodprice = $product['complementary'][$y]['comp_original_price']; $compqty = $product['complementary'][$y]['quantity']; $comptotal += $compprodprice * $compqty; } } } if (isset($product['discount_price']) && $product['discount_price'] < $product['product_price']) { $curprice = $product['discount_price']; } else { $curprice = $product['product_price']; } $itemTotal += $curprice * $product['quantity'] + $comptotal; # $comptotal added to add the complementary amount to the table -- Baskaran } if (isset($this->response->data[$this->response->root]['order-adjustment']['shipping']['merchant-calculated-shipping-adjustment'])) { $shipping = $this->response->data[$this->response->root]['order-adjustment']['shipping']['merchant-calculated-shipping-adjustment']; } else { $shipping = array('shipping-cost' => array('VALUE' => 0), 'shipping-name' => array('VALUE' => '')); } $shippingCost = $shipping['shipping-cost']['VALUE']; $vendorIds = $GLOBALS['ISC_CLASS_CART']->api->GetCartVendorIds(); $vendorIds = array_shift($vendorIds); //array_pop replaced by array_shift to consider only the first vendor after merging vendors $_SESSION['CHECKOUT']['PENDING_DATA']['VENDORS'][$vendorIds . '_0'] = array(); // The cost of shipping $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['COST'] = $shippingCost; // The handling cost $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['HANDLING'] = 0; // The name of the tax being applied $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_NAME'] = $orderSummary['taxName']; // The dollar value of the tax being applied $_SESSION['CHECKOUT']['PENDING_DATA']['VENDORS'][$vendorIds . '_0']['TAX_COST'] = $orderSummary['taxCost']; $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_COST'] = $orderSummary['taxCost']; // The rate the tax is being applied at as a percentage (0-100) $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_RATE'] = $orderSummary['taxRate']; // Is the tax already being included in the price of the products 0/1 $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_INCLUDED'] = $orderSummary['taxIncluded']; $orderTotal = $itemTotal + $shippingCost; if (!$orderSummary['taxIncluded'] && !(GetConfig('TaxTypeSelected') == 2)) { $orderTotal += $orderSummary['taxCost']; } // The total of the order including items, shipping, handling and tax $_SESSION['CHECKOUT']['PENDING_DATA']['VENDORS'][$vendorIds . '_0']['ORDER_TOTAL'] = $orderTotal; $_SESSION['CHECKOUT']['PENDING_DATA']['VENDORS'][$vendorIds . '_0']['ITEM_TOTAL'] = $itemTotal; $_SESSION['CHECKOUT']['PENDING_DATA']['ORDER_TOTAL'] = $orderTotal; //$GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess($this->logtype, 'response details '.print_r($this->response, true)); // The shipping address array $_SESSION['CHECKOUT']['SHIPPING_ADDRESS'] = $this->GetAddressFromResponse($this->response->data[$this->response->root]['buyer-shipping-address']); // The billing address array $_SESSION['CHECKOUT']['BILLING_ADDRESS'] = $this->GetAddressFromResponse($this->response->data[$this->response->root]['buyer-billing-address']); // The english name of the provider $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['PROVIDER'] = $shipping['shipping-name']['VALUE']; // The id of the provider $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['MODULE'] = $this->GetShippingProviderModuleByName($shipping['shipping-name']['VALUE']); $shippingZoneId = GetShippingZoneIdByAddress($_SESSION['CHECKOUT']['SHIPPING_ADDRESS']); $shippingZone = GetShippingZoneById($shippingZoneId); // The amount of store credit being applied to the order $creditDiscount = 0; // The name of the gift certificates being applied $giftCertificates = ''; $giftCertificateDiscount = 0; // The total amount of all the gift certs being applied $_SESSION['CHECKOUT']['PENDING_DATA']['GIFTCERTIFICATE_AMOUNT'] = $giftCertificateDiscount; // The amount being sent to the checkout gateway (order total - gift certifcate discounts - store credit discounts) $_SESSION['CHECKOUT']['PENDING_DATA']['GATEWAY_AMOUNT'] = $orderTotal - $creditDiscount - $giftCertificateDiscount; //$GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess($this->logtype, 'checkout before creating the pending order '.print_r($_SESSION['CHECKOUT'], true)); // Now that we're here, we have everything we need to create the pending order. // Create it and store it. We hard code the geoip information since google will be // making the request $selectedCurrency = GetCurrencyById($GLOBALS['CurrentCurrency']); $pendingOrder = array('customertoken' => '', 'customerid' => 0, 'itemtotal' => $orderSummary['itemTotal'], 'shippingcost' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['COST'], 'handlingcost' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['HANDLING'], 'taxname' => $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_NAME'], 'taxcost' => $_SESSION['CHECKOUT']['PENDING_DATA']['VENDORS'][$vendorIds . '_0']['TAX_COST'], 'taxrate' => $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_RATE'], 'totalincludestax' => $_SESSION['CHECKOUT']['PENDING_DATA']['TAX_INCLUDED'], 'totalcost' => $_SESSION['CHECKOUT']['PENDING_DATA']['ORDER_TOTAL'], 'shippingaddress' => $_SESSION['CHECKOUT']['SHIPPING_ADDRESS'], 'billingaddress' => $_SESSION['CHECKOUT']['BILLING_ADDRESS'], 'shippingprovider' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['PROVIDER'], 'shippingmodule' => $_SESSION['CHECKOUT']['SHIPPING'][$vendorIds . '_0']['MODULE'], 'paymentmethod' => 'checkout_googlecheckout', 'isdigitalorder' => (int) $all_digital_downloads, 'storecreditamount' => $creditDiscount, 'giftcertificateamount' => $_SESSION['CHECKOUT']['PENDING_DATA']['GIFTCERTIFICATE_AMOUNT'], 'giftcertificates' => $giftCertificates, 'gatewayamount' => $_SESSION['CHECKOUT']['PENDING_DATA']['GATEWAY_AMOUNT'], 'currencyid' => $selectedCurrency['currencyid'], 'currencyexchangerate' => $selectedCurrency['currencyexchangerate'], 'ordshippingzoneid' => $shippingZoneId, 'ordshippingzone' => $shippingZone['zonename']); return $pendingOrder; }
/** * Calculate the shipping cost for an array of products in the cart to the specified address. * * @param array The shipping address (shipcountryid, shipstateid, shipzip) to fetch the available methods/quotes for. * @param array Array containing the product information (generally from self::api::GetProductsInCart) * @param int The vendor ID that the shipping zone should be fetched from. * @return array An array of calculated shipping quotes. */ public function GetAvailableShippingMethodsForProducts($address, $products, $vendorId = 0) { if (!is_array($address) || !is_array($products)) { return false; } // Fetch the shipping zone that this address belongs in $shippingZone = GetShippingZoneIdByAddress($address, $vendorId); $zone = GetShippingZoneById($shippingZone); $shippingQuotes = array(); $shippableTotal = 0; $subTotal = 0; $fixedShippingCost = 0; $fixedShippingProducts = 0; $shippingQuoteProducts = array(); $includesDigitalProducts = false; // Loop through the products and build an array of those that we can ship // also save the sub total so we can pass it to the shipping providers foreach ($products as $k => $product) { // Skip over any invalid products if (!isset($product['data'])) { continue; } $quantity = (int) $product['quantity']; // Determine the actual price of the product that this customer is paying if (isset($product['discount_price'])) { $price = $product['discount_price']; } else { if (isset($product['type']) && $product['type'] == "giftcertificate") { $price = $product['giftamount']; } else { $price = $product['original_price']; } } if (isset($product['wrapping']['wrapprice'])) { $price += $product['wrapping']['wrapprice']; } $subTotal += $quantity * $price; if ($product['data']['prodtype'] == PT_PHYSICAL && $product['data']['prodfixedshippingcost'] == 0) { $shippableTotal += $quantity * $price; } if ($product['data']['prodtype'] == PT_PHYSICAL && (!isset($product['data']['prodfreeshipping']) || $product['data']['prodfreeshipping'] != 1)) { if ($product['data']['prodfixedshippingcost'] > 0) { $fixedShippingCost += $product['data']['prodfixedshippingcost'] * $quantity; ++$fixedShippingProducts; } else { $shippingQuoteProducts[$k] = $k; } } else { if ($product['data']['prodtype'] == PT_DIGITAL) { $includesDigitalProducts = true; } } } // Now that we have all of the information we need, we can start calculating // shipping $zoneHandlingFee = 0; if ($zone['zonehandlingtype'] == 'global' && $zone['zonehandlingseparate']) { $zoneHandlingFee = $zone['zonehandlingfee']; if ($includesDigitalProducts) { $zoneHandlingFee += GetConfig('DigitalOrderHandlingFee'); } } // Free shipping if ($zone['zonefreeshipping'] == 1 && $subTotal >= $zone['zonefreeshippingtotal'] || $this->api->GetCartFreeShipping(true)) { $adjustedPrice = $this->FactorInZoneHandling($shippingZone, 0, 0, $includesDigitalProducts); if ($adjustedPrice > 0) { $freeShippingName = GetConfig('StoreName'); } else { $freeShippingName = GetLang('FreeShipping'); } $shippingQuotes[] = array('description' => $freeShippingName, 'price' => $adjustedPrice, 'methodId' => -1, 'module' => '', 'handling' => $zoneHandlingFee); } // All products in the cart have a fixed shipping cost, just return that if ($fixedShippingProducts == count($products) || empty($shippingQuoteProducts)) { $adjustedPrice = $this->FactorInZoneHandling($shippingZone, $fixedShippingCost, 0, $includesDigitalProducts); if ($adjustedPrice > 0) { $shippingName = GetConfig('StoreName'); } else { $shippingName = GetLang('FreeShipping'); } $shippingQuotes = array(); $shippingQuotes[] = array('description' => $shippingName, 'price' => $adjustedPrice, 'methodId' => -1, 'module' => '', 'handling' => $zoneHandlingFee); return $shippingQuotes; } // Get any shipping methods available for this module $query = "\n\t\t\t\tSELECT *\n\t\t\t\tFROM [|PREFIX|]shipping_methods\n\t\t\t\tWHERE zoneid='" . (int) $shippingZone . "' AND methodenabled='1' AND methodvendorid='" . (int) $zone['zonevendorid'] . "'\n\t\t\t"; $result = $GLOBALS['ISC_CLASS_DB']->Query($query); while ($method = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) { if ($zone['zonehandlingtype'] == 'module' && $zone['zonehandlingseparate']) { $methodHandling = $method['methodhandlingfee']; if ($includesDigitalProducts) { $methodHandling += GetConfig('DigitalOrderHandlingFee'); } } else { $methodHandling = $zoneHandlingFee; } // Set up the shipping module behind this method $shippingModule = null; GetModuleById('shipping', $shippingModule, $method['methodmodule']); if (!is_object($shippingModule)) { continue; } $shippingModule->SetMethodId($method['methodid']); // Add each item to the shipping quote foreach ($shippingQuoteProducts as $productId) { $cartProduct = $products[$productId]; if (!isset($cartProduct['data'])) { continue; } $shippingModule->AddItem($cartProduct['data']['prodweight'], $cartProduct['data']['proddepth'], $cartProduct['data']['prodwidth'], $cartProduct['data']['prodheight'], $cartProduct['quantity'], $cartProduct['data']['prodname']); } // Set the destination settings $shippingModule->SetDestinationCountry($address['shipcountryid']); if (!isset($address['shipstate'])) { $address['shipstate'] = GetStateById($address['shipstateid']); } $shippingModule->SetDestinationState($address['shipstate']); $shippingModule->SetDestinationZip($address['shipzip']); $shippingModule->SetDestinationType("RES"); // Set the subtotal $shippingModule->SetSubTotal($shippableTotal); // Get the available services for this shipping method $moduleQuotes = array(); if (method_exists($shippingModule, 'GetServiceQuotes')) { $methodQuotes = $shippingModule->GetServiceQuotes(); // Can't ship by this method - nothing was returned if ($methodQuotes === false) { continue; } if (!is_array($methodQuotes)) { $methodQuotes = array($methodQuotes); } // For each of the returned quotes, add them to the quote stack foreach ($methodQuotes as $quote) { if (!is_object($quote)) { $quote = $quote[0]; } $shippingQuotes[] = array('description' => $quote->GetDesc(true), 'price' => $this->FactorInZoneHandling($zone['zoneid'], $quote->GetPrice() + $fixedShippingCost, $method['methodhandlingfee'], $includesDigitalProducts), 'handling' => $methodHandling, 'module' => $method['methodmodule'], 'methodId' => $method['methodid']); // Get the transit time if ($quote->GetTransit() != '' && $quote->GetTransit() != -1) { $shippingQuotes[count($shippingQuotes) - 1]['transit'] = $quote->GetTransit(); } } } else { $err = ''; $quote = $shippingModule->GetQuote($err); // added for find the shippin cost if it is missing in the object. but it is available in variable for make a offer cart. /*$temp1 = $shippingModule->_shippingcost; $temp2 = $shippingModule->rules['cost'][0]; $minamtforfreeship = $shippingModule->rules['upper'][0];*/ if ($quote !== false) { /*if ($temp1 == 0 and $temp2 > 0 and $minamtforfreeship > $_SESSION['the_offered_price']) { $shippingQuotes[] = array( 'description' => $method['methodname'], 'price' => $this->FactorInZoneHandling($shippingZone, $temp2 + $fixedShippingCost, $method['methodhandlingfee'], $includesDigitalProducts), 'handling' => $methodHandling, 'module' => $method['methodmodule'], 'methodId' => $method['methodid'] ); } else {*/ $shippingQuotes[] = array('description' => $method['methodname'], 'price' => $this->FactorInZoneHandling($shippingZone, $quote->GetPrice() + $fixedShippingCost, $method['methodhandlingfee'], $includesDigitalProducts), 'handling' => $methodHandling, 'module' => $method['methodmodule'], 'methodId' => $method['methodid']); //} } } } // Order the shipping quotes from least expensive to most expensiv uasort($shippingQuotes, array($this, 'SortShippingQuotes')); // Now return what we've got return $shippingQuotes; }