public static function reset()
 {
     self::$_instance = null;
 }
function synchroOrder($id_order)
{
    echo "Synchronier order : {$id_order}<br>";
    // Retrieve order information
    $order = Db::getInstance()->GetRow("select * from " . _DB_PREFIX_ . "orders where id_order='" . $id_order . "'");
    $id_customer = $order['id_customer'];
    $id_address_delivery = $order['id_address_delivery'];
    $date_order = $order['date_add'];
    $total = $order['total_paid'];
    $total = sprintf("%.2f", $total);
    $total_net = $order['total_paid_tax_excl'];
    $total_vat = $total - $total_net;
    $total_vat = sprintf("%.2f", $total_vat);
    // delivery
    $total_shipping_TTC = $order['total_shipping_tax_incl'];
    $total_shipping_TTC = sprintf("%.2f", $total_shipping_TTC);
    $total_shipping_HT = $order['total_shipping_tax_excl'];
    $total_shipping_HT = sprintf("%.2f", $total_shipping_HT);
    $carrier_tax_rate = $order['carrier_tax_rate'];
    $carrier_tax_rate = sprintf("%.2f", $carrier_tax_rate);
    $delivery_number = $order['delivery_number'];
    $delivery_date = $order['delivery_date'];
    $total_shipping_TVA = $total_shipping_TTC - $total_shipping_HT;
    $total_shipping_TVA = sprintf("%.2f", $total_shipping_TVA);
    $payment_type = $order['module'];
    // instead of payment which is localized
    $valid = $order['valid'];
    if ($valid == 0) {
        echo "order is not valid. skip it.";
        return TRUE;
    }
    // get order status
    $create_invoice = false;
    $statut_propal = 4;
    //** Propal validée signée
    $order_status = 0;
    // draft by default
    $commande_facturee = 0;
    //** Commande NON facturée
    $invoice_status = 0;
    //** Facture en brouillon
    $paye = 0;
    //** Facture non payée
    $facture = 0;
    //** Commande Facturée --> Passe la commande en traitée quand statut='Livré'
    // handle order status
    $state = $order['current_state'];
    switch ($state) {
        case 0:
            // Paiement by check or virement
        // Paiement by check or virement
        case 10:
            // Paiement by check or virement
            $order_status = 0;
            // draft
            break;
        case 2:
            // Paiement accepted
            $create_invoice = true;
            $invoice_status = 2;
            // paid
            $order_status = 1;
            // validated
            break;
        case 3:
            // En cours de préparation
            $create_invoice = true;
            $invoice_status = 2;
            // paid
            $order_status = 2;
            // In delivery (not sent yet)
            break;
        case 4:
            // In delivery
            $create_invoice = true;
            $invoice_status = 2;
            // paid
            $order_status = 3;
            // closed
            break;
        case 5:
            // delivered
        // delivered
        case 35:
            // delivered
        // delivered
        case 37:
            // delivered
            $create_invoice = true;
            $invoice_status = 2;
            // paid
            $order_status = 3;
            // > closed (has been sent)
            break;
        case 6:
            // cancelled or refund
        // cancelled or refund
        case 7:
            // cancelled or refund
            //$order_status = 0; // due to current dolibarr limitation using webservices
            $order_status = '-1';
            // canceled
            break;
        case 8:
            // paiement error or not validated
            $order_status = 0;
            // draft
            break;
    }
    // For now, we only want to synchonize orders that have been validated and paid
    if ($order_status <= 0) {
        echo "<br />Warning : order isn't valid. Status ==" . $order_status;
        return TRUE;
    }
    // load order details
    $products = Db::getInstance()->executeS("select * from " . _DB_PREFIX_ . "order_detail where id_order='" . $id_order . "'");
    $count = 0;
    foreach ($products as $product) {
        $line = new DolibarrOrderLines();
        $line->desc = $product['product_name'];
        $line->qty = $product['product_quantity'];
        $line->unitprice = $product['unit_price_tax_excl'];
        $line->remise = $product['reduction_amount'];
        $line->remise_percent = $product['reduction_percent'];
        $line->total_net = $product['total_price_tax_excl'];
        $line->total = $product['total_price_tax_incl'];
        $line->total_vat = sprintf("%.2f", $product['total_price_tax_incl'] - $product['total_price_tax_excl']);
        // vat_rate isn't set properly on order_detail so compute it...
        $line->vat_rate = sprintf("%.1f", ($product['total_price_tax_incl'] - $product['total_price_tax_excl']) / $product['total_price_tax_excl'] * 100);
        if ($line->vat_rate > 19.8 && $line->vat_rate < 20.2) {
            $line->vat_rate = 20;
        } else {
            if ($line->vat_rate > 9.800000000000001 && $line->vat_rate < 10.2) {
                $line->vat_rate = 10;
            }
        }
        $lines[$count] = $line;
        $count++;
    }
    // add shipping line
    $lines[$count] = addShippingLine($order);
    $dolibarr = Dolibarr::getInstance();
    // retrieve user
    $client = $dolibarr->getUser("PSUSER-" . $id_customer);
    if ($client["result"]->result_code == 'NOT_FOUND') {
        echo "<br />Error : client doesn't exist. Try to synchronize clients first.";
        return FALSE;
    }
    // Retrieve delivery address
    $fk_delivery_address = retrieveDeliveryAddress($dolibarr, $id_address_delivery);
    if ($fk_delivery_address == false) {
        return FALSE;
    }
    // Check if already exists in Dolibarr
    $exists = $dolibarr->getOrder($id_order);
    // Create order
    $dolibarrOrder = new DolibarrOrder();
    $dolibarrOrder->ref_ext = $id_order;
    $dolibarrOrder->thirdparty_id = $client["thirdparty"]->id;
    $dolibarrOrder->fk_delivery_address = (int) $fk_delivery_address;
    $dolibarrOrder->date = $order["date_add"];
    if ($delivery_number != "0") {
        $dolibarrOrder->date_livraison = $delivery_date;
    }
    $dolibarrOrder->status = 1;
    // we start with status validated, we will update status after if needed
    /*$dolibarrOrder->total = $total;
      $dolibarrOrder->total_net = $total_net;
      $dolibarrOrder->total_vat = $total_v;*/
    $dolibarrOrder->lines = $lines;
    if ($exists["result"]->result_code == 'NOT_FOUND') {
        // Create new order
        echo "Create new order : ";
        var_dump($dolibarrOrder);
        $result = $dolibarr->createOrder($dolibarrOrder);
        echo $result["result"]->result_code . "<br/>";
        if ($result["result"]->result_code != 'OK') {
            echo "<br />Erreur de synchronisation : " . $result["result"]->result_label;
            return FALSE;
        }
    }
    // update it now to have a correct status
    if (version_compare(Configuration::get('dolibarr_version'), '3.7.0') == -1) {
        echo "<br />Dolibarr version < 3.7 can't update orders, skip update. Please consider updating Dolibarr to 3.7.x to have a full synchronisation.";
    } else {
        // Update order status
        echo "<br />update order >status = " . $order_status;
        $oldOrder = $exists["order"];
        $dolibarrOrder->status = $order_status;
        $result = $dolibarr->updateOrder($dolibarrOrder);
        echo $result["result"]->result_code . "<br/>";
        if ($result["result"]->result_code != 'OK') {
            echo "<br />Erreur de synchronisation : " . $result["result"]->result_label;
            return FALSE;
        }
    }
    // Create invoice if necessary
    if ($create_invoice) {
        echo "<br />Creating invoice.<br />";
        //invoices dont really exists in prestashop, so id_order=id_invoice
        $exists = $dolibarr->getInvoice($id_order);
        $dolibarrInvoice = new DolibarrInvoice();
        $dolibarrInvoice->ref_ext = $id_order;
        $dolibarrInvoice->thirdparty_id = $client["thirdparty"]->id;
        $dolibarrInvoice->date = $order["date_add"];
        $dolibarrInvoice->total = $total;
        $dolibarrInvoice->total_net = $total_net;
        $dolibarrInvoice->total_vat = $total_vat;
        if ($delivery_number != "0") {
            $dolibarrInvoice->date_livraison = $delivery_date;
        }
        if ($invoice_status == 1 || $invoice_status == 2) {
            // if order is validated or paid, we mark invoice as validated first
            $dolibarrInvoice->status = 1;
        }
        if ($payment_type == "paypal") {
            $dolibarrInvoice->payment_mode_id = 50;
            // ONLINE PAYMENT
        } else {
            if ($payment_type == "cheque") {
                $dolibarrInvoice->payment_mode_id = 7;
                // CHEQUE
            } else {
                echo "Payment mode not mapped : " . $payment_type . "-> please report this issue, thanks ! ";
                return FALSE;
            }
        }
        $dolibarrInvoice->lines = createInvoiceLines($lines);
        if ($exists["result"]->result_code == 'NOT_FOUND') {
            // Create new invoice
            echo "<br>Create new invoice : ";
            $result = $dolibarr->createInvoice($dolibarrInvoice);
            echo $result["result"]->result_code . "<br/>";
            if ($result["result"]->result_code != 'OK') {
                echo "Erreur de synchronisation : " . $result["result"]->result_label;
                return FALSE;
            }
        }
        if (version_compare(Configuration::get('dolibarr_version'), '3.7.1') == -1) {
            echo "<br />Your version of Dolibarr can't mark invoice as paid, please do it manually. This will be fixed in next version (maybe 3.7.1)";
            return TRUE;
        } else {
            // update invoice status
            echo "<br>update invoice status : ";
            $dolibarrInvoice->status = $invoice_status;
            $result = $dolibarr->updateInvoice($dolibarrInvoice);
            echo $result["result"]->result_code . "<br/>";
            if ($result["result"]->result_code == 'KO') {
                echo "Erreur de synchronisation : " . $result["result"]->result_label;
                return FALSE;
            } else {
                if ($result["result"]->result_code == 'NOT_FOUND') {
                    echo "Invoice not found : " . $result["result"]->result_label;
                    return FALSE;
                }
            }
        }
    }
    return TRUE;
}
function synchroClient($id_customer)
{
    echo "<br/>Synchronize client : {$id_customer}<br>";
    // retrieve params
    $prefix_ref_client = Configuration::get('prefix_ref_client');
    $prefix_ref_client = accents_sans("{$prefix_ref_client}");
    $client_status = Configuration::get('client_status');
    // retrieve client data
    $donnees_customer = Db::getInstance()->GetRow("select * from " . _DB_PREFIX_ . "customer where id_customer='" . $id_customer . "'");
    //var_dump($donnees_customer);
    $id_gender = $donnees_customer['id_gender'];
    $note = $donnees_customer['note'];
    $note = accents_minuscules("{$note}");
    $birthday = $donnees_customer['birthday'];
    if ($id_gender == 9) {
        $civilite = "";
    } elseif ($id_gender == 1) {
        $civilite = "MR";
    } elseif ($id_gender == 2) {
        $civilite = "MME";
    } elseif ($id_gender == 3) {
        $civilite = "MME";
    } else {
        $civilite = "MR";
    }
    $mail = $donnees_customer['email'];
    echo "Email : {$mail}<br>";
    $dolibarr = Dolibarr::getInstance();
    // Check if already exists in Dolibarr
    $exists = $dolibarr->getUser("PSUSER-" . $id_customer);
    $client = new DolibarrThirdParty();
    $client->ref_ext = "PSUSER-" . $id_customer;
    if ($prefix_ref_client == "") {
        $client->customer_code = -1;
    } else {
        $client->customer_code = $prefix_ref_client . $id_customer;
    }
    $client->status = $client_status;
    $client->ref = $donnees_customer['firstname'] . " " . $donnees_customer['lastname'];
    $client->email = $mail;
    $client->date_modification = new DateTime('NOW');
    $client->url = _PS_BASE_URL_ . __PS_BASE_URI__;
    if ($exists["result"]->result_code == 'NOT_FOUND') {
        // Create new user
        echo "Create new user :"******"result"]->result_code . "<br/>";
        if ($result["result"]->result_code != 'OK') {
            echo "Erreur de synchronisation : " . $result["result"]->result_label;
            var_dump($result);
            return FALSE;
        }
    } else {
        // Update user
        echo "update user : "******"thirdparty"];
        $client->id = $oldClient->id;
        echo $client->id . "<br";
        $result = $dolibarr->updateUser($client);
        echo $result["result"]->result_code . "<br/>";
        if ($result["result"]->result_code != 'OK') {
            echo "Erreur de synchronisation : " . $result["result"]->result_label;
        }
    }
    if ($result["result"]->result_code == 'OK') {
        // synchronize client addresses
        if ($addresses = Db::getInstance()->ExecuteS("select * from " . _DB_PREFIX_ . "address where id_customer='" . $id_customer . "'")) {
            foreach ($addresses as $address) {
                echo "<br/> Synchronize address : ";
                $contact = new DolibarrContact();
                $contact->ref_ext = $address['id_address'];
                $contact->socid = $result["id"];
                $contact->lastname = $address['lastname'];
                $contact->firstname = $address['firstname'];
                $address1 = $address['address1'];
                $address1 = accents_majuscules("{$address1}");
                $address2 = $address['address2'];
                $address2 = accents_majuscules("{$address2}");
                $contact->address = $address1 . ' ' . $address2;
                $contact->zip = $address['postcode'];
                $contact->town = accents_majuscules($address['city']);
                $contact->note = $address['other'];
                //TODO improve country correspondance
                $id_country = $address['id_country'];
                if ($id_country == 8) {
                    $country = 1;
                    // for FRANCE
                } else {
                    $country = "";
                }
                $contact->country_id = $country;
                $phone = $address['phone'];
                $phone = tel_cacateres("{$phone}");
                $mobile = $address['phone_mobile'];
                $mobile = tel_cacateres("{$mobile}");
                $contact->phone_perso = $phone;
                $contact->phone_mobile = $mobile;
                $contact->email = $mail;
                $contact->birthday = $birthday;
                $contact->civility_id = $civilite;
                $result = $dolibarr->getContact($contact->ref_ext);
                if ($result["result"]->result_code == 'NOT_FOUND') {
                    // Create address
                    echo "<br>create address : ";
                    $result = $dolibarr->createContact($contact);
                    echo $result["result"]->result_code . "<br/>";
                    if ($result["result"]->result_code != 'OK') {
                        echo "Erreur de synchronisation address : " . $result["result"]->result_label;
                        var_dump($result);
                        return FALSE;
                    }
                } else {
                    if ($result["result"]->result_code == 'OK') {
                        // Update address
                        echo "<br>update address : ";
                        $contact->id = $result["contact"]->id;
                        // we can't update contact using it's ref_ext so we use id
                        $result = $dolibarr->updateContact($contact);
                        echo $result["result"]->result_code . "<br/>";
                        if ($result["result"]->result_code != 'OK') {
                            echo "Erreur de synchronisation address : " . $result["result"]->result_label;
                            var_dump($result);
                            return FALSE;
                        }
                    } else {
                        echo "Erreur de synchronisation address : " . $result["result"]->result_label;
                        var_dump($result);
                        return FALSE;
                    }
                }
            }
        }
    }
    return TRUE;
}
    public function getContent()
    {
        if (Tools::getValue('submit' . $this->name) == "1") {
            $dolibarr_server_url = Tools::getValue('dolibarr_server_url');
            $dolibarr_key = Tools::getValue('dolibarr_key');
            $dolibarr_login = Tools::getValue('dolibarr_login');
            $dolibarr_password = Tools::getValue('dolibarr_password');
            $prefix_ref_client = Tools::getValue('prefix_ref_client');
            $client_status = Tools::getValue('client_status');
            $use_barcode = Tools::getValue('use_barcode');
            $prefix_ref_product = Tools::getValue('prefix_ref_product');
            $product_description = Tools::getValue('product_description');
            $delivery_line_label = Tools::getValue('delivery_line_label');
            Configuration::updateValue('dolibarr_server_url', $dolibarr_server_url);
            Configuration::updateValue('dolibarr_key', $dolibarr_key);
            Configuration::updateValue('dolibarr_login', $dolibarr_login);
            if ($dolibarr_password) {
                // only save if a value was entered
                Configuration::updateValue('dolibarr_password', $dolibarr_password);
            }
            Configuration::updateValue('prefix_ref_client', $prefix_ref_client);
            Configuration::updateValue('client_status', $client_status);
            Configuration::updateValue('use_barcode', $use_barcode);
            Configuration::updateValue('prefix_ref_product', $prefix_ref_product);
            Configuration::updateValue('product_description', $product_description);
            Configuration::updateValue('delivery_line_label', $delivery_line_label);
            //Configuration::updateValue('option_image', $option_image);
            // test dolibarr webservices connexion
            $client = new SoapClient($dolibarr_server_url . "/webservices/server_other.php?wsdl");
            if (is_null($client)) {
                Configuration::updateValue('validated', '0');
                $testdoliserveur = $this->l("DOLIBARR : Paramètres incorrectes : vérifez l'adresse du serveur et que les webservices sont bien activés.<br>");
            } else {
                $dolibarr = Dolibarr::getInstance();
                $response = $dolibarr->getVersions();
                if ($response["result"]->result_code == 'OK') {
                    $testdoliserveur = $this->l("DOLIBARR : Server parameters OK");
                    Configuration::updateValue('validated', '1');
                    Configuration::updateValue('dolibarr_version', $response["dolibarr"]);
                } else {
                    Configuration::updateValue('validated', '0');
                    $testdoliserveur = $this->l("DOLIBARR : Wrong server parameters. Check api key, login or password.");
                }
            }
            $validated = Configuration::get('validated');
            if ($validated != '1') {
                $this->_html .= '
				<div class="alert error">
				<img src="../img/admin/warning.gif" alt="' . $this->l('Confirmation') . '" />
				' . $this->l('Erreur Paramètres') . '
				<fieldset class="width10"><legend><img src="../img/admin/contact.gif" />' . $this->l('Rapport') . '</legend>
				<b style="color: #000033;">' . $this->l($testdoliserveur) . '</b><br />
				</fieldset>
				</div>';
            } else {
                $this->_html .= '
				<div class="conf confirm">
				<img src="../img/admin/ok.gif" alt="' . $this->l('Confirmation') . '" />
				' . $this->l('Paramètres Enregistrés') . '
				<fieldset class="width10"><legend><img src="../img/admin/contact.gif" />' . $this->l('Rapport') . '</legend>
				<b style="color: #000033;">' . $this->l($testdoliserveur) . '</b><br />
				</fieldset> 
				</div>';
            }
        }
        $output = $this->_html;
        $output .= $this->_displayErrors();
        $output .= '<fieldset style="width8">
						<legend>' . $this->l('Informations') . '</legend>  
								   <a>' . $this->l('Dolibar version : ') . Configuration::get('dolibarr_version') . '</a><br /></fieldset><br /> ';
        //if (!Tools::isSubmit('action')) {
        $output .= $this->displayForm();
        //}
        $output .= $this->displayActions();
        return $output;
    }
