Current File : /var/www/vinorea/modules/ipexportimport/classes/import/order/EIAOrderInvoice.php
<?php
/**
 *
 * NOTICE OF LICENSE
 *
 *  @author    SmartPresta <tehran.alishov@gmail.com>
 *  @copyright 2024 SmartPresta
 *  @license   Commercial License
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

class EIAOrderInvoice
{

    private $id_order;
    private $paymentObj;
    private $number;
    private $delivery_number;
    private $delivery_date;
    private $total_discount_tax_excl;
    private $total_discount_tax_incl;
    private $total_paid_tax_excl;
    private $total_paid_tax_incl;
    private $total_products;
    private $total_products_wt;
    private $total_shipping_tax_excl;
    private $total_shipping_tax_incl;
    private $shipping_tax_computation_method;
    private $total_wrapping_tax_excl;
    private $total_wrapping_tax_incl;
    private $shop_address;
    private $invoice_address;
    private $delivery_address;
    private $note;
    private $date_add;
    private $id_order_invoice;
    private $invoice_tax;
    private $id_invoice_payment;
    private $row;
    private $id_process;
    public $validateOnly;

    public function __construct($id_order, $invoiceData = null, $row = null, $id_process = null, $validateOnly = false, $paymentObj = null)
    {
        $this->row = $row;
        $this->id_process = $id_process;
        $this->validateOnly = $validateOnly;
        $this->id_order = (int) $id_order;
        $this->paymentObj = $paymentObj;
        $this->id_order_invoice = isset($invoiceData['id_order_invoice']) ? $invoiceData['id_order_invoice'] : array();
        $this->number = isset($invoiceData['inv_number']) ? $invoiceData['inv_number'] : array();
        $this->delivery_number = isset($invoiceData['invoice_delivery_number']) ? $invoiceData['invoice_delivery_number'] : array();
        $this->delivery_date = isset($invoiceData['invoice_delivery_date']) ? $invoiceData['invoice_delivery_date'] : array();
        $this->total_discount_tax_excl = isset($invoiceData['invoice_total_discount_tax_excl']) ? $invoiceData['invoice_total_discount_tax_excl'] : array();
        $this->total_discount_tax_incl = isset($invoiceData['invoice_total_discount_tax_incl']) ? $invoiceData['invoice_total_discount_tax_incl'] : array();
        $this->total_paid_tax_excl = isset($invoiceData['invoice_total_paid_tax_excl']) ? $invoiceData['invoice_total_paid_tax_excl'] : array();
        $this->total_paid_tax_incl = isset($invoiceData['invoice_total_paid_tax_incl']) ? $invoiceData['invoice_total_paid_tax_incl'] : array();
        $this->total_products = isset($invoiceData['invoice_total_products']) ? $invoiceData['invoice_total_products'] : array();
        $this->total_products_wt = isset($invoiceData['invoice_total_products_wt']) ? $invoiceData['invoice_total_products_wt'] : array();
        $this->total_shipping_tax_excl = isset($invoiceData['invoice_total_shipping_tax_excl']) ? $invoiceData['invoice_total_shipping_tax_excl'] : array();
        $this->total_shipping_tax_incl = isset($invoiceData['invoice_total_shipping_tax_incl']) ? $invoiceData['invoice_total_shipping_tax_incl'] : array();
        $this->shipping_tax_computation_method = isset($invoiceData['invoice_shipping_tax_computation_method']) ? $invoiceData['invoice_shipping_tax_computation_method'] : array();
        $this->total_wrapping_tax_excl = isset($invoiceData['invoice_total_wrapping_tax_excl']) ? $invoiceData['invoice_total_wrapping_tax_excl'] : array();
        $this->total_wrapping_tax_incl = isset($invoiceData['invoice_total_wrapping_tax_incl']) ? $invoiceData['invoice_total_wrapping_tax_incl'] : array();
        $this->shop_address = isset($invoiceData['invoice_shop_address']) ? $invoiceData['invoice_shop_address'] : array();
        $this->invoice_address = isset($invoiceData['invoice_address']) ? $invoiceData['invoice_address'] : array();
        $this->delivery_address = isset($invoiceData['invoice_delivery_address']) ? $invoiceData['invoice_delivery_address'] : array();
        $this->note = isset($invoiceData['invoice_note']) ? $invoiceData['invoice_note'] : array();
        $this->date_add = isset($invoiceData['invoice_date_add']) ? $invoiceData['invoice_date_add'] : array();
        $this->invoice_tax = isset($invoiceData['invoice_tax']) ? $invoiceData['invoice_tax'] : array();
        $this->id_invoice_payment = isset($invoiceData['id_invoice_payment']) ? $invoiceData['id_invoice_payment'] : array();
    }

    public function save()
    {
        $invoices = $this->getOrderInvoices();
        if (!$invoices) {
            foreach ($this->number as $key => $val) {
                $this->setDataObject($key);
            }
        } else {
            foreach ($invoices as $key => $invoice) {
                $this->setDataObject($key, $invoice->id);
            }
        }
    }

    private function setDataObject($key, $id_order_invoice = null)
    {
        if (!$id_order_invoice && !empty($this->id_order_invoice[$key])) {
            $id_order_invoice = (int) $this->id_order_invoice[$key];
        }
        
        $invoiceObj = new OrderInvoice($id_order_invoice);
        $invoiceObj->id_order = $this->id_order;
        
        if (!empty($this->number[$key]) || $this->number[$key] == '0') {
            $invoiceObj->number = $this->number[$key];
        }
        
        if (!empty($this->delivery_number[$key]) || $this->delivery_number[$key] == '0') {
            $invoiceObj->delivery_number = $this->delivery_number[$key];
        }
        
        if (!empty($this->delivery_date[$key])) {
            $invoiceObj->delivery_date = $this->delivery_date[$key];
        }
        
        if (!empty($this->total_discount_tax_excl[$key])) {
            $invoiceObj->total_discount_tax_excl = EIATools::preparePrice($this->total_discount_tax_excl[$key]);
        } elseif (!$invoiceObj->total_discount_tax_excl) {
            $invoiceObj->total_discount_tax_excl = 0;
        }
        
        if (!empty($this->total_discount_tax_incl[$key])) {
            $invoiceObj->total_discount_tax_incl = EIATools::preparePrice($this->total_discount_tax_incl[$key]);
        } elseif (!$invoiceObj->total_discount_tax_incl) {
            $invoiceObj->total_discount_tax_incl = 0;
        }
        
        if (!empty($this->total_paid_tax_excl[$key])) {
            $invoiceObj->total_paid_tax_excl = EIATools::preparePrice($this->total_paid_tax_excl[$key]);
        } elseif (!$invoiceObj->total_paid_tax_excl) {
            $invoiceObj->total_paid_tax_excl = 0;
        }
        
        if (!empty($this->total_paid_tax_incl[$key])) {
            $invoiceObj->total_paid_tax_incl = EIATools::preparePrice($this->total_paid_tax_incl[$key]);
        } elseif (!$invoiceObj->total_paid_tax_incl) {
            $invoiceObj->total_paid_tax_incl = 0;
        }
        
        if (!empty($this->total_products[$key])) {
            $invoiceObj->total_products = EIATools::preparePrice($this->total_products[$key]);
        } elseif (!$invoiceObj->total_products) {
            $invoiceObj->total_products = 0;
        }
        
        if (!empty($this->total_products_wt[$key])) {
            $invoiceObj->total_products_wt = EIATools::preparePrice($this->total_products_wt[$key]);
        } elseif (!$invoiceObj->total_products_wt) {
            $invoiceObj->total_products_wt = 0;
        }
        
        if (!empty($this->total_shipping_tax_excl[$key])) {
            $invoiceObj->total_shipping_tax_excl = EIATools::preparePrice($this->total_shipping_tax_excl[$key]);
        } elseif (!$invoiceObj->total_shipping_tax_excl) {
            $invoiceObj->total_shipping_tax_excl = 0;
        }
        
        if (!empty($this->total_shipping_tax_incl[$key])) {
            $invoiceObj->total_shipping_tax_incl = EIATools::preparePrice($this->total_shipping_tax_incl[$key]);
        } elseif (!$invoiceObj->total_shipping_tax_incl) {
            $invoiceObj->total_shipping_tax_incl = 0;
        }
        
        if (!empty($this->shipping_tax_computation_method[$key]) || $this->shipping_tax_computation_method[$key] == '0') {
            $invoiceObj->shipping_tax_computation_method = (int) $this->shipping_tax_computation_method[$key];
        }
        
        if (!empty($this->total_wrapping_tax_excl[$key])) {
            $invoiceObj->total_wrapping_tax_excl = EIATools::preparePrice($this->total_wrapping_tax_excl[$key]);
        } elseif (!$invoiceObj->total_wrapping_tax_excl) {
            $invoiceObj->total_wrapping_tax_excl = 0;
        }
        
        if (!empty($this->total_wrapping_tax_incl[$key])) {
            $invoiceObj->total_wrapping_tax_incl = EIATools::preparePrice($this->total_wrapping_tax_incl[$key]);
        } elseif (!$invoiceObj->total_wrapping_tax_incl) {
            $invoiceObj->total_wrapping_tax_incl = 0;
        }
        
        if (isset($this->shop_address[$key]) && $this->shop_address[$key]) {
            $invoiceObj->shop_address = $this->shop_address[$key];
        }

        if (isset($this->invoice_address[$key]) && $this->invoice_address[$key]) {
            $invoiceObj->invoice_address = $this->invoice_address[$key];
        }

        if (isset($this->delivery_address[$key]) && $this->delivery_address[$key]) {
            $invoiceObj->delivery_address = $this->delivery_address[$key];
        }

        if (isset($this->note[$key]) && $this->note[$key]) {
            $invoiceObj->note = $this->note[$key];
        }

        if (isset($this->date_add[$key]) && $this->date_add[$key]) {
            $invoiceObj->date_add = $this->date_add[$key];
        }
        if (($error = $invoiceObj->validateFields(false, true)) !== true) {
            throw new PrestaShopException("Error: $error. ID: $this->id_order. Row in file: $this->row.");
        }

        if (!$this->validateOnly) {
            $res = 0;
            if ((int) $invoiceObj->id > 0) {
                $res = $invoiceObj->update();
            } elseif ($id_order_invoice) {
                $invoiceObj->id = $id_order_invoice;
                $invoiceObj->force_id = true;
                $res = $invoiceObj->add();
            }
            if ($res) {
                if (!empty($this->invoice_tax[$key])) {
                    $this->setOrderInvoiceTax($invoiceObj->id, $this->invoice_tax[$key]);
                    $this->setOrderInvoicePayment($invoiceObj->id, $this->id_invoice_payment[$key]);
                }
            }
        }
    }
    
    private function setOrderInvoiceTax($id_order_invoice, $invoice_taxes)
    {
        if (!$invoice_taxes) {
            return false;
        }
        
        $invoice_taxes = explode('&', $invoice_taxes);
        $values = '';
        Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'order_invoice_tax` WHERE id_order_invoice = ' . (int) $id_order_invoice);
        foreach ($invoice_taxes as $invoice_tax) {
            $parts = explode(':', trim($invoice_tax));
            if (!empty($parts[2]) && trim($parts[2])) {
                $id_tax = (int) EIAOrdersImport::getTaxIdByName(trim($parts[2]));
            } elseif (!empty($parts[1]) && trim($parts[1])) {
                $id_tax = (int) trim($parts[1]);
            } else {
                $id_tax = 0;
            }
            $type = !empty($parts[0]) && trim($parts[0]) ? trim($parts[0]) : '';
            $amount = !empty($parts[3]) && trim($parts[3]) ? EIATools::preparePrice(trim($parts[3])) : 0;
            $values .= '(' . (int) $id_order_invoice . ', "' . pSQL($type) . '", ' . $id_tax . ', ' . $amount . '),';
        }
        $values = rtrim($values, ',');
        $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'order_invoice_tax` VALUES ' . $values;

        Db::getInstance()->execute($sql);
    }

    private function setOrderInvoicePayment($id_order_invoice, $ids_payment)
    {
        if (!$ids_payment) {
            return false;
        }

        $ids_payment = explode('&', $ids_payment);
        $values = '';
        Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'order_invoice_payment` 
            WHERE id_order_invoice = ' . (int) $id_order_invoice . ' AND id_order = ' . (int) $this->id_order);
        foreach ($ids_payment as $id_payment) {
            if ($this->paymentObj && isset($this->paymentObj->id_map[(int) $id_payment])) {
                $id_payment = $this->paymentObj->id_map[(int) $id_payment];
            }
            $values .= '(' . (int) $id_order_invoice . ',' . (int) $id_payment . ',' . (int) $this->id_order . '),';
        }
        $values = rtrim($values, ',');
        $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'order_invoice_payment` VALUES ' . $values;

        Db::getInstance()->execute($sql);
    }

    private function getOrderInvoices()
    {
        $sql = "
            SELECT *
            FROM " . _DB_PREFIX_ . "order_invoice
            WHERE id_order = " . (int) $this->id_order;

        return ObjectModel::hydrateCollection('OrderInvoice', Db::getInstance()->executeS($sql));
    }

}