<?php

require_once 'newedge/classes/NE_View.php';
require_once 'newedge/classes/NE_Network.php';
require_once 'modules/admin/models/Package.php';
require_once 'modules/clients/models/ObjectCustomFields.php';
require_once 'modules/admin/models/PackageAddonGateway.php';
require_once 'modules/admin/models/Countries.php';
require_once 'modules/billing/models/Coupon.php';
require_once "modules/admin/models/ActiveOrderGateway.php";

/**
* @package Admin
*/
class SignupView extends NE_View
{
    var $showHeader     = true;
    var $jsLibs = array(
        'javascript/datefields.js',
        'javascript/signup_checkout.js',
        'templates/admin/views/clients/profile/VAT.js',
        'javascript/common.js'
    );
    var $cssPages = array(
    	'templates/default/style/signup.css'
    );

    // Can probably remove some of these once we're done
    var $clienttype;
    var $domain;
    var $package;
    var $transfer;
    var $paymenttype;
    var $paymentterm;
    var $currency;
    var $selectedCurrency;
    var $couponcode;
    var $ccnumber;
    var $ccmonth;
    var $ccyear;
    var $member_email;
    var $member_password;
    var $new_password;
    var $new_password_confirm;
    var $domain_username;
    var $domain_password;

    // new vars
    var $runningTotal = array();


    /**
    * @todo only load necessary templates, from each view
    */
    function initialize()
    {
        // If no allow direct link, then redirect to signup
        if(isset($_GET['package']) && $_GET['package'] > 0){
            if(!$this->getAllowDirectLink($_GET['package'])){
                NE_Lib::redirectPage('signup.php');
            }
        }


        // Escape some generic vars to avoid doing it on every page
        if(isset($_REQUEST['product']) && !is_numeric($_REQUEST['product'])) {
            $_REQUEST['product'] = null;
        }

        if(isset($_REQUEST['productGroup']) && !is_numeric($_REQUEST['productGroup'])) {
            $_REQUEST['productGroup'] = null;
        }        
		
        if(isset($_REQUEST['priceTerm']) && !is_numeric($_REQUEST['priceTerm'])) {
            $_REQUEST['priceTerm'] = null;
        }

        $this->db->escape_string(@$_REQUEST['formId']);
        
        if (isset($_REQUEST['clienttype'])) {
            $this->clienttype = htmlspecialchars($_REQUEST['clienttype']);
            
            if($this->clienttype != ""){
            
                $query = "SELECT id FROM promotion WHERE id=?";
                $result = $this->db->query($query, $this->clienttype);
                list($myPromotionId) = $result->fetch();
                if($myPromotionId == NULL){
                    NE_Lib::redirectPage('signup.php');
                }
            }
        } else {
            $this->clienttype = "";
        }

        if (isset($_REQUEST['domain'])) {
            $this->domain = strtolower(htmlspecialchars($_REQUEST['domain']));
        } else {
            $this->domain = "";
        }
        
        if (isset($_REQUEST['coupon_code'])) {
            $this->couponcode = htmlspecialchars($_REQUEST['coupon_code']);
        } else {
            $this->couponcode = "";
        }

        if (isset($_REQUEST['package'])) {
            $this->package = $_REQUEST['package'];
            // make sure that the package isn't set to deny signups

            require_once 'modules/admin/models/Package.php';
            
            $myPackage = new Package($this->package);
            if($this->package != 0){
                if ($myPackage->GetShow() == NULL || $myPackage->GetShow() == -1) {
                    NE_Lib::redirectPage('signup.php');
                }
            }
        } else {
            $this->package = 0;
        }

        if (!isset($_REQUEST['transfer']) || !in_array($_REQUEST['transfer'], array(-1, 0, 1, 2))) {
            $_REQUEST['transfer'] = -1;
        }
        $this->transfer = htmlspecialchars($_REQUEST['transfer']);

        if (isset($_REQUEST['paymenttype'])) {
            $this->paymenttype = htmlspecialchars($_REQUEST['paymenttype']);
        } else {
            $this->paymenttype = '';
        }

        if (isset($_REQUEST['ccnumber'])) {
            $this->ccnumber = htmlspecialchars($_REQUEST['ccnumber']);
        } else {
            $this->ccnumber = '';
        }

        if (isset($_REQUEST['ccmonth'])) {
            $this->ccmonth = htmlspecialchars($_REQUEST['ccmonth']);
        } else {
            $this->ccmonth = '';
        }

        if (isset($_REQUEST['ccyear'])) {
            $this->ccyear = htmlspecialchars($_REQUEST['ccyear']);
        } else {
            $this->ccyear = '';
        }

        if (isset($_REQUEST['paymentterm'])) {
            if(in_array($_REQUEST['paymentterm'], array(0, 1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120))){
                $this->paymentterm = htmlspecialchars($_REQUEST['paymentterm']);
            }else{
                NE_Lib::redirectPage('signup.php');
            }
        } else {
            $_REQUEST['paymentterm'] = 0;
            $this->paymentterm = 0;
        }

        if (isset($_REQUEST['currency'])) {
            $_SESSION['currency'] = base64_encode($_REQUEST['currency']);
        } else if (isset($_SESSION['currency'])) {
            $_REQUEST['currency'] = base64_decode($_SESSION['currency']);
        }
        if (!isset($_REQUEST['currency'])) {
            $_REQUEST['currency'] = $this->settings->get('Default Currency');
            $_SESSION['currency'] = base64_encode($_REQUEST['currency']);
        }
        // LETS AVOID SOMEONE SETTING THIS PARAMETER BY URL
        //if(!isset($_REQUEST['selectedcurrency'])){
            $_REQUEST['selectedcurrency'] = $_REQUEST['currency'];
        //}
        $this->selectedCurrency = htmlspecialchars($_REQUEST['selectedcurrency']);
        $this->currency = htmlspecialchars($_REQUEST['currency']);

        if (isset($_REQUEST['member_email'])) {
            $this->member_email = htmlspecialchars($_REQUEST['member_email']);
        } else if ($this->user->getEmail() != '') {
            $this->member_email = htmlspecialchars($this->user->getEmail());
        } else {
            $this->member_email = '';
        }

        if (isset($_REQUEST['member_password'])) {
            $this->member_password = htmlspecialchars($_REQUEST['member_password']);
        } else {
            $_REQUEST['member_password'] = '';
            $this->member_password = '';
        }

        if (isset($_REQUEST['new_password'])) {
            $this->new_password = htmlspecialchars($_REQUEST['new_password']);
        } else {
            $this->new_password = '';
        }
        
        if (isset($_REQUEST['new_password_confirm'])) {
            $this->new_password_confirm = htmlspecialchars($_REQUEST['new_password_confirm']);
        } else {
            $this->new_password_confirm = '';
        }
        
        if (isset($_REQUEST['new_domain_username'])) {
            $this->domain_username = htmlspecialchars($_REQUEST['new_domain_username']);
        } else {
            $this->domain_username = "";
        }
        
        if (isset($_REQUEST['new_domain_password'])) {
            $this->domain_password = htmlspecialchars($_REQUEST['new_domain_password']);
        } else {
            $this->domain_password = "";
        }
        
        if ($this->user->isAnonymous()) {
            $this->showMenu = false;
        }
    }

    function templateInit()
    {
        
        // Assign the IP & Host info
        $ip = NE_Network::getRemoteAddr();
        if($ip){
            $host = @gethostbyaddr($ip);
            $this->tplView->host = $host;
            $this->tplView->ip = $ip;
        }

        // Assign some other vars used in the template
        $this->tplView->template = $this->settings->getTemplate();

        if (($this->settings->get('plugin_maxmind_Enabled') || $this->settings->get('plugin_maxmindphone_Enabled')) && $this->settings->get('plugin_maxmind_Show MaxMind Logo')) {
            $this->tplView->maxmindEnabled = true;
        } else {
            $this->tplView->maxmindEnabled = false;
        }

        $this->tplInit = true;
    }

    function processProrating($prorateToDay, $incFollPayment, $paymentTerm, $price)
    {
        $tProratedPrice = 0;
        $proratedDays = 0;
        $proIncFollowing = 0;
        $tmpNextBill = 0;
        $proNextBill = 0;

        // 0 means disable prorating
        if ($prorateToDay != 0 && $paymentTerm != 0) {
            $today = date('d');
            $month = date('m');

            if ($today < $prorateToDay) {
                  $proratedDays = $prorateToDay - $today;
                  $tmpNextBill = mktime(0,0,0, $month, $prorateToDay);
            } elseif ($today == $prorateToDay) {
                  $proratedDays = 0; // Don't pro-rate
                  $tmpNextBill = mktime(0,0,0,$month + $paymentTerm, $prorateToDay);
                  return array($price, $tProratedPrice, $proratedDays, $proIncFollowing, $tmpNextBill, $tmpNextBill);
            } else {
                  $today_stamp = mktime(0,0,0,$month, $today);
                  $end_date_stamp = mktime(0,0,0,$month + 1, $prorateToDay);
                  $proratedDays = round(($end_date_stamp-$today_stamp) / (60*60*24) ); // Conversion from seconds to days
                  $tmpNextBill = mktime(0,0,0,$month + 1, $prorateToDay);
            }
        }

        //Check to see if this sale is going to get prorated
        if ($proratedDays > 0) {
            // Assuming each month is thirty-days for pricing
            if ($paymentTerm == 1) {
                  $tProratedPrice = ($price / 30) * $proratedDays;
            } elseif ($paymentTerm == 3) {
                  $tProratedPrice = ($price / 90) * $proratedDays;
            } elseif ($paymentTerm == 6) {
                  $tProratedPrice = ($price / 180) * $proratedDays;
            } elseif ($paymentTerm == 12) {
                  $tProratedPrice = ($price / 360) * $proratedDays;
            } elseif ($paymentTerm == 24) {
                  $tProratedPrice = ($price / 720) * $proratedDays;
            }

            // Decide if we are also billing the customer for the full
            // next billing cycle, or just for this prorated ammount.
            $proIncFollowing = 1;
            // Needs to be after the previous chunk of logic
            if ($prorateToDay != 0) {
               // -1 Never bill next payment
               // 0 Bill if prorating less than 11 days
               // 1 Always bill next payment
               // We unset $price so that it is not included in the total
               // payment due line displayed to the user.  Doesn't actually
               // affect anything outside of this function.
               if ($incFollPayment == -1
                   || ($incFollPayment == 0 && $proratedDays > 10)
                   || ($incFollPayment == 2 && $paymentTerm == 1)
                   || ($incFollPayment == 3 && $paymentTerm != 1)
                   )
                {
                   $price = 0;
                   $proIncFollowing = 0;
               }
            }
            // Include the following payment if we are supposed to
            if($proIncFollowing == 1){
                   if ($paymentTerm == 12) { // 12 months == 1 year
                   $proNextBill = strtotime('+1 year', $tmpNextBill);
                } else { // X month
                   $proNextBill = strtotime('+'.$paymentTerm.' month', $tmpNextBill);
                }
            } else { // No following payment
                $proNextBill = strtotime('+0 month', $tmpNextBill);
            }
        }

        return array($price, $tProratedPrice, $proratedDays, $proIncFollowing, $tmpNextBill, $proNextBill);
    }
    
    /*
     * Function to process the progress Bar
     */
    function getProgressBar($override = null)
    {
        // Set the step internally so we can manipulate it if required
        $step = $_REQUEST['step'];

        // Change the steps if required
        if($override) {
            $step = $override;
        }

        // Return the step
        return $step;
    }

    /*
     * Function to process the cart summary
     */
    function getCartSummary()
    {

        // Override the cart
        if(@$_GET['cleanCart']) {
            $this->destroyCart();
            $this->destroyCurrency();
            $this->destroyInvoiceInformation();
            NE_Lib::redirectPage('order.php');
        }

    	$this->tplView->showTimer = false;	

        $packagesWithStockEnabled = array();
        // Check if the cart has been tampered with
        if(NE_Lib::generateSignupCartHash() == @$_SESSION['cartHash'] && @$_SESSION['cartHash'] != null) {

            // Get the cart items
            $cartItems = unserialize(base64_decode(@$_SESSION['cartContents']));

            // Set an array to use for product group info to avoid getting it potientially many times
            $productGroupInfo = array();

            if(count($cartItems) == 0) {
                // Something went wrong so empty the cart just to be sure
                $this->destroyCart();

                // Return nothing
                return array("total" => $this->currencys->format($this->currency, '0', true, false, "NONE", true), 'items' => '', 'totalCount' => 0);

            }
            // Calculate the next due date when prorating
            $realProNextBill = 0;
            
            // Set an array for products to hide options
            $hideOptions = array();

            // Work out a running total
            $runningTotal = 0;
            $trueTotal = 0;
            $finalCart = array();
            $i = 0;
            foreach($cartItems AS $value => $key) {

                // Skip coupons
                if($value == 'couponCodes') {
                    continue;
                }

                //print_r($key);
                
                // Make a working item
                $workingItem = array();

                // Set some vars
                $workingItem['cartID'] = $i;

                // Gracefully ignore a product ID of 0
                if($key['productId'] == 0 ) {
                    continue;
                }

                // Get the product's information
                $package = new Package($key['productId']);
                $package->getProductPricing();
                
                //we want to keep track of weather we need to show the timer information on cart summary
                //lets get a count of stock enabled products in our cart
                if ($package->getStockEnabled()) {                
                	$packagesWithStockEnabled[] = $value;
            	} 

                // Get the product group information
                if(!@$productGroupInfo[$package->planid]) {
                    $productGroup = PackageTypeGateway::getPackageTypes($package->planid);
                    $productGroupInfo[$package->planid] = $productGroup->fetch();
                }

                // Set some vars
                $workingItem['name'] = $package->planname;

                $workingItem['groupName'] = $productGroupInfo[$package->planid]->fields['name'];
                $workingItem['groupType'] = $productGroupInfo[$package->planid]->fields['type'];
                $workingItem['cartItemId'] = $key['cartItemId'];
                $workingItem['hasAddons'] = false;
                $workingItem['appliedCoupon'] = '';
                $includesAddons = false;
                $affectsSetup = false;
                $affectsPrice = false;
                
                // Set safe names up with no quotes for the JS delete functions
                $workingItem['safeGroupName'] = str_replace("'", "", $productGroupInfo[$package->planid]->fields['name']);
                $workingItem['safeGroupName'] = str_replace('"', "", $workingItem['safeGroupName']);
                $workingItem['safeName'] = str_replace("'", "", $package->planname);
                $workingItem['safeName'] = str_replace('"', "", $workingItem['name']);
                
                
                // Set any hidden attributes
                if(isset($hideOptions[$key['cartItemId']])) {
                    $workingItem['hidden'] = $hideOptions[$key['cartItemId']];
                }

                // Is the product taxable?
                $workingItem['taxable'] = $package->isTaxable();

                // Do we have an automatic coupon?
                if(isset($package->pricingInformation['automaticCoupon']) && !@is_array($cartItems['couponCodes'][$key['couponCode']])) {

                    $return = Coupon::validate($package->pricingInformation['automaticCoupon'], $productGroupInfo[$package->planid]->fields['id'], $package->id, $key['params']['term']);

                    if(@is_array($return)) {

                        // Push the coupon code to the product
                        $cartItems[$value]['couponCode'] = $return['id'];

                        // Add the coupon code the session
                        $cartItems['couponCodes'][$return['id']] = $return;

                        // Update session
                        $_SESSION['cartContents'] = base64_encode(serialize($cartItems));

                        // Save the new hash
                        $_SESSION['cartHash'] = NE_Lib::generateSignupCartHash();

                        // Set up the coupon information
                        $key['couponCode'] = $return['id'];
                    }
                }
                

                // Process the addons here first so we can add to the package pricing later
                // Have to reset the arrays here as we don't enter the IF statement meaning addon totals stay for the next product
                $finalAddons = array();
                $addonsTotal = array();
                if(@$key['params']['addons']) {

                    $packageAddons = $this->getAddons($key['productId'], $key['params']['term']);

                    // Loop the addons in the array
                    foreach($key['params']['addons'] AS $addonId => $addonValue) {

                        // Explode the addon value
                        $addonExplode = explode("_", $addonValue);

                        // Check we have enough info from the post
                        if(count($addonExplode) == 4) {

                            // Set addons up
                            $workingItem['hasAddons'] = true;

                            // Get the addon
                            foreach($packageAddons as $addon) {

                                // Do we have the right addon?
                                if($addon['id'] == $addonId) {

                                    // Get the price
                                    foreach($addon['prices'] AS $price) {
                                        if($price['price_id'] == $addonExplode[2] && $price['recurringprice_cyle'] == $addonExplode[3]) {
                                            $workingAddon = array();
                                            $workingAddon['name'] = $addon['name'];
                                            $workingAddon['item'] = $price['price'];
                                            $workingAddon['taxable'] = @$addon['taxable'];
                                            $workingAddon['recurringprice_cyle'] = @$price['recurringprice_cyle'];

                                            //$workingAddon['price'] = @$addon['price'];
                                            $workingAddon['item_price'] = $price['item_price'];
                                            $workingAddon['item_setup'] = $price['item_setup'];
                                            $workingAddon['price_float_prorated'] = $price['price_float_prorated'];
                                            $workingAddon['next_bill_date'] = $price['next_bill_date'];

                                            $finalAddons[] = $workingAddon;

                                            // Add to the total
                                            @$addonsTotal['price'] += $price['item_price'];
                                            @$addonsTotal['setup'] += $price['item_setup'];
                                        }
                                    }
                                }
                            }
                        }
                    }

                    $workingItem['addons'] = $finalAddons;
                    $workingItem['addonsTruePrice'] = @$addonsTotal['price'];
                    $workingItem['addonsTrueSetup'] = @$addonsTotal['setup'];
                }

                // Get pricing based on types
                // Note this is before ANY deductions or additions.

                if($workingItem['groupType'] == 3) {

                    $workingItem['isDomain'] = true;
                    $workingItem['domainName'] = @$key['params']['sld'].".".@$key['params']['tld'];

                    // Check the pricing is valid, and get the right options
                    $domainPricing = $package->isTermValid(@$key['params']['term'], @$key['params']['tld']);

                    // Work out the total
                    if($key['params']['domainType'] == 0) {

                        // Add the extra text for the title
                        $workingItem['titleText'] = ' '.$this->lang('/ Register');
                        $workingItem['term'] = $package->getTermText($key['params']['term']);

                        // Add the true prices & terms
                        $workingItem['truePrice'] = $domainPricing['price'];
                        $workingItem['totalPrice'] = $domainPricing['price'];
                        $workingItem['renewPrice'] = $domainPricing['renew'];
                        $workingItem['renewTotalPrice'] = $domainPricing['renew'];
                        $workingItem['trueSetup'] = null;
                        $workingItem['setupFee'] = null;
                        $workingItem['trueTerm'] = $key['params']['term']*12;


                    } elseif($key['params']['domainType'] == 1) {

                        // Add the extra title text
                        $workingItem['titleText'] = ' '.$this->lang('/ Transfer');
                        $workingItem['term'] = $package->getTermText($key['params']['term']);

                        // Add the true prices & terms
                        $workingItem['truePrice'] = $domainPricing['transfer'];
                        $workingItem['totalPrice'] = $domainPricing['transfer'];
                        $workingItem['renewPrice'] = $domainPricing['renew'];
                        $workingItem['renewTotalPrice'] = $domainPricing['renew'];
                        $workingItem['trueSetup'] = null;
                        $workingItem['setupFee'] = null;
                        $workingItem['trueTerm'] = $key['params']['term']*12;

                    }

                } else {

                    // Check if we have a valid price term
                    if($package->isPriceIncluded($key['params']['term'])) {

                        // Set some basic information
                        $workingItem['term'] = $package->getTermText($key['params']['term']);

                        // Add the true prices & terms
                        $workingItem['truePrice'] = $package->getPrice(@$key['params']['term']);
                        $workingItem['totalPrice'] = $package->getPrice(@$key['params']['term']);
                        $workingItem['trueSetup'] = @$package->getSetupFee(@$key['params']['term']);
                        $workingItem['setupFee'] = @$package->getSetupFee(@$key['params']['term']);
                        $workingItem['trueTerm'] = $key['params']['term'];
                    } else {
                        // Something went wrong so abandon ship
                        echo("Invalid price term found");
                        $this->destroyCart();
                    }
                }

                // Set the extra ddon pricing
                $addonsTotal['totalPrice'] = @$addonsTotal['price'];
                $addonsTotal['totalSetup'] = @$addonsTotal['setup'];

                /*
                 * Handle any deductions from coupons and also additions from addons.
                 * The coupon codes decide when we include the addon prices
                 */
                $couponAmount = 0;
                if(@is_array($cartItems['couponCodes'][$key['couponCode']])) {

                    // Set some basic coupon related information
                    $workingItem['hasCoupon'] = true;
                    $workingItem['appliedCoupon'] = $cartItems['couponCodes'][$key['couponCode']]['code'];
                    $workingItem['appliedCouponId'] = $cartItems['couponCodes'][$key['couponCode']]['id'];
                    $workingItem['appliedCouponTaxable'] = $cartItems['couponCodes'][$key['couponCode']]['taxable'];

                    // What type of coupon are we doing?
                    if($cartItems['couponCodes'][$key['couponCode']]['type'] == 0) {

                        $includesAddons = false;
                        
                        // Amount based coupon
                        // NOTE: We don't take into account the addon pricing here as the coupon system
                        // does not support this yet.
                        $couponAmount = $cartItems['couponCodes'][$key['couponCode']]['discount'];
                        $couponAmountRenew = $couponAmount;
                        $workingItem['appliedCouponAmount'] = $couponAmount;

                        // If we have a recurring coupon then deduct the amount from the product fee first
                        if($cartItems['couponCodes'][$key['couponCode']]['recurring'] == 1) {

                            // Deduct it from the product fee first
                            if(@$workingItem['truePrice']  || @$addonsTotal['price']) {

                                $affectsPrice = true;
                                
                                if(isset($workingItem['truePrice'])) {
                                    $couponAmount = $couponAmount - $workingItem['truePrice'];
                                    $workingItem['totalPrice'] = max(0, 0 - $couponAmount);
                                    
                                    if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                                        $couponAmountRenew = $couponAmountRenew - @$workingItem['renewPrice'];
                                        $workingItem['renewTotalPrice'] = max(0, 0 - $couponAmountRenew);
                                    }
                                }

                                if(isset($addonsTotal['price']) && $couponAmount > 0) {
                                    $couponAmount = $couponAmount - $addonsTotal['price'];
                                    $addonsTotal['totalPrice'] = max(0, 0 - $couponAmount);
                                }
                            }

                            // Deduct the rest from the setup fees
                            if($couponAmount > 0 && (@$workingItem['trueSetup'] || @$addonsTotal['setup'])) {
                                
                                $affectsSetup = true;

                                if(isset($workingItem['trueSetup'])) {
                                    $couponAmount = $couponAmount - $workingItem['trueSetup'];
                                    $workingItem['setupFee'] = max(0, 0 - $couponAmount);
                                }

                                if(isset($addonsTotal['setup']) && $couponAmount > 0) {
                                    $couponAmount = $couponAmount - $addonsTotal['setup'];
                                    $addonsTotal['totalSetup'] = max(0, 0 - $couponAmount);
                                }
                            }

                        } else {

                            // Deduct it from the setup fees first then product fee
                            if(@$workingItem['trueSetup'] || @$addonsTotal['setup']) {

                                $affectsSetup = true;
                                $includesAddons = false;
                                
                                if(isset($workingItem['trueSetup'])) {
                                    $couponAmount = $couponAmount - $workingItem['trueSetup'];
                                    $workingItem['setupFee'] = max(0, 0 - $couponAmount);
                                }

                                if(isset($addonsTotal['setup']) && $couponAmount > 0) {
                                    $couponAmount = $couponAmount - $addonsTotal['setup'];
                                    $addonsTotal['totalSetup'] = max(0, 0 - $couponAmount);
                                }
                            }

                            // Do we have of the coupon amount left to apply to the fee?
                            if($couponAmount > 0) {

                                // Amount based
                                $affectsPrice = true;
                                $includesAddons = false;
                                
                                if(isset($workingItem['truePrice'])) {
                                    $couponAmount = $couponAmount - $workingItem['truePrice'];
                                    $workingItem['totalPrice'] = max(0, 0 - $couponAmount);
                                }

                                if(isset($addonsTotal['price']) && $couponAmount > 0) {
                                    $couponAmount = $couponAmount - $addonsTotal['price'];
                                    $addonsTotal['totalPrice'] = max(0, 0 - $couponAmount);
                                }
                            }
                        }
                    } else {

                        // This is where the fun starts, we need to handle %age based coupons
                        $couponAmount = $cartItems['couponCodes'][$key['couponCode']]['discount'];
                        
                        // We need to work out what exactly the coupon applies to figure wize
                        $couponAppliesTo = $cartItems['couponCodes'][$key['couponCode']]['applicableTo'];

                        //echo $couponAppliesTo;

                        // Remove this other invoice items code
                        if($couponAppliesTo > 63) {
                            $couponAppliesTo = $couponAppliesTo - 64;
                        }

                        if($this->settings->get('Prorate To Day') != 0) {
                            if(($couponAppliesTo & COUPON_APPLIESTO_PACKAGE) != 0){
                                $couponAppliesTo = $couponAppliesTo - COUPON_APPLIESTO_PACKAGE;
                            }
                            
                            if(($couponAppliesTo & COUPON_APPLIESTO_ADDONS) != 0){
                                $couponAppliesTo = $couponAppliesTo - COUPON_APPLIESTO_ADDONS;
                            }
                        }

                        // Update the coupon applies to
                        $cartItems['couponCodes'][$key['couponCode']]['applicableTo'] = $couponAppliesTo;
                        // Update session
                        $_SESSION['cartContents'] = base64_encode(serialize($cartItems));
                        // Save the new hash
                        $_SESSION['cartHash'] = NE_Lib::generateSignupCartHash();

                        if($couponAppliesTo == 4 || $couponAppliesTo == 5 || $couponAppliesTo == 7) {

                            // Package Only
                            $affectsPrice = true;

                            // Calculate the totals
                            $couponAmount = @$workingItem['truePrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                            $workingItem['appliedCouponAmount'] = $couponAmount;
                            
                            if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                                $itemDiscountRenew = @$workingItem['renewPrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                $workingItem['renewTotalPrice'] = max(@$workingItem['renewTotalPrice'] - $itemDiscountRenew, 0);
                            }
                            
                            $couponAmount = @$workingItem['truePrice'] - $couponAmount;

                            if($couponAmount > 0) {
                                $workingItem['totalPrice'] = $couponAmount;
                            } else {
                                $workingItem['totalPrice'] = '0.00';
                            }

                        } elseif($couponAppliesTo == 8 || $couponAppliesTo == 9 || $couponAppliesTo == 11) {

                            // Setup fee only
                            $affectsSetup = true;

                            // Calculate the totals
                            $couponAmount = @$workingItem['trueSetup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                            $workingItem['appliedCouponAmount'] = $couponAmount;
                            $couponAmount = @$workingItem['trueSetup'] - $couponAmount;

                            if($couponAmount > 0) {
                                $workingItem['setupFee'] = $couponAmount;
                            } else {
                                $workingItem['setupFee'] = '0.00';
                            }
                            
                        } elseif($couponAppliesTo == 12 || $couponAppliesTo == 13 || $couponAppliesTo == 15) {

                            // Setup fee & price
                            $affectsSetup = true;
                            $affectsPrice = true;

                            // Get the total discount from price & setup combined
                            $couponAmount = (@$workingItem['truePrice'] + @$workingItem['trueSetup']) * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                            $workingItem['appliedCouponAmount'] = $couponAmount;
                            
                            if(isset($workingItem['truePrice'])) {
                               $itemDiscount = $workingItem['truePrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $workingItem['totalPrice'] = $workingItem['truePrice'] - $itemDiscount;
                               
                               if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                                   $itemDiscountRenew = @$workingItem['renewPrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                   $workingItem['renewTotalPrice'] = @$workingItem['renewTotalPrice'] - $itemDiscountRenew;
                               }
                           }

                           if(isset($workingItem['trueSetup'])) {
                               $itemDiscount = $workingItem['trueSetup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $workingItem['setupFee'] = $workingItem['trueSetup'] - $itemDiscount;
                           }

                        } elseif($couponAppliesTo == 16 || $couponAppliesTo == 17 || $couponAppliesTo == 19) {
                            
                            // Addons only
                            $affectsPrice = true;
                            
                            // Get the total discount from price & setup combined
                            $couponAmount = $addonsTotal['price'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                            $workingItem['appliedCouponAmount'] = $couponAmount;
                            
                            if(isset($addonsTotal['price'])) {
                                $itemDiscount = $addonsTotal['price'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                $addonsTotal['totalPrice'] = $addonsTotal['price'] - $itemDiscount;
                            }
                            
                        } elseif($couponAppliesTo == 32 || $couponAppliesTo == 33 || $couponAppliesTo == 35 ) {
                            
                            // Addons setup only
                            $affectsSetup = true;
                            
                            // Get the total discount from price & setup combined
                            $couponAmount = $addonsTotal['setup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                            $workingItem['appliedCouponAmount'] = $couponAmount;
                            
                            if(isset($addonsTotal['setup'])) {
                                $itemDiscount = $addonsTotal['setup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                $addonsTotal['totalSetup'] = $addonsTotal['setup'] - $itemDiscount;
                            }
                            
                        } elseif($couponAppliesTo == 20  || $couponAppliesTo == 21 || $couponAppliesTo == 23) {
                            
                            // Package & addon prices only
                            $affectsPrice = true;
                            
                            // Get the total discount from price & setup combined
                            $couponAmount = (@$workingItem['truePrice'] + @$addonsTotal['price']) * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                            $workingItem['appliedCouponAmount'] = $couponAmount;

                            if(isset($workingItem['truePrice'])) {
                                $itemDiscount = $workingItem['truePrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                $workingItem['totalPrice'] = $workingItem['truePrice'] - $itemDiscount;
                                
                                if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                                   $itemDiscountRenew = @$workingItem['renewPrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                   $workingItem['renewTotalPrice'] = @$workingItem['renewTotalPrice'] - $itemDiscountRenew;
                               }
                            }

                            if(isset($addonsTotal['price'])) {
                                $itemDiscount = $addonsTotal['price'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                $addonsTotal['totalPrice'] = $addonsTotal['price'] - $itemDiscount;
                            }
                            
                        } elseif($couponAppliesTo == 40 || $couponAppliesTo == 41 || $couponAppliesTo == 43) {

                            // Package Setup & Addon Setup
                           $affectsSetup = true;

                           // Get the total discount from price & setup combined
                           $couponAmount = (@$workingItem['trueSetup'] + @$addonsTotal['setup']) * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                           $workingItem['appliedCouponAmount'] = $couponAmount;

                           if(isset($addonsTotal['setup'])) {
                              $itemDiscount = $addonsTotal['setup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                              $addonsTotal['totalSetup'] = $addonsTotal['setup'] - $itemDiscount;
                           }

                           if(isset($workingItem['trueSetup'])) {
                              $itemDiscount = $workingItem['trueSetup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                              $workingItem['setupFee'] = $workingItem['trueSetup'] - $itemDiscount;
                           }
                            
                       } elseif($couponAppliesTo == 48  || $couponAppliesTo == 49 || $couponAppliesTo == 51) {
                           
                           // Addon & Addon Setup Only
                           $affectsPrice = true;
                           $affectsSetup = true;
                           
                           // Get the total discount from price & setup combined
                           $couponAmount = (@$addonsTotal['price'] + @$addonsTotal['setup']) * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                           $workingItem['appliedCouponAmount'] = $couponAmount;
                           
                           if(isset($addonsTotal['price'])) {
                               $itemDiscount = $addonsTotal['price'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $addonsTotal['totalPrice'] = $addonsTotal['price'] - $itemDiscount;
                           }
                           
                           if(isset($addonsTotal['setup'])) {
                               $itemDiscount = $addonsTotal['setup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $addonsTotal['totalSetup'] = $addonsTotal['setup'] - $itemDiscount;
                           }
                            
                        } elseif($couponAppliesTo == 60 || $couponAppliesTo == 61 || $couponAppliesTo == 63) {
                           
                           // Coupon applies to everything
                           $affectsPrice = true;
                           $affectsSetup = true;
                           $includesAddons = false;
                           
                           // Get the total discount from price & setup combined
                           $couponAmount = (@$workingItem['truePrice'] + @$workingItem['trueSetup'] + @$addonsTotal['price'] + @$addonsTotal['setup']) * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                           $workingItem['appliedCouponAmount'] = $couponAmount;

                           if(isset($workingItem['truePrice'])) {
                               $itemDiscount = $workingItem['truePrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $workingItem['totalPrice'] = $workingItem['truePrice'] - $itemDiscount;
                               
                               if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                                   $itemDiscountRenew = @$workingItem['renewPrice'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                                   $workingItem['renewTotalPrice'] = @$workingItem['renewTotalPrice'] - $itemDiscountRenew;
                               }
                           }
                           
                           if(isset($addonsTotal['price'])) {
                               $itemDiscount = $addonsTotal['price'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $addonsTotal['totalPrice'] = $addonsTotal['price'] - $itemDiscount;
                           }
                           
                           if(isset($workingItem['trueSetup'])) {
                               $itemDiscount = $workingItem['trueSetup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $workingItem['setupFee'] = $workingItem['trueSetup'] - $itemDiscount;
                           }
                           
                           if(isset($addonsTotal['setup'])) {
                               $itemDiscount = $addonsTotal['setup'] * $cartItems['couponCodes'][$key['couponCode']]['discount'];
                               $addonsTotal['totalSetup'] = $addonsTotal['setup'] - $itemDiscount;
                           }
                       }
                    }
                }

                // Do we have to add up the addon prices?
                if(!@$includesAddons) {
                    $workingItem['finalPrice'] = @$workingItem['totalPrice'] + @$addonsTotal['totalPrice'];
                    $workingItem['tempTruePrice'] = @$workingItem['truePrice'] + @$addonsTotal['price'];

                    $workingItem['finalSetup'] = @$workingItem['setupFee'] + @$addonsTotal['totalSetup'];
                    $workingItem['tempTrueSetup'] = @$workingItem['trueSetup'] + @$addonsTotal['setup'];
                } else {
                    $workingItem['finalPrice'] = $workingItem['totalPrice'];
                    $workingItem['tempTruePrice'] = $workingItem['truePrice'] + @$addonsTotal['price'];
                    $workingItem['finalSetup'] = $workingItem['setupFee'];
                    $workingItem['tempTrueSetup'] = $workingItem['trueSetup'] + @$addonsTotal['setup'];
                }

                if($workingItem['finalPrice'] == $workingItem['tempTruePrice']
                  && $workingItem['finalSetup'] == $workingItem['tempTrueSetup']){
                      // Remove the coupon information
                      if(isset($cartItems[$value]['couponCode'])){
                          unset($cartItems[$value]['couponCode']);
                      }
                      if(isset($key['couponCode'])){
                          unset($key['couponCode']);
                      }
                      
                      // Update session
                      $_SESSION['cartContents'] = base64_encode(serialize($cartItems));
                      // Save the new hash
                      $_SESSION['cartHash'] = NE_Lib::generateSignupCartHash();
                }

                // Process prorating
                $workingItem['isProRated'] = false;
                if($this->settings->get('Prorate To Day') != 0) {
                    // We are prorating, so the only discount possible is an Amount Coupon.
                    $discount = max($workingItem['tempTruePrice'] - $workingItem['finalPrice'], 0);
                    
                    // Lets add the amount to the $couponAmount, and we will deduct it again also with the prorate.
                    if($discount > 0){
                        if($couponAmount > 0){
                            $couponAmount += $discount;
                        }else{
                            $couponAmount = $discount;
                        }
                    }

                    if((!isset($workingItem['isDomain']) || $workingItem['isDomain'] != 1) && $workingItem['trueTerm'] != 0){
                        list($itemPrice, $proRatedPrice, $proratedDays, $proIncFollowing, $tmpnextBill, $proNextBill) = $this->processProrating($this->settings->get('Prorate To Day'), $this->settings->get('Include Following Payment'), $workingItem['trueTerm'], $workingItem['truePrice']);

                        if($itemPrice != 0) {
                            // Lets discount as much as we can from the $couponAmount
                            $workingItem['finalPrice'] = max($workingItem['truePrice'] + $proRatedPrice - $couponAmount, 0);
                            $couponAmount = $couponAmount - $workingItem['truePrice'] - $proRatedPrice;

                            $workingItem['tempTruePrice'] = $itemPrice + $proRatedPrice;
                        } else {
                            // Lets discount as much as we can from the $couponAmount
                            $workingItem['finalPrice'] = max($proRatedPrice - $couponAmount, 0);
                            $couponAmount = $couponAmount - $proRatedPrice;
                            $workingItem['tempTruePrice'] = $proRatedPrice;
                        }
                        
                        if($proRatedPrice > 0){
                            $workingItem['isProRated'] = true;
                        }
                    }else{
                        // Lets discount as much as we can from the $couponAmount
                        $workingItem['finalPrice'] = max($workingItem['truePrice'] - $couponAmount, 0);
                        $couponAmount = $couponAmount - $workingItem['truePrice'];
                        $workingItem['tempTruePrice'] = $workingItem['truePrice'];
                        $proNextBill = 0;
                    }

                    if($couponAmount < 0){
                        $couponAmount = 0;
                    }

                    if($realProNextBill != 0){
                        if($proNextBill != 0){
                            $realProNextBill = min($realProNextBill, $proNextBill);
                        }
                    }else{
                        $realProNextBill = $proNextBill;
                    }

                    if(@is_array($workingItem['addons'])) {
                        foreach($workingItem['addons'] AS $tempAddon) {
                            list($itemPrice, $proRatedPrice, $proratedDays, $proIncFollowing, $tmpnextBill, $proNextBill) = $this->processProrating($this->settings->get('Prorate To Day'), $this->settings->get('Include Following Payment'), $tempAddon['recurringprice_cyle'], $tempAddon['item_price']);
                            
                            if($itemPrice != 0) {
                                // Lets discount as much as we can from the $couponAmount
                                $workingItem['finalPrice'] += max($tempAddon['item_price'] + $proRatedPrice - $couponAmount, 0);
                                $workingItem['tempTruePrice'] += $itemPrice + $proRatedPrice;
                                
                                if(($tempAddon['item_price'] + $proRatedPrice) > $couponAmount){
                                    $couponAmount = 0;
                                }else{
                                    $couponAmount -= ($tempAddon['item_price'] + $proRatedPrice);
                                }
                            } else {
                                // Lets discount as much as we can from the $couponAmount
                                $workingItem['finalPrice'] += max($proRatedPrice - $couponAmount, 0);
                                $workingItem['tempTruePrice'] += $proRatedPrice;
                                
                                if($proRatedPrice > $couponAmount){
                                    $couponAmount = 0;
                                }else{
                                    $couponAmount -= $proRatedPrice;
                                }
                            }
                            
                            if($proRatedPrice > 0){
                                $workingItem['isProRated'] = true;
                                
                                if($realProNextBill != 0){
                                    if($proNextBill != 0){
                                        $realProNextBill = min($realProNextBill, $proNextBill);
                                    }
                                }else{
                                    $realProNextBill = $proNextBill;
                                }
                            }
                        }
                    }
                    
                    if($workingItem['isProRated']){
                        $this->tplView->isProRating = true;
                        $this->tplView->proRatingTo = date('jS', $realProNextBill);
                        $this->tplView->proRateDate = date($this->settings->get('Date Format'), $realProNextBill);
                    }
                }

                $trueTotal += @$workingItem['tempTrueSetup'];
                $trueTotal += @$workingItem['tempTruePrice'];

                // Loop the addons and add the recurring amounts 
                if(@is_array($workingItem['addons'])) {
                    foreach($workingItem['addons'] AS $tempAddon) {
                        
                        // Do we have a coupon adjusted price?
                        if(@$tempAddon['adjustedPrice']) {
                            $tempAddonPrice = $tempAddon['adjustedPrice'];
                        } else {
                            $tempAddonPrice = $tempAddon['item_price'];
                        }
                        
                        // Add the recurring amount. This number will always be true after coupons
                        $this->recurringAmount($tempAddon['recurringprice_cyle'], $tempAddonPrice);

                    }
                }

                // Now we handle any / all deductions and format the pricing
                if($affectsPrice == true) {
                    $workingItem['totalFormatted'] = $this->currencys->format($this->currency, @$workingItem['tempTruePrice'], true, false, "NONE", true);
                    $workingItem['newTotal'] = $this->currencys->format($this->currency, @$workingItem['finalPrice'], true, false, "NONE", true);
                } else {
                    $workingItem['totalFormatted'] = $this->currencys->format($this->currency, $workingItem['finalPrice'], true, false, "NONE", true);
                }

                if(@$workingItem['trueSetup'] != 0 || @$workingItem['finalSetup'] != 0) {
                    if($affectsSetup == true) {
                        $workingItem['setupFormatted'] = $this->currencys->format($this->currency, @$workingItem['tempTrueSetup'], true, false, "NONE", true);
                        $workingItem['newSetup'] = $this->currencys->format($this->currency, @$workingItem['finalSetup'], true, false, "NONE", true);
                    } else {
                        $workingItem['setupFormatted'] = $this->currencys->format($this->currency, @$workingItem['finalSetup'], true, false, "NONE", true);
                    }
                }

                // Handle the running total & recurring prices
                if(@$cartItems['couponCodes'][$key['couponCode']]['recurring'] == 1) {

                    // Add subtotal
                    //$this->runningTotal($workingItem['totalPrice'], @$workingItem['setupFee']); //THis line seems to show a wrong value. Replaced with the one below
                    $this->runningTotal($workingItem['finalPrice'], @$workingItem['finalSetup']);

                    // Add recurring item
                    if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                        $this->recurringAmount(@$workingItem['trueTerm'], @$workingItem['renewTotalPrice']);
                    }else{
                        $this->recurringAmount(@$workingItem['trueTerm'], @$workingItem['totalPrice']);
                    }
                } else {

                    // Add subtotal
                    $this->runningTotal($workingItem['finalPrice'], @$workingItem['finalSetup']);

                    // Add Recurring item
                    if(@$workingItem['groupType'] == 3 && @$workingItem['isDomain'] == 1){
                        $this->recurringAmount(@$workingItem['trueTerm'], @$workingItem['renewPrice']);
                    }else{
                        $this->recurringAmount(@$workingItem['trueTerm'], @$workingItem['truePrice']);
                    }
                }

                // Work out what domain to display
                if($productGroupInfo[$package->planid]->fields['type'] == 1 || $productGroupInfo[$package->planid]->fields['type'] == 2) {
                    
                    // Check if we have an associated domain
                    if(@$key['bundledDomain'] && @$cartItems[$key['bundledDomain']]) {
                        $workingItem['associatedDomain'] = $cartItems[$key['bundledDomain']]['params']['sld'].".".$cartItems[$key['bundledDomain']]['params']['tld'];
                        
                        // Hide the delete button of the associated domain
                        $hideOptions[$key['bundledDomain']]['delete'] = true;
                        $workingItem['bundledDomainId'] = $key['bundledDomain'];
                    } elseif(isset($key['bundledDomain']) && !@is_numeric($key['bundledDomain'])) {
                        // Domain is probably self managed so add it here.
                        $workingItem['associatedDomain'] = $key['bundledDomain'];
                    } else {
                        // Query to get the ID of the DOmain Name custom field
                        $query = "SELECT id FROM customField WHERE name = ? AND groupId = 2 AND subGroupId = 1 ORDER BY id ASC LIMIT 1";
                        $result = $this->db->query($query, 'Domain Name');
                        $domainCustomFieldId = $result->fetch();
                        
                        if(@$key['params']['customFields'][$domainCustomFieldId['id']]) {
                            $workingItem['associatedDomain'] = @$key['params']['customFields'][$domainCustomFieldId['id']];
                        } else {
                            $workingItem['associatedDomain'] = false;
                        }
                    }
                } else {
                    $workingItem['associatedDomain'] = false;
                }
                
                // Add the working item to the final array
                $finalCart[] = $workingItem;

                // Increment $i
                ++$i;
            }


            // Update the running total
            $runningTotal = @$this->runningTotal['total'];

            // Calculate if we need a 'then' section for recurring items
            if(@is_array($this->runningTotal['recurringItem'])) {

                // Create the array
                $recurringItems = array();
                $hostingTwelve = 0;
                $hostingTwentyFour = 0;

                // Loop hosting
                if(@is_array($this->runningTotal['recurringItem'][1])) {
                    foreach ($this->runningTotal['recurringItem'][1] as $key => $value) {
                        // Format the hosting
                        if(@$key == 1 && $value != 0) {
                            $recurringItems[] = array('period' => '1', 'text' => $this->lang('Month'), 'amount' => $this->currencys->format($this->currency, $value, true, false, "NONE", true));
                        } if(@$key == 3 && $value != 0) {
                            $recurringItems[] = array('period' => '3', 'text' => $this->lang('Months'), 'amount' => $this->currencys->format($this->currency, $value, true, false, "NONE", true));
                        } if(@$key == 6 && $value != 0) {
                            $recurringItems[] = array('period' => '6', 'text' => $this->lang('Months'), 'amount' => $this->currencys->format($this->currency, $value, true, false, "NONE", true));
                        } if(@$key == 12 && $value != 0) {
                            $hostingTwelve = $value;
                        } if(@$key == 24 && $value != 0) {
                            $hostingTwentyFour = $value;
                        }
                    }
                }

                // Loop the array
                foreach ($this->runningTotal['recurringItem'] AS $key => $value) {

                    // Format the Domains
                     if($key == 3 && @$value[0]) {
                        $recurringItems[] = array('period' => '0', 'text' => $this->lang('One Time'), 'amount' => $this->currencys->format($this->currency, $value[0], true, false, "NONE", true));
                    } if($key == 3 && @$value[1]) {
                        $recurringItems[] = array('period' => '1', 'text' => $this->lang('Year'), 'amount' => $this->currencys->format($this->currency, $value[1] + $hostingTwelve, true, false, "NONE", true));
                        $hostingTwelve = -1;
                    } if($key == 3 && @$value[2]) {
                        $recurringItems[] = array('period' => '2', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[2] + $hostingTwentyFour, true, false, "NONE", true));
                        $hostingTwentyFour = -1;
                    } if($key == 3 && @$value[3]) {
                        $recurringItems[] = array('period' => '3', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[3], true, false, "NONE", true));
                    } if($key == 3 && @$value[4]) {
                        $recurringItems[] = array('period' => '4', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[4], true, false, "NONE", true));
                    } if($key == 3 && @$value[5]) {
                        $recurringItems[] = array('period' => '5', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[5], true, false, "NONE", true));
                    } if($key == 3 && @$value[6]) {
                        $recurringItems[] = array('period' => '6', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[6], true, false, "NONE", true));
                    } if($key == 3 && @$value[7]) {
                        $recurringItems[] = array('period' => '7', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[7], true, false, "NONE", true));
                    } if($key == 3 && @$value[8]) {
                        $recurringItems[] = array('period' => '8', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[8], true, false, "NONE", true));
                    } if($key == 3 && @$value[9]) {
                        $recurringItems[] = array('period' => '9', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[9], true, false, "NONE", true));
                    } if($key == 3 && @$value[10]) {
                        $recurringItems[] = array('period' => '10', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $value[10], true, false, "NONE", true));
                    }
                }

                // Check to see if 12 and 24 hosting was ran
                if($hostingTwelve  > '0') {
                    $recurringItems[] = array('period' => '1', 'text' => $this->lang('Year'), 'amount' => $this->currencys->format($this->currency, $hostingTwelve, true, false, "NONE", true));
                }
                if($hostingTwentyFour > '0') {
                    $recurringItems[] = array('period' => '2', 'text' => $this->lang('Years'), 'amount' => $this->currencys->format($this->currency, $hostingTwentyFour, true, false, "NONE", true));
                }
            } else {
                $recurringItems = false;
            }		

            // Return the cart
            $retArray = array('total' => array('price' => $this->currencys->format($this->currency, $runningTotal, true, false, "NONE", true), 'recurringItems' => $recurringItems, 'truePrice' => $runningTotal, 'totalBeforeCoupons' => $trueTotal, 'totalBeforeCouponsFormatted' => $this->currencys->format($this->currency, $trueTotal, true, false, "NONE", true)),
                         'items' => $finalCart,
                         'totalCount' => count($finalCart));

        } else {

            // Something went wrong so empty the cart just to be sure
            $this->destroyCart();
        	$this->tplView->showTimer = false;				
            // Return nothing
            $retArray = array("total" => $this->currencys->format($this->currency, '0', true, false, "NONE", true), 'items' => '', 'totalCount' => 0);
        }                

		//when do we show stock timer if we have a product that is 
		//controlled by stock and we have stock timer above 0 minutes
		$stockTimer = (int) $this->settings->get('Stock Timer');
        if ( (count($packagesWithStockEnabled)>0) && ($retArray['totalCount'] > 0) && ($stockTimer > 0)   ) {
        	$this->tplView->showTimer = true;
        	$this->tplView->timerMinutes = $stockTimer;
        	foreach($packagesWithStockEnabled as $packageWithStockEnabled) {
				$activeOrder = new ActiveOrder($packageWithStockEnabled);				
				$activeOrder->setExpires($stockTimer+1);
        	}
        }
        
        return $retArray;

    }


    /*
     * Function to process the cart tax
     * Can be called from step 4 or by ajax so we don't do ANY session handling
     */
    function processCartTax(&$cartItems, $country, $state, $vatNumber, $isTaxable, $userID) {
        
        // Set some variables
        $validVat = false;
        $returnArray = array();
        $couponDiscount = 0;
        
        // Check if the VAT number is valid
        if(isset($vatNumber) && $vatNumber != ''){
            include_once 'modules/clients/actions/CheckVAT.php';

            $CheckVATAction = new CheckVAT('user', 'CheckVAT');
            $vatResponse = $CheckVATAction->ValidateVAT($country, $vatNumber, $userID);

            if($vatResponse[0] == 1){
                $validVat = true;
            }
        }

        // Get the country
        if($country == null) {
            $country = $this->settings->get('Default Country');
        }
       
        // Get the tax information
        include_once 'modules/clients/actions/GetTax.php';
        $GetTaxAction = new GetTax($this->moduleName, 'GetTax');
        $GetTaxAction->setUser($this->user);
        $taxes = $GetTaxAction->getTaxes($country, $state);
        $taxes['allPreTaxCoupon'] = 0;
        $taxes['allPostTaxCoupon'] = 0;
        
        // Loop the cart items
        if(is_array($cartItems['items'])) {
            foreach($cartItems['items'] AS $item){

                // Process prorating
                if($this->settings->get('Prorate To Day') != 0) {
                    if((!isset($item['isDomain']) || $item['isDomain'] != 1) && $item['trueTerm'] != 0){
                        list($itemPrice, $proRatedPrice, $proratedDays, $proIncFollowing, $tmpnextBill, $proNextBill) = $this->processProrating($this->settings->get('Prorate To Day'), $this->settings->get('Include Following Payment'), $item['trueTerm'], $item['truePrice']);
                        
                        if($itemPrice != 0) {
                            $lineTotal = $itemPrice + $proRatedPrice;
                        } else {
                            $lineTotal = $proRatedPrice;
                        }
                    }else{
                        $lineTotal = $item['truePrice'];
                    }

                    $lineTotal += @$item['trueSetup'];

                    if(@is_array($item['addons'])) {
                        foreach($item['addons'] AS $tempAddon) {
                            list($itemPrice, $proRatedPrice, $proratedDays, $proIncFollowing, $tmpnextBill, $proNextBill) = $this->processProrating($this->settings->get('Prorate To Day'), $this->settings->get('Include Following Payment'), $tempAddon['recurringprice_cyle'], $tempAddon['item_price']);
                            
                            if($itemPrice != 0) {
                                $lineTotal += $itemPrice + $proRatedPrice;
                            } else {
                                $lineTotal += $proRatedPrice;
                            }
                            
                            $lineTotal += $tempAddon['item_setup'];
                        }
                    }
                } else {
                    $lineTotal = $item['truePrice'] + @$item['trueSetup'];
                    
                    if(@is_array($item['addons'])) {
                        foreach($item['addons'] AS $tempAddon) {
                            $lineTotal += $tempAddon['item_price'] + $tempAddon['item_setup'];
                        }
                    }
                }

                // Is this product taxable?
                if($item['taxable']){
                    // Store the TOTAL for this ordered product
                    @$taxes['taxableAmount'] += $lineTotal;
                }

                // Handle the coupon Discount
                if(@$item['hasCoupon']) {
                    if(@$item['appliedCouponTaxable'] && $item['taxable']) {
                        $taxes['allPreTaxCoupon'] += @$item['appliedCouponAmount'];
                    } else {
                        $taxes['allPostTaxCoupon'] += @$item['appliedCouponAmount'];
                    }
                    $couponDiscount += @$item['appliedCouponAmount'];
                }
            }
        }

        // Process the tax amount
        if($isTaxable && ($taxes['taxrate'] > 0 || $taxes['tax2rate'] > 0)){
            
            // Store the taxable rates
            $taxrate = $taxes['taxrate'];
            $tax2rate = $taxes['tax2rate'];
            if($validVat){
                if($taxes['vat']){
                    $taxrate = 0;
                }
                if($taxes['vat2']){
                    $tax2rate = 0;
                }
            }
            
            // Setup the array
            $returnArray['taxRequired'] = true;
            $returnArray['subTotal'] = $cartItems['total']['totalBeforeCouponsFormatted']; // Saving the TOTAL cart amount before deductions

            // Calculate the total amount availble to be taxed
            // This number is the taxableAmount MINUS and preTaxCoupons
            $taxes['totalTaxableAmount'] = @$taxes['taxableAmount'] - @$taxes['allPreTaxCoupon'];
            
            // Apply the taxes.
            // We also need to tax the postTaxCoupon amount.
            if($taxes['taxrate'] > 0){
                $returnArray['taxName'] = $taxes['taxname']." (".$taxes['taxrate']."%)";
                $cartItems['total']['taxAmount'] = ($taxes['totalTaxableAmount'] * $taxrate / 100);
                
                // Fix for when tax is calculated as below 0
                if($cartItems['total']['taxAmount'] < 0) {
                    $cartItems['total']['taxAmount'] = 0;
                }
                $returnArray['taxAmount'] = $this->currencys->format($this->currency, $cartItems['total']['taxAmount'], true, false, "NONE", true);
            }
            if($taxes['tax2rate'] > 0){
                $returnArray['tax2Name'] = $taxes['tax2name']." (".$taxes['tax2rate']."%)";
                
                if($taxes['tax2compound']){
                    $cartItems['total']['subtotalTaxable2'] = $taxes['totalTaxableAmount'] + ($taxes['totalTaxableAmount'] * $taxrate / 100);
                }else{
                    $cartItems['total']['subtotalTaxable2'] = $taxes['totalTaxableAmount'];
                }
                
                $cartItems['total']['tax2Amount'] = ($cartItems['total']['subtotalTaxable2'] * $tax2rate / 100);
                
                // Fix for if tax2 is calculated as a negative number
                if($cartItems['total']['tax2Amount'] < 0) {
                    $cartItems['total']['tax2Amount'] = 0;
                }
                
                $returnArray['tax2Amount'] = $this->currencys->format($this->currency, $cartItems['total']['tax2Amount'], true, false, "NONE", true);
            }
            
            // Get the total price with taxes and pre-tax coupons.


            $cartItems['total']['truePriceWithTaxes'] = (($cartItems['total']['totalBeforeCoupons'] - @$taxes['allPreTaxCoupon']) + @$cartItems['total']['taxAmount'] + @$cartItems['total']['tax2Amount']);

            // Subtract the post tax coupon amount
            $cartItems['total']['truePriceWithTaxes'] = $cartItems['total']['truePriceWithTaxes'] - @$taxes['allPostTaxCoupon'];

            // Format it and save the total to pay.
            $cartItems['total']['priceWithTaxes'] = $this->currencys->format($this->currency, max($cartItems['total']['truePriceWithTaxes'], 0), true, false, "NONE", true);
            $returnArray['totalPay'] = $cartItems['total']['priceWithTaxes'];
        
            
        } else {
            
            // Just set some basic totals
            $returnArray['subTotal'] = $cartItems['total']['totalBeforeCouponsFormatted'];
            
            $returnArray['totalPay'] = $this->currencys->format($this->currency, max($cartItems['total']['totalBeforeCoupons'] - @$couponDiscount, 0), true, false, "NONE", true);
        }

        // Format coupon amounts
        if($couponDiscount > 0) {
            $returnArray['couponDiscount'] = $this->currencys->format($this->currency, $couponDiscount, true, false, "NONE", true);
        }
        
        return $returnArray;
    }


    /*
     * Function to add an item to the cart
     */
    function addToCart($packageId = null, $params = null)
    {

    	// Stop what we're doing if the session to stop adding is present
    	if(isset($_SESSION['avoidaddpackage']) && $_SESSION['avoidaddpackage'] == true) {
    	
			// Return nothing
			return null;
			
		} else {

			// Check if we got everything
			if($packageId == null) {
				// Destroy the cart as something went wrong
				$this->destroyCart();
			}
	
			// get the current cart
			$cartContents = unserialize(base64_decode(@$_SESSION['cartContents']));
			$cartItemId = uniqid();
								
            // Handle stock control if required
            $stock = false;            
            $package = new Package($packageId);            
            $stockInfo = unserialize($package->stockInfo);
            if(is_array($stockInfo)) {
                // Check if we are doing stockControl
                if($stockInfo['stockEnabled'] == 1) {
                    $stock = true;
                    // Decrease the stock control option
                    --$stockInfo['availableStock'];
                    // Serialize it and send it back
                    $package->stockInfo = serialize($stockInfo);
                    // Save the pacakge
                    $package->save();
                }
                
                $stockTimer = (int) $this->settings->get('Stock Timer');
        		if ($stockTimer > 0) {
	    			//lets add to cart this order if it is time sensitive
					$activeOrder = new ActiveOrder();
					$activeOrder->setForcedId($cartItemId);
					$activeOrder->product_id = $packageId;
					$activeOrder->save();
					$activeOrder->setExpires($stockTimer+1);
				}
                
            }
            

			// Add to the cart
			$cartContents[$cartItemId] = array('productId' => $packageId,
											   'params' => $params,
											   'stock' => $stock,
											   'cartItemId' => $cartItemId);
	
			// Save it to the session
			$_SESSION['cartContents'] = base64_encode(serialize($cartContents));
	
			// Save the new hash
			$_SESSION['cartHash'] = NE_Lib::generateSignupCartHash();            
	
	
			return $cartItemId;
		}
    }

    /*
     * Function to remove an item from the cart
     */
    function removeFromCart($cartItemId)
    {

        // get the current cart
        $cartContents = unserialize(base64_decode(@$_SESSION['cartContents']));

        // Check if the cart item is valid
        if(@is_array($cartContents[$cartItemId])) {
        	
        	//lets add the stock back
    		if ($cartContents[$cartItemId]['stock']) {
        		$gateway = new ActiveOrderGateway($this->user);
	       		$gateway->removeCartItem($cartItemId,$cartContents[$cartItemId]['productId']);  
	       	}
        
            unset($cartContents[$cartItemId]);

            // Save it to the session
            $_SESSION['cartContents'] = base64_encode(serialize($cartContents));
        } 
    }

    /*
     * Function to push updates to a cart item
     */
     function updateCartItem($cartItemId, $params) {

        // Check if we got everything
        if($cartItemId == null) {

            // Destroy the cart as something went wrong
            $this->destroyCart();
        }

        // get the current cart
        $cartContents = unserialize(base64_decode(@$_SESSION['cartContents']));

        // Check if the ID we have is valid
        if(@is_array($cartContents[$cartItemId])) {
            foreach($params AS $key => $value) {
                @$cartContents[$cartItemId][$key] = $value;
            }

            // Save it to the session
            $_SESSION['cartContents'] = base64_encode(serialize($cartContents));

            // Save the new hash
            $_SESSION['cartHash'] = NE_Lib::generateSignupCartHash();

        } else {
            // Destroy the cart as something went wrong
            $this->destroyCart();
        }
        
     }

   	/*
	* Function that removes any active_orders entries for these cart items
	* since the order has been completed there isn't an active order any longer.
	* This prevents the expires datetime to be accidently reached by another function
	* and readding the stock items for a product that was purchased
	*
	*/
	function orderCompleted()
	{
            $sqlItems = array();
            $cartItems = unserialize(base64_decode(@$_SESSION['cartContents']));
            if (is_array($cartItems)) {
                foreach($cartItems AS $item) {
                    if ( isset($item['cartItemId']) ) {
                        $sqlItems[] = "'".$item['cartItemId']."'";
                    }
                }
            }

            if (count($sqlItems > 0)) {
                $items = implode(",", $sqlItems);
                $sql = "delete from active_orders where id IN($items)";
                $this->db->query($sql);
            }
	}

    /*
     * Function to destroy the cart
     */
    function destroyCart() {
        //we should loop to see which cart items have stock enabled
        //so that we can readd the stock properly (so lets remove from cart properly)        
        $cartItems = unserialize(base64_decode(@$_SESSION['cartContents']));
        if (is_array($cartItems)) {
	        foreach($cartItems AS $item) {
	          if(isset($item['cartItemId'])){
	        	    $this->removeFromCart($item['cartItemId']);
	        	}
	        }
        }
		
        // Destroy the cart contents
        $_SESSION['cartHash'] = null;
        unset($_SESSION['cartHash']);
        $_SESSION['cartContents'] = null;
        unset($_SESSION['cartContents']);
    }

    /*
     * Function to destroy the currency
     */
    function destroyCurrency() {

        //echo("Destroying Currency");

        // Destroy the currency
        $_SESSION['currency'] = null;
        unset($_SESSION['currency']);
    }

    /*
     * Function to destroy the invoice information
     */
    function destroyInvoiceInformation() {

        //echo("Destroying Invoice Information");

        // Destroy the invoice information
        $_SESSION['invoice_information'] = null;
        unset($_SESSION['invoice_information']);
    }

    /*
     * Function to handle the recurring amounts
     *
     */
    function recurringAmount($term, $recurringAmount, $type = 1) {

        if($term != 0) {
            @$this->runningTotal['recurringItem'][$type][$term] += $recurringAmount;
        }
    }

    //function runningTotal($term, $lineAmount, $setup = null, $type = 1, $hasCoupon = false, $couponRecurring = false, $amountAfterCoupon = null, $isAddon = null) {

    /*
     * Function to handle the subtotal calculation. We add the calculated line total
     * $term - Payment term of the line
     */
    function runningTotal($lineAmount, $setup = null) {

        // Add the total
        @$this->runningTotal['total'] += $lineAmount + $setup;
    }

    /*
     * Function to store the data for a product that's being ordered BEFORE its properly added to the cart
     */
    function addTempItem($params,$cartItemId=0) {

        // Get the current contents of the temp item
        $currentItem = $this->getTempItem();

        // Merge the arrays
        if(is_array($currentItem)) {
            $params = @array_merge($params, $currentItem);
        }

        // Save it to the session
        $_SESSION['tempCartItem'] = base64_encode(serialize($params));

        // Save the new hash
        $_SESSION['tempCartItemHash'] = $this->generateTempItemHash();
        $_SESSION['tempCartItemId'] = $cartItemId;
    }

    /*
     * Function to return a temp item's information to be added to the cart. There can only ever be 1 temp item.
     */
    function getTempItem() {

        if($this->generateTempItemHash() == @$_SESSION['tempCartItemHash'] && @$_SESSION['tempCartItemHash'] != null) {
            return unserialize(base64_decode(@$_SESSION['tempCartItem']));
        } else {
            return false;
        }
    }


    /*
     * Function to destroy a temp item once finished with it
     */
    function destroyTempItem($removeFromCart = false) {

		if (isset($_SESSION['tempCartItemId']) && $removeFromCart) {	
			$this->removeFromCart($_SESSION['tempCartItemId']);
		}

        // Destroy the cart contents
        $_SESSION['tempCartItemHash'] = null;
        $_SESSION['tempCartItem'] = null;
        $_SESSION['tempCartItemId'] = null;
        
        unset($_SESSION['tempCartItemHash']);
        unset($_SESSION['tempCartItem']);
        unset($_SESSION['tempCartItemId']);        
    }


    /*
     * Function to get a temp item's hash to ensure security
     */
    function generateTempItemHash() {

        // Check the session
        if(@$_SESSION['tempCartItem']) {

            // MD5 the base64 along with a unique string
            return md5($_SESSION['tempCartItem']."ClientExecOrderForm-TempItem");

        } else {
            return null;
        }
    }

	
	function _processCartSummary($params, $formLocation, $currentLocation)
	{	

            if($formLocation == 'domainReg') {

                // Instead of duplicating code, see if we have a temp item and add that first
                if(@$this->getTempItem()) {

                    // Add the product
                    // TODO: Support mutiple products
                    $tempItem = $this->getTempItem();

                    // Make the params to pass
                    $postParams = array('term' => $tempItem['term']);

                    // Add to the cart
                    $parentProduct = $this->addToCart($tempItem['product'], $tempItem);

                    $this->destroyTempItem(true);
                    
                    // Check if we have a subdomain posted to us & add it to the product if we do
                    if(isset($params['isSubdomain']) && ($params['isSubdomain'] == 'true' || $params['isSubdomain'] == true)) { 
                    
                    	// We do, so remove the (free) and add it to the product
                    	$subdomainTLD = explode(" ", $params['tld']);
                    	$subdomainTLD = @$subdomainTLD[0];
                    	
                    	$this->updateCartItem($parentProduct, array('bundledDomain' => $params['registerName'].".".$subdomainTLD));
                    }
                }

                $postParams = array();

                //  Handle Addons
                $addonFields = array();
                $customFields = array();
                foreach($_POST AS $key => $value) {

                        // Explode to look for custom fields
                        $explodePost = explode("_", $key);

                        // Check for custom fields
                        if(@$explodePost[0] == 'PCT') {
                            $customFields[$explodePost[1]] = $value;
                        }
                        
                        // Check for addons
                        if(@$explodePost[0] == 'addonSelect') {
                                $addonFields[$explodePost[1]] = $value;
                        }
                }

                $postParams['customFields'] = $customFields;
                // Add the addons
                $postParams['addons'] = $addonFields;

                // Work out what we are supposed to be doing with this domain
                if(@$params['domainAction'] == 'register') {

                        // Get any extra attributes
                        $extraAttributes = array();
                        foreach($params AS $key => $value) {

                                // Avoid trying to add a namesuggest domain that we don't want to use
                                if($value == '-1') {
                                        continue;
                                }

                                $keyExplode = explode("-", $key);

                                // Fix for . being removed from vars
                                @$keyExplode[0] = str_replace("_", ".", @$keyExplode[0]);

                                // Get some extra attributes
                                if(@$keyExplode[1] == 'EA') {
                                        $extraAttributes[$keyExplode[0]][$keyExplode[2]] = $value;

                                }
                        }

                        // We are registering, so work out what to do
                        foreach($params AS $key => $value) {

                                // Avoid trying to add a namesuggest domain that we don't want to use
                                if($value == '-1') {
                                        continue;
                                }

                                // try exploding the key
                                $keyExplode = explode("-", $key);

                                // See if it was a domain
                                if(@$keyExplode[1] == 'registrationTerm') {

                                        // Fix for . being removed from vars
                                        @$keyExplode[0] = str_replace("_", ".", @$keyExplode[0]);

                                        $postParams['term'] = @$value;
                                        $postParams['isDomain'] = true;
                                        $postParams['domainType'] = '0';
                                        $postParams['sld'] = $params['registerName'];
                                        $postParams['tld'] = @$keyExplode[0];
                                        $postParams['extraAttributes'] = @$extraAttributes[@$keyExplode[0]];

                                        // Add to the cart
                                        $domainProduct = $this->addToCart($params['product'], $postParams);

                                        // Push domain up to parent product if we have it
                                        if(@$parentProduct) {
                                                $this->updateCartItem($parentProduct, array('bundledDomain' => $domainProduct));
                                        }
                                }
                        }

                } elseif(@$params['domainAction'] == 'transfer') {
                    // If we are forcing the checklist, ensure they have checked both boxes
                    // ToDo:
                   // When we have support for validation in PHP, we need to add this:
                    /*if ( $this->settings->get('Force Transfer Checklist') )  {
                        if ( !isset($_REQUEST['domain_unlocked']) || !isset($_REQUEST['private_registration']) ) {

                        }
                    }*/

                    // Transferring a domain
                    $postParams['term'] = @$params['transferTerm'];
                    $postParams['isDomain'] = true;
                    $postParams['domainType'] = 1;
                    $postParams['sld'] = $params['transferName'];
                    $postParams['tld'] = $params['transferTld'];
                    $postParams['extraAttributes'] = array('eppCode' => @$_REQUEST['eppCode']);

                    // Add to the cart
                    $domainProduct = $this->addToCart($params['product'], $postParams);

                    // Push domain up to parent product if we have it
                    if(@$parentProduct) {
                            $this->updateCartItem($parentProduct, array('bundledDomain' => $domainProduct));
                    }
                } elseif(@$params['domainAction'] == 'subdomain') {

                        // We don't want to actually add the domain we entered to CE so just push the bundled domain
                        if(@$parentProduct) {
                                $this->updateCartItem($parentProduct, array('bundledDomain' => $params['subDomain'].".".$params['subDomainTld']));
                        }

                } elseif(@$params['domainAction'] == 'manage') {

                        // We don't want to actually add the domain we entered to CE so just push the bundled domain
                        if(@$parentProduct) {
                                $this->updateCartItem($parentProduct, array('bundledDomain' => $params['manageName']));
                        }
                }

            } elseif($formLocation == 'configureProduct') {

                // Handle custom fields
                if(@$this->getTempItem()) {

                    // Add the product
                    // TODO: Support mutiple products
                    $tempItem = $this->getTempItem();

                    // Make the params to pass
                    $postParams = array('term' => $tempItem['term']);

                    // Process the posted custom fields
                    $customFields = array();
                    $addonFields = array();
                    foreach($_POST AS $key => $value) {

                        // Explode to look for custom fields
                        $explodePost = explode("_", $key);

                        // Check for custom fields
                        if(@$explodePost[0] == 'PCT') {

                            // Check if wehave a domain name field
                            if(isset($explodePost[2])) {
                                // We could have a subdomain so handle that
                                if(isset($_POST['subDomainTld']) && $_POST['subDomainTld'] != '0') {
                                    $customFields[$explodePost[1]] = $value.".".$_POST['subDomainTld'];
                                } else {
                                    $customFields[$explodePost[1]] = $value;
                                }
                            } else {
                                $customFields[$explodePost[1]] = $value;
                            }
                        }

                        // Check for addons
                        if(@$explodePost[0] == 'addonSelect') {
                            $addonFields[$explodePost[1]] = $value;
                        }
                    }

                    // Add the two
                    $postParams['customFields'] = $customFields;
                    $postParams['addons'] = $addonFields;

                    // Add to the cart
                    $parentProduct = $this->addToCart($tempItem['product'], $postParams);

                    $this->destroyTempItem(true);
                }
            }
	}


    /*
     * Function to process the data from a form post and then work out what to do next
     *
     * Returns an array of information on what we should be doing next.
     * - nextURL
     * - childProduct
     *
     * @input array - Array of form post data, can be sanitized or just pass $_POST
     * @input string - Location of the form that posted to us, can be static, usually pass $_REQUEST['formid']
     * @input string - Location of the page that is calling this function
     * 
     * @return array Information on what to do next
     */
    function processFormPost($params, $formLocation, $currentLocation) {
    	$cartItemId = 0;
    	//creating to cart immediately after selecting the product
        if($formLocation == 'packageSelect') {
  
            // We got straight here from a product, so just add it
            if(@$params['product']) {            
                // Make the params to pass
                $postParams = array('term' => @$params['priceTerm']);
                // Add to the cart
                $cartItemId = $this->addToCart($params['product'], $postParams);
            }
            // Destroy the temp item just to be safe
            $this->destroyTempItem(true);
        }


        // If we are being called by the cart summary we need to add to the cart
        if($currentLocation == 'cartSummary') {
			$this->_processCartSummary($params, $formLocation, $currentLocation);

        } elseif($currentLocation == 'domainReg') {
        	if(isset($_SESSION['tempCartItemId'])) $cartItemId = $_SESSION['tempCartItemId'];
            $this->addTempItem(array('product' => @$_REQUEST['product'], 'term' => @$_REQUEST['priceTerm']),$cartItemId);
        } elseif($currentLocation == 'configureProduct') {
        	//adding a temp item that we will add to after configuration of product
            //Currently all we need to do here is add the temp item
        	if(isset($_SESSION['tempCartItemId'])) $cartItemId = $_SESSION['tempCartItemId'];            
            $this->addTempItem(array('product' => @$_REQUEST['product'], 'term' => @$_REQUEST['priceTerm']),$cartItemId);
        } else {
            // Handle the temp item

        }
        return $cartItemId;
 
    }

    /*
     * Function to get the user viewable custom fields.
     * Re-written to not use loads of utterly stupid code
     */
    function getCustomProfileFields($value = null) {

        // Get the countries
        $countries = new Countries($this->user);

        // Set the array
        $profileFields = array();

        // Disable password injection
        $injectPassword = false;

        // Get custom fields
        $query = "SELECT id, `desc`, type, name, isRequired, width, isChangable, dropdownoptions "
                ."FROM customuserfields "
                ."WHERE insignup=1 and (isadminonly=0 OR isadminonly=2) AND company_id=? "
                ."ORDER BY myOrder";
        $result = $this->db->query($query, NE_Registry::getCompany()->getId());
        while (list($tID,$desc,$tType,$tName,$tisRequired,$tWidth,$tChangable,$dropdownoptions) = $result->fetch()) {


            // Password injection
            if($injectPassword == true) {

                $customField = array();
                $customField['isRequired'] = $tisRequired;
                $customField['fieldId'] = 'password';
                $customField['rowLabel'] = $this->lang('Password');
                $customField['fieldType'] = 'password';
                $customField['validationClass'] = 'password';

                // Add it
                $profileFields[] = $customField;


                $customField = array();
                $customField['isRequired'] = $tisRequired;
                $customField['fieldId'] = 'password_again';
                $customField['rowLabel'] = $this->lang('Password Again');
                $customField['fieldType'] = 'password';
                $customField['validationClass'] = 'password_again';

                // Add it
                $profileFields[] = $customField;

                // Disable password injection
                $injectPassword = false;

            }

            // STart the array
            $customField = array();

            // save the real name
            $tOriginalName = $tName;

            // Set some basic fields
            $customField['isRequired'] = $tisRequired;
            $customField['rawName'] = $tName;
            $customField['fieldId'] =$tID;
            $customField['rowLabel'] = $this->varLang($tName);
            $customField['fieldWidth'] = $tWidth;
            $customField['fieldDescription'] = $desc;

            // Get a value if we have one
            $customField['value'] = @$value['CT_'.$tID];

            // Handle the different field types
            if ($tType==typeLANGUAGE) {

                // Set the field type
                $customField['fieldType'] = 'language';

                // if there isn't any language set up for this customer, show the default one as selected
                $defaultLang = $this->settings->getLanguage();

                // Get the laguages from the text files
                $d = dir("language");
                $languages = array();
                while (false !== ($tentry = $d->read())) {
                    if ($tentry != '.' && $tentry != '..' && $tentry != 'CVS' && strpos($tentry, '.txt') !== false && strtolower($tentry) != 'words.txt') {
                        $tkey = ucfirst(strtolower(mb_substr($tentry, 0, -4)));
                        $languages[$tkey] = $this->varLang($tkey);
                    }
                }
                $d->close();
                asort($languages);

                $tempLanguages = array();
                foreach($languages AS $key => $entry){
                    $tempLanguage = array();
                    $tempLanguage['typeLanguageOptionValue'] =$key;
                    $tempLanguage['typeLanguageOptionSelected'] = ($customField['value'] == $key || $defaultLang == $key)? 'selected="selected"' : '';
                    $tempLanguage['typeLanguageOptionLabel'] =$entry;
                    $tempLanguages[] = $tempLanguage;
                }
                $customField['languages'] = $tempLanguages;
                
            } elseif ($tType==typeTEXTAREA) {

                // Set the field type
                $customField['fieldType'] = 'textarea';

                // Default value
                //$customField['value'] = @$_SESSION['previous_data']['CT_'.$tID];

            } elseif ($tType==typeDROPDOWN) {

                // Set the field type
                $customField['fieldType'] = 'dropdown';

                $script_name_array = explode(",", trim($dropdownoptions));

                //
                $tempDropdownOptions = array();
                foreach ($script_name_array as $option) {
                    $tempDropdown = array();

                    if (preg_match('/(.*)(?<!\\\)\((.*)(?<!\\\)\)/', $option, $matches)) {
                        $valueDropDown = $matches[2];
                        $label = $matches[1];
                    } else {
                        $valueDropDown = $label = $option;
                    }
                    $label = str_replace(array('\\(', '\\)'), array('(', ')'), $label);
                    $selected = (($valueDropDown == $customField['value'])? 'selected="selected"' : '');

                    $tempDropdown["typeDropdownOptionValue"] = $valueDropDown;
                    $tempDropdown["typeDropdownOptionSelected"] = $selected;
                    $tempDropdown["typeDropdownOptionLabel"] = $label;
                    $tempDropdownOptions[] = $tempDropdown;
                }

                // Add the options
                $customField['dropdownoptions'] = $tempDropdownOptions;

            } elseif ($tType==typeCOUNTRY) {

                // Set the field type
                $customField['fieldType'] = 'country';

                // Get list of countries
                if ( strlen($customField['value']) > 0 ) {
                    $tCountryCode = $customField['value'];
                } else {
                    $tCountryCode = $this->settings->get("Default Country");
                    $ip = NE_Network::getRemoteAddr();
                    if($ip !== false){
                        $CountryCode = NE_Network::getCountryCodeFromIP($ip);
                        if($CountryCode !== false){
                            $validCountryCode = $countries->validCountryCode($CountryCode, true);
                            if($validCountryCode !== false){
                                $tCountryCode = $validCountryCode;
                            }
                        }
                    }

                }
                $customField['countries'] = $countries->getCodes($tCountryCode, $this, true, true);

            } elseif ($tType==typeYESNO || $tType == typeALLOWEMAIL) {
               
                // Set the field type
                $customField['fieldType'] = 'yesno';

                if ( isset($customField['value']) ) {
                    if ($customField['value'] == 1){
                        $customField['yesSelected'] = 'selected="selected"';
                        $customField['noSelected'] = '';
                    } else {
                        $customField['yesSelected'] = '';
                        $customField['noSelected'] = 'selected="selected"';
                    }
                } else {
                    $customField['yesSelected'] = 'selected="selected"';
                    $customField['noSelected'] = '';
                }

            } elseif ($tType==TYPEDATE) {
                
                // Set the field type
                $customField['fieldType'] = 'date';

                // We store the date as yyyy-mm-dd so convert to the proper date format
                $tValue = NE_Lib::db_to_form($customField['value'], $this->settings->get('Date Format'), "/");
                if ($this->settings->get('Date Format') == 'm/d/Y') {
                    $dateFormat = '%m/%d/%Y';
                } else {
                    $dateFormat = '%d/%m/%Y';
                }

                //$customField['value'] = $tValue;
                $customField['dateFormat'] = $dateFormat;
                $customField['typeDateConstant'] = TYPEDATE;

            } elseif ($tType==typeVATNUMBER) {

                $customField['fieldType'] = 'vat';

                // Only show the VAT custom field if there is a tax rule using VAT.
                $query = "SELECT COUNT(*) FROM `taxrule` WHERE `vat`='1'";
                $vatResult = $this->db->query($query);
                $vatRow = $vatResult->fetch();

                if($vatRow[0] < 1){
                    continue;
                }

            } elseif ($tType == typeSTATE) {

                // Force the field to type text
                $customField['fieldType'] = 'state';
                $customField['fieldSize'] = '20';
                
            } elseif ($tType == typeZIPCODE) {

                // Force the field to type text
                $customField['fieldType'] = 'text';
                $customField['fieldSize'] = '20';
                
            } elseif ($tType == typeADDRESS) {

                // Force the field to type text
                $customField['fieldType'] = 'text';
                $customField['fieldSize'] = '40';

            } elseif ($tType==typeORGANIZATION) {

                $customField['checkedIsOrganization'] = false;
                $customField['fieldType'] = 'organization';
                //$customField['fieldDescription'] = $this->lang("Select the box if you want to designate this account as a business rather than an individual.");


            } elseif ($tType==typeEMAIL){

                $customField['fieldType'] = 'email';

                // Injector for password fields on next run
                if($tChangable == 2) {
                    $injectPassword = true;
                }

            } elseif ($tType==typePHONENUMBER){

                $customField['fieldType'] = 'phone';

            } else {

                // Force everything else to a text field
                $customField['fieldType'] = 'text';
            }

            $profileFields[] = $customField;

        }

        //print_r($profileFields);
        //exit;

        // Return it all
        return array('profileFields' => @$profileFields, 'arrRemove' => @$arrRemove, 'arrCustomFields' => @$arrCustomFields);
    }

    function getCustomFields($type, &$package=false) {

        $returnArray = array();

        $advancedSettings = @unserialize($package->advanced);

        if ($type == 'package') {
            $query = "SELECT id, name, fieldType, isRequired, dropDownOptions, `desc`, 20, groupId, subGroupId FROM customField WHERE groupId IN (?,?) AND InSignup = 1 AND inSettings = 1 ORDER BY groupId DESC, fieldOrder ASC";
            $result = $this->db->query($query, CUSTOM_FIELDS_FOR_PACKAGE, CUSTOM_FIELDS_FOR_PRODUCTTYPE);
            // If we don't have a domain product bundled to a hosting product, we need to inject a Domain name custom field to the start of the array
            if ($package->productGroup->fields['type'] == 1) {
                
                // Check if we have a domain product bundled
                $bundledProducts = $package->getBundledProducts();
                $hasDomainProduct = 0;

                // Check the array & Loop the products
                if (is_array($bundledProducts)) {
                    foreach ($bundledProducts AS $key) {

                        // Get the product
                        $bundledProduct = new Package($key);

                        // Check if the bundle is a domain
                        if ($bundledProduct->productGroup->fields['type'] == 3) {
                            $hasDomainProduct = 1;
                        }
                    }
                }

            }
        } else if ($type == 'profile') {
            $query = "SELECT id, name, type, isrequired, dropdownoptions, `desc`, width, 0, 0 "
                    ."FROM customuserfields "
                    ."WHERE insignup = 1 AND inSettings = 1 AND company_id=? "
                    ."ORDER BY myOrder ";
            $result = $this->db->query($query, NE_Registry::getCompany()->getId());
        }

        while (list($tID, $tName, $tType, $tRequired, $dropdownoptions, $desc, $width, $groupId, $subGroupId) = $result->fetch(MYSQL_NUM)) {
            if ($type == 'package') {
                // Check to ensure if we are to show this custom field for the product group.
                if ($groupId == CUSTOM_FIELDS_FOR_PACKAGE && $subGroupId != 0) {
                    $innerQuery = "SELECT * FROM promotion_customdomainfields WHERE promotionid=? AND customid=?";
                    $innerResult = $this->db->query($innerQuery, $_REQUEST['productGroup'], $tID);
                    if ($innerResult->getNumRows() == 0) {
                        continue;
                    }
                }

                // Handle system added fields
                if ($groupId == 2) {
                    if ($package->productGroup->fields['type'] != $subGroupId)
                        continue;
                }
            }

            // Check if we are adding a domain name with a bundled package
            if((@$hasDomainProduct == 1 || @$advancedSettings['hostingcustomfields'] == 1) && (@$tName == 'Domain Name') && ($groupId!=CUSTOM_FIELDS_FOR_PACKAGE) ) {
                continue;
            }

            // Check if we are asking for domain username & password
            if(($this->settings->get("Prompt for domain username and password") == 0 || @$advancedSettings['hostingcustomfields'] == 1) && ((@$tName == 'User Name' || @$tName == 'Password') && ($groupId!=CUSTOM_FIELDS_FOR_PACKAGE) ) )  {
                continue;
            }
            
            // SSL Product, we need to check if usingInviteURL and disable fields
            if ( $package->productGroup->fields['type'] == 2 ) {
                if ( isset($advancedSettings['registrar']) ) {
                    include_once ("modules/admin/models/PluginGateway.php");
                    $pluginGateway = new PluginGateway($this->user);
                    $sslPlugin = $pluginGateway->getPluginByName('ssl', $advancedSettings['registrar']);
                    
                    if ( ($sslPlugin->usingInviteURL == true) && ($tName == 'Certificate CSR' || $tName == 'Certificate Admin Email') && ($groupId!=CUSTOM_FIELDS_FOR_PACKAGE) ) {
                        continue;
                    }
                }
            }

            $savedValue = '';
            $tmpArray = array();

            $tmpArray['id'] = $tID;
            $tmpArray['name'] = $tName;
            $tmpArray['type'] = $tType;
            $tmpArray['required'] = $tRequired;
            $tmpArray['class'] = ($tRequired) ? 'required' : 'txtbox';
            $tmpArray['savedValue'] = '';
            $tmpArray['desc'] = $desc;

            // Add isDomain to the array
            if(@$tName == 'Domain Name' && $groupId!=CUSTOM_FIELDS_FOR_PACKAGE) {
                $tmpArray['isDomain'] = true;
            }

            // Grab saved value if needbe
            if ($type == 'package') {
                if (( isset($_REQUEST['PCT_' . $tID]) ) && ( $_REQUEST['PCT_' . $tID] != '' )) {
                    $tmpArray['savedValue'] = htmlspecialchars($_REQUEST['PCT_' . $tID], ENT_QUOTES);
                }
            } else if ($type == 'profile') {
                if (( isset($_REQUEST['CT_' . $tID]) ) && ( $_REQUEST['CT_' . $tID] != '' )) {
                    $tmpArray['savedValue'] = htmlspecialchars($_REQUEST['CT_' . $tID], ENT_QUOTES);
                }
            }

            switch ($tType) {
                case typeCOUNTRY:
                    $countries = new Countries($this->user);
                    
                    if ( strlen($tmpArray['savedValue']) > 0 ) {
                        $tCountryCode = $tmpArray['savedValue'];
                    } else {
                        $tCountryCode = $this->settings->get("Default Country");
                        $ip = NE_Network::getRemoteAddr();
                        if($ip !== false){
                            $CountryCode = NE_Network::getCountryCodeFromIP($ip);
                            if($CountryCode !== false){
                                $validCountryCode = $countries->validCountryCode($CountryCode, true);
                                if($validCountryCode !== false){
                                    $tCountryCode = $validCountryCode;
                                }
                            }
                        }
                    }
                    $selectOptions = array();
                    $codes = $countries->getCodesArr(true);
                    foreach ( $codes as $code => $name )
                    {
                        $tmp['value'] = $code;
                        $tmp['selected'] = (($tCountryCode == $code) ? 'selected="selected"' : '');
                        $tmp['label'] = $name;
                        $selectOptions[] = $tmp;
                    }
                    $tmpArray['select_options'] = $selectOptions;
                    break;

                case typeYESNO:
                    // check saved value
                    if ($savedValue == "1") {
                        $selectedyes = "SELECTED";
                        $selectedno = "";
                    } else {
                        $selectedyes = "";
                        $selectedno = "SELECTED";
                    }

                    $tmpArray['selectedyes'] = $selectedyes;
                    $tmpArray['selectedno'] = $selectedno;
                    break;

                case typeDROPDOWN:
                    $script_name_array = explode(",", trim($dropdownoptions));
                    $selectOptions = array();

                    foreach ($script_name_array as $option) {
                        // Allows for a label to be different then the value:
                        // such as: value,label 2(value 2),value 3
                        if (preg_match('/(.*)(?<!\\\)\((.*)(?<!\\\)\)/', $option, $matches)) {
                            $value = $matches[2];
                            $label = $matches[1];
                        } else {
                            $value = $label = $option;
                        }

                        $label = str_replace(array('\\(', '\\)'), array('(', ')'), $label);
                        $selected = (($savedValue == $value) ? 'selected="selected"' : '');
                        $tmp = array();
                        $tmp['value'] = $value;
                        $tmp['selected'] = $selected;
                        $tmp['label'] = $label;
                        $selectOptions[] = $tmp;
                    }
                    $tmpArray['select_options'] = $selectOptions;
                    break;
            }

            $returnArray[] = $tmpArray;
        }
        return $returnArray;
    }

    function getAddons($productId = null, $priceTerm = null) {

        if(!$productId) {
            $productId = @$_REQUEST['product'];
        }
        if(!$priceTerm) {
            $priceTerm = @$_REQUEST['priceTerm'];
        }

        $currency = new Currency($this->user);
        // package addons
        $selectedAddons = array();
        if (isset($_REQUEST['addonChargesStr'])) {
            $selectedAddons = $this->_getPriceIds($_REQUEST['addonChargesStr']);
        }

        $returnArray = array();

        $packageAddonGateway = new PackageAddonGateway();
        $addons = $packageAddonGateway->getPackageAddons($productId, 'addonIterator');
        $thereArePackageAddons = false;
        $cycleLang = array(
            1 => $this->lang('Monthly'),
            3 => $this->lang('Quarterly'),
            6 => $this->lang('Semiannually'),
            12 => $this->lang('Annually'),
            24 => $this->lang('Every 2 years'),
        );

        while ($addon = $addons->fetch()) {
            //print_r($addon);
            $tmpArray = array();
            $lastid = null;

            $query = "SELECT style FROM package WHERE id=?";
            $result = $this->db->query($query, $productId);
            list($existStyle) = $result->fetch();

            $firstIteration = true;
            $thereAreAddonsOptions = false;

            $tmpArray['id'] = $addon->getId();
            $tmpArray['taxable'] = $addon->getTaxable() ? 1 : 0;
            $tmpArray['name'] = $addon->getName();
            $tmpArray['desc'] = $addon->getDescription();
            // Array to store all the differnent prices of the addon
            $tmpArray['prices'] = array();

            // loop over each cycle price
            foreach ($addon->getCyclePrices($priceTerm) as $price) {

                $priceOption = $price['detail'];

                if (!isset($price['setupFee'])) {
                    $price['setupFee'] = 0;
                }

                if (!isset($price['cycleFee'])) {
                    $price['cycleFee'] = 0;
                }

                if ($price['setupFee'] != 0 || $price['cycleFee'] != 0) {
                    $priceOption .= ': ';
                    if ($price['setupFee'] != 0) {
                        $priceOption .= $currency->format($this->currency, $price['setupFee'], true, false, "NONE", true) . ' ' . $this->lang('one time fee');
                        if ($price['cycleFee'] != 0) {
                            $priceOption .= ' ' . $this->lang('+') . ' ';
                        }
                    }
                    if ($price['cycleFee'] != 0) {
                        $priceOption .= $currency->format($this->currency, $price['cycleFee'], true, false, "NONE", true) . " " . $cycleLang[$price['cycle']];
                    }
                }

                $thereAreAddonsOptions = true;
                $tmpPriceArray = array();
                $tmpPriceArray['price_id'] = $price['id'];
                $tmpPriceArray['price'] = $priceOption;
                $tmpPriceArray['price_float'] = $currency->format($this->currency, $price['cycleFee']);
                $tmpPriceArray['recurringprice_cyle'] = $price['cycle'];
                $tmpPriceArray['setupprice_value'] = $currency->format($this->currency, (isset($price['setupFee']) && $price['setupFee'] > 0) ? $price['setupFee'] : 0);
                $tmpPriceArray['item_name'] = $price['detail'];
                $tmpPriceArray['item_price'] = $price['cycleFee'];
                $tmpPriceArray['item_setup'] = $price['setupFee'];

                // prorating for package addons
                list($tAddonPrice, $addonProratedPrice, $addonProratedDays, $addonProIncFollowing, $addonTmpNextBill, $addonProNextBill)
                        = $this->processProrating($this->settings->get('Prorate To Day'), $this->settings->get('Include Following Payment'), $price['cycle'], $price['cycleFee']);

                if ($price['cycle'] != 0) {
                    $tmpPriceArray['price_float_prorated'] = $addonProratedPrice;
                    $tmpPriceArray['next_bill_date'] = $addonProNextBill;
                } else {
                    $tmpPriceArray['price_float_prorated'] = 0;
                    $tmpPriceArray['next_bill_date'] = 0;
                }

                // Ensure we don't reinitialize the price array if it already exists
                if ($lastid != $price['id']) {
                    $lastid = $price['id'];
                }

                if (!(isset($existStyle)) || ($existStyle == 0)) {
                    // dropdown
                    if ($selectedAddons) {
                        if (in_array($price['id'], array_keys($selectedAddons))) {
                            $selArr = $selectedAddons[$price['id']];
                            $tmpPriceArray['price_selected'] = in_array($price['cycle'], $selArr) ? 'selected = "true"' : '';
                        } else {
                            $tmpPriceArray['price_selected'] = $firstIteration ? 'selected = "true"' : '';
                        }
                    } else {
                        $tmpPriceArray['price_selected'] = $firstIteration ? 'selected = "true"' : '';
                    }
                } else {
                    // radio buttons
                    if ($selectedAddons) {
                        if (in_array($price['id'], array_keys($selectedAddons))) {
                            $selArr = $selectedAddons[$price['id']];
                            $tmpPriceArray['price_selected'] = in_array($price['cycle'], $selArr) ? 'checked = "true"' : '';
                        } else {
                            $tmpPriceArray['price_selected'] = $firstIteration ? 'checked = "true"' : '';
                        }
                    } else {
                        $tmpPriceArray['price_selected'] = $firstIteration ? 'checked = "true"' : '';
                    }
                }
                $firstIteration = false;
                $tmpArray['prices'][] = $tmpPriceArray;
            }

            if ($thereAreAddonsOptions) {
                $thereArePackageAddons = true;

                if (!(isset($existStyle)) || ($existStyle == 0)) {
                    $tmpArray['radio_buttons'] = 0;
                } else {
                    $tmpArray['radio_buttons'] = 1;
                }
            }
            $returnArray[] = $tmpArray;
        }
        return $returnArray;
    }

}

?>