function synchroProduct($id_product)
{
    echo "<br/>Synchronize product : {$id_product}<br>";
    $product_description = Configuration::get('product_description');
    $use_barcode = Configuration::get('use_barcode');
    if ($product = Db::getInstance()->GetRow("select * from " . _DB_PREFIX_ . "product where id_product = '" . $id_product . "'")) {
        // retrieve params
        $prefix_ref_product = Configuration::get('prefix_ref_product');
        $prefix_ref_product = accents_sans("{$prefix_ref_product}");
        //retrieve product data
        $prix_produit_normal_HT = $product['price'];
        $active = $product['active'];
        $reference = $product['reference'];
        $reference = produits_caract("{$reference}");
        $en_vente = $product['active'];
        $barcode = $product['ean13'];
        //$datec=$product['date_add'];
        //$tms=$product['date_upd'];
        //$weight=$product['weight'];
        // find tva rate
        $id_tax_rules_group = $product['id_tax_rules_group'];
        //var_dump($id_tax_rules_group);
        $donnees_id_tax_rules_group = Db::getInstance()->GetRow("select * from " . _DB_PREFIX_ . "tax_rule where id_tax_rules_group = '" . $id_tax_rules_group . "'");
        //var_dump($donnees_id_tax_rules_group);
        $id_tax = $donnees_id_tax_rules_group['id_tax'];
        //var_dump($id_tax);
        $donnees_tax = Db::getInstance()->GetRow("select * from " . _DB_PREFIX_ . "tax where id_tax = '" . $id_tax . "'");
        $vat_rate = $donnees_tax['rate'];
        $prix_produit_normal_HT = sprintf("%.5f", $prix_produit_normal_HT);
        //find description
        $product_data = Db::getInstance()->GetRow("select * from " . _DB_PREFIX_ . "product_lang where id_product = '" . $id_product . "' AND id_lang = '" . Context::getContext()->language->id . "'");
        if ($product_description == '0') {
            $description = $product_data['description_short'];
        } else {
            $description = $product_data['description'];
        }
        $label = $product_data['name'];
        // RECUPERATION DES DONNEES DU PRODUIT DANS LA BASE ARTICLES *********************************************
        // RECUPERATION ID IMAGE ****************************************************
        //$donnees_id_image = Db::getInstance()->GetRow("select * from ".$prefix_presta."image where id_product='".$product_id."'");
        //$id_image=$donnees_id_image['id_image'];
        // FIN RECUPERATION ID IMAGE ****************************************************
        $dolibarr = Dolibarr::getInstance();
        $product = new DolibarrProduct();
        $product->ref_ext = $prefix_ref_product . $id_product;
        $product->ref = $reference;
        $product->label = $label;
        $product->description = $description;
        $product->price_net = $prix_produit_normal_HT;
        $product->vat_rate = $vat_rate;
        if ($use_barcode == '1') {
            $product->barcode = $barcode;
            $product->barcode_type = '2';
            // 2 = ean13
        }
        // Check if already exists in Dolibarr
        $exists = $dolibarr->getProduct($prefix_ref_product . $id_product);
        if ($exists["result"]->result_code == 'NOT_FOUND') {
            // Create new product
            echo "Create new product : ";
            $result = $dolibarr->createProduct($product);
            echo $result["result"]->result_code . "<br/>";
            if ($result["result"]->result_code != 'OK') {
                echo "Erreur de synchronisation : " . $result["result"]->result_label;
                echo "<br>product : ";
                var_dump($product);
                echo "<br>result : ";
                var_dump($result);
                return FALSE;
            }
        } else {
            if ($exists["result"]->result_code == 'OK') {
                // Update product
                echo "update product : ";
                $oldProduct = $exists["product"];
                $product->id = $oldProduct->id;
                $result = $dolibarr->updateProduct($product);
                echo $result["result"]->result_code . "<br/>";
                if ($result["result"]->result_code != 'OK') {
                    if (strpos($result["result"]->result_label, 'CONSTRAINT `fk_product_barcode_type') !== FALSE) {
                        echo "Synchronisation Error : Looks like you have enabled barcode in this module but not in your Dolibarr installation.";
                    } else {
                        echo "Erreur de synchronisation : " . $result["result"]->result_label;
                        echo "<br>product : ";
                        var_dump($product);
                        echo "<br>result : ";
                        var_dump($result);
                        return FALSE;
                    }
                }
            } else {
                if (strpos($result["result"]->result_label, 'CONSTRAINT `fk_product_barcode_type') !== FALSE) {
                    echo "Synchronisation Error : Looks like you have enabled barcode in this module but not in your Dolibarr installation.";
                } else {
                    echo "Erreur de synchronisation : " . $result["result"]->result_label;
                    echo "<br>product : ";
                    var_dump($product);
                    echo "<br>result : ";
                    var_dump($result);
                    return FALSE;
                }
            }
        }
    }
    return TRUE;
}