From 8fa7b924d5975f5d69d8571bc31a04dd15acfb5f Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 9 Dec 2017 12:08:50 +0100 Subject: [PATCH 001/386] enhance image using awesome icon --- htdocs/core/lib/functions.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9683517f377..ba842682221 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6245,7 +6245,7 @@ function dol_validElement($element) * Return img flag of country for a language code or country code * * @param string $codelang Language code (en_IN, fr_CA...) or Country code (IN, FR) - * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') * @return string HTML img string with flag. */ function picto_from_langcode($codelang, $moreatt = '') @@ -6258,7 +6258,7 @@ function picto_from_langcode($codelang, $moreatt = '') if ($codelang == 'auto') { - return img_picto_common($langs->trans('AutoDetectLang'), 'flags/int.png', $moreatt); + return ''; } $langtocountryflag = array( From a33411b8bd5842f1f201aaa03475d596b9c5f233 Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Wed, 20 Dec 2017 09:06:11 +0100 Subject: [PATCH 002/386] Create 7.0.0-8.0.0.sql --- .../install/mysql/migration/7.0.0-8.0.0.sql | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 htdocs/install/mysql/migration/7.0.0-8.0.0.sql diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql new file mode 100644 index 00000000000..e9a72ab9360 --- /dev/null +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -0,0 +1,26 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 7.0.0 or higher. +-- +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To drop an index: -- VMYSQL4.0 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.0 DROP INDEX nomindex +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_c_shipment_mode CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): -- VPGSQL8.2 NOT POSSIBLE. MUST DELETE/CREATE TABLE +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. + +-- For 8.0 +ALTER TABLE llx_societe ADD COLUMN fk_entrepot int DEFAULT 0; From e308124ed6d473f6b0694586c3a29b3eb4831320 Mon Sep 17 00:00:00 2001 From: AlainRnet Date: Wed, 20 Dec 2017 17:41:26 +0100 Subject: [PATCH 003/386] Show total number of records by category There is so much information missing in these categories and it is also not possible to sort or display other information than currently displayed. Here is a small hack to display the total number of record(s) in the list header of each category. --- htdocs/categories/viewcat.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index daa5ade05b5..255dc4888aa 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -353,7 +353,7 @@ if ($type == Categorie::TYPE_PRODUCT) print "
"; print "\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -402,7 +402,7 @@ if ($type == Categorie::TYPE_SUPPLIER) { print "
"; print '
'.$langs->trans("ProductsAndServices")."
'.$langs->trans("ProductsAndServices")." (".count($prods).")
'."\n"; - print '\n"; + print '\n"; if (count($socs) > 0) { @@ -451,7 +451,7 @@ if($type == Categorie::TYPE_CUSTOMER) { print "
"; print '
'.$langs->trans("Suppliers")."
'.$langs->trans("Suppliers")." (".count($socs).")
'."\n"; - print '\n"; + print '\n"; if (count($socs) > 0) { @@ -507,7 +507,7 @@ if ($type == Categorie::TYPE_MEMBER) { print "
"; print "
'.$langs->trans("Customers")."
'.$langs->trans("Customers")." (".count($socs).")
\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -558,7 +558,7 @@ if ($type == Categorie::TYPE_CONTACT) { print "
"; print '
'.$langs->trans("Member")."
'.$langs->trans("Member")." (".count($prods).")
'."\n"; - print '\n"; + print '\n"; if (count($contacts) > 0) { @@ -613,7 +613,7 @@ if ($type == Categorie::TYPE_ACCOUNT) { print "
"; print "
'.$langs->trans("Contact")."
'.$langs->trans("Contact")." (".count($contacts).")
\n"; - print '\n"; + print '\n"; if (count($accounts) > 0) { @@ -666,7 +666,7 @@ if ($type == Categorie::TYPE_PROJECT) { print "
"; print "
'.$langs->trans("Account")."
'.$langs->trans("Account")." (".count($accounts).")
\n"; - print '\n"; + print '\n"; if (count($projects) > 0) { From a9c7dc48abfaa23a0411535576472daf4cbb1a23 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sun, 24 Dec 2017 17:31:31 +0100 Subject: [PATCH 004/386] New option to force e-mail recipient, helpful for test purposes --- htdocs/admin/mails.php | 11 +++++++++++ htdocs/core/class/CMailFile.class.php | 8 +++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index d482322a054..677e6099a8d 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -70,6 +70,7 @@ complete_substitutions_array($substitutionarrayfortest, $langs); if ($action == 'update' && empty($_POST["cancel"])) { dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS", GETPOST("MAIN_DISABLE_ALL_MAILS"),'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_FORCE_SENDTO", GETPOST("MAIN_MAIL_FORCE_SENDTO"),'chaine',0,'',$conf->entity); // Send mode parameters dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"),'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"),'chaine',0,'',$conf->entity); @@ -238,6 +239,11 @@ if ($action == 'edit') print ''; + + // Force e-mail recipient + print ''; // Separator @@ -477,6 +483,11 @@ else // Disable print ''; + + // Force e-mail recipient + print ''; // Separator diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 86a6cb008d3..c79b7ac0cea 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -495,7 +495,7 @@ class CMailFile $res=false; - if (empty($conf->global->MAIN_DISABLE_ALL_MAILS)) + if (empty($conf->global->MAIN_DISABLE_ALL_MAILS) || !empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) { require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; $hookmanager = new HookManager($db); @@ -557,6 +557,12 @@ class CMailFile $keyfortls ='MAIN_MAIL_EMAIL_TLS_EMAILING'; $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING'; } + + if(!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) { + $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; + $this->addr_cc = ''; + $this->addr_bcc = ''; + } // Action according to choosed sending method if ($this->sendmode == 'mail') From d770f732193e97811ec9f94fd3d1e8b6a07ed009 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Tue, 26 Dec 2017 16:21:15 +0100 Subject: [PATCH 005/386] Add option translation --- htdocs/langs/en_US/admin.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a4ece445581..e2c39c45a3d 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -272,6 +272,7 @@ MAIN_MAIL_EMAIL_FROM=Sender email for automatic emails (By default in php.ini: < MAIN_MAIL_ERRORS_TO=Sender email used for error returns emails sent MAIN_MAIL_AUTOCOPY_TO= Send systematically a hidden carbon-copy of all sent emails to MAIN_DISABLE_ALL_MAILS=Disable all emails sendings (for test purposes or demos) +MAIN_MAIL_FORCE_SENDTO=Send all emails to (instead of real recipients, for test purposes) MAIN_MAIL_SENDMODE=Method to use to send EMails MAIN_MAIL_SMTPS_ID=SMTP ID if authentication required MAIN_MAIL_SMTPS_PW=SMTP Password if authentication required From 33f6ba19da673faf0bec863cfebcdee5d4a608f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 28 Dec 2017 16:20:08 +0100 Subject: [PATCH 006/386] display weight volume in propal --- htdocs/comm/propal/card.php | 16 ++++++++++++++++ htdocs/commande/card.php | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index edd2607a11c..78c38c1cc32 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -2100,6 +2100,22 @@ if ($action == 'create') print ''; } + $tmparray=$object->getTotalWeightVolume(); + $totalWeight=$tmparray['weight']; + $totalVolume=$tmparray['volume']; + if ($totalWeight) { + print ''; + print ''; + } + if ($totalVolume) { + print ''; + print ''; + } + // Incoterms if (!empty($conf->incoterm->enabled)) { diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index bb6d2d78571..32bbdb9d0d8 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2268,12 +2268,15 @@ if ($action == 'create' && $user->rights->commande->creer) $tmparray=$object->getTotalWeightVolume(); $totalWeight=$tmparray['weight']; $totalVolume=$tmparray['volume']; - if ($totalWeight || $totalVolume) + if ($totalWeight) { print ''; print ''; + } + if ($totalVolume) + { print ''; print ''; +print ''; +print ''; +print ''; + // Start date print ''; print ''; @@ -177,12 +188,18 @@ $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql.= ", ".MAIN_DB_PREFIX."facture as f"; $sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = d.fk_product"; +if (! empty($TSelectedCats)) { + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=p.rowid'; +} $sql.= " WHERE f.fk_soc = s.rowid"; $sql.= ' AND f.entity IN ('.getEntity('facture').')'; $sql.= " AND f.fk_statut > 0"; $sql.= " AND d.fk_facture = f.rowid"; if ($id > 0) $sql.= " AND d.fk_product =".$id; +if (! empty($TSelectedCats)) { + $sql .= ' AND cp.fk_categorie IN ('.implode(',', $TSelectedCats) . ')'; +} if (!empty($startdate)) $sql.= " AND f.datef >= '".$db->idate($startdate)."'"; if (!empty($enddate)) From 2c473d35cc7468b15be0082796dc135c04e2df3d Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Wed, 10 Jan 2018 12:11:02 +0100 Subject: [PATCH 013/386] NEW : Add product and product categories filters on customer margins --- htdocs/margin/customerMargins.php | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index c83ca406347..b216db9d430 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -35,6 +35,9 @@ $langs->load("margins"); // Security check $socid = GETPOST('socid','int'); +$TSelectedProducts = GETPOST('products', 'array'); +$TSelectedCats = GETPOST('categories', 'array'); + if (! empty($user->societe_id)) $socid=$user->societe_id; $result = restrictedArea($user, 'societe','',''); $result = restrictedArea($user,'margins'); @@ -132,6 +135,29 @@ if (! $sortfield) } } +// Products +$TRes = $form->select_produits_list('','','',20,0,'',1,2,1,0,'', 1); + +$TProducts = array(); +foreach($TRes as $prod) { + $TProducts[$prod['key']] = $prod['label']; +} + +print ''; +print ''; + +// Categories +$TCats = $form->select_all_categories(0, array(), '', 64, 0, 1); + +print ''; +print ''; +print ''; +print ''; + // Start date print ''; print ''; + print ''; + + print ''; + print ''; print ''; } + // Multiprice level if (! empty($conf->global->PRODUIT_MULTIPRICES)) diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 6f473f8deb3..9856b4f95b2 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -101,6 +101,15 @@ if (empty($reshook)) $result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int')); if ($result < 0) dol_print_error($db,$object->error); } + + // update supplier order min amount + if ($action == 'setsupplier_order_min_amount') + { + $object->fetch($id); + $object->supplier_order_min_amount=GETPOST('supplier_order_min_amount'); + $result=$object->update($object->id, $user); + if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); + } } @@ -230,6 +239,16 @@ if ($object->id > 0) } print ""; print ''; + + print ''; + print ''; + print ''; // Categories if (! empty($conf->categorie->enabled)) diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql new file mode 100644 index 00000000000..dd549e684f2 --- /dev/null +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -0,0 +1,29 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 8.0.0 or higher. +-- +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To drop an index: -- VMYSQL4.0 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.0 DROP INDEX nomindex +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_c_shipment_mode CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): -- VPGSQL8.2 NOT POSSIBLE. MUST DELETE/CREATE TABLE +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. +-- -- VPGSQL8.2 DELETE FROM llx_usergroup_user WHERE fk_user NOT IN (SELECT rowid from llx_user); +-- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); + + +ALTER TABLE llx_societe ADD COLUMN order_min_amount double(24,8) DEFAULT NULL AFTER outstanding_limit; +ALTER TABLE llx_societe ADD COLUMN supplier_order_min_amount double(24,8) DEFAULT NULL AFTER order_min_amount; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index c23ca3a183c..0556f77b951 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -96,6 +96,8 @@ create table llx_societe fk_barcode_type integer NULL DEFAULT 0, -- barcode type price_level integer NULL, -- level of price for multiprices outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit + order_min_amount double(24,8) DEFAULT NULL, -- min amount for orders + supplier_order_min_amount double(24,8) DEFAULT NULL, -- min amount for supplier orders default_lang varchar(6), -- default language logo varchar(255) DEFAULT NULL, canvas varchar(32) DEFAULT NULL, -- type of canvas if used (null by default) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index cd4b66a23a1..dc91e7f668c 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -334,6 +334,12 @@ class Societe extends CommonObject */ var $price_level; var $outstanding_limit; + + /** + * Min order amounts + */ + var $order_min_amount; + var $supplier_order_min_amount; /** * Id of sales representative to link (used for thirdparty creation). Not filled by a fetch, because we can have several sales representatives. @@ -785,6 +791,8 @@ class Societe extends CommonObject $this->idprof6 = (! empty($this->idprof6)?trim($this->idprof6):''); $this->prefix_comm = trim($this->prefix_comm); $this->outstanding_limit = price2num($this->outstanding_limit); + $this->order_min_amount = price2num($this->order_min_amount); + $this->supplier_order_min_amount = price2num($this->supplier_order_min_amount); $this->tva_assuj = trim($this->tva_assuj); $this->tva_intra = dol_sanitizeFileName($this->tva_intra,''); @@ -955,6 +963,8 @@ class Societe extends CommonObject $sql .= ",default_lang = ".(! empty($this->default_lang)?"'".$this->db->escape($this->default_lang)."'":"null"); $sql .= ",logo = ".(! empty($this->logo)?"'".$this->db->escape($this->logo)."'":"null"); $sql .= ",outstanding_limit= ".($this->outstanding_limit!=''?$this->outstanding_limit:'null'); + $sql .= ",order_min_amount= ".($this->order_min_amount!=''?$this->order_min_amount:'null'); + $sql .= ",supplier_order_min_amount= ".($this->supplier_order_min_amount!=''?$this->supplier_order_min_amount:'null'); $sql .= ",fk_prospectlevel='".$this->db->escape($this->fk_prospectlevel)."'"; $sql .= ",webservices_url = ".(! empty($this->webservices_url)?"'".$this->db->escape($this->webservices_url)."'":"null"); From 9899a026302a211837f36fbe2f09cbe92a1374f9 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 20 Jan 2018 20:11:30 +0100 Subject: [PATCH 021/386] Display alert if order total is under order min amount --- htdocs/commande/card.php | 6 +++++- htdocs/fourn/commande/card.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 2d4d138f61a..1c236eda1dd 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2388,8 +2388,12 @@ if ($action == 'create' && $user->rights->commande->creer) } // Total HT + $alert = ''; + if($object->total_ht < $object->thirdparty->order_min_amount) { + $alert = ' ' . img_warning($langs->trans('OrderMinAmount').': '.price($object->thirdparty->order_min_amount)); + } print ''; - print ''; + print ''; // Total VAT print ''; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 617039f25da..81ea1a0f951 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2052,8 +2052,12 @@ elseif (! empty($object->id)) } // Total + $alert = ''; + if($object->total_ht < $object->thirdparty->supplier_order_min_amount) { + $alert = ' ' . img_warning($langs->trans('OrderMinAmount').': '.price($object->thirdparty->supplier_order_min_amount)); + } print ''; - print ''; + print ''; print ''; // Total VAT From 53e6da8c7c32ad21b7e816a54034cb763c4e3bdf Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 20 Jan 2018 21:57:36 +0100 Subject: [PATCH 022/386] Missing fetch and translation --- htdocs/langs/en_US/companies.lang | 1 + htdocs/societe/class/societe.class.php | 3 +++ 2 files changed, 4 insertions(+) diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 7cff22df092..04528266b64 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -405,6 +405,7 @@ ProductsIntoElements=List of products/services into %s CurrentOutstandingBill=Current outstanding bill OutstandingBill=Max. for outstanding bill OutstandingBillReached=Max. for outstanding bill reached +OrderMinAmount=Minimum amount for order MonkeyNumRefModelDesc=Return numero with format %syymm-nnnn for customer code and %syymm-nnnn for supplier code where yy is year, mm is month and nnnn is a sequence with no break and no return to 0. LeopardNumRefModelDesc=The code is free. This code can be modified at any time. ManagingDirectors=Manager(s) name (CEO, director, president...) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index dc91e7f668c..675dd2a3123 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1142,6 +1142,7 @@ class Societe extends CommonObject $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo'; $sql .= ', s.fk_shipping_method'; $sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms'; + $sql .= ', s.order_min_amount, s.supplier_order_min_amount'; $sql .= ', s.fk_multicurrency, s.multicurrency_code'; $sql .= ', fj.libelle as forme_juridique'; $sql .= ', e.libelle as effectif'; @@ -1289,6 +1290,8 @@ class Societe extends CommonObject $this->webservices_key = $obj->webservices_key; $this->outstanding_limit = $obj->outstanding_limit; + $this->order_min_amount = $obj->order_min_amount; + $this->supplier_order_min_amount = $obj->supplier_order_min_amount; // multiprix $this->price_level = $obj->price_level; From 496ac644eb1cfc9977144b7bee49fed0e4924e83 Mon Sep 17 00:00:00 2001 From: Rui Strecht Date: Thu, 25 Jan 2018 16:10:04 +0000 Subject: [PATCH 023/386] Updated label and added new translation for label --- htdocs/contact/card.php | 20 ++++++++++++++++++-- htdocs/langs/en_US/companies.lang | 1 + htdocs/langs/pt_PT/companies.lang | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index bc0031b5992..87189528d5a 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -607,7 +607,15 @@ else // State if (empty($conf->global->SOCIETE_DISABLE_STATE)) { - print ''; } diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 7cff22df092..c5bc84acaf8 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -56,6 +56,7 @@ Address=Address State=State/Province StateShort=State Region=Region +Region-State=Region - State Country=Country CountryCode=Country code CountryId=Country id diff --git a/htdocs/langs/pt_PT/companies.lang b/htdocs/langs/pt_PT/companies.lang index 4875dc8e3de..8f797802925 100644 --- a/htdocs/langs/pt_PT/companies.lang +++ b/htdocs/langs/pt_PT/companies.lang @@ -56,6 +56,7 @@ Address=Direcção State=Distrito StateShort=Estado Region=Região +Region-State=Distrito - Concelho Country=País CountryCode=Código país CountryId=ID país From a13866f091bfa94fd8eabbcb0a19603fa857df7c Mon Sep 17 00:00:00 2001 From: Rui Strecht Date: Thu, 25 Jan 2018 16:14:39 +0000 Subject: [PATCH 024/386] Changed MAIN_SHOW_REGION_IN_STATE to MAIN_SHOW_REGION_IN_STATE_SELECT for clarity --- htdocs/contact/card.php | 4 ++-- htdocs/core/class/html.formcompany.class.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 87189528d5a..9c35714dcd5 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -607,7 +607,7 @@ else // State if (empty($conf->global->SOCIETE_DISABLE_STATE)) { - if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE) && ($conf->global->MAIN_SHOW_REGION_IN_STATE == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE == 2)) + if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) { print ''; @@ -1700,7 +1708,15 @@ else // State if (empty($conf->global->SOCIETE_DISABLE_STATE)) { - print ''; } From ec38b8a5a25c8e5472a3c694039da62a2b6a8147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 25 Jan 2018 17:50:11 +0100 Subject: [PATCH 027/386] Update interface_99_modMyModule_MyModuleTriggers.class.php --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 06b34ccb8b3..4f1627c2940 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4645,11 +4645,11 @@ abstract class CommonObject } else { - if ($trigger) + if (!$notrigger) { // Call trigger $this->context=array('extrafieldaddupdate'=>1); - $result=$this->call_trigger(strtoupper(get_class($this)) . '_EXTRAFIELDS_MODIFY', $userused); + $result=$this->call_trigger(strtoupper(get_class($this)) . '_MODIFY', $userused); if ($result < 0) $error++; // End call trigger } From d0e83b79025d7fe922411e725b7b6b0926f9fab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 26 Jan 2018 08:14:39 +0100 Subject: [PATCH 028/386] trigger on bank account update --- htdocs/core/class/commonobject.class.php | 50 +++++++++++++++++++----- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 4f1627c2940..9cc686f22e5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1888,10 +1888,18 @@ abstract class CommonObject * Change the bank account * * @param int $fk_account Id of bank account + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @param User $userused Object user * @return int 1 if OK, 0 if KO */ - function setBankAccount($fk_account) + function setBankAccount($fk_account, $notrigger=false, $userused=null) { + global $user; + + if (empty($userused)) $userused=$user; + + $error = 0; + if (! $this->table_element) { dol_syslog(get_class($this)."::setBankAccount was called on objet with property table_element not defined",LOG_ERR); return -1; @@ -1903,15 +1911,37 @@ abstract class CommonObject $sql.= " SET fk_account = ".$fk_account; $sql.= " WHERE rowid=".$this->id; - if ($this->db->query($sql)) { - $this->fk_account = ($fk_account=='NULL')?null:$fk_account; - return 1; - } else { - dol_syslog(get_class($this).'::setBankAccount Error '.$sql.' - '.$this->db->error()); - $this->error=$this->db->error(); - return 0; - } - } + $resql = $this->db->query($sql); + if (! $resql) + { + dol_syslog(get_class($this).'::setBankAccount Error '.$sql.' - '.$this->db->error()); + $this->error = $this->db->lasterror(); + $error++; + } + else + { + if (!$notrigger) + { + // Call trigger + $this->context=array('bankaccountupdate'=>1); + $result = $this->call_trigger(strtoupper(get_class($this)) . '_MODIFY', $userused); + if ($result < 0) $error++; + // End call trigger + } + } + if ($error) + { + $this->db->rollback(); + return -1; + } + else + { + $this->fk_account = ($fk_account=='NULL')?null:$fk_account; + $this->db->commit(); + return 1; + } + } + // TODO: Move line related operations to CommonObjectLine? From 336c44dc8802a1ddf5f4c9ab958df33f90bfcadc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 26 Jan 2018 08:33:35 +0100 Subject: [PATCH 029/386] trigger on shipping method update --- htdocs/core/class/commonobject.class.php | 48 +++++++++++++++++++----- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9cc686f22e5..c0583f09552 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1790,29 +1790,57 @@ abstract class CommonObject * Change the shipping method * * @param int $shipping_method_id Id of shipping method + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @param User $userused Object user + * * @return int 1 if OK, 0 if KO */ - function setShippingMethod($shipping_method_id) + function setShippingMethod($shipping_method_id, $notrigger=false, $userused=null) { + global $user; + + if (empty($userused)) $userused=$user; + + $error = 0; + if (! $this->table_element) { dol_syslog(get_class($this)."::setShippingMethod was called on objet with property table_element not defined",LOG_ERR); return -1; } + + $this->db->begin(); + if ($shipping_method_id<0) $shipping_method_id='NULL'; dol_syslog(get_class($this).'::setShippingMethod('.$shipping_method_id.')'); $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; $sql.= " SET fk_shipping_method = ".$shipping_method_id; $sql.= " WHERE rowid=".$this->id; - - if ($this->db->query($sql)) { - $this->shipping_method_id = ($shipping_method_id=='NULL')?null:$shipping_method_id; - return 1; - } else { + $resql = $this->db->query($sql); + if (! $resql) { dol_syslog(get_class($this).'::setShippingMethod Error ', LOG_DEBUG); - $this->error=$this->db->error(); - return 0; - } + $this->error = $this->db->lasterror(); + $error++; + } else { + if (!$notrigger) + { + // Call trigger + $this->context=array('shippingmethodupdate'=>1); + $result = $this->call_trigger(strtoupper(get_class($this)) . '_MODIFY', $userused); + if ($result < 0) $error++; + // End call trigger + } + } + if ($error) + { + $this->db->rollback(); + return -1; + } else { + $this->shipping_method_id = ($shipping_method_id=='NULL')?null:$shipping_method_id; + $this->db->commit(); + return 1; + } + } @@ -1904,6 +1932,8 @@ abstract class CommonObject dol_syslog(get_class($this)."::setBankAccount was called on objet with property table_element not defined",LOG_ERR); return -1; } + $this->db->begin(); + if ($fk_account<0) $fk_account='NULL'; dol_syslog(get_class($this).'::setBankAccount('.$fk_account.')'); From b9d5ed37ddb900c3b15038ef47fcfc01b7484c68 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Jan 2018 12:46:44 +0100 Subject: [PATCH 030/386] Prepare 8.0 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index c270e2f44fa..a38376e8294 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','7.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); From eb3eee9b6a0cc70b9fcf20807d61682ebf5dd9e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Jan 2018 15:25:47 +0100 Subject: [PATCH 031/386] Code comment --- htdocs/core/class/extrafields.class.php | 24 ++++++++++++------------ htdocs/install/mysql/tables/llx_user.sql | 3 +-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index c7b2d394a4b..3a3181e14a5 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -140,15 +140,15 @@ class ExtraFields * @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check - * @param int $list Visibilty - * @param int $ishidden Deprecated. Use visibility instead. + * @param int $list Visibilty (0=never visible, 1=visible on list+forms, 2=list onyl, 3=form only) + * @param int $notused Deprecated. * @param string $computed Computed value * @param string $entity Entity of extrafields (for multicompany modules) * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $computed='', $entity='', $langfile='', $enabled='1') + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $notused=0, $computed='', $entity='', $langfile='', $enabled='1') { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -165,7 +165,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden, $default, $computed, $entity, $langfile, $enabled); + $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $notused, $default, $computed, $entity, $langfile, $enabled); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -282,7 +282,7 @@ class ExtraFields * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Visibily - * @param int $ishidden Deprecated. Use visibility instead. + * @param int $notused Deprecated. * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields @@ -290,7 +290,7 @@ class ExtraFields * @param string $enabled Condition to have the field enabled or not * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $default='', $computed='',$entity='', $langfile='', $enabled='1') + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $notused=0, $default='', $computed='',$entity='', $langfile='', $enabled='1') { global $conf,$user; @@ -490,7 +490,7 @@ class ExtraFields * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Visibility - * @param int $ishidden Deprecated. Use visiblity instead. + * @param int $notused Deprecated. * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields @@ -498,7 +498,7 @@ class ExtraFields * @param string $enabled Condition to have the field enabled or not * @return int >0 if OK, <=0 if KO */ - function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $ishidden=0, $default='', $computed='', $entity='', $langfile='', $enabled='1') + function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $notused=0, $default='', $computed='', $entity='', $langfile='', $enabled='1') { if ($elementtype == 'thirdparty') $elementtype='societe'; if ($elementtype == 'contact') $elementtype='socpeople'; @@ -546,7 +546,7 @@ class ExtraFields { if ($label) { - $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden,$default,$computed,$entity,$langfile,$enabled); + $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$notused,$default,$computed,$entity,$langfile,$enabled); } if ($result > 0) { @@ -597,7 +597,7 @@ class ExtraFields * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Visiblity - * @param int $ishidden Deprecated. Use visility instead. + * @param int $notused Deprecated. * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields @@ -605,10 +605,10 @@ class ExtraFields * @param string $enabled Condition to have the field enabled or not * @return int <=0 if KO, >0 if OK */ - private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$ishidden=0,$default='',$computed='',$entity='',$langfile='',$enabled='1') + private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$notused=0,$default='',$computed='',$entity='',$langfile='',$enabled='1') { global $conf, $user; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$notused.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled); // Clean parameters if ($elementtype == 'thirdparty') $elementtype='societe'; diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index 4385483209a..2ecb52511d4 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -15,7 +15,6 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . --- -- =========================================================================== create table llx_user @@ -37,7 +36,7 @@ create table llx_user pass_encoding varchar(24), pass varchar(128), pass_crypted varchar(128), - pass_temp varchar(128), -- temporary password when asked for forget password + pass_temp varchar(128), -- temporary password when asked for forget password or 'hashtoallowreset:YYYMMDDHHMMSS' (where date is max date of validaity) api_key varchar(128), -- key to use REST API by this user gender varchar(10), civility varchar(6), From 6cae36cc336d7d60ab2b6563e3b79afd86132e76 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Jan 2018 17:00:14 +0100 Subject: [PATCH 032/386] NEW Add key __USER_REMOTE_IP__ into available substitution variables --- htdocs/core/lib/functions.lib.php | 3 ++- htdocs/langs/en_US/other.lang | 4 +++- htdocs/langs/en_US/users.lang | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index bd7fa7b6fd4..88d4e550b03 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5620,7 +5620,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob '__USER_LASTNAME__' => (string) $user->lastname, '__USER_FIRSTNAME__' => (string) $user->firstname, '__USER_FULLNAME__' => (string) $user->getFullName($outputlangs), - '__USER_SUPERVISOR_ID__' => (string) $user->fk_user + '__USER_SUPERVISOR_ID__' => (string) $user->fk_user, + '__USER_REMOTE_IP__' => (string) $_SERVER['REMOTE_ADDR'] ) ); } diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 132a200ab2e..1585504479e 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -227,7 +227,9 @@ Chart=Chart PassEncoding=Password encoding PermissionsAdd=Permissions added PermissionsDelete=Permissions removed - +YourPasswordMustHaveAtLeastXChars=Your password must have at least %s chars +YourPasswordHasBeenReset=Your password has been reset successfully +ApplicantIpAddress=IP address of applicant ##### Export ##### ExportsArea=Exports area AvailableFormats=Available formats diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang index 3c1a8644bf0..c149e9d6a53 100644 --- a/htdocs/langs/en_US/users.lang +++ b/htdocs/langs/en_US/users.lang @@ -44,7 +44,9 @@ NewGroup=New group CreateGroup=Create group RemoveFromGroup=Remove from group PasswordChangedAndSentTo=Password changed and sent to %s. +PasswordChangeRequest=Request to change password for %s PasswordChangeRequestSent=Request to change password for %s sent to %s. +ConfirmPasswordReset=Confirm password reset MenuUsersAndGroups=Users & Groups LastGroupsCreated=Latest %s created groups LastUsersCreated=Latest %s users created From a61b42075903c5a997224a5c9625ddd46e6ca50b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Jan 2018 23:29:49 +0100 Subject: [PATCH 033/386] Fix css --- htdocs/core/lib/functions.lib.php | 7 ++++--- htdocs/index.php | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 30164def386..9cbf52c1cc8 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3367,18 +3367,19 @@ function img_searchclear($titlealt = 'default', $other = '') * @param integer $infoonimgalt Info is shown only on alt of star picto, otherwise it is show on output after the star picto * @param int $nodiv No div * @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'xxx'=Other + * @param string $morecss More CSS * @return string String with info text */ -function info_admin($text, $infoonimgalt = 0, $nodiv=0, $admin='1') +function info_admin($text, $infoonimgalt = 0, $nodiv=0, $admin='1', $morecss='') { global $conf, $langs; if ($infoonimgalt) { - return img_picto($text, 'info', 'class="hideonsmartphone"'); + return img_picto($text, 'info', 'class="hideonsmartphone'.($morecss?' '.$morecss:'').'"'); } - return ($nodiv?'':'
').' '.$text.($nodiv?'':'
'); + return ($nodiv?'':'
').' '.$text.($nodiv?'':'
'); } diff --git a/htdocs/index.php b/htdocs/index.php index 867f305a680..b01e37927c4 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -656,7 +656,7 @@ if ($user->admin && empty($conf->global->MAIN_REMOVE_INSTALL_WARNING)) { $langs->load("errors"); //if (! empty($message)) $message.='
'; - $message.=info_admin($langs->trans("WarningLockFileDoesNotExists",DOL_DATA_ROOT).' '.$langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install")); + $message.=info_admin($langs->trans("WarningLockFileDoesNotExists",DOL_DATA_ROOT).' '.$langs->trans("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth'); } // Conf files must be in read only mode @@ -665,7 +665,7 @@ if ($user->admin && empty($conf->global->MAIN_REMOVE_INSTALL_WARNING)) $langs->load("errors"); //$langs->load("other"); //if (! empty($message)) $message.='
'; - $message.=info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install")); + $message.=info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->trans("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth'); } if ($message) From 28417a6c248d63684c674d50471ac72cd1062a51 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Jan 2018 23:54:45 +0100 Subject: [PATCH 034/386] Fix css --- htdocs/admin/dict.php | 8 ++++---- htdocs/blockedlog/admin/blockedlog_list.php | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index a1fc7c87d68..438c7cd5227 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -187,7 +187,7 @@ $tabsql[9] = "SELECT c.code_iso as code, c.label, c.unicode, c.active FROM ".MAI $tabsql[10]= "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[11]= "SELECT t.rowid as rowid, t.element, t.source, t.code, t.libelle, t.position, t.active FROM ".MAIN_DB_PREFIX."c_type_contact AS t"; $tabsql[12]= "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = " . getEntity($tabname[12]); -$tabsql[13]= "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.accountancy_code, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = " . getEntity($tabname[13]); +$tabsql[13]= "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = " . getEntity($tabname[13]); $tabsql[14]= "SELECT e.rowid as rowid, e.code as code, e.libelle, e.price, e.organization, e.fk_pays as country_id, c.code as country_code, c.label as country, e.active FROM ".MAIN_DB_PREFIX."c_ecotaxe AS e, ".MAIN_DB_PREFIX."c_country as c WHERE e.fk_pays=c.rowid and c.active=1"; $tabsql[15]= "SELECT rowid as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format"; $tabsql[16]= "SELECT code, label as libelle, sortorder, active FROM ".MAIN_DB_PREFIX."c_prospectlevel"; @@ -265,7 +265,7 @@ $tabfield[9] = "code,label,unicode"; $tabfield[10]= "country_id,country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[11]= "element,source,code,libelle,position"; $tabfield[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; -$tabfield[13]= "code,libelle,type,accountancy_code,entity"; +$tabfield[13]= "code,libelle,type,entity"; $tabfield[14]= "code,libelle,price,organization,country_id,country"; $tabfield[15]= "code,libelle,width,height,unit"; $tabfield[16]= "code,libelle,sortorder"; @@ -304,7 +304,7 @@ $tabfieldvalue[9] = "code,label,unicode"; $tabfieldvalue[10]= "country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[11]= "element,source,code,libelle,position"; $tabfieldvalue[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder"; -$tabfieldvalue[13]= "code,libelle,type,accountancy_code"; +$tabfieldvalue[13]= "code,libelle,type"; $tabfieldvalue[14]= "code,libelle,price,organization,country"; $tabfieldvalue[15]= "code,libelle,width,height,unit"; $tabfieldvalue[16]= "code,libelle,sortorder"; @@ -343,7 +343,7 @@ $tabfieldinsert[9] = "code_iso,label,unicode"; $tabfieldinsert[10]= "fk_pays,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[11]= "element,source,code,libelle,position"; $tabfieldinsert[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; -$tabfieldinsert[13]= "code,libelle,type,accountancy_code,entity"; +$tabfieldinsert[13]= "code,libelle,type,entity"; $tabfieldinsert[14]= "code,libelle,price,organization,fk_pays"; $tabfieldinsert[15]= "code,label,width,height,unit"; $tabfieldinsert[16]= "code,label,sortorder"; diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 633f84b6582..08b384d7ac5 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -359,7 +359,8 @@ print ''; // User print '
'; // Actions code From f2a3c83053a6fe1d126b03b7bec467add770917c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Jan 2018 18:46:52 +0100 Subject: [PATCH 035/386] Better error messages --- htdocs/comm/card.php | 7 ++++--- htdocs/societe/consumption.php | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 8fb590d61b4..fa2af2dc3eb 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -211,7 +211,7 @@ if ($id > 0 && empty($object->id)) { // Load data of third party $res=$object->fetch($id); - if ($object->id <= 0) dol_print_error($db,$object->error,$object->errors); + if ($object->id < 0) dol_print_error($db, $object->error, $object->errors); } $title=$langs->trans("CustomerCard"); @@ -220,7 +220,7 @@ $help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('',$title,$help_url); -if ($id > 0) +if ($object->id > 0) { $head = societe_prepare_head($object); @@ -1271,7 +1271,8 @@ if ($id > 0) } else { - dol_print_error($db,'Bad value for socid parameter'); + $langs->load("errors"); + print $langs->trans('ErrorRecordNotFound'); } // End of page diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index c9c26326426..ffb4cac77fa 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -268,7 +268,7 @@ if ($type_element == 'supplier_order') $thirdTypeSelect='supplier'; } if ($type_element == 'contract') -{ // Supplier : Show products from orders. +{ // Order require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $documentstatic=new Contrat($db); $documentstaticline=new ContratLigne($db); From f1cd905bf174dede00914b62f34701068d007e8f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Jan 2018 19:29:57 +0100 Subject: [PATCH 036/386] Fix var not initialized --- htdocs/core/class/extrafields.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 3a3181e14a5..226d367140b 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -111,6 +111,9 @@ class ExtraFields { $this->db = $db; $this->error = array(); + $this->attributes = array(); + + // For old usage $this->attribute_elementtype = array(); $this->attribute_type = array(); $this->attribute_label = array(); From 7a2992bc4b29f311fb9a54f69bb7298e4f7adb84 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Jan 2018 19:35:30 +0100 Subject: [PATCH 037/386] Fix var serialized twice --- htdocs/core/class/extrafields.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 226d367140b..bc37c428bb6 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -311,7 +311,7 @@ class ExtraFields { if(is_array($param) && count($param) > 0) { - $params = $this->db->escape(serialize($param)); + $params = serialize($param); } elseif (strlen($param) > 0) { From 97c2828d04cd808c3116011ae690737e8f8beaa9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2018 10:57:01 +0100 Subject: [PATCH 038/386] Fix install.lock not always saved --- htdocs/install/step5.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/install/step5.php b/htdocs/install/step5.php index 91c517f9644..5181c35f2f9 100644 --- a/htdocs/install/step5.php +++ b/htdocs/install/step5.php @@ -345,7 +345,8 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i',$action)) // Create lock file // If first install -if ($action == "set" && $success) { +if ($action == "set" && $success) +{ if (empty($conf->global->MAIN_VERSION_LAST_UPGRADE) || ($conf->global->MAIN_VERSION_LAST_UPGRADE == DOL_VERSION)) { // Install is finished @@ -353,14 +354,14 @@ if ($action == "set" && $success) { $createlock=0; - if (! empty($force_install_lockinstall)) + if (! empty($force_install_lockinstall) || ! empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE)) { // Install is finished, we create the lock file $lockfile=DOL_DATA_ROOT.'/install.lock'; $fp = @fopen($lockfile, "w"); if ($fp) { - if ($force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility + if (empty($force_install_lockinstall) || $force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility fwrite($fp, "This is a lock file to prevent use of install pages (set with permission ".$force_install_lockinstall.")"); fclose($fp); @chmod($lockfile, octdec($force_install_lockinstall)); @@ -403,14 +404,14 @@ elseif (empty($action) || preg_match('/upgrade/i',$action)) $createlock=0; - if (! empty($force_install_lockinstall)) + if (! empty($force_install_lockinstall) || ! empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE)) { // Upgrade is finished, we create the lock file $lockfile=DOL_DATA_ROOT.'/install.lock'; $fp = @fopen($lockfile, "w"); if ($fp) { - if ($force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility + if (empty($force_install_lockinstall) || $force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility fwrite($fp, "This is a lock file to prevent use of install pages (set with permission ".$force_install_lockinstall.")"); fclose($fp); @chmod($lockfile, octdec($force_install_lockinstall)); From cebda2b141ee3c5c5eb694911cdbeb93640d17a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 28 Jan 2018 10:57:12 +0100 Subject: [PATCH 039/386] Prepare 8.0 --- htdocs/install/check.php | 11 ++++++----- htdocs/install/mysql/migration/7.0.0-8.0.0.sql | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/install/check.php b/htdocs/install/check.php index 50409fb55e5..8262a5f05df 100644 --- a/htdocs/install/check.php +++ b/htdocs/install/check.php @@ -421,11 +421,12 @@ else array('from'=>'3.5.0', 'to'=>'3.6.0'), array('from'=>'3.6.0', 'to'=>'3.7.0'), array('from'=>'3.7.0', 'to'=>'3.8.0'), - array('from'=>'3.8.0', 'to'=>'3.9.0'), - array('from'=>'3.9.0', 'to'=>'4.0.0'), - array('from'=>'4.0.0', 'to'=>'5.0.0'), - array('from'=>'5.0.0', 'to'=>'6.0.0'), - array('from'=>'6.0.0', 'to'=>'7.0.0') + array('from'=>'3.8.0', 'to'=>'3.9.0'), + array('from'=>'3.9.0', 'to'=>'4.0.0'), + array('from'=>'4.0.0', 'to'=>'5.0.0'), + array('from'=>'5.0.0', 'to'=>'6.0.0'), + array('from'=>'6.0.0', 'to'=>'7.0.0'), + array('from'=>'7.0.0', 'to'=>'8.0.0') ); $count=0; diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql index e9a72ab9360..1b9375ef1a8 100644 --- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -23,4 +23,4 @@ -- Note: fields with type BLOB/TEXT can't have default value. -- For 8.0 -ALTER TABLE llx_societe ADD COLUMN fk_entrepot int DEFAULT 0; +ALTER TABLE llx_societe ADD COLUMN fk_entrepot integer DEFAULT 0; From 9825586d41256e4b529a3d809ea3c21e0e5fa441 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 29 Jan 2018 11:12:56 +0100 Subject: [PATCH 040/386] Fix css --- htdocs/public/paybox/newpayment.php | 10 +++++----- htdocs/public/payment/newpayment.php | 10 +++++----- htdocs/public/paypal/newpayment.php | 10 +++++----- htdocs/public/stripe/newpayment.php | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/public/paybox/newpayment.php b/htdocs/public/paybox/newpayment.php index c386dc7e84e..eb90814eb7b 100644 --- a/htdocs/public/paybox/newpayment.php +++ b/htdocs/public/paybox/newpayment.php @@ -321,7 +321,7 @@ if (! GETPOST("source") && $valid) // Tag print ''."\n"; @@ -407,7 +407,7 @@ if (GETPOST("source") == 'order' && $valid) // Tag print ''."\n"; @@ -495,7 +495,7 @@ if (GETPOST("source") == 'invoice' && $valid) // Tag print ''."\n"; @@ -671,7 +671,7 @@ if (GETPOST("source") == 'contractline' && $valid) // Tag print ''."\n"; @@ -784,7 +784,7 @@ if (GETPOST("source") == 'membersubscription' && $valid) // Tag print ''."\n"; diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 3f2c2979e00..fd1389ba8cb 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -661,7 +661,7 @@ if (! $source) // Tag print ''."\n"; @@ -752,7 +752,7 @@ if ($source == 'order') // Tag print ''."\n"; @@ -877,7 +877,7 @@ if ($source == 'invoice') // Tag print ''."\n"; @@ -1093,7 +1093,7 @@ if ($source == 'contractline') // Tag print ''."\n"; @@ -1252,7 +1252,7 @@ if ($source == 'membersubscription') // Tag print ''."\n"; diff --git a/htdocs/public/paypal/newpayment.php b/htdocs/public/paypal/newpayment.php index 2bb58e4b676..27024d48de1 100644 --- a/htdocs/public/paypal/newpayment.php +++ b/htdocs/public/paypal/newpayment.php @@ -404,7 +404,7 @@ if (! GETPOST("source")) // Tag print ''."\n"; @@ -490,7 +490,7 @@ if (GETPOST("source") == 'order') // Tag print ''."\n"; @@ -600,7 +600,7 @@ if (GETPOST("source") == 'invoice') // Tag print ''."\n"; @@ -798,7 +798,7 @@ if (GETPOST("source") == 'contractline') // Tag print ''."\n"; @@ -937,7 +937,7 @@ if (GETPOST("source") == 'membersubscription') // Tag print ''."\n"; diff --git a/htdocs/public/stripe/newpayment.php b/htdocs/public/stripe/newpayment.php index 38d81f7e991..dfd0425bb26 100644 --- a/htdocs/public/stripe/newpayment.php +++ b/htdocs/public/stripe/newpayment.php @@ -470,7 +470,7 @@ if (! GETPOST("source")) // Tag print ''."\n"; @@ -556,7 +556,7 @@ if (GETPOST("source") == 'order') // Tag print ''."\n"; @@ -667,7 +667,7 @@ if (GETPOST("source") == 'invoice') // Tag print ''."\n"; @@ -867,7 +867,7 @@ if (GETPOST("source") == 'contractline') // Tag print ''."\n"; @@ -1006,7 +1006,7 @@ if (GETPOST("source") == 'membersubscription') // Tag print ''."\n"; From 97da464343be809e06952e5745c544b52d0721d2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 29 Jan 2018 11:21:40 +0100 Subject: [PATCH 041/386] Fix price in member public form --- htdocs/public/paybox/newpayment.php | 2 +- htdocs/public/payment/newpayment.php | 2 +- htdocs/public/paypal/newpayment.php | 2 +- htdocs/public/stripe/newpayment.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/public/paybox/newpayment.php b/htdocs/public/paybox/newpayment.php index eb90814eb7b..9d7f79081a9 100644 --- a/htdocs/public/paybox/newpayment.php +++ b/htdocs/public/paybox/newpayment.php @@ -767,7 +767,7 @@ if (GETPOST("source") == 'membersubscription' && $valid) $valtoshow=GETPOST("newamount",'int'); if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow); print ''; - print ''; + print ''; } else { $valtoshow=$amount; diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index fd1389ba8cb..efeb1323a3d 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -1235,7 +1235,7 @@ if ($source == 'membersubscription') //$valtoshow=GETPOST("newamount",'int'); if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow); print ''; - print ''; + print ''; } else { $valtoshow=$amount; diff --git a/htdocs/public/paypal/newpayment.php b/htdocs/public/paypal/newpayment.php index 27024d48de1..fac192bd318 100644 --- a/htdocs/public/paypal/newpayment.php +++ b/htdocs/public/paypal/newpayment.php @@ -920,7 +920,7 @@ if (GETPOST("source") == 'membersubscription') $valtoshow=GETPOST("newamount",'int'); if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow); print ''; - print ''; + print ''; } else { $valtoshow=$amount; diff --git a/htdocs/public/stripe/newpayment.php b/htdocs/public/stripe/newpayment.php index dfd0425bb26..36b27658ee0 100644 --- a/htdocs/public/stripe/newpayment.php +++ b/htdocs/public/stripe/newpayment.php @@ -989,7 +989,7 @@ if (GETPOST("source") == 'membersubscription') $valtoshow=GETPOST("newamount",'int'); if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow); print ''; - print ''; + print ''; } else { $valtoshow=$amount; From f761c9efabb2f4e151d9cda4aaf37b8669aec49a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 30 Jan 2018 18:02:24 +0100 Subject: [PATCH 042/386] Add param morecss on error message --- htdocs/core/lib/functions.lib.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9cbf52c1cc8..0aa42f7572f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2278,7 +2278,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $titlealt=($withpicto=='fax'?$langs->trans("Fax"):$langs->trans("Phone")); } $rep=''; - + if ($hookmanager) { $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid,'titlealt' => $titlealt, 'picto' => $withpicto); $reshook = $hookmanager->executeHooks('printPhone', $parameters, $phone); @@ -2304,7 +2304,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep if ($adddivfloat) $rep.=''; else $rep.=''; } - + return $rep; } @@ -3520,15 +3520,16 @@ function dol_print_error($db='',$error='',$errors=null) * @param string $prefixcode Prefix of public error code * @param string $errormessage Complete error message * @param array $errormessages Array of error messages + * @param string $morecss More css * @return void */ -function dol_print_error_email($prefixcode, $errormessage='', $errormessages=array()) +function dol_print_error_email($prefixcode, $errormessage='', $errormessages=array(), $morecss='error') { global $langs,$conf; $langs->load("errors"); $now=dol_now(); - print '
'; - + // Force e-mail recipient print ''; - + // Force e-mail recipient print '"; //} - if($conf->categorie->enabled) { + if ($conf->categorie->enabled) { // Categories print '"; } @@ -1464,6 +1464,7 @@ else $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', 'parent', 64, 0, 1); $c = new Categorie($db); $cats = $c->containing($object->id,Categorie::TYPE_PRODUCT); + $arrayselected=array(); foreach($cats as $cat) { $arrayselected[] = $cat->id; } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index f05f6993322..9fdad8916e1 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1909,6 +1909,7 @@ else $cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1); $c = new Categorie($db); $cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER); + $arrayselected=array(); foreach ($cats as $cat) { $arrayselected[] = $cat->id; } @@ -1923,6 +1924,7 @@ else $cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1); $c = new Categorie($db); $cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER); + $arrayselected=array(); foreach ($cats as $cat) { $arrayselected[] = $cat->id; } From 2930fc7dfa85a0c5db9cefe58e716572867097e9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 02:27:31 +0100 Subject: [PATCH 059/386] Fix missing mainmenu and leftmenu into menu definition --- htdocs/core/menus/init_menu_auguria.sql | 13 +++++++------ htdocs/core/menus/standard/eldy.lib.php | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index c7339a55ea0..9704f3df684 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -168,9 +168,10 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1600__+MAX_llx_menu__, 'billing', 'supplier_bills', 6__+MAX_llx_menu__, '/fourn/facture/list.php?leftmenu=suppliers_bills', 'BillsSuppliers', 0, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1601__+MAX_llx_menu__, 'billing', '', 1600__+MAX_llx_menu__, '/fourn/facture/card.php?action=create&leftmenu=suppliers_bills', 'NewBill', 1, 'bills', '$user->rights->fournisseur->facture->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1602__+MAX_llx_menu__, 'billing', '', 1600__+MAX_llx_menu__, '/fourn/facture/list.php?leftmenu=suppliers_bills', 'List', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1603__+MAX_llx_menu__, 'billing', '', 1600__+MAX_llx_menu__, '/fourn/facture/paiement.php?leftmenu=suppliers_bills', 'Payments', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 2, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1605__+MAX_llx_menu__, 'billing', '', 1603__+MAX_llx_menu__, '/fourn/facture/rapport.php?leftmenu=suppliers_bills', 'Reporting', 2, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1604__+MAX_llx_menu__, 'billing', '', 1600__+MAX_llx_menu__, '/compta/facture/stats/index.php?leftmenu=customers_bills&mode=supplier', 'Statistics', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 8, __ENTITY__); + +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1603__+MAX_llx_menu__, 'billing', 'suppliers_bills_payment', 1600__+MAX_llx_menu__, '/fourn/facture/paiement.php?leftmenu=suppliers_bills_payment', 'Payments', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 2, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1605__+MAX_llx_menu__, 'billing', 'suppliers_bills_reports', 1603__+MAX_llx_menu__, '/fourn/facture/rapport.php?leftmenu=suppliers_bills_reports', 'Reporting', 2, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1604__+MAX_llx_menu__, 'billing', 'customers_bills_stats', 1600__+MAX_llx_menu__, '/compta/facture/stats/index.php?leftmenu=customers_bills_stats&mode=supplier', 'Statistics', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 8, __ENTITY__); -- Billing - Customer invoice insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1700__+MAX_llx_menu__, 'billing', 'customer_bills', 6__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills', 'BillsCustomers', 0, 'bills', '$user->rights->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1701__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/card.php?action=create&leftmenu=customers_bills', 'NewBill', 1, 'bills', '$user->rights->facture->creer', '', 2, 3, __ENTITY__); @@ -182,9 +183,9 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1722__+MAX_llx_menu__, 'billing', '', 1705__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills_paid&search_status=2', 'BillShortStatusPaid', 2, 'bills', '$user->rights->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1723__+MAX_llx_menu__, 'billing', '', 1705__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills_canceled&search_status=3', 'BillShortStatusCanceled', 2, 'bills', '$user->rights->facture->lire', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1704__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/paiement/list.php?leftmenu=customers_bills_payment', 'Payments', 1, 'bills', '$user->rights->facture->lire', '', 2, 6, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1710__+MAX_llx_menu__, 'billing', '', 1704__+MAX_llx_menu__, '/compta/paiement/rapport.php?leftmenu=customers_bills_reports', 'Reportings', 2, 'bills', '$user->rights->facture->lire', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1714__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/stats/index.php?leftmenu=customers_bills_stats', 'Statistics', 1, 'bills', '$user->rights->facture->lire', '', 2, 8, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1704__+MAX_llx_menu__, 'billing', 'customers_bills_payment', 1700__+MAX_llx_menu__, '/compta/paiement/list.php?leftmenu=customers_bills_payment', 'Payments', 1, 'bills', '$user->rights->facture->lire', '', 2, 6, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1710__+MAX_llx_menu__, 'billing', 'customers_bills_reports', 1704__+MAX_llx_menu__, '/compta/paiement/rapport.php?leftmenu=customers_bills_reports', 'Reportings', 2, 'bills', '$user->rights->facture->lire', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1714__+MAX_llx_menu__, 'billing', 'customers_bills_stats', 1700__+MAX_llx_menu__, '/compta/facture/stats/index.php?leftmenu=customers_bills_stats', 'Statistics', 1, 'bills', '$user->rights->facture->lire', '', 2, 8, __ENTITY__); -- Billing - Orders to bill insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled', __HANDLER__, 'left', 1900__+MAX_llx_menu__, 'billing', 'orders', 6__+MAX_llx_menu__, '/commande/list.php?leftmenu=orders&viewstatut=3', 'MenuOrdersToBill', 0, 'orders', '$user->rights->commande->lire', '', 0, 3, __ENTITY__); -- Donations diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 8c14f0e3df2..81791c993f2 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -811,15 +811,15 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } $newmenu->add("/compta/facture/invoicetemplate_list.php",$langs->trans("ListOfTemplates"),1,$user->rights->facture->creer); // No need to see recurring invoices, if user has no permission to create invoice. - $newmenu->add("/compta/paiement/list.php?leftmenu=customer_bills_payment",$langs->trans("Payments"),1,$user->rights->facture->lire); + $newmenu->add("/compta/paiement/list.php?leftmenu=customers_bills_payment",$langs->trans("Payments"),1,$user->rights->facture->lire,'',$mainmenu,'customers_bills_payment'); if (! empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) { - $newmenu->add("/compta/paiement/avalider.php",$langs->trans("MenuToValid"),2,$user->rights->facture->lire); + $newmenu->add("/compta/paiement/avalider.php",$langs->trans("MenuToValid"),2,$user->rights->facture->lire,'',$mainmenu,'customer_bills_tovalid'); } - $newmenu->add("/compta/paiement/rapport.php?leftmenu=customer_bills_reports",$langs->trans("Reportings"),2,$user->rights->facture->lire); + $newmenu->add("/compta/paiement/rapport.php?leftmenu=customers_bills_reports",$langs->trans("Reportings"),2,$user->rights->facture->lire,'',$mainmenu,'customers_bills_reports'); - $newmenu->add("/compta/facture/stats/index.php?leftmenu=customer_bills_stats", $langs->trans("Statistics"),1,$user->rights->facture->lire); + $newmenu->add("/compta/facture/stats/index.php?leftmenu=customers_bills_stats", $langs->trans("Statistics"),1,$user->rights->facture->lire,'',$mainmenu,'customers_bills_stats'); } // Suppliers invoices @@ -836,11 +836,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_paid&search_status=2", $langs->trans("BillShortStatusPaid"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_paid'); } - $newmenu->add("/fourn/facture/paiement.php", $langs->trans("Payments"),1,$user->rights->fournisseur->facture->lire); + $newmenu->add("/fourn/facture/paiement.php", $langs->trans("Payments"),1,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_payment'); - $newmenu->add("/fourn/facture/rapport.php",$langs->trans("Reportings"),2,$user->rights->fournisseur->facture->lire); + $newmenu->add("/fourn/facture/rapport.php",$langs->trans("Reportings"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_report'); - $newmenu->add("/compta/facture/stats/index.php?mode=supplier", $langs->trans("Statistics"),1,$user->rights->fournisseur->facture->lire); + $newmenu->add("/compta/facture/stats/index.php?mode=supplier", $langs->trans("Statistics"),1,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_stats'); } // Orders From 13e71306ac7bf92dfb3d6b15b2d34939ab42dcd6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 02:27:48 +0100 Subject: [PATCH 060/386] Start to work on payment import --- htdocs/core/modules/modPaypal.class.php | 15 +++++++++++++++ htdocs/core/modules/modStripe.class.php | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modPaypal.class.php b/htdocs/core/modules/modPaypal.class.php index 227540e825e..08f1c77e6d6 100644 --- a/htdocs/core/modules/modPaypal.class.php +++ b/htdocs/core/modules/modPaypal.class.php @@ -107,6 +107,21 @@ class modPaypal extends DolibarrModules // Main menu entries $this->menus = array(); // List of menus to add $r=0; + $this->menu[$r]=array( + 'fk_menu'=>'fk_mainmenu=billing,fk_leftmenu=customers_bills_payment', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'mainmenu'=>'billing', + 'leftmenu'=>'customers_bills_payment_paypal', + 'type'=>'left', // This is a Left menu entry + 'titre'=>'PaypalImportPayment', + 'url'=>'/paypal/importpayments.php', + 'langs'=>'paypal', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>501, + 'enabled'=>'$conf->paypal->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'$user->rights->banque->consolidate', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2 + ); // 0=Menu for internal users, 1=external users, 2=both + $r++; // Add here entries to declare new menus // Example to declare the Top Menu entry: diff --git a/htdocs/core/modules/modStripe.class.php b/htdocs/core/modules/modStripe.class.php index 61fe75d8f2e..7e6b15dee74 100644 --- a/htdocs/core/modules/modStripe.class.php +++ b/htdocs/core/modules/modStripe.class.php @@ -92,8 +92,22 @@ class modStripe extends DolibarrModules $r=0; // Main menu entries - $this->menus = array(); // List of menus to add $r=0; + $this->menu[$r]=array( + 'fk_menu'=>'fk_mainmenu=billing,fk_leftmenu=customers_bills_payment', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'mainmenu'=>'billing', + 'leftmenu'=>'customers_bills_payment_stripe', + 'type'=>'left', // This is a Left menu entry + 'titre'=>'StripeImportPayment', + 'url'=>'/stripe/importpayments.php', + 'langs'=>'stripe', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>500, + 'enabled'=>'$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'perms'=>'$user->rights->banque->consolidate', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2 + ); // 0=Menu for internal users, 1=external users, 2=both + $r++; // Exports $r=1; From 9731a7fedc9703408e4ccaf8ff531265e0c1a970 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 15:31:40 +0100 Subject: [PATCH 061/386] Code for update more similar than insert --- htdocs/core/class/commonobject.class.php | 48 ++++++++++++++++-------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 18d3f203dac..62eef427bd9 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1345,6 +1345,7 @@ abstract class CommonObject * @param User|string $fuser Update the user of last update field with this user. If not provided, current user is used except if value is 'none' * @param string $trigkey Trigger key to run (in most cases something like 'XXX_MODIFY') * @return int <0 if KO, >0 if OK + * @see updateExtraField */ function setValueFrom($field, $value, $table='', $id=null, $format='', $id_field='', $fuser=null, $trigkey='') { @@ -4511,6 +4512,7 @@ abstract class CommonObject * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) * @param User $userused Object user * @return int -1=error, O=did nothing, 1=OK + * @see updateExtraField, setValueFrom */ function insertExtraFields($trigger='',$userused=null) { @@ -4666,16 +4668,14 @@ abstract class CommonObject $this->error=$this->db->lasterror(); $error++; } - else + + if (! $error && $trigger) { - if ($trigger) - { - // Call trigger - $this->context=array('extrafieldaddupdate'=>1); - $result=$this->call_trigger($trigger, $userused); - if ($result < 0) $error++; - // End call trigger - } + // Call trigger + $this->context=array('extrafieldaddupdate'=>1); + $result=$this->call_trigger($trigger, $userused); + if ($result < 0) $error++; + // End call trigger } if ($error) @@ -4694,15 +4694,19 @@ abstract class CommonObject /** * Update an exta field value for the current object. - * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) - * This function delte record with all extrafields and insert them again from the array $this->array_options. + * Data to describe values to update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) * - * @param string $key Key of the extrafield - * @return int -1=error, O=did nothing, 1=OK + * @param string $key Key of the extrafield + * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) + * @param User $userused Object user + * @return int -1=error, O=did nothing, 1=OK + * @see setValueFrom */ - function updateExtraField($key) + function updateExtraField($key, $trigger, $userused) { - global $conf,$langs; + global $conf,$langs,$user; + + if (empty($userused)) $userused=$user; $error=0; @@ -4769,7 +4773,21 @@ abstract class CommonObject $resql = $this->db->query($sql); if (! $resql) { + $error++; $this->error=$this->db->lasterror(); + } + + if (! $error && $trigger) + { + // Call trigger + $this->context=array('extrafieldupdate'=>1); + $result=$this->call_trigger($trigger, $userused); + if ($result < 0) $error++; + // End call trigger + } + + if ($error) + { $this->db->rollback(); return -1; } From 4cfec30f93829fcd1496ff387401ee24394a61d2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 15:35:55 +0100 Subject: [PATCH 062/386] Start to work on PDF template for timesheet --- .../project/doc/pdf_timespent.modules.php | 608 ++++++++++++++++++ 1 file changed, 608 insertions(+) create mode 100644 htdocs/core/modules/project/doc/pdf_timespent.modules.php diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php new file mode 100644 index 00000000000..21853f1bbf8 --- /dev/null +++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php @@ -0,0 +1,608 @@ + + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/project/doc/pdf_baleine.modules.php + * \ingroup project + * \brief File of class to generate project document Baleine + * \author Regis Houssin + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + + +/** + * Class to manage generation of project document Baleine + */ + +class pdf_timespent extends ModelePDFProjects +{ + var $emetteur; // Objet societe qui emet + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("projects"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "timespent"; + $this->description = $langs->trans("DocumentModelTimeSpent"); + + // Dimension page pour format A4 + $this->type = 'pdf'; + $formatarray=pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; + $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; + $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; + $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; + + $this->option_logo = 1; // Affiche logo FAC_PDF_LOGO + $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION + $this->option_codeproduitservice = 1; // Affiche code produit-service + + // Recupere emmetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + + // Defini position des colonnes + $this->posxref=$this->marge_gauche+1; + $this->posxlabel=$this->marge_gauche+25; + $this->posxtimespent=$this->marge_gauche+120; + //$this->posxprogress=$this->marge_gauche+140; + $this->posxdatestart=$this->marge_gauche+152; + $this->posxdateend=$this->marge_gauche+170; + if ($this->page_largeur < 210) // To work with US executive format + { + $this->posxref-=20; + $this->posxlabel-=20; + $this->posxtimespent-=20; + //$this->posxprogress-=20; + $this->posxdatestart-=20; + $this->posxdateend-=20; + } + } + + + /** + * Fonction generant le projet sur le disque + * + * @param Project $object Object project a generer + * @param Translate $outputlangs Lang output object + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs) + { + global $conf, $hookmanager, $langs, $user; + + if (! is_object($outputlangs)) $outputlangs=$langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("projects"); + + if ($conf->projet->dir_output) + { + //$nblignes = count($object->lines); // This is set later with array of tasks + + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->projet->dir_output; + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + + // Create pdf instance + $pdf=pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1,0); + + $heightforinfotot = 40; // Height reserved to output the info and total part + $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (empty($conf->global->MAIN_DISABLE_FPDI) && ! empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + // Complete object by loading several other informations + $task = new Task($this->db); + $tasksarray = $task->getTasksArray(0,0,$object->id); + + if (! $object->id > 0) // Special case when used with object = specimen, we may return all lines + { + $tasksarray=array_slice($tasksarray, 0, min(5, count($tasksarray))); + } + + $object->lines=$tasksarray; + $nblignes=count($object->lines); + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("Project")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Project")); + if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $tab_top = 50; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10); + $tab_height = 170; + $tab_height_newpage = 190; + + // Show public note + $notetoshow=empty($object->note_public)?'':$object->note_public; + if ($notetoshow) + { + $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + + $tab_top -= 2; + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxref-1, $tab_top-2, dol_htmlentitiesbr($notetoshow), 0, 1); + $nexY = $pdf->GetY(); + $height_note=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1); + + $tab_height = $tab_height - $height_note; + $tab_top = $nexY+6; + } + else + { + $height_note=0; + } + + $heightoftitleline = 10; + $iniY = $tab_top + $heightoftitleline + 1; + $curY = $tab_top + $heightoftitleline + 1; + $nexY = $tab_top + $heightoftitleline + 1; + + // Loop on each lines + for ($i = 0 ; $i < $nblignes ; $i++) + { + $curY = $nexY; + $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0,0,0); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore=$pdf->getPage(); + + // Description of line + $ref=$object->lines[$i]->ref; + $libelleline=$object->lines[$i]->label; + //$progress=($object->lines[$i]->progress?$object->lines[$i]->progress.'%':''); + $datestart=dol_print_date($object->lines[$i]->date_start,'day'); + $dateend=dol_print_date($object->lines[$i]->date_end,'day'); + $planned_timespent=convertSecondToTime((int) $object->lines[$i]->planned_timespent,'allhourmin'); + + $showpricebeforepagebreak=1; + + $pdf->startTransaction(); + // Label + $pdf->SetXY($this->posxlabel, $curY); + $pdf->MultiCell($this->posxtimespent-$this->posxlabel, 3, $outputlangs->convToOutputCharset($libelleline), 0, 'L'); + $pageposafter=$pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + // Label + $pdf->SetXY($this->posxlabel, $curY); + $posybefore=$pdf->GetY(); + $pdf->MultiCell($this->posxtimespent-$this->posxlabel, 3, $outputlangs->convToOutputCharset($libelleline), 0, 'L'); + $pageposafter=$pdf->getPage(); + $posyafter=$pdf->GetY(); + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposafter+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + $forcedesconsamepage=1; + if ($forcedesconsamepage) + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposafter+1); + $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + $curY = $tab_top_newpage + $heightoftitleline + 1; + + // Label + $pdf->SetXY($this->posxlabel, $curY); + $posybefore=$pdf->GetY(); + $pdf->MultiCell($this->posxtimespent-$this->posxlabel, 3, $outputlangs->convToOutputCharset($libelleline), 0, 'L'); + $pageposafter=$pdf->getPage(); + $posyafter=$pdf->GetY(); + } + } + //var_dump($i.' '.$posybefore.' '.$posyafter.' '.($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)).' '.$showpricebeforepagebreak); + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $posYAfterDescription=$pdf->GetY(); + + $nexY = $pdf->GetY(); + $pageposafter=$pdf->getPage(); + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description is moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + //var_dump($pageposbefore.'-'.$pageposafter.'-'.$showpricebeforepagebreak); + $pdf->setPage($pageposafter); $curY = $tab_top_newpage + $heightoftitleline + 1; + } + + $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut + + // Ref of task + $pdf->SetXY($this->posxref, $curY); + $pdf->MultiCell($this->posxlabel-$this->posxref, 3, $outputlangs->convToOutputCharset($ref), 0, 'L'); + // timespent + $pdf->SetXY($this->posxtimespent, $curY); + $pdf->MultiCell($this->posxdatestart-$this->posxtimespent, 3, $planned_timespent?$planned_timespent:'', 0, 'R'); + // Progress + //$pdf->SetXY($this->posxprogress, $curY); + //$pdf->MultiCell($this->posxdatestart-$this->posxprogress, 3, $progress, 0, 'R'); + // Date + $pdf->SetXY($this->posxdatestart, $curY); + $pdf->MultiCell($this->posxdateend-$this->posxdatestart, 3, $datestart, 0, 'C'); + $pdf->SetXY($this->posxdateend, $curY); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxdateend, 3, $dateend, 0, 'C'); + + // Add line + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1); + $pdf->SetLineStyle(array('dash'=>0)); + } + + $nexY+=2; // Passe espace entre les lignes + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak) + { + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + // Show square + if ($pagenb == 1) + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); + else + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + + // Pied de page + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file, 'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // Pas d'erreur + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->transnoentities("ErrorConstantNotDefined","PROJECT_OUTPUTDIR"); + return 0; + } + } + + + /** + * Show table for lines + * + * @param PDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y + * @param Translate $outputlangs Langs object + * @param int $hidetop Hide top bar of array + * @param int $hidebottom Hide bottom bar of array + * @return void + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0) + { + global $conf,$mysoc; + + $heightoftitleline = 10; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetDrawColor(128,128,128); + + // Draw rect of all tab (title + lines). Rect prend une longueur en 3eme param + $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height); + + // line prend une position y en 3eme param + $pdf->line($this->marge_gauche, $tab_top+$heightoftitleline, $this->page_largeur-$this->marge_droite, $tab_top+$heightoftitleline); + + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size); + + $pdf->SetXY($this->posxref, $tab_top+1); + $pdf->MultiCell($this->posxlabel-$this->posxref,3, $outputlangs->transnoentities("Tasks"),'','L'); + + $pdf->SetXY($this->posxlabel, $tab_top+1); + $pdf->MultiCell($this->posxtimespent-$this->posxlabel, 3, $outputlangs->transnoentities("Description"), 0, 'L'); + + $pdf->SetXY($this->posxtimespent, $tab_top+1); + $pdf->MultiCell($this->posxdatestart-$this->posxtimespent, 3, $outputlangs->transnoentities("TimeSpent"), 0, 'R'); + + //$pdf->SetXY($this->posxprogress, $tab_top+1); + //$pdf->MultiCell($this->posxdatestart-$this->posxprogress, 3, '%', 0, 'R'); + + $pdf->SetXY($this->posxdatestart, $tab_top+1); + $pdf->MultiCell($this->posxdateend-$this->posxdatestart, 3, $outputlangs->transnoentities("Date"), 0, 'C'); + + $pdf->SetXY($this->posxdateend, $tab_top+1); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxdatestart, 3, '', 0, 'C'); + } + + /** + * Show top header of page. + * + * @param PDF $pdf Object PDF + * @param Project $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @return void + */ + function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + { + global $langs,$conf,$mysoc; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $posx=$this->page_largeur-$this->marge_droite-100; + $posy=$this->marge_haute; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$mysoc->logo; + if ($mysoc->logo) + { + if (is_readable($logo)) + { + $height=pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + } + } + else $pdf->MultiCell(100, 4, $outputlangs->transnoentities($this->emetteur->name), 0, 'L'); + + $pdf->SetFont('','B', $default_font_size + 3); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Project")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); + $pdf->SetFont('','', $default_font_size + 2); + + $posy+=6; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateStart")." : " . dol_print_date($object->date_start,'day',false,$outputlangs,true), '', 'R'); + + $posy+=6; + $pdf->SetXY($posx,$posy); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateEnd")." : " . dol_print_date($object->date_end,'day',false,$outputlangs,true), '', 'R'); + + if (is_object($object->thirdparty)) + { + $posy+=6; + $pdf->SetXY($posx,$posy); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("ThirdParty")." : " . $object->thirdparty->getFullName($outputlangs), '', 'R'); + } + + $pdf->SetTextColor(0,0,60); + + // Add list of linked objects + /* Removed: A project can have more than thousands linked objects (orders, invoices, proposals, etc.... + $object->fetchObjectLinked(); + + foreach($object->linkedObjects as $objecttype => $objects) + { + var_dump($objects);exit; + if ($objecttype == 'commande') + { + $outputlangs->load('orders'); + $num=count($objects); + for ($i=0;$i<$num;$i++) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $text=$objects[$i]->ref; + if ($objects[$i]->ref_client) $text.=' ('.$objects[$i]->ref_client.')'; + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), '', 'R'); + } + } + } + */ + + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param Project $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return integer + */ + function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) + { + global $conf; + $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf,$outputlangs,'PROJECT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext); + } + +} + From 9a0dca57afd868c50aa942b2a5cd49d866a947aa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 15:40:18 +0100 Subject: [PATCH 063/386] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index c0583f09552..76f8e55ff15 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4564,11 +4564,11 @@ abstract class CommonObject * Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...) * This function delete record with all extrafields and insert them again from the array $this->array_options. * - * @param bool $notrigger false=launch triggers after, true=disable triggers + * @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY) * @param User $userused Object user * @return int -1=error, O=did nothing, 1=OK */ - function insertExtraFields($notrigger=false, $userused=null) + function insertExtraFields($trigger='', $userused=null) { global $conf,$langs,$user; @@ -4703,16 +4703,14 @@ abstract class CommonObject $this->error=$this->db->lasterror(); $error++; } - else + + if (!$error && !$trigger) { - if (!$notrigger) - { - // Call trigger - $this->context=array('extrafieldaddupdate'=>1); - $result=$this->call_trigger(strtoupper(get_class($this)) . '_MODIFY', $userused); - if ($result < 0) $error++; - // End call trigger - } + // Call trigger + $this->context=array('extrafieldaddupdate'=>1); + $result=$this->call_trigger(strtoupper($trigger, $userused); + if ($result < 0) $error++; + // End call trigger } if ($error) From 6291cb4cbe6b135f96994975d6fd5c5cd1184c61 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 15:41:34 +0100 Subject: [PATCH 064/386] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 76f8e55ff15..592960670a0 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4708,7 +4708,7 @@ abstract class CommonObject { // Call trigger $this->context=array('extrafieldaddupdate'=>1); - $result=$this->call_trigger(strtoupper($trigger, $userused); + $result=$this->call_trigger($trigger, $userused); if ($result < 0) $error++; // End call trigger } From a8ad9fb77d42e7e8fc9115afba67bfe60aa6f9ee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 16:28:25 +0100 Subject: [PATCH 065/386] Fix default sort order --- htdocs/compta/tva/reglement.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/tva/reglement.php b/htdocs/compta/tva/reglement.php index 1a0b0699128..66099cd63db 100644 --- a/htdocs/compta/tva/reglement.php +++ b/htdocs/compta/tva/reglement.php @@ -97,7 +97,7 @@ $formother=new FormOther($db); $tva_static = new Tva($db); $bankstatic = new Account($db); -$sql = "SELECT t.rowid, t.amount, t.label, t.datev as dv, t.datep as dp, t.fk_typepayment as type, t.num_payment, t.fk_bank, pst.code as payment_code,"; +$sql = "SELECT t.rowid, t.amount, t.label, t.datev, t.datep, t.fk_typepayment as type, t.num_payment, t.fk_bank, pst.code as payment_code,"; $sql.= " ba.rowid as bid, ba.ref as bref, ba.number as bnumber, ba.account_number, ba.fk_accountancy_journal, ba.label as blabel"; $sql.= " FROM ".MAIN_DB_PREFIX."tva as t"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pst ON t.fk_typepayment = pst.id AND pst.entity IN (".getEntity('c_paiement').")"; @@ -192,8 +192,8 @@ if ($result) print ''; print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"t.rowid","",$param,"",$sortfield,$sortorder); print_liste_field_titre("Label",$_SERVER["PHP_SELF"],"t.label","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre("DateValue",$_SERVER["PHP_SELF"],"dv","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre("DatePayment",$_SERVER["PHP_SELF"],"dp","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre("DateValue",$_SERVER["PHP_SELF"],"t.datev","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre("DatePayment",$_SERVER["PHP_SELF"],"t.datep","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre("Type",$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); if (! empty($conf->banque->enabled)) print_liste_field_titre("Account",$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); print_liste_field_titre("PayedByThisPayment",$_SERVER["PHP_SELF"],"t.amount","",$param,'align="right"',$sortfield,$sortorder); @@ -222,8 +222,8 @@ if ($result) print "\n"; // Label print "\n"; - print '\n"; - print '\n"; + print '\n"; + print '\n"; // Type print $type; // Account From 47cb9aef50fe1a0afe18572716ef2e8459adc077 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 17:07:38 +0100 Subject: [PATCH 066/386] Fix: complete labels of operation if bank journal --- htdocs/accountancy/journal/bankjournal.php | 57 +++++++++++-------- .../compta/paiement/class/paiement.class.php | 32 +++++++++-- htdocs/compta/tva/class/tva.class.php | 8 ++- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index fcb24f7757a..8b9215f5c4c 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -271,7 +271,8 @@ if ($result) { if ($links[$key]['type'] == 'payment') { $paymentstatic->id = $links[$key]['url_id']; - $tabpay[$obj->rowid]["lib"] .= ' ' . $paymentstatic->getNomUrl(2); + $paymentstatic->ref = $links[$key]['url_id']; + $tabpay[$obj->rowid]["lib"] .= ' ' . $paymentstatic->getNomUrl(2, '', ''); // TODO Do not include list of invoice in tooltip, the dol_string_nohtmltag is ko with this $tabpay[$obj->rowid]["paymentid"] = $paymentstatic->id; } else if ($links[$key]['type'] == 'payment_supplier') { $paymentsupplierstatic->id = $links[$key]['url_id']; @@ -320,11 +321,12 @@ if ($result) { } } else if ($links[$key]['type'] == 'payment_donation') { $paymentdonstatic->id = $links[$key]['url_id']; + $paymentdonstatic->ref = $links[$key]['url_id']; $paymentdonstatic->fk_donation = $links[$key]['url_id']; $tabpay[$obj->rowid]["lib"] .= ' ' . $paymentdonstatic->getNomUrl(2); $tabpay[$obj->rowid]["paymentdonationid"] = $paymentdonstatic->id; $tabtp[$obj->rowid][$account_pay_donation] += $obj->amount; - } else if ($links[$key]['type'] == 'payment_vat') { + } else if ($links[$key]['type'] == 'payment_vat') { // Payment VAT $paymentvatstatic->id = $links[$key]['url_id']; $paymentvatstatic->ref = $links[$key]['url_id']; $paymentvatstatic->label = $links[$key]['label']; @@ -428,11 +430,10 @@ if (! $error && $action == 'writebookkeeping') { { if ($mt) { - $reflabel = $langs->trans("Bank"); - $reflabel.= ' '.$val['bank_account_ref']; - if (! empty($val['soclib'])) { - $reflabel .= " - " . dol_string_nohtmltag($val['soclib']); - } + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= dol_string_nohtmltag($val['lib']) . " - "; + $reflabel.= $langs->trans("Bank").' '.dol_string_nohtmltag($val['bank_account_ref']); + if (! empty($val['soclib'])) $reflabel .= " - " . dol_string_nohtmltag($val['soclib']); $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; @@ -486,7 +487,9 @@ if (! $error && $action == 'writebookkeeping') { foreach ( $tabtp[$key] as $k => $mt ) { if ($mt) { - $reflabel = dol_string_nohtmltag($val['soclib']); + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= dol_string_nohtmltag($val['lib']) . ($val['soclib']?" - ":""); + $reflabel.= dol_string_nohtmltag($val['soclib']); $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; @@ -586,7 +589,9 @@ if (! $error && $action == 'writebookkeeping') { foreach ( $tabbq[$key] as $k => $mt ) { if ($mt) { - $reflabel = 'WaitingAccount'; + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= dol_string_nohtmltag($val['lib']) . " - "; + $reflabel.= dol_string_nohtmltag('WaitingAccount'); $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; @@ -717,11 +722,10 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! foreach ( $tabbq[$key] as $k => $mt ) { if ($mt) { - $reflabel = $langs->trans("Bank"); - $reflabel.= ' '.$val['bank_account_ref']; - if (! empty($val['soclib'])) { - $reflabel .= " - " . dol_string_nohtmltag($val['soclib']); - } + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= dol_string_nohtmltag($val['lib']) . " - "; + $reflabel.= $langs->trans("Bank").' '.dol_string_nohtmltag($val['bank_account_ref']); + if (! empty($val['soclib'])) $reflabel .= " - " . dol_string_nohtmltag($val['soclib']); print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; @@ -743,7 +747,9 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! foreach ( $tabtp[$key] as $k => $mt ) { if ($mt) { - $reflabel = dol_string_nohtmltag($val['soclib']); + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= dol_string_nohtmltag($val['lib']) . ($val['soclib']?" - ":""); + $reflabel.= dol_string_nohtmltag($val['soclib']); print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; @@ -773,7 +779,9 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! foreach ( $tabbq[$key] as $k => $mt ) { if ($mt) { - $reflabel = 'WaitingAccount'; + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= dol_string_nohtmltag($val['lib']) . " - "; + $reflabel.= dol_string_nohtmltag('WaitingAccount'); print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; @@ -904,11 +912,10 @@ if (empty($action) || $action == 'view') { { if ($mt) { - $reflabel = $langs->trans("Bank"); - $reflabel.= ' '.$val['bank_account_ref']; - if (! empty($val['soclib'])) { - $reflabel .= " - " . $val['soclib']; - } + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= $val['lib'] . " - "; + $reflabel.= $langs->trans("Bank").' '.$val['bank_account_ref']; + if (! empty($val['soclib'])) $reflabel .= " - " . $val['soclib']; //var_dump($tabpay[$key]); print ''; @@ -949,7 +956,9 @@ if (empty($action) || $action == 'view') { foreach ( $tabtp[$key] as $k => $mt ) { if ($mt) { - $reflabel = $val['soclib']; + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= $val['lib'] . ($val['soclib']?" - ":""); + $reflabel.= $val['soclib']; print ''; print ''; @@ -1024,7 +1033,9 @@ if (empty($action) || $action == 'view') { foreach ( $tabbq[$key] as $k => $mt ) { if ($mt) { - $reflabel = 'WaitingAccount'; + $reflabel = ''; + if (! empty($val['lib'])) $reflabel .= $val['lib'] . " - "; + $reflabel.= 'WaitingAccount'; print ''; print ''; diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 00ae831dc3a..fdcfc89c4e0 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -1042,12 +1042,15 @@ class Paiement extends CommonObject * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param string $option Sur quoi pointe le lien * @param string $mode 'withlistofinvoices'=Include list of invoices into tooltip + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$option='',$mode='withlistofinvoices') + function getNomUrl($withpicto=0, $option='', $mode='withlistofinvoices', $notooltip=0) { global $langs; + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + $result=''; $label = $langs->trans("ShowPayment").': '.$this->ref; if ($mode == 'withlistofinvoices') @@ -1064,12 +1067,31 @@ class Paiement extends CommonObject } } } - $link = ''; + + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowMyObject"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + } + else $linkclose = ($morecss?' class="'.$morecss.'"':''); + + $url = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$this->id; + + $linkstart = ''; $linkend=''; - if ($withpicto) $result.=($link.img_object($langs->trans("ShowPayment"), 'payment', 'class="classfortooltip"').$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link.($this->ref?$this->ref:$this->id).$linkend; + $result .= $linkstart; + if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); + if ($withpicto && $withpicto != 2) $result.= $this->ref; + $result .= $linkend; + return $result; } diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php index b951c05f574..43b525ff230 100644 --- a/htdocs/compta/tva/class/tva.class.php +++ b/htdocs/compta/tva/class/tva.class.php @@ -655,9 +655,11 @@ class Tva extends CommonObject * @param int $notooltip 1=Disable tooltip * @return string Chaine with URL */ - function getNomUrl($withpicto=0, $option='', $notooltip=0) + function getNomUrl($withpicto=0, $option='', $notooltip=0) { - global $langs; + global $langs, $conf; + + if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips $result=''; $label=$langs->trans("ShowVatPayment").': '.$this->ref; @@ -690,7 +692,7 @@ class Tva extends CommonObject return $result; } - + /** * Return amount of payments already done * From bd00b514bff8d1c2cb61985f684c82dcbc1d97e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 20:19:00 +0100 Subject: [PATCH 067/386] Delete intervention API --- .../class/api_interventions.class.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index 23073737d7e..3f5fad3d74f 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -284,6 +284,39 @@ class Interventions extends DolibarrApi } } + /** + * Delete order + * + * @param int $id Order ID + * @return array + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->ficheinter->supprimer) { + throw new RestException(401); + } + $result = $this->fichinter->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Intervention not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('commande',$this->fichinter->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if( ! $this->fichinter->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete intervention : '.$this->fichinter->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Intervention deleted' + ) + ); + + } + /** * Validate an intervention * From 22b95b1c4393415c14ab9e08e827dc70efb544ce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 5 Feb 2018 23:06:48 +0100 Subject: [PATCH 068/386] Simpler top menu code --- htdocs/core/menus/standard/auguria.lib.php | 3 ++- htdocs/core/menus/standard/eldy.lib.php | 3 ++- htdocs/core/menus/standard/empty.php | 3 ++- htdocs/theme/eldy/style.css.php | 6 +----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 4dae9628c30..b7f2d220868 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -169,7 +169,8 @@ function print_start_menu_entry_auguria($idsel,$classname,$showmode) if ($showmode) { print '
'.$langs->trans("Project")."
'.$langs->trans("Project")." (".count($projects).")
'.$langs->trans("MAIN_DISABLE_ALL_MAILS").''; print $form->selectyesno('MAIN_DISABLE_ALL_MAILS',$conf->global->MAIN_DISABLE_ALL_MAILS,1); print '
'.$langs->trans("MAIN_MAIL_FORCE_SENDTO").''; + print ''; + print '
'.$langs->trans("MAIN_DISABLE_ALL_MAILS").''.yn($conf->global->MAIN_DISABLE_ALL_MAILS).'
'.$langs->trans("MAIN_MAIL_FORCE_SENDTO").''.$conf->global->MAIN_MAIL_FORCE_SENDTO; + if (! empty($conf->global->MAIN_MAIL_FORCE_SENDTO) && ! isValidEmail($conf->global->MAIN_MAIL_FORCE_SENDTO)) print img_warning($langs->trans("ErrorBadEMail")); + print '
' . $langs->trans("CalculatedWeight") . ''; + print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND)?$conf->global->MAIN_WEIGHT_DEFAULT_ROUND:-1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT)?$conf->global->MAIN_WEIGHT_DEFAULT_UNIT:'no'); + print '
' . $langs->trans("CalculatedVolume") . ''; + print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no'); + print '
'.$langs->trans("CalculatedWeight").''; print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND)?$conf->global->MAIN_WEIGHT_DEFAULT_ROUND:-1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT)?$conf->global->MAIN_WEIGHT_DEFAULT_UNIT:'no'); print '
'.$langs->trans("CalculatedVolume").''; print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no'); From 12e414509ca3bf9c1a956bc11a558a2adee9c035 Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Tue, 2 Jan 2018 11:24:28 +0100 Subject: [PATCH 007/386] Add a hook in dol_print_phone To allow more controls in this print function as in dol_print_address (there is a hook so we can create links to maps...). Eg : create a other click to dial functions (different from dolibarr ones with more parameters, because each provider give differents api ) etc Hope this one will be accepted and usefull for the community. And happy new year :) --- htdocs/core/lib/functions.lib.php | 44 +++++++++++++++++++------------ 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 9e7bb7f7ce8..77882d590d6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2172,7 +2172,7 @@ function dol_print_skype($skype,$cid=0,$socid=0,$addlink=0,$max=64) */ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$separ=" ",$withpicto='',$titlealt='',$adddivfloat=0) { - global $conf,$user,$langs,$mysoc; + global $conf, $user, $langs, $mysoc, $hookmanager; // Clean phone parameter $phone = preg_replace("/[\s.-]/","",trim($phone)); @@ -2262,23 +2262,33 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $titlealt=($withpicto=='fax'?$langs->trans("Fax"):$langs->trans("Phone")); } $rep=''; - $picto = ''; - if($withpicto){ - if($withpicto=='fax'){ - $picto = 'phoning_fax'; - }elseif($withpicto=='phone'){ - $picto = 'phoning'; - }elseif($withpicto=='mobile'){ - $picto = 'phoning_mobile'; - }else{ - $picto = ''; + + if ($hookmanager) { + $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid); + $reshook = $hookmanager->executeHooks('printPhone', $parameters, $phone); + $rep.=$hookmanager->resPrint; + } + if (empty($reshook)) + { + $picto = ''; + if($withpicto){ + if($withpicto=='fax'){ + $picto = 'phoning_fax'; + }elseif($withpicto=='phone'){ + $picto = 'phoning'; + }elseif($withpicto=='mobile'){ + $picto = 'phoning_mobile'; + }else{ + $picto = ''; + } } - } - if ($adddivfloat) $rep.='
'; - else $rep.=''; - $rep.=($withpicto?img_picto($titlealt, 'object_'.$picto.'.png').' ':'').$newphone; - if ($adddivfloat) $rep.='
'; - else $rep.=''; + if ($adddivfloat) $rep.='
'; + else $rep.=''; + $rep.=($withpicto?img_picto($titlealt, 'object_'.$picto.'.png').' ':'').$newphone; + if ($adddivfloat) $rep.='
'; + else $rep.=''; + } + return $rep; } From ab896dc49d50448c6bcd68d0ac76023340fd493e Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Tue, 2 Jan 2018 11:39:00 +0100 Subject: [PATCH 008/386] Update functions.lib.php --- htdocs/core/lib/functions.lib.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 77882d590d6..06574be96a5 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2268,8 +2268,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $reshook = $hookmanager->executeHooks('printPhone', $parameters, $phone); $rep.=$hookmanager->resPrint; } - if (empty($reshook)) - { + $picto = ''; if($withpicto){ if($withpicto=='fax'){ @@ -2287,7 +2286,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $rep.=($withpicto?img_picto($titlealt, 'object_'.$picto.'.png').' ':'').$newphone; if ($adddivfloat) $rep.=''; else $rep.=''; - } + return $rep; } From e794a3b321d764fa007ea56532a3412730707dfb Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Tue, 2 Jan 2018 11:44:54 +0100 Subject: [PATCH 009/386] Update functions.lib.php add more parameters and add if empty --- htdocs/core/lib/functions.lib.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 06574be96a5..0fa71c97c49 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2264,11 +2264,12 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $rep=''; if ($hookmanager) { - $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid); + $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid,'titlealt' => $titlealt, 'picto' => $picto); $reshook = $hookmanager->executeHooks('printPhone', $parameters, $phone); $rep.=$hookmanager->resPrint; } - + if (empty($reshook)) + { $picto = ''; if($withpicto){ if($withpicto=='fax'){ @@ -2286,7 +2287,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $rep.=($withpicto?img_picto($titlealt, 'object_'.$picto.'.png').' ':'').$newphone; if ($adddivfloat) $rep.=''; else $rep.=''; - + } return $rep; } From 3438cfb1e7a63231e2d9a025f82ead63d0d619fe Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Tue, 2 Jan 2018 11:48:41 +0100 Subject: [PATCH 010/386] Update functions.lib.php syntax error $withpicto --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0fa71c97c49..f69bf3979cd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2264,7 +2264,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $rep=''; if ($hookmanager) { - $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid,'titlealt' => $titlealt, 'picto' => $picto); + $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid,'titlealt' => $titlealt, 'picto' => $withpicto); $reshook = $hookmanager->executeHooks('printPhone', $parameters, $phone); $rep.=$hookmanager->resPrint; } From 6ba5ca36c4b7a7a666a997effd2cd6001ac66a8e Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Fri, 5 Jan 2018 08:59:31 +0100 Subject: [PATCH 011/386] Update llx_societe.sql Goes with https://github.com/Dolibarr/dolibarr/pull/7975 --- htdocs/install/mysql/tables/llx_societe.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index c23ca3a183c..fe20f426094 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -104,5 +104,6 @@ create table llx_societe webservices_key varchar(128), -- supplier webservice key fk_multicurrency integer, - multicurrency_code varchar(255) + multicurrency_code varchar(255), + fk_entrepot int DEFAULT 0 -- Id de l'entrepôt par défaut (Warehouse ID by default) )ENGINE=innodb; From 30c6891b957bd33579ced61d98033508c2bd8970 Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Wed, 10 Jan 2018 10:24:42 +0100 Subject: [PATCH 012/386] NEW : Add product categories filter on product margin --- htdocs/langs/fr_FR/categories.lang | 1 + htdocs/margin/productMargins.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/htdocs/langs/fr_FR/categories.lang b/htdocs/langs/fr_FR/categories.lang index 10ab0fd65e4..99d1375b28c 100644 --- a/htdocs/langs/fr_FR/categories.lang +++ b/htdocs/langs/fr_FR/categories.lang @@ -85,3 +85,4 @@ CategorieRecursivHelp=Si activé : quand un élément est ajouté dans une cat AddProductServiceIntoCategory=Ajouter le produit/service suivant ShowCategory=Afficher tag/catégorie ByDefaultInList=Par défaut dans la liste +ChooseCategory=Choisissez les catégories diff --git a/htdocs/margin/productMargins.php b/htdocs/margin/productMargins.php index 9d52b25de36..ef99e593b82 100644 --- a/htdocs/margin/productMargins.php +++ b/htdocs/margin/productMargins.php @@ -37,6 +37,7 @@ $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $action=GETPOST('action','alpha'); $confirm=GETPOST('confirm','alpha'); +$TSelectedCats=GETPOST('categories', 'array'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); @@ -121,6 +122,16 @@ else { } +// Categories +$TCats = $form->select_all_categories(0, array(), '', 64, 0, 1); + +print '
'.$langs->trans('ChooseCategory').''; +print $form->multiselectarray('categories', $TCats, $TSelectedCats, 0, 0, 'minwidth500'); +print '
'.$langs->trans('DateStart').' ('.$langs->trans("DateValidation").')
'.$langs->trans('ChooseProduct/Service').''; +print $form->multiselectarray('products', $TProducts, $TSelectedProducts, 0, 0, 'minwidth500'); +print '
'.$langs->trans('ChooseCategory').''; +print $form->multiselectarray('categories', $TCats, $TSelectedCats, 0, 0, 'minwidth500'); +print '
'.$langs->trans('DateStart').' ('.$langs->trans("DateValidation").')'; @@ -186,6 +212,10 @@ $sql.= " sum(".$db->ifsql('d.total_ht < 0','-1 * (abs(d.total_ht) - (d.buy_price $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql.= ", ".MAIN_DB_PREFIX."facture as f"; $sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; +if(! empty($TSelectedCats)) { + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=d.fk_product'; +} + if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE f.fk_soc = s.rowid"; if ($socid > 0) $sql.= ' AND s.rowid = '.$socid; @@ -194,6 +224,12 @@ $sql.= " AND f.fk_statut > 0"; $sql.= ' AND s.entity IN ('.getEntity('societe').')'; $sql.= " AND d.fk_facture = f.rowid"; $sql.= " AND (d.product_type = 0 OR d.product_type = 1)"; +if(! empty($TSelectedProducts)) { + $sql .= ' AND d.fk_product IN ('.implode(',', $TSelectedProducts) . ')'; +} +if(! empty($TSelectedCats)) { + $sql .= ' AND cp.fk_categorie IN ('.implode(',', $TSelectedCats) . ')'; +} if (!empty($startdate)) $sql.= " AND f.datef >= '".$db->idate($startdate)."'"; if (!empty($enddate)) From c45e5c91b118dbd985c42c57d91ff898671149ea Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sun, 14 Jan 2018 17:13:42 +0100 Subject: [PATCH 014/386] New hidden option MAIN_DISABLE_FREE_LINES --- htdocs/core/tpl/objectline_create.tpl.php | 80 +++++++++++++---------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 2d6178ed79b..2ea5b6899d7 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -142,49 +142,54 @@ else { element == 'contrat') + + $freelines = false; + if(empty($conf->global->MAIN_DISABLE_FREE_LINES)) { - if (empty($conf->product->enabled) && empty($conf->service->enabled) && empty($conf->global->CONTRACT_SUPPORT_PRODUCTS)) $forceall=-1; // With contract, by default, no choice at all, except if CONTRACT_SUPPORT_PRODUCTS is set - else $forceall=0; - } - - // Free line - echo ''; - // Show radio free line - if ($forceall >= 0 && (! empty($conf->product->enabled) || ! empty($conf->service->enabled))) - { - echo ''; - echo ' '; - } - else - { - echo ''; - // Show type selector - if ($forceall >= 0) + $freelines = true; + $forceall=1; // We always force all type for free lines (module product or service means we use predefined product or service) + if ($object->element == 'contrat') { - if (empty($conf->product->enabled) || empty($conf->service->enabled)) echo $langs->trans("Type"); - else echo $langs->trans("FreeLineOfType"); + if (empty($conf->product->enabled) && empty($conf->service->enabled) && empty($conf->global->CONTRACT_SUPPORT_PRODUCTS)) $forceall=-1; // With contract, by default, no choice at all, except if CONTRACT_SUPPORT_PRODUCTS is set + else $forceall=0; + } + + // Free line + echo ''; + // Show radio free line + if ($forceall >= 0 && (! empty($conf->product->enabled) || ! empty($conf->service->enabled))) + { + echo ''; echo ' '; } + else + { + echo ''; + // Show type selector + if ($forceall >= 0) + { + if (empty($conf->product->enabled) || empty($conf->service->enabled)) echo $langs->trans("Type"); + else echo $langs->trans("FreeLineOfType"); + echo ' '; + } + } + + echo $form->select_type_of_lines(isset($_POST["type"])?GETPOST("type",'alpha',2):-1,'type',1,1,$forceall); + + echo ''; } - echo $form->select_type_of_lines(isset($_POST["type"])?GETPOST("type",'alpha',2):-1,'type',1,1,$forceall); - - echo ''; - // Predefined product/service if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) { - if ($forceall >= 0) echo '
'; + if ($forceall >= 0 && $freelines) echo '
'; echo ''; echo '
'; + print $form->editfieldkey("OrderMinAmount",'order_min_amount',$object->order_min_amount,$object,$user->rights->societe->creer); + print ''; + print $form->editfieldval("OrderMinAmount",'order_min_amount',$object->order_min_amount,$object,$user->rights->societe->creer,$limit_field_type,($object->order_min_amount != '' ? price($object->order_min_amount) : '')); + print '
'; + print $form->editfieldkey("OrderMinAmount",'supplier_order_min_amount',$object->supplier_order_min_amount,$object,$user->rights->societe->creer); + print ''; + $limit_field_type = (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE)) ? 'numeric' : 'amount'; + print $form->editfieldval("OrderMinAmount",'supplier_order_min_amount',$object->supplier_order_min_amount,$object,$user->rights->societe->creer,$limit_field_type,($object->supplier_order_min_amount != '' ? price($object->supplier_order_min_amount) : '')); + + print '
' . $langs->trans('AmountHT') . '' . price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency) . '' . price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency) . $alert . '
' . $langs->trans('AmountVAT') . '' . price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency) . '
'.$langs->trans("AmountHT").''.price($object->total_ht,'',$langs,1,-1,-1,$conf->currency).''.price($object->total_ht,'',$langs,1,-1,-1,$conf->currency).$alert.'
'; + if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE) && ($conf->global->MAIN_SHOW_REGION_IN_STATE == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE == 2)) + { + print '
'; + } + else + { + print '
'; + } + if ($object->country_id) { print $formcompany->select_state(GETPOST("state_id",'alpha')?GETPOST("state_id",'alpha'):$object->state_id,$object->country_code,'state_id'); @@ -852,7 +860,15 @@ else // State if (empty($conf->global->SOCIETE_DISABLE_STATE)) { - print '
'; + if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE) && ($conf->global->MAIN_SHOW_REGION_IN_STATE == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE == 2)) + { + print '
'; + } + else + { + print '
'; + } + print $formcompany->select_state($object->state_id,isset($_POST["country_id"])?GETPOST("country_id"):$object->country_id,'state_id'); print '
'; } @@ -860,7 +860,7 @@ else // State if (empty($conf->global->SOCIETE_DISABLE_STATE)) { - if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE) && ($conf->global->MAIN_SHOW_REGION_IN_STATE == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE == 2)) + if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) { print '
'; } diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index c434202ba2e..d3990acc9c8 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -266,10 +266,10 @@ class FormCompany $out.= '
'.fieldLabel('State','state_id').''; + if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) + { + print '
'.fieldLabel('Region-State','state_id').''; + } + else + { + print '
'.fieldLabel('State','state_id').''; + } + if ($object->country_id) print $formcompany->select_state($object->state_id,$object->country_code); else print $countrynotdefined; print '
'.fieldLabel('State','state_id').''; + if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) + { + print '
'.fieldLabel('Region-State','state_id').''; + } + else + { + print '
'.fieldLabel('State','state_id').''; + } + print $formcompany->select_state($object->state_id,$object->country_code); print '
'; -print $form->select_dolusers($search_fk_user, 'search_fk_user', 1); +print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); - print ''.$fulltag.''; + print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("MAIN_DISABLE_ALL_MAILS").''; print $form->selectyesno('MAIN_DISABLE_ALL_MAILS',$conf->global->MAIN_DISABLE_ALL_MAILS,1); print '
'.$langs->trans("MAIN_MAIL_FORCE_SENDTO").''; print ''; @@ -483,7 +483,7 @@ else // Disable print '
'.$langs->trans("MAIN_DISABLE_ALL_MAILS").''.yn($conf->global->MAIN_DISABLE_ALL_MAILS).'
'.$langs->trans("MAIN_MAIL_FORCE_SENDTO").''.$conf->global->MAIN_MAIL_FORCE_SENDTO; if (! empty($conf->global->MAIN_MAIL_FORCE_SENDTO) && ! isValidEmail($conf->global->MAIN_MAIL_FORCE_SENDTO)) print img_warning($langs->trans("ErrorBadEMail")); @@ -655,25 +655,7 @@ else dol_fiche_end(); - if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)) - { - print '
'; - /* - // Warning 1 - if ($linuxlike) - { - $sendmailoption=ini_get('mail.force_extra_parameters'); - if (empty($sendmailoption) || ! preg_match('/ba/',$sendmailoption)) - { - print info_admin($langs->trans("SendmailOptionNotComplete")); - } - }*/ - // Warning 2 - print info_admin($langs->trans("SendmailOptionMayHurtBuggedMTA")); - } - - - // Boutons actions + // Actions button print '
'; print ''.$langs->trans("Modify").''; @@ -700,6 +682,22 @@ else print '
'; + if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)) + { + /* + // Warning 1 + if ($linuxlike) + { + $sendmailoption=ini_get('mail.force_extra_parameters'); + if (empty($sendmailoption) || ! preg_match('/ba/',$sendmailoption)) + { + print info_admin($langs->trans("SendmailOptionNotComplete")); + } + }*/ + // Warning 2 + print info_admin($langs->trans("SendmailOptionMayHurtBuggedMTA")); + } + if ($conf->global->MAIN_MAIL_SENDMODE == 'mail' && ! in_array($action, array('testconnect', 'test', 'testhtml'))) { $text = $langs->trans("WarningPHPMail"); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 71acd0e71cb..c2201c5d118 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -269,7 +269,7 @@ MAIN_MAIL_SMTP_SERVER=SMTP/SMTPS Host (By default in php.ini: %s) MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike=SMTP/SMTPS Port (Not defined into PHP on Unix like systems) MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike=SMTP/SMTPS Host (Not defined into PHP on Unix like systems) MAIN_MAIL_EMAIL_FROM=Sender email for automatic emails (By default in php.ini: %s) -MAIN_MAIL_ERRORS_TO=Sender email used for error returns emails sent +MAIN_MAIL_ERRORS_TO=Email used as 'Errors-To' field in emails sent MAIN_MAIL_AUTOCOPY_TO= Send systematically a hidden carbon-copy of all sent emails to MAIN_DISABLE_ALL_MAILS=Disable all emails sendings (for test purposes or demos) MAIN_MAIL_FORCE_SENDTO=Send all emails to (instead of real recipients, for test purposes) From 4fdde55c59ab8961dadd0d7db43aa07c0c1b7a8e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 4 Feb 2018 12:14:39 +0100 Subject: [PATCH 053/386] Keep empty graph if graph is called with empty data --- htdocs/core/class/dolgraph.class.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 329383160aa..ba7a67be3cb 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -594,7 +594,7 @@ class DolGraph * @param string $fileurl Url path to show image if saved onto disk * @return integer|null */ - function draw($file,$fileurl='') + function draw($file, $fileurl='') { if (empty($file)) { @@ -602,12 +602,17 @@ class DolGraph dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR); return -2; } - if (! is_array($this->data) || count($this->data) < 1) + if (! is_array($this->data)) { $this->error="Call to draw method was made but SetData was not called or called with an empty dataset for parameters"; dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR); return -1; } + if (count($this->data) < 1) + { + $this->error="Call to draw method was made but SetData was is an empty dataset"; + dol_syslog(get_class($this)."::draw ".$this->error, LOG_WARNING); + } $call = "draw_".$this->_library; call_user_func_array(array($this,$call), array($file,$fileurl)); } @@ -822,7 +827,7 @@ class DolGraph $legends=array(); $nblot=count($this->data[0])-1; // -1 to remove legend - if ($nblot < 0) dol_print_error('', 'Bad value for property ->data. Must be set by mydolgraph->SetData before calling mydolgrapgh->draw'); + if ($nblot < 0) dol_syslog('Bad value for property ->data. Must be set by mydolgraph->SetData before calling mydolgrapgh->draw', LOG_WARNING); $firstlot=0; // Works with line but not with bars //if ($nblot > 2) $firstlot = ($nblot - 2); // We limit nblot to 2 because jflot can't manage more than 2 bars on same x From 42f8da7496671bab030b153b5246e975214b37ed Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 4 Feb 2018 12:56:17 +0100 Subject: [PATCH 054/386] NEW Add trigger CONTRACT_MODIFY --- htdocs/contrat/class/contrat.class.php | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index ad6b16163a5..fd1019390be 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1268,26 +1268,14 @@ class Contrat extends CommonObject { if (! $notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action calls a trigger. - - //// Call triggers - //$result=$this->call_trigger('MYOBJECT_MODIFY',$user); - //if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} - //// End call triggers + // Call triggers + $result=$this->call_trigger('CONTRACT_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers } } - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($this->array_options) && count($this->array_options)>0) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($this->array_options) && count($this->array_options)>0) // For avoid conflicts if trigger used + if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($this->array_options) && count($this->array_options)>0) // For avoid conflicts if trigger used { $result=$this->insertExtraFields(); if ($result < 0) From bb42589d6bd726ee864387fd14e3c5bc884faeb5 Mon Sep 17 00:00:00 2001 From: fappels Date: Sun, 4 Feb 2018 12:59:02 +0100 Subject: [PATCH 055/386] Fix paging when filtering If total resultset is smaller then paging size (filtering), goto and load page 0. If total resultset is smaller the limit, no need to do paging. --- .../modulebuilder/template/myobject_list.php | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 71894b8659b..f7bf371c289 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -253,17 +253,30 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); } - -$sql.= $db->plimit($limit+1, $offset); - -$resql=$db->query($sql); -if (! $resql) +if (($page * $limit) > $nbtotalofrecords) { - dol_print_error($db); - exit; + $page = 0; + $offset = 0; } +// if total resultset is smaller the limit, no need to do paging. +if ($limit > $nbtotalofrecords) +{ + $resql = $result; + $num = $nbtotalofrecords; +} +else +{ + $sql.= $db->plimit($limit+1, $offset); -$num = $db->num_rows($resql); + $resql=$db->query($sql); + if (! $resql) + { + dol_print_error($db); + exit; + } + + $num = $db->num_rows($resql); +} // Direct jump if only one record found if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) @@ -317,7 +330,7 @@ if ($user->rights->mymodule->delete) $arrayofmassactions['predelete']=$langs->tr if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); -print ''; +print ''; if ($optioncss != '') print ''; print ''; print ''; From 83e1545720405ebc93c1c66e2f9c529073712fd7 Mon Sep 17 00:00:00 2001 From: fappels Date: Sun, 4 Feb 2018 12:59:30 +0100 Subject: [PATCH 056/386] Fix comment --- htdocs/modulebuilder/template/myobject_list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index f7bf371c289..7c3575401e4 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -253,6 +253,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); } +// if total resultset is smaller then paging size (filtering), goto and load page 0 if (($page * $limit) > $nbtotalofrecords) { $page = 0; From aff6bced4a0f96488c71a6aed78d889723ff3f1c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 4 Feb 2018 13:20:47 +0100 Subject: [PATCH 057/386] Fix default value was not save at creation --- htdocs/core/class/extrafields.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1161fb8abd8..fd3c60a5b85 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -168,7 +168,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $notused, $default, $computed, $entity, $langfile, $enabled); + $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $notused, $default_value, $computed, $entity, $langfile, $enabled); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { From ec15048964636cf8fef91cfecfe6cc20874a5ef4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 4 Feb 2018 14:34:31 +0100 Subject: [PATCH 058/386] Fix init category selected --- htdocs/product/card.php | 5 +++-- htdocs/societe/card.php | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index a54f1d90885..861c46328df 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1106,11 +1106,11 @@ else print "
'.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', 'parent', 64, 0, 1); - print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); + print $form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), '', 0, '', 0, '100%'); print "
".$tva_static->getNomUrl(1)."".dol_trunc($obj->label,40)."'.dol_print_date($db->jdate($obj->dv),'day')."'.dol_print_date($db->jdate($obj->dp),'day')."'.dol_print_date($db->jdate($obj->datev),'day')."'.dol_print_date($db->jdate($obj->datep),'day')."
'; + + print ''; + print ''; + + print "
'.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
'.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
\n"; + + print "\n"; + + print dol_fiche_end(); + + $modulepart = 'expedition'; + $permission = $user->rights->expedition->creer; + $permtoedit = $user->rights->expedition->creer; + $param = '&id=' . $object->id; + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; + } + else{ + dol_print_error($db); + } +} +else{ + header('Location: index.php'); + exit; +} + + +llxFooter(); + +$db->close(); From 8847293527a098c5de27a544073f1137dca85c38 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 8 Feb 2018 12:25:30 +0100 Subject: [PATCH 074/386] Add new html containers and somme html5 data-* for contract card. --- htdocs/contrat/card.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index ae1178adf9a..aedb8f639a7 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1499,8 +1499,10 @@ else // Title line for service $cursorline=1; + print '
'; while ($cursorline <= $nbofservices) { + print '
'; print '
'; print ''; print ''; @@ -2015,10 +2017,12 @@ else print '
'; } - + + print '
'; $cursorline++; } - + print '
'; + // Form to add new line if ($user->rights->contrat->creer && ($object->statut == 0)) { From f5ace81116681974d4bb29ebceafe8cefb94f972 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 13:07:05 +0100 Subject: [PATCH 075/386] Update myobject_list.php --- htdocs/modulebuilder/template/myobject_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 7c3575401e4..ef384edb818 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -260,7 +260,7 @@ if (($page * $limit) > $nbtotalofrecords) $offset = 0; } // if total resultset is smaller the limit, no need to do paging. -if ($limit > $nbtotalofrecords) +if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) { $resql = $result; $num = $nbtotalofrecords; From 9c954de0811a9f39a127afef7fbc9f0d248c9f8c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 14:25:44 +0100 Subject: [PATCH 076/386] Error management --- htdocs/comm/card.php | 6 +++--- htdocs/expensereport/class/expensereport.class.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 82a3c621db8..6dfd05354d8 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -176,7 +176,7 @@ if (empty($reshook)) $result=$object->update($object->id, $user); if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); } - + // update order min amount if ($action == 'setorder_min_amount') { @@ -412,7 +412,7 @@ if ($object->id > 0) print ''; print ''; - + print ''; print ''; print $form->editfieldkey("OrderMinAmount",'order_min_amount',$object->order_min_amount,$object,$user->rights->societe->creer); @@ -422,7 +422,7 @@ if ($object->id > 0) print ''; print ''; } - + // Multiprice level if (! empty($conf->global->PRODUIT_MULTIPRICES)) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 2052b63fe0c..b1523f3bbf9 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1091,7 +1091,7 @@ class ExpenseReport extends CommonObject { $num = $this->ref; } - if (empty($num)) return -1; + if (empty($num) || $num < 0) return -1; $this->newref = $num; From b56da9c11ee4291d667151cd2cea4e4d9df12b1a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 15:11:05 +0100 Subject: [PATCH 077/386] Better balance css columns in dashboard --- htdocs/index.php | 6 ++---- htdocs/theme/eldy/style.css.php | 12 ++++++++++++ htdocs/theme/md/style.css.php | 12 ++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index b01e37927c4..3eb1aa2285a 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -616,20 +616,18 @@ print '
'; $boxlist.='
'; -$boxlist.='
'; +$boxlist.='
'; $boxlist.=$boxwork; $boxlist.=$resultboxes['boxlista']; $boxlist.= '
'; -$boxlist.= '
'; -$boxlist.= '
'; +$boxlist.= '
'; $boxlist.=$boxstat; $boxlist.=$resultboxes['boxlistb']; -$boxlist.= '
'; $boxlist.= '
'; $boxlist.= "\n"; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e287c710bfa..3d3d5b2c63e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1214,6 +1214,12 @@ div.ficheaddleft { browser->layout != 'phone') { print "padding-".$left.": 16px;\n"; } else print "margin-top: 10px;\n"; ?> } +div.firstcolumn div.box { + padding-right: 10px; +} +div.secondcolumn div.box { + padding-left: 10px; +} /* Force values on one colum for small screen */ @media only screen and (max-width: 1000px) { @@ -1251,6 +1257,12 @@ div.ficheaddleft { margin-top: 10px; } + div.firstcolumn div.box { + padding-right: 0px; + } + div.secondcolumn div.box { + padding-left: 0px; + } } /* For table into table into card */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 545cce84f20..d53d47d1637 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1223,6 +1223,12 @@ div.ficheaddleft { browser->layout != 'phone') { print "padding-".$left.": 16px;\n"; } else print "margin-top: 10px;\n"; ?> } +div.firstcolumn div.box { + padding-right: 10px; +} +div.secondcolumn div.box { + padding-left: 10px; +} /* Force values on one colum for small screen */ @media only screen and (max-width: 900px) { @@ -1261,6 +1267,12 @@ div.ficheaddleft { margin-top: 10px; } + div.firstcolumn div.box { + padding-right: 0px; + } + div.secondcolumn div.box { + padding-left: 0px; + } } /* For table into table into card */ From ea24a8a7a78364e6741d13155a0c55515aef8e65 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 15:58:00 +0100 Subject: [PATCH 078/386] Add migration process for 8.0 into travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 10a2b6e8347..13ac2ae1d62 100644 --- a/.travis.yml +++ b/.travis.yml @@ -327,6 +327,9 @@ script: php upgrade.php 6.0.0 7.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade600700.log php upgrade2.php 6.0.0 7.0.0 MAIN_MODULE_WEBSITE,MAIN_MODULE_SUPPLIERPROPOSAL > $TRAVIS_BUILD_DIR/upgrade600700-2.log php step5.php 6.0.0 7.0.0 > $TRAVIS_BUILD_DIR/upgrade600700-3.log + php upgrade.php 7.0.0 8.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade700800.log + php upgrade2.php 7.0.0 8.0.0 MAIN_MODULE_WEBSITE,MAIN_MODULE_SUPPLIERPROPOSAL > $TRAVIS_BUILD_DIR/upgrade700800-2.log + php step5.php 7.0.0 8.0.0 > $TRAVIS_BUILD_DIR/upgrade700800-3.log cd - set +e echo From 8240b6b5f3f8edf9a032a6a2055a8804afe88e6f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 16:00:09 +0100 Subject: [PATCH 079/386] travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 13ac2ae1d62..b3e57791fc8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -328,7 +328,7 @@ script: php upgrade2.php 6.0.0 7.0.0 MAIN_MODULE_WEBSITE,MAIN_MODULE_SUPPLIERPROPOSAL > $TRAVIS_BUILD_DIR/upgrade600700-2.log php step5.php 6.0.0 7.0.0 > $TRAVIS_BUILD_DIR/upgrade600700-3.log php upgrade.php 7.0.0 8.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade700800.log - php upgrade2.php 7.0.0 8.0.0 MAIN_MODULE_WEBSITE,MAIN_MODULE_SUPPLIERPROPOSAL > $TRAVIS_BUILD_DIR/upgrade700800-2.log + php upgrade2.php 7.0.0 8.0.0 > $TRAVIS_BUILD_DIR/upgrade700800-2.log php step5.php 7.0.0 8.0.0 > $TRAVIS_BUILD_DIR/upgrade700800-3.log cd - set +e From 91bed7c01482a23bd4033ffdce8275bc9b43a2e8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 16:13:12 +0100 Subject: [PATCH 080/386] FIX #8079 --- htdocs/compta/bank/bankentries_list.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 380392c6805..78e95180dc5 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -924,6 +924,7 @@ if ($resql) $balance = 0; // For balance $balancecalculated = false; + $posconciliatecol = 0; // Loop on each record $sign = 1; @@ -1347,7 +1348,11 @@ if ($resql) } } print ''; - if (! $i) $totalarray['nbfield']++; + if (! $i) + { + $totalarray['nbfield']++; + $posconciliatecol = $totalarray['nbfield']; + } } if (! empty($arrayfields['b.conciliated']['checked'])) @@ -1430,6 +1435,12 @@ if ($resql) } elseif ($totalarray['totaldebfield'] == $i) print ''.price(-1 * $totalarray['totaldeb']).''; elseif ($totalarray['totalcredfield'] == $i) print ''.price($totalarray['totalcred']).''; + elseif ($i == $posconciliatecol) + { + print ''; + if ($user->rights->banque->consolidate && $action == 'reconcile') print ''; + print ''; + } else print ''; } print ''; From 490e0939269ffaf4d215a237e42bd9b7d350e414 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 16:41:50 +0100 Subject: [PATCH 081/386] Fix look and feel v7 --- htdocs/compta/bank/bankentries_list.php | 56 +++++++++++++++---------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 78e95180dc5..c6baf1c47f1 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -383,12 +383,14 @@ if (dol_strlen($search_dv_start) > 0) $param .= '&search_start_dvmonth=' . GETPO if (dol_strlen($search_dv_end) > 0) $param .= '&search_end_dvmonth=' . GETPOST('search_end_dvmonth', 'int') . '&search_end_dvday=' . GETPOST('search_end_dvday', 'int') . '&search_end_dvyear=' . GETPOST('search_end_dvyear', 'int'); if ($search_req_nb) $param.='&req_nb='.urlencode($search_req_nb); if (GETPOST("thirdparty")) $param.='&thirdparty='.urlencode(GETPOST("thirdparty")); -if ($optioncss != '') $param.='&optioncss='.$optioncss; +if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; $options = array(); +$buttonreconcile = ''; + if ($id > 0 || ! empty($ref)) { $title = $langs->trans("FinancialAccount").' - '.$langs->trans("Transactions"); @@ -420,18 +422,19 @@ if ($id > 0 || ! empty($ref)) if ($action != 'reconcile') { - print '
'; + //print '
'; - if ($object->canBeConciliated() > 0) { + if ($object->canBeConciliated() > 0) + { // If not cash account and can be reconciliate if ($user->rights->banque->consolidate) { - print ''.$langs->trans("Conciliate").''; + $buttonreconcile = ''.$langs->trans("Conciliate").''; } else { - print ''.$langs->trans("Conciliate").''; + $buttonreconcile = ''.$langs->trans("Conciliate").''; } } - print '
'; + //print '
'; } } else @@ -585,7 +588,7 @@ if ($resql) $nbmax=15; // We accept to show last 15 receipts (so we can have more than one year) $liste=""; $sql = "SELECT DISTINCT num_releve FROM ".MAIN_DB_PREFIX."bank"; - $sql.= " WHERE fk_account=".$id." AND num_releve IS NOT NULL"; + $sql.= " WHERE fk_account=".$object->id." AND num_releve IS NOT NULL"; $sql.= $db->order("num_releve","DESC"); $sql.= $db->plimit($nbmax+1); print '

'; @@ -614,17 +617,17 @@ if ($resql) { dol_print_error($db); } - /** - * Using BANK_REPORT_LAST_NUM_RELEVE to automatically report last num (or not) - */ - if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE == 1) { - print ' - - '; - } - print '

'; + + // Using BANK_REPORT_LAST_NUM_RELEVE to automatically report last num (or not) + if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE == 1) + { + print ' + + '; + } + print '

'; } // Form to add a transaction with no invoice @@ -721,11 +724,6 @@ if ($resql) // Title $bankcateg=new BankCateg($db); - $morehtml='
'; - $morehtml.= ' "; // ' Page '; - $morehtml.=''; - $morehtml.='/'.$nbtotalofpages.' '; - $morehtml.='
'; $addbutton = ''; if ($action != 'addline' && $action != 'reconcile') @@ -754,6 +752,18 @@ if ($resql) $addbutton = ''.$langs->trans("AddBankRecord").''; } } + + $morehtml='
'; + $morehtml.= ' "; // ' Page '; + $morehtml.=''; + $morehtml.='/'.$nbtotalofpages.' '; + $morehtml.='
'; + + if ($action != 'addline' && $action != 'reconcile') + { + $morehtml.=$buttonreconcile; + } + $morehtml.=$addbutton; $picto='title_bank'; From 493a9a72897e8d8cf0c8de29e17a1148cfc8e966 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 16:49:28 +0100 Subject: [PATCH 082/386] Fix td balance --- htdocs/compta/bank/bankentries_list.php | 2 +- htdocs/langs/en_US/errors.lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index c6baf1c47f1..692df2fcb22 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -1022,7 +1022,7 @@ if ($resql) print ''; print price(price2num($balance, 'MT'), 1, $langs); print ''; - print ''; + print ''; print ''; print ''; } diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index e51bdfc1be0..e4ecb9f5af8 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -73,7 +73,7 @@ ErrorLDAPSetupNotComplete=Dolibarr-LDAP matching is not complete. ErrorLDAPMakeManualTest=A .ldif file has been generated in directory %s. Try to load it manually from command line to have more information on errors. ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "statut not started" if field "done by" is also filled. ErrorRefAlreadyExists=Ref used for creation already exists. -ErrorPleaseTypeBankTransactionReportName=Please type bank statement name where entry is reported (Format YYYYMM or YYYYMMDD) +ErrorPleaseTypeBankTransactionReportName=Please ennter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD) ErrorRecordHasChildren=Failed to delete record since it has some childs. ErrorRecordHasAtLeastOneChildOfType=Object has at least one child of type %s ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into other object. From 0f519636008d0935b03489f55993baceb2bea032 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 19:00:13 +0100 Subject: [PATCH 083/386] NEW Externalsite module can accept iframe content. --- htdocs/externalsite/admin/externalsite.php | 11 +- htdocs/externalsite/frames.php | 127 ++++++++++++++------- htdocs/theme/eldy/style.css.php | 14 +++ htdocs/theme/md/style.css.php | 10 ++ 4 files changed, 120 insertions(+), 42 deletions(-) diff --git a/htdocs/externalsite/admin/externalsite.php b/htdocs/externalsite/admin/externalsite.php index 3d1fb6af478..6e234c1145f 100644 --- a/htdocs/externalsite/admin/externalsite.php +++ b/htdocs/externalsite/admin/externalsite.php @@ -26,6 +26,8 @@ * \brief Page de configuration du module externalsite */ +if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; @@ -50,7 +52,7 @@ if ($action == 'update') $db->begin(); $label = GETPOST('EXTERNALSITE_LABEL','alpha'); - $exturl = GETPOST('EXTERNALSITE_URL','alpha'); + $exturl = GETPOST('EXTERNALSITE_URL','none'); $i+=dolibarr_set_const($db,'EXTERNALSITE_LABEL',trim($label),'chaine',0,'',$conf->entity); $i+=dolibarr_set_const($db,'EXTERNALSITE_URL',trim($exturl),'chaine',0,'',$conf->entity); @@ -104,9 +106,12 @@ print ""; print ''; print ''.$langs->trans("ExternalSiteURL").""; -print "global->EXTERNALSITE_URL)?'':$conf->global->EXTERNALSITE_URL)) . "\" size=\"40\">"; +print ''; print "http://localhost/myurl/"; -print "
http://wikipedia.org/"; +print "
https://wikipedia.org/"; +print "
<iframe>...</iframe>"; print ""; print ""; diff --git a/htdocs/externalsite/frames.php b/htdocs/externalsite/frames.php index 6005b8e55b6..383bfb0228e 100644 --- a/htdocs/externalsite/frames.php +++ b/htdocs/externalsite/frames.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2004-2018 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,55 +17,104 @@ */ /** - * \file htdocs/externalsite/frames.php - * \ingroup externalsite - * \brief Page that build two frames: One for menu, the other for the target page to show - * \author Laurent Destailleur + * \file htdocs/externalsite/frames.php + * \ingroup externalsite + * \brief Page that build two frames: One for menu, the other for the target page to show + * Usage: + * mydomain.com/externalsite/frames.php to show URL set into setup + * mydomain.com/externalsite/frames.php?keyforcontent to show content defined into conf->global->$keyforcontent */ require '../main.inc.php'; $langs->load("externalsite"); -if (empty($conf->global->EXTERNALSITE_URL)) -{ - llxHeader(); - print '
'.$langs->trans('ExternalSiteModuleNotComplete').'
'; - llxFooter(); -} $mainmenu=GETPOST('mainmenu', "aZ09"); $leftmenu=GETPOST('leftmenu', "aZ09"); $idmenu=GETPOST('idmenu', 'int'); $theme=GETPOST('theme', 'alpha'); $codelang=GETPOST('lang', 'aZ09'); - -print " - - -Dolibarr frame for external web site - - -global->MAIN_MENU_INVERT)?"rows":"cols")."=\"".$heightforframes.",*\" border=0 framespacing=0 frameborder=0> - - global->EXTERNALSITE_URL."\"> - - <body> - - </body> - - - - -<body> - <br><div class=\"center\"> - Sorry, your browser is too old or not correctly configured to view this area.<br> - Your browser must support frames.<br> - </div> -</body> - - - -"; +$keyforcontent = GETPOST('keyforcontent', 'aZ09'); +/* + * View + */ + +if (empty($keyforcontent) && empty($conf->global->EXTERNALSITE_URL)) +{ + llxHeader(); + print '
'.$langs->trans('ExternalSiteModuleNotComplete').'
'; + llxFooter(); +} + +if (! empty($keyforcontent)) +{ + llxHeader(); + + print '
'; + + if (! preg_match('/EXTERNAL_SITE_CONTENT_/', $keyforcontent)) + { + $langs->load("errors"); + print $langs->trans("Variablekeyforcontentmustbenamed", 'EXTERNAL_SITE_CONTENT_'); + } + else if (empty($conf->global->$keyforcontent)) + { + $langs->load("errors"); + print $langs->trans("ErrorNoContentDefinedIntoVar", $keyforcontent); + } + else + { + print $conf->global->$keyforcontent; + } + + print '
'; + llxFooter(); +} +else +{ + if (preg_match('/^\//', $conf->global->EXTERNALSITE_URL) || preg_match('/^http/i', $conf->global->EXTERNALSITE_URL)) + { + print " + + + Dolibarr frame for external web site + + + global->MAIN_MENU_INVERT)?"rows":"cols")."=\"".$heightforframes.",*\" border=0 framespacing=0 frameborder=0> + + "; + print ''; + print " + + <body> + + </body> + + + + + <body> + <br><div class=\"center\"> + Sorry, your browser is too old or not correctly configured to view this area.<br> + Your browser must support frames.<br> + </div> + </body> + + + + "; + } + else + { + llxHeader(); + print '
'; + print $conf->global->EXTERNALSITE_URL; + print '
'; + llxFooter(); + } +} diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 95910558311..03d1ccdd8a7 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3206,6 +3206,20 @@ a.impayee:active { font-weight: bold; color: #550000; } a.impayee:hover { font-weight: bold; color: #550000; } +/* + * External web site + */ + +.framecontent { + width: 100%; + height: 100%; +} + +.framecontent iframe { + width: 100%; + height: 100%; +} + /* * Other diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 79d17292234..7f0a522eae5 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3265,6 +3265,16 @@ a.impayee:hover { font-weight: bold; color: #550000; } +/* + * External web site + */ + +.framecontent iframe { + width: 100%; + height: 100%; +} + + /* * Other */ From a7682eb59f098d68043f503dcfdd986ab08ac821 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 8 Feb 2018 21:01:34 +0100 Subject: [PATCH 084/386] CSS --- htdocs/theme/md/style.css.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 7f0a522eae5..c9a0a9239b2 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3269,12 +3269,18 @@ a.impayee:hover { font-weight: bold; color: #550000; } * External web site */ +.framecontent { + width: 100%; + height: 100%; +} + .framecontent iframe { width: 100%; height: 100%; } + /* * Other */ From 424fc4cd13067908c37dc5984291b191f5580ce6 Mon Sep 17 00:00:00 2001 From: Romain DESCHAMPS Date: Fri, 9 Feb 2018 09:11:47 +0100 Subject: [PATCH 085/386] add missing links in supplier card boxes --- htdocs/fourn/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 6096ff03f9f..453cb6068ad 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -325,7 +325,7 @@ if ($object->id > 0) $outstandingTotal=$tmp['total_ht']; $outstandingTotalIncTax=$tmp['total_ttc']; $text=$langs->trans("OverAllSupplierProposals"); - $link=''; + $link=DOL_URL_ROOT.'/supplier_proposal/list.php?socid='.$object->id; $icon='bill'; if ($link) $boxstat.=''; $boxstat.='
'; @@ -343,7 +343,7 @@ if ($object->id > 0) $outstandingTotal=$tmp['total_ht']; $outstandingTotalIncTax=$tmp['total_ttc']; $text=$langs->trans("OverAllOrders"); - $link=''; + $link=DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->id; $icon='bill'; if ($link) $boxstat.=''; $boxstat.='
'; @@ -361,7 +361,7 @@ if ($object->id > 0) $outstandingTotalIncTax=$tmp['total_ttc']; $text=$langs->trans("OverAllInvoices"); - $link=''; + $link=DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->id; $icon='bill'; if ($link) $boxstat.=''; $boxstat.='
'; From 207a4a8dc4934bb38faf33041d08caf09dd21036 Mon Sep 17 00:00:00 2001 From: Romain DESCHAMPS Date: Fri, 9 Feb 2018 09:14:34 +0100 Subject: [PATCH 086/386] add missing links in cust. card boxes --- htdocs/comm/card.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 6dfd05354d8..81443f04d62 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -568,7 +568,7 @@ if ($object->id > 0) $outstandingTotal=$tmp['total_ht']; $outstandingTotalIncTax=$tmp['total_ttc']; $text=$langs->trans("OverAllProposals"); - $link=''; + $link=DOL_URL_ROOT.'/comm/propal/list.php?socid='.$object->id; $icon='bill'; if ($link) $boxstat.=''; $boxstat.='
'; @@ -580,13 +580,13 @@ if ($object->id > 0) if (! empty($conf->commande->enabled)) { - // Box proposals + // Box commandes $tmp = $object->getOutstandingOrders(); $outstandingOpened=$tmp['opened']; $outstandingTotal=$tmp['total_ht']; $outstandingTotalIncTax=$tmp['total_ttc']; $text=$langs->trans("OverAllOrders"); - $link=''; + $link=DOL_URL_ROOT.'/commande/list.php?socid='.$object->id; $icon='bill'; if ($link) $boxstat.=''; $boxstat.='
'; @@ -598,12 +598,13 @@ if ($object->id > 0) if (! empty($conf->facture->enabled)) { + // Box factures $tmp = $object->getOutstandingBills(); $outstandingOpened=$tmp['opened']; $outstandingTotal=$tmp['total_ht']; $outstandingTotalIncTax=$tmp['total_ttc']; $text=$langs->trans("OverAllInvoices"); - $link=''; + $link=DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->id; $icon='bill'; if ($link) $boxstat.=''; $boxstat.='
'; From 6fb08dcc53b3f64c016a66909685487b1416eb7e Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Fri, 9 Feb 2018 11:50:33 +0100 Subject: [PATCH 087/386] NEW doActions on categorycard --- htdocs/categories/viewcat.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 1c6186d5df4..6d85b170bc7 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -66,13 +66,14 @@ $extrafields = new ExtraFields($db); $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array array -$hookmanager->initHooks(array('categorycard')); +$hookmanager->initHooks(array('categorycard','globalcard')); /* * Actions */ - +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks // Remove element from category if ($id > 0 && $removeelem > 0) { From a691dec90b6d72b14a1c7e8b07da4810ff03adb8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 9 Feb 2018 16:06:23 +0100 Subject: [PATCH 088/386] Fix lose validator user in edit --- htdocs/holiday/card.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index e3009c975bc..e626f950a2b 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -1180,6 +1180,7 @@ else print ''; } + // Validator if (!$edit) { print ''; print ''.$langs->trans('ReviewedByCP').''; @@ -1189,7 +1190,7 @@ else print ''; print ''.$langs->trans('ReviewedByCP').''; print ''; - print $form->select_dolusers($object->fk_user, "valideur", 1, ($user->admin ? '' : array($user->id))); // By default, hierarchical parent + print $form->select_dolusers($object->fk_validator, "valideur", 1, ($user->admin ? '' : array($user->id))); // By default, hierarchical parent print ''; print ''; } From eb8664e649f41c381540f03e44f42a748310ca70 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 9 Feb 2018 16:08:28 +0100 Subject: [PATCH 089/386] NEW Can export leave requests --- htdocs/core/menus/standard/eldy.lib.php | 4 +++- htdocs/core/modules/modHoliday.class.php | 22 ++++++++++++++++++++-- htdocs/exports/export.php | 6 ++++-- htdocs/langs/en_US/holiday.lang | 10 ++++++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index fed1cecdc23..5a44a3677fd 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -70,7 +70,9 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode else $classname = 'class="tmenu"'; $idsel='home'; - $menu->add('/index.php?mainmenu=home&leftmenu=home', $langs->trans("Home"), 0, $showmode, $atarget, "home", '', 10, $id, $idsel, $classname); + $titlehome = $langs->trans("Home"); + if (! empty($conf->global->THEME_TOPMENU_DISABLE_IMAGE)) $titlehome = '   '; + $menu->add('/index.php?mainmenu=home&leftmenu=home', $titlehome, 0, $showmode, $atarget, "home", '', 10, $id, $idsel, $classname); // Third parties $tmpentry=array('enabled'=>(( ! empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ! empty($conf->fournisseur->enabled)), 'perms'=>(! empty($user->rights->societe->lire) || ! empty($user->rights->fournisseur->lire)), 'module'=>'societe|fournisseur'); diff --git a/htdocs/core/modules/modHoliday.class.php b/htdocs/core/modules/modHoliday.class.php index 75bb6a04a07..aef9eb9a7bb 100644 --- a/htdocs/core/modules/modHoliday.class.php +++ b/htdocs/core/modules/modHoliday.class.php @@ -57,7 +57,7 @@ class modHoliday extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) - $this->description = "Leave management"; + $this->description = "Leave requests"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version $this->version = 'dolibarr'; // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) @@ -158,7 +158,25 @@ class modHoliday extends DolibarrModules // Exports - $r=1; + $r=0; + + $r++; + $this->export_code[$r]='leaverequest_'.$r; + $this->export_label[$r]='ListeCP'; + $this->export_icon[$r]='holiday'; + $this->export_permission[$r]=array(array("holiday","read_all")); + $this->export_fields_array[$r]=array('d.rowid'=>"LeaveId",'d.fk_type'=>'TypeOfLeaveId','t.code'=>'TypeOfLeaveCode','t.label'=>'TypeOfLeaveLabel','d.fk_user'=>'UserID','u.lastname'=>'Lastname','u.firstname'=>'Firstname','u.login'=>"Login",'d.date_debut'=>'DateStart','d.date_fin'=>'DateEnd','d.halfday'=>'HalfDay','d.date_valid'=>'DateApprove','d.fk_validator'=>"UserForApprovalID",'ua.lastname'=>"UserForApprovalLastname",'ua.firstname'=>"UserForApprovalFirstname",'ua.login'=>"UserForApprovalLogin",'d.description'=>'Description','d.statut'=>'Status'); + $this->export_entities_array[$r]=array('u.lastname'=>'user','u.firstname'=>'user','u.login'=>'user','ua.lastname'=>'user','ua.firstname'=>'user','ua.login'=>'user'); + $this->export_alias_array[$r]=array('d.rowid'=>"idholiday"); + $this->export_dependencies_array[$r]=array(); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'holiday as d'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_holiday_types as t ON t.rowid = d.fk_type'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua ON ua.rowid = d.fk_validator,'; + $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'user as u'; + $this->export_sql_end[$r] .=' WHERE d.fk_user = u.rowid'; + $this->export_sql_end[$r] .=' AND d.entity IN ('.getEntity('holiday').')'; // Example: // $this->export_code[$r]=$this->rights_class.'_'.$r; diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 92a63afcd0e..e76d8e113cf 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -69,8 +69,9 @@ $entitytoicon = array( 'category' => 'category', 'shipment' => 'sending', 'shipment_line'=> 'sending', - 'expensereport'=> 'trip', + 'expensereport'=> 'trip', 'expensereport_line'=> 'trip', + 'holiday' => 'holiday', 'contract_line' => 'contract', 'translation' => 'generic' ); @@ -115,7 +116,8 @@ $entitytolang = array( 'action' => 'Event', 'expensereport'=> 'ExpenseReport', 'expensereport_line'=> 'ExpenseReportLine', - 'contract' => 'Contract', + 'holiday' => 'TitreRequestCP', + 'contract' => 'Contract', 'contract_line'=> 'ContractLine', 'translation' => 'Translation' ); diff --git a/htdocs/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang index 0ed06cceb40..f73bbdeee52 100644 --- a/htdocs/langs/en_US/holiday.lang +++ b/htdocs/langs/en_US/holiday.lang @@ -16,7 +16,12 @@ CancelCP=Canceled RefuseCP=Refused ValidatorCP=Approbator ListeCP=List of leaves +LeaveId=Leave ID ReviewedByCP=Will be approved by +UserForApprovalID=User for approval ID +UserForApprovalFirstname=Firstname of approval user +UserForApprovalLastname=Lastname of approval user +UserForApprovalLogin=Login of approval user DescCP=Description SendRequestCP=Create leave request DelayToRequestCP=Leave requests must be made at least %s day(s) before them. @@ -30,6 +35,9 @@ ErrorUserViewCP=You are not authorized to read this leave request. InfosWorkflowCP=Information Workflow RequestByCP=Requested by TitreRequestCP=Leave request +TypeOfLeaveId=Type of leave ID +TypeOfLeaveCode=Type of leave code +TypeOfLeaveLabel=Type of leave label NbUseDaysCP=Number of days of vacation consumed EditCP=Edit DeleteCP=Delete @@ -81,6 +89,8 @@ EmployeeFirstname=Employee first name TypeWasDisabledOrRemoved=Leave type (id %s) was disabled or removed LastHolidays=Latest %s leave requests AllHolidays=All leave requests +HalfDay=Half day +NotTheAssignedApprover=You are not the assigned approver ## Configuration du Module ## LastUpdateCP=Latest automatic update of leaves allocation From 633dc507fe5150c25765b3ba60e6b0277bc6c0b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 9 Feb 2018 20:11:32 +0100 Subject: [PATCH 090/386] NEW Use a css style for weekend in time spent --- htdocs/core/lib/project.lib.php | 23 ++++++++-- htdocs/projet/activity/perday.php | 58 +++++++++++++++++++------- htdocs/projet/activity/perweek.php | 67 +++++++++++++++++++++--------- htdocs/theme/eldy/style.css.php | 5 +++ 4 files changed, 116 insertions(+), 37 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 7106657d417..67600a7ba3e 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -996,9 +996,19 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr elseif (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning '; elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon '; - // Duration - print ''; + global $daytoparse; + $tmparray = dol_getdate($daytoparse,true); // detail of current day + $idw = $tmparray['wday']; + global $numstartworkingday, $numendworkingday; + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + // Duration + print ''; $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id]; $totalforeachday[$preselectedday]+=$dayWorkLoad; @@ -1280,7 +1290,14 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); - $tableCell =''; + global $numstartworkingday, $numendworkingday; + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + $tableCell =''; if ($alreadyspent) { $tableCell.=''; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index f30b0ac4757..dd3aa856817 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -365,7 +365,6 @@ $nav.=' id > 0 ? '?id='.$project->id : '').'">'; print ''; print ''; @@ -482,23 +481,43 @@ if ($usertoprocess->id == $user->id) print ''.$langs->trans("TimeSpentByUser").'';*/ print ''.$langs->trans("TimeSpent").'
('.$langs->trans("Everybody").')'; print ''.$langs->trans("TimeSpent").($usertoprocess->firstname?'
('.$usertoprocess->firstname.')':'').''; -print ''.$langs->trans("HourStart").''; -print ''.$langs->trans("Duration").''; -print ''.$langs->trans("Note").''; -print ''; -print "\n"; - +print ''.$langs->trans("HourStart").''; // By default, we can edit only tasks we are assigned to $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)?1:0); // Get if user is available or not for each day $holiday = new Holiday($db); + $isavailable=array(); +if (! empty($conf->global->MAIN_DEFAULT_WORKING_DAYS)) +{ + $tmparray=explode('-', $conf->global->MAIN_DEFAULT_WORKING_DAYS); + if (count($tmparray) >= 2) + { + $numstartworkingday = $tmparray[0]; + $numendworkingday = $tmparray[1]; + } +} $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse); // $daytoparse is a date with hours = 0 $isavailable[$daytoparse]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day +$tmparray = dol_getdate($daytoparse,true); // detail of current day +$idw = $tmparray['wday']; + +$cssweekend=''; +if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. +{ + $cssweekend='weekend'; +} + +print ''.$langs->trans("Duration").''; +print ''.$langs->trans("Note").''; +print ''; +print "\n"; + + if (count($tasksarray) > 0) { //var_dump($tasksarray); // contains only selected tasks @@ -571,13 +590,24 @@ if (count($tasksarray) > 0) if ($conf->use_javascript_ajax) { - print ' - '; - print $langs->trans("Total"); - //print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; - print ' -
 
- + print ''; + print ''; + print $langs->trans("Total"); + //print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; + print ''; + + $tmparray = dol_getdate($daytoparse,true); // detail of current day + $idw = $tmparray['wday']; + + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + print '
 
'; + + print ' '; } diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index a3c8c9ebe54..ba0e773d114 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -461,7 +461,7 @@ print ''; print ''; print ''; print ''; -for($i=0;$i<7;$i++) +for($idw=0;$idw<7;$idw++) { print ''; } @@ -489,12 +489,22 @@ $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['fi // Get if user is available or not for each day $holiday = new Holiday($db); -$isavailable=array(); -for ($i=0;$i<7;$i++) +$isavailable=array(); +if (! empty($conf->global->MAIN_DEFAULT_WORKING_DAYS)) { - $dayinloopfromfirstdaytoshow = dol_time_plus_duree($firstdaytoshow, $i, 'd'); // $firstdaytoshow is a date with hours = 0 - $dayinloop = dol_time_plus_duree($startday, $i, 'd'); + $tmparray=explode('-', $conf->global->MAIN_DEFAULT_WORKING_DAYS); + if (count($tmparray) >= 2) + { + $numstartworkingday = $tmparray[0]; + $numendworkingday = $tmparray[1]; + } +} + +for ($idw=0; $idw<7; $idw++) +{ + $dayinloopfromfirstdaytoshow = dol_time_plus_duree($firstdaytoshow, $idw, 'd'); // $firstdaytoshow is a date with hours = 0 + $dayinloop = dol_time_plus_duree($startday, $idw, 'd'); // Useless because $dayinloopwithouthours should be same than $dayinloopfromfirstdaytoshow //$tmparray = dol_getdate($dayinloop); @@ -505,7 +515,14 @@ for ($i=0;$i<7;$i++) $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $dayinloopfromfirstdaytoshow); $isavailable[$dayinloopfromfirstdaytoshow]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day - print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; + + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; } print ''; print "\n"; @@ -578,7 +595,13 @@ if (count($tasksarray) > 0) print ''; for ($idw = 0; $idw < 7; $idw++) { - print ''; + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + print ''; $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); $timeonothertasks=($totalforeachday[$tmpday] - $totalforvisibletasks[$tmpday]); if ($timeonothertasks) @@ -599,15 +622,19 @@ if (count($tasksarray) > 0) '; print $langs->trans("Total"); print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; - print ' -
 
-
 
-
 
-
 
-
 
-
 
-
 
- + print ''; + + for ($idw = 0; $idw < 7; $idw++) + { + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + print '
 
'; + } + print ' '; } } @@ -642,11 +669,11 @@ if ($conf->use_javascript_ajax) } });'."\n"; - $i=0; - while ($i < 7) + $idw=0; + while ($idw < 7) { - print ' updateTotal('.$i.',\''.$modeinput.'\');'; - $i++; + print ' updateTotal('.$idw.',\''.$modeinput.'\');'; + $idw++; } print "\n});\n"; print ''; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 03d1ccdd8a7..eea9a06f16f 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -388,18 +388,23 @@ input.buttonpaymentstripe { background-repeat: no-repeat; background-position: 8px 11px; } + /* Used by timesheets */ span.timesheetalreadyrecorded input { border: none; border-bottom: solid 1px rgba(0,0,0,0.4); margin-right: 1px !important; } +td.weekend { + background-color: #eee; +} td.onholidaymorning, td.onholidayafternoon { background-color: #fdf6f2; } td.onholidayallday { background-color: #f4eede; } + td.actionbuttons a { padding-left: 6px; } From e984d7df9f074dd0c84a9bb3b73965441920620c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 9 Feb 2018 23:52:43 +0100 Subject: [PATCH 091/386] NEW Add total of time spent in timespent page at top of page too. --- htdocs/core/js/timesheet.js | 16 ++++++------- htdocs/core/lib/project.lib.php | 4 ++-- htdocs/langs/en_US/projects.lang | 4 ++-- htdocs/projet/activity/perday.php | 36 +++++++++++++++++++++++----- htdocs/projet/activity/perweek.php | 38 ++++++++++++++++++++++++------ htdocs/theme/eldy/style.css.php | 6 +++++ htdocs/theme/md/style.css.php | 7 ++++++ 7 files changed, 85 insertions(+), 26 deletions(-) diff --git a/htdocs/core/js/timesheet.js b/htdocs/core/js/timesheet.js index ba3f8b2edd1..20a713ce220 100644 --- a/htdocs/core/js/timesheet.js +++ b/htdocs/core/js/timesheet.js @@ -213,11 +213,9 @@ function updateTotal(days,mode) } }); - if (document.getElementById('totalDay['+days+']')) // May be null if no task records to output (nbline is also 0 in this case) - { - document.getElementById('totalDay['+days+']').innerHTML = pad(total.getHours())+':'+pad(total.getMinutes()); - //addText(,total.getHours()+':'+total.getMinutes()); - } + if (total.getHours() || total.getMinutes()) jQuery('.totalDay'+days).addClass("bold"); + else jQuery('.totalDay'+days).removeClass("bold"); + jQuery('.totalDay'+days).text(pad(total.getHours())+':'+pad(total.getMinutes())); } else { @@ -257,10 +255,10 @@ function updateTotal(days,mode) } } } - if (document.getElementById('totalDay['+days+']')) // May be null if no task records to output (nbline is also 0 in this case) - { - document.getElementById('totalDay['+days+']').innerHTML = total; - } + + if (total) jQuery('.totalDay'+days).addClass("bold"); + else jQuery('.totalDay'+days).removeClass("bold"); + jQuery('.totalDay'+days).text(total); } } diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 67600a7ba3e..49474d1e190 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -940,7 +940,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print "\n"; // Planned Workload - print ''; + print ''; if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin'); else print '--:--'; print ''; @@ -1224,7 +1224,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ print "\n"; // Planned Workload - print ''; + print ''; if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin'); else print '--:--'; print ''; diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 86d09ff3edc..ab044618556 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -10,13 +10,13 @@ PrivateProject=Project contacts ProjectsImContactFor=Projects I'm explicitely a contact of AllAllowedProjects=All project I can read (mine + public) AllProjects=All projects -MyProjectsDesc=This view is limited to projects you are a contact for. +MyProjectsDesc=This view is limited to projects you are a contact for ProjectsPublicDesc=This view presents all projects you are allowed to read. TasksOnProjectsPublicDesc=This view presents all tasks on projects you are allowed to read. ProjectsPublicTaskDesc=This view presents all projects and tasks you are allowed to read. ProjectsDesc=This view presents all projects (your user permissions grant you permission to view everything). TasksOnProjectsDesc=This view presents all tasks on all projects (your user permissions grant you permission to view everything). -MyTasksDesc=This view is limited to projects or tasks you are a contact for. +MyTasksDesc=This view is limited to projects or tasks you are a contact for OnlyOpenedProject=Only open projects are visible (projects in draft or closed status are not visible). ClosedProjectsAreHidden=Closed projects are not visible. TasksPublicDesc=This view presents all projects and tasks you are allowed to read. diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index dd3aa856817..8475b607de6 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -345,7 +345,7 @@ $tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($proj llxHeader("",$title,"",'','','',array('/core/js/timesheet.js')); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); +//print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); $param=''; $param.=($mode?'&mode='.$mode:''); @@ -375,7 +375,7 @@ print ''; print ''; $head=project_timesheet_prepare_head($mode, $usertoprocess); -dol_fiche_head($head, 'inputperday', '', -1, 'task'); +dol_fiche_head($head, 'inputperday', $langs->trans('TimeSpent'), -1, 'task'); // Show description of content print '
'; @@ -474,7 +474,7 @@ print ''.$langs->trans("Project").''; print ''.$langs->trans("ThirdParty").''; //print ''.$langs->trans("RefTask").''; print ''.$langs->trans("Task").''; -print ''.$langs->trans("PlannedWorkload").''; +print ''.$langs->trans("PlannedWorkload").''; print ''.$langs->trans("ProgressDeclared").''; /*print ''.$langs->trans("TimeSpent").''; if ($usertoprocess->id == $user->id) print ''.$langs->trans("TimeSpentByYou").''; @@ -517,6 +517,32 @@ print ''.$langs->trans("Note").''; print ''; print "\n"; +$colspan = 8; + +if ($conf->use_javascript_ajax) +{ + print ''; + print ''; + print $langs->trans("Total"); + //print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; + print ''; + + $tmparray = dol_getdate($daytoparse,true); // detail of current day + $idw = $tmparray['wday']; + + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + print '
 
'; + + print ' + + '; +} + if (count($tasksarray) > 0) { @@ -565,8 +591,6 @@ if (count($tasksarray) > 0) } } - $colspan = 8; - // There is a diff between total shown on screen and total spent by user, so we add a line with all other cumulated time of user if ($isdiff) { @@ -605,7 +629,7 @@ if (count($tasksarray) > 0) $cssweekend='weekend'; } - print '
 
'; + print '
 
'; print ' diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index ba0e773d114..c3c4efa836f 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -347,7 +347,7 @@ $tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($proj llxHeader("",$title,"",'','','',array('/core/js/timesheet.js')); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); +//print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); $param=''; $param.=($mode?'&mode='.$mode:''); @@ -376,7 +376,7 @@ print ''; print ''; $head=project_timesheet_prepare_head($mode, $usertoprocess); -dol_fiche_head($head, 'inputperweek', '', -1, 'task'); +dol_fiche_head($head, 'inputperweek', $langs->trans('TimeSpent'), -1, 'task'); // Show description of content print '
'; @@ -477,7 +477,7 @@ print ''.$langs->trans("Project").''; print ''.$langs->trans("ThirdParty").''; //print ''.$langs->trans("RefTask").''; print ''.$langs->trans("Task").''; -print ''.$langs->trans("PlannedWorkload").''; +print ''.$langs->trans("PlannedWorkload").''; print ''.$langs->trans("ProgressDeclared").''; /*print ''.$langs->trans("TimeSpent").''; if ($usertoprocess->id == $user->id) print ''.$langs->trans("TimeSpentByYou").''; @@ -522,11 +522,37 @@ for ($idw=0; $idw<7; $idw++) $cssweekend='weekend'; } - print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; + print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; } print ''; print "\n"; +$colspan=7; + +if ($conf->use_javascript_ajax) +{ + print ' + '; + print $langs->trans("Total"); + print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; + print ''; + + for ($idw = 0; $idw < 7; $idw++) + { + $cssweekend=''; + if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + { + $cssweekend='weekend'; + } + + print '
 
'; + } + print ' + '; +} + + + // By default, we can edit only tasks we are assigned to $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)?1:0); @@ -584,8 +610,6 @@ if (count($tasksarray) > 0) } } - $colspan=7; - // There is a diff between total shown on screen and total spent by user, so we add a line with all other cumulated time of user if ($isdiff) { @@ -632,7 +656,7 @@ if (count($tasksarray) > 0) $cssweekend='weekend'; } - print '
 
'; + print '
 
'; } print ' '; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index eea9a06f16f..e7f50732cd4 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -404,6 +404,9 @@ td.onholidaymorning, td.onholidayafternoon { td.onholidayallday { background-color: #f4eede; } +td.leftborder, td.hide0 { + border-left: 1px solid #ccc; +} td.actionbuttons a { padding-left: 6px; @@ -597,6 +600,9 @@ textarea.centpercent { .wordbreak { word-break: break-all; } +.bold { + font-weight: bold !important; +} .nobold { font-weight: normal !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c9a0a9239b2..869654cc0cd 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -408,6 +408,10 @@ td.onholidayallday { td.actionbuttons a { padding-left: 6px; } +td.leftborder, td.hide0 { + border-left: 1px solid #ccc; +} + select.flat, form.flat select { font-weight: normal; font-size: unset; @@ -594,6 +598,9 @@ textarea.centpercent { .wordbreak { word-break: break-all; } +.bold { + font-weight: bold !important; +} .nobold { font-weight: normal !important; } From 2315997aada1cf4657064923ad6d9d95f20b6230 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Feb 2018 00:00:12 +0100 Subject: [PATCH 092/386] CSS enhancement --- htdocs/core/lib/project.lib.php | 2 +- htdocs/projet/activity/perday.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 49474d1e190..9070cb307f7 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -986,7 +986,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr } // Form to add new time - print ''; + print ''; $tableCell=$form->select_date($preselectedday,$lines[$i]->id,1,1,2,"addtime",0,0,1,$disabledtask); print $tableCell; print ''; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 8475b607de6..ef671f2c7e5 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -481,7 +481,7 @@ if ($usertoprocess->id == $user->id) print ''.$langs->trans("TimeSpentByUser").'';*/ print ''.$langs->trans("TimeSpent").'
('.$langs->trans("Everybody").')'; print ''.$langs->trans("TimeSpent").($usertoprocess->firstname?'
('.$usertoprocess->firstname.')':'').''; -print ''.$langs->trans("HourStart").''; +print ''.$langs->trans("HourStart").''; // By default, we can edit only tasks we are assigned to $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)?1:0); From 01f09e6c091a989337be6a5d679a0f5234f9e26d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Feb 2018 00:04:05 +0100 Subject: [PATCH 093/386] CSS enhancement --- htdocs/projet/activity/perday.php | 12 ++++++------ htdocs/projet/activity/perweek.php | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index ef671f2c7e5..6a556fcae3f 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -507,10 +507,10 @@ $tmparray = dol_getdate($daytoparse,true); // detail of current day $idw = $tmparray['wday']; $cssweekend=''; -if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. +/*if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. { $cssweekend='weekend'; -} +}*/ print ''.$langs->trans("Duration").''; print ''.$langs->trans("Note").''; @@ -531,10 +531,10 @@ if ($conf->use_javascript_ajax) $idw = $tmparray['wday']; $cssweekend=''; - if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + /*if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. { $cssweekend='weekend'; - } + }*/ print '
 
'; @@ -624,10 +624,10 @@ if (count($tasksarray) > 0) $idw = $tmparray['wday']; $cssweekend=''; - if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + /*if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. { $cssweekend='weekend'; - } + }*/ print '
 
'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index c3c4efa836f..d64a5fad6cd 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -540,10 +540,10 @@ if ($conf->use_javascript_ajax) for ($idw = 0; $idw < 7; $idw++) { $cssweekend=''; - if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + /*if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. { $cssweekend='weekend'; - } + }*/ print '
 
'; } @@ -651,10 +651,10 @@ if (count($tasksarray) > 0) for ($idw = 0; $idw < 7; $idw++) { $cssweekend=''; - if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. + /*if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. { $cssweekend='weekend'; - } + }*/ print '
 
'; } From 74116f495eff43f3305441735e64035383913647 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Feb 2018 00:05:04 +0100 Subject: [PATCH 094/386] CSS enhancement --- htdocs/projet/activity/perday.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 6a556fcae3f..85848eefedc 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -507,10 +507,10 @@ $tmparray = dol_getdate($daytoparse,true); // detail of current day $idw = $tmparray['wday']; $cssweekend=''; -/*if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. +if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday) // This is a day is not inside the setup of working days, so we use a week-end css. { $cssweekend='weekend'; -}*/ +} print ''.$langs->trans("Duration").''; print ''.$langs->trans("Note").''; From ec66bde3c9910a0104cbe34701abe55774e89326 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Feb 2018 12:15:24 +0100 Subject: [PATCH 095/386] Add option WEBSITE_USE_WEBSITE_ACCOUNTS --- htdocs/admin/website.php | 21 ++++++++++++++++++++- htdocs/core/lib/company.lib.php | 2 +- htdocs/langs/en_US/website.lang | 2 ++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index 9811052509a..54a91d6ee92 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -401,6 +401,23 @@ $titre=$langs->trans("WebsiteSetup"); $linkback='
'.$langs->trans("BackToModuleList").''; print load_fiche_titre($titre,$linkback,'title_setup'); +// Onglets +$head=array(); +$h = 0; + +$head[$h][0] = DOL_URL_ROOT."/admin/website.php"; +$head[$h][1] = $langs->trans("WebSites"); +$head[$h][2] = 'website'; +$h++; + +$head[$h][0] = DOL_URL_ROOT."/admin/website_options.php"; +$head[$h][1] = $langs->trans("Options"); +$head[$h][2] = 'options'; +$h++; + +dol_fiche_head($head, 'website', '', -1); + + print $langs->trans("WebsiteSetupDesc").'
'; print "
\n"; @@ -648,7 +665,9 @@ if ($id) } } -print '
'; +dol_fiche_end(); + +//print '
'; llxFooter(); diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 4f1726a45c6..d3b242840ae 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -206,7 +206,7 @@ function societe_prepare_head(Societe $object) $h++; } - if (! empty($conf->website->enabled) && (!empty($user->rights->societe->lire) )) + if (! empty($conf->website->enabled) && (! empty($conf->global->WEBSITE_USE_WEBSITE_ACCOUNTS)) && (!empty($user->rights->societe->lire))) { $head[$h][0] = DOL_URL_ROOT.'/societe/website.php?id='.$object->id; $head[$h][1] = $langs->trans("WebSiteAccounts"); diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index a329661a056..c7cdd65ff4e 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -64,3 +64,5 @@ BackToListOfThirdParty=Back to list for Third Party DisableSiteFirst=Disable website first MyContainerTitle=My web site title AnotherContainer=Another container +WEBSITE_USE_WEBSITE_ACCOUNTS=Enable the web site account table +WEBSITE_USE_WEBSITE_ACCOUNTSTooltip=Enable the table to store web site accounts (login/pass) for each website / thirdparty \ No newline at end of file From e25bd56e22bae24f2e1933e56fb5aa113f70128f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 10 Feb 2018 12:16:06 +0100 Subject: [PATCH 096/386] Add option WEBSITE_USE_WEBSITE_ACCOUNTS --- htdocs/admin/website_options.php | 153 +++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 htdocs/admin/website_options.php diff --git a/htdocs/admin/website_options.php b/htdocs/admin/website_options.php new file mode 100644 index 00000000000..e54f19dc8c9 --- /dev/null +++ b/htdocs/admin/website_options.php @@ -0,0 +1,153 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/website.php + * \ingroup setup + * \brief Page to administer web sites + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; +require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; + +$langs->load("errors"); +$langs->load("admin"); +$langs->load("companies"); +$langs->load("website"); + +$action=GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; +$confirm=GETPOST('confirm','alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$rowid=GETPOST('rowid','alpha'); + +if (!$user->admin) accessforbidden(); + +$status = 1; + +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('admin')); + +$arrayofparameters=array('WEBSITE_USE_WEBSITE_ACCOUNTS'=>array('css'=>'minwidth200')); + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + + +/* + * View + */ + +$form = new Form($db); +$formadmin=new FormAdmin($db); + +llxHeader('', $langs->trans("WebsiteSetup")); + +$titre=$langs->trans("WebsiteSetup"); +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($titre,$linkback,'title_setup'); + +// Onglets +$head=array(); +$h = 0; + +$head[$h][0] = DOL_URL_ROOT."/admin/website.php"; +$head[$h][1] = $langs->trans("WebSites"); +$head[$h][2] = 'website'; +$h++; + +$head[$h][0] = DOL_URL_ROOT."/admin/website_options.php"; +$head[$h][1] = $langs->trans("Options"); +$head[$h][2] = 'options'; +$h++; + +dol_fiche_head($head, 'options', '', -1); + + +if ($action == 'edit') +{ + print '
'; + print ''; + print ''; + + print ''; + print ''; + + foreach($arrayofparameters as $key => $val) + { + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip')); + print '
'; + + print '
'; + print ''; + print '
'; + + print '
'; + print '
'; +} +else +{ + print ''; + print ''; + + foreach($arrayofparameters as $key => $val) + { + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip')); + print '' . $conf->global->$key . '
'; + + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; +} + + +dol_fiche_end(); +//print '
'; + + +llxFooter(); +$db->close(); + From b48d369258fea70f62f7956a0887bb14be2595cc Mon Sep 17 00:00:00 2001 From: Ysandor Date: Sat, 10 Feb 2018 20:38:53 +0100 Subject: [PATCH 097/386] add the possibility to remove a category from a thirdparty I don't know if there is a good reason for not proposing to unlink a thirdparty from a category but if it is not the case here is a piece of code allowing to remove a category that works for me and seems general enough to be useful to other people. The new function is inspired from the addCategory function. PS : This is the first time i'm trying to contribute on github so don't hesitate to tell me if I did something wrong. --- .../societe/class/api_thirdparties.class.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 7326d99e2b7..6910f5d6dc3 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -552,7 +552,45 @@ class Thirdparties extends DolibarrApi return $this->company; } + /** + * Delete category to a thirdparty + * + * @param int $id Id of thirdparty + * @param array $request_data Request datas + * + * @return mixed + * + * @url POST {id}/deleteCategory + */ + function deleteCategory($id, $request_data = NULL) { + if (!isset($request_data["category_id"])) + throw new RestException(400, "category_id field missing"); + $category_id = $request_data["category_id"]; + if(! DolibarrApiAccess::$user->rights->societe->creer) { + throw new RestException(401); + } + + $result = $this->company->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Thirdparty not found'); + } + $category = new Categorie($this->db); + $result = $category->fetch($category_id); + if( ! $result ) { + throw new RestException(404, 'category not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('societe',$this->company->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + if( ! DolibarrApi::_checkAccessToResource('category',$category->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $category->del_type($this->company,'customer'); + return $this->company; + } /** * Get outstanding proposals of thirdparty From 1300f7172f44e25e6b7b0821e562ae28e421a02a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 02:05:14 +0100 Subject: [PATCH 098/386] NEW Can fix the bank account of a payment if payment not conciliated --- htdocs/compta/bank/ligne.php | 56 +++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 33621d4b9a9..f6740ed6fda 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -62,6 +62,7 @@ if (! $user->rights->banque->lire && ! $user->rights->banque->consolidate) acces /* * Actions */ + if ($cancel) { if ($backtopage) @@ -108,10 +109,23 @@ if ($user->rights->banque->modifier && $action == "update") { $error=0; - $ac = new Account($db); - $ac->fetch($id); + $acline = new AccountLine($db); + $acline->fetch($rowid); - if ($ac->courant == Account::TYPE_CASH && $_POST['value'] != 'LIQ') + $acsource = new Account($db); + $acsource->fetch($id); + + $actarget = new Account($db); + if (GETPOST('accountid','int') > 0 && ! $acline->rappro && ! $acline->getVentilExportCompta()) // We ask to change bank account + { + $actarget->fetch(GETPOST('accountid','int')); + } + else + { + $actarget->fetch($id); + } + + if ($actarget->courant == Account::TYPE_CASH && GETPOST('value','alpha') != 'LIQ') { setEventMessages($langs->trans("ErrorCashAccountAcceptsOnlyCashMoney"), null, 'errors'); $error++; @@ -119,16 +133,6 @@ if ($user->rights->banque->modifier && $action == "update") if (! $error) { - // Avant de modifier la date ou le montant, on controle si ce n'est pas encore rapproche - $conciliated=0; - $sql = "SELECT b.rappro FROM ".MAIN_DB_PREFIX."bank as b WHERE rowid=".$rowid; - $result = $db->query($sql); - if ($result) - { - $objp = $db->fetch_object($result); - $conciliated=$objp->rappro; - } - $db->begin(); $amount = price2num($_POST['amount']); @@ -142,15 +146,15 @@ if ($user->rights->banque->modifier && $action == "update") if (isset($_POST['banque'])) $sql.=" banque='".$db->escape($_POST["banque"])."',"; if (isset($_POST['emetteur'])) $sql.=" emetteur='".$db->escape($_POST["emetteur"])."',"; // Blocked when conciliated - if (! $conciliated) + if (! $acline->rappro) { if (isset($_POST['label'])) $sql.=" label='".$db->escape($_POST["label"])."',"; if (isset($_POST['amount'])) $sql.=" amount='".$amount."',"; if (isset($_POST['dateomonth'])) $sql.=" dateo = '".$db->idate($dateop)."',"; if (isset($_POST['datevmonth'])) $sql.=" datev = '".$db->idate($dateval)."',"; } - $sql.= " fk_account = ".$id; - $sql.= " WHERE rowid = ".$rowid; + $sql.= " fk_account = ".$actarget->id; + $sql.= " WHERE rowid = ".$acline->id; $result = $db->query($sql); if (! $result) @@ -282,7 +286,7 @@ if ($result) $account = $acct->id; $bankline = new AccountLine($db); - $bankline->fetch($rowid,$ref); + $bankline->fetch($rowid, $ref); $links=$acct->get_url($rowid); $bankline->load_previous_next_ref('','rowid'); @@ -311,21 +315,19 @@ if ($result) print '
'; print ''; - // Ref - /* - print '"; - print ''; - print ''; - */ - $i++; // Bank account print ''; print ''; print ''; From f637269a270cc3627c033998d5a8bd582f7dfb44 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 04:05:13 +0100 Subject: [PATCH 099/386] Fix bad list of id for supplier categories --- htdocs/categories/class/categorie.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 5658460927c..46063c0f8c4 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -896,10 +896,14 @@ class Categorie extends CommonObject $sub_type = $type; $subcol_name = "fk_".$type; - if ($type=="customer" || $type=="supplier") { + if ($type=="customer") { $sub_type="societe"; $subcol_name="fk_soc"; } + if ($type=="supplier") { + $sub_type="fournisseur"; + $subcol_name="fk_soc"; + } if ($type=="contact") { $subcol_name="fk_socpeople"; } From aaf4db2e034012133c82415c29a2fb93f9e5a1ba Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 12 Feb 2018 04:05:51 +0100 Subject: [PATCH 100/386] Fix API on thirdparty categories --- .../societe/class/api_thirdparties.class.php | 177 +++++++++++++++--- 1 file changed, 150 insertions(+), 27 deletions(-) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 6910f5d6dc3..58e96d015b2 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -90,7 +90,7 @@ class Thirdparties extends DolibarrApi $this->company->absolute_discount = price2num($absolute_discount, 'MT'); $this->company->absolute_creditnote = price2num($absolute_creditnote, 'MT'); - return $this->_cleanObjectDatas($this->company); + return $this->_cleanObjectDatas($this->company); } /** @@ -238,7 +238,7 @@ class Thirdparties extends DolibarrApi } if($this->company->update($id, DolibarrApiAccess::$user,1,'','','update')) - return $this->get ($id); + return $this->get($id); return false; } @@ -479,7 +479,7 @@ class Thirdparties extends DolibarrApi } /** - * Get categories for a thirdparty + * Get customer categories for a thirdparty * * @param int $id ID of thirdparty * @param string $sortfield Sort field @@ -497,36 +497,41 @@ class Thirdparties extends DolibarrApi throw new RestException(401); } + $result = $this->company->fetch($id); + if( ! $result ) + { + throw new RestException(404, 'Thirdparty not found'); + } + $categories = new Categorie($this->db); $result = $categories->getListForItem($id, 'customer', $sortfield, $sortorder, $limit, $page); - if (empty($result)) { - throw new RestException(404, 'No category found'); + if (is_numeric($result) && $result < 0) + { + throw new RestException(503, 'Error when retrieve category list : '.$categories->error); } - if ($result < 0) { - throw new RestException(503, 'Error when retrieve category list : '.$categories->error); + if (is_numeric($result) && $result == 0) // To fix a return of 0 instead of empty array of method getListForItem + { + return array(); } return $result; } /** - * Add category to a thirdparty + * Add a customer category to a thirdparty * - * @param int $id Id of thirdparty - * @param array $request_data Request datas + * @param int $id Id of thirdparty + * @param int $category_id Id of category * * @return mixed * - * @url POST {id}/addCategory + * @url POST {id}/categories/{category_id} */ - function addCategory($id, $request_data = NULL) { - if (!isset($request_data["category_id"])) - throw new RestException(400, "category_id field missing"); - $category_id = $request_data["category_id"]; - + function addCategory($id, $category_id) + { if(! DolibarrApiAccess::$user->rights->societe->creer) { throw new RestException(401); } @@ -549,24 +554,22 @@ class Thirdparties extends DolibarrApi } $category->add_type($this->company,'customer'); - return $this->company; + + return $this->_cleanObjectDatas($this->company); } /** - * Delete category to a thirdparty + * Remove the link between a customer category and the thirdparty * - * @param int $id Id of thirdparty - * @param array $request_data Request datas + * @param int $id Id of thirdparty + * @param int $category_id Id of category * * @return mixed * - * @url POST {id}/deleteCategory + * @url DELETE {id}/categories/{category_id} */ - function deleteCategory($id, $request_data = NULL) { - if (!isset($request_data["category_id"])) - throw new RestException(400, "category_id field missing"); - $category_id = $request_data["category_id"]; - + function deleteCategory($id, $category_id) + { if(! DolibarrApiAccess::$user->rights->societe->creer) { throw new RestException(401); } @@ -589,9 +592,129 @@ class Thirdparties extends DolibarrApi } $category->del_type($this->company,'customer'); - return $this->company; + + return $this->_cleanObjectDatas($this->company); } + /** + * Get supplier categories for a thirdparty + * + * @param int $id ID of thirdparty + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * + * @return mixed + * + * @url GET {id}/supplier_categories + */ + function getSupplierCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) + { + if (! DolibarrApiAccess::$user->rights->categorie->lire) { + throw new RestException(401); + } + + $result = $this->company->fetch($id); + if( ! $result ) + { + throw new RestException(404, 'Thirdparty not found'); + } + + $categories = new Categorie($this->db); + + $result = $categories->getListForItem($id, 'supplier', $sortfield, $sortorder, $limit, $page); + + if (is_numeric($result) && $result < 0) + { + throw new RestException(503, 'Error when retrieve category list : '.$categories->error); + } + + if (is_numeric($result) && $result == 0) // To fix a return of 0 instead of empty array of method getListForItem + { + return array(); + } + + return $result; + } + + /** + * Add a supplier category to a thirdparty + * + * @param int $id Id of thirdparty + * @param int $category_id Id of category + * + * @return mixed + * + * @url POST {id}/supplier_categories/{category_id} + */ + function addSupplierCategory($id, $category_id) + { + if(! DolibarrApiAccess::$user->rights->societe->creer) { + throw new RestException(401); + } + + $result = $this->company->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Thirdparty not found'); + } + $category = new Categorie($this->db); + $result = $category->fetch($category_id); + if( ! $result ) { + throw new RestException(404, 'category not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('societe',$this->company->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + if( ! DolibarrApi::_checkAccessToResource('category',$category->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $category->add_type($this->company,'supplier'); + + return $this->_cleanObjectDatas($this->company); + } + + /** + * Remove the link between a category and the thirdparty + * + * @param int $id Id of thirdparty + * @param int $category_id Id of category + * + * @return mixed + * + * @url DELETE {id}/supplier_categories/{category_id} + */ + function deleteSupplierCategory($id, $category_id) + { + if(! DolibarrApiAccess::$user->rights->societe->creer) { + throw new RestException(401); + } + + $result = $this->company->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Thirdparty not found'); + } + $category = new Categorie($this->db); + $result = $category->fetch($category_id); + if( ! $result ) { + throw new RestException(404, 'category not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('societe',$this->company->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + if( ! DolibarrApi::_checkAccessToResource('category',$category->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $category->del_type($this->company,'supplier'); + + return $this->_cleanObjectDatas($this->company); + } + + /** * Get outstanding proposals of thirdparty * From d762226a70ed31da529fa45900327a78710b1566 Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Mon, 12 Feb 2018 14:39:18 +0100 Subject: [PATCH 101/386] FIX : Call to trigger on chargesociale create --- .../compta/sociales/class/chargesociales.class.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index cf359d691ec..b6386ae3b98 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -155,6 +155,7 @@ class ChargeSociales extends CommonObject function create($user) { global $conf; + $error=0; $now=dol_now(); @@ -190,8 +191,17 @@ class ChargeSociales extends CommonObject $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX."chargesociales"); //dol_syslog("ChargesSociales::create this->id=".$this->id); - $this->db->commit(); - return $this->id; + $result=$this->call_trigger('PAYMENTSOCIALECONTRIBUTION_CREATE',$user); + if ($result < 0) $error++; + + if(empty($error)) { + $this->db->commit(); + return $this->id; + } + else { + $this->db->rollback(); + return -1*$error; + } } else { From 2aaf3a466d97b6898047bbde05f3f5ad50519e8d Mon Sep 17 00:00:00 2001 From: Gerhard Stephan Date: Mon, 12 Feb 2018 21:38:51 +0100 Subject: [PATCH 102/386] Load product data optional fields to the line -> enables to use "line_options_{extrafield}" This fixes the issue #3185 https://github.com/Dolibarr/dolibarr/issues/3185 --- htdocs/core/class/commondocgenerator.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 666011b3f4a..dee67990cdc 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -527,7 +527,13 @@ abstract class CommonDocGenerator $line->fetch_optionals($line->rowid,$extralabels); $resarray = $this->fill_substitutionarray_with_extrafields($line,$resarray,$extrafields,$array_key=$array_key,$outputlangs); - + + // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" + $product = new Product($this->db); + $result = $product->fetch(null, $line->product_ref); + foreach($product->array_options as $key=>$label) + $resarray["line_".$key] = $label; + return $resarray; } From f93934905fba82d5d4acddb33388bf44fe6c0d50 Mon Sep 17 00:00:00 2001 From: Gerhard Stephan Date: Tue, 13 Feb 2018 08:41:57 +0100 Subject: [PATCH 103/386] Implemented a correct error handling, if the $line->product_ref has not been set --- htdocs/core/class/commondocgenerator.class.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index dee67990cdc..015173f1f05 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -529,10 +529,13 @@ abstract class CommonDocGenerator $resarray = $this->fill_substitutionarray_with_extrafields($line,$resarray,$extrafields,$array_key=$array_key,$outputlangs); // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" - $product = new Product($this->db); - $result = $product->fetch(null, $line->product_ref); - foreach($product->array_options as $key=>$label) - $resarray["line_".$key] = $label; + if (isset($line->product_ref)) + { + $product = new Product($this->db); + $result = $product->fetch(null, $line->product_ref); + foreach($product->array_options as $key=>$label) + $resarray["line_".$key] = $label; + } return $resarray; } From 1a4aa894893b252a2aa69f37f262423ab04120ee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 13:55:36 +0100 Subject: [PATCH 104/386] NEW Can share any file from the "Document" tab. --- htdocs/core/actions_linkedfiles.inc.php | 85 +++++++++++----- htdocs/core/class/html.formfile.class.php | 59 ++++++++++-- htdocs/core/lib/files.lib.php | 7 +- htdocs/document.php | 31 +++--- htdocs/ecm/file_card.php | 4 - htdocs/viewimage.php | 112 +++++++++++++++++++--- 6 files changed, 227 insertions(+), 71 deletions(-) diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php index 0e0c444af33..7f938ba9b6c 100644 --- a/htdocs/core/actions_linkedfiles.inc.php +++ b/htdocs/core/actions_linkedfiles.inc.php @@ -182,37 +182,70 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave','alpha')) $filenamefrom=dol_sanitizeFileName(GETPOST('renamefilefrom','alpha'), '_', 0); // Do not remove accents $filenameto=dol_sanitizeFileName(GETPOST('renamefileto','alpha'), '_', 0); // Do not remove accents - // Security: - // Disallow file with some extensions. We rename them. - // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. - if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$filenameto) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + if ($filenamefrom != $filenameto) { - $filenameto.= '.noexe'; - } + // Security: + // Disallow file with some extensions. We rename them. + // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. + if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$filenameto) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + { + $filenameto.= '.noexe'; + } - if ($filenamefrom && $filenameto) - { - $srcpath = $upload_dir.'/'.$filenamefrom; - $destpath = $upload_dir.'/'.$filenameto; + if ($filenamefrom && $filenameto) + { + $srcpath = $upload_dir.'/'.$filenamefrom; + $destpath = $upload_dir.'/'.$filenameto; - $result = dol_move($srcpath, $destpath); - if ($result) - { - if ($object->id) - { - $object->addThumbs($destpath); - } + $result = dol_move($srcpath, $destpath); + if ($result) + { + if ($object->id) + { + $object->addThumbs($destpath); + } - // TODO Add revert function of addThumbs to remove for old name - //$object->delThumbs($srcpath); + // TODO Add revert function of addThumbs to remove for old name + //$object->delThumbs($srcpath); - setEventMessages($langs->trans("FileRenamed"), null); - } - else - { - $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now. - setEventMessages($langs->trans("ErrorFailToRenameFile", $filenamefrom, $filenameto), null, 'errors'); - } + setEventMessages($langs->trans("FileRenamed"), null); + } + else + { + $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now. + setEventMessages($langs->trans("ErrorFailToRenameFile", $filenamefrom, $filenameto), null, 'errors'); + } + } } } + + // Update properties in ECM table + if (GETPOST('ecmfileid', 'int') > 0) + { + $shareenabled = GETPOST('shareenabled', 'alpha'); + + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(GETPOST('ecmfileid', 'int')); + if ($result > 0) + { + if ($shareenabled) + { + if (empty($ecmfile->share)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $ecmfile->share = getRandomPassword(true); + } + } + else + { + $ecmfile->share = ''; + } + $result = $ecmfile->update($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + } } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 4bff96700d5..ac5bfdcabb7 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -938,7 +938,7 @@ class FormFile * @param string $url Full url to use for click links ('' = autodetect) * @param int $showrelpart 0=Show only filename (default), 1=Show first level 1 dir * @param int $permtoeditline Permission to edit document line (You must provide a value, -1 is deprecated and must not be used any more) - * @param string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this if you want to complete file data with database indexes. + * @param string $upload_dir Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this to complete file data with database indexes. * @param string $sortfield Sort field ('name', 'size', 'position', ...) * @param string $sortorder Sort order ('ASC' or 'DESC') * @param int $disablemove 1=Disable move button, 0=Position move is possible. @@ -951,6 +951,7 @@ class FormFile global $user, $conf, $langs, $hookmanager; global $bc,$bcdd; global $sortfield, $sortorder, $maxheightmini; + global $dolibarr_main_url_root; // Define relative path used to store the file if (empty($relativepath)) @@ -1038,6 +1039,7 @@ class FormFile print ''; if (empty($useinecm)) print ''; print ''; + print ''; if (! $disablemove) print ''; print "\n"; } @@ -1047,7 +1049,8 @@ class FormFile print_liste_field_titre('Documents2',$url,"name","",$param,'align="left"',$sortfield,$sortorder); print_liste_field_titre('Size',$url,"size","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre('Date',$url,"date","",$param,'align="center"',$sortfield,$sortorder); - if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); + if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); // Preview + print_liste_field_titre(''); print_liste_field_titre(''); if (! $disablemove) print_liste_field_titre(''); print "\n"; @@ -1063,7 +1066,6 @@ class FormFile //var_dump($sortfield); $filearray=dol_sort_array($filearray, $sortfield, $sortorder); } - //var_dump($filearray); } $nboffiles=count($filearray); @@ -1146,6 +1148,48 @@ class FormFile else print ' '; print ''; } + + // Hash of file (only if we are in a mode where a scan of dir were done and we have id of file in ECM table) + print ''; + + // Actions buttons if (! $editline) { // Delete or view link @@ -1215,6 +1259,7 @@ class FormFile else { print ''; @@ -1227,9 +1272,9 @@ class FormFile } if ($nboffiles == 0) { - $colspan=(empty($useinecm)?'5':'5'); - if (empty($disablemove)) $colspan++; - print ''; @@ -1249,6 +1294,8 @@ class FormFile print ''; } + print ajax_autoselect('downloadlink'); + return $nboffiles; } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 206d1bb8099..b53e588c275 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -225,7 +225,8 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc { global $conf, $db; - $sql=" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; + $sql =" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m,"; + $sql.=" acl, position, share"; if ($mode) $sql.=", description"; $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; $sql.=" WHERE filepath = '".$db->escape($path)."'"; @@ -258,7 +259,8 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc "keywords" => $obj->keywords, "cover" => $obj->cover, "position" => (int) $obj->position, - "acl" => $obj->acl + "acl" => $obj->acl, + "share" => $obj->share ); } $i++; @@ -318,6 +320,7 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir) $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl']; $filearray[$key]['rowid']=$filearrayindatabase[$key2]['rowid']; $filearray[$key]['label']=$filearrayindatabase[$key2]['label']; + $filearray[$key]['share']=$filearrayindatabase[$key2]['share']; $found=1; break; } diff --git a/htdocs/document.php b/htdocs/document.php index 1c722e4cb55..50f4a61186d 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -25,9 +25,9 @@ * \file htdocs/document.php * \brief Wrapper to download data files * \remarks Call of this wrapper is made with URL: - * document.php?modulepart=repfichierconcerne&file=relativepathoffile - * document.php?modulepart=logs&file=dolibarr.log - * document.php?modulepart=logs&hashp=sharekey + * DOL_URL_ROOT.'/document.php?modulepart=repfichierconcerne&file=relativepathoffile' + * DOL_URL_ROOT.'/document.php?modulepart=logs&file=dolibarr.log' + * DOL_URL_ROOT.'/document.php?hashp=sharekey' */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -36,9 +36,9 @@ //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); //if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); //if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); // Disable "main.inc.php" hooks // For bittorent link, we don't need to load/check we are into a login session if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'bittorrent' && ! defined("NOLOGIN")) @@ -58,9 +58,6 @@ if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias') && ! defined define("NOLOGIN",1); define("NOCSRFCHECK",1); // We accept to go on this page from external web site. } -if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); -if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); -if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); /** * Header empty @@ -75,7 +72,6 @@ function llxHeader() { } */ function llxFooter() { } - require 'main.inc.php'; // Load $user and permissions require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -103,21 +99,17 @@ if (in_array($modulepart, array('facture_paiement','unpaid'))) /* - * Action + * Actions */ // None + /* * View */ -// Define mime type -$type = 'application/octet-stream'; -if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); -else $type=dol_mimetype($original_file); - // Define attachment (attachment=true to force choice popup 'open'/'save as') $attachment = true; if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false; @@ -160,6 +152,10 @@ if (! empty($hashp)) } } +// Define mime type +$type = 'application/octet-stream'; +if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); +else $type=dol_mimetype($original_file); // Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); @@ -252,9 +248,6 @@ header('Content-Length: ' . dol_filesize($fullpath_original_file)); header('Cache-Control: Public, must-revalidate'); header('Pragma: public'); -//ob_clean(); -//flush(); - readfile($fullpath_original_file_osencoded); if (is_object($db)) $db->close(); diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php index 8c62cbe18f2..e0926e0f777 100644 --- a/htdocs/ecm/file_card.php +++ b/htdocs/ecm/file_card.php @@ -341,13 +341,9 @@ if (! empty($object->share)) { if ($action != 'edit') { - $modulepart='ecm'; $forcedownload=0; $paramlink=''; - //if (! empty($modulepart)) $paramlink.=($paramlink?'&':'').'modulepart='.$modulepart; // For sharing with hash (so public files), modulepart is not required. - //if (! empty($object->entity)) $paramlink.='&entity='.$object->entity; // For sharing with hash (so public files), entity is not required. - //$paramlink.=($paramlink?'&':'').'file='.urlencode($filepath); // No need of name of file for public link, we will use the hash if (! empty($object->share)) $paramlink.=($paramlink?'&':'').'hashp='.$object->share; // Hash for public share if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1'; diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 3f7ddbcd1cb..3e2b59ae404 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -20,8 +20,10 @@ /** * \file htdocs/viewimage.php - * \brief Wrapper to show images into Dolibarr screens - * \remarks Call to wrapper is '' + * \brief Wrapper to show images into Dolibarr screens. + * \remarks Call to wrapper is : + * DOL_URL_ROOT.'/viewimage.php?modulepart=diroffile&file=relativepathofofile&cache=0 + * DOL_URL_ROOT.'/viewimage.php?hashp=sharekey */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -35,7 +37,16 @@ if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); // Disable "main.inc.php" hooks // Some value of modulepart can be used to get resources that are public so no login are required. -if ((isset($_GET["modulepart"]) && ($_GET["modulepart"] == 'mycompany' || $_GET["modulepart"] == 'companylogo')) && ! defined("NOLOGIN")) define("NOLOGIN",'1'); +if ((isset($_GET["modulepart"]) && ($_GET["modulepart"] == 'mycompany' || $_GET["modulepart"] == 'companylogo')) && ! defined("NOLOGIN")) +{ + define("NOLOGIN",'1'); +} +// For direct external download link, we don't need to load/check we are into a login session +if (isset($_GET["hashp"]) && ! defined("NOLOGIN")) +{ + define("NOLOGIN",1); +} +// Some value of modulepart can be used to get resources that are public so no login are required. if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias') && ! defined("NOLOGIN")) { define("NOLOGIN",'1'); @@ -57,18 +68,20 @@ function llxHeader() { } */ function llxFooter() { } -require 'main.inc.php'; +require 'main.inc.php'; // Load $user and permissions require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $action=GETPOST('action','alpha'); -$original_file=GETPOST("file",'alpha'); +$original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). +$hashp=GETPOST('hashp','aZ09'); $modulepart=GETPOST('modulepart','alpha'); -$urlsource=GETPOST("urlsource",'alpha'); +$urlsource=GETPOST('urlsource','alpha'); $entity=GETPOST('entity','int')?GETPOST('entity','int'):$conf->entity; // Security check -if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); +if (empty($modulepart) && empty($hashp)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); +if (empty($original_file) && empty($hashp)) accessforbidden('Bad link. Missing identification to find file (original_file or hashp)',0,0,1); if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility @@ -97,9 +110,45 @@ if (GETPOST("cache",'alpha')) //print $dolibarr_nocache; exit; } +// If we have a hash public (hashp), we guess the original_file. +if (! empty($hashp)) +{ + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', '', '', $hashp); + if ($result > 0) + { + $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepath is relative to document directory + $moduleparttocheck = $tmp[0]; + if ($modulepart) // Not required for link using public hashp + { + if ($moduleparttocheck == $modulepart) + { + // We remove first level of directory + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + //var_dump($original_file); exit; + } + else + { + accessforbidden('Bad link. File is from another module part.',0,0,1); + } + } + else + { + $modulepart = $moduleparttocheck; + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + } + } + else + { + $langs->load("errors"); + accessforbidden($langs->trans("ErrorFileNotFoundWithSharedLink"),0,0,1); + } +} + // Define mime type $type = 'application/octet-stream'; -if (! empty($_GET["type"])) $type=$_GET["type"]; +if (GETPOST('type','alpha')) $type=GETPOST('type','alpha'); else $type=dol_mimetype($original_file); // Security: Delete string ../ into $original_file @@ -110,16 +159,49 @@ $refname=basename(dirname($original_file)."/"); // Security check if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); -$check_access = dol_check_secure_access_document($modulepart,$original_file,$entity,$refname); + +$check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, $refname); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; -$fullpath_original_file = $check_access['original_file']; +$fullpath_original_file = $check_access['original_file']; // $fullpath_original_file is now a full path name + +if (! empty($hashp)) +{ + $accessallowed = 1; // When using hashp, link is public so we force $accessallowed + $sqlprotectagainstexternals = ''; +} +else +{ + // Basic protection (against external users only) + if ($user->societe_id > 0) + { + if ($sqlprotectagainstexternals) + { + $resql = $db->query($sqlprotectagainstexternals); + if ($resql) + { + $num=$db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($user->societe_id != $obj->fk_soc) + { + $accessallowed=0; + break; + } + $i++; + } + } + } + } +} // Security: // Limit access if permissions are wrong if (! $accessallowed) { - accessforbidden(); + accessforbidden(); } // Security: @@ -128,7 +210,7 @@ if (preg_match('/\.\./',$fullpath_original_file) || preg_match('/[<>|]/',$fullpa { dol_syslog("Refused to deliver file ".$fullpath_original_file); print "ErrorFileNameInvalid: ".$original_file; - exit; + exit; } @@ -174,8 +256,10 @@ else // Open and return file { clearstatcache(); + $filename = basename($fullpath_original_file); + // Output files on browser - dol_syslog("viewimage.php return file $fullpath_original_file content-type=$type"); + dol_syslog("viewimage.php return file $fullpath_original_file filename=$filename content-type=$type"); // This test is to avoid error images when image is not available (for example thumbs). if (! dol_is_file($fullpath_original_file) && empty($_GET["noalt"])) @@ -186,7 +270,7 @@ else // Open and return file exit;*/ } - // Les drois sont ok et fichier trouve + // Permissions are ok and file found, so we return it if ($type) { top_httphead($type); From 7743f88e98efa921e7ccca9ebb947e1c8509c413 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 14:03:11 +0100 Subject: [PATCH 105/386] Fix bad escaping --- htdocs/core/tpl/ajaxrow.tpl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index a75ed1846ff..e4a63b23b3d 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -71,7 +71,8 @@ $(document).ready(function(){ function() { console.log("tableDND end of ajax call"); if (reloadpage == 1) { - location.href = ''; + //console.log(''); + location.href = ''; } else { $("# .drag").each( function( intIndex ) { From 8a32ae69353d087c2b964c665efeb47dee644d1e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 15:46:39 +0100 Subject: [PATCH 106/386] Move ajax_autoselect into functions.lib.php --- htdocs/core/lib/ajax.lib.php | 18 ------------------ htdocs/core/lib/functions.lib.php | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 2ddc7125d4a..845a758703e 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -358,24 +358,6 @@ function ajax_dialog($title,$message,$w=350,$h=150) } -/** - * Make content of an input box selected when we click into input field. - * - * @param string $htmlname Id of html object - * @param string $addlink Add a 'link to' after - */ -function ajax_autoselect($htmlname, $addlink='') -{ - global $langs; - $out = ''; - if ($addlink) $out.=' '.$langs->trans("Link").''; - return $out; -} - /** * Convert a html select field into an ajax combobox. * Use ajax_combobox() only for small combo list! If not, use instead ajax_autocompleter(). diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a736f3c139a..534555cd8e5 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6861,6 +6861,25 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='' } +/** + * Make content of an input box selected when we click into input field. + * + * @param string $htmlname Id of html object + * @param string $addlink Add a 'link to' after + */ +function ajax_autoselect($htmlname, $addlink='') +{ + global $langs; + $out = ''; + if ($addlink) $out.=' '.$langs->trans("Link").''; + return $out; +} + + /** * Return mime type of a file * From 35aece060cdf34320183525130ce6f7588efe661 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 15:47:17 +0100 Subject: [PATCH 107/386] Search field in correct column --- htdocs/core/class/html.formfile.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index ac5bfdcabb7..3d560c9644e 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1289,13 +1289,13 @@ class FormFile } } + print ajax_autoselect('downloadlink'); + if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline) { print ''; } - print ajax_autoselect('downloadlink'); - return $nboffiles; } } @@ -1344,8 +1344,8 @@ class FormFile if (! empty($addfilterfields)) { print ''; - print ''; print ''; + print ''; print ''; print ''; // Action column From 92e67ebb8fe34bf73fd632eacf9d7a66d3925f13 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 16:33:45 +0100 Subject: [PATCH 108/386] Fix svg image preview ko --- htdocs/core/lib/functions.lib.php | 3 ++- htdocs/core/lib/images.lib.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 534555cd8e5..457f8068c0e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6844,7 +6844,7 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='' if (empty($conf->use_javascript_ajax)) return ''; - $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css'); + $mime_preview = array('bmp', 'jpeg', 'png', 'gif', 'tiff', 'pdf', 'plain', 'css', 'svg+xml'); //$mime_preview[]='vnd.oasis.opendocument.presentation'; //$mime_preview[]='archive'; $num_mime = array_search(dol_mimetype($relativepath, '', 1), $mime_preview); @@ -6950,6 +6950,7 @@ function dol_mimetype($file, $default='application/octet-stream', $mode=0) if (preg_match('/\.gif$/i',$tmpfile)) { $mime='image/gif'; $imgmime='image.png'; $famime='file-image-o'; } if (preg_match('/\.bmp$/i',$tmpfile)) { $mime='image/bmp'; $imgmime='image.png'; $famime='file-image-o'; } if (preg_match('/\.(tif|tiff)$/i',$tmpfile)) { $mime='image/tiff'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.svg$/i',$tmpfile)) { $mime='image/svg+xml';$imgmime='image.png'; $famime='file-image-o'; } // Calendar if (preg_match('/\.vcs$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } if (preg_match('/\.ics$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index e6f69da1d93..f0a666b03e9 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -37,7 +37,7 @@ $quality = 80; */ function image_format_supported($file) { - $regeximgext='\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.xpm|\.xbm'; // See also into product.class.php + $regeximgext='\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.xpm|\.xbm|\.svg'; // See also into product.class.php // Case filename is not a format image if (! preg_match('/('.$regeximgext.')$/i',$file,$reg)) return -1; From 4f369bd746075fa2f60c55167f8218a2a2d5f8cf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 16:34:43 +0100 Subject: [PATCH 109/386] NEW Can force usage of shared link for photo of products --- htdocs/product/class/product.class.php | 40 +++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e6439031146..73d867e7141 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4095,9 +4095,11 @@ class Product extends CommonObject * @param int $maxHeight Max height of original image when size='small' (so we can use original even if small requested). If 0, always use 'small' thumb image. * @param int $maxWidth Max width of original image when size='small' * @param int $nolink Do not add a href link to view enlarged imaged into a new tab + * @param int $notitle Do not add title tag on image + * @param int $usesharelink Use the public shared link of image (if not available, the 'nophoto' image will be shown instead) * @return string Html code to show photo. Number of photos shown is saved in this->nbphoto */ - function show_photos($sdir,$size=0,$nbmax=0,$nbbyrow=5,$showfilename=0,$showaction=0,$maxHeight=120,$maxWidth=160,$nolink=0) + function show_photos($sdir,$size=0,$nbmax=0,$nbbyrow=5,$showfilename=0,$showaction=0,$maxHeight=120,$maxWidth=160,$nolink=0,$notitle=0,$usesharelink=0) { global $conf,$user,$langs; @@ -4196,15 +4198,39 @@ class Product extends CommonObject // Si fichier vignette disponible et image source trop grande, on utilise la vignette, sinon on utilise photo origine $alt=$langs->transnoentitiesnoconv('File').': '.$relativefile; $alt.=' - '.$langs->transnoentitiesnoconv('Size').': '.$imgarray['width'].'x'.$imgarray['height']; + if ($notitle) $alt=''; - if (empty($maxHeight) || $photo_vignette && $imgarray['height'] > $maxHeight) + if ($usesharelink) { - $return.= ''; - $return.= ''; + if ($val['share']) + { + if (empty($maxHeight) || $photo_vignette && $imgarray['height'] > $maxHeight) + { + $return.= ''; + $return.= ''; + } + else { + $return.= ''; + $return.= ''; + } + } + else + { + $return.= ''; + $return.= ''; + } } - else { - $return.= ''; - $return.= ''; + else + { + if (empty($maxHeight) || $photo_vignette && $imgarray['height'] > $maxHeight) + { + $return.= ''; + $return.= ''; + } + else { + $return.= ''; + $return.= ''; + } } if (empty($nolink)) $return.= ''; From b128c95a74ffa4e6e3aaea01933ac8eab15255b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 13 Feb 2018 19:08:46 +0100 Subject: [PATCH 110/386] NEW Add showempty parameter in country selection --- htdocs/core/class/html.form.class.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cbd2eb5c3b3..4e8f67d6552 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -646,9 +646,10 @@ class Form * @param integer $maxlength Max length for labels (0=no limit) * @param string $morecss More css class * @param string $usecodeaskey 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key + * @param int $showempty Show empty choice * @return string HTML string with select */ - function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300',$usecodeaskey='') + function select_country($selected='', $htmlname='country_id', $htmloption='', $maxlength=0, $morecss='minwidth300', $usecodeaskey='', $showempty=1) { global $conf,$langs; @@ -693,20 +694,22 @@ class Form foreach ($countryArray as $row) { + if (empty($showempty) && empty($row['rowid'])) continue; + if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++; if (empty($row['favorite']) && $atleastonefavorite) { $atleastonefavorite=0; - $out.= ''; + $out.= ''; } if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) ) { $foundselected=true; - $out.= ''; - if ($socid > 0) + if ($societe->id > 0) { // Discounts for third party print ''; } @@ -1944,6 +2139,18 @@ else } $resteapayeraffiche = $resteapayer; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { // Never use this + $filterabsolutediscount = "fk_invoice_supplier IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote = "fk_invoice_supplier IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } else { + $filterabsolutediscount = "fk_invoice_supplier IS NOT NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')"; + $filtercreditnote = "fk_invoice_supplier IS NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')"; + } + + $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 'supplier'); + $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 'supplier'); + $absolute_discount = price2num($absolute_discount, 'MT'); + $absolute_creditnote = price2num($absolute_creditnote, 'MT'); /* * View card @@ -1953,6 +2160,17 @@ else dol_fiche_head($head, 'card', $titre, -1, 'bill'); + $formconfirm = ''; + + // Confirmation de la conversion de l'avoir en reduc + if ($action == 'converttoreduc') { + if($object->type == FactureFournisseur::TYPE_STANDARD) $type_fac = 'ExcessReceived'; // TODO translation trop-perçu => trop-payé + elseif($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) $type_fac = 'CreditNote'; + elseif($object->type == FactureFournisseur::TYPE_DEPOSIT) $type_fac = 'Deposit'; + $text = $langs->trans('ConfirmConvertToReduc', strtolower($langs->transnoentities($type_fac))); // TODO translation client => fournisseur + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2); + } + // Clone confirmation if ($action == 'clone') { @@ -2189,7 +2407,88 @@ else print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; } print ''; - + + // Relative and absolute discounts + $addrelativediscount = '' . $langs->trans("EditRelativeDiscounts") . ''; + $addabsolutediscount = '' . $langs->trans("EditGlobalDiscounts") . ''; + $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; + $viewabsolutediscount = '' . $langs->trans("ViewAvailableGlobalDiscounts") . ''; + + print ''; + // Label print ''; print ''; @@ -2539,18 +2838,19 @@ else print $langs->trans('AlreadyPaid'); print ' :'; - $resteapayer = $object->total_ttc - $totalpaye; + //$resteapayer = $object->total_ttc - $totalpaye; $resteapayeraffiche = $resteapayer; + $cssforamountpaymentcomplete = 'amountpaymentcomplete'; // Loop on each credit note or deposit amount applied $creditnoteamount = 0; $depositamount = 0; - /* + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql .= " re.description, re.fk_facture_source"; - $sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except_supplier as re"; - $sql .= " WHERE fk_facture = " . $object->id; + $sql .= " re.description, re.fk_invoice_supplier_source"; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re"; + $sql .= " WHERE fk_invoice_supplier = " . $object->id; $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -2558,7 +2858,7 @@ else $invoice = new FactureFournisseur($db); while ($i < $num) { $obj = $db->fetch_object($resql); - $invoice->fetch($obj->fk_facture_source); + $invoice->fetch($obj->fk_invoice_supplier_source); print ''; print ''; print ''; $i ++; if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) @@ -2579,7 +2879,7 @@ else } else { dol_print_error($db); } - */ + // Paye partiellement 'escompte' if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') { @@ -2627,7 +2927,7 @@ else else print $langs->trans('ExcessReceived'); print ' :'; - print ''; + print ''; print ''; } else // Credit note @@ -2649,7 +2949,7 @@ else else print $langs->trans('ExcessPaydBack'); print ' :'; - print ''; + print ''; print ''; // Sold credit note @@ -2792,7 +3092,7 @@ else } // Reverse back money or convert to reduction - if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) { + if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) { // For credit note only if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0) { @@ -2806,6 +3106,11 @@ else } } + // For standard invoice with excess paid + if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $user->rights->facture->creer && empty($discount->id)) + { + print ''; // TODO translation : trop-perçu => trop payé + } // For credit note if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer && $object->getSommePaiement() == 0) { print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index b9b431f3e3e..4adfae72258 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1718,14 +1718,15 @@ class Societe extends CommonObject * @param User $user Filtre sur un user auteur des remises * @param string $filter Filtre autre * @param integer $maxvalue Filter on max value for discount + * @param string $mode 'supplier' to get available discounts for suppliers, 'customer' instead * @return int <0 if KO, Credit note amount otherwise */ - function getAvailableDiscounts($user='',$filter='',$maxvalue=0) + function getAvailableDiscounts($user='',$filter='',$maxvalue=0,$mode='customer') { require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; $discountstatic=new DiscountAbsolute($this->db); - $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue); + $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$mode); if ($result >= 0) { return $result; diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index ffb4cac77fa..1420562da19 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -490,7 +490,7 @@ if ($sql_select) $txt=''; print img_object($langs->trans("ShowReduc"),'reduc').' '; if ($objp->description == '(DEPOSIT)') $txt=$langs->trans("Deposit"); - elseif ($objp->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived"); + elseif ($objp->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived"); // TODO handle (EXCESS PAID) //else $txt=$langs->trans("Discount"); print $txt; ?> @@ -517,7 +517,7 @@ if ($sql_select) echo ($txt?' - ':'').$langs->transnoentities("DiscountFromDeposit",$discount->getNomUrl(0)); // Add date of deposit if (! empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) echo ' ('.dol_print_date($discount->datec).')'; - } + } // TODO handle (EXCESS PAID) else { echo ($txt?' - ':'').dol_htmlentitiesbr($objp->description); From daca27b2ed8e8a2924105de16b32f7f8d894d117 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Wed, 14 Feb 2018 18:02:40 +0100 Subject: [PATCH 113/386] NEW: supplier credit notes: split display in thirdparty discount page + fixes + refactoring --- htdocs/comm/card.php | 2 +- htdocs/comm/remx.php | 372 +++++++++++++++++- htdocs/core/class/discount.class.php | 93 ++++- htdocs/core/class/html.form.class.php | 15 +- .../fourn/class/fournisseur.facture.class.php | 2 +- htdocs/fourn/facture/card.php | 21 +- .../install/mysql/migration/7.0.0-8.0.0.sql | 1 + .../tables/llx_societe_remise_except.key.sql | 1 + .../tables/llx_societe_remise_except.sql | 3 +- htdocs/societe/class/societe.class.php | 25 +- 10 files changed, 476 insertions(+), 59 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 81443f04d62..d732a10a347 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -392,7 +392,7 @@ if ($object->id > 0) print '
'.$langs->trans("Ref")."'; - print $form->showrefnav($bankline, 'rowid', $linkback, 1, 'rowid', 'rowid'); - print '
'.$langs->trans("Account").''; - print $acct->getNomUrl(1,'transactions','reflabel'); + if (! $objp->rappro && ! $bankline->getVentilExportCompta()) + { + print $form->select_comptes($acct->id, 'accountid', 0, '', 0); + } + else + { + print $acct->getNomUrl(1,'transactions','reflabel'); + } print '
'; + if ($relativedir && $filearray[$key]['rowid'] > 0) + { + if ($editline) + { + print $langs->trans("FileSharedViaALink").' '; + print ' '; + } + else + { + if ($file['share']) + { + // Define $urlwithroot + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + //print ''.$langs->trans("Hash").' : '.$file['share'].''; + $forcedownload=0; + $paramlink=''; + if (! empty($file['share'])) $paramlink.=($paramlink?'&':'').'hashp='.$file['share']; // Hash for public share + if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1'; + + $fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:''); + //if (! empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path + //elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label; // Hash of file content + + print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' '; + print ''; + //print ' '.$langs->trans("Download").''; // No target here + } + else + { + //print ''.$langs->trans("FileNotShared").''; + } + } + } + print ''; + print ''; print ''; print ''; print '
'; + $colspan=(empty($useinecm)?'6':'6'); + if (empty($disablemove)) $colspan++; // 6 columns or 7 + print '
'; if (empty($textifempty)) print $langs->trans("NoFileFound"); else print $textifempty; print '
' . $langs->trans('Discounts') . ''; - if ($soc->remise_percent) - print $langs->trans("CompanyHasRelativeDiscount", '' . $soc->remise_percent . ''); + if ($societe->remise_percent) + print $langs->trans("CompanyHasRelativeDiscount", '' . $societe->remise_percent . ''); else print $langs->trans("CompanyHasNoRelativeDiscount"); - print ' (' . $langs->trans("EditRelativeDiscount") . ')'; + print ' (' . $langs->trans("EditRelativeDiscount") . ')'; print '. '; print '
'; if ($absolute_discount) - print $langs->trans("CompanyHasAbsoluteDiscount", '' . price($absolute_discount) . '', $langs->trans("Currency" . $conf->currency)); + print $langs->trans("CompanyHasAbsoluteDiscount", '' . price($absolute_discount) . '', $langs->trans("Currency" . $conf->currency)); else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print ' (' . $langs->trans("EditGlobalDiscounts") . ')'; + print ' (' . $langs->trans("EditGlobalDiscounts") . ')'; print '.'; print '
' . $langs->trans('Discounts'); + print ''; + if ($societe->remise_percent) + print $langs->trans("CompanyHasRelativeDiscount", $societe->remise_percent); + else + print $langs->trans("CompanyHasNoRelativeDiscount"); + // print ' ('.$addrelativediscount.')'; + + // Is there is commercial discount or down payment available ? + if ($absolute_discount > 0) { + print '. '; + if ($object->statut > 0 || $object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) { + if ($object->statut == 0) { + print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency)); + print '. '; + } else { + if ($object->statut < 1 || $object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) { + $text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency)); + print '
' . $text . '.
'; + } else { + $text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency)); + $text2 = $langs->trans("AbsoluteDiscountUse"); + print $form->textwithpicto($text, $text2); + } + } + } else { + // Discount available of type fixed amount (not credit note) + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $societe->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')', 0, 'supplier'); + } + } else { + if ($absolute_creditnote > 0) // If not, link will be added later + { + if ($object->statut == FactureFournisseur::STATUS_DRAFT && $object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->type != FactureFournisseur::TYPE_DEPOSIT) + print ' (' . $addabsolutediscount . ')
'; + else + print '. '; + } else + print '. '; + } + // Is there credit notes availables ? + if ($absolute_creditnote > 0) + { + // If validated, we show link "add credit note to payment" + if ($object->statut != FactureFournisseur::STATUS_VALIDATED || $object->type == FactureFournisseur::TYPE_CREDIT_NOTE) { + if ($object->statut == 0 && $object->type != FactureFournisseur::TYPE_DEPOSIT) { + $text = $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)); + print $form->textwithpicto($text, $langs->trans("CreditNoteDepositUse")); + } else { + print $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)) . '.'; + } + } else { // We can add a credit note on a down payment or standard invoice or situation invoice + // There is credit notes discounts available + if (! $absolute_discount) print '
'; + // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, $resteapayer, '', 0, 'supplier'); + $more=' ('.$addcreditnote. (($addcreditnote && $viewabsolutediscount) ? ' - ' : '') . $viewabsolutediscount . ')'; + $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, 0, $more, 0, 'supplier'); // We allow credit note even if amount is higher + } + } + if (! $absolute_discount && ! $absolute_creditnote) { + print $langs->trans("CompanyHasNoAbsoluteDiscount"); + if ($object->statut == FactureFournisseur::STATUS_DRAFT && $object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->type != FactureFournisseur::TYPE_DEPOSIT) + print ' (' . $addabsolutediscount . ')
'; + else + print '. '; + } + // if ($object->statut == 0 && $object->type != 2 && $object->type != 3) + // { + // if (! $absolute_discount && ! $absolute_creditnote) print '
'; + // print '   -   '; + // print $addabsolutediscount; + // print '   -   '.$addcreditnote; // We disbale link to credit note + // } + print '
'.$form->editfieldkey("Label",'label',$object->label,$object,($user->rights->fournisseur->facture->creer)).' 0)?' class="amountalreadypaid"':'').'>' . price($totalpaye) . ' 
'; if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) print $langs->trans("CreditNote") . ' '; @@ -2568,7 +2868,7 @@ else print ' :' . price($obj->amount_ttc) . ''; - print 'rowid . '">' . img_delete() . ''; + print 'rowid . '">' . img_delete() . ''; // TODO unlinkdiscount print '
' . price($resteapayeraffiche) . '' . price($resteapayeraffiche) . ' 
' . price($sign * $resteapayeraffiche) . '' . price($sign * $resteapayeraffiche) . ' 
'; print ''; print ''; - $amount_discount=$object->getAvailableDiscounts(); + $amount_discount=$object->getAvailableDiscounts(); // TODO adapt to supplier discounts if ($amount_discount < 0) dol_print_error($db,$object->error); if ($amount_discount > 0) print ''.price($amount_discount,1,$langs,1,-1,-1,$conf->currency).''; //else print $langs->trans("DiscountNone"); diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 0127b8f15be..072baa675fb 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -26,6 +26,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; $langs->load("orders"); @@ -143,6 +144,7 @@ if ($action == 'setremise' && $user->rights->societe->creer) $amount_ht=GETPOST('amount_ht'); $desc=GETPOST('desc','alpha'); $tva_tx=GETPOST('tva_tx','alpha'); + $discount_type=! empty($_POST['discount_type'])?GETPOST('discount_type','alpha'):0; if (price2num($amount_ht) > 0) { @@ -157,7 +159,7 @@ if ($action == 'setremise' && $user->rights->societe->creer) { $soc = new Societe($db); $soc->fetch($id); - $discountid=$soc->set_remise_except($amount_ht,$user,$desc,$tva_tx); + $discountid=$soc->set_remise_except($amount_ht,$user,$desc,$tva_tx,$discount_type); if ($discountid > 0) { @@ -215,6 +217,7 @@ if (GETPOST('action','aZ09') == 'confirm_remove' && GETPOST("confirm")=='yes') $form=new Form($db); $facturestatic=new Facture($db); +$facturefournstatic=new FactureFournisseur($db); llxHeader('',$langs->trans("GlobalDiscount")); @@ -244,12 +247,13 @@ if ($socid > 0) print '
'; print ''; - // Calcul avoirs en cours + // Calcul avoirs client en cours $remise_all=$remise_user=0; $sql = "SELECT SUM(rc.amount_ht) as amount, rc.fk_user"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; $sql.= " WHERE rc.fk_soc = " . $object->id; $sql.= " AND rc.entity = " . $conf->entity; + $sql.= " AND discount_type = 0"; // Exclude supplier discounts $sql.= " AND (fk_facture_line IS NULL AND fk_facture IS NULL)"; $sql.= " GROUP BY rc.fk_user"; $resql=$db->query($sql); @@ -264,14 +268,47 @@ if ($socid > 0) dol_print_error($db); } - print ''; + print ''; // TODO adapt text print ''; if (! empty($user->fk_soc)) // No need to show this for external users { - print ''; + print ''; // TODO adapt text print ''; } + + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + // Calcul avoirs fournisseur en cours + $remise_all=$remise_user=0; + $sql = "SELECT SUM(rc.amount_ht) as amount, rc.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " WHERE rc.fk_soc = " . $object->id; + $sql.= " AND rc.entity = " . $conf->entity; + $sql.= " AND discount_type = 1"; // Exclude customer discounts + $sql.= " AND (fk_invoice_supplier_line IS NULL AND fk_invoice_supplier IS NULL)"; + $sql.= " GROUP BY rc.fk_user"; + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + $remise_all+=$obj->amount; + if ($obj->fk_user == $user->id) $remise_user+=$obj->amount; + } + else + { + dol_print_error($db); + } + + print ''; // TODO adapt text + print ''; + + if (! empty($user->fk_soc)) // No need to show this for external users + { + print ''; // TODO adapt text + print ''; + } + } + print '
'.$langs->trans("CustomerAbsoluteDiscountAllUsers").'
'.$langs->trans("CustomerAbsoluteDiscountAllUsers").''.$remise_all.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'.$langs->trans("CustomerAbsoluteDiscountMy").'
'.$langs->trans("CustomerAbsoluteDiscountMy").''.$remise_user.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'.$langs->trans("CustomerAbsoluteDiscountAllUsers").''.$remise_all.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'.$langs->trans("CustomerAbsoluteDiscountMy").''.$remise_user.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'; print '
'; @@ -284,6 +321,11 @@ if ($socid > 0) print '
'; print ''; + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print ''; + print ''; + } print ''; print ''; @@ -321,9 +363,18 @@ if ($socid > 0) print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.GETPOST('remid'), $langs->trans('RemoveDiscount'), $langs->trans('ConfirmRemoveDiscount'), 'confirm_remove', '', 0, 1); } + /* - * Liste remises fixes restant en cours (= liees a aucune facture ni ligne de facture) + * Liste remises fixes client restant en cours (= liees a aucune facture ni ligne de facture) */ + + print load_fiche_titre($langs->trans("DiscountStillRemaining")); + + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print '
'; + print '
'; + } + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; $sql.= " rc.datec as dc, rc.description,"; $sql.= " rc.fk_facture_source,"; @@ -334,13 +385,16 @@ if ($socid > 0) $sql.= " WHERE rc.fk_soc = " . $object->id; $sql.= " AND rc.entity = " . $conf->entity; $sql.= " AND u.rowid = rc.fk_user"; + $sql.= " AND rc.discount_type = 0"; // Eliminate supplier discounts $sql.= " AND (rc.fk_facture_line IS NULL AND rc.fk_facture IS NULL)"; $sql.= " ORDER BY rc.datec DESC"; $resql=$db->query($sql); if ($resql) { - print load_fiche_titre($langs->trans("DiscountStillRemaining")); + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print load_fiche_titre($langs->trans("CustomerDiscounts"), '', ''); // TODO translate + } print '
'.$langs->trans('DiscountType').' '; + print '
'.$langs->trans("AmountHT").''; print ' '.$langs->trans("Currency".$conf->currency).'
'; print ''; print ''; // Need 120+ for format with AM/PM @@ -449,11 +503,157 @@ if ($socid > 0) dol_print_error($db); } + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print ''; // class="fichehalfleft" + print '
'; + print '
'; + + /* + * Liste remises fixes fournisseur restant en cours (= liees a aucune facture ni ligne de facture) + */ + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql.= " rc.datec as dc, rc.description,"; + $sql.= " rc.fk_invoice_supplier_source,"; + $sql.= " u.login, u.rowid as user_id,"; + $sql.= " fa.ref, fa.type as type"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as fa ON rc.fk_invoice_supplier_source = fa.rowid"; + $sql.= " WHERE rc.fk_soc = " . $object->id; + $sql.= " AND rc.entity = " . $conf->entity; + $sql.= " AND u.rowid = rc.fk_user"; + $sql.= " AND rc.discount_type = 1"; // Eliminate customer discounts + $sql.= " AND (rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; + $sql.= " ORDER BY rc.datec DESC"; + + $resql=$db->query($sql); + if ($resql) + { + print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); // TODO translate + print '
'.$langs->trans("Date").'
'; + print ''; + print ''; // Need 120+ for format with AM/PM + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $showconfirminfo=array(); + + $i = 0; + $num = $db->num_rows($resql); + if ($num > 0) + { + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS PAID\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + if ($user->rights->societe->creer || $user->rights->facture->creer) + { + print ''; + } + else print ''; + print ''; + + if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) + { + $showconfirminfo['rowid']=$obj->rowid; + $showconfirminfo['amount_ttc']=$obj->amount_ttc; + } + $i++; + } + } + else + { + print ''; + } + $db->free($resql); + print "
'.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").''.$langs->trans("AmountTTC").''.$langs->trans("DiscountOfferedBy").' 
'.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(EXCESS PAID\)/',$langs->trans("ExcessPaid"),$obj->description).' '.$facturefournstatic->getNomURl(1); // TODO translate ExcessPaid + print ''; + print $obj->description; + print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ''; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_split($langs->trans("SplitDiscount")).''; + print '   '; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_delete($langs->trans("RemoveDiscount")).''; + print ' 
'.$langs->trans("None").'
"; + + if (count($showconfirminfo)) + { + $amount1=price2num($showconfirminfo['amount_ttc']/2,'MT'); + $amount2=($showconfirminfo['amount_ttc']-$amount1); + $formquestion=array( + 'text' => $langs->trans('TypeAmountOfEachNewDiscount'), + array('type' => 'text', 'name' => 'amount_ttc_1', 'label' => $langs->trans("AmountTTC").' 1', 'value' => $amount1, 'size' => '5'), + array('type' => 'text', 'name' => 'amount_ttc_2', 'label' => $langs->trans("AmountTTC").' 2', 'value' => $amount2, 'size' => '5') + ); + $langs->load("dict"); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.$showconfirminfo['rowid'].($backtopage?'&backtopage='.urlencode($backtopage):''), $langs->trans('SplitDiscount'), $langs->trans('ConfirmSplitDiscount',price($showconfirminfo['amount_ttc']),$langs->transnoentities("Currency".$conf->currency)), 'confirm_split', $formquestion, 0, 0); + } + } + else + { + dol_print_error($db); + } + + print '
'; // class="ficheaddleft" + print '
'; // class="fichehalfright" + print '
'; // class="fichecenter" + } + print '
'; /* * List discount consumed (=liees a une ligne de facture ou facture) */ + + print load_fiche_titre($langs->trans("DiscountAlreadyCounted")); + + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print '
'; + print '
'; + } // Remises liees a lignes de factures $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; @@ -471,6 +671,7 @@ if ($socid > 0) $sql.= " AND rc.fk_facture_line = fc.rowid"; $sql.= " AND fc.fk_facture = f.rowid"; $sql.= " AND rc.fk_user = u.rowid"; + $sql.= " AND rc.discount_type = 0"; // Eliminate supplier discounts $sql.= " ORDER BY dc DESC"; //$sql.= " UNION "; // Remises liees a factures @@ -487,7 +688,7 @@ if ($socid > 0) $sql2.= " WHERE rc.fk_soc =". $object->id; $sql2.= " AND rc.fk_facture = f.rowid"; $sql2.= " AND rc.fk_user = u.rowid"; - + $sql2.= " AND rc.discount_type = 0"; // Eliminate supplier discounts $sql2.= " ORDER BY dc DESC"; $resql=$db->query($sql); @@ -495,7 +696,9 @@ if ($socid > 0) if ($resql) $resql2=$db->query($sql2); if ($resql2) { - print load_fiche_titre($langs->trans("DiscountAlreadyCounted")); + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print load_fiche_titre($langs->trans("CustomerDiscounts"), '', ''); // TODO translate + } print ''; print ''; print ''; // Need 120+ for format with AM/PM @@ -598,6 +801,159 @@ if ($socid > 0) dol_print_error($db); } + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print ''; // class="fichehalfleft" + print '
'; + print '
'; + + // Remises liees a lignes de factures + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql.= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line, rc.fk_invoice_supplier,"; + $sql.= " rc.fk_invoice_supplier_source,"; + $sql.= " u.login, u.rowid as user_id,"; + $sql.= " f.rowid, f.ref as facnumber,"; + $sql.= " fa.ref, fa.type as type"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; + $sql.= " , ".MAIN_DB_PREFIX."user as u"; + $sql.= " , ".MAIN_DB_PREFIX."facture_fourn_det as fc"; + $sql.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as fa ON rc.fk_invoice_supplier_source = fa.rowid"; + $sql.= " WHERE rc.fk_soc =". $object->id; + $sql.= " AND rc.fk_invoice_supplier_line = fc.rowid"; + $sql.= " AND fc.fk_facture_fourn = f.rowid"; + $sql.= " AND rc.fk_user = u.rowid"; + $sql.= " AND rc.discount_type = 1"; // Eliminate customer discounts + $sql.= " ORDER BY dc DESC"; + //$sql.= " UNION "; + // Remises liees a factures + $sql2 = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql2.= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line, rc.fk_invoice_supplier,"; + $sql2.= " rc.fk_invoice_supplier_source,"; + $sql2.= " u.login, u.rowid as user_id,"; + $sql2.= " f.rowid, f.ref as facnumber,"; + $sql2.= " fa.ref, fa.type as type"; + $sql2.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; + $sql2.= " , ".MAIN_DB_PREFIX."user as u"; + $sql2.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as fa ON rc.fk_invoice_supplier_source = fa.rowid"; + $sql2.= " WHERE rc.fk_soc =". $object->id; + $sql2.= " AND rc.fk_invoice_supplier = f.rowid"; + $sql2.= " AND rc.fk_user = u.rowid"; + $sql2.= " AND rc.discount_type = 1"; // Eliminate customer discounts + $sql2.= " ORDER BY dc DESC"; + + $resql=$db->query($sql); + $resql2=null; + if ($resql) $resql2=$db->query($sql2); + if ($resql2) + { + print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); // TODO translate + print '
'.$langs->trans("Date").'
'; + print ''; + print ''; // Need 120+ for format with AM/PM + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $tab_sqlobj=array(); + $tab_sqlobjOrder=array(); + $num = $db->num_rows($resql); + if ($num > 0) + { + for ($i = 0;$i < $num; $i++) + { + $sqlobj = $db->fetch_object($resql); + $tab_sqlobj[] = $sqlobj; + $tab_sqlobjOrder[]=$db->jdate($sqlobj->dc); + } + } + $db->free($resql); + + $num = $db->num_rows($resql2); + for ($i = 0;$i < $num;$i++) + { + $sqlobj = $db->fetch_object($resql2); + $tab_sqlobj[] = $sqlobj; + $tab_sqlobjOrder[]= $db->jdate($sqlobj->dc); + } + $db->free($resql2); + array_multisort($tab_sqlobjOrder,SORT_DESC,$tab_sqlobj); + + $num = count($tab_sqlobj); + if ($num > 0) + { + $i = 0 ; + while ($i < $num ) + { + $obj = array_shift($tab_sqlobj); + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS PAID\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; // TODO adapt to supplier invoice of use getNomUrl + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $i++; + } + } + else + { + print ''; + } + + print "
'.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").''.$langs->trans("AmountTTC").''.$langs->trans("Author").' 
'.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(EXCESS PAID\)/',$langs->trans("Invoice"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + print $obj->description; + print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; // TODO getNomUrl ? + print ' 
'.$langs->trans("None").'
"; + } + else + { + dol_print_error($db); + } + + print '
'; // class="ficheaddleft" + print '
'; // class="fichehalfright" + print '
'; // class="fichecenter" + } } llxFooter(); diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index c8aa11996b6..b62e35c183e 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -34,6 +34,7 @@ class DiscountAbsolute public $id; // Id discount public $fk_soc; + public $discount_type; // 0 => customer discount, 1 => supplier discount public $amount_ht; // public $amount_tva; // public $amount_ttc; // @@ -76,7 +77,7 @@ class DiscountAbsolute return -1; } - $sql = "SELECT sr.rowid, sr.fk_soc,"; + $sql = "SELECT sr.rowid, sr.fk_soc, sr.discount_type,"; $sql.= " sr.fk_user,"; $sql.= " sr.amount_ht, sr.amount_tva, sr.amount_ttc, sr.tva_tx,"; $sql.= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,"; @@ -101,6 +102,7 @@ class DiscountAbsolute $this->id = $obj->rowid; $this->fk_soc = $obj->fk_soc; + $this->discount_type = $obj->discount_type; $this->amount_ht = $obj->amount_ht; $this->amount_tva = $obj->amount_tva; @@ -166,11 +168,11 @@ class DiscountAbsolute // Insert request $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_except"; - $sql.= " (entity, datec, fk_soc, fk_user, description,"; + $sql.= " (entity, datec, fk_soc, discount_type, fk_user, description,"; $sql.= " amount_ht, amount_tva, amount_ttc, tva_tx,"; $sql.= " fk_facture_source, fk_invoice_supplier_source"; $sql.= ")"; - $sql.= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec!=''?$this->datec:dol_now())."', ".$this->fk_soc.", ".$user->id.", '".$this->db->escape($this->description)."',"; + $sql.= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec!=''?$this->datec:dol_now())."', ".$this->fk_soc.", ".(empty($this->discount_type)?0:intval($this->discount_type)).", ".$user->id.", '".$this->db->escape($this->description)."',"; $sql.= " ".$this->amount_ht.", ".$this->amount_tva.", ".$this->amount_ttc.", ".$this->tva_tx.","; $sql.= " ".($this->fk_facture_source ? "'".$this->db->escape($this->fk_facture_source)."'":"null").","; $sql.= " ".($this->fk_invoice_supplier_source ? "'".$this->db->escape($this->fk_invoice_supplier_source)."'":"null"); @@ -202,7 +204,7 @@ class DiscountAbsolute global $conf, $langs; // Check if we can remove the discount - if ($this->fk_facture_source) // TODO check + if ($this->fk_facture_source) { $sql="SELECT COUNT(rowid) as nb"; $sql.=" FROM ".MAIN_DB_PREFIX."societe_remise_except"; @@ -228,15 +230,46 @@ class DiscountAbsolute return -1; } } + + // Check if we can remove the discount + if ($this->fk_invoice_supplier_source) + { + $sql="SELECT COUNT(rowid) as nb"; + $sql.=" FROM ".MAIN_DB_PREFIX."societe_remise_except"; + $sql.=" WHERE (fk_invoice_supplier_line IS NOT NULL"; // Not used as absolute simple discount + $sql.=" OR fk_invoice_supplier IS NOT NULL)"; // Not used as credit note and not used as deposit + $sql.=" AND fk_invoice_supplier_source = ".$this->fk_invoice_supplier_source; + //$sql.=" AND rowid != ".$this->id; + + dol_syslog(get_class($this)."::delete Check if we can remove discount", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + if ($obj->nb > 0) + { + $this->error='ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved'; + return -2; + } + } + else + { + dol_print_error($this->db); + return -1; + } + } $this->db->begin(); // Delete but only if not used $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_remise_except "; if ($this->fk_facture_source) $sql.= " WHERE fk_facture_source = ".$this->fk_facture_source; // Delete all lines of same serie + elseif ($this->fk_invoice_supplier_source) $sql.= " WHERE fk_invoice_supplier_source = ".$this->fk_invoice_supplier_source; // Delete all lines of same serie else $sql.= " WHERE rowid = ".$this->id; // Delete only line $sql.= " AND (fk_facture_line IS NULL"; // Not used as absolute simple discount $sql.= " AND fk_facture IS NULL)"; // Not used as credit note and not used as deposit + $sql.= " AND (fk_invoice_supplier_line IS NULL"; // Not used as absolute simple discount + $sql.= " AND fk_invoice_supplier IS NULL)"; // Not used as credit note and not used as deposit dol_syslog(get_class($this)."::delete Delete discount", LOG_DEBUG); $result=$this->db->query($sql); @@ -263,6 +296,26 @@ class DiscountAbsolute return -1; } } + elseif($this->fk_invoice_supplier_source) { + + $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn"; + $sql.=" set paye=0, fk_statut=1"; + $sql.=" WHERE (type = 2 or type = 3) AND rowid=".$this->fk_invoice_supplier_source; + + dol_syslog(get_class($this)."::delete Update credit note or deposit invoice statut", LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } else { $this->db->commit(); @@ -286,10 +339,9 @@ class DiscountAbsolute * * @param int $rowidline Invoice line id (To use discount into invoice lines) * @param int $rowidinvoice Invoice id (To use discount as a credit note to reduc payment of invoice) - * @param string $mode 'supplier' to link to supplier invoice, 'customer' instead * @return int <0 if KO, >0 if OK */ - function link_to_invoice($rowidline,$rowidinvoice,$mode='customer') + function link_to_invoice($rowidline,$rowidinvoice) { // Check parameters if (! $rowidline && ! $rowidinvoice) @@ -304,7 +356,7 @@ class DiscountAbsolute } $sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except"; - if($mode == 'supplier') { + if(! empty($this->discount_type)) { if ($rowidline) $sql.=" SET fk_invoice_supplier_line = ".$rowidline; if ($rowidinvoice) $sql.=" SET fk_invoice_supplier = ".$rowidinvoice; } else { @@ -317,7 +369,7 @@ class DiscountAbsolute $resql = $this->db->query($sql); if ($resql) { - if($mode == 'supplier') { + if(! empty($this->discount_type)) { $this->fk_invoice_supplier_line=$rowidline; $this->fk_invoice_supplier=$rowidinvoice; } else { @@ -338,13 +390,12 @@ class DiscountAbsolute * Link the discount to a particular invoice line or a particular invoice. * Do not call this if discount is linked to a reconcialiated invoice * - * @param string $mode 'supplier' to unlink a supplier invoice, 'customer' instead * @return int <0 if KO, >0 if OK */ - function unlink_invoice($mode = 'customer') + function unlink_invoice() { $sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except"; - if($mode = 'supplier') { + if(! empty($this->discount_type)) { $sql.=" SET fk_invoice_supplier_line = NULL, fk_invoice_supplier = NULL"; } else { $sql.=" SET fk_facture_line = NULL, fk_facture = NULL"; @@ -368,14 +419,14 @@ class DiscountAbsolute /** * Return amount (with tax) of discounts currently available for a company, user or other criteria * - * @param Societe $company Object third party for filter - * @param User $user Filtre sur un user auteur des remises - * @param string $filter Filtre autre - * @param int $maxvalue Filter on max value for discount - * @param string $mode 'customer' = discounts the customer has, 'supplier' = discount i have at this supplier + * @param Societe $company Object third party for filter + * @param User $user Filtre sur un user auteur des remises + * @param string $filter Filtre autre + * @param int $maxvalue Filter on max value for discount + * @param int $discount_type 0 => customer discount, 1 => supplier discount * @return int <0 if KO, amount otherwise */ - function getAvailableDiscounts($company='', $user='',$filter='', $maxvalue=0, $mode='customer') + function getAvailableDiscounts($company='', $user='',$filter='', $maxvalue=0, $discount_type=0) { global $conf; @@ -383,8 +434,12 @@ class DiscountAbsolute //$sql = "SELECT rc.amount_ttc as amount"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; $sql.= " WHERE rc.entity = " . $conf->entity; - if ($mode == 'supplier') $sql.= " AND (rc.fk_facture_source IS NULL AND rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available - else $sql.= " AND (rc.fk_invoice_supplier_source IS NULL AND rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; // Available + $sql.= " AND rc.discount_type=".intval($discount_type); + if (! empty($discount_type)) { + $sql.= " AND (rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; // Available from supplier + } else { + $sql.= " AND (rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available to customer + } if (is_object($company)) $sql.= " AND rc.fk_soc = ".$company->id; if (is_object($user)) $sql.= " AND rc.fk_user = ".$user->id; if ($filter) $sql.=' AND ('.$filter.')'; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 8a1cc6ac33c..e6ab69dff95 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4220,10 +4220,10 @@ class Form * @param int $maxvalue Max value for lines that can be selected * @param string $more More string to add * @param int $hidelist 1=Hide list - * @param string $mode 'supplier' to list available discounts for suppliers, 'customer' instead + * @param int $discount_type 0 => customer discount, 1 => supplier discount * @return void */ - function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0, $mode='customer') + function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0, $discount_type=0) { global $conf,$langs; if ($htmlname != "none") @@ -4232,7 +4232,7 @@ class Form print ''; print ''; print '
'; - if($mode == 'supplier') { + if(! empty($discount_type)) { if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { if (! $filter || $filter=="fk_invoice_supplier IS NOT NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice @@ -4260,11 +4260,10 @@ class Form if (empty($hidelist)) { print '
'; - if($mode == 'supplier') { - $newfilter = 'fk_facture_source IS NULL AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Exclude customer discounts + $newfilter = 'discount_type='.intval($discount_type); + if(! empty($discount_type)) { $newfilter.= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available } else { - $newfilter = 'fk_invoice_supplier_source IS NULL AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Exclude supplier discounts $newfilter.= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available } if ($filter) $newfilter.=' AND ('.$filter.')'; @@ -4272,9 +4271,9 @@ class Form if ($nbqualifiedlines > 0) { print '   '; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b23c9af5fce..198954572d1 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2672,7 +2672,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->error = $this->db->lasterror(); } } - + // TODO free discount linked to line as in customer invoice if (! $error) { $this->db->commit(); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index a397d40d147..e3c68177b41 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -133,7 +133,7 @@ if (empty($reshook)) $object->fetch_thirdparty(); $result = $object->add_object_linked('order_supplier', GETPOST('linkedOrder')); } - + var_dump($conf->global->MAIN_VERSION_LAST_UPGRADE, $conf->global->MAIN_VERSION_LAST_INSTALL); // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes') { @@ -272,7 +272,7 @@ if (empty($reshook)) { $discount = new DiscountAbsolute($db); $result = $discount->fetch(GETPOST("discountid")); - $discount->unlink_invoice('supplier'); + $discount->unlink_invoice(); } elseif ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer) @@ -419,7 +419,7 @@ if (empty($reshook)) if (! $error) { - $result = $discount->link_to_invoice(0, $id, 'supplier'); + $result = $discount->link_to_invoice(0, $id); if ($result < 0) { setEventMessages($discount->error, $discount->errors, 'errors'); } @@ -486,6 +486,7 @@ if (empty($reshook)) else { setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors'); } + $discount->discount_type = 1; // Supplier discount $discount->fk_soc = $object->socid; $discount->fk_invoice_supplier_source = $object->id; @@ -1679,7 +1680,7 @@ if ($action == 'create') if ($societe->id > 0) { - $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 'supplier'); + $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1); print $societe->getNomUrl(1); print ''; } @@ -2143,12 +2144,12 @@ else $filterabsolutediscount = "fk_invoice_supplier IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice $filtercreditnote = "fk_invoice_supplier IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice } else { - $filterabsolutediscount = "fk_invoice_supplier IS NOT NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')"; + $filterabsolutediscount = "fk_invoice_supplier IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')"; $filtercreditnote = "fk_invoice_supplier IS NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')"; } - $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 'supplier'); - $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 'supplier'); + $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1); + $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1); $absolute_discount = price2num($absolute_discount, 'MT'); $absolute_creditnote = price2num($absolute_creditnote, 'MT'); @@ -2442,7 +2443,7 @@ else } else { // Discount available of type fixed amount (not credit note) print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $societe->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')', 0, 'supplier'); + $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $societe->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')', 0, 1); } } else { if ($absolute_creditnote > 0) // If not, link will be added later @@ -2468,9 +2469,9 @@ else } else { // We can add a credit note on a down payment or standard invoice or situation invoice // There is credit notes discounts available if (! $absolute_discount) print '
'; - // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, $resteapayer, '', 0, 'supplier'); + // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, $resteapayer, '', 0, 1); $more=' ('.$addcreditnote. (($addcreditnote && $viewabsolutediscount) ? ' - ' : '') . $viewabsolutediscount . ')'; - $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, 0, $more, 0, 'supplier'); // We allow credit note even if amount is higher + $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, 0, $more, 0, 1); // We allow credit note even if amount is higher } } if (! $absolute_discount && ! $absolute_creditnote) { diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql index 9bfe0bd2915..bfc2c79a679 100644 --- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -35,3 +35,4 @@ ALTER TABLE llx_projet ADD COLUMN bill_time integer DEFAULT 0; ALTER TABLE llx_societe ADD COLUMN order_min_amount double(24,8) DEFAULT NULL AFTER outstanding_limit; ALTER TABLE llx_societe ADD COLUMN supplier_order_min_amount double(24,8) DEFAULT NULL AFTER order_min_amount; +ALTER TABLE llx_societe_remise_except ADD COLUMN discount_type integer DEFAULT 0 NOT NULL AFTER fk_soc; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql index 148a8777915..525af592041 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql @@ -26,6 +26,7 @@ ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_soc ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_line (fk_facture_line); ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture (fk_facture); ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_source (fk_facture_source); +ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_discount_type (discount_type); ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid); diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.sql index 3a19a026ca9..151e33d7f1e 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_except.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_except.sql @@ -23,7 +23,8 @@ create table llx_societe_remise_except ( rowid integer AUTO_INCREMENT PRIMARY KEY, entity integer DEFAULT 1 NOT NULL, -- multi company id - fk_soc integer NOT NULL, -- client + fk_soc integer NOT NULL, -- customer or supplier + discount_type integer DEFAULT 0 NOT NULL, -- 0 => customer, 1 => supplier datec datetime, amount_ht double(24,8) NOT NULL, amount_tva double(24,8) DEFAULT 0 NOT NULL, diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 4adfae72258..2e980ba7ff8 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1661,13 +1661,14 @@ class Societe extends CommonObject /** * Add a discount for third party * - * @param float $remise Amount of discount - * @param User $user User adding discount - * @param string $desc Reason of discount - * @param float $tva_tx VAT rate + * @param float $remise Amount of discount + * @param User $user User adding discount + * @param string $desc Reason of discount + * @param float $tva_tx VAT rate + * @param int $discount_type 0 => customer discount, 1 => supplier discount * @return int <0 if KO, id of discount record if OK */ - function set_remise_except($remise, User $user, $desc, $tva_tx=0) + function set_remise_except($remise, User $user, $desc, $tva_tx=0, $discount_type=0) { global $langs; @@ -1693,11 +1694,13 @@ class Societe extends CommonObject $discount = new DiscountAbsolute($this->db); $discount->fk_soc=$this->id; + $discount->discount_type=$discount_type; $discount->amount_ht=price2num($remise,'MT'); $discount->amount_tva=price2num($remise*$tva_tx/100,'MT'); $discount->amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT'); $discount->tva_tx=price2num($tva_tx,'MT'); $discount->description=$desc; + $result=$discount->create($user); if ($result > 0) { @@ -1715,18 +1718,18 @@ class Societe extends CommonObject /** * Renvoie montant TTC des reductions/avoirs en cours disponibles de la societe * - * @param User $user Filtre sur un user auteur des remises - * @param string $filter Filtre autre - * @param integer $maxvalue Filter on max value for discount - * @param string $mode 'supplier' to get available discounts for suppliers, 'customer' instead + * @param User $user Filtre sur un user auteur des remises + * @param string $filter Filtre autre + * @param integer $maxvalue Filter on max value for discount + * @param int $discount_type 0 => customer discount, 1 => supplier discount * @return int <0 if KO, Credit note amount otherwise */ - function getAvailableDiscounts($user='',$filter='',$maxvalue=0,$mode='customer') + function getAvailableDiscounts($user='',$filter='',$maxvalue=0,$discount_type=0) { require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; $discountstatic=new DiscountAbsolute($this->db); - $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$mode); + $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$discount_type); if ($result >= 0) { return $result; From ea2e46cccd091eb3ae07a40389eed178a6a5690c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 14 Feb 2018 20:46:40 +0100 Subject: [PATCH 114/386] Update chargesociales.class.php --- htdocs/compta/sociales/class/chargesociales.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index b6386ae3b98..07b7d1a5ae7 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -191,7 +191,7 @@ class ChargeSociales extends CommonObject $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX."chargesociales"); //dol_syslog("ChargesSociales::create this->id=".$this->id); - $result=$this->call_trigger('PAYMENTSOCIALECONTRIBUTION_CREATE',$user); + $result=$this->call_trigger('PAYMENTSOCIALCONTRIBUTION_CREATE',$user); if ($result < 0) $error++; if(empty($error)) { From 78697c1735a0861c4136ddde0314433aed614bef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 14 Feb 2018 21:14:24 +0100 Subject: [PATCH 115/386] USe fk_product is better than ref --- htdocs/comm/propal/card.php | 10 ++++++---- htdocs/core/class/commondocgenerator.class.php | 18 +++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8bd9f7ffa98..54e3cf36c45 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -104,8 +104,11 @@ if ($id > 0 || ! empty($ref)) { $ret = $object->fetch($id, $ref); if ($ret > 0) $ret = $object->fetch_thirdparty(); - if ($ret < 0) - dol_print_error('', $object->error); + if ($ret <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action = ''; + } } // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -1711,7 +1714,7 @@ if ($action == 'create') print ''; } -} else { +} elseif ($object->id > 0) { /* * Show object in view mode */ @@ -1818,7 +1821,6 @@ if ($action == 'create') $linkback = '' . $langs->trans("BackToList") . ''; - $morehtmlref='
'; // Ref customer $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->propal->creer, 'string', '', 0, 1); diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 015173f1f05..aeca3d5a102 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -425,7 +425,7 @@ abstract class CommonDocGenerator { $object->fetch_projet(); } - + $resarray[$array_key.'_project_ref'] = $object->project->ref; $resarray[$array_key.'_project_title'] = $object->project->title; $resarray[$array_key.'_project_description'] = $object->project->description; @@ -510,7 +510,7 @@ abstract class CommonDocGenerator 'line_multicurrency_total_tva_locale' => price($line->multicurrency_total_tva, 0, $outputlangs), 'line_multicurrency_total_ttc_locale' => price($line->multicurrency_total_ttc, 0, $outputlangs), ); - + // Units if ($conf->global->PRODUCT_USE_UNITS) { @@ -527,16 +527,16 @@ abstract class CommonDocGenerator $line->fetch_optionals($line->rowid,$extralabels); $resarray = $this->fill_substitutionarray_with_extrafields($line,$resarray,$extrafields,$array_key=$array_key,$outputlangs); - + // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" - if (isset($line->product_ref)) + if (isset($line->fk_product) && $line->fk_product > 0) { - $product = new Product($this->db); - $result = $product->fetch(null, $line->product_ref); - foreach($product->array_options as $key=>$label) + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($line->fk_product); + foreach($tmpproduct->array_options as $key=>$label) $resarray["line_".$key] = $label; - } - + } + return $resarray; } From 51028c845de6e827f48ae26fe2de1d14c3eec682 Mon Sep 17 00:00:00 2001 From: Gerhard Stephan Date: Thu, 15 Feb 2018 10:15:27 +0100 Subject: [PATCH 116/386] Export to PDF using LibreOffice 5 command line --- htdocs/includes/odtphp/odf.php | 143 ++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 65 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 19fd3390937..0b3501be6be 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -574,85 +574,98 @@ IMG; dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); $this->saveToDisk($name); - $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 - // Method 1 sometimes hang the server. - - if (preg_match('/unoconv/', $conf->global->MAIN_ODT_AS_PDF)) + // Export to PDF using LibreOffice + if ($conf->global->MAIN_ODT_AS_PDF == 'libreoffice') { - // If issue with unoconv, see https://github.com/dagwieers/unoconv/issues/87 - - // MAIN_ODT_AS_PDF should be "sudo -u unoconv /usr/bin/unoconv" and userunoconv must have sudo to be root by adding file /etc/sudoers.d/unoconv with content www-data ALL=(unoconv) NOPASSWD: /usr/bin/unoconv . - - // Try this with www-data user: /usr/bin/unoconv -vvvv -f pdf /tmp/document-example.odt - // It must return: - //Verbosity set to level 4 - //Using office base path: /usr/lib/libreoffice - //Using office binary path: /usr/lib/libreoffice/program - //DEBUG: Connection type: socket,host=127.0.0.1,port=2002;urp;StarOffice.ComponentContext - //DEBUG: Existing listener not found. - //DEBUG: Launching our own listener using /usr/lib/libreoffice/program/soffice.bin. - //LibreOffice listener successfully started. (pid=9287) - //Input file: /tmp/document-example.odt - //unoconv: file `/tmp/document-example.odt' does not exist. - //unoconv: RuntimeException during import phase: - //Office probably died. Unsupported URL : "type detection failed" - //DEBUG: Terminating LibreOffice instance. - //DEBUG: Waiting for LibreOffice instance to exit - - // It fails: - // - set shel of user to bash instead of nologin. - // - set permission to read/write to user on home directory /var/www so user can create the libreoffice , dconf and .cache dir and files then set permission back - - $command = $conf->global->MAIN_ODT_AS_PDF.' '.escapeshellcmd($name); - //$command = '/usr/bin/unoconv -vvv '.escapeshellcmd($name); + // Executing convert to PDF using libreoffice 5 (using windows libreoffice must be in path) + $command ='soffice.exe -headless -convert-to pdf -outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); + exec($command, $output_arr, $retval); + + // Split extension from name to allow deleting the source using MAIN_ODT_AS_PDF_DEL_SOURCE + $name=preg_replace('/\.odt/i', '', $name); } else { - // deprecated old method - $name=preg_replace('/\.odt/i', '', $name); + $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 + // Method 1 sometimes hang the server. - if (!empty($conf->global->MAIN_DOL_SCRIPTS_ROOT)) + if (preg_match('/unoconv/', $conf->global->MAIN_ODT_AS_PDF)) { - $command = $conf->global->MAIN_DOL_SCRIPTS_ROOT.'/scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($name).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); + // If issue with unoconv, see https://github.com/dagwieers/unoconv/issues/87 + + // MAIN_ODT_AS_PDF should be "sudo -u unoconv /usr/bin/unoconv" and userunoconv must have sudo to be root by adding file /etc/sudoers.d/unoconv with content www-data ALL=(unoconv) NOPASSWD: /usr/bin/unoconv . + + // Try this with www-data user: /usr/bin/unoconv -vvvv -f pdf /tmp/document-example.odt + // It must return: + //Verbosity set to level 4 + //Using office base path: /usr/lib/libreoffice + //Using office binary path: /usr/lib/libreoffice/program + //DEBUG: Connection type: socket,host=127.0.0.1,port=2002;urp;StarOffice.ComponentContext + //DEBUG: Existing listener not found. + //DEBUG: Launching our own listener using /usr/lib/libreoffice/program/soffice.bin. + //LibreOffice listener successfully started. (pid=9287) + //Input file: /tmp/document-example.odt + //unoconv: file `/tmp/document-example.odt' does not exist. + //unoconv: RuntimeException during import phase: + //Office probably died. Unsupported URL : "type detection failed" + //DEBUG: Terminating LibreOffice instance. + //DEBUG: Waiting for LibreOffice instance to exit + + // It fails: + // - set shel of user to bash instead of nologin. + // - set permission to read/write to user on home directory /var/www so user can create the libreoffice , dconf and .cache dir and files then set permission back + + $command = $conf->global->MAIN_ODT_AS_PDF.' '.escapeshellcmd($name); + //$command = '/usr/bin/unoconv -vvv '.escapeshellcmd($name); } else { - dol_syslog(get_class($this).'::exportAsAttachedPDF is used but the constant MAIN_DOL_SCRIPTS_ROOT with path to script directory was not defined.', LOG_WARNING); - $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($name).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); - } - } + // deprecated old method + $name=preg_replace('/\.odt/i', '', $name); - //$dirname=dirname($name); - //$command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name.' '.$dirname; - - dol_syslog(get_class($this).'::exportAsAttachedPDF $execmethod='.$execmethod.' Run command='.$command,LOG_DEBUG); - if ($execmethod == 1) - { - exec($command, $output_arr, $retval); - } - if ($execmethod == 2) - { - $outputfile = DOL_DATA_ROOT.'/odt2pdf.log'; - - $ok=0; - $handle = fopen($outputfile, 'w'); - if ($handle) - { - dol_syslog(get_class($this)."Run command ".$command,LOG_DEBUG); - fwrite($handle, $command."\n"); - $handlein = popen($command, 'r'); - while (!feof($handlein)) + if (!empty($conf->global->MAIN_DOL_SCRIPTS_ROOT)) { - $read = fgets($handlein); - fwrite($handle, $read); - $output_arr[]=$read; + $command = $conf->global->MAIN_DOL_SCRIPTS_ROOT.'/scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($name).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); + } + else + { + dol_syslog(get_class($this).'::exportAsAttachedPDF is used but the constant MAIN_DOL_SCRIPTS_ROOT with path to script directory was not defined.', LOG_WARNING); + $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($name).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); } - pclose($handlein); - fclose($handle); } - if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); - } + //$dirname=dirname($name); + //$command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name.' '.$dirname; + + dol_syslog(get_class($this).'::exportAsAttachedPDF $execmethod='.$execmethod.' Run command='.$command,LOG_DEBUG); + if ($execmethod == 1) + { + exec($command, $output_arr, $retval); + } + if ($execmethod == 2) + { + $outputfile = DOL_DATA_ROOT.'/odt2pdf.log'; + + $ok=0; + $handle = fopen($outputfile, 'w'); + if ($handle) + { + dol_syslog(get_class($this)."Run command ".$command,LOG_DEBUG); + fwrite($handle, $command."\n"); + $handlein = popen($command, 'r'); + while (!feof($handlein)) + { + $read = fgets($handlein); + fwrite($handle, $read); + $output_arr[]=$read; + } + pclose($handlein); + fclose($handle); + } + if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + } + if ($retval == 0) { dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); From 3ffc67105260f2fdc875ec70b291abf34e6500c7 Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Thu, 15 Feb 2018 10:47:32 +0100 Subject: [PATCH 117/386] Add phone format for several countries --- htdocs/core/lib/functions.lib.php | 254 +++++++++++++++++++++++++++++- 1 file changed, 252 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 457f8068c0e..89e31d00703 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2223,13 +2223,263 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep } } - if (strtoupper($countrycode) == "CA") + elseif (strtoupper($countrycode) == "CA") { if (dol_strlen($phone) == 10) { $newphone=($separ!=''?'(':'').substr($newphone,0,3).($separ!=''?')':'').$separ.substr($newphone,3,3).($separ!=''?'-':'').substr($newphone,6,4); } } - + elseif (strtoupper($parameters['countrycode']) == "PT" ) + {//Portugal + if (dol_strlen($object) == 13) + {//ex: +351_ABC_DEF_GHI + $newphone= substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "SR" ) + {//Suriname + if (dol_strlen($object) == 10) + {//ex: +597_ABC_DEF + $newphone= substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3); + } + elseif (dol_strlen($object) == 11) + {//ex: +597_ABC_DEFG + $newphone= substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,4); + } + } + elseif (strtoupper($parameters['countrycode']) == "DE" ) + {//Allemagne + if (dol_strlen($object) == 14) + {//ex: +49_ABCD_EFGH_IJK + $newphone= substr($newphone,0,3).$separ.substr($newphone,3,4).$separ.substr($newphone,7,4).$separ.substr($newphone,11,3); + } + elseif (dol_strlen($object) == 13) + {//ex: +49_ABC_DEFG_HIJ + $newphone= substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,4).$separ.substr($newphone,10,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "ES") + {//Espagne + if (dol_strlen($object) == 12) + {//ex: +34_ABC_DEF_GHI + $newphone= substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "BF") + {// Burkina Faso + if (dol_strlen($newphone) == 12) + {//ex : +22 A BC_DE_FG_HI + $newphone= substr($newphone,0,3).$separ.substr($newphone,3,1).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "RO") + {// Roumanie + if (dol_strlen($newphone) == 12) + {//ex : +40 AB_CDE_FG_HI + $newphone= substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "TR") + {//Turquie + if (dol_strlen($object) == 13) + {//ex : +90 ABC_DEF_GHIJ + $newphone= substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,4); + } + } + elseif (strtoupper($parameters['countrycode']) == "US") + {//Etat-Unis + if (dol_strlen($newphone) == 12) + {//ex: +1 ABC_DEF_GHIJ + $newphone= substr($newphone,0,2).$separ.substr($newphone,2,3).$separ.substr($newphone,5,3).$separ.substr($newphone,8,4); + } + } + elseif (strtoupper($parameters['countrycode']) == "MX") + {//Mexique + if (dol_strlen($newphone) == 12) + {//ex: +52 ABCD_EFG_HI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,4).$separ.substr($newphone,7,3).$separ.substr($newphone,10,2); + } + elseif (dol_strlen($newphone) == 11) + {//ex: +52 AB_CD_EF_GH + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,2).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2); + } + elseif (dol_strlen($newphone) == 13) + {//ex: +52 ABC_DEF_GHIJ + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,4); + } + } + elseif (strtoupper($parameters['countrycode']) == "ML") + {//Mali + if(dol_strlen($newphone) == 12) + {//ex: +223 AB_CD_EF_GH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "TH") + {//Thaïlande + if(dol_strlen($newphone) == 11) + {//ex: +66_ABC_DE_FGH + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,2).$separ.substr($newphone,8,3); + } + elseif(dol_strlen($newphone) == 12) + {//ex: +66_A_BCD_EF_GHI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,1).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "MU") + {//Maurice + if(dol_strlen($newphone) == 11) + {//ex: +230_ABC_DE_FG + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2); + } + elseif(dol_strlen($newphone) == 12) + {//ex: +230_ABCD_EF_GH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,4).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "ZA") + {//Afrique du sud + if(dol_strlen($newphone) == 12) + {//ex: +27_AB_CDE_FG_HI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "SY") + {//Syrie + if(dol_strlen($newphone) == 12) + {//ex: +963_AB_CD_EF_GH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + elseif(dol_strlen($newphone) == 13) + {//ex: +963_AB_CD_EF_GHI + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "AE") + {//Emirats Arabes Unis + if(dol_strlen($newphone) == 12) + {//ex: +971_ABC_DEF_GH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,2); + } + elseif(dol_strlen($newphone) == 13) + {//ex: +971_ABC_DEF_GHI + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); + } + elseif(dol_strlen($newphone) == 14) + {//ex: +971_ABC_DEF_GHIK + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,4); + } + } + elseif (strtoupper($parameters['countrycode']) == "DZ") + {//Algérie + if(dol_strlen($newphone) == 13) + {//ex: +213_ABC_DEF_GHI + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "BE") + {//Belgique + if(dol_strlen($newphone) == 11) + {//ex: +32_ABC_DE_FGH + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,2).$separ.substr($newphone,8,3); + } + elseif(dol_strlen($newphone) == 12) + {//ex: +32_ABC_DEF_GHI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "PF") + {//Polynésie française + if(dol_strlen($newphone) == 12) + {//ex: +689_AB_CD_EF_GH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "CO") + {//Colombie + if(dol_strlen($newphone) == 13) + {//ex: +57_ABC_DEF_GH_IJ + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "JO") + {//Jordanie + if(dol_strlen($newphone) == 12) + {//ex: +962_A_BCD_EF_GH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,1).$separ.substr($newphone,5,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "MG") + {//Madagascar + if(dol_strlen($newphone) == 13) + {//ex: +261_AB_CD_EF_GHI + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "GB") + {//Royaume uni + if(dol_strlen($newphone) == 13) + {//ex: +44_ABCD_EFG_HIJ + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,4).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "CH") + {//Suisse + if(dol_strlen($newphone) == 12) + {//ex: +41_AB_CDE_FG_HI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); + } + elseif(dol_strlen($newphone) == 15) + {// +41_AB_CDE_FGH_IJKL + $newphone =$newphone = substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,3).$separ.substr($newphone,11,4); + } + } + elseif (strtoupper($parameters['countrycode']) == "TN") + {//Tunisie + if(dol_strlen($newphone) == 12) + {//ex: +216_AB_CDE_FGH + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); + } + } + elseif (strtoupper($parameters['countrycode']) == "GF") + {//Guyane francaise + if(dol_strlen($newphone) == 13) + {//ex: +594_ABC_DE_FG_HI (ABC=594 de nouveau) + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "GP") + {//Guadeloupe + if(dol_strlen($newphone) == 13) + {//ex: +590_ABC_DE_FG_HI (ABC=590 de nouveau) + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "MQ") + {//Martinique + if(dol_strlen($newphone) == 13) + {//ex: +596_ABC_DE_FG_HI (ABC=596 de nouveau) + $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); + } + } + elseif (strtoupper($parameters['countrycode']) == "IT") + {//Italie + if(dol_strlen($newphone) == 12) + {//ex: +39_ABC_DEF_GHI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); + } + elseif(dol_strlen($newphone) == 13) + {//ex: +39_ABC_DEF_GH_IJ + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); + } + } + elseif(strtoupper($parameters['countrycode']) == "AU") + {//Australie + if(dol_strlen($newphone) == 12) + {//ex: +61_A_BCDE_FGHI + $newphone = substr($newphone,0,3).$separ.substr($newphone,3,1).$separ.substr($newphone,4,4).$separ.substr($newphone,8,4); + } + } if (! empty($addlink)) // Link on phone number (+ link to add action if conf->global->AGENDA_ADDACTIONFORPHONE set) { if (! empty($conf->browser->phone) || (! empty($conf->clicktodial->enabled) && ! empty($conf->global->CLICKTODIAL_USE_TEL_LINK_ON_PHONE_NUMBERS))) // If phone or option for, we use link of phone From d547d1a9cf6cc82c2c969cedb0a762f356e8e792 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 15 Feb 2018 13:15:21 +0100 Subject: [PATCH 118/386] Suggest better change for #8196. To be tested. --- htdocs/includes/odtphp/odf.php | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 19fd3390937..77201ed9178 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -561,7 +561,7 @@ IMG; * Convert the ODT file to PDF and export the file as attached file by HTTP * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh * - * @param string $name (optional) + * @param string $name Name of ODT file to generate before generating PDF * @throws OdfException * @return void */ @@ -577,7 +577,23 @@ IMG; $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 // Method 1 sometimes hang the server. - if (preg_match('/unoconv/', $conf->global->MAIN_ODT_AS_PDF)) + + // Export to PDF using LibreOffice + if ($conf->global->MAIN_ODT_AS_PDF == 'libreoffice') + { + // Executing convert to PDF using libreoffice 5 + if (isset($_SERVER["WINDIR"])) + { + // using windows libreoffice that must be in path + $command ='soffice.exe -headless -convert-to pdf -outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); + } + else + { + // using linux/mac libreoffice that must be in path + $command ='soffice -headless -convert-to pdf -outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); + } + } + elseif (preg_match('/unoconv/', $conf->global->MAIN_ODT_AS_PDF)) { // If issue with unoconv, see https://github.com/dagwieers/unoconv/issues/87 @@ -609,16 +625,16 @@ IMG; else { // deprecated old method - $name=preg_replace('/\.odt/i', '', $name); + $tmpname=preg_replace('/\.odt/i', '', $name); if (!empty($conf->global->MAIN_DOL_SCRIPTS_ROOT)) { - $command = $conf->global->MAIN_DOL_SCRIPTS_ROOT.'/scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($name).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); + $command = $conf->global->MAIN_DOL_SCRIPTS_ROOT.'/scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($tmpname).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); } else { dol_syslog(get_class($this).'::exportAsAttachedPDF is used but the constant MAIN_DOL_SCRIPTS_ROOT with path to script directory was not defined.', LOG_WARNING); - $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($name).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); + $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($tmpname).' '.(is_numeric($conf->global->MAIN_ODT_AS_PDF)?'jodconverter':$conf->global->MAIN_ODT_AS_PDF); } } @@ -661,12 +677,15 @@ IMG; } if (!empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $name=preg_replace('/\.od(x|t)/i', '', $name); header('Content-type: application/pdf'); header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); - readfile("$name.pdf"); + readfile($name.".pdf"); } if (!empty($conf->global->MAIN_ODT_AS_PDF_DEL_SOURCE)) - unlink("$name.odt"); + { + unlink($name); + } } else { dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); From 0172ecb425b50c59c60f0cbf2937bc2537c268da Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 15 Feb 2018 13:21:58 +0100 Subject: [PATCH 119/386] Code comment --- htdocs/includes/odtphp/odf.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 77201ed9178..5119a533d84 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -585,6 +585,7 @@ IMG; if (isset($_SERVER["WINDIR"])) { // using windows libreoffice that must be in path + // Note PHP Config "fastcgi.impersonate=0" must set to 0 - Default is 1 $command ='soffice.exe -headless -convert-to pdf -outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name); } else From 9965a25eaa11ef87fe07bbf076c06197193205e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 15 Feb 2018 13:23:13 +0100 Subject: [PATCH 120/386] Code comment --- htdocs/includes/odtphp/odf.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 5119a533d84..dd39f97c9f7 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -616,8 +616,8 @@ IMG; //DEBUG: Terminating LibreOffice instance. //DEBUG: Waiting for LibreOffice instance to exit - // It fails: - // - set shel of user to bash instead of nologin. + // If it fails: + // - set shell of user to bash instead of nologin. // - set permission to read/write to user on home directory /var/www so user can create the libreoffice , dconf and .cache dir and files then set permission back $command = $conf->global->MAIN_ODT_AS_PDF.' '.escapeshellcmd($name); From 634f3bc025fe7e5ffed57d3ace07df6b6d12b582 Mon Sep 17 00:00:00 2001 From: dolibarr95 <24292300+dolibarr95@users.noreply.github.com> Date: Thu, 15 Feb 2018 13:38:21 +0100 Subject: [PATCH 121/386] Bad copy/paste --- htdocs/core/lib/functions.lib.php | 58 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 89e31d00703..3c1dcab3378 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2229,14 +2229,14 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone=($separ!=''?'(':'').substr($newphone,0,3).($separ!=''?')':'').$separ.substr($newphone,3,3).($separ!=''?'-':'').substr($newphone,6,4); } } - elseif (strtoupper($parameters['countrycode']) == "PT" ) + elseif (strtoupper($countrycode) == "PT" ) {//Portugal if (dol_strlen($object) == 13) {//ex: +351_ABC_DEF_GHI $newphone= substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); } } - elseif (strtoupper($parameters['countrycode']) == "SR" ) + elseif (strtoupper($countrycode) == "SR" ) {//Suriname if (dol_strlen($object) == 10) {//ex: +597_ABC_DEF @@ -2247,7 +2247,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone= substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,4); } } - elseif (strtoupper($parameters['countrycode']) == "DE" ) + elseif (strtoupper($countrycode) == "DE" ) {//Allemagne if (dol_strlen($object) == 14) {//ex: +49_ABCD_EFGH_IJK @@ -2258,42 +2258,42 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone= substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,4).$separ.substr($newphone,10,3); } } - elseif (strtoupper($parameters['countrycode']) == "ES") + elseif (strtoupper($countrycode) == "ES") {//Espagne if (dol_strlen($object) == 12) {//ex: +34_ABC_DEF_GHI $newphone= substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); } } - elseif (strtoupper($parameters['countrycode']) == "BF") + elseif (strtoupper($countrycode) == "BF") {// Burkina Faso if (dol_strlen($newphone) == 12) {//ex : +22 A BC_DE_FG_HI $newphone= substr($newphone,0,3).$separ.substr($newphone,3,1).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); } } - elseif (strtoupper($parameters['countrycode']) == "RO") + elseif (strtoupper($countrycode) == "RO") {// Roumanie if (dol_strlen($newphone) == 12) {//ex : +40 AB_CDE_FG_HI $newphone= substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); } } - elseif (strtoupper($parameters['countrycode']) == "TR") + elseif (strtoupper($countrycode) == "TR") {//Turquie if (dol_strlen($object) == 13) {//ex : +90 ABC_DEF_GHIJ $newphone= substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,4); } } - elseif (strtoupper($parameters['countrycode']) == "US") + elseif (strtoupper($countrycode) == "US") {//Etat-Unis if (dol_strlen($newphone) == 12) {//ex: +1 ABC_DEF_GHIJ $newphone= substr($newphone,0,2).$separ.substr($newphone,2,3).$separ.substr($newphone,5,3).$separ.substr($newphone,8,4); } } - elseif (strtoupper($parameters['countrycode']) == "MX") + elseif (strtoupper($countrycode) == "MX") {//Mexique if (dol_strlen($newphone) == 12) {//ex: +52 ABCD_EFG_HI @@ -2308,14 +2308,14 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,4); } } - elseif (strtoupper($parameters['countrycode']) == "ML") + elseif (strtoupper($countrycode) == "ML") {//Mali if(dol_strlen($newphone) == 12) {//ex: +223 AB_CD_EF_GH $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); } } - elseif (strtoupper($parameters['countrycode']) == "TH") + elseif (strtoupper($countrycode) == "TH") {//Thaïlande if(dol_strlen($newphone) == 11) {//ex: +66_ABC_DE_FGH @@ -2326,7 +2326,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,3).$separ.substr($newphone,3,1).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,3); } } - elseif (strtoupper($parameters['countrycode']) == "MU") + elseif (strtoupper($countrycode) == "MU") {//Maurice if(dol_strlen($newphone) == 11) {//ex: +230_ABC_DE_FG @@ -2337,14 +2337,14 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,4).$separ.substr($newphone,4,4).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); } } - elseif (strtoupper($parameters['countrycode']) == "ZA") + elseif (strtoupper($countrycode) == "ZA") {//Afrique du sud if(dol_strlen($newphone) == 12) {//ex: +27_AB_CDE_FG_HI $newphone = substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); } } - elseif (strtoupper($parameters['countrycode']) == "SY") + elseif (strtoupper($countrycode) == "SY") {//Syrie if(dol_strlen($newphone) == 12) {//ex: +963_AB_CD_EF_GH @@ -2355,7 +2355,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,3); } } - elseif (strtoupper($parameters['countrycode']) == "AE") + elseif (strtoupper($countrycode) == "AE") {//Emirats Arabes Unis if(dol_strlen($newphone) == 12) {//ex: +971_ABC_DEF_GH @@ -2370,14 +2370,14 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,4); } } - elseif (strtoupper($parameters['countrycode']) == "DZ") + elseif (strtoupper($countrycode) == "DZ") {//Algérie if(dol_strlen($newphone) == 13) {//ex: +213_ABC_DEF_GHI $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); } } - elseif (strtoupper($parameters['countrycode']) == "BE") + elseif (strtoupper($countrycode) == "BE") {//Belgique if(dol_strlen($newphone) == 11) {//ex: +32_ABC_DE_FGH @@ -2388,42 +2388,42 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); } } - elseif (strtoupper($parameters['countrycode']) == "PF") + elseif (strtoupper($countrycode) == "PF") {//Polynésie française if(dol_strlen($newphone) == 12) {//ex: +689_AB_CD_EF_GH $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,2); } } - elseif (strtoupper($parameters['countrycode']) == "CO") + elseif (strtoupper($countrycode) == "CO") {//Colombie if(dol_strlen($newphone) == 13) {//ex: +57_ABC_DEF_GH_IJ $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); } } - elseif (strtoupper($parameters['countrycode']) == "JO") + elseif (strtoupper($countrycode) == "JO") {//Jordanie if(dol_strlen($newphone) == 12) {//ex: +962_A_BCD_EF_GH $newphone = substr($newphone,0,4).$separ.substr($newphone,4,1).$separ.substr($newphone,5,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2); } } - elseif (strtoupper($parameters['countrycode']) == "MG") + elseif (strtoupper($countrycode) == "MG") {//Madagascar if(dol_strlen($newphone) == 13) {//ex: +261_AB_CD_EF_GHI $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,2).$separ.substr($newphone,8,2).$separ.substr($newphone,10,3); } } - elseif (strtoupper($parameters['countrycode']) == "GB") + elseif (strtoupper($countrycode) == "GB") {//Royaume uni if(dol_strlen($newphone) == 13) {//ex: +44_ABCD_EFG_HIJ $newphone = substr($newphone,0,3).$separ.substr($newphone,3,4).$separ.substr($newphone,7,3).$separ.substr($newphone,10,3); } } - elseif (strtoupper($parameters['countrycode']) == "CH") + elseif (strtoupper($countrycode) == "CH") {//Suisse if(dol_strlen($newphone) == 12) {//ex: +41_AB_CDE_FG_HI @@ -2434,35 +2434,35 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone =$newphone = substr($newphone,0,3).$separ.substr($newphone,3,2).$separ.substr($newphone,5,3).$separ.substr($newphone,8,3).$separ.substr($newphone,11,4); } } - elseif (strtoupper($parameters['countrycode']) == "TN") + elseif (strtoupper($countrycode) == "TN") {//Tunisie if(dol_strlen($newphone) == 12) {//ex: +216_AB_CDE_FGH $newphone = substr($newphone,0,4).$separ.substr($newphone,4,2).$separ.substr($newphone,6,3).$separ.substr($newphone,9,3); } } - elseif (strtoupper($parameters['countrycode']) == "GF") + elseif (strtoupper($countrycode) == "GF") {//Guyane francaise if(dol_strlen($newphone) == 13) {//ex: +594_ABC_DE_FG_HI (ABC=594 de nouveau) $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); } } - elseif (strtoupper($parameters['countrycode']) == "GP") + elseif (strtoupper($countrycode) == "GP") {//Guadeloupe if(dol_strlen($newphone) == 13) {//ex: +590_ABC_DE_FG_HI (ABC=590 de nouveau) $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); } } - elseif (strtoupper($parameters['countrycode']) == "MQ") + elseif (strtoupper($countrycode) == "MQ") {//Martinique if(dol_strlen($newphone) == 13) {//ex: +596_ABC_DE_FG_HI (ABC=596 de nouveau) $newphone = substr($newphone,0,4).$separ.substr($newphone,4,3).$separ.substr($newphone,7,2).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); } } - elseif (strtoupper($parameters['countrycode']) == "IT") + elseif (strtoupper($countrycode) == "IT") {//Italie if(dol_strlen($newphone) == 12) {//ex: +39_ABC_DEF_GHI @@ -2473,7 +2473,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $newphone = substr($newphone,0,3).$separ.substr($newphone,3,3).$separ.substr($newphone,6,3).$separ.substr($newphone,9,2).$separ.substr($newphone,11,2); } } - elseif(strtoupper($parameters['countrycode']) == "AU") + elseif(strtoupper($countrycode) == "AU") {//Australie if(dol_strlen($newphone) == 12) {//ex: +61_A_BCDE_FGHI From 93965e857baa5d4ed5d5ff18f70ef2b6ad67183b Mon Sep 17 00:00:00 2001 From: Gerhard Stephan Date: Thu, 15 Feb 2018 16:02:13 +0100 Subject: [PATCH 122/386] fetched from dolibarr/dolibarr --- ChangeLog | 8 +- htdocs/adherents/type.php | 4 +- htdocs/comm/propal/card.php | 10 +- htdocs/compta/facture/class/facture.class.php | 3 + .../sociales/class/chargesociales.class.php | 14 +- htdocs/compta/tva/class/tva.class.php | 3 + htdocs/contrat/card.php | 16 +- htdocs/contrat/services_list.php | 3 +- htdocs/contrat/tpl/linkedobjectblock.tpl.php | 17 +- htdocs/core/actions_linkedfiles.inc.php | 85 ++++-- .../core/class/commondocgenerator.class.php | 18 +- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/class/html.form.class.php | 11 +- htdocs/core/class/html.formfile.class.php | 61 +++- htdocs/core/class/translate.class.php | 2 +- htdocs/core/lib/ajax.lib.php | 18 -- htdocs/core/lib/company.lib.php | 2 +- htdocs/core/lib/files.lib.php | 7 +- htdocs/core/lib/functions.lib.php | 276 +++++++++++++++++- htdocs/core/lib/images.lib.php | 2 +- .../commande/doc/pdf_einstein.modules.php | 12 +- htdocs/core/modules/modBlockedLog.class.php | 4 +- htdocs/core/modules/modWebsite.class.php | 2 +- htdocs/core/tpl/ajaxrow.tpl.php | 3 +- htdocs/document.php | 31 +- htdocs/ecm/file_card.php | 4 - htdocs/fourn/card.php | 33 ++- .../fourn/class/fournisseur.facture.class.php | 2 + htdocs/install/check.php | 6 +- htdocs/install/repair.php | 64 +++- htdocs/install/step5.php | 6 + htdocs/install/upgrade2.php | 177 ++++++++++- htdocs/langs/en_US/companies.lang | 10 +- htdocs/langs/en_US/install.lang | 2 + htdocs/langs/en_US/website.lang | 6 +- htdocs/product/class/product.class.php | 40 ++- htdocs/product/fournisseurs.php | 4 +- htdocs/product/list.php | 4 +- htdocs/societe/card.php | 4 +- htdocs/viewimage.php | 112 ++++++- htdocs/website/class/websitepage.class.php | 2 + htdocs/website/index.php | 24 +- test/phpunit/CodingPhpTest.php | 4 +- 43 files changed, 926 insertions(+), 192 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b985647586..8c04eaf7a42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,11 +14,13 @@ Following changes may create regressions for some external modules, but were nec ***** ChangeLog for 7.0.0 compared to 6.0.5 ***** For users: +NEW: Add a preview icon after files that can be previewed (pdf + images) NEW: When payment is registered, PDF of invoices are also regenerated so payments appears with no need to click on regenerate. NEW: #5711 Add shipment line deleting and editing for draft shipments. +NEW: Accept substitution key __(ABC)__ replaced with value of translation of key ABC NEW: Accept substitution key __[ABC]__ replaced with value of const ABC -NEW: Accountancy Add variant on sell account for intracommunity sales & export sales +NEW: Accountancy Add fields for sale accounting account for intracommunity sales & export sales NEW: Add a button "Activate all services" on contracts NEW: Add a confirmation for all mass action 'delete' NEW: Add a group task line for tasks on same level on gantt diagram @@ -583,7 +585,9 @@ Following changes may create regression for some external modules, but were nece exists, but if an external module need action on it, it must provides itself its trigger file. * Use $conf->global->MULTICOMPANY_TRANSVERSE_MODE instead $conf->multicompany->transverse_mode. So, if you set var $multicompany_transverse_mode to 1 into your conf file, you must remove this line and a new key into - the Home - setup - other admin page. + the Home - setup - other admin page. +* If you use Multicompany transverse mode, it will be necessary to check the activation of the modules in the children + entities and to review completely the rights of the groups and the users. * Use getEntity('xxx') instead getEntity('xxx', 1) and use getEntity('xxx', 0) instead getEntity('xxx') * Some other change were done in the way we read permission of a user when module multicompany is enabled. You can retreive the old behavior by adding constant MULTICOMPANY_BACKWARD_COMPATIBILITY to 1. diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index eb44809178f..cc9fd872062 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -107,7 +107,7 @@ if ($action == 'add' && $user->rights->adherent->configurer) $object->subscription = (int) trim($subscription); $object->note = trim($comment); $object->mail_valid = trim($mail_valid); - $object->vote = trim($vote); + $object->vote = (boolean) trim($vote); // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost($extralabels,$object); @@ -160,7 +160,7 @@ if ($action == 'update' && $user->rights->adherent->configurer) $object->subscription = (int) trim($subscription); $object->note = trim($comment); $object->mail_valid = trim($mail_valid); - $object->vote = trim($vote); + $object->vote = (boolean) trim($vote); // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost($extralabels,$object); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8bd9f7ffa98..54e3cf36c45 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -104,8 +104,11 @@ if ($id > 0 || ! empty($ref)) { $ret = $object->fetch($id, $ref); if ($ret > 0) $ret = $object->fetch_thirdparty(); - if ($ret < 0) - dol_print_error('', $object->error); + if ($ret <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action = ''; + } } // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -1711,7 +1714,7 @@ if ($action == 'create') print ''; } -} else { +} elseif ($object->id > 0) { /* * Show object in view mode */ @@ -1818,7 +1821,6 @@ if ($action == 'create') $linkback = '' . $langs->trans("BackToList") . ''; - $morehtmlref='
'; // Ref customer $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->propal->creer, 'string', '', 0, 1); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 35ab14454ef..12d6fa10769 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3004,6 +3004,9 @@ class Facture extends CommonInvoice $line->total_ttc = $tabprice[2]; $line->total_localtax1 = $tabprice[9]; $line->total_localtax2 = $tabprice[10]; + $line->multicurrency_total_ht = $tabprice[16]; + $line->multicurrency_total_tva = $tabprice[17]; + $line->multicurrency_total_ttc = $tabprice[18]; $line->update($user); $this->update_price(1); $this->db->commit(); diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index 61728562d2e..2d75584cbda 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -156,6 +156,7 @@ class ChargeSociales extends CommonObject function create($user) { global $conf; + $error=0; $now=dol_now(); @@ -191,8 +192,17 @@ class ChargeSociales extends CommonObject $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX."chargesociales"); //dol_syslog("ChargesSociales::create this->id=".$this->id); - $this->db->commit(); - return $this->id; + $result=$this->call_trigger('PAYMENTSOCIALCONTRIBUTION_CREATE',$user); + if ($result < 0) $error++; + + if(empty($error)) { + $this->db->commit(); + return $this->id; + } + else { + $this->db->rollback(); + return -1*$error; + } } else { diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php index d575d1a97b9..c9db79e6202 100644 --- a/htdocs/compta/tva/class/tva.class.php +++ b/htdocs/compta/tva/class/tva.class.php @@ -670,6 +670,9 @@ class Tva extends CommonObject $linkclose=''; if (empty($notooltip)) { + + + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label=$langs->trans("ShowMyObject"); diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 92290ee0656..c2b6e03ee5b 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1561,7 +1561,7 @@ else if ($action != 'editline' || GETPOST('rowid') != $objp->rowid) { - print ''; + print ''; // Label if ($objp->fk_product > 0) { @@ -1571,12 +1571,10 @@ else $productstatic->ref=$objp->pref; $productstatic->entity=$objp->pentity; $productstatic->label=$objp->plabel; - $text = $productstatic->getNomUrl(1,'',20); + $text = $productstatic->getNomUrl(1,'',32); if ($objp->plabel) { $text .= ' - '; - //$productstatic->ref=$objp->label; - //$text .= $productstatic->getNomUrl(0,'',16); $text .= $objp->plabel; } $description = $objp->description; @@ -1713,8 +1711,8 @@ else $productstatic->type=$objp->ptype; $productstatic->ref=$objp->pref; $productstatic->entity=$objp->pentity; - print $productstatic->getNomUrl(1,'',20); - print $objp->label?' - '.dol_trunc($objp->label,16):''; + print $productstatic->getNomUrl(1,'',32); + print $objp->label?' - '.dol_trunc($objp->label,32):''; print '
'; } else @@ -1822,7 +1820,7 @@ else 'text' => $langs->trans("ConfirmMoveToAnotherContractQuestion"), array('type' => 'select', 'name' => 'newcid', 'values' => $arraycontractid)); - $form->form_confirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'),$langs->trans("MoveToAnotherContract"),$langs->trans("ConfirmMoveToAnotherContract"),"confirm_move",$formquestion); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'),$langs->trans("MoveToAnotherContract"),$langs->trans("ConfirmMoveToAnotherContract"),"confirm_move",$formquestion); print '
'; } @@ -1834,7 +1832,7 @@ else $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); $comment = GETPOST('comment','alpha'); - $form->form_confirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment),$langs->trans("ActivateService"),$langs->trans("ConfirmActivateService",dol_print_date($dateactstart,"%A %d %B %Y")),"confirm_active", '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment),$langs->trans("ActivateService"),$langs->trans("ConfirmActivateService",dol_print_date($dateactstart,"%A %d %B %Y")),"confirm_active", '', 0, 1); print '
'; } @@ -1853,7 +1851,7 @@ else } else { - $form->form_confirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne','int')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment), $langs->trans("CloseService"), $langs->trans("ConfirmCloseService",dol_print_date($dateactend,"%A %d %B %Y")), "confirm_closeline", '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne','int')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment), $langs->trans("CloseService"), $langs->trans("ConfirmCloseService",dol_print_date($dateactend,"%A %d %B %Y")), "confirm_closeline", '', 0, 1); } print '
'; } diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 5bede6be358..108fb6d4403 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -75,7 +75,7 @@ $opclotureyear=GETPOST('opclotureyear'); $filter_opcloture=GETPOST('filter_opcloture'); // Initialize context for list -$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'servicelist'.$mode; +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'contractservicelist'.$mode; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array($contextpage)); @@ -483,7 +483,6 @@ if (! empty($arrayfields['cd.date_cloture']['checked'])) print ''; } // Extra fields -// Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index e0b76ba689b..a44f20679b8 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -1,5 +1,6 @@ + * Copyright (C) 2018 Juanjo Menent * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,10 +51,22 @@ foreach($linkedObjectBlock as $key => $objectlink) getNomUrl(1); ?> date_contrat,'day'); ?> - total_ttc); ?> + rights->contrat->lire && empty($conf->global->CONTRACT_SHOW_TOTAL_OF_PRODUCT_AS_PRICE)) + { + $totalcontrat = 0; + foreach ($objectlink->lines as $linecontrat) { + $totalcontrat = $totalcontrat + $linecontrat->total_ht; + $total = $total + $linecontrat->total_ht; + } + echo price($totalcontrat); + } ?> getLibStatut(7); ?> ">transnoentitiesnoconv("RemoveLink")); ?> - \ No newline at end of file + diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php index 0e0c444af33..7f938ba9b6c 100644 --- a/htdocs/core/actions_linkedfiles.inc.php +++ b/htdocs/core/actions_linkedfiles.inc.php @@ -182,37 +182,70 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave','alpha')) $filenamefrom=dol_sanitizeFileName(GETPOST('renamefilefrom','alpha'), '_', 0); // Do not remove accents $filenameto=dol_sanitizeFileName(GETPOST('renamefileto','alpha'), '_', 0); // Do not remove accents - // Security: - // Disallow file with some extensions. We rename them. - // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. - if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$filenameto) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + if ($filenamefrom != $filenameto) { - $filenameto.= '.noexe'; - } + // Security: + // Disallow file with some extensions. We rename them. + // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code. + if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$filenameto) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) + { + $filenameto.= '.noexe'; + } - if ($filenamefrom && $filenameto) - { - $srcpath = $upload_dir.'/'.$filenamefrom; - $destpath = $upload_dir.'/'.$filenameto; + if ($filenamefrom && $filenameto) + { + $srcpath = $upload_dir.'/'.$filenamefrom; + $destpath = $upload_dir.'/'.$filenameto; - $result = dol_move($srcpath, $destpath); - if ($result) - { - if ($object->id) - { - $object->addThumbs($destpath); - } + $result = dol_move($srcpath, $destpath); + if ($result) + { + if ($object->id) + { + $object->addThumbs($destpath); + } - // TODO Add revert function of addThumbs to remove for old name - //$object->delThumbs($srcpath); + // TODO Add revert function of addThumbs to remove for old name + //$object->delThumbs($srcpath); - setEventMessages($langs->trans("FileRenamed"), null); - } - else - { - $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now. - setEventMessages($langs->trans("ErrorFailToRenameFile", $filenamefrom, $filenameto), null, 'errors'); - } + setEventMessages($langs->trans("FileRenamed"), null); + } + else + { + $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now. + setEventMessages($langs->trans("ErrorFailToRenameFile", $filenamefrom, $filenameto), null, 'errors'); + } + } } } + + // Update properties in ECM table + if (GETPOST('ecmfileid', 'int') > 0) + { + $shareenabled = GETPOST('shareenabled', 'alpha'); + + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(GETPOST('ecmfileid', 'int')); + if ($result > 0) + { + if ($shareenabled) + { + if (empty($ecmfile->share)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $ecmfile->share = getRandomPassword(true); + } + } + else + { + $ecmfile->share = ''; + } + $result = $ecmfile->update($user); + if ($result < 0) + { + setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); + } + } + } } diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 015173f1f05..aeca3d5a102 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -425,7 +425,7 @@ abstract class CommonDocGenerator { $object->fetch_projet(); } - + $resarray[$array_key.'_project_ref'] = $object->project->ref; $resarray[$array_key.'_project_title'] = $object->project->title; $resarray[$array_key.'_project_description'] = $object->project->description; @@ -510,7 +510,7 @@ abstract class CommonDocGenerator 'line_multicurrency_total_tva_locale' => price($line->multicurrency_total_tva, 0, $outputlangs), 'line_multicurrency_total_ttc_locale' => price($line->multicurrency_total_ttc, 0, $outputlangs), ); - + // Units if ($conf->global->PRODUCT_USE_UNITS) { @@ -527,16 +527,16 @@ abstract class CommonDocGenerator $line->fetch_optionals($line->rowid,$extralabels); $resarray = $this->fill_substitutionarray_with_extrafields($line,$resarray,$extrafields,$array_key=$array_key,$outputlangs); - + // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" - if (isset($line->product_ref)) + if (isset($line->fk_product) && $line->fk_product > 0) { - $product = new Product($this->db); - $result = $product->fetch(null, $line->product_ref); - foreach($product->array_options as $key=>$label) + $tmpproduct = new Product($this->db); + $result = $tmpproduct->fetch($line->fk_product); + foreach($tmpproduct->array_options as $key=>$label) $resarray["line_".$key] = $label; - } - + } + return $resarray; } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 69002d9ae93..0dd9a245136 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3496,7 +3496,7 @@ abstract class CommonObject /** * Return if a country is inside the EEC (European Economic Community) - * @deprecated + * @deprecated Use function isInEEC function instead * * @return boolean true = country inside EEC, false = country outside EEC */ diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cbd2eb5c3b3..4e8f67d6552 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -646,9 +646,10 @@ class Form * @param integer $maxlength Max length for labels (0=no limit) * @param string $morecss More css class * @param string $usecodeaskey 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key + * @param int $showempty Show empty choice * @return string HTML string with select */ - function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300',$usecodeaskey='') + function select_country($selected='', $htmlname='country_id', $htmloption='', $maxlength=0, $morecss='minwidth300', $usecodeaskey='', $showempty=1) { global $conf,$langs; @@ -693,20 +694,22 @@ class Form foreach ($countryArray as $row) { + if (empty($showempty) && empty($row['rowid'])) continue; + if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++; if (empty($row['favorite']) && $atleastonefavorite) { $atleastonefavorite=0; - $out.= ''; + $out.= ''; } if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) ) { $foundselected=true; - $out.= '