<?php
/***************************************************************************
 *																		*
 * Copyright (c) 2005 ISPG Technologies (I) Pvt Ltd. All rights reserved.	*
 *																		  *
 * This  is  commercial  software,  only  users  who have purchased a valid *
 * license  and  accept  to the terms of the  License Agreement can install *
 * and use this program.													*
 *																		  *
 ****************************************************************************
 * PLEASE READ THE FULL TEXT  OF THE SOFTWARE  LICENSE   AGREEMENT  IN  THE *
 * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE.			*
 ****************************************************************************/ //
//$Id: CartModel.php, v 1.1 2012/12/24 20:52:11
//
class CartModel extends ProductModel {
    var $ObjView;
    //Function to add a item to the existing cart	
    public function addITemToCart($postData, $cartID) {
        $ObjUsers                = new UserModel();
        $ObjCurrency             = new CurrencyModel();
        $productID               = $postData['productID'];
        $basepar                 = isset($postData['basepar'])?$postData['basepar']:''; 
        $userID                  = $postData['userID'];
        $productOptionID         = $postData['productOptionID'];
        $currentQuantity         = $postData['quantity'];
        $productPrice            = $postData['price'];
        $businessKey             = $postData['businessKey'];
        $productImage            = $postData['productImage'];
        $giveAsGift              = $postData['giveAsGift'];
        $brandID                 = $postData['brandID'];
        $productDefaultCurrency  = $postData['productDefaultCurrency'];
        $productOptionName       = stripslashes($postData['productOptionName']);
        $productTitle            = stripslashes($postData['productTitle']);
        $productDispatchTime     = isset($postData['productDispatchTime']) ? $postData['productDispatchTime'] : '';
        $postData['freeProduct'] = isset($postData['freeProduct']) ? $postData['freeProduct'] : '';
        $postData['freeProduct'] = ($postData['freeProduct'] == '') ? 'No' : $postData['freeProduct'];
        $currentAdminCommision   = $postData['actualPrice'] * ($postData['productCommissionRate'] / 100) * $currentQuantity;
        $currentServiceFee       = $postData['productServiceFee'] * $currentQuantity;
        $currentSubTotalAmount   = ($productPrice * $currentQuantity);
        $currentTotalAmount      = ($productPrice * $currentQuantity) + $currentServiceFee;
        $resCart                 = $this->getCartSummary($cartID);
        if (empty($resCart))
            return false;
        if ($this->ObjView) {
            $defaultCurrencyId = $this->ObjView->_defaultCurrency;
        } else {
            $resDefaultCurrency = $ObjCurrency->getDefaultCurrencyDetails('', 'ID');
            $defaultCurrencyId  = $resDefaultCurrency['currencyID'];
        }
        $cartcurrencyId = $resCart['currencyID'];
        if ($resCart['orderPromoCode'] != '') {
            $currentPromoDiscount = 0;
        }
        if ($userID > 0) {
            $userCreditAmount = $ObjUsers->getAvailableBalance($userID);
            if ($this->ObjView) {
                $userCreditAmount = $this->ObjView->convertValueCustom($userCreditAmount, $defaultCurrencyId, $cartcurrencyId);
            } else {
                $userCreditAmount = $ObjCurrency->convertValueCustom($userCreditAmount, $defaultCurrencyId, $cartcurrencyId);
            }
        }
        $userCurrencyID = ($resCart['userCurrencyID']>0)?$resCart['userCurrencyID']:$postData['userCurrencyID'];
        $userCurrencyExcRate = ($resCart['userCurrencyExcRate']>0)?$resCart['userCurrencyExcRate']:$postData['userCurrencyExcRate'];
        $userCreditAmount                          = (isset($userCreditAmount) && $userCreditAmount > 0) ? $userCreditAmount : 0;
        $subTotal                                  = $resCart['orderSubtotal'] + $currentSubTotalAmount;
        $promoDiscount                             = isset($currentPromoDiscount) ? $currentPromoDiscount : 0;
        $adminCommision                            = $resCart['orderCommissionAmount'] + $currentAdminCommision;
        $serviceFee                                = $resCart['orderOtherServiceCharge'] + $currentServiceFee;
        $quantity                                  = $resCart['orderQty'] + $currentQuantity;
        $orderTotal                                = ($subTotal + $serviceFee) - ($promoDiscount);
        $userCreditAmount                          = ($userCreditAmount > $orderTotal) ? $orderTotal : $userCreditAmount;
        $orderTotal                                = $orderTotal - $userCreditAmount;
        $imagePath                                 = $productImage;
        $serializedData['productOptionName']       = $productOptionName;
        $serializedData['productTitle']            = $productTitle;
        $serializedData['imagePath']               = $imagePath;
       $serializedData['orderCommissionAmount']   = number_format($currentAdminCommision, 5, '.', '');
          $serializedData['orderOtherServiceCharge'] = number_format($currentServiceFee, 5, '.', '');
        $serializedData['promoCode']               = isset($postData['promoCode']) ? $postData['promoCode'] : '';
        $serializedData['orderItemQuantity']       = $currentQuantity;
        $serializedData['orderItemSubtotal']       = number_format($currentSubTotalAmount, 5, '.', '');
        $serializedData['orderItemTotal']          = number_format($currentTotalAmount, 5, '.', '');
        $serializedData['unitPrice']               = number_format($productPrice, 5, '.', '');
        $serializedData['productCommissionRate']   = number_format($postData['productCommissionRate'], 5, '.', '');
        $serializedData['businessKey']             = $businessKey;
        $serializedData['productImage']            = $productImage;
        $serializedData['productDefaultCurrency']  = $productDefaultCurrency;
        $serializedData['orderTaxAmount']          = 0;
        $serializedData['shippingAmount']          = 0;
		$serializedData['redeemDiscountAmount']          = 0;
        $serializedData['productDispatchTime']     = $productDispatchTime;
        $serializedData['measurementLength']       = isset($postData['measurementLength']) ? $postData['measurementLength'] : '';
        $serializedData['measurementWeight']       = isset($postData['measurementWeight']) ? $postData['measurementWeight'] : '';
        $serializedData['packageWeight']           = isset($postData['packageWeight']) ? $postData['packageWeight'] : '';
        $serializedData['packageLength']           = isset($postData['packageLength']) ? $postData['packageLength'] : '';
        $serializedData['packageWidth']            = isset($postData['packageWidth']) ? $postData['packageWidth'] : '';
        $serializedData['packageHeight']           = isset($postData['packageHeight']) ? $postData['packageHeight'] : '';
        $serializedData['vsbID']                   = isset($postData['vsbID']) ? $postData['vsbID'] : '';
        $serializedData['free_shipping']           = ((isset($postData['freeShipping']) && $postData['freeShipping']=='Yes') ? 'true' : 'false');
		$serializedData['showroom']           = isset($postData['showroom']) ? $postData['showroom'] :0;
        $showroomID                                = isset($postData['showroom']) ? $postData['showroom'] :0;        
        if (isset($postData['type']) && $postData['type'] == 'update') {
            $customOptionValues = $postData['customOptionValues'];
        } else {
            if ($postData['customOptionValues'] != '') {
                $extraString = substr(trim($this->decodeSplChar($postData['customOptionValues'])), 2);
                $mainArray   = explode('->', $extraString);
                if (count($mainArray) > 0) {
                    foreach ($mainArray as $item) {
                        $subArray = explode('~:', $item);
                        if (count($subArray) > 0) {
                            foreach ($subArray as $key => $subItem) {
                                $customOptionArray = explode('~*', $subItem);
                                if ($key == 0) {
                                    $arrayKey = $customOptionArray[1];
                                }
                                $tempArray[$customOptionArray[0]] = $customOptionArray[1];
                            }
                            $customOptionValues[$arrayKey][] = $tempArray;
                            unset($tempArray);
                        }
                    }
                }
            }
        }
        if (isset($postData['type']) && $postData['type'] == 'update') {
            $combinationValues = $postData['strcombinationValues'];
        } else {
            if ($postData['strcombinationValues'] != '') {
                $extraString = substr(trim($this->decodeSplChar($postData['strcombinationValues'])), 2);
                $mainArray   = explode('->', $extraString);
                $skuDetails  = $mainArray[0];
                array_shift($mainArray);
                $combinationPriceDetails = $mainArray[0];
                array_shift($mainArray);
                $combinationPriceDiffTypeDetails = $mainArray[0];
                array_shift($mainArray);
                if (count($mainArray) > 0) {
                    foreach ($mainArray as $item) {
                        $subArray = explode('~:', $item);
                        if (count($subArray) > 0) {
                            foreach ($subArray as $key => $subItem) {
                                $customOptionArray                = explode('~*', $subItem);
                                $tempArray[$customOptionArray[0]] = $customOptionArray[1];
                            }
                            $combinationValues['customOption'][] = $tempArray;
                            unset($tempArray);
                        }
                    }
                }
                $cimbinationSKU                                = explode('~*', $skuDetails);
                $combinationValues['cimbinationSKU']           = $cimbinationSKU[1];
                $combinationPrice                              = explode('~*', $combinationPriceDetails);
                $combinationValues['combinationPrice']         = $combinationPrice[1];
                $combinationPriceDiff                          = explode('~*', $combinationPriceDiffTypeDetails);
                $combinationValues['combinationPriceDiffType'] = $combinationPriceDiff[1];
            }
        }
        //$productURL	= 'product/id/'.$productID.'/';
        //$serializedData['productURL']					=$productURL;
        $ObjUrl                               = new UrlrewriteModel();
        $type                                 = 'product';
        $languageIDs                          = isset($postData['languageIDs']) ? $postData['languageIDs'] : '';
        $languageIDs['Current']               = isset($languageIDs['Current']) ? $languageIDs['Current'] : '';
        if($basepar>0){
            $newProductID = $basepar;
        }else{
            $newProductID = $productID;
        }
        $resUrl                               = $ObjUrl->getRequestPathByIdPath($languageIDs['Current'], $type . '/' . $newProductID . '/');
        $productURL                           = $resUrl['requestPath'];
        $serializedData['productURL']         = $resUrl['requestPath'];
        $serializedData['combinationValues']  = isset($combinationValues) ? $combinationValues : array();
        $serializedData['customOptionValues'] = isset($customOptionValues) ? $customOptionValues : array();
        $postData['combinationHash']          = isset($postData['combinationHash'])?$postData['combinationHash']:'';
        $serializedData['combinationHash']    = $postData['combinationHash'];
        $postData['optionsHash']  		      = isset($postData['optionsHash'] ) ?$postData['optionsHash']  : '';	
        $serializedData['bundleProduct']      = (!empty($postData['bundleProduct']) && $postData['bundleProduct']=='Yes') ? $postData['bundleProduct'] : '';
        $serializedData['bundleID']           = (!empty($postData['bundleProduct']) && $postData['bundleProduct']=='Yes') ? $postData['bundleID'] : 0;
        $serializedData                       = $this->escape(serialize($serializedData), false, false);
        $freeBaseProductID                    =(!empty($postData['freeBaseProductID']) && $postData['freeProduct']=='Yes')? $postData['freeBaseProductID']:0;
		//to delete previous cart
		$sql            = " DELETE FROM " . DB_PREFIX . "cart_items WHERE  cartID='".$cartID."'";
		$resDeleteItems = $this->ObjDatabase->setQuery($sql);
        $sql                                  = " INSERT INTO " . DB_PREFIX . "cart_items 
					(
						cartID,
						productID,
						productOptionID,
                                                businessID,
						orderItemPrice,
						orderItemQuantity,
						orderItemSubtotal,
						orderGiveAsGift,
						itemDetails,
						addedTime,
						combinationHash,
						optionsHash,
						actualPrice,
						offerPrice,
						tierPrice,
						freeProduct,
                                                freeBaseProductID
					)
					VALUES
					(
						'" . $cartID . "',
						'" . $productID . "',
						'" . $productOptionID . "',
                                                '" . $postData['currbusinessid'] . "',
						'" . $productPrice . "',
						'" . $currentQuantity . "',
						'" . $currentSubTotalAmount . "',
						'" . $giveAsGift . "',
						'" . $serializedData . "',
						NOW(),
						'" . $postData['combinationHash'] . "',
						'" . $postData['optionsHash'] . "',
						'" . $postData['actualPrice'] . "',
						'" . $postData['offerPrice'] . "',
						'" . $postData['tierPrice'] . "',
						'" . $postData['freeProduct'] . "',
                                                '" . $postData['freeBaseProductID'] . "'    
					)";
        
        $result                               = $this->ObjDatabase->setQuery($sql);
        $sql                                  = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							cartID = '" . $cartID . "'";
        $sql .= ($userID > 0) ? ",userID = " . $userID : "";
        $sql .= ($subTotal > 0) ? ",orderSubtotal = " . $subTotal : "";
        $sql .= ($showroomID > 0) ? ",showroomID = " . $showroomID : "";
        $sql .= ($brandID > 0) ? ",brandID = " . $brandID : "";
        $sql .= ($orderTotal > 0) ? ",orderTotalAmount = " . $orderTotal : "";
        $sql .= ($quantity > 0) ? ",orderQty = " . $quantity : "";
        $sql .= ($userCreditAmount > 0) ? ",orderUserCreditAmount = 
					" . $userCreditAmount : "";
        $sql .= ($adminCommision > 0) ? ",orderCommissionAmount = 
					" . $adminCommision : "";
        $sql .= ($serviceFee > 0) ? ",orderOtherServiceCharge = " . $serviceFee : "";
        $sql .= ($productDefaultCurrency > 0) ? ",currencyID = " . $productDefaultCurrency : "";
        $sql .= ($userCurrencyID > 0) ? ",userCurrencyID = " . $userCurrencyID : "";
        $sql .= ($userCurrencyExcRate > 0) ? ",userCurrencyExcRate = " . $userCurrencyExcRate : "";
        $sql .= " WHERE cartID=" . (int) $cartID . " LIMIT 1";
        $result = $this->ObjDatabase->setQuery($sql);
        return true;
    }
    //Add a item to the fresh cart
    public function createCart($postData) {
        $ObjUsers                = new UserModel();
        $ObjCurrency             = new CurrencyModel();
        $productID               = $postData['productID'];
        $basepar                 = isset($postData['basepar'])?$postData['basepar']:'';
        $userID                  = $postData['userID'];
        $productOptionID         = $postData['productOptionID'];
        $currentQuantity         = $postData['quantity'];
        $productPrice            = $postData['price'];
        $businessKey             = $postData['businessKey'];
        $productImage            = $postData['productImage'];
        $giveAsGift              = $postData['giveAsGift'];
        $postData['freeProduct'] = isset($postData['freeProduct']) ? $postData['freeProduct'] : '';
        $productDefaultCurrency  = $postData['productDefaultCurrency'];
        $userCurrency            = $postData['userCurrencyID'];
        $brandID                 = $postData['brandID'];
        $userCurrencyExcRate            = $postData['userCurrencyExcRate'];
        $productOptionName       = stripslashes($postData['productOptionName']);
        $productTitle            = stripslashes($postData['productTitle']);
        $currentAdminCommision   = $postData['actualPrice'] * ($postData['productCommissionRate'] / 100) * $currentQuantity;
        $currentServiceFee       = $postData['productServiceFee'] * $currentQuantity;
        $productDispatchTime     = isset($postData['productDispatchTime']) ? $postData['productDispatchTime'] : '';
        $postData['freeProduct'] = ($postData['freeProduct'] == '') ? 'No' : $postData['freeProduct'];
        $currentSubTotalAmount   = ($productPrice * $currentQuantity);
        if ($this->ObjView) {
            $defaultCurrencyId = $this->ObjView->_defaultCurrency;
        } else {
            $resDefaultCurrency = $ObjCurrency->getDefaultCurrencyDetails('', 'ID');
            $defaultCurrencyId  = $resDefaultCurrency['currencyID'];
        }
        if ($userID > 0) {
            $userCreditAmount = $ObjUsers->getAvailableBalance($userID);
            if ($this->ObjView) {
                $userCreditAmount = $this->ObjView->convertValueCustom($userCreditAmount, $defaultCurrencyId, $productDefaultCurrency);
            } else {
                $userCreditAmount = $ObjCurrency->convertValueCustom($userCreditAmount, $defaultCurrencyId, $productDefaultCurrency);
            }
        }
        $currentPromoDiscount                       = isset($currentPromoDiscount) ? $currentPromoDiscount : 0;
        $userCreditAmount                           = (isset($userCreditAmount) && $userCreditAmount > 0) ? $userCreditAmount : 0;
        $currentTotalAmount                         = (($productPrice * $currentQuantity) + $currentServiceFee) - ($currentPromoDiscount);
        $subTotal                                   = $currentSubTotalAmount;
        $promoDiscount                              = $currentPromoDiscount;
        $adminCommision                             = $currentAdminCommision;
        $serviceFee                                 = $currentServiceFee;
        $quantity                                   = $currentQuantity;
        $userCreditAmount                           = ($userCreditAmount > $currentTotalAmount) ? $currentTotalAmount : $userCreditAmount;
        $orderTotal                                 = $currentTotalAmount - $userCreditAmount;
        $imagePath                                  = $productImage;
        $serializedData['productOptionName']        = $productOptionName;
        $serializedData['productTitle']             = $productTitle;
        $serializedData['imagePath']                = $imagePath;
        $serializedData['orderCommissionAmount']    = number_format($currentAdminCommision, 5, '.', '');
        $serializedData['orderOtherServiceCharge']  = number_format($currentServiceFee, 5, '.', '');
        $serializedData['promoCode']                = isset($postData['promoCode']) ? $postData['promoCode'] : 0;
        $serializedData['orderPromoDiscountAmount'] = number_format($currentPromoDiscount, 5, '.', '');
        $serializedData['orderItemQuantity']        = $currentQuantity;
        $serializedData['orderItemSubtotal']        = number_format($currentSubTotalAmount, 5, '.', '');
        $serializedData['orderItemTotal']           = number_format($currentTotalAmount, 5, '.', '');
        $serializedData['unitPrice']                = number_format($productPrice, 5, '.', '');
        $serializedData['productCommissionRate']    = number_format($postData['productCommissionRate'], 5, '.', '');
        $serializedData['businessKey']              = $businessKey;
        $serializedData['productImage']             = $productImage;
        $serializedData['productDefaultCurrency']   = $productDefaultCurrency;
        $serializedData['orderTaxAmount']           = 0;
        $serializedData['shippingAmount']           = 0;
        $serializedData['productDispatchTime']      = $productDispatchTime;
        $serializedData['measurementLength']        = $postData['measurementLength'];
        $serializedData['measurementWeight']        = $postData['measurementWeight'];
        $serializedData['packageWeight']            = $postData['packageWeight'];
        $serializedData['packageLength']            = $postData['packageLength'];
        $serializedData['packageWidth']             = $postData['packageWidth'];
        $serializedData['packageHeight']            = $postData['packageHeight'];
        $serializedData['vsbID']                   = isset($postData['vsbID']) ? $postData['vsbID'] : '';
        if ($postData['customOptionValues'] != '') {
            $extraString = substr(trim($this->decodeSplChar($postData['customOptionValues'])), 2);
            $mainArray   = explode('->', $extraString);
            if (count($mainArray) > 0) {
                foreach ($mainArray as $item) {
                    $subArray = explode('~:', $item);
                    if (count($subArray) > 0) {
                        foreach ($subArray as $key => $subItem) {
                            $customOptionArray = explode('~*', $subItem);
                            if ($key == 0) {
                                $arrayKey = $customOptionArray[1];
                            }
                            $tempArray[$customOptionArray[0]] = $customOptionArray[1];
                        }
                        $customOptionValues[$arrayKey][] = $tempArray;
                        unset($tempArray);
                    }
                }
            }
        }
        if ($postData['strcombinationValues'] != '') {
            $extraString = substr(trim($this->decodeSplChar($postData['strcombinationValues'])), 2);
            $mainArray   = explode('->', $extraString);
            $skuDetails  = $mainArray[0];
            array_shift($mainArray);
            $combinationPriceDetails = $mainArray[0];
            array_shift($mainArray);
            $combinationPriceDiffTypeDetails = $mainArray[0];
            array_shift($mainArray);
            if (count($mainArray) > 0) {
                foreach ($mainArray as $item) {
                    $subArray = explode('~:', $item);
                    if (count($subArray) > 0) {
                        foreach ($subArray as $key => $subItem) {
                            $customOptionArray                = explode('~*', $subItem);
                            $tempArray[$customOptionArray[0]] = $customOptionArray[1];
                        }
                        $combinationValues['customOption'][] = $tempArray;
                        unset($tempArray);
                    }
                }
            }
            $cimbinationSKU                                = explode('~*', $skuDetails);
            $combinationValues['cimbinationSKU']           = $cimbinationSKU[1];
            $combinationPrice                              = explode('~*', $combinationPriceDetails);
            $combinationValues['combinationPrice']         = $combinationPrice[1];
            $combinationPriceDiff                          = explode('~*', $combinationPriceDiffTypeDetails);
            $combinationValues['combinationPriceDiffType'] = $combinationPriceDiff[1];
        }
        //$productURL	= 'product/id/'.$productID.'/';
        $languageIDs                          = $postData['languageIDs'];
        $ObjUrl                               = new UrlrewriteModel();
        $type                                 = 'product';
        if($basepar>0){
            $newProductID = $basepar;
        }else{
            $newProductID = $productID;
        }
        $resUrl                               = $ObjUrl->getRequestPathByIdPath($languageIDs['Current'], $type . '/' . $newProductID . '/');
        $productURL                           = $resUrl['requestPath'];
        $serializedData['productURL']         = $resUrl['requestPath'];
        $serializedData['showroom']           = isset($postData['showroom']) ? $postData['showroom'] :0;
        $serializedData['combinationValues']  = isset($combinationValues) ? $combinationValues : array();
        $serializedData['customOptionValues'] = isset($customOptionValues) ? $customOptionValues : array();
        $postData['combinationHash'] 		  = isset($postData['combinationHash']) ?$postData['combinationHash'] : '';
        $postData['optionsHash']  		  = isset($postData['optionsHash'] ) ?$postData['optionsHash']  : '';
        $serializedData['combinationHash']    = $postData['combinationHash'];
        $serializedData['bundleProduct']      = (!empty($postData['bundleProduct']) && $postData['bundleProduct']=='Yes') ? $postData['bundleProduct'] : '';
        $serializedData['bundleID']           = (!empty($postData['bundleProduct']) && $postData['bundleProduct']=='Yes') ? $postData['bundleID'] : 0;
        $postData['promoCode']                = isset($postData['promoCode']) ? $postData['promoCode'] : '';
        $serializedData                       = $this->escape(serialize($serializedData), false, false);
        $sql                                  = " INSERT INTO " . DB_PREFIX . "cart
								(
									userID,
									orderSubtotal,
									orderTotalAmount,
									orderQty,
									orderPromoDiscountAmount,
									orderUserCreditAmount,
									orderCommissionAmount,
									orderOtherServiceCharge,
									orderPromoCode,
									currencyID,
                                                                        userCurrencyID,
                                                                        userCurrencyExcRate,showroomID,brandID
								)
								VALUES
								(
									'" . $userID . "',
									'" . $subTotal . "',
									'" . $orderTotal . "',
									'" . $quantity . "',
									'" . $promoDiscount . "',
									'" . $userCreditAmount . "',
									'" . $adminCommision . "',
									'" . $serviceFee . "',
									'" . $postData['promoCode'] . "',
									'" . $productDefaultCurrency . "',
                                                                        '" . $userCurrency . "', 
                                                                        '" . $userCurrencyExcRate . "', '" . $postData['showroom'] . "','".$brandID."'  )";
        $result                               = $this->ObjDatabase->setQuery($sql);
        $cartID                               = $this->ObjDatabase->getInsertId();
        $freeBaseProductID                    =(!empty($postData['freeBaseProductID']) && $postData['freeProduct']=='Yes')? $postData['freeBaseProductID']:0;
		//to delete previous cart
		$sql            = " DELETE FROM " . DB_PREFIX . "cart_items WHERE  cartID='".$cartID."'";
		$resDeleteItems = $this->ObjDatabase->setQuery($sql);
        $sql                                  = " INSERT INTO " . DB_PREFIX . "cart_items 	
								(
									cartID,
									productID,
									productOptionID,
                                                                        businessID,
									orderItemPrice,
									orderItemQuantity,
									orderItemSubtotal,
									orderGiveAsGift,
									itemDetails,
									addedTime,
									combinationHash,
									optionsHash,
									actualPrice,
									offerPrice,
									tierPrice,
									freeProduct,
                                                                        freeBaseProductID
								) 
								VALUES
								(
									'" . $cartID . "',
									'" . $productID . "',
									'" . $productOptionID . "',
                                                                        '" . $postData['currbusinessid'] . "',
									'" . $productPrice . "',
									'" . $currentQuantity . "',
									'" . $currentSubTotalAmount . "',
									'" . $giveAsGift . "',
									'" . $serializedData . "',
									NOW(),
									'" . $postData['combinationHash'] . "',
									'" . $postData['optionsHash'] . "',
									'" . $postData['actualPrice'] . "',
									'" . $postData['offerPrice'] . "',
									'" . $postData['tierPrice'] . "',
									'" . $postData['freeProduct'] . "',
                                                                        '". $freeBaseProductID."'
								)";
        $result                               = $this->ObjDatabase->setQuery($sql);
        return $cartID;
    }
    //Function get the summary of the cart
    public function getCartSummary($cartID) {
        $result = array();
        if ($cartID > 0) {
            $sql    = " SELECT 
									* 
								FROM 
									" . DB_PREFIX . "cart 
								WHERE 
									cartID= " . (int) $cartID . " LIMIT 0,1";
            $result = $this->ObjDatabase->readValue($sql);
        }
        return $result;
    }
    //Function to update promo discount the cart table
    private function updatePromoDiscount($cartID, $promoCode, $promoDiscount, $promoID) {
    }
    //Function check if a promo code is used or not
    public function checkPromoCodeIsUsed($promoID, $userID = 0, $masterOrderID = 0) {
    }
    // Fucntion to check if a promo code is valid or not
    public function promoCodeIsValid($promoCode) {
    }
    //Function get a promo code for a product
    public function getPromocodeByProduct($promoID, $productID) {
    }
    // Function to get complete cart details
    public function getCartDetails($cartID = 0, $userID = 0, $item = 'all',$totWeight='') {
        $ObjLanguage             = new LanguageModel(); 
        $currentLanguageID       = $ObjLanguage->getDefaultLanguageID();
        $resCartSummary          = array();
        $resCartSummary['items'] = array();
        $weight                  = 0;
        if ($cartID > 0 || $userID > 0) {
            $sql = " SELECT 
							cart.*,
							usr.userFirstName,
							usr.userLastName,
							usr.userEmail,
                                                        usr.userGroupID
						FROM 
							" . DB_PREFIX . "cart AS cart 
						LEFT JOIN 
							" . DB_PREFIX . "users usr 
						ON (usr.userID = cart.userID)";
            $sql .= ($cartID > 0) ? " WHERE cartID= " . (int) $cartID . "" : "	WHERE cart.userID= " . (int) $userID . " LIMIT 0,1";
           
            $resCartSummary = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
            if (!empty($resCartSummary)) {
                $sql = " SELECT 
								cartIte.*,
								product.productTippedDate,
								product.productMaxGiftBuy,
								product.productDispatchTime,
								product.brandID,
                                                                product.freeProductsCount,
                                                                product.qtyPerBatch,
                                                                product.sellAsBatch,
                                                                product.batchType,
                                                                productDispatchTime.dispatchTime as busDispatchTime,
                                                                busDet.businessName,
                                                                prodOpt.optionSKU,
                                                                ROUND(prodOptBus.monthlyInstallment) as monthlyInstallment
							FROM 
								" . DB_PREFIX . "cart_items AS cartIte 
							LEFT JOIN 
								" . DB_PREFIX . "products product 
							ON 
								(product.productID = cartIte.productID)
							LEFT JOIN 
								" . DB_PREFIX . "products_options_business prodOptBus 
							ON 
								(prodOptBus.productOptionID = cartIte.productOptionID AND
                                                                 prodOptBus.businessID = cartIte.businessID)
                                                        LEFT JOIN 
								" . DB_PREFIX . "product_options prodOpt 
							ON 
								(prodOpt.productOptionID = prodOptBus.productOptionID)
                                                        LEFT JOIN 
								" . DB_PREFIX . "product_dispatched_in_days productDispatchTime 
							ON 
								(productDispatchTime.dispatchID = prodOptBus.businessDispatchTime)
                                                        LEFT JOIN 
								" . DB_PREFIX . "business_details busDet 
							ON 
								(busDet.businessID = cartIte.businessID AND
                                                                 busDet.languageID = '".$currentLanguageID."')
							WHERE 
								cartID= '" . $resCartSummary['cartID'] . "' ";
                if ($item == 'paid') {
                    $sql .= " AND freeProduct='No' ";
                }
                $sql .= " ORDER BY 
								cartIte.addedTime asc";
                
                $resCartItemSummary      = $this->ObjDatabase->readValues($sql, MYSQLI_ASSOC);
                $resCartSummary['items'] = $resCartItemSummary;
                if($totWeight!='' && !empty($resCartItemSummary)) {
                    foreach($resCartItemSummary as $items) {
                        $unser = unserialize($items['itemDetails']);
                        $weight = $weight + $unser['packageWeight'];
                    }                    
                }
                $resCartSummary['orderWeight'] = $weight;
            }
        }
        return $resCartSummary;
    }
    //Function to get cart item details
    public function getCartItems($cartID = 0, $cartItemID = 0,$type='') {
        if ($cartID > 0) {
            $sql                = " 
						SELECT 
							cartIte.*,
							product.isProductDeal,
                                                        CASE WHEN product.isProductDeal = 'Yes' THEN 
                                                            (CASE WHEN proOpt.dealPrice <= 0 THEN 0
                                                            ELSE 
                                                            ROUND((((proOpt.productOptionRegularPrice-proOpt.dealPrice)*100)/proOpt.productOptionRegularPrice),2) 
                                                            END) 
                                                        ELSE
                                                            (CASE WHEN proOpt.productOptionProductPrice <= 0 THEN 0
                                                            ELSE 
                                                            ROUND((((proOpt.productOptionRegularPrice-proOpt.productOptionProductPrice)*100)/proOpt.productOptionRegularPrice),2) 
                                                            END) 
                                                        END AS dealDiscount,	
							product.productImage,
							proOpt.productOptionRegularPrice,
                                                        proOpt.dealPrice
						FROM 
							" . DB_PREFIX . "cart_items AS cartIte 
						INNER JOIN
							" . DB_PREFIX . "products AS product
								ON (product.productID=cartIte.productID)
						INNER JOIN
							" . DB_PREFIX . "product_options AS proOpt
								ON 	(
									cartIte.productOptionID=proOpt.productOptionID
								)
						WHERE 
							cartID= '" . $cartID . "'";
            if($type!='') {
                $sql .= " AND cartIte.cartItemID!='".$cartItemID."'";
            }
            $resCartItemSummary = $this->ObjDatabase->readValues($sql);
        } else if ($cartItemID > 0) {
            $sql                = " SELECT 
								cartIte.*,
                                                                CASE WHEN product.isProductDeal = 'Yes' THEN 
                                                            (CASE WHEN proOpt.dealPrice <= 0 THEN 0
                                                            ELSE 
                                                            ROUND((((proOpt.productOptionRegularPrice-proOpt.dealPrice)*100)/proOpt.productOptionRegularPrice),2) 
                                                            END) 
                                                        ELSE
                                                            (CASE WHEN proOpt.productOptionProductPrice <= 0 THEN 0
                                                            ELSE 
                                                            ROUND((((proOpt.productOptionRegularPrice-proOpt.productOptionProductPrice)*100)/proOpt.productOptionRegularPrice),2) 
                                                            END) 
                                                        END AS dealDiscount,	
								product.isProductDeal,
								proOpt.productOptionRegularPrice,proOpt.dealPrice
							FROM 
								" . DB_PREFIX . "cart_items AS cartIte 
							INNER JOIN
								" . DB_PREFIX . "products AS product
								ON (product.productID=cartIte.productID)
							INNER JOIN
								" . DB_PREFIX . "product_options AS proOpt
									ON 	(
										cartIte.productOptionID=proOpt.productOptionID
									)
							WHERE 
								cartItemID= " . (int) $cartItemID . " LIMIT 0,1";
            $resCartItemSummary = $this->ObjDatabase->readValue($sql);
        }
        return $resCartItemSummary;
    }
    // Function to get a particular users purchase details
    public function getUserPurchaseDetails($userID = 0) {
        $purchaseArray = array();
        if ($userID > 0) {
            $sql                    = " SELECT 
							sum(ordIte.orderItemQuantity) as orderItemCount,
							ordIte.productID 
						FROM 
							" . DB_PREFIX . "order_masters as ordMas 
						LEFT JOIN 
							" . DB_PREFIX . "order_items as ordIte 
							ON 
							(ordIte.masterOrderID=ordMas.masterOrderID) 
						WHERE 
							ordMas.userID > 0 
							AND ordIte.orderGiveAsGift='No' 
							AND ordMas.userID=" . (int) $userID . " 
							AND (ordMas.orderStatus = 'Pending' ||
							ordMas.orderStatus ='Process' || 
							ordMas.orderStatus = 'Completed' || ordMas.orderStatus = 'New')
						GROUP BY 
							ordIte.productID";
            $resSelfPurchaseDataSet = $this->ObjDatabase->readValuesObject($sql);
            $selfPurchaseCount      = $resSelfPurchaseDataSet->num_rows;
            if ($selfPurchaseCount > 0) {
                for ($i = 0; $i < $selfPurchaseCount; $i++) {
                    $selfPurchase                                      = $resSelfPurchaseDataSet->fetch_array(MYSQLI_ASSOC);
                    $purchaseArray[$selfPurchase['productID']]['self'] = ($selfPurchase['orderItemCount'] > 0) ? $selfPurchase['orderItemCount'] : 0;
                }
            }
            return $purchaseArray;
        }
    }
    //Function to delete an item from the cart
    public function deleteItemFromCart($cartID = 0, $cartItemID = 0, $productOptionID = 0, $optionsHash = '', $section = 'list',$freeProduct='',$productID='',$freeBaseProductID='',$type='',$currBusinessID=0) {
        
        $cartID = (int)$cartID;
        
        if ($cartID > 0) {
            if($type!='' && $productID>0) {
                $sql            = " DELETE FROM " . DB_PREFIX . "cart_items WHERE freeProduct='Yes' AND freeBaseProductID>0 AND freeBaseProductID = '" . $productID ."' AND cartID='".$cartID."'";
                $resDeleteItems = $this->ObjDatabase->setQuery($sql);
            }
            $sql = " DELETE FROM 
							" . DB_PREFIX . "cart_items 
						WHERE cartID = '" . $cartID . "'";
            $sql .= ($cartItemID > 0) ? " AND cartItemID = '" . $cartItemID."' " : "";
            $sql .= ($freeProduct!='') ? " AND freeProduct = '" . $freeProduct ."'":'';
            $sql .= ($freeBaseProductID!='') ? " AND freeBaseProductID = '" . $freeBaseProductID ."' AND freeBaseProductID>0":'';
            $sql .= ($productID!='') ? " AND productID = '" . $productID ."' " : "";
            $sql .= ($productOptionID > 0) ? " AND productOptionID = '" . $productOptionID ."' ": "";
            $sql .= ($currBusinessID > 0) ? " AND businessID = " . $currBusinessID : "";
            if ($section == 'list') {
                $sql .= ($optionsHash != '') ? " AND optionsHash = '" . $optionsHash . "'" : " AND optionsHash = '" . $optionsHash . "' ";
            }
            $resDeleteItems           = $this->ObjDatabase->setQuery($sql);
            $resCart                  = $this->getCartDetails($cartID);
            $ordersubTotal            = 0;
            $orderCommissionAmount    = 0;
            $orderOtherServiceCharge  = 0;
            $orderPromoDiscountAmount = 0;
            $orderItemQuantity        = 0;
            if (!empty($resCart['items'])) {
                foreach ($resCart['items'] as $cart) {
                    $ordersubTotal += ($cart['orderItemPrice'] * $cart['orderItemQuantity']);
                    $serializedData = unserialize($cart['itemDetails']);
                    $orderCommissionAmount += $serializedData['orderCommissionAmount'];
                    $orderOtherServiceCharge += $serializedData['orderOtherServiceCharge'];
                    $orderItemQuantity += $serializedData['orderItemQuantity'];
                    $orderPromoDiscountAmount += isset($serializedData['orderPromoDiscountAmount']) ? $serializedData['orderPromoDiscountAmount'] : 0;
                }
            }
            $orderTotal            = ($ordersubTotal + $orderOtherServiceCharge) - ($orderPromoDiscountAmount);
            $orderUserCreditAmount = ($resCart['orderUserCreditAmount'] > $orderTotal) ? $orderTotal : $resCart['orderUserCreditAmount'];
            $orderTotal            = $orderTotal - $orderUserCreditAmount;
            $sql                   = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							cartID =" . (int) $cartID . ",
							orderSubtotal=" . $ordersubTotal . ",
							orderTotalAmount=" . $orderTotal . ",
							orderQty=" . $orderItemQuantity . ",
							orderUserCreditAmount=" . $orderUserCreditAmount . ",
							orderCommissionAmount=" . $orderCommissionAmount . ",
							orderOtherServiceCharge=" . $orderOtherServiceCharge . " 
						WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateItems        = $this->ObjDatabase->setQuery($sql);
            if (empty($resCart['items'])) {
                $sql                   = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
                                                userCurrencyID=0,userCurrencyExcRate=0
                                                WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
            }
        }
        return true;
    }
    // Function to delete item from cart with out updating the cart total amounts
    public function deleteCartItem($cartID = 0, $cartItemID = 0,$type='',$productID='',$singledelete='') {
        if($singledelete!='') {
             $sql            = " DELETE FROM 
                                                                    " . DB_PREFIX . "cart_items 
                                                            WHERE 
                                                                    cartItemID in (" . $cartItemID.")";
             $resDeleteItems = $this->ObjDatabase->setQuery($sql);
        } else {
        if ($cartID > 0 || $cartItemID > 0) {
            if ($cartItemID > 0) {
                if($type!='' && $productID>0) {
                     $sql            = " DELETE FROM " . DB_PREFIX . "cart_items WHERE freeProduct='Yes' AND freeBaseProductID>0 AND freeBaseProductID = '" . $productID ."' AND cartID='".$cartID."'";
                     $resDeleteItems = $this->ObjDatabase->setQuery($sql);
                }
                $sql            = " DELETE FROM 
								" . DB_PREFIX . "cart_items 
							WHERE 
								cartItemID = " . $cartItemID;
                $resDeleteItems = $this->ObjDatabase->setQuery($sql);
            } else {
                $sql            = " DELETE FROM 
								" . DB_PREFIX . "cart_items 
							WHERE 
								cartID = " . $cartID;
                $resDeleteItems = $this->ObjDatabase->setQuery($sql);
            }
        }
        }
        return true;
    }
    // Function to update a cart item details
    public function updateCartItem($cartID = 0, $cartItemID = 0, $postData = array()) {
        if ($cartItemID > 0) {
            $postData['itemDetails'] = $this->escape($postData['itemDetails'], false, false);
            $sql                     = " UPDATE 
							" . DB_PREFIX . "cart_items 
						SET 
							cartItemID = '" . $cartItemID . "'";
            $sql .= (isset($postData['isProductDeal'] )) ? ",isProductDeal = '" . $postData['isProductDeal'] . "'" : "";
            $sql .= (isset($postData['dealDiscount'] )) ? ",dealDiscount = '" . $postData['dealDiscount'] . "'" : "";
            $sql .= ($postData['orderItemPrice'] > 0) ? ",orderItemPrice = '" . $postData['orderItemPrice'] . "'" : "";
            $sql .= ($postData['orderItemQuantity'] > 0) ? ",orderItemQuantity ='" . $postData['orderItemQuantity'] . "'" : "";
            $sql .= ",offerPrice ='" . $postData['offerPrice'] . "'";
            $sql .= ",tierPrice ='" . $postData['tierPrice'] . "'";
            $sql .= ($postData['orderItemSubtotal'] > 0) ? ",orderItemSubtotal = '" . $postData['orderItemSubtotal'] . "'" : "";
            $sql .= ($postData['itemDetails'] != '') ? ",itemDetails = '" . $postData['itemDetails'] . "'" : "";
            $sql .= (isset($postData['productOptionID']) && $postData['productOptionID'] > 0) ? ",productOptionID = '" . $postData['productOptionID'] . "'" : "";
            $sql .= "	WHERE 
							cartItemID=" . (int) $cartItemID . " LIMIT 1";
            $resUpdateItems = $this->ObjDatabase->setQuery($sql);
            //$resResetCartTotals = $this->resetCartTotals($cartID);
        }
        return true;
    }
    // Function to reset the cart total amounts 
    public function resetCartTotals($cartID = 0, $setSpecialCampaignDiscount = true) {
        $ObjUsers    = new UserModel();
        $ObjCurrency = new CurrencyModel();
        $ObjSettings = new SettingsModel();
        $inclusive_tax = $ObjSettings->getSettings('inclusive_tax','value');
        if ($this->ObjView) {
            $defaultCurrencyId = $this->ObjView->_defaultCurrency;
        } else {
            $resDefaultCurrency = $ObjCurrency->getDefaultCurrencyDetails('', 'ID');
            $defaultCurrencyId  = $resDefaultCurrency['currencyID'];
        }
        if ($cartID > 0) {
            $resCart          = $this->getCartDetails($cartID);
            $userID           = $resCart['userID'];
            $cartCurrency     = $resCart['currencyID'];
            $userCreditAmount = $ObjUsers->getAvailableBalance($userID);
            $userCreditAmount = ($userCreditAmount > 0) ? $userCreditAmount : 0;
            if ($this->ObjView) {
                $userCreditAmount = $this->ObjView->convertValueCustom($userCreditAmount, $defaultCurrencyId, $cartCurrency);
            } else {
                $userCreditAmount = $ObjCurrency->convertValueCustom($userCreditAmount, $defaultCurrencyId, $cartCurrency);
            }
            $ordersubTotal            = 0;
            $orderCommissionAmount    = 0;
            $orderOtherServiceCharge  = 0;
            $orderPromoDiscountAmount = 0;
			$redeemDiscountAmount	  = 0;
            $orderItemQuantity        = 0;
            $orderShippingAmount      = 0;
            $orderTaxAmount           = 0;
			$orderConvenientFee		  = 0;
            
            if (!empty($resCart['items'])) {
                foreach ($resCart['items'] as $cart) {
                    $ordersubTotal += ($cart['orderItemPrice'] * $cart['orderItemQuantity']);
                    $serializedData = unserialize($cart['itemDetails']);
                    $orderCommissionAmount += $serializedData['orderCommissionAmount'];
                    $orderOtherServiceCharge += $serializedData['orderOtherServiceCharge'];
                    $orderItemQuantity += $serializedData['orderItemQuantity'];
                    $orderShippingAmount += $serializedData['shippingAmount'];
                    $orderTaxAmount += $serializedData['orderTaxAmount'];
                    $orderPromoDiscountAmount += isset($serializedData['orderPromoDiscountAmount']) ? $serializedData['orderPromoDiscountAmount'] : 0;
					$redeemDiscountAmount += isset($serializedData['redeemDiscountAmount']) ? $serializedData['redeemDiscountAmount'] : 0;
                }
                
            } else {
                //Reset Promocode for empty items
                $this->updatePromoDiscount($cartID, '', 0, 0);
            }
            $orderConvenientFee       = $resCart['orderConvenientFee'];
            $addTaxAmount             =  ($inclusive_tax=='Yes') ? 0 : $orderTaxAmount;            
            $orderTotal               = ($ordersubTotal + $orderOtherServiceCharge + $orderShippingAmount + $addTaxAmount+$orderConvenientFee) - ($orderPromoDiscountAmount);
            $tot_without_dis          = ($ordersubTotal + $orderOtherServiceCharge + $orderShippingAmount + $addTaxAmount+$orderConvenientFee);
            $orderPromoDiscountAmount = ($orderPromoDiscountAmount > $tot_without_dis ? $tot_without_dis : $orderPromoDiscountAmount);
            $orderUserCreditAmount    = ($userCreditAmount > $orderTotal) ? $orderTotal : $userCreditAmount;
            $orderTotal               = $orderTotal - $orderUserCreditAmount;
			$orderTotal               = $orderTotal - $redeemDiscountAmount;
            $sql                      = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							cartID ='" . $cartID . "',
							orderSubtotal=" . $ordersubTotal . ",
							orderTotalAmount=" . $orderTotal . ",
							orderQty=" . $orderItemQuantity . ",
							orderUserCreditAmount='" . $orderUserCreditAmount . "',
							orderPromoDiscountAmount='" . $orderPromoDiscountAmount . "',
							orderCommissionAmount='" . $orderCommissionAmount . "',
							orderOtherServiceCharge='" . $orderOtherServiceCharge . "',
							shippingAmount='" . $orderShippingAmount . "',
							orderTaxAmount='" . $orderTaxAmount . "' 
						WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateItems           = $this->ObjDatabase->setQuery($sql);
            if (empty($resCart['items'])) {
                $sql                   = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
                                                userCurrencyID=0,userCurrencyExcRate=0
                                                WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
            }
        }
        return true;
    }
    // Function to get product option details of a cart item 
    public function listCartItemOptions($languageIDs, $productID, $status = 'Active') {
        $defaultLanguageID = $languageIDs['Default'];
        $currentLanguageID = $languageIDs['Current'];
        $sql               = " SELECT 
						productOptDet.productOptionID,
						SUBSTRING(productOptDet.productOptionName,1,80) as productOptionName
					FROM 
						" . DB_PREFIX . "products product
					INNER JOIN 
						" . DB_PREFIX . "product_options productOpt 
						ON 
						(
							productOpt.productID=product.productID 
							AND 
							productOpt.productOptionStatus='Active'  
							AND 
							(
								productOpt.productQuantityUnlimited >0 
								OR 
								productOpt.productOptionQuantity >0
							)
						)
					INNER JOIN 
						" . DB_PREFIX . "product_option_details AS productOptDet 
						ON 
						(
							productOptDet.productOptionID=productOpt.productOptionID 
							AND 
							productOptDet.languageID=" . $currentLanguageID . "
						)
					WHERE 
						product.productID=" . $productID;
        $resProduct        = $this->ObjDatabase->readValues($sql);
        return $resProduct;
    }
    public function getDefaultOptionID($productID='') {
        if ($productID > 0) {
             $paramsArray              = array(
                'tableName' => 'product_options',
                'fieldName' => 'productOptionID',
                'conditionField' => 'productID',
                'condition' => '=',
                'conditionValue' => $productID,
                'conditionField1' => 'productOptionDefault',
                'condition1' => '=',
                'conditionValue1' => 'Yes', 
                'conditionFieldType' => ''
            );
            $productOptDet     = $this->getFieldValue($paramsArray);
            $productOptionID   = $productOptDet['productOptionID'];
            return $productOptionID;
        }
    }
    // Function to get cart items product details
    public function getCartProductDetails($productID = 0, $productOptionID, $languageIDs = array(), $combinationHash = 0,$businessID=0,$showAllProducts='') {
		 if($showAllProducts=='Yes') {
			$updprodstatus = " IN ('Active','Inactive') ";
			$updprodcombstatus = " IN ('A','I') ";	
		} else {
			$updprodstatus = " = 'Active' ";
			$updprodcombstatus = " = 'A' ";			
		}
        if ($productID > 0) {
            $paramsArray              = array(
                'tableName' => 'products',
                'fieldName' => 'InventoryTrackLevel',
                'conditionField' => 'productID',
                'condition' => '=',
                'conditionValue' => $productID,
                'conditionFieldType' => 'int'
            );
            $resInventoryTrackLevel   = $this->getFieldValue($paramsArray);
            $productQuantityUnlimited = ($resInventoryTrackLevel['InventoryTrackLevel'] == 'No') ? 1 : 0;
            
            if($businessID>0){
                $sqlFieldsAppend      =   "productOptBus.productOptionProductPrice,";
                if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                    $sqlFieldsAppend .= " proBusCom.businessCombQuantity as productOptionQuantity,
                                          IF(proBusCom.businessCombQuantity = '',1,0) as productQuantityUnlimited ,";
                } else {
                    $sqlFieldsAppend .= " productOptBus.productOptionQuantity,
                                          " . $productQuantityUnlimited . " as productQuantityUnlimited,";
                }
                
                $sqlBusOptJoin        = "INNER JOIN 
                                                " . DB_PREFIX . "products_options_business productOptBus 
                                                ON 
                                                (productOptBus.productOptionID = productOpt.productOptionID
                                                 AND productOptBus.businessID = '".$businessID."')";
            }else{
                $sqlFieldsAppend      =   "productOpt.productOptionProductPrice,";
                if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                    $sqlFieldsAppend .= " proCom.combinationQty as productOptionQuantity,
                                          IF(proCom.combinationQty = '',1,0) as productQuantityUnlimited ,";
                } else {
                    $sqlFieldsAppend .= " productOpt.productOptionQuantity,
                                        " . $productQuantityUnlimited . " as productQuantityUnlimited,";
                }
                
                $sqlBusOptJoin        = "";
            }
            $sql                      = " SELECT 
							product.productMinBuyLimit,
							product.productMaxGiftBuy,
							product.productMaxBuyLimit,
							productTyp.productTypeKey,
							product.productCommissionRate,
							product.productServiceFee,
							product.productTippedDate,
							product.productDefaultCurrency,
							product.businessID,
                                                        product.productImage,
							product.InventoryTrackLevel,
							product.shippingSetting,
							product.productDispatchTime,
							product.taxPayableToBusiness,
                                                        product.isProductDeal,
                                                        product.dealMaxBuyLimit,
                                                        $sqlFieldsAppend
							product.measurementLength,
							product.measurementWeight,
							productOpt.packageWeight,
							productOpt.packageLength,
							productOpt.packageWidth,
							productOpt.packageHeight,
							productOpt.packageWeight,
							productOpt.packageLength,
							productOpt.packageWidth,
							productOpt.packageHeight,
							productOptDet.productOptionName,
                                                        productDet.productTitle,
							productTyp.productTypeUrlKey,
							product.productImage,
							product.productID,
                                                        product.brandID,
                                                        bus.businessKey,
                                                        product.freeProductsCount,product.productStatus
						FROM 
							" . DB_PREFIX . "products product 
						INNER JOIN 
							" . DB_PREFIX . "product_types AS productTyp 
							ON 
							(productTyp.productTypeID=product.productTypeID)
						INNER JOIN " . DB_PREFIX . "product_options AS productOpt 
							ON 
							(productOpt.productOptionID=" . $productOptionID . ")
                                                INNER JOIN " . DB_PREFIX . "business AS bus 
							ON 
							(bus.businessID=product.businessID)
                                                $sqlBusOptJoin";       
            if (count($languageIDs) > 0) {
                $currentLanguageID = $languageIDs['Current'];
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=" . (int) $productOptionID . " 
								AND productOptDet.languageID=" . (int) $currentLanguageID . ") ";
                 $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_details AS productDet 
								ON 
								(productDet.productID=product.productID
								AND productDet.languageID=" . (int) $currentLanguageID . ") ";
            } else {
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=" . (int) $productOptionID . " 
								AND productOptDet.languageID=1) ";

                 
                $sql .= " LEFT JOIN 

								" . DB_PREFIX . "product_details AS productDet 
								ON 
								(productDet.productID=product.productID	AND productDet.languageID=1) ";
            }
            if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                $sql .= " LEFT JOIN 
							" . DB_PREFIX . "product_combination AS proCom 
							ON (
								proCom.productID=product.productID  
								AND proCom.status ".$updprodcombstatus."
								AND
								proCom.combinationHash = " . $combinationHash . "
							)";
                if($businessID>0){
                    $sql .= " LEFT JOIN 
							" . DB_PREFIX . "product_combination_business AS proBusCom 
							ON (
								proBusCom.combinationID=proCom.combinationID  
								AND 
								proBusCom.businessID = '".$businessID."'
							)";
                }
            }
            $sql .= " WHERE product.productID=" . $productID . " and product.productStatus ".$updprodstatus." LIMIT 0,1";
            
            $resProduct = $this->ObjDatabase->readValue($sql);
            return $resProduct;
        } else if ($productOptionID > 0) {
            $sql = " SELECT 
							product.productMinBuyLimit, 
							product.productMaxGiftBuy,
							product.productMaxBuyLimit,
							productTyp.productTypeKey,
							product.productCommissionRate,
							product.productServiceFee,
							product.businessID,
                                                        product.brandID,
							product.productTippedDate,
							product.productDefaultCurrency,
							productOpt.productOptionQuantity,
							productOpt.productQuantityUnlimited,
							productOpt.productOptionProductPrice,
							product.measurementLength,
							product.measurementWeight,
							productOpt.packageWeight,
							productOpt.packageLength,
							productOpt.packageWidth,
							productOpt.packageHeight,
							productOptDet.productOptionName,
							productTyp.productTypeUrlKey,
							product.productImage,
							product.productID,
							product.InventoryTrackLevel,
							product.productUrl,
							productOpt.optionSKU,
							product.shippingSetting,
							product.productDispatchTime,
							product.taxPayableToBusiness,
                                                        product.isProductDeal,
                                                        product.dealMaxBuyLimit,product.productStatus
						FROM  
							" . DB_PREFIX . "product_options productOpt 
						INNER JOIN 
							" . DB_PREFIX . "products AS product 
							ON 
							(product.productID=productOpt.productID)
						INNER JOIN 
							" . DB_PREFIX . "product_types AS productTyp 
							ON 
							(productTyp.productTypeID=product.productTypeID) ";
            if (count($languageIDs) > 0) {
                $currentLanguageID = $languageIDs['Current'];
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=" . (int) $productOptionID . " 
								AND productOptDet.languageID=" . (int) $currentLanguageID . ") ";
            } else {
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=" . (int) $productOptionID . " 
								AND  productOptDet.languageID=1) ";
            }
            $sql .= " WHERE 
								productOpt.productOptionID=" . (int) $productOptionID . " and product.productStatus ".$updprodstatus." LIMIT 0,1";
            $resProduct = $this->ObjDatabase->readValue($sql);
            return $resProduct;
        } else {
            return array();
        }
    }
    // Function to check if a product exist or not
    public function checkProductExists($productID = 0, $productOptionID = 0) {
        if ($productID > 0 && $productOptionID > 0) {
            $sql                 = " SELECT 
							product.productID 
						FROM  
							" . DB_PREFIX . "products product 
						LEFT JOIN 
							" . DB_PREFIX . "product_options productOpt 
							ON 
							(productOpt.productOptionID=" . $productOptionID . ")
						LEFT JOIN 
							" . DB_PREFIX . "product_types AS productTyp 
							ON 
							(productTyp.productTypeID=product.productTypeID) 
						LEFT JOIN 
							" . DB_PREFIX . "timezones AS timZ 
							ON
							(timZ.timeZoneID=product.productTimeZone)
						WHERE 
							(product.productStatus='Active' OR  product.productStatus='Buybox')
							AND productOpt.productOptionStatus='Active'
							AND productTyp.productTypeStatus='Active' 
							AND product.productID=" . (int) $productID . " LIMIT 0,1";
            
            $resOrderToProductID = $this->ObjDatabase->readValue($sql);
            if (empty($resOrderToProductID['productID'])) {
                return 0;
            }
            return 1;
        } else {
            return 0;
        }
    }
    public function getPurchasedQty($userID) {
            if ($userID > 0) {
                $sql                        = " SELECT 
								sum(ordIte.orderItemQuantity) as orderItemCount 
							FROM 
								" . DB_PREFIX . "order_masters as ordMas 
							LEFT JOIN 
								" . DB_PREFIX . "order_items as ordIte 
								ON 
								(ordIte.masterOrderID=ordMas.masterOrderID) 
							WHERE 
								ordMas.userID > 0 
								AND ordIte.orderGiveAsGift='No' 
								AND ordMas.userID=" . (int) $userID. " 
								AND (ordMas.orderStatus = 'Pending' || 
								ordMas.orderStatus = 'Process' || 
								ordMas.orderStatus = 'Completed' || ordMas.orderStatus = 'New') 
								AND ordIte.productID=" . (int) $resProduct['productID'] . " LIMIT 0,1";
                $resSelfPurchase            = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
                return (!empty($resSelfPurchase['orderItemCount']))?$resSelfPurchase['orderItemCount']:0; 
            }
    }
    // Function to get cart item product details along with purchase details
    public function getCartItemDetails($cartItemID, $cloneGift = 'No') {
        if ($cartItemID > 0) {
            $paramsArray  = array(
                'tableName' => 'cart_items',
                'fieldName' => 'productID',
                'conditionField' => 'cartItemID',
                'condition' => '=',
                'conditionValue' => $cartItemID,
                'conditionFieldType' => 'int'
            );
            $resProductID = $this->getFieldValue($paramsArray);
            if ($resProductID['productID'] < 1)
                return false;
            $paramsArray              = array(
                'tableName' => 'cart_items',
                'fieldName' => 'combinationHash',
                'conditionField' => 'cartItemID',
                'condition' => '=',
                'conditionValue' => $cartItemID,
                'conditionFieldType' => 'int'
            );
            $rescombination           = $this->getFieldValue($paramsArray);
            $combinationHash          = $rescombination['combinationHash'];
            $paramsArray              = array(
                'tableName' => 'products',
                'fieldName' => 'InventoryTrackLevel',
                'conditionField' => 'productID',
                'condition' => '=',
                'conditionValue' => (int) $resProductID['productID'],
                'conditionFieldType' => 'int'
            );
            $resInventoryTrackLevel   = $this->getFieldValue($paramsArray);
            $productQuantityUnlimited = ($resInventoryTrackLevel['InventoryTrackLevel'] == 'No') ? 1 : 0;
            $sql                      = "	SELECT 
							cartIte.*,
							product.productMinBuyLimit,
							product.productMaxGiftBuy,
							product.productMaxBuyLimit,
							productTyp.productTypeKey,
							product.productCommissionRate,
							product.isProductDeal,
							product.dealMaxBuyLimit,
                                                        IF(productOptBus.dealPrice>0,productOptBus.dealPrice,ROUND((productOptBus.productOptionProductPrice)-(productOptBus.productOptionProductPrice*(product.dealDiscount/100)))) AS dealPrice,
                                                        product.dealDiscount,
                                                        productOptBus.productOptionRegularPrice,

							product.productServiceFee,";
            if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                $sql .= " proBusCom.businessCombQuantity as productOptionQuantity,
                          IF(proBusCom.businessCombQuantity = '',1,0) as productQuantityUnlimited ,";
            } else {
                $sql .= " productOptBus.productOptionQuantity,
                        " . $productQuantityUnlimited . " as productQuantityUnlimited,";
            }
            $sql .= "	productOptBus.productOptionProductPrice,
							cart.userID,
							cart.cartID,
							product.productID
						FROM 
							" . DB_PREFIX . "cart_items cartIte
						INNER JOIN 
							" . DB_PREFIX . "cart cart 
							ON 
							(cart.cartID = cartIte.cartID)
						INNER JOIN 
							" . DB_PREFIX . "products product 
							ON 
							(product.productID = cartIte.productID)
						INNER JOIN 
							" . DB_PREFIX . "product_types AS productTyp 
							ON 
							(productTyp.productTypeID=product.productTypeID)
						INNER JOIN 
							" . DB_PREFIX . "product_options AS productOpt 
							ON 
							(productOpt.productOptionID=cartIte.productOptionID)
                                                INNER JOIN 
							" . DB_PREFIX . "products_options_business productOptBus 
							ON 
							(productOptBus.productOptionID = productOpt.productOptionID
                                                         AND productOptBus.businessID = cartIte.businessID)";
            if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                $sql .= " LEFT JOIN 
							" . DB_PREFIX . "product_combination AS proCom 
							ON (
								proCom.productID=product.productID  
								AND 
								proCom.combinationHash = " . $combinationHash . "
							)
                         LEFT JOIN 
							" . DB_PREFIX . "product_combination_business AS proBusCom 
							ON (
								proBusCom.combinationID=proCom.combinationID  
								AND 
								proBusCom.businessID = cartIte.businessID
							)";
            }
            $sql .= " WHERE 
							cartIte.cartItemID=" . $cartItemID . " LIMIT 0,1";
            $resProduct = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
            if ($resProduct['userID'] > 0) {
                $sql                        = " SELECT 
								sum(ordIte.orderItemQuantity) as orderItemCount 
							FROM 
								" . DB_PREFIX . "order_masters as ordMas 
							LEFT JOIN 
								" . DB_PREFIX . "order_items as ordIte 
								ON 
								(ordIte.masterOrderID=ordMas.masterOrderID) 
							WHERE 
								ordMas.userID > 0 
								AND ordIte.orderGiveAsGift='No' 
								AND ordMas.userID=" . (int) $resProduct['userID'] . " 
								AND (ordMas.orderStatus = 'Pending' || 
								ordMas.orderStatus = 'Process' || 
								ordMas.orderStatus = 'Completed' || ordMas.orderStatus = 'New') 
								AND ordIte.productID=" . (int) $resProduct['productID'] . " LIMIT 0,1";
                $resSelfPurchase            = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
                $resProduct['selfPurchase'] = $resSelfPurchase['orderItemCount'];
            }
            $sql    = " SELECT 
							* 
						FROM 
							" . DB_PREFIX . "cart_items as cartIte  
						WHERE 
							cartIte.cartID = '" . $resProduct['cartID'] . "'";
            $result = $this->ObjDatabase->readValues($sql);
            foreach ($result as $key => $items) {
                if ($items['cartItemID'] != $cartItemID) {
                    if ($items['productID'] != $resProduct['productID']) {
                        //$resProduct['selfPurchase'] = (isset($resProduct['selfPurchase'])?$resProduct['selfPurchase']+$items['orderItemQuantity']:$items['orderItemQuantity']);
                    }
                    if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options' && $items['combinationHash'] == $resProduct['combinationHash']) {
//                        $resProduct['currentCartSelfPurchase'] = (isset($resProduct['currentCartSelfPurchase']) ? ($resProduct['currentCartSelfPurchase'] + $items['orderItemQuantity']) : $items['orderItemQuantity']);
//                    } else if ($items['productOptionID'] == $resProduct['productOptionID']) {
//                        $resProduct['currentCartSelfPurchase'] = (isset($resProduct['currentCartSelfPurchase']) ? ($resProduct['currentCartSelfPurchase'] + $items['orderItemQuantity']) : $items['orderItemQuantity']);
                        
                    }
                }
            }
            return $resProduct;
        }
    }
    // Function to update cart user ID also upadte the billing , shipping, 
    //discount , user cerdit
    public function updateCartUserID($cartID, $userID) {
        if ($userID < 1) {
            $sql = " UPDATE 
							" . DB_PREFIX . "cart 
						SET userID = '" . $userID . "',
							orderUserCreditAmount=0,
							orderPromoDiscountAmount=0,
							orderPromoCode='' 
						WHERE cartID='" . (int) $cartID . "' LIMIT 1";
            $this->ObjDatabase->setQuery($sql);
            $this->resetCartTotals($cartID);
        }
        $sql = " UPDATE 
						" . DB_PREFIX . "cart 
					SET 
						userID=" . (int) $userID . ",
						shippingAmount=0,
						orderTaxAmount=0 
					WHERE 
						cartID='" . (int) $cartID . "' LIMIT 1";
        $this->ObjDatabase->setQuery($sql);
        /* To Reset User Specific Info When User Switches */
        $resCart = $this->getCartDetails($cartID, 0);
        if (count($resCart['items']) > 0) {
            foreach ($resCart['items'] as $key => $items) {
                $arrCartItemDetails                             = unserialize($items['itemDetails']);
                $arrCartItemDetails['shippingAmount']           = 0;
                $arrCartItemDetails['isTaxable']                = 'No';
                $arrCartItemDetails['orderItemTaxRate']         = 0;
                $arrCartItemDetails['orderItemTaxDescription']  = '';
                $arrCartItemDetails['orderTaxAmount']           = 0;
                $arrCartItemDetails['orderPromoDiscountAmount'] = 0;
                $sql                                            = " UPDATE 
								" . DB_PREFIX . "cart_items 
							SET 
								itemDetails = '" . $this->escape(serialize($arrCartItemDetails), false, false) . "'
							WHERE 
								cartItemID = '" . (int) $items['cartItemID'] . "' 
								AND cartID = '" . (int) $cartID . "' LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
            }
        }
        $extraData                        = $this->getUnserializedCartData($cartID);
        $extraData['userBillingAddress']  = '';
        $extraData['userShippingAddress'] = '';
        $sql                              = " UPDATE 
						" . DB_PREFIX . "cart 
					SET 
						extra = '" . $this->escape(serialize($extraData), false, false) . "' 
					WHERE 
						cartID='" . (int) $cartID . "' LIMIT 1";
        $this->ObjDatabase->setQuery($sql);
        /* To Reset User Specific Info When User Switches */
    }
    // Function to list payment gateways based on purchaing currency
    public function listPaymentGateways($currencyID, $section = 'cart',$countryCode='') {
        if ($currencyID > 0) {
            $sql         = "	SELECT 
							paymentSettingsGroup.paySetGroupID,
							paymentSettingsGroup.paySetGroupLabel,
							paymentSettingsGroup.paySetGroupKey,
							paymentSettings.paySetValue,
							paymentSettings1.paySetValue as label ,
                                                        paymentSettings2.paySetValue as transaction_mode,
                                                        paymentSettings3.paySetValue as payment_country
						FROM 
							" . DB_PREFIX . "payment_settings_group as paymentSettingsGroup 
						LEFT JOIN 
							" . DB_PREFIX . "payment_settings paymentSettings  
							ON 
							(paymentSettings.paySetGroupID=paymentSettingsGroup.paySetGroupID 
							AND paySetKey='transaction_currencies')
						LEFT JOIN 
							" . DB_PREFIX . "payment_settings paymentSettings1  
							ON 
							(paymentSettings1.paySetGroupID=paymentSettingsGroup.paySetGroupID 
							AND paymentSettings1.paySetKey='payment_method_name')
                                                LEFT JOIN 
							" . DB_PREFIX . "payment_settings paymentSettings2  
							ON 
							(paymentSettings2.paySetGroupID=paymentSettingsGroup.paySetGroupID 
							AND paymentSettings2.paySetKey='transaction_mode')
                                                LEFT JOIN 
							" . DB_PREFIX . "payment_settings paymentSettings3  
							ON 
							(paymentSettings3.paySetGroupID=paymentSettingsGroup.paySetGroupID 
							AND paymentSettings3.paySetKey='payment_country')
						WHERE 
							paymentSettingsGroup.paySetGroupStatus='Active' 
						GROUP BY 
							paymentSettingsGroup.paySetGroupID ORDER BY paymentSettingsGroup.paySetGroupSortOrder ";
            $resGateways = $this->ObjDatabase->readValues($sql);
            if (count($resGateways) > 0) {
                $returnArray = array();
                foreach ($resGateways as $resGateway) {
                    if ($resGateway['paySetValue'] != '' || $resGateway['paySetGroupKey'] == 'Free_Checkout') {
                        $transactionCurrency = explode('~*', $resGateway['paySetValue']);
                        $transactionCountry = explode('|', $resGateway['payment_country']);
                        if (in_array($currencyID, $transactionCurrency) && (in_array($countryCode, $transactionCountry) || $resGateway['payment_country']=='')) {
                            if ($section == 'giftcoupon' && ($resGateway['paySetGroupKey'] == 'ChequeMoneyOrder' || $resGateway['paySetGroupKey'] == 'CashOnDeliveryRedemption')) {
                                continue;
                            }
                            $tempArray[0]                = $resGateway['paySetGroupKey'];
                            $tempArray[1]                = $resGateway['label'];
                            $tempArray['paySetGroupKey'] = $resGateway['paySetGroupKey'];
                            $tempArray['label']          = $resGateway['label'];
                            $tempArray['transaction_mode']          = $resGateway['transaction_mode'];
                            array_push($returnArray, $tempArray);
                            unset($tempArray);
                        } else if ($resGateway['paySetGroupKey'] == 'Free_Checkout') {
                            $tempArray[0]                = $resGateway['paySetGroupKey'];
                            $tempArray[1]                = $resGateway['paySetGroupLabel'];
                            $tempArray['paySetGroupKey'] = $resGateway['paySetGroupKey'];
                            $tempArray['label']          = $resGateway['paySetGroupLabel'];
                            $tempArray['transaction_mode']          = $resGateway['transaction_mode'];
                            array_push($returnArray, $tempArray);
                            unset($tempArray);
                        }
                    }
                }
            }
        }
        return $returnArray;
    }
    //FETCHING ALL SETTINGS BY GROUP ID
    public function listPaymentSettingByGroupKey($groupKey, $settingsKey = '') {
        $sql                      = " SELECT 
						paySet.paySetValue 
					FROM 
						" . DB_PREFIX . "payment_settings as paySet
					INNER JOIN 
						" . DB_PREFIX . "payment_settings_group paySetGrp 
						ON 
						(paySet.paySetGroupID=paySetGrp.paySetGroupID 
						AND paySetGrp.paySetGroupKey='" . $groupKey . "') 
					WHERE 
						paySet.paySetKey = '" . $settingsKey . "' 
						AND paySet.payFieldShow='Y' LIMIT 0,1";
        $resSelectPaymentSettings = $this->ObjDatabase->readValue($sql);
        return $resSelectPaymentSettings;
    }
    //Function to update billing address
    public function updateUserBilling($userID = 0, $addressID = 0, $cartID = 0) {
        if ($addressID == 0) {
            $sql                             = " SELECT 
							usr.userFirstName as billingFirstName,
							usr.userLastName as billingLastName,
							usr.userAdress1 as billingAddress1,
							usr.userAdress2 as billingAddress2,
							usr.userCity as billingCity,
							usr.userProvince as billingProvince,
							usr.userZip as billingZip,
							usr.stateID as billingState,
							usr.countryID as billingCountry,
							usr.userPhone as billingPhone,
							usr.userEmail as billingEmail
						FROM 
							" . DB_PREFIX . "users as usr  
						WHERE 
							usr.userID = " . (int) $userID . " LIMIT 0,1";
            $resBillingAddress               = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
            $extraData                       = $this->getUnserializedCartData($cartID);
            $extraData['userBillingAddress'] = $resBillingAddress;
            $sql                             = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							extra = '" . $this->escape(serialize($extraData), false, false) . "' 
						WHERE 
							cartID=" . (int) $cartID;
            $resUpdateCart                   = $this->ObjDatabase->setQuery($sql);
        }
    }
    
    //Function to update the shipping address
    public function updateUserShipping($userID = 0, $addressID = 0, $cartID = 0) {
        if ($addressID == 0) {
            $sql                              = " SELECT 
							usrShi.shippingFname,
							usrShi.shippingLname,
							usrShi.shippingAddress1,
							usrShi.shippingAddress2,
							usrShi.shippingCity,
							usrShi.shippingProvince,
							usrShi.shippingZip,
							usrShi.shippingStateID,
							usrShi.shippingCountryID 
						FROM 
							" . DB_PREFIX . "user_shipping as usrShi  
						WHERE 
							usrShi.userID = " . (int) $userID . " 
							AND usrShi.addressPrimary='Yes' 
							AND usrShi.addressStatus='Active' LIMIT 0,1";
            $resShippingAddress               = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
            $extraData                        = $this->getUnserializedCartData($cartID);
            $extraData['userShippingAddress'] = $resShippingAddress;
            $sql                              = " UPDATE 
									" . DB_PREFIX . "cart 
								SET 
									extra = '" . $this->escape(serialize($extraData), false, false) . "' 
								WHERE 
									cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateCart                    = $this->ObjDatabase->setQuery($sql);
        }
    }
    // Function to create a Order from cart 
    // @usage clicking on complete order button
    public function createOrder($order = array(), $orderNumerReuired = 'Yes') {
        $parentOrderID = $order['parentOrderID'];
        if (count($order['items']) > 0) {
            foreach ($order['items'] as $key => $items) {
                $businessID               = $key;
                $orderData                = $items;
                $orderBasedSerializedData = $this->escape(serialize($orderData['orderBasedUnserializedData']));
            }
        }
        $languageID = (isset($order['languageID']) && $order['languageID'] > 0) ? $order['languageID'] : 1;
        //if ($order['userID'] < 1) {
            $billingDetails   = unserialize($order['billingAddress']);
            $billingFirstName = $this->escape($order['userName'], false, false);
            $billingLastName  = '';
            $customerEmail    = $this->escape($order['userEmail'], false, false);
            $guestOrder       = 'Yes';
            $billingPhone     = $this->escape($order['billingPhone'], false, false); 
        /*} else {
            $billingFirstName = '';
            $billingLastName  = '';
            $customerEmail    = $this->escape($order['userEmail'], false, false);
            $guestOrder       = 'No';
        }*/
        $orderSource = (isset($order['platform']) && $order['platform']!='')?$order['platform']:'web';
        $orderSource = ($orderSource=='desktop')?'web':$orderSource;
        $sql            = " INSERT INTO " . DB_PREFIX . "order_masters
					(
						parentOrderID,
						orderTotalAmount,
						orderSubtotal,
						promoID,
						orderPromoCode,
						orderPromoDiscountAmount,
						orderUserCreditAmount,
						paymentSettingsGroupID,
						orderPaymentMethodName,
						paymentType,
						billingAddress,
						shippingAddress,
						netpayOrderID,
						netpayPaymentType,
						orderHold,
						purchasedCurrency,
						languageID,
						transactionID,
						orderCreatedDate,
						orderStatusDate,
						orderQty,
						orderStatus,
						userID,
						paymentStatus,
						orderType,
						convertedMasterOrderSubtotal,
						convertedOrderPromoDiscountAmount,
						convertedOrderUserCreditAmount,
						convertedMasterOrderTotal,
						
						orderTaxAmount,
						orderCommissionAmount,
						orderPaymentGatewayCharge,
						orderOtherServiceCharge,
						orderRemoved,
						shippingAmount,
						businessID,
						businessPayment,
						convertedBusinessPayment,
						extraData,
						billingFirstName,
						billingLastName,
						customer_email,
						guest_order,
						orderConvenientFee,
						redeemPoint,
                        redeemDiscountAmount,
                                                orderSource,
                                                userCurrencyID,
                                                userCurrencyExcRate,
                                                billingPhone,
                                                showroomID,
                                                subtitle,
                                                brandID,
                                                orderPaidAmount
					)
					VALUES
					(
						'" . $parentOrderID . "',
						'" . $order['orderTotalAmount'] . "',
						'" . $order['orderSubtotal'] . "',
						'" . $order['promoID'] . "',
						'" . $order['orderPromoCode'] . "',
						'" . $order['orderPromoDiscountAmount'] . "',
						'" . $order['userCreditAmount'] . "',
						'" . $order['paymentSettingsGroupID'] . "',
						'" . $order['orderPaymentMethodName'] . "',
						'" . $order['paymentType'] . "',
						'" . $this->escape($order['billingAddress'], false, false) . "',
						'" . $this->escape($order['shippingDeliveryAddress'], false, false) . "',
						'" . $order['netpayOrderID'] . "',
						'" . $order['netpayPaymentType'] . "',
						'" . $order['orderHold'] . "',
						'" . $order['currencyID'] . "',
						'" . $languageID . "',
						'0',
						NOW(),
						NOW(),
						'" . $order['masterOrderQty'] . "',
						'" . $order['orderStatus'] . "',
						'" . $order['userID'] . "',
						'" . $order['paymentStatus'] . "',
						'product',
						'" . $order['convertedMasterOrderSubTotalAmount'] . "',
						'" . $order['convertedOrderPromoDiscountAmount'] . "',
						'" . $order['convertedOrderUserCreditAmount'] . "',
						'" . $order['convertedMasterOrderTotalAmount'] . "',
						'" . $orderData['orderTaxAmount'] . "',
						'" . $orderData['orderCommissionAmount'] . "',
						0,
						'" . $orderData['orderOtherServiceCharge'] . "',
						'No',
						'" . $orderData['shippingAmount'] . "',
						'" . $businessID . "',
						'" . $orderData['businessPayment'] . "',
						'" . $orderData['convertedBusinessPayment'] . "',
						'" . $orderBasedSerializedData . "',
						'" . $billingFirstName . "',
						'" . $billingLastName . "',
						'" . $customerEmail . "',
						'" . $guestOrder . "',
						'" . $orderData['convenientFee'] . "',
						'".$order['redeemPoint']."',
                        '".$order['redeemDiscountAmount']."',
                            '". $this->escape($orderSource)."',
                            '". $this->escape($order['userCurrencyID'])."', 
                            '". $this->escape($order['userCurrencyExcRate'])."'   ,
                                '". $this->escape($billingPhone)."',
                                '". $this->escape($order['showroomID'])."',
                                '". $this->escape($order['subtitle'])."' ,
                                '". $this->escape($order['brandID'])."',
                                '". $this->escape($order['orderPaidAmount'])."'    
					)";
        

        $resInsertItem  = $this->ObjDatabase->setQuery($sql);
        $OrderMsterID   = $this->ObjDatabase->getInsertId();
        $invoice_prefix = $order['invoice_prefix'];
        $invoice_number = $invoice_prefix . $OrderMsterID;
        $sql            = "UPDATE " . DB_PREFIX . "order_masters SET orderNumber = '" . $invoice_number . "' WHERE masterOrderID=" . $OrderMsterID . "";
        $update         = $this->ObjDatabase->setQuery($sql);
        if (count($order['items']) > 0) {
            foreach ($order['items'] as $key => $items) {
                if (count($items['subItem']) > 0) {
                    foreach ($items['subItem'] as $key => $subItems) {
                        $unser                      = unserialize($subItems['itemDetails']);
                        $shippingMethod             = $unser['shippingMethod']['methodName'];
                        $unser['productOptionName'] = $this->decodeSplChar($unser['productOptionName']);
                        $serializedData             = $this->escape($subItems['itemDetails'], false, false);
                        $sql                        = " INSERT INTO " . DB_PREFIX . "order_items
									(
										masterOrderID,
										productID,
										productOptionID,
										orderItemPrice,
										orderItemQuantity,
										orderItemSubtotal,
										orderGiveAsGift,
										productOptionName,
										addedTime,
										extra,
										shipmentStatus,
										shipmentDate,
										carrierDetails,
										combinationHash,
										shippingMethod,
										shippingSetting,
										taxSetting,
										freeProduct,
										originalSubtotal,
                                                                                freeBaseProductID
									) 
									VALUES 
									(
										'" . $OrderMsterID . "',
										'" . $subItems['productID'] . "',
										'" . $subItems['productOptionID'] . "',
										'" . $subItems['orderItemPrice'] . "',
										'" . $subItems['orderItemQuantity'] . "',
										'" . $subItems['orderItemSubtotal'] . "',
										'" . $subItems['orderGiveAsGift'] . "',
										'" . $this->escape($unser['productOptionName'], false, false) . "',
										NOW(),
										'" . $serializedData . "',
										'Pending',
										'',
										'',
										'" . $subItems['combinationHash'] . "',
										'" . $shippingMethod . "',
										'" . $subItems['shippingSetting'] . "',
										'" . $subItems['taxSetting'] . "',
										'" . $subItems['freeProduct'] . "',
										'" . $subItems['actualPrice'] * $subItems['orderItemQuantity'] . "',
                                                                                '" . $subItems['freeBaseProductID'] ."'
									)";
                        $resInsertItem              = $this->ObjDatabase->setQuery($sql);
                    }
                }
            }
        }
        return $OrderMsterID;
    }
    // Function to clear the cart
    public function clearCart($cartID = 0) {
        $ObjDailyProductMail = new DailyProductMailModel();
        $ObjCookie           = Registry::getInstance('Cookie');
        $campaignID          = $ObjCookie->getCookie("EMAIL_CAMPAIGN_ID");
        $campaignEmail       = $ObjCookie->getCookie("EMAIL_CAMPAIGN_USER");
        if ($cartID > 0) {
            $sql = " DELETE FROM 
							" . DB_PREFIX . "cart 
						WHERE 
							cartID='" . (int) $cartID . "'";
            $this->ObjDatabase->setQuery($sql);
            $sql = " DELETE FROM 
							" . DB_PREFIX . "cart_items 
						WHERE 
							cartID='" . (int) $cartID . "'";
            $this->ObjDatabase->setQuery($sql);
            if ($campaignEmail != '' && $campaignID > 0) {
                $extraData = $ObjDailyProductMail->getCartExtraData($campaignID);
                $extra     = unserialize($extraData);
                if (isset($extra['discountUsers']) && count($extra['discountUsers']) > 0) {
                    foreach ($extra['discountUsers'] as $user) {
                        if ($user != $campaignEmail) {
                            $newUserArray[] = $user;
                        }
                    }
                    $extra['discountUsers'] = (isset($newUserArray) ? $newUserArray : array());
                }
                $sql = " UPDATE 
								" . DB_PREFIX . "campaigns 
							SET 
								extra = '" . $this->escape(serialize($extra), false, false) . "'
							 WHERE 
								campaignID=" . (int) $campaignID . " LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
            }
        }
    }
    // Function to getting master order details
    public function getOrderMasterDetails($orderMasterID = 0, $orderNumber = '') {
        if ($orderMasterID > 0 || $orderNumber != '') {
            $sql = " SELECT
							*
						FROM 
							" . DB_PREFIX . "order_masters as ordMas
						WHERE ";
            if ($orderMasterID > 0) {
                $sql .= " ordMas.masterOrderID = " . (int) $orderMasterID . "
						GROUP BY
							ordMas.masterOrderID LIMIT 0,1";
                $resOrder = $this->ObjDatabase->readValue($sql);
                return $resOrder;
            } else {
                $sql .= " ordMas.orderNumber = '" . $orderNumber . "'
						GROUP BY
							ordMas.orderNumber";
                $resOrder = $this->ObjDatabase->readValues($sql);
                return $resOrder;
            }
        }
    }
    // Function to get the order details of master order
    public function getOrderDetails($orderMasterID = 0, $orderNumber = '', $parentOrderID = 0) {
        if ($orderMasterID > 0 || $orderNumber != '' || $parentOrderID > 0) {
            $sql = " SELECT 
							ordMas.*,
							bus.businessDefaultLanguageID,
							bus.businessEmail 
						FROM 
							" . DB_PREFIX . "order_masters ordMas 
						INNER JOIN 
							" . DB_PREFIX . "business bus 
							ON 
							(bus.businessID = ordMas.businessID)";
            if ($orderMasterID > 0) {
                $sql .= " WHERE ordMas.masterOrderID=" . (int) $orderMasterID;
            } else if ($parentOrderID > 0) {
                $sql .= " WHERE ordMas.masterOrderID='" . $parentOrderID . "' OR ordMas.parentOrderID='" . $parentOrderID . "'";
            } else {
                $sql .= " WHERE ordMas.orderNumber='" . $orderNumber . "'";
            }
            $resOrderItems = $this->ObjDatabase->readValues($sql);
            return $resOrderItems;
        }
    }
    // Function to get the order item details of a master order
    public function getOrderItemDetails($orderMasterID = 0, $languageIDs = array(), $orderID = 0, $orderNumber = '') {
        if (count($languageIDs) > 0) {
            $currentLanguageID = $languageIDs['Current'];
            $defaultLanguageID = $languageIDs['Default'];
            if ($orderMasterID > 0 || $orderID > 0 || $orderNumber != '') {
                $sql = " SELECT 
								ordIte.*,
                                                                productOpt.productOptionCashBack,
								productOptDet.productOptionName as optionName,
								busDet.businessName,
								bus.businessEmail,
								bus.businessPhone,
								bus.businessDefaultLanguageID,
								bus.businessKey,
								productDet.productTitle,
								ordMas.masterOrderID,
								ordMas.orderNumber,
                                                                ordMas.businessID,
								productOpt.optionSKU,
                                                                product.qtyPerBatch,
                                                                product.sellAsBatch,
                                                                product.batchType
							FROM 
								" . DB_PREFIX . "order_items ordIte
							INNER JOIN 
								" . DB_PREFIX . "order_masters ordMas 
								ON (";
                if ($orderNumber != '') {
                    $sql .= " ordMas.masterOrderID=ordIte.masterOrderID 
								AND ordMas.orderNumber='" . $orderNumber . "' ) ";
                } else {
                    $sql .= " ordMas.masterOrderID=" . (int) $orderMasterID . " AND ordIte.masterOrderID = ordMas.masterOrderID ) ";
                }
                $sql .= "INNER JOIN 
								" . DB_PREFIX . "products product 
								ON (product.productID = ordIte.productID)
							INNER JOIN  
								" . DB_PREFIX . "product_details productDet 
								ON (productDet.productID = product.productID 
								AND productDet.languageID=" . (int) $currentLanguageID . ")	
							INNER JOIN 
								" . DB_PREFIX . "business bus 
								ON (bus.businessID = ordMas.businessID)
							INNER JOIN 
								" . DB_PREFIX . "business_details busDet 
								ON (busDet.businessID = bus.businessID 
								AND busDet.languageID=" . (int) $currentLanguageID . ")
							INNER JOIN  
								" . DB_PREFIX . "product_options productOpt
								ON (productOpt.productOptionID = ordIte.productOptionID) 	
							INNER JOIN  
								" . DB_PREFIX . "product_option_details productOptDet 
								ON (productOptDet.productOptionID = ordIte.productOptionID 
								AND productOptDet.languageID=" . (int) $currentLanguageID . ") 
							GROUP BY ordIte.orderItemID";
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        } else {
            if ($orderMasterID > 0 || $orderID > 0 || $orderNumber != '') {
                $sql = " SELECT 
								ordIte.*,
                                                                ordMas.businessID 
							FROM 
								" . DB_PREFIX . "order_items ordIte
							INNER JOIN  
								" . DB_PREFIX . "order_masters ordMas 
								ON (";
                if ($orderNumber != '') {
                    $sql .= " ordMas.masterOrderID=ordIte.masterOrderID 
								AND ordMas.orderNumber='" . $orderNumber . "' ) ";
                } else {
                    $sql .= " ordMas.masterOrderID=" . (int) $orderMasterID . " AND ordIte.masterOrderID = ordMas.masterOrderID ) ";
                }
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        }
    }
    
    // Function updating the product inventory after each purchase
    public function updateProductInventory($orderID, $oldOrderID = '',$cancelled='') {
        $resOrderItems = $this->getOrderItemDetails($orderID);
        // To get cancelled order qty
        if ($oldOrderID > 0) {
            $resOldOrderItems = $this->getOrderItemDetails($oldOrderID);
        } else {
            $resOldOrderItems = '';
        }
        $newQty = 0;
        if (count($resOrderItems) > 0) {
            foreach ($resOrderItems as $key => $OrderItem) {
                $currQty                = $OrderItem['orderItemQuantity'];
                $paramsArray            = array(
                    'tableName' => 'products',
                    'fieldName' => 'InventoryTrackLevel',
                    'conditionField' => 'productID',
                    'condition' => '=',
                    'conditionValue' => $OrderItem['productID'],
                    'conditionFieldType' => 'int'
                );
                $resInventoryTrackLevel = $this->getFieldValue($paramsArray);
                if ($resInventoryTrackLevel['InventoryTrackLevel'] != 'No') {
                    if (!empty($resOldOrderItems) && $resOldOrderItems[$key]['orderItemQuantity'] != '') {
                        $newQty = $resOldOrderItems[$key]['orderItemQuantity'];
                    }
                    if($cancelled=='Yes' && $oldOrderID=='') {
                        $newQty  = $currQty;
                        $currQty = 0;
                    }                    
                    if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
//                        $sql                = " UPDATE 
//										" . DB_PREFIX . "product_combination
//									SET 
//										combinationQty = (( (CAST(combinationQty AS  UNSIGNED INTEGER)) 
//                                            + ( CAST('" . $newQty . "' AS  UNSIGNED INTEGER))  )
//                                        - (
//										CAST('" . $currQty . "' AS  UNSIGNED INTEGER)))
//									WHERE 
//										combinationHash = " . $OrderItem['combinationHash'] . " 
//										LIMIT 1";//AND combinationQty >0 LIMIT 1
//                        
//                        //echo $sql;		
//                        $resInventoryUpdate = $this->ObjDatabase->setQuery($sql);
                        $ObjProduct         =   new ProductModel();
                        $combinationID      =  $ObjProduct->getCombinationByHash($OrderItem['combinationHash']);
                        
                        $sql                = " UPDATE 
										" . DB_PREFIX . "product_combination_business
									SET 
										businessCombQuantity = (( (CAST(businessCombQuantity AS  UNSIGNED INTEGER)) 
                                            + ( CAST('" . $newQty . "' AS  UNSIGNED INTEGER))  )
                                        - (
										CAST('" . $currQty . "' AS  UNSIGNED INTEGER)))
									WHERE 
										combinationID = " . $combinationID . " 
                                                                                AND businessID = '".$OrderItem['businessID']."'
										LIMIT 1";//AND combinationQty >0 LIMIT 1
                        
                        //echo $sql;		
                        $resInventoryUpdate = $this->ObjDatabase->setQuery($sql);
                    } else {
//                        $sql                = " UPDATE 
//										" . DB_PREFIX . "product_options
//									SET 
//										productOptionQuantity = (((CAST(productOptionQuantity AS  UNSIGNED INTEGER)) 
//                                        +  (  CAST('" . $newQty . "' AS  UNSIGNED INTEGER))) 
//                                        - (	CAST('" . $currQty . "' AS  UNSIGNED INTEGER)))
//									WHERE 
//										productOptionID = '" . $OrderItem['productOptionID'] . "' 
//										LIMIT 1";//AND productOptionQuantity >0 
//                        $resInventoryUpdate = $this->ObjDatabase->setQuery($sql);
                        
                        $sql                = " UPDATE 
										" . DB_PREFIX . "products_options_business
									SET 
										productOptionQuantity = (((CAST(productOptionQuantity AS  UNSIGNED INTEGER)) 
                                        +  (  CAST('" . $newQty . "' AS  UNSIGNED INTEGER))) 
                                        - (	CAST('" . $currQty . "' AS  UNSIGNED INTEGER)))
									WHERE 
										productOptionID = '" . $OrderItem['productOptionID'] . "'
                                                                                AND businessID = '".$OrderItem['businessID']."'
										LIMIT 1";//AND productOptionQuantity >0 
                        $resInventoryUpdate = $this->ObjDatabase->setQuery($sql);
                    }
                }
                
                // updating sold quantity 
                $sql = " UPDATE 
								" . DB_PREFIX . "product_options
							SET 
								soldQuantity = ((soldQuantity-" . (int) $newQty . ") + " . (int) $currQty . ")	
							WHERE 
								productOptionID = " . (int) $OrderItem['productOptionID'] . " LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
                
                $sql = " UPDATE 
								" . DB_PREFIX . "products_options_business
							SET 
								soldQuantity = ((soldQuantity-" . (int) $newQty . ") + " . (int) $currQty . ")	
							WHERE 
								productOptionID = " . (int) $OrderItem['productOptionID'] . "
                                                                AND businessID = '".$OrderItem['businessID']."' LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
                
                $sql = " UPDATE 
								" . DB_PREFIX . "products
							SET 
								productSoldQuantity = ((productSoldQuantity-" . (int) $newQty . ") + " . (int) $currQty . ") 
							WHERE 
								productID = " . (int) $OrderItem['productID'] . " LIMIT 1";
                $this->ObjDatabase->setQuery($sql);
                // updating sold quantity 
            }
        }
    }
    // function to cheak if any product id out of stock
    public function checkProductOutOfStock($languageIDs, $orderID, $section = '') {
        $defaultLanguageID = $languageIDs['Default'];
        $currentLanguageID = $languageIDs['Current'];
        $resOrderItems     = $this->getOrderItemDetails($orderID);
        $outOfStockOptions = array();
        if (count($resOrderItems) > 0) {
            foreach ($resOrderItems as $OrderItem) {
                $paramsArray            = array(
                    'tableName' => 'products',
                    'fieldName' => 'InventoryTrackLevel',
                    'conditionField' => 'productID',
                    'condition' => '=',
                    'conditionValue' => $OrderItem['productID'],
                    'conditionFieldType' => 'int'
                );
                $resInventoryTrackLevel = $this->getFieldValue($paramsArray);
                if ($section == 'paymentSuccess') {
                    $stockCheck = $OrderItem['orderItemQuantity'];
                } else {
                    $paramsArray                = array(
                        'tableName' => 'products',
                        'fieldName' => 'productQuantityNotifyAt',
                        'conditionField' => 'productID',
                        'condition' => '=',
                        'conditionValue' => $OrderItem['productID'],
                        'conditionFieldType' => 'int'
                    );
                    $resProductQuantityNotifyAt = $this->getFieldValue($paramsArray);
                    if ($resProductQuantityNotifyAt['productQuantityNotifyAt'] > 0) {
                        $stockCheck = $resProductQuantityNotifyAt['productQuantityNotifyAt'] - 1;
                    } else {
                        $stockCheck = 1;
                    }
                }
                if ($resInventoryTrackLevel['InventoryTrackLevel'] != 'No') {
                    $sql = " SELECT  
									productOpt.productOptionID,
									productOptDet.productOptionName AS optName,
									productDet.productTitle
								FROM 
									" . DB_PREFIX . "product_options AS productOpt
								LEFT JOIN 
									" . DB_PREFIX . "product_option_details AS productOptDet
									ON(productOpt.productOptionID = productOptDet.productOptionID)
								LEFT JOIN 
									" . DB_PREFIX . "product_details AS productDet
									 ON(productDet.productID = productOpt.productID AND productDet.languageID=
									 '" . $defaultLanguageID . "')
								LEFT JOIN 
									" . DB_PREFIX . "product_combination AS proCom 
										ON (
											proCom.productID=" . (int) $OrderItem['productID'] . "  
											AND 
											proCom.status = 'A'
										)	 
								WHERE ";
                    if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                        $sql .= " productOpt.productOptionID = '" . $OrderItem['productOptionID'] . "'";
                        if ($section == 'paymentSuccess') {
                            $sql .= " AND proCom.combinationQty <" . $stockCheck;
                        } else {
                            $sql .= " AND proCom.combinationQty <=" . $stockCheck;
                        }
                        $sql .= " AND proCom.combinationQty !=''
									AND proCom.combinationHash =" . $OrderItem['combinationHash'] . "
									AND productOptDet.languageID=" . (int) $defaultLanguageID . "";
                    } else {
                        $sql .= " productOpt.productOptionID = '" . $OrderItem['productOptionID'] . "'";
                        if ($section == 'paymentSuccess') {
                            $sql .= " AND productOpt.productOptionQuantity <" . $stockCheck;
                        } else {
                            $sql .= " AND productOpt.productOptionQuantity <=" . $stockCheck;
                        }
                        $sql .= " AND productOpt.productQuantityUnlimited =0
									AND productOptDet.languageID=" . (int) $defaultLanguageID . "";
                    }
                    //echo $sql;
                    $sql .= " LIMIT 0,1";
                    $resGetInventory = $this->ObjDatabase->readValue($sql);
                }
                if (isset($resGetInventory) && count($resGetInventory) > 0) {
                    unset($tempArray);
                    $tempArray['optName']      = $resGetInventory['optName'];
                    $tempArray['productTitle'] = $resGetInventory['productTitle'];
                    if (isset($outOfStockOptions[$OrderItem['productID']]) && is_array($outOfStockOptions[$OrderItem['productID']])) {
                    } else {
                        $outOfStockOptions[$OrderItem['productID']] = array();
                    }
                    array_push($outOfStockOptions[$OrderItem['productID']], $tempArray);
                }
            }
        }
        return $outOfStockOptions;
    }
    // Function to change the master order/payment status along with order status/payment
    public function changeMasterOrderStatus($orderMasterID, $status = '', $paymentStatus = '', $parent_order_id = 0,$type='') {
        if ($orderMasterID > 0 || $parent_order_id > 0) {
             //UPDATE ORDER STSTUS ID
            if($status!='' && $status=='Process'){
                $dynamicOrderStatus = 'order-received';
                $comments = $dynamicOrderStatus;
            } else {
                $dynamicOrderStatus = strtolower($status);
            }
            // PCJ
            $sql = " UPDATE 
							" . DB_PREFIX . "order_masters 
						SET ";
            if ($orderMasterID > 0) {
                $sql .= " masterOrderID = " . (int) $orderMasterID . " ";
            } else if ($parent_order_id > 0 && $type=='') {
                $sql .= " orderStatusDate=NOW() ";
            }
            $sql .= ($dynamicOrderStatus != '') ? ",dynamicOrderStatus='" . $dynamicOrderStatus . "'" : "";
            if($type!='') {
                $sql .= ($status != '') ? " orderStatus='" . $status . "'" : "";
            } else {
                $sql .= ($status != '') ? ",orderStatus='" . $status . "'" : "";
            }
            $sql .= ($paymentStatus != '') ? ",paymentStatus='" . $paymentStatus . "'" : "";
            if ($orderMasterID > 0) {
                $sql .= " WHERE masterOrderID=" . (int) $orderMasterID . " LIMIT 1";
            } else if ($parent_order_id > 0) {
                $sql .= " WHERE masterOrderID='" . $parent_order_id . "' OR parentOrderID='" . $parent_order_id . "' ";
            }
            $resUpdateOrderStatus = $this->ObjDatabase->setQuery($sql);
            if ($status == 'Error' && $paymentStatus = 'Denied') {
                $this->updateOrderHoldOrders();
            }
            // UPDATE ORDER STATUS LOG
            $comments = isset($comments)?$comments:'Order status changed to '.$dynamicOrderStatus;
            $sql = "INSERT INTO " . DB_PREFIX . "order_status_log( `masterOrderID`, `dynamicOrderStatus`,  `comments`) "
                    . " VALUES ('" . $orderMasterID . "','" . $dynamicOrderStatus . "' ,'".$this->escape($comments)."') ";
            return $this->ObjDatabase->setQuery($sql);
        }
    }
    //Function to update the master order number
    public function updateOrderNumber($orderMasterID) {
        if ($orderMasterID > 0) {
            $sql            = " SELECT 
							orderNumber 
						FROM 
							" . DB_PREFIX . "order_masters  
						WHERE 
							masterOrderID=" . (int) $orderMasterID . " LIMIT 0,1";
            $resOrderNumber = $this->ObjDatabase->readValue($sql);
            if ($resOrderNumber['orderNumber'] < 1) {
                $sql                 = " SELECT 
								MAX(masterOrderID)+1 
							FROM 
								" . DB_PREFIX . "order_masters LIMIT 0,1";
                $resOrderNumber      = $this->ObjDatabase->readValue($sql);
                $orderNumber         = ($resOrderNumber[0] > 0) ? $resOrderNumber[0] : 1;
                $sql                 = " UPDATE 
								" . DB_PREFIX . "order_masters 
							SET 
								orderNumber = '" . $orderNumber . "' 
							WHERE 
								masterOrderID=" . (int) $orderMasterID . " LIMIT 1";
                $resUpdateOrderNumbe = $this->ObjDatabase->setQuery($sql);
                return $orderNumber;
            }
        }
    }
    //fucntion to get the unserialized cart extra data
    public function getUnserializedCartData($cartID = 0) {
        $sql           = " SELECT 
						extra 
					FROM 
						" . DB_PREFIX . "cart
					WHERE 
						cartID= " . (int) $cartID . " LIMIT 0,1";
        $resSelectCart = $this->ObjDatabase->readValue($sql);
        $arrExtraData  = unserialize($resSelectCart['extra']);
        return $arrExtraData;
    }
    // Function to update the cart billing/shipping address
    public function updateUserCartAddress($userID = 0, $cartID = 0, $arrAddress, $adrsType) {
        $extraData = $this->getUnserializedCartData($cartID);
        if ($adrsType == 'Billing') {
            $extraData['userBillingAddress'] = $arrAddress;
        } else if ($adrsType == 'Shipping') {
            $extraData['userShippingAddress'] = $arrAddress;
        }
        $sql                  = " UPDATE 
						" . DB_PREFIX . "cart 
					SET 
						extra = '" . $this->escape(serialize($extraData), false, false) . "' 
					WHERE 
						cartID=" . (int) $cartID . " LIMIT 1";
        $resUpdateCartAddress = $this->ObjDatabase->setQuery($sql);
        if ($adrsType == 'Billing') {
            $this->taxStateId   = ($arrAddress['billingState'] > 0) ? $arrAddress['billingState'] : 0;
            $this->taxCountryId = $arrAddress['billingCountry'];
        }
    }
    public function updateShippingAddress($arrShippingAdrs, $shipAddressID,$type='',$userID='') {
            extract($arrShippingAdrs);
            $shippingFname     = $this->escape($shippingFname);
            $shippingLname     = $this->escape($shippingLname);
            $shippingAddress1  = ($type=='')?$this->escape($shippingAddress):$this->escape($shippingAddress1);
            $shippingAddress2  = ($type=='')?$this->escape($shippingAddress1):$this->escape($shippingAddress2);
            $shippingCity      = $this->escape($shippingCity);
            $shippingZip       = $this->escape($shippingZip);
            $shippingCountryID = $this->escape($shippingCountryID);
            $shippingStateID   = $this->escape($shippingStateID);
            $shippingProvince  = $this->escape($shippingProvince);
            $shippingPhone     = $this->escape($shippingPhone);
            
           $sql            = " update " . DB_PREFIX . "user_shipping set shippingFname='" . $shippingFname . "',shippingLname='" . $shippingLname . "',
                                shippingAddress1='" . $shippingAddress1 . "',shippingAddress2='" . $shippingAddress2 . "',shippingCity='" . $shippingCity . "',
				shippingZip='" . $shippingZip . "',shippingCountryID='" . $shippingCountryID . "',shippingStateID='" . $shippingStateID . "',
				shippingProvince='" . $shippingProvince . "',shippingPhone='" . $shippingPhone . "' where userShippingID=".$shipAddressID."";					
			
           
            $this->ObjDatabase->setQuery($sql);
            
    }
    public function makeShippingAddressPrimary($userShippingID, $userID) {
        $sql = "UPDATE  
					`" . DB_PREFIX . "user_shipping` 
				SET 
					addressPrimary	= 
									CASE 
										WHEN 
											userShippingID=" . (int) $userShippingID . " THEN 'Yes' 
										ELSE 
											'No' 
									END	
				 WHERE 
					userID=" . (int) $userID . "";
        
        $this->ObjDatabase->setQuery($sql);
    }
    // Function to save the cart shipping address to the address bokk
    public function saveCartShippingAddressToList($arrShippingAdrs, $userID,$type='') {
        extract($arrShippingAdrs);
        $shippingFname     = $this->escape($shippingFname);
        $shippingLname     = $this->escape($shippingLname);
        $shippingAddress1  = ($type=='')?$this->escape($shippingAddress) :$this->escape($shippingAddress1);
        $shippingAddress2  = ($type=='')?$this->escape($shippingAddress1):$this->escape($shippingAddress2);
        $shippingCity      = $this->escape($shippingCity);
        $shippingZip       = $this->escape($shippingZip);
        $shippingCountryID = $this->escape($shippingCountryID);
        $shippingStateID   = $this->escape($shippingStateID);
        $shippingProvince  = $this->escape($shippingProvince);
        $shippingPhone     = $this->escape($shippingPhone);
        $sql               = " SELECT 
						(
							SELECT 
								userShippingID 
							FROM 
								" . DB_PREFIX . "user_shipping 
							WHERE 
								userID='" . $userID . "' AND 
								shippingFname='" . $shippingFname . "' AND
								shippingLname='" . $shippingLname . "' AND
								shippingAddress1='" . $shippingAddress1 . "' AND
								shippingAddress2='" . $shippingAddress2 . "' AND
								shippingCity='" . $shippingCity . "' AND
								shippingZip='" . $shippingZip . "' AND
								shippingCountryID='" . $shippingCountryID . "' AND
								shippingStateID='" . $shippingStateID . "' AND
								shippingProvince='" . $shippingProvince . "' AND                                                                
								addressStatus='Active'
							LIMIT 0,1
						)AS dupAddress, 
						(
							SELECT 
								userShippingID 
							FROM 
								" . DB_PREFIX . "user_shipping 
							WHERE 
								userID=" . (int) $userID . " AND 
								addressPrimary='Yes' AND 
								addressStatus='Active'
							LIMIT 0,1					
						) AS dupPrimaryAddress LIMIT 0,1";
        $resSelectAdrs     = $this->ObjDatabase->readValue($sql);
        if (!isset($resSelectAdrs['dupAddress']) && !($resSelectAdrs['dupAddress'] > 0)) {
            $addressPrimary = (isset($resSelectAdrs['dupPrimaryAddress']) && $resSelectAdrs['dupPrimaryAddress'] > 0) ? "No" : "Yes";
            $sql            = " INSERT INTO " . DB_PREFIX . "user_shipping 
						(
							userID,
							shippingFname,
							shippingLname,
							shippingAddress1,
							shippingAddress2,
							shippingCity,
							shippingZip,
							shippingCountryID,
							shippingStateID,
							shippingProvince,
							addressPrimary,
                                                        shippingPhone
						)
						VALUES
						(
							'" . $userID . "',
							'" . $shippingFname . "',
							'" . $shippingLname . "',
							'" . $shippingAddress1 . "',
							'" . $shippingAddress2 . "',
							'" . $shippingCity . "',
							'" . $shippingZip . "',
							'" . $shippingCountryID . "',
							'" . $shippingStateID . "',
							'" . $shippingProvince . "',
							'" . $addressPrimary . "',
                                                        '" . $shippingPhone . "'
						)";
            $this->ObjDatabase->setQuery($sql);
        }
    }
    //GET ALL TAX RATES
    public function getTaxRates() {
        $countryID     = intval($this->taxCountryId);
        $stateID       = $this->taxStateId;
        /*$sql           = " SELECT 
						taxRat.* 
					FROM 
						" . DB_PREFIX . "tax_rates AS taxRat
					INNER JOIN 
						" . DB_PREFIX . "geozones AS geo 
						ON (taxRat.geoZoneID = geo.geoZoneID)
					INNER JOIN 
						" . DB_PREFIX . "geozone_to_regions AS geoToReg 
						ON (taxRat.geoZoneID = geoToReg.geoZoneID)
					INNER JOIN 
						" . DB_PREFIX . "tax_classes AS taxCla 
						ON (taxCla.taxClassID=taxRat.taxClassID)
					LEFT JOIN 
						" . DB_PREFIX . "state_details AS staDet 
						ON (staDet.stateID=geoToReg.stateID)
					WHERE  
						((geoToReg.countryID = '0' 
						AND geoToReg.stateID = '0') 
						OR ((geoToReg.countryID = '" . $countryID . "') 
						AND (geoToReg.stateID = '0' 
						OR geoToReg.stateID = '" . $this->escape($stateID) . "' 
						OR staDet.stateName LIKE '" . $this->escape($stateID) . "')))  
						AND geo.geoZoneStatus='Active' 
						AND taxCla.taxClassStatus='Active' 	 	
					GROUP BY 
						taxRat.taxRateID 
					ORDER BY 
						taxRat.taxClassID, taxRat.taxPriority ";*/
        //new function
        $sql           = " SELECT 
						taxRat.* 
					FROM 
						" . DB_PREFIX . "tax_rates AS taxRat
					INNER JOIN 
						" . DB_PREFIX . "geozones AS geo 
						ON (taxRat.geoZoneID = geo.geoZoneID)
					INNER JOIN 
						" . DB_PREFIX . "geozone_to_regions AS geoToReg 
						ON (taxRat.geoZoneID = geoToReg.geoZoneID)
					INNER JOIN 
						" . DB_PREFIX . "tax_classes AS taxCla 
						ON (taxCla.taxClassID=taxRat.taxClassID)
					LEFT JOIN 
						" . DB_PREFIX . "state_details AS staDet 
						ON (staDet.stateID=geoToReg.stateID)
					WHERE  
						((geoToReg.countryID = '0' 
						AND geoToReg.stateID = '0') 
						OR ((geoToReg.countryID = '" . $countryID . "'";
        if($stateID >0) {
            $sql        .=      " AND geoToReg.stateID = '" . $stateID . "'";
        }
	$sql        .=      " ))) AND geo.geoZoneStatus='Active' 
						AND taxCla.taxClassStatus='Active' 	 	
					GROUP BY 
						taxRat.taxRateID 
					ORDER BY 
						taxRat.taxClassID, taxRat.taxPriority ";
       
        $resGetTaxRate = $this->ObjDatabase->readValues($sql);
        $tax_rates     = array(
            "0" => array(
                "multiplier" => 1,
                "taxRate" => 0,
                "taxClassDescription" => ""
            )
        );
        if ($resGetTaxRate) {
            $_tax_rates = $resGetTaxRate;
            for ($i = 0; $i < count($_tax_rates); $i++) {
                $class_id      = $_tax_rates[$i]["taxClassID"];
                $rate_priority = $_tax_rates[$i]["taxPriority"];
                if (!array_key_exists($class_id, $tax_rates)) {
                    $tax_rates[$class_id] = array(
                        "multiplier" => 1,
                        "taxPriority" => array(),
                        "taxClassDescription" => ""
                    );
                }
                if (!array_key_exists($rate_priority, $tax_rates[$class_id]["taxPriority"])) {
                    $tax_rates[$class_id]["taxPriority"][$rate_priority] = 0;
                }
                $tax_rates[$class_id]["taxPriority"][$rate_priority] += $_tax_rates[$i]["taxRate"];
                $tax_rates[$class_id]["taxClassDescription"] .= ($tax_rates[$class_id]["taxClassDescription"] == "" ? "" : " + ");
                $tax_rates[$class_id]["taxClassDescription"] .= $_tax_rates[$i]["taxDescription"] . " <span class='display-ib'>(" . (number_format($_tax_rates[$i]["taxRate"],2)) . "%)</span>";
            }
            foreach ($tax_rates as $class_id => $class_data) {
                if ($class_id > 0) {
                    $start = 100;
                    foreach ($class_data["taxPriority"] as $rate_priority => $tax_summ) {
                        $start = $start + ($start / 100 * $tax_summ);
                    }
                    $tax_rates[$class_id]["multiplier"] = $start / 100;
                    $tax_rates[$class_id]["taxRate"]    = ($tax_rates[$class_id]["multiplier"] - 1) * 100;
                }
            }
        }
        return $tax_rates;
    }
    // UPDATE ORDER ITEMS TAX
    public function updateCartItemsTax($cartID, $taxCalculationParam) {
        $enableTax    = $taxCalculationParam["taxApplicable"];
        $cartDetails  = $this->getCartDetails($cartID);
        $arrExtraData = isset($cartDetails['extra']) ? unserialize($cartDetails['extra']) : '';
        $addressType  = $taxCalculationParam["addressType"]; // Address type for tax calculation        
        if ($enableTax == 'Yes' && !empty($cartDetails)) {
            if ($addressType == 'Shipping Address') {                
                $this->taxCountryId = isset($arrExtraData['userShippingAddress']['shippingCountryID']) ? $arrExtraData['userShippingAddress']['shippingCountryID'] : '';
                $this->taxStateId   = isset($arrExtraData['userShippingAddress']['shippingStateID']) ? $arrExtraData['userShippingAddress']['shippingStateID'] : '';
            } else {
                $this->taxCountryId = isset($arrExtraData['userBillingAddress']['billingCountry']) ? $arrExtraData['userBillingAddress']['billingCountry'] : '';
                $this->taxStateId   = isset($arrExtraData['userBillingAddress']['billingState']) ? $arrExtraData['userBillingAddress']['billingState'] : '';
            }
            $userID           = isset($cartDetails['userID']) ? $cartDetails['userID'] : '';
            $taxRates         = $this->getTaxRates();            
            $taxAfterDiscount = $taxCalculationParam["applyAfterDiscount"];
            foreach ($cartDetails['items'] as $cartItem) {
                $taxRate            = 0;
                $taxDescription     = "";
                $cartItemTaxRate    = 0;
                $disPer             = 0;
                $taxAmount          = 0;
                $ordItem            = $this->getProductTaxDetails($cartItem['productID']);                
                $isTaxable          = $ordItem["isTaxable"];
                $taxClassID         = $ordItem["taxClassID"];
                $arrCartItemDetails = unserialize($cartItem['itemDetails']);
                if ($isTaxable == "Yes") {
                    
                    if ($ordItem["taxRate"] > 0) {
                        $cartItemTaxRate = $ordItem["taxRate"];
                        $taxDescription  = "";
                    } elseif ($taxClassID > 0 && array_key_exists($taxClassID, $taxRates)) {
                        $cartItemTaxRate = $taxRates[$taxClassID]["taxRate"];
                        $taxDescription  = $taxRates[$taxClassID]["taxClassDescription"];
                    }
                    $cartItemTaxRate = ($cartItemTaxRate > 0) ? $cartItemTaxRate : 0;
                    
                    if (isset($arrCartItemDetails['orderPromoDiscountAmount']) && $taxAfterDiscount == "Yes" && $cartItem['orderItemSubtotal'] > 0) {
                        $discountAmount = $arrCartItemDetails['orderPromoDiscountAmount'];
                        if($cartDetails['freeShipping']=='Yes' && $cartDetails['shippingAmount']>0) {
                            $discountAmount = ($discountAmount>$cartDetails['shippingAmount']) ? $discountAmount - $cartDetails['shippingAmount']:$cartDetails['shippingAmount']-$discountAmount;
                        }
                        $disPer = $discountAmount / ($cartItem['orderItemSubtotal'] / 100);
                    }
                    $mainItemPrice = $cartItem['orderItemPrice'];
                    if($taxCalculationParam["inclusive_tax"]=='Yes') {
                        $mainItemPrice = $mainItemPrice/(($cartItemTaxRate /100) + 1 );
                    }                    
                    $taxAmount      = ($cartItem['orderItemQuantity'] * ($mainItemPrice - $mainItemPrice / 100 * $disPer) * $cartItemTaxRate) / 100;
                    $taxAmount      =  $taxAmount > 0 ? $taxAmount : 0.00;
                     
                }
                //if($userID > 0)
                //{
                $addTaxAmount       = ($taxCalculationParam["inclusive_tax"]=='Yes')?0:$taxAmount;
                $arrCartItemDetails['isTaxable']               = $isTaxable;
                $arrCartItemDetails['orderItemTaxRate']        = $cartItemTaxRate;
                $arrCartItemDetails['orderItemTaxDescription'] = $taxDescription;
                $arrCartItemDetails['orderTaxAmount']          = $taxAmount;
                $arrCartItemDetails['orderItemTotal']          = $arrCartItemDetails['orderItemSubtotal'] + $arrCartItemDetails['orderOtherServiceCharge'] - (isset($arrCartItemDetails['orderPromoDiscountAmount']) ? $arrCartItemDetails['orderPromoDiscountAmount'] : 0) + $addTaxAmount + $arrCartItemDetails['shippingAmount']+$arrCartItemDetails['orderConvenientFee'];
                $sql                                           = " UPDATE 
									" . DB_PREFIX . "cart_items 
								SET 
									itemDetails = '" . $this->escape(serialize($arrCartItemDetails), false, false) . "'
								WHERE 
									cartItemID = " . (int) $cartItem['cartItemID'] . " 
									AND cartID = " . (int) $cartID . " LIMIT 1";
                $resUpdateItems                                = $this->ObjDatabase->setQuery($sql);
                //}
            }
            //$this->resetCartTotals($cartID);
        }
    }
    public function getUserDeliverZoneID($params = array()) {
        extract($params);
        $languageIDs['Current'] = 1;
        $ObjDelivery            = new DeliveryZoneModel();
        $ObjCart                = new CartModel();
        $userDeliveryZoneIDs    = array();
        $deliveryZones          = $ObjDelivery->listDeliveryZones($languageIDs);
        foreach ($deliveryZones as $zone) {
            $deliveryZoneFound   = false;
            $deliveryZoneDetails = $ObjCart->getDeliveryZoneDetails($languageIDs, $zone['deliveryZoneID']);
            if (count($deliveryZoneDetails) > 0) {
                //Looping with delivery zone values
                foreach ($deliveryZoneDetails as $key1 => $zoneReg) {
                    //If delivery zone countryID matching the users countryID
                    if ($zoneReg['countryID'] == $shippingCountryID && $shippingCountryID > 0) {
                        //If delivery zone type is region or local with state ID and user state matching delivery zone state
                        if ($zoneReg['StateID'] > 0 && $zoneReg['StateID'] == $shippingStateID && $shippingStateID > 0) {
                            //Delivery zone type is range with zip code or zip code combination / Delivery zone type is Local
                            if (($zoneReg['zipCodes'] != '' || $zoneReg['isRange'] == 'Yes') && $shippingZip != '') {
                                //Delivery zone type is range with zip code
                                if ($zoneReg['isRange'] == 'Yes' && is_numeric($shippingZip)) {
                                    if ($shippingZip >= $zoneReg['rangeFrom'] && $shippingZip <= $zoneReg['rangeTo']) {
                                        $deliveryZoneFound = true;
                                        break;
                                    }
                                } else if (substr($zoneReg['zipCodes'], -1) == '*') //Delivery zone type is zip code combination / Delivery zone type is Local
                                    {
                                    $zipArray         = explode('*', $zoneReg['zipCodes']);
                                    $startingZip      = $zipArray[0];
                                    $starting_str_len = strlen($startingZip);
                                    $user_sub_zip     = substr($shippingZip, 0, $starting_str_len);
                                    if ($user_sub_zip == $startingZip) {
                                        $deliveryZoneFound = true;
                                        break;
                                    }
                                } else //Delivery zone type is fixed zip code / Delivery zone type is Local
                                    {
                                    $zipArray = explode(',', $zoneReg['zipCodes']);
                                    if (in_array($shippingZip, $zipArray)) {
                                        $deliveryZoneFound = true;
                                        break;
                                    }
                                }
                            } else if ($zoneReg['zipCodes'] == '') //Delivery zone type is region
                                {
                                $deliveryZoneFound = true;
                                break;
                            }
                        } //If delivery zone type is Region with out state ID
                        else if ($shippingStateSelectedType == 'province') {
                            //Delivery zone type is range with zip code / Delivery zone type is Local
                            if ($zoneReg['isRange'] == 'Yes' && is_numeric($shippingZip)) {
                                if ((int) $shippingZip >= $zoneReg['rangeFrom'] && (int) $shippingZip <= $zoneReg['rangeTo']) {
                                    $deliveryZoneFound = true;
                                    break;
                                }
                            } else if (substr($zoneReg['zipCodes'], -1) == '*') //Delivery zone type is zip code combination / Delivery zone type is Local
                                {
                                $zipArray         = explode('*', $zoneReg['zipCodes']);
                                $startingZip      = $zipArray[0];
                                $starting_str_len = strlen($startingZip);
                                $user_sub_zip     = substr($shippingZip, 0, $starting_str_len);
                                if ($user_sub_zip == $startingZip) {
                                    $deliveryZoneFound = true;
                                    break;
                                }
                            } elseif (!empty($zoneReg['zipCodes'])) //Delivery zone type is fixed zip code / Delivery zone type is Local
                                {
                                $zipArray = explode(',', $zoneReg['zipCodes']);
                                if (in_array($shippingZip, $zipArray)) {
                                    $deliveryZoneFound = true;
                                    break;
                                }
                            } else if ($zoneReg['zipCodes'] == '' && $zoneReg['StateID'] < 1) {
                                $deliveryZoneFound = true;
                                break;
                            }
                        } //Delivery zone type is national
                        else if ($zoneReg['zipCodes'] == '' && $zoneReg['StateID'] < 1) {
                            $deliveryZoneFound = true;
                            break;
                        }
                    }
                } //delivery zone details Loop ends
                if ($deliveryZoneFound) {
                    $userDeliveryZoneIDs[] = $zone['deliveryZoneID'];
                }
            }
        }
        return $userDeliveryZoneIDs;
    }
     //CALCULATE SHIPPING RATES
    public function calculateShippingRate($cartID, $shippingCalculationParam,$shipInfo=array()) {
        $ObjCurrency = new CurrencyModel();
        $businessIDs = array();
        extract($shippingCalculationParam);
        $cartDetails                         = $this->getCartDetails($cartID);
        $arrExtraData                        = isset($cartDetails['extra']) ? unserialize($cartDetails['extra']) : '';
        $extraCharge                         = isset($extraCharge) ? $extraCharge : '';
        if(!empty($shipInfo)) {
            $shippingParams['shippingZip']       = $shipInfo['shippingZip'];
            $shippingParams['shippingStateID']   = $shipInfo['shippingStateID'];
            $shippingParams['shippingCountryID'] = $shipInfo['shippingCountryID'];
            $shippingParams['shippingCity']      = $shipInfo['shippingCity'];
            $shippingParams['shippingFname']     = $shipInfo['shippingFname'];
            $shippingParams['shippingLname']     = $shipInfo['shippingLname'];
            $shippingParams['shippingAddress']   = $shipInfo['shippingAddress'];
            $shippingParams['shippingPhone']     = $shipInfo['shippingPhone'];
            if ($shippingParams['shippingStateID'] < 1) {
                $shippingParams['shippingStateSelectedType'] = 'province';
            } else {
                $shippingParams['shippingStateSelectedType'] = 'state';
            }
        } else {
            $shippingParams['shippingZip']       = isset($arrExtraData['userShippingAddress']['shippingZip']) ? $arrExtraData['userShippingAddress']['shippingZip'] : '';
            $shippingParams['shippingStateID']   = isset($arrExtraData['userShippingAddress']['shippingStateID']) ? $arrExtraData['userShippingAddress']['shippingStateID'] : '';
            $shippingParams['shippingCountryID'] = isset($arrExtraData['userShippingAddress']['shippingCountryID']) ? $arrExtraData['userShippingAddress']['shippingCountryID'] : '';
            if ($shippingParams['shippingStateID'] < 1 && isset($arrExtraData['userShippingAddress']['shippingProvince']) && $arrExtraData['userShippingAddress']['shippingProvince'] != '') {
                $shippingParams['shippingStateSelectedType'] = 'province';
            } else {
                $shippingParams['shippingStateSelectedType'] = 'state';
            }
        }
        
        $userDeliveryZoneIDs                     = $this->getUserDeliverZoneID($shippingParams);
        $shippingParams['cartID']                = $cartID;
        $shippingParams['shippingTaxable']       = $shippingCalculationParam['shippingTaxable'];
        $shippingParams['globalShippingCity']    = isset($shippingCalculationParam['globalShippingCity']) ? $shippingCalculationParam['globalShippingCity'] : '';
        $shippingParams['globalShippingCountry'] = isset($shippingCalculationParam['globalShippingCountry']) ? $shippingCalculationParam['globalShippingCountry'] : '';
        $shippingParams['globalShippingState']   = isset($shippingCalculationParam['globalShippingState']) ? $shippingCalculationParam['globalShippingState'] : '';
        $shippingParams['globalShippingZipcode'] = isset($shippingCalculationParam['globalShippingZipcode']) ? $shippingCalculationParam['globalShippingZipcode'] : '';
        $shippingMethodID                        = 1;
        if (count($cartDetails['items']) > 0) {
            $historyMethodID    =   array();
            foreach ($cartDetails['items'] as $itemkey=>$cartItem) {
                $arrCartItemDetails                = unserialize($cartItem['itemDetails']);
                $shippingParams['productID']       = $cartItem['productID'];
                $businessID                        = $cartItem['businessID'];
                $shippingParams['cartItemID']      = $cartItem['cartItemID'];
                $settingsGroupID                   = isset($arrCartItemDetails['shippingMethod']['methodID']) ? $arrCartItemDetails['shippingMethod']['methodID'] : '';
                $method                            = isset($arrCartItemDetails['shippingMethod']) ? $arrCartItemDetails['shippingMethod'] : '';
                $shippingParams['settingsGroupID'] = $settingsGroupID;
                $business_wise_shipping            = isset($arrCartItemDetails['shippingMethod']['business_wise']) ? $arrCartItemDetails['shippingMethod']['business_wise'] : 'No';
                $cartItemQuantity                  = $cartItem['orderItemQuantity'];
                $needDoublecheck                   = true;
                if(empty($settingsGroupID)){
                    $historyMethodID[]  =   $settingsGroupID;
                }
                if ($settingsGroupID > 0) {
                    if ($method['settingsGroupKey'] == 'free_shipping' || $method['settingsGroupParent'] == 1) {
                        $paramsArray       = array(
                            'tableName' => 'shipping_to_product',
                            'fieldName' => 'maxQtyPerShipping',
                            'conditionField' => 'shippingServiceID',
                            'condition' => '=',
                            'conditionValue' => $settingsGroupID,
                            'conditionField1' => 'productID',
                            'condition1' => '=',
                            'conditionValue1' => $cartItem['productID'],
                            'conditionField2' => 'status',
                            'condition2' => '=',
                            'conditionValue2' => 'A',
                            'conditionFieldType' => ''
                        );
                        $resFreeShipQty    = $this->getFieldValue($paramsArray);
                        $maxQtyPerShipping = $resFreeShipQty['maxQtyPerShipping'];
                        if ($cartItemQuantity >= $maxQtyPerShipping) {
                            $shippingCharge = 0;
                            $shippingtype   = 'Free';
                        } else {
                            $shippingMethodID = 0;
                            //continue;
                        }
                    } else if ($shippingFreeEnable != 'No') {
                        if ($shippingFreeEnable == 'Globally') {
                            $defaultCurrencyId = $defaultCurrency;
                            $cartcurrencyId    = $cartDetails['currencyID'];
                            if ($this->ObjView) {
                                $cartAmount = $this->ObjView->convertValueCustom($cartDetails['orderSubtotal'], $cartcurrencyId, $defaultCurrencyId);
                            } else {
                                $cartAmount = $ObjCurrency->convertValueCustom($cartDetails['orderSubtotal'], $cartcurrencyId, $defaultCurrencyId);
                            }
                            $cartQty = $cartDetails['orderQty'];
                            if (($cartAmount > $freeShippingAmount && $freeShippingAmount > 0) || ($cartQty > $freeShippingQty && $freeShippingQty > 0)) {
                                $shippingCharge = 0;
                                $shippingtype   = 'Free';
                            } else {
                                $shippingtype = 'Paid';
                                if ($method['settingsGroupKey'] != '') {
                                    $paramsArray           = array(
                                        'tableName' => 'shipping_methods',
                                        'fieldName' => 'settingsGroupKey',
                                        'conditionField' => 'settingsGroupID',
                                        'condition' => '=',
                                        'conditionValue' => $method['settingsGroupParent'],
                                        'conditionFieldType' => 'int'
                                    );
                                    $resshippingGateWayKey = $this->getFieldValue($paramsArray);
                                    $shippingGateWayKey    = $resshippingGateWayKey['settingsGroupKey'];
                                    $ObjShippingLib        = new Shipping($shippingGateWayKey);
                                    $ObjShipping           = $ObjShippingLib->getShippingObject();
                                    if (!is_object($ObjShipping)) {
                                    } else {
                                        list($shippingCharge, $extraCharge, $maxQtyPerShipping) = $ObjShipping->getShippingRate($shippingParams, 'update');
                                        if ($group_shipping_cost == 'Yes') {
                                            $shippingCharge = $this->getgroupShippingAmount($cartID, $cartItem['businessID'], $settingsGroupID, $userDeliveryZoneIDs,$shippingCharge);
                                        }
                                        $needDoublecheck = false;
                                    }
                                }
                            }
                        } else if ($shippingFreeEnable == 'Business wise') {
                            $businesswiseDetails = $this->getBusinessWiseCartDetails($cartItem['productID'], $cartID);
                            $defaultCurrencyId   = $defaultCurrency;
                            $cartcurrencyId      = $cartDetails['currencyID'];
                            if ($this->ObjView) {
                                $cartAmount = $this->ObjView->convertValueCustom($businesswiseDetails['orderItemSubtotal'], $cartcurrencyId, $defaultCurrencyId);
                            } else {
                                $cartAmount = $ObjCurrency->convertValueCustom($businesswiseDetails['orderItemSubtotal'], $cartcurrencyId, $defaultCurrencyId);
                            }
                            $cartQty = $businesswiseDetails['orderItemQuantity'];
                            if (($cartAmount > $freeShippingAmount && $freeShippingAmount > 0) || ($cartQty > $freeShippingQty && $freeShippingQty > 0)) {
                                $shippingCharge = 0;
                                $shippingtype   = 'Free';
                            } else {
                                $shippingtype = 'Paid';
                                if ($method['settingsGroupKey'] != '') {
                                    $paramsArray           = array(
                                        'tableName' => 'shipping_methods',
                                        'fieldName' => 'settingsGroupKey',
                                        'conditionField' => 'settingsGroupID',
                                        'condition' => '=',
                                        'conditionValue' => $method['settingsGroupParent'],
                                        'conditionFieldType' => 'int'
                                    );
                                    $resshippingGateWayKey = $this->getFieldValue($paramsArray);
                                    $shippingGateWayKey    = $resshippingGateWayKey['settingsGroupKey'];
                                    $ObjShippingLib        = new Shipping($shippingGateWayKey);
                                    $ObjShipping           = $ObjShippingLib->getShippingObject();
                                    if (!is_object($ObjShipping)) {
                                    } else {
                                        list($shippingCharge, $extraCharge, $maxQtyPerShipping) = $ObjShipping->getShippingRate($shippingParams, 'update');
                                        if ($group_shipping_cost == 'Yes' && $business_wise_shipping == 'Yes') {
                                            $shippingCharge = $this->getgroupShippingAmount($cartID, $cartItem['businessID'], $settingsGroupID, $userDeliveryZoneIDs,$shippingCharge);
                                        }
                                        $needDoublecheck = false;
                                    }
                                }
                            }
                        }
                    } else {
                        $shippingtype = 'Paid';
                        if ($method['settingsGroupKey'] != '') {
                            $paramsArray           = array(
                                'tableName' => 'shipping_methods',
                                'fieldName' => 'settingsGroupKey',
                                'conditionField' => 'settingsGroupID',
                                'condition' => '=',
                                'conditionValue' => $method['settingsGroupParent'],
                                'conditionFieldType' => 'int'
                            );
                            $resshippingGateWayKey = $this->getFieldValue($paramsArray);
                            $shippingGateWayKey    = $resshippingGateWayKey['settingsGroupKey'];
                            $ObjShippingLib        = new Shipping($shippingGateWayKey);
                            $ObjShipping           = $ObjShippingLib->getShippingObject();
                            if (!is_object($ObjShipping)) {
                            } else {
                                
                                list($shippingCharge, $extraCharge, $maxQtyPerShipping) = $ObjShipping->getShippingRate($shippingParams, 'update');
                                $needDoublecheck = false;
                                if ($group_shipping_cost == 'Yes') {    
                                    if($shipping_cost_global=='Yes')
                                        $cartItem['businessID'] = 0;
                                    $shippingCharge = $this->getgroupShippingAmount($cartID, $cartItem['businessID'], $settingsGroupID, $userDeliveryZoneIDs,$shippingCharge);
                                  
                                }
                            }
                        }
                    }
                    //if ($cartItem['freeProduct'] == 'Yes' || ($group_shipping_cost == 'Yes'  && in_array($businessID, $businessIDs))) {
                    if ($arrCartItemDetails['free_shipping'] == 'true' || ($group_shipping_cost == 'Yes'  && in_array($businessID, $businessIDs))) {
                        $shippingCharge = 0;
                        $shippingtype   = 'Free';
                    }
                    
                    if($itemkey>0 && $shippingCharge>0 && $shipping_cost_global=='Yes' && $group_shipping_cost == 'Yes' ) {
                        $shippingCharge = 0;
                        $shippingtype   = 'Free';
                    }
                    $historyMethodID[]  =   $settingsGroupID;
                    $arrCartItemDetails['shippingAmount']                      = $shippingCharge;
                    $arrCartItemDetails['shippingMethod']['shippingCharge']    = $shippingCharge;
                    $arrCartItemDetails['shippingMethod']['shippingtype']      = $shippingtype;
                    $arrCartItemDetails['shippingMethod']['extraCharge']       = $extraCharge;
                    $arrCartItemDetails['shippingMethod']['maxQtyPerShipping'] = (isset($maxQtyPerShipping)) ? $maxQtyPerShipping : '';
                    //print_r($arrCartItemDetails['shippingMethod']);
                    if ($shippingMethodID == 0) {
                        $arrCartItemDetails['shippingMethod']['methodID'] = 0;
                    }
                    $serlCartItemDetails = $this->escape(serialize($arrCartItemDetails), false, false);
                    if ($group_shipping_cost == 'Yes' ) { //&& $business_wise_shipping == 'Yes'
                        $businessIDs[] = $businessID;
                    }
                    $sql           = " UPDATE 
									" . DB_PREFIX . "cart_items 
								SET 
									itemDetails='" . $serlCartItemDetails . "' 
								WHERE 
									cartID=" . (int) $cartID . " 
									AND cartItemID=" . (int) $cartItem['cartItemID'] . " LIMIT 1";
                    
                    $resUpdateItem = $this->ObjDatabase->setQuery($sql);
                    if ($method['settingsGroupKey'] != '' && $cartItem['freeProduct']!= 'Yes') {
                        $paramsArray           = array(
                            'tableName' => 'shipping_methods',
                            'fieldName' => 'settingsGroupKey',
                            'conditionField' => 'settingsGroupID',
                            'condition' => '=',
                            'conditionValue' => $method['settingsGroupParent'],
                            'conditionFieldType' => 'int'
                        );
                        $resshippingGateWayKey = $this->getFieldValue($paramsArray);
                        $shippingGateWayKey    = $resshippingGateWayKey['settingsGroupKey'];
                        $ObjShippingLib        = new Shipping($shippingGateWayKey);
                        $ObjShipping           = $ObjShippingLib->getShippingObject();
                        if (!is_object($ObjShipping)) {
                        } else {
                            //Double checking
                            //If address not matching for shiping method need to reset
                            //list($shippingChargeTmp, $extraChargeTmp, $maxQtyPerShippingTmp) = $ObjShipping->getShippingRate($shippingParams, 'update');
                        }
                    }
                }
            }
            
        }
        return true;
    }
           
    //GET SHIPPING RATES
    public function getProductTaxDetails($productID) {
        $sql           = " SELECT 
						isTaxable, 
						taxClassID, 
						taxRate 
					FROM 
						" . DB_PREFIX . "products product 
					WHERE 
						productID=" . (int) $productID . " LIMIT 0,1";
        $resTaxDetails = $this->ObjDatabase->readValue($sql);
        return $resTaxDetails;
    }
    //Function to get the distinct order item details
    public function getDistinctOrderItemDetails($orderMasterID = 0, $languageIDs = array(), $orderID = 0, $orderNumber = '') {
        if (count($languageIDs) > 0) {
            $currentLanguageID = $languageIDs['Current'];
            $defaultLanguageID = $languageIDs['Default'];
            if ($orderMasterID > 0 || $orderID > 0 || $orderNumber != '') {
                $sql = " SELECT 
								ordIte.*,
								productDet.productTitle as productTitle,
								busDet.businessName,
								bus.businessEmail,
								bus.businessDefaultLanguageID,
								product.productUrl,
								bus.businessKey,
								product.productImage								
							FROM 
								" . DB_PREFIX . "order_items ordIte
							INNER JOIN 
								" . DB_PREFIX . "order_masters ordMas 
								ON (";
                if ($orderNumber != '') {
                    $sql .= " ordIte.masterOrderID=ordMas.masterOrderID 
								AND ordMas.orderNumber='" . $orderNumber . "') ";
                } else {
                    $sql .= " ordMas.masterOrderID=" . (int) $orderMasterID . " AND ordIte.masterOrderID = ordMas.masterOrderID )";
                }
                $sql .= "INNER JOIN 
								" . DB_PREFIX . "products product 
								ON (product.productID = ordIte.productID)
							INNER JOIN 
								" . DB_PREFIX . "product_details productDet 
								ON (productDet.productID = product.productID 
								AND productDet.languageID=" . (int) $currentLanguageID . ")
							INNER JOIN 
								" . DB_PREFIX . "business bus 
								ON (bus.businessID = ordMas.businessID)
							INNER JOIN 
								" . DB_PREFIX . "business_details busDet 
								ON (busDet.businessID = bus.businessID 
								AND busDet.languageID=" . (int) $currentLanguageID . ")
                                                                    GROUP BY 
								ordIte.productID";
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        } else {
            if ($orderMasterID > 0 || $orderID > 0 || $orderNumber != '') {
                $sql           = " SELECT 
								ordIte.*,
								sum(orderItemQuantity) as totalQuantity,
								ordMas.orderNumber
							FROM 
								" . DB_PREFIX . "order_items ordIte 
							INNER JOIN  
								" . DB_PREFIX . "order_masters ordMas 
								ON (ordMas.masterOrderID=" . (int) $orderMasterID . " AND ordIte.masterOrderID = ordMas.masterOrderID ) 
							GROUP BY 
								ordIte.productID";
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        }
    }
    // Function to get the distinct order items product id
    public function getDistinctOrderItemProductID($orderMasterID = 0, $orderNumber = '') {
        if ($orderMasterID > 0 || $orderNumber != '') {
            $sql = " SELECT 
							distinct(ordIte.productID) 
						FROM 
							" . DB_PREFIX . "order_items ordIte
						INNER JOIN  
							" . DB_PREFIX . "order_masters ordMas 
							ON (ordIte.masterOrderID=ordMas.masterOrderID ";
            if ($orderMasterID > 0) {
                $sql .= " AND ordMas.masterOrderID=" . (int) $orderMasterID . ")";
            } else {
                $sql .= " AND ordMas.orderNumber='" . $orderNumber . "')";
            }
            $resOrderItems = $this->ObjDatabase->readValues($sql);
            return $resOrderItems;
        }
    }
    //Select and Update All Orders generated before 5 Minutes and in OrderHold status
    public function updateOrderHoldOrders() {
        $sql             = " SELECT 
						GROUP_CONCAT(DISTINCT masterOrderID) AS masterOrderIDs
					FROM 
						" . DB_PREFIX . "order_masters ordMas
					WHERE 
						ordMas.orderNumber=0 
						AND ordMas.orderHold='Yes' 
						AND ordMas.orderType='product' 
						AND ordMas.orderCreatedDate < DATE_SUB(NOW(),INTERVAL 5 MINUTE)";
        $resHoldedOrders = $this->ObjDatabase->readValue($sql);
        $masterOrderIDs  = $resHoldedOrders['masterOrderIDs'];
        if ($masterOrderIDs != '') {
            $sql          = " UPDATE 
							" . DB_PREFIX . "order_masters 
						SET 
							orderHold = 'No' 
						WHERE  
							masterOrderID IN (" . $masterOrderIDs . ")";
            $resHoldOrder = $this->ObjDatabase->setQuery($sql);
        }
    }
    public function getDistinctCartItem($cartID) {
        $sql        = " SELECT 
							distinct(productID)
						FROM  
							" . DB_PREFIX . "cart cart
						INNER JOIN 
							" . DB_PREFIX . "cart_items AS cartIte 
							ON 
							(cartIte.cartID=cart.cartID)			
						WHERE 
							cart.cartID=" . (int) $cartID;
        $resProduct = $this->ObjDatabase->readValues($sql);
        return $resProduct;
    }
    public function setSpecialCampaignDiscount($cartID = 0) {
        $ObjDailyProductMail = new DailyProductMailModel();
        $ObjUser             = new UserModel();
        $ObjCurrency         = new CurrencyModel();
        $ObjCookie           = Registry::getInstance('Cookie');
        $resCart             = $this->getCartDetails($cartID);
        $userID              = $resCart['userID'];
        $campaignID          = $ObjCookie->getCookie("EMAIL_CAMPAIGN_ID");
        $campaignEmail       = $ObjCookie->getCookie("EMAIL_CAMPAIGN_USER");
        $notificationID      = $ObjCookie->getCookie("EMAIL_NOTIFICATION_ID");
        if ($campaignEmail == '') {
            return;
        }
        if ($userID > 0) {
            $userDetails = $ObjUser->getUserInfoForSubscription($userID);
            if ($userDetails['userEmail'] != $campaignEmail) {
                if (count($resCart['items']) > 0) {
                    foreach ($resCart['items'] as $cartItems) {
                        $itemDiscount     = 0;
                        $unserializedData = unserialize($cartItems['itemDetails']);
                        $unserializedData['orderPromoDiscountAmount'] += $itemDiscount;
                        $serializedData = serialize($unserializedData);
                        $sql            = " UPDATE 
										" . DB_PREFIX . "cart_items 
									SET 
										itemDetails = '" . $this->escape($serializedData, false, false) . "'
									 WHERE 
										cartItemID=" . (int) $cartItems['cartItemID'] . " LIMIT 1";
                        $result         = $this->ObjDatabase->setQuery($sql);
                    }
                }
                $sql    = " UPDATE 
								" . DB_PREFIX . "cart 
							SET 
								orderPromoCode = '',
								orderPromoDiscountAmount='',
								promoID=0
							 WHERE 
								cartID=" . (int) $cartID . " LIMIT 1";
                $result = $this->ObjDatabase->setQuery($sql);
                return;
            }
        }
        if (($campaignID > 0 && $campaignEmail != '') || ($notificationID > 0 && $campaignEmail != '')) {
            $mailExist = false;
            $extraData = $ObjDailyProductMail->getCartExtraData($campaignID, $notificationID);
            $extra     = unserialize($extraData);
            if ($campaignID > 0) {
                if (isset($extra['discountUsers']) && count($extra['discountUsers']) > 0) {
                    if (in_array($campaignEmail, $extra['discountUsers'])) {
                        $mailExist = true;
                    } else {
                        $mailExist = false;
                    }
                } else {
                    $mailExist = false;
                }
            }
            if (((isset($extra['discountUsers']) && count($extra['discountUsers'])) || $notificationID > 0) && $extra['discount'] > 0 && $resCart['orderTotalAmount'] >= 0) {
                if ($mailExist || $notificationID > 0) {
                    $promoType = ($campaignID > 0) ? "CAMP_" . $campaignID : "NOTIF_" . $notificationID;
                    $promoCode = $promoType . "_" . date('d') . '_' . date('m') . '_' . date('Y');
                    if ($extra['discountType'] == 'Percentage') {
                        $discountAmount = $resCart['orderSubtotal'] * ($extra['discount'] / 100);
                        if (count($resCart['items']) > 0) {
                            //$itemdiscount	=  $discountAmount/count($resCart['items']);
                        }
                    } else {
                        if ($this->ObjView) {
                            $defaultCurrencyId = $this->ObjView->_defaultCurrency;
                        } else {
                            $resDefaultCurrency = $ObjCurrency->getDefaultCurrencyDetails('', 'ID');
                            $defaultCurrencyId  = $resDefaultCurrency['currencyID'];
                        }
                        if ($this->ObjView) {
                            $discountAmount = $this->ObjView->convertValueCustom($extra['discount'], $defaultCurrencyId, $resCart['currencyID']);
                        } else {
                            $discountAmount = $ObjCurrency->convertValueCustom($extra['discount'], $defaultCurrencyId, $resCart['currencyID']);
                        }
                        if ($discountAmount > $resCart['orderSubtotal'] && $resCart['orderSubtotal'] > 0) {
                            $discountAmount = $resCart['orderSubtotal'];
                        }
                        if (count($resCart['items']) > 0) {
                            //$itemdiscount	=  $discountAmount/count($resCart['items']);
                        }
                    }
                    if (count($resCart['items']) > 0) {
                        foreach ($resCart['items'] as $cartItems) {
                            $itemdiscount     = $discountAmount * ((($cartItems['orderItemSubtotal'] / $resCart['orderSubtotal']) * 100) / 100);
                            $unserializedData = unserialize($cartItems['itemDetails']);
                            if (!isset($unserializedData['orderPromoDiscountAmount'])) {
                                $unserializedData['orderPromoDiscountAmount'] = 0;
                            }
                            $unserializedData['orderPromoDiscountAmount'] += $itemdiscount;
                            $serializedData = serialize($unserializedData);
                            $sql            = " UPDATE 
											" . DB_PREFIX . "cart_items 
										SET 
											itemDetails = '" . $this->escape($serializedData, false, false) . "'
										 WHERE 
											cartItemID=" . (int) $cartItems['cartItemID'] . " LIMIT 1";
                            $result         = $this->ObjDatabase->setQuery($sql);
                        }
                    }
                    $sql    = " UPDATE 
									" . DB_PREFIX . "cart 
								SET 
									orderPromoCode = '" . $promoCode . "',
									orderPromoDiscountAmount=orderPromoDiscountAmount+" . $discountAmount . ",
									promoID=0
								 WHERE 
									cartID=" . (int) $cartID . " LIMIT 1";
                    $result = $this->ObjDatabase->setQuery($sql);
                    return;
                }
            }
        }
    }
    public function saveCartNotification($cartID, $extra) {
        $sql    = " INSERT INTO " . DB_PREFIX . "cart_notifications 	
					(
						cartID,
						extra,
						sendTime
					) 
					VALUES
					(
						" . (int) $cartID . ",
						'" . serialize($extra) . "',
						NOW()
					)";
        $result = $this->ObjDatabase->setQuery($sql);
        return $this->ObjDatabase->getInsertId();
    }
    public function getNotificationDetails($notificationID) {
        $sql    = " SELECT 
							*
						FROM  
							" . DB_PREFIX . "cart_notifications
						WHERE 
							notificationID=" . (int) $notificationID . " LIMIT 0,1";
        $result = $this->ObjDatabase->readValue($sql);
        return $result;
    }
    public function getOrderMasterDetailsByOrderNumber($orderNumber = '') {
        if ($orderNumber != '') {
            $sql      = " SELECT
							ordMas.masterOrderID,
							ordMas.orderNumber,
							ordMas.orderType,
							ordMas.promoID,
							ordMas.orderPromoCode,
							ordMas.paymentSettingsGroupID,
							ordMas.orderPaymentMethodName,
							ordMas.paymentType,
							ordMas.languageID,
							ordMas.purchasedCurrency,
							ordMas.billingAddress,
							ordMas.shippingAddress,	
							ordMas.netpayOrderID,
							ordMas.netpayPaymentType,
							ordMas.orderHold,
							ordMas.orderHold,
							ordMas.transactionID,
							ordMas.paymentStatus,
							ordMas.orderStatus,
							ordMas.paymentNotes,
							ordMas.userID,
							ordMas.cityID,
							ordMas.orderCreatedDate,
							ordMas.orderStatusDate,
							ordMas.customer_email,
							SUM(ordMas.orderTotalAmount) as orderTotalAmount,
							SUM(ordMas.convertedMasterOrderTotal) as convertedMasterOrderTotal,
							SUM(ordMas.orderSubtotal) as masterOrderSubtotal,
							SUM(ordMas.orderSubtotal) as orderSubtotal,
							SUM(ordMas.convertedMasterOrderSubtotal) as convertedMasterOrderSubtotal,
							SUM(ordMas.orderQty) as orderQty,
							SUM(ordMas.orderPromoDiscountAmount) as orderPromoDiscountAmount,
							SUM(ordMas.convertedOrderPromoDiscountAmount) as convertedOrderPromoDiscountAmount,
							SUM(ordMas.orderUserCreditAmount) as orderUserCreditAmount,
							SUM(ordMas.convertedOrderUserCreditAmount) as convertedOrderUserCreditAmount,
							SUM(ordMas.orderQty) as orderQty,
							SUM(ordMas.orderTaxAmount) as orderTaxAmount,
							SUM(ordMas.orderCommissionAmount) as orderCommissionAmount,
							SUM(ordMas.orderPaymentGatewayCharge) as
							orderPaymentGatewayCharge,
							SUM(ordMas.orderOtherServiceCharge) as
							orderOtherServiceCharge,
							SUM(ordMas.shippingAmount) as shippingAmount  
						FROM 
							" . DB_PREFIX . "order_masters as ordMas 
						WHERE 
							ordMas.orderNumber = '" . $orderNumber . "'
						GROUP BY
							ordMas.orderNumber LIMIT 0,1";
            $resOrder = $this->ObjDatabase->readValue($sql);
            return $resOrder;
        }
    }
    public function getOrderMasterIDByOrderNumber($order_id = 0, $orderType = 'sigle',$languageID ='') {
        $fields = 'orderMas.masterOrderID,orderMas.orderNumber,orderMas.businessID';
        if($languageID!='') {
            $fields .= ',orderMas.orderTotalAmount,orderMas.billingAddress,busDet.businessName,bus.businessPhone';
        }
        $sql = " SELECT ".$fields." FROM  " . DB_PREFIX . "order_masters orderMas ";        
        if ($languageID > 0) {
            $sql .= "
                                            LEFT JOIN 
                                                            " . DB_PREFIX . "business AS bus 
                                                    ON (
                                                            orderMas.businessID = bus.businessID 
                                                                                    )					
                                            LEFT JOIN 
                                                    " . DB_PREFIX . "business_details busDet 
                                                    ON( busDet.businessID=orderMas.businessID
                                                    AND busDet.languageID=" . (int) $languageID . ")";
        }
        $sql        .= " WHERE orderMas.masterOrderID='" . $order_id . "' OR orderMas.parentOrderID='" . $order_id . "'";
        if ($orderType == 'sigle') {
            $result = $this->ObjDatabase->readValue($sql);
            return $result['masterOrderID'];
        } else {
            $result = $this->ObjDatabase->readValues($sql);
            return $result;
        }
    }
    public function getOrderMasterIDByTransactionID($transactionID = 0, $orderType = 'sigle') {
        $sql    = " SELECT 
							masterOrderID,
							orderNumber
						FROM  
							" . DB_PREFIX . "order_masters
						WHERE 
							transactionID='" . $transactionID . "'";
        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    }
    public function getCombination($combinationHash = 0, $productOptionID = 0,$currBusinessID=0) {
        if($currBusinessID>0){
            $sqlJoin        =   " INNER JOIN ".DB_PREFIX."product_combination_business prodCombBus ON
                                  (prodCombBus.combinationID = proCom.combinationID AND
                                   prodCombBus.businessID = '".$currBusinessID."')";
            $sqlFields      =   "prodCombBus.businessCombQuantity as combinationQty,
                                 prodCombBus.businessCombPrice as combinationPrice,
                                 prodCombBus.businessCombDiff as combinationPriceDiffType,";
        }else{
            $sqlJoin        =   "";
            $sqlFields      =   "proCom.combinationQty,
                                 proCom.combinationPrice,
                                 proCom.combinationPriceDiffType,";
        }
        $sql = " SELECT 
						proCom.combinationID,
                                                proCom.productID,
                                                proCom.combination,
                                                proCom.combinationHash,
                                                proCom.combinationSKU,
                                                proCom.combinationBarCode,
                                                $sqlFields
                                                proCom.status,
                                                proCom.combinationWeight,
                                                proCom.combinationWeightDiffType,
                                                proCom.combinationHeight,
                                                proCom.combinationWidth,
                                                proCom.combinationLength
					FROM  
						" . DB_PREFIX . "product_combination proCom
                                        $sqlJoin
					WHERE proCom.status='A' AND ";
        if ($combinationHash != '') {
            $sql .= " proCom.combinationHash=" . $combinationHash;
        }
        $sql .= " LIMIT 0,1";
        $result = $this->ObjDatabase->readValue($sql);
        return $result;
    }
    public function getProductCustomOptions($productID = 0, $customOptionID = 0, $languageIDs = array()) {
        $currentLanguageID = isset($languageIDs['Current']) ? $languageIDs['Current'] : 0;
        if ($productID > 0 || $customOptionID > 0) {
            $sql = "SELECT 
						proCusOpt.customOptionID,
						proCusOpt.inputType,
						proCusOpt.validateRule,
						proCusOpt.priceDiff,
						proCusOpt.priceDiffType";
            if ($currentLanguageID > 0) {
                $sql .= " ,proCusOptDet.customOptionName ";
            }
            $sql .= " FROM 
						" . DB_PREFIX . "product_custom_option as proCusOpt";
            if ($currentLanguageID > 0) {
                $sql .= " LEFT JOIN 
						" . DB_PREFIX . "product_custom_option_details as proCusOptDet
					ON
						proCusOpt.customOptionID = proCusOptDet.customOptionID 
						AND proCusOptDet.languageID = " . (int) $currentLanguageID;
            }
            if ($productID > 0) {
                $sql .= " LEFT JOIN 
						" . DB_PREFIX . "product_custom_option_link as proCusOptLin
					ON
						proCusOptLin.customOptionID=proCusOpt.customOptionID
					WHERE 
						proCusOptLin.productID =" . (int) $productID;
            } else if ($customOptionID > 0) {
                $sql .= " WHERE 
						proCusOpt.customOptionID =" . (int) $customOptionID;
            }
            $sql .= " AND proCusOpt.status = 'A' 
					ORDER BY 
						proCusOpt.customOptionID";
            if ($customOptionID > 0) {
                $sql .= " LIMIT 0,1";
                $result = $this->ObjDatabase->readValue($sql);
            } else {
                $result = $this->ObjDatabase->readValues($sql);
            }
            if (count($result) > 0) {
                return $result;
            } else {
                return array();
            }
        }
    }
    public function getProductCustomOptionVariant($VariantID, $languageIDs = array()) {
        $currentLanguageID = $languageIDs['Current'];
        if ($VariantID > 0) {
            $sql = "SELECT 
						proCusOptVar.customOptionVariantID,";
            if ($currentLanguageID > 0) {
                $sql .= " proCusOptVarDet.value,";
            }
            $sql .= "	proCusOptVar.customOptionID, 
						proCusOptVar.variantThumbImage, 
						proCusOptVar.priceDiff, 
						proCusOptVar.priceDiffType, 
						proCusOptVar.weightDiff, 
						proCusOptVar.weightDiffType, 
						proCusOptVar.sortOrder,
						proCusOptVar.isDefault,
						proCusOptVar.status						 
					FROM 
						" . DB_PREFIX . "product_custom_option_variant as proCusOptVar";
            if ($currentLanguageID > 0) {
                $sql .= " LEFT JOIN 
						" . DB_PREFIX . "product_custom_option_variant_details as proCusOptVarDet 
						ON proCusOptVar.customOptionVariantID = proCusOptVarDet.customOptionVariantID 
						AND proCusOptVarDet.languageID = " . (int) $currentLanguageID;
            }
            $sql .= " WHERE 
						proCusOptVar.customOptionVariantID =" . (int) $VariantID . "   
					ORDER BY 
						proCusOptVar.sortOrder, 
						proCusOptVar.customOptionVariantID LIMIT 0,1";
            $result = $this->ObjDatabase->readValue($sql);
            return $result;
        }
    }
    public function getProductOptionPrice($productOptionID = 0) {
        $sql    = " SELECT 
						productOptionProductPrice
					FROM  
						" . DB_PREFIX . "product_options
					WHERE 
						productOptionID=" . (int) $productOptionID . " LIMIT 0,1";
        $result = $this->ObjDatabase->readValue($sql);
        return $result['productOptionProductPrice'];
    }
    public function getFieldValue($paramsArray = array()) {
        extract($paramsArray);
        $sql = "SELECT 
						" . $fieldName . "
					 FROM 
						" . DB_PREFIX . $tableName;
        if ($conditionField != '' && $condition != '') {
            $sql .= " WHERE 
							" . $conditionField . " " . $condition;
            if ($conditionFieldType == 'int') {
                $sql .= " " . $conditionValue;
            } else {
                $sql .= "'" . $conditionValue . "'";
            }
        }
        if (isset($conditionField1) && $conditionField1 != '' && $condition1 != '') {
            $sql .= " AND
							" . $conditionField1 . " " . $condition1;
            if ($conditionFieldType == 'int') {
                $sql .= " " . $conditionValue1;
            } else {
                $sql .= "'" . $conditionValue1 . "'";
            }
        }
        if (isset($conditionField2) && $conditionField2 != '' && $condition2 != '') {
            $sql .= " AND
							" . $conditionField2 . " " . $condition2;
            if ($conditionFieldType == 'int') {
                $sql .= " " . $conditionValue2;
            } else {
                $sql .= "'" . $conditionValue2 . "'";
            }
        }
        if (isset($conditionField3) && $conditionField3 != '' && $condition3 != '') {
            $sql .= " AND
							" . $conditionField3 . " " . $condition3;
            if ($conditionFieldType == 'int') {
                $sql .= " " . $conditionValue3;
            } else {
                $sql .= "'" . $conditionValue3 . "'";
            }
        }
        $sql .= " LIMIT 0,1";
        $result = $this->ObjDatabase->readValue($sql);
        return $result;
    }
    public function listProductShippingMethods($productID='', $settingsGroupID = 0,$productIDs='',$orderID='') {
        $sql = " SELECT 
						shiMet.settingsGroupID,
						shiMet.isRealTimeCalculation,
						shiMet.settingsGroupXmlLabel,
						shiMet.settingsGroupKey,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.taxClassID,
						shiMet.settingsGroupParent,
						shiToPro.shippingtoproductID,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.handlingCharge, ";
        if($productIDs!='') {
            $sql .= "                product.productID ";
            if($orderID!='') {
                $sql .= "                ,ordMas.businessID,ordIte.orderItemID ";
            }else{
                $sql .= "                ,product.businessID ";
            }
        } else {
            $sql .= "               " . $productID . " as productID ";
        }
	$sql .= "				FROM
						" . DB_PREFIX . "shipping_to_product as shiToPro
					LEFT JOIN 
						" . DB_PREFIX . "shipping_methods shiMet
						ON(shiMet.settingsGroupParent!=0 
						AND shiMet.settingsGroupID=shiToPro.shippingServiceID) ";
        if($productIDs!='') {
                  $sql .= "                       LEFT JOIN 
						" . DB_PREFIX . "products product
						ON(product.productID=shiToPro.productID)";
                  if($orderID!='') {
                      $sql .= "                       LEFT JOIN 
						" . DB_PREFIX . "order_items ordIte
						ON(ordIte.productID=product.productID ";
                      if($orderID!='') {
                            $sql .= " AND ordIte.masterOrderID='".$orderID."'";
                      }
                      $sql .= " )
                                        LEFT JOIN 
						" . DB_PREFIX . "order_masters ordMas
						ON(ordMas.masterOrderID=ordIte.masterOrderID)";
                  }
                  $sql .= " 				WHERE 
						shiToPro.productID in (" . $productIDs . ") AND shiToPro.status='A'";
                  
        } else {
            $sql .= " 				WHERE 
						shiToPro.productID=" . (int) $productID . " AND shiToPro.status='A'";
        }        
	
        if ($settingsGroupID > 0) {
            $sql .= " AND shiMet.settingsGroupID=" . (int) $settingsGroupID . "";
        }
        if($productIDs!='') {
            if($orderID!='') {
                $sql .= " GROUP BY ordMas.businessID order by shiToPro.ModifiedDate desc";
            }else{
                $sql .= " GROUP BY product.businessID order by shiToPro.ModifiedDate desc";
            }
            
        } else {
            $sql .= " GROUP BY shiToPro.ModifiedDate desc";
        }
        //echo $sql;exit;
        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    }
    public function listShippingMethods($cartID, $settingsGroupID = 0, $languageIDs = array(), $group_shipping_cost = 'No', $userDeliveryZoneIDs = array(),$shipping_cost_global='') {
        $currentLanguageID = isset($languageIDs['Current']) ? $languageIDs['Current'] : '1';
        if ($group_shipping_cost == 'Yes') {
            $resSameShipmentcount = $this->checkProductCountOfCart($cartID, $settingsGroupID, $languageIDs, $group_shipping_cost, $userDeliveryZoneIDs,$shipping_cost_global);
            $resSameShipmentcount1 = $resSameShipmentcount[0];
            $commonShipments                        = $resSameShipmentcount[1];//  array($sameshipmentcount,$commonShipments)
        }
        $sql               = " SELECT 
		";
        if ($group_shipping_cost == 'Yes') {
            $sql .= "
						GROUP_CONCAT(DISTINCT productOptDet.productOptionName   ORDER BY carIte.productID DESC SEPARATOR ' <br>') as productOptionName,
						GROUP_CONCAT(DISTINCT carIte.productID  ORDER BY carIte.productID DESC) AS productIDs,
                                                GROUP_CONCAT(DISTINCT carIte.productID  ORDER BY carIte.productID DESC) AS productID,
						SUM(orderItemQuantity) AS orderItemQuantity,
						MAX(shiToPro.baseCharge) AS baseCharge,
						MAX(shiToPro.maxQtyPerShipping) AS maxQtyPerShipping,
						MAX(shiToPro.chargePerExtraQty) AS chargePerExtraQty,
						MAX(shiToPro.handlingCharge) AS handlingCharge,
						GROUP_CONCAT(DISTINCT shippingtoproductID   ORDER BY baseCharge DESC) as shippingtoproductID,
                                                GROUP_CONCAT(settingsGroupID  ORDER BY baseCharge DESC ) as settingsGroupIDCC,
			";
        } else {
            $sql .= "
						productOptDet.productOptionName,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.handlingCharge,
						shiToPro.shippingtoproductID,
                                                carIte.productID,
			";
        }
        $sql .= "	
						shiMet.settingsGroupID,
						shiMet.isRealTimeCalculation,
						shiMet.settingsGroupXmlLabel,
						
                                                carIte.productOptionID,
						carIte.businessID,
						carIte.itemDetails,
						shiMet.settingsGroupKey,
						shiToPro.taxClassID,
						shiMet.settingsGroupParent
						
					FROM
						" . DB_PREFIX . "cart_items carIte
					INNER JOIN
						" . DB_PREFIX . "products product
							ON	(
							carIte.productID = product.productID
							)
					INNER JOIN
						" . DB_PREFIX . "product_options as productOpt
							ON(
							productOpt.productOptionID= carIte.productOptionID
							
							)
					INNER JOIN
					" . DB_PREFIX . "product_option_details as productOptDet
						ON(
						productOptDet.productOptionID= productOpt.productOptionID
						AND
						languageID ='" . $currentLanguageID . "'
						)		
					LEFT JOIN 
						" . DB_PREFIX . "shipping_to_product as shiToPro
							ON 	(
								shiToPro.productID=carIte.productID 
								AND 
								shiToPro.status='A'
							)
					LEFT JOIN 
						" . DB_PREFIX . "shipping_methods shiMet
							ON	(
								shiMet.settingsGroupParent!=0 
								AND 
								shiMet.settingsGroupID=shiToPro.shippingServiceID
							)
					WHERE 
						carIte.cartID=" . (int) $cartID . " and carIte.freeBaseProductID<=0
                                                AND carIte.freeProduct!='Yes'";
        if ($settingsGroupID > 0) {
            $sql .= " AND shiMet.settingsGroupID=" . (int) $settingsGroupID . "";
        }
        $sql2 = $sql;
        if (isset($userDeliveryZoneIDs) && !empty($userDeliveryZoneIDs)) {
            $sql2 .= " AND shippingtoproductID IS NULL ";
            $sql .= "
						AND
						shippingtoproductID IN 
							(
								SELECT 
									shippingtoproductID 
								FROM 
									" . DB_PREFIX . "product_to_shipping_deliveryzone 
								WHERE 
									deliveryZoneID IN (
										'" . implode("','", $userDeliveryZoneIDs) . "'
									)
							)
						";
            
        }
        if ($group_shipping_cost == 'Yes') {

            if($shipping_cost_global=='Yes') {
                if($resSameShipmentcount1 == 'Yes')
                {$sql .= " GROUP BY shiMet.settingsGroupID ";
                }$sql2 .= " GROUP BY shiMet.settingsGroupID ";
            } else {
                $sql .= " GROUP BY carIte.businessID ";//,shiMet.settingsGroupID
                $sql2 .= " GROUP BY carIte.businessID ";
                if($resSameShipmentcount1 == 'Yes')
                {$sql .= " ,shiMet.settingsGroupID ";
                $sql2 .= " ,shiMet.settingsGroupID ";}
        }
        }
        
//        $sql .= " 
//					ORDER BY
//                                                shiToPro.baseCharge desc,
//						product.businessID,
//						carIte.addedTime desc,shiToPro.ModifiedDate desc
//						
//						";
//        $sql2 .= " 
//					ORDER BY
//                                                shiToPro.baseCharge desc,
//						product.businessID,
//						carIte.addedTime desc,shiToPro.ModifiedDate desc
//						
//						";
//$sql2 .= " GROUP BY shippingtoproductID ";
        //echo $sql; exit;
        $this->ObjDatabase->setQuery("SET @@session.group_concat_max_len= 50000;");
        
        
        
        $result = $this->ObjDatabase->readValues($sql." UNION ".$sql2);
        //$result = $this->ObjDatabase->readValues($sql);
        
        //$result2 = $this->ObjDatabase->readValues($sql2);
        
        if($shipping_cost_global=='Yes') {
            $result[0]['settingsGroupID']   =   explode(',',$result[0]['settingsGroupIDCC'])[0];
        }
        //echo "<pre>";print_r($result);exit;
        return $result;
    }
    public function listShippingMethodsAdminOrder($productIDs, $settingsGroupID = 0, $languageIDs = array(), $group_shipping_cost = 'No', $userDeliveryZoneIDs = array(),$shipping_cost_global='') {
        $currentLanguageID = isset($languageIDs['Current']) ? $languageIDs['Current'] : '1';
        $sql               = " SELECT 
		";
        if ($group_shipping_cost == 'Yes') {
            $sql .= "
						GROUP_CONCAT(productOptDet.productOptionName SEPARATOR ' <br>') as productOptionName,
						GROUP_CONCAT(DISTINCT product.productID) AS productIDs,						
						MAX(shiToPro.baseCharge) AS baseCharge,
						MAX(shiToPro.maxQtyPerShipping) AS maxQtyPerShipping,
						MAX(shiToPro.chargePerExtraQty) AS chargePerExtraQty,
						MAX(shiToPro.handlingCharge) AS handlingCharge,
						GROUP_CONCAT(DISTINCT shippingtoproductID) as shippingtoproductID,
			";
        } else {
            $sql .= "
						productOptDet.productOptionName,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.handlingCharge,
						shiToPro.shippingtoproductID,
			";
        }
        $sql .= "	
						shiMet.settingsGroupID,
						shiMet.isRealTimeCalculation,
						shiMet.settingsGroupXmlLabel,
						product.productID,
						product.businessID,						
						shiMet.settingsGroupKey,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.taxClassID,
						shiMet.settingsGroupParent,
						shiToPro.shippingtoproductID,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.handlingCharge
					FROM
						" . DB_PREFIX . "products product
					
					INNER JOIN
						" . DB_PREFIX . "product_options as productOpt
							ON(
							productOpt.productOptionID= carIte.productOptionID
							
							)
					INNER JOIN
					" . DB_PREFIX . "product_option_details as productOptDet
						ON(
						productOptDet.productOptionID= productOpt.productOptionID
						AND
						languageID ='" . $currentLanguageID . "'
						)		
					LEFT JOIN 
						" . DB_PREFIX . "shipping_to_product as shiToPro
							ON 	(
								shiToPro.productID=carIte.productID 
								AND 
								shiToPro.status='A'
							)
					LEFT JOIN 
						" . DB_PREFIX . "shipping_methods shiMet
							ON	(
								shiMet.settingsGroupParent!=0 
								AND 
								shiMet.settingsGroupID=shiToPro.shippingServiceID
							)
					WHERE 
						product.productID in (" . (int) $productIDs . ")";
        if ($settingsGroupID > 0) {
            $sql .= " AND shiMet.settingsGroupID=" . (int) $settingsGroupID . "";
        }
        if (isset($userDeliveryZoneIDs) && !empty($userDeliveryZoneIDs)) {
            $sql .= "
						AND
						shippingtoproductID IN 
							(
								SELECT 
									shippingtoproductID 
								FROM 
									" . DB_PREFIX . "product_to_shipping_deliveryzone 
								WHERE 
									deliveryZoneID IN (
										'" . implode("','", $userDeliveryZoneIDs) . "'
									)
							)
						";
        }
        if ($group_shipping_cost == 'Yes') {
            if($shipping_cost_global=='Yes') {
                $sql .= " GROUP BY shiMet.settingsGroupID ";
            } else {
                $sql .= " GROUP BY product.businessID,shiMet.settingsGroupID ";
        }
        }
        $sql .= " 
					ORDER BY
						product.businessID,
						shiToPro.ModifiedDate desc
						
						";
        
        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    }
    public function groupShippingAmount($params = array()) {
        extract($params);
         $sql = "
			SELECT
				MAX(shiToPro.baseCharge) AS baseCharge,
				MAX(shiToPro.maxQtyPerShipping) AS maxQtyPerShipping ,
				MAX(shiToPro.chargePerExtraQty) AS chargePerExtraQty,
				MAX(shiToPro.handlingCharge) AS handlingCharge,
				SUM(orderItemQuantity) AS orderItemQuantity
			FROM 
				dp_cart_items carIte 
				INNER JOIN
				" . DB_PREFIX . "products product
					ON	(
					carIte.productID = product.productID
					)
				INNER JOIN
				" . DB_PREFIX . "product_options as productOpt
					ON(
					productOpt.productOptionID= carIte.productOptionID
					
					)	
				INNER JOIN
				" . DB_PREFIX . "shipping_to_product as shiToPro
					ON 	(
						shiToPro.productID=carIte.productID 
						AND 
						shiToPro.status='A'
					)
				LEFT JOIN 
				" . DB_PREFIX . "shipping_methods shiMet
					ON	(
						shiMet.settingsGroupParent!=0 
						AND 
						shiMet.settingsGroupID=shiToPro.shippingServiceID
					)	
			WHERE 1 ";
                        if($businessID > 0)
			$sql .= "	AND carIte.businessID = '" . $businessID . "' ";
                        
			$sql .= "	AND
				cartID = '" . $cartID . "'
				AND
				shiMet.settingsGroupID = '" . $methodID . "'
		";
        if (isset($userDeliveryZoneIDs) && !empty($userDeliveryZoneIDs)) {
            $sql .= "
					AND
					shippingtoproductID IN 
					(
					SELECT shippingtoproductID FROM " . DB_PREFIX . "product_to_shipping_deliveryzone WHERE deliveryZoneID IN ('" . implode("','", $userDeliveryZoneIDs) . "')
					)
			";
        }
       
        return $this->ObjDatabase->readValue($sql);
    }
    public function listShippingMethodsDeliveryZones($shippingtoproductID, $productID, $group_shipping_cost = 'No') {
        if ($group_shipping_cost == 'Yes') {
            $shippingtoproductIDs = explode(",", trim($shippingtoproductID, ","));
        } else {
            $shippingtoproductIDs = array(
                $shippingtoproductID
            );
        }
        $sql    = " SELECT 
						proToShiDelZon.deliveryZoneID
					FROM
						" . DB_PREFIX . "shipping_to_product shiToPro
					INNER JOIN 
						" . DB_PREFIX . "product_to_shipping_deliveryzone proToShiDelZon
						ON(proToShiDelZon.shippingtoproductID=shiToPro.shippingtoproductID)
					WHERE 
						shiToPro.productID=" . (int) $productID . " AND proToShiDelZon.shippingtoproductID IN ('" . implode("','", $shippingtoproductIDs) . "')
					GROUP BY
						proToShiDelZon.deliveryZoneID";
        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    }
    //FUNCTION TO GET DELIVERYZONE DETAILS
    function getDeliveryZoneDetails($languageIDs, $deliveryZoneID) {
        $returnArray           = array();
        $currentLanguageID     = isset($languageIDs['Current']) ? $languageIDs['Current'] : '';
        $sql                   = " SELECT 
						delZonReg.countryID,
						delZonReg.StateID,
						delZonReg.zipCodes,
						IF(delZonReg.zipCodes='',0,1) as zipPri,
						COALESCE(delZonReg.StateID,0) as statePri,
						COALESCE(delZonReg.countryID,0) as countryPri,
						cou.countryAvailable,
						sta.stateStatus,
						delZonReg.isRange,
						delZonReg.rangeFrom,
						delZonReg.rangeTo
					FROM 
						" . DB_PREFIX . "deliveryzones delZon 
                                        LEFT JOIN 
                                                `" . DB_PREFIX . "deliveryzone_details` delZonDet
                                ON
                                                delZon.deliveryZoneID=delZonDet.deliveryZoneID
                                                AND delZonDet.languageID=" . (int) $currentLanguageID . "
					INNER JOIN 
						" . DB_PREFIX . "deliveryzone_to_regions delZonReg 
						ON delZonReg.deliveryZoneID=delZon.deliveryZoneID
					LEFT JOIN
						" . DB_PREFIX . "countries cou 
						ON cou.countryID=delZonReg.countryID
					LEFT JOIN
						" . DB_PREFIX . "states sta 
						ON sta.StateID=delZonReg.StateID	
					WHERE
						delZon.deliveryZoneID=" . (int) $deliveryZoneID . " AND delZon.deliveryZoneStatus='Active'
					GROUP BY 
						delZonReg.deliveryZoneRegionID
					ORDER BY 
						zipPri desc,statePri desc,countryPri desc";
        $resSelectDeliveryzone = $this->ObjDatabase->readValues($sql);
        if (count($resSelectDeliveryzone) > 0) {
            foreach ($resSelectDeliveryzone as $key1 => $zoneReg) {
                if ($zoneReg['countryID'] > 0 && $zoneReg['countryAvailable'] == 'No') {
                    continue;
                } else if ($zoneReg['StateID'] > 0 && $zoneReg['stateStatus'] != 'Active') {
                    continue;
                } else {
                    $returnArray[] = $zoneReg;
                }
            }
        }
        return $returnArray;
    }
    public function getBusinessWiseCartDetails($productID, $cartID) {
        $paramsArray    = array(
            'tableName' => 'products',
            'fieldName' => 'businessID',
            'conditionField' => 'productID',
            'condition' => '=',
            'conditionValue' => $productID,
            'conditionFieldType' => 'int'
        );
        $resBusiness    = $this->getFieldValue($paramsArray);
        $businessID     = $resBusiness['businessID'];
        $sql            = " SELECT 
						sum(carIte.orderItemSubtotal) as orderItemSubtotal,
						sum(carIte.orderItemQuantity) as orderItemQuantity
					FROM 
						" . DB_PREFIX . "cart_items AS carIte 
					INNER JOIN 
						" . DB_PREFIX . "products dea 
						ON (dea.businessID = " . (int) $businessID . ")
					WHERE carIte.productId= dea.productID AND carIte.CartID=" . (int) $cartID . " LIMIT 0,1";
        $resCartSummary = $this->ObjDatabase->readValue($sql);
        return $resCartSummary;
    }
    public function listShippingMethodsByShippingService($productID, $settingsGroupID) {
        $sql    = " SELECT 
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.taxClassID,
						shiToPro.shippingtoproductID,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.handlingCharge
					FROM
						" . DB_PREFIX . "shipping_to_product shiToPro
					WHERE 
						shiToPro.productID=" . (int) $productID . " AND shiToPro.status='A' AND 
						shiToPro.shippingServiceID=" . (int) $settingsGroupID;
        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    }
    public function updateShippingMethod($cartID, $productID, $methodID, $businessID = 0) {
        $methodDetails = $this->listShippingMethods($cartID, $methodID);
        $sql           = " SELECT 
							shiMet.settingsGroupXmlLabel,
							shiMet.settingsGroupID,
							shiMet.settingsGroupKey,
							shiMet.settingsGroupParent
						FROM 
							" . DB_PREFIX . "shipping_methods AS shiMet 
						WHERE 
							settingsGroupID= " . (int) $methodID . " LIMIT 0,1";
        //echo $sql;
        $methodDetails = $this->ObjDatabase->readValue($sql);
        $sql           = " SELECT 
							cartIte.itemDetails,
							cartIte.cartItemID		
						FROM 
								" . DB_PREFIX . "cart_items AS cartIte";
        if ($businessID > 0) {
            $sql .= "
							INNER JOIN
								" . DB_PREFIX . "products AS product
									ON	(
										product.productID = cartIte.productID
									)
			";
        }
        $sql .= "					
						WHERE 
							cartID= " . (int) $cartID . " ";
        if ($businessID > 0) {
            $sql .= "					
							AND cartIte.businessID =" . (int) $businessID . "";
        } else if ($productID > 0) {
            //update shipping method of free products associated with this product                
            $sql .= "					
							AND (productID ='" . (int) $productID . "' or (freeProduct='Yes' and freeBaseProductID='" . (int) $productID . "')) ";
            
        }
        //echo $sql;
        $resCartItemSummary = $this->ObjDatabase->readValues($sql);
        if (count($resCartItemSummary) > 0) {
            foreach ($resCartItemSummary as $key => $item) {
                $itemDetails                                          = unserialize($item['itemDetails']);
                $itemDetails['shippingMethod']['methodName']          = $methodDetails['settingsGroupXmlLabel'];
                $itemDetails['shippingMethod']['methodID']            = $methodDetails['settingsGroupID'];
                $itemDetails['shippingMethod']['settingsGroupKey']    = $methodDetails['settingsGroupKey'];
                $itemDetails['shippingMethod']['settingsGroupParent'] = $methodDetails['settingsGroupParent'];
                $itemDetails['shippingMethod']['business_wise']       = ($businessID > 0) ? 'Yes' : 'No';
                //print_r($itemDetails['shippingMethod']);
                $serlCartItemDetails                                  = $this->escape(serialize($itemDetails), false, false);
                $sql                                                  = " UPDATE 
								" . DB_PREFIX . "cart_items 
							SET 
								itemDetails='" . $serlCartItemDetails . "' 
							WHERE 
								cartID=" . (int) $cartID . " 
								AND cartItemID=" . (int) $item['cartItemID'] . " LIMIT 1";
                $resUpdateItem                                        = $this->ObjDatabase->setQuery($sql);
                                
            }
           
        }
       
    }
    public function getTaxRateByTaxClassID($taxParams) {
        extract($taxParams);
        /*
        $taxParams['stateID']		= $stateID;
        $taxParams['countryID']		= $countryID;
        $taxParams['taxClassID']	= $taxClassID;
        */
        $sql           = " SELECT 
						taxRat.taxRateID,
						taxRat.taxClassID,
						taxRat.geoZoneID,
						taxRat.taxDescription,
						SUM(taxRat.taxRate) as taxRate
					FROM 
						" . DB_PREFIX . "tax_rates AS taxRat
					INNER JOIN 
						" . DB_PREFIX . "geozones AS geo 
						ON (taxRat.geoZoneID = geo.geoZoneID)
					INNER JOIN 
						" . DB_PREFIX . "geozone_to_regions AS geoToReg 
						ON (taxRat.geoZoneID = geoToReg.geoZoneID)
					INNER JOIN 
						" . DB_PREFIX . "tax_classes AS taxCla 
						ON (taxCla.taxClassID=taxRat.taxClassID AND taxCla.taxClassID=" . (int) $taxClassID . ")
					WHERE  
						((geoToReg.countryID = '0' 
						AND geoToReg.stateID = '0') 
						OR ((geoToReg.countryID = " . (int) $countryID . ") 
						AND (geoToReg.stateID = '0' 
						OR geoToReg.stateID = '" . $this->escape($stateID) . "')))  
						AND geo.geoZoneStatus='Active' 
						AND taxCla.taxClassStatus='Active'
					GROUP BY 
						taxRat.taxClassID 
					ORDER BY 
						taxRat.taxClassID, taxRat.taxPriority LIMIT 0,1";
        $resGetTaxRate = $this->ObjDatabase->readValue($sql);
        return $resGetTaxRate;
    }
    //Function to reset the master order number
    public function resetOrderNumber($orderMasterID, $newOrderNumber = 0) {
        if ($orderMasterID > 0) {
            if ($newOrderNumber > 0) {
                $orderNumber = $newOrderNumber;
            } else {
                $sql            = " SELECT 
								MAX(masterOrderID)+1 
							FROM 
								" . DB_PREFIX . "order_masters LIMIT 0,1";
                $resOrderNumber = $this->ObjDatabase->readValue($sql);
                $orderNumber    = ($resOrderNumber[0] > 0) ? $resOrderNumber[0] : 1;
            }
            $sql                 = " UPDATE 
							" . DB_PREFIX . "order_masters 
						SET 
							orderNumber = '" . $orderNumber . "' 
						WHERE 
							masterOrderID=" . (int) $orderMasterID;
            $resUpdateOrderNumbe = $this->ObjDatabase->setQuery($sql);
            return $orderNumber;
        }
    }
    public function saveUserBillingAddress($userID, $orderDetails) {
        $sql            = " SELECT  
						userAdress1,userCity 
					FROM 
						" . DB_PREFIX . "users 
					WHERE 
						userID =" . (int) $userID . " LIMIT 0,1";
        $resUserDetails = $this->ObjDatabase->readValue($sql);
        if ($resUserDetails['userAdress1'] == '' || $resUserDetails['userCity'] == '') {
            $billingAddress       = unserialize($orderDetails['billingAddress']);
            $sql                  = " UPDATE 
							" . DB_PREFIX . "users 
						SET
							userAdress1='" . $this->escape($billingAddress['billingAddress']) . "',
							userAdress2='" . $this->escape($billingAddress['billingAddress1']) . "',
							userCity='" . $this->escape($billingAddress['billingCity']) . "',
							stateID='" . $this->escape($billingAddress['billingState']) . "',
							userProvince='" . $this->escape($billingAddress['billingProvince']) . "',
							countryID='" . $this->escape($billingAddress['billingCountry']) . "',
							userZip='" . $this->escape($billingAddress['billingZip']) . "',
							userPhone='" . $this->escape($billingAddress['billingPhone']) . "'
						WHERE 
							userID=" . (int) $userID;
            $resupdateUserAccount = $this->ObjDatabase->setQuery($sql);
        }
    }
    public function recreateOrder($order) {
        $orderBasedSerializedData = $this->escape(serialize($order['extraData']));
        $dynamicOrderStatus = ($order['dynamicOrderStatus']!='')?$order['dynamicOrderStatus']:'order-received';
        $dynamicOrderStatus = strtolower($dynamicOrderStatus);
        $sql                      = " INSERT INTO " . DB_PREFIX . "order_masters
					(
						orderNumber,
						orderTotalAmount,
						orderSubtotal,
						promoID,
						orderPromoCode,
						orderPromoDiscountAmount,
						orderUserCreditAmount,
						paymentSettingsGroupID,
						orderPaymentMethodName,
						paymentType,
						billingAddress,
						shippingAddress,
						netpayOrderID,
						netpayPaymentType,
						orderHold,
						purchasedCurrency,
						languageID,
						transactionID,
						orderCreatedDate,
						orderStatusDate,
						orderQty,
						orderStatus,
                                                dynamicOrderStatus,
						userID,
						paymentStatus,
						orderType,
						convertedMasterOrderSubtotal,
						convertedOrderPromoDiscountAmount,
						convertedOrderUserCreditAmount,
						convertedMasterOrderTotal,
						orderTaxAmount,
						orderCommissionAmount,
						orderPaymentGatewayCharge,
						orderOtherServiceCharge,
                                                orderConvenientFee,
						orderRemoved,
						shippingAmount,
						businessID,
						businessPayment,
						convertedBusinessPayment,
						extraData,
						PaymentNotes,
						billingFirstName,
						billingLastName,
						customer_email,
						guest_order,
						redeemPoint,
                        redeemDiscountAmount,
                                                userCurrencyID,
                                                userCurrencyExcRate
					)
					VALUES
					(
						'" . $order['orderNumber'] . "',
						'" . $order['orderTotalAmount'] . "',
						'" . $order['orderSubtotal'] . "',
						'" . $order['promoID'] . "',
						'" . $order['orderPromoCode'] . "',
						'" . $order['orderPromoDiscountAmount'] . "',
						'" . $order['orderUserCreditAmount'] . "',
						'" . $order['paymentSettingsGroupID'] . "',
						'" . $order['orderPaymentMethodName'] . "',
						'" . $order['paymentType'] . "',
						'" . $this->escape($order['billingAddress'], false, false) . "',
						'" . $this->escape($order['shippingAddress'], false, false) . "',
						'" . $order['netpayOrderID'] . "',
						'" . $order['netpayPaymentType'] . "',
						'" . $order['orderHold'] . "',
						'" . $order['purchasedCurrency'] . "',
						'" . $order['languageID'] . "',
						'" . $order['transactionID'] . "',
						NOW(),
						NOW(),
						'" . $order['orderQty'] . "',
						'" . $order['orderStatus'] . "',
                                                '" . $dynamicOrderStatus . "',    
						'" . $order['userID'] . "',
						'" . $order['paymentStatus'] . "',
						'product',
						'" . $order['convertedMasterOrderSubtotal'] . "',
						'" . $order['convertedOrderPromoDiscountAmount'] . "',
						'" . $order['convertedOrderUserCreditAmount'] . "',
						'" . $order['convertedMasterOrderTotal'] . "',
						'" . $order['orderTaxAmount'] . "',
						'" . $order['orderCommissionAmount'] . "',
						'" . $order['orderPaymentGatewayCharge'] . "',
						'" . $order['orderOtherServiceCharge'] . "',
                                                '" . $order['orderConvenientFee'] . "',    
						'No',
						'" . $order['shippingAmount'] . "',
						'" . $order['businessID'] . "',
						'" . $order['businessPayment'] . "',
						'" . $order['convertedBusinessPayment'] . "',
						'" . $orderBasedSerializedData . "',
						'" . $order['paymentNotes'] . "',
						'" . $order['billingFirstName'] . "',
						'" . $order['billingLastName'] . "',
						'" . $order['customer_email'] . "',
						'" . $order['guest_order'] . "',
						'" . $order['redeemPoint'] . "',
                        '" . $order['redeemDiscountAmount'] . "',
                                                '". $this->escape($order['userCurrencyID'])."', 
                                                '". $this->escape($order['userCurrencyExcRate'])."' 
					)";
        //echo $sql;
        //echo '<pre>';print_r($order);exit;
        $resInsertItem            = $this->ObjDatabase->setQuery($sql);
        $OrderMsterID             = $this->ObjDatabase->getInsertId();
        if (count($order['orderItems']) > 0) {
            foreach ($order['orderItems'] as $key => $subItems) {
                $unser                      = unserialize($subItems['itemDetails']);
                $shippingMethod             = isset($unser['shippingMethod']['methodName']) ? $unser['shippingMethod']['methodName'] : '';
                $unser['productOptionName'] = $this->decodeSplChar($unser['productOptionName']);
                $serializedData             = $this->escape($subItems['itemDetails'], false, false);
                $sql                        = " INSERT INTO " . DB_PREFIX . "order_items
							(
								masterOrderID,
								productID,
								productOptionID,
								orderItemPrice,
								orderItemQuantity,
								orderItemSubtotal,
								orderGiveAsGift,
								productOptionName,
								addedTime,
								extra,
								shipmentStatus,
								shipmentDate,
								carrierDetails,
								combinationHash,
								shippingMethod,
								shippingSetting,
								taxSetting,
								originalSubtotal
							) 
							VALUES 
							(
								'" . $OrderMsterID . "',
								'" . $subItems['productID'] . "',
								'" . $subItems['productOptionID'] . "',
								'" . $subItems['orderItemPrice'] . "',
								'" . $subItems['orderItemQuantity'] . "',
								'" . $subItems['orderItemSubtotal'] . "',
								'" . $subItems['orderGiveAsGift'] . "',
								'" . $this->escape($unser['productOptionName'], false, false) . "',
								NOW(),
								'" . $serializedData . "',
								'" . $subItems['shipmentStatus'] . "',
								'" . $subItems['shipmentDate'] . "',
								'" . $subItems['carrierDetails'] . "',
								'" . $subItems['combinationHash'] . "',
								'" . $shippingMethod . "',
								'" . $subItems['shippingSetting'] . "',
								'" . $subItems['taxSetting'] . "',
								'" . $subItems['orderItemQuantity'] * $subItems['originalItemPrice'] . "'
							)";
                $resInsertItem              = $this->ObjDatabase->setQuery($sql);
                $OrderItemID                = $this->ObjDatabase->getInsertId();
                $orderItemIDArray[$key]     = $OrderItemID;
            }
        }
        return array(
            $OrderMsterID,
            $orderItemIDArray
        );
    }
    public function getDistinctCartBusiness($cartID) {
        $sql        = " SELECT 
							distinct(dea.businessID)
						FROM  
							" . DB_PREFIX . "cart cart
						INNER JOIN 
							" . DB_PREFIX . "cart_items AS cartIte 
							ON 
							(cartIte.cartID=cart.cartID)
						INNER JOIN 
							" . DB_PREFIX . "products AS dea 
							ON 
							(dea.productID=cartIte.productID)	
						WHERE 
							cart.cartID=" . (int) $cartID;
        $resProduct = $this->ObjDatabase->readValues($sql);
        return $resProduct;
    }
    
    public function getDistinctCartItemBusiness($cartID) {
        $sql        = " SELECT 
							distinct(businessID)
						FROM  
							" . DB_PREFIX . "cart_items AS cartIte
						WHERE 
							cartIte.cartID=" . (int) $cartID;
        $resProduct = $this->ObjDatabase->readValues($sql);
        return $resProduct;
    }
    //Function to reset the master order number
    public function getNextOrderNumber() {
        $sql            = " SELECT 
						MAX(masterOrderID)+1 
					FROM 
						" . DB_PREFIX . "order_masters LIMIT 0,1";
        $resOrderNumber = $this->ObjDatabase->readValue($sql);
        $orderNumber    = ($resOrderNumber[0] > 0) ? $resOrderNumber[0] : 1;
        return $orderNumber;
    }
    // Function to get cart items product details
    public function getProductQuantity($productID = 0, $productOptionID, $combinationHash = 0,$businessID=0) {
        if ($productID > 0) {
            $paramsArray            = array(
                'tableName' => 'products',
                'fieldName' => 'InventoryTrackLevel',
                'conditionField' => 'productID',
                'condition' => '=',
                'conditionValue' => $productID,
                'conditionFieldType' => 'int'
            );
            $resInventoryTrackLevel = $this->getFieldValue($paramsArray);
            if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'No') {
                return 'Unlimited';
            } else {
                if($businessID>0){
                    if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                        $sql        = "	SELECT 
                                                                            proComBus.businessCombQuantity as productOptionQuantity
                                                                    FROM 
                                                                            " . DB_PREFIX . "product_combination_business proComBus
                                                                    INNER JOIN " . DB_PREFIX . "product_combination proCom ON
                                                                                    (proCom.combinationID = proComBus.combinationID)
                                                                    WHERE 
                                                                            proCom.combinationHash = '" . $combinationHash . "'
                                                                            AND proComBus.businessID = '".$businessID."'
                                                                            ORDER BY proComBus.combinationID desc LIMIT 0,1";
                        $resProduct = $this->ObjDatabase->readValue($sql);
                        return $resProduct['productOptionQuantity'];
                    } else {
                        $sql        = "	SELECT 
                                                                            productOptBus.productOptionQuantity
                                                                    FROM 
                                                                            " . DB_PREFIX . "products_options_business AS productOptBus 
                                                                    WHERE 
                                                                            productOptBus.productOptionID=" . (int) $productOptionID . "
                                                                            AND productOptBus.businessID = '".$businessID."' LIMIT 0,1";
                        $resProduct = $this->ObjDatabase->readValue($sql);
                        return $resProduct['productOptionQuantity'];
                    }
                }else{
                    if ($resInventoryTrackLevel['InventoryTrackLevel'] == 'Options') {
                        $sql        = "	SELECT 
                                                                            proCom.combinationQty as productOptionQuantity
                                                                    FROM 
                                                                            " . DB_PREFIX . "product_combination proCom 
                                                                    WHERE 
                                                                            proCom.combinationHash = '" . $combinationHash . "' ORDER BY combinationID desc LIMIT 0,1";
                        $resProduct = $this->ObjDatabase->readValue($sql);
                        return $resProduct['productOptionQuantity'];
                    } else {
                        $sql        = "	SELECT 
                                                                            productOpt.productOptionQuantity
                                                                    FROM 
                                                                            " . DB_PREFIX . "product_options AS productOpt 
                                                                    WHERE 
                                                                            productOpt.productOptionID=" . (int) $productOptionID . " LIMIT 0,1";
                        $resProduct = $this->ObjDatabase->readValue($sql);
                        return $resProduct['productOptionQuantity'];
                    }
                }
            }
        }
    }
    public function getUserCartItems($userID = '', $persistLifetime = 0) {
        if ($userID != '') {
            $sql        = " SELECT 
							cart.cartID,
							cart.userID,
							cartIte.cartItemID,
							cartIte.productOptionID,
							cartIte.optionsHash,
							cartIte.orderItemQuantity,
							cartIte.orderItemPrice,
							cartIte.itemDetails,
							actualPrice,
							offerPrice,
							tierPrice
						FROM  
							" . DB_PREFIX . "cart cart
						INNER JOIN 
							" . DB_PREFIX . "cart_items AS cartIte 
							ON 
							(cartIte.cartID=cart.cartID)	
						WHERE 
							cart.userID=" . (int) $userID . " 
							AND addedTime between NOW() - INTERVAL " . (int) $persistLifetime . " DAY and NOW()
						GROUP BY
							cartIte.cartItemID
						ORDER BY
							cartIte.addedTime DESC";
            $resProduct = $this->ObjDatabase->readValues($sql);
            return $resProduct;
        }
    }
    //fucntion to get the unserialized cart extra data
    public function getUnserializedCartItemData($cartItemID = 0) {
        $sql           = " SELECT 
						itemDetails 
					FROM 
						" . DB_PREFIX . "cart_items
					WHERE 
						cartItemID= " . (int) $cartItemID . " LIMIT 0,1";
        $resSelectCart = $this->ObjDatabase->readValue($sql);
        $arrExtraData  = unserialize($resSelectCart['itemDetails']);
        return $arrExtraData;
    }
    public function updateCartItemCartID($cartItemID, $cartID) {
        $sql           = " UPDATE 
						" . DB_PREFIX . "cart_items 
					SET 
						cartID=" . (int) $cartID . "
					WHERE 
						cartItemID=" . (int) $cartItemID . " LIMIT 1";
        $resUpdateItem = $this->ObjDatabase->setQuery($sql);
    }
    // Function to delete item from cart with out updating the cart total amounts
    public function deleteCart($cartID = 0) {
        if ($cartID > 0) {
            $sql            = " DELETE FROM 
							" . DB_PREFIX . "cart 
						WHERE 
							cartID = " . $cartID;
            $resDeleteItems = $this->ObjDatabase->setQuery($sql);
        }
        return true;
    }
    //Get last order by a user
    public function getlastOrderByUser($userID, $type, $includeOrderHold = 'No') {
        $sql = " SELECT 
						ordMas.orderUserCreditAmount,
						ordMas.orderHold,
						ordMas.orderNumber,
						ordMas.convertedOrderUserCreditAmount
					FROM 
						" . DB_PREFIX . "order_masters ordMas
					WHERE 
						ordMas.userID='" . $userID . "' 
						AND ordMas.orderType='" . $type . "'
						AND ordMas.paymentStatus !='Received'
						AND ordMas.orderStatus !='Completed'";
        if ($includeOrderHold == 'Yes') {
            $sql .= " AND ordMas.orderHold='Yes'";
        }
        $sql .= " ORDER BY 
						ordMas.masterOrderID DESC 
					LIMIT 0,1";
        $resSelectOrders = $this->ObjDatabase->readValue($sql);
        return $resSelectOrders;
    }
    public function resetShippingMethod($cartID = 0, $productID = 0) {
        if ($cartID > 0 || $productID > 0) {
            $sql = " SELECT 
							itemDetails,
							cartItemID
						FROM 
							" . DB_PREFIX . "cart_items AS cartIte 
						WHERE 
							cartID= '" . $cartID . "'";
            if ($productID > 0) {
                $sql .= " AND productID = '" . $productID . "'";
            }
            $resCartItemSummary = $this->ObjDatabase->readValues($sql);
            if (count($resCartItemSummary) > 0) {
                foreach ($resCartItemSummary as $cartItem) {
                    $arrExtraData = unserialize($cartItem['itemDetails']);
                    unset($arrExtraData['shippingMethod']);
                    $extra         = $this->escape(serialize($arrExtraData), false, false);
                    $sql           = " UPDATE 
									" . DB_PREFIX . "cart_items 
								SET 
									itemDetails='" . $extra . "' 
								WHERE 
									cartItemID=" . (int) $cartItem['cartItemID'] . " LIMIT 1";
                    $resUpdateItem = $this->ObjDatabase->setQuery($sql);
                    //echo $sql;
                    //exit;
                }
            }
        }
    }
    public function getProductOptionTitle($productOptionID = 0, $languageID = 0) {
        $sql                  = " SELECT 
							productOptionName
						FROM 
							" . DB_PREFIX . "product_option_details AS productOptDet 
						WHERE 
							productOptionID= " . (int) $productOptionID . "
							AND languageID = " . (int) $languageID;
        $resproductOptionName = $this->ObjDatabase->readValue($sql);
        return $resproductOptionName['productOptionName'];
    }
    public function getProductTitle($productID = 0, $languageID = 0,$type='') {
        $sql                  = " SELECT 
							productTitle
						FROM 
							" . DB_PREFIX . "product_details AS productDet
						WHERE 
							productID= " . (int) $productID . "
							AND languageID = " . (int) $languageID;
        $resproductOptionName = $this->ObjDatabase->readValue($sql);
        return $resproductOptionName['productTitle'];
    }
    public function resetMasterOrderBusinessPayment($businessPayment, $adminBusinessPayment, $paymentGatewayCharge, $extraData, $masterOrderID) {
        $sql            = "	UPDATE
					" . DB_PREFIX . "order_masters
				SET  
					orderPaymentGatewayCharge='" . $paymentGatewayCharge . "',
					businessPayment='" . $businessPayment . "',
					convertedBusinessPayment='" . $adminBusinessPayment . "',
					extraData=
					'" . $this->escape(serialize($extraData), FALSE, FALSE) . "'
				WHERE
					masterOrderID=" . (int) $masterOrderID;
        $resUpdateOrder = $this->ObjDatabase->setQuery($sql);
    }
    public function resetOrderItemExtra($extraData, $orderItemID) {
        $sql            = "	UPDATE
					" . DB_PREFIX . "order_items
				SET  
					extra='" . $this->escape(serialize($extraData), FALSE, FALSE) . "' 
				WHERE
					orderItemID=" . $orderItemID;
        $resUpdateOrder = $this->ObjDatabase->setQuery($sql);
    }
    //Check Promo usage : Given in CartCOntroller :: sendBuyNowError()
    public function checkPomoUsage($masterOrderDetails) {
        $result['error'] = 0;
        return $result;
    }
    public function getVariantTiePrice($params = array()) {
        //print_r($params);
        extract($params);
        $current_quantity   = isset($current_quantity) ? $current_quantity : 0;
        $cart_item_quantity = isset($cart_item_quantity) ? $cart_item_quantity : 0;
        if ($cart_id > 0) {
            $cart_item_quantity = $this->getCartItemQuntity($params);
        }
        $sql    = " SELECT 
							MIN(tierPrice) as tierPrice
						FROM 
							" . DB_PREFIX . "variant_tier_price AS tiePri
						WHERE 
							productOptionID= " . (int) $product_option_id . "
							AND quantity <= " . ((int) $cart_item_quantity + (int) $current_quantity) . "
							AND (allGroups='1' OR userGroupID=" . (int) $user_group_id . ")";
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        //echo $sql;
        return $result['tierPrice'];
    }
    public function getCartItemQuntity($params = array()) {
        extract($params);
        $sql    = " SELECT 
							SUM(orderItemQuantity) as orderItemQuantity
						FROM 
							" . DB_PREFIX . "cart_items AS carIte
						WHERE
							cartID=" . (int) $cart_id . " AND 
							productOptionID= " . (int) $product_option_id;
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        //echo $sql;
        return $result['orderItemQuantity'];
    }
    //Function to get cart item actual and offer price
    public function getCartItemPrice($params = array()) {
        extract($params);
        $currBusinessID     =   isset($curr_business_id) ? $curr_business_id : 0;
        if($currBusinessID>0){
            $optRegPrice    =   "productOptBus.productOptionRegularPrice";
            $optProdPrice   =   "productOptBus.productOptionProductPrice";
            $optDealPrice   =   "IF(productOptBus.dealPrice>0,productOptBus.dealPrice,ROUND((productOptBus.productOptionProductPrice)-(productOptBus.productOptionProductPrice*(product.dealDiscount/100))))";
            $sqlOptBusJoin  =   "INNER JOIN ".DB_PREFIX."products_options_business productOptBus ON
                                 (productOptBus.productOptionID = productOpt.productOptionID 
                                  AND productOptBus.businessID = '".$currBusinessID."')";
            
            $sqlGrpPriceJoin=   "LEFT JOIN
					" . DB_PREFIX . "variant_group_price AS varGroPri
						ON	(
							varGroPri.productOptionID = productOpt.productOptionID
							AND
							varGroPri.userGroupID=" . (int) $user_group_id . "
                                                        AND
                                                        varGroPri.businessID = '".$currBusinessID."'
						)";
            $sqlVarPriceJoin =  " AND varOffPri.businessID = productOptBus.businessID";
        }else{
            $optRegPrice    =   "productOpt.productOptionRegularPrice";
            $optProdPrice   =   "productOpt.productOptionProductPrice";
            $optDealPrice   =   "IF(productOpt.dealPrice>0,productOpt.dealPrice,ROUND((productOpt.productOptionProductPrice)-(productOpt.productOptionProductPrice*(product.dealDiscount/100))))";
            $sqlOptBusJoin  =   "";
            $sqlVarPriceJoin =  "";
            
            $sqlGrpPriceJoin=   "LEFT JOIN
					" . DB_PREFIX . "variant_group_price AS varGroPri
						ON	(
							varGroPri.productOptionID = productOpt.productOptionID
							AND
							varGroPri.userGroupID=" . (int) $user_group_id . "
						)";
        }
        $sql    = " SELECT 
					productOpt.productOptionID,
					$optRegPrice as actualPrice,
					$optProdPrice,
                                        $optDealPrice as dealPrice,
					product.isProductDeal,
					product.dealDiscount,
					LEAST(
						COALESCE(
							varOffPri.offerPrice,
							$optProdPrice
						),
						COALESCE(
							varGroPri.specialPrice,
							$optProdPrice
						) 
					)
					AS offerPrice
				FROM 
					" . DB_PREFIX . "product_options productOpt 
				INNER JOIN
					" . DB_PREFIX . "products product 
						ON (
							productOpt.productID = product.productID
						)
                                $sqlOptBusJoin
				LEFT JOIN
					" . DB_PREFIX . "variant_offer_price AS varOffPri
						ON	(
							varOffPri.productOptionID = productOpt.productOptionID
							AND
							varOffPri.userGroupID=" . (int) $user_group_id . "
                                                        $sqlVarPriceJoin
						)	
				$sqlGrpPriceJoin
				WHERE		
					productOpt.productOptionStatus='Active' 
					AND productOpt.productOptionID=" . (int) $product_option_id;
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        return $result;
    }
    // Link Guest User orders to new account
    public function linkOrderToUser($userID, $emailID) {
        $sql = "	UPDATE
					" . DB_PREFIX . "order_masters
				SET  
					userID ='" . $userID . "'
				WHERE
					customer_email='" . $emailID . "'";
        $this->ObjDatabase->setQuery($sql);
        // Updating referral purchases	
        //Query taking time 
        /*$updareReferal = "UPDATE " . DB_PREFIX . "users_referrals usrRef 
							JOIN " . DB_PREFIX . "referral_purchases refPur 
								ON usrRef.referrerID=refPur.referrerID 
							SET referedTo = '" . $userID . "' 
							WHERE
								refPur.masterOrderID 
									IN (SELECT 
										GROUP_CONCAT(masterOrderID) orderIDs
										FROM " . DB_PREFIX . "order_masters 
										WHERE customer_email='" . $emailID . "')
							";
        $this->ObjDatabase->setQuery($updareReferal);*/
        
        $sqlGetRefOrders = "SELECT refPur.referrerID From " . DB_PREFIX . "referral_purchases refPur JOIN 
                                " . DB_PREFIX . "order_masters orderMas ON (refPur.masterOrderID=orderMas.masterOrderID)
                                 WHERE orderMas.customer_email='" . $emailID . "'  
                                ";
        $rsGetRefOrders = $this->ObjDatabase->readValues($sqlGetRefOrders);
        if(!empty($rsGetRefOrders)) {
            foreach($rsGetRefOrders as $rsDet) {
                $updareReferal = "UPDATE " . DB_PREFIX . "users_referrals SET referedTo = '" . $userID . "' 
                                                    WHERE referrerID='".$rsDet['referrerID']."'";
                $this->ObjDatabase->setQuery($updareReferal);
            }
        }            
        
    }
    public function getCustomOptionDeatils($params = array()) {
        extract($params);
        $sql    = " SELECT 
							customOptionName,
							inputType,
							priceDiff,
							priceDiffType
						FROM 
							" . DB_PREFIX . "product_custom_option AS cusOpt
						LEFT JOIN
							" . DB_PREFIX . "product_custom_option_details AS cusOptDet
						ON 
							(cusOptDet.customOptionID=cusOpt.customOptionID AND cusOptDet.languageID=" . (int) $language_id . ")	
						WHERE 
							cusOpt.customOptionID= " . (int) $custom_option_id;
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        return $result;
    }
    public function getCustomOptionVariantDeatils($params = array()) {
        extract($params);
        $sql    = " SELECT 
							priceDiff,
							priceDiffType,
							value,
							customOptionID
						FROM  
							" . DB_PREFIX . "product_custom_option_variant AS cusOptVar
						LEFT JOIN
							" . DB_PREFIX . "product_custom_option_variant_details AS cusOptVarDet
						ON 
							(cusOptVarDet.customOptionVariantID=cusOptVar.customOptionVariantID AND cusOptVarDet.languageID=" . (int) $language_id . ")	
						WHERE 
							cusOptVar.customOptionVariantID= " . (int) $custom_option_variant_id;
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        //echo $sql;
        return $result;
    }
    // Function to update user email address in cart table
    public function updateCartUserEmail($cartID = 0, $emailID) {
        $extraData                      = $this->getUnserializedCartData($cartID);
        $extraData['userCheckoutEmail'] = $emailID;
        $sql                            = " UPDATE 
						" . DB_PREFIX . "cart 
					SET 
						extra = '" . $this->escape(serialize($extraData), false, false) . "' 
					WHERE 
						cartID=" . (int) $cartID . " LIMIT 1";
        $resUpdateCartAddress           = $this->ObjDatabase->setQuery($sql);
        return $resUpdateCartAddress;
    }
    public function getCombinationDeatils($params = array()) {
        extract($params);
        $currBusinessID     =   isset($curr_business_id) ? $curr_business_id : 0;
        if($currBusinessID>0){
            $sqlJoin        =   " INNER JOIN ".DB_PREFIX."product_combination_business prodCombBus ON
                                  (prodCombBus.combinationID = prodComb.combinationID AND
                                   prodCombBus.businessID = '".$currBusinessID."')";
            $sqlFields      =   "prodCombBus.businessCombPrice as combinationPrice,
                                 prodCombBus.businessCombDiff as combinationPriceDiffType,";
        }else{
            $sqlJoin        =   "";
            $sqlFields      =   "prodComb.combinationPrice,
                                 prodComb.combinationPriceDiffType,";
        }
        $sql    = " SELECT 
							prodComb.combinationSKU,
							$sqlFields
							prodComb.combination
						FROM 
							" . DB_PREFIX . "product_combination prodComb
                                                $sqlJoin
						WHERE 
							prodComb.combinationHash= '" . $combination_hash . "'
							AND prodComb.status='A'
						ORDER BY 
							prodComb.combinationID DESC";
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        return $result;
    }
    public function resetCartItemsTierPrice($cartID = 0, $user_group_id = 0) {
        if ($cartID > 0) {
            $params['cart_id']          = $cartID;
            $params['user_group_id']    = $user_group_id;
            $params['current_quantity'] = 0;
            $cart_items                 = $this->getCartItems($cartID, 0);
            $extra_price                        =       0;
            if (count($cart_items) > 0) {
                foreach ($cart_items as $key => $item) { 
                    $extra_Comb_price                   =       0;
                    $currbusinessid = $this->getCartItemBusinessID($item['cartItemID']);
                    if ($item['freeProduct'] == 'Yes')
                        continue;
                    $params['combination_hash']		= 	$item['combinationHash'];
                    $params['product_option_id']	= 	$item['productOptionID'];
                    $params['curr_business_id']         =       $currbusinessid;
                    
                    
					
                    $dealDiscount			= 	$item['dealDiscount'];
                    $isProductDeal			= 	$item['isProductDeal'];
                    $productOptionRegularPrice		= 	$item['productOptionRegularPrice'];
                    $serializedData                     =       unserialize($item['itemDetails']);
                    $bundleProd                         =       isset($serializedData['bundleProduct']) ? $serializedData['bundleProduct'] : "";
                    $customOptionValues                 =       $serializedData['customOptionValues'];
                    $strcombinationValuesExists         =       $serializedData['combinationValues'];
                    
                    //echo "<pre>"; print_r($customOptionValues); exit;
                    if(isset($customOptionValues) && count($customOptionValues)>0){
                        foreach($customOptionValues as $cusValues){
                            if(isset($cusValues[0]['priceDiff']) && $cusValues[0]['priceDiff']>0){
                                 $extra_Comb_price      =       $extra_Comb_price+($cusValues[0]['priceDiff']+0);
                            }
                        }
                    }
                    
                    if(isset($strcombinationValuesExists) && count($strcombinationValuesExists)>0){
                        if(isset($strcombinationValuesExists['combinationPrice']) && $strcombinationValuesExists['combinationPrice']>0){
                            $extra_Comb_price           =       $strcombinationValuesExists['combinationPrice']+0;
                        }
                    }
					
                    $result							= 	$this->getCartItemPrice($params);
                    $tier_price						= 	$this->getVariantTiePrice($params);
                    if($bundleProd=="Yes"){
                        $offer_price					= 	$result['productOptionProductPrice'];
                        $purchased_price				= 	$result['productOptionProductPrice'];
                        $extra_price                                    = 	0;
                        $current_price                                  = 	$result['productOptionProductPrice'];
                    }else{
                        $offer_price					= 	$result['offerPrice']+$extra_Comb_price;
                        $itemOfferPrice                                 =       $item['offerPrice']+$extra_Comb_price;
                        if($item['tierPrice'] > 0){
                            $purchased_price				= 	($item['tierPrice'] > 0 && $item['tierPrice'] < $itemOfferPrice) ? $item['tierPrice'] : $itemOfferPrice;
                            $extra_price                                    = 	$item['orderItemPrice'] - $purchased_price;
                        }
                        $current_price                                  = 	($tier_price > 0 && $tier_price < $offer_price) ? $tier_price : $offer_price;
                    }
//                    echo $itemOfferPrice."<br/>";
//                    echo $result['offerPrice']."<br/>";
//                    echo $current_price."<br/>";
//                    echo $item['orderItemPrice']."<br/>";
//                    echo $extra_Comb_price."<br/>";  exit;
                    $actual_price					= 	$result['actualPrice'];
                    if($isProductDeal=='Yes'){
                            //$extra_price		=	0;
                            $deal_price			= 	$result['dealPrice'];
//                            $current_price		= 	($deal_price > 0 && $deal_price < $current_price) ? $deal_price : $current_price;
                            $current_price		= 	$deal_price;
                            $offer_price                =       $deal_price;
                    } 
					
                    //if($current_price>$purchased_price || $current_price<$purchased_price)
                    //{
						
                    $post_data['offerPrice']                   = $offer_price;
                    $post_data['tierPrice']                    = $tier_price;
                    $offer_price                               = $current_price;
                    $product_commission_rate                   = $serializedData['productCommissionRate'];
                    $quantity                                  = $item['orderItemQuantity'];
                    $currentAdminCommision                     = $actual_price * ($product_commission_rate / 100) * $quantity;
                    $currentServiceFee                         = $serializedData['orderOtherServiceCharge'];
                    $currentSubTotalAmount                     = (($current_price + $extra_price) * $quantity);
                    $currentTotalAmount                        = (($current_price + $extra_price) * $quantity) + $currentAdminCommision + $currentServiceFee;
                    $serializedData['orderCommissionAmount']   	= number_format($currentAdminCommision, 2, '.', '');
                    $serializedData['orderOtherServiceCharge'] 	= number_format($currentServiceFee, 2, '.', '');
                    $serializedData['orderItemQuantity']       	= $quantity;
                    $serializedData['orderItemSubtotal']       	= number_format($currentSubTotalAmount, 2, '.', '');
                    $serializedData['orderItemTotal']          	= number_format($currentTotalAmount, 2, '.', '');
                    $serializedData['unitPrice']               	= number_format($current_price + $extra_price, 2, '.', '');
                    $serializedData['productCommissionRate']   	= number_format($product_commission_rate, 2, '.', '');
                    $serializedData                            	= $this->escape(serialize($serializedData), false, false);
                    $post_data['orderItemPrice']               	= $current_price + $extra_price;
                    $post_data['orderItemQuantity']            	= $item['orderItemQuantity'];
                    $post_data['orderItemSubtotal']            	= $currentSubTotalAmount;
                    $post_data['dealDiscount']            		= $dealDiscount;
                    $post_data['isProductDeal']            		= $isProductDeal;
                    $post_data['itemDetails']                 	= $serializedData;
                    //echo "<pre>"; print_r($post_data); exit;
                    $this->updateCartItem($cartID, $item['cartItemID'], $post_data);
                    //}
                }
                //exit;
            }
        }
    }
    public function getRuleUsageCount($ruleID, $userCheckoutEmail = '',$coupon_code='',$type='') {
        if($type=='') {
            $sql = "
                                    SELECT
                                            COUNT(cartUsageID) AS usage_count
                                    FROM
                                            " . DB_PREFIX . "cart_rules_usage cartRul
                                    WHERE
                                            cartRul.ruleID='" . $ruleID . "'";
            if ($userCheckoutEmail != '') {
                $sql .= " AND cartRul.userEmail='" . $userCheckoutEmail . "'";
            }
        } else {
            $sql = "
                                    SELECT
                                            timesUsed AS usage_count
                                    FROM
                                            " . DB_PREFIX . "cart_promo_coupons cartPromo
                                    WHERE
                                            cartPromo.ruleID='" . $ruleID . "' and cartPromo.couponCode='".$coupon_code."'";
           
        }
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
       
        return $result['usage_count'];
    }
    //Calculate Offer Price Routine
    //$params :$debug 
    public function fn_promotion_apply($params = array(), &$cart,$fromPageType='') {
        //echo '<pre>';print_r($params); exit;
        extract($params);
        $debug                              = 1;
        $today                              = date("Y-m-d");
        $promo_id                           = isset($promo_id) ? $promo_id : 0;
        $discount_amount                    = isset($discount_amount) ? $discount_amount : 0;
        $applied_promotions                 = array();
        $applied_promotion_ids_array        = $promo_stop_rules = array(); // To check stop rules
        $promoApp                           = !empty($promoApp) ? $promoApp:'';
        if($promoApp!='') {
            $promoApp = ",'".$this->escape($promoApp)."'";
        }
        $sql                                = "
				SELECT
					*
				FROM
					" . DB_PREFIX . "cart_rules cartRul
				LEFT JOIN
					" . DB_PREFIX . "cart_rule_user_group cartRulUseGro
				ON (cartRulUseGro.ruleID=cartRul.ruleID)
				LEFT JOIN 
					" . DB_PREFIX . "cart_rule_details cartRulDet
				ON (cartRulDet.ruleID=cartRul.ruleID AND cartRulDet.languageID=" . (int) $current_language_id . ")
				WHERE
					IF(DATE_FORMAT(cartRul.fromDate, '%Y-%m-%d'),DATE_FORMAT(cartRul.fromDate, '%Y-%m-%d')<='" . $today . "',1)
					AND IF(DATE_FORMAT(cartRul.toDate, '%Y-%m-%d'),DATE_FORMAT(cartRul.toDate, '%Y-%m-%d')>='" . $today . "',1)
					AND cartRul.status='A'
					AND cartRul.couponType=1 
					AND 
						(
							ruleType='Bundle' 
							OR 
							cartRulUseGro.userGroupID=" . (int) $user_group_id . "
			 			) ";
        if($fromPageType!='' && $fromPageType=='orderedit') {
            $sql .=			" AND ruleType='Normal' ";
        }        
	
        $sql .= " AND cartRul.promoWebAppEnabled in ('Both'".$promoApp.")";
        $sql .= "               GROUP BY cartRul.ruleID ORDER BY cartRul.priority"; 
        
        
        $promotions_result                  = $this->ObjDatabase->readValues($sql, MYSQLI_ASSOC);               
        $cart['extra']['userCheckoutEmail'] = isset($cart['extra']['userCheckoutEmail']) ? $cart['extra']['userCheckoutEmail'] : '';
        $user_email                         = ($user_id > 0) ? $user_email : $cart['extra']['userCheckoutEmail'];
        if (count($promotions_result) > 0) {
            foreach ($promotions_result as $k => $v) {
                if ($v['maxUsageCount'] > 0) {
                    $usage_count = $this->getRuleUsageCount($v['ruleID']);                    
                    if ($usage_count >= $v['maxUsageCount']) {
                        continue;
                    }
                }
                if ($v['maxUsagePerPerson'] > 0 && $user_email != '') {
                    $usage_count = $this->getRuleUsageCount($v['ruleID'], $user_email);
                    if ($usage_count >= $v['maxUsagePerPerson']) {
                        continue;
                    }
                }
                $promotions[$k]                    = $v;
                $promotions[$k]['conditions']      = !empty($v['conditions']) ? unserialize($v['conditions']) : array();
                $promotions[$k]['bonusConditions'] = !empty($v['bonusConditions']) ? unserialize($v['bonusConditions']) : array();
            }
        }
        if (count($cart['items']) > 0) {
            foreach ($cart['items'] as $k => $v) {
                $cart['items'][$k]['categories']     = explode(',', $this->getProductCategories($v['productID']));
                $cart['items'][$k]['attributes']     = $this->getProductAttributeValues($v['productID']);
                $cart['items'][$k]['attributeTexts'] = $this->getProductAttributeValuesText($v['productID'], $language_id);
            }
        }
       
        if (isset($promotions) && count($promotions) > 0) {
            foreach ($promotions as $promotion) {
                // Rule is valid and can be applied
                if ($this->fn_promotion_check($promotion['ruleID'], $promotion['conditions'], $cart, $params)) {
                    // Stop Rules checking
                    if (in_array("Y", $promo_stop_rules)) {
                        continue;
                    }
                    $applied_promotions[$promotion['ruleID']] = $promotion;
                    $applied_promotion_ids_array[]            = $promotion['ruleID'];
                    $promo_stop_rules[]                       = $promotion['stopRules'];
                    $sucess_promo[$promotion['ruleID']]       = 'Rule ' . $promotion['ruleID'] . ' is valid and can be applied';
                } else {
                    $fail_promo[$promotion['ruleID']] = 'Rule ' . $promotion['ruleID'] . ' is not valid and can\'nt be applied';
                }
            }
        }
        if ($coupon_code != '') {
            $applied_promotions_coupon = $this->fn_promotion_apply_coupon($params, $cart);
            $error_code                = (is_array($applied_promotions_coupon)) ? 0 : $applied_promotions_coupon;
        }
		
        $params['coupon_code'] = (isset($error_code) && $error_code > 0) ? '' : $coupon_code;
        if (isset($applied_promotions_coupon) && is_array($applied_promotions_coupon))
            $applied_promotions = array_merge($applied_promotions, $applied_promotions_coupon);
        if (count($applied_promotions) > 0) {
            if($fromPageType!='' && $fromPageType=='orderedit') {
                $cart = $this->fn_promotion_apply_bonus($params, $applied_promotions, $cart);    
            } else {
            $free_products = $this->fn_promotion_apply_bonus($params, $applied_promotions, $cart);
            }
        } else {
		$itemCount	=count($cart['items']);
                foreach ($cart['items'] as $keyc=>$cartItems) {
                    $unserializedData                             = ($fromPageType=='')?unserialize($cartItems['itemDetails']):unserialize($cartItems['extra']);
                $unserializedData['orderPromoDiscountAmount'] = isset($applicable_items_discount[$cartItems['cartItemID']]) ? $applicable_items_discount[$cartItems['cartItemID']] : '';
				if(isset($promotions_result['ruleType']) && $promotions_result['ruleType']=='Bundle'){
					$unserializedData['orderPromoDiscountAmount'] =$unserializedData['orderPromoDiscountAmount']/$itemCount;
				}
                    $unserializedData['free_shipping']            = "false";                
                $unserializedData['promotions']               = array();
                $serializedData                               = serialize($unserializedData);
                        if($fromPageType=='') {
                    $sql                                          = " UPDATE 
								" . DB_PREFIX . "cart_items 
							SET 
								itemDetails = '" . $this->escape($serializedData, false, false) . "'
							 WHERE 
								cartItemID=" . (int) $cartItems['cartItemID'] . " LIMIT 1";
                    $result                                       = $this->ObjDatabase->setQuery($sql);
                        } else {
                            $cart['items'][$keyc]['extra']      =   serialize($unserializedData);
            }

                }

            $cart_extra_data                       = $cart['extra'];
            $cart_extra_data['applied_promotions'] = isset($applied_promotions_details) ? $applied_promotions_details : array();
                $free_shipping                         = 'No';
                if($fromPageType=='') {
            $sql                                   = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							orderPromoCode='" . $params['coupon_code'] . "',
							promoID=" . (int) $promo_id . ",
							orderPromoDiscountAmount='" . $discount_amount . "',
                                                                extra = '" . $this->escape(serialize($cart_extra_data), false, false) . "',
                                                                freeShipping='" . $free_shipping . "'
						WHERE 
							cartID=" . (int) $cart_id . " LIMIT 1";
            $result                                = $this->ObjDatabase->setQuery($sql);
                } else {
                    $cart['orderPromoDiscountAmount']   = $discount_amount;
                    $cart['orderPromoCode']             = $params['coupon_code'];
        }
            
        }
        if($fromPageType!='' && $fromPageType=='orderedit') {
            return $cart;
        } else {
        $error_code    = isset($error_code) ? $error_code : 0;
        $free_products = isset($free_products) ? $free_products : array();
        return array(
            $error_code,
            $free_products
        );
    }

    }
    public function deleteFreeProducts($cartID = 0) {
        $sql    = " DELETE FROM 
						" . DB_PREFIX . "cart_items
					WHERE 
						cartID=" . (int) $cartID . " AND freeProduct='Yes' and freeBaseProductID<=0";
        $result = $this->ObjDatabase->setQuery($sql);
        //echo $sql;
    }
    public function fn_promotion_apply_coupon($params = array(), &$cart) {
        //echo '<pre>';//print_r($params);
        $applied_promotions = array();
        extract($params);
        $promoApp                           = !empty($promoApp) ? $promoApp:'';
        if($promoApp!='') {
            $promoApp = ",'".$this->escape($promoApp)."'";
        }
        $today      = date("Y-m-d");
        $sql        = "
				SELECT
					*
				FROM
					" . DB_PREFIX . "cart_rules cartRul
				LEFT JOIN
					" . DB_PREFIX . "cart_rule_user_group cartRulUseGro
				ON (cartRulUseGro.ruleID=cartRul.ruleID)
				LEFT JOIN 
					" . DB_PREFIX . "cart_promo_coupons cartRulCup
				ON (cartRulCup.ruleID=cartRul.ruleID)
				LEFT JOIN 
					" . DB_PREFIX . "cart_rule_details cartRulDet
				ON (cartRulDet.ruleID=cartRul.ruleID AND cartRulDet.languageID=" . (int) $current_language_id . ")
				WHERE
					IF(DATE_FORMAT(cartRul.fromDate, '%Y-%m-%d'),DATE_FORMAT(cartRul.fromDate, '%Y-%m-%d')<='" . $today . "',1)
					AND IF(DATE_FORMAT(cartRul.toDate, '%Y-%m-%d'),DATE_FORMAT(cartRul.toDate, '%Y-%m-%d')>='" . $today . "',1)
					AND cartRul.status='A'
					AND cartRul.couponType!=1
					AND cartRulCup.couponCode = '" . $coupon_code . "'
					AND cartRulUseGro.userGroupID=" . (int) $user_group_id . " ";
        $sql .= " AND cartRul.promoWebAppEnabled in ('Both'".$promoApp.")";
        $sql .= "               GROUP BY cartRul.ruleID ORDER BY cartRul.priority"; 
				
        //echo $sql;exit;
        $promotion  = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        $user_email = ($user_id > 0) ? $user_email : $cart['extra']['userCheckoutEmail'];
        
        if (isset($promotion['maxUsageCount']) && $promotion['maxUsageCount'] > 0) {    
            if($coupon_code=='') {
                $usage_count = $this->getRuleUsageCount($promotion['ruleID']);            
                if ($usage_count >= $promotion['maxUsageCount']) {
                    return 1;
                } 
            }
            else {
                $usage_count = $this->getRuleUsageCount($promotion['ruleID'],'',$coupon_code,'C');
                if ($usage_count >= $promotion['maxUsageCount']) {
                    return 1;
                }
            }
        }
        if (isset($promotion['maxUsagePerPerson']) && $promotion['maxUsagePerPerson'] > 0 && $user_email != '') {
            $usage_count = $this->getRuleUsageCount($promotion['ruleID'], $user_email);            
            if ($usage_count >= $promotion['maxUsagePerPerson']) {
                return 1;
            }
        }
        if (empty($promotion)) {
            return 1;
        }
        if (isset($cart['applied_promotions']) && count($cart['applied_promotions']) > 0) {
            foreach ($cart['applied_promotions'] as $k => $v) {
                if ($v['priority'] < $promotion['priority'] && $v['stopRules'] == 'Y') {
                    $stop_rule = true;
                    break;
                }
            }
            if ($stop_rule) {
                return 2;
            }
        }
        $promotion['conditions']      = !empty($promotion['conditions']) ? unserialize($promotion['conditions']) : array();
        $promotion['bonusConditions'] = !empty($promotion['bonusConditions']) ? unserialize($promotion['bonusConditions']) : array();
        if (count($cart['items']) > 0) {
            foreach ($cart['items'] as $k => $v) {
                $cart['items'][$k]['categories']     = explode(',', $this->getProductCategories($v['productID']));
                $cart['items'][$k]['attributes']     = $this->getProductAttributeValues($v['productID']);
                $cart['items'][$k]['attributeTexts'] = $this->getProductAttributeValuesText($v['productID'], $language_id);
            }
        }
        // Rule is valid and can be applied
        if ($this->fn_promotion_check($promotion['ruleID'], $promotion['conditions'], $cart, $params)) {
            $applied_promotions[$promotion['ruleID']] = $promotion;
            //$sucess_promo[$promotion['ruleID']]	= 'Rule '.$promotion['ruleID'].' is valid and can be applied';
            return $applied_promotions;
        } else {
            return 1;
            //$fail_promo[$promotion['ruleID']]	= 'Rule '.$promotion['ruleID'].' is not valid and can\'nt be applied';
        }
    }
    public function fn_promotion_apply_bonus($params = array(), $applied_promotions, $cart) {
        extract($params);
        $bundleProducts = array();
		
        foreach ($cart['items'] as  $item) {
          $cartProduct[]   = $item['productID'];
          $itemDetailsTemp = unserialize($item['itemDetails']);  
          if($itemDetailsTemp['bundleID']>0) {
              $bundleProducts[$itemDetailsTemp['bundleID']][] = $item['productID'];              
		}	
	
        }	
	//echo "<pre>";print_r($bundleProducts);exit;
        $promo_id        = '';
        $subtotal_amount = isset($subtotal_amount) ? $subtotal_amount : '';
        $discount_amount = isset($discount_amount) ? $discount_amount : '';

        if (count($applied_promotions) > 0) {
            $applicable_items_discount                 = array();
            $promotion_based_applicable_items_discount = array();
            $applied_promotions_details                = array();
            $free_shipping_for_all                     = false;
            //echo "<pre>"; print_r($applied_promotions); exit;
            
            foreach ($applied_promotions as $k => $v) {
                $promotion_can_apply   = false;
                $items_subtotal_amount = 0;
                $items_qty             = 0;
                $applicable_items      = array();
                $bundle_items          = array();
                $v['couponCode']       = isset($v['couponCode']) ? $v['couponCode'] : '';
				$itemCount			   = count($cart['items']);
						if($v['ruleType']=='Bundle'){
                                                        
                                                        $sqlCheck	= "SELECT prodOptBus.productOptionProductPrice AS productRegularPrice
                                                                            FROM 
                                                                                     " . DB_PREFIX . "product_options prodOpt inner join " . DB_PREFIX . "products product ON (product.productID=prodOpt.productID) 
                                                                            INNER JOIN
                                                                                    ".DB_PREFIX."products_options_business AS prodOptBus
                                                                                        ON	(
                                                                                                prodOptBus.productOptionID = prodOpt.productOptionID
                                                                                                AND
                                                                                                prodOptBus.businessOptionDefault='Yes'
                                                                                )
                                                                            inner join " . DB_PREFIX . "business bus ON (bus.businessID=prodOptBus.businessID) WHERE 
                                                                                     prodOpt.productID in (".$v['conditions']['conditions'][1]['value'].") AND prodOpt.productOptionDefault='Yes' AND prodOpt.productOptionStatus='Active' AND product.productStatus='Active' AND bus.businessStatus='Active' ";
							
                                                        $resCheck       = $this->ObjDatabase->readValuesSlave($sqlCheck);                                                        
                                                        //echo $v['conditions']['conditions'][1]['value']."<br>";
							$productArray	=	explode(',',$v['conditions']['conditions'][1]['value']);
                                                       
                                                        if(empty($resCheck) || (count($resCheck)!=count($productArray))) {                                                            
                                                            continue;
                                                        }
                                                        
                                                        if(!empty($bundleProducts[$v['ruleID']])) {
                                                            $result = array_diff($productArray, $bundleProducts[$v['ruleID']]);	
                                                        } else {
                                                            continue;
                                                        }
							if(!empty($result))
								continue;
							
						}				
                if ($itemCount > 0) {
                    foreach ($cart['items'] as $j => $q) {
                        if ($q['freeProduct'] == 'Yes')
                            continue;
                        $cart_products['items'][0] = $q;
                        // Rule is valid and can be applied
                        if ($this->fn_promotion_check($v['ruleID'], $v['bonusConditions'], $cart_products, $params, 'bonuses')) {
                            $items_subtotal_amount += $q['orderItemSubtotal'];
                            $items_qty += $q['orderItemQuantity'];
                            $promotion_can_apply                                              = true;
                            $applicable_items[$q['cartItemID']]['p']                          = $q['orderItemSubtotal'];
                            $applicable_items[$q['cartItemID']]['q']                          = $q['orderItemQuantity'];
                            $item_details                                                     = unserialize($q['itemDetails']);
                            $applicable_items[$q['cartItemID']]['n']                          = $item_details['productOptionName'];
                            $applicable_items[$q['cartItemID']]['option_id']                  = $q['productOptionID'];
                            $applicable_items[$q['cartItemID']]['product_id']                 = $q['productID'];
                            $applicable_items[$q['cartItemID']]['actual_price']               = $q['actualPrice'];
                            $itemDetailsTemp                                                  = unserialize($q['itemDetails']);                           
                            $applicable_items[$q['cartItemID']]['bundleID']                   = $itemDetailsTemp['bundleID']; 
                            
                            if($itemDetailsTemp['bundleID']>0 && $v['ruleType']=='Bundle' && $itemDetailsTemp['bundleID']==$v['ruleID']) {
                                $bundle_items[]['n']                          = $item_details['productOptionName'];
                            }
                            $promotion_based_applicable_items_discount[$q['cartItemID']]['p'] = $q['orderItemSubtotal'];
                            $promotion_based_applicable_items_discount[$q['cartItemID']]['q'] = $q['orderItemQuantity'];
                            $promotion_based_applicable_items_discount[$q['cartItemID']]['n'] = $item_details['productOptionName'];
                        }
                        $subtotal_amount += $q['orderItemSubtotal'];
                    }
                }
               
                if ($promotion_can_apply) {
                   
                    if ($v['freeShipping'] == 'yes' && !$free_shipping_for_all) {
                        $free_shipping_for_all      = true;
                        $free_shipping_promotion_id = $v['ruleID'];
                    }
                    if ($v['apply'] == 'by_percentage') {
                        $current_discount_amount = (($items_subtotal_amount * $v['discountAmount']) / 100);
                        $discount_amount += $current_discount_amount;
                        if (count($applicable_items) > 0) {
                            foreach ($applicable_items as $i => $r) {
                                $item_discount                                                                  = ($items_subtotal_amount > 0) ? $r['p'] / $items_subtotal_amount * $current_discount_amount : 0;
                                $applicable_items_discount[$i]                                                  = (isset($applicable_items_discount[$i]) ? $applicable_items_discount[$i] : 0) + $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] = isset($promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d']) ? $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] : 0;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] += $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['ruleID'] = $v['ruleID'];
                            }
                        }
                    } else if ($v['apply'] == 'by_fixed') {
                        $current_discount_amount     = $v['discountAmount'] * $items_qty;
						if($v['ruleType']=='Bundle'){
                                $productArray               =	explode(',',$v['conditions']['conditions'][1]['value']);                                                       
                                $productCount               =	count($productArray);
                                $current_discount_amount    =   $current_discount_amount/$productCount ;
						}						
                        $tmp_current_discount_amount = 0;
						//echo "<pre>";print_r($applicable_items);exit;
                        if (count($applicable_items) > 0) {
                            foreach ($applicable_items as $i => $r) {
                                
						if($v['ruleType']=='Bundle'){
							$result = array_diff($productArray, $cartProduct);	
                                        if(!empty($result)) {                                                            
								continue;
                                        }
							
						}		
                                if($v['ruleType']=='Bundle'){	
                                                                        
                                    
									if (in_array($r['product_id'], $productArray) && $v['ruleID']==$r['bundleID']) {
                                                                            
										$item_discount = ($items_qty > 0) ? $r['q'] / $items_qty * $current_discount_amount : 0;
                                                                                
										//echo $item_discount= ($r['p'] <= $item_discount) ? $r['p'] : $item_discount;
										$applicable_items_discount[$i]   = (isset($applicable_items_discount[$i]) ? $applicable_items_discount[$i] : 0) + $item_discount;								
									}else{
									 $item_discount=0;
									}									
								}else{	
                                $item_discount = ($items_qty > 0) ? $r['q'] / $items_qty * $current_discount_amount : 0;
								$item_discount= ($r['p'] <= $item_discount) ? $r['p'] : $item_discount;
                                $applicable_items_discount[$i] = (isset($applicable_items_discount[$i]) ? $applicable_items_discount[$i] : 0) + $item_discount;								
								}	
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] = isset($promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d']) ? $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] : 0;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] += $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['ruleID'] = $v['ruleID'];
								if($v['ruleType']=='Bundle'){
									if (in_array($r['product_id'], $productArray) && $v['ruleID']==$r['bundleID']) {
										$discount_amount += $item_discount;
										$tmp_current_discount_amount += $item_discount;
									}
								}else{
									$discount_amount += $item_discount;
									$tmp_current_discount_amount += $item_discount;
								}
								
                            }
                        }
                        $current_discount_amount = $tmp_current_discount_amount;
						
                    } else if ($v['apply'] == 'cart_fixed') {
                        $current_discount_amount = ($items_subtotal_amount <= $v['discountAmount']) ? $items_subtotal_amount : $v['discountAmount'];
                        $discount_amount += $current_discount_amount;
                        if (count($applicable_items) > 0) {
                            foreach ($applicable_items as $i => $r) {
                                $item_discount                                                                  = ($items_subtotal_amount > 0) ? $r['p'] / $items_subtotal_amount * $current_discount_amount : 0;
                                $applicable_items_discount[$i]                                                  = (isset($applicable_items_discount[$i]) ? $applicable_items_discount[$i] : 0) + $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] = (isset($promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d']) ? $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] : 0);
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] += $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['ruleID'] = $v['ruleID'];
                            }
                        }
                    } else {
                        $current_discount_amount = 0;
                        $discount_amount += $current_discount_amount;
                        if (count($applicable_items) > 0) {
                            foreach ($applicable_items as $i => $r) {
                                $item_discount                                                                  = ($items_subtotal_amount > 0) ? $r['p'] / $items_subtotal_amount * $current_discount_amount : 0;
                                $applicable_items_discount[$i]                                                  = (isset($applicable_items_discount[$i]) ? $applicable_items_discount[$i] : 0) + $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] = (isset($promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d']) ? $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] : 0);
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['d'] += $item_discount;
                                $promotion_based_applicable_items_discount[$i]['promotions'][$v['ruleID']]['ruleID'] = $v['ruleID'];
                            }
                        }
                    }
                    
                    //echo '<pre>'; print_r(json_decode($v['freeProducts'],true));
                    if ($v['freeProducts'] != '') {
                        $free_array = json_decode($v['freeProducts'], true);
                        //echo '<pre>';print_r($free_array);
                        if (count($free_array) > 0) {
                            foreach ($free_array as $k => $s) {
                                if ($s['variants'] != '') {
                                    $option_id_array = explode(",", $s['variants']);
                                    if (count($option_id_array) > 0) {
                                        foreach ($option_id_array as $key => $option_id) {
                                            $key                                 = $s['productID'] . "_" . $option_id;
                                            $free_products[$key]['productID']    = $s['productID'];
                                            $free_products[$key]['combinations'] = $s['combinations'];
                                            if (isset($free_products[$key]['quantity']))
                                                $free_products[$key]['quantity'] += $s['quantity'];
                                            else
                                                $free_products[$key]['quantity'] = $s['quantity'];
                                            $free_products[$key]['variants']      = $option_id;
                                            $free_products[$key]['customOptions'] = $s['customOptions'];
                                            $free_products[$key]['freeShipping']      = $s['freeShipping'];
                                        }
                                    }
                                } else if ($s['combinations'] != '') {
                                    $combination_array = explode(",", $s['combinations']);
                                    if (count($combination_array) > 0) {
                                        foreach ($combination_array as $key => $combination) {
                                            $key                                 = $s['productID'] . "_" . $combination;
                                            $free_products[$key]['productID']    = $s['productID'];
                                            $free_products[$key]['combinations'] = $combination;
                                            if (isset($free_products[$key]['quantity']))
                                                $free_products[$key]['quantity'] += $s['quantity'];
                                            else
                                                $free_products[$key]['quantity'] = $s['quantity'];
                                            $free_products[$key]['variants']      = $s['variants'];
                                            $free_products[$key]['freeShipping']  = $s['freeShipping'];
                                            $free_products[$key]['customOptions'] = $s['customOptions'];
                                        }
                                    }
                                } else {
                                    $key                                 = $s['productID'];
                                    $free_products[$key]['productID']    = $s['productID'];
                                    $free_products[$key]['combinations'] = $s['combinations'];
                                    if (isset($free_products[$key]['quantity']))
                                        $free_products[$key]['quantity'] += $s['quantity'];
                                    else
                                        $free_products[$key]['quantity'] = $s['quantity'];
                                    $free_products[$key]['variants']      = $s['variants'];
                                    $free_products[$key]['customOptions'] = $s['customOptions'];
                                    $free_products[$key]['freeShipping']  = $s['freeShipping'];
                                }
                            }
                        }
                    }
                    $applied_promotions_details[$v['ruleID']]['ruleID']           = $v['ruleID'];
                    $applied_promotions_details[$v['ruleID']]['ruleName']         = $v['ruleName'];
                    $applied_promotions_details[$v['ruleID']]['discountAmount']   = number_format($v['discountAmount'], 2, '.', '');
					
                    $applied_promotions_details[$v['ruleID']]['discount']         = $current_discount_amount;
                    $applied_promotions_details[$v['ruleID']]['apply']            = $v['apply'];
                    $applied_promotions_details[$v['ruleID']]['freeShipping']     = $v['freeShipping'];
                    $applied_promotions_details[$v['ruleID']]['freeProducts']     = $v['freeProducts'];
                    $applied_promotions_details[$v['ruleID']]['ruleType']         = ($v['couponCode'] == '') ? 'no_coupon' : 'coupon';
                    $applied_promotions_details[$v['ruleID']]['bundlePromo']      = $v['ruleType'];
                    $applied_promotions_details[$v['ruleID']]['couponCode']       = $v['couponCode'];
                    $applied_promotions_details[$v['ruleID']]['applicable_items'] = $applicable_items;
                    $applied_promotions_details[$v['ruleID']]['bundle_items']     = $bundle_items;
                    $applied_promotions_details[$v['ruleID']]['giftCoupon']       = $v['giftCoupon'];
                }
                if ($v['couponCode'] != '') {
                    $promo_id = $v['ruleID'];
                }
            }
            
            //echo '<pre>';print_r($promotion_based_applicable_items_discount);
            if ($free_shipping_for_all) {
                $current_discount_amount = $cart['shippingAmount'];
               
                $discount_amount += $current_discount_amount;
                if (count($cart['items']) > 0) {
                    foreach ($cart['items'] as $i => $r) {
                        if ($r['freeProduct'] == 'Yes') {
                            continue;
                        } else {
                            if(!in_array($r['cartItemID'], array_keys($applicable_items))) {
                                if(!in_array($r['cartItemID'], array_keys($applicable_items_discount))) {
                                    continue;
                        }
                      }
                 }
                        $item_unserialize                            = ($fromtype!='' && $fromtype=='orderedit')?unserialize($r['extra']):unserialize($r['itemDetails']);
                        $item_discount                               = $item_unserialize['shippingAmount'];
                        $applicable_items_discount[$r['cartItemID']] = (isset($applicable_items_discount[$r['cartItemID']]) ? $applicable_items_discount[$r['cartItemID']] + $item_discount : $item_discount);
                        if (isset($free_shipping_promotion_id)) {
                            if (isset($promotion_based_applicable_items_discount[$r['cartItemID']]['promotions'][$free_shipping_promotion_id])) {
                                $promotion_based_applicable_items_discount[$r['cartItemID']]['promotions'][$free_shipping_promotion_id]['d'] += $item_discount;
                            } else {
                                $promotion_based_applicable_items_discount[$r['cartItemID']]['promotions'][$free_shipping_promotion_id]['d'] = $item_discount;
                            }
                            $promotion_based_applicable_items_discount[$r['cartItemID']]['promotions'][$free_shipping_promotion_id]['ruleID'] = $free_shipping_promotion_id;
                            $promotion_based_applicable_items_discount[$r['cartItemID']]['free_shipping']                                     = "true";
                        }
                    }
                }
            }
           
            $itemDiscountTotals = 0;
            foreach ($cart['items'] as $keyc=>$cartItems) {
                if ($cartItems['freeProduct'] == 'Yes' /* || !in_array($r['cartItemID'],array_keys($applicable_items)) */ )
                    continue;
                $unserializedData                             = ($fromtype!='' && $fromtype=='orderedit')?unserialize($cartItems['extra']):unserialize($cartItems['itemDetails']);
                $unserializedData['orderPromoDiscountAmount'] = (isset($applicable_items_discount[$cartItems['cartItemID']]) ? $applicable_items_discount[$cartItems['cartItemID']] : 0);
                $tot_without_dis                              = ($unserializedData['orderItemSubtotal'] + $unserializedData['orderOtherServiceCharge'] + $unserializedData['shippingAmount'] + $unserializedData['orderTaxAmount']);
                $unserializedData['orderPromoDiscountAmount'] =  $unserializedData['orderPromoDiscountAmount'];
                $unserializedData['promotions']               = (isset($promotion_based_applicable_items_discount[$cartItems['cartItemID']]['promotions']) ? $promotion_based_applicable_items_discount[$cartItems['cartItemID']]['promotions'] : array());
                $unserializedData['free_shipping']            = isset($promotion_based_applicable_items_discount[$cartItems['cartItemID']]['free_shipping']) ? $promotion_based_applicable_items_discount[$cartItems['cartItemID']]['free_shipping'] : "false";
				
                $itemDiscountTotals += $unserializedData['orderPromoDiscountAmount'];
                $serializedData = serialize($unserializedData);
                if($fromtype!='' && $fromtype=='orderedit') {
                    $cart['items'][$keyc]['extra'] = $serializedData;
                } else {
                $sql            = " UPDATE 
								" . DB_PREFIX . "cart_items 
							SET 
								itemDetails = '" . $this->escape($serializedData, false, false) . "'
							 WHERE 
								cartItemID=" . (int) $cartItems['cartItemID'] . " LIMIT 1";
                $result         = $this->ObjDatabase->setQuery($sql);
            }
            }
            $discount_amount                       = ($discount_amount > $itemDiscountTotals) ? $itemDiscountTotals : $discount_amount;
            $cart_extra_data                       = $cart['extra'];
            $free_shipping                         = ($free_shipping_for_all) ? 'Yes' : 'No';
            $cart_extra_data['applied_promotions'] = $applied_promotions_details;
            
            if($fromtype=='') {
                
            $sql                                   = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							orderPromoCode='" . $coupon_code . "',
							promoID=" . (int) $promo_id . ",
							orderPromoDiscountAmount='" . $discount_amount . "',
							extra = '" . $this->escape(serialize($cart_extra_data), false, false) . "',
							freeShipping='" . $free_shipping . "'
						WHERE 
							cartID=" . (int) $cart_id . " LIMIT 1";
							
            $result                                = $this->ObjDatabase->setQuery($sql);
        }
        }
        if($fromtype!='' && $fromtype=='orderedit') {
            $cart['orderPromoDiscountAmount'] = $discount_amount;
            $cart['orderPromoCode']           = $coupon_code;
           
            return $cart;
        } else {
        return (isset($free_products)) ? $free_products : array();
    }
    }
    public function getProductCategories($productID = 0) {
        $sql    = " SELECT
					GROUP_CONCAT(productCategoryID) AS productCategoryIDs
				FROM
					" . DB_PREFIX . "product_to_category
				WHERE
					productID = " . (int) $productID;
        $result = $this->ObjDatabase->readValueSlave($sql, MYSQLI_ASSOC);
        return $result['productCategoryIDs'];
    }
    public function getProductAttributeValues($productID = 0) {
        $data   = array();
        $sql    = " SELECT
					GROUP_CONCAT(attrOptionID) as attrOptionID,
					attributeID	as attributeID
				FROM
					" . DB_PREFIX . "product_attribute_values
				WHERE
					productID = " . (int) $productID . " GROUP BY attributeID";
        $result = $this->ObjDatabase->readValuesSlave($sql, MYSQLI_ASSOC);
        if (count($result) > 0) {
            foreach ($result as $i => $r) {
                $data[$r['attributeID']] = explode(',', $r['attrOptionID']);
            }
        }
        return $data;
    }
    public function getProductAttributeValuesText($productID = 0, $language_id = 0) {
        $data   = array();
        $sql    = " SELECT
					attrDetValue AS attrDetValues,
					attributeID	as attributeID
				FROM
					" . DB_PREFIX . "product_attribute_values attVal
				LEFT JOIN	
					" . DB_PREFIX . "product_attribute_value_details as attValDet
				ON (attValDet.attrValueID=attVal.attrValueID AND languageID =" . (int) $language_id . ")	
				WHERE
					attVal.productID = " . (int) $productID;
        $result = $this->ObjDatabase->readValuesSlave($sql, MYSQLI_ASSOC);
        if (count($result) > 0) {
            foreach ($result as $i => $r) {
                $data[$r['attributeID']] = $r['attrDetValues'];
            }
        }
        return $data;
    }
    /**
     * Check promotiontion conditions
     *
     * @param int $promotion_id promotion ID
     * @param array $condition conditions set
     * @param array $data data array
     * @return bool true if promotion can be applied, false - otherwise
     */
    private function fn_promotion_check($promotion_id, $condition, $data, $params, $type = 'conditions') {
        // This is unconditional promotiontion
        if (empty($condition)) {
            return true;
        }
        $sub_type = ($type == 'conditions') ? 'condition' : 'bonus';
        // if this is the conditions group, check each condition in cycle
        //echo "<pre>"; print_r($condition); exit;
        if (!empty($condition[$type])) {
            foreach ($condition[$type] as $cond) {
                if (!empty($cond[$type])) {
                    $c_res = $this->fn_promotion_check($promotion_id, $cond, $data, $params, $type);
                } else {
                    $c_res = $this->fn_promotion_validate($promotion_id, $cond, $data, $params, $type, $sub_type);
                }
                if (!isset($result)) {
                    $result = $c_res;
                }
                // Check result, if any condition is correct
                if ($condition['set'] == 'any' && $c_res == $condition['set_value']) {
                    return true;
                    //If we need to compare all conditions, summ the result
                } elseif ($condition['set'] == 'all') {
                    $result = $result & $c_res;
                }
            }
            return ($condition['set_value'] == true) ? $result : !$result;
            // If this is the ordinary condition, check it directly
        } else {
            return $this->fn_promotion_validate($promotion_id, $condition, $data, $params, $type, $sub_type);
        }
    }
    /**
     * Validate rule
     *
     * @param int $promotion_id promotion ID
     * @param array $promotion rule data
     * @param array $data data array
     * @return bool true if rule can be applied, false - otherwise
     */
    function fn_promotion_validate($promotion_id, $promotion, $data, $params, $type, $sub_type,$ObjCart=array()) {
        //$schema = fn_promotion_get_schema('conditions');
      
        $group_type = ($type == 'conditions') ? 'condition_group' : 'bonus_group';
        extract($params);
        $stop_validating = false;
        //echo "<pre>";print_r($promotion);print_r($data);print_r($params);
         
        if (empty($promotion[$sub_type])) { // if promotion is unconditional, apply it
            return true;
        }
        $promotion['value'] = !isset($promotion['value']) ? '' : $promotion['value'];
        if ($promotion[$sub_type] != '') {
            $value = '';
            // Ordinary field
            if ($promotion[$group_type] != '') {
                $operand_one;
                if ($promotion[$group_type] == 'cartAttribute') {
                    //echo $promotion[$sub_type];exit;
                    switch ($promotion[$sub_type]) {
                        //For selected Users
                        case 'users':
                            $operand_one = $data['userID'];
                            break;
                        //User Country (shipping)	
                        case 'country':
                            $operand_one = (isset($data['extra']['userShippingAddress']['shippingCountryID']) ? $data['extra']['userShippingAddress']['shippingCountryID'] : 0);
                            break;
                        //User State (shipping)	
                        case 'state':
                            
                            $operand_one = (isset($data['extra']['userShippingAddress']['shippingStateID']) ? $data['extra']['userShippingAddress']['shippingStateID'] : 0);
                            break;
                        //User zip/postal code (shipping)	
                        case 'zip_postal_code':
                            $operand_one = (isset($data['extra']['userShippingAddress']['shippingZip']) ? $data['extra']['userShippingAddress']['shippingZip'] : '');
                            break;
                        //Order Subtotal	
                        case 'subtotal':
                            $operand_one = number_format((float) $data['orderSubtotal'], $currency_decimal_places, '.', '');
                            break;
                        //Total products in the cart	
                        //Order Subtotal	
                        case 'merchant_subtotal':
                            $merchant_subtotal = 0;
                            $businessID        = $promotion['value_select'];
                            foreach ($data['items'] as $items) {
                                if ($items['businessID'] == $businessID) {
                                    $merchant_subtotal += $items['orderItemSubtotal'];
                                }
                            }
                            $operand_one = number_format((float) $merchant_subtotal, $currency_decimal_places, '.', '');
                            break;
                        //Total products in the cart	
                        case 'total_products':
                            $operand_one = $data['orderQty'];
                            break;
                        //Total products weight in the cart	
                        case 'total_products_weight':
                            $operand_one = $data['orderWeight']; 
                            break;
                        //Payment Method used	
                        case 'payment_method':
                            $operand_one = $data['paymentSettingsGroupID'];
                            break;
                    }
                    if ($promotion['operator'] == 'nin') {
                        if ($this->fn_promotion_validate_attribute($operand_one, ((isset($promotion['value']) && $promotion['value'] != '') ? $promotion['value'] : $promotion['value_select']), 'in')) {
                            return false;
                        } else {
                            return true;
                        }
                    } else {
                        if ($this->fn_promotion_validate_attribute($operand_one, ((isset($promotion['value']) && $promotion['value'] != '') ? $promotion['value'] : $promotion['value_select']), $promotion['operator'])) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                } else if ($promotion[$group_type] == 'cartItemAttribute') {
                    switch ($promotion[$sub_type]) {
                        //Item Price in cart
                        case 'price':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['operator'] == 'in' || $promotion['operator'] == 'nin') {
                                        $promo_chk_value = $promotion['value'];
                                    } else {
                                        $promo_chk_value = number_format((float) $promotion['value'], $currency_decimal_places, '.', '');
                                    }
                                    if ($promotion['operator'] == 'nin') {
                                        if ($this->fn_promotion_validate_attribute(number_format((float) $v['orderItemPrice'], $currency_decimal_places, '.', ''), $promo_chk_value, 'in')) {
                                            $c_res = false;
                                        } else {
                                            $c_res = true;
                                        }
                                    } else {
                                        if ($this->fn_promotion_validate_attribute(number_format((float) $v['orderItemPrice'], $currency_decimal_places, '.', ''), $promo_chk_value, $promotion['operator'])) {
                                            $c_res = true;
                                        } else {
                                            $c_res = false;
                                        }
                                    }
                                    if (!isset($result)) {
                                        $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                        //Item Quantity in cart
                        case 'quantity':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['operator'] == 'nin') {
                                        if ($this->fn_promotion_validate_attribute($v['orderItemQuantity'], $promotion['value'], 'in')) {
                                            $c_res = false;
                                        } else {
                                            $c_res = true;
                                        }
                                    } else {
                                        if ($this->fn_promotion_validate_attribute($v['orderItemQuantity'], $promotion['value'], $promotion['operator'])) {
                                            $c_res = true;
                                        } else {
                                            $c_res = false;
                                        }
                                    }
                                    if (!isset($result)) {
                                        $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                        //Row total in cart	
                        case 'row_total':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['operator'] == 'in' || $promotion['operator'] == 'nin') {
                                        $promo_chk_value = $promotion['value'];
                                    } else {
                                        $promo_chk_value = number_format((float) $promotion['value'], $currency_decimal_places, '.', '');
                                    }
                                    if ($promotion['operator'] == 'nin') {
                                        if ($this->fn_promotion_validate_attribute(number_format((float) $v['orderItemSubtotal'], $currency_decimal_places, '.', ''), $promo_chk_value, 'in')) {
                                            $c_res = false;
                                        } else {
                                            $c_res = true;
                                        }
                                    } else {
                                        if ($this->fn_promotion_validate_attribute(number_format((float) $v['orderItemSubtotal'], $currency_decimal_places, '.', ''), $promo_chk_value, $promotion['operator'])) {
                                            $c_res = true;
                                        } else {
                                            $c_res = false;
                                        }
                                    }
                                    if (!isset($result)) {
                                        $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                        //Products	
                        case 'products':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    $product_id = $v['productID'];
                                    
                                    if (isset($promotion['options']) && !empty($promotion['options'][$product_id]['combinations'])) {
                                        $combination_string = implode(",", $promotion['options'][$product_id]['combinations']);
                                        if ($promotion['operator'] == 'nin') {
                                            if ($this->fn_promotion_validate_attribute($v['combinationHash'], $combination_string, 'in')) {
                                                $c_res = false;
                                            } else {
                                                $c_res = true;
                                            }
                                        } else {
                                            if ($this->fn_promotion_validate_attribute($v['combinationHash'], $combination_string, $promotion['operator'])) {
                                                $c_res = true;
                                            } else {
                                                $c_res = false;
                                            }
                                        }
                                    } else {
                                        if ($promotion['operator'] == 'nin') {
                                            if ($this->fn_promotion_validate_attribute($v['productID'], $promotion['value'], 'in')) {
                                                $c_res = false;
                                            } else {
                                                $c_res = true;
                                            }
                                        } else {
                                            if ($this->fn_promotion_validate_attribute($v['productID'], $promotion['value'], $promotion['operator'])) {
                                                $c_res = true;
                                            } else {
                                                $c_res = false;
                                            }
                                        }
                                    }
                                    if (!isset($result)) {
                                        $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                    }
                } else if ($promotion[$group_type] == 'productAttribute') {
                    switch ($promotion[$sub_type]) {
                        // item Categories
                        case 'categories':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['operator'] == 'nin') {
                                        if ($this->fn_promotion_validate_attribute($v['categories'], $promotion['value'], 'in')) {
                                            $c_res	= false;
                                        } else {
                                            $c_res	= true;
                                        }
                                    } else {
                                        if ($this->fn_promotion_validate_attribute($v['categories'], $promotion['value'], $promotion['operator'])) {
                                            $c_res	= true;
                                        } else {
                                            $c_res	= false;
                                        }
                                    }
                                    if (!isset($result)) 
                                    {
                                            $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                        // item attributes	
                        case 'attributes':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['value'] != '') {
                                        $attributeTexts = (isset($v['attributeTexts'][$promotion['condition_element']]) ? $v['attributeTexts'][$promotion['condition_element']] : '');
                                        if ($promotion['operator'] == 'nin') {
                                            if ($this->fn_promotion_validate_attribute($attributeTexts, $promotion['value'], 'in')) {
                                                $c_res	= false;
                                            } else {
                                                $c_res	= true;
                                            }
                                        } else {
                                            if ($this->fn_promotion_validate_attribute($attributeTexts, $promotion['value'], $promotion['operator'])) {
                                                $c_res	= true;
                                            } else {
                                                $c_res	= false;
                                            }
                                        }
                                    } else {
                                        $attributes = (isset($v['attributes'][$promotion['condition_element']]) ? $v['attributes'][$promotion['condition_element']] : '');
                                        if ($promotion['operator'] == 'nin') {
                                            if ($this->fn_promotion_validate_attribute($attributes, $promotion['value_select'], 'in')) {
                                                $c_res	= false;
                                            } else {
                                                $c_res	= true;
                                            }
                                        } else {
                                            if ($this->fn_promotion_validate_attribute($attributes, $promotion['value_select'], $promotion['operator'])) {
                                                $c_res	= true;
                                            } else {
                                                $c_res	= false;
                                            }
                                        }
                                    }
                                    if (!isset($result)) 
                                    {
                                            $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                        // item brands
                        case 'brands':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['operator'] == 'nin') {
                                        if ($this->fn_promotion_validate_attribute($v['brandID'], $promotion['value'], 'in')) {
                                            $c_res	= false;
                                        } else {
                                            $c_res	= true;
                                        }
                                    } else {
                                        if ($this->fn_promotion_validate_attribute($v['brandID'], $promotion['value'], $promotion['operator'])) {
                                            $c_res	= true;
                                        } else {
                                            $c_res	= false;
                                        }
                                    }
                                    if (!isset($result)) 
                                    {
                                            $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                        // item brands
                        case 'business':
                            if (count($data['items']) > 0) {
                                foreach ($data['items'] as $v) {
                                    if ($promotion['operator'] == 'nin') {
                                        if ($this->fn_promotion_validate_attribute($v['businessID'], $promotion['value'], 'in')) {
                                            $c_res	= false;
                                        } else {
                                            $c_res	= true;
                                        }
                                    } else {
                                        if ($this->fn_promotion_validate_attribute($v['businessID'], $promotion['value'], $promotion['operator'])) {
                                            $c_res	= true;
                                        } else {
                                            $c_res	= false;
                                        }
                                    }
                                    if (!isset($result)) 
                                    {
                                            $result = $c_res;
                                    }
                                    $result = $result || $c_res;
                                }
                                return $result;
                            }
                            break;
                    }
                }
            }
        }
        return false;
    }
    /**
     * Validate attribute
     *
     * @param mixed $val value to compare with (can be one-dimensional array, in this case, every item will be checked)
     * @param mixed $condition value to compare to
     * @param string $op compare operator
     * @return bool true in success, false - otherwise
     */
    public function fn_promotion_validate_attribute($value, $condition, $op) {
        $result = false;
        if (!isset($condition)) { // condition can't be empty
            return false;
        }
        $val = !is_array($value) ? array(
            $value
        ) : $value;
        if ($op == 'neq') {
            return !in_array($condition, $val);
        }
        foreach ($val as $v) {
            if ($op == 'eq') {                
                $result = ($v == $condition);
            } elseif ($op == 'lte') {
                $result = ($v <= $condition);
            } elseif ($op == 'lt') {
                $result = ($v < $condition);
            } elseif ($op == 'gte') {
                $result = ($v >= $condition);
            } elseif ($op == 'gt') {
                $result = ($v > $condition);
            } elseif ($op == 'cont') {
                $result = (stripos((string) $v, (string) $condition) !== false);
            } elseif ($op == 'ncont') {
                $result = (stripos((string) $v, (string) $condition) === false);
            } elseif ($op == 'in') {
                $condition = is_array($condition) ? $condition : explode(',', $condition);
                if (is_array($v)) {
                    foreach ($condition as $item) {
                        if (sizeof($v) != sizeof($item)) {
                            if (sizeof(array_intersect_assoc($v, $item)) == sizeof($item)) {
                                $result = true;
                                break;
                            }
                        } else {
                            array_multisort($v);
                            array_multisort($item);
                            if ($v == $item) {
                                $result = true;
                                break;
                            }
                        }
                    }
                } else {
                    $result = in_array($v, $condition, is_bool($v));
                }
            } elseif ($op == 'nin') {
                $condition = is_array($condition) ? $condition : explode(',', $condition);
                if (is_array($v)) {
                    $result = true;
                    foreach ($condition as $item) {
                        if (sizeof($v) != sizeof($item)) {
                            if (sizeof(array_intersect_assoc($v, $item)) == sizeof($item)) {
                                $result = false;
                                break;
                            }
                        } else {
                            array_multisort($v);
                            array_multisort($item);
                            if ($v == $item) {
                                $result = false;
                                break;
                            }
                        }
                    }
                } else {
                    $result = !in_array($v, $condition);
                }
            }
            if (!empty($result)) {
                return true;
            }
        }
        return false;
    }
    public function updatePromocodeUsage($params = array()) {
        extract($params);
        $sql = " INSERT INTO
								" . DB_PREFIX . "cart_rules_usage
											(
												ruleID,
												userEmail,
												masterOrderID,
												orderQty,
												discount,
												orderTotalAmount,
												couponID,
												couponAmount,
												orderTime
											)
									VALUES
											('" . $rule_id . "',
											'" . $user_email . "',
											'" . $master_order_id . "',
											'" . $quantity . "',
											'" . $discount . "',
											'" . $order_total . "',
											'" . $coupon_id . "',
											'" . $coupon_amount . "',
											NOW()
											)";
        $this->ObjDatabase->setQuery($sql);
        $this->ObjDatabase->setQuery("
				UPDATE
					" . DB_PREFIX . "cart_rules 
				SET
					timesUsed = IF(timesUsed>0,timesUsed+1,1),
					timesInUse = IF(timesInUse>0,timesInUse-1,0)
				WHERE
					ruleID = '" . $rule_id . "'
			");
    }
    public function getFreeProductDetails($params = array()) {
        extract($params);
        if ($product_option_id > 0) {
            $sql = " SELECT 
							product.productServiceFee,
							productOptDet.productOptionName,
							productOptDet.productOptionName as productTitle, 
							product.productImage,
							product.productID,
							bus.businessKey,
							productOpt.productOptionID,
                                                        bus.businessID
						FROM  
							" . DB_PREFIX . "product_options productOpt 
						INNER JOIN 
							" . DB_PREFIX . "products AS product 
							ON 
							(product.productID=productOpt.productID) 
						INNER JOIN 
							" . DB_PREFIX . "business AS bus 
							ON 
							(bus.businessID=product.businessID) ";
            if ($language_id > 0) {
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=" . (int) $product_option_id . " 
								AND productOptDet.languageID=" . (int) $language_id . ") ";
            } else {
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=" . (int) $product_option_id . " 
								AND  productOptDet.languageID=1) ";
            }
            $sql .= " WHERE 
								productOpt.productOptionID=" . (int) $product_option_id . " LIMIT 0,1";
            $resProduct = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        } else {
            $sql = " SELECT 
							product.productServiceFee,
							productOptDet.productOptionName,
							productOptDet.productOptionName as productTitle, 
							product.productImage,
							product.productID,
							bus.businessKey,
							productOpt.productOptionID,
                                                        bus.businessID
						FROM  
							" . DB_PREFIX . "product_options productOpt 
						INNER JOIN 
							" . DB_PREFIX . "products AS product 
							ON 
							(product.productID=productOpt.productID AND productOpt.productOptionDefault='Yes') 
						INNER JOIN 
							" . DB_PREFIX . "business AS bus 
							ON 
							(bus.businessID=product.businessID) ";
            if ($language_id > 0) {
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=productOpt.productOptionID 
								AND productOptDet.languageID=" . (int) $language_id . ") ";
            } else {
                $sql .= " LEFT JOIN 
								" . DB_PREFIX . "product_option_details AS productOptDet 
								ON 
								(productOptDet.productOptionID=productOpt.productOptionID
								AND  productOptDet.languageID=1) ";
            }
            $sql .= " WHERE 
								product.productID=" . (int) $product_id . " LIMIT 0,1";
            $resProduct = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        }
        return $resProduct;
    }
    public function getProductProperties($product_id = 0, $fields = array()) {
        if (count($fields) == 0) {
            $field = '*';
        } else {
            $field = implode(",", $fields);
        }
        $sql    = " SELECT 
							" . $field . "
						FROM  
							" . DB_PREFIX . "products AS product 
						WHERE 
							product.productID=" . (int) $product_id . " LIMIT 0,1";
        $result = $this->ObjDatabase->readValue($sql, MYSQLI_ASSOC);
        return $result;
    }
    public function getOrderMasterDetailsByParentOrderID($order_id = 0,$apiCode='') {
        if ($order_id > 0) {
            $sql      = " SELECT
							ordMas.masterOrderID,
							ordMas.orderNumber,
							ordMas.orderType,
							ordMas.promoID,
							ordMas.orderPromoCode,
							ordMas.paymentSettingsGroupID,
							ordMas.orderPaymentMethodName,
							ordMas.paymentType,
							ordMas.languageID,
							ordMas.purchasedCurrency,
							ordMas.billingAddress,
							ordMas.shippingAddress,	
							ordMas.netpayOrderID,
							ordMas.netpayPaymentType,
							ordMas.orderHold,
							ordMas.orderHold,
							ordMas.transactionID,
							ordMas.paymentStatus,
							ordMas.orderStatus,
							ordMas.paymentNotes,
							ordMas.userID,
							ordMas.cityID,
							ordMas.orderCreatedDate,
							ordMas.orderStatusDate,
							ordMas.customer_email,
                                                        ordMas.blueEx_CN,
                                                        ordMas.subtitle,
                                                        ordMas.delivery_CN,
                                                        ordMas.merchant_account_id,
							SUM(ordMas.orderTotalAmount) as orderTotalAmount,
							SUM(ordMas.convertedMasterOrderTotal) as convertedMasterOrderTotal,
							SUM(ordMas.orderSubtotal) as masterOrderSubtotal,
							SUM(ordMas.orderSubtotal) as orderSubtotal,
							SUM(ordMas.convertedMasterOrderSubtotal) as convertedMasterOrderSubtotal,
							SUM(ordMas.orderQty) as orderQty,
							SUM(ordMas.orderPromoDiscountAmount) as orderPromoDiscountAmount,
							SUM(ordMas.convertedOrderPromoDiscountAmount) as convertedOrderPromoDiscountAmount,
							SUM(ordMas.orderUserCreditAmount) as orderUserCreditAmount,
							SUM(ordMas.convertedOrderUserCreditAmount) as convertedOrderUserCreditAmount,
							SUM(ordMas.orderQty) as orderQty,
							SUM(ordMas.orderTaxAmount) as orderTaxAmount,
							SUM(ordMas.orderCommissionAmount) as orderCommissionAmount,
							SUM(ordMas.orderPaymentGatewayCharge) as
							orderPaymentGatewayCharge,
							SUM(ordMas.orderOtherServiceCharge) as
							orderOtherServiceCharge,
                                                        SUM(ordMas.orderConvenientFee) as
							orderConvenientFee,
							SUM(ordMas.shippingAmount) as shippingAmount  
						FROM 
							" . DB_PREFIX . "order_masters as ordMas 
						WHERE 
							ordMas.masterOrderID = '" . $order_id . "'";
                                               
                            if($apiCode=='') {
                                $sql .= "   OR ordMas.parentOrderID = '".$order_id."' ";
                            } else {
                                $sql .= "   OR (ordMas.parentOrderID = '".$order_id."' and ordMas.orderStatus in ('Process','Completed')) ";
                            }
                                  
            
            $resOrder = $this->ObjDatabase->readValue($sql);
            return $resOrder;
        }
    }
    // Function to get the order item details of a master order
    public function getOrderItemDetailsByParentOrderID($order_id = 0, $languageIDs = array(),$apiCode='',$reOrder='',$userID='') {
        if (count($languageIDs) > 0) {
            $currentLanguageID = $languageIDs['Current'];
            $defaultLanguageID = $languageIDs['Default'];
            if ($order_id > 0) {
                $sql           = " SELECT 
								ordIte.*,
								productOptDet.productOptionName as optionName,
								busDet.businessName,
								bus.businessEmail,
								bus.businessDefaultLanguageID,
								bus.businessKey,
                                                                bus.api_id,
                                                                bus.businessPhone,
                                                                busloc.locCountryID,
                                                                busLocDet.locAddress1,
                                                                busLocDet.locAddress2,
                                                                busLocDet.locCity,
								productDet.productTitle,
								ordMas.masterOrderID,
								ordMas.orderNumber,
								productOpt.optionSKU,                                                                
                                                                ordMas.businessID,
                                                                product.qtyPerBatch,
                                                                product.sellAsBatch,
                                                                product.batchType 
							FROM 
								" . DB_PREFIX . "order_items ordIte
							INNER JOIN 
								" . DB_PREFIX . "order_masters ordMas 
								ON 
								(
									(ordMas.masterOrderID=" . (int) $order_id . ""; 
								
                
                                    if($apiCode=='') {
                                        $sql    .= " 	 OR ordMas.parentOrderID = ".(int)$order_id."";
                                    } else {
                                        $sql    .= " 	 OR (ordMas.parentOrderID = ".(int)$order_id." and ordMas.orderStatus in ('Process','Completed'))";
                                    }
                                
                                 $sql    .= ") AND ordIte.masterOrderID = ordMas.masterOrderID 
								) 
							INNER JOIN 
								" . DB_PREFIX . "products product 
								ON (product.productID = ordIte.productID)
							INNER JOIN  
								" . DB_PREFIX . "product_details productDet 
								ON (productDet.productID = product.productID 
								AND productDet.languageID=" . (int) $currentLanguageID . ")	
							INNER JOIN 
								" . DB_PREFIX . "business bus 
								ON (bus.businessID = ordMas.businessID)
							INNER JOIN 
								" . DB_PREFIX . "business_details busDet 
								ON (busDet.businessID = bus.businessID 
								AND busDet.languageID=" . (int) $currentLanguageID . ")
                                                       LEFT JOIN 
								".DB_PREFIX."business_locations busloc 
								ON (busloc.businessID = bus.businessID and busloc.isLocationBasic='Yes')
                                                        LEFT JOIN 
								".DB_PREFIX."business_location_details busLocDet 
								ON (busLocDet.businessLocID = busloc.businessLocID 
								AND busLocDet.languageID=".(int)$currentLanguageID.")      
							INNER JOIN  
								" . DB_PREFIX . "product_options productOpt
								ON (productOpt.productOptionID = ordIte.productOptionID) 	
							INNER JOIN  
								" . DB_PREFIX . "product_option_details productOptDet 
								ON (productOptDet.productOptionID = ordIte.productOptionID 
								AND productOptDet.languageID=" . (int) $currentLanguageID . ") 
							GROUP BY ordIte.orderItemID";
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        } else {
            if ($order_id > 0) {
                $sql           = " SELECT ordIte.*,ordMas.businessID FROM " . DB_PREFIX . "order_items ordIte INNER JOIN " . DB_PREFIX . "order_masters ordMas 
								ON 
								(
									(ordMas.masterOrderID=" . (int) $order_id . " ";
                if($reOrder=='') {
                    $sql        .=  " OR ordMas.parentOrderID = " . (int) $order_id . "";
                }
                $sql           .=  ") AND ordIte.masterOrderID = ordMas.masterOrderID) ";
                if($userID >0) {
                    $sql           .=  " where ordMas.userID='".$userID."' ";
                }                
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        }
    }
    //Function to get the distinct order item details
    public function getDistinctOrderItemDetailsByParentOrderID($order_id = 0, $languageIDs = array()) {
        if (count($languageIDs) > 0) {
            $currentLanguageID = $languageIDs['Current'];
            $defaultLanguageID = $languageIDs['Default'];
            if ($order_id > 0) {
                $sql           = " SELECT 
								ordIte.*,
								sum(ordIte.orderItemQuantity) as totalQuantity,
								productDet.productTitle as productTitle,
								busDet.businessName,
								bus.businessEmail,
								bus.businessDefaultLanguageID,
								product.productUrl,
								bus.businessKey,
								product.productImage								
							FROM 
								" . DB_PREFIX . "order_items ordIte
							INNER JOIN 
								" . DB_PREFIX . "order_masters ordMas 
								ON 
								( 
									(ordMas.masterOrderID=" . (int) $order_id . " OR ordMas.parentOrderID=" . (int) $order_id . ") AND ordIte.masterOrderID = ordMas.masterOrderID 
								)
							INNER JOIN 
								" . DB_PREFIX . "products product 
								ON (product.productID = ordIte.productID)
							INNER JOIN 
								" . DB_PREFIX . "product_details productDet 
								ON (productDet.productID = product.productID 
								AND productDet.languageID=" . (int) $currentLanguageID . ")
							INNER JOIN 
								" . DB_PREFIX . "business bus 
								ON (bus.businessID = ordMas.businessID)
							INNER JOIN 
								" . DB_PREFIX . "business_details busDet 
								ON (busDet.businessID = bus.businessID 
								AND busDet.languageID=" . (int) $currentLanguageID . ")
                            GROUP BY 
								ordIte.productID";
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        } else {
            if ($order_id > 0) {
                $sql           = " SELECT 
								ordIte.*,
								sum(orderItemQuantity) as totalQuantity,
								ordMas.orderNumber
							FROM 
								" . DB_PREFIX . "order_items ordIte 
							INNER JOIN  
								" . DB_PREFIX . "order_masters ordMas 
								ON ((ordMas.masterOrderID=" . (int) $order_id . " OR ordMas.parentOrderID=" . (int) $order_id . ") AND ordIte.masterOrderID = ordMas.masterOrderID ) 
							GROUP BY 
								ordIte.productID";
                $resOrderItems = $this->ObjDatabase->readValues($sql);
                return $resOrderItems;
            }
        }
    }
    public function getMasterAndChildOrders($order_id = 0, $languageID) {
        if ($order_id > 0) {
            $sql = " SELECT
							* ";
            if ($languageID > 0) {
                $sql .= "
							, busDet.businessName
							, bus.businessPhone							";
            }
            $sql .= " FROM 
							" . DB_PREFIX . "order_masters as ordMas ";
            if ($languageID > 0) {
                $sql .= "
						LEFT JOIN 
								" . DB_PREFIX . "business AS bus 
							ON (
								ordMas.businessID = bus.businessID 
											)					
						LEFT JOIN 
							" . DB_PREFIX . "business_details busDet 
							ON( busDet.businessID=ordMas.businessID
							AND busDet.languageID=" . (int) $languageID . ")";
            }
            $sql .= " WHERE 
							ordMas.masterOrderID = '" . $order_id . "'
							OR
							ordMas.parentOrderID = '" . $order_id . "' ";
            $resOrder = $this->ObjDatabase->readValues($sql);
            return $resOrder;
        }
    }
    public function productSizeToUnit($classID) {
        return $this->ObjDatabase->getField("SELECT class FROM " . DB_PREFIX . "measurement_class WHERE classID ='" . trim($classID) . "'");
    }
    //Function to get cart item details field value
    public function getCartItemDimensions($cartID = 0, $productID = 0) {
        $sql = " SELECT 
						cartIte.itemDetails  
					FROM 
						" . DB_PREFIX . "cart_items AS cartIte 
					WHERE 1 ";
        if ($cartID > 0)
            $sql .= " AND cartID= '" . $cartID . "'";
        if ($cartID > 0)
            $sql .= " AND productID= " . (int) $productID . " LIMIT 0,1";
        $resCartItemSummary = $this->ObjDatabase->getField($sql);
        return $resCartItemSummary;
    }
    public function assignCartToUser($userID = 0) {
        $sql    = " INSERT INTO " . DB_PREFIX . "cart
								(
									userID,
									orderSubtotal,
									orderTotalAmount,
									orderQty,
									orderPromoDiscountAmount,
									orderUserCreditAmount,
									orderCommissionAmount,
									orderOtherServiceCharge,
									currencyID
								)
								VALUES
								(
									'" . $userID . "',
									'0',
									'0',
									'0',
									'0',
									'0',
									'0',
									'0',
									'0')";
        $result = $this->ObjDatabase->setQuery($sql);
        $cartID = $this->ObjDatabase->getInsertId();
        $result = $this->updateUserBilling($userID, 0, $cartID);
        $result = $this->updateUserShipping($userID, 0, $cartID);
        return $cartID;
    }
	
    public function getOrderItemQuantity($order_item_id = 0) {
        if ($order_item_id > 0) {
            $sql      = " SELECT
							orderItemQuantity
						FROM 
							" . DB_PREFIX . "order_items as ordIte  
						WHERE 
							orderItemID = " . (int) $order_item_id;
            $resOrder = $this->ObjDatabase->readValue($sql);
            //echo $sql;
            return $resOrder['orderItemQuantity'];
        } else {
            return 0;
        }
    }
    public function getOrderItemByItemID($orderID,$productID,$productOptionID) {
        if ($orderID > 0 && $productID>0 && $productOptionID>0) {
            $sql      = " SELECT extra	FROM " . DB_PREFIX . "order_items as ordIte  WHERE masterOrderID = '" . (int) $order_item_id."' AND productID='" . (int) $productID."' AND productOptionID='" . (int) $productOptionID."' ";
            $resOrder = $this->ObjDatabase->readValue($sql);
            //echo $sql;
            return $resOrder;
        } else {
            return array();
        }
    }
    //Update Coupon Usage
    public function updateCouponUsage($params = array()) {
        extract($params);
        if ($orderPromoCode != '' && $promoID > 0) {
            $this->ObjDatabase->setQuery("
				UPDATE
					" . DB_PREFIX . "cart_promo_coupons 
				SET
					timesUsed = IF(timesUsed>0,timesUsed+1,1)
				WHERE
					couponCode = '" . $orderPromoCode . "'
					AND ruleID = '" . $promoID . "'
			");
        }
    }
    // Function to get guest users purchase details
    public function getGuestUserPurchaseDetails($guestEmailID) {
        $purchaseArray = array();
        if ($guestEmailID != '') {
            $sql                    = " SELECT 
							sum(ordIte.orderItemQuantity) as orderItemCount,
							ordIte.productID 
						FROM 
							" . DB_PREFIX . "order_masters as ordMas 
						LEFT JOIN 
							" . DB_PREFIX . "order_items as ordIte 
							ON 
							(ordIte.masterOrderID=ordMas.masterOrderID) 
						WHERE 
							ordIte.orderGiveAsGift='No' 
							AND ordMas.customer_email='" . $this->escape($guestEmailID) . "'
							AND (ordMas.orderStatus = 'Pending' ||
							ordMas.orderStatus ='Process' || 
							ordMas.orderStatus = 'Completed' || ordMas.orderStatus = 'New')
						GROUP BY 
							ordIte.productID";
            $resSelfPurchaseDataSet = $this->ObjDatabase->readValuesObject($sql);
            $selfPurchaseCount      = $resSelfPurchaseDataSet->num_rows;
            if ($selfPurchaseCount > 0) {
                for ($i = 0; $i < $selfPurchaseCount; $i++) {
                    $selfPurchase                                      = $resSelfPurchaseDataSet->fetch_array(MYSQLI_ASSOC);
                    $purchaseArray[$selfPurchase['productID']]['self'] = ($selfPurchase['orderItemCount'] > 0) ? $selfPurchase['orderItemCount'] : 0;
                }
            }
            return $purchaseArray;
        }
    }
    public function removeCartUserEmail($cartID = 0) {
        $extraData = $this->getUnserializedCartData($cartID);
        unset($extraData['userCheckoutEmail']);
        $sql = " UPDATE 
						" . DB_PREFIX . "cart 
					SET 
						extra = '" . $this->escape(serialize($extraData), false, false) . "' 
					WHERE 
						cartID=" . (int) $cartID . " LIMIT 1";
        return $this->ObjDatabase->setQuery($sql);
    }
    public function getCampaignUsageCount($user_id = 0, $reg_email = '', $promoCode = '', $cart_id = 0) {
        if ($promoCode != '' && $cart_id > 0) {
            $extraData = $this->getUnserializedCartData($cart_id);
            $sql       = " SELECT
							cartID
						FROM	
							" . DB_PREFIX . "cart 
						WHERE 
							cartID!=" . (int) $cart_id . " 
							AND orderPromoCode = '" . $promoCode . "' 
							AND userID = " . (int) $user_id . " ";
            if ($user_id > 0) {
                $result = $this->ObjDatabase->readValue($sql);
                return $result['cartID'];
            } else {
                $result = $this->ObjDatabase->readValues($sql);
                if (isset($result) && count($result) > 0) {
                    foreach ($result as $key => $value) {
                        $extra = unserialize($value['extra']);
                        if ($extra['userCheckoutEmail'] == $extraData['userCheckoutEmail']) {
                            return 1;
                        }
                    }
                }
            }
            if ($user_id > 0 || $extraData['userCheckoutEmail'] != '') {
                $sql = " SELECT
							masterOrderID
						FROM	
							" . DB_PREFIX . "order_masters 
						WHERE 
							orderPromoCode = '" . $promoCode . "'
							AND userID = '" . $user_id . "'";
                if ($extraData['userCheckoutEmail'] != '') {
                    $sql .= " AND customer_email = '" . $extraData['userCheckoutEmail'] . "'";
                }
                $sql .= " LIMIT 1";
                $result = $this->ObjDatabase->readValue($sql);
                return $result['masterOrderID'];
            }
        }
        return 0;
    }
    
    //get cart promo usage details
    public function getCartPromoUsageDetails($ruleID) {
        $sql = "
				SELECT
					maxUsageCount,
					maxUsagePerPerson,
					timesUsed,
					timesInUse
				FROM
					" . DB_PREFIX . "cart_rules
				WHERE
					ruleID = '" . $ruleID . "'
					AND 
					(
						maxUsageCount > 0 
						OR maxUsagePerPerson > 0
					)";
        return $this->ObjDatabase->readValue($sql);
    }
    //update cart promo temp usage
    public function updatecartPromoTempUsage($ruleID, $action = 'increment') {
        if ($action == 'increment') //increment
            {
            $actionSql = 'timesInUse = IF(timesInUse>0,timesInUse+1,1)';
        } else //decrement
            {
            $actionSql = 'timesInUse = IF(timesInUse>0,timesInUse-1,0)';
        }
        $this->ObjDatabase->setQuery("
				UPDATE
					" . DB_PREFIX . "cart_rules 
				SET
					" . $actionSql . "
				WHERE
					ruleID IN (" . $ruleID . ")
			");
    }
    public function getgroupShippingAmount($cartID, $businessID, $methodID, $userDeliveryZoneIDs,$shippingCharge) {
        $params = array(
            'businessID' => $businessID,
            'cartID' => $cartID,
            'methodID' => $methodID,
            'userDeliveryZoneIDs' => $userDeliveryZoneIDs
        );
        $result = $this->groupShippingAmount($params);
        //$result['baseCharge'] = $shippingCharge;
        if ($result['orderItemQuantity'] > $result['maxQtyPerShipping']) {
            $extraQty       = $result['orderItemQuantity'] - $result['maxQtyPerShipping'];
            $extraCharge    = $extraQty * $result['chargePerExtraQty'];
            $shippingCharge = ($result['baseCharge']) + $result['handlingCharge'] + $extraCharge;
        } else {
            $shippingCharge = ($result['baseCharge']) + $result['handlingCharge'];
        }
        return $shippingCharge;
    }
    public function getUserDefaultShippingAddress($userID)
        {
            $sql	= " SELECT 
                                    * 
                            FROM 
                                    ".DB_PREFIX."user_shipping 
                            WHERE 
                                    userID=".(int)$userID." AND 
                                    addressPrimary='Yes' AND 
                                    addressStatus='Active'
                            LIMIT 0,1";
	    $resSelectAdrs 	= $this->ObjDatabase->readValue($sql);
            return $resSelectAdrs;
        }
        /*
         * return shipping origin and buisiness details for a product
         */
        public function getShippingOrigin($productID,$languageIDs = '1')
        {
            $sql	= " SELECT
                                            products.businessID,
                                            products.shippingOrigin
                                    FROM 
                                            ".DB_PREFIX."products as products  
                                    WHERE 
                                            productID = ".(int)$productID;
            $res	= $this->ObjDatabase->readValues($sql);

            //echo $sql;
            if($res[0]['shippingOrigin'] == 0){
                //shipping origin is admin location
               $city =  $this->getSettingValue('shipping_settings', 'global_shipping_city');
               $state =  $this->getSettingValue('shipping_settings', 'global_shipping_state');
               $country =  $this->getSettingValue('shipping_settings', 'global_shipping_country');
               $zip =  $this->getSettingValue('shipping_settings', 'global_shipping_zipcode');
               $result[0]['location'] = $city.','.$state.','.$zip.','.$country;
               $result[0]['businessID'] = $res[0]['businessID'];
               $result[0]['businessLocID'] = 0;
               $result[0]['city'] = $city;
               $result[0]['country'] = $country; //04-03-15
               $result[0]['zip'] = $zip; //04-03-15
            }else{
                //retrieve the merchant warehouse location
                //country And Zip is added at query 04-03-15 for new shiping setups
               $sql = "
                SELECT
                                busLoc.businessLocID,	
                                busLoc.businessID,
                                busDet.businessName,
                                CONCAT_WS(',',
                                busLocDet.locName,
                                IF(busLocDet.locProvince!='',					
                                busLocDet.locProvince,busLocDet.locCity),				
                                busLoc.locZip
                                )  AS location,
                                busLocDet.locName AS city,
                                busLoc.locCountryID AS country,
                                busLoc.locZip AS zip

                FROM 
                                ".DB_PREFIX."business_locations  busLoc
                LEFT JOIN 
                                ".DB_PREFIX."business_location_details busLocDet
                ON
                (
                                busLocDet.businessLocID	= busLoc.businessLocID
                                AND	busLocDet.languageID = '".$languageIDs."'										
                )
                 LEFT JOIN 
                        ".DB_PREFIX."business_details busDet
                 ON (busLoc.businessID=busDet.businessID)
                 
                WHERE  busLoc.locStatus='Active' AND busLoc.businessID='".$res[0]['businessID']."' AND busLoc.businessLocID = '".$res[0]['shippingOrigin']."'  ";		
                $result = $this->ObjDatabase->readValues($sql);
                
            }
            return $result;
            
        }
        /*
         * function to list all shipping methods for a product id
         */
        public function listAllShippingMethods($productID,$language_id='')
	{		
		$sql	= " SELECT 
                                                shiToPro.shippingServiceID, ";
                if($language_id > 0)
                    $sql	.= " 		shipLang.labelServices_name AS settingsGroupXmlLabel "; //24-04-15
                else
                    $sql	.= " 		shipMethod.settingsGroupXmlLabel ";
		$sql	.= "
					FROM
						".DB_PREFIX."shipping_to_product shiToPro
                                        LEFT JOIN 
                                            ".DB_PREFIX."shipping_methods shipMethod
                                        ON (shipMethod.settingsGroupID = shiToPro.shippingServiceID) ";
                                    
		$sql	.= "		WHERE 
						shiToPro.productID=".(int)$productID." AND shiToPro.status='A'";
		$result = $this->ObjDatabase->readValues($sql);
		return $result;
	}
        
        public function listShippingMethodsByProductID($cartID,$productID,$language_id='')
	{				
		 $sql	= " SELECT 
						shiMet.settingsGroupID,
						shiMet.isRealTimeCalculation,";
                if($language_id > 0) { //24-04-15
                    $sql	.= " 		shipLang.labelServices_name AS settingsGroupXmlLabel, "; 
                }else {
                    $sql	.= " 		shiMet.settingsGroupXmlLabel, ";
                }
		$sql	.= "
						carIte.productID,
						carIte.itemDetails,
						shiMet.settingsGroupKey,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.taxClassID,
						shiMet.settingsGroupParent,
						shiToPro.shippingtoproductID,
						shiToPro.baseCharge,
						shiToPro.maxQtyPerShipping,
						shiToPro.chargePerExtraQty,
						shiToPro.handlingCharge
					FROM
						".DB_PREFIX."cart_items carIte
					LEFT JOIN 
						".DB_PREFIX."shipping_to_product as shiToPro
						ON (shiToPro.productID=carIte.productID AND shiToPro.status='A')
					LEFT JOIN 
						".DB_PREFIX."shipping_methods shiMet
						ON(shiMet.settingsGroupParent!=0 
						AND shiMet.settingsGroupID=shiToPro.shippingServiceID)";
                                 
		$sql	.= "
					WHERE 
						carIte.cartID=".(int)$cartID." 
                                              AND 
                                                carIte.productID=".(int)$productID."
                                        GROUP BY shiMet.settingsGroupID";
									
			$sql	.= " ORDER BY
						carIte.addedTime desc,shiToPro.ModifiedDate desc";		
		$result = $this->ObjDatabase->readValues($sql);
		return $result;
	}
         // END FUNCTION
        // DELETE Shipping Method
        public function deleteShippingMethod($cartID,$productID)
	{			
		$sql	= " SELECT 
							cartIte.itemDetails,
							cartIte.cartItemID		
						FROM 
							".DB_PREFIX. "cart_items AS cartIte 
						WHERE 
							cartID= ".(int)$cartID." AND productID =".(int)$productID."";
		$resCartItemSummary 		= $this->ObjDatabase->readValues($sql);
		if(count($resCartItemSummary )>0)
		{
			foreach ($resCartItemSummary as $key => $item)
			{
				$itemDetails = unserialize($item['itemDetails']);
				unset($itemDetails['shippingMethod']['methodName']);
				unset($itemDetails['shippingMethod']['methodID']);
				unset($itemDetails['shippingMethod']['settingsGroupKey']);
				unset($itemDetails['shippingMethod']['settingsGroupParent']);
                                unset($itemDetails['shippingMethod']['shippingCharge']);
                                unset($itemDetails['shippingAmount']);
				$serlCartItemDetails	= $this->escape(serialize($itemDetails),false,false);
				$sql	= " UPDATE 
								".DB_PREFIX."cart_items 
							SET 
								itemDetails='".$serlCartItemDetails."' 
							WHERE 
								cartID=".(int)$cartID." 
								AND cartItemID=".(int)$item['cartItemID']." LIMIT 1";
				$resUpdateItem			= $this->ObjDatabase->setQuery($sql);
				
			}
		}
                
	}

       

        //06-03-15 GET Cart Item Id From Cart Id and Product Id
        public function getCartItemId($cartID,$productID) {
            
            $sql="SELECT 
                    `cartItemID` 
                FROM 
                    `".DB_PREFIX."cart_items` 
                WHERE 
                    `cartID`='".$cartID."' AND `productID`='".$productID."'";
            $result = $this->ObjDatabase->readValue($sql);
            return $result['cartItemID'];
        }
        // Function to update the cart billing & shipping address for onestepcheckout
	public function updateUserCartAddressOnestep($userID=0,$cartID=0,$arrAddress,$arrAddress1='',$adrsType)
	{ 
		$extraData 				= $this->getUnserializedCartData($cartID);
		if($adrsType == 'Billing'){
			$extraData['userBillingAddress']	= $arrAddress;
		}else if($adrsType == 'Shipping'){
			$extraData['userShippingAddress']	= $arrAddress;			
		}	
		$sql	= " UPDATE 
						".DB_PREFIX."cart 
					SET 
						extra = '".$this->escape(serialize($extraData),false,false)."' 
					WHERE 
						cartID=".(int)$cartID." LIMIT 1";
                
		$resUpdateCartAddress  	= $this->ObjDatabase->setQuery($sql);
		
		if($adrsType == 'Billing'){
			$this->taxStateId   = ($arrAddress['billingState']>0) ? $arrAddress['billingState'] : 0;	
			$this->taxCountryId = $arrAddress['billingCountry'];
		}
	}
        // Function to get complete cart details on 8-12-2014
	public function getCartDetailsAll($languageIDs=array(),$cartID=0, $userID=0,$item='all')
	{
             
                $languageID					= $languageIDs['Default'];
		$currentLanguageID 			= $languageIDs['Current'];
//               $defaultLanguageID		= 	$languageIDs['Default'];
//		$currentLanguageID		= 	$languageIDs['Current'];
		$resCartSummary		=	array();
		$resCartSummary['items']	=	array();
		if($cartID >0 || $userID >0)
		{
			$sql	= " SELECT 
							cart.*,
							usr.userFirstName,
							usr.userLastName,
							usr.userEmail 
						FROM 
							".DB_PREFIX."cart AS cart 
						LEFT JOIN 
							".DB_PREFIX."users usr 
						ON (usr.userID = cart.userID)"; 
			$sql	.= ($cartID > 0) ? " WHERE cartID= ".(int)$cartID."" : 
					"	WHERE cart.userID= ".(int)$userID." LIMIT 0,1";
			$resCartSummary 		= $this->ObjDatabase->readValue($sql,MYSQLI_ASSOC);
			if(!empty($resCartSummary))
			{
				$sql	= " SELECT 
								cartIte.*,
								product.productTippedDate,
								product.productMaxGiftBuy,
								cartIte.businessID,
								product.productDispatchTime,
								product.brandID,
                                                                product.isProductDeal,
                                                                product.shippingOrigin,
                                                                product.freeProductsCount,
                                                                busdt.businessName
							FROM 
								".DB_PREFIX. "cart_items AS cartIte 
							LEFT JOIN 
								".DB_PREFIX."products product 
							ON 
								(product.productID = cartIte.productID)
                                                       INNER JOIN
                                                       ".DB_PREFIX."business bus                                                                                        ON
                                                           (cartIte.businessID=bus.businessID) 
                                                      INNER JOIN 
                                                       ".DB_PREFIX."business_details AS busdt 
                                                       ON (cartIte.businessID=busdt.businessID AND busdt.languageID='".$currentLanguageID."')
							WHERE 
								cartID= '".$resCartSummary['cartID']."' ";
				if($item=='paid')
				{
					$sql	.= " AND freeProduct='No' ";
				}
				$sql	.=" ORDER BY 
								cartIte.businessID ASC,cartIte.addedTime asc";
                               // echo $sql;
                              //  exit;
                                
                               
				$resCartItemSummary	= $this->ObjDatabase->readValues($sql,MYSQLI_ASSOC);
				$resCartSummary['items']	= $resCartItemSummary;
			}
			
		}
                
		return $resCartSummary;
	}
         public function getUserShipping($userID=0,$addressID=0,$cartID=0)
	{
            $sql	= " SELECT 
							usrShi.shippingFname,
							usrShi.shippingLname,
							usrShi.shippingAddress1,
							usrShi.shippingAddress2,
							usrShi.shippingCity,
							usrShi.shippingProvince,
							usrShi.shippingZip,
							usrShi.shippingStateID,
							usrShi.shippingCountryID 
						FROM 
							".DB_PREFIX."user_shipping as usrShi  
						WHERE 
							usrShi.userID = ".(int)$userID." 
							AND usrShi.userShippingID='".$addressID."' 
							LIMIT 0,1";
            $resShippingAddress		= $this->ObjDatabase->readValue($sql,MYSQLI_ASSOC);
            return $resShippingAddress;
        }
        public function updateCartItemsCODFee($cartID,$cartItemID,$serializedData) {
           // $serializedData = $this->escape(serialize($serializedData), false, false);        

                $sqlUpdate= "UPDATE ".DB_PREFIX."cart_items SET itemDetails='".$this->escape(serialize($serializedData), false, false)."' WHERE cartItemID='".$cartItemID."' and cartID='".$cartID."'";	  
                $resUpdateOrder=   $this->ObjDatabase->setQuery($sqlUpdate);        
                return true; 
        }
        public function updateCODFee($cartID,$fee) {
                $sql="	UPDATE ".DB_PREFIX."cart SET orderConvenientFee='".$fee."' WHERE ";
                $sql .= " cartID='".$cartID."'";        
                $resUpdateOrder=   $this->ObjDatabase->setQuery($sql);
                return true; 
        }
	public function getProductIDByOption($productOptionID) {
            $sql        = "select productID from ".DB_PREFIX."product_options where productOptionID='".$productOptionID."'";
            $productID  = $this->ObjDatabase->getField($sql);
            return $productID; 

        }
        public function checkCartExistsByProductID($cartID='',$productID='',$productOptionID='',$freeBaseProductID='') {
            $sql        = "select * from ".DB_PREFIX."cart_items where productID='".(int)$productID."' and cartID='".(int)$cartID."'  and freeProduct='Yes' and freeBaseProductID='".(int)$freeBaseProductID."'";
            if($productOptionID>0) {
                $sql    .= " and productOptionID='".(int)$productOptionID."'";
            }
            
            $cartDet    = $this->ObjDatabase->readValue($sql);
            return $cartDet; 
        }
        public function getTotalFreeCntByID($cartID='',$freeBaseProductID='',$orderID='',$orderItemID='') {
            if($orderID>0 && $orderItemID>0) {
                $sql        = "select sum(orderItemQuantity) as totCnt from ".DB_PREFIX."order_items where masterOrderID='".(int)$orderID."' and freeProduct='Yes' and freeBaseProductID='".(int)$freeBaseProductID."' order by freeBaseProductID";
            } else {
                $sql        = "select sum(orderItemQuantity) as totCnt from ".DB_PREFIX."cart_items where cartID='".(int)$cartID."' and freeProduct='Yes' and freeBaseProductID='".(int)$freeBaseProductID."' order by freeBaseProductID";
            }
            $cartDet    = $this->ObjDatabase->readValue($sql);
            return !empty($cartDet['totCnt'])?$cartDet['totCnt']:0; 
        }
        public function getCartFreeProductsByID($cartID='',$freeBaseProductID='') {
            $sql        = "select * from ".DB_PREFIX."cart_items where cartID='".(int)$cartID."' and freeProduct='Yes' and freeBaseProductID>0 and freeBaseProductID='".(int)$freeBaseProductID."' order by cartItemID asc";
            $cartDet    = $this->ObjDatabase->readValues($sql);
            return $cartDet; 
        }
        public function getTotalQtyCntByID($cartID='',$productID='',$orderID='',$orderItemID='') {
            
            if($orderID>0 && $orderItemID>0) {
               $sql        = "select sum(orderItemQuantity) as totCnt from ".DB_PREFIX."order_items where masterOrderID='".(int)$orderID."' and freeProduct='No' and freeBaseProductID<=0 and productID='".$productID."' and orderItemID='".$orderItemID."' group by orderItemID";
               
            } else {
                $sql        = "select sum(orderItemQuantity) as totCnt from ".DB_PREFIX."cart_items where cartID='".(int)$cartID."' and freeProduct='No' and freeBaseProductID<=0 and productID='".$productID."' group by productID";
            }
            $cartDet    = $this->ObjDatabase->readValue($sql);
            return !empty($cartDet['totCnt'])?$cartDet['totCnt']:0; 
        }
        public function deleteCartItemFreeGif($cartID='',$freeBaseProductID='') {
            $sql        = "Delete from ".DB_PREFIX."cart_items where cartID='".(int)$cartID."' and freeProduct='Yes' and freeBaseProductID='".(int)$freeBaseProductID."'";
            $resDelete  = $this->ObjDatabase->setQuery($sql);
            return true; 
        }
        public function getUserGroupID($userID='') {
            if($userID>0) {
                $sql            = "select userGroupID from ".DB_PREFIX."users where userID='".$userID."'";
                $userGroupID    = $this->ObjDatabase->getField($sql);
                return $userGroupID; 
            } else {
                return 0; 
            }
        }
	public function getBusinessShippingCharge($productID='') {
		 $sql    = "
			SELECT
					shippingCharge
			FROM
					`" . DB_PREFIX . "business` bus
			LEFT JOIN
					`" . DB_PREFIX . "products` products
			ON(bus.businessID=products.businessID)
			WHERE 	products.`productID` = '" . $productID . "' ";
        $result = $this->ObjDatabase->readValueSlave($sql);
        return $result['shippingCharge'];
}
	public function getCategoryShippingCharge($productID='') {
		 $sql    = "
			SELECT
					shippingCharge
			FROM
					`" . DB_PREFIX . "product_categories` prodcat
			LEFT JOIN
					`" . DB_PREFIX . "product_to_category` prodToCat
			ON(prodcat.productCategoryID=prodToCat.productCategoryID)
			WHERE 	prodToCat.`productID` = '" . $productID . "' AND prodToCat.`productCategoryID` != '0'";
        $result = $this->ObjDatabase->readValueSlave($sql);
        return $result['shippingCharge'];
    }
	public function getBrandShippingCharge($productID='') {
		 $sql    = "
			SELECT
					shippingCharge
			FROM
					`" . DB_PREFIX . "brands` brand
			LEFT JOIN
					`" . DB_PREFIX . "products` products
			ON(brand.brandID=products.brandID)
			WHERE 	products.`productID` = '" . $productID . "' ";
        $result = $this->ObjDatabase->readValueSlave($sql);
        return $result['shippingCharge'];
    }
    public function getFreeProductsSubTotal($orderID) {        
        $sql    = "SELECT sum(originalSubtotal) as originalSubtotal FROM " . DB_PREFIX . "order_items where masterOrderID='".$orderID."' and freeProduct='Yes' and freeBaseProductID>0 group by masterOrderID";
        $result = $this->ObjDatabase->readValue($sql);
        return !empty($result)?$result['originalSubtotal']:0;
    }
    public function getFreeProductsByOrderItemID($orderItemID) {        
        $sql    = "SELECT ordItems.* FROM " . DB_PREFIX . "order_items ordItems JOIN " . DB_PREFIX . "order_items ordItem ON (ordItems.freeBaseProductID=ordItem.productID AND ordItems.masterOrderID=ordItem.masterOrderID)  where ordItems.freeProduct='Yes' AND ordItems.freeBaseProductID>0 AND ordItem.orderItemID='".$orderItemID."'";       
        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    }
      public function cartItemCheck($post_data)
    {
        
        $sql="  SELECT items.*
                FROM ".DB_PREFIX."cart_items as items 
                LEFT join ".DB_PREFIX."cart as cart on (cart.cartID=items.cartID)
                WHERE cart.cartID='".$post_data['cartID']."'  AND items.productID='".$post_data['productID']."' ";
              
        if($post_data['userID'] > 0){
                $sql.="    AND  cart.userID='".$post_data['userID']."'  ";
            }
        
            if($post_data['productOptionID']){
                $sql.="    AND items.productOptionID='".$post_data['productOptionID']."' ";
            }
            if($post_data['combinationHash']){
                $sql.="    AND  items.combinationHash='".$post_data['combinationHash']."' ";
            }
        
            return $result = $this->ObjDatabase->readValue($sql);
        
    } 
    public function listPickupLocations($languageIDs, $productID){
        $pickupLocations   =  $this->getBusinessLocations($languageIDs, $productID);
        return $pickupLocations;
    }  
    public function getBusinessLocations($languageIDs, $productID,$businessLocID=0) {
        $sql = " SELECT 
                                        busLoc.businessLocID,
                                        CONCAT_WS(',',busLocDet.locName, 
                                        NULLIF(busLocDet.locAddress1,''),
                                        NULLIF(busLocDet.locAddress2,''),
                                        NULLIF(staDet.stateName,''),
                                        NULLIF(busLocDet.locCity,''),
                                        NULLIF(busLocDet.locProvince,''),
                                        NULLIF(busLoc.locZip,''),
                                        NULLIF(cntryDet.countryName,'')) AS locAddress ";
        $sql .= " FROM " . DB_PREFIX . "product_to_business_locations productToBusLoc ";

        $sql .= " 	
                                LEFT JOIN
                                        " . DB_PREFIX . "business_locations  busLoc 
                                        ON (busLoc.businessLocID=productToBusLoc.businessLocID)
                                LEFT JOIN " . DB_PREFIX . "business_location_details AS busLocDet
                                        ON( busLocDet.businessLocID = busLoc.businessLocID";

        if ($languageIDs) {
            $currentLanguageID = $languageIDs['Current'];
            $defaultLanguageID = $languageIDs['Default'];
            $sql .= "  AND 
                                            busLocDet.languageID = '" . $currentLanguageID . "'";
        }
        $sql .=" ) 
                                    LEFT JOIN 
                                            " . DB_PREFIX . "country_details cntryDet 
                                               ON ( cntryDet.countryID=busLoc.locCountryID ";
        if ($languageIDs) {
            $sql .= " AND cntryDet.languageID = '" . $currentLanguageID . "' ";
        }
        $sql .=" ) 
                                    LEFT JOIN 
                                            " . DB_PREFIX . "state_details staDet 
                                              ON  ( staDet.stateID=busLoc.locStateID ";
        if ($languageIDs) {
            $sql .= " AND staDet.languageID = '" . $currentLanguageID . "' ";
        }
        $sql .=" ) 
                                    WHERE ";

        $sql .= "productToBusLoc.productID= '" . $productID . "'";
        $sql .= "  AND busLoc.locStatus!='Deleted' ";
        if($businessLocID>0){
            $sql .= "AND busLoc.businessLocID= '" . $businessLocID . "'";
        }

        $result = $this->ObjDatabase->readValues($sql);
        return $result;
    } 
     public function  getMobileOrderIDFromCartID($cartID){
            if($cartID>0) {
                $sql            = "select mobileappOrderID from ".DB_PREFIX."cart where cartID='".$cartID."'";
                $userGroupID    = $this->ObjDatabase->getField($sql);
                return $userGroupID; 
            } else {
                return 0; 
            }
     }
     public function  linkCartToOrder($cartID,$orderID=0){
            if($cartID > 0){
                $sql                                  = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							mobileappOrderID = '" . $orderID . "'";
       
                $sql .= " WHERE cartID=" . (int) $cartID . " LIMIT 1";
                $result = $this->ObjDatabase->setQuery($sql);
                return $result;
            }
            else{
                return 0;
            }
        }
    public function updatePaymentSettingsID($cartID,$paymentID) {
           $sql	= " UPDATE ".DB_PREFIX."cart set paymentSettingsGroupID='$paymentID' where cartID='".$cartID."'";
           $resUpdate  = $this->ObjDatabase->setQuery($sql);	
           return true;
    }  
	public function getSelfPurchaseCount($userID='',$productID='') {
		if ($userID > 0) {
                $sql                        = " SELECT 
								sum(ordIte.orderItemQuantity) as orderItemCount 
							FROM 
								" . DB_PREFIX . "order_masters as ordMas 
							LEFT JOIN 
								" . DB_PREFIX . "order_items as ordIte 
								ON 
								(ordIte.masterOrderID=ordMas.masterOrderID) 
							WHERE 
								ordMas.userID > 0 
								AND ordIte.orderGiveAsGift='No' 
								AND ordMas.userID=" . (int) $userID . " 
								AND (ordMas.orderStatus = 'Pending' || 
								ordMas.orderStatus = 'Process' || 
								ordMas.orderStatus = 'Completed' || ordMas.orderStatus = 'New') 
								AND ordIte.productID=" . (int) $productID . " LIMIT 0,1";
                $resSelfPurchase            = $this->ObjDatabase->readValue($sql, MYSQL_ASSOC);
                return $resSelfPurchase['orderItemCount'];
            }
	}
        public function updateCartDeviceInfo($deviceToken='',$deviceType='',$cartID='') {
            if($deviceToken!='' && $deviceType!='' && $cartID!='') {
                $sql = "update " . DB_PREFIX . "cart set  deviceToken='".$deviceToken."' , deviceType='".$deviceType."' where cartID='".$cartID."'";
                
				$this->ObjDatabase->setQuery($sql);                
            }
            return true;
        }
        public function updateCartCurrency($cartID='',$currencyID='') {
            if($cartID!='' && $currencyID!='') {
                $sql    =   "UPDATE " . DB_PREFIX . "cart set currencyID='".$currencyID."' where cartID='".$cartID."'";
                $this->ObjDatabase->setQuery($sql);
                return true;
            }
        } 
		
    
    public function checkShipmentCountOfCart($cartID, $settingsGroupID = 0, $languageIDs = array(), $group_shipping_cost = 'No', $userDeliveryZoneIDs = array(),$shipping_cost_global='') {
        $sameshipmentcount = 'Yes';
        $currentLanguageID = isset($languageIDs['Current']) ? $languageIDs['Current'] : '1';
        $sql               = " SELECT 
		";
        
        $sql .= "
						COUNT(shiMet.settingsGroupID) AS shipmentCount,
						carIte.productOptionID,
						carIte.productID
		";
        $sql .= "			FROM
						" . DB_PREFIX . "cart_items carIte
					INNER JOIN
						" . DB_PREFIX . "products product
							ON	(
							carIte.productID = product.productID
							)
					INNER JOIN
						" . DB_PREFIX . "product_options as productOpt
							ON(
							productOpt.productOptionID= carIte.productOptionID
							
							)
					INNER JOIN
					" . DB_PREFIX . "product_option_details as productOptDet
						ON(
						productOptDet.productOptionID= productOpt.productOptionID
						AND
						languageID ='" . $currentLanguageID . "'
						)		
					LEFT JOIN 
						" . DB_PREFIX . "shipping_to_product as shiToPro
							ON 	(
								shiToPro.productID=carIte.productID 
								AND 
								shiToPro.status='A'
							)
					LEFT JOIN 
						" . DB_PREFIX . "shipping_methods shiMet
							ON	(
								shiMet.settingsGroupParent!=0 
								AND 
								shiMet.settingsGroupID=shiToPro.shippingServiceID
							)
					WHERE 
						carIte.cartID=" . (int) $cartID . " and carIte.freeBaseProductID<=0";
        if ($settingsGroupID > 0) {
            $sql .= " AND shiMet.settingsGroupID=" . (int) $settingsGroupID . "";
        }
        if (isset($userDeliveryZoneIDs) && !empty($userDeliveryZoneIDs)) {
            $sql .= "
                        AND
                        shippingtoproductID IN 
                                (
                                        SELECT 
                                                shippingtoproductID 
                                        FROM 
                                                " . DB_PREFIX . "product_to_shipping_deliveryzone 
                                        WHERE 
                                                deliveryZoneID IN (
                                                        '" . implode("','", $userDeliveryZoneIDs) . "'
                                                )
                                )
                        ";
        }
        
        $sql .= " GROUP BY carIte.cartItemID,shiMet.settingsGroupID ";
        
       
        
        $sql .= " 
                ORDER BY
                        shiToPro.baseCharge desc,
                        carIte.businessID,
                        carIte.addedTime desc,shiToPro.ModifiedDate desc

                        ";
        //echo $sql;
        $this->ObjDatabase->setQuery("SET @@session.group_concat_max_len= 50000;");
        $result = $this->ObjDatabase->readValues($sql);
        $shipmentcount  =   0;
        for($i=0;$i<count($result);$i++){
            if($shipmentcount == 0)
                $shipmentcount  = $result[$i]['shipmentCount'];
            else{
                if($shipmentcount != $result[$i]['shipmentCount']){
                    $sameshipmentcount = 'No';
                    return $sameshipmentcount;
                }
            }
        }
        return $sameshipmentcount;
    }
    
    
    public function checkProductCountOfCart($cartID, $settingsGroupID = 0, $languageIDs = array(), $group_shipping_cost = 'No', $userDeliveryZoneIDs = array(),$shipping_cost_global='') {
        $sameshipmentcount = 'Yes';
        $currentLanguageID = isset($languageIDs['Current']) ? $languageIDs['Current'] : '1';
        $sql               = " SELECT 
		";
        
        $sql .= "
						shiMet.settingsGroupID,
						COUNT(carIte.productOptionID) AS distinctItem
		";
        $sql .= "			FROM
						" . DB_PREFIX . "cart_items carIte
					INNER JOIN
						" . DB_PREFIX . "products product
							ON	(
							carIte.productID = product.productID
							)
					INNER JOIN
						" . DB_PREFIX . "product_options as productOpt
							ON(
							productOpt.productOptionID= carIte.productOptionID
							
							)
					INNER JOIN
					" . DB_PREFIX . "product_option_details as productOptDet
						ON(
						productOptDet.productOptionID= productOpt.productOptionID
						AND
						languageID ='" . $currentLanguageID . "'
						)		
					LEFT JOIN 
						" . DB_PREFIX . "shipping_to_product as shiToPro
							ON 	(
								shiToPro.productID=carIte.productID 
								AND 
								shiToPro.status='A'
							)
					LEFT JOIN 
						" . DB_PREFIX . "shipping_methods shiMet
							ON	(
								shiMet.settingsGroupParent!=0 
								AND 
								shiMet.settingsGroupID=shiToPro.shippingServiceID
							)
					WHERE 
						carIte.cartID=" . (int) $cartID . " and carIte.freeBaseProductID<=0";
        if ($settingsGroupID > 0) {
            $sql .= " AND shiMet.settingsGroupID=" . (int) $settingsGroupID . "";
        }
        if (isset($userDeliveryZoneIDs) && !empty($userDeliveryZoneIDs)) {
            $sql .= "
                        AND
                        shippingtoproductID IN 
                                (
                                        SELECT 
                                                shippingtoproductID 
                                        FROM 
                                                " . DB_PREFIX . "product_to_shipping_deliveryzone 
                                        WHERE 
                                                deliveryZoneID IN (
                                                        '" . implode("','", $userDeliveryZoneIDs) . "'
                                                )
                                )
                        ";
        }
        
        $sql .= " GROUP BY shiMet.settingsGroupID ";
        
       
        
        $sql .= " 
                ORDER BY
                        distinctItem desc,
                        carIte.businessID,
                        carIte.addedTime desc,shiToPro.ModifiedDate desc

                        ";
        //echo $sql;
        $this->ObjDatabase->setQuery("SET @@session.group_concat_max_len= 50000;");
        $result = $this->ObjDatabase->readValues($sql);
        $sameshipmentcount  =   'Yes';
        $commonShipments  =  array();
        $resCartItems   =   $this->getCartItems((int)$cartID);
        for($i=0;$i<count($result);$i++){
            if(count($resCartItems) != $result[$i]['distinctItem']){
                $sameshipmentcount = 'No';
                
            }else{
                $commonShipments[] = $result[$i]['settingsGroupID'];
            }
        }
        //echo $sameshipmentcount;
//        if(count($commonShipments) == count($resCartItems))
//            $sameshipmentcount = 'Yes';
//        else
//            $sameshipmentcount = 'No';
        //print_r($commonShipments);
        return array($sameshipmentcount,$commonShipments);
    }
    
    public function getCartItemBusinessID($cartItemID){
            $sqlSelect          =   "SELECT businessID FROM ".DB_PREFIX."cart_items WHERE cartItemID = '".$cartItemID."'";
            $result             =   $this->ObjDatabase->getField($sqlSelect);
            return $result;
        }
    public function updateShippingHistory($newOrderID, $orderID, $oldOrderItemArray, $newCreatedOrderItemArray) {
        $ObjOrder = new OrderModel();
        if (count($oldOrderItemArray) > 0) {
            foreach ($oldOrderItemArray as $key => $value) {
                $sql    = " SELECT 
							*
						FROM 
							" . DB_PREFIX . "shipment_items AS busShiHis	
						WHERE busShiHis.orderItemID='" . $value . "'";
                $result = $this->ObjDatabase->readValues($sql);
                if (count($result) > 0) {
                    foreach ($result as $value1) {
                        $sql             = " SELECT 
									*
								FROM 
									" . DB_PREFIX . "shipments AS shipments	
								WHERE shipments.shippingID='" . $value1['shippingID'] . "'";
                        $resultShipments = $this->ObjDatabase->readValue($sql);
                        if (isset($shipmentArray[$resultShipments['shippingID']]) && $shipmentArray[$resultShipments['shippingID']] > 0) {
                            $shippingID = $resultShipments['shippingID'];
                        } else {
                            $POST['comment'] = $resultShipments['comment'];
                            if ($resultShipments['notifyCustomer'] == 'Yes') {
                                $POST['notify'] = $resultShipments['notifyCustomer'];
                            } else {
                                unset($POST['notify']);
                            }
                            $POST['masterOrderID']                         = $newOrderID;
                            $POST['shipmentStatus']                        = $resultShipments['shippingStatus'];
                            $POST['trackingNumber']                        = $resultShipments['trackingNumber'];
                            $POST['shipmentCarrier']                       = $resultShipments['carrier'];
                            $POST['createdBy']                             = ($resultShipments['createdBy'] == 'admin') ? 'admin' : '';
                            $shippingID                                    = $ObjOrder->saveShipMent($POST);
                            $shipmentArray[$resultShipments['shippingID']] = $shippingID;
                        }
                        $newOrderItemID                    = $newCreatedOrderItemArray[$key];
                        $shipmentItems['ShipmentID']       = $shippingID;
                        $shipmentItems['shippingQuantity'] = $value1['quantity'];
                        $ObjOrder->saveShippingHistory($shipmentItems, $newOrderItemID, 'admin');
                    }
                }
            }
        }
    }
    
    public function updateDownloadProductInfoToCart($params,$cartID){
        $sql = " SELECT extra FROM " . DB_PREFIX . "cart WHERE cartID = '".$cartID."' ";
        $resSelectCart = $this->ObjDatabase->readValue($sql);
        $arrExtraData  = unserialize($resSelectCart['extra']);
        $params['userFirstName'] = $this->encryptDecrypt("encrypt",$params['subtitle']."".$params['userFirstName']);
        $params['userLastName']  = $this->encryptDecrypt("encrypt",$params['userLastName']);      
        $params['userEmail']     = $this->encryptDecrypt("encrypt",$params['userEmail']);      
        $params['userPhone']     = $this->encryptDecrypt("encrypt",$params['userPhone']);      
        $arrExtraData['informationDownload']    =   $params;
         $sql                      = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							extra='" . serialize($arrExtraData) . "' 
						WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateItems           = $this->ObjDatabase->setQuery($sql);
        
        $sql = " SELECT cart.extra,cart_items.itemDetails,cart_items.productID FROM " . DB_PREFIX . "cart cart "
                . " LEFT JOIN dp_cart_items cart_items ON ( cart_items.cartID = cart.cartID ) "
                . "WHERE cart.cartID = '".$cartID."' ";
        $resDownloadDataCart = $this->ObjDatabase->readValues($sql);
        $sql = " INSERT INTO " . DB_PREFIX . "download_product_info (productID,itemDetails,extra,createdDate,brandID) VALUES ( '".$resDownloadDataCart[0]['productID']."','".$this->escape($resDownloadDataCart[0]['itemDetails'])."','".$this->escape($resDownloadDataCart[0]['extra'])."',NOW(),'".$params['brandID']."') ";
        $resDownloadInfo           = $this->ObjDatabase->setQuery($sql);
        return $downloadID                               = $this->ObjDatabase->getInsertId();
    }
    
    public function updateDownloadProductInfoOTP($pincode,$cartID){
        $sql = " SELECT extra FROM " . DB_PREFIX . "cart WHERE cartID = '".$cartID."' ";
        $resSelectCart = $this->ObjDatabase->readValue($sql);
        $arrExtraData  = unserialize($resSelectCart['extra']);
        $arrExtraData['informationDownloadOTP']    =   $pincode;
         $sql                      = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							extra='" . serialize($arrExtraData) . "' 
						WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateItems           = $this->ObjDatabase->setQuery($sql);
        
    }
    
    public function updateDownloadProductInfoCallbackOTP($pincode,$cartID){
        $sql = " SELECT extra FROM " . DB_PREFIX . "cart WHERE cartID = '".$cartID."' ";
        $resSelectCart = $this->ObjDatabase->readValue($sql);
        $arrExtraData  = unserialize($resSelectCart['extra']);
        $arrExtraData['callBackOTP']    =   $pincode;
         $sql                      = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							extra='" . serialize($arrExtraData) . "' 
						WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateItems           = $this->ObjDatabase->setQuery($sql);
        
    }
    
    public function saveCallbackdata($postdata,$itemdetails,$productID,$brandID=''){
        $sql                                  = " INSERT INTO " . DB_PREFIX . "callback_requests
								(
									userFirstName,
                                                                        subtitle,
									userLastName,
									userEmail,
									userPhone,
									userComment,
									createdDate,
									status,
                                                                        itemDetails,
                                                                        productID,
                                                                        brandID
								)
								VALUES
								(
									'" . $this->encryptDecrypt("encrypt",$postdata['userFirstName']) . "',
                                                                        '" . $postdata['subtitle'] . "',   
									'" . $this->encryptDecrypt("encrypt",$postdata['userLastName']) . "',
									'" . $this->encryptDecrypt("encrypt",$postdata['userEmail']) . "',
									'" . $this->encryptDecrypt("encrypt","+".$postdata['userPhone']) . "',
									'" . $postdata['comment'] . "',
									NOW(),
									'A',
                                                                        '" . $this->escape($itemdetails) . "',"
                                                                     . "'" . $productID . "','".$brandID."')";
        $result                               = $this->ObjDatabase->setQuery($sql);
    }
    
    public function updateDownloadProductInfoOTPPay($pincode,$cartID){
        $sql = " SELECT extra FROM " . DB_PREFIX . "cart WHERE cartID = '".$cartID."' ";
        $resSelectCart = $this->ObjDatabase->readValue($sql);
        $arrExtraData  = unserialize($resSelectCart['extra']);
        $arrExtraData['paymentOTP']    =   $pincode;
         $sql                      = " UPDATE 
							" . DB_PREFIX . "cart 
						SET 
							extra='" . serialize($arrExtraData) . "' 
						WHERE 
							cartID=" . (int) $cartID . " LIMIT 1";
            $resUpdateItems           = $this->ObjDatabase->setQuery($sql);
        
    }
    
    public function getBroucherSummary($qrID,$languageIDs){
        $sql = " SELECT *,pdtDet.productTitle FROM " . DB_PREFIX . "download_product_info downloadInfo "
                . " LEFT JOIN " . DB_PREFIX . "product_details pdtDet ON (pdtDet.productID = downloadInfo.productID AND pdtDet.languageID = '".$languageIDs['Current']."' ) " 
                . "WHERE downloadInfo.downloadPdtID = '".(int)$qrID."' ";
        return $resDownloadDataCart = $this->ObjDatabase->readValue($sql);
    }
    public function updateOrderEmail($email='',$name='',$phone='',$orderID='') {
        if($orderID>0) {
            $sqlUpdate = "UPDATE " . DB_PREFIX . "order_masters set customer_email='".$this->encryptDecrypt("encrypt",$email)."',billingPhone='".$this->encryptDecrypt("encrypt",$phone)."',billingFirstName='".$this->encryptDecrypt("encrypt",$name)."' where masterOrderID='".$orderID."'";
            $this->ObjDatabase->setQuery($sqlUpdate);
        }
        return true;
    }
	    public function listDownloadProductInfo($params) {
        extract($params);
        $languageIDs            = isset($languageIDs) ? $languageIDs : array();
        $languageIDs['Current'] = isset($languageIDs['Current']) ? $languageIDs['Current'] : 0;
        $languageIDs['Default'] = isset($languageIDs['Default']) ? $languageIDs['Default'] : 0;
        $limitFrom              = isset($limitFrom) ? $limitFrom : 0;
        $limitTo                = isset($limitTo) ? $limitTo : '';
        $currentLanguageID      = $languageIDs['Current'];
        $sql      = " SELECT 
						SQL_CALC_FOUND_ROWS 
						downloadPtdInfo.*,
						optDet.productOptionName,
						brandDet.brandName						
                                                    FROM 
                                                            " . DB_PREFIX . "download_product_info downloadPtdInfo
                                                    LEFT JOIN 
                                                            " . DB_PREFIX . "products product 
                                                            ON product.productID=downloadPtdInfo.productID                                                     
                                                    LEFT JOIN 
                                                            " . DB_PREFIX . "product_options productOpt 
                                                            ON productOpt.productID=product.productID	
                                                    LEFT JOIN 
                                                            " . DB_PREFIX . "product_option_details optDet 
                                                            ON (optDet.productOptionID=productOpt.productOptionID
                                                            AND optDet.languageID = '" . $currentLanguageID . "')
													LEFT JOIN 
															" . DB_PREFIX . "brands AS brand
																ON	(
																	brand.brandID = downloadPtdInfo.brandID
																)                     
																			LEFT JOIN 
															" . DB_PREFIX . "brand_details AS brandDet
																ON	(
																	brandDet.brandID = brand.brandID
																	AND
																	brandDet.languageID = '" . $languageIDs['Current'] . "'
																)
                                                    where 1 ";
        
            
        if ($productKey != '') {
            $sql .= " AND optDet.productOptionName LIKE '%" . $this->escape($productKey) . "%' ";
        }
		if ($brandID != '') {
            $sql .= " AND downloadPtdInfo.brandID = '" . $brandID . "' ";
        }		
		$sql .= " ORDER BY downloadPtdInfo.downloadPdtID ";
		$sql .= "  DESC";
        if ($limitTo) {
            $sql .= " LIMIT  " . $limitFrom . "," . $limitTo . "";
        }

        if ($export) {
            return $this->ObjDatabase->readValuesObject($sql, MYSQLI_ASSOC);
        }
        return $this->ObjDatabase->readValues($sql, MYSQLI_ASSOC);
    }
}
