Esempio n. 1
0
 public function ajaxProcessAddProductOnOrder()
 {
     // Load object
     $order = new Order((int) Tools::getValue('id_order'));
     if (!Validate::isLoadedObject($order)) {
         die(Tools::jsonEncode(array('result' => false, 'error' => Tools::displayError('The order object cannot be loaded.'))));
     }
     if ($order->hasBeenShipped()) {
         die(Tools::jsonEncode(array('result' => false, 'error' => Tools::displayError('You cannot add products to delivered orders. '))));
     }
     $product_informations = $_POST['add_product'];
     if (isset($_POST['add_invoice'])) {
         $invoice_informations = $_POST['add_invoice'];
     } else {
         $invoice_informations = array();
     }
     $product = new Product($product_informations['product_id'], false, $order->id_lang);
     if (!Validate::isLoadedObject($product)) {
         die(Tools::jsonEncode(array('result' => false, 'error' => Tools::displayError('The product object cannot be loaded.'))));
     }
     if (isset($product_informations['product_attribute_id']) && $product_informations['product_attribute_id']) {
         $combination = new Combination($product_informations['product_attribute_id']);
         if (!Validate::isLoadedObject($combination)) {
             die(Tools::jsonEncode(array('result' => false, 'error' => Tools::displayError('The combination object cannot be loaded.'))));
         }
     }
     // Total method
     $total_method = Cart::BOTH_WITHOUT_SHIPPING;
     // Create new cart
     $cart = new Cart();
     $cart->id_shop_group = $order->id_shop_group;
     $cart->id_shop = $order->id_shop;
     $cart->id_customer = $order->id_customer;
     $cart->id_carrier = $order->id_carrier;
     $cart->id_address_delivery = $order->id_address_delivery;
     $cart->id_address_invoice = $order->id_address_invoice;
     $cart->id_currency = $order->id_currency;
     $cart->id_lang = $order->id_lang;
     $cart->secure_key = $order->secure_key;
     // Save new cart
     $cart->add();
     // Save context (in order to apply cart rule)
     $this->context->cart = $cart;
     $this->context->customer = new Customer($order->id_customer);
     // always add taxes even if there are not displayed to the customer
     $use_taxes = true;
     $initial_product_price_tax_incl = Product::getPriceStatic($product->id, $use_taxes, isset($combination) ? $combination->id : null, 2, null, false, true, 1, false, $order->id_customer, $cart->id, $order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)});
     // Creating specific price if needed
     if ($product_informations['product_price_tax_incl'] != $initial_product_price_tax_incl) {
         $specific_price = new SpecificPrice();
         $specific_price->id_shop = 0;
         $specific_price->id_shop_group = 0;
         $specific_price->id_currency = 0;
         $specific_price->id_country = 0;
         $specific_price->id_group = 0;
         $specific_price->id_customer = $order->id_customer;
         $specific_price->id_product = $product->id;
         if (isset($combination)) {
             $specific_price->id_product_attribute = $combination->id;
         } else {
             $specific_price->id_product_attribute = 0;
         }
         $specific_price->price = $product_informations['product_price_tax_excl'];
         $specific_price->from_quantity = 1;
         $specific_price->reduction = 0;
         $specific_price->reduction_type = 'amount';
         $specific_price->from = '0000-00-00 00:00:00';
         $specific_price->to = '0000-00-00 00:00:00';
         $specific_price->add();
     }
     // Add product to cart
     $update_quantity = $cart->updateQty($product_informations['product_quantity'], $product->id, isset($product_informations['product_attribute_id']) ? $product_informations['product_attribute_id'] : null, isset($combination) ? $combination->id : null, 'up', 0, new Shop($cart->id_shop));
     if ($update_quantity < 0) {
         // If product has attribute, minimal quantity is set with minimal quantity of attribute
         $minimal_quantity = $product_informations['product_attribute_id'] ? Attribute::getAttributeMinimalQty($product_informations['product_attribute_id']) : $product->minimal_quantity;
         die(Tools::jsonEncode(array('error' => sprintf(Tools::displayError('You must add %d minimum quantity', false), $minimal_quantity))));
     } elseif (!$update_quantity) {
         die(Tools::jsonEncode(array('error' => Tools::displayError('You already have the maximum quantity available for this product.', false))));
     }
     // If order is valid, we can create a new invoice or edit an existing invoice
     if ($order->hasInvoice()) {
         $order_invoice = new OrderInvoice($product_informations['invoice']);
         // Create new invoice
         if ($order_invoice->id == 0) {
             // If we create a new invoice, we calculate shipping cost
             $total_method = Cart::BOTH;
             // Create Cart rule in order to make free shipping
             if (isset($invoice_informations['free_shipping']) && $invoice_informations['free_shipping']) {
                 $cart_rule = new CartRule();
                 $cart_rule->id_customer = $order->id_customer;
                 $cart_rule->name = array(Configuration::get('PS_LANG_DEFAULT') => $this->l('[Generated] CartRule for Free Shipping'));
                 $cart_rule->date_from = date('Y-m-d H:i:s', time());
                 $cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600);
                 $cart_rule->quantity = 1;
                 $cart_rule->quantity_per_user = 1;
                 $cart_rule->minimum_amount_currency = $order->id_currency;
                 $cart_rule->reduction_currency = $order->id_currency;
                 $cart_rule->free_shipping = true;
                 $cart_rule->active = 1;
                 $cart_rule->add();
                 // Add cart rule to cart and in order
                 $cart->addCartRule($cart_rule->id);
                 $values = array('tax_incl' => $cart_rule->getContextualValue(true), 'tax_excl' => $cart_rule->getContextualValue(false));
                 $order->addCartRule($cart_rule->id, $cart_rule->name[Configuration::get('PS_LANG_DEFAULT')], $values);
             }
             $order_invoice->id_order = $order->id;
             if ($order_invoice->number) {
                 Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $order->id_shop);
             } else {
                 $order_invoice->number = Order::getLastInvoiceNumber() + 1;
             }
             $invoice_address = new Address((int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)});
             $carrier = new Carrier((int) $order->id_carrier);
             $tax_calculator = $carrier->getTaxCalculator($invoice_address);
             $order_invoice->total_paid_tax_excl = Tools::ps_round((double) $cart->getOrderTotal(false, $total_method), 2);
             $order_invoice->total_paid_tax_incl = Tools::ps_round((double) $cart->getOrderTotal($use_taxes, $total_method), 2);
             $order_invoice->total_products = (double) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
             $order_invoice->total_products_wt = (double) $cart->getOrderTotal($use_taxes, Cart::ONLY_PRODUCTS);
             $order_invoice->total_shipping_tax_excl = (double) $cart->getTotalShippingCost(null, false);
             $order_invoice->total_shipping_tax_incl = (double) $cart->getTotalShippingCost();
             $order_invoice->total_wrapping_tax_excl = abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING));
             $order_invoice->total_wrapping_tax_incl = abs($cart->getOrderTotal($use_taxes, Cart::ONLY_WRAPPING));
             $order_invoice->shipping_tax_computation_method = (int) $tax_calculator->computation_method;
             // Update current order field, only shipping because other field is updated later
             $order->total_shipping += $order_invoice->total_shipping_tax_incl;
             $order->total_shipping_tax_excl += $order_invoice->total_shipping_tax_excl;
             $order->total_shipping_tax_incl += $use_taxes ? $order_invoice->total_shipping_tax_incl : $order_invoice->total_shipping_tax_excl;
             $order->total_wrapping += abs($cart->getOrderTotal($use_taxes, Cart::ONLY_WRAPPING));
             $order->total_wrapping_tax_excl += abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING));
             $order->total_wrapping_tax_incl += abs($cart->getOrderTotal($use_taxes, Cart::ONLY_WRAPPING));
             $order_invoice->add();
             $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl));
             $order_carrier = new OrderCarrier();
             $order_carrier->id_order = (int) $order->id;
             $order_carrier->id_carrier = (int) $order->id_carrier;
             $order_carrier->id_order_invoice = (int) $order_invoice->id;
             $order_carrier->weight = (double) $cart->getTotalWeight();
             $order_carrier->shipping_cost_tax_excl = (double) $order_invoice->total_shipping_tax_excl;
             $order_carrier->shipping_cost_tax_incl = $use_taxes ? (double) $order_invoice->total_shipping_tax_incl : (double) $order_invoice->total_shipping_tax_excl;
             $order_carrier->add();
         } else {
             $order_invoice->total_paid_tax_excl += Tools::ps_round((double) $cart->getOrderTotal(false, $total_method), 2);
             $order_invoice->total_paid_tax_incl += Tools::ps_round((double) $cart->getOrderTotal($use_taxes, $total_method), 2);
             $order_invoice->total_products += (double) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
             $order_invoice->total_products_wt += (double) $cart->getOrderTotal($use_taxes, Cart::ONLY_PRODUCTS);
             $order_invoice->update();
         }
     }
     // Create Order detail information
     $order_detail = new OrderDetail();
     $order_detail->createList($order, $cart, $order->getCurrentOrderState(), $cart->getProducts(), isset($order_invoice) ? $order_invoice->id : 0, $use_taxes, (int) Tools::getValue('add_product_warehouse'));
     // update totals amount of order
     $order->total_products += (double) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
     $order->total_products_wt += (double) $cart->getOrderTotal($use_taxes, Cart::ONLY_PRODUCTS);
     $order->total_paid += Tools::ps_round((double) $cart->getOrderTotal(true, $total_method), 2);
     $order->total_paid_tax_excl += Tools::ps_round((double) $cart->getOrderTotal(false, $total_method), 2);
     $order->total_paid_tax_incl += Tools::ps_round((double) $cart->getOrderTotal($use_taxes, $total_method), 2);
     if (isset($order_invoice) && Validate::isLoadedObject($order_invoice)) {
         $order->total_shipping = $order_invoice->total_shipping_tax_incl;
         $order->total_shipping_tax_incl = $order_invoice->total_shipping_tax_incl;
         $order->total_shipping_tax_excl = $order_invoice->total_shipping_tax_excl;
     }
     // discount
     $order->total_discounts += (double) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
     $order->total_discounts_tax_excl += (double) abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS));
     $order->total_discounts_tax_incl += (double) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
     // Save changes of order
     $order->update();
     // Update weight SUM
     $order_carrier = new OrderCarrier((int) $order->getIdOrderCarrier());
     if (Validate::isLoadedObject($order_carrier)) {
         $order_carrier->weight = (double) $order->getTotalWeight();
         if ($order_carrier->update()) {
             $order->weight = sprintf("%.3f " . Configuration::get('PS_WEIGHT_UNIT'), $order_carrier->weight);
         }
     }
     // Update Tax lines
     $order_detail->updateTaxAmount($order);
     // Delete specific price if exists
     if (isset($specific_price)) {
         $specific_price->delete();
     }
     $products = $this->getProducts($order);
     // Get the last product
     $product = end($products);
     $resume = OrderSlip::getProductSlipResume((int) $product['id_order_detail']);
     $product['quantity_refundable'] = $product['product_quantity'] - $resume['product_quantity'];
     $product['amount_refundable'] = $product['total_price_tax_incl'] - $resume['amount_tax_incl'];
     $product['amount_refund'] = Tools::displayPrice($resume['amount_tax_incl']);
     $product['return_history'] = OrderReturn::getProductReturnDetail((int) $product['id_order_detail']);
     $product['refund_history'] = OrderSlip::getProductSlipDetail((int) $product['id_order_detail']);
     if ($product['id_warehouse'] != 0) {
         $warehouse = new Warehouse((int) $product['id_warehouse']);
         $product['warehouse_name'] = $warehouse->name;
     } else {
         $product['warehouse_name'] = '--';
     }
     // Get invoices collection
     $invoice_collection = $order->getInvoicesCollection();
     $invoice_array = array();
     foreach ($invoice_collection as $invoice) {
         $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id, (int) $order->id_shop);
         $invoice_array[] = $invoice;
     }
     // Assign to smarty informations in order to show the new product line
     $this->context->smarty->assign(array('product' => $product, 'order' => $order, 'currency' => new Currency($order->id_currency), 'can_edit' => $this->tabAccess['edit'], 'invoices_collection' => $invoice_collection, 'current_id_lang' => Context::getContext()->language->id, 'link' => Context::getContext()->link, 'current_index' => self::$currentIndex, 'display_warehouse' => (int) Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')));
     $this->sendChangedNotification($order);
     die(Tools::jsonEncode(array('result' => true, 'view' => $this->createTemplate('_product_line.tpl')->fetch(), 'can_edit' => $this->tabAccess['add'], 'order' => $order, 'invoices' => $invoice_array, 'documents_html' => $this->createTemplate('_documents.tpl')->fetch(), 'shipping_html' => $this->createTemplate('_shipping.tpl')->fetch(), 'discount_form_html' => $this->createTemplate('_discount_form.tpl')->fetch())));
 }
Esempio n. 2
0
    /**
     * This method allows to generate first invoice of the current order
     */
    public function setInvoice($use_existing_payment = false)
    {
        if (!$this->hasInvoice()) {
            if ($id = (int) $this->hasDelivery()) {
                $order_invoice = new OrderInvoice($id);
            } else {
                $order_invoice = new OrderInvoice();
            }
            $order_invoice->id_order = $this->id;
            if (!$id) {
                $order_invoice->number = 0;
            }
            $address = new Address((int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $carrier = new Carrier((int) $this->id_carrier);
            $tax_calculator = $carrier->getTaxCalculator($address, $this->id, Configuration::get('PS_ATCP_SHIPWRAP'));
            $order_invoice->total_discount_tax_excl = $this->total_discounts_tax_excl;
            $order_invoice->total_discount_tax_incl = $this->total_discounts_tax_incl;
            $order_invoice->total_paid_tax_excl = $this->total_paid_tax_excl;
            $order_invoice->total_paid_tax_incl = $this->total_paid_tax_incl;
            $order_invoice->total_products = $this->total_products;
            $order_invoice->total_products_wt = $this->total_products_wt;
            $order_invoice->total_shipping_tax_excl = $this->total_shipping_tax_excl;
            $order_invoice->total_shipping_tax_incl = $this->total_shipping_tax_incl;
            $order_invoice->shipping_tax_computation_method = $tax_calculator->computation_method;
            $order_invoice->total_wrapping_tax_excl = $this->total_wrapping_tax_excl;
            $order_invoice->total_wrapping_tax_incl = $this->total_wrapping_tax_incl;
            // Save Order invoice
            $order_invoice->save();
            if (Configuration::get('PS_INVOICE')) {
                $this->setLastInvoiceNumber($order_invoice->id, $this->id_shop);
            }
            if (Configuration::get('PS_ATCP_SHIPWRAP')) {
                $wrapping_tax_calculator = Adapter_ServiceLocator::get('AverageTaxOfProductsTaxCalculator')->setIdOrder($this->id);
            } else {
                $wrapping_tax_manager = TaxManagerFactory::getManager($address, (int) Configuration::get('PS_GIFT_WRAPPING_TAX_RULES_GROUP'));
                $wrapping_tax_calculator = $wrapping_tax_manager->getTaxCalculator();
            }
            $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl, $order_invoice->total_shipping_tax_incl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode));
            $order_invoice->saveWrappingTaxCalculator($wrapping_tax_calculator->getTaxesAmount($order_invoice->total_wrapping_tax_excl, $order_invoice->total_wrapping_tax_incl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode));
            // Update order_carrier
            $id_order_carrier = Db::getInstance()->getValue('
				SELECT `id_order_carrier`
				FROM `' . _DB_PREFIX_ . 'order_carrier`
				WHERE `id_order` = ' . (int) $order_invoice->id_order . '
				AND (`id_order_invoice` IS NULL OR `id_order_invoice` = 0)');
            if ($id_order_carrier) {
                $order_carrier = new OrderCarrier($id_order_carrier);
                $order_carrier->id_order_invoice = (int) $order_invoice->id;
                $order_carrier->update();
            }
            // Update order detail
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_detail`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Update order payment
            if ($use_existing_payment) {
                $id_order_payments = Db::getInstance()->executeS('
					SELECT DISTINCT op.id_order_payment
					FROM `' . _DB_PREFIX_ . 'order_payment` op
					INNER JOIN `' . _DB_PREFIX_ . 'orders` o ON (o.reference = op.order_reference)
					LEFT JOIN `' . _DB_PREFIX_ . 'order_invoice_payment` oip ON (oip.id_order_payment = op.id_order_payment)
					WHERE (oip.id_order != ' . (int) $order_invoice->id_order . ' OR oip.id_order IS NULL) AND o.id_order = ' . (int) $order_invoice->id_order);
                if (count($id_order_payments)) {
                    foreach ($id_order_payments as $order_payment) {
                        Db::getInstance()->execute('
							INSERT INTO `' . _DB_PREFIX_ . 'order_invoice_payment`
							SET
								`id_order_invoice` = ' . (int) $order_invoice->id . ',
								`id_order_payment` = ' . (int) $order_payment['id_order_payment'] . ',
								`id_order` = ' . (int) $order_invoice->id_order);
                    }
                    // Clear cache
                    Cache::clean('order_invoice_paid_*');
                }
            }
            // Update order cart rule
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_cart_rule`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Keep it for backward compatibility, to remove on 1.6 version
            $this->invoice_date = $order_invoice->date_add;
            if (Configuration::get('PS_INVOICE')) {
                $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
                $invoice_number = Hook::exec('actionSetInvoice', array(get_class($this) => $this, get_class($order_invoice) => $order_invoice, 'use_existing_payment' => (bool) $use_existing_payment));
                if (is_numeric($invoice_number)) {
                    $this->invoice_number = (int) $invoice_number;
                } else {
                    $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
                }
            }
            $this->update();
        }
    }
Esempio n. 3
0
    /**
     * This method allows to generate first invoice of the current order
     */
    public function setInvoice($use_existing_payment = false)
    {
        if (Configuration::get('PS_INVOICE') && !$this->hasInvoice()) {
            if ($id = (int) $this->hasDelivery()) {
                $order_invoice = new OrderInvoice($id);
            } else {
                $order_invoice = new OrderInvoice();
            }
            $order_invoice->id_order = $this->id;
            if (!$id) {
                $order_invoice->number = 0;
            }
            $address = new Address((int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $carrier = new Carrier((int) $this->id_carrier);
            $tax_calculator = $carrier->getTaxCalculator($address);
            $order_invoice->total_discount_tax_excl = $this->total_discounts_tax_excl;
            $order_invoice->total_discount_tax_incl = $this->total_discounts_tax_incl;
            $order_invoice->total_paid_tax_excl = $this->total_paid_tax_excl;
            $order_invoice->total_paid_tax_incl = $this->total_paid_tax_incl;
            $order_invoice->total_products = $this->total_products;
            $order_invoice->total_products_wt = $this->total_products_wt;
            $order_invoice->total_shipping_tax_excl = $this->total_shipping_tax_excl;
            $order_invoice->total_shipping_tax_incl = $this->total_shipping_tax_incl;
            $order_invoice->shipping_tax_computation_method = $tax_calculator->computation_method;
            $order_invoice->total_wrapping_tax_excl = $this->total_wrapping_tax_excl;
            $order_invoice->total_wrapping_tax_incl = $this->total_wrapping_tax_incl;
            // Save Order invoice
            $order_invoice->save();
            $this->setLastInvoiceNumber($order_invoice->id, $this->id_shop);
            $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl));
            // Update order_carrier
            $id_order_carrier = Db::getInstance()->getValue('
				SELECT `id_order_carrier`
				FROM `' . _DB_PREFIX_ . 'order_carrier`
				WHERE `id_order` = ' . (int) $order_invoice->id_order . '
				AND (`id_order_invoice` IS NULL OR `id_order_invoice` = 0)');
            if ($id_order_carrier) {
                $order_carrier = new OrderCarrier($id_order_carrier);
                $order_carrier->id_order_invoice = (int) $order_invoice->id;
                $order_carrier->update();
            }
            // Update order detail
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_detail`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Update order payment
            if ($use_existing_payment) {
                $id_order_payments = Db::getInstance()->executeS('
					SELECT DISTINCT op.id_order_payment
					FROM `' . _DB_PREFIX_ . 'order_payment` op
					INNER JOIN `' . _DB_PREFIX_ . 'orders` o ON (o.reference = op.order_reference)
					LEFT JOIN `' . _DB_PREFIX_ . 'order_invoice_payment` oip ON (oip.id_order_payment = op.id_order_payment)
					WHERE (oip.id_order != ' . (int) $order_invoice->id_order . ' OR oip.id_order IS NULL) AND o.id_order = ' . (int) $order_invoice->id_order);
                if (count($id_order_payments)) {
                    foreach ($id_order_payments as $order_payment) {
                        Db::getInstance()->execute('
							INSERT INTO `' . _DB_PREFIX_ . 'order_invoice_payment`
							SET
								`id_order_invoice` = ' . (int) $order_invoice->id . ',
								`id_order_payment` = ' . (int) $order_payment['id_order_payment'] . ',
								`id_order` = ' . (int) $order_invoice->id_order);
                    }
                    // Clear cache
                    Cache::clean('order_invoice_paid_*');
                }
            }
            // Update order cart rule
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_cart_rule`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Keep it for backward compatibility, to remove on 1.6 version
            $this->invoice_date = $order_invoice->date_add;
            $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
            $this->update();
        }
    }
Esempio n. 4
0
    /**
     * This method allows to generate first invoice of the current order
     */
    public function setInvoice($use_existing_payment = false)
    {
        if (!$this->hasInvoice()) {
            $order_invoice = new OrderInvoice();
            $order_invoice->id_order = $this->id;
            $order_invoice->number = Configuration::get('PS_INVOICE_START_NUMBER');
            // If invoice start number has been set, you clean the value of this configuration
            if ($order_invoice->number) {
                Configuration::updateValue('PS_INVOICE_START_NUMBER', false);
            } else {
                $order_invoice->number = Order::getLastInvoiceNumber() + 1;
            }
            $invoice_address = new Address((int) $this->id_address_invoice);
            $carrier = new Carrier((int) $this->id_carrier);
            $tax_calculator = $carrier->getTaxCalculator($invoice_address);
            $order_invoice->total_discount_tax_excl = $this->total_discounts_tax_excl;
            $order_invoice->total_discount_tax_incl = $this->total_discounts_tax_incl;
            $order_invoice->total_paid_tax_excl = $this->total_paid_tax_excl;
            $order_invoice->total_paid_tax_incl = $this->total_paid_tax_incl;
            $order_invoice->total_products = $this->total_products;
            $order_invoice->total_products_wt = $this->total_products_wt;
            $order_invoice->total_shipping_tax_excl = $this->total_shipping_tax_excl;
            $order_invoice->total_shipping_tax_incl = $this->total_shipping_tax_incl;
            $order_invoice->shipping_tax_computation_method = $tax_calculator->computation_method;
            $order_invoice->total_wrapping_tax_excl = $this->total_wrapping_tax_excl;
            $order_invoice->total_wrapping_tax_incl = $this->total_wrapping_tax_incl;
            // Save Order invoice
            $order_invoice->add();
            $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl));
            // Update order_carrier
            $id_order_carrier = Db::getInstance()->getValue('
				SELECT `id_order_carrier`
				FROM `' . _DB_PREFIX_ . 'order_carrier`
				WHERE `id_order` = ' . (int) $order_invoice->id_order . '
				AND (`id_order_invoice` IS NULL OR `id_order_invoice` = 0)');
            if ($id_order_carrier) {
                $order_carrier = new OrderCarrier($id_order_carrier);
                $order_carrier->id_order_invoice = (int) $order_invoice->id;
                $order_carrier->update();
            }
            // Update order detail
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_detail`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Update order payment
            if ($use_existing_payment) {
                $id_order_payments = Db::getInstance()->executeS('
					SELECT op.id_order_payment 
					FROM `' . _DB_PREFIX_ . 'order_payment` op
					INNER JOIN `' . _DB_PREFIX_ . 'orders` o ON (o.reference = op.order_reference)
					LEFT JOIN `' . _DB_PREFIX_ . 'order_invoice_payment` oip ON (oip.id_order_payment = op.id_order_payment)					
					WHERE oip.id_order_payment IS NULL AND o.id_order = ' . (int) $order_invoice->id_order);
                if (count($id_order_payments)) {
                    foreach ($id_order_payments as $order_payment) {
                        Db::getInstance()->execute('
							INSERT INTO `' . _DB_PREFIX_ . 'order_invoice_payment`
							SET
								`id_order_invoice` = ' . (int) $order_invoice->id . ',
								`id_order_payment` = ' . (int) $order_payment['id_order_payment'] . ',
								`id_order` = ' . (int) $order_invoice->id_order);
                    }
                }
            }
            // Update order cart rule
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_cart_rule`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Keep it for backward compatibility, to remove on 1.6 version
            $this->invoice_date = $order_invoice->date_add;
            $this->invoice_number = $order_invoice->number;
            $this->update();
        }
    }