From d6c450253886b73d1dd557abb468795737481fe9 Mon Sep 17 00:00:00 2001 From: KHELIFA Date: Fri, 23 Nov 2018 15:07:22 +0100 Subject: [PATCH] Version 4.0.27 --- ChangeLog.md | 17 ++ admin/eCommerceSetup.php | 111 ++++++++-- admin/tpl/eCommerceSetup.tpl.php | 9 + class/actions_ecommerceng.class.php | 8 +- class/business/eCommerceSynchro.class.php | 168 ++++++++++---- ...eCommerceRemoteAccessWoocommerce.class.php | 205 +++++++++++------- core/modules/modECommerceNg.class.php | 2 +- ...ce_90_modECommerceng_ECommerceng.class.php | 50 +++-- langs/en_US/ecommerce.lang | 5 +- langs/en_US/woocommerce.lang | 14 +- langs/fr_FR/ecommerce.lang | 6 +- langs/fr_FR/woocommerce.lang | 26 ++- sql/llx_ecommerce_societe.key.sql | 2 +- sql/update_multi_societe_remote_id.sql | 1 + tpl/site.tpl.php | 2 +- 15 files changed, 452 insertions(+), 174 deletions(-) create mode 100755 sql/update_multi_societe_remote_id.sql diff --git a/ChangeLog.md b/ChangeLog.md index fb6e27a..3ceddb8 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,22 @@ # ChangeLog +## 4.0.27.0 + +- Ajout d'une variable global ECOMMERCENG_WOOCOMMERCE_VAT_NUMBER_META_NAME pour renseigner le nom de la meta donnée correspondant à la TVA client. +- Correction de la prise en consideration du pays lors de la creation du tiers. +- Ajout d'une variable global ECOMMERCENG_WOOCOMMERCE_DEFAULT_LANG_OTHER_COUNTRY pour renseigner la langue par défaut si le pays du tiers est different de sa société sinon laisse vide +- Création d'un nouveau tiers si le nom de la société de facturation est different de celui de livraison sur une commande et rattache le contact de livraison à celui-ci. +- Ne synchronise maintenant que les nouveaux tiers de Woocmmerce vers Dolibarr. +- Récupère tous les types de tiers (quelques soit le role de l'utilisateur). +- Une société peut être lié à plusieurs utilisateurs de woocommerce. +- Corrections synchronisations des contacts lors de la synchronisation des tiers de Woocmmerce vers Dolibarr. +- Support la fusion des sociétés. + +## 4.0.26.0 + +- Ajout du choix du type de prix sur WooCommerce (régulier ou de vente) synchronisé avec le prix de vente sur Dolibarr. +- Correction synchronisation du prix de vente minimum de ECommerce vers Dolibarr. + ## 4.0.25.0 - La suppression des liens des produits supprime aussi les catégories de la boutique sur les produits. diff --git a/admin/eCommerceSetup.php b/admin/eCommerceSetup.php index c187ff8..2466f4f 100644 --- a/admin/eCommerceSetup.php +++ b/admin/eCommerceSetup.php @@ -257,6 +257,8 @@ ); } + $ecommerceProductSynchPrice = GETPOST('ecommerce_product_synch_price', 'alpha'); + $ecommerceProductSynchDirection = array( 'image' => GETPOST('ecommerce_product_image_synch_direction', 'alpha'), 'ref' => GETPOST('ecommerce_product_ref_synch_direction', 'alpha'), @@ -274,6 +276,7 @@ 'payment_cond' => $_POST['ecommerce_payment_cond'], 'realtime_dtoe' => $ecommerceRealtimeDolibarrToECommerce, 'product_synch_direction' => $ecommerceProductSynchDirection, + 'product_synch_price' => $ecommerceProductSynchPrice, ); } @@ -292,10 +295,38 @@ if ($siteDb->type == 2) { // Woocommerce $result = ecommerceng_add_extrafields($db, $langs, [ [ + 'attrname' => "ecommerceng_description_{$conf->entity}", + 'label' => 'ECommercengWoocommerceDescription', + 'type' => 'text', + 'pos' => 1, + 'size' => '', + 'elementtype' => 'product', + 'unique' => 0, + 'required' => 0, + 'default_value' => '', + 'param' => '', + 'alwayseditable' => 1, + 'perms' => '', + 'list' => 1, + ],[ + 'attrname' => "ecommerceng_short_description_{$conf->entity}", + 'label' => 'ECommercengWoocommerceShortDescription', + 'type' => 'text', + 'pos' => 2, + 'size' => '', + 'elementtype' => 'product', + 'unique' => 0, + 'required' => 0, + 'default_value' => '', + 'param' => '', + 'alwayseditable' => 1, + 'perms' => '', + 'list' => 1, + ],[ 'attrname' => "ecommerceng_wc_status_{$siteDb->id}_{$conf->entity}", 'label' => $langs->trans('ECommercengWoocommerceStatus', $siteDb->name), 'type' => 'select', - 'pos' => 1, + 'pos' => 3, 'size' => '', 'elementtype' => 'product', 'unique' => 0, @@ -311,10 +342,38 @@ 'perms' => '', 'list' => 1, ],[ - 'attrname' => "ecommerceng_description_{$conf->entity}", - 'label' => 'ECommercengWoocommerceDescription', - 'type' => 'text', - 'pos' => 2, + 'attrname' => "ecommerceng_tax_class_{$siteDb->id}_{$conf->entity}", + 'label' => $langs->trans('ECommercengWoocommerceTaxClass', $siteDb->name), + 'type' => 'sellist', + 'pos' => 4, + 'size' => '', + 'elementtype' => 'product', + 'unique' => 0, + 'required' => 0, + 'default_value' => '', + 'param' => array('options' => array("c_ecommerceng_tax_class:label:code::active=1 AND site_id={$siteDb->id} AND entity={$conf->entity}" => null)), + 'alwayseditable' => 1, + 'perms' => '', + 'list' => 1, + /*],[ + 'attrname' => "ecommerceng_wc_regular_price_{$siteDb->id}_{$conf->entity}", + 'label' => $langs->trans('ECommercengWoocommerceRegularPrice', $siteDb->name), + 'type' => 'price', + 'pos' => 5, + 'size' => '', + 'elementtype' => 'product', + 'unique' => 0, + 'required' => 0, + 'default_value' => '', + 'param' => '', + 'alwayseditable' => 1, + 'perms' => '', + 'list' => 1,*/ + ],[ + 'attrname' => "ecommerceng_wc_sale_price_{$siteDb->id}_{$conf->entity}", + 'label' => $langs->trans('ECommercengWoocommerceSalePrice', $siteDb->name), + 'type' => 'price', + 'pos' => 6, 'size' => '', 'elementtype' => 'product', 'unique' => 0, @@ -324,12 +383,11 @@ 'alwayseditable' => 1, 'perms' => '', 'list' => 1, - ], - [ - 'attrname' => "ecommerceng_short_description_{$conf->entity}", - 'label' => 'ECommercengWoocommerceShortDescription', - 'type' => 'text', - 'pos' => 3, + ],[ + 'attrname' => "ecommerceng_wc_date_on_sale_from_{$siteDb->id}_{$conf->entity}", + 'label' => $langs->trans('ECommercengWoocommerceDateOnSaleFrom', $siteDb->name), + 'type' => 'date', + 'pos' => 7, 'size' => '', 'elementtype' => 'product', 'unique' => 0, @@ -339,23 +397,21 @@ 'alwayseditable' => 1, 'perms' => '', 'list' => 1, - ], - [ - 'attrname' => "ecommerceng_tax_class_{$siteDb->id}_{$conf->entity}", - 'label' => $langs->trans('ECommercengWoocommerceTaxClass', $siteDb->name), - 'type' => 'sellist', - 'pos' => 4, + ],[ + 'attrname' => "ecommerceng_wc_date_on_sale_to_{$siteDb->id}_{$conf->entity}", + 'label' => $langs->trans('ECommercengWoocommerceDateOnSaleTo', $siteDb->name), + 'type' => 'date', + 'pos' => 8, 'size' => '', 'elementtype' => 'product', 'unique' => 0, 'required' => 0, 'default_value' => '', - 'param' => array('options' => array("c_ecommerceng_tax_class:label:code::active=1 AND site_id={$siteDb->id} AND entity={$conf->entity}" => null)), + 'param' => '', 'alwayseditable' => 1, 'perms' => '', 'list' => 1, - ], - [ + ],[ 'attrname' => "ecommerceng_online_payment_{$conf->entity}", 'label' => 'ECommercengWoocommerceOnlinePayment', 'type' => 'boolean', @@ -391,6 +447,20 @@ 'alwayseditable' => 0, 'perms' => '', 'list' => 1, + ],[ + 'attrname' => "ecommerceng_wc_role_{$siteDb->id}_{$conf->entity}", + 'label' => $langs->trans('ECommercengWoocommerceCompanyRole', $siteDb->name), + 'type' => 'varchar', + 'pos' => 0, + 'size' => '255', + 'elementtype' => 'societe', + 'unique' => 0, + 'required' => 0, + 'default_value' => '', + 'param' => '', + 'alwayseditable' => 0, + 'perms' => '', + 'list' => 1, ], ], $error); } @@ -667,6 +737,7 @@ } } + $ecommerceProductSynchPrice = isset($siteDb->parameters['product_synch_price']) ? $siteDb->parameters['product_synch_price'] : 'regular'; $ecommerceProductImageSynchDirection = isset($siteDb->parameters['product_synch_direction']['image']) ? $siteDb->parameters['product_synch_direction']['image'] : ''; $ecommerceProductRefSynchDirection = isset($siteDb->parameters['product_synch_direction']['ref']) ? $siteDb->parameters['product_synch_direction']['ref'] : ''; $ecommerceProductDescriptionSynchDirection = isset($siteDb->parameters['product_synch_direction']['description']) ? $siteDb->parameters['product_synch_direction']['description'] : ''; diff --git a/admin/tpl/eCommerceSetup.tpl.php b/admin/tpl/eCommerceSetup.tpl.php index 889bcb1..4ec6bc0 100644 --- a/admin/tpl/eCommerceSetup.tpl.php +++ b/admin/tpl/eCommerceSetup.tpl.php @@ -298,6 +298,15 @@ trans('Description') ?> + > + trans('ECommerceWoocommerceProductSyncPrice') ?> + + selectarray('ecommerce_product_synch_price', array(/*'selling'=>$langs->trans('ECommerceWoocommerceSellingPrice'),*/ 'regular'=>$langs->trans('ECommerceWoocommerceRegularPrice')), $ecommerceProductSyncPrice); + ?> + + trans('ECommerceWoocommerceProductSyncPriceDescription') ?> + > trans('ECommerceProductImageSyncDirection') ?> diff --git a/class/actions_ecommerceng.class.php b/class/actions_ecommerceng.class.php index 09bd9d1..5ab0ac1 100644 --- a/class/actions_ecommerceng.class.php +++ b/class/actions_ecommerceng.class.php @@ -220,10 +220,10 @@ function afterODTCreation($parameters, &$object, &$action, $hookmanager) foreach ($sites as $site) { if (!$error) { $eCommerceCommande = new eCommerceCommande($db); - $eCommerceCommande->fetchByCommandeId($commande_id, $site->id); + $eCommerceCommande->fetchByCommandeId($commande_id, $site->id); // TODO $eCommerceCommande->remote_societe_id a rajouter a la table $eCommerceSociete = new eCommerceSociete($db); - $eCommerceSociete->fetchByFkSociete($societe_id, $site->id); + $eCommerceSociete->fetchByFkSociete($societe_id, $site->id); // TODO a qui donnée l'auteur du media si plusieur utilisateur lié a la societe if ($eCommerceCommande->remote_id > 0 && $eCommerceSociete->remote_id > 0) { $eCommerceSynchro = new eCommerceSynchro($db, $site); @@ -299,10 +299,10 @@ function afterPDFCreation($parameters, &$object, &$action, $hookmanager) foreach ($sites as $site) { if (!$error) { $eCommerceCommande = new eCommerceCommande($db); - $eCommerceCommande->fetchByCommandeId($commande_id, $site->id); + $eCommerceCommande->fetchByCommandeId($commande_id, $site->id); // TODO $eCommerceCommande->remote_societe_id a rajouter a la table $eCommerceSociete = new eCommerceSociete($db); - $eCommerceSociete->fetchByFkSociete($societe_id, $site->id); + $eCommerceSociete->fetchByFkSociete($societe_id, $site->id); // TODO a qui donnée l'auteur du media si plusieur utilisateur lié a la societe if ($eCommerceCommande->remote_id > 0 && $eCommerceSociete->remote_id > 0) { $eCommerceSynchro = new eCommerceSynchro($db, $site); diff --git a/class/business/eCommerceSynchro.class.php b/class/business/eCommerceSynchro.class.php index 6845390..3bfcb27 100644 --- a/class/business/eCommerceSynchro.class.php +++ b/class/business/eCommerceSynchro.class.php @@ -52,6 +52,9 @@ class eCommerceSynchro public $user; //Data access + /** + * @var DoliDB + */ private $db; public $eCommerceRemoteAccess; @@ -1102,12 +1105,18 @@ public function synchSociete($toNb=0) $dBSociete->client = $societeArray['client']; if (isset($societeArray['name_alias'])) $dBSociete->name_alias = $societeArray['name_alias']; if (isset($societeArray['email'])) $dBSociete->email = $societeArray['email']; - if (isset($societeArray['vatnumber'])) { - $dBSociete->tva_intra = $societeArray['vatnumber']; - } + if (isset($societeArray['vatnumber'])) $dBSociete->tva_intra = $societeArray['vatnumber']; //dol_trunc($societeArray['vatnumber'], 20, 'right', 'UTF-8', 1); + if (isset($societeArray['country_id'])) $dBSociete->country_id = $societeArray['country_id']; + if (isset($societeArray['default_lang'])) $dBSociete->default_lang = $societeArray['default_lang']; $dBSociete->tva_assuj = 1; // tva_intra is not saved if this field is not set $dBSociete->context['fromsyncofecommerceid'] = $this->eCommerceSite->id; + if (is_array($societeArray['extrafields'])) { + foreach ($societeArray['extrafields'] as $extrafield => $extrafield_value) { + $dBSociete->array_options['options_'.$extrafield] = $extrafield_value; + } + } + $result = $dBSociete->update($dBSociete->id, $this->user); if ($result < 0) { @@ -1144,26 +1153,26 @@ public function synchSociete($toNb=0) if ($result == -2) { $error++; - $this->error='Several thirdparties with name '.$societeArray['name'].' were found in Dolibarr. Sync is not possible. Please rename one of it to avoid duplicate.'; + $this->error='Several thirdparties with name "'.$societeArray['name'].'" were found in Dolibarr. Sync is not possible. Please rename one of it to avoid duplicate.'; $this->errors[]=$this->error; } - if (! $error && $result > 0) // We did not found with remote id but we found one with the fetch on name. - { - $eCommerceSocieteBis=new eCommerceSociete($this->db); - $synchExistsBis = $eCommerceSocieteBis->fetchByFkSociete($dBSociete->id, $this->eCommerceSite->id); - dol_syslog("Warning: we did not found the remote id into dolibarr eCommerceSociete table but we found a record with the name."); - if ($synchExistsBis > 0 && $eCommerceSocieteBis->id != $this->eCommerceSociete->id) - { - // We found a dolibarr record with name, but this one is alreayd linked and we know it is linked with another remote id because - // the current remote_id was not found when we previously did the fetchByRemoteId - // So we make as if we didn't found the thirdparty. It may be a duplicate name created in same transaction from Magento - dol_syslog("Warning: the record found with the name already has a remote_id in the eCommerceSite. So what we found is not what we want. We forget the find."); - unset($dBSociete); // Clear object, fetch was not what we wanted - $dBSociete = new Societe($this->db); - $result = 0; - } - } +// if (! $error && $result > 0) // We did not found with remote id but we found one with the fetch on name. +// { +// $eCommerceSocieteBis=new eCommerceSociete($this->db); +// $synchExistsBis = $eCommerceSocieteBis->fetchByFkSociete($dBSociete->id, $this->eCommerceSite->id); +// dol_syslog("Warning: we did not found the remote id into dolibarr eCommerceSociete table but we found a record with the name."); +// if ($synchExistsBis > 0 && $eCommerceSocieteBis->id != $this->eCommerceSociete->id) +// { +// // We found a dolibarr record with name, but this one is alreayd linked and we know it is linked with another remote id because +// // the current remote_id was not found when we previously did the fetchByRemoteId +// // So we make as if we didn't found the thirdparty. It may be a duplicate name created in same transaction from Magento +// dol_syslog("Warning: the record found with the name already has a remote_id in the eCommerceSite. So what we found is not what we want. We forget the find."); +// unset($dBSociete); // Clear object, fetch was not what we wanted +// $dBSociete = new Societe($this->db); +// $result = 0; +// } +// } if ($result == 0) { @@ -1172,14 +1181,20 @@ public function synchSociete($toNb=0) $dBSociete->client = $societeArray['client']; if (isset($societeArray['name_alias'])) $dBSociete->name_alias = $societeArray['name_alias']; if (isset($societeArray['email'])) $dBSociete->email = $societeArray['email']; - if (isset($societeArray['vatnumber'])) { - $dBSociete->tva_intra = dol_trunc($societeArray['vatnumber'], 20, 'right', 'UTF-8', 1); - } + if (isset($societeArray['vatnumber'])) $dBSociete->tva_intra = $societeArray['vatnumber']; //dol_trunc($societeArray['vatnumber'], 20, 'right', 'UTF-8', 1); + if (isset($societeArray['country_id'])) $dBSociete->country_id = $societeArray['country_id']; + if (isset($societeArray['default_lang'])) $dBSociete->default_lang = $societeArray['default_lang']; $dBSociete->tva_assuj = 1; // tva_intra is not saved if this field is not set $dBSociete->context['fromsyncofecommerceid'] = $this->eCommerceSite->id; $dBSociete->code_client = -1; // Automatic code $dBSociete->code_fournisseur = -1; // Automatic code + if (is_array($societeArray['extrafields'])) { + foreach ($societeArray['extrafields'] as $extrafield => $extrafield_value) { + $dBSociete->array_options['options_'.$extrafield] = $extrafield_value; + } + } + $result = $dBSociete->create($this->user); if ($result < 0) { @@ -1197,12 +1212,18 @@ public function synchSociete($toNb=0) $dBSociete->client = $societeArray['client']; if (isset($societeArray['name_alias'])) $dBSociete->name_alias = $societeArray['name_alias']; if (isset($societeArray['email'])) $dBSociete->email = $societeArray['email']; - if (isset($societeArray['vatnumber'])) { - $dBSociete->tva_intra = $societeArray['vatnumber']; - } + if (isset($societeArray['vatnumber'])) $dBSociete->tva_intra = $societeArray['vatnumber']; //dol_trunc($societeArray['vatnumber'], 20, 'right', 'UTF-8', 1); + if (isset($societeArray['country_id'])) $dBSociete->country_id = $societeArray['country_id']; + if (isset($societeArray['default_lang'])) $dBSociete->default_lang = $societeArray['default_lang']; $dBSociete->tva_assuj = 1; // tva_intra is not saved if this field is not set $dBSociete->context['fromsyncofecommerceid'] = $this->eCommerceSite->id; + if (is_array($societeArray['extrafields'])) { + foreach ($societeArray['extrafields'] as $extrafield => $extrafield_value) { + $dBSociete->array_options['options_'.$extrafield] = $extrafield_value; + } + } + $result = $dBSociete->update($dBSociete->id, $this->user); if ($result < 0) { @@ -1229,6 +1250,10 @@ public function synchSociete($toNb=0) //if a previous synchro exists if ($synchExists > 0 && !isset($this->error)) { +// $old_remote_ids = explode(',', $this->eCommerceSociete->remote_id); +// if (!in_array($societeArray['remote_id'], $old_remote_ids)) { +// $this->eCommerceSociete->remote_id = $this->eCommerceSociete->remote_id.','.$societeArray['remote_id']; +// } //eCommerce update if ($this->eCommerceSociete->update($this->user) < 0) { @@ -1257,11 +1282,12 @@ public function synchSociete($toNb=0) { dol_syslog("Make a remote call to get contacts"); // Slow because done on each thirdparty to sync. $listofaddressids=$this->eCommerceRemoteAccess->getRemoteAddressIdForSociete($societeArray['remote_id']); // Ask contacts to magento + if (is_array($listofaddressids) || $this->eCommerceSite->type == 2) + { if ($this->eCommerceSite->type == 2) { // Woocommerce $listofaddressids = $societeArray['remote_datas']; } - if (is_array($listofaddressids)) - { + $socpeoples = $this->eCommerceRemoteAccess->convertRemoteObjectIntoDolibarrSocpeople($listofaddressids); foreach($socpeoples as $tmpsocpeople) { @@ -1275,7 +1301,7 @@ public function synchSociete($toNb=0) else { $error++; - $this->errors[] = $this->langs->trans('ECommerceSynchSocieteErrorCreateUpdateSociete') . ' ' . $societeArray['name'] . ' ' . $societeArray['email'] . ' ' . $societeArray['client']; + $this->errors[] = $this->langs->trans('ECommerceSynchSocieteErrorCreateUpdateSociete') . ' "' . $societeArray['name'] . '" "' . $societeArray['email'] . '" "' . $societeArray['client'].'"'; } unset($dBSociete); @@ -1699,6 +1725,9 @@ public function synchProduct($toNb=0) (isset($productArray['price_min']) && $price_min_org != $productArray['price_min']) || price2num((float) $productArray['tax_rate']) != price2num((float) $tax_rate_org) ) { + if ($productArray['price_min'] === '') { + $productArray['price_min'] = $price_min_org <= $productArray['price'] ? $price_min_org : $productArray['price']; + } // The price type from eCommerce is defined for the site: TI/TE (Tax Include / Tax Excluded) if (empty($conf->global->PRODUIT_MULTIPRICES)) { $dBProduct->updatePrice($productArray['price'], $price_base_type, $this->user, $productArray['tax_rate'], $productArray['price_min']); @@ -1986,7 +2015,7 @@ public function synchProduct($toNb=0) */ public function synchCommande($toNb=0) { - global $conf, $user; + global $conf, $user, $mysoc; $error = 0; @@ -2430,6 +2459,65 @@ public function synchCommande($toNb=0) $commandeArray['socpeopleFacture']['fk_soc'] = $fk_soc_socpeopleFacture; $commandeArray['socpeopleLivraison']['fk_soc'] = $fk_soc_socpeopleLivraison; + if ($commandeArray['socpeopleCommande']['company'] != $commandeArray['socpeopleLivraison']['company']) { + $sCompany = $commandeArray['socpeopleLivraison']; + $fk_soc_socpeopleLivraison = 0; + + // First, we check company does not already exists with email + if (!empty($sCompany['email'])) { + $fk_soc_socpeopleLivraison = get_company_by_email($this->db, $sCompany['email'], $this->eCommerceSite->id); + } + + // If not, search for the company name + if ($fk_soc_socpeopleLivraison <= 0 && !empty($sCompany['company_name'])) { + $dBSociete = new Societe($this->db); + $result = $dBSociete->fetch(0, $sCompany['company_name']); + if ($result > 0) { + $fk_soc_socpeopleLivraison = $dBSociete->id; + } elseif ($result == -2) { + $error++; + $this->error='Several thirdparties with name "'.$sCompany['company_name'].'" were found in Dolibarr. Sync is not possible. Please rename one of it to avoid duplicate.'; + $this->errors[]=$this->error; + } + } + + // If not, create company + if ($fk_soc_socpeopleLivraison <= 0 && !$error) { + // Create company + $dBSociete = new Societe($this->db); + $dBSociete->name = $sCompany['company_name']; + $dBSociete->client = 1; + $dBSociete->email = $sCompany['email']; +// $dBSociete->phone = $sCompany['phone']; +// $dBSociete->fax = $sCompany['fax']; +// $dBSociete->address = $sCompany['address']; +// $dBSociete->zip = $sCompany['zip']; +// $dBSociete->town = $sCompany['town']; + if (isset($sCompany['country_id'])) { + $dBSociete->country_id = $sCompany['country_id']; + $dBSociete->default_lang = $dBSociete->country_id != $mysoc->country_id && !empty($conf->global->ECOMMERCENG_WOOCOMMERCE_DEFAULT_LANG_OTHER_COUNTRY) ? $conf->global->ECOMMERCENG_WOOCOMMERCE_DEFAULT_LANG_OTHER_COUNTRY : null; + } + $dBSociete->code_client = -1; // Automatic code + $dBSociete->code_fournisseur = -1; // Automatic code + + $result = $dBSociete->create($this->user); + if ($result < 0) { + $error++; + $this->errors[] = $this->langs->trans('ECommerceSynchSocieteCreatedInOrderError', $this->eCommerceSite->name, $commandeArray['ref_client']) . ' ' . $dBSociete->error; + $this->errors = array_merge($this->errors, $dBSociete->errors); + } else { + $fk_soc_socpeopleLivraison = $dBSociete->id; + + $dBSociete->update_note("Site: '{$this->eCommerceSite->name}' - Order: {$commandeArray['ref_client']}", '_private'); + } + } + + // Set new company to the shipping contact + if ($fk_soc_socpeopleLivraison > 0) { + $commandeArray['socpeopleLivraison']['fk_soc'] = $fk_soc_socpeopleLivraison; + } + } + if (! $error) { dol_syslog("synchCommande Now we sync people/address"); @@ -3630,20 +3718,18 @@ public function __destruct() */ function getContactIdFromInfos($contact) { - global $db; - $contactId = -1; $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'socpeople'; - $sql .= ' WHERE lastname LIKE "'.$db->escape(trim($contact->lastname)).'"'; - $sql .= ' AND firstname LIKE "'.$db->escape(trim($contact->firstname)).'"'; - $sql .= ' AND address LIKE "'.$db->escape(trim($contact->address)).'"'; - $sql .= ' AND town LIKE "'.$db->escape(trim($contact->town)).'"'; - $sql .= ' AND zip LIKE "'.$db->escape(trim($contact->zip)).'"'; + $sql .= ' WHERE lastname LIKE "'.$this->db->escape(trim($contact->lastname)).'"'; + $sql .= ' AND firstname LIKE "'.$this->db->escape(trim($contact->firstname)).'"'; + $sql .= ' AND address LIKE "'.$this->db->escape(trim($contact->address)).'"'; + $sql .= ' AND town LIKE "'.$this->db->escape(trim($contact->town)).'"'; + $sql .= ' AND zip LIKE "'.$this->db->escape(trim($contact->zip)).'"'; if (isset($contact->country_id)) $sql .= ' AND fk_pays='.($contact->country_id>0?$contact->country_id:'NULL'); - if (isset($contact->email)) $sql .= ' AND email LIKE "'.$db->escape(trim($contact->email)).'"'; - if (isset($contact->phone_pro)) $sql .= ' AND phone LIKE "'.$db->escape(trim($contact->phone_pro)).'"'; - if (isset($contact->fax)) $sql .= ' AND fax LIKE "'.$db->escape(trim($contact->fax)).'"'; + if (isset($contact->email)) $sql .= ' AND email LIKE "'.$this->db->escape(trim($contact->email)).'"'; + if (isset($contact->phone_pro)) $sql .= ' AND phone LIKE "'.$this->db->escape(trim($contact->phone_pro)).'"'; + if (isset($contact->fax)) $sql .= ' AND fax LIKE "'.$this->db->escape(trim($contact->fax)).'"'; $sql .= ' AND fk_soc='.$contact->fk_soc; $resql = $this->db->query($sql); @@ -3669,7 +3755,5 @@ function getContactIdFromInfos($contact) return $contactId; } } - - } diff --git a/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php b/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php index d0af0f5..ed0642a 100644 --- a/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php +++ b/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php @@ -259,18 +259,16 @@ public function getSocieteToUpdate($fromDate, $toDate) $from_date = isset($fromDate) && !empty($fromDate) ? new DateTime(dol_print_date($fromDate, 'standard')) : null; $to_date = isset($toDate) && !empty($toDate) ? new DateTime(dol_print_date($toDate, 'standard')) : null; - $filter = ['limit' => $per_page]; - // Not work with customers - //if (isset($fromDate) && !empty($fromDate)) $filter['updated_at_min'] = dol_print_date($fromDate - (24 * 60 * 60), 'dayrfc'); - //if (isset($toDate) && !empty($toDate)) $filter['updated_at_max'] = dol_print_date($toDate + (24 * 60 * 60), 'dayrfc'); - + $no_more = false; while (true) { try { - $page = $this->clientOld->get('customers', + $page = $this->client->get('customers', [ 'page' => $idxPage++, - 'filter' => $filter, - 'fields' => 'id,created_at,last_update' + 'per_page' => $per_page, + 'orderby' => 'registered_date', + 'order' => 'desc', + 'role' => 'all', ] ); } catch (HttpClientException $fault) { @@ -281,12 +279,11 @@ public function getSocieteToUpdate($fromDate, $toDate) return false; } - if (!isset($page->customers) || ($nbCustomers = count($page->customers)) == 0) break; - $page = $page->customers; + if (!is_array($page) || ($nbCustomers = count($page)) == 0) break; foreach ($page as $customer) { $id = $customer->id; - $date_customer = $this->getDateTimeFromGMTDateTime(!empty($customer->updated_at) ? $customer->updated_at : $customer->created_at); + $date_customer = $this->getDateTimeFromGMTDateTime(/*!empty($customer->date_modified_gmt) ? $customer->date_modified_gmt : */$customer->date_created_gmt); $update_customer = false; if ($from_date == $date_customer) { if ($this->eCommerceSociete->fetchByRemoteId($id, $this->site->id) > 0) { @@ -304,8 +301,14 @@ public function getSocieteToUpdate($fromDate, $toDate) if ($update_customer || (!isset($from_date) || $from_date < $date_customer) && (!isset($to_date) || $date_customer <= $to_date)) { $result[$id] = $id; $last_update[$id] = $date_customer->format('Y-m-d H:i:s'); + } else { + $no_more = true; } + + if ($no_more) break; } + + if ($no_more) break; } //important - order by last update @@ -350,7 +353,7 @@ public function getProductToUpdate($fromDate, $toDate) [ 'page' => $idxPage++, 'filter' => $filter, - 'fields' => 'id,created_at,updated_at,variations' + 'fields' => 'id,created_at,updated_at,variations', ] ); } catch (HttpClientException $fault) { @@ -541,7 +544,7 @@ public function getFactureToUpdate($fromDate, $toDate) public function convertRemoteObjectIntoDolibarrSociete($remoteObject, $toNb=0) { dol_syslog(__METHOD__ . ": Get " . count($remoteObject) . " remote companies ID: " . implode(', ', $remoteObject) . " for site ID {$this->site->id}", LOG_DEBUG); - global $conf, $langs; + global $conf, $langs, $mysoc; $companies = []; $nb_max_by_request = empty($conf->global->ECOMMERCENG_MAXSIZE_MULTICALL) ? 100 : min($conf->global->ECOMMERCENG_MAXSIZE_MULTICALL, 100); @@ -554,6 +557,9 @@ public function convertRemoteObjectIntoDolibarrSociete($remoteObject, $toNb=0) [ 'per_page' => $nb_max_by_request, 'include' => implode(',', $request), + 'orderby' => 'registered_date', + 'order' => 'desc', + 'role' => 'all', ] ); } catch (HttpClientException $fault) { @@ -568,22 +574,43 @@ public function convertRemoteObjectIntoDolibarrSociete($remoteObject, $toNb=0) foreach ($results as $company) { $last_update = $this->getDateTimeFromGMTDateTime(!empty($company->date_modified_gmt) ? $company->date_modified_gmt : $company->date_created_gmt); - // Company - if (!empty($company->billing->company)) { - $companies[] = [ + // Global infos + $item = [ 'remote_id' => $company->id, 'last_update' => $last_update->format('Y-m-d H:i:s'), - 'type' => 'company', - 'name' => $company->billing->company, 'name_alias' => null, - 'email' => !empty($conf->global->ECOMMERCENG_WOOCOMMERCE_GET_EMAIL_ON_COMPANY) ? $company->email : null, 'email_key' => $company->email, 'client' => 1, 'vatnumber' => null, 'note_private' => "Site: '{$this->site->name}' - ID: {$company->id}", 'country_id' => getCountry($company->billing->country, 3), + 'default_lang' => $mysoc->default_lang, 'remote_datas' => $company, + 'extrafields' => [ + "ecommerceng_wc_role_{$this->site->id}_{$conf->entity}" => $langs->trans('ECommercengWoocommerceCompanyRole_' . $company->role), + ], ]; + + // Default language + if ($item['country_id'] != $mysoc->country_id && !empty($conf->global->ECOMMERCENG_WOOCOMMERCE_DEFAULT_LANG_OTHER_COUNTRY)) { + $item['default_lang'] = $conf->global->ECOMMERCENG_WOOCOMMERCE_DEFAULT_LANG_OTHER_COUNTRY; + } + + // Meta datas + if (!empty($conf->global->ECOMMERCENG_WOOCOMMERCE_VAT_NUMBER_META_NAME)) { + foreach ($company->meta_data as $data) { + if ($data->key == $conf->global->ECOMMERCENG_WOOCOMMERCE_VAT_NUMBER_META_NAME) { + $item['vatnumber'] = $data->value; + break; + } + } + } + + // Company + if (!empty($company->billing->company)) { + $item['type'] = 'company'; + $item['name'] = $company->billing->company; + $item['email'] = !empty($conf->global->ECOMMERCENG_WOOCOMMERCE_GET_EMAIL_ON_COMPANY) ? $company->email : null; } // User else { @@ -592,25 +619,16 @@ public function convertRemoteObjectIntoDolibarrSociete($remoteObject, $toNb=0) if (!empty($firstname) && !empty($lastname)) { $name = dolGetFirstLastname($firstname, $lastname); } elseif (!empty($firstname)) { - $name = dolGetFirstLastname($firstname, $langs->trans("ECommercengWoocommerceLastnameNotInformed")); + $name = dolGetFirstLastname($firstname, $langs->transnoentitiesnoconv("ECommercengWoocommerceLastnameNotInformed")); } else { - $name = $langs->trans('ECommercengWoocommerceWithoutFirstnameLastname'); + $name = $langs->transnoentitiesnoconv('ECommercengWoocommerceWithoutFirstnameLastname'); } - $companies[] = [ - 'remote_id' => $company->id, - 'last_update' => $last_update->format('Y-m-d H:i:s'), - 'type' => 'user', - 'name' => $name, - 'name_alias' => null, - 'email' => $company->email, - 'email_key' => $company->email, - 'client' => 1, - 'vatnumber' => null, - 'note_private' => "Site: '{$this->site->name}' - ID: {$company->id}", - 'country_id' => getCountry($company->billing->country, 3), - 'remote_datas' => $company, - ]; + $item['type'] = 'user'; + $item['name'] = $name; + $item['email'] = $company->email; } + + $companies[] = $item; } } } @@ -645,14 +663,14 @@ public function convertRemoteObjectIntoDolibarrSocpeople($remoteCompany) $bContact = $remoteCompany->billing; if (!empty($bContact->address_1) || !empty($bContact->address_2) || !empty($bContact->postcode) || !empty($bContact->city) || !empty($bContact->country) || - !empty($bContact->email) || !empty($bContact->phone) + !empty($bContact->email) || !empty($bContact->company) || !empty($bContact->phone) ) { $firstname = !empty($bContact->first_name) ? $bContact->first_name : $remoteCompany->first_name; $lastname = !empty($bContact->last_name) ? $bContact->last_name : $remoteCompany->last_name; if (!empty($firstname) && empty($lastname)) { - $lastname = $langs->trans("ECommercengWoocommerceLastnameNotInformed"); + $lastname = $langs->transnoentitiesnoconv("ECommercengWoocommerceLastnameNotInformed"); } elseif (empty($firstname) && empty($lastname)) { - $lastname = $langs->trans('ECommercengWoocommerceWithoutFirstnameLastname'); + $lastname = $langs->transnoentitiesnoconv('ECommercengWoocommerceWithoutFirstnameLastname'); } $contacts[] = [ 'remote_id' => null, @@ -682,9 +700,9 @@ public function convertRemoteObjectIntoDolibarrSocpeople($remoteCompany) $firstname = !empty($sContact->first_name) ? $sContact->first_name : $remoteCompany->first_name; $lastname = !empty($sContact->last_name) ? $sContact->last_name : $remoteCompany->last_name; if (!empty($firstname) && empty($lastname)) { - $lastname = $langs->trans("ECommercengWoocommerceLastnameNotInformed"); + $lastname = $langs->transnoentitiesnoconv("ECommercengWoocommerceLastnameNotInformed"); } elseif (empty($firstname) && empty($lastname)) { - $lastname = $langs->trans('ECommercengWoocommerceWithoutFirstnameLastname'); + $lastname = $langs->transnoentitiesnoconv('ECommercengWoocommerceWithoutFirstnameLastname'); } $contacts[] = [ 'remote_id' => null, @@ -725,6 +743,7 @@ public function convertRemoteObjectIntoDolibarrProduct($remoteObject, $toNb=0) $products_variation = []; $nb_max_by_request = empty($conf->global->ECOMMERCENG_MAXSIZE_MULTICALL) ? 100 : min($conf->global->ECOMMERCENG_MAXSIZE_MULTICALL, 100); + $productSynchPrice = isset($this->site->parameters['product_synch_price']) ? $this->site->parameters['product_synch_price'] : 'regular'; $productImageSynchDirection = isset($this->site->parameters['product_synch_direction']['image']) ? $this->site->parameters['product_synch_direction']['image'] : ''; $productRefSynchDirection = isset($this->site->parameters['product_synch_direction']['ref']) ? $this->site->parameters['product_synch_direction']['ref'] : ''; $productDescriptionSynchDirection = isset($this->site->parameters['product_synch_direction']['description']) ? $this->site->parameters['product_synch_direction']['description'] : ''; @@ -789,6 +808,12 @@ public function convertRemoteObjectIntoDolibarrProduct($remoteObject, $toNb=0) $remote_id = $product->id; // id product $last_update = $last_update_product->format('Y-m-d H:i:s'); + $price = $productSynchPrice == 'selling' ? $product->price : $product->regular_price; + $date_on_sale_from = $this->getDateTimeFromGMTDateTime($product->date_on_sale_from_gmt); + $date_on_sale_from = isset($date_on_sale_from) ? $date_on_sale_from->getTimestamp() : ''; + $date_on_sale_to = $this->getDateTimeFromGMTDateTime($product->date_on_sale_to_gmt); + $date_on_sale_to = isset($date_on_sale_to) ? $date_on_sale_to->getTimestamp() : ''; + // Produit de base if (in_array($remote_id, $remoteObject, true)) { $products_last_update[$remote_id] = $last_update; @@ -797,29 +822,26 @@ public function convertRemoteObjectIntoDolibarrProduct($remoteObject, $toNb=0) 'remote_id' => $remote_id, 'last_update' => $last_update, 'fk_product_type' => ($product->virtual ? 1 : 0), // 0 (product) or 1 (service) - //'ref' => $product->sku, 'label' => $product->name, - //'weight' => $product->weight, - 'price' => $product->price, + 'price' => $price, 'envente' => empty($product->variations) ? 1 : 0, 'enachat' => empty($product->variations) ? 1 : 0, 'finished' => 1, // 1 = manufactured, 0 = raw material 'canvas' => $canvas, 'categories' => $categories, 'tax_rate' => $this->getTaxRate($product->tax_class, $product->tax_status), - 'price_min' => $product->price, + 'price_min' => '', 'fk_country' => '', 'url' => $product->permalink, // Stock 'stock_qty' => $product->stock_quantity, 'is_in_stock' => $product->in_stock, // not used 'extrafields' => [ - //"ecommerceng_wc_status_{$this->site->id}_{$conf->entity}" => $product->status, - //"ecommerceng_description_{$conf->entity}" => $product->description, - //"ecommerceng_short_description_{$conf->entity}" => $product->short_description, - //"ecommerceng_tax_class_{$this->site->id}_{$conf->entity}" => $this->getTaxClass($product->tax_class, $product->tax_status), + "ecommerceng_wc_regular_price_{$this->site->id}_{$conf->entity}" => $product->regular_price, + "ecommerceng_wc_sale_price_{$this->site->id}_{$conf->entity}" => $product->sale_price, + "ecommerceng_wc_date_on_sale_from_{$this->site->id}_{$conf->entity}" => $date_on_sale_from, + "ecommerceng_wc_date_on_sale_to_{$this->site->id}_{$conf->entity}" => $date_on_sale_to, ], - //'images' => $images, ]; if ($productImageSynchDirection == 'etod' || $productImageSynchDirection == 'all') { @@ -905,6 +927,12 @@ public function convertRemoteObjectIntoDolibarrProduct($remoteObject, $toNb=0) $remote_id = $product->id . '|' . $variation->id; // id product | id variation $last_update = $last_update_product->format('Y-m-d H:i:s'); //$last_update_product_variation->format('Y-m-d H:i:s'); + $price = $productSynchPrice == 'selling' ? $variation->price : $variation->regular_price; + $date_on_sale_from = $this->getDateTimeFromGMTDateTime($variation->date_on_sale_from_gmt); + $date_on_sale_from = isset($date_on_sale_from) ? $date_on_sale_from->getTimestamp() : ''; + $date_on_sale_to = $this->getDateTimeFromGMTDateTime($variation->date_on_sale_to_gmt); + $date_on_sale_to = isset($date_on_sale_to) ? $date_on_sale_to->getTimestamp() : ''; + // Variation $products_last_update[$remote_id] = $last_update; $products_variation[$remote_id] = 1; @@ -912,27 +940,25 @@ public function convertRemoteObjectIntoDolibarrProduct($remoteObject, $toNb=0) 'remote_id' => $remote_id, 'last_update' => $last_update, 'fk_product_type' => ($variation->virtual ? 1 : 0), // 0 (product) or 1 (service) - //'ref' => $variation->sku, 'label' => $product->name . $attributesLabel, - //'weight' => $variation->weight, - 'price' => $variation->price, + 'price' => $price, 'envente' => 1, 'enachat' => 1, 'finished' => 1, // 1 = manufactured, 0 = raw material 'canvas' => $canvas, 'categories' => $categories, - //'tax_rate' => $this->getTaxRate($variation->tax_class, $variation->tax_status), - 'price_min' => $variation->price, + 'price_min' => '', 'fk_country' => '', 'url' => $variation->permalink, // Stock 'stock_qty' => $variation->stock_quantity, 'is_in_stock' => $variation->in_stock, // not used 'extrafields' => [ - //"ecommerceng_description_{$conf->entity}" => $variation->description, - //"ecommerceng_tax_class_{$this->site->id}_{$conf->entity}" => $this->getTaxClass($variation->tax_class, $variation->tax_status), + "ecommerceng_wc_regular_price_{$this->site->id}_{$conf->entity}" => $variation->regular_price, + "ecommerceng_wc_sale_price_{$this->site->id}_{$conf->entity}" => $variation->sale_price, + "ecommerceng_wc_date_on_sale_from_{$this->site->id}_{$conf->entity}" => $date_on_sale_from, + "ecommerceng_wc_date_on_sale_to_{$this->site->id}_{$conf->entity}" => $date_on_sale_to, ], - //'images' => $images, ]; if ($productImageSynchDirection == 'etod' || $productImageSynchDirection == 'all') { @@ -1074,14 +1100,15 @@ public function convertRemoteObjectIntoDolibarrCommande($remoteObject, $toNb=0) $firstname = $bContact->first_name; $lastname = $bContact->last_name; if (!empty($firstname) && empty($lastname)) { - $lastname = $langs->trans("ECommercengWoocommerceLastnameNotInformed"); + $lastname = $langs->transnoentitiesnoconv("ECommercengWoocommerceLastnameNotInformed"); } elseif (empty($firstname) && empty($lastname)) { - $lastname = $langs->trans('ECommercengWoocommerceWithoutFirstnameLastname'); + $lastname = $langs->transnoentitiesnoconv('ECommercengWoocommerceWithoutFirstnameLastname'); } $contactBilling = [ 'remote_id' => "", 'type' => 1, //eCommerceSocpeople::CONTACT_TYPE_ORDER, 'last_update' => $last_update->format('Y-m-d H:i:s'), + 'company' => $bContact->company, 'firstname' => $firstname, 'lastname' => $lastname, 'address' => $bContact->address_1 . (!empty($bContact->address_1) && !empty($bContact->address_2) ? "\n" : "") . $bContact->address_2, @@ -1111,14 +1138,15 @@ public function convertRemoteObjectIntoDolibarrCommande($remoteObject, $toNb=0) $firstname = $sContact->first_name; $lastname = $sContact->last_name; if (!empty($firstname) && empty($lastname)) { - $lastname = $langs->trans("ECommercengWoocommerceLastnameNotInformed"); + $lastname = $langs->transnoentitiesnoconv("ECommercengWoocommerceLastnameNotInformed"); } elseif (empty($firstname) && empty($lastname)) { - $lastname = $langs->trans('ECommercengWoocommerceWithoutFirstnameLastname'); + $lastname = $langs->transnoentitiesnoconv('ECommercengWoocommerceWithoutFirstnameLastname'); } $contactShipping = [ 'remote_id' => "", 'type' => 1, //eCommerceSocpeople::CONTACT_TYPE_DELIVERY, 'last_update' => $last_update->format('Y-m-d H:i:s'), + 'company' => $sContact->company, 'firstname' => $firstname, 'lastname' => $lastname, 'address' => $sContact->address_1 . (!empty($sContact->address_1) && !empty($sContact->address_2) ? "\n" : "") . $sContact->address_2, @@ -1129,6 +1157,19 @@ public function convertRemoteObjectIntoDolibarrCommande($remoteObject, $toNb=0) 'phone' => null, 'fax' => null, ]; + + if (empty($sContact->company)) { + if (!empty($firstname) && !empty($lastname)) { + $name = dolGetFirstLastname($firstname, $lastname); + } elseif (!empty($firstname)) { + $name = dolGetFirstLastname($firstname, $langs->transnoentitiesnoconv("ECommercengWoocommerceLastnameNotInformed")); + } else { + $name = $langs->transnoentitiesnoconv('ECommercengWoocommerceWithoutFirstnameLastname'); + } + $contactShipping['company_name'] = $name; + } else { + $contactShipping['company_name'] = $sContact->company; + } } else { $contactShipping = $contactBilling; $contactShipping['type'] = 1; //eCommerceSocpeople::CONTACT_TYPE_DELIVERY; @@ -1416,6 +1457,7 @@ public function updateRemoteProduct($remote_id, $object) $remote_product_variation_id = $idsProduct[2]; } + $productSynchPrice = isset($this->site->parameters['product_synch_price']) ? $this->site->parameters['product_synch_price'] : 'regular'; $productImageSynchDirection = isset($this->site->parameters['product_synch_direction']['image']) ? $this->site->parameters['product_synch_direction']['image'] : ''; $productRefSynchDirection = isset($this->site->parameters['product_synch_direction']['ref']) ? $this->site->parameters['product_synch_direction']['ref'] : ''; $productDescriptionSynchDirection = isset($this->site->parameters['product_synch_direction']['description']) ? $this->site->parameters['product_synch_direction']['description'] : ''; @@ -1470,6 +1512,7 @@ public function updateRemoteProduct($remote_id, $object) dol_syslog(__METHOD__ . ': Error:' . $error_msg, LOG_ERR); return false; } + $regular_price = $object->array_options["options_ecommerceng_wc_regular_price_{$this->site->id}_{$conf->entity}"]; // images $images = []; @@ -1608,7 +1651,7 @@ public function updateRemoteProduct($remote_id, $object) $variationData = [ //'description' => nl2br($object->array_options["options_ecommerceng_description_{$conf->entity}"]), // string Variation description. //'sku' => $object->ref, // string Unique identifier. - 'regular_price' => $price, // string Variation regular price. + 'regular_price' => $productSynchPrice == 'regular' ? $price : $regular_price, // string Variation regular price. //'sale_price' => '', // string Variation sale price. //'date_on_sale_from' => '', // date-time Start date of sale price, in the site’s timezone. //'date_on_sale_from_gmt' => '', // date-time Start date of sale price, as GMT. @@ -1780,7 +1823,7 @@ public function updateRemoteProduct($remote_id, $object) //'description' => nl2br($object->array_options["options_ecommerceng_description_{$conf->entity}"]), // string Product description. //'short_description' => nl2br($object->array_options["options_ecommerceng_short_description_{$conf->entity}"]), // string Product short description. //'sku' => $object->ref, // string Unique identifier. - 'regular_price' => $price, // string Product regular price. + 'regular_price' => $productSynchPrice == 'regular' ? $price : $regular_price, // string Product regular price. //'sale_price' => '', // string Product sale price. //'date_on_sale_from' => '', // date-time Start date of sale price, in the site’s timezone. //'date_on_sale_from_gmt' => '', // date-time Start date of sale price, as GMT. @@ -1870,6 +1913,10 @@ public function updateRemoteProduct($remote_id, $object) } } + // Update extrafields infos + $object->array_options["options_ecommerceng_wc_regular_price_{$this->site->id}_{$conf->entity}"] = $productSynchPrice == 'regular' ? $price : $regular_price; + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) $object->insertExtraFields(); + dol_syslog(__METHOD__ . ": end", LOG_DEBUG); return true; } @@ -1887,11 +1934,14 @@ public function updateRemoteStockProduct($remote_id, $object) dol_syslog(__METHOD__ . ": Update stock of the remote product ID $remote_id for MouvementStock ID {$object->id}, new qty: {$object->qty_after} for site ID {$this->site->id}", LOG_DEBUG); global $langs, $user; + $new_stocks = ceil($object->qty_after); + $stocks_label = $object->qty_after . ' -> ' . $new_stocks; + if (preg_match('/^(\d+)\|(\d+)$/', $remote_id, $idsProduct) == 1) { // Variations $variationData = [ //'manage_stock' => '', // boolean Stock management at variation level. Default is false. - 'stock_quantity' => $object->qty_after, // integer Stock quantity. + 'stock_quantity' => $new_stocks, // integer Stock quantity. 'in_stock' => $object->qty_after > 0, // boolean Controls whether or not the variation is listed as “in stock” or “out of stock” on the frontend. Default is true. //'backorders' => '', // string If managing stock, this controls if backorders are allowed. Options: no, notify and yes. Default is no. ]; @@ -1899,16 +1949,16 @@ public function updateRemoteStockProduct($remote_id, $object) try { $result = $this->client->put("products/$idsProduct[1]/variations/$idsProduct[2]", $variationData); } catch (HttpClientException $fault) { - $this->errors[] = $langs->trans('ECommerceWoocommerceUpdateRemoteStockProductVariation', $this->site->name, $fault->getCode() . ': ' . $fault->getMessage()); + $this->errors[] = $langs->trans('ECommerceWoocommerceUpdateRemoteStockProductVariation', $stocks_label, $idsProduct[2], $idsProduct[1], $this->site->name) . ' ' . $fault->getCode() . ': ' . $fault->getMessage(); dol_syslog(__METHOD__ . - ': Error:' . $langs->transnoentitiesnoconv('ECommerceWoocommerceUpdateRemoteStockProductVariation', $this->site->name, $fault->getCode() . ': ' . $fault->getMessage()) . - ' - Request:' . json_encode($fault->getRequest()) . ' - Response:' . json_encode($fault->getResponse()), LOG_ERR); + ': Error:' . $langs->transnoentitiesnoconv('ECommerceWoocommerceUpdateRemoteStockProductVariation', $stocks_label, $idsProduct[2], $idsProduct[1], $this->site->name) . ' ' . $fault->getCode() . ': ' . $fault->getMessage()) . + ' - Request:' . json_encode($fault->getRequest()) . ' - Response:' . json_encode($fault->getResponse(), LOG_ERR); return false; } } else { $productData = [ //'manage_stock' => false, // boolean Stock management at product level. Default is false. - 'stock_quantity' => $object->qty_after, // integer Stock quantity. + 'stock_quantity' => $new_stocks, // integer Stock quantity. 'in_stock' => $object->qty_after > 0, // boolean Controls whether or not the product is listed as “in stock” or “out of stock” on the frontend. Default is true. //'backorders' => '', // string If managing stock, this controls if backorders are allowed. Options: no, notify and yes. Default is no. ]; @@ -1916,10 +1966,10 @@ public function updateRemoteStockProduct($remote_id, $object) try { $result = $this->client->put("products/$remote_id", $productData); } catch (HttpClientException $fault) { - $this->errors[] = $langs->trans('ECommerceWoocommerceUpdateRemoteStockProduct', $this->site->name, $fault->getCode() . ': ' . $fault->getMessage()); + $this->errors[] = $langs->trans('ECommerceWoocommerceUpdateRemoteStockProduct', $stocks_label, $idsProduct[1], $this->site->name) . ' ' . $fault->getCode() . ': ' . $fault->getMessage(); dol_syslog(__METHOD__ . - ': Error:' . $langs->transnoentitiesnoconv('ECommerceWoocommerceUpdateRemoteStockProduct', $this->site->name, $fault->getCode() . ': ' . $fault->getMessage()) . - ' - Request:' . json_encode($fault->getRequest()) . ' - Response:' . json_encode($fault->getResponse()), LOG_ERR); + ': Error:' . $langs->transnoentitiesnoconv('ECommerceWoocommerceUpdateRemoteStockProduct', $stocks_label, $idsProduct[1], $this->site->name) . ' ' . $fault->getCode() . ': ' . $fault->getMessage()) . + ' - Request:' . json_encode($fault->getRequest()) . ' - Response:' . json_encode($fault->getResponse(), LOG_ERR); return false; } } @@ -2366,6 +2416,8 @@ public function createRemoteProduct($object) } } + $productSynchPrice = isset($this->site->parameters['product_synch_price']) ? $this->site->parameters['product_synch_price'] : 'regular'; + $regular_price = $object->array_options["options_ecommerceng_wc_regular_price_{$this->site->id}_{$conf->entity}"]; $status = $object->array_options["options_ecommerceng_wc_status_{$this->site->id}_{$conf->entity}"]; // Product @@ -2379,7 +2431,7 @@ public function createRemoteProduct($object) //'description' => $object->array_options["options_ecommerceng_description_{$conf->entity}"], // string Product description. //'short_description' => $object->array_options["options_ecommerceng_short_description_{$conf->entity}"], // string Product short description. //'sku' => $object->ref, // string Unique identifier. - 'regular_price' => $price, // string Product regular price. + 'regular_price' => $productSynchPrice == 'regular' ? $price : $regular_price, // string Product regular price. //'sale_price' => '', // string Product sale price. //'date_on_sale_from' => '', // date-time Start date of sale price, in the site’s timezone. //'date_on_sale_from_gmt' => '', // date-time Start date of sale price, as GMT. @@ -2578,6 +2630,7 @@ public function batchUpdateRemoteProducts($batch) dol_syslog(__METHOD__ . ": Create batch products from Dolibarr products IDs: '{$ids}' for site ID {$this->site->id}", LOG_DEBUG); global $conf, $langs; + $productSynchPrice = isset($this->site->parameters['product_synch_price']) ? $this->site->parameters['product_synch_price'] : 'regular'; $productImageSynchDirection = isset($this->site->parameters['product_synch_direction']['image']) ? $this->site->parameters['product_synch_direction']['image'] : ''; $productRefSynchDirection = isset($this->site->parameters['product_synch_direction']['ref']) ? $this->site->parameters['product_synch_direction']['ref'] : ''; $productDescriptionSynchDirection = isset($this->site->parameters['product_synch_direction']['description']) ? $this->site->parameters['product_synch_direction']['description'] : ''; @@ -2830,6 +2883,10 @@ public function batchUpdateRemoteProducts($batch) $status = $product_static->array_options["options_ecommerceng_wc_status_{$this->site->id}_{$conf->entity}"]; $description = $product_static->array_options["options_ecommerceng_description_{$conf->entity}"]; + $regular_price = $product_static->array_options["options_ecommerceng_wc_regular_price_{$this->site->id}_{$conf->entity}"]; + $sale_price = $product_static->array_options["options_ecommerceng_wc_sale_price_{$this->site->id}_{$conf->entity}"]; + $date_on_sale_from = $product_static->array_options["options_ecommerceng_wc_date_on_sale_from_{$this->site->id}_{$conf->entity}"]; + $date_on_sale_to = $product_static->array_options["options_ecommerceng_wc_date_on_sale_to_{$this->site->id}_{$conf->entity}"]; // Product $productData = [ @@ -2842,8 +2899,8 @@ public function batchUpdateRemoteProducts($batch) //'description' => (!empty($description) ? $description : $product_static->description), // string Product description. //'short_description' => $product_static->array_options["options_ecommerceng_short_description_{$conf->entity}"], // string Product short description. //'sku' => $sku, // string Unique identifier. - 'regular_price' => $price, // string Product regular price. - //'sale_price' => '', // string Product sale price. + 'regular_price' => $productSynchPrice == 'regular' ? $price : $regular_price, // string Product regular price. + //'sale_price' => $productSynchPrice == 'selling' ? $price : $sale_price, // string Product sale price. //'date_on_sale_from' => '', // date-time Start date of sale price, in the site’s timezone. //'date_on_sale_from_gmt' => '', // date-time Start date of sale price, as GMT. //'date_on_sale_to' => '', // date-time End date of sale price, in the site’s timezone. diff --git a/core/modules/modECommerceNg.class.php b/core/modules/modECommerceNg.class.php index 2cab90d..0d89e63 100644 --- a/core/modules/modECommerceNg.class.php +++ b/core/modules/modECommerceNg.class.php @@ -61,7 +61,7 @@ function __construct($db) $this->editor_url = 'http://www.open-dsi.fr'; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = '4.0.25'; + $this->version = '4.0.27'; // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) diff --git a/core/triggers/interface_90_modECommerceng_ECommerceng.class.php b/core/triggers/interface_90_modECommerceng_ECommerceng.class.php index 8e6adc1..e7f5018 100644 --- a/core/triggers/interface_90_modECommerceng_ECommerceng.class.php +++ b/core/triggers/interface_90_modECommerceng_ECommerceng.class.php @@ -125,44 +125,50 @@ function run_trigger($action,$object,$user,$langs,$conf) { $this->db->begin(); + if ($object->context['merge'] == 1) { + $merge_from_id = $object->context['mergefromid']; + + // Update all company link + $sql = "UPDATE " . MAIN_DB_PREFIX . "ecommerce_societe SET fk_societe = " . $object->id . " WHERE fk_societe = " . $merge_from_id; + + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $error_msg = $langs->trans('ECommerceUpdateRemoteCompanyLinkWhenMergeCompany', $merge_from_id, $object->id, $this->db->lasterror()); + $this->errors[] = "Error " . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' SQL: ' . $sql . '; Error:' . $error_msg, LOG_ERR); + } + } else { $eCommerceSite = new eCommerceSite($this->db); $sites = $eCommerceSite->listSites('object'); - foreach($sites as $site) - { - if ($object->context['fromsyncofecommerceid'] && $object->context['fromsyncofecommerceid'] == $site->id) - { + foreach ($sites as $site) { + if ($object->context['fromsyncofecommerceid'] && $object->context['fromsyncofecommerceid'] == $site->id) { dol_syslog("Triggers was ran from a create/update to sync from ecommerce to dolibarr, so we won't run code to sync from dolibarr to ecommerce"); continue; } - if (! $error) - { + if (!$error) { if (empty($site->parameters['realtime_dtoe']['thridparty'])) { dol_syslog("Triggers disabled from the config of the module"); continue; } - $eCommerceSociete = new eCommerceSociete($this->db); - $eCommerceSociete->fetchByFkSociete($object->id, $site->id); + $eCommerceSociete->fetchByFkSociete($object->id, $site->id); // TODO ne met a jour que le premier lié - if ($eCommerceSociete->remote_id > 0) - { + if ($eCommerceSociete->remote_id > 0) { $eCommerceSynchro = new eCommerceSynchro($this->db, $site); dol_syslog("Trigger ".$action." try to connect to eCommerce site ".$site->name); $eCommerceSynchro->connect(); - if (count($eCommerceSynchro->errors)) - { + if (count($eCommerceSynchro->errors)) { $error++; setEventMessages($eCommerceSynchro->error, $eCommerceSynchro->errors, 'errors'); } - if (! $error) - { + if (!$error) { $result = $eCommerceSynchro->eCommerceRemoteAccess->updateRemoteSociete($eCommerceSociete->remote_id, $object); $now = dol_now(); - if (! $result) - { + if (!$result) { $error++; $this->error=$eCommerceSynchro->eCommerceRemoteAccess->error; $this->errors=$eCommerceSynchro->eCommerceRemoteAccess->errors; @@ -180,16 +186,13 @@ function run_trigger($action,$object,$user,$langs,$conf) dol_syslog(__METHOD__ . ': Error:' . $error_msg, LOG_WARNING); } } - } - else - { + } else { // Get current categories require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $c = new Categorie($this->db); $catids = $c->containing($object->id, Categorie::TYPE_CUSTOMER, 'id'); - if (in_array($site->fk_cat_societe, $catids)) - { + if (in_array($site->fk_cat_societe, $catids)) { dol_syslog("Societe with id ".$object->id." is not linked to an ecommerce record but has category flag to push on eCommerce. So we push it"); // TODO /*$eCommerceSynchro = new eCommerceSynchro($this->db, $site); @@ -205,14 +208,13 @@ function run_trigger($action,$object,$user,$langs,$conf) { $result = $eCommerceSynchro->eCommerceRemoteAccess->updateRemoteProduct($eCommerceProduct->remote_id); }*/ - } - else - { + } else { dol_syslog("Societe with id ".$object->id." is not linked to an ecommerce record and does not has category flag to push on eCommerce."); } } } } + } if ($error) { diff --git a/langs/en_US/ecommerce.lang b/langs/en_US/ecommerce.lang index d4411b1..10c4a9f 100644 --- a/langs/en_US/ecommerce.lang +++ b/langs/en_US/ecommerce.lang @@ -236,4 +236,7 @@ SyncProductFirst = Synchroniser d'abord les produits ECommerceCreateRemoteCategoryLink = Erreur de la création du lien de la catégorie 'id:%s' sur le site '%s': %s ECommerceSyncheCommerceMotherCategoryCreateError=Erreur de création du lien de la catégorie racine pour la catégorie distante '%s' 'id:%s' sur le site '%s'. -ECommerceNGUpdateElementDateMoreRecent=Inclus aussi les éléments dont la date de mise à jour est plus récente que celle de synchronisation \ No newline at end of file +ECommerceNGUpdateElementDateMoreRecent=Inclus aussi les éléments dont la date de mise à jour est plus récente que celle de synchronisation +ECommerceOnlyNew = Only new + +ECommerceUpdateRemoteCompanyLinkWhenMergeCompany = Erreur de mise à jour des lien de la société 'id:%s' lors de la fusion avec la société 'id:%s': %s diff --git a/langs/en_US/woocommerce.lang b/langs/en_US/woocommerce.lang index fef7679..5d4657a 100644 --- a/langs/en_US/woocommerce.lang +++ b/langs/en_US/woocommerce.lang @@ -23,8 +23,8 @@ ECommerceWoocommerceUpdateRemoteProductSendImage=Erreur de l'envoi d'une image p ECommerceWoocommerceUpdateRemoteProductVariation=Erreur de mise à jour de la variation 'id:%s' du produit distant 'id:%s' sur le site '%s': %s ECommerceWoocommerceUpdateRemoteSociete=Erreur de mise à jour de la société distante 'id:%s' sur le site '%s': %s ECommerceWoocommerceUpdateRemoteSocpeople=Erreur de mise à jour des contacts/adresses de la société distante 'id:%s' sur le site '%s': %s -ECommerceWoocommerceUpdateRemoteStockProduct=Erreur de mise à jour des stocks de la variation 'id:%s' du produit distant 'id:%s' sur le site '%s': %s -ECommerceWoocommerceUpdateRemoteStockProductVariation=Erreur de mise à jour des stocks du produit distant 'id:%s' sur le site '%s': %s +ECommerceWoocommerceUpdateRemoteStockProduct=Erreur de mise à jour des stocks (%s) du produit distant 'id:%s' sur le site '%s': +ECommerceWoocommerceUpdateRemoteStockProductVariation=Erreur de mise à jour des stocks (%s) de la variation 'id:%s' du produit distant 'id:%s' sur le site '%s': ECommerceWoocommerceGetAllWoocommerceTaxClass=Erreur de récupération des données des classes de taxes sur le site '%s': %s ECommerceWoocommerceGetWoocommerceTaxes=Erreur de récupération des données des taxes sur le site '%s': %s @@ -49,3 +49,13 @@ ECommercengWoocommerceStatusPublish=Publish ECommercengWoocommerceWithoutFirstnameLastname=No firstname/lastname informed ECommercengWoocommerceLastnameNotInformed=[Lastname not informed] ECommerceWoocommerceUpdateRemoteBatchProduct = Erreur lors de la mise à jour du produit (sku : %s) sur le site '%s': %s + +ECommercengWoocommerceCompanyRole = Role for the site "%s" +ECommercengWoocommerceCompanyRole_administrator = Administrator +ECommercengWoocommerceCompanyRole_author = Author +ECommercengWoocommerceCompanyRole_contributor = Contributor +ECommercengWoocommerceCompanyRole_customer = Customer +ECommercengWoocommerceCompanyRole_editor = Editor +ECommercengWoocommerceCompanyRole_subscriber = Subscriber +ECommercengWoocommerceCompanyRole_shop_manager = Shop manager +ECommercengWoocommerceCompanyRole_ = No role for this site diff --git a/langs/fr_FR/ecommerce.lang b/langs/fr_FR/ecommerce.lang index 0907bfa..2553ffb 100644 --- a/langs/fr_FR/ecommerce.lang +++ b/langs/fr_FR/ecommerce.lang @@ -256,4 +256,8 @@ EcommerceNGConfirmUnlinkToECommerce=Êtes-vous sûr de vouloir enlever ce produi ECommerceResetCategoriesProductSuccess=catégories du site sur les produits ont bien été retirées. ECommerceSynchProductError=Erreur lors de la synchronisation du produit distant: -ECommerceErrorProductAlreadyLinkedWithRemoteProduct=Le produit avec cette réf. est déjà lié au produit distant ID: %s. \ No newline at end of file +ECommerceErrorProductAlreadyLinkedWithRemoteProduct=Le produit avec cette réf. est déjà lié au produit distant ID: %s. + +ECommerceOnlyNew = Seulement les nouveaux + +ECommerceUpdateRemoteCompanyLinkWhenMergeCompany = Erreur de mise à jour des lien de la société 'id:%s' lors de la fusion avec la société 'id:%s': %s diff --git a/langs/fr_FR/woocommerce.lang b/langs/fr_FR/woocommerce.lang index df23919..e62150a 100644 --- a/langs/fr_FR/woocommerce.lang +++ b/langs/fr_FR/woocommerce.lang @@ -23,8 +23,8 @@ ECommerceWoocommerceUpdateRemoteProductSendImage=Erreur de l'envoi d'une image p ECommerceWoocommerceUpdateRemoteProductVariation=Erreur de mise à jour de la variation 'id:%s' du produit distant 'id:%s' sur le site '%s': %s ECommerceWoocommerceUpdateRemoteSociete=Erreur de mise à jour de la société distante 'id:%s' sur le site '%s': %s ECommerceWoocommerceUpdateRemoteSocpeople=Erreur de mise à jour des contacts/adresses de la société distante 'id:%s' sur le site '%s': %s -ECommerceWoocommerceUpdateRemoteStockProduct=Erreur de mise à jour des stocks de la variation 'id:%s' du produit distant 'id:%s' sur le site '%s': %s -ECommerceWoocommerceUpdateRemoteStockProductVariation=Erreur de mise à jour des stocks du produit distant 'id:%s' sur le site '%s': %s +ECommerceWoocommerceUpdateRemoteStockProduct=Erreur de mise à jour des stocks (%s) du produit distant 'id:%s' sur le site '%s': +ECommerceWoocommerceUpdateRemoteStockProductVariation=Erreur de mise à jour des stocks (%s) de la variation 'id:%s' du produit distant 'id:%s' sur le site '%s': ECommerceWoocommerceGetAllWoocommerceTaxClass=Erreur de récupération des données des classes de taxes sur le site '%s': %s ECommerceWoocommerceGetWoocommerceTaxes=Erreur de récupération des données des taxes sur le site '%s': %s ECommerceWoocommerceCreateRemoteProductSendImage=Erreur de l'envoi d'une image pour le produit 'ref:%s' dans les média de Wordpress sur le site '%s': %s @@ -70,4 +70,24 @@ ECommerceWoocommerceCreateRemoteBatchCategory = Erreur lors de cre ECommerceWoocommerceCreateRemoteBatchProduct = Erreur lors de creation du produit (sku : %s) sur le site '%s': %s ECommerceWoocommerceUpdateRemoteBatchProduct = Erreur lors de la mise à jour du produit (sku : %s) sur le site '%s': %s -ECommerceWoocommerceErrorBaseTypeOfProductWithSiteParameter = Erreur de base de prix (HT/TTC) pour la saisie du prix du produit '%s', il doit être en '%s' pour le site '%s'. \ No newline at end of file +ECommerceWoocommerceErrorBaseTypeOfProductWithSiteParameter = Erreur de base de prix (HT/TTC) pour la saisie du prix du produit '%s', il doit être en '%s' pour le site '%s'. + +ECommerceWoocommerceProductSyncPrice = Synchronisation des prix de vente +ECommerceWoocommerceProductSyncPriceDescription = Ce paramètre détermine quel type de prix dans WooCommerce doit être synchronisé avec le prix de vente dans Dolibarr +ECommerceWoocommerceRegularPrice = Prix régulier +ECommerceWoocommerceSellingPrice = Prix de vente + +ECommercengWoocommerceRegularPrice = Prix régulier pour le site [%s] +ECommercengWoocommerceSalePrice = Prix promo pour le site [%s] +ECommercengWoocommerceDateOnSaleFrom = Date de début de la promo pour le site [%s] +ECommercengWoocommerceDateOnSaleTo = Date de fin de la promo pour le site [%s] + +ECommercengWoocommerceCompanyRole = Role pour le site "%s" +ECommercengWoocommerceCompanyRole_administrator = Administrateur +ECommercengWoocommerceCompanyRole_author = Auteur +ECommercengWoocommerceCompanyRole_contributor = Contributeur +ECommercengWoocommerceCompanyRole_customer = Client +ECommercengWoocommerceCompanyRole_editor = Éditeur +ECommercengWoocommerceCompanyRole_subscriber = Abonné +ECommercengWoocommerceCompanyRole_shop_manager = Gestionnaire boutique +ECommercengWoocommerceCompanyRole_ = Pas de rôle sur ce site diff --git a/sql/llx_ecommerce_societe.key.sql b/sql/llx_ecommerce_societe.key.sql index 2e0aaa6..d020a39 100644 --- a/sql/llx_ecommerce_societe.key.sql +++ b/sql/llx_ecommerce_societe.key.sql @@ -17,5 +17,5 @@ -- =================================================================== ALTER TABLE llx_ecommerce_societe ADD INDEX idx_ecommerce_societe_fk_societe ( fk_societe ); ALTER TABLE llx_ecommerce_societe ADD INDEX idx_ecommerce_societe_fk_site ( fk_site ); -ALTER TABLE llx_ecommerce_societe ADD UNIQUE KEY uk_ecommerce_societe_fk_site_fk_societe ( fk_site ,fk_societe ); +--ALTER TABLE llx_ecommerce_societe ADD UNIQUE KEY uk_ecommerce_societe_fk_site_fk_societe ( fk_site ,fk_societe ); --ALTER TABLE llx_ecommerce_societe ADD CONSTRAINT fk_ecommerce_societe_fk_societe FOREIGN KEY (fk_societe) REFERENCES llx_societe(rowid); \ No newline at end of file diff --git a/sql/update_multi_societe_remote_id.sql b/sql/update_multi_societe_remote_id.sql new file mode 100755 index 0000000..917eafd --- /dev/null +++ b/sql/update_multi_societe_remote_id.sql @@ -0,0 +1 @@ +ALTER TABLE llx_ecommerce_societe DROP INDEX uk_ecommerce_societe_fk_site_fk_societe; diff --git a/tpl/site.tpl.php b/tpl/site.tpl.php index 1fdb645..d39a39c 100644 --- a/tpl/site.tpl.php +++ b/tpl/site.tpl.php @@ -159,7 +159,7 @@ $var=!$var; ?> > - trans('ECommerceSociete') ?> + trans('ECommerceSociete') ?> (trans('ECommerceOnlyNew') ?>) *** ***