Back to PhocacartOrder class

Method saveOrderMain

public
saveOrderMain
(mixed $data)

Method saveOrderMain - Source code

public function saveOrderMain($data)
{
    $msgSuffix = '<span id="ph-msg-ns" class="ph-hidden"></span>';
    $pC = PhocacartUtils::getComponentParameters();
    $min_order_amount = $pC->get('min_order_amount', 0);
    $stock_checkout = $pC->get('stock_checkout', 0);
    $stock_checking = $pC->get('stock_checking', 0);
    $unit_weight = $pC->get('unit_weight', '');
    $unit_volume = $pC->get('unit_volume', '');
    $unit_size = $pC->get('unit_size', '');
    $order_language = $pC->get('order_language', 0);
    $skip_shipping_method = $pC->get('skip_shipping_method', 0);
    $skip_payment_method = $pC->get('skip_payment_method', 0);
    // LANGUAGES
    $lang = Factory::getLanguage();
    $userLang = $lang->getTag();
    // Get language user uses in frontend
    $pLang = new PhocacartLanguage();
    $defaultLang = $pLang->getDefaultLanguage(0);
    // Get default language of frontend
    if ($order_language == 0) {
        // If the order should be stored in default language force it and and the end change it back so user get right message
        $pLang->setLanguage($defaultLang);
    }
    $uri = Uri::getInstance();
    $action = $uri->toString();
    $app = Factory::getApplication();
    $user = PhocacartUser::getUser();
    $guest = PhocacartUserGuestuser::getGuestUser();
    $cart = new PhocacartCartRendercheckout();
    $cart->setInstance(3);
    //order
    $cart->setType($this->type);
    $cart->setFullItems();
    $fullItems = $cart->getFullItems();
    $currency = PhocacartCurrency::getCurrency();
    if (empty($fullItems[0])) {
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_('COM_PHOCACART_SHOPPING_CART_IS_EMPTY');
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    $shippingId = $cart->getShippingId();
    $cart->addShippingCosts($shippingId);
    $shippingC = $cart->getShippingCosts();
    $payment = $cart->getPaymentMethod();
    $cart->addPaymentCosts($payment['id']);
    // validity of payment will be checked
    $paymentC = $cart->getPaymentCosts();
    $couponCart = $cart->getCoupon();
    $coupon = false;
    if (isset($couponCart['id']) && $couponCart['id'] > 0) {
        $couponO = new PhocacartCoupon();
        $couponO->setType($this->type);
        $couponO->setCoupon((int) $couponCart['id']);
        $coupon = $couponO->getCoupon();
    }
    if (!$coupon) {
        $coupon = $couponCart;
    }
    $cart->roundTotalAmount();
    $total = $cart->getTotal();
    // --------------------
    // TERMS AND CONDITIONS, PRIVACY
    // --------------------
    // checked in controller
    // --------------------
    // CHECK COUPON
    // --------------------
    if (isset($coupon['id']) && (int) $coupon['id'] > 0 && $cart->getCouponValid() == false) {
        $msg = Text::_('COM_PHOCACART_COUPON_INVALID_EXPIRED_REACHED_USAGE_LIMIT') . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        PhocacartPayment::removePayment(0, 1);
        return false;
    }
    // --------------------
    // CHECK OPENING TIMES
    // --------------------
    // Possible parameter: display message on info page: PhocacartTime::checkOpeningTimes(), Hide message on info page: PhocacartTime::checkOpeningTimes(0)
    if (PhocacartTime::checkOpeningTimes() == false) {
        // Message set in checkOpeningTimes() method
        return false;
    }
    // --------------------
    // CHECK GUEST USER
    // --------------------
    if ((!isset($user->id) || isset($user->id) && $user->id < 1) && $guest == false && !PhocacartPos::isPos()) {
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_('COM_PHOCACART_GUEST_CHECKOUT_DISABLED') . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    // --------------------
    // CHECK CAPTCHA
    // --------------------
    $pos = PhocacartPos::isPosView();
    $enable_captcha_checkout = PhocacartCaptcha::enableCaptchaCheckout();
    if ($enable_captcha_checkout && !$pos) {
        if (!PhocacartCaptchaRecaptcha::isValid()) {
            if ($order_language == 0) {
                $pLang->setLanguageBack($defaultLang);
            }
            $msg = Text::_('COM_PHOCACART_WRONG_CAPTCHA') . $msgSuffix;
            $app->enqueueMessage($msg, 'error');
            return false;
            // What happens when the CAPTCHA was entered incorrectly
            //$info = array();
            //$info['field'] = 'question_captcha';
        }
    }
    // --------------------
    // CHECK MINIMUM ORDER AMOUNT
    // --------------------
    if ($min_order_amount > 0 && $total[0]['brutto'] < $min_order_amount) {
        $price = new PhocacartPrice();
        $price->setCurrency($currency->id);
        $priceFb = $price->getPriceFormat($total[0]['brutto']);
        $priceFm = $price->getPriceFormat($min_order_amount);
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_('COM_PHOCACART_MINIMUM_ORDER_AMOUNT_NOT_MET_UPDATE_CART_BEFORE_ORDERING');
        $msg .= '<br />';
        $msg .= Text::_('COM_PHOCACART_MINIMUM_ORDER_AMOUNT_IS') . ': ' . $priceFm;
        $msg .= '<br />';
        $msg .= Text::_('COM_PHOCACART_YOUR_ORDER_AMOUNT_IS') . ': ' . $priceFb . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    // --------------------
    // CHECK STOCK VALIDITY
    // --------------------
    $stockValid = $cart->getStockValid();
    if ($stock_checking == 1 && $stock_checkout == 1 && $stockValid == 0) {
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_('COM_PHOCACART_PRODUCTS_NOT_AVAILABLE_IN_QUANTITY_OR_NOT_IN_STOCK_UPDATE_QUANTITY_BEFORE_ORDERING') . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    // --------------------
    // CHECK MIN QUANTITY
    // --------------------
    $minQuantityValid = $cart->getMinimumQuantityValid();
    if ($minQuantityValid == 0) {
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_('COM_PHOCACART_MINIMUM_ORDER_QUANTITY_OF_ONE_OR_MORE_PRODUCTS_NOT_MET_UPDATE_QUANTITY_BEFORE_ORDERING') . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    // --------------------
    // CHECK MIN MULTIPLE QUANTITY
    // --------------------
    $minMultipleQuantityValid = $cart->getMinimumMultipleQuantityValid();
    if ($minMultipleQuantityValid == 0) {
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_('COM_PHOCACART_MINIMUM_MULTIPLE_ORDER_QUANTITY_OF_ONE_OR_MORE_PRODUCTS_NOT_MET_UPDATE_QUANTITY_BEFORE_ORDERING') . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    // --------------------
    // CHECK IF PRODUCT OR ATTRIBUTES EXIST
    // --------------------
    $productsRemoved = $cart->getProductsRemoved();
    if (!empty($productsRemoved)) {
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        // Message is set by cart class
        //$msg = JText::_('') . $msgSuffix;
        //$app->enqueueMessage($msg, 'error');
        return false;
    }
    $db = Factory::getDBO();
    //JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_phocacart/tables');
    // ORDER
    $d = array();
    if ($guest) {
        $d['user_id'] = 0;
    } else {
        $d['user_id'] = (int) $user->id;
    }
    // SET STATUS
    // STATUS IS SET DIRECTLY
    // 1) here in order class - when ordering done $d['status_id']
    // 2) in phocacartorder.php model (administration - changing order)
    // 3) in phocacarteditstatus.php model (administration - changing status)
    // 4) or in e.g. payment methods through PhocacartOrderStatus::changeStatusInOrderTable method
    $statusId = $pC->get('default_order_status', 1);
    // Ordered (Pending) as default
    // Free Download
    // 1) All products are digital
    // 2) Order is zero price
    if (isset($total[0]['countdigitalproducts']) && isset($total[0]['countallproducts']) && (int) $total[0]['countdigitalproducts'] == $total[0]['countallproducts'] && $total[0]['brutto'] == 0 && $total[0]['netto'] == 0) {
        $statusId = $pC->get('default_order_status_free_download', 1);
        // Ordered (Pending) as default
    }
    //$dispatcher = J EventDispatcher::getInstance();
    $plugin = PluginHelper::importPlugin('pcp', htmlspecialchars(strip_tags($payment['method'])));
    if ($plugin) {
        $eventData = array();
        $eventData['pluginname'] = htmlspecialchars(strip_tags($payment['method']));
        Factory::getApplication()->triggerEvent('onPCPbeforeSaveOrder', array(&$statusId, (int) $payment['id'], $eventData));
        $d['status_id'] = (int) $statusId;
        // e.g. by POS Cash we get automatically the status as completed
    } else {
        $d['status_id'] = $statusId;
        // no plugin or no event found
    }
    $d['type'] = PhocacartType::getTypeByTypeArray($this->type);
    // Data order
    $d['comment'] = isset($data['phcomment']) ? $data['phcomment'] : '';
    $d['privacy'] = isset($data['privacy']) ? (int) $data['privacy'] : '';
    $d['terms'] = isset($data['phcheckouttac']) ? (int) $data['phcheckouttac'] : '';
    $d['newsletter'] = isset($data['newsletter']) ? (int) $data['newsletter'] : 0;
    // Data POS
    $d['amount_pay'] = isset($data['amount_pay']) ? $data['amount_pay'] : 0;
    $d['amount_tendered'] = isset($data['amount_tendered']) ? $data['amount_tendered'] : 0;
    $d['amount_change'] = isset($data['amount_change']) ? $data['amount_change'] : 0;
    $d['published'] = 1;
    $d['shipping_id'] = (int) $shippingId;
    $shippingParams = array();
    if ((int) $shippingId > 0 && isset($shippingC['params_shipping']) && !empty($shippingC['params_shipping']) && $shippingC['params_shipping'] != '') {
        $shippingParams = json_decode($shippingC['params_shipping'], true);
    }
    if ((int) $shippingId > 0 && isset($shippingC['method']) && $shippingC['method'] != '') {
        $shippingParams['method'] = htmlspecialchars(strip_tags($shippingC['method']));
    }
    if ((int) $shippingId > 0 && isset($shippingC['title']) && $shippingC['title'] != '') {
        $shippingParams['title'] = htmlspecialchars(strip_tags($shippingC['title']));
    }
    $shippingParams['total_weight'] = $total[0]['weight'];
    $shippingParams['total_length'] = $total[0]['length'];
    $shippingParams['total_width'] = $total[0]['width'];
    $shippingParams['total_height'] = $total[0]['height'];
    $shippingParams['total_volume'] = $total[0]['volume'];
    $d['params_shipping'] = json_encode($shippingParams);
    $d['payment_id'] = (int) $payment['id'];
    $paymentParams = array();
    if ((int) $payment['id'] > 0 && isset($paymentC['params_payment']) && !empty($paymentC['params_payment']) && $paymentC['params_payment'] != '') {
        $paymentParams = json_decode($paymentC['params_payment'], true);
    }
    if ((int) $payment['id'] > 0 && isset($paymentC['method']) && $payment['method'] != '') {
        $paymentParams['method'] = htmlspecialchars(strip_tags($payment['method']));
    }
    if ((int) $payment['id'] > 0 && isset($paymentC['title']) && $payment['title'] != '') {
        $paymentParams['title'] = htmlspecialchars(strip_tags($payment['title']));
    }
    $d['params_payment'] = json_encode($paymentParams);
    $d['coupon_id'] = (int) $coupon['id'];
    $d['currency_id'] = (int) $currency->id;
    $d['currency_code'] = $currency->code;
    $d['currency_exchange_rate'] = $currency->exchange_rate;
    $d['ip'] = !empty($_SERVER['REMOTE_ADDR']) ? (string) $_SERVER['REMOTE_ADDR'] : '';
    $user_agent = !empty($_SERVER['HTTP_USER_AGENT']) ? (string) $_SERVER['HTTP_USER_AGENT'] : '';
    $d['user_agent'] = substr($user_agent, 0, 200);
    $d['order_token'] = PhocacartUtils::getToken();
    $d['tax_calculation'] = $pC->get('tax_calculation', 0);
    $d['unit_weight'] = $unit_weight;
    $d['unit_volume'] = $unit_volume;
    $d['unit_size'] = $unit_size;
    $d['discount_id'] = $cart->getCartDiscountId();
    $d['vendor_id'] = $cart->getVendorId();
    $d['ticket_id'] = $cart->getTicketId();
    $d['unit_id'] = $cart->getUnitId();
    $d['section_id'] = $cart->getSectionId();
    $d['loyalty_card_number'] = $cart->getLoyaltyCartNumber();
    $d['user_lang'] = $userLang;
    $d['default_lang'] = $defaultLang;
    // --------------------
    // CHECK PAYMENT AND SHIPPING - TEST IF THE ORDER HAS RIGHT SHIPPING AND PAYMENT METHOD
    // --------------------
    $shippingClass = new PhocacartShipping();
    $shippingClass->setType($this->type);
    $paymentClass = new PhocacartPayment();
    $paymentClass->setType($this->type);
    if ($guest) {
        $address = PhocacartUserGuestuser::getUserAddressGuest();
    } else {
        $address = PhocacartUser::getUserAddress($user->id);
    }
    $dataAddress = array();
    $dataAddress['bcountry'] = isset($address[0]->country) && (int) $address[0]->country > 0 ? (int) $address[0]->country : 0;
    $dataAddress['bregion'] = isset($address[0]->region) && (int) $address[0]->region > 0 ? (int) $address[0]->region : 0;
    $dataAddress['scountry'] = isset($address[1]->country) && (int) $address[1]->country > 0 ? (int) $address[1]->country : 0;
    $dataAddress['sregion'] = isset($address[1]->region) && (int) $address[1]->region > 0 ? (int) $address[1]->region : 0;
    $country = $shippingClass->getUserCountryShipping($dataAddress);
    $region = $shippingClass->getUserRegionShipping($dataAddress);
    $zip = $shippingClass->getUserZipShipping($dataAddress);
    // Check Shipping method
    if ($shippingId > 0) {
        // 1) User selected some method
        //    - check if this method even exists
        //	  - and check if the selected method meets every criteria and rules to be selected
        //$shippingMethods	= $shippingClass->checkAndGetShippingMethod($shippingId); CANNOT BE USED BECAUSE OF DIFFERENT VARIABLES IN ORDER
        $shippingMethods = $shippingClass->getPossibleShippingMethods($total[0]['netto'], $total[0]['brutto'], $total[0]['quantity'], $country, $region, $zip, $total[0]['weight'], $total[0]['length'], $total[0]['width'], $total[0]['height'], $shippingId, 0);
    } else {
        // 2) No shipping method selected
        $shippingMethods = false;
    }
    $sOCh = array();
    // Shipping Options Checkout
    // PRODUCTTYPE - Digital products are even gift vouchers
    $sOCh['all_digital_products'] = isset($total[0]['countdigitalproducts']) && isset($total[0]['countallproducts']) && (int) $total[0]['countdigitalproducts'] == $total[0]['countallproducts'] ? 1 : 0;
    $shippingNotUsed = PhocacartShipping::isShippingNotUsed($sOCh);
    // REVERSE
    $shippingNotFoundAllowProceed = false;
    if (empty($shippingMethods) && $skip_shipping_method == 3) {
        // In case no shipping method will be found for customer even all rules were applied - allow proceeding order without selecting shipping method
        // THIS CASE CAN BE VENDOR ERROR (wrong setting of shipping methods) OR PURPOSE - be aware when using $skip_shipping_method = 3
        // Cooperates with components/com_phocacart/views/checkout/view.html.php 230
        // Find all possible shipping methods (without shipping method selected) to see if there is really no rule to display any method
        $shippingtMethodsAllPossible = $shippingClass->getPossibleShippingMethods($total[0]['netto'], $total[0]['brutto'], $total[0]['quantity'], $country, $region, $zip, $total[0]['weight'], $total[0]['length'], $total[0]['width'], $total[0]['height'], 0, 0);
        if (empty($shippingtMethodsAllPossible)) {
            $shippingNotFoundAllowProceed = true;
        }
    }
    if (!empty($shippingMethods)) {
        // IS OK - some shipping method was selected
    } else {
        if (empty($shippingMethods) && PhocacartPos::isPos()) {
            // IS OK - shipping method was not selected but we are in POS
        } else {
            if (empty($shippingMethods) && $shippingNotUsed) {
                // IS OK - shipping method was not selected but there is none for selecting (shipping methods intentionally not used in shop)
                //         a) no shipping method is used
                //         b) or e.g. all items in cart are downloadable products and in Phoca Cart options is set that in such case shipping need not to be selected
                $shippingId = 0;
                // Needed for payment method check
            } else {
                if ($shippingNotFoundAllowProceed) {
                    // IS OK
                    $shippingId = 0;
                } else {
                    if ($order_language == 0) {
                        $pLang->setLanguageBack($defaultLang);
                    }
                    $msg = Text::_('COM_PHOCACART_PLEASE_SELECT_RIGHT_SHIPPING_METHOD');
                    $app->enqueueMessage($msg, 'error');
                    return false;
                }
            }
        }
    }
    $country = $paymentClass->getUserCountryPayment($dataAddress);
    $region = $paymentClass->getUserRegionPayment($dataAddress);
    // Check Payment method
    if ($payment['id'] > 0) {
        // 1) User selected some method
        //    - check if this method even exists
        //	  - and check if the selected method meets every criteria and rules to be selected
        //$paymentMethods	= $paymentClass->checkAndGetPaymentMethod($payment['id']); CANNOT BE USED BECAUSE OF DIFFERENT VARIABLES IN ORDER
        $paymentMethods = $paymentClass->getPossiblePaymentMethods($total[0]['netto'], $total[0]['brutto'], $country, $region, $shippingId, $payment['id'], 0);
    } else {
        // 2) No payment method selected
        $paymentMethods = false;
    }
    $pOCh = array();
    // Payment Options Checkout
    $pOCh['order_amount_zero'] = $total[0]['brutto'] == 0 && $total[0]['netto'] == 0 ? 1 : 0;
    $paymentNotUsed = PhocacartPayment::isPaymentNotUsed($pOCh);
    // REVERSE
    $paymentNotFoundAllowProceed = false;
    if (empty($paymentMethods) && $skip_payment_method == 3) {
        // In case no payment method will be found for customer even all rules were applied - allow proceed order without payment
        // THIS CASE CAN BE VENDOR ERROR (wrong setting of shipping methods) OR PURPOSE - be aware when using $skip_shipping_method = 3
        // Cooperates with components/com_phocacart/views/checkout/view.html.php 270
        // Find all possible payments methods (without payment method selected) to see if there is really no rule to display any method
        $paymentMethodsAllPossible = $paymentClass->getPossiblePaymentMethods($total[0]['netto'], $total[0]['brutto'], $country, $region, $shippingId, 0, 0);
        if (empty($paymentMethodsAllPossible)) {
            $paymentNotFoundAllowProceed = true;
        }
    }
    if (!empty($paymentMethods)) {
        // IS OK
    } else {
        if (empty($paymentMethods) && PhocacartPos::isPos()) {
            // IS OK
        } else {
            if (empty($paymentMethods) && $paymentNotUsed) {
                // IS OK
                $paymentId = 0;
            } else {
                if ($paymentNotFoundAllowProceed) {
                    // IS OK
                    $paymentId = 0;
                } else {
                    if ($order_language == 0) {
                        $pLang->setLanguageBack($defaultLang);
                    }
                    $msg = Text::_('COM_PHOCACART_PLEASE_SELECT_RIGHT_PAYMENT_METHOD');
                    $app->enqueueMessage($msg, 'error');
                    return false;
                }
            }
        }
    }
    $row = Table::getInstance('PhocacartOrder', 'Table', array());
    if (!$row->bind($d)) {
        //throw new Exception($row->getError());
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_($row->getError()) . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    $row->date = gmdate('Y-m-d H:i:s');
    $row->modified = $row->date;
    if (!$row->check()) {
        //throw new Exception($row->getError());
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_($row->getErrorMsg()) . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    if (!$row->store()) {
        //throw new Exception($row->getError());
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        $msg = Text::_($row->getErrorMsg()) . $msgSuffix;
        $app->enqueueMessage($msg, 'error');
        return false;
    }
    // GET ID OF ORDER
    if ((int) $row->id > 0) {
        // Set Order Billing
        $orderBillingData = $this->saveOrderBilling($row->id, $row->date, $d['status_id']);
        // ADDRESS;
        //$address = PhocacartUser::getUserAddress($user->id); - set above
        // Type 0 is Billing Address
        if (isset($address[0]->type) && $address[0]->type == 0) {
            $this->cleanTable('phocacart_order_users', $row->id);
            $this->saveOrderUsers($address[0], $row->id);
        } else {
            if (isset($address[1]->type) && $address[1]->type == 0) {
                $this->cleanTable('phocacart_order_users', $row->id);
                $this->saveOrderUsers($address[1], $row->id);
            }
        }
        // Type 1 is Shipping Address
        if (isset($address[1]->type) && $address[1]->type == 1) {
            $this->saveOrderUsers($address[1], $row->id);
        } else {
            if (isset($address[0]->type) && $address[0]->type == 1) {
                $this->saveOrderUsers($address[0], $row->id);
            }
        }
        //PRODUCT
        if (!empty($fullItems[1])) {
            $this->cleanTable('phocacart_order_products', $row->id);
            $this->cleanTable('phocacart_order_attributes', $row->id);
            foreach ($fullItems[1] as $k => $v) {
                // While saving:
                // Check if attributes which are required were filled
                // Check if products can be accessed (include their categories)
                $orderProductId = $this->saveOrderProducts($v, $row->id);
                /*
                $v['id'] = product_id
                $row->id = order_id
                $orderProductId = order_product_id
                */
                if ($orderProductId > 0) {
                    // PRODUCT DISCOUNTS - we are here because we need Product ID and Order Product ID - both are different ids
                    $this->saveOrderProductDiscounts($orderProductId, $v['id'], $row->id, $k, $fullItems);
                }
                if ($orderProductId > 0) {
                    // DOWNLOAD - we are here because we need Product ID and Order Product ID - both are different ids
                    if (!isset($v['attributes'])) {
                        $v['attributes'] = false;
                    }
                    $this->saveOrderDownloads($orderProductId, $v['id'], $v['catid'], $row->id);
                }
                if ($orderProductId > 0) {
                    // DOWNLOAD - we are here because we need Product ID and Order Product ID - both are different ids
                    if (!isset($v['attributes'])) {
                        $v['attributes'] = false;
                    }
                    // User can buy gift coupons
                    // When user buys one the same coupon (quantity > 1) we need to create more coupons from one "product"
                    if (isset($v['quantity'])) {
                        for ($i = 1; $i <= (int) $v['quantity']; $i++) {
                            $this->saveOrderGiftCoupons($orderProductId, $v, $row->id, $k, $fullItems);
                        }
                    }
                }
                if ($orderProductId > 0) {
                    // UPDATE the number of sales of one product - to save sql queries in frontend
                    $this->updateNumberOfSalesOfProduct($orderProductId, $v['id'], $row->id);
                }
                if (!$orderProductId) {
                    // DELETE NEWLY CREATED ORDER WHEN FAIL (not accessible product, required option)
                    $this->deleteOrder($row->id);
                    $this->cleanTable('phocacart_order_products', $row->id);
                    $this->cleanTable('phocacart_order_attributes', $row->id);
                    $this->cleanTable('phocacart_order_users', $row->id);
                    $this->cleanTable('phocacart_order_product_discounts', $row->id);
                    $this->cleanTable('phocacart_order_discounts', $row->id);
                    $this->cleanTable('phocacart_order_coupons', $row->id);
                    $msg = Text::_('COM_PHOCACART_ORDER_NOT_EXECUTED_PRODUCT_NOT_ACCESSIBLE_OR_REQUIRED_ATTRIBUTE_OPTION_NOT_SELECTED');
                    $app->enqueueMessage($msg, 'error');
                    return false;
                }
            }
        }
        // DISCOUNTS
        $this->cleanTable('phocacart_order_discounts', $row->id);
        if ($total[2]['dnetto'] > 0) {
            $this->saveOrderDiscounts(Text::_('COM_PHOCACART_PRODUCT_DISCOUNT'), $total[2], $row->id);
        }
        if ($total[3]['dnetto'] > 0) {
            $this->saveOrderDiscounts(Text::_('COM_PHOCACART_CART_DISCOUNT'), $total[3], $row->id);
        }
        // COUPONS
        if (!empty($coupon)) {
            $this->cleanTable('phocacart_order_coupons', $row->id);
            $this->saveOrderCoupons($coupon, $total[4], $row->id);
            PhocacartCoupon::storeCouponCount((int) $coupon['id']);
            PhocacartCoupon::storeCouponCountUser((int) $coupon['id'], $d['user_id']);
        }
        // REWARD
        $this->cleanTable('phocacart_reward_points', $row->id);
        // REWARD DISCOUNT - user used the points to buy items
        if ($user->id > 0 && isset($total[0]['rewardproductusedtotal']) && (int) $total[0]['rewardproductusedtotal'] > 0) {
            $rewardProductTotal = -(int) $total[0]['rewardproductusedtotal'];
            $this->saveRewardPoints($user->id, $rewardProductTotal, $orderBillingData, 0, -1);
        }
        // REWARD POINTS + user get the points when buying items
        if ($user->id > 0 && isset($total[0]['points_received']) && (int) $total[0]['points_received'] > 0) {
            $this->saveRewardPoints($user->id, (int) $total[0]['points_received'], $orderBillingData, 0, 1);
        }
        // HISTORY AND ORDER STATUS
        $this->cleanTable('phocacart_order_history', $row->id);
        $notify = 0;
        $status = PhocacartOrderStatus::getStatus($d['status_id']);
        if (isset($status['email_customer'])) {
            $notify = $status['email_customer'];
        }
        // If vendor makes and order in POS e.g. then store his/her as the one who made the change
        $userReal = Factory::getUser();
        $this->saveOrderHistory($d['status_id'], $notify, $userReal->id, $row->id);
        // BE AWARE***********
        // $d is newly defined so use d2
        // *******************
        // TOTAL
        if (!empty($total[0])) {
            $this->cleanTable('phocacart_order_total', $row->id);
            $ordering = 1;
            $d2 = array();
            $d2['order_id'] = $row->id;
            $d2['amount_currency'] = 0;
            $d2['title_lang'] = '';
            $d2['title_lang_suffix'] = '';
            $d2['title_lang_suffix2'] = '';
            if (isset($total[1]['netto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_SUBTOTAL');
                $d2['title_lang'] = 'COM_PHOCACART_SUBTOTAL';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                $d2['type'] = 'netto';
                $d2['amount'] = $total[1]['netto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 1;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            // Reward Discount
            if (isset($total[5]['dnetto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_REWARD_DISCOUNT') . $total[5]['rewardproducttxtsuffix'];
                $d2['title_lang'] = 'COM_PHOCACART_REWARD_DISCOUNT';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = $total[5]['rewardproducttxtsuffix'];
                $d2['type'] = 'dnetto';
                $d2['amount'] = '-' . $total[5]['dnetto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 1;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            if (isset($total[5]['dbrutto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_REWARD_DISCOUNT') . $total[5]['rewardproducttxtsuffix'];
                $d2['title_lang'] = 'COM_PHOCACART_REWARD_DISCOUNT';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = $total[5]['rewardproducttxtsuffix'];
                $d2['type'] = 'dbrutto';
                $d2['amount'] = '-' . $total[5]['dbrutto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 0;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            // Product Discount
            if (isset($total[2]['dnetto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_PRODUCT_DISCOUNT');
                $d2['title_lang'] = 'COM_PHOCACART_PRODUCT_DISCOUNT';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                $d2['type'] = 'dnetto';
                $d2['amount'] = '-' . $total[2]['dnetto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 1;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            if (isset($total[2]['dbrutto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_PRODUCT_DISCOUNT');
                $d2['title_lang'] = 'COM_PHOCACART_PRODUCT_DISCOUNT';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                $d2['type'] = 'dbrutto';
                $d2['amount'] = '-' . $total[2]['dbrutto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 0;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            /*if (!empty($total[2]['tax'])) {
                  foreach($total[2]['tax'] as $k => $v) {
                      if ($v['tax'] > 0) {
                          $d2['title']	= $v['title'];
                          $d2['type']		= 'dtax';
                          $d2['amount']	= $v['tax'];
                          $d2['ordering']	= $ordering;
                          $this->saveOrderTotal($d2);
                          $ordering++;
                      }
                  }
              }*/
            // Cart Discount
            if (isset($total[3]['dnetto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_CART_DISCOUNT') . $total[3]['discountcarttxtsuffix'];
                $d2['title_lang'] = 'COM_PHOCACART_CART_DISCOUNT';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = $total[3]['discountcarttxtsuffix'];
                $d2['type'] = 'dnetto';
                $d2['amount'] = '-' . $total[3]['dnetto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 1;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            if (isset($total[3]['dbrutto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_CART_DISCOUNT') . $total[3]['discountcarttxtsuffix'];
                $d2['title_lang'] = 'COM_PHOCACART_CART_DISCOUNT';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = $total[3]['discountcarttxtsuffix'];
                $d2['type'] = 'dbrutto';
                $d2['amount'] = '-' . $total[3]['dbrutto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 0;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            /*if (!empty($total[3]['tax'])) {
                  foreach($total[3]['tax'] as $k => $v) {
                      if ($v['tax'] > 0) {
                          $d2['title']	= $v['title'];
                          $d2['type']		= 'dtax';
                          $d2['amount']	= $v['tax'];
                          $d2['ordering']	= $ordering;
                          $this->saveOrderTotal($d2);
                          $ordering++;
                      }
                  }
              }*/
            // Coupon Discount
            if (isset($total[4]['dnetto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_COUPON');
                $d2['title_lang'] = 'COM_PHOCACART_COUPON';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                if (isset($coupon['title']) && $coupon['title'] != '') {
                    $d2['title'] = $coupon['title'] . $total[4]['couponcarttxtsuffix'];
                    $d2['title_lang'] = $coupon['title'];
                    $d2['title_lang_suffix'] = '';
                    $d2['title_lang_suffix2'] = $total[4]['couponcarttxtsuffix'];
                }
                $d2['type'] = 'dnetto';
                $d2['amount'] = '-' . $total[4]['dnetto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 1;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            if (isset($total[4]['dbrutto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_COUPON');
                $d2['title_lang'] = 'COM_PHOCACART_COUPON';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                if (isset($coupon['title']) && $coupon['title'] != '') {
                    $d2['title'] = $coupon['title'] . $total[4]['couponcarttxtsuffix'];
                    $d2['title_lang'] = $coupon['title'];
                    $d2['title_lang_suffix2'] = $total[4]['couponcarttxtsuffix'];
                }
                $d2['type'] = 'dbrutto';
                $d2['amount'] = '-' . $total[4]['dbrutto'];
                $d2['ordering'] = $ordering;
                $d2['published'] = 0;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            /*if (!empty($total[4]['tax'])) {
                  foreach($total[4]['tax'] as $k => $v) {
                      if ($v['tax'] > 0) {
                          $d2['title']	= $v['title'];
                          $d2['type']		= 'dtax';
                          $d2['amount']	= $v['tax'];
                          $d2['ordering']	= $ordering;
                          $this->saveOrderTotal($d2);
                          $ordering++;
                      }
                  }
              }*/
            if (!empty($total[0]['tax'])) {
                foreach ($total[0]['tax'] as $k => $v) {
                    if ($v['tax'] > 0) {
                        $d2['title'] = $v['title'];
                        $d2['title_lang'] = $v['title'];
                        $d2['title_lang_suffix'] = '';
                        $d2['title_lang_suffix2'] = '';
                        $d2['type'] = 'tax';
                        $d2['amount'] = $v['tax'];
                        $d2['ordering'] = $ordering;
                        $d2['published'] = 1;
                        //$d2['item_id']	        = (int)$k;// ID (Type) of VAT (10% or 20%)
                        $taxKeyA = PhocacartTax::getTaxIdsFromKey($k);
                        $d2['item_id'] = (int) $taxKeyA['id'];
                        $d2['item_id_c'] = (int) $taxKeyA['countryid'];
                        $d2['item_id_r'] = (int) $taxKeyA['regionid'];
                        $this->saveOrderTotal($d2);
                        $ordering++;
                    }
                }
            }
            $d2['published'] = 1;
            // Shipping
            if (!empty($shippingC)) {
                if (isset($shippingC['nettotxt']) && isset($shippingC['netto'])) {
                    $d2['title'] = $shippingC['title'] . ' - ' . $shippingC['nettotxt'];
                    $d2['title_lang'] = $shippingC['title'];
                    $d2['title_lang_suffix'] = $shippingC['netto_title_lang'];
                    $d2['title_lang_suffix2'] = '';
                    $d2['type'] = 'snetto';
                    $d2['amount'] = $shippingC['netto'];
                    $d2['ordering'] = $ordering;
                    $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                    $this->saveOrderTotal($d2);
                    $ordering++;
                }
                if (isset($shippingC['taxtxt']) && isset($shippingC['tax']) && $shippingC['tax'] > 0) {
                    $d2['title'] = $shippingC['title'] . ' - ' . $shippingC['taxtxt'];
                    $d2['title_lang'] = isset($shippingC['title']) && $shippingC['title'] != '' ? $shippingC['title'] : $shippingC['tax_title_lang'];
                    $d2['title_lang_suffix'] = $shippingC['tax_title_suffix'];
                    $d2['title_lang_suffix2'] = '(' . $shippingC['tax_title_suffix2'] . ')';
                    $d2['type'] = 'stax';
                    //$d2['item_id']	        = (int)$shippingC['taxid'];
                    $taxKeyA = PhocacartTax::getTaxIdsFromKey($shippingC['taxkey']);
                    $d2['item_id'] = (int) $taxKeyA['id'];
                    $d2['item_id_c'] = (int) $taxKeyA['countryid'];
                    $d2['item_id_r'] = (int) $taxKeyA['regionid'];
                    $d2['amount'] = $shippingC['tax'];
                    $d2['ordering'] = $ordering;
                    $this->saveOrderTotal($d2);
                    $ordering++;
                }
                if (isset($shippingC['bruttotxt']) && isset($shippingC['brutto'])) {
                    $d2['title'] = $shippingC['title'] . ' - ' . $shippingC['bruttotxt'];
                    $d2['title_lang'] = $shippingC['title'];
                    $d2['title_lang_suffix'] = $shippingC['brutto_title_lang'];
                    $d2['title_lang_suffix2'] = '';
                    $d2['type'] = 'sbrutto';
                    $d2['amount'] = $shippingC['brutto'];
                    $d2['ordering'] = $ordering;
                    $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                    $this->saveOrderTotal($d2);
                    $ordering++;
                }
            }
            // Payment
            if (!empty($paymentC)) {
                if (isset($paymentC['nettotxt']) && isset($paymentC['netto'])) {
                    $d2['title'] = $paymentC['title'] . ' - ' . $paymentC['nettotxt'];
                    $d2['title_lang'] = $paymentC['title'];
                    $d2['title_lang_suffix'] = $paymentC['netto_title_lang'];
                    $d2['title_lang_suffix2'] = '';
                    $d2['type'] = 'pnetto';
                    $d2['amount'] = $paymentC['netto'];
                    $d2['ordering'] = $ordering;
                    $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                    $this->saveOrderTotal($d2);
                    $ordering++;
                }
                if (isset($paymentC['taxtxt']) && isset($paymentC['tax']) && $paymentC['tax']) {
                    $d2['title'] = $paymentC['title'] . ' - ' . $paymentC['taxtxt'];
                    $d2['title_lang'] = isset($paymentC['title']) && $paymentC['title'] != '' ? $paymentC['title'] : $paymentC['tax_title_lang'];
                    $d2['title_lang_suffix'] = $paymentC['tax_title_suffix'];
                    $d2['title_lang_suffix2'] = '(' . $paymentC['tax_title_suffix2'] . ')';
                    $d2['type'] = 'ptax';
                    //$d2['item_id']	        = (int)$paymentC['taxid'];
                    $taxKeyA = PhocacartTax::getTaxIdsFromKey($paymentC['taxkey']);
                    $d2['item_id'] = (int) $taxKeyA['id'];
                    $d2['item_id_c'] = (int) $taxKeyA['countryid'];
                    $d2['item_id_r'] = (int) $taxKeyA['regionid'];
                    $d2['amount'] = $paymentC['tax'];
                    $d2['ordering'] = $ordering;
                    $this->saveOrderTotal($d2);
                    $ordering++;
                }
                if (isset($paymentC['bruttotxt']) && isset($paymentC['brutto'])) {
                    $d2['title'] = $paymentC['title'] . ' - ' . $paymentC['bruttotxt'];
                    $d2['title_lang'] = $paymentC['title'];
                    $d2['title_lang_suffix'] = $paymentC['brutto_title_lang'];
                    $d2['title_lang_suffix2'] = '';
                    $d2['type'] = 'pbrutto';
                    $d2['amount'] = $paymentC['brutto'];
                    $d2['ordering'] = $ordering;
                    $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                    $this->saveOrderTotal($d2);
                    $ordering++;
                }
            }
            // Rounding
            if (isset($total[0]['rounding'])) {
                $d2['title'] = Text::_('COM_PHOCACART_ROUNDING');
                $d2['title_lang'] = 'COM_PHOCACART_ROUNDING';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                $d2['type'] = 'rounding';
                $d2['amount'] = $total[0]['rounding'];
                $d2['amount_currency'] = $total[0]['rounding_currency'];
                $d2['ordering'] = $ordering;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            // Brutto
            if (isset($total[0]['brutto'])) {
                $d2['title'] = Text::_('COM_PHOCACART_TOTAL');
                $d2['title_lang'] = 'COM_PHOCACART_TOTAL';
                $d2['title_lang_suffix'] = '';
                $d2['title_lang_suffix2'] = '';
                $d2['type'] = 'brutto';
                $d2['amount'] = $total[0]['brutto'];
                $d2['amount_currency'] = $total[0]['brutto_currency'];
                $d2['ordering'] = $ordering;
                $d2['item_id'] = $d2['item_id_c'] = $d2['item_id_r'] = 0;
                $this->saveOrderTotal($d2);
                $ordering++;
            }
            // TAX RECAPITULATION
            if (isset($total[0]['taxrecapitulation'])) {
                $this->cleanTable('phocacart_order_tax_recapitulation', $row->id);
                $orderingTC = 1;
                $d3 = array();
                $d3['order_id'] = $row->id;
                if (!empty($total[0]['taxrecapitulation']['items'])) {
                    foreach ($total[0]['taxrecapitulation']['items'] as $kTc => $vTc) {
                        //$d3['item_id']					= (int)$kTc;
                        $taxKeyA = PhocacartTax::getTaxIdsFromKey($kTc);
                        $d3['item_id'] = (int) $taxKeyA['id'];
                        $d3['item_id_c'] = (int) $taxKeyA['countryid'];
                        $d3['item_id_r'] = (int) $taxKeyA['regionid'];
                        $d3['title'] = $vTc['title'];
                        $d3['title_lang'] = $vTc['title_lang'];
                        $d3['title_lang_suffix'] = '';
                        $d3['title_lang_suffix2'] = $vTc['title_lang_suffix2'];
                        $d3['type'] = 'tax';
                        $d3['amount_netto'] = $vTc['netto'];
                        $d3['amount_tax'] = $vTc['tax'];
                        $d3['amount_brutto'] = $vTc['brutto'];
                        $d3['amount_brutto_currency'] = $vTc['brutto_currency'];
                        $d3['ordering'] = $orderingTC;
                        $this->saveOrderTaxRecapitulation($d3);
                        $orderingTC++;
                    }
                }
                // Clean d3 for next rows
                $d3['item_id'] = 0;
                $d3['item_id_c'] = 0;
                $d3['item_id_r'] = 0;
                $d3['amount_netto'] = 0;
                $d3['amount_tax'] = 0;
                $d3['amount_brutto'] = 0;
                $d3['amount_brutto_currency'] = 0;
                $d3['title'] = Text::_('COM_PHOCACART_ROUNDING');
                $d3['title_lang'] = 'COM_PHOCACART_ROUNDING';
                $d3['title_lang_suffix'] = '';
                $d3['title_lang_suffix2'] = '';
                $d3['type'] = 'rounding';
                // Complete Rounding
                $d3['amount_brutto'] = $total[0]['rounding'];
                $d3['amount_brutto_currency'] = $total[0]['rounding_currency'];
                $d3['ordering'] = $orderingTC;
                $this->saveOrderTaxRecapitulation($d3);
                $orderingTC++;
                $d3['title'] = Text::_('COM_PHOCACART_ROUNDING') . ' (' . Text::_('COM_PHOCACART_INCL_TAX_RECAPITULATION_ROUNDING') . ')';
                $d3['title_lang'] = 'COM_PHOCACART_ROUNDING';
                $d3['title_lang_suffix'] = 'COM_PHOCACART_INCL_TAX_RECAPITULATION_ROUNDING';
                $d3['title_lang_suffix2'] = '';
                $d3['type'] = 'trcrounding';
                // Only Tax Recapitulation Rounding - tax recapitulation rounding is a part of whole rounding
                $d3['amount_brutto'] = $total[0]['taxrecapitulation']['rounding'];
                $d3['amount_brutto_currency'] = $total[0]['taxrecapitulation']['rounding_currency'];
                $d3['ordering'] = $orderingTC;
                $this->saveOrderTaxRecapitulation($d3);
                $orderingTC++;
                $d3['title'] = Text::_('COM_PHOCACART_TOTAL');
                $d3['title_lang'] = 'COM_PHOCACART_TOTAL';
                $d3['title_lang_suffix'] = '';
                $d3['title_lang_suffix2'] = '';
                $d3['type'] = 'brutto';
                $d3['amount_netto'] = $total[0]['taxrecapitulation']['netto_incl_sp'];
                $d3['amount_tax'] = $total[0]['taxrecapitulation']['tax'];
                //$d3['amount_brutto']			= $total[0]['taxrecapitulation']['brutto'];
                $d3['amount_brutto'] = $total[0]['taxrecapitulation']['brutto_incl_rounding'];
                //$d3['amount_brutto_currency']	= $total[0]['taxrecapitulation']['brutto_currency'];
                $d3['amount_brutto_currency'] = $total[0]['taxrecapitulation']['brutto_currency_incl_rounding'];
                $d3['ordering'] = $orderingTC;
                $this->saveOrderTaxRecapitulation($d3);
                $orderingTC++;
            }
        }
        // EVENT Shipping
        if ((int) $shippingId > 0 && isset($shippingC['method']) && $shippingC['method'] != '') {
            PluginHelper::importPlugin('pcs', htmlspecialchars(strip_tags($shippingC['method'])));
            $eventData = array();
            $eventData['pluginname'] = htmlspecialchars(strip_tags($shippingC['method']));
            $eventData['id'] = (int) $row->id;
            Factory::getApplication()->triggerEvent('onPCSafterSaveOrder', array('com_phocacart.library.order', $eventData));
        }
        // CHANGE STATUS
        // STOCK MOVEMENT (including a) Main Product, b) Product Variations method)
        // Change Status is not setting the status, it is about do getting info about status for sending emails, checking stock,
        if ($guest) {
            // Don't check the user (status.php, render.php)
            PhocacartOrderStatus::changeStatus($row->id, $d['status_id'], $d['order_token']);
            // Notify user, notify others, emails send - will be decided in function
        } else {
            PhocacartOrderStatus::changeStatus($row->id, $d['status_id']);
            // Notify user, notify others, emails send - will be decided in function
        }
        // Proceed or not proceed to payment gateway - depends on payment method
        // By every new order - clean the proceed payment session
        $session = Factory::getSession();
        $session->set('proceedpayment', array(), 'phocaCart');
        $response = PhocacartPayment::proceedToPaymentGateway($payment);
        $proceed = $response['proceed'];
        $this->message_after_order = $response['message'];
        if ($proceed) {
            $proceedPayment['orderid'] = $row->id;
            $session->set('proceedpayment', $proceedPayment, 'phocaCart');
            if ($this->downloadable_product == 1) {
                $this->action_after_order = 4;
                // PAYMENT/DOWNLOAD
            } else {
                $this->action_after_order = 3;
                // PAYMENT/NO DOWNLOAD
            }
        } else {
            if ($this->downloadable_product == 1) {
                $this->action_after_order = 2;
                // ORDER/DOWNLOAD
            } else {
                $this->action_after_order = 1;
                // ORDER/NO DOWNLOAD
            }
        }
        $this->data_after_order['order_id'] = (int) $row->id;
        $this->data_after_order['order_token'] = $row->order_token;
        $this->data_after_order['user_id'] = (int) $row->user_id;
        $this->data_after_order['shipping_id'] = (int) $row->shipping_id;
        $this->data_after_order['payment_id'] = (int) $row->payment_id;
        $this->data_after_order['shipping_method'] = '';
        $shippingMethod = json_decode($row->params_shipping);
        if (isset($shippingMethod->method)) {
            $this->data_after_order['shipping_method'] = $shippingMethod->method;
        }
        $this->data_after_order['payment_method'] = '';
        $paymentMethod = json_decode($row->params_payment);
        if (isset($paymentMethod->method)) {
            $this->data_after_order['payment_method'] = $paymentMethod->method;
        }
        //return true;
        if ($order_language == 0) {
            $pLang->setLanguageBack($defaultLang);
        }
        // UPDATE NEWSLETTER INFO
        if ((int) $d['newsletter'] > 0 && (int) $user->id > 0) {
            $name = '';
            $email = '';
            $privacy = (int) $d['privacy'] == 1 ? 1 : 0;
            if (isset($user->name)) {
                $name = $user->name;
                // Guest Users (find some name in billing or shipping address)
            } else {
                if (isset($address[0]->name_first) && isset($address[0]->name_last)) {
                    $name = $address[0]->name_first . ' ' . $address[0]->name_last;
                } else {
                    if (isset($address[1]->name_first) && isset($address[1]->name_last)) {
                        $name = $address[1]->name_first . ' ' . $address[1]->name_last;
                    } else {
                        if (isset($address[0]->name_last)) {
                            $name = $address[0]->name_last;
                        } else {
                            if (isset($address[1]->name_last)) {
                                $name = $address[1]->name_last;
                            } else {
                                if (isset($address[0]->name_first)) {
                                    $name = $address[0]->name_first;
                                } else {
                                    if (isset($address[1]->name_first)) {
                                        $name = $address[1]->name_first;
                                    } else {
                                        if (isset($address[0]->name)) {
                                            $name = $address[0]->name;
                                        } else {
                                            if (isset($address[1]->name)) {
                                                $name = $address[1]->name;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (isset($user->email)) {
                $email = $user->email;
                // Guest Users
            } else {
                if (isset($address[0]->email)) {
                    $email = $address[0]->email;
                } else {
                    if (isset($address[1]->email)) {
                        $email = $address[1]->email;
                    }
                }
            }
            PhocacartNewsletter::updateNewsletterInfoByUser((int) $user->id, 1);
            // Internal Phoca Cart Table
            if ($name != '' && $email != '') {
                PhocacartNewsletter::storeSubscriber($name, $email, $privacy);
                // External Phoca Email Table
            }
        }
        return $row->id;
    } else {
        return false;
    }
    return false;
}