diff --git a/COPYRIGHT b/COPYRIGHT index aedcb1be614..c43d77581a7 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,13 +1,24 @@ -License -------- +Copyright and license +---------------------- -Dolibarr is released 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 (GPL-3+). -More information: https://www.gnu.org/licenses/gpl-3.0.txt +The Dolibarr software as a whole is distributed under 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 (GPL-3+). More information: https://www.gnu.org/licenses/gpl-3.0.txt. +A copy of this license is available in the COPYING file. +Dolibarr depends on third-party components and code snippets released under their own license (obviously, all compatible with the one of Dolibarr). +These dependencies are listed in the bottom of this file. -Dolibarr uses some external libraries released under different licenses. This is compatibility summary: + +The Dolibarr images resources (available in the doc directory) is distributed under the Creative Commons Attribution 4.0 International license (CC BY 4.0). + + +The name Dolibarr is a trademark initially registered by Laurent Destailleur and ceased to the Dolibarr foundation. You can use the name Dolibarr +for your own need as long as you follow the rules defined on the page https://wiki.dolibarr.org/index.php/Rules_to_use_the_brand_name_%22Dolibarr%22 +The use of the name DoliStore is also restricted to the same rules defined on https://wiki.dolibarr.org/index.php/Rules_to_use_the_brand_name_%22Dolibarr%22 + + + +Licence of dependencies of third-party components used by Dolibarr (all compatible with the Licence of Dolibarr): Component Version License GPL Compatible Usage ------------------------------------------------------------------------------------- @@ -28,7 +39,7 @@ php-iban 1.4.7 LGPL-3+ Yes PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests PSR/Logs 1.0 Library for logs (used by DebugBar) -PSR/simple-cache ? MIT License Yes Library for cache (used by PHPSpreadSheet) +PSR/simple-cache ? MIT License Yes Library for cache (used by PHPSpreadSheet) Restler 3.1.1 LGPL-3+ Yes Library to develop REST Web services (+ swagger-ui js lib into dir explorer) Sabre 3.2.2 BSD Yes DAV support Swift Mailer 5.4.2-DEV MIT License Yes Comprehensive mailing tools for PHP @@ -63,11 +74,10 @@ Font libraries: Fontawesome 5.13 Font Awesome Free Licence Yes -For licenses compatibility informations: -https://www.gnu.org/licenses/licenses.en.html +For more licenses compatibility informations: https://www.gnu.org/licenses/licenses.en.html -Copyright / Authors +Authors ------------------- See page https://github.com/Dolibarr/dolibarr/graphs/contributors diff --git a/ChangeLog b/ChangeLog index bb44e0fa0be..50a0ff10131 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,8 @@ NEW: Add a performance center page with all information and advices related to t NEW: A lot of fix into english text after a small proofreading campaign (still not perfect, but really better) NEW: All main menu entries are using the picto of the module NEW: Add a copy to clipboard button on some fields -NEW: Add an example of scheduled job to send email reminder for unpayed invoices +NEW: Add an example of scheduled job to send email reminder for unpayed invoices +NEW: Can make massive stock transfers from a CSV file. NEW: Accountancy - Add FEC import NEW: Accountancy - Add a confirmation form with options on export NEW: Accountancy - Add select date from/to in already bind customer and supplier list @@ -159,6 +160,7 @@ NEW: #13739 #17390 Product API route added to get product stock and product with WARNING: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* Module SimplePOS is deprecated. If you need a POS module, please use the module TakePOS. * The ICS value for direct debit or credit transfer is now store on each bank account instead of into the global setup. * API /setup/shipment_methods has been replaced with API /setup/shipping_methods * Field "total" renamed into to "total_ht" for table llx_facture, llx_facture_rec for better field name consistency @@ -167,7 +169,7 @@ Following changes may create regressions for some external modules, but were nec * If your database is PostgreSql, you must use version 9.1.0 or more (Dolibarr need the SQL function CONCAT) * If your database is MySql or MariaDB, you need at least version 5.1 * Function set_price_level() has been renamed into setPriceLevel() to follow camelcase rules - +* Remove deprecated subtituion key __REFCLIENT__ (Replaced with __REF_CLIENT__) ***** ChangeLog for 13.0.3 compared to 13.0.2 ***** diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 9ea62de9048..4f80f06d444 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -245,6 +245,14 @@ RESTLER: // @CHANGE LDR if (!is_string($haystack)) return false; +* Replace + + $loaders = array_unique(static::$rogueLoaders); + + with + + $loaders = array_unique(static::$rogueLoaders, SORT_REGULAR); + +With swagger 2 provided into /explorer: ---------------------------------------- diff --git a/dev/initdemo/mysqldump_dolibarr_3.5.0.sql b/dev/initdemo/mysqldump_dolibarr_3.5.0.sql index 46053d1a187..252643afb59 100644 --- a/dev/initdemo/mysqldump_dolibarr_3.5.0.sql +++ b/dev/initdemo/mysqldump_dolibarr_3.5.0.sql @@ -5503,7 +5503,7 @@ CREATE TABLE `llx_product` ( LOCK TABLES `llx_product` WRITE; /*!40000 ALTER TABLE `llx_product` DISABLE KEYS */; -INSERT INTO `llx_product` VALUES (1,'2010-07-08 14:33:17','2013-03-12 09:30:24',0,0,'PIDRESS',1,NULL,'Pink dress','A beatifull pink dress','',NULL,NULL,100.00000000,112.50000000,90.00000000,101.25000000,'HT',12.500,0,0.000,0.000,1,1,1,0,'',20,NULL,0,'','',NULL,100,0,NULL,0,NULL,0,NULL,0,2,0.00000000,NULL,1,0,NULL,0),(2,'2010-07-09 00:30:01','2013-01-19 17:31:58',0,0,'Product_P1',1,NULL,'Product P1','','','',32,0.00000000,0.00000000,0.00000000,0.00000000,'HT',12.500,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,998,0.00000000,NULL,0,0,NULL,0),(3,'2010-07-09 00:30:25','2012-12-08 13:11:14',0,0,'Service_S1',1,NULL,'Service S1','','',NULL,NULL,0.00000000,0.00000000,0.00000000,0.00000000,'HT',12.500,0,0.000,0.000,1,1,1,1,'1m',NULL,NULL,0,'','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0.00000000,NULL,0,0,NULL,0),(4,'2010-07-10 14:44:06','2013-01-19 17:22:48',0,0,'DECAP',1,NULL,'Decapsuleur','','',NULL,NULL,5.00000000,5.62500000,0.00000000,0.00000000,'HT',12.500,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,2,-3,NULL,0,NULL,0,NULL,0,1001,10.00000000,NULL,1,0,NULL,0),(5,'2011-07-20 23:11:38','2011-07-27 17:02:59',0,0,'aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(6,'2011-07-29 22:16:44','2011-07-29 20:16:44',0,0,'Copy_of_aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,0,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(7,'2011-07-29 22:31:21','2011-07-29 20:31:21',0,0,'Copy_of_Copy_of_aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,0,0,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(8,'2011-07-29 22:46:54','2011-07-29 20:46:54',0,0,'Copy_of_Copy_of_Copy_of_aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,0,0,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(10,'2008-12-31 00:00:00','2012-12-08 13:11:14',0,0,'PR123456',1,NULL,'My product','This is a description example for record','Some note',NULL,NULL,100.00000000,110.00000000,0.00000000,0.00000000,'HT',10.000,0,0.000,0.000,NULL,0,0,0,'1y',0,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0.00000000,NULL,NULL,0,'20110729232310',0),(11,'2013-01-13 20:24:42','2013-01-19 17:22:48',0,0,'gh',1,NULL,'hfghf','','','',NULL,0.00000000,0.00000000,0.00000000,0.00000000,'HT',0.000,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,-1,0.00000000,'',1,0,NULL,0); +INSERT INTO `llx_product` VALUES (1,'2010-07-08 14:33:17','2013-03-12 09:30:24',0,0,'PINKDRESS',1,NULL,'Pink dress','A beatifull pink dress','',NULL,NULL,100.00000000,112.50000000,90.00000000,101.25000000,'HT',12.500,0,0.000,0.000,1,1,1,0,'',20,NULL,0,'','',NULL,100,0,NULL,0,NULL,0,NULL,0,2,0.00000000,NULL,1,0,NULL,0),(2,'2010-07-09 00:30:01','2013-01-19 17:31:58',0,0,'Product_P1',1,NULL,'Product P1','','','',32,0.00000000,0.00000000,0.00000000,0.00000000,'HT',12.500,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,998,0.00000000,NULL,0,0,NULL,0),(3,'2010-07-09 00:30:25','2012-12-08 13:11:14',0,0,'Service_S1',1,NULL,'Service S1','','',NULL,NULL,0.00000000,0.00000000,0.00000000,0.00000000,'HT',12.500,0,0.000,0.000,1,1,1,1,'1m',NULL,NULL,0,'','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0.00000000,NULL,0,0,NULL,0),(4,'2010-07-10 14:44:06','2013-01-19 17:22:48',0,0,'DECAP',1,NULL,'Decapsuleur','','',NULL,NULL,5.00000000,5.62500000,0.00000000,0.00000000,'HT',12.500,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,2,-3,NULL,0,NULL,0,NULL,0,1001,10.00000000,NULL,1,0,NULL,0),(5,'2011-07-20 23:11:38','2011-07-27 17:02:59',0,0,'aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(6,'2011-07-29 22:16:44','2011-07-29 20:16:44',0,0,'Copy_of_aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,0,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(7,'2011-07-29 22:31:21','2011-07-29 20:31:21',0,0,'Copy_of_Copy_of_aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,0,0,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(8,'2011-07-29 22:46:54','2011-07-29 20:46:54',0,0,'Copy_of_Copy_of_Copy_of_aaaa',1,NULL,'aaaa','cccc','bbbb','',NULL,10.00000000,11.96000000,0.00000000,0.00000000,'HT',19.600,0,0.000,0.000,1,0,0,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,NULL,0.00000000,'',1,0,NULL,0),(10,'2008-12-31 00:00:00','2012-12-08 13:11:14',0,0,'PR123456',1,NULL,'My product','This is a description example for record','Some note',NULL,NULL,100.00000000,110.00000000,0.00000000,0.00000000,'HT',10.000,0,0.000,0.000,NULL,0,0,0,'1y',0,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0.00000000,NULL,NULL,0,'20110729232310',0),(11,'2013-01-13 20:24:42','2013-01-19 17:22:48',0,0,'gh',1,NULL,'hfghf','','','',NULL,0.00000000,0.00000000,0.00000000,0.00000000,'HT',0.000,0,0.000,0.000,1,1,1,0,'',NULL,NULL,0,'','',NULL,NULL,0,NULL,0,NULL,0,NULL,0,-1,0.00000000,'',1,0,NULL,0); /*!40000 ALTER TABLE `llx_product` ENABLE KEYS */; UNLOCK TABLES; diff --git a/doc/images/README.md b/doc/images/README.md index 7422d246d40..e93c9f9c3d4 100644 --- a/doc/images/README.md +++ b/doc/images/README.md @@ -10,17 +10,16 @@ https://github.com/Dolibarr/foundation -* Few icons are / were from website led24.de -* Attention: This website is no longer available! +# LICENCE OF IMAGE RESOURCES +-------------------------------- -This is original README file for this source: -------------------------------------------------------- +* All image resources (except dolihelp.ico and doliadmin.ico) in this directory are distributed under licence CC BY-SA + +List of icons from http://led24.de/iconset/ are: +- doliadmin.ico +- dolihelp.ico + +This is original README file for the package with this 2 images: You can do whatever you want with these icons (use on web or in desktop applications) as long as you don’t pass them off as your own and remove this readme file. A credit statement and a link back to http://led24.de/iconset/ or http://led24.de/ would be appreciated. - -Follow us on twitter http://twitter.com/gasyoun or email leds24@gmail.com -512 icons 20/05/2009 -------------------------------------------------------- -List of icons from http://led24.de/iconset/ are: -- dolihelp.ico diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index f0fd9702009..0f4d538cfac 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -609,10 +609,12 @@ if ($id) { print ''; if ($num) { + $i = 0; // Lines with values while ($i < $num) { $obj = $db->fetch_object($resql); //print_r($obj); + print ''; if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) { print '
'; @@ -708,6 +710,7 @@ if ($id) { print "\n"; } + $i++; } } diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 75283667fcb..a35333020cd 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -68,7 +68,9 @@ if ($search_accountancy_code_end == - 1) { $search_accountancy_code_end = ''; } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new BookKeeping($db); +$hookmanager->initHooks(array('balancelist')); // Note that conf->hooks_modules contains array $formaccounting = new FormAccounting($db); $formother = new FormOther($db); @@ -155,16 +157,23 @@ if (empty($user->rights->accounting->mouvements->lire)) { * Action */ -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers - $show_subgroup = ''; - $search_date_start = ''; - $search_date_end = ''; - $search_accountancy_code_start = ''; - $search_accountancy_code_end = ''; - $search_ledger_code = array(); - $filter = array(); +$parameters = array('socid'=>$socid); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } +if (empty($reshook)) { + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers + $show_subgroup = ''; + $search_date_start = ''; + $search_date_end = ''; + $search_accountancy_code_start = ''; + $search_accountancy_code_end = ''; + $search_ledger_code = array(); + $filter = array(); + } +} /* * View @@ -183,11 +192,11 @@ if ($action == 'export_csv') { } foreach ($object->lines as $line) { - print length_accountg($line->numero_compte).$sep; - print $object->get_compte_desc($line->numero_compte).$sep; - print price($line->debit).$sep; - print price($line->credit).$sep; - print price($line->debit - $line->credit).$sep; + print '"'.length_accountg($line->numero_compte).'"'.$sep; + print '"'.$object->get_compte_desc($line->numero_compte).'"'.$sep; + print '"'.price($line->debit).'"'.$sep; + print '"'.price($line->credit).'"'.$sep; + print '"'.price($line->debit - $line->credit).'"'.$sep; print "\n"; } @@ -226,22 +235,28 @@ if ($action != 'export_csv') { print ''; print ''; - $button = 'global->ACCOUNTING_EXPORT_FORMAT.')" />'; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $button = 'global->ACCOUNTING_EXPORT_FORMAT.')" />'; - print ''; + '; + } print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $button, $result, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + $selectedfields = ''; + $moreforfilter = ''; $moreforfilter .= '
'; @@ -283,12 +298,18 @@ if ($action != 'export_csv') { print ' '; print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, '', 'accounts'); print ''; - print ''; + + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields); + $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + // Action column + print ''; $searchpicto = $form->showFilterButtons(); print $searchpicto; print ''; - - print ''; + print ''."\n"; print ''; print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); @@ -298,8 +319,14 @@ if ($action != 'export_csv') { print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder); - print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60" class="center"', $sortfield, $sortorder); - print "\n"; + + // Hook fields + $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); + $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print ''."\n"; $total_debit = 0; $total_credit = 0; diff --git a/htdocs/adherents/admin/member.php b/htdocs/adherents/admin/member.php index 925f2c9094d..621873afc94 100644 --- a/htdocs/adherents/admin/member.php +++ b/htdocs/adherents/admin/member.php @@ -197,6 +197,8 @@ print ''; print ''; print load_fiche_titre($langs->trans("MemberMainOptions"), '', ''); + +print '
'; print ''; print ''; print ''; @@ -268,6 +270,7 @@ if ($conf->facture->enabled) { } print '
'.$langs->trans("Description").'
'; +print '
'; print '
'; print ''; @@ -338,6 +341,7 @@ if ($resql) { print load_fiche_titre($langs->trans("MembersDocModules"), '', ''); +print '
'; print ''; print ''; print ''; @@ -446,6 +450,8 @@ foreach ($dirmodels as $reldir) { } print '
'.$langs->trans("Name").'
'; +print '
'; + print "
"; print dol_get_fiche_end(); diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index 06796ef193c..bb320e9f48a 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -172,6 +172,7 @@ print '
'; if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) { print '
'; + print '
'; print ''; print ''; @@ -234,6 +235,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) { print "\n"; print '
'; + print '
'; print '
'; print ''; @@ -262,7 +264,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) { //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current print ''; print ajax_autoselect('publicurlmember'); diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 49a3cc74182..5182a6ff778 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -6,7 +6,7 @@ * Copyright (C) 2012 Marcos García * Copyright (C) 2012-2020 Philippe Grand * Copyright (C) 2015-2018 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2021 Waël Almoman * * This program is free software; you can redistribute it and/or modify @@ -1088,7 +1088,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (!$value['active']) { break; } - print ''.$langs->trans($value['label']).''; + $val = (GETPOSTISSET('member_'.$key) ? GETPOST('member_'.$key, 'alpha') : (empty($object->socialnetworks[$key]) ? '' : $object->socialnetworks[$key])); + print ''.$langs->trans($value['label']).''; } } diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 1ec9d498b9d..749eacbbe10 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -5,6 +5,7 @@ * Copyright (C) 2013-2015 Raphaël Doursenaud * Copyright (C) 2014-2016 Juanjo Menent * Copyright (C) 2018 Alexandre Spangaro + * Copyright (C) 2021 Frédéric France * * 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 @@ -305,7 +306,12 @@ $memberstatic = new Adherent($db); $now = dol_now(); -$sql = "SELECT d.rowid, d.ref, d.login, d.lastname, d.firstname, d.gender, d.societe as company, d.fk_soc,"; +if (!empty($search_categ) || !empty($catid)) { + $sql = "SELECT DISTINCT"; +} else { + $sql = "SELECT"; +} +$sql .= " d.rowid, d.ref, d.login, d.lastname, d.firstname, d.gender, d.societe as company, d.fk_soc,"; $sql .= " d.civility, d.datefin, d.address, d.zip, d.town, d.state_id, d.country,"; $sql .= " d.email, d.phone, d.phone_perso, d.phone_mobile, d.skype, d.birth, d.public, d.photo,"; $sql .= " d.fk_adherent_type as type_id, d.morphy, d.statut, d.datec as date_creation, d.tms as date_update,"; @@ -325,7 +331,7 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // N $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX."adherent as d"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (!empty($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (d.rowid = ef.fk_object)"; } if (!empty($search_categ) || !empty($catid)) { @@ -336,7 +342,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = d $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = d.state_id)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on (s.rowid = d.fk_soc)"; $sql .= ", ".MAIN_DB_PREFIX."adherent_type as t"; -$sql .= " WHERE d.fk_adherent_type = t.rowid "; +$sql .= " WHERE d.fk_adherent_type = t.rowid"; if ($catid > 0) { $sql .= " AND cm.fk_categorie = ".((int) $catid); } @@ -708,7 +714,7 @@ if (!empty($arrayfields['d.morphy']['checked'])) { if (!empty($arrayfields['t.libelle']['checked'])) { print ''; $listetype = $membertypestatic->liste_array(); - print $form->selectarray("search_type", $listetype, $type, 1, 0, 0, '', 0, 32); + print $form->selectarray("search_type", $listetype, $search_type, 1, 0, 0, '', 0, 32); print ''; } @@ -792,8 +798,8 @@ if (!empty($arrayfields['d.statut']['checked'])) { $liststatus = array( '-1'=>$langs->trans("Draft"), '1'=>$langs->trans("Validated"), - '0'=>$langs->trans("Resiliated"), - '-2'=>$langs->trans("Excluded") + '0'=>$langs->trans("MemberStatusResiliatedShort"), + '-2'=>$langs->trans("MemberStatusExcludedShort") ); print $form->selectarray('search_status', $liststatus, $search_status, -3); print ''; @@ -891,6 +897,7 @@ print "\n"; $i = 0; $totalarray = array(); +$totalarray['nbfield'] = 0; while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); @@ -947,7 +954,7 @@ while ($i < min($num, $limit)) { } // Firstname if (!empty($arrayfields['d.firstname']['checked'])) { - print ""; + print ''; print $obj->firstname; print "\n"; if (!$i) { @@ -956,7 +963,7 @@ while ($i < min($num, $limit)) { } // Lastname if (!empty($arrayfields['d.lastname']['checked'])) { - print ""; + print ''; print $obj->lastname; print "\n"; if (!$i) { @@ -976,13 +983,13 @@ while ($i < min($num, $limit)) { } // Company if (!empty($arrayfields['d.company']['checked'])) { - print ""; + print ''; print $companyname; print "\n"; } // Login if (!empty($arrayfields['d.login']['checked'])) { - print "".$obj->login."\n"; + print ''.$obj->login."\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1007,7 +1014,7 @@ while ($i < min($num, $limit)) { if (!empty($arrayfields['t.libelle']['checked'])) { $membertypestatic->id = $obj->type_id; $membertypestatic->label = $obj->type; - print ''; + print ''; print $membertypestatic->getNomUrl(1, 32); print ''; if (!$i) { @@ -1016,7 +1023,7 @@ while ($i < min($num, $limit)) { } // Address if (!empty($arrayfields['d.address']['checked'])) { - print ''; + print ''; print $obj->address; print ''; if (!$i) { @@ -1096,7 +1103,7 @@ while ($i < min($num, $limit)) { print ''; print dol_print_date($datefin, 'day'); if ($memberstatic->hasDelay()) { - $textlate .= ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; + $textlate = ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; print " ".img_warning($langs->trans("SubscriptionLate").$textlate); } print ''; diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 55cafade309..d3d84cb3624 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -477,6 +477,7 @@ print "\n"; $totalarray = array(); +$totalarray['nbfield'] = 0; while ($i < min($num, $limit)) { $obj = $db->fetch_object($result); @@ -527,7 +528,7 @@ while ($i < min($num, $limit)) { // Lastname if (!empty($arrayfields['d.lastname']['checked'])) { - print ''.$adherent->getNomUrl(-1, 0, 'card', 'lastname').''; + print ''.$adherent->getNomUrl(-1, 0, 'card', 'lastname').''; if (!$i) { $totalarray['nbfield']++; } @@ -550,7 +551,7 @@ while ($i < min($num, $limit)) { // Label if (!empty($arrayfields['t.libelle']['checked'])) { - print ''; + print ''; print $obj->note; print ''; if (!$i) { diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 2d3133c9fce..e86c78763ee 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -302,7 +302,7 @@ if ($action == 'edit') { // Disable print ''.$langs->trans("MAIN_DISABLE_ALL_MAILS").''; - print $form->selectyesno('MAIN_DISABLE_ALL_MAILS', $conf->global->MAIN_DISABLE_ALL_MAILS, 1); + print $form->selectyesno('MAIN_DISABLE_ALL_MAILS', getDolGlobalString('MAIN_DISABLE_ALL_MAILS'), 1); print ''; // Force e-mail recipient @@ -514,7 +514,7 @@ if ($action == 'edit') { $liste['company'] = $langs->trans('CompanyEmail').' ('.(empty($conf->global->MAIN_INFO_SOCIETE_MAIL) ? $langs->trans("NotDefined") : $conf->global->MAIN_INFO_SOCIETE_MAIL).')'; print ''.$langs->trans('MAIN_MAIL_DEFAULT_FROMTYPE').''; - print $form->selectarray('MAIN_MAIL_DEFAULT_FROMTYPE', $liste, $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE, 0); + print $form->selectarray('MAIN_MAIL_DEFAULT_FROMTYPE', $liste, getDolGlobalString('MAIN_MAIL_DEFAULT_FROMTYPE'), 0); print ''; // From @@ -529,7 +529,7 @@ if ($action == 'edit') { // Add user to select destinaries list print ''.$langs->trans("MAIN_MAIL_ENABLED_USER_DEST_SELECT").''; - print $form->selectyesno('MAIN_MAIL_ENABLED_USER_DEST_SELECT', $conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT, 1); + print $form->selectyesno('MAIN_MAIL_ENABLED_USER_DEST_SELECT', getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT'), 1); print ''; print ''; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 142d5accb0f..1a6d99261bd 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -386,7 +386,8 @@ foreach ($modulesdir as $dir) { } $moduleposition = ($objMod->module_position ? $objMod->module_position : '50'); - if ($moduleposition == '50' && ($objMod->isCoreOrExternalModule() == 'external')) { + if ($objMod->isCoreOrExternalModule() == 'external' && $moduleposition < 100000) { + // an external module should never return a value lower than '80'. $moduleposition = '80'; // External modules at end by default } diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index 6ea6d195040..7cc9ae3e3be 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -178,6 +178,7 @@ print dol_get_fiche_head($head, 'reception', $langs->trans("Receptions"), -1, 'r print load_fiche_titre($langs->trans("ReceptionsNumberingModules")); +print '
'; print ''; print ''; print ''; @@ -272,8 +273,10 @@ foreach ($dirmodels as $reldir) { } } -print '
'.$langs->trans("Name").'

'; +print ''; +print '
'; +print '
'; /* * Documents models for Receptions Receipt @@ -302,6 +305,7 @@ if ($resql) { dol_print_error($db); } +print '
'; print ''; print ''; print ''; @@ -417,6 +421,8 @@ foreach ($dirmodels as $reldir) { } print '
'.$langs->trans("Name").'
'; +print '
'; + print '
'; diff --git a/htdocs/admin/resource.php b/htdocs/admin/resource.php index b8bb566c79b..06ae59d64a3 100644 --- a/htdocs/admin/resource.php +++ b/htdocs/admin/resource.php @@ -74,6 +74,7 @@ print ''; print ''; print ''; +print '
'; print ''; print ''; print ''."\n"; @@ -132,6 +133,7 @@ print ''; print ''; print '
'.$langs->trans("Parameters").'
'; +print '
'; print ''; diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 55d6a518250..a4a9e91e3ff 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -743,6 +743,23 @@ if ($conf->use_javascript_ajax) { } print "\n"; print "\n"; + +/* Disabled. Would be better to be managed with a user cookie +if (!empty($conf->productbatch->enabled)) { + print ''; + print '' . $langs->trans("ShowAllBatchByDefault") . ''; + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('STOCK_SHOW_ALL_BATCH_BY_DEFAULT'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("STOCK_SHOW_ALL_BATCH_BY_DEFAULT", $arrval, $conf->global->STOCK_SHOW_ALL_BATCH_BY_DEFAULT); + } + print "\n"; + print "\n"; +} +*/ + print ''; print ''; diff --git a/htdocs/admin/system/modules.php b/htdocs/admin/system/modules.php index f3892e105bb..150ca10a359 100644 --- a/htdocs/admin/system/modules.php +++ b/htdocs/admin/system/modules.php @@ -65,6 +65,7 @@ $arrayfields = array( ); $arrayfields = dol_sort_array($arrayfields, 'position'); +$param = ''; /* diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php index b1014cc98c7..32fbe8ab41c 100644 --- a/htdocs/admin/system/perf.php +++ b/htdocs/admin/system/perf.php @@ -464,11 +464,99 @@ if ($conf->db->type == 'mysql' || $conf->db->type == 'mysqli') { print '
'; } -// Product search +print '
'; +print ''.$langs->trans("ComboListOptim").': '; +print '
'; +// Product combo list +$sql = "SELECT COUNT(*) as nb"; +$sql .= " FROM ".MAIN_DB_PREFIX."product as p"; +$resql = $db->query($sql); +if ($resql) { + $limitforoptim = 5000; + $num = $db->num_rows($resql); + $obj = $db->fetch_object($resql); + $nb = $obj->nb; + if ($nb > $limitforoptim) { + if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) { + print img_picto('', 'warning.png').' '.$langs->trans("YouHaveXObjectUseComboOptim", $nb, $langs->transnoentitiesnoconv("ProductsOrServices"), 'PRODUIT_USE_SEARCH_TO_SELECT'); + } else { + print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("ProductsOrServices"), 'PRODUIT_USE_SEARCH_TO_SELECT', $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); + } + } else { + print img_picto('', 'tick.png').' '.$langs->trans("NbOfObjectIsLowerThanNoPb", $nb, $langs->transnoentitiesnoconv("ProductsOrServices")); + } + print '
'; + $db->free($resql); +} +// Thirdparty combo list +$sql = "SELECT COUNT(*) as nb"; +$sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; +$resql = $db->query($sql); +if ($resql) { + $limitforoptim = 5000; + $num = $db->num_rows($resql); + $obj = $db->fetch_object($resql); + $nb = $obj->nb; + if ($nb > $limitforoptim) { + if (empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) { + print img_picto('', 'warning.png').' '.$langs->trans("YouHaveXObjectUseComboOptim", $nb, $langs->transnoentitiesnoconv("ThirdParties"), 'COMPANY_USE_SEARCH_TO_SELECT'); + } else { + print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("ThirdParties"), 'COMPANY_USE_SEARCH_TO_SELECT', $conf->global->COMPANY_USE_SEARCH_TO_SELECT); + } + } else { + print img_picto('', 'tick.png').' '.$langs->trans("NbOfObjectIsLowerThanNoPb", $nb, $langs->transnoentitiesnoconv("ThirdParties")); + } + print '
'; + $db->free($resql); +} +// Contact combo list +$sql = "SELECT COUNT(*) as nb"; +$sql .= " FROM ".MAIN_DB_PREFIX."socpeople as s"; +$resql = $db->query($sql); +if ($resql) { + $limitforoptim = 5000; + $num = $db->num_rows($resql); + $obj = $db->fetch_object($resql); + $nb = $obj->nb; + if ($nb > $limitforoptim) { + if (empty($conf->global->CONTACT_USE_SEARCH_TO_SELECT)) { + print img_picto('', 'warning.png').' '.$langs->trans("YouHaveXObjectUseComboOptim", $nb, $langs->transnoentitiesnoconv("Contacts"), 'CONTACT_USE_SEARCH_TO_SELECT'); + } else { + print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("Contacts"), 'CONTACT_USE_SEARCH_TO_SELECT', $conf->global->CONTACT_USE_SEARCH_TO_SELECT); + } + } else { + print img_picto('', 'tick.png').' '.$langs->trans("NbOfObjectIsLowerThanNoPb", $nb, $langs->transnoentitiesnoconv("Contacts")); + } + print '
'; + $db->free($resql); +} +// Contact combo list +$sql = "SELECT COUNT(*) as nb"; +$sql .= " FROM ".MAIN_DB_PREFIX."projet as s"; +$resql = $db->query($sql); +if ($resql) { + $limitforoptim = 5000; + $num = $db->num_rows($resql); + $obj = $db->fetch_object($resql); + $nb = $obj->nb; + if ($nb > $limitforoptim) { + if (empty($conf->global->PROJECT_USE_SEARCH_TO_SELECT)) { + print img_picto('', 'warning.png').' '.$langs->trans("YouHaveXObjectUseComboOptim", $nb, $langs->transnoentitiesnoconv("Projects"), 'PROJECT_USE_SEARCH_TO_SELECT'); + } else { + print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("Projects"), 'PROJECT_USE_SEARCH_TO_SELECT', $conf->global->PROJECT_USE_SEARCH_TO_SELECT); + } + } else { + print img_picto('', 'tick.png').' '.$langs->trans("NbOfObjectIsLowerThanNoPb", $nb, $langs->transnoentitiesnoconv("Projects")); + } + print '
'; + $db->free($resql); +} + + print '
'; print ''.$langs->trans("SearchOptim").': '; print '
'; -$tab = array(); +// Product search $sql = "SELECT COUNT(*) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."product as p"; $resql = $db->query($sql); @@ -480,8 +568,9 @@ if ($resql) { if ($nb > $limitforoptim) { if (empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)) { print img_picto('', 'warning.png').' '.$langs->trans("YouHaveXObjectUseSearchOptim", $nb, $langs->transnoentitiesnoconv("ProductsOrServices"), 'PRODUCT_DONOTSEARCH_ANYWHERE'); + print $langs->trans("YouHaveXObjectUseSearchOptimDesc"); } else { - print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("ProductsOrServices")); + print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("ProductsOrServices"), 'PRODUCT_DONOTSEARCH_ANYWHERE', $conf->global->PRODUCT_DONOTSEARCH_ANYWHERE); } } else { print img_picto('', 'tick.png').' '.$langs->trans("NbOfObjectIsLowerThanNoPb", $nb, $langs->transnoentitiesnoconv("ProductsOrServices")); @@ -491,20 +580,20 @@ if ($resql) { } // Thirdparty search -$tab = array(); $sql = "SELECT COUNT(*) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $resql = $db->query($sql); if ($resql) { - $limitforoptim = 10000; + $limitforoptim = 100000; $num = $db->num_rows($resql); $obj = $db->fetch_object($resql); $nb = $obj->nb; if ($nb > $limitforoptim) { if (empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) { print img_picto('', 'warning.png').' '.$langs->trans("YouHaveXObjectUseSearchOptim", $nb, $langs->transnoentitiesnoconv("ThirdParties"), 'COMPANY_DONOTSEARCH_ANYWHERE'); + print $langs->trans("YouHaveXObjectUseSearchOptimDesc"); } else { - print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("ThirdParties")); + print img_picto('', 'tick.png').' '.$langs->trans("YouHaveXObjectAndSearchOptimOn", $nb, $langs->transnoentitiesnoconv("ThirdParties"), 'COMPANY_DONOTSEARCH_ANYWHERE', $conf->global->COMPANY_DONOTSEARCH_ANYWHERE); } } else { print img_picto('', 'tick.png').' '.$langs->trans("NbOfObjectIsLowerThanNoPb", $nb, $langs->transnoentitiesnoconv("ThirdParties")); diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 36f08309e02..087ad76631d 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -155,8 +155,8 @@ print ''.$langs->trans("PermissionsOnFilesInWebRoot").': '; $arrayoffilesinroot = dol_dir_list(DOL_DOCUMENT_ROOT, 'all', 1, '', array('\/custom'), 'name', SORT_ASC, 4, 1, '', 1); $fileswithwritepermission = array(); foreach ($arrayoffilesinroot as $fileinroot) { - // Test permission on file - if ($fileinroot['perm'] & 0222) { + // Test if there is at least one write permission file. If yes, add the entry into array $fileswithwritepermission + if (isset($fileinroot['perm']) && ($fileinroot['perm'] & 0222)) { $fileswithwritepermission[] = $fileinroot['relativename']; } } @@ -217,7 +217,7 @@ print '
'; print '$dolibarr_nocsrfcheck: '.$dolibarr_nocsrfcheck; if (!empty($dolibarr_nocsrfcheck)) { - print img_picto('', 'warning').'   '.$langs->trans("IfYouAreOnAProductionSetThis", 0); + print '   '.img_picto('', 'warning').' '.$langs->trans("IfYouAreOnAProductionSetThis", 0); } print '
'; @@ -234,16 +234,18 @@ print '
'; print '
'; print '
'; print '
'; -print load_fiche_titre($langs->trans("Menu").' '.$langs->trans("SecuritySetup"), '', 'folder'); +print load_fiche_titre($langs->trans("Menu").' '.$langs->trans("SecuritySetup").' + '.$langs->trans("OtherSetup"), '', 'folder'); //print ''.$langs->trans("PasswordEncryption").': '; print 'MAIN_SECURITY_HASH_ALGO = '.(empty($conf->global->MAIN_SECURITY_HASH_ALGO) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_HASH_ALGO)."   "; if (empty($conf->global->MAIN_SECURITY_HASH_ALGO)) { print '     If unset: \'md5\''; } -print '
'; if ($conf->global->MAIN_SECURITY_HASH_ALGO != 'password_hash') { - print 'MAIN_SECURITY_SALT = '.(empty($conf->global->MAIN_SECURITY_SALT) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_SALT).'
'; + print '
MAIN_SECURITY_SALT = '.(empty($conf->global->MAIN_SECURITY_SALT) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_SALT).'
'; +} else { + print '('.$langs->trans("Recommanded").': password_hash)'; + print '
'; } if ($conf->global->MAIN_SECURITY_HASH_ALGO != 'password_hash') { print '
The recommanded value for MAIN_SECURITY_HASH_ALGO is now \'password_hash\' but setting it now will make ALL existing passwords of all users not valid, so update is not possible.
'; @@ -259,18 +261,20 @@ print '
'; print 'MAIN_SECURITY_ANTI_SSRF_SERVER_IP = '.(empty($conf->global->MAIN_SECURITY_ANTI_SSRF_SERVER_IP) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_ANTI_SSRF_SERVER_IP)."
"; print '
'; +print 'MAIN_ALLOW_SVG_FILES_AS_IMAGES = '.(empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES) ? '0   ('.$langs->trans("Recommanded").': 0)' : $conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)."
"; +print '
'; print 'MAIN_EXEC_USE_POPEN = '; if (empty($conf->global->MAIN_EXEC_USE_POPEN)) { - print ''.$langs->trans("Undefined").'   '; + print ''.$langs->trans("Undefined").''; } else { - print $conf->global->MAIN_EXEC_USE_POPEN.'   '; + print $conf->global->MAIN_EXEC_USE_POPEN; } if ($execmethod == 1) { - print ' --> "exec" PHP method will be used for shell commands.'; + print '   ("exec" PHP method will be used for shell commands)'; } if ($execmethod == 2) { - print ' --> "popen" PHP method will be used for shell commands.'; + print '   ("popen" PHP method will be used for shell commands)'; } print "
"; print '
'; @@ -278,7 +282,7 @@ print '
'; print ''.$langs->trans("AntivirusEnabledOnUpload").': '; print empty($conf->global->MAIN_ANTIVIRUS_COMMAND) ? '' : img_picto('', 'tick').' '; -print yn($conf->global->MAIN_ANTIVIRUS_COMMAND ? 1 : 0); +print yn(empty($conf->global->MAIN_ANTIVIRUS_COMMAND) ? 0 : 1); if (!empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) { print '   - '.$conf->global->MAIN_ANTIVIRUS_COMMAND; if (defined('MAIN_ANTIVIRUS_COMMAND')) { diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php index fbc2412a9df..d09551a5478 100644 --- a/htdocs/admin/tools/listevents.php +++ b/htdocs/admin/tools/listevents.php @@ -68,6 +68,7 @@ $search_user = GETPOST("search_user", "alpha"); $search_desc = GETPOST("search_desc", "alpha"); $search_ua = GETPOST("search_ua", "restricthtml"); $search_prefix_session = GETPOST("search_prefix_session", "restricthtml"); +$optioncss = GETPOST("optioncss", "aZ"); // Option for the css output (always '' except when 'print') $now = dol_now(); $nowarray = dol_getdate($now); @@ -372,7 +373,7 @@ if ($result) { print_liste_field_titre("UserAgent", $_SERVER["PHP_SELF"], "e.user_agent", "", $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['e.prefix_session']['checked'])) { - print_liste_field_titre("PrefixSession", $_SERVER["PHP_SELF"], "e.prefix_session", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("SuffixSessionName", $_SERVER["PHP_SELF"], "e.prefix_session", "", $param, '', $sortfield, $sortorder); } print_liste_field_titre(''); print "\n"; diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index 2ede168b601..acb11e70332 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -188,7 +188,7 @@ if ($action == 'delete') { $form = new Form($db); $formadmin = new FormAdmin($db); -$wikihelp = 'EN:Setup Translation|FR:Paramétrage traduction|ES:Configuración'; +$wikihelp = 'EN:Setup_Translation|FR:Paramétrage_Traduction|ES:Configuración_Traducción'; llxHeader('', $langs->trans("Setup"), $wikihelp); $param = '&mode='.urlencode($mode); diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 0dccf65e5e7..83649d46a28 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -126,6 +126,7 @@ $head = user_admin_prepare_head(); print dol_get_fiche_head($head, 'card', $langs->trans("MenuUsersAndGroups"), -1, 'user'); +print '
'; print ''; print ''; print ''; @@ -171,6 +172,7 @@ if ($conf->use_javascript_ajax) { print ''; print '
'.$langs->trans("Parameter").'
'; +print '
'; print '
'; @@ -197,6 +199,7 @@ if ($resql) { print load_fiche_titre($langs->trans("UsersDocModules"), '', ''); +print '
'; print ''; print ''; print ''; @@ -306,7 +309,9 @@ foreach ($dirmodels as $reldir) { } print '
'.$langs->trans("Name").'
'; -print "
"; +print '
'; + +print '
'; print dol_get_fiche_end(); diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 10e96b50014..245f90edf72 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -937,6 +937,7 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; if ($backtopage) { print ''; } @@ -1183,7 +1184,7 @@ if ($action == 'create') { $projectid = GETPOST('projectid', 'int'); print ''.$langs->trans("Project").''; - print img_picto('', 'project', 'class="paddingrightonly"'); + print img_picto('', 'project', 'class="pictofixedwidth"'); print $formproject->select_projects((!empty($societe->id) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); print ' '; @@ -1430,6 +1431,7 @@ if ($id > 0) { print ''; print ''; print ''; + print ''; if ($backtopage) { print ''; } @@ -1984,7 +1986,7 @@ if ($id > 0) { print ' '; // Done by - if ($conf->global->AGENDA_ENABLE_DONEBY) { + if (!empty($conf->global->AGENDA_ENABLE_DONEBY)) { print ''.$langs->trans("ActionDoneBy").''; if ($object->userdoneid > 0) { $tmpuser = new User($db); @@ -2078,10 +2080,10 @@ if ($id > 0) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; // Reminders - if ($conf->global->AGENDA_REMINDER_EMAIL || $conf->global->AGENDA_REMINDER_BROWSER) { - $filtreuserid = $user->id; + if (!empty($conf->global->AGENDA_REMINDER_EMAIL) || !empty($conf->global->AGENDA_REMINDER_BROWSER)) { + $filteruserid = $user->id; if ($user->rights->agenda->allactions->read) { - $filtreuserid = 0; + $filteruserid = 0; } $object->loadReminders('', $filteruserid, false); diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index e3cc54f5a35..8c6fc94e31f 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -320,7 +320,7 @@ if ($search_title != '') { $param .= '&search_title='.urlencode($search_title); } if ($search_note != '') { - $param .= '&search_note='.$search_note; + $param .= '&search_note='.urlencode($search_note); } if (GETPOST('datestartday', 'int')) { $param .= '&datestartday='.GETPOST('datestartday', 'int'); @@ -520,6 +520,7 @@ $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + // TODO Set and use an optimized request in $sqlforcount with no fields and no useless join to caluclate nb of records $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 @@ -829,7 +830,11 @@ if ($resql) { $actionstatic->location = $obj->location; $actionstatic->note_private = dol_htmlentitiesbr($obj->note); - $actionstatic->fetchResources(); + // Initialize $this->userassigned && this->socpeopleassigned array && this->userownerid + // but only if we need it + if (!empty($arrayfields['a.fk_contact']['checked'])) { + $actionstatic->fetchResources(); + } print ''; @@ -1006,7 +1011,7 @@ if ($resql) { } if (!empty($arrayfields['a.percent']['checked'])) { // Status/Percent - $datep = $db->jdate($obj->datep); + $datep = $db->jdate($obj->dp); print ''.$actionstatic->LibStatut($obj->percent, 5, 0, $datep).''; } // Action column diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index afd6273d6c0..08e223ed89f 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -68,6 +68,8 @@ $modulesdir = dolGetModulesDirs('/mailings'); $object = new Mailing($db); $result = $object->fetch($id); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('ciblescard', 'globalcard')); // Security check if (!$user->rights->mailing->lire || (empty($conf->global->EXTERNAL_USERS_ARE_AUTHORIZED) && $user->socid > 0)) { @@ -438,6 +440,10 @@ if ($object->fetch($id) >= 0) { } } // End foreach dir + $parameters = array(); + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
'; print '

'; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 984d77e7263..b5bd94f0c2e 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1436,11 +1436,9 @@ if (empty($reshook)) { */ $form = new Form($db); -$formother = new FormOther($db); $formfile = new FormFile($db); $formpropal = new FormPropal($db); $formmargin = new FormMargin($db); -$companystatic = new Societe($db); if (!empty($conf->projet->enabled)) { $formproject = new FormProjets($db); } @@ -1582,7 +1580,7 @@ if ($action == 'create') { //$warehouse_id = $soc->warehouse_id; } else { print ''; - print img_picto('', 'company').$form->select_company('', 'socid', '(s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500'); + print img_picto('', 'company').$form->select_company('', 'socid', '(s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); // reload page to retrieve customer informations if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) { print ''; $out .= $this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter); - $out .= ' '; + $out .= ' '; $out .= '
'; } @@ -3025,6 +3025,10 @@ class Form global $langs, $conf; global $price_level, $status, $finished; + if (!isset($status)) { + $status = 1; + } + $selected_input_value = ''; if (!empty($conf->use_javascript_ajax) && !empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) { if ($selected > 0) { @@ -3040,7 +3044,7 @@ class Form print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); print ($hidelabel ? '' : $langs->trans("RefOrLabel").' : ').''; } else { - print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', -1, 0, 0, $alsoproductwithnosupplierprice, $morecss, 0, $placeholder); + print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', $status, 0, 0, $alsoproductwithnosupplierprice, $morecss, 0, $placeholder); } } @@ -3054,7 +3058,7 @@ class Form * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) * @param string $filtre Pour filtre sql * @param string $filterkey Filtre des produits - * @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request) + * @param int $statut -1=Return all products, 0=Products not on buy, 1=Products on buy * @param int $outputmode 0=HTML select string, 1=Array * @param int $limit Limit of line number * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices @@ -3107,7 +3111,9 @@ class Form $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_units u ON u.rowid = p.fk_unit"; } $sql .= " WHERE p.entity IN (".getEntity('product').")"; - $sql .= " AND p.tobuy = 1"; + if ($statut != -1) { + $sql .= " AND p.tobuy = ".((int) $statut); + } if (strval($filtertype) != '') { $sql .= " AND p.fk_product_type=".$this->db->escape($filtertype); } @@ -3670,13 +3676,14 @@ class Form /** * Retourne la liste des types de delais de livraison possibles * - * @param int $selected Id du type de delais pre-selectionne - * @param string $htmlname Nom de la zone select - * @param string $filtertype To add a filter + * @param int $selected Id du type de delais pre-selectionne + * @param string $htmlname Nom de la zone select + * @param string $filtertype To add a filter * @param int $addempty Add empty entry + * @param string $morecss More CSS * @return void */ - public function selectAvailabilityDelay($selected = '', $htmlname = 'availid', $filtertype = '', $addempty = 0) + public function selectAvailabilityDelay($selected = '', $htmlname = 'availid', $filtertype = '', $addempty = 0, $morecss = '') { global $langs, $user; @@ -3684,7 +3691,7 @@ class Form dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); - print ''; if ($addempty) { print ''; } @@ -3694,7 +3701,7 @@ class Form } else { print ''; } print ''; @@ -4154,15 +4161,16 @@ class Form /** * Return a HTML select list of shipping mode * - * @param string $selected Id shipping mode pre-selected - * @param string $htmlname Name of select zone - * @param string $filtre To filter list. This parameter must not come from input of users - * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @param string $moreattrib To add more attribute on select + * @param string $selected Id shipping mode pre-selected + * @param string $htmlname Name of select zone + * @param string $filtre To filter list. This parameter must not come from input of users + * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. + * @param string $moreattrib To add more attribute on select * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info + * @param string $morecss More CSS * @return void */ - public function selectShippingMethod($selected = '', $htmlname = 'shipping_method_id', $filtre = '', $useempty = 0, $moreattrib = '', $noinfoadmin = 0) + public function selectShippingMethod($selected = '', $htmlname = 'shipping_method_id', $filtre = '', $useempty = 0, $moreattrib = '', $noinfoadmin = 0, $morecss = '') { global $langs, $conf, $user; @@ -4183,7 +4191,7 @@ class Form $num = $this->db->num_rows($result); $i = 0; if ($num) { - print ''; if ($useempty == 1 || ($useempty == 2 && $num > 1)) { print ''; } @@ -4887,7 +4895,7 @@ class Form var more = ""; var inputvalue; if ($("input[name=\'" + inputname + "\']").attr("type") == "radio") { - inputvalue = $("input[name=\'" + inputname + "\']").val(); + inputvalue = $("input[name=\'" + inputname + "\']:checked").val(); } else { if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; } inputvalue = $("#" + inputname + more).val(); @@ -4946,16 +4954,18 @@ class Form $formconfirm .= ''."\n"; // Line title - $formconfirm .= ''."\n"; + $formconfirm .= ''."\n"; // Line text if (is_array($formquestion) && !empty($formquestion['text'])) { - $formconfirm .= ''."\n"; + $formconfirm .= ''."\n"; } // Line form fields if ($more) { - $formconfirm .= ''."\n"; } @@ -4963,10 +4973,10 @@ class Form // Line with question $formconfirm .= ''; $formconfirm .= ''; - $formconfirm .= ''; - $formconfirm .= ''; $formconfirm .= ''."\n"; $formconfirm .= '
'.img_picto('', 'recent').' '.$title.'
'; + $formconfirm .= img_picto('', 'recent').' '.$title; + $formconfirm .= '
'.$formquestion['text'].'
'.$formquestion['text'].'
'."\n"; + $formconfirm .= '
'."\n"; $formconfirm .= $more; $formconfirm .= '
'.$question.''; - $formconfirm .= $this->selectyesno("confirm", $newselectedchoice); + $formconfirm .= ''; + $formconfirm .= $this->selectyesno("confirm", $newselectedchoice, 0, false, 0, 0, 'marginleftonly marginrightonly'); + $formconfirm .= ''; $formconfirm .= '
'."\n"; @@ -6920,7 +6930,7 @@ class Form if ($addjscombo && $jsbeautify) { // Enhance with select2 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; - $out .= ajax_combobox($htmlname); + $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', $show_empty < 0 ? (string) $show_empty : '-1'); } $out .= ''."\n"; if ($useempty) { $resultyesno .= ''."\n"; } @@ -8188,41 +8199,47 @@ class Form if ($modulepart == 'societe') { $dir = $conf->societe->multidir_output[$entity]; if (!empty($object->logo)) { - if ((string) $imagesize == 'mini') { - $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.getImageFileNameForSize($object->logo, '_mini'); // getImageFileNameForSize include the thumbs - } elseif ((string) $imagesize == 'small') { - $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.getImageFileNameForSize($object->logo, '_small'); - } else { - $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.$object->logo; + if (dolIsAllowedForPreview($object->logo)) { + if ((string) $imagesize == 'mini') { + $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.getImageFileNameForSize($object->logo, '_mini'); // getImageFileNameForSize include the thumbs + } elseif ((string) $imagesize == 'small') { + $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.getImageFileNameForSize($object->logo, '_small'); + } else { + $file = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.$object->logo; + } + $originalfile = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.$object->logo; } - $originalfile = get_exdir(0, 0, 0, 0, $object, 'thirdparty').'logos/'.$object->logo; } $email = $object->email; } elseif ($modulepart == 'contact') { $dir = $conf->societe->multidir_output[$entity].'/contact'; if (!empty($object->photo)) { - if ((string) $imagesize == 'mini') { - $file = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.getImageFileNameForSize($object->photo, '_mini'); - } elseif ((string) $imagesize == 'small') { - $file = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.getImageFileNameForSize($object->photo, '_small'); - } else { - $file = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.$object->photo; + if (dolIsAllowedForPreview($object->photo)) { + if ((string) $imagesize == 'mini') { + $file = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.getImageFileNameForSize($object->photo, '_mini'); + } elseif ((string) $imagesize == 'small') { + $file = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.getImageFileNameForSize($object->photo, '_small'); + } else { + $file = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.$object->photo; + } + $originalfile = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.$object->photo; } - $originalfile = get_exdir(0, 0, 0, 0, $object, 'contact').'photos/'.$object->photo; } $email = $object->email; $capture = 'user'; } elseif ($modulepart == 'userphoto') { $dir = $conf->user->dir_output; if (!empty($object->photo)) { - if ((string) $imagesize == 'mini') { - $file = get_exdir(0, 0, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_mini'); - } elseif ((string) $imagesize == 'small') { - $file = get_exdir(0, 0, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_small'); - } else { - $file = get_exdir(0, 0, 0, 0, $object, 'user').$object->photo; + if (dolIsAllowedForPreview($object->photo)) { + if ((string) $imagesize == 'mini') { + $file = get_exdir(0, 0, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_mini'); + } elseif ((string) $imagesize == 'small') { + $file = get_exdir(0, 0, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_small'); + } else { + $file = get_exdir(0, 0, 0, 0, $object, 'user').$object->photo; + } + $originalfile = get_exdir(0, 0, 0, 0, $object, 'user').$object->photo; } - $originalfile = get_exdir(0, 0, 0, 0, $object, 'user').$object->photo; } if (!empty($conf->global->MAIN_OLD_IMAGE_LINKS)) { $altfile = $object->id.".jpg"; // For backward compatibility @@ -8232,14 +8249,16 @@ class Form } elseif ($modulepart == 'memberphoto') { $dir = $conf->adherent->dir_output; if (!empty($object->photo)) { - if ((string) $imagesize == 'mini') { - $file = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_mini'); - } elseif ((string) $imagesize == 'small') { - $file = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_small'); - } else { - $file = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; + if (dolIsAllowedForPreview($object->photo)) { + if ((string) $imagesize == 'mini') { + $file = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_mini'); + } elseif ((string) $imagesize == 'small') { + $file = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_small'); + } else { + $file = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; + } + $originalfile = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; } - $originalfile = get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo; } if (!empty($conf->global->MAIN_OLD_IMAGE_LINKS)) { $altfile = $object->id.".jpg"; // For backward compatibility @@ -8250,14 +8269,16 @@ class Form // Generic case to show photos $dir = $conf->$modulepart->dir_output; if (!empty($object->photo)) { - if ((string) $imagesize == 'mini') { - $file = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_mini'); - } elseif ((string) $imagesize == 'small') { - $file = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_small'); - } else { - $file = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; + if (dolIsAllowedForPreview($object->photo)) { + if ((string) $imagesize == 'mini') { + $file = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_mini'); + } elseif ((string) $imagesize == 'small') { + $file = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_small'); + } else { + $file = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; + } + $originalfile = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; } - $originalfile = get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo; } if (!empty($conf->global->MAIN_OLD_IMAGE_LINKS)) { $altfile = $object->id.".jpg"; // For backward compatibility diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 7cf9978d32b..47506d5cbfa 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -726,7 +726,7 @@ class FormFile } // Language code (if multilang) - if (($allowgenifempty || (is_array($modellist) && count($modellist) > 0)) && $conf->global->MAIN_MULTILANGS && !$forcenomultilang && (!empty($modellist) || $showempty)) { + if (($allowgenifempty || (is_array($modellist) && count($modellist) > 0)) && !empty($conf->global->MAIN_MULTILANGS) && !$forcenomultilang && (!empty($modellist) || $showempty)) { include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($this->db); $defaultlang = $codelang ? $codelang : $langs->getDefaultLang(); @@ -812,7 +812,7 @@ class FormFile completeFileArrayWithDatabaseInfo($file_list, $relativedir); //var_dump($sortfield.' - '.$sortorder); - if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) $file_list = dol_sort_array($file_list, $sortfield, $sortorder); } } @@ -851,7 +851,7 @@ class FormFile // Show file size $size = (!empty($file['size']) ? $file['size'] : dol_filesize($filedir."/".$file["name"])); - $out .= ''.dol_print_size($size, 1, 1).''; + $out .= ''.dol_print_size($size, 1, 1).''; // Show file date $date = (!empty($file['date']) ? $file['date'] : dol_filemtime($filedir."/".$file["name"])); @@ -1774,11 +1774,16 @@ class FormFile continue; // We do not show orphelins files } - print ''."\n"; + print ''."\n"; print ''; print ''; if ($found > 0 && is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) { - print $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]->getNomUrl(1, 'document'); + $tmpobject = $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]; + //if (! in_array($tmpobject->element, array('expensereport'))) { + print $tmpobject->getNomUrl(1, 'document'); + //} else { + // print $tmpobject->getNomUrl(1); + //} } else { print $langs->trans("ObjectDeleted", ($id ? $id : $ref)); } diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index 0f97ed878cf..a578f08f3c1 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -932,7 +932,7 @@ class Ldap * Returns an array containing a details or list of LDAP record(s) * ldapsearch -LLLx -hlocalhost -Dcn=admin,dc=parinux,dc=org -w password -b "ou=adherents,ou=people,dc=parinux,dc=org" userPassword * - * @param string $search Value of fiel to search, '*' for all. Not used if $activefilter is set. + * @param string $search Value of field to search, '*' for all. Not used if $activefilter is set. * @param string $userDn DN (Ex: ou=adherents,ou=people,dc=parinux,dc=org) * @param string $useridentifier Name of key field (Ex: uid) * @param array $attributeArray Array of fields required. Note this array must also contains field $useridentifier (Ex: sn,userPassword) diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index d2987e8fc63..a4f6bb11706 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -319,9 +319,9 @@ class Utils } if ($dolibarr_main_db_character_set == 'utf8mb4') { // We save output into utf8mb4 charset - $param .= " --default-character-set=utf8mb4"; + $param .= " --default-character-set=utf8mb4 --no-tablespaces"; } else { - $param .= " --default-character-set=utf8"; // We always save output into utf8 charset + $param .= " --default-character-set=utf8 --no-tablespaces"; // We always save output into utf8 charset } $paramcrypted = $param; $paramclear = $param; diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index c0a8844b572..20debf50f12 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -214,17 +214,17 @@ print ' print "\n/* JS CODE TO ENABLE ClipBoard copy paste*/\n"; print 'jQuery(\'.clipboardCPShowOnHover\').hover( function() { - console.log("We hover a value with a copy paste feature"); + console.log("We hover a value with a copy paste feature"); $(this).children(".clipboardCPButton, .clipboardCPText").show(); }, function() { - console.log("We hover out the value with a copy paste feature"); + console.log("We hover out the value with a copy paste feature"); $(this).children(".clipboardCPButton, .clipboardCPText").hide(); } );'; -print 'jQuery(\'.clipboardCPButton\').click(function() { +print 'jQuery(\'.clipboardCPButton, .clipboardCPValueToPrint\').click(function() { /* console.log(this.parentNode); */ - console.log("We click on a clipboardCPButton tag"); + console.log("We click on a clipboardCPButton or clipboardCPValueToPrint class"); if (window.getSelection) { selection = window.getSelection(); diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 303382f285b..ae260171a0b 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1545,6 +1545,7 @@ function form_constantes($tableau, $strictw3c = 0, $helptext = '') print ''; } + print '
'; print ''; print ''; print ''; @@ -1715,6 +1716,7 @@ function form_constantes($tableau, $strictw3c = 0, $helptext = '') } } print '
'.$langs->trans("Description").'
'; + print '
'; if (!empty($strictw3c) && $strictw3c == 1) { print '
'; diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 8874b96eda5..99cf4e4f8d1 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -411,10 +411,11 @@ function ajax_dialog($title, $message, $w = 350, $h = 150) * @param int $minLengthToAutocomplete Minimum length of input string to start autocomplete * @param int $forcefocus Force focus on field * @param string $widthTypeOfAutocomplete 'resolve' or 'off' + * @param string $idforemptyvalue '-1' * @return string Return html string to convert a select field into a combo, or '' if feature has been disabled for some reason. * @see selectArrayAjax() of html.form.class */ -function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve') +function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve', $idforemptyvalue = '-1') { global $conf; @@ -454,15 +455,15 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = templateResult: function (data, container) { /* Format visible output into combo list */ /* Code to add class of origin OPTION propagated to the new select2
  • tag */ if (data.element) { $(container).addClass($(data.element).attr("class")); } - console.log($(data.element).attr("data-html")); - if (data.id == -1 && $(data.element).attr("data-html") == undefined) { + //console.log($(data.element).attr("data-html")); + if (data.id == '.((int) $idforemptyvalue).' && $(data.element).attr("data-html") == undefined) { return \' \'; } if ($(data.element).attr("data-html") != undefined) return htmlEntityDecodeJs($(data.element).attr("data-html")); // If property html set, we decode html entities and use this return data.text; }, templateSelection: function (selection) { /* Format visible output of selected value */ - if (selection.id == -1) return \'\'+selection.text+\'\'; + if (selection.id == '.((int) $idforemptyvalue).') return \'\'+selection.text+\'\'; return selection.text; }, escapeMarkup: function(markup) { diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index ce5e7129bcf..7e34eec5ecd 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2232,7 +2232,8 @@ function dol_most_recent_file($dir, $regexfilter = '', $excludefilter = array('( } /** - * Security check when accessing to a document (used by document.php, viewimage.php and webservices) + * Security check when accessing to a document (used by document.php, viewimage.php and webservices to get documents). + * TODO Replace code that set $accesallowed by a call to restrictedArea() * * @param string $modulepart Module of document ('module', 'module_user_temp', 'module_user' or 'module_temp') * @param string $original_file Relative path with filename, relative to modulepart. @@ -2446,6 +2447,16 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping for events if ($fuser->rights->agenda->myactions->{$read}) { $accessallowed = 1; + // If we known $id of project, call checkUserAccessToObject to check permission on the given agenda event on properties and assigned users + if ($refname && !preg_match('/^specimen/i', $original_file)) { + include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + $tmpobject = new ActionComm($db); + $tmpobject->fetch((int) $refname); + $accessallowed = checkUserAccessToObject($user, array('agenda'), $tmpobject->id, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id', ''); + if ($user->socid && $tmpobject->socid) { + $accessallowed = checkUserAccessToObject($user, array('societe'), $tmpobject->socid); + } + } } $original_file = $conf->agenda->dir_output.'/'.$original_file; } elseif ($modulepart == 'category' && !empty($conf->categorie->multidir_output[$entity])) { @@ -2612,12 +2623,26 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping pour les projets if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed = 1; + // If we known $id of project, call checkUserAccessToObject to check permission on properties and contact of project + if ($refname && !preg_match('/^specimen/i', $original_file)) { + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + $tmpproject = new Project($db); + $tmpproject->fetch('', $refname); + $accessallowed = checkUserAccessToObject($user, array('projet'), $tmpproject->id, 'projet&project', '', '', 'rowid', ''); + } } $original_file = $conf->projet->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")"; } elseif ($modulepart == 'project_task' && !empty($conf->projet->dir_output)) { if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed = 1; + // If we known $id of project, call checkUserAccessToObject to check permission on properties and contact of project + if ($refname && !preg_match('/^specimen/i', $original_file)) { + include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; + $tmptask = new Task($db); + $tmptask->fetch('', $refname); + $accessallowed = checkUserAccessToObject($user, array('projet_task'), $tmptask->id, 'projet&project', '', '', 'rowid', ''); + } } $original_file = $conf->projet->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")"; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8d171a048b0..45d1bdca12e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3514,9 +3514,9 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'github', 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp', 'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top', 'commercial', 'companies', 'generic', 'home', 'hrm', 'members', 'products', 'invoicing', - 'partnership', 'payment', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'refresh', 'salary', 'shipment', 'supplier_invoice', 'technic', 'ticket', + 'partnership', 'payment', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'salary', 'shipment', 'supplier_invoice', 'technic', 'ticket', 'error', 'warning', - 'reception', 'recruitmentcandidature', 'recruitmentjobposition', 'resource', + 'recent', 'reception', 'recruitmentcandidature', 'recruitmentjobposition', 'resource', 'shapes', 'supplier', 'supplier_proposal', 'supplier_order', 'supplier_invoice', 'timespent', 'title_setup', 'title_accountancy', 'title_bank', 'title_hrm', 'title_agenda', 'uncheck', 'user-cog', 'website', 'workstation', @@ -3558,7 +3558,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'other'=>'square', 'playdisabled'=>'play', 'pdf'=>'file-pdf', 'poll'=>'check-double', 'pos'=>'cash-register', 'preview'=>'binoculars', 'project'=>'project-diagram', 'projectpub'=>'project-diagram', 'projecttask'=>'tasks', 'propal'=>'file-signature', 'partnership'=>'handshake', 'payment'=>'money-check-alt', 'phoning'=>'phone', 'phoning_mobile'=>'mobile-alt', 'phoning_fax'=>'fax', 'previous'=>'arrow-alt-circle-left', 'printer'=>'print', 'product'=>'cube', 'service'=>'concierge-bell', - 'reception'=>'dolly', 'recruitmentjobposition'=>'id-card-alt', 'recruitmentcandidature'=>'id-badge', + 'recent' => 'question', 'reception'=>'dolly', 'recruitmentjobposition'=>'id-card-alt', 'recruitmentcandidature'=>'id-badge', 'resize'=>'crop', 'supplier_order'=>'dol-order_supplier', 'supplier_proposal'=>'file-signature', 'refresh'=>'redo', 'resource'=>'laptop-house', 'security'=>'key', 'salary'=>'wallet', 'shipment'=>'dolly', 'stock'=>'box-open', 'stats' => 'chart-bar', 'split'=>'code-branch', 'stripe'=>'stripe-s', @@ -6879,8 +6879,6 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, // For backward compatibility $substitutionarray['__REFCLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null)); $substitutionarray['__REFSUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null); - $substitutionarray['__REFCLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null)); - $substitutionarray['__REFSUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null); $substitutionarray['__SUPPLIER_ORDER_DATE_DELIVERY__'] = (isset($object->date_livraison) ? dol_print_date($object->date_livraison, 'day', 0, $outputlangs) : ''); $substitutionarray['__SUPPLIER_ORDER_DELAY_DELIVERY__'] = (isset($object->availability_code) ? ($outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : '')) : ''); @@ -10236,7 +10234,8 @@ function readfileLowMemory($fullpath_original_file_osencoded, $method = -1) } /** - * Create a button to copy $valuetocopy in the clipboard + * Create a button to copy $valuetocopy in the clipboard. + * Code that handle the click is inside lib_foot.jsp.php * * @param string $valuetocopy The value to print * @param int $showonlyonhover Show the copy-paste button only on hover @@ -10245,6 +10244,12 @@ function readfileLowMemory($fullpath_original_file_osencoded, $method = -1) */ function showValueWithClipboardCPButton($valuetocopy, $showonlyonhover = 1, $texttoshow = '') { + global $conf; + + /*if (!empty($conf->dol_no_mouse_hover)) { + $showonlyonhover = 0; + }*/ + if ($texttoshow) { $result = ''.$valuetocopy.''.$texttoshow.''; } else { diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 0315e848e94..ffa06ebd508 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -2694,7 +2694,7 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide // define progress color according to time spend vs workload $progressBarClass = 'progress-bar-info'; if ($task->planned_workload) { - $progressCalculated = round(100 * doubleval($task->duration_effective) / doubleval($task->planned_workload), 2); + $progressCalculated = round(100 * floatval($task->duration_effective) / floatval($task->planned_workload), 2); // this conf is actually hidden, by default we use 10% for "be carefull or warning" $warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.10; @@ -2702,12 +2702,12 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide $diffTitle = '
    '.$langs->trans('ProgressDeclared').' : '.$task->progress.($task->progress ? '%' : ''); $diffTitle .= '
    '.$langs->trans('ProgressCalculated').' : '.$progressCalculated.($progressCalculated ? '%' : ''); - //var_dump($progressCalculated.' '.$warningRatio.' '.$task->progress.' '.doubleval($task->progress * $warningRatio)); - if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { + //var_dump($progressCalculated.' '.$warningRatio.' '.$task->progress.' '.floatval($task->progress * $warningRatio)); + if (floatval($progressCalculated) > floatval($task->progress * $warningRatio)) { $progressBarClass = 'progress-bar-danger'; $title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', abs($task->progress - $progressCalculated).' '.$langs->trans("point")); $diff = ' '.($task->progress - $progressCalculated).'%'; - } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% + } elseif (floatval($progressCalculated) > floatval($task->progress)) { // warning if close at 10% $progressBarClass = 'progress-bar-warning'; $title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', abs($task->progress - $progressCalculated).' '.$langs->trans("point")); $diff = ' '.($task->progress - $progressCalculated).'%'; @@ -2771,18 +2771,18 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide $out .= ''; $out .= '
    '; - $diffval = doubleval($task->progress) - doubleval($progressCalculated); + $diffval = floatval($task->progress) - floatval($progressCalculated); if ($diffval >= 0) { // good - $out .= '
    '; + $out .= '
    '; if (!empty($task->progress)) { - $out .= '
    '; + $out .= '
    '; } $out .= '
    '; } else { // bad - $out .= '
    '; - $out .= '
    '; + $out .= '
    '; + $out .= '
    '; $out .= '
    '; } $out .= '
    '; @@ -2811,17 +2811,17 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '') // define color according to time spend vs workload $badgeClass = 'badge '; if ($task->planned_workload) { - $progressCalculated = round(100 * doubleval($task->duration_effective) / doubleval($task->planned_workload), 2); + $progressCalculated = round(100 * floatval($task->duration_effective) / floatval($task->planned_workload), 2); // this conf is actually hidden, by default we use 10% for "be carefull or warning" $warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.10; - if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { + if (floatval($progressCalculated) > floatval($task->progress * $warningRatio)) { $badgeClass .= 'badge-danger'; if (empty($tooltip)) { $tooltip = $task->progress.'% < '.$langs->trans("TimeConsumed").' '.$progressCalculated.'%'; } - } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% + } elseif (floatval($progressCalculated) > floatval($task->progress)) { // warning if close at 10% $badgeClass .= 'badge-warning'; if (empty($tooltip)) { $tooltip = $task->progress.'% < '.$langs->trans("TimeConsumed").' '.$progressCalculated.'%'; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index de4d67b1647..598802ea574 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -173,17 +173,21 @@ function dol_verifyHash($chain, $hash, $type = '0') * This method check permission on module then call checkUserAccessToObject() for permission on object (according to entity and socid of user). * * @param User $user User to check - * @param string $features Features to check (it must be module $object->element. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) + * @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'. + * Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) + * This is used to check permission $user->rights->features->... * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional). * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. + * This is used to check permission $user->rights->features->feature2... * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) * @param int $isdraft 1=The object with id=$objectid is a draft - * @return int Always 1, die process if not allowed + * @param int $mode Mode (0=default, 1=return with not die) + * @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed. * @see dol_check_secure_access_document(), checkUserAccessToObject() */ -function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0) +function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0) { global $db, $conf; global $hookmanager; @@ -228,7 +232,11 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f if (isset($hookmanager->resArray['result'])) { if ($hookmanager->resArray['result'] == 0) { - accessforbidden(); // Module returns 0, so access forbidden + if ($mode) { + return 0; + } else { + accessforbidden(); // Module returns 0, so access forbidden + } } } if ($reshook > 0) { // No other test done. @@ -343,7 +351,11 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f } if (!$readok) { - accessforbidden(); + if ($mode) { + return 0; + } else { + accessforbidden(); + } } //print "Read access is ok"; @@ -432,7 +444,11 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f } if ($wemustcheckpermissionforcreate && !$createok) { - accessforbidden(); + if ($mode) { + return 0; + } else { + accessforbidden(); + } } //print "Write access is ok"; } @@ -445,7 +461,11 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f } if (!$createuserok) { - accessforbidden(); + if ($mode) { + return 0; + } else { + accessforbidden(); + } } //print "Create user access is ok"; } @@ -520,26 +540,34 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f } if (!$deleteok && !($isdraft && $createok)) { - accessforbidden(); + if ($mode) { + return 0; + } else { + accessforbidden(); + } } //print "Delete access is ok"; } - // If we have a particular object to check permissions on, we check this object - // is linked to a company allowed to $user. + // If we have a particular object to check permissions on, we check if $user has permission + // for this given object (link to company, is contact for project, ...) if (!empty($objectid) && $objectid > 0) { $ok = checkUserAccessToObject($user, $featuresarray, $objectid, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity); $params = array('objectid' => $objectid, 'features' => join(',', $featuresarray), 'features2' => $feature2); //print 'checkUserAccessToObject ok='.$ok; - return $ok ? 1 : accessforbidden('', 1, 1, 0, $params); + if ($mode) { + return $ok ? 1 : 0; + } else { + return $ok ? 1 : accessforbidden('', 1, 1, 0, $params); + } } return 1; } /** - * Check access by user to object. - * This function is also called by restrictedArea that check before if module is enabled and permissions of user compared to $action. + * Check access by user to object is ok. + * This function is also called by restrictedArea that check before if module is enabled and if permission of user for $action is ok. * * @param User $user User to check * @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...) @@ -552,7 +580,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f * @return bool True if user has access, False otherwise * @see restrictedArea() */ -function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = '', $dbt_select = 'rowid', $parenttableforentity = '') +function checkUserAccessToObject($user, array $featuresarray, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = '', $dbt_select = 'rowid', $parenttableforentity = '') { global $db, $conf; @@ -686,6 +714,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableand include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $projectstatic = new Project($db); $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0); + $tmparray = explode(',', $tmps); if (!in_array($objectid, $tmparray)) { return false; diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 700c9c5ed86..6d01fcfee0a 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -339,7 +339,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) $thumbsbyrow = 6; print '
    '; - print ''; + print '
    '; // Title if ($foruserprofile) { diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 8824d9cc06d..721b908b9d1 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -283,11 +283,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, /** - * Save content of the index.php and/or wrapper.php page + * Save content of the index.php and/or the wrapper.php page * * @param string $pathofwebsite Path of website root * @param string $fileindex Full path of file index.php - * @param string $filetpl File tpl the index.php page redirect to + * @param string $filetpl File tpl the index.php page redirect to (used only if $fileindex is provided) * @param string $filewrapper Full path of file wrapper.php * @return boolean True if OK */ diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index d9c2cad7c9f..9eb6a43f9b0 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -167,7 +167,7 @@ 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_proposal->enabled', __HANDLER__, 'left', 1653__+MAX_llx_menu__, 'commercial', '', 1650__+MAX_llx_menu__, '/comm/propal/stats/index.php?leftmenu=supplier_proposals&mode=supplier', 'Statistics', 1, 'supplier_proposal', '$user->rights->supplier_proposal->lire', '', 2, 2, __ENTITY__); -- Commercial - Supplier's orders 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_order->enabled', __HANDLER__, 'left', 5100__+MAX_llx_menu__, 'commercial', 'orders_suppliers', 5__+MAX_llx_menu__, '/fourn/commande/index.php?mainmenu=commercial&leftmenu=orders_suppliers', 'SuppliersOrders', 0, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->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->supplier_order->enabled', __HANDLER__, 'left', 5101__+MAX_llx_menu__, 'commercial', '', 5100__+MAX_llx_menu__, '/fourn/commande/card.php?mainmenu=commercial&action=create&leftmenu=orders_suppliers', 'NewOrder', 1, 'orders', '($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->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_order->enabled', __HANDLER__, 'left', 5101__+MAX_llx_menu__, 'commercial', '', 5100__+MAX_llx_menu__, '/fourn/commande/card.php?mainmenu=commercial&action=create&leftmenu=orders_suppliers', 'NewSupplierOrderShort', 1, 'orders', '($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->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_order->enabled', __HANDLER__, 'left', 5102__+MAX_llx_menu__, 'commercial', '', 5100__+MAX_llx_menu__, '/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers', 'List', 1, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->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_order->enabled && $leftmenu=="orders_suppliers"', __HANDLER__, 'left', 5103__+MAX_llx_menu__, 'commercial', '', 5102__+MAX_llx_menu__, '/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers&statut=0', 'StatusOrderDraftShort', 1, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->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_order->enabled && $leftmenu=="orders_suppliers"', __HANDLER__, 'left', 5104__+MAX_llx_menu__, 'commercial', '', 5102__+MAX_llx_menu__, '/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers&statut=1', 'StatusOrderValidated', 1, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire)', '', 2, 3, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 74c66e899f4..2232b3333dd 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -959,7 +959,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM if (!empty($conf->supplier_order->enabled)) { $langs->load("orders"); $newmenu->add("/fourn/commande/index.php?leftmenu=orders_suppliers", $langs->trans("SuppliersOrders"), 0, $user->rights->fournisseur->commande->lire, '', $mainmenu, 'orders_suppliers', 400, '', '', '', img_picto('', 'supplier_order', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/fourn/commande/card.php?action=create&leftmenu=orders_suppliers", $langs->trans("NewOrder"), 1, $user->rights->fournisseur->commande->creer); + $newmenu->add("/fourn/commande/card.php?action=create&leftmenu=orders_suppliers", $langs->trans("NewSupplierOrderShort"), 1, $user->rights->fournisseur->commande->creer); $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers", $langs->trans("List"), 1, $user->rights->fournisseur->commande->lire); if ($usemenuhider || empty($leftmenu) || $leftmenu == "orders_suppliers") { diff --git a/htdocs/core/modules/modCashDesk.class.php b/htdocs/core/modules/modCashDesk.class.php index ba6c7ddce6c..a128b92ee29 100644 --- a/htdocs/core/modules/modCashDesk.class.php +++ b/htdocs/core/modules/modCashDesk.class.php @@ -51,7 +51,7 @@ class modCashDesk extends DolibarrModules $this->name = preg_replace('/^mod/i', '', get_class($this)); $this->description = "CashDesk module"; - $this->version = 'dolibarr'; + $this->version = 'deprecated'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->picto = 'cash-register'; diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index b3079691cd5..7c7813fbe14 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -487,8 +487,10 @@ print load_fiche_titre($title); $infoarray = dol_getImageSize($dir."/".GETPOST("file", 'alpha')); $height = $infoarray['height']; $width = $infoarray['width']; -print ''.$langs->trans("CurrentInformationOnImage").': '; -print $langs->trans("Width").': '.$width.' x '.$langs->trans("Height").': '.$height.'
    '; +print ''.$langs->trans("CurrentInformationOnImage").': '; +print ''; +print $langs->trans("Width").': '.$width.' x '.$langs->trans("Height").': '.$height.''; +print '
    '; print '
    '."\n"; @@ -546,36 +548,42 @@ if (!empty($conf->use_javascript_ajax)) { print ''.$langs->trans("Recenter").''; print $langs->trans("DefineNewAreaToPick").'...
    '; print '
    '; - print '
    '; - print ''; - print '
    '; - print '

    '; - print ''; - print ''; - print ' -
    - '.$langs->trans("NewSizeAfterCropping").': - - - - - - -
    + if (empty($conf->dol_no_mouse_hover)) { + print '
    '; + print ''; + print '
    '; + print '
    '; - - - - - - - -
    - -   - - '."\n"; + print ''; + print ''; + print ' +
    + '.$langs->trans("NewSizeAfterCropping").': + + + + + + +
    + + + + + + + + +
    + +   + + '."\n"; + } else { + $langs->load("other"); + print '
    '.$langs->trans("FeatureNotAvailableOnDevicesWithoutMouse").'
    '; + } print ''."\n"; print '
    '; } diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index 9c1387d7d58..731cc580ea1 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -76,7 +76,7 @@ if ($action == 'presend') { if (empty($object->ref_client)) { $topicmail = $outputlangs->trans($defaulttopic, '__REF__'); } elseif (!empty($object->ref_client)) { - $topicmail = $outputlangs->trans($defaulttopic, '__REF__ (__REFCLIENT__)'); + $topicmail = $outputlangs->trans($defaulttopic, '__REF__ (__REF_CLIENT__)'); } // Build document if it not exists diff --git a/htdocs/core/tpl/extrafields_add.tpl.php b/htdocs/core/tpl/extrafields_add.tpl.php index f194a177178..2f44bbe9c48 100644 --- a/htdocs/core/tpl/extrafields_add.tpl.php +++ b/htdocs/core/tpl/extrafields_add.tpl.php @@ -47,7 +47,7 @@ if (empty($reshook)) { if (isset($tpl_context)) { $params['tpl_context'] = $tpl_context; } - $params['cols'] = $parameters['colspanvalue']; + $params['cols'] = key_exists('colspanvalue', $parameters) ? $parameters['colspanvalue'] : ''; print $object->showOptionals($extrafields, 'create', $params); } diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php index 4c56b0223cd..021ff42a9d3 100644 --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -12,7 +12,7 @@ if (empty($extrafieldsobjectkey) && is_object($object)) { // Loop to show all columns of extrafields from $obj, $extrafields and $db if (!empty($extrafieldsobjectkey)) { // $extrafieldsobject is the $object->table_element like 'societe', 'socpeople', ... - if (is_array($extrafields->attributes[$extrafieldsobjectkey]['label']) && count($extrafields->attributes[$extrafieldsobjectkey]['label'])) { + if (key_exists('label', $extrafields->attributes[$extrafieldsobjectkey]) && is_array($extrafields->attributes[$extrafieldsobjectkey]['label']) && count($extrafields->attributes[$extrafieldsobjectkey]['label'])) { if (empty($extrafieldsobjectprefix)) { $extrafieldsobjectprefix = 'ef.'; } diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index 21150d19936..4b8680e11bb 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -149,7 +149,7 @@ if ($massaction == 'presend') { $formmail->withtofree = empty($liste) ? 1 : 0; $formmail->withtocc = 1; $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic = $langs->transnoentities($topicmail, '__REF__', '__REFCLIENT__'); + $formmail->withtopic = $langs->transnoentities($topicmail, '__REF__', '__REF_CLIENT__'); $formmail->withfile = 1; // $formmail->withfile = 2; Not yet supported in mass action $formmail->withmaindocfile = 1; // Add a checkbox "Attach also main document" diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index b960a2fdb8f..3ae04c64833 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -16,9 +16,9 @@ * along with this program. If not, see . */ - use Luracast\Restler\RestException; +use Luracast\Restler\RestException; - require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; +require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; /** * API class for donations @@ -33,7 +33,7 @@ class Donations extends DolibarrApi * @var array $FIELDS Mandatory fields, checked when create and update object */ public static $FIELDS = array( - 'socid' + 'amount' ); /** @@ -199,7 +199,7 @@ class Donations extends DolibarrApi }*/ if ($this->don->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, "Error creating order", array_merge(array($this->don->error), $this->don->errors)); + throw new RestException(500, "Error creating donation", array_merge(array($this->don->error), $this->don->errors)); } return $this->don->id; @@ -311,7 +311,7 @@ class Donations extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->don->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); + $result = $this->don->valid_promesse($id, DolibarrApiAccess::$user->id, $notrigger); if ($result == 0) { throw new RestException(304, 'Error nothing done. May be object is already validated'); } @@ -364,7 +364,7 @@ class Donations extends DolibarrApi private function _validate($data) { $don = array(); - foreach (Orders::$FIELDS as $field) { + foreach (Donations::$FIELDS as $field) { if (!isset($data[$field])) { throw new RestException(400, $field." field missing"); } diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index 0376ade3f31..56062868d86 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -380,7 +380,7 @@ class Don extends CommonObject $sql .= ", phone"; $sql .= ", phone_mobile"; $sql .= ") VALUES ("; - $sql .= "'".$this->db->idate($now)."'"; + $sql .= "'".$this->db->idate($this->date ? $this->date : $now)."'"; $sql .= ", ".$conf->entity; $sql .= ", ".price2num($this->amount); $sql .= ", ".($this->modepaymentid ? $this->modepaymentid : "null"); diff --git a/htdocs/ecm/dir_add_card.php b/htdocs/ecm/dir_add_card.php index 4cf557acde6..1416983e3a3 100644 --- a/htdocs/ecm/dir_add_card.php +++ b/htdocs/ecm/dir_add_card.php @@ -188,7 +188,7 @@ if ($action == 'add' && $permtoadd) { exit; } } -} elseif ($action == 'confirm_deletesection' && $confirm == 'yes') { +} elseif ($action == 'confirm_deletesection' && $confirm == 'yes' && $permtoadd) { // Deleting file $result = $ecmdir->delete($user); setEventMessages($langs->trans("ECMSectionWasRemoved", $ecmdir->label), null, 'mesgs'); diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php index 4c93e005266..d84a7330e69 100644 --- a/htdocs/ecm/dir_card.php +++ b/htdocs/ecm/dir_card.php @@ -88,17 +88,23 @@ if ($module == 'ecm') { } // Permissions +$permtoread = 0; $permtoadd = 0; $permtoupload = 0; if ($module == 'ecm') { + $permtoread = $user->rights->ecm->read; $permtoadd = $user->rights->ecm->setup; $permtoupload = $user->rights->ecm->upload; } if ($module == 'medias') { + $permtoread = ($user->rights->mailing->lire || $user->rights->website->read); $permtoadd = ($user->rights->mailing->creer || $user->rights->website->write); $permtoupload = ($user->rights->mailing->creer || $user->rights->website->write); } +if (!$permtoread) { + accessforbidden(); +} /* @@ -106,7 +112,7 @@ if ($module == 'medias') { */ // Upload file -if (GETPOST("sendit") && !empty($conf->global->MAIN_UPLOAD_DOC)) { +if (GETPOST("sendit") && !empty($conf->global->MAIN_UPLOAD_DOC) && $permtoupload) { if (dol_mkdir($upload_dir) >= 0) { $resupload = dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_dir."/".dol_unescapefile($_FILES['userfile']['name']), 0, 0, $_FILES['userfile']['error']); if (is_numeric($resupload) && $resupload > 0) { @@ -131,7 +137,7 @@ if (GETPOST("sendit") && !empty($conf->global->MAIN_UPLOAD_DOC)) { } // Remove file -if ($action == 'confirm_deletefile' && $confirm == 'yes') { +if ($action == 'confirm_deletefile' && $confirm == 'yes' && $permtoupload) { $langs->load("other"); $file = $upload_dir."/".GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). $ret = dol_delete_file($file); @@ -145,7 +151,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes') { } // Remove dir -if ($action == 'confirm_deletedir' && $confirm == 'yes') { +if ($action == 'confirm_deletedir' && $confirm == 'yes' && $permtoupload) { $backtourl = DOL_URL_ROOT."/ecm/index.php"; if ($module == 'medias') { $backtourl = DOL_URL_ROOT."/website/index.php?file_manager=1"; @@ -181,7 +187,7 @@ if ($action == 'confirm_deletedir' && $confirm == 'yes') { } // Update dirname or description -if ($action == 'update' && !GETPOST('cancel', 'alpha')) { +if ($action == 'update' && !GETPOST('cancel', 'alpha') && $permtoadd) { $error = 0; if ($module == 'ecm') { diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php index 93885c2843a..14bc7e377f0 100644 --- a/htdocs/ecm/file_card.php +++ b/htdocs/ecm/file_card.php @@ -36,10 +36,6 @@ $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); -if (!$user->rights->ecm->setup) { - accessforbidden(); -} - // Get parameters $socid = GETPOST("socid", "int"); @@ -105,6 +101,14 @@ if ($result < 0) { exit; } +// Permissions +$permtoread = $user->rights->ecm->read; +$permtoadd = $user->rights->ecm->setup; +$permtoupload = $user->rights->ecm->upload; + +if (!$permtoread) { + accessforbidden(); +} /* @@ -123,7 +127,7 @@ if ($cancel) { } // Rename file -if ($action == 'update') { +if ($action == 'update' && $permtoadd) { $error = 0; $oldlabel = GETPOST('urlfile', 'alpha'); diff --git a/htdocs/ecm/file_note.php b/htdocs/ecm/file_note.php index d2f3f7b4792..505e432f982 100644 --- a/htdocs/ecm/file_note.php +++ b/htdocs/ecm/file_note.php @@ -22,7 +22,7 @@ /** * \file htdocs/ecm/file_note.php * \ingroup ecm - * \brief Fiche de notes sur une ecm file + * \brief Tab for notes on an ECM file */ require '../main.inc.php'; @@ -39,10 +39,6 @@ $ref = GETPOST('ref', 'alpha'); $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); -if (!$user->rights->ecm->setup) { - accessforbidden(); -} - // Get parameters $socid = GETPOST("socid", "int"); // Security check @@ -109,6 +105,13 @@ if ($result < 0) { $permissionnote = $user->rights->ecm->setup; // Used by the include of actions_setnotes.inc.php +$permtoread = $user->rights->ecm->read; + +if (!$permtoread) { + accessforbidden(); +} + + /* * Actions */ diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 26bf242b0f2..3a8d33343c7 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -34,12 +34,6 @@ require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; // Load translation files required by the page $langs->loadLangs(array("ecm", "companies", "other", "users", "orders", "propal", "bills", "contracts")); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'ecm', 0); - // Get parameters $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); @@ -81,6 +75,12 @@ $userstatic = new User($db); $error = 0; +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'ecm', 0); + /* * Actions diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php index bcfff8aa2da..d54dcf14d1e 100644 --- a/htdocs/ecm/index_auto.php +++ b/htdocs/ecm/index_auto.php @@ -440,15 +440,13 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i', $act continue; // If condition to show is ok } - $var = false; - print ''; // Bank Account if (!empty($conf->banque->enabled)) { print ''; } @@ -2227,7 +2229,8 @@ if ($action == 'create') { $langs->load('projects'); print ''; } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 4fd45d6cff0..0c4f21ae4be 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -300,17 +300,16 @@ if (empty($reshook)) { $totalcreditnotes = $objecttmp->getSumCreditNotesUsed(); $totaldeposits = $objecttmp->getSumDepositsUsed(); $objecttmp->resteapayer = price2num($objecttmp->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); - if ($objecttmp->paye || $objecttmp->resteapayer == 0) { + if ($objecttmp->statut == FactureFournisseur::STATUS_DRAFT) { + $error++; + setEventMessages($objecttmp->ref.' '.$langs->trans("Draft"), $objecttmp->errors, 'errors'); + } elseif ($objecttmp->paye || $objecttmp->resteapayer == 0) { $error++; setEventMessages($objecttmp->ref.' '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors'); } elseif ($objecttmp->resteapayer < 0) { $error++; setEventMessages($objecttmp->ref.' '.$langs->trans("AmountMustBePositive"), $objecttmp->errors, 'errors'); } - if (!($objecttmp->statut > FactureFournisseur::STATUS_DRAFT)) { - $error++; - setEventMessages($objecttmp->ref.' '.$langs->trans("Draft"), $objecttmp->errors, 'errors'); - } $rsql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande"; $rsql .= " , pfd.date_traite as date_traite"; @@ -340,7 +339,7 @@ if (empty($reshook)) { } } - //Massive withdraw request for request with no errors + // Massive withdraw request for request with no errors if (!empty($listofbills)) { $nbwithdrawrequestok = 0; foreach ($listofbills as $aBill) { @@ -363,88 +362,6 @@ if (empty($reshook)) { } -if ($massaction == 'transfer_request') { - $langs->load("withdrawals"); - - if (!$user->rights->paymentbybanktransfer->create) { - $error++; - setEventMessages($langs->trans("NotEnoughPermissions"), null, 'errors'); - } else { - //Checking error - $error = 0; - - $arrayofselected = is_array($toselect) ? $toselect : array(); - $listofbills = array(); - foreach ($arrayofselected as $toselectid) { - $objecttmp = new FactureFournisseur($db); - $result = $objecttmp->fetch($toselectid); - if ($result > 0) { - $totalpaye = $objecttmp->getSommePaiement(); - $totalcreditnotes = $objecttmp->getSumCreditNotesUsed(); - $totaldeposits = $objecttmp->getSumDepositsUsed(); - $objecttmp->resteapayer = price2num($objecttmp->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); - if ($objecttmp->paye || $objecttmp->resteapayer == 0) { - $error++; - setEventMessages($objecttmp->ref.' '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors'); - } elseif ($objecttmp->resteapayer < 0) { - $error++; - setEventMessages($objecttmp->ref.' '.$langs->trans("AmountMustBePositive"), $objecttmp->errors, 'errors'); - } - if (!($objecttmp->statut > FactureFournisseur::STATUS_DRAFT)) { - $error++; - setEventMessages($objecttmp->ref.' '.$langs->trans("Draft"), $objecttmp->errors, 'errors'); - } - - $rsql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande"; - $rsql .= " , pfd.date_traite as date_traite"; - $rsql .= " , pfd.amount"; - $rsql .= " , u.rowid as user_id, u.lastname, u.firstname, u.login"; - $rsql .= " FROM ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; - $rsql .= " , ".MAIN_DB_PREFIX."user as u"; - $rsql .= " WHERE fk_facture_fourn = ".$objecttmp->id; - $rsql .= " AND pfd.fk_user_demande = u.rowid"; - $rsql .= " AND pfd.traite = 0"; - $rsql .= " ORDER BY pfd.date_demande DESC"; - - $result_sql = $db->query($rsql); - if ($result_sql) { - $numprlv = $db->num_rows($result_sql); - } - - if ($numprlv > 0) { - $error++; - setEventMessages($objecttmp->ref.' '.$langs->trans("RequestAlreadyDone"), $objecttmp->errors, 'warnings'); - } elseif (!empty($objecttmp->mode_reglement_code) && $objecttmp->mode_reglement_code != 'VIR') { - $error++; - setEventMessages($objecttmp->ref.' '.$langs->trans("BadPaymentMethod"), $objecttmp->errors, 'errors'); - } else { - $listofbills[] = $objecttmp; // $listofbills will only contains invoices with good payment method and no request already done - } - } - } - - //Massive withdraw request for request with no errors - if (!empty($listofbills)) { - $nbwithdrawrequestok = 0; - foreach ($listofbills as $aBill) { - $db->begin(); - $result = $aBill->demande_prelevement($user, $aBill->resteapayer, 'bank-transfer', 'supplier_invoice'); - if ($result > 0) { - $db->commit(); - $nbwithdrawrequestok++; - } else { - $db->rollback(); - setEventMessages($aBill->error, $aBill->errors, 'errors'); - } - } - if ($nbwithdrawrequestok > 0) { - setEventMessages($langs->trans("BankTransferRequestsDone", $nbwithdrawrequestok), null, 'mesgs'); - } - } - } -} - - /* * View */ @@ -623,7 +540,7 @@ if ($search_login) { $sql .= natural_search('u.login', $search_login); } if ($search_status != '' && $search_status >= 0) { - $sql .= " AND f.fk_statut = ".$db->escape($search_status); + $sql .= " AND f.fk_statut = ".((int) $search_status); } if ($search_paymentmode > 0) { $sql .= " AND f.fk_mode_reglement = ".((int) $search_paymentmode); @@ -646,7 +563,7 @@ if ($search_categ_sup == -2) { $sql .= " AND cs.fk_categorie IS NULL"; } if ($search_status != '' && $search_status >= 0) { - $sql .= " AND f.fk_statut = ".$search_status; + $sql .= " AND f.fk_statut = ".((int) $search_status); } if ($filter && $filter != -1) { $aFilter = explode(',', $filter); @@ -857,14 +774,10 @@ if ($resql) { //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); - if ($conf->paymentbybanktransfer->enabled) { - $langs->load("withdrawals"); - $arrayofmassactions['transfer_request'] = $langs->trans("MakeBankTransferOrder"); - } //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); if (!empty($conf->paymentbybanktransfer->enabled) && !empty($user->rights->paymentbybanktransfer->create)) { $langs->load('withdrawals'); - $arrayofmassactions['banktransfertrequest'] = $langs->trans("MakeBankTransferOrder"); + $arrayofmassactions['banktransfertrequest'] = img_picto('', 'payment', 'class="pictofixedwidth"').$langs->trans("MakeBankTransferOrder"); } if ($user->rights->fournisseur->facture->supprimer) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); @@ -876,7 +789,7 @@ if ($resql) { $url = DOL_URL_ROOT.'/fourn/facture/card.php?action=create'; if (!empty($socid)) { - $url .= '&socid='.$socid; + $url .= '&socid='.urlencode($socid); } $newcardbutton = dolGetButtonTitle($langs->trans('NewBill'), '', 'fa fa-plus-circle', $url, '', ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer)); diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index ffd394a35b3..55dd1c4bafb 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -1992,8 +1992,6 @@ class Holiday extends CommonObject */ public function fetchLog($order, $filter) { - global $langs; - $sql = "SELECT"; $sql .= " cpl.rowid,"; $sql .= " cpl.date_action,"; diff --git a/htdocs/holiday/view_log.php b/htdocs/holiday/view_log.php index a2ecbe1e8b3..cd43e03f957 100644 --- a/htdocs/holiday/view_log.php +++ b/htdocs/holiday/view_log.php @@ -373,7 +373,7 @@ if (!empty($arrayfields['cpl.fk_type']['checked'])) { // Filter: Previous balance if (!empty($arrayfields['cpl.prev_solde']['checked'])) { - print ''; } @@ -385,7 +385,7 @@ if (!empty($arrayfields['variation']['checked'])) { // Filter: New Balance if (!empty($arrayfields['cpl.new_solde']['checked'])) { - print ''; } @@ -428,12 +428,20 @@ if (!empty($arrayfields['cpl.new_solde']['checked'])) { print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print ''; -// TODO: $i = 0; -$i = 1; +$j = 0; +while ($j < ($page * $limit)) { + $obj = next($object->logs); + $j++; +} + +$i = 0; while ($i < min($num, $limit)) { //TODO: $obj = $db->fetch_object($resql); - $obj = next($object->logs); + $obj = current($object->logs); + if (empty($obj)) { + break; + } $holidaylogstatic->id = $obj['rowid']; $holidaylogstatic->date = $obj['date_action']; @@ -511,6 +519,7 @@ while ($i < min($num, $limit)) { print ''; $i++; + next($object->logs); } if ($log_holiday == '2') { diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index 5ed160a070a..b11506ea86c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -263,7 +263,7 @@ class AutoLoader * @return bool false unless className now exists */ private function loadLastResort($className, $loader = null) { - $loaders = array_unique(static::$rogueLoaders); + $loaders = array_unique(static::$rogueLoaders, SORT_REGULAR); if (isset($loader)) { if (false === array_search($loader, $loaders)) static::$rogueLoaders[] = $loader; diff --git a/htdocs/index.php b/htdocs/index.php index 5485f9bc7be..91b2de32087 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -472,7 +472,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $classe = (!empty($classes[$keyIndex]) ? $classes[$keyIndex] : ''); if (isset($boardloaded[$classe]) && is_object($boardloaded[$classe])) { $groupElement['globalStats']['total'] = $boardloaded[$classe]->nb[$globalStatsKey] ? $boardloaded[$classe]->nb[$globalStatsKey] : 0; - $nbTotal = doubleval($groupElement['globalStats']['total']); + $nbTotal = floatval($groupElement['globalStats']['total']); if ($nbTotal >= 10000) { $nbTotal = round($nbTotal / 1000, 2).'k'; } diff --git a/htdocs/install/mysql/data/llx_00_c_country.sql b/htdocs/install/mysql/data/llx_00_c_country.sql index 296b6d0e412..677447f1af2 100644 --- a/htdocs/install/mysql/data/llx_00_c_country.sql +++ b/htdocs/install/mysql/data/llx_00_c_country.sql @@ -106,16 +106,16 @@ INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (75 INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (76,'HR','HRV','Croatie',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (77,'CU','CUB','Cuba',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (78,'CY','CYP','Cyprus',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (79,'CZ','CZE','République Tchèque',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (80,'DK','DNK','Danemark',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (79,'CZ','CZE','Czech Republic',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (80,'DK','DNK','Denmark',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (81,'DJ','DJI','Djibouti',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (82,'DM','DMA','Dominique',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (83,'DO','DOM','République Dominicaine',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (84,'EC','ECU','Equateur',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (85,'EG','EGY','Egypte',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (86,'SV','SLV','Salvador',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (87,'GQ','GNQ','Guinée Equatoriale',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (88,'ER','ERI','Erythrée',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (82,'DM','DMA','Dominica',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (83,'DO','DOM','Dominican Republic',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (84,'EC','ECU','Republic of Ecuador',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (85,'EG','EGY','Egypt',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (86,'SV','SLV','El Salvador',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (87,'GQ','GNQ','Equatorial Guinea',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (88,'ER','ERI','Eritrea',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (89,'EE','EST','Estonia',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (90,'ET','ETH','Ethiopia',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (91,'FK','FLK','Falkland Islands',1,0); @@ -194,27 +194,27 @@ INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (40 INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (300,'CW','CUW','Curaçao',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (301,'SX','SXM','Sint Maarten',1,0); --End of antilles nederland -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (165,'NC','NCL','Nouvelle-Calédonie',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (166,'NZ','NZL','Nouvelle-Zélande',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (165,'NC','NCL','New Caledonia',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (166,'NZ','NZL','New Zealand',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (167,'NI','NIC','Nicaragua',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (168,'NE','NER','Niger',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (169,'NG','NGA','Nigeria',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (170,'NU','NIU','Nioué',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (171,'NF','NFK','Ile Norfolk',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (172,'MP','MNP','Mariannes du Nord',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (173,'NO','NOR','Norvège',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (170,'NU','NIU','Niue',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (171,'NF','NFK','Norfolk Island',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (172,'MP','MNP','Northern Mariana Islands',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (173,'NO','NOR','Norway',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (174,'OM','OMN','Oman',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (175,'PK','PAK','Pakistan',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (176,'PW','PLW','Palaos',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (177,'PS','PSE','Territoire Palestinien Occupé',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (176,'PW','PLW','Palau',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (177,'PS','PSE','Palestinian territories',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (178,'PA','PAN','Panama',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (179,'PG','PNG','Papouasie-Nouvelle-Guinée',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (179,'PG','PNG','Papua New Guinea',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (180,'PY','PRY','Paraguay',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (181,'PE','PER','Peru',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (182,'PH','PHL','Philippines',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (183,'PN','PCN','Iles Pitcairn',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (183,'PN','PCN','Pitcairn Islands',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (184,'PL','POL','Pologne',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (185,'PR','PRI','Porto Rico',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (185,'PR','PRI','Puerto Rico',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (186,'QA','QAT','Qatar',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (188,'RO','ROU','Roumanie',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (189,'RW','RWA','Rwanda',1,0); diff --git a/htdocs/install/mysql/data/llx_20_c_departements.sql b/htdocs/install/mysql/data/llx_20_c_departements.sql index 5e739f07b72..27a9f8dd1f5 100644 --- a/htdocs/install/mysql/data/llx_20_c_departements.sql +++ b/htdocs/install/mysql/data/llx_20_c_departements.sql @@ -62,6 +62,7 @@ -- Slovenia (need to check code SI-Id) -- Taiwan -- Tunisia +-- United States of America @@ -1120,6 +1121,60 @@ INSERT INTO llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc INSERT INTO llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) VALUES (1001, 'TN24', '', 0, '', 'Zaghouan'); +-- USA States (id country=11) +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'AL', '', 0, 'ALABAMA', 'Alabama'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'AK', '', 0, 'ALASKA', 'Alaska'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'AZ', '', 0, 'ARIZONA', 'Arizona'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'AR', '', 0, 'ARKANSAS', 'Arkansas'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'CA', '', 0, 'CALIFORNIA', 'California'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'CO', '', 0, 'COLORADO', 'Colorado'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'CT', '', 0, 'CONNECTICUT', 'Connecticut'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'DE', '', 0, 'DELAWARE', 'Delaware'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'FL', '', 0, 'FLORIDA', 'Florida'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'GA', '', 0, 'GEORGIA', 'Georgia'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'HI', '', 0, 'HAWAII', 'Hawaii'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'ID', '', 0, 'IDAHO', 'Idaho'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'IL', '', 0, 'ILLINOIS','Illinois'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'IN', '', 0, 'INDIANA', 'Indiana'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'IA', '', 0, 'IOWA', 'Iowa'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'KS', '', 0, 'KANSAS', 'Kansas'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'KY', '', 0, 'KENTUCKY', 'Kentucky'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'LA', '', 0, 'LOUISIANA', 'Louisiana'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'ME', '', 0, 'MAINE', 'Maine'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MD', '', 0, 'MARYLAND', 'Maryland'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MA', '', 0, 'MASSACHUSSETTS', 'Massachusetts'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MI', '', 0, 'MICHIGAN', 'Michigan'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MN', '', 0, 'MINNESOTA', 'Minnesota'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MS', '', 0, 'MISSISSIPPI', 'Mississippi'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MO', '', 0, 'MISSOURI', 'Missouri'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'MT', '', 0, 'MONTANA', 'Montana'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NE', '', 0, 'NEBRASKA', 'Nebraska'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NV', '', 0, 'NEVADA', 'Nevada'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NH', '', 0, 'NEW HAMPSHIRE', 'New Hampshire'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NJ', '', 0, 'NEW JERSEY', 'New Jersey'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NM', '', 0, 'NEW MEXICO', 'New Mexico'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NY', '', 0, 'NEW YORK', 'New York'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'NC', '', 0, 'NORTH CAROLINA', 'North Carolina'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'ND', '', 0, 'NORTH DAKOTA', 'North Dakota'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'OH', '', 0, 'OHIO', 'Ohio'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'OK', '', 0, 'OKLAHOMA', 'Oklahoma'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'OR', '', 0, 'OREGON', 'Oregon'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'PA', '', 0, 'PENNSYLVANIA', 'Pennsylvania'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'RI', '', 0, 'RHODE ISLAND', 'Rhode Island'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'SC', '', 0, 'SOUTH CAROLINA', 'South Carolina'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'SD', '', 0, 'SOUTH DAKOTA', 'South Dakota'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'TN', '', 0, 'TENNESSEE', 'Tennessee'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'TX', '', 0, 'TEXAS', 'Texas'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'UT', '', 0, 'UTAH', 'Utah'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'VT', '', 0, 'VERMONT', 'Vermont'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'VA', '', 0, 'VIRGINIA', 'Virginia'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'WA', '', 0, 'WASHINGTON', 'Washington'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'WV', '', 0, 'WEST VIRGINIA', 'West Virginia'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'WI', '', 0, 'WISCONSIN', 'Wisconsin'); +insert into llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc, nom) values (1101, 'WY', '', 0, 'WYOMING', 'Wyoming'); + + + -- Provinces Bolivia (id country=52) @@ -1513,59 +1568,6 @@ INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc --- Provinces US (id country=11) -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('AL', 1101, '', 0, 'ALABAMA', 'Alabama', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('AK', 1101, '', 0, 'ALASKA', 'Alaska', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('AZ', 1101, '', 0, 'ARIZONA', 'Arizona', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('AR', 1101, '', 0, 'ARKANSAS', 'Arkansas', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('CA', 1101, '', 0, 'CALIFORNIA', 'California', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('CO', 1101, '', 0, 'COLORADO', 'Colorado', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('CT', 1101, '', 0, 'CONNECTICUT', 'Connecticut', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('DE', 1101, '', 0, 'DELAWARE', 'Delaware', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('FL', 1101, '', 0, 'FLORIDA', 'Florida', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('GA', 1101, '', 0, 'GEORGIA', 'Georgia', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('HI', 1101, '', 0, 'HAWAII', 'Hawaii', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('ID', 1101, '', 0, 'IDAHO', 'Idaho', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('IL', 1101, '', 0, 'ILLINOIS','Illinois', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('IN', 1101, '', 0, 'INDIANA', 'Indiana', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('IA', 1101, '', 0, 'IOWA', 'Iowa', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('KS', 1101, '', 0, 'KANSAS', 'Kansas', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('KY', 1101, '', 0, 'KENTUCKY', 'Kentucky', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('LA', 1101, '', 0, 'LOUISIANA', 'Louisiana', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('ME', 1101, '', 0, 'MAINE', 'Maine', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MD', 1101, '', 0, 'MARYLAND', 'Maryland', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MA', 1101, '', 0, 'MASSACHUSSETTS', 'Massachusetts', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MI', 1101, '', 0, 'MICHIGAN', 'Michigan', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MN', 1101, '', 0, 'MINNESOTA', 'Minnesota', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MS', 1101, '', 0, 'MISSISSIPPI', 'Mississippi', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MO', 1101, '', 0, 'MISSOURI', 'Missouri', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('MT', 1101, '', 0, 'MONTANA', 'Montana', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NE', 1101, '', 0, 'NEBRASKA', 'Nebraska', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NV', 1101, '', 0, 'NEVADA', 'Nevada', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NH', 1101, '', 0, 'NEW HAMPSHIRE', 'New Hampshire', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NJ', 1101, '', 0, 'NEW JERSEY', 'New Jersey', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NM', 1101, '', 0, 'NEW MEXICO', 'New Mexico', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NY', 1101, '', 0, 'NEW YORK', 'New York', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('NC', 1101, '', 0, 'NORTH CAROLINA', 'North Carolina', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('ND', 1101, '', 0, 'NORTH DAKOTA', 'North Dakota', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('OH', 1101, '', 0, 'OHIO', 'Ohio', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('OK', 1101, '', 0, 'OKLAHOMA', 'Oklahoma', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('OR', 1101, '', 0, 'OREGON', 'Oregon', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('PA', 1101, '', 0, 'PENNSYLVANIA', 'Pennsylvania', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('RI', 1101, '', 0, 'RHODE ISLAND', 'Rhode Island', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('SC', 1101, '', 0, 'SOUTH CAROLINA', 'South Carolina', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('SD', 1101, '', 0, 'SOUTH DAKOTA', 'South Dakota', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('TN', 1101, '', 0, 'TENNESSEE', 'Tennessee', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('TX', 1101, '', 0, 'TEXAS', 'Texas', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('UT', 1101, '', 0, 'UTAH', 'Utah', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('VT', 1101, '', 0, 'VERMONT', 'Vermont', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('VA', 1101, '', 0, 'VIRGINIA', 'Virginia', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('WA', 1101, '', 0, 'WASHINGTON', 'Washington', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('WV', 1101, '', 0, 'WEST VIRGINIA', 'West Virginia', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('WI', 1101, '', 0, 'WISCONSIN', 'Wisconsin', 1); -insert into llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) values ('WY', 1101, '', 0, 'WYOMING', 'Wyoming', 1); - - -- San Salvador (id country=86) INSERT INTO llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) VALUES ('SS', 8601, '', 0, '', 'San Salvador', 1); INSERT INTO llx_c_departements ( code_departement, fk_region, cheflieu, tncc, ncc, nom, active) VALUES ('SA', 8603, '', 0, '', 'Santa Ana', 1); diff --git a/htdocs/install/mysql/data/llx_accounting_abc.sql b/htdocs/install/mysql/data/llx_accounting_abc.sql index 3c178f7c70d..806d084ce85 100644 --- a/htdocs/install/mysql/data/llx_accounting_abc.sql +++ b/htdocs/install/mysql/data/llx_accounting_abc.sql @@ -174,10 +174,10 @@ INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUE INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 15,'SYSCOHADA-TG', 'Plan comptable Ouest-Africain', 1); -- Description of chart of account USA US-BASE -INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 11, 'US-BASE', 'USA basic chart of accounts', 1); +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 11, 'US-BASE', 'USA basic chart of accounts', 1); -- Description of chart of account Canada CA-ENG-BASE -INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 14, 'CA-ENG-BASE', 'Canadian basic chart of accounts - English', 1); +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 14, 'CA-ENG-BASE', 'Canadian basic chart of accounts - English', 1); -- Description of chart of account Mexico SAT/24-2019 -INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 154, 'SAT/24-2019', 'Catalogo y codigo agrupador fiscal del 2019', 1); +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 154, 'SAT/24-2019', 'Catalogo y codigo agrupador fiscal del 2019', 1); diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index b95ea30f8fb..c9736e429c4 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -62,6 +62,11 @@ UPDATE llx_c_country SET eec = 1 WHERE code IN ('AT','BE','BG','CY','CZ','DE','D ALTER TABLE llx_export_model MODIFY COLUMN type varchar(64); +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 11, 'US-BASE', 'USA basic chart of accounts', 1); +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 14, 'CA-ENG-BASE', 'Canadian basic chart of accounts - English', 1); +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 154, 'SAT/24-2019', 'Catalogo y codigo agrupador fiscal del 2019', 1); + + -- For v14 ALTER TABLE llx_product_lot ADD COLUMN eol_date datetime NULL; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 467fba89199..2eaba13de3c 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1323,9 +1323,12 @@ ConditionIsCurrently=Condition is currently %s YouUseBestDriver=You use driver %s which is the best driver currently available. YouDoNotUseBestDriver=You use driver %s but driver %s is recommended. NbOfObjectIsLowerThanNoPb=You have only %s %s in the database. This does not require any particular optimization. +ComboListOptim=Combo list loading optimization SearchOptim=Search optimization -YouHaveXObjectUseSearchOptim=You have %s %s in the database. You can add the constant %s to 1 in Home-Setup-Other. Limit the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response. -YouHaveXObjectAndSearchOptimOn=You have %s %s in the database and constant %s is set to 1 in Home-Setup-Other. +YouHaveXObjectUseComboOptim=You have %s %s in the database. You can go into setup of module to enable loading of combo list on key pressed event. +YouHaveXObjectUseSearchOptim=You have %s %s in the database. You can add the constant %s to 1 in Home-Setup-Other. +YouHaveXObjectUseSearchOptimDesc=This limits the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response. +YouHaveXObjectAndSearchOptimOn=You have %s %s in the database and constant %s is set to %s in Home-Setup-Other. BrowserIsOK=You are using the %s web browser. This browser is ok for security and performance. BrowserIsKO=You are using the %s web browser. This browser is known to be a bad choice for security, performance and reliability. We recommend using Firefox, Chrome, Opera or Safari. PHPModuleLoaded=PHP component %s is loaded @@ -2103,7 +2106,6 @@ PDF_SHOW_PROJECT=Show project on document ShowProjectLabel=Project Label PDF_USE_ALSO_LANGUAGE_CODE=If you want to have some texts in your PDF duplicated in 2 different languages in the same generated PDF, you must set here this second language so generated PDF will contains 2 different languages in same page, the one chosen when generating PDF and this one (only few PDF templates support this). Keep empty for 1 language per PDF. FafaIconSocialNetworksDesc=Enter here the code of a FontAwesome icon. If you don't know what is FontAwesome, you can use the generic value fa-address-book. -FeatureNotAvailableWithReceptionModule=Feature not available when module Reception is enabled RssNote=Note: Each RSS feed definition provides a widget that you must enable to have it available in dashboard JumpToBoxes=Jump to Setup -> Widgets MeasuringUnitTypeDesc=Use here a value like "size", "surface", "volume", "weight", "time" diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index f47354958eb..2414a92cefb 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -70,7 +70,7 @@ ProductionForRef=Production of %s AutoCloseMO=Close automatically the Manufacturing Order if quantities to consume and to produce are reached NoStockChangeOnServices=No stock change on services ProductQtyToConsumeByMO=Product quantity still to consume by open MO -ProductQtyToProduceByMO=Product quentity still to produce by open MO +ProductQtyToProduceByMO=Product quantity still to produce by open MO AddNewConsumeLines=Add new line to consume ProductsToConsume=Products to consume ProductsToProduce=Products to produce diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang index 87d196eb22f..5dab5b99bf1 100644 --- a/htdocs/langs/en_US/orders.lang +++ b/htdocs/langs/en_US/orders.lang @@ -11,6 +11,7 @@ OrderDate=Order date OrderDateShort=Order date OrderToProcess=Order to process NewOrder=New order +NewSupplierOrderShort=New order NewOrderSupplier=New Purchase Order ToOrder=Make order MakeOrder=Make order @@ -73,6 +74,7 @@ DeleteOrder=Delete order CancelOrder=Cancel order OrderReopened= Order %s re-open AddOrder=Create order +AddSupplierOrderShort=Create order AddPurchaseOrder=Create purchase order AddToDraftOrders=Add to draft order ShowOrder=Show order diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 95297a98859..bb35099ab82 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -129,6 +129,7 @@ ClosedByLogin=User login who closed FileWasRemoved=File %s was removed DirWasRemoved=Directory %s was removed FeatureNotYetAvailable=Feature not yet available in the current version +FeatureNotAvailableOnDevicesWithoutMouse=Feature not available on devices without mouse FeaturesSupported=Supported features Width=Width Height=Height @@ -263,7 +264,7 @@ ContactCreatedByEmailCollector=Contact/address created by email collector from e ProjectCreatedByEmailCollector=Project created by email collector from email MSGID %s TicketCreatedByEmailCollector=Ticket created by email collector from email MSGID %s OpeningHoursFormatDesc=Use a - to separate opening and closing hours.
    Use a space to enter different ranges.
    Example: 8-12 14-18 -PrefixSession=Prefix for session ID +SuffixSessionName=Suffix for session name ##### Export ##### ExportsArea=Exports area diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index ddb94c70279..93cf9e9e037 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -252,4 +252,6 @@ ReOpen=Reopen ConfirmFinish=Do you confirm the closing of the inventory ? This will generate all stock movements to update your stock to the real qty you entered into the inventory. ObjectNotFound=%s not found MakeMovementsAndClose=Generate movements and close -AutofillWithExpected=Fill real quantity with expected quantity \ No newline at end of file +AutofillWithExpected=Fill real quantity with expected quantity +ShowAllBatchByDefault=By default, show batch details on product "stock" tab +CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration diff --git a/htdocs/langs/fr_FR/orders.lang b/htdocs/langs/fr_FR/orders.lang index 0732013a49b..9bbc7154567 100644 --- a/htdocs/langs/fr_FR/orders.lang +++ b/htdocs/langs/fr_FR/orders.lang @@ -11,6 +11,7 @@ OrderDate=Date de commande OrderDateShort=Date de commande OrderToProcess=Commande à traiter NewOrder=Nouvelle commande +NewSupplierOrderShort=Nouvelle commande NewOrderSupplier=Nouvelle Commande d'Achat ToOrder=Passer commande MakeOrder=Passer commande @@ -73,6 +74,7 @@ DeleteOrder=Supprimer la commande CancelOrder=Annuler la commande OrderReopened= Commande %s réouverte AddOrder=Créer commande +AddSupplierOrderShort=Créer commande AddPurchaseOrder=Créer commande d'achat AddToDraftOrders=Ajouter à commande brouillon ShowOrder=Afficher commande diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index c0cd183c506..c03fe42f01e 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -91,7 +91,7 @@ NoPredefinedProductToDispatch=Pas de produits prédéfinis dans cet objet. Aucun DispatchVerb=Ventiler StockLimitShort=Limite pour alerte StockLimit=Limite stock pour alerte -StockLimitDesc=(empty) means no warning.
    0 can be used to trigger a warning as soon as the stock is empty. +StockLimitDesc=(vide) n'affichera aucune icone d'alerte.
    0 peut être saisi pour afficher une alerte en cas de stock nul. PhysicalStock=Stock physique RealStock=Stock réel RealStockDesc=Le stock physique ou réel est le stock présent dans les entrepôts. @@ -255,3 +255,5 @@ ConfirmFinish=Confirmez-vous la clôture de l’inventaire? Ceci générera tous ObjectNotFound=%s introuvable MakeMovementsAndClose=Générer les mouvements et fermer AutofillWithExpected=Remplir la quantité réelle avec la quantité prévue +ShowAllBatchByDefault=Dérouler par défaut le détail des lots dans l'onglet "stock" +CollapseBatchDetailHelp=Vous pouvez définir l'affichage par défaut du détail des lots dans la configuration du module stocks diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 7b40647ebcb..72698a2f8aa 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -142,27 +142,23 @@ function testSqlAndScriptInject($val, $type) } $inj += preg_match('/base\s+href/si', $val); $inj += preg_match('/=data:/si', $val); - // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp - $inj += preg_match('/onmouse([a-z]*)\s*=/i', $val); // onmousexxx can be set on img or any html tag like - $inj += preg_match('/ondrag([a-z]*)\s*=/i', $val); // - $inj += preg_match('/ontouch([a-z]*)\s*=/i', $val); // - $inj += preg_match('/on(abort|afterprint|beforeprint|beforeunload|blur|canplay|canplaythrough|change|click|contextmenu|copy|cut)\s*=/i', $val); - $inj += preg_match('/on(dblclick|drop|durationchange|ended|error|focus|focusin|focusout|hashchange|input|invalid)\s*=/i', $val); - $inj += preg_match('/on(keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|loadend|offline|online|pagehide|pageshow)\s*=/i', $val); - $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|resize|reset|scroll|search|seeking|select|show|stalled|start|submit|suspend)\s*=/i', $val); - $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting)\s*=/i', $val); + // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers + $inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $val); // onmousexxx can be set on img or any html tag like + $inj += preg_match('/on(abort|afterprint|animation|auxclick|beforeprint|beforeunload|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)\s*=/i', $val); + $inj += preg_match('/on(dblclick|drop|durationchange|emptied|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)\s*=/i', $val); + $inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $val); + $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $val); + $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)\s*=/i', $val); // We refuse html into html because some hacks try to obfuscate evil strings by inserting HTML into HTML. Example: error=alert(1) to bypass test on onerror $tmpval = preg_replace('/<[^<]+>/', '', $val); - // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp - $inj += preg_match('/onmouse([a-z]*)\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like - $inj += preg_match('/ondrag([a-z]*)\s*=/i', $tmpval); // - $inj += preg_match('/ontouch([a-z]*)\s*=/i', $tmpval); // - $inj += preg_match('/on(abort|afterprint|beforeprint|beforeunload|blur|canplay|canplaythrough|change|click|contextmenu|copy|cut)\s*=/i', $tmpval); - $inj += preg_match('/on(dblclick|drop|durationchange|ended|error|focus|focusin|focusout|hashchange|input|invalid)\s*=/i', $tmpval); - $inj += preg_match('/on(keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|loadend|offline|online|pagehide|pageshow)\s*=/i', $tmpval); - $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|resize|reset|scroll|search|seeking|select|show|stalled|start|submit|suspend)\s*=/i', $tmpval); - $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting)\s*=/i', $tmpval); + // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers + $inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $val); // onmousexxx can be set on img or any html tag like + $inj += preg_match('/on(abort|afterprint|animation|auxclick|beforeprint|beforeunload|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)\s*=/i', $tmpval); + $inj += preg_match('/on(dblclick|drop|durationchange|emptied|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)\s*=/i', $tmpval); + $inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $tmpval); + $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $tmpval); + $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)\s*=/i', $tmpval); //$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ... $inj += preg_match('/:|:|:/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...' @@ -953,7 +949,7 @@ if (!defined('NOLOGIN')) { $_SESSION["dol_dst_second"] = isset($dol_dst_second) ? $dol_dst_second : ''; $_SESSION["dol_screenwidth"] = isset($dol_screenwidth) ? $dol_screenwidth : ''; $_SESSION["dol_screenheight"] = isset($dol_screenheight) ? $dol_screenheight : ''; - $_SESSION["dol_company"] = $conf->global->MAIN_INFO_SOCIETE_NOM; + $_SESSION["dol_company"] = getDolGlobalString("MAIN_INFO_SOCIETE_NOM"); $_SESSION["dol_entity"] = $conf->entity; // Store value into session (values stored only if defined) if (!empty($dol_hide_topmenu)) { @@ -2317,7 +2313,7 @@ function top_menu_quickadd() $dropDownQuickAddHtml .= ' '; diff --git a/htdocs/margin/tabs/productMargins.php b/htdocs/margin/tabs/productMargins.php index 4c34e04c54c..6f2337d1baf 100644 --- a/htdocs/margin/tabs/productMargins.php +++ b/htdocs/margin/tabs/productMargins.php @@ -39,10 +39,6 @@ $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); -if (empty($user->rights->margins->liretous)) { - accessforbidden(); -} $object = new Product($db); @@ -63,6 +59,12 @@ if (!$sortfield) { $sortfield = "f.datef"; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + +if (empty($user->rights->margins->liretous)) { + accessforbidden(); +} + /* * View diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php index b1c569c0912..505ff9f9f31 100644 --- a/htdocs/margin/tabs/thirdpartyMargins.php +++ b/htdocs/margin/tabs/thirdpartyMargins.php @@ -33,8 +33,6 @@ $socid = GETPOST('socid', 'int'); if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'societe', '', ''); - $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -61,6 +59,12 @@ if ($socid > 0) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('thirdpartymargins', 'globalcard')); +$result = restrictedArea($user, 'societe', $object->id, ''); + +if (empty($user->rights->margins->liretous)) { + accessforbidden(); +} + /* * Actions diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php index e38ddf9b93c..00cfcf842d5 100644 --- a/htdocs/master.inc.php +++ b/htdocs/master.inc.php @@ -230,7 +230,7 @@ if (!defined('NOREQUIREDB') && !defined('NOREQUIRESOC')) { // Set default language (must be after the setValues setting global $conf->global->MAIN_LANG_DEFAULT. Page main.inc.php will overwrite langs->defaultlang with user value later) if (!defined('NOREQUIRETRAN')) { $langcode = (GETPOST('lang', 'aZ09') ? GETPOST('lang', 'aZ09', 1) : (empty($conf->global->MAIN_LANG_DEFAULT) ? 'auto' : $conf->global->MAIN_LANG_DEFAULT)); - if (defined('MAIN_LANG_DEFAULT')) { + if (defined('MAIN_LANG_DEFAULT')) { // So a page can force the language whatever is setup and parameters in URL $langcode = constant('MAIN_LANG_DEFAULT'); } $langs->setDefaultLang($langcode); diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index 4619b04f7a1..bbd2724fb1c 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -131,7 +131,7 @@ $formproject = new FormProjets($db); if ($object->id > 0) { $title = $langs->trans("Agenda"); //if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; - $help_url = 'EN:Module_Agenda_En'; + $help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda|DE:Modul_Agenda'; llxHeader('', $title, $help_url); if (!empty($conf->notification->enabled)) { diff --git a/htdocs/opensurvey/results.php b/htdocs/opensurvey/results.php index 6d12259a39f..1c7a98739d7 100644 --- a/htdocs/opensurvey/results.php +++ b/htdocs/opensurvey/results.php @@ -251,7 +251,40 @@ if (GETPOSTISSET("ajoutercolonne") && $object->format == "D") { header('Location: results.php?id='.$object->id_sondage); } } - + if ($cleinsertion >= 0) { + $sql = 'SELECT s.reponses'; + $sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_user_studs as s"; + $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'"; + $resql = $db->query($sql); + if (!$resql) { + dol_print_error($db); + } else { + $num = $db->num_rows($resql); + $compteur = 0; + while ($compteur < $num) { + $obj = $db->fetch_object($resql); + $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_user_studs"; + if ($cleinsertion == 0) { + $sql .= " SET reponses = '0".$db->escape($obj->reponses)."'"; + } else { + $reponsesadd = str_split($obj->reponses); + $lengthresponses = count($reponsesadd); + for ($cpt = $lengthresponses; $cpt > $cleinsertion; $cpt--) { + $reponsesadd[$cpt] = $reponsesadd[$cpt-1]; + } + $reponsesadd[$cleinsertion] = '0'; + $reponsesadd = implode($reponsesadd); + $sql .= " SET reponses = '".$db->escape($reponsesadd)."'"; + } + $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'"; + $resql = $db->query($sql); + if (!$resql) { + dol_print_error($db); + } + $compteur++; + } + } + } $adresseadmin = $object->mail_admin; } else { $erreur_ajout_date = "yes"; diff --git a/htdocs/product/agenda.php b/htdocs/product/agenda.php index ea32e47c8a5..815014e259f 100644 --- a/htdocs/product/agenda.php +++ b/htdocs/product/agenda.php @@ -73,7 +73,21 @@ if (!$sortorder) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('agendathirdparty')); -$result = restrictedArea($user, 'produit|service', $id, 'product&product'); +$object = new Product($db); +if ($id > 0 || !empty($ref)) { + $object->fetch($id, $ref); +} + +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', 0, 'product&product', '', ''); +} /* diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 98fb4132bb8..61568a5510a 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -152,7 +152,17 @@ if (!empty($canvas)) { // Security check $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : '')); $fieldtype = (!empty($id) ? 'rowid' : 'ref'); -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +} // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productcard', 'globalcard')); @@ -1181,7 +1191,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($type != 1 && !empty($conf->stock->enabled)) { // Default warehouse print ''; - print $conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL; if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print ''; } diff --git a/htdocs/product/stats/bom.php b/htdocs/product/stats/bom.php index 053d9d6b1a8..505bc8ed060 100644 --- a/htdocs/product/stats/bom.php +++ b/htdocs/product/stats/bom.php @@ -41,7 +41,6 @@ $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatscontract')); @@ -67,6 +66,8 @@ if (!$sortfield) { $sortfield = "b.date_valid"; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + /* * View diff --git a/htdocs/product/stats/card.php b/htdocs/product/stats/card.php index 2dae292884e..d791100ae4a 100644 --- a/htdocs/product/stats/card.php +++ b/htdocs/product/stats/card.php @@ -58,7 +58,6 @@ if (!empty($user->socid)) { // Security check $fieldvalue = (!empty($id) ? $id : $ref); $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); $tmp = dol_getdate(dol_now()); $currentyear = $tmp['year']; @@ -66,6 +65,8 @@ if (empty($search_year)) { $search_year = $currentyear; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + /* * Actions diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php index fe8016f362a..9ba4dee7081 100644 --- a/htdocs/product/stats/commande.php +++ b/htdocs/product/stats/commande.php @@ -43,13 +43,10 @@ $socid = ''; if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatsorder')); -$mesg = ''; - // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -75,6 +72,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_year = ''; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + + /* * View */ diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index bc8346e39b1..6037f608b58 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -42,7 +42,6 @@ $socid = ''; if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatssupplyorder')); @@ -74,6 +73,8 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_year = ''; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + /* * View diff --git a/htdocs/product/stats/contrat.php b/htdocs/product/stats/contrat.php index e419593208c..f91e74edf50 100644 --- a/htdocs/product/stats/contrat.php +++ b/htdocs/product/stats/contrat.php @@ -40,13 +40,10 @@ $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatscontract')); -$mesg = ''; - // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -65,6 +62,8 @@ if (!$sortfield) { $sortfield = "c.date_contrat"; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + /* * View diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php index fa7d4fae24f..0681aa9b5ca 100644 --- a/htdocs/product/stats/facture.php +++ b/htdocs/product/stats/facture.php @@ -44,7 +44,6 @@ $socid = ''; if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatsinvoice')); @@ -77,6 +76,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_year = ''; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); /* diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php index 018f1c28f02..69ef83ae5a7 100644 --- a/htdocs/product/stats/facture_fournisseur.php +++ b/htdocs/product/stats/facture_fournisseur.php @@ -44,13 +44,10 @@ $socid = ''; if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatssupplyinvoice')); -$mesg = ''; - // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -76,6 +73,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_year = ''; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + + /* * View */ diff --git a/htdocs/product/stats/mo.php b/htdocs/product/stats/mo.php index 1cabfd9ef85..fefb89592e7 100644 --- a/htdocs/product/stats/mo.php +++ b/htdocs/product/stats/mo.php @@ -40,13 +40,10 @@ $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatscontract')); -$mesg = ''; - // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -65,6 +62,8 @@ if (!$sortfield) { $sortfield = "c.date_valid"; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + /* * View diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index 7dfc8b6d1db..96303ac598d 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -48,8 +48,6 @@ $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatspropal')); -$mesg = ''; - // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); @@ -76,6 +74,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_year = ''; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + + /* * View */ diff --git a/htdocs/product/stats/supplier_proposal.php b/htdocs/product/stats/supplier_proposal.php index 86689786b2d..1b236ed3999 100644 --- a/htdocs/product/stats/supplier_proposal.php +++ b/htdocs/product/stats/supplier_proposal.php @@ -43,13 +43,10 @@ $socid = ''; if (!empty($user->socid)) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productstatspropal')); -$mesg = ''; - // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); @@ -76,6 +73,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_year = ''; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + + /* * View */ diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php index b8698ff7ad3..91284944397 100644 --- a/htdocs/product/stock/card.php +++ b/htdocs/product/stock/card.php @@ -5,6 +5,7 @@ * Copyright (C) 2005-2014 Regis Houssin * Copyright (C) 2016 Francis Appels * Copyright (C) 2021 Noé Cendrier + * Copyright (C) 2021 Frédéric France * * 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 @@ -612,6 +613,14 @@ if ($action == 'create') { } $sql = "SELECT p.rowid as rowid, p.ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.price, p.price_ttc, p.entity,"; + $sql .= "p.tosell, p.tobuy,"; + $sql .= "p.accountancy_code_sell,"; + $sql .= "p.accountancy_code_sell_intra,"; + $sql .= "p.accountancy_code_sell_export,"; + $sql .= "p.accountancy_code_buy,"; + $sql .= "p.accountancy_code_buy_intra,"; + $sql .= "p.accountancy_code_buy_export,"; + $sql .= 'p.barcode,'; if ($separatedPMP) { $sql .= " pa.pmp as ppmp,"; } else { @@ -683,6 +692,15 @@ if ($action == 'create') { $productstatic->entity = $objp->entity; $productstatic->status_batch = $objp->tobatch; $productstatic->fk_unit = $objp->fk_unit; + $productstatic->status = $objp->tosell; + $productstatic->status_buy = $objp->tobuy; + $productstatic->barcode = $objp->barcode; + $productstatic->accountancy_code_sell = $objp->accountancy_code_sell; + $productstatic->accountancy_code_sell_intra = $objp->accountancy_code_sell_intra; + $productstatic->accountancy_code_sell_export = $objp->accountancy_code_sell_export; + $productstatic->accountancy_code_buy = $objp->accountancy_code_buy; + $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_buy_intra; + $productstatic->accountancy_code_buy_export = $objp->accountancy_code_buy_export; print $productstatic->getNomUrl(1, 'stock', 16); print ''; @@ -768,6 +786,7 @@ if ($action == 'create') { } print ''; print ''; + print ''; print ''; } else { dol_print_error($db); diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php index 9b022a840fc..42a03a1836a 100644 --- a/htdocs/product/stock/class/api_stockmovements.class.php +++ b/htdocs/product/stock/class/api_stockmovements.class.php @@ -95,7 +95,7 @@ class StockMovements extends DolibarrApi */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') { - global $db, $conf; + global $conf; $obj_ret = array(); @@ -176,7 +176,7 @@ class StockMovements extends DolibarrApi } if ($qty == 0) { - throw new RestException(503, "Making a stock movement with a quentity of 0 is not possible"); + throw new RestException(503, "Making a stock movement with a quantity of 0 is not possible"); } // Type increase or decrease diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index d8dad67bee2..959336c1671 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -126,31 +126,32 @@ class MouvementStock extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Add a movement of stock (in one direction only). + * This is the lowest level method to record a stock change. * $this->origin can be also be set to save the source object of movement. * - * @param User $user User object - * @param int $fk_product Id of product - * @param int $entrepot_id Id of warehouse - * @param int $qty Qty of movement (can be <0 or >0 depending on parameter type) - * @param int $type Direction of movement: - * 0=input (stock increase by a stock transfer), 1=output (stock decrease by a stock transfer), - * 2=output (stock decrease), 3=input (stock increase) - * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2. - * @param int $price Unit price HT of product, used to calculate average weighted price (AWP or PMP in french). If 0, average weighted price is not changed. - * @param string $label Label of stock movement - * @param string $inventorycode Inventory code - * @param string $datem Force date of movement + * @param User $user User object + * @param int $fk_product Id of product + * @param int $entrepot_id Id of warehouse + * @param int $qty Qty of movement (can be <0 or >0 depending on parameter type) + * @param int $type Direction of movement: + * 0=input (stock increase by a stock transfer), 1=output (stock decrease by a stock transfer), + * 2=output (stock decrease), 3=input (stock increase) + * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2. + * @param int $price Unit price HT of product, used to calculate average weighted price (AWP or PMP in french). If 0, average weighted price is not changed. + * @param string $label Label of stock movement + * @param string $inventorycode Inventory code + * @param string $datem Force date of movement * @param integer|string $eatby eat-by date. Will be used if lot does not exists yet and will be created. * @param integer|string $sellby sell-by date. Will be used if lot does not exists yet and will be created. - * @param string $batch batch number - * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record - * @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use) - * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct) - * @return int <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK + * @param string $batch batch number + * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record + * @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use) + * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct) + * @return int <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK */ public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0) { - // phpcs:disable + // phpcs:enable global $conf, $langs; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -159,39 +160,40 @@ class MouvementStock extends CommonObject $error = 0; dol_syslog(get_class($this)."::_create start userid=$user->id, fk_product=$fk_product, warehouse_id=$entrepot_id, qty=$qty, type=$type, price=$price, label=$label, inventorycode=$inventorycode, datem=".$datem.", eatby=".$eatby.", sellby=".$sellby.", batch=".$batch.", skip_batch=".$skip_batch); - // start hook at beginning - global $action, $hookmanager; - $hookmanager->initHooks(array('mouvementstock')); - // Hook of thirdparty module - if (is_object($hookmanager)) { + // Call hook at beginning + global $action, $hookmanager; + $hookmanager->initHooks(array('mouvementstock')); + + if (is_object($hookmanager)) { $parameters = array( - 'currentcontext' => 'mouvementstock', - 'user' => &$user, - 'fk_product' => &$fk_product, - 'entrepot_id' => &$entrepot_id, - 'qty' => &$qty, - 'type' => &$type, - 'price' => &$price, - 'label' => &$label, - 'inventorycode' => &$inventorycode, - 'datem' => &$datem, - 'eatby' => &$eatby, - 'sellby' => &$sellby, - 'batch' => &$batch, - 'skip_batch' => &$skip_batch, - 'id_product_batch' => &$id_product_batch + 'currentcontext' => 'mouvementstock', + 'user' => &$user, + 'fk_product' => &$fk_product, + 'entrepot_id' => &$entrepot_id, + 'qty' => &$qty, + 'type' => &$type, + 'price' => &$price, + 'label' => &$label, + 'inventorycode' => &$inventorycode, + 'datem' => &$datem, + 'eatby' => &$eatby, + 'sellby' => &$sellby, + 'batch' => &$batch, + 'skip_batch' => &$skip_batch, + 'id_product_batch' => &$id_product_batch ); - $reshook = $hookmanager->executeHooks('stockMovementCreate', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + $reshook = $hookmanager->executeHooks('stockMovementCreate', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { - if (!empty($hookmanager->resPrint)) + if (!empty($hookmanager->resPrint)) { dol_print_error('', $hookmanager->resPrint); + } return $reshook; } elseif ($reshook > 0) { return $hookmanager->resPrint; } - } - // end hook at beginning + } + // end hook at beginning // Clean parameters $price = price2num($price, 'MU'); // Clean value for the casse we receive a float zero value, to have it a real zero value. @@ -199,7 +201,8 @@ class MouvementStock extends CommonObject $now = (!empty($datem) ? $datem : dol_now()); // Check parameters - if (empty($fk_product)) return 0; + if (!($fk_product > 0)) return 0; + if (!($entrepot_id > 0)) return 0; if (is_numeric($eatby) && $eatby < 0) { dol_syslog(get_class($this)."::_create start ErrorBadValueForParameterEatBy eatby = ".$eatby); @@ -235,19 +238,25 @@ class MouvementStock extends CommonObject dol_print_error('', "Failed to fetch product"); return -1; } - if ($product->id <= 0) { // Can happen if database is corrupted + if ($product->id <= 0) { // Can happen if database is corrupted (a product id exist in stock with product that has been removed) return 0; } + // Define if we must make the stock change (If product type is a service or if stock is used also for services) + // Only record into stock tables wil be disabled by this (the rest like writing into lot table or movement of subproucts are done) + $movestock = 0; + if ($product->type != Product::TYPE_SERVICE || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) $movestock = 1; + $this->db->begin(); - $product->load_stock('novirtual'); + // Set value $product->stock_reel and detail per warehouse into $product->stock_warehouse array + if ($movestock) { + $product->load_stock('novirtual'); + } - // Test if product require batch data. If yes, and there is not, we throw an error. - if (!empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) - { - if (empty($batch)) - { + // Test if product require batch data. If yes, and there is not or values are not correct, we throw an error. + if (!empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { + if (empty($batch)) { $langs->load("errors"); $this->errors[] = $langs->transnoentitiesnoconv("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->ref); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); @@ -263,26 +272,20 @@ class MouvementStock extends CommonObject // If found and eatby/sellby not defined into table and not provided, we do nothing // If not found, we add record $sql = "SELECT pb.rowid, pb.batch, pb.eatby, pb.sellby FROM ".MAIN_DB_PREFIX."product_lot as pb"; - $sql .= " WHERE pb.fk_product = ".$fk_product." AND pb.batch = '".$this->db->escape($batch)."'"; + $sql .= " WHERE pb.fk_product = ".((int) $fk_product)." AND pb.batch = '".$this->db->escape($batch)."'"; dol_syslog(get_class($this)."::_create scan serial for this product to check if eatby and sellby match", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - if ($num > 0) - { - while ($i < $num) - { + if ($num > 0) { + while ($i < $num) { $obj = $this->db->fetch_object($resql); - if ($obj->eatby) - { - if ($eatby) - { + if ($obj->eatby) { + if ($eatby) { $tmparray = dol_getdate($eatby, true); $eatbywithouthour = dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); - if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) // We test date without hours and with hours for backward compatibility - { + if ($this->db->jdate($obj->eatby) != $eatby && $this->db->jdate($obj->eatby) != $eatbywithouthour) { // We test date without hours and with hours for backward compatibility // If found and eatby/sellby defined into table and provided and differs, return error $langs->load("stocks"); $this->errors[] = $langs->transnoentitiesnoconv("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->eatby), 'dayhour'), dol_print_date($eatbywithouthour, 'dayhour')); @@ -294,14 +297,12 @@ class MouvementStock extends CommonObject $eatby = $obj->eatby; // If found and eatby/sellby defined into table and not provided, we take value from table } } else { - if ($eatby) // If found and eatby/sellby not defined into table and provided, we update table - { + if ($eatby) { // If found and eatby/sellby not defined into table and provided, we update table $productlot = new Productlot($this->db); $result = $productlot->fetch($obj->rowid); $productlot->eatby = $eatby; $result = $productlot->update($user); - if ($result <= 0) - { + if ($result <= 0) { $this->error = $productlot->error; $this->errors = $productlot->errors; $this->db->rollback(); @@ -309,14 +310,11 @@ class MouvementStock extends CommonObject } } } - if ($obj->sellby) - { - if ($sellby) - { + if ($obj->sellby) { + if ($sellby) { $tmparray = dol_getdate($sellby, true); $sellbywithouthour = dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); - if ($this->db->jdate($obj->sellby) != $sellby && $this->db->jdate($obj->sellby) != $sellbywithouthour) // We test date without hours and with hours for backward compatibility - { + if ($this->db->jdate($obj->sellby) != $sellby && $this->db->jdate($obj->sellby) != $sellbywithouthour) { // We test date without hours and with hours for backward compatibility // If found and eatby/sellby defined into table and provided and differs, return error $this->errors[] = $langs->transnoentitiesnoconv("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->sellby)), dol_print_date($sellby)); dol_syslog($langs->transnoentities("ThisSerialAlreadyExistWithDifferentDate", $batch, dol_print_date($this->db->jdate($obj->sellby)), dol_print_date($sellby)), LOG_ERR); @@ -326,17 +324,13 @@ class MouvementStock extends CommonObject } else { $sellby = $obj->sellby; // If found and eatby/sellby defined into table and not provided, we take value from table } - } - else - { - if ($sellby) // If found and eatby/sellby not defined into table and provided, we update table - { + } else { + if ($sellby) { // If found and eatby/sellby not defined into table and provided, we update table $productlot = new Productlot($this->db); $result = $productlot->fetch($obj->rowid); $productlot->sellby = $sellby; $result = $productlot->update($user); - if ($result <= 0) - { + if ($result <= 0) { $this->error = $productlot->error; $this->errors = $productlot->errors; $this->db->rollback(); @@ -347,9 +341,7 @@ class MouvementStock extends CommonObject $i++; } - } - else // If not found, we add record - { + } else { // If not found, we add record $productlot = new Productlot($this->db); $productlot->entity = $conf->entity; $productlot->fk_product = $fk_product; @@ -358,44 +350,33 @@ class MouvementStock extends CommonObject $productlot->eatby = $eatby; $productlot->sellby = $sellby; $result = $productlot->create($user); - if ($result <= 0) - { + if ($result <= 0) { $this->error = $productlot->error; $this->errors = $productlot->errors; $this->db->rollback(); return -4; } } - } - else - { + } else { dol_print_error($this->db); $this->db->rollback(); return -1; } } - // Define if we must make the stock change (If product type is a service or if stock is used also for services) - $movestock = 0; - if ($product->type != Product::TYPE_SERVICE || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) $movestock = 1; - // Check if stock is enough when qty is < 0 // Note that qty should be > 0 with type 0 or 3, < 0 with type 1 or 2. - if ($movestock && $qty < 0 && empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) - { - if (!empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) - { + if ($movestock && $qty < 0 && empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER)) { + if (!empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { $foundforbatch = 0; $qtyisnotenough = 0; - foreach ($product->stock_warehouse[$entrepot_id]->detail_batch as $batchcursor => $prodbatch) - { + foreach ($product->stock_warehouse[$entrepot_id]->detail_batch as $batchcursor => $prodbatch) { if ($batch != $batchcursor) continue; $foundforbatch = 1; if ($prodbatch->qty < abs($qty)) $qtyisnotenough = $prodbatch->qty; break; } - if (!$foundforbatch || $qtyisnotenough) - { + if (!$foundforbatch || $qtyisnotenough) { $langs->load("stocks"); include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; $tmpwarehouse = new Entrepot($this->db); @@ -406,11 +387,8 @@ class MouvementStock extends CommonObject $this->db->rollback(); return -8; } - } - else - { - if (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) - { + } else { + if (empty($product->stock_warehouse[$entrepot_id]->real) || $product->stock_warehouse[$entrepot_id]->real < abs($qty)) { $langs->load("stocks"); $this->error = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; $this->errors[] = $langs->trans('qtyToTranferIsNotEnough').' : '.$product->ref; @@ -420,8 +398,7 @@ class MouvementStock extends CommonObject } } - if ($movestock && $entrepot_id > 0) // Change stock for current product, change for subproduct is done after - { + if ($movestock) { // Change stock for current product, change for subproduct is done after // Set $origintype, fk_origin, fk_project $fk_project = 0; if (!empty($this->origin)) { // This is set by caller for tracking reason @@ -431,10 +408,8 @@ class MouvementStock extends CommonObject $fk_project = $fk_origin; } else { $res = $this->origin->fetch($fk_origin); - if ($res > 0) - { - if (!empty($this->origin->fk_project)) - { + if ($res > 0) { + if (!empty($this->origin->fk_project)) { $fk_project = $this->origin->fk_project; } } @@ -466,13 +441,10 @@ class MouvementStock extends CommonObject dol_syslog(get_class($this)."::_create insert record into stock_mouvement", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $mvid = $this->db->last_insert_id(MAIN_DB_PREFIX."stock_mouvement"); $this->id = $mvid; - } - else - { + } else { $this->error = $this->db->lasterror(); $this->errors[] = $this->error; $error = -1; @@ -485,18 +457,15 @@ class MouvementStock extends CommonObject // Test if there is already a record for couple (warehouse / product), so later we will make an update or create. $alreadyarecord = 0; - if (!$error) - { + if (!$error) { $sql = "SELECT rowid, reel FROM ".MAIN_DB_PREFIX."product_stock"; $sql .= " WHERE fk_entrepot = ".((int) $entrepot_id)." AND fk_product = ".((int) $fk_product); // This is a unique key dol_syslog(get_class($this)."::_create check if a record already exists in product_stock", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $obj = $this->db->fetch_object($resql); - if ($obj) - { + if ($obj) { $alreadyarecord = 1; $oldqtywarehouse = $obj->reel; $fk_product_stock = $obj->rowid; @@ -510,10 +479,8 @@ class MouvementStock extends CommonObject // Calculate new AWP (PMP) $newpmp = 0; - if (!$error) - { - if ($type == 0 || $type == 3) - { + if (!$error) { + if ($type == 0 || $type == 3) { // After a stock increase // Note: PMP is calculated on stock input only (type of movement = 0 or 3). If type == 0 or 3, qty should be > 0. // Note: Price should always be >0 or 0. PMP should be always >0 (calculated on input) @@ -540,10 +507,8 @@ class MouvementStock extends CommonObject } } // Update stock quantity - if (!$error) - { - if ($alreadyarecord > 0) - { + if (!$error) { + if ($alreadyarecord > 0) { $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET reel = reel + ".((float) $qty); $sql .= " WHERE fk_entrepot = ".((int) $entrepot_id)." AND fk_product = ".((int) $fk_product); } else { @@ -554,51 +519,29 @@ class MouvementStock extends CommonObject dol_syslog(get_class($this)."::_create update stock value", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { $this->errors[] = $this->db->lasterror(); $error = -3; - } - elseif (empty($fk_product_stock)) - { + } elseif (empty($fk_product_stock)) { $fk_product_stock = $this->db->last_insert_id(MAIN_DB_PREFIX."product_stock"); } } - // Update detail stock for batch product - if (!$error && !empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) - { - // check unicity for serial numbered equipments ( different for lots managed products) - if ( $product->status_batch == 2 && $qty > 0 ) - { - if ( $this->getBatchCount($fk_product, $batch) > 0 ) - { - $error++; - $this->errors[] = $langs->trans("SerialNumberAlreadyInUse", $batch, $product->ref); - } - elseif ( $qty > 1 ) - { - $error++; - $this->errors[] = $langs->trans("TooManyQtyForSerialNumber", $product->ref, $batch); - } + // Update detail of stock for the lot. + if (!$error && !empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { + if ($id_product_batch > 0) { + $result = $this->createBatch($id_product_batch, $qty); + } else { + $param_batch = array('fk_product_stock' =>$fk_product_stock, 'batchnumber'=>$batch); + $result = $this->createBatch($param_batch, $qty); } - - if ( ! $error ) - { - if ($id_product_batch > 0) - { - $result = $this->createBatch($id_product_batch, $qty); - } else { - $param_batch = array('fk_product_stock' =>$fk_product_stock, 'batchnumber'=>$batch); - $result = $this->createBatch($param_batch, $qty); - } - if ($result < 0) $error++; + if ($result < 0) { + $error++; } } // Update PMP and denormalized value of stock qty at product level - if (!$error) - { + if (!$error) { $newpmp = price2num($newpmp, 'MU'); // $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty; @@ -610,8 +553,7 @@ class MouvementStock extends CommonObject dol_syslog(get_class($this)."::_create update AWP", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { $this->errors[] = $this->db->lasterror(); $error = -4; } @@ -625,26 +567,31 @@ class MouvementStock extends CommonObject } // Add movement for sub products (recursive call) - if (!$error && !empty($conf->global->PRODUIT_SOUSPRODUITS) && empty($conf->global->INDEPENDANT_SUBPRODUCT_STOCK) && empty($disablestockchangeforsubproduct)) - { + if (!$error && !empty($conf->global->PRODUIT_SOUSPRODUITS) && empty($conf->global->INDEPENDANT_SUBPRODUCT_STOCK) && empty($disablestockchangeforsubproduct)) { $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, 0, $label, $inventorycode); // we use 0 as price, because AWP must not change for subproduct } - if ($movestock && !$error) - { + if ($movestock && !$error) { // Call trigger $result = $this->call_trigger('STOCK_MOVEMENT', $user); if ($result < 0) $error++; // End call triggers + + // Check unicity for serial numbered equipments once all movement were done. + if (!$error && !empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch) { + if ($product->status_batch == 2 && $qty > 0) { // We check only if we increased qty + if ($this->getBatchCount($fk_product, $batch) > 1) { + $error++; + $this->errors[] = $langs->trans("TooManyQtyForSerialNumber", $batch, $product->ref); + } + } + } } - if (!$error) - { + if (!$error) { $this->db->commit(); return $mvid; - } - else - { + } else { $this->db->rollback(); dol_syslog(get_class($this)."::_create error code=".$error, LOG_ERR); return -6; @@ -768,35 +715,27 @@ class MouvementStock extends CommonObject dol_syslog(get_class($this)."::_createSubProduct for parent product ".$idProduct, LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $i = 0; - while ($obj = $this->db->fetch_object($resql)) - { + while ($obj = $this->db->fetch_object($resql)) { $pids[$i] = $obj->fk_product_fils; $pqtys[$i] = $obj->qty; $i++; } $this->db->free($resql); - } - else - { + } else { $error = -2; } // Create movement for each subproduct - foreach ($pids as $key => $value) - { - if (!$error) - { + foreach ($pids as $key => $value) { + if (!$error) { $tmpmove = dol_clone($this, 1); $result = $tmpmove->_create($user, $pids[$key], $entrepot_id, ($qty * $pqtys[$key]), $type, 0, $label, $inventorycode); // This will also call _createSubProduct making this recursive - if ($result < 0) - { + if ($result < 0) { $this->error = $tmpmove->error; $this->errors = array_merge($this->errors, $tmpmove->errors); - if ($result == -2) - { + if ($result == -2) { $this->errors[] = $langs->trans("ErrorNoteAlsoThatSubProductCantBeFollowedByLot"); } $error = $result; @@ -862,27 +801,26 @@ class MouvementStock extends CommonObject } - /** - * Return nb of subproducts lines for a product - * - * @param int $id Id of product - * @return int <0 if KO, nb of subproducts if OK - * @deprecated A count($product->getChildsArbo($id,1)) is same. No reason to have this in this class. - */ - /* - public function nbOfSubProducts($id) - { - $nbSP=0; + // /** + // * Return nb of subproducts lines for a product + // * + // * @param int $id Id of product + // * @return int <0 if KO, nb of subproducts if OK + // * @deprecated A count($product->getChildsArbo($id,1)) is same. No reason to have this in this class. + // */ + // public function nbOfSubProducts($id) + // { + // $nbSP=0; - $resql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."product_association"; - $resql.= " WHERE fk_product_pere = ".((int) $id); - if ($this->db->query($resql)) - { - $obj=$this->db->fetch_object($resql); - $nbSP=$obj->nb; - } - return $nbSP; - }*/ + // $resql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."product_association"; + // $resql.= " WHERE fk_product_pere = ".((int) $id); + // if ($this->db->query($resql)) + // { + // $obj=$this->db->fetch_object($resql); + // $nbSP=$obj->nb; + // } + // return $nbSP; + // } /** * Count number of product in stock before a specific date @@ -901,8 +839,7 @@ class MouvementStock extends CommonObject dol_syslog(get_class($this).__METHOD__.'', LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $obj = $this->db->fetch_object($resql); if ($obj) $nb = $obj->nb; return (empty($nb) ? 0 : $nb); @@ -930,19 +867,16 @@ class MouvementStock extends CommonObject $result = 0; // Try to find an existing record with same batch number or id - if (is_numeric($dluo)) - { + if (is_numeric($dluo)) { $result = $pdluo->fetch($dluo); - if (empty($pdluo->id)) - { + if (empty($pdluo->id)) { // We didn't find the line. May be it was deleted before by a previous move in same transaction. $this->error = 'Error. You ask a move on a record for a serial that does not exists anymore. May be you take the same serial on same warehouse several times in same shipment or it was used by another shipment. Remove this shipment and prepare another one.'; $this->errors[] = $this->error; $result = -2; } } elseif (is_array($dluo)) { - if (isset($dluo['fk_product_stock'])) - { + if (isset($dluo['fk_product_stock'])) { $vfk_product_stock = $dluo['fk_product_stock']; $vbatchnumber = $dluo['batchnumber']; @@ -956,8 +890,7 @@ class MouvementStock extends CommonObject $result = -1; } - if ($result >= 0) - { + if ($result >= 0) { // No error if ($pdluo->id > 0) { // product_batch record found //print "Avant ".$pdluo->qty." Apres ".($pdluo->qty + $qty)."
    "; @@ -975,8 +908,7 @@ class MouvementStock extends CommonObject $pdluo->batch = $vbatchnumber; $result = $pdluo->create($user, 1); - if ($result < 0) - { + if ($result < 0) { $this->error = $pdluo->error; $this->errors = $pdluo->errors; } @@ -1036,6 +968,10 @@ class MouvementStock extends CommonObject require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php'; $origin = new Reception($this->db); break; + case 'inventory': + require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; + $origin = new Inventory($this->db); + break; default: if ($origintype) { @@ -1269,16 +1205,14 @@ class MouvementStock extends CommonObject } /** - * Retrieve number of equipments for a product batch + * Retrieve number of equipments for a product lot/serial * - * @param int $fk_product Product id - * @param varchar $batch batch number - * @return int <0 if KO, number of equipments if OK + * @param int $fk_product Product id + * @param string $batch batch number + * @return int <0 if KO, number of equipments found if OK */ private function getBatchCount($fk_product, $batch) { - global $conf; - $cpt = 0; $sql = "SELECT sum(pb.qty) as cpt"; diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index b97e9b6c2d2..5908785e1cb 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -9,6 +9,7 @@ * Copyright (C) 2014-2015 Cédric Gross * Copyright (C) 2015 Marcos García * Copyright (C) 2018-2019 Frédéric France + * Copyright (C) 2021 Gauthier VERDOL * * 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 @@ -81,8 +82,6 @@ if (!empty($batchnumber)) { if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit&stock', $id, 'product&product', '', '', $fieldid); - $object = new Product($db); $extrafields = new ExtraFields($db); @@ -114,6 +113,17 @@ $hookmanager->initHooks(array('stockproductcard', 'globalcard')); $error = 0; +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $id, 'product&product', '', '', $fieldid); +} + /* * Actions @@ -521,6 +531,45 @@ if ($id > 0 || $ref) { llxHeader('', $title, $helpurl); + if (!empty($conf->use_javascript_ajax)) { + ?> + + 0) { $head = product_prepare_head($object); $titre = $langs->trans("CardProduct".$object->type); @@ -859,15 +908,21 @@ if (!$variants) { print ''; if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) { $colspan = 3; - print ''; + print ''; print ''; if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { $colspan--; - print ''; + print ''; } if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { $colspan--; - print ''; + print ''; } print ''; print ''; @@ -914,7 +969,14 @@ if (!$variants) { $stock_real = price2num($obj->reel, 'MS'); print ''; - print ''; + print ''; print ''; // PMP print ''; @@ -984,7 +1046,7 @@ if (!$variants) { print ''; print ''; } else { - print "\n".''; print '\n"; + $oldtypeid = $member->typeid; + $newtypeid = (int) (GETPOSTISSET("typeid") ? GETPOST("typeid", 'int') : $member->typeid); - require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; - $adht = new AdherentType($db); - // Amount by member type - $amountbytype = $adht->amountByType(1); - // Set the member type - $member->typeid = (int) (GETPOSTISSET("typeid") ? GETPOST("typeid", 'int') : $member->typeid); - // If we change the type of membership, we set also label of new type - $member->type = dol_getIdFromCode($db, $member->typeid, 'adherent_type', 'rowid', 'libelle'); - // Set amount for the subscription - $amount = (!empty($amountbytype[$member->typeid])) ? $amountbytype[$member->typeid] : $member->last_subscription_amount; - // list member type - if ( !$action) { - $form = new Form($db); // so we can call method selectarray - print '\n"; - } elseif ($action == dopayment) { - print '\n"; + + // Set the new member type + $member->typeid = $newtypeid; + $member->type = dol_getIdFromCode($db, $newtypeid, 'adherent_type', 'rowid', 'libelle'); + + // list member type + if (!$action) { + // Set amount for the subscription + $amount = (!empty($amountbytype[$member->typeid])) ? $amountbytype[$member->typeid] : $member->last_subscription_amount; + + print '\n"; + } elseif ($action == dopayment) { + print '\n"; + } + } else { + print '\n"; } } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 4973a328023..aa8205bfa99 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -48,13 +48,13 @@ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; if (!empty($conf->adherent->enabled)) { require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; } -if (! empty($conf->accounting->enabled)) { +if (!empty($conf->accounting->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; } -if (! empty($conf->accounting->enabled)) { +if (!empty($conf->accounting->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; } -if (! empty($conf->accounting->enabled)) { +if (!empty($conf->accounting->enabled)) { require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; } @@ -398,12 +398,12 @@ if (empty($reshook)) { $error++; } - if (!empty($conf->mailing->enabled) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && GETPOST('contact_no_email', 'int')==-1 && !empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) { + if (!empty($conf->mailing->enabled) && !empty($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && GETPOST('contact_no_email', 'int')==-1 && !empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("No_Email")), null, 'errors'); } - if (!empty($conf->mailing->enabled) && GETPOST("private", 'int') == 1 && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && GETPOST('contact_no_email', 'int')==-1 && !empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) { + if (!empty($conf->mailing->enabled) && GETPOST("private", 'int') == 1 && !empty($conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS) && $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS==-1 && GETPOST('contact_no_email', 'int')==-1 && !empty(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL))) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("No_Email")), null, 'errors'); } @@ -610,7 +610,7 @@ if (empty($reshook)) { } // Logo/Photo save - $dir = $conf->societe->multidir_output[$conf->entity]."/".$object->id."/logos/"; + $dir = $conf->societe->multidir_output[$conf->entity]."/".$object->id."/logos/"; $file_OK = is_uploaded_file($_FILES['photo']['tmp_name']); if ($file_OK) { if (image_format_supported($_FILES['photo']['name'])) { @@ -852,7 +852,7 @@ if (empty($reshook)) { // Set parent company if ($action == 'set_thirdparty' && $user->rights->societe->creer) { $object->fetch($socid); - $result = $object->set_parent(GETPOST('parent_id', 'int')); + $result = $object->setParent(GETPOST('parent_id', 'int')); } // Set sales representatives @@ -892,7 +892,7 @@ $form = new Form($db); $formfile = new FormFile($db); $formadmin = new FormAdmin($db); $formcompany = new FormCompany($db); -if (! empty($conf->accounting->enabled)) { +if (!empty($conf->accounting->enabled)) { $formaccounting = new FormAccounting($db); } @@ -1399,7 +1399,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } print ''; - print ''; + print ''; } print ''; print ''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index e53675d8bb6..7554ad2fbe2 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -3321,22 +3321,32 @@ class Societe extends CommonObject } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Define parent commany of current company * * @param int $id Id of thirdparty to set or '' to remove * @return int <0 if KO, >0 if OK */ - public function set_parent($id) + public function setParent($id) { - // phpcs:enable + dol_syslog(get_class($this).'::setParent', LOG_DEBUG); + if ($this->id) { - $sql = "UPDATE ".MAIN_DB_PREFIX."societe"; - $sql .= " SET parent = ".($id > 0 ? $id : "null"); - $sql .= " WHERE rowid = ".$this->id; - dol_syslog(get_class($this).'::set_parent', LOG_DEBUG); - $resql = $this->db->query($sql); + // Check if the id we want to add as parent has not already one parent that is the current id we try to update + if ($id > 0) { + $sameparent = $this->validateFamilyTree($id, $this->id, 0); + if ($sameparent < 0) { + return -1; + } + if ($sameparent == 1) { + setEventMessages('ParentCompanyToAddIsAlreadyAChildOfModifiedCompany', null, 'warnings'); + return -1; + } + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe SET parent = '.($id > 0 ? $id : 'null').' WHERE rowid = '.((int) $this->id); + + $resql = $this->db->query($sql); if ($resql) { $this->parent = $id; return 1; @@ -3348,6 +3358,40 @@ class Societe extends CommonObject } } + /** + * Check if a thirdparty $idchild is or not inside the parents (or grand parents) of another thirdparty id $idparent. + * + * @param int $idparent Id of thirdparty to check + * @param int $idchild Id of thirdparty to compare to + * @param int $counter Counter to protect against infinite loops + * @return int <0 if KO, 0 if OK or 1 if at some level a parent company was the child to compare to + */ + public function validateFamilyTree($idparent, $idchild, $counter = 0) + { + if ($counter > 100) { + dol_syslog("Too high level of parent - child for company. May be an infinite loop ?", LOG_WARNING); + } + + $sql = 'SELECT s.parent'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; + $sql .= ' WHERE rowid = '.$idparent; + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + + if ($obj->parent == '') { + return 0; + } elseif ($obj->parent == $idchild) { + return 1; + } else { + $sameparent = $this->validateFamilyTree($obj->parent, $idchild, ($counter + 1)); + } + return $sameparent; + } else { + return -1; + } + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Returns if a profid sould be verified to be unique diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index f79857d744f..0a3e9207a96 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -467,10 +467,10 @@ if ($search_sale && $search_sale != '-1') { $sql .= ", sc.fk_soc, sc.fk_user"; } // We'll need these fields in order to filter by categ -if ($search_categ_cus) { +if ($search_categ_cus && $search_categ_cus!=-1) { $sql .= ", cc.fk_categorie, cc.fk_soc"; } -if ($search_categ_sup) { +if ($search_categ_sup && $search_categ_sup!=-1) { $sql .= ", cs.fk_categorie, cs.fk_soc"; } // Add fields from extrafields @@ -494,10 +494,10 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_effectif as staff on (staff.id = s.fk_ef $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as region on (region. code_region = state.fk_region)"; // We'll need this table joined to the select in order to filter by categ -if (!empty($search_categ_cus)) { +if (!empty($search_categ_cus) && $search_categ_cus!=-1) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_societe as cc ON s.rowid = cc.fk_soc"; // We'll need this table joined to the select in order to filter by categ } -if (!empty($search_categ_sup)) { +if (!empty($search_categ_sup) && $search_categ_sup!=-1) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc"; // We'll need this table joined to the select in order to filter by categ } $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."c_stcomm as st ON s.fk_stcomm = st.id"; diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 7f325090b5e..5614b3c6138 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -514,7 +514,7 @@ class Stripe extends CommonObject if (!$resql) { $error++; $this->error = $this->db->lasterror(); - dol_syslog(get_class($this)."::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database."); + dol_syslog(get_class($this)."::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database.", LOG_ERR); } } } else { diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index cad41f905ef..633f0785fe1 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1862,7 +1862,7 @@ if ($action == 'create') { // Create an order if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled)) && $object->statut == SupplierProposal::STATUS_SIGNED) { if ($usercancreateorder) { - print ''; + print ''; } } diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 1f9e6c32b2b..d51fd21279e 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -289,6 +289,8 @@ function LoadProducts(position, issubcat) { if (currentcat==val.fk_parent) { $("#prodivdesc"+ishow).show(); $("#prodesc"+ishow).text(val.label); + $("#probutton"+ishow).text(val.label); + $("#probutton"+ishow).show(); $("#proprice"+ishow).attr("class", "hidden"); $("#proprice"+ishow).html(""); $("#proimg"+ishow).attr("src","genimg/index.php?query=cat&id="+val.rowid); @@ -386,6 +388,8 @@ function MoreProducts(moreorless) { if (typeof (data[idata]) == "undefined") { $("#prodivdesc"+ishow).hide(); $("#prodesc"+ishow).text(""); + $("#probutton"+ishow).text(""); + $("#probutton"+ishow).hide(); $("#proprice"+ishow).attr("class", ""); $("#proprice"+ishow).html(""); $("#proimg"+ishow).attr("src","genimg/empty.png"); @@ -396,6 +400,8 @@ function MoreProducts(moreorless) { //Only show products with status=1 (for sell) $("#prodivdesc"+ishow).show(); $("#prodesc"+ishow).text(data[parseInt(idata)]['label']); + $("#probutton"+ishow).text(data[parseInt(idata)]['label']); + $("#probutton"+ishow).show(); if (data[parseInt(idata)]['price_formated']) { $("#proprice"+ishow).attr("class", "productprice"); $("#proprice"+ishow).html(data[parseInt(idata)]['price_formated']); @@ -544,6 +550,8 @@ function Search2(keyCodeForEnter) { for (i = 0; i < ; i++) { if (typeof (data[i]) == "undefined") { $("#prodesc" + i).text(""); + $("#probutton" + i).text(""); + $("#probutton" + i).hide(); $("#proprice" + i).attr("class", "hidden"); $("#proprice" + i).html(""); $("#proimg" + i).attr("src", "genimg/empty.png"); @@ -557,6 +565,8 @@ function Search2(keyCodeForEnter) { var titlestring = ; $("#prodesc" + i).text(data[i]['label']); $("#prodivdesc" + i).show(); + $("#probutton" + i).text(data[i]['label']); + $("#probutton" + i).show(); if (data[i]['price_formated']) { $("#proprice" + i).attr("class", "productprice"); $("#proprice" + i).html(data[i]['price_formated']); diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index d874266f81d..7122c252cbe 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -51,7 +51,12 @@ if (!empty($conf->global->THEME_DARKMODEENABLED)) { }*/ div.tabsAction > a.butAction, div.tabsAction > a.butActionRefused, div.tabsAction > a.butActionDelete, div.tabsAction > span.butAction, div.tabsAction > span.butActionRefused, div.tabsAction > span.butActionDelete, -div.tabsAction > div.divButAction > span.butAction { +div.tabsAction > div.divButAction > span.butAction, +div.tabsAction > div.divButAction > span.butActionDelete, +div.tabsAction > div.divButAction > span.butActionRefused, +div.tabsAction > div.divButAction > a.butAction, +div.tabsAction > div.divButAction > a.butActionDelete, +div.tabsAction > div.divButAction > a.butActionRefused { margin-bottom: 1.4em !important; margin-right: 0px !important; } @@ -303,6 +308,23 @@ div.pagination li:first-child a.btnTitle{ } } +/* rule to reduce top menu - 3rd reduction: The menu for user is on left */ +@media only screen and (max-width: global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3) ? round($nbtopmenuentries * 47, 0) + 130 : $conf->global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3; ?>px) /* reduction 3 */ +{ + .butAction, .butActionRefused, .butActionDelete { + font-size: 0.9em; + } +} + +/* smartphone */ +@media only screen and (max-width: 767px) +{ + .butAction, .butActionRefused, .butActionDelete { + font-size: 0.85em; + } +} + + global->MAIN_BUTTON_HIDE_UNAUTHORIZED) && (!$user->admin)) { ?> .butActionRefused, .butActionNewRefused, .btnTitle.refused { display: none !important; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index e451a2af30b..4468c36a7da 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -633,6 +633,9 @@ th .button { .quatrevingtquinzepercent { width: 95%; } +.quatrevingtpercentminusx { + width: calc(80% - 52px); +} textarea.centpercent { width: 96%; } @@ -902,8 +905,8 @@ span.fa.fa-plus-circle.paddingleft { height: 28px; vertical-align: middle; } -.divsocialnetwork:not(:first-child) { - padding-left: 20px; +.divsocialnetwork:not(:last-child) { + padding-: 20px; } div.divsearchfield { float: ; @@ -1027,6 +1030,7 @@ ul.attendees li { list-style-type: none; padding-top:1px; padding-bottom:1px; + line-height: 1.6em; } .googlerefreshcal { padding-top: 4px; @@ -1472,6 +1476,10 @@ select.widthcentpercentminusxx, span.widthcentpercentminusxx:not(.select2-select width: calc(100% - 40px) !important; display: inline-block; } + select.widthcentpercentminusxx, span.widthcentpercentminusxx:not(.select2-selection), input.widthcentpercentminusxx { + width: calc(100% - 70px) !important; + display: inline-block; + } .logopublicpayment #dolpaymentlogo { max-width: 260px; @@ -6770,10 +6778,14 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before /* For copy-paste feature */ /* ============================================================================== */ +span.clipboardCPValueToPrint { + display: inline-block; +} span.clipboardCPValue.hidewithsize { width: 0 !important; display: inline-block; color: transparent; + white-space: nowrap; } .clipboardCPShowOnHover .clipboardCPButton { diff --git a/htdocs/theme/md/btn.inc.php b/htdocs/theme/md/btn.inc.php index c0d6e2c9cd7..2517415a96f 100644 --- a/htdocs/theme/md/btn.inc.php +++ b/htdocs/theme/md/btn.inc.php @@ -379,6 +379,23 @@ div.pagination .btnTitle:hover .btnTitle-label{ } } +/* rule to reduce top menu - 3rd reduction: The menu for user is on left */ +@media only screen and (max-width: global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3) ? round($nbtopmenuentries * 47, 0) + 130 : $conf->global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3; ?>px) /* reduction 3 */ +{ + .butAction, .butActionRefused, .butActionDelete { + font-size: 0.9em; + } +} + +/* smartphone */ +@media only screen and (max-width: 767px) +{ + .butAction, .butActionRefused, .butActionDelete { + font-size: 0.85em; + } +} + + global->MAIN_BUTTON_HIDE_UNAUTHORIZED) && (!$user->admin)) { ?> .butActionRefused, .butActionNewRefused, .btnTitle.refused { display: none !important; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 1ebe047ead7..f1fb649f4af 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -780,6 +780,9 @@ th .button { textarea.centpercent { width: 96%; } +.quatrevingtpercentminusx { + width: calc(80% - 52px); +} .small, small { font-size: 85%; } @@ -1002,8 +1005,8 @@ body[class*="colorblind-"] .text-success{ height: 28px; vertical-align: middle; } -.divsocialnetwork:not(:first-child) { - padding-left: 20px; +.divsocialnetwork:not(:last-child) { + padding-: 20px; } div.divsearchfield { float: ; @@ -1496,6 +1499,18 @@ table[summary="list_of_modules"] .fa-cog { padding-right: 10px !important; } + .hideonsmartphone { display: none; } + .hideonsmartphoneimp { display: none !important; } + + select.minwidth100imp, select.minwidth100, select.minwidth200, select.minwidth200imp, select.minwidth300 { + width: calc(100% - 40px) !important; + display: inline-block; + } + select.widthcentpercentminusxx, span.widthcentpercentminusxx:not(.select2-selection), input.widthcentpercentminusxx { + width: calc(100% - 70px) !important; + display: inline-block; + } + .poweredbyimg { width: 48px; } @@ -1580,8 +1595,6 @@ table[summary="list_of_modules"] .fa-cog { line-height: 1.4em; } - .hideonsmartphone { display: none; } - .hideonsmartphoneimp { display: none !important; } .noenlargeonsmartphone { width : 50px !important; display: inline !important; } .maxwidthonsmartphone, #search_newcompany.ui-autocomplete-input { max-width: 100px; } .maxwidth50onsmartphone { max-width: 40px; } @@ -6634,10 +6647,14 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before /* For copy-paste feature */ /* ============================================================================== */ +span.clipboardCPValueToPrint { + display: inline-block; +} span.clipboardCPValue.hidewithsize { width: 0 !important; display: inline-block; color: transparent; + white-space: nowrap; } .clipboardCPShowOnHover .clipboardCPButton { diff --git a/htdocs/user/agenda_extsites.php b/htdocs/user/agenda_extsites.php index 3faf6dc770c..b474bdfc678 100644 --- a/htdocs/user/agenda_extsites.php +++ b/htdocs/user/agenda_extsites.php @@ -206,15 +206,15 @@ while ($i <= $MAXAGENDA) { print '"; // Name $name_value = (GETPOST('AGENDA_EXT_NAME_'.$id.'_'.$key) ?GETPOST('AGENDA_EXT_NAME_'.$id.'_'.$key) : (empty($object->conf->$name) ? '' : $object->conf->$name)); - print ''; + print ''; // URL $src_value = (GETPOST('AGENDA_EXT_SRC_'.$id.'_'.$key) ?GETPOST('AGENDA_EXT_SRC_'.$id.'_'.$key) : (empty($object->conf->$src) ? '' : $object->conf->$src)); - print ''; + print ''; // Offset TZ $offsettz_value = (GETPOST('AGENDA_EXT_OFFSETTZ_'.$id.'_'.$key) ? GETPOST('AGENDA_EXT_OFFSETTZ_'.$id.'_'.$key) : (empty($object->conf->$offsettz) ? 0 : $object->conf->$offsettz)); print ''; // Color (Possible colors are limited by Google) - print ''; print ''; + print ''; print ''; @@ -1163,7 +1164,7 @@ if ($action == 'create' || $action == 'adduserldap') { print $langs->trans("Note"); print '\n"; @@ -1557,7 +1558,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "\n"; // Accountancy code - if ($conf->accounting->enabled) { + if (!empty($conf->accounting->enabled)) { print ''; print ''; } @@ -1590,13 +1591,15 @@ if ($action == 'create' || $action == 'adduserldap') { // Default language if (!empty($conf->global->MAIN_MULTILANGS)) { + $langs->load("languages"); require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - print ''; } @@ -2445,7 +2448,7 @@ if ($action == 'create' || $action == 'adduserldap') { print '
    '.$langs->trans('PaymentMode').''; - $form->select_types_paiements(GETPOSTISSET('mode_reglement_id') ?GETPOST('mode_reglement_id', 'int') : $mode_reglement_id, 'mode_reglement_id', 'DBIT'); + print img_picto('', 'bank', 'class="pictofixedwidth"'); + $form->select_types_paiements(GETPOSTISSET('mode_reglement_id') ?GETPOST('mode_reglement_id', 'int') : $mode_reglement_id, 'mode_reglement_id', 'DBIT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); print '
    '.$langs->trans('BankAccount').''; - print img_picto('', 'bank_account').$form->select_comptes((GETPOSTISSET('fk_account') ?GETPOST('fk_account', 'alpha') : $fk_account), 'fk_account', 0, '', 1, '', 0, '', 1); + print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes((GETPOSTISSET('fk_account') ?GETPOST('fk_account', 'alpha') : $fk_account), 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1); print '
    '.$langs->trans('Project').''; - print img_picto('', 'project').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500'); + print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); + print ' id.($fac_rec ? '&fac_rec='.$fac_rec : '')).'">'; print '
    '; + print ''; print ''; print ''; + print ''; print ''; print '
    '.$langs->trans("DefaultWarehouse").''; - print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'pictofixedwidth'); + print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"'); print $formproduct->selectWarehouses(GETPOST('fk_default_warehouse'), 'fk_default_warehouse', 'warehouseopen', 1); print ' '; print ''; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 16c72297e10..2ccc5e63c8f 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -14,7 +14,7 @@ * Copyright (C) 2014 Ion agorria * Copyright (C) 2016-2018 Ferran Marcet * Copyright (C) 2017 Gustavo Novaro - * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2019-2021 Frédéric France * * 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 @@ -372,6 +372,9 @@ class Product extends CommonObject public $oldcopy; + /** + * @var int Default warehouse Id + */ public $fk_default_warehouse; /** * @var int ID @@ -388,6 +391,10 @@ class Product extends CommonObject * @see $ref_supplier */ public $ref_fourn; + + /** + * @var string ref supplier + */ public $ref_supplier; /** @@ -1627,6 +1634,36 @@ class Product extends CommonObject } } + /** + * used to check if price have really change to avoid log pollution + * + * @param int $level price level to change + * @return array + */ + private function getArrayForPriceCompare($level = 0) + { + + $testExit = array('multiprices','multiprices_ttc','multiprices_base_type','multiprices_min','multiprices_min_ttc','multiprices_tva_tx','multiprices_recuperableonly'); + + foreach ($testExit as $field) { + if (!isset($this->$field[$level])) { + return array(); + } + } + + $lastPrice = array( + 'level' => $level ? $level : 1, + 'multiprices' => doubleval($this->multiprices[$level]), + 'multiprices_ttc' => doubleval($this->multiprices_ttc[$level]), + 'multiprices_base_type' => $this->multiprices_base_type[$level], + 'multiprices_min' => doubleval($this->multiprices_min[$level]), + 'multiprices_min_ttc' => doubleval($this->multiprices_min_ttc[$level]), + 'multiprices_tva_tx' => doubleval($this->multiprices_tva_tx[$level]), + 'multiprices_recuperableonly' => doubleval($this->multiprices_recuperableonly[$level]), + ); + + return $lastPrice; + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -1975,6 +2012,8 @@ class Product extends CommonObject { global $conf, $langs; + $lastPriceData = $this->getArrayForPriceCompare($level); // temporary store current price before update + $id = $this->id; dol_syslog(get_class($this)."::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level." npr=".$newnpr." newdefaultvatcode=".$newdefaultvatcode); @@ -2107,7 +2146,11 @@ class Product extends CommonObject // Price by quantity $this->price_by_qty = $newpbq; - $this->_log_price($user, $level); // Save price for level into table product_price + // check if price have really change before log + $newPriceData = $this->getArrayForPriceCompare($level); + if (!empty(array_diff_assoc($newPriceData, $lastPriceData)) || empty($conf->global->PRODUIT_MULTIPRICES)) { + $this->_log_price($user, $level); // Save price for level into table product_price + } $this->level = $level; // Store level of price edited for trigger @@ -5141,7 +5184,7 @@ class Product extends CommonObject * Load value ->stock_theorique of a product. Property this->id must be defined. * This function need a lot of load. If you use it on list, use a cache to execute it one for each product id. * - * @param int $includedraftpoforvirtual Include draft status of PO for virtual stock calculation + * @param int $includedraftpoforvirtual Include draft status and not yet approved Purchase Orders for virtual stock calculation * @return int < 0 if KO, > 0 if OK * @see load_stock(), loadBatchInfo() */ @@ -5180,9 +5223,9 @@ class Product extends CommonObject $stock_sending_client = $this->stats_expedition['qty']; } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled)) { - $filterStatus = '1,2,3,4'; + $filterStatus = empty($conf->global->SUPPLIER_ORDER_STATUS_FOR_VIRTUAL_STOCK) ? '2,3,4' : $conf->global->SUPPLIER_ORDER_STATUS_FOR_VIRTUAL_STOCK; if (isset($includedraftpoforvirtual)) { - $filterStatus = '0,'.$filterStatus; + $filterStatus = '0,1,2,'.$filterStatus; // 1,2 may have already been inside $filterStatus but it is better to have twice than missing $filterStatus does not include them } $result = $this->load_stats_commande_fournisseur(0, $filterStatus, 1); if ($result < 0) { diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index 442232686d3..c9499bf415b 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -50,7 +50,6 @@ if (!empty($user->socid)) { } $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : '')); $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); $object = new Product($db); $objectid = 0; @@ -60,6 +59,19 @@ if ($id > 0 || !empty($ref)) { $id = $object->id; } +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +} + /* * Actions diff --git a/htdocs/product/document.php b/htdocs/product/document.php index 372e3c19bdc..0b15ad7a85c 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -95,9 +95,19 @@ if ($id > 0 || !empty($ref)) { } $modulepart = 'produit'; + $permissiontoadd = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->creer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->creer)); -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +} /* diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 0d5ea9647f5..8b2a792b872 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -103,17 +103,16 @@ if ($id > 0 || $ref) { $object->fetch($id, $ref); } -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); - -if (!$sortfield) { - $sortfield = "s.nom"; +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); } -if (!$sortorder) { - $sortorder = "ASC"; -} - -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); /* diff --git a/htdocs/product/note.php b/htdocs/product/note.php index add915181a2..fad4df3500b 100644 --- a/htdocs/product/note.php +++ b/htdocs/product/note.php @@ -51,7 +51,16 @@ if ($id > 0 || !empty($ref)) { $permissionnote = $user->rights->produit->creer; // Used by the include of actions_setnotes.inc.php -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +} /* diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index f23b6eae92d..5aa54b0963c 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -60,9 +60,7 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -$staticproduct = new Product($db); - -$result = restrictedArea($user, 'produit|service', 0, 'product&product'); +restrictedArea($user, 'produit|service', 0, 'product&product', '', ''); /* diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 7dfb94be79f..295a999a778 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -82,7 +82,16 @@ if ((!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productpricecard', 'globalcard')); -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +} /* @@ -1470,7 +1479,6 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul } print ''.$langs->trans("PriceBase").''.$langs->trans("DefaultTaxRate").'   
    '; + if (!empty($conf->use_javascript_ajax)) { + print ''.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'   '; + print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").''; + //print ' '.$form->textwithpicto('', $langs->trans('CollapseBatchDetailHelp'), 1, 'help', ''); + } + print ''.$langs->trans("batch_number").''.$langs->trans("EatByDate").''.$langs->trans("EatByDate").''.$langs->trans("SellByDate").''.$langs->trans("SellByDate").'
    '.$entrepotstatic->getNomUrl(1).''; + print $entrepotstatic->getNomUrl(1); + if (!empty($conf->use_javascript_ajax) && !empty($conf->productbatch->enabled) && $object->hasbatch()) { + print ''; + print (empty($conf->global->STOCK_SHOW_ALL_BATCH_BY_DEFAULT) ? '(+)' : '(-)'); + print ''; + } + print ''.$stock_real.($stock_real < 0 ? ' '.img_warning() : '').''.(price2num($object->pmp) ? price2num($object->pmp, 'MU') : '').'
    '; + print "\n".'
    '; print ''; print $product_lot_static->getNomUrl(1); diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 45b45136410..b2c3b0d0b2f 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -45,7 +45,22 @@ $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + +if ($id > 0 || !empty($ref)) { + $object = new Product($db); + $object->fetch($id, $ref); +} + +if ($object->id > 0) { + if ($object->type == $object::TYPE_PRODUCT) { + restrictedArea($user, 'produit', $object->id, 'product&product', '', ''); + } + if ($object->type == $object::TYPE_SERVICE) { + restrictedArea($user, 'service', $object->id, 'product&product', '', ''); + } +} else { + restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); +} /* diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 0b8e21f5afd..9f81218ba8d 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -274,7 +274,8 @@ class Task extends CommonObject } $sql .= " WHERE "; if (!empty($ref)) { - $sql .= "t.ref = '".$this->db->escape($ref)."'"; + $sql .= "entity IN (".getEntity('project').")"; + $sql .= " AND t.ref = '".$this->db->escape($ref)."'"; } else { $sql .= "t.rowid = ".((int) $id); } @@ -1986,7 +1987,8 @@ class Task extends CommonObject global $conf, $langs; // For external user, no check is done on company because readability is managed by public status of project and assignement. - //$socid=$user->socid; + //$socid = $user->socid; + $socid = 0; $projectstatic = new Project($this->db); $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid); @@ -2007,10 +2009,7 @@ class Task extends CommonObject $sql .= " AND p.rowid IN (".$this->db->sanitize($projectsListId).")"; } // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser - //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; - if ($socid) { - $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).")"; - } + //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).")"; // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser // if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; diff --git a/htdocs/public/agenda/agendaexport.php b/htdocs/public/agenda/agendaexport.php index d40d75c0acf..2aaeb12de23 100644 --- a/htdocs/public/agenda/agendaexport.php +++ b/htdocs/public/agenda/agendaexport.php @@ -96,9 +96,9 @@ if (!isset($conf->global->MAIN_AGENDA_EXPORT_PAST_DELAY)) { $format = 'ical'; $type = 'event'; if (GETPOST("format", 'alpha')) { - $format = GETPOST("format", 'apha'); + $format = GETPOST("format", 'alpha'); } -if (GETPOST("type", 'apha')) { +if (GETPOST("type", 'alpha')) { $type = GETPOST("type", 'alpha'); } @@ -115,20 +115,20 @@ if (GETPOST("idfrom", 'int')) { if (GETPOST("idto", 'int')) { $filters['idto'] = GETPOST("idto", 'int'); } -if (GETPOST("project", 'apha')) { - $filters['project'] = GETPOST("project", 'apha'); +if (GETPOST("project", 'alpha')) { + $filters['project'] = GETPOST("project", 'alpha'); } -if (GETPOST("logina", 'apha')) { - $filters['logina'] = GETPOST("logina", 'apha'); +if (GETPOST("logina", 'alpha')) { + $filters['logina'] = GETPOST("logina", 'alpha'); } -if (GETPOST("logint", 'apha')) { - $filters['logint'] = GETPOST("logint", 'apha'); +if (GETPOST("logint", 'alpha')) { + $filters['logint'] = GETPOST("logint", 'alpha'); } -if (GETPOST("notactiontype", 'apha')) { - $filters['notactiontype'] = GETPOST("notactiontype", 'apha'); +if (GETPOST("notactiontype", 'alpha')) { + $filters['notactiontype'] = GETPOST("notactiontype", 'alpha'); } -if (GETPOST("actiontype", 'apha')) { - $filters['actiontype'] = GETPOST("actiontype", 'apha'); +if (GETPOST("actiontype", 'alpha')) { + $filters['actiontype'] = GETPOST("actiontype", 'alpha'); } if (GETPOST("notolderthan", 'int')) { $filters['notolderthan'] = GETPOST("notolderthan", "int"); diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 287f9a576db..b58a57fc706 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -254,11 +254,15 @@ $parameters = [ $reshook = $hookmanager->executeHooks('doValidatePayment', $parameters, $object, $action); // Check security token +$tmpsource = $source; +if ($tmpsource == 'membersubscription') { + $tmpsource = 'member'; +} $valid = true; if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { - if ($source && $REF) { - $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$source.$REF, 2); // Use the source in the hash to avoid duplicates if the references are identical + if ($tmpsource && $REF) { + $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$tmpsource.$REF, 2); // Use the source in the hash to avoid duplicates if the references are identical } else { $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); } @@ -758,6 +762,8 @@ if ($action == 'charge' && !empty($conf->stripe->enabled)) { * View */ +$form = new Form($db); + $head = ''; if (!empty($conf->global->ONLINE_PAYMENT_CSS_URL)) { $head = ''."\n"; @@ -770,7 +776,7 @@ $replacemainarea = (empty($conf->dol_hide_leftmenu) ? '
    ' : '').'
    '; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea); // Check link validity -if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) { +if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', 'donation_ref', ''))) { $langs->load("errors"); dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref)); // End of page @@ -1479,32 +1485,42 @@ if ($source == 'member' || $source == 'membersubscription') { } if ($member->type) { - // Last member type - print '
    '.$langs->trans("LastMemberType"); - print ''.dol_escape_htmltag($member->type); - print "
    '.$langs->trans("NewSubscription"); - print ''; - print $form->selectarray("typeid", $adht->liste_array(1), $member->typeid, 0, 0, 0, 'onchange="window.location.replace(\''.$urlwithroot.'/public/payment/newpayment.php?source='.urlencode($source).'&ref='.urlencode($ref).'&amount='.urlencode($amount).'&typeid=\' + this.value + \'&securekey='.urlencode($SECUREKEY).'\');"', 0, 0, 0, '', '', 1); - print "
    '.$langs->trans("NewMemberType"); + if ($oldtypeid != $newtypeid && !empty($conf->global->MEMBER_ALLOW_CHANGE_OF_TYPE)) { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; + $adht = new AdherentType($db); + // Amount by member type + $amountbytype = $adht->amountByType(1); + + // Last member type + print '
    '.$langs->trans("LastMemberType"); + print ''.dol_escape_htmltag($member->type); + print "
    '.$langs->trans("NewSubscription"); + print ''; + print $form->selectarray("typeid", $adht->liste_array(1), $member->typeid, 0, 0, 0, 'onchange="window.location.replace(\''.$urlwithroot.'/public/payment/newpayment.php?source='.urlencode($source).'&ref='.urlencode($ref).'&amount='.urlencode($amount).'&typeid=\' + this.value + \'&securekey='.urlencode($SECUREKEY).'\');"', 0, 0, 0, '', '', 1); + print "
    '.$langs->trans("NewMemberType"); + print ''.dol_escape_htmltag($member->type); + print ''; + print "
    '.$langs->trans("MemberType"); print ''.dol_escape_htmltag($member->type); - print ''; print "
    '.$form->editfieldkey($langs->trans('No_Email') .' ('.$langs->trans('Contact').')', 'contact_no_email', '', $object, 0).'browser->layout == 'phone') || empty($conf->mailing->enabled) ? ' colspan="3"' : '').'>'.$form->selectyesno('contact_no_email', (GETPOSTISSET("contact_no_email") ?GETPOST("contact_no_email", 'alpha') : $object->no_email), 1, false, 1).'browser->layout == 'phone') || empty($conf->mailing->enabled) ? ' colspan="3"' : '').'>'.$form->selectyesno('contact_no_email', (GETPOSTISSET("contact_no_email") ? GETPOST("contact_no_email", 'alpha') : (empty($object->no_email) ? 0 : 1)), 1, false, 1).'
    '.$form->editfieldkey('Web', 'url', '', $object, 0).''.$langs->trans("AgendaExtNb", $key)."'; + print ''; //print $formadmin->selectColor($conf->global->$color, "google_agenda_color".$key, $colorlist); $color_value = (GETPOST("AGENDA_EXT_COLOR_".$id.'_'.$key) ?GETPOST("AGENDA_EXT_COLOR_".$id.'_'.$key) : (empty($object->conf->$color) ? 'ffffff' : $object->conf->$color)); print $formother->selectColor($color_value, "AGENDA_EXT_COLOR_".$id.'_'.$key, 'extsitesconfig', 1, '', 'hideifnotset'); diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php index 356e23a5de0..0b179653487 100644 --- a/htdocs/user/bank.php +++ b/htdocs/user/bank.php @@ -59,6 +59,29 @@ if ($user->socid > 0) { $socid = $user->socid; } $feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); + +$object = new User($db); +if ($id > 0 || !empty($ref)) { + $result = $object->fetch($id, $ref, '', 1); + $object->getrights(); +} + +$account = new UserBankAccount($db); +if (!$bankid) { + $account->fetch(0, '', $id); +} else { + $account->fetch($bankid); +} +if (empty($account->userid)) { + $account->userid = $object->id; +} + + +// Define value to know what current user can do on users +$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); +$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); +$permissiontoaddbankaccount = (!empty($user->rights->salaries->write) || !empty($user->rights->hrm->employee->write) || !empty($user->rights->user->creer)); + // Ok if user->rights->salaries->read or user->rights->hrm->read //$result = restrictedArea($user, 'salaries|hrm', $id, 'user&user', $feature2); $ok = false; @@ -78,30 +101,12 @@ if (!$ok) { accessforbidden(); } -$object = new User($db); -if ($id > 0 || !empty($ref)) { - $result = $object->fetch($id, $ref, '', 1); - $object->getrights(); -} - -$account = new UserBankAccount($db); -if (!$bankid) { - $account->fetch(0, '', $id); -} else { - $account->fetch($bankid); -} -if (empty($account->userid)) { - $account->userid = $object->id; -} - -$permissiontoaddbankaccount = (!empty($user->rights->salaries->write) || !empty($user->rights->hrm->employee->write) || !empty($user->rights->user->creer)); - /* * Actions */ -if ($action == 'add' && !$cancel) { +if ($action == 'add' && !$cancel && $permissiontoaddbankaccount) { $account->userid = $object->id; $account->bank = GETPOST('bank', 'alpha'); @@ -128,7 +133,7 @@ if ($action == 'add' && !$cancel) { } } -if ($action == 'update' && !$cancel) { +if ($action == 'update' && !$cancel && $permissiontoaddbankaccount) { $account->userid = $object->id; /* @@ -199,7 +204,7 @@ if ($action == 'update' && !$cancel) { } // update personal email -if ($action == 'setpersonal_email') { +if ($action == 'setpersonal_email' && $canadduser) { $object->personal_email = (string) GETPOST('personal_email', 'alphanohtml'); $result = $object->update($user); if ($result < 0) { @@ -208,7 +213,7 @@ if ($action == 'setpersonal_email') { } // update personal mobile -if ($action == 'setpersonal_mobile') { +if ($action == 'setpersonal_mobile' && $canadduser) { $object->personal_mobile = (string) GETPOST('personal_mobile', 'alphanohtml'); $result = $object->update($user); if ($result < 0) { @@ -216,25 +221,26 @@ if ($action == 'setpersonal_mobile') { } } -// update default_c_exp_tax_cat -if ($action == 'setdefault_c_exp_tax_cat') { - $object->default_c_exp_tax_cat = GETPOST('default_c_exp_tax_cat', 'int'); - $result = $object->update($user); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); +if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { + // update default_c_exp_tax_cat + if ($action == 'setdefault_c_exp_tax_cat' && $canadduser) { + $object->default_c_exp_tax_cat = GETPOST('default_c_exp_tax_cat', 'int'); + $result = $object->update($user); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + // update default range + if ($action == 'setdefault_range' && $canadduser) { + $object->default_range = GETPOST('default_range', 'int'); + $result = $object->update($user); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } } } -// update default range -if ($action == 'setdefault_range') { - $object->default_range = GETPOST('default_range', 'int'); - $result = $object->update($user); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } -} - - /* * View diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 332c98f56da..d189ced83aa 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -615,8 +615,8 @@ if (empty($reshook)) { } // Action initialisation donnees depuis record LDAP - if ($action == 'adduserldap') { - $selecteduser = $_POST['users']; + if ($action == 'adduserldap' && $canadduser) { + $selecteduser = GETPOST('users'); $required_fields = array( $conf->global->LDAP_KEY_USERS, @@ -1110,7 +1110,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Accountancy code - if ($conf->accounting->enabled) { + if (!empty($conf->accounting->enabled)) { print '
    '.$langs->trans("AccountancyCode").''; print ''; @@ -1134,7 +1134,8 @@ if ($action == 'create' || $action == 'adduserldap') { } if (!empty($conf->global->MAIN_MULTILANGS)) { - print '
    '.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print '
    '.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))).''."\n"; print img_picto('', 'language').$formadmin->select_language(GETPOST('default_lang', 'alpha') ?GETPOST('default_lang', 'alpha') : ($object->lang ? $object->lang : ''), 'default_lang', 0, 0, 1, 0, 0, 'maxwidth200onsmartphone'); print '
    '; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('note', GETPOSTISSET('note') ? GETPOST('note', 'restricthtml') : '', '', 120, 'dolibarr_notes', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_3, '90%'); + $doleditor = new DolEditor('note', GETPOSTISSET('note') ? GETPOST('note', 'restricthtml') : '', '', 120, 'dolibarr_notes', '', false, true, getDolGlobalString('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%'); $doleditor->Create(); print "
    '.$langs->trans("AccountancyCode").''.$object->accountancy_code.'
    '.$langs->trans("DefaultLang").''; + print '
    '; + print $form->textwithpicto($langs->trans("DefaultLang"), $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))); + print ''; //$s=picto_from_langcode($object->default_lang); //print ($s?$s.' ':''); - $langs->load("languages"); $labellang = ($object->lang ? $langs->trans('Language_'.$object->lang) : ''); - print $form->textwithpicto($labellang, $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))); + print $labellang; print '

    '; // Accountancy code - if ($conf->accounting->enabled) { + if (!empty($conf->accounting->enabled)) { print ""; print ''; print ''; print ''; @@ -2718,16 +2721,15 @@ if ($action == 'create' || $action == 'adduserldap') { if ($action != 'edit' && $action != 'presend') { print '
    '; - /* - * Generated documents - */ + + // Generated documents $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->user->dir_output."/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = $user->rights->user->user->lire; $delallowed = $user->rights->user->user->creer; - print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); + print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', empty($soc->default_lang) ? '' : $soc->default_lang); $somethingshown = $formfile->numoffiles; // Show links to link elements @@ -2741,7 +2743,6 @@ if ($action == 'create' || $action == 'adduserldap') { $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'user', $socid, 1); - print '
    '; } diff --git a/htdocs/user/list.php b/htdocs/user/list.php index a697fdf96c0..693590ff7d2 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -68,7 +68,7 @@ $pagenext = $page + 1; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new User($db); $extrafields = new ExtraFields($db); -$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id; +$diroutputmassaction = $conf->user->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('userlist')); // Fetch optionals attributes and labels @@ -124,9 +124,9 @@ $arrayfields = array( 'u.office_phone'=>array('label'=>"PhonePro", 'checked'=>1, 'position'=>31), 'u.user_mobile'=>array('label'=>"PhoneMobile", 'checked'=>1, 'position'=>32), 'u.email'=>array('label'=>"EMail", 'checked'=>1, 'position'=>35), - 'u.api_key'=>array('label'=>"ApiKey", 'checked'=>0, 'position'=>40, "enabled"=>($conf->api->enabled && $user->admin)), + 'u.api_key'=>array('label'=>"ApiKey", 'checked'=>0, 'position'=>40, "enabled"=>(!empty($conf->api->enabled) && $user->admin)), 'u.fk_soc'=>array('label'=>"Company", 'checked'=>($contextpage == 'employeelist' ? 0 : 1), 'position'=>45), - 'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>($conf->salaries->enabled && !empty($user->rights->salaries->readall))), + 'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>(!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))), 'u.datelastlogin'=>array('label'=>"LastConnexion", 'checked'=>1, 'position'=>100), 'u.datepreviouslogin'=>array('label'=>"PreviousConnexion", 'checked'=>0, 'position'=>110), 'u.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), @@ -188,7 +188,7 @@ if ($mode == 'employee') { accessforbidden(); } } else { - if (!$user->rights->user->user->lire && !$user->admin) { + if (empty($user->rights->user->user->lire) && empty($user->admin)) { accessforbidden(); } } @@ -345,7 +345,7 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // N $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (key_exists('label', $extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (u.rowid = ef.fk_object)"; } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid"; @@ -571,13 +571,13 @@ print ''; $url = DOL_URL_ROOT.'/user/card.php?action=create'.($mode == 'employee' ? '&employee=1' : '').'&leftmenu='; if (!empty($socid)) { - $url .= '&socid='.$socid; + $url .= '&socid='.urlencode($socid); } $newcardbutton = dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd); $moreparam = array('morecss'=>'btnTitleSelected'); -$morehtmlright .= dolGetButtonTitle($langs->trans("List"), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php'.(($search_statut != '' && $search_statut >= 0) ? '?search_statut='.$search_statut : ''), '', 1, $moreparam); +$morehtmlright = dolGetButtonTitle($langs->trans("List"), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/user/list.php'.(($search_statut != '' && $search_statut >= 0) ? '?search_statut='.$search_statut : ''), '', 1, $moreparam); $moreparam = array('morecss'=>'marginleftonly'); $morehtmlright .= dolGetButtonTitle($langs->trans("HierarchicView"), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/user/hierarchy.php'.(($search_statut != '' && $search_statut >= 0) ? '?search_statut='.$search_statut : ''), '', 1, $moreparam); @@ -808,7 +808,7 @@ print ''."\n"; // Detect if we need a fetch on each output line $needToFetchEachLine = 0; -if (is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { +if (key_exists('computed', $extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { if (preg_match('/\$object/', $val)) { $needToFetchEachLine++; // There is at least one compute field that use $object @@ -821,6 +821,7 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // -------------------------------------------------------------------- $i = 0; $totalarray = array(); +$totalarray['nbfield'] = 0; $arrayofselected = is_array($toselect) ? $toselect : array(); while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); @@ -828,12 +829,14 @@ while ($i < ($limit ? min($num, $limit) : $num)) { break; // Should not happen } + if (empty($obj->country_code)) $obj->country_code = ''; // TODO Add join in select with country table to get country_code + // Store properties in $object $object->setVarsFromFetchObj($obj); $userstatic->id = $obj->rowid; $userstatic->admin = $obj->admin; - $userstatic->ref = $obj->label; + $userstatic->ref = $obj->rowid; $userstatic->login = $obj->login; $userstatic->statut = $obj->statut; $userstatic->office_phone = $obj->office_phone; @@ -928,6 +931,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $totalarray['nbfield']++; } } + if (!empty($arrayfields['u.office_phone']['checked'])) { print "\n"; if (!$i) { @@ -941,7 +945,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { } } if (!empty($arrayfields['u.email']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 2856f787b52..b492e31177f 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -231,19 +231,9 @@ if ($action == 'edit') { dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); - if (!empty($conf->use_javascript_ajax)) {/* - print '';*/ - } + print dol_get_fiche_end(); + + if (!empty($conf->use_javascript_ajax)) { print '
    '.$langs->trans("AccountancyCode").''; @@ -2500,7 +2503,7 @@ if ($action == 'create' || $action == 'adduserldap') { // Default language if (!empty($conf->global->MAIN_MULTILANGS)) { - print '
    '.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print '
    '.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0, 'string', '', 0, 0, 'id', $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))).''."\n"; print img_picto('', 'language').$formadmin->select_language($object->lang, 'default_lang', 0, 0, 1); print '
    ".dol_print_phone($obj->office_phone, $obj->country_code, 0, $obj->rowid, 'AC_TEL', ' ', 'phone')."'.dol_print_email($obj->email, $obj->rowid, $obj->socid, 'AC_EMAIL', 0, 0, 1)."'.dol_print_email($obj->email, $obj->rowid, $obj->fk_soc, 'AC_EMAIL', 0, 0, 1)."