diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 24d31acddd6..98320613bfc 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -259,7 +259,7 @@ llxHeader('', $title); $linkback = ''; //$linkback = '' . $langs->trans("BackToModuleList") . ''; -print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'accountancy'); +print load_fiche_titre($title, $linkback, 'accountancy'); print '
'; print ''; diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index f007208cf57..0bd60445613 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -59,6 +59,8 @@ class AccountancyExport public static $EXPORT_TYPE_LDCOMPTA10 = 120; public static $EXPORT_TYPE_GESTIMUMV3 = 130; public static $EXPORT_TYPE_GESTIMUMV5 = 135; + public static $EXPORT_TYPE_ISUITEEXPERT = 200; + // Generic FEC after that public static $EXPORT_TYPE_FEC = 1000; public static $EXPORT_TYPE_FEC2 = 1010; @@ -123,6 +125,7 @@ class AccountancyExport self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinum_v5'), self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'), self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'), + self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert', ); ksort($listofexporttypes, SORT_NUMERIC); @@ -158,6 +161,7 @@ class AccountancyExport self::$EXPORT_TYPE_GESTIMUMV5 => 'gestimumv5', self::$EXPORT_TYPE_FEC => 'fec', self::$EXPORT_TYPE_FEC2 => 'fec2', + self::$EXPORT_TYPE_ISUITEEXPERT => 'isuiteexpert', ); return $formatcode[$type]; @@ -243,6 +247,10 @@ class AccountancyExport 'label' => $langs->trans('Modelcsv_FEC2'), 'ACCOUNTING_EXPORT_FORMAT' => 'txt', ), + self::$EXPORT_TYPE_ISUITEEXPERT => array( + 'label' => 'iSuite Expert', + 'ACCOUNTING_EXPORT_FORMAT' => 'csv', + ), ), 'cr'=> array( '1' => $langs->trans("Unix"), @@ -334,6 +342,9 @@ class AccountancyExport case self::$EXPORT_TYPE_FEC2: $this->exportFEC2($TData); break; + case self::$EXPORT_TYPE_ISUITEEXPERT : + $this->exportiSuiteExpert($TData); + break; default: $this->errors[] = $langs->trans('accountancy_error_modelnotfound'); break; @@ -1752,6 +1763,62 @@ class AccountancyExport } } + /** + * Export format : iSuite Expert + * + * by OpenSolus [https://opensolus.fr] + * + * @param array $objectLines data + * + * @return void + */ + public function exportiSuiteExpert($objectLines) + { + $this->separator = ';'; + $this->end_line = "\r\n"; + + + foreach ($objectLines as $line) { + $tab = array(); + + $date = dol_print_date($line->doc_date, '%d/%m/%Y'); + + $tab[] = $line->piece_num; + $tab[] = $date; + $tab[] = substr($date, 6, 4); + $tab[] = substr($date, 3, 2); + $tab[] = substr($date, 0, 2); + $tab[] = $line->doc_ref; + //Conversion de chaine UTF8 en Latin9 + $tab[] = mb_convert_encoding(str_replace(' - Compte auxiliaire', '', $line->label_operation), "Windows-1252", 'UTF-8'); + + //Calcul de la longueur des numéros de comptes + $taille_numero = strlen(length_accountg($line->numero_compte)); + + //Création du numéro de client générique + $numero_cpt_client = '411'; + for ($i = 1; $i <= ($taille_numero - 3); $i++) { + $numero_cpt_client .= '0'; + } + + //Création des comptes auxiliaire des clients + if (length_accountg($line->numero_compte) == $numero_cpt_client) { + $tab[] = rtrim(length_accounta($line->subledger_account), "0"); + } else { + $tab[] = length_accountg($line->numero_compte); + } + $nom_client = explode(" - ", $line->label_operation); + $tab[] = mb_convert_encoding($nom_client[0], "Windows-1252", 'UTF-8'); + $tab[] = price($line->debit); + $tab[] = price($line->credit); + $tab[] = price($line->montant); + $tab[] = $line->code_journal; + + $separator = $this->separator; + print implode($separator, $tab) . $this->end_line; + } + } + /** * trunc * diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index dde599a1462..ede72c9d9e6 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -158,6 +158,9 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; + if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { + $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'"; + } dol_syslog('htdocs/accountancy/customer/index.php'); $result = $db->query($sql); @@ -201,11 +204,13 @@ if ($action == 'validatehistory') { } } - // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) - if (!empty($objp->company_code_sell)) { - $objp->code_sell_t = $objp->company_code_sell; - $objp->aarowid_suggest = $objp->aarowid_thirdparty; - $suggestedaccountingaccountfor = ''; + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($objp->company_code_sell)) { + $objp->code_sell_t = $objp->company_code_sell; + $objp->aarowid_suggest = $objp->aarowid_thirdparty; + $suggestedaccountingaccountfor = ''; + } } if ($objp->aarowid_suggest > 0) { diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index b5c6804c7d6..f047ddf70de 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -166,6 +166,9 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_product_perentity . ".accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; + if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { + $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'"; + } dol_syslog('htdocs/accountancy/supplier/index.php'); @@ -202,11 +205,13 @@ if ($action == 'validatehistory') { } } - // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) - if (!empty($objp->company_code_buy)) { - $objp->code_buy_t = $objp->company_code_buy; - $objp->aarowid_suggest = $objp->aarowid_thirdparty; - $suggestedaccountingaccountfor = ''; + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($objp->company_code_buy)) { + $objp->code_buy_t = $objp->company_code_buy; + $objp->aarowid_suggest = $objp->aarowid_thirdparty; + $suggestedaccountingaccountfor = ''; + } } if ($objp->aarowid_suggest > 0) { diff --git a/htdocs/adherents/admin/member.php b/htdocs/adherents/admin/member.php index 621873afc94..d03beec610e 100644 --- a/htdocs/adherents/admin/member.php +++ b/htdocs/adherents/admin/member.php @@ -263,6 +263,7 @@ if ($conf->facture->enabled) { print ''.$langs->trans("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS").''; print ''; $selected = (empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) ? '' : $conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + print img_picto('', 'product', 'class="pictofixedwidth"'); $form->select_produits($selected, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', '', 0); print ''; } diff --git a/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php b/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php index 87b8a6874c4..419b32f3c34 100644 --- a/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php +++ b/htdocs/adherents/canvas/default/tpl/adherentcard_create.tpl.php @@ -31,8 +31,6 @@ print load_fiche_titre($this->control->tpl['title']); dol_htmloutput_errors((is_numeric($object->error) ? '' : $object->error), $object->errors); -dol_htmloutput_errors((is_numeric($GLOBALS['error']) ? '' : $GLOBALS['error']), $GLOBALS['errors']); - dol_htmloutput_errors($this->control->tpl['error'], $this->control->tpl['errors']); echo $this->control->tpl['ajax_selectcountry']; ?> diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index da84fd5bf6b..7c5d074d51e 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1054,6 +1054,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Country $object->country_id = $object->country_id ? $object->country_id : $mysoc->country_id; print ''.$langs->trans('Country').''; + print img_picto('', 'country', 'class="pictofixedwidth"'); print $form->select_country(GETPOSTISSET('country_id') ? GETPOST('country_id', 'alpha') : $object->country_id, 'country_id'); if ($user->admin) { print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); @@ -1064,6 +1065,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (empty($conf->global->MEMBER_DISABLE_STATE)) { print ''.$langs->trans('State').''; if ($object->country_id) { + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state(GETPOSTISSET('state_id') ? GETPOST('state_id', 'int') : $object->state_id, $object->country_code); } else { print $countrynotdefined; @@ -1303,6 +1305,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Country //$object->country_id=$object->country_id?$object->country_id:$mysoc->country_id; // In edit mode we don't force to company country if not defined print ''.$langs->trans('Country').''; + print img_picto('', 'country', 'class="pictofixedwidth"'); print $form->select_country(GETPOSTISSET("country_id") ? GETPOST("country_id", "alpha") : $object->country_id, 'country_id'); if ($user->admin) { print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); @@ -1312,21 +1315,22 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // State if (empty($conf->global->MEMBER_DISABLE_STATE)) { print ''.$langs->trans('State').''; + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($object->state_id, GETPOSTISSET("country_id") ? GETPOST("country_id", "alpha") : $object->country_id); print ''; } // Pro phone print ''.$langs->trans("PhonePro").''; - print ''.img_picto('', 'object_phoning').' phone).'">'; + print ''.img_picto('', 'object_phoning', 'class="pictofixedwidth"').' phone).'">'; // Personal phone print ''.$langs->trans("PhonePerso").''; - print ''.img_picto('', 'object_phoning').' phone_perso).'">'; + print ''.img_picto('', 'object_phoning', 'class="pictofixedwidth"').' phone_perso).'">'; // Mobile phone print ''.$langs->trans("PhoneMobile").''; - print ''.img_picto('', 'object_phoning_mobile').' phone_mobile).'">'; + print ''.img_picto('', 'object_phoning_mobile', 'class="pictofixedwidth"').' phone_mobile).'">'; if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index d669270b565..1c93b247dfc 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -65,6 +65,7 @@ $search_filter = GETPOST("search_filter", 'alpha'); $search_status = GETPOST("search_status", 'intcomma'); $catid = GETPOST("catid", 'int'); $optioncss = GETPOST('optioncss', 'alpha'); +$socid = GETPOST('socid', 'int'); $filter = GETPOST("filter", 'alpha'); if ($filter) { diff --git a/htdocs/admin/accountant.php b/htdocs/admin/accountant.php index 1e924699cd5..7c82775abad 100644 --- a/htdocs/admin/accountant.php +++ b/htdocs/admin/accountant.php @@ -131,7 +131,7 @@ print ''; -print img_picto('', 'globe-americas', 'class="paddingrightonly"'); +print img_picto('', 'globe-americas', 'class="pictofixedwidth"'); print $form->select_country((GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : '')), 'country_id'); if ($user->admin) { print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); @@ -139,27 +139,28 @@ if ($user->admin) { print ''."\n"; print ''; -$formcompany->select_departement((GETPOSTISSET('state_id') ? GETPOST('state_id', 'alpha') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_STATE) ? $conf->global->MAIN_INFO_ACCOUNTANT_STATE : '')), (GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : '')), 'state_id'); +print img_picto('', 'state', 'class="pictofixedwidth"'); +print $formcompany->select_state((GETPOSTISSET('state_id') ? GETPOST('state_id', 'alpha') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_STATE) ? $conf->global->MAIN_INFO_ACCOUNTANT_STATE : '')), (GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : (!empty($conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY) ? $conf->global->MAIN_INFO_ACCOUNTANT_COUNTRY : '')), 'state_id'); print ''."\n"; print ''; -print img_picto('', 'object_phoning', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'object_phoning', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; print ''; -print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; print ''; -print img_picto('', 'object_email', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'object_email', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; // Web print ''; -print img_picto('', 'globe', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'globe', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; diff --git a/htdocs/admin/accounting.php b/htdocs/admin/accounting.php index e775f5bd8e3..ebe0712b03a 100644 --- a/htdocs/admin/accounting.php +++ b/htdocs/admin/accounting.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2018-2021 Alexandre Spangaro * * 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 @@ -18,7 +18,7 @@ /** * \file htdocs/admin/accounting.php * \ingroup accounting - * \brief Setup page to configure accountanting module + * \brief Setup page to configure accounting module */ require '../main.inc.php'; @@ -32,7 +32,7 @@ $action = GETPOST('action', 'aZ09'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'adminaccoutant'; // To manage different context of search // Load translation files required by the page -$langs->loadLangs(array('admin', 'companies')); +$langs->loadLangs(array('admin', 'companies', 'accountancy')); if (!$user->admin) { accessforbidden(); @@ -52,12 +52,13 @@ $error = 0; * View */ +$title = $langs->trans("ConfigAccountingExpert"); $help_url = ''; -llxHeader('', $langs->trans("ConfigAccountingExpert"), $help_url); +llxHeader('', $title, $help_url); $linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ConfigAccountingExpert"), $linkback, 'title_setup'); +print load_fiche_titre($title, $linkback, 'title_setup'); print "
\n"; print ''.$langs->trans("AccountancySetupDoneFromAccountancyMenu", $langs->transnoentitiesnoconv("Accounting").' - '.$langs->transnoentitiesnoconv("Setup"))."
\n"; diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index 7b1c94de1ec..25ada4d2d89 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -1,6 +1,6 @@ - * Copyright (C) 2005-2020 Laurent Destailleur + * Copyright (C) 2005-2021 Laurent Destailleur * Copyright (C) 2011-2013 Juanjo Menent * * This program is free software; you can redistribute it and/or modify @@ -20,7 +20,7 @@ /** * \file htdocs/admin/clicktodial.php * \ingroup clicktodial - * \brief Page to setup module clicktodial + * \brief Page to setup module ClickToDial */ require '../main.inc.php'; @@ -99,7 +99,12 @@ print ''; -print $langs->trans("Example").':
http://myphoneserver/mypage?login=__LOGIN__&password=__PASS__&caller=__PHONEFROM__&called=__PHONETO__'; +print '
'; +print ''; +print $langs->trans("Example").':
'; +print 'http://myphoneserver/mypage?login=__LOGIN__&password=__PASS__&caller=__PHONEFROM__&called=__PHONETO__
'; +print 'sip:__PHONETO__@my.sip.server'; +print '
'; //if (! empty($user->clicktodial_url)) //{ diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 804ed9934bf..d2dac38b500 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -417,7 +417,7 @@ print ''; -print img_picto('', 'globe-americas', 'class="paddingrightonly"'); +print img_picto('', 'globe-americas', 'class="pictofixedwidth"'); print $form->select_country($mysoc->country_id, 'country_id', '', 0); if ($user->admin) { print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); @@ -430,35 +430,37 @@ if (!empty($conf->global->MAIN_INFO_SOCIETE_STATE)) { $tmp = explode(':', $conf->global->MAIN_INFO_SOCIETE_STATE); $state_id = $tmp[0]; } -$formcompany->select_departement($state_id, $mysoc->country_code, 'state_id'); +print img_picto('', 'state', 'class="pictofixedwidth"'); +print $formcompany->select_state($state_id, $mysoc->country_code, 'state_id'); print ''."\n"; // Currency print ''; +print img_picto('', 'multicurrency', 'class="pictofixedwidth"'); print $form->selectCurrency($conf->currency, "currency"); print ''."\n"; // Phone print ''; -print img_picto('', 'object_phoning', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'object_phoning', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; // Fax print ''; -print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; // Email print ''; -print img_picto('', 'object_email', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'object_email', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; // Web print ''; -print img_picto('', 'globe', '', false, 0, 0, '', 'paddingright'); +print img_picto('', 'globe', '', false, 0, 0, '', 'pictofixedwidth'); print ''; print ''."\n"; @@ -466,7 +468,7 @@ print ''."\n"; if (!empty($conf->barcode->enabled)) { print ''; print ''; - print ''; + print ''; print ''; print ''; } diff --git a/htdocs/admin/company_socialnetworks.php b/htdocs/admin/company_socialnetworks.php index 4809a418861..2d4b2e6d128 100644 --- a/htdocs/admin/company_socialnetworks.php +++ b/htdocs/admin/company_socialnetworks.php @@ -74,6 +74,8 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha'))) { } } } + + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php index dc801059e41..038d8d0915c 100644 --- a/htdocs/admin/defaultvalues.php +++ b/htdocs/admin/defaultvalues.php @@ -241,7 +241,7 @@ if ($defaultvalue) { } -print 'entity) && !empty($debug)) ? '?debug=1' : '').'" method="POST">'; +print ''; if ($optioncss != '') { print ''; } @@ -393,8 +393,8 @@ if (!is_array($result) && $result<0) { // Actions print ''; if ($action != 'edit' || GETPOST('rowid') != $defaultvalue->id) { - print ''.img_edit().''; - print ''.img_delete().''; + print ''.img_edit().''; + print ''.img_delete().''; } else { print ''; print ''; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 35e20b96570..1bfc3611439 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -100,7 +100,7 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 0, 29, 0, 33, 34, 32, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 15, 30, 0, 37, 42, 0, 43, 0, 25, 0); +$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0); // Name of SQL tables of dictionaries $tabname = array(); @@ -223,7 +223,7 @@ $tabsql[24] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFI $tabsql[25] = "SELECT rowid as rowid, code, label, active, module FROM ".MAIN_DB_PREFIX."c_type_container as t WHERE t.entity IN (".getEntity('c_type_container').")"; //$tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; $tabsql[27] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN_DB_PREFIX."c_stcomm"; -$tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; +$tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newByMonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; $tabsql[29] = "SELECT rowid as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status"; $tabsql[30] = "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards"; //$tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s"; @@ -315,7 +315,7 @@ $tabfield[24] = "code,label"; $tabfield[25] = "code,label"; //$tabfield[26]= "code,label,short_label"; $tabfield[27] = "code,libelle,picto"; -$tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country"; +$tabfield[28] = "code,label,affect,delay,newByMonth,country_id,country"; $tabfield[29] = "code,label,percent,position"; $tabfield[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfield[31]= "pcg_version,label"; @@ -361,7 +361,7 @@ $tabfieldvalue[24] = "code,label"; $tabfieldvalue[25] = "code,label"; //$tabfieldvalue[26]= "code,label,short_label"; $tabfieldvalue[27] = "code,libelle,picto"; -$tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country"; +$tabfieldvalue[28] = "code,label,affect,delay,newByMonth,country"; $tabfieldvalue[29] = "code,label,percent,position"; $tabfieldvalue[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfieldvalue[31]= "pcg_version,label"; @@ -407,7 +407,7 @@ $tabfieldinsert[24] = "code,label"; $tabfieldinsert[25] = "code,label"; //$tabfieldinsert[26]= "code,label,short_label"; $tabfieldinsert[27] = "code,libelle,picto"; -$tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country"; +$tabfieldinsert[28] = "code,label,affect,delay,newByMonth,fk_country"; $tabfieldinsert[29] = "code,label,percent,position"; $tabfieldinsert[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfieldinsert[31]= "pcg_version,label"; @@ -548,7 +548,7 @@ $tabhelp[24] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[25] = array('code'=>$langs->trans('EnterAnyCode')); //$tabhelp[26] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[27] = array('code'=>$langs->trans("EnterAnyCode"), 'picto'=>$langs->trans("PictoHelp")); -$tabhelp[28] = array('affect'=>$langs->trans("FollowedByACounter"), 'delay'=>$langs->trans("MinimumNoticePeriod"), 'newbymonth'=>$langs->trans("NbAddedAutomatically")); +$tabhelp[28] = array('affect'=>$langs->trans("FollowedByACounter"), 'delay'=>$langs->trans("MinimumNoticePeriod"), 'newByMonth'=>$langs->trans("NbAddedAutomatically")); $tabhelp[29] = array('code'=>$langs->trans("EnterAnyCode"), 'percent'=>$langs->trans("OpportunityPercent"), 'position'=>$langs->trans("PositionIntoComboList")); $tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->trans("LabelName"), 'paper_size'=>$langs->trans("LabelPaperSize")); //$tabhelp[31] = array('pcg_version'=>$langs->trans("EnterAnyCode")); @@ -568,8 +568,8 @@ $tabhelp[43] = array('code'=>$langs->trans("EnterAnyCode")); // Table to store complete informations (will replace all other table). Key is table name. $tabcomplete = array( 'c_forme_juridique'=>array('picto'=>'company'), - 'c_departements'=>array('picto'=>'country'), - 'c_regions'=>array('picto'=>'country'), + 'c_departements'=>array('picto'=>'state'), + 'c_regions'=>array('picto'=>'region'), 'c_country'=>array('picto'=>'country'), 'c_civility'=>array('picto'=>'contact'), 'c_actioncomm'=>array('picto'=>'action'), @@ -695,7 +695,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { $listfieldmodify = explode(',', $tabfieldinsert[$id]); $listfieldvalue = explode(',', $tabfieldvalue[$id]); - // Check that all fields are filled + // Check that all mandatory fields are filled $ok = 1; foreach ($listfield as $f => $value) { // Discard check of mandatory fields for country for some tables @@ -882,12 +882,12 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { } if ($keycode == 'sortorder') { // For column name 'sortorder', we use the field name 'position' - $sql .= "'".(int) GETPOST('position', 'int')."'"; + $sql .= (int) GETPOST('position', 'int'); } elseif ($_POST[$keycode] == '' && !($keycode == 'code' && $id == 10)) { $sql .= "null"; // For vat, we want/accept code = '' } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfile', 'private', 'position', 'scale'))) { + } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; @@ -898,8 +898,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { $sql .= ",1)"; dol_syslog("actionadd", LOG_DEBUG); - $result = $db->query($sql); - if ($result) { // Add is ok + $resql = $db->query($sql); + if ($resql) { // Add is ok setEventMessages($langs->transnoentities("RecordCreatedSuccessfully"), null, 'mesgs'); // Clean $_POST array, we keep only id of dictionary @@ -956,7 +956,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { $sql .= "null"; // For vat, we want/accept code = '' } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('private', 'position', 'scale'))) { + } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; @@ -1234,7 +1234,7 @@ if ($id) { $class = ''; if ($value == 'pos') { - $valuetoshow = $langs->trans("Position"); $class = 'maxwidth100'; + $valuetoshow = $langs->trans("Position"); $class = 'right'; } if ($value == 'source') { $valuetoshow = $langs->trans("Contact"); @@ -1341,6 +1341,9 @@ if ($id) { if ($value == 'short_label') { $valuetoshow = $langs->trans("ShortLabel"); } + if ($value == 'fk_parent') { + $valuetoshow = $langs->trans("ParentID"); $class = 'center'; + } if ($value == 'range_account') { $valuetoshow = $langs->trans("Range"); } @@ -1389,7 +1392,7 @@ if ($id) { if ($value == 'delay') { $valuetoshow = $langs->trans("NoticePeriod"); } - if ($value == 'newbymonth') { + if ($value == 'newByMonth') { $valuetoshow = $langs->trans("NewByMonth"); } if ($value == 'fk_tva') { @@ -1623,11 +1626,8 @@ if ($id) { if ($value == 'code') { $valuetoshow = $langs->trans("Code"); } - if ($value == 'pos') { - $cssprefix = 'right '; $valuetoshow = $langs->trans("Position"); - } - if ($value == 'position') { - $cssprefix = 'right '; $valuetoshow = $langs->trans("Position"); + if (in_array($value, array('pos', 'position'))) { + $valuetoshow = $langs->trans("Position"); $cssprefix = 'right '; } if ($value == 'libelle' || $value == 'label') { $valuetoshow = $langs->trans("Label"); @@ -1686,6 +1686,9 @@ if ($id) { if ($value == 'short_label') { $valuetoshow = $langs->trans("ShortLabel"); } + if ($value == 'fk_parent') { + $valuetoshow = $langs->trans("ParentID"); $cssprefix = 'center '; + } if ($value == 'range_account') { $valuetoshow = $langs->trans("Range"); } @@ -1734,7 +1737,7 @@ if ($id) { if ($value == 'delay') { $valuetoshow = $langs->trans("NoticePeriod"); } - if ($value == 'newbymonth') { + if ($value == 'newByMonth') { $valuetoshow = $langs->trans("NewByMonth"); } if ($value == 'fk_tva') { @@ -1992,19 +1995,13 @@ if ($id) { if ($value == 'tracking') { $class .= ' tdoverflowauto'; } - if ($value == 'position') { + if (in_array($value, array('pos', 'position'))) { $class .= ' right'; } - if ($value == 'localtax1_type') { + if (in_array($value, array('localtax1_type', 'localtax2_type'))) { $class .= ' nowrap'; } - if ($value == 'localtax2_type') { - $class .= ' nowrap'; - } - if ($value == 'pos') { - $class .= ' right'; - } - if ($value == 'use_default') { + if (in_array($value, array('use_default', 'fk_parent'))) { $class .= ' center'; } if ($value == 'public') { @@ -2271,7 +2268,13 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; print $form->selectarray('source', $sourceList, (!empty($obj->{$value}) ? $obj->{$value}:'')); print ''; + } elseif (in_array($value, array('public', 'use_default'))) { + // Fields 0/1 with a combo select Yes/No + print ''; + print $form->selectyesno($value, (!empty($obj->{$value}) ? $obj->{$value}:''), 1); + print ''; } elseif ($value == 'private') { + // Fields 'no'/'yes' with a combo select Yes/No print ''; print $form->selectyesno("private", (!empty($obj->{$value}) ? $obj->{$value}:'')); print ''; @@ -2367,7 +2370,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print $form->selectExpenseRanges($obj->fk_range); print ''; } else { - $fieldValue = isset($obj->{$value}) ? $obj->{$value}:''; + $fieldValue = isset($obj->{$value}) ? $obj->{$value}: ''; if ($value == 'sortorder') { $fieldlist[$field] = 'position'; @@ -2377,15 +2380,24 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') if ($fieldlist[$field] == 'code') { $class = 'maxwidth100'; } - if (in_array($fieldlist[$field], array('dayrule', 'day', 'month', 'year', 'pos', 'use_default', 'affect', 'delay', 'position', 'public', 'sortorder', 'sens', 'category_type'))) { + if (in_array($fieldlist[$field], array('pos', 'position'))) { + $classtd = 'right'; $class = 'maxwidth50 right'; + } + if (in_array($fieldlist[$field], array('dayrule', 'day', 'month', 'year', 'use_default', 'affect', 'delay', 'public', 'sortorder', 'sens', 'category_type', 'fk_parent'))) { $class = 'maxwidth50 center'; } - if (in_array($fieldlist[$field], array('use_default', 'public'))) { + if (in_array($fieldlist[$field], array('use_default', 'public', 'fk_parent'))) { $classtd = 'center'; } if (in_array($fieldlist[$field], array('libelle', 'label', 'tracking'))) { $class = 'quatrevingtpercent'; } + // Fields that must be suggested as '0' instead of '' + if ($fieldlist[$field] == 'fk_parent') { + if (empty($fieldValue)) { + $fieldValue = '0'; + } + } print ''; $transfound = 0; $transkey = ''; diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index a57df57d782..53d27efeba2 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -54,12 +54,12 @@ $arrayofparameters = array( 'EVENTORGANIZATION_CATEG_THIRDPARTY_BOOTH'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1), //'EVENTORGANIZATION_FILTERATTENDEES_CAT'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1), //'EVENTORGANIZATION_FILTERATTENDEES_TYPE'=>array('type'=>'thirdparty_type:', 'enabled'=>1), - 'EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), - 'EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), - 'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), - 'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), - 'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), - 'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1), + 'EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF'=>array('type'=>'emailtemplate:conferenceorbooth', 'enabled'=>1), + 'EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH'=>array('type'=>'emailtemplate:conferenceorbooth', 'enabled'=>1), + 'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH'=>array('type'=>'emailtemplate:conferenceorbooth', 'enabled'=>1), + 'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT'=>array('type'=>'emailtemplate:conferenceorbooth', 'enabled'=>1), + 'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER'=>array('type'=>'emailtemplate:conferenceorbooth', 'enabled'=>1), + 'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES'=>array('type'=>'emailtemplate:conferenceorbooth', 'enabled'=>1), 'EVENTORGANIZATION_SECUREKEY'=>array('type'=>'securekey', 'enabled'=>1), 'SERVICE_BOOTH_LOCATION'=>array('type'=>'product', 'enabled'=>1), 'SERVICE_CONFERENCE_ATTENDEE_SUBSCRIPTION'=>array('type'=>'product', 'enabled'=>1), diff --git a/htdocs/admin/fckeditor.php b/htdocs/admin/fckeditor.php index 987f435e38f..3388b649a67 100644 --- a/htdocs/admin/fckeditor.php +++ b/htdocs/admin/fckeditor.php @@ -117,7 +117,7 @@ if (GETPOST('save', 'alpha')) { $error++; } - $fckeditor_test = GETPOST('formtestfield'); + $fckeditor_test = GETPOST('formtestfield', 'restricthtml'); if (!empty($fckeditor_test)) { if (!dolibarr_set_const($db, 'FCKEDITOR_TEST', $fckeditor_test, 'chaine', 0, '', $conf->entity)) { $error++; diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index 396570b2155..aa571644871 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -51,6 +51,7 @@ if (!empty($conf->global->MAIN_MOTD_SETUPPAGE)) { $conf->global->MAIN_MOTD_SETUPPAGE = preg_replace('//i', '
', $conf->global->MAIN_MOTD_SETUPPAGE); if (!empty($conf->global->MAIN_MOTD_SETUPPAGE)) { $i = 0; + $reg = array(); while (preg_match('/__\(([a-zA-Z|@]+)\)__/i', $conf->global->MAIN_MOTD_SETUPPAGE, $reg) && $i < 100) { $tmp = explode('|', $reg[1]); if (!empty($tmp[1])) { diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index e27c48b0416..8ba5a990c33 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -499,7 +499,7 @@ foreach ($object->fields as $key => $val) { if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { print $form->selectarray('search_'.$key, $val['arrayofkeyval'], empty($search[$key]) ? '' : $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); } elseif (strpos($val['type'], 'integer:') === 0) { - print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 1); + print $object->showInputField($val, $key, empty($search[$key]) ? '' : $search[$key], '', '', 'search_', 'maxwidth150', 1); } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { print ''; } diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 494dfc2f625..f60e011f41c 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -919,7 +919,6 @@ if ($mode == 'common' || $mode == 'commonkanban') { if ($objMod->needUpdate) { $versionTitle = $langs->trans('ModuleUpdateAvailable').' : '.$objMod->lastVersion; print ''.$versiontrans.''; - $foundoneexternalmodulewithupdate++; } else { print $versiontrans; } @@ -937,6 +936,9 @@ if ($mode == 'common' || $mode == 'commonkanban') { print "\n"; } + if ($objMod->needUpdate) { + $foundoneexternalmodulewithupdate++; + } } if ($action == 'checklastversion') { diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 7d7b5e36a40..d5873e2a50e 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -371,17 +371,7 @@ print $formadmin->select_language($selected, 'PDF_USE_ALSO_LANGUAGE_CODE', 0, nu //} print ''; -//Desc - -print ''.$langs->trans("HideDescOnPDF").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MAIN_GENERATE_DOCUMENTS_HIDE_DESC'); -} else { - print $form->selectyesno('MAIN_GENERATE_DOCUMENTS_HIDE_DESC', (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC)) ? $conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC : 0, 1); -} -print ''; - -//Ref +// Ref print ''.$langs->trans("HideRefOnPDF").''; if ($conf->use_javascript_ajax) { @@ -391,7 +381,17 @@ if ($conf->use_javascript_ajax) { } print ''; -//Details +// Desc + +print ''.$langs->trans("HideDescOnPDF").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_GENERATE_DOCUMENTS_HIDE_DESC'); +} else { + print $form->selectyesno('MAIN_GENERATE_DOCUMENTS_HIDE_DESC', (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC)) ? $conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC : 0, 1); +} +print ''; + +// Details print ''.$langs->trans("HideDetailsOnPDF").''; if ($conf->use_javascript_ajax) { diff --git a/htdocs/admin/pdf_other.php b/htdocs/admin/pdf_other.php index 03c27fd3721..ed14f2ac119 100644 --- a/htdocs/admin/pdf_other.php +++ b/htdocs/admin/pdf_other.php @@ -78,7 +78,8 @@ $head = pdf_admin_prepare_head(); print dol_get_fiche_head($head, 'other', $langs->trans("other"), -1, 'pdf'); -print ''.$form->textwithpicto($langs->trans("PDFOtherDesc"), $s)."
\n"; +$tooltiptext = ''; +print ''.$form->textwithpicto($langs->trans("PDFOtherDesc"), $tooltiptext)."
\n"; print "
\n"; print load_fiche_titre($langs->trans("Proposal"), '', ''); @@ -116,10 +117,11 @@ print ''; print ''; print ''; - +/* print '
'; print ''; print '
'; +*/ print ''; diff --git a/htdocs/admin/security.php b/htdocs/admin/security.php index e94dd6bad39..064fb5650a4 100644 --- a/htdocs/admin/security.php +++ b/htdocs/admin/security.php @@ -251,7 +251,7 @@ foreach ($arrayhandler as $key => $module) { } elseif ($tmp == 'NotConfigured') { print $langs->trans($tmp); } else { - print $tmp; + print ''.$tmp.''; } print ''."\n"; diff --git a/htdocs/admin/system/dolibarr.php b/htdocs/admin/system/dolibarr.php index 9af09164469..0271488b65a 100644 --- a/htdocs/admin/system/dolibarr.php +++ b/htdocs/admin/system/dolibarr.php @@ -309,57 +309,58 @@ print '
'; // Parameters in conf.php file (when a parameter start with ?, it is shown only if defined) $configfileparameters = array( - 'dolibarr_main_url_root' => $langs->trans("URLRoot"), - '?dolibarr_main_url_root_alt' => $langs->trans("URLRoot").' (alt)', - 'dolibarr_main_document_root'=> $langs->trans("DocumentRootServer"), - '?dolibarr_main_document_root_alt' => $langs->trans("DocumentRootServer").' (alt)', - 'dolibarr_main_data_root' => $langs->trans("DataRootServer"), - 'dolibarr_main_instance_unique_id' => $langs->trans("InstanceUniqueID"), - 'separator1' => '', - 'dolibarr_main_db_host' => $langs->trans("DatabaseServer"), - 'dolibarr_main_db_port' => $langs->trans("DatabasePort"), - 'dolibarr_main_db_name' => $langs->trans("DatabaseName"), - 'dolibarr_main_db_type' => $langs->trans("DriverType"), - 'dolibarr_main_db_user' => $langs->trans("DatabaseUser"), - 'dolibarr_main_db_pass' => $langs->trans("DatabasePassword"), - 'dolibarr_main_db_character_set' => $langs->trans("DBStoringCharset"), - 'dolibarr_main_db_collation' => $langs->trans("DBSortingCollation"), - '?dolibarr_main_db_prefix' => $langs->trans("Prefix"), - 'separator2' => '', - 'dolibarr_main_authentication' => $langs->trans("AuthenticationMode"), - '?multicompany_transverse_mode'=> $langs->trans("MultiCompanyMode"), - 'separator'=> '', - '?dolibarr_main_auth_ldap_login_attribute' => 'dolibarr_main_auth_ldap_login_attribute', - '?dolibarr_main_auth_ldap_host' => 'dolibarr_main_auth_ldap_host', - '?dolibarr_main_auth_ldap_port' => 'dolibarr_main_auth_ldap_port', - '?dolibarr_main_auth_ldap_version' => 'dolibarr_main_auth_ldap_version', - '?dolibarr_main_auth_ldap_dn' => 'dolibarr_main_auth_ldap_dn', - '?dolibarr_main_auth_ldap_admin_login' => 'dolibarr_main_auth_ldap_admin_login', - '?dolibarr_main_auth_ldap_admin_pass' => 'dolibarr_main_auth_ldap_admin_pass', - '?dolibarr_main_auth_ldap_debug' => 'dolibarr_main_auth_ldap_debug', - 'separator3' => '', - '?dolibarr_lib_ADODB_PATH' => 'dolibarr_lib_ADODB_PATH', - '?dolibarr_lib_FPDF_PATH' => 'dolibarr_lib_FPDF_PATH', - '?dolibarr_lib_TCPDF_PATH' => 'dolibarr_lib_TCPDF_PATH', - '?dolibarr_lib_FPDI_PATH' => 'dolibarr_lib_FPDI_PATH', - '?dolibarr_lib_TCPDI_PATH' => 'dolibarr_lib_TCPDI_PATH', - '?dolibarr_lib_NUSOAP_PATH' => 'dolibarr_lib_NUSOAP_PATH', - '?dolibarr_lib_GEOIP_PATH' => 'dolibarr_lib_GEOIP_PATH', - '?dolibarr_lib_ODTPHP_PATH' => 'dolibarr_lib_ODTPHP_PATH', - '?dolibarr_lib_ODTPHP_PATHTOPCLZIP' => 'dolibarr_lib_ODTPHP_PATHTOPCLZIP', - '?dolibarr_js_CKEDITOR' => 'dolibarr_js_CKEDITOR', - '?dolibarr_js_JQUERY' => 'dolibarr_js_JQUERY', - '?dolibarr_js_JQUERY_UI' => 'dolibarr_js_JQUERY_UI', - '?dolibarr_font_DOL_DEFAULT_TTF' => 'dolibarr_font_DOL_DEFAULT_TTF', - '?dolibarr_font_DOL_DEFAULT_TTF_BOLD' => 'dolibarr_font_DOL_DEFAULT_TTF_BOLD', - 'separator4' => '', - 'dolibarr_main_prod' => 'Production mode (Hide all error messages)', - 'dolibarr_main_restrict_os_commands' => 'Restrict CLI commands for backups', - 'dolibarr_main_restrict_ip' => 'Restrict access to some IPs only', - '?dolibarr_mailing_limit_sendbyweb' => 'Limit nb of email sent by page', - '?dolibarr_mailing_limit_sendbycli' => 'Limit nb of email sent by cli', - '?dolibarr_strict_mode' => 'Strict mode is on/off', - '?dolibarr_nocsrfcheck' => 'Disable CSRF security checks' + 'dolibarr_main_prod' => 'Production mode (Hide all error messages)', + 'dolibarr_main_instance_unique_id' => $langs->trans("InstanceUniqueID"), + 'separator0' => '', + 'dolibarr_main_url_root' => $langs->trans("URLRoot"), + '?dolibarr_main_url_root_alt' => $langs->trans("URLRoot").' (alt)', + 'dolibarr_main_document_root'=> $langs->trans("DocumentRootServer"), + '?dolibarr_main_document_root_alt' => $langs->trans("DocumentRootServer").' (alt)', + 'dolibarr_main_data_root' => $langs->trans("DataRootServer"), + 'separator1' => '', + 'dolibarr_main_db_host' => $langs->trans("DatabaseServer"), + 'dolibarr_main_db_port' => $langs->trans("DatabasePort"), + 'dolibarr_main_db_name' => $langs->trans("DatabaseName"), + 'dolibarr_main_db_type' => $langs->trans("DriverType"), + 'dolibarr_main_db_user' => $langs->trans("DatabaseUser"), + 'dolibarr_main_db_pass' => $langs->trans("DatabasePassword"), + 'dolibarr_main_db_character_set' => $langs->trans("DBStoringCharset"), + 'dolibarr_main_db_collation' => $langs->trans("DBSortingCollation"), + '?dolibarr_main_db_prefix' => $langs->trans("DatabasePrefix"), + 'separator2' => '', + 'dolibarr_main_authentication' => $langs->trans("AuthenticationMode"), + '?multicompany_transverse_mode'=> $langs->trans("MultiCompanyMode"), + 'separator'=> '', + '?dolibarr_main_auth_ldap_login_attribute' => 'dolibarr_main_auth_ldap_login_attribute', + '?dolibarr_main_auth_ldap_host' => 'dolibarr_main_auth_ldap_host', + '?dolibarr_main_auth_ldap_port' => 'dolibarr_main_auth_ldap_port', + '?dolibarr_main_auth_ldap_version' => 'dolibarr_main_auth_ldap_version', + '?dolibarr_main_auth_ldap_dn' => 'dolibarr_main_auth_ldap_dn', + '?dolibarr_main_auth_ldap_admin_login' => 'dolibarr_main_auth_ldap_admin_login', + '?dolibarr_main_auth_ldap_admin_pass' => 'dolibarr_main_auth_ldap_admin_pass', + '?dolibarr_main_auth_ldap_debug' => 'dolibarr_main_auth_ldap_debug', + 'separator3' => '', + '?dolibarr_lib_ADODB_PATH' => 'dolibarr_lib_ADODB_PATH', + '?dolibarr_lib_FPDF_PATH' => 'dolibarr_lib_FPDF_PATH', + '?dolibarr_lib_TCPDF_PATH' => 'dolibarr_lib_TCPDF_PATH', + '?dolibarr_lib_FPDI_PATH' => 'dolibarr_lib_FPDI_PATH', + '?dolibarr_lib_TCPDI_PATH' => 'dolibarr_lib_TCPDI_PATH', + '?dolibarr_lib_NUSOAP_PATH' => 'dolibarr_lib_NUSOAP_PATH', + '?dolibarr_lib_GEOIP_PATH' => 'dolibarr_lib_GEOIP_PATH', + '?dolibarr_lib_ODTPHP_PATH' => 'dolibarr_lib_ODTPHP_PATH', + '?dolibarr_lib_ODTPHP_PATHTOPCLZIP' => 'dolibarr_lib_ODTPHP_PATHTOPCLZIP', + '?dolibarr_js_CKEDITOR' => 'dolibarr_js_CKEDITOR', + '?dolibarr_js_JQUERY' => 'dolibarr_js_JQUERY', + '?dolibarr_js_JQUERY_UI' => 'dolibarr_js_JQUERY_UI', + '?dolibarr_font_DOL_DEFAULT_TTF' => 'dolibarr_font_DOL_DEFAULT_TTF', + '?dolibarr_font_DOL_DEFAULT_TTF_BOLD' => 'dolibarr_font_DOL_DEFAULT_TTF_BOLD', + 'separator4' => '', + 'dolibarr_main_restrict_os_commands' => 'Restrict CLI commands for backups', + 'dolibarr_main_restrict_ip' => 'Restrict access to some IPs only', + '?dolibarr_mailing_limit_sendbyweb' => 'Limit nb of email sent by page', + '?dolibarr_mailing_limit_sendbycli' => 'Limit nb of email sent by cli', + '?dolibarr_strict_mode' => 'Strict mode is on/off', + '?dolibarr_nocsrfcheck' => 'Disable CSRF security checks' ); print '
'; @@ -400,8 +401,10 @@ foreach ($configfileparameters as $key => $value) { if (in_array($newkey, array('dolibarr_main_db_pass', 'dolibarr_main_auth_ldap_admin_pass'))) { if (empty($dolibarr_main_prod)) { print ''; + print showValueWithClipboardCPButton(${$newkey}, 0, '********'); + } else { + print '**********'; } - print '**********'; } elseif ($newkey == 'dolibarr_main_url_root' && preg_match('/__auto__/', ${$newkey})) { print ${$newkey}.' => '.constant('DOL_MAIN_URL_ROOT'); } elseif ($newkey == 'dolibarr_main_document_root_alt') { @@ -420,9 +423,14 @@ foreach ($configfileparameters as $key => $value) { } } elseif ($newkey == 'dolibarr_main_instance_unique_id') { //print $conf->file->instance_unique_id; - global $dolibarr_main_cookie_cryptkey; - $valuetoshow = ${$newkey} ? ${$newkey} : $dolibarr_main_cookie_cryptkey; // Use $dolibarr_main_instance_unique_id first then $dolibarr_main_cookie_cryptkey - print $valuetoshow; + global $dolibarr_main_cookie_cryptkey, $dolibarr_main_instance_unique_id; + $valuetoshow = $dolibarr_main_instance_unique_id ? $dolibarr_main_instance_unique_id : $dolibarr_main_cookie_cryptkey; // Use $dolibarr_main_instance_unique_id first then $dolibarr_main_cookie_cryptkey + if (empty($dolibarr_main_prod)) { + print ''; + print showValueWithClipboardCPButton($valuetoshow, 0, '********'); + } else { + print '**********'; + } if (empty($valuetoshow)) { print img_warning("EditConfigFileToAddEntry", 'dolibarr_main_instance_unique_id'); } diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 0b2f2678521..032a23a68c8 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -251,7 +251,7 @@ print '
'; if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) { print '$dolibarr_main_db_pass: '; if (!empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass)) { - print img_picto('', 'warning').' '.$langs->trans("DatabasePasswordNotObfuscated").'   ('.$langs->trans("Recommanded").': '.$langs->trans("SetOptionTo", $langs->transnoentitiesnoconv("MainDbPasswordFileConfEncrypted"), yn(1)).')'; + print img_picto('', 'warning').' '.$langs->trans("DatabasePasswordNotObfuscated").'   ('.$langs->trans("Recommended").': '.$langs->trans("SetOptionTo", $langs->transnoentitiesnoconv("MainDbPasswordFileConfEncrypted"), yn(1)).')'; //print ' ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("IPsOfUsers")).')'; } else { print img_picto('', 'tick').' '.$langs->trans("DatabasePasswordObfuscated"); @@ -267,49 +267,14 @@ if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) { print '
'; print '
'; print '
'; -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\''; -} -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).'
'; -} 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.
'; - print 'If you really want to switch, you must:
'; - print '- Go on home - setup - other and add constant MAIN_SECURITY_HASH_ALGO to value \'password_hash\'
'; - print '- In same session, WITHOUT LOGGING OUT, go into your admin user record and set a new password
'; - print '- You can now logout and login with this new password. You must now reset password of all other users.
'; - print '

'; -} +print load_fiche_titre($langs->trans("Menu").' '.$langs->trans("SecuritySetup"), '', 'folder'); + + +print ''.$langs->trans("UseCaptchaCode").': '; +print empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA) ? '' : img_picto('', 'tick').' '; +print yn(empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA) ? 0 : 1); print '
'; - - -print 'MAIN_SECURITY_ANTI_SSRF_SERVER_IP = '.(empty($conf->global->MAIN_SECURITY_ANTI_SSRF_SERVER_IP) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Example").': static-ips-of-server - '.$langs->trans("Note").': common loopback ip like 127.*.*.*, [::1] are already added)' : $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").''; -} else { - print $conf->global->MAIN_EXEC_USE_POPEN; -} -if ($execmethod == 1) { - print '   ("exec" PHP method will be used for shell commands)'; -} -if ($execmethod == 2) { - print '   ("popen" PHP method will be used for shell commands)'; -} -print "
"; print '
'; @@ -354,6 +319,62 @@ if (empty($out)) { } print '
'; +print '
'; +print '
'; +print '
'; + + +print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', '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\''; +} +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).'
'; +} 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.
'; + print 'If you really want to switch, you must:
'; + print '- Go on home - setup - other and add constant MAIN_SECURITY_HASH_ALGO to value \'password_hash\'
'; + print '- In same session, WITHOUT LOGGING OUT, go into your admin user record and set a new password
'; + print '- You can now logout and login with this new password. You must now reset password of all other users.
'; + print '

'; +} +print '
'; + +print 'MAIN_SECURITY_ANTI_SSRF_SERVER_IP = '.(empty($conf->global->MAIN_SECURITY_ANTI_SSRF_SERVER_IP) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Example").': static-ips-of-server - '.$langs->trans("Note").': common loopback ip like 127.*.*.*, [::1] are already added)' : $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_RESTRICTHTML_ONLY_VALID_HTML = '.(empty($conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommanded").': 1)' : $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML)."
"; +print '
'; + +print 'MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = '.(empty($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommanded").': 1)' : $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)."
"; +print '
'; + +print 'MAIN_EXEC_USE_POPEN = '; +if (empty($conf->global->MAIN_EXEC_USE_POPEN)) { + print ''.$langs->trans("Undefined").''; +} else { + print $conf->global->MAIN_EXEC_USE_POPEN; +} +if ($execmethod == 1) { + print '   ("exec" PHP method will be used for shell commands)'; +} +if ($execmethod == 2) { + print '   ("popen" PHP method will be used for shell commands)'; +} +print "
"; +print '
'; + // Modules/Applications @@ -405,7 +426,7 @@ if (empty($conf->api->enabled) && empty($conf->webservices->enabled)) { print '
'; } if (!empty($conf->api->enabled)) { - print 'API_ENDPOINT_RULES = '.(empty($conf->global->API_ENDPOINT_RULES) ? ''.$langs->trans("Undefined").'' : $conf->global->API_ENDPOINT_RULES)."
\n"; + print 'API_ENDPOINT_RULES = '.(empty($conf->global->API_ENDPOINT_RULES) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Example").': endpoint1:1,endpoint2:1,...)' : $conf->global->API_ENDPOINT_RULES)."
\n"; print '
'; } } diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 1f59762c865..f5f301e9c16 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -1013,7 +1013,7 @@ class Setup extends DolibarrApi $list[$tab->elementtype][$tab->name]['computed'] = $tab->fieldcomputed; $list[$tab->elementtype][$tab->name]['unique'] = $tab->fieldunique; $list[$tab->elementtype][$tab->name]['required'] = $tab->fieldrequired; - $list[$tab->elementtype][$tab->name]['param'] = ($tab->param ? unserialize($tab->param) : ''); + $list[$tab->elementtype][$tab->name]['param'] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); // This may be a string encoded with serialise() or json_encode() $list[$tab->elementtype][$tab->name]['pos'] = $tab->pos; $list[$tab->elementtype][$tab->name]['alwayseditable'] = $tab->alwayseditable; $list[$tab->elementtype][$tab->name]['perms'] = $tab->perms; diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 366d7042d77..112456480e1 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -777,10 +777,8 @@ class BlockedLog public function dolDecodeBlockedData($data, $mode = 0) { try { - //include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; //include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $aaa = unserialize($data); - //$aaa = unserialize($data); } catch (Exception $e) { //print $e->getErrs); } diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index b598b95ae0a..cd530994b9b 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -532,10 +532,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ if (!empty($object->table_element_line)) { - print '
+ print ' + '; diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index a47b1692ca9..76f16c838be 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -83,6 +83,10 @@ foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -104,7 +108,7 @@ foreach ($object->fields as $key => $val) { 'checked'=>(($visible < 0) ? 0 : 1), 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), 'position'=>$val['position'], - 'help'=>$val['help'] + 'help'=> isset($val['help']) ? $val['help'] : '' ); } } @@ -131,7 +135,8 @@ $result = restrictedArea($user, 'bom'); */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -151,6 +156,10 @@ 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 foreach ($object->fields as $key => $val) { $search[$key] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } } $toselect = array(); $search_array_options = array(); @@ -277,18 +286,18 @@ $now = dol_now(); $help_url = 'EN:Module_BOM'; $title = $langs->trans('ListOfBOMs'); +$morejs = array(); +$morecss = array(); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; -foreach ($object->fields as $key => $val) { - $sql .= 't.'.$key.', '; -} +$sql .= $object->getFieldList('t'); // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.' as options_'.$key.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key.', ' : ''); } } // Add fields from hooks @@ -297,33 +306,52 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (isset($extrafields->attributes[$object->table_element]['label']) && 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 (t.rowid = ef.fk_object)"; } +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; if ($object->ismultientitymanaged == 1) { $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; } else { $sql .= " WHERE 1 = 1"; } foreach ($search as $key => $val) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if (strpos($object->fields[$key]['type'], 'integer:') === 0) { - if ($search[$key] == '-1') { - $search[$key] = ''; + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || $search[$key] === '0') { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName=preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t." . $columnName . " >= '" . $db->idate($search[$key]) . "'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } } - $mode_search = 2; - } - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); } } if ($search_all) { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } +//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear); // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks @@ -332,7 +360,7 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; /* If a group by is required -$sql.= " GROUP BY " +$sql.= " GROUP BY "; foreach($object->fields as $key => $val) { $sql.='t.'.$key.', '; @@ -345,7 +373,7 @@ if (! empty($extrafields->attributes[$object->table_element]['label'])) { } // Add where from hooks $parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook +$reshook=$hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; $sql=preg_replace('/,\s*$/','', $sql); */ @@ -391,7 +419,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -416,6 +444,10 @@ if ($optioncss != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( @@ -431,7 +463,7 @@ if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'pr } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); -print ''; +print ''."\n"; if ($optioncss != '') { print ''; } @@ -440,11 +472,12 @@ print ''; print ''; print ''; +print ''; print ''; $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bom/bom_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $user->rights->bom->write); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bom', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); // Add code for pre mass action (confirmation or email presend form) $topicmail = "SendBillOfMaterialsRef"; @@ -504,11 +537,18 @@ foreach ($object->fields as $key => $val) { if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { - print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth125', 1); - } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { - print ''; + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (!preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print ''; + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
'; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
'; + print '
'; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
'; } print ''; } @@ -559,7 +599,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 (isset($extrafields->attributes[$object->table_element]['computed']) && 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 @@ -572,6 +612,7 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // -------------------------------------------------------------------- $i = 0; $totalarray = array(); +$totalarray['nbfield'] = 0; while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); if (empty($obj)) { @@ -597,17 +638,16 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; } - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status' && empty($val['arrayofkeyval'])) { + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } - if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) { - $cssforfield = 'tdoverflowmax100'; - } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; if ($key == 'status') { print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); } else { print $object->showOutputField($val, $key, $object->$key, ''); } diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 0fe08bb1a4a..3996b5e49bd 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -97,23 +97,23 @@ class BOM extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1, 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax200'), 'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth150', 'csslist'=>'minwidth150 center'), //'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')), - 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'picto'=>'product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp', 'css'=>'maxwidth500'), + 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'picto'=>'product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax100'), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,), 'qty' => array('type'=>'real', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'default'=>1, 'position'=>55, 'notnull'=>1, 'isameasure'=>'1', 'css'=>'maxwidth75imp'), //'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLossForProductProduced'), 'duration' => array('type'=>'duration', 'label'=>'EstimatedDuration', 'enabled'=>1, 'visible'=>-1, 'position'=>101, 'notnull'=>-1, 'css'=>'maxwidth50imp', 'help'=>'EstimatedDurationDesc'), - 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'picto'=>'stock', 'enabled'=>1, 'visible'=>-1, 'position'=>102, 'css'=>'maxwidth500'), + 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'picto'=>'stock', 'enabled'=>1, 'visible'=>-1, 'position'=>102, 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax100'), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>-2, 'position'=>161, 'notnull'=>-1,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>-2, 'position'=>162, 'notnull'=>-1,), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>300, 'notnull'=>1,), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>1,), 'date_valid' => array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-2, 'position'=>502, 'notnull'=>0,), - 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCreation', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid',), - 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1,), - 'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>512, 'notnull'=>0,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCreation', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax100'), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1, 'csslist'=>'tdoverflowmax100'), + 'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'position'=>512, 'notnull'=>0, 'csslist'=>'tdoverflowmax100'), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>1010), 'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>2, 'position'=>1000, 'notnull'=>1, 'default'=>0, 'index'=>1, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Enabled', 9=>'Disabled')), @@ -786,6 +786,9 @@ class BOM extends CommonObject } $label .= '
'; $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->label)) { + $label .= '
'.$langs->trans('Label').': '.$this->label; + } $url = DOL_URL_ROOT.'/bom/bom_card.php?id='.$this->id; diff --git a/htdocs/categories/card.php b/htdocs/categories/card.php index 734f2e89506..141e061ac20 100644 --- a/htdocs/categories/card.php +++ b/htdocs/categories/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2017 Laurent Destailleur + * Copyright (C) 2006-2021 Laurent Destailleur * Copyright (C) 2005-2014 Regis Houssin * Copyright (C) 2007 Patrick Raguin * Copyright (C) 2013 Florian Henry @@ -257,6 +257,7 @@ if ($user->rights->categorie->creer) { // Parent category print ''.$langs->trans("AddIn").''; + print img_picto($langs->trans("ParentCategory"), 'category', 'class="pictofixedwidth"'); print $form->select_all_categories($type, $catorigin, 'parent'); print ajax_combobox('parent'); print ''; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 9b76329d8da..c87af9558e8 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -138,16 +138,18 @@ if (empty($action) && !GETPOSTISSET('action')) { if ($action == 'default') { // When action is default, we want a calendar view and not the list $action = (($defaultview != 'show_list') ? $defaultview : 'show_month'); } -if (GETPOST('viewcal', 'restricthtml') && GETPOST('action', 'alpha') != 'show_day' && GETPOST('action', 'alpha') != 'show_week') { +if (GETPOST('viewcal', 'int') && GETPOST('action', 'alpha') != 'show_day' && GETPOST('action', 'alpha') != 'show_week') { $action = 'show_month'; $day = ''; } // View by month -if (GETPOST('viewweek', 'restricthtml') || GETPOST('action', 'alpha') == 'show_week') { +if (GETPOST('viewweek', 'int') || GETPOST('action', 'alpha') == 'show_week') { $action = 'show_week'; $week = ($week ? $week : date("W")); $day = ($day ? $day : date("d")); } // View by week -if (GETPOST('viewday', 'restricthtml') || GETPOST('action', 'alpha') == 'show_day') { +if (GETPOST('viewday', 'int') || GETPOST('action', 'alpha') == 'show_day') { $action = 'show_day'; $day = ($day ? $day : date("d")); } // View by day +$object = new ActionComm($db); + // Load translation files required by the page $langs->loadLangs(array('agenda', 'other', 'commercial')); @@ -197,6 +199,7 @@ if (GETPOST("viewperuser", 'alpha') || $action == 'show_peruser') { exit; } +/* if ($action == 'delete_action') { $event = new ActionComm($db); $event->fetch($actionid); @@ -206,6 +209,7 @@ if ($action == 'delete_action') { $result = $event->delete(); } +*/ /* @@ -484,25 +488,25 @@ $viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="pictoaction //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewCal"), 'object_calendarmonth', 'class="pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewCal").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewWeek").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewDay").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview block"'); //$viewmode .= ''; @@ -939,6 +943,7 @@ if ($showbirthday) { } } +// LEAVE CALENDAR $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.statut, x.rowid, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE u.rowid = x.fk_user"; @@ -1877,7 +1882,8 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $cacheusers[$tmpid] = $newuser; } - $listofusertoshow .= '
'.$cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'paddingright valigntextbottom'); + $listofusertoshow = ''; + $listofusertoshow .= '
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valigntextbottom'); print $listofusertoshow; } else { // Other calendar // Picto diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index d801b4429c7..e03d13c29e8 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -577,7 +577,6 @@ if (empty($reshook)) { if (!$isupload) { $mesgs = array(); - $object->sujet = (string) GETPOST("sujet"); $object->body = (string) GETPOST("bodyemail", 'restricthtml'); $object->bgcolor = (string) GETPOST("bgcolor"); @@ -744,7 +743,7 @@ if ($action == 'create') { print '
'; // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtml'), '', 600, 'dolibarr_mailings', '', true, true, $conf->global->FCKEDITOR_ENABLE_MAILING, 20, '90%'); + $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, true, $conf->global->FCKEDITOR_ENABLE_MAILING, 20, '90%'); $doleditor->Create(); print '
'; diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index 04d2f7c17d8..d281fcb1a3a 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -208,6 +208,12 @@ class Mailing extends CommonObject { global $conf, $langs; + // Check properties + if ($this->body === 'InvalidHTMLString') { + $this->error = 'InvalidHTMLString'; + return -1; + } + $this->db->begin(); $this->title = trim($this->title); @@ -257,6 +263,12 @@ class Mailing extends CommonObject */ public function update($user) { + // Check properties + if ($this->body === 'InvalidHTMLString') { + $this->error = 'InvalidHTMLString'; + return -1; + } + $sql = "UPDATE ".MAIN_DB_PREFIX."mailing "; $sql .= " SET titre = '".$this->db->escape($this->title)."'"; $sql .= ", sujet = '".$this->db->escape($this->sujet)."'"; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8b5f757ad0e..3c0d8dd9a28 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -843,16 +843,16 @@ if (empty($reshook)) { } } - if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal. + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors'); $error++; } @@ -871,7 +871,7 @@ if (empty($reshook)) { } } - if (!$error && ($qty >= 0) && (!empty($product_desc) || !empty($idprod))) { + if (!$error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) { $pu_ht = 0; $pu_ttc = 0; $price_min = 0; @@ -885,7 +885,7 @@ if (empty($reshook)) { // Ecrase $desc par celui du produit // Ecrase $tva_tx par celui du produit // Replaces $fk_unit with the product unit - if (!empty($idprod)) { + if (!empty($idprod) && $idprod > 0) { $prod = new Product($db); $prod->fetch($idprod); @@ -2450,10 +2450,11 @@ if ($action == 'create') { // Show object lines $result = $object->getLinesArray(); - print ' + print ' + '; @@ -2594,9 +2595,14 @@ if ($action == 'create') { } // Close as accepted/refused - if ($object->statut == Propal::STATUS_VALIDATED && $usercanclose) { - print '
global->MAIN_JUMP_TAG) ? '' : '#close').'"'; - print '>'.$langs->trans('SetAcceptedRefused').''; + if ($object->statut == Propal::STATUS_VALIDATED) { + if ($usercanclose) { + print 'global->MAIN_JUMP_TAG) ? '' : '#close').'"'; + print '>'.$langs->trans('SetAcceptedRefused').''; + } else { + print ''.$langs->trans('SetAcceptedRefused').''; + } } // Clone diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 940e0156c7e..3bc30d7d729 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -605,7 +605,7 @@ class Propal extends CommonObject $this->db->begin(); $product_type = $type; - if (!empty($fk_product)) { + if (!empty($fk_product) && $fk_product > 0) { $product = new Product($this->db); $result = $product->fetch($fk_product); $product_type = $product->type; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index d99c8b81b2c..2d4eb5fb164 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -220,17 +220,16 @@ $permissiontoread = $user->rights->propal->lire; $permissiontoadd = $user->rights->propal->creer; $permissiontodelete = $user->rights->propal->supprimer; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $permissiontovalidate = $user->rights->propale->propal_advance->validate; - $permissiontoclose = $user->rights->propale->propal_advance->close; - $permissiontosendbymail = $user->rights->propale->propal_advance->send; + $permissiontovalidate = $user->rights->propal->propal_advance->validate; + $permissiontoclose = $user->rights->propal->propal_advance->close; + $permissiontosendbymail = $user->rights->propal->propal_advance->send; } else { $permissiontovalidate = $user->rights->propal->creer; $permissiontoclose = $user->rights->propal->creer; + $permissiontosendbymail = $user->rights->propal->lire; } - - /* * Actions */ diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 6d0badf6380..7363ceace5c 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -645,15 +645,15 @@ if (empty($reshook)) { } } - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ($qty < 0)) { setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht == '' && $price_ht_devise == '') { // Unit price can be 0 but not ''. Also price can be negative for order. + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht == '' && $price_ht_devise == '') { // Unit price can be 0 but not ''. Also price can be negative for order. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; } @@ -661,7 +661,7 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error++; } @@ -680,7 +680,7 @@ if (empty($reshook)) { } } - if (!$error && ($qty >= 0) && (!empty($product_desc) || !empty($idprod))) { + if (!$error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) { // Clean parameters $date_start = dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); $date_end = dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); @@ -690,7 +690,7 @@ if (empty($reshook)) { // Ecrase $desc par celui du produit // Ecrase $tva_tx par celui du produit // Ecrase $base_price_type par celui du produit - if (!empty($idprod)) { + if (!empty($idprod) && $idprod > 0) { $prod = new Product($db); $prod->fetch($idprod); @@ -2417,10 +2417,11 @@ if ($action == 'create' && $usercancreate) { */ $result = $object->getLinesArray(); - print ' + print ' + '; if (!empty($conf->use_javascript_ajax) && $object->statut == Commande::STATUS_DRAFT) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index aa9897f9dc7..333d4e2ded6 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1518,7 +1518,7 @@ class Commande extends CommonOrder $this->db->begin(); $product_type = $type; - if (!empty($fk_product)) { + if (!empty($fk_product) && $fk_product > 0) { $product = new Product($this->db); $result = $product->fetch($fk_product); $product_type = $product->type; @@ -4389,7 +4389,7 @@ class OrderLine extends CommonOrderLine $sql .= " '".price2num($this->localtax2_tx)."',"; $sql .= " '".$this->db->escape($this->localtax1_type)."',"; $sql .= " '".$this->db->escape($this->localtax2_type)."',"; - $sql .= ' '.(!empty($this->fk_product) ? $this->fk_product : "null").','; + $sql .= ' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product : "null").','; $sql .= " '".$this->db->escape($this->product_type)."',"; $sql .= " '".price2num($this->remise_percent)."',"; $sql .= " ".(price2num($this->subprice) !== '' ?price2num($this->subprice) : "null").","; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 73413d1070f..77eedcd3e34 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -494,7 +494,7 @@ if ($search_billed != '' && $search_billed >= 0) { $sql .= ' AND c.facture = '.((int) $search_billed); } if ($search_status <> '') { - if ($search_status < 4 && $search_status > -3) { + if ($search_status < 4 && $search_status > -4) { if ($search_status == 1 && empty($conf->expedition->enabled)) { $sql .= ' AND c.fk_statut IN (1,2)'; // If module expedition disabled, we include order with status 'sending in process' into 'validated' } else { @@ -513,6 +513,11 @@ if ($search_status <> '') { //$sql.= ' AND c.facture = 0'; // invoice not created $sql .= ' AND ((c.fk_statut IN (1,2)) OR (c.fk_statut = 3 AND c.facture = 0))'; // validated, in process or closed but not billed } + + + if ($search_status == -4) { // "validate and in progress" + $sql .= ' AND (c.fk_statut IN (1,2))'; // validated, in process + } } if ($search_datecloture_start) { @@ -675,6 +680,9 @@ if ($resql) { if ($search_status == -3) { $title .= ' - '.$langs->trans('StatusOrderValidated').', '.(empty($conf->expedition->enabled) ? '' : $langs->trans("StatusOrderSent").', ').$langs->trans('StatusOrderToBill'); } + if ($search_status == -4) { + $title .= ' - '.$langs->trans("StatusOrderValidatedShort").'+'.$langs->trans("StatusOrderSentShort"); + } $num = $db->num_rows($resql); @@ -1236,6 +1244,7 @@ if ($resql) { Commande::STATUS_SHIPMENTONPROCESS=>$langs->trans("StatusOrderSentShort"), Commande::STATUS_CLOSED=>$langs->trans("StatusOrderDelivered"), -3=>$langs->trans("StatusOrderValidatedShort").'+'.$langs->trans("StatusOrderSentShort").'+'.$langs->trans("StatusOrderDelivered"), + -4=>$langs->trans("StatusOrderValidatedShort").'+'.$langs->trans("StatusOrderSentShort"), Commande::STATUS_CANCELED=>$langs->trans("StatusOrderCanceledShort") ); print $form->selectarray('search_status', $liststatus, $search_status, -4, 0, 0, '', 0, 0, 0, '', 'maxwidth100', 1); diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 7f1c830d45b..ea9f7799849 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -399,7 +399,8 @@ if ($action == 'create') { // State print ''.$langs->trans('State').''; if ($selectedcode) { - $formcompany->select_departement(GETPOSTISSET("account_state_id") ? GETPOST("account_state_id") : '', $selectedcode, 'account_state_id'); + print img_picto('', 'state', 'class="pictofixedwidth"'); + print $formcompany->select_state(GETPOSTISSET("account_state_id") ? GETPOST("account_state_id") : '', $selectedcode, 'account_state_id'); } else { print $countrynotdefined; } @@ -407,7 +408,10 @@ if ($action == 'create') { // Web print ''.$langs->trans("Web").''; - print ''; + print ''; + print img_picto('', 'globe', 'class="pictofixedwidth"'); + print ''; + print ''; // Tags-Categories if ($conf->categorie->enabled) { @@ -865,6 +869,7 @@ if ($action == 'create') { if (!$selectedcode) { $selectedcode = $conf->currency; } + print img_picto('', 'multicurrency', 'class="pictofixedwidth"'); print $form->selectCurrency((GETPOSTISSET("account_currency_code") ? GETPOST("account_currency_code") : $selectedcode), 'account_currency_code'); //print $langs->trans("Currency".$conf->currency); //print ''; @@ -897,6 +902,7 @@ if ($action == 'create') { // State print ''.$langs->trans('State').''; if ($selectedcode) { + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state(GETPOSTISSET("account_state_id") ? GETPOST("account_state_id") : $object->state_id, $selectedcode, 'account_state_id'); } else { print $countrynotdefined; @@ -925,7 +931,9 @@ if ($action == 'create') { // Web print ''.$langs->trans("Web").''; - print 'url).'">'; + print ''; + print img_picto('', 'globe', 'class="pictofixedwidth"'); + print 'url).'">'; print ''; // Tags-Categories diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 46d1bb93684..8619ff25dae 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -829,8 +829,8 @@ class Account extends CommonObject $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null"); $sql .= ",comment = '".$this->db->escape($this->comment)."'"; - $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null"); - $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null"); + $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null"); + $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null"); $sql .= ",ics = '".$this->db->escape($this->ics)."'"; $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'"; diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index 67599ffff0e..c1b446a9dd0 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -564,7 +564,7 @@ foreach ($accounts as $key => $type) { // Account number if (!empty($arrayfields['b.account_number']['checked'])) { - print ''; + print ''; if (!empty($conf->accounting->enabled) && !empty($objecttmp->account_number)) { $accountingaccount = new AccountingAccount($db); $accountingaccount->fetch('', $objecttmp->account_number, 1); diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index 6ccd953a68b..d9b54ad1c3d 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -163,8 +163,8 @@ if (GETPOST("account") || GETPOST("ref")) { $sqls[] = $sql; // Social contributions - $sql = " SELECT 'social_contribution' as family, cs.rowid as objid, cs.libelle as ref, (-1*cs.amount) as total_ttc, ccs.libelle as type, cs.date_ech as dlr"; - $sql .= ", cs.fk_account"; + $sql = " SELECT 'social_contribution' as family, cs.rowid as objid, cs.libelle as ref, (-1*cs.amount) as total_ttc, ccs.libelle as type, cs.date_ech as dlr,"; + $sql .= " 0 as socid, 'noname' as name, 0 as fournisseur"; $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id"; $sql .= " WHERE cs.entity = ".$conf->entity; @@ -188,7 +188,18 @@ if (GETPOST("account") || GETPOST("ref")) { $resql = $db->query($sql); if ($resql) { while ($sqlobj = $db->fetch_object($resql)) { - $tab_sqlobj[] = $sqlobj; + $tmpobj = new stdClass(); + $tmpobj->family = $sqlobj->family; + $tmpobj->objid = $sqlobj->objid; + $tmpobj->ref = $sqlobj->ref; + $tmpobj->total_ttc = $sqlobj->total_ttc; + $tmpobj->type = $sqlobj->type; + $tmpobj->dlt = $sqlobj->dlr; + $tmpobj->socid = $sqlobj->socid; + $tmpobj->name = $sqlobj->name; + $tmpobj->fournisseur = $sqlobj->fournisseur; + + $tab_sqlobj[] = $tmpobj; $tab_sqlobjOrder[] = $db->jdate($sqlobj->dlr); } $db->free($resql); @@ -201,15 +212,6 @@ if (GETPOST("account") || GETPOST("ref")) { if (!$error) { array_multisort($tab_sqlobjOrder, $tab_sqlobj); - // Apply distinct filter - foreach ($tab_sqlobj as $key => $value) { - $tab_sqlobj[$key] = "'".serialize($value)."'"; - } - $tab_sqlobj = array_unique($tab_sqlobj); - foreach ($tab_sqlobj as $key => $value) { - $tab_sqlobj[$key] = unserialize(trim($value, "'")); - } - $num = count($tab_sqlobj); $i = 0; diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index ec7af37940c..42e53085ea8 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -131,7 +131,7 @@ foreach ($object->fields as $key => $val) { 'checked'=>(($visible < 0) ? 0 : 1), 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), 'position'=>$val['position'], - 'help'=>$val['help'] + 'help'=> isset($val['help']) ? $val['help'] : '' ); } } diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index dd4042b9e34..affdd2e8991 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -447,15 +447,15 @@ if (empty($reshook)) { } } - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ($qty < 0)) { setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && (!($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not '' + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (!($price_ht >= 0) || $price_ht == '')) { // Unit price can be 0 but not '' setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; } @@ -463,7 +463,7 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error++; } @@ -473,7 +473,7 @@ if (empty($reshook)) { $error++; } - if (!$error && ($qty >= 0) && (!empty($product_desc) || !empty($idprod))) { + if (!$error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) { $ret = $object->fetch($id); if ($ret < 0) { dol_print_error($db, $object->error); @@ -495,7 +495,7 @@ if (empty($reshook)) { // Ecrase $tva_tx par celui du produit // Ecrase $base_price_type par celui du produit // Replaces $fk_unit with the product's - if (!empty($idprod)) { + if (!empty($idprod) && $idprod > 0) { $prod = new Product($db); $prod->fetch($idprod); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 1f6a03ca351..699a10d3ef5 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2000,7 +2000,7 @@ if (empty($reshook)) { } } - if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { + if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ($qty < 0)) { setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } @@ -2010,11 +2010,11 @@ if (empty($reshook)) { $error++; } } - if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } - if (($prod_entry_mode == 'free' && empty($idprod) && (($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $price_ht == '') && $price_ht_devise == '') && $object->type != Facture::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' + if (($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $price_ht == '') && $price_ht_devise == '') && $object->type != Facture::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' if ($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { $langs->load("errors"); if ($object->type == $object::TYPE_DEPOSIT) { @@ -2057,7 +2057,7 @@ if (empty($reshook)) { } } - if (!$error && ($qty >= 0) && (!empty($product_desc) || !empty($idprod))) { + if (!$error && ($qty >= 0) && (!empty($product_desc) || (!empty($idprod) && $idprod > 0))) { $ret = $object->fetch($id); if ($ret < 0) { dol_print_error($db, $object->error); @@ -2079,7 +2079,7 @@ if (empty($reshook)) { // Ecrase $tva_tx par celui du produit // Ecrase $base_price_type par celui du produit // Replaces $fk_unit with the product's - if (!empty($idprod)) { + if (!empty($idprod) && $idprod > 0) { $prod = new Product($db); $prod->fetch($idprod); @@ -3296,11 +3296,11 @@ if ($action == 'create') { if (is_array($facids)) { foreach ($facids as $facparam) { $options .= ''; } } @@ -5195,10 +5195,11 @@ if ($action == 'create') { } } - print ' + print ' + '; @@ -5393,7 +5394,7 @@ if ($action == 'create') { } // Create a credit note - if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && $object->statut > 0 && $usercancreate) { + if (($object->type == Facture::TYPE_STANDARD || ($object->type == Facture::TYPE_DEPOSIT && empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) || $object->type == Facture::TYPE_PROFORMA) && $object->statut > 0 && $usercancreate) { if (!$objectidnext) { print ''.$langs->trans("CreateCreditNote").''; } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index fab10da3751..9cbfb33e5bd 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3213,7 +3213,7 @@ class Facture extends CommonInvoice $this->db->begin(); $product_type = $type; - if (!empty($fk_product)) { + if (!empty($fk_product) && $fk_product > 0) { $product = new Product($this->db); $result = $product->fetch($fk_product); $product_type = $product->type; @@ -4090,8 +4090,8 @@ class Facture extends CommonInvoice * Invoices matching the following rules are returned: * (Status validated or abandonned for a reason 'other') + not payed + no payment at all + not already replaced * - * @param int $socid Id thirdparty - * @return array|int Array of invoices ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) + * @param int $socid Id thirdparty + * @return array|int Array of invoices ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) */ public function list_replacable_invoices($socid = 0) { @@ -4100,28 +4100,34 @@ class Facture extends CommonInvoice $return = array(); - $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut,"; + $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut as status, f.paye as paid,"; $sql .= " ff.rowid as rowidnext"; + //$sql .= ", SUM(pf.amount) as alreadypaid"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source"; $sql .= " WHERE (f.fk_statut = ".self::STATUS_VALIDATED." OR (f.fk_statut = ".self::STATUS_ABANDONED." AND f.close_code = '".self::CLOSECODE_ABANDONED."'))"; $sql .= " AND f.entity IN (".getEntity('invoice').")"; - $sql .= " AND f.paye = 0"; // Pas classee payee completement - $sql .= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait - $sql .= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement + $sql .= " AND f.paye = 0"; // Not paid completely + $sql .= " AND pf.fk_paiement IS NULL"; // No payment already done + $sql .= " AND ff.fk_statut IS NULL"; // Return true if it is not a replacement invoice if ($socid > 0) { $sql .= " AND f.fk_soc = ".((int) $socid); } + //$sql .= " GROUP BY f.rowid, f.ref, f.fk_statut, f.paye, ff.rowid"; $sql .= " ORDER BY f.ref"; dol_syslog(get_class($this)."::list_replacable_invoices", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { - $return[$obj->rowid] = array('id' => $obj->rowid, - 'ref' => $obj->ref, - 'status' => $obj->fk_statut); + $return[$obj->rowid] = array( + 'id' => $obj->rowid, + 'ref' => $obj->ref, + 'status' => $obj->status, + 'paid' => $obj->paid, + 'alreadypaid' => 0 + ); } //print_r($return); return $return; @@ -5336,7 +5342,7 @@ class FactureLigne extends CommonInvoiceLine $this->error = 'ErrorProductTypeMustBe0orMore'; return -1; } - if (!empty($this->fk_product)) { + if (!empty($this->fk_product) && $this->fk_product > 0) { // Check product exists $result = Product::isExistingObject('product', $this->fk_product); if ($result <= 0) { @@ -5371,7 +5377,7 @@ class FactureLigne extends CommonInvoiceLine $sql .= " ".price2num($this->localtax2_tx).","; $sql .= " '".$this->db->escape($this->localtax1_type)."',"; $sql .= " '".$this->db->escape($this->localtax2_type)."',"; - $sql .= ' '.(!empty($this->fk_product) ? $this->fk_product : "null").','; + $sql .= ' '.((!empty($this->fk_product) && $this->fk_product > 0) ? $this->fk_product : "null").','; $sql .= " ".((int) $this->product_type).","; $sql .= " ".price2num($this->remise_percent).","; $sql .= " ".price2num($this->subprice).","; diff --git a/htdocs/compta/sociales/class/cchargesociales.class.php b/htdocs/compta/sociales/class/cchargesociales.class.php index 8cfadd84f4f..ee9a270b283 100644 --- a/htdocs/compta/sociales/class/cchargesociales.class.php +++ b/htdocs/compta/sociales/class/cchargesociales.class.php @@ -260,13 +260,13 @@ class Cchargesociales // Update request $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET'; $sql .= ' libelle = '.(isset($this->libelle) ? "'".$this->db->escape($this->libelle)."'" : "null").','; - $sql .= ' deductible = '.(isset($this->deductible) ? $this->deductible : "null").','; - $sql .= ' active = '.(isset($this->active) ? $this->active : "null").','; + $sql .= ' deductible = '.(isset($this->deductible) ? ((int) $this->deductible) : "null").','; + $sql .= ' active = '.(isset($this->active) ? ((int) $this->active) : "null").','; $sql .= ' code = '.(isset($this->code) ? "'".$this->db->escape($this->code)."'" : "null").','; - $sql .= ' fk_pays = '.(isset($this->fk_pays) ? $this->fk_pays : "null").','; + $sql .= ' fk_pays = '.((isset($this->fk_pays) && $this->fk_pays > 0) ? ((int) $this->fk_pays) : "null").','; $sql .= ' module = '.(isset($this->module) ? "'".$this->db->escape($this->module)."'" : "null").','; $sql .= ' accountancy_code = '.(isset($this->accountancy_code) ? "'".$this->db->escape($this->accountancy_code)."'" : "null"); - $sql .= ' WHERE id='.$this->id; + $sql .= ' WHERE id='.((int) $this->id); $this->db->begin(); diff --git a/htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php b/htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php index cceb6310dc2..bc8ff9ebcf4 100644 --- a/htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php +++ b/htdocs/contact/canvas/default/tpl/contactcard_create.tpl.php @@ -30,8 +30,6 @@ print load_fiche_titre($this->control->tpl['title']); dol_htmloutput_errors((is_numeric($object->error) ? '' : $object->error), $object->errors); -dol_htmloutput_errors((is_numeric($GLOBALS['error']) ? '' : $GLOBALS['error']), $GLOBALS['errors']); - dol_htmloutput_errors($this->control->tpl['error'], $this->control->tpl['errors']); echo $this->control->tpl['ajax_selectcountry']; ?> diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index dea4f9d185d..469869f00e9 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -726,6 +726,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } if ($object->country_id) { + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state(GETPOST("state_id", 'alpha') ? GETPOST("state_id", 'alpha') : $object->state_id, $object->country_code, 'state_id'); } else { print $countrynotdefined; @@ -1019,6 +1020,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state(GETPOSTISSET('state_id') ? GETPOST('state_id', 'alpha') : $object->state_id, $object->country_code, 'state_id'); print ''; } diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index a5f408f4299..165a7bf7bc3 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -100,15 +100,15 @@ class Contact extends CommonObject 'firstname' =>array('type'=>'varchar(50)', 'label'=>'Firstname', 'enabled'=>1, 'visible'=>1, 'position'=>50, 'showoncombobox'=>1, 'searchall'=>1), 'address' =>array('type'=>'varchar(255)', 'label'=>'Address', 'enabled'=>1, 'visible'=>-1, 'position'=>55), 'zip' =>array('type'=>'varchar(25)', 'label'=>'Zip', 'enabled'=>1, 'visible'=>1, 'position'=>60), - 'town' =>array('type'=>'text', 'label'=>'Town', 'enabled'=>1, 'visible'=>1, 'position'=>65), + 'town' =>array('type'=>'text', 'label'=>'Town', 'enabled'=>1, 'visible'=>-1, 'position'=>65), 'fk_departement' =>array('type'=>'integer', 'label'=>'Fk departement', 'enabled'=>1, 'visible'=>3, 'position'=>70), 'fk_pays' =>array('type'=>'integer', 'label'=>'Fk pays', 'enabled'=>1, 'visible'=>3, 'position'=>75), 'birthday' =>array('type'=>'date', 'label'=>'Birthday', 'enabled'=>1, 'visible'=>3, 'position'=>80), 'poste' =>array('type'=>'varchar(80)', 'label'=>'PostOrFunction', 'enabled'=>1, 'visible'=>-1, 'position'=>85), 'phone' =>array('type'=>'varchar(30)', 'label'=>'Phone', 'enabled'=>1, 'visible'=>1, 'position'=>90, 'searchall'=>1), - 'phone_perso' =>array('type'=>'varchar(30)', 'label'=>'PhonePerso', 'enabled'=>1, 'visible'=>1, 'position'=>95, 'searchall'=>1), + 'phone_perso' =>array('type'=>'varchar(30)', 'label'=>'PhonePerso', 'enabled'=>1, 'visible'=>-1, 'position'=>95, 'searchall'=>1), 'phone_mobile' =>array('type'=>'varchar(30)', 'label'=>'PhoneMobile', 'enabled'=>1, 'visible'=>1, 'position'=>100, 'searchall'=>1), - 'fax' =>array('type'=>'varchar(30)', 'label'=>'Fax', 'enabled'=>1, 'visible'=>1, 'position'=>105, 'searchall'=>1), + 'fax' =>array('type'=>'varchar(30)', 'label'=>'Fax', 'enabled'=>1, 'visible'=>-1, 'position'=>105, 'searchall'=>1), 'email' =>array('type'=>'varchar(255)', 'label'=>'Email', 'enabled'=>1, 'visible'=>1, 'position'=>110, 'searchall'=>1), 'socialnetworks' =>array('type'=>'text', 'label'=>'SocialNetworks', 'enabled'=>1, 'visible'=>3, 'position'=>115), 'photo' =>array('type'=>'varchar(255)', 'label'=>'Photo', 'enabled'=>1, 'visible'=>3, 'position'=>170), diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index fe8e20bac9c..e5a9ab3f0d6 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -1097,28 +1097,28 @@ while ($i < min($num, $limit)) { } // Phone if (!empty($arrayfields['p.phone']['checked'])) { - print ''.dol_print_phone($obj->phone_pro, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''; + print ''.dol_print_phone($obj->phone_pro, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''; if (!$i) { $totalarray['nbfield']++; } } // Phone perso if (!empty($arrayfields['p.phone_perso']['checked'])) { - print ''.dol_print_phone($obj->phone_perso, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''; + print ''.dol_print_phone($obj->phone_perso, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''; if (!$i) { $totalarray['nbfield']++; } } // Phone mobile if (!empty($arrayfields['p.phone_mobile']['checked'])) { - print ''.dol_print_phone($obj->phone_mobile, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'mobile').''; + print ''.dol_print_phone($obj->phone_mobile, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'mobile').''; if (!$i) { $totalarray['nbfield']++; } } // Fax if (!empty($arrayfields['p.fax']['checked'])) { - print ''.dol_print_phone($obj->fax, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'fax').''; + print ''.dol_print_phone($obj->fax, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'fax').''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 05c7436c22e..32edf9a1558 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -386,7 +386,7 @@ if (empty($reshook)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); $error++; } - if (GETPOST('prod_entry_mode', 'alpha') == 'free' && empty($idprod) && empty($product_desc)) { + if (GETPOST('prod_entry_mode', 'alpha') == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors'); $error++; } diff --git a/htdocs/core/boxes/box_graph_nb_tickets_type.php b/htdocs/core/boxes/box_graph_nb_tickets_type.php index 86ea5e2a11c..2da54d84e7a 100644 --- a/htdocs/core/boxes/box_graph_nb_tickets_type.php +++ b/htdocs/core/boxes/box_graph_nb_tickets_type.php @@ -69,20 +69,11 @@ class box_graph_nb_tickets_type extends ModeleBoxes global $theme_datacolor, $badgeStatus8; require_once DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php"; + require_once DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/theme_vars.inc.php"; - $badgeStatus0 = '#cbd3d3'; // draft - $badgeStatus1 = '#bc9526'; // validated - $badgeStatus1b = '#bc9526'; // validated - $badgeStatus2 = '#9c9c26'; // approved - $badgeStatus3 = '#bca52b'; - $badgeStatus4 = '#25a580'; // Color ok - $badgeStatus4b = '#25a580'; // Color ok - $badgeStatus5 = '#cad2d2'; - $badgeStatus6 = '#cad2d2'; - $badgeStatus7 = '#baa32b'; $badgeStatus8 = '#993013'; - $badgeStatus9 = '#e7f0f0'; + $text = $langs->trans("BoxTicketType"); $this->info_box_head = array( 'text' => $text, diff --git a/htdocs/core/boxes/box_scheduled_jobs.php b/htdocs/core/boxes/box_scheduled_jobs.php index 793b0cc8c79..53cf5c79571 100644 --- a/htdocs/core/boxes/box_scheduled_jobs.php +++ b/htdocs/core/boxes/box_scheduled_jobs.php @@ -85,7 +85,7 @@ class box_scheduled_jobs extends ModeleBoxes $resultarray = array(); $result = 0; - $sql = "SELECT t.rowid, t.datelastrun, t.datenextrun,"; + $sql = "SELECT t.rowid, t.datelastrun, t.datenextrun, t.datestart,"; $sql .= " t.label, t.status, t.test, t.lastresult"; $sql .= " FROM " . MAIN_DB_PREFIX . "cronjob as t"; $sql .= " WHERE status <> ".$cronstatic::STATUS_DISABLED; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ec9449eba8f..b3ae722a5d3 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6254,10 +6254,12 @@ abstract class CommonObject $this->array_options["options_".$key] = price2num($this->array_options["options_".$key]); break; case 'date': - $this->array_options["options_".$key] = $this->db->idate($this->array_options["options_".$key]); - break; case 'datetime': - $this->array_options["options_".$key] = $this->db->idate($this->array_options["options_".$key]); + if (empty($this->array_options["options_".$key])) { + $this->array_options["options_".$key] = null; + } else { + $this->array_options["options_".$key] = $this->db->idate($this->array_options["options_".$key]); + } break; /* case 'link': @@ -6305,7 +6307,11 @@ abstract class CommonObject } if ($linealreadyfound) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key." = '".$this->db->escape($this->array_options["options_".$key])."'"; + if ($this->array_options["options_".$key] === null) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key." = null"; + } else { + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key." = '".$this->db->escape($this->array_options["options_".$key])."'"; + } $sql .= " WHERE fk_object = ".$this->id; } else { $result = $this->insertExtraFields('', $user); @@ -7486,6 +7492,9 @@ abstract class CommonObject if ($display_type == 'card') { $out .= ''; + if ( ! empty($conf->global->MAIN_VIEW_LINE_NUMBER) ) { + $out .= ''; + } $out .= ''; @@ -7711,7 +7720,7 @@ abstract class CommonObject $buyPrice = $unitPrice * (1 - $discountPercent / 100); } else { // Get cost price for margin calculation - if (!empty($fk_product)) { + if (!empty($fk_product) && $fk_product > 0) { if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'costprice') { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $product = new Product($this->db); @@ -8167,15 +8176,6 @@ abstract class CommonObject } else { $queryarray[$field] = $this->db->idate($this->{$field}); } - } elseif ($this->isArray($info)) { - if (!empty($this->{$field})) { - if (!is_array($this->{$field})) { - $this->{$field} = array($this->{$field}); - } - $queryarray[$field] = serialize($this->{$field}); - } else { - $queryarray[$field] = null; - } } elseif ($this->isDuration($info)) { // $this->{$field} may be null, '', 0, '0', 123, '123' if ((isset($this->{$field}) && $this->{$field} != '') || !empty($info['notnull'])) { @@ -8236,16 +8236,6 @@ abstract class CommonObject } else { $this->{$field} = $db->jdate($obj->{$field}); } - } elseif ($this->isArray($info)) { - if (!empty($obj->{$field})) { - $this->{$field} = @unserialize($obj->{$field}); - // Hack for data not in UTF8 - if ($this->{$field } === false) { - @unserialize(utf8_decode($obj->{$field})); - } - } else { - $this->{$field} = array(); - } } elseif ($this->isInt($info)) { if ($field == 'rowid') { $this->id = (int) $obj->{$field}; diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index b1819e24ab0..a1725526898 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -596,7 +596,7 @@ class DolGraph // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Get max value + * Get max value among all values of all series * * @return int Max value */ @@ -607,25 +607,26 @@ class DolGraph return 0; } - $k = 0; - $vals = array(); + $max = null; - $nblines = count($this->data); - $nbvalues = (empty($this->data[0]) ? 0 : count($this->data[0]) - 1); + $nbseries = (empty($this->data[0]) ? 0 : count($this->data[0]) - 1); - for ($j = 0; $j < $nblines; $j++) { - for ($i = 0; $i < $nbvalues; $i++) { - $vals[$k] = $this->data[$j][$i + 1]; - $k++; + foreach ($this->data as $x) { // Loop on each x + for ($i = 0; $i < $nbseries; $i++) { // Loop on each serie + if (is_null($max)) { + $max = $x[$i + 1]; // $i+1 because the index 0 is the legend + } elseif ($max < $x[$i + 1]) { + $max = $x[$i + 1]; + } } } - rsort($vals); - return $vals[0]; + + return $max; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Return min value of all data + * Return min value of all values of all series * * @return int Min value of all data */ @@ -636,20 +637,21 @@ class DolGraph return 0; } - $k = 0; - $vals = array(); + $min = null; - $nblines = count($this->data); - $nbvalues = (empty($this->data[0]) ? 0 : count($this->data[0]) - 1); + $nbseries = (empty($this->data[0]) ? 0 : count($this->data[0]) - 1); - for ($j = 0; $j < $nblines; $j++) { - for ($i = 0; $i < $nbvalues; $i++) { - $vals[$k] = $this->data[$j][$i + 1]; - $k++; + foreach ($this->data as $x) { // Loop on each x + for ($i = 0; $i < $nbseries; $i++) { // Loop on each serie + if (is_null($min)) { + $min = $x[$i + 1]; // $i+1 because the index 0 is the legend + } elseif ($min > $x[$i + 1]) { + $min = $x[$i + 1]; + } } } - sort($vals); - return $vals[0]; + + return $min; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index c109bc65733..45c87401416 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -390,7 +390,7 @@ class dolReceiptPrinter extends Printer $error = 0; $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'printer_receipt'; $sql .= ' (name, fk_type, fk_profile, parameter, entity)'; - $sql .= ' VALUES ("'.$this->db->escape($name).'", '.$type.', '.$profile.', "'.$this->db->escape($parameter).'", '.$conf->entity.')'; + $sql .= ' VALUES ("'.$this->db->escape($name).'", '.((int) $type).', '.((int) $profile).', "'.$this->db->escape($parameter).'", '.$conf->entity.')'; $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -415,10 +415,10 @@ class dolReceiptPrinter extends Printer $error = 0; $sql = 'UPDATE '.MAIN_DB_PREFIX.'printer_receipt'; $sql .= ' SET name="'.$this->db->escape($name).'"'; - $sql .= ', fk_type='.$type; - $sql .= ', fk_profile='.$profile; + $sql .= ', fk_type='.((int) $type); + $sql .= ', fk_profile='.((int) $profile); $sql .= ', parameter="'.$this->db->escape($parameter).'"'; - $sql .= ' WHERE rowid='.$printerid; + $sql .= ' WHERE rowid='.((int) $printerid); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -438,7 +438,7 @@ class dolReceiptPrinter extends Printer global $conf; $error = 0; $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'printer_receipt'; - $sql .= ' WHERE rowid='.$printerid; + $sql .= ' WHERE rowid='.((int) $printerid); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -480,7 +480,7 @@ class dolReceiptPrinter extends Printer global $conf; $error = 0; $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'printer_receipt_template'; - $sql .= " WHERE rowid = ".((int) $this->db->escape($templateid)); + $sql .= " WHERE rowid = ".((int) $templateid); $sql .= " AND entity = ".$conf->entity; $resql = $this->db->query($sql); if (!$resql) { @@ -505,7 +505,7 @@ class dolReceiptPrinter extends Printer $sql = 'UPDATE '.MAIN_DB_PREFIX.'printer_receipt_template'; $sql .= ' SET name="'.$this->db->escape($name).'"'; $sql .= ', template="'.$this->db->escape($template).'"'; - $sql .= ' WHERE rowid='.$templateid; + $sql .= ' WHERE rowid='.((int) $templateid); $resql = $this->db->query($sql); if (!$resql) { $error++; @@ -524,6 +524,7 @@ class dolReceiptPrinter extends Printer public function sendTestToPrinter($printerid) { global $conf; + $error = 0; $img = EscposImage::load(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo_bw.png'); //$this->profile = CapabilityProfile::load("TM-T88IV"); @@ -543,7 +544,7 @@ class dolReceiptPrinter extends Printer // If is DummyPrintConnector send to log to debugging if ($this->printer->connector instanceof DummyPrintConnector) { - $data = $this->printer->connector-> getData(); + $data = $this->printer->connector->getData(); dol_syslog($data); } $this->printer->close(); @@ -899,7 +900,7 @@ class dolReceiptPrinter extends Printer public function initPrinter($printerid) { global $conf; - if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { + if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { $this->connector = new DummyPrintConnector(); $this->printer = new Printer($this->connector, $this->profile); return; @@ -934,8 +935,8 @@ class dolReceiptPrinter extends Printer $parameters = explode(':', $parameter); $this->connector = new NetworkPrintConnector($parameters[0], $parameters[1]); break; - case 4: - $this->connector = new WindowsPrintConnector($parameter); + case 4: // LPT1, smb://... + $this->connector = new WindowsPrintConnector(dol_sanitizePathName($parameter)); break; case 5: $this->connector = new CupsPrintConnector($parameter); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index b4d7f1a74df..54d812aeafb 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -936,7 +936,7 @@ class ExtraFields $this->attribute_computed[$tab->name] = $tab->fieldcomputed; $this->attribute_unique[$tab->name] = $tab->fieldunique; $this->attribute_required[$tab->name] = $tab->fieldrequired; - $this->attribute_param[$tab->name] = ($tab->param ? unserialize($tab->param) : ''); + $this->attribute_param[$tab->name] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); $this->attribute_pos[$tab->name] = $tab->pos; $this->attribute_alwayseditable[$tab->name] = $tab->alwayseditable; $this->attribute_perms[$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms); @@ -954,7 +954,7 @@ class ExtraFields $this->attributes[$tab->elementtype]['computed'][$tab->name] = $tab->fieldcomputed; $this->attributes[$tab->elementtype]['unique'][$tab->name] = $tab->fieldunique; $this->attributes[$tab->elementtype]['required'][$tab->name] = $tab->fieldrequired; - $this->attributes[$tab->elementtype]['param'][$tab->name] = ($tab->param ? unserialize($tab->param) : ''); + $this->attributes[$tab->elementtype]['param'][$tab->name] = ($tab->param ? jsonOrUnserialize($tab->param) : ''); $this->attributes[$tab->elementtype]['pos'][$tab->name] = $tab->pos; $this->attributes[$tab->elementtype]['alwayseditable'][$tab->name] = $tab->alwayseditable; $this->attributes[$tab->elementtype]['perms'][$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 0b1504d229a..048fbb0cad3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -589,6 +589,7 @@ class Form if (!$htmltext) { return $text; } + $direction = (int) $direction; // For backward compatibility when $direction was set to '' instead of 0 $tag = 'td'; if ($notabs == 2) { @@ -1251,6 +1252,9 @@ class Form if (is_null($ajaxoptions)) { $ajaxoptions = array(); } + + require_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + // No immediate load of all database $placeholder = ''; if ($selected && empty($selected_input_value)) { @@ -2176,7 +2180,7 @@ class Form * * @param int $selected Preselected products * @param string $htmlname Name of HTML select field (must be unique in page). - * @param int $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param int|string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) * @param int $limit Limit on number of returned lines * @param int $price_level Level of price to show * @param int $status Sell status -1=Return all products, 0=Products not on sell, 1=Products on sell @@ -2604,7 +2608,7 @@ class Form } } if ($showempty) { - $out .= ''; + $out .= ''; } $i = 0; diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index 411b45e03a7..8e03f158a02 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -393,9 +393,10 @@ class FormAdmin * @param string $htmlname Name of HTML select field * @param string $filter Value to filter on code * @param int $showempty Add empty value + * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) * @return string Return HTML output */ - public function select_paper_format($selected = '', $htmlname = 'paperformat_id', $filter = 0, $showempty = 0) + public function select_paper_format($selected = '', $htmlname = 'paperformat_id', $filter = 0, $showempty = 0, $forcecombo = 0) { // phpcs:enable global $langs; @@ -444,6 +445,11 @@ class FormAdmin } $out .= ''; + if (!$forcecombo) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + $out .= ajax_combobox($htmlname); + } + return $out; } } diff --git a/htdocs/core/class/html.formintervention.class.php b/htdocs/core/class/html.formintervention.class.php index 7058e80b1d7..b9564c6aa52 100644 --- a/htdocs/core/class/html.formintervention.class.php +++ b/htdocs/core/class/html.formintervention.class.php @@ -57,10 +57,11 @@ class FormIntervention * @param int $selected Id intervention preselected * @param string $htmlname Nom de la zone html * @param int $maxlength Maximum length of label - * @param int $showempty Show empty line + * @param int $showempty Show empty line ('1' or string to show for empty line) + * @param int $draftonly Show only drafts intervention * @return int Nbre of project if OK, <0 if KO */ - public function select_interventions($socid = -1, $selected = '', $htmlname = 'interventionid', $maxlength = 16, $showempty = 1) + public function select_interventions($socid = -1, $selected = '', $htmlname = 'interventionid', $maxlength = 16, $showempty = 1, $draftonly = false) { // phpcs:enable global $db, $user, $conf, $langs; @@ -80,13 +81,17 @@ class FormIntervention $sql .= " AND f.fk_soc = ".((int) $socid); } } + if ($draftonly) $sql .= " AND f.fk_statut = 0"; dol_syslog(get_class($this)."::select_intervention", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $out .= ''; } - $stringtoprint .= ' '; + $stringtoprint .= ' '; + $levelid = 1; while ($levelid <= $use_multilevel) { $tabscript = array(); @@ -741,7 +742,7 @@ class FormTicket $iselected = $groupticketchild == $obj->code ?'selected':''; $stringtoprint .= ''; if (empty($tabscript[$groupcodefather])) { - $tabscript[$groupcodefather] = 'if($("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid-1:'').'")[0].value == "'.dol_escape_js($groupcodefather).'"){ + $tabscript[$groupcodefather] = 'if ($("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid-1:'').'")[0].value == "'.dol_escape_js($groupcodefather).'"){ $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").show() console.log("We show childs tickets of '.$groupcodefather.' group ticket") }else{ @@ -756,23 +757,31 @@ class FormTicket dol_print_error($this->db); } $stringtoprint .=''; + //$stringtoprint .= ajax_combobox($htmlname.'_child_'.$levelid); $stringtoprint .=''; } + $stringtoprint .= ajax_combobox($htmlname); + return $stringtoprint; } } diff --git a/htdocs/core/commonfieldsinexport.inc.php b/htdocs/core/commonfieldsinexport.inc.php index a02a21afdd6..3b201e4f10a 100644 --- a/htdocs/core/commonfieldsinexport.inc.php +++ b/htdocs/core/commonfieldsinexport.inc.php @@ -37,7 +37,7 @@ if (class_exists($keyforclass)) { /* * case 'sellist': * $tmp=''; - * $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + * $tmpparam=jsonOrUnserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null * if ($tmpparam['options'] && is_array($tmpparam['options'])) { * $tmpkeys=array_keys($tmpparam['options']); * $tmp=array_shift($tmpkeys); diff --git a/htdocs/core/extrafieldsinexport.inc.php b/htdocs/core/extrafieldsinexport.inc.php index 861ef142c25..70dd0077e57 100644 --- a/htdocs/core/extrafieldsinexport.inc.php +++ b/htdocs/core/extrafieldsinexport.inc.php @@ -39,7 +39,7 @@ if ($resql) { // This can fail when class is used on old database (during mig case 'checkbox': case 'select': if (!empty($conf->global->EXPORT_LABEL_FOR_SELECT)) { - $tmpparam = unserialize($obj->param); // $tmpparam may be array with 'options' = array(key1=>val1, key2=>val2 ...) + $tmpparam = jsonOrUnserialize($obj->param); // $tmpparam may be array with 'options' = array(key1=>val1, key2=>val2 ...) if ($tmpparam['options'] && is_array($tmpparam['options'])) { $typeFilter = "Select:".$obj->param; } @@ -47,7 +47,7 @@ if ($resql) { // This can fail when class is used on old database (during mig break; case 'sellist': $tmp = ''; - $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + $tmpparam = jsonOrUnserialize($obj->param); // $tmp may be array 'options' => array 'c_currencies:code_iso:code_iso' => null if ($tmpparam['options'] && is_array($tmpparam['options'])) { $tmpkeys = array_keys($tmpparam['options']); $tmp = array_shift($tmpkeys); diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index dce74d93653..764fde5097e 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -47,6 +47,11 @@ session_cache_limiter('public'); require_once '../../main.inc.php'; + +/* + * View + */ + // Define javascript type top_httphead('text/javascript; charset=UTF-8'); // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index a56084d0f32..db63b1a75d4 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -50,6 +50,11 @@ session_cache_limiter('public'); require_once '../../main.inc.php'; + +/* + * View + */ + // Define javascript type top_httphead('text/javascript; charset=UTF-8'); // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. diff --git a/htdocs/core/js/lib_notification.js.php b/htdocs/core/js/lib_notification.js.php index dc46a5e2072..616463b944d 100644 --- a/htdocs/core/js/lib_notification.js.php +++ b/htdocs/core/js/lib_notification.js.php @@ -41,132 +41,147 @@ if (!defined('NOREQUIREHTML')) { define('NOREQUIREHTML', 1); } +session_cache_limiter('public'); + require_once '../../main.inc.php'; -if (!($_SERVER['HTTP_REFERER'] === $dolibarr_main_url_root.'/' || $_SERVER['HTTP_REFERER'] === $dolibarr_main_url_root.'/index.php' - || preg_match('/getmenu_div\.php/', $_SERVER['HTTP_REFERER']))) { - global $langs, $conf; - top_httphead('text/javascript; charset=UTF-8'); +/* + * View + */ - print 'var login = \''.$_SESSION['dol_login'].'\';'."\n"; - print 'var nowtime = Date.now();'; - print 'var time_auto_update = '.$conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY.';'."\n"; // Always defined - print 'var time_js_next_test;'."\n"; - ?> - - /* Check if permission ok */ - if (Notification.permission !== "granted") { - console.log("Ask Notification.permission"); - Notification.requestPermission() - } - - /* Launch timer */ - // We set a delay before launching first test so next check will arrive after the time_auto_update compared to previous one. - //var time_first_execution = (time_auto_update + (time_js_next_test - nowtime)) * 1000; //need milliseconds - var time_first_execution = global->MAIN_BROWSER_NOTIFICATION_CHECK_FIRST_EXECUTION) ? 0 : $conf->global->MAIN_BROWSER_NOTIFICATION_CHECK_FIRST_EXECUTION); ?>; - if (login != '') { - setTimeout(first_execution, time_first_execution * 1000); - time_js_next_test = nowtime + time_first_execution; - console.log("Launch browser notif check: setTimeout is set to launch 'first_execution' function after a wait of time_first_execution="+time_first_execution+". nowtime (time php page generation) = "+nowtime+" time_js_next_check = "+time_js_next_test); - } //first run auto check +top_httphead('text/javascript; charset=UTF-8'); +// Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. +if (empty($dolibarr_nocache)) { + header('Cache-Control: max-age=10800, public, must-revalidate'); +} else { + header('Cache-Control: no-cache'); +} - function first_execution() { - console.log("Call first_execution then set repeat time to time_auto_update = MAIN_BROWSER_NOTIFICATION_FREQUENCY = "+time_auto_update); - check_events(); //one check before setting the new time for other checks - setInterval(check_events, time_auto_update * 1000); // Set new time to run next check events - } +print "jQuery(document).ready(function () {\n"; - function check_events() { - if (Notification.permission === "granted") - { - time_js_next_test += time_auto_update; - console.log("Call ajax to check_events with time_js_next_test = "+time_js_next_test); +//print " console.log('referrer=".dol_escape_js($_SERVER['HTTP_REFERER'])."');\n"; - $.ajax("", { - type: "post", // Usually post or get - async: true, - data: { time_js_next_test: time_js_next_test, forcechecknow: 1, token: 'notrequired' }, - dataType: "json", - success: function (result) { - //console.log(result); - var arrayofpastreminders = Object.values(result.pastreminders); - if (arrayofpastreminders && arrayofpastreminders.length > 0) { - console.log("Retrieved "+arrayofpastreminders.length+" reminders to do."); - var audio = null; - global->AGENDA_REMINDER_BROWSER_SOUND)) { - print 'audio = new Audio(\''.DOL_URL_ROOT.'/theme/common/sound/notification_agenda.wav\');'; +print ' var nowtime = Date.now();'; +print ' var time_auto_update = '.$conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY.';'."\n"; // Always defined +print ' var time_js_next_test;'."\n"; +?> + +/* Check if permission ok */ +if (Notification.permission !== "granted") { + console.log("Ask Notification.permission"); + Notification.requestPermission() +} + +/* Launch timer */ + +// We set a delay before launching first test so next check will arrive after the time_auto_update compared to previous one. +//var time_first_execution = (time_auto_update + (time_js_next_test - nowtime)) * 1000; //need milliseconds +var time_first_execution = global->MAIN_BROWSER_NOTIFICATION_CHECK_FIRST_EXECUTION) ? 0 : $conf->global->MAIN_BROWSER_NOTIFICATION_CHECK_FIRST_EXECUTION); ?>; + +setTimeout(first_execution, time_first_execution * 1000); +time_js_next_test = nowtime + time_first_execution; +console.log("Launch browser notif check: setTimeout is set to launch 'first_execution' function after a wait of time_first_execution="+time_first_execution+". nowtime (time php page generation) = "+nowtime+" time_js_next_check = "+time_js_next_test); + + +function first_execution() { + console.log("Call first_execution then set repeat time to time_auto_update = MAIN_BROWSER_NOTIFICATION_FREQUENCY = "+time_auto_update); + check_events(); //one check before setting the new time for other checks + setInterval(check_events, time_auto_update * 1000); // Set new time to run next check events +} + +function check_events() { + if (Notification.permission === "granted") + { + time_js_next_test += time_auto_update; + console.log("Call ajax to check_events with time_js_next_test = "+time_js_next_test); + + $.ajax("", { + type: "post", // Usually post or get + async: true, + data: { time_js_next_test: time_js_next_test, forcechecknow: 1, token: 'notrequired' }, + dataType: "json", + success: function (result) { + //console.log(result); + var arrayofpastreminders = Object.values(result.pastreminders); + if (arrayofpastreminders && arrayofpastreminders.length > 0) { + console.log("Retrieved "+arrayofpastreminders.length+" reminders to do."); + var audio = null; + global->AGENDA_REMINDER_BROWSER_SOUND)) { + print 'audio = new Audio(\''.DOL_URL_ROOT.'/theme/common/sound/notification_agenda.wav\');'; + } + ?> + var listofreminderids = ''; + var noti = [] + + $.each(arrayofpastreminders, function (index, value) { + console.log(value); + var url = "notdefined"; + var title = "Not defined"; + var body = value.label; + if (value.type == 'agenda' && value.location != null && value.location != '') { + body += '\n' + value.location; } - ?> - var listofreminderids = ''; - var noti = [] - $.each(arrayofpastreminders, function (index, value) { - console.log(value); - var url = "notdefined"; - var title = "Not defined"; - var body = value.label; - if (value.type == 'agenda' && value.location != null && value.location != '') { - body += '\n' + value.location; - } + if (value.type == 'agenda' && (value.event_date_start_formated != null || value.event_date_start_formated['event_date_start'] != '')) { + body += '\n' + value.event_date_start_formated; + } - if (value.type == 'agenda' && (value.event_date_start_formated != null || value.event_date_start_formated['event_date_start'] != '')) { - body += '\n' + value.event_date_start_formated; - } + if (value.type == 'agenda') + { + url = '' + value.id_agenda; + title = 'trans('EventReminder')) ?>'; + } + var extra = { + icon: '', + //image: '', + body: body, + tag: value.id_agenda, + requireInteraction: true + }; - if (value.type == 'agenda') - { - url = '' + value.id_agenda; - title = 'trans('EventReminder')) ?>'; - } - var extra = { - icon: '', - //image: '', - body: body, - tag: value.id_agenda, - requireInteraction: true + // We release the notify + console.log("Send notification on browser"); + noti[index] = new Notification(title, extra); + if (index==0 && audio) + { + audio.play(); + } + + if (noti[index]) { + noti[index].onclick = function (event) { + console.log("A click on notification on browser has been done"); + event.preventDefault(); // prevent the browser from focusing the Notification's tab + window.focus(); + window.open(url, '_blank'); + noti[index].close(); }; - // We release the notify - console.log("Send notification on browser"); - noti[index] = new Notification(title, extra); - if (index==0 && audio) - { - audio.play(); - } + listofreminderids = (listofreminderids == '' ? '' : listofreminderids + ',') + value.id_reminder + } + }); - if (noti[index]) { - noti[index].onclick = function (event) { - console.log("A click on notification on browser has been done"); - event.preventDefault(); // prevent the browser from focusing the Notification's tab - window.focus(); - window.open(url, '_blank'); - noti[index].close(); - }; - - listofreminderids = (listofreminderids == '' ? '' : listofreminderids + ',') + value.id_reminder - } - }); - - // Update status of all notifications we sent on browser (listofreminderids) - console.log("Flag notification as done for listofreminderids="+listofreminderids); - $.ajax(""+listofreminderids, { - type: "POST", // Usually post or get - async: true, - data: { time_js_next_test: time_js_next_test, token: 'notrequired' } - }); - } else { - console.log("No reminder to do found, next search at "+time_js_next_test); - } + // Update status of all notifications we sent on browser (listofreminderids) + console.log("Flag notification as done for listofreminderids="+listofreminderids); + $.ajax(""+listofreminderids, { + type: "POST", // Usually post or get + async: true, + data: { time_js_next_test: time_js_next_test, token: 'notrequired' } + }); + } else { + console.log("No reminder to do found, next search at "+time_js_next_test); } - }); - } - else - { - console.log("Cancel check_events. Useless because javascript Notification.permission is "+Notification.permission+" (blocked manualy or web site is not https)."); - } + } + }); + } + else + { + console.log("Cancel check_events. Useless because javascript Notification.permission is "+Notification.permission+" (blocked manualy or web site is not https)."); } - global->MAIN_RESTRICTHTML_ONLY_VALID_HTML) && $check != 'restricthtmlallowunvalid') { + try { + $dom = new DOMDocument; + // Add a trick to solve pb with text without parent tag + // like '

Foo

bar

' that ends up with '

Foo

bar

' + // like 'abc' that ends up with '

abc

' + $out = '
'.$out.'
'; + + $dom->loadHTML($out, LIBXML_ERR_NONE|LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOXMLDECL); + $out = trim($dom->saveHTML()); + + // Remove the trick added to solve pb with text without parent tag + $out = preg_replace('/^
/', '', $out); + $out = preg_replace('/<\/div>$/', '', $out); + } catch (Exception $e) { + //print $e->getMessage(); + return 'InvalidHTMLString'; + } + } + + // Ckeditor use the numeric entitic for apostrophe so we force it to text entity (all other special chars are correctly + // encoded using text entities). This is a fix for CKeditor (CKeditor still encode in HTML4 instead of HTML5). + $out = preg_replace('/'/i', ''', $out); + // We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step. // No need to use a loop here, this step is not to sanitize (this is done at next step, this is to try to save chars, even if they are // using a non coventionnel way to be encoded, to not have them sanitized just after) $out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', 'realCharForNumericEntities', $out); - // Now we remove all remaining HTML entities staring with a number. We don't want such entities. + // Now we remove all remaining HTML entities starting with a number. We don't want such entities. $out = preg_replace('/&#x?[0-9]+/i', '', $out); // For example if we have javascript with an entities without the ; to hide the 'a' of 'javascript'. $out = dol_string_onlythesehtmltags($out, 0, 1, 1); // We should also exclude non expected attributes if (!empty($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)) { - $out = dol_string_onlythesehtmlattributes($out); + // Warning, the function may add a LF so we are forced to trim to compare with old $out without having always a difference and an infinit loop. + $out = trim(dol_string_onlythesehtmlattributes($out)); } } while ($oldstringtoclean != $out); break; @@ -993,7 +1019,7 @@ function dol_buildpath($path, $type = 0, $returnemptyifnotfound = 0) function dol_clone($object, $native = 0) { if (empty($native)) { - $myclone = unserialize(serialize($object)); + $myclone = unserialize(serialize($object)); // serialize then unserialize is hack to be sure to have a new object for all fields } else { $myclone = clone $object; // PHP clone is a shallow copy only, not a real clone, so properties of references will keep the reference (refering to the same target/variable) } @@ -1025,10 +1051,11 @@ function dol_size($size, $type = '') /** - * Clean a string to use it as a file name + * Clean a string to use it as a file name. + * Replace also '--' and ' -' strings, they are used for parameters separation. * * @param string $str String to clean - * @param string $newstr String to replace bad chars with + * @param string $newstr String to replace bad chars with. * @param int $unaccent 1=Remove also accent (default), 0 do not remove them * @return string String cleaned (a-zA-Z_) * @@ -1040,12 +1067,16 @@ function dol_sanitizeFileName($str, $newstr = '_', $unaccent = 1) // Char '>' '<' '|' '$' and ';' are special chars for shells. // Char '/' and '\' are file delimiters. // -- car can be used into filename to inject special paramaters like --use-compress-program to make command with file as parameter making remote execution of command - $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', ':', '°', '$', ';', '--'); - return dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); + $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', ':', '°', '$', ';'); + $tmp = dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); + $tmp = preg_replace('/\-\-+/', '_', $tmp); + $tmp = preg_replace('/\s+\-/', ' _', $tmp); + return $tmp; } /** - * Clean a string to use it as a path name + * Clean a string to use it as a path name. + * Replace also '--' and ' -' strings, they are used for parameters separation. * * @param string $str String to clean * @param string $newstr String to replace bad chars with @@ -1057,7 +1088,10 @@ function dol_sanitizeFileName($str, $newstr = '_', $unaccent = 1) function dol_sanitizePathName($str, $newstr = '_', $unaccent = 1) { $filesystem_forbidden_chars = array('<', '>', '?', '*', '|', '"', '°'); - return dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); + $tmp = dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); + $tmp = preg_replace('/\-\-+/', '_', $tmp); + $tmp = preg_replace('/\s+\-/', ' _', $tmp); + return $tmp; } /** @@ -1153,21 +1187,26 @@ function dol_string_unaccent($str) * Clean a string from all punctuation characters to use it as a ref or login. * This is a more complete function than dol_sanitizeFileName. * - * @param string $str String to clean - * @param string $newstr String to replace forbidden chars with - * @param array $badcharstoreplace List of forbidden characters - * @return string Cleaned string + * @param string $str String to clean + * @param string $newstr String to replace forbidden chars with + * @param array|string $badcharstoreplace List of forbidden characters to replace + * @param array|string $badcharstoremove List of forbidden characters to remove + * @return string Cleaned string * * @see dol_sanitizeFilename(), dol_string_unaccent(), dol_string_nounprintableascii() */ -function dol_string_nospecial($str, $newstr = '_', $badcharstoreplace = '') +function dol_string_nospecial($str, $newstr = '_', $badcharstoreplace = '', $badcharstoremove = '') { $forbidden_chars_to_replace = array(" ", "'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ",", ";", "=", '°'); // more complete than dol_sanitizeFileName $forbidden_chars_to_remove = array(); + //$forbidden_chars_to_remove=array("(",")"); + if (is_array($badcharstoreplace)) { $forbidden_chars_to_replace = $badcharstoreplace; } - //$forbidden_chars_to_remove=array("(",")"); + if (is_array($badcharstoremove)) { + $forbidden_chars_to_remove = $badcharstoremove; + } return str_replace($forbidden_chars_to_replace, $newstr, str_replace($forbidden_chars_to_remove, "", $str)); } @@ -3521,8 +3560,8 @@ 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', 'question', 'refresh', 'salary', 'shipment', - 'supplier_invoice', 'supplier_invoicea', 'supplier_invoicer', 'supplier_invoiced', + 'partnership', 'payment', 'pencil-ruler', 'preview', 'project', 'projectpub', 'projecttask', 'question', 'refresh', 'region', + 'salary', 'shipment', 'state', 'supplier_invoice', 'supplier_invoicea', 'supplier_invoicer', 'supplier_invoiced', 'technic', 'ticket', 'error', 'warning', 'recent', 'reception', 'recruitmentcandidature', 'recruitmentjobposition', 'resource', @@ -3571,8 +3610,8 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ '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', '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', + 'refresh'=>'redo', 'region'=>'map-marked', 'resource'=>'laptop-house', + 'state'=>'map-marked-alt', 'security'=>'key', 'salary'=>'wallet', 'shipment'=>'dolly', 'stock'=>'box-open', 'stats' => 'chart-bar', 'split'=>'code-branch', 'stripe'=>'stripe-s', 'supplier'=>'building', 'supplier_invoice'=>'file-invoice-dollar', 'technic'=>'cogs', 'ticket'=>'ticket-alt', 'timespent'=>'clock', 'title_setup'=>'tools', 'title_accountancy'=>'money-check-alt', 'title_bank'=>'university', 'title_hrm'=>'umbrella-beach', 'title_agenda'=>'calendar-alt', @@ -3610,13 +3649,13 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ } if (in_array($pictowithouttext, array('dollyrevert', 'member', 'members', 'contract', 'group', 'resource', 'shipment'))) { - $morecss = 'em092'; + $morecss .= ' em092'; } if (in_array($pictowithouttext, array('conferenceorbooth', 'collab', 'eventorganization', 'holiday', 'info', 'project', 'workstation'))) { - $morecss = 'em088'; + $morecss .= ' em088'; } if (in_array($pictowithouttext, array('asset', 'intervention', 'payment', 'loan', 'partnership', 'stock', 'technic'))) { - $morecss = 'em080'; + $morecss .= ' em080'; } // Define $marginleftonlyshort @@ -3673,7 +3712,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'partnership'=>'#6c6aa8', 'playdisabled'=>'#ccc', 'printer'=>'#444', 'projectpub'=>'#986c6a', 'reception'=>'#a69944', 'resize'=>'#444', 'rss'=>'#cba', //'shipment'=>'#a69944', 'security'=>'#999', 'stats'=>'#444', 'switch_off'=>'#999', 'technic'=>'#999', 'timespent'=>'#555', - 'uncheck'=>'#800', 'uparrow'=>'#555', 'user-cog'=>'#999', 'country'=>'#aaa', 'globe-americas'=>'#aaa', + 'uncheck'=>'#800', 'uparrow'=>'#555', 'user-cog'=>'#999', 'country'=>'#aaa', 'globe-americas'=>'#aaa', 'region'=>'#aaa', 'state'=>'#aaa', 'website'=>'#304', 'workstation'=>'#a69944' ); if (isset($arrayconvpictotocolor[$pictowithouttext])) { @@ -3956,7 +3995,7 @@ function img_edit($titlealt = 'default', $float = 0, $other = '') * @param string $other Add more attributes on img * @return string Return tag img */ -function img_view($titlealt = 'default', $float = 0, $other = '') +function img_view($titlealt = 'default', $float = 0, $other = 'class="valignmiddle"') { global $langs; @@ -5470,7 +5509,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer = "", $thirdparty_sell } else { $sql .= " AND t.recuperableonly = '".$db->escape($vatnpr)."'"; } - dol_syslog("get_localtax", LOG_DEBUG); + $resql = $db->query($sql); if ($resql) { @@ -6298,7 +6337,7 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1, $stringtoclean = preg_replace('/:|�+58|:/i', '', $stringtoclean); // refused string ':' encoded (no reason to have a : encoded like this) to disable 'javascript:...' $stringtoclean = preg_replace('/javascript\s*:/i', '', $stringtoclean); - $temp = strip_tags($stringtoclean, $allowed_tags_string); + $temp = strip_tags($stringtoclean, $allowed_tags_string); // Warning: This remove also undesired changing string obfuscated with that pass injection detection into harmfull string if ($cleanalsosomestyles) { // Clean for remaining html tags $temp = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/i', '', $temp); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless @@ -6348,8 +6387,8 @@ function dol_string_onlythesehtmlattributes($stringtoclean, $allowed_attributes } $return = $dom->saveHTML(); - //$return = 'aaaa

bb

ssdd

'."\n

aaa

aa

bb

"; + $return = preg_replace('/^/', '', $return); $return = preg_replace('/<\/body><\/html>$/', '', $return); return $return; @@ -7435,7 +7474,7 @@ function print_date_range($date_start, $date_end, $format = '', $outputlangs = ' * @param int $date_end End date * @param string $format Output format * @param Translate $outputlangs Output language - * @param integer $withparenthesis 1=Add parenthesis, 0=non parenthesis + * @param integer $withparenthesis 1=Add parenthesis, 0=no parenthesis * @return string String */ function get_date_range($date_start, $date_end, $format = '', $outputlangs = '', $withparenthesis = 1) @@ -8087,7 +8126,7 @@ function picto_from_langcode($codelang, $moreatt = '') } if ($codelang == 'auto') { - return ''; + return ''; } $langtocountryflag = array( @@ -10301,9 +10340,10 @@ function readfileLowMemory($fullpath_original_file_osencoded, $method = -1) */ function showValueWithClipboardCPButton($valuetocopy, $showonlyonhover = 1, $texttoshow = '') { + /* global $conf; - /*if (!empty($conf->dol_no_mouse_hover)) { + if (!empty($conf->dol_no_mouse_hover)) { $showonlyonhover = 0; }*/ @@ -10315,3 +10355,20 @@ function showValueWithClipboardCPButton($valuetocopy, $showonlyonhover = 1, $tex return $result; } + + +/** + * Decode an encode string. The string can be encoded in json format (recommended) or with serialize (avoid this) + * + * @param string $stringtodecode String to decode (json or serialize coded) + * @return mixed The decoded object. + */ +function jsonOrUnserialize($stringtodecode) +{ + $result = json_decode($stringtodecode); + if ($result === null) { + $result = unserialize($stringtodecode); + } + + return $result; +} diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 1ba9e0e3d1c..26d66ceae23 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -849,7 +849,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t // Contacts of task if (count($arrayfields) > 0 && !empty($arrayfields['c.assigned']['checked'])) { - print ''; + print ''; foreach (array('internal', 'external') as $source) { $tab = $lines[$i]->liste_contact(-1, $source); $num = count($tab); diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 523b8ccf2cb..4408e2ccd52 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -476,8 +476,8 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len } $generated_password = str_shuffle($randomCode); - } else // Old platform, non cryptographic random - { + } else { + // Old platform, non cryptographic random $max = strlen($lowercase) - 1; for ($x = 0; $x < $nbofchar; $x++) { $tmp = mt_rand(0, $max); diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index cd9ae5ad297..29f208e5254 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -906,7 +906,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) } // Use MAIN_OPTIMIZEFORTEXTBROWSER - if ($foruserprofile) { + if ($foruserprofile && !empty($fuser->conf->MAIN_OPTIMIZEFORTEXTBROWSER)) { //$default=yn($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER); $default = $langs->trans('No'); print ''; @@ -953,7 +953,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) // Use MAIN_OPTIMIZEFORTEXTBROWSER - if ($foruserprofile) { + if ($foruserprofile && !empty($fuser->conf->MAIN_OPTIMIZEFORCOLORBLIND)) { //$default=yn($conf->global->MAIN_OPTIMIZEFORCOLORBLIND); $default = $langs->trans('No'); print ''; diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 9de95be506b..0f3927709eb 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -29,7 +29,7 @@ * * @param string $usertotest Login * @param string $passwordtotest Password - * @param int $entitytotest Number of instance (always 1 if module multicompany not enabled) + * @param int $entitytotest Numero of instance (always 1 if module multicompany not enabled) * @return string Login if OK, '' if KO */ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) @@ -151,10 +151,13 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) if ($result > 0) { if ($result == 2) { // Connection is ok for user/pass into LDAP $login = $usertotest; - if (!empty($conf->global->LDAP_FIELD_LOGIN)) { - $login = $ldap->login; - } dol_syslog("functions_ldap::check_user_password_ldap $login authentication ok"); + // For the case, we search the user id using a search key without the login (but using other fields like id), + // we need to get the real login to use in the ldap answer. + if (!empty($conf->global->LDAP_FIELD_LOGIN) && !empty($ldap->login)) { + $login = $ldap->login; + dol_syslog("functions_ldap::check_user_password_ldap login is now $login (LDAP_FIELD_LOGIN=".$conf->global->LDAP_FIELD_LOGIN.")"); + } require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; @@ -207,7 +210,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) } $usertmp = new User($db); - $resultFetchUser = $usertmp->fetch('', $login, $sid); + $resultFetchUser = $usertmp->fetch('', $login, $sid, 1, ($entitytotest > 0 ? $entitytotest : -1)); if ($resultFetchUser > 0) { dol_syslog("functions_ldap::check_user_password_ldap Sync user found user id=".$usertmp->id); // On verifie si le login a change et on met a jour les attributs dolibarr @@ -215,7 +218,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) if ($usertmp->login != $ldap->login && $ldap->login) { $usertmp->login = $ldap->login; $usertmp->update($usertmp); - // TODO Que faire si update echoue car on update avec un login deja existant. + // TODO Que faire si update echoue car on update avec un login deja existant pour un autre compte. } //$resultUpdate = $usertmp->update_ldap2dolibarr($ldap); @@ -231,7 +234,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) $usertmp->fetch('', $login); $ret = $mc->checkRight($usertmp->id, $entitytotest); if ($ret < 0) { - dol_syslog("functions_ldap::check_user_password_ldap Authentication KO entity '".$entitytotest."' not allowed for user '".$usertmp->id."'", LOG_NOTICE); + dol_syslog("functions_ldap::check_user_password_ldap Authentication KO entity '".$entitytotest."' not allowed for user id '".$usertmp->id."'", LOG_NOTICE); $login = ''; // force authentication failure } unset($usertmp); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 90de417c767..c192d5e6ac6 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1797,11 +1797,11 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $newmenu->add("/holiday/card.php?mainmenu=hrm&leftmenu=holiday&action=create", $langs->trans("New"), 1, $user->rights->holiday->write); $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->holiday->read); if ($usemenuhider || empty($leftmenu) || $leftmenu == "hrm") { - $newmenu->add("/holiday/list.php?search_statut=1&mainmenu=hrm&leftmenu=hrm", $langs->trans("DraftCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_statut=2&mainmenu=hrm&leftmenu=hrm", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_statut=3&mainmenu=hrm&leftmenu=hrm", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_statut=4&mainmenu=hrm&leftmenu=hrm", $langs->trans("CancelCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_statut=5&mainmenu=hrm&leftmenu=hrm", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=1&mainmenu=hrm&leftmenu=hrm", $langs->trans("DraftCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=2&mainmenu=hrm&leftmenu=hrm", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=3&mainmenu=hrm&leftmenu=hrm", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=4&mainmenu=hrm&leftmenu=hrm", $langs->trans("CancelCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=5&mainmenu=hrm&leftmenu=hrm", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read); } $newmenu->add("/holiday/define_holiday.php?mainmenu=hrm&action=request", $langs->trans("MenuConfCP"), 1, $user->rights->holiday->read); $newmenu->add("/holiday/month_report.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("MenuReportMonth"), 1, $user->rights->holiday->readall); diff --git a/htdocs/core/modules/export/export_csv.modules.php b/htdocs/core/modules/export/export_csv.modules.php index 2d15f3999d0..88ae937bb6d 100644 --- a/htdocs/core/modules/export/export_csv.modules.php +++ b/htdocs/core/modules/export/export_csv.modules.php @@ -277,8 +277,8 @@ class ExportCsv extends ModeleExports $newvalue = $this->csvClean($newvalue, $outputlangs->charset_output); - if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7)) { - $array = unserialize($typefield); + if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) { + $array = json_decode($typefield, true); $array = $array['options']; $newvalue = $array[$newvalue]; } diff --git a/htdocs/core/modules/export/export_excel2007.modules.php b/htdocs/core/modules/export/export_excel2007.modules.php index 370fc49df7e..54842ff8278 100644 --- a/htdocs/core/modules/export/export_excel2007.modules.php +++ b/htdocs/core/modules/export/export_excel2007.modules.php @@ -315,8 +315,8 @@ class ExportExcel2007 extends ModeleExports $newvalue = $this->excel_clean($newvalue); $typefield = isset($array_types[$code]) ? $array_types[$code] : ''; - if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7)) { - $array = unserialize($typefield); + if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) { + $array = json_decode($typefield, true); $array = $array['options']; $newvalue = $array[$newvalue]; } diff --git a/htdocs/core/modules/export/export_tsv.modules.php b/htdocs/core/modules/export/export_tsv.modules.php index c93787a762c..7718dd3e350 100644 --- a/htdocs/core/modules/export/export_tsv.modules.php +++ b/htdocs/core/modules/export/export_tsv.modules.php @@ -252,8 +252,8 @@ class ExportTsv extends ModeleExports $newvalue = $this->tsv_clean($newvalue, $outputlangs->charset_output); - if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7)) { - $array = unserialize($typefield); + if (preg_match('/^Select:/i', $typefield) && $typefield = substr($typefield, 7)) { + $array = json_decode($typefield, true); $array = $array['options']; $newvalue = $array[$newvalue]; } diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 1768029b97e..6bec94d6130 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -623,6 +623,12 @@ class ImportCsv extends ModeleImports } } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'numeric') { $newval = price2num($newval); + } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'accountingaccount') { + if (empty($conf->global->ACCOUNTING_MANAGE_ZERO)) { + $newval = rtrim(trim($newval), "0"); + } else { + $newval = trim($newval); + } } //print 'Val to use as insert is '.$newval.'
'; diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index d90a52755e3..0378180475d 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -664,6 +664,12 @@ class ImportXlsx extends ModeleImports } } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'numeric') { $newval = price2num($newval); + } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'accountingaccount') { + if (empty($conf->global->ACCOUNTING_MANAGE_ZERO)) { + $newval = rtrim(trim($newval), "0"); + } else { + $newval = trim($newval); + } } //print 'Val to use as insert is '.$newval.'
'; diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 21618c56bc9..e0bf3a9bbc5 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -60,7 +60,7 @@ class modAccounting extends DolibarrModules $this->dirs = array('/accounting/temp'); // Config pages - $this->config_page_url = array('accounting.php'); + $this->config_page_url = array('accounting.php?mainmenu=accountancy&leftmenu=accountancy_admin'); // Dependencies $this->depends = array("modFacture", "modBanque", "modTax"); // List of modules id that must be enabled if this module is enabled @@ -297,6 +297,10 @@ class modAccounting extends DolibarrModules ); $this->import_fieldshidden_array[$r] = array('b.doc_type'=>'const-import_from_external', 'b.fk_doc'=>'const-0', 'b.fk_docdet'=>'const-0', 'b.fk_user_author'=>'user->id', 'b.date_creation'=>'const-'.dol_print_date(dol_now(), 'standard')); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) $this->import_regex_array[$r] = array('b.doc_date'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'); + $this->import_convertvalue_array[$r] = array( + 'b.numero_compte' => array('rule' => 'accountingaccount'), + 'b.subledger_account' => array('rule' => 'accountingaccount') + ); $this->import_examplevalues_array[$r] = array( 'b.piece_num'=>'123 (!!! use next value not already used)', 'b.doc_date'=>dol_print_date(dol_now(), "%Y-%m-%d"), @@ -350,6 +354,8 @@ class modAccounting extends DolibarrModules 'b.sens'=>'rule-computeSens' ); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) $this->import_convertvalue_array[$r]=array( + 'b.numero_compte'=>array('rule'=>'accountingaccount'), + 'b.subledger_account'=>array('rule'=>'accountingaccount'), 'b.montant' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeAmount', 'element' => 'Accountancy'), 'b.sens' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeDirection', 'element' => 'Accountancy'), ); @@ -395,6 +401,7 @@ class modAccounting extends DolibarrModules $this->import_fields_array[$r] = array('aa.fk_pcg_version'=>"Chartofaccounts*", 'aa.account_number'=>"AccountAccounting*", 'aa.label'=>"Label*", 'aa.account_parent'=>"Accountparent", "aa.fk_accounting_category"=>"AccountingCategory", "aa.pcg_type"=>"Pcgtype*", 'aa.active'=>'Status*', 'aa.datec'=>"DateCreation"); $this->import_regex_array[$r] = array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system', 'aa.account_number'=>'^.{1,32}$', 'aa.label'=>'^.{1,255}$', 'aa.account_parent'=>'^.{0,32}$', 'aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category', 'aa.pcg_type'=>'^.{1,20}$', 'aa.active'=>'^0|1$', 'aa.datec'=>'^\d{4}-\d{2}-\d{2}$'); $this->import_convertvalue_array[$r] = array( + 'aa.account_number'=>array('rule'=>'accountingaccount'), 'aa.account_parent'=>array('rule'=>'fetchidfromref', 'classfile'=>'/accountancy/class/accountingaccount.class.php', 'class'=>'AccountingAccount', 'method'=>'fetch', 'element'=>'AccountingAccount'), 'aa.fk_accounting_category'=>array('rule'=>'fetchidfromcodeorlabel', 'classfile'=>'/accountancy/class/accountancycategory.class.php', 'class'=>'AccountancyCategory', 'method'=>'fetch', 'dict'=>'DictionaryAccountancyCategory'), ); diff --git a/htdocs/core/modules/modClickToDial.class.php b/htdocs/core/modules/modClickToDial.class.php index f28659bbd5d..18f1e6befeb 100644 --- a/htdocs/core/modules/modClickToDial.class.php +++ b/htdocs/core/modules/modClickToDial.class.php @@ -18,7 +18,7 @@ /** * \defgroup clicktodial Module clicktodial - * \brief Module pour gerer l'appel automatique + * \brief Module to manage a ClickToDial system * \file htdocs/core/modules/modClickToDial.class.php * \ingroup clicktodial * \brief Description and activation file for the module Click to Dial @@ -46,7 +46,8 @@ class modClickToDial extends DolibarrModules $this->family = "interface"; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i', '', get_class($this)); - $this->description = "Gestion du Click To Dial"; + $this->description = "Integration of a ClickToDial system (Asterisk, ...)"; + $this->descriptionlong = "Support a Click To Dial feature with a SIP system. When clicking on a phone number, your phone system automatically call the callee."; $this->version = 'dolibarr'; // 'development' or 'experimental' or 'dolibarr' or version diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 41107d5c34a..5d71a5abdc8 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -285,7 +285,7 @@ class modFournisseur extends DolibarrModules $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'Vendor invoices and lines of invoices'; - $this->export_icon[$r] = 'bill'; + $this->export_icon[$r] = 'invoice'; $this->export_permission[$r] = array(array("fournisseur", "facture", "export")); $this->export_fields_array[$r] = array( 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 'ps.nom'=>'ParentCompany', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'c.code'=>'CountryCode', 's.phone'=>'Phone', @@ -328,81 +328,14 @@ class modFournisseur extends DolibarrModules ); $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) { // This can fail when class is used on old database (during migration for example) - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $tmp = ''; - $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) { - $var = array_keys($tmpparam['options']); - $tmp = array_shift($var); - } - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { - $typeFilter = "List:".$tmp; - } - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'invoice'; - } - } - // End add extra fields - // Add extra fields line - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) { // This can fail when class is used on old database (during migration for example) - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extraline.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $tmp = ''; - $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) { - $tmp = array_shift(array_keys($tmpparam['options'])); - } - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { - $typeFilter = "List:".$tmp; - } - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'invoice_line'; - } - } + $keyforselect = 'facture_fourn'; + $keyforelement = 'invoice'; + $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $keyforselect = 'facture_fourn_det'; + $keyforelement = 'invoice_line'; + $keyforaliasextra = 'extraline'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // End add extra fields line $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; @@ -426,7 +359,7 @@ class modFournisseur extends DolibarrModules $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'Factures fournisseurs et reglements'; - $this->export_icon[$r] = 'bill'; + $this->export_icon[$r] = 'invoice'; $this->export_permission[$r] = array(array("fournisseur", "facture", "export")); $this->export_fields_array[$r] = array( 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'c.code'=>'CountryCode', 's.phone'=>'Phone', @@ -465,43 +398,10 @@ class modFournisseur extends DolibarrModules 'p.datep'=>'payment', 'p.num_paiement'=>'payment', 'p.fk_bank'=>'account', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project'); $this->export_dependencies_array[$r] = array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) { // This can fail when class is used on old database (during migration for example) - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $tmp = ''; - $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) { - $array_keys = array_keys($tmpparam['options']); - $tmp = array_shift($array_keys); - } - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { - $typeFilter = "List:".$tmp; - } - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'invoice'; - } - } + $keyforselect = 'facture_fourn'; + $keyforelement = 'invoice'; + $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // End add extra fields object $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; @@ -564,83 +464,16 @@ class modFournisseur extends DolibarrModules ); $this->export_dependencies_array[$r] = array('order_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) { // This can fail when class is used on old database (during migration for example) - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $tmp = ''; - $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - $tmpkey = array_keys($tmpparam['options']); - if ($tmpparam['options'] && is_array($tmpparam['options'])) { - $tmp = array_shift($tmpkey); - } - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { - $typeFilter = "List:".$tmp; - } - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'order'; - } - } + $keyforselect = 'commande_fournisseur'; + $keyforelement = 'order'; + $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // End add extra fields object // Add extra fields line - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) { // This can fail when class is used on old database (during migration for example) - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extraline.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $tmp = ''; - $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - - if ($tmpparam['options'] && is_array($tmpparam['options'])) { - $tmpparam_param_key = array_keys($tmpparam['options']); - $tmp = array_shift($tmpparam_param_key); - } - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { - $typeFilter = "List:".$tmp; - } - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'order_line'; - } - } + $keyforselect = 'commande_fournisseurdet'; + $keyforelement = 'order_line'; + $keyforaliasextra = 'extraline'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // End add extra fields line $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 3459973a699..3caf5db88c6 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -322,7 +322,7 @@ class modProduct extends DolibarrModules $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = "ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r] = array(array("produit", "export")); - $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref", + $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref", 'p.label'=>"Label", 'pr.price_base_type'=>"PriceBase", 'pr.price_level'=>"PriceLevel", 'pr.price'=>"PriceLevelUnitPriceHT", 'pr.price_ttc'=>"PriceLevelUnitPriceTTC", 'pr.price_min'=>"MinPriceLevelUnitPriceHT", 'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", @@ -337,7 +337,7 @@ class modProduct extends DolibarrModules // 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", // 'p.datec'=>'Date','p.tms'=>'Date' //); - $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product", + $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product", 'p.label'=>"Label", 'pr.price_base_type'=>"product", 'pr.price_level'=>"product", 'pr.price'=>"product", 'pr.price_ttc'=>"product", 'pr.price_min'=>"product", 'pr.price_min_ttc'=>"product", @@ -348,6 +348,8 @@ class modProduct extends DolibarrModules $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile + $this->export_sql_end[$r] .= ' AND pr.date_price = (SELECT MAX(pr2.date_price) FROM '.MAIN_DB_PREFIX.'product_price as pr2 WHERE pr2.fk_product = pr.fk_product AND pr2.entity IN ('.getEntity('product').'))'; // export only latest prices not full history + $this->export_sql_end[$r] .= ' ORDER BY p.ref, pr.price_level'; } if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { @@ -356,7 +358,7 @@ class modProduct extends DolibarrModules $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = "ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r] = array(array("produit", "export")); - $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref", + $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref", 'p.label'=>"Label", 's.nom'=>'ThirdParty', 'pr.price_base_type'=>"PriceBase", 'pr.price'=>"PriceUnitPriceHT", 'pr.price_ttc'=>"PriceUnitPriceTTC", @@ -367,7 +369,7 @@ class modProduct extends DolibarrModules if (is_object($mysoc) && $usenpr) { $this->export_fields_array[$r]['pr.recuperableonly'] = 'NPR'; } - $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product", + $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product", 'p.label'=>"Label", 's.nom'=>'company', 'pr.price_base_type'=>"product", 'pr.price'=>"product", 'pr.price_ttc'=>"product", @@ -572,7 +574,13 @@ class modProduct extends DolibarrModules 'class' => 'CProductNature', 'method' => 'fetch', 'dict' => 'DictionaryProductNature' - ), + ), + 'p.accountancy_code_sell'=>array('rule'=>'accountingaccount'), + 'p.accountancy_code_sell_intra'=>array('rule'=>'accountingaccount'), + 'p.accountancy_code_sell_export'=>array('rule'=>'accountingaccount'), + 'p.accountancy_code_buy'=>array('rule'=>'accountingaccount'), + 'p.accountancy_code_buy_intra'=>array('rule'=>'accountingaccount'), + 'p.accountancy_code_buy_export'=>array('rule'=>'accountingaccount'), ); $this->import_regex_array[$r] = array( diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 8b1a1dc8525..15f2b5fecca 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -127,19 +127,19 @@ class modTicket extends DolibarrModules 'tabsql' => array( 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_severity as f', - 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default, f.public FROM '.MAIN_DB_PREFIX.'c_ticket_category as f', + 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default, f.public, f.fk_parent FROM '.MAIN_DB_PREFIX.'c_ticket_category as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_resolution as f' ), 'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC", "pos ASC"), - 'tabfield' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public", "code,label,pos,use_default"), - 'tabfieldvalue' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public", "code,label,pos,use_default"), - 'tabfieldinsert' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public", "code,label,pos,use_default"), + 'tabfield' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public,fk_parent", "code,label,pos,use_default"), + 'tabfieldvalue' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public,fk_parent", "code,label,pos,use_default"), + 'tabfieldinsert' => array("code,label,pos,use_default", "code,label,pos,use_default", "code,label,pos,use_default,public,fk_parent", "code,label,pos,use_default"), 'tabrowid' => array("rowid", "rowid", "rowid", "rowid"), 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled), 'tabhelp' => array( array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), - array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"), 'public'=>$langs->trans("Enter0or1").'
'.$langs->trans("TicketGroupIsPublicDesc")), + array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"), 'public'=>$langs->trans("Enter0or1").'
'.$langs->trans("TicketGroupIsPublicDesc"), 'fk_parent'=>$langs->trans("IfThisCategoryIsChildOfAnother")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")) ), ); diff --git a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php index e091b5069e9..a358f916429 100644 --- a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php +++ b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php @@ -99,7 +99,7 @@ class modGeneratePassStandard extends ModeleGenPassword $password = ""; // define possible characters - $possible = "0123456789bcdfghjkmnpqrstvwxyz"; + $possible = "0123456789qwertyuiopasdfghjklzxcvbnmASDFGHJKLZXCVBNMQWERTYUIOP"; // set up a counter $i = 0; @@ -107,10 +107,13 @@ class modGeneratePassStandard extends ModeleGenPassword // add random characters to $password until $length is reached while ($i < $this->length) { // pick a random character from the possible ones - $char = substr($possible, mt_rand(0, dol_strlen($possible) - 1), 1); + if (function_exists('random_int')) { // Cryptographic random + $char = substr($possible, random_int(0, dol_strlen($possible) - 1), 1); + } else { + $char = substr($possible, mt_rand(0, dol_strlen($possible) - 1), 1); + } - // we don't want this character if it's already in the password - if (!strstr($password, $char)) { + if (substr_count($password, $char) <= 6) { // we don't want this character if it's already 5 times in the password $password .= $char; $i++; } diff --git a/htdocs/core/tpl/commonfields_add.tpl.php b/htdocs/core/tpl/commonfields_add.tpl.php index 3a43f04c149..cd07c0b8191 100644 --- a/htdocs/core/tpl/commonfields_add.tpl.php +++ b/htdocs/core/tpl/commonfields_add.tpl.php @@ -47,7 +47,7 @@ foreach ($object->fields as $key => $val) { print ''; print ''; if (!empty($val['picto'])) { - print img_picto('', $val['picto']); + print img_picto('', $val['picto'], '', false, 0, 0, '', 'pictofixedwidth'); } if (in_array($val['type'], array('int', 'integer'))) { $value = GETPOST($key, 'int'); diff --git a/htdocs/core/tpl/commonfields_edit.tpl.php b/htdocs/core/tpl/commonfields_edit.tpl.php index 9fef2d2f2b9..9670271d1a4 100644 --- a/htdocs/core/tpl/commonfields_edit.tpl.php +++ b/htdocs/core/tpl/commonfields_edit.tpl.php @@ -48,7 +48,7 @@ foreach ($object->fields as $key => $val) { print ''; if (!empty($val['picto'])) { - print img_picto('', $val['picto']); + print img_picto('', $val['picto'], '', false, 0, 0, '', 'pictofixedwidth'); } if (in_array($val['type'], array('int', 'integer'))) { $value = GETPOSTISSET($key) ?GETPOST($key, 'int') : $object->$key; diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 9af5bc7d7b4..e668d1e6d58 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -356,7 +356,7 @@ if (!empty($conf->global->MAIN_EASTER_EGG_COMMITSTRIP)) { - '; } -print "\n"; - -print dol_get_fiche_end(); - -// Save -print '
'; -print ''; -if (!empty($backtopage)) { - print '     '; -} -print '
'; - - -print "\n"; -print "
"; -print '
'; - - llxFooterVierge(); $db->close(); diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 1fbf420888d..2f566d4bb31 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -1302,6 +1302,12 @@ if ($ispaymentok) { $error++; } // End call triggers + } elseif (get_class($object) == 'stdClass') { + //In some case $object is not instanciate (for paiement on custom object) We need to deal with payment + include_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; + $paiement = new Paiement($db); + $result = $paiement->call_trigger('PAYMENTONLINE_PAYMENT_OK', $user); + if ($result < 0) $error++; } print $langs->trans("YourPaymentHasBeenRecorded")."
\n"; diff --git a/htdocs/public/project/suggestbooth.php b/htdocs/public/project/suggestbooth.php index 6329441778f..3ab8e165c7e 100644 --- a/htdocs/public/project/suggestbooth.php +++ b/htdocs/public/project/suggestbooth.php @@ -405,6 +405,7 @@ if (empty($reshook) && $action == 'add') { $facture->paye = 0; $facture->date = dol_now(); $facture->cond_reglement_id = $contact->cond_reglement_id; + $facture->fk_project = $project->id; if (empty($facture->cond_reglement_id)) { $paymenttermstatic = new PaymentTerm($contact->db); @@ -469,7 +470,7 @@ if (empty($reshook) && $action == 'add') { $labeltouse = $conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH; if (!empty($labeltouse)) { - $arraydefaultmessage = $formmail->getEMailTemplate($db, 'eventorganization_send', $user, $outputlangs, $labeltouse, 1, ''); + $arraydefaultmessage = $formmail->getEMailTemplate($db, 'conferenceorbooth', $user, $outputlangs, $labeltouse, 1, ''); } if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { @@ -569,7 +570,7 @@ jQuery(document).ready(function () { print ''."\n"; // Name -print ''; +print ''; print ''; print ''; // Email @@ -577,21 +578,6 @@ print ''."\n"; -// Type of event -print ''."\n"; -print ''; -// Label -print ''."\n"; -print ''."\n"; -// Note -print ''."\n"; -print ''."\n"; -// Start Date -print ''."\n"; -print ''."\n"; -// End Date -print ''."\n"; -print ''."\n"; // Address print ''."\n"; @@ -603,9 +589,8 @@ print $formcompany->select_ziptown(GETPOST('town'), 'town', array('zipcode', 'se print ''; // Country print ''; } +// Type of event +print ''."\n"; +print ''; +// Label +print ''."\n"; +print ''."\n"; +// Note +print ''."\n"; +print ''."\n"; +// Start Date +print ''."\n"; +print ''."\n"; +// End Date +print ''."\n"; +print ''."\n"; + print "
lastname).'" autofocus="autofocus">
'.$langs->trans("Email").'*'.$langs->trans("Company").'*'; print '
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("Label").'*
'.$langs->trans("Note").'*
'.$langs->trans("DateStart").'*
'.$langs->trans("DateEnd").'*
'.$langs->trans("Address").''."\n"; print '
'.$langs->trans('Country'); -if (!empty(floatval($project->price_booth))) { - print '*'; -} +print '*'; + print ''; $country_id = GETPOST('country_id'); if (!$country_id && !empty($conf->global->MEMBER_NEWFORM_FORCECOUNTRYCODE)) { @@ -635,6 +620,22 @@ if (empty($conf->global->SOCIETE_DISABLE_STATE)) { } print '
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("LabelOfBooth").'*
'.$langs->trans("Description").'*
'.$langs->trans("DateStart").'*
'.$langs->trans("DateEnd").'*
\n"; diff --git a/htdocs/public/project/suggestconference.php b/htdocs/public/project/suggestconference.php index 00b093ba215..399969bc80d 100644 --- a/htdocs/public/project/suggestconference.php +++ b/htdocs/public/project/suggestconference.php @@ -409,7 +409,7 @@ if (empty($reshook) && $action == 'add') { $labeltouse = $conf->global->EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF; if (!empty($labeltouse)) { - $arraydefaultmessage = $formmail->getEMailTemplate($db, 'eventorganization_send', $user, $outputlangs, $labeltouse, 1, ''); + $arraydefaultmessage = $formmail->getEMailTemplate($db, 'conferenceorbooth', $user, $outputlangs, $labeltouse, 1, ''); } if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { @@ -508,11 +508,11 @@ jQuery(document).ready(function () { print ''."\n"; // Last Name -print ''; +print ''; print ''; print ''; // First Name -print ''; +print ''; print ''; print ''; // Email @@ -520,21 +520,6 @@ print ''."\n"; -// Type of event -print ''."\n"; -print ''; -// Label -print ''."\n"; -print ''."\n"; -// Note -print ''."\n"; -print ''."\n"; -// Start Date -print ''."\n"; -print ''."\n"; -// End Date -print ''."\n"; -print ''."\n"; // Address print ''."\n"; @@ -574,6 +559,22 @@ if (empty($conf->global->SOCIETE_DISABLE_STATE)) { } print ''; } +// Type of event +print ''."\n"; +print ''; +// Label +print ''."\n"; +print ''."\n"; +// Note +print ''."\n"; +print ''."\n"; +// Start Date +print ''."\n"; +print ''."\n"; +// End Date +print ''."\n"; +print ''."\n"; + print "
lastname).'" autofocus="autofocus">
firstname).'" autofocus="autofocus">
'.$langs->trans("Email").'*'.$langs->trans("Company").'*'; print '
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("Label").'*
'.$langs->trans("Note").'*
'.$langs->trans("DateStart").'
'.$langs->trans("DateEnd").'
'.$langs->trans("Address").''."\n"; print '
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("LabelOfconference").'*
'.$langs->trans("Description").'*
'.$langs->trans("DateStart").'
'.$langs->trans("DateEnd").'
\n"; diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index d3f97e6f3d1..6e9ee616327 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -183,7 +183,7 @@ if ($conf->use_javascript_ajax) { print '
'; print ''; - print ''."\n"; + print ''."\n"; $listofstatus = array(0, 1, 3, 5, 8, 9); foreach ($listofstatus as $status) { $dataseries[] = array(dol_html_entity_decode($staticrecruitmentcandidature->LibStatut($status, 1), ENT_QUOTES | ENT_HTML5), (isset($vals[$status]) ? (int) $vals[$status] : 0)); diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index 2f87fdd99d2..35ceb8a1931 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -502,6 +502,9 @@ class Salary extends CommonObject if ($this->datesp && $this->dateep) { $label .= '
'.$langs->trans('Period').': '.dol_print_date($this->datesp, 'day').' - '.dol_print_date($this->dateep, 'day'); } + if (isset($this->amount)) { + $label .= '
'.$langs->trans('Amount').': '.price($this->amount); + } $url = DOL_URL_ROOT.'/salaries/card.php?id='.$this->id; diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index 690f8df4c8c..7a8b3ebca10 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -140,7 +140,7 @@ foreach ($object->fields as $key => $val) { 'checked'=>(($visible < 0) ? 0 : 1), 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), 'position'=>$val['position'], - 'help'=>$val['help'] + 'help'=> isset($val['help']) ? $val['help'] : '' ); } } diff --git a/htdocs/salaries/payments.php b/htdocs/salaries/payments.php index bfc795ebcef..f129e6304ab 100644 --- a/htdocs/salaries/payments.php +++ b/htdocs/salaries/payments.php @@ -124,6 +124,22 @@ foreach ($object->fields as $key => $val) { } } +// Definition of array of fields for columns +$arrayfields = array(); +foreach ($object->fields as $key => $val) { + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) { + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); + } +} + $permissiontoread = $user->rights->salaries->read; $permissiontoadd = $user->rights->salaries->write; $permissiontodelete = $user->rights->salaries->delete; @@ -666,11 +682,13 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; // If no record found if ($num == 0) { - $colspan = 1; - foreach ($arrayfields as $key => $val) { if (!empty($val['checked'])) { + /*$colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { $colspan++; - } - } + } + }*/ + $colspan = 12; print ''; } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 8e1d03411cd..76ae78fdb51 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -495,10 +495,22 @@ if (empty($reshook)) { $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); if (GETPOSTISSET('accountancy_code_sell')) { - $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + $accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + + if (empty($accountancy_code_sell) || $accountancy_code_sell == '-1') { + $object->accountancy_code_sell = ''; + } else { + $object->accountancy_code_sell = $accountancy_code_sell; + } } if (GETPOSTISSET('accountancy_code_buy')) { - $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + + if (empty($accountancy_code_buy) || $accountancy_code_buy == '-1') { + $object->accountancy_code_buy = ''; + } else { + $object->accountancy_code_buy = $accountancy_code_buy; + } } // Incoterms @@ -554,7 +566,7 @@ if (empty($reshook)) { } // We set country_id, country_code and country for the selected country - $object->country_id = GETPOST('country_id') != '' ?GETPOST('country_id') : $mysoc->country_id; + $object->country_id = GETPOST('country_id', 'int') != '' ? GETPOST('country_id', 'int') : $mysoc->country_id; if ($object->country_id) { $tmparray = getCountry($object->country_id, 'all'); $object->country_code = $tmparray['code']; @@ -1058,10 +1070,22 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $object->default_lang = GETPOST('default_lang'); if (GETPOSTISSET('accountancy_code_sell')) { - $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + $accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + + if (empty($accountancy_code_sell) || $accountancy_code_sell == '-1') { + $object->accountancy_code_sell = ''; + } else { + $object->accountancy_code_sell = $accountancy_code_sell; + } } if (GETPOSTISSET('accountancy_code_buy')) { - $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + + if (empty($accountancy_code_buy) || $accountancy_code_buy == '-1') { + $object->accountancy_code_buy = ''; + } else { + $object->accountancy_code_buy = $accountancy_code_buy; + } } $object->logo = (isset($_FILES['photo']) ?dol_sanitizeFileName($_FILES['photo']['name']) : ''); @@ -1385,6 +1409,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } if ($object->country_id) { + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($object->state_id, $object->country_code); } else { print $countrynotdefined; @@ -1784,10 +1809,22 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); if (GETPOSTISSET('accountancy_code_sell')) { - $object->accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + $accountancy_code_sell = GETPOST('accountancy_code_sell', 'alpha'); + + if (empty($accountancy_code_sell) || $accountancy_code_sell == '-1') { + $object->accountancy_code_sell = ''; + } else { + $object->accountancy_code_sell = $accountancy_code_sell; + } } if (GETPOSTISSET('accountancy_code_buy')) { - $object->accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); + + if (empty($accountancy_code_buy) || $accountancy_code_buy == '-1') { + $object->accountancy_code_buy = ''; + } else { + $object->accountancy_code_buy = $accountancy_code_buy; + } } //Incoterms @@ -2068,6 +2105,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index a213cca5577..eff2ba39c21 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -894,7 +894,7 @@ class Societe extends CommonObject $sql .= ", ".(!empty($user->id) ? ((int) $user->id) : "null"); $sql .= ", ".(!empty($this->typent_id) ? ((int) $this->typent_id) : "null"); $sql .= ", ".(!empty($this->canvas) ? "'".$this->db->escape($this->canvas)."'" : "null"); - $sql .= ", ".$this->status; + $sql .= ", ".((int) $this->status); $sql .= ", ".(!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null"); $sql .= ", 0"; $sql .= ", ".(int) $this->fk_incoterms; @@ -1369,13 +1369,13 @@ class Societe extends CommonObject $sql .= ",zip = ".(!empty($this->zip) ? "'".$this->db->escape($this->zip)."'" : "null"); $sql .= ",town = ".(!empty($this->town) ? "'".$this->db->escape($this->town)."'" : "null"); - $sql .= ",fk_departement = '".(!empty($this->state_id) ? $this->state_id : '0')."'"; - $sql .= ",fk_pays = '".(!empty($this->country_id) ? $this->country_id : '0')."'"; + $sql .= ",fk_departement = ".((!empty($this->state_id) && $this->state_id > 0) ? ((int) $this->state_id) : 'null'); + $sql .= ",fk_pays = ".((!empty($this->country_id) && $this->country_id > 0) ? ((int) $this->country_id) : 'null'); $sql .= ",phone = ".(!empty($this->phone) ? "'".$this->db->escape($this->phone)."'" : "null"); $sql .= ",fax = ".(!empty($this->fax) ? "'".$this->db->escape($this->fax)."'" : "null"); $sql .= ",email = ".(!empty($this->email) ? "'".$this->db->escape($this->email)."'" : "null"); - $sql .= ", socialnetworks = '".$this->db->escape(json_encode($this->socialnetworks))."'"; + $sql .= ",socialnetworks = '".$this->db->escape(json_encode($this->socialnetworks))."'"; $sql .= ",url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null"); $sql .= ",parent = ".($this->parent > 0 ? $this->parent : "null"); diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php index f5a4392a0c0..14901dc8a9c 100644 --- a/htdocs/societe/index.php +++ b/htdocs/societe/index.php @@ -185,6 +185,7 @@ $thirdpartygraph .= ''; $thirdpartygraph .= '
'.$langs->trans("Statistics").' - '.$langs->trans("Candidatures").'
'.$langs->trans("Statistics").' - '.$langs->trans("RecruitmentCandidatures").'
'.$langs->trans("NoRecordFound").'
'.$form->editfieldkey('State', 'state_id', '', $object, 0).''; } + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($object->state_id, $object->country_code); print '
'; $thirdpartygraph .= '
'; +$thirdpartycateggraph = ''; if (!empty($conf->categorie->enabled) && !empty($conf->global->CATEGORY_GRAPHSTATS_ON_THIRDPARTIES)) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $elementtype = 'societe'; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 633f0785fe1..5d22ea05684 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -552,16 +552,16 @@ if (empty($reshook)) { } } - if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal. + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPrice")), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors'); $error++; } diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 5906db24ee7..6d43222bcf2 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -587,7 +587,7 @@ class SupplierProposal extends CommonObject $this->line->date_end = $date_end; // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { + if (!empty($fk_product) && $fk_product > 0 && empty($fk_fournprice) && empty($pa_ht)) { // When fk_fournprice is 0, we take the lowest buying price include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($this->db); @@ -777,7 +777,7 @@ class SupplierProposal extends CommonObject $this->line->fk_unit = $fk_unit; // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { + if (!empty($fk_product) && $fk_product > 0 && empty($fk_fournprice) && empty($pa_ht)) { // by external module, take lowest buying price include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($this->db); @@ -2216,7 +2216,7 @@ class SupplierProposal extends CommonObject $this->nbtodo = $this->nbtodolate = 0; $clause = " WHERE"; - $sql = "SELECT p.rowid, p.ref, p.datec as datec"; + $sql = "SELECT p.rowid, p.ref, p.datec as datec, p.date_cloture as datefin"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p"; if (!$user->rights->societe->client->voir && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; @@ -2239,13 +2239,13 @@ class SupplierProposal extends CommonObject $label = $labelShort = ''; $status = ''; if ($mode == 'opened') { - $delay_warning = $conf->supplier_proposal->cloture->warning_delay; + $delay_warning = !empty($conf->supplier_proposal->cloture->warning_delay) ? $conf->supplier_proposal->cloture->warning_delay : 0; $status = self::STATUS_VALIDATED; $label = $langs->trans("SupplierProposalsToClose"); $labelShort = $langs->trans("ToAcceptRefuse"); } if ($mode == 'signed') { - $delay_warning = $conf->supplier_proposal->facturation->warning_delay; + $delay_warning = !empty($conf->supplier_proposal->facturation->warning_delay) ? $conf->supplier_proposal->facturation->warning_delay : 0; $status = self::STATUS_SIGNED; $label = $langs->trans("SupplierProposalsToProcess"); // May be billed or ordered $labelShort = $langs->trans("ToClose"); diff --git a/htdocs/takepos/ajax/ajax.php b/htdocs/takepos/ajax/ajax.php index 0ccdeb86b9b..30635c58b8c 100644 --- a/htdocs/takepos/ajax/ajax.php +++ b/htdocs/takepos/ajax/ajax.php @@ -60,11 +60,11 @@ if (empty($user->rights->takepos->run)) { if ($action == 'getProducts') { $object = new Categorie($db); if ($category == "supplements") { - $category = $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY; + $category = getDolGlobalInt('TAKEPOS_SUPPLEMENTS_CATEGORY'); } $result = $object->fetch($category); if ($result > 0) { - $prods = $object->getObjectsInCateg("product", 0, 0, 0, $conf->global->TAKEPOS_SORTPRODUCTFIELD, 'ASC'); + $prods = $object->getObjectsInCateg("product", 0, 0, 0, getDolGlobalString('TAKEPOS_SORTPRODUCTFIELD'), 'ASC'); // Removed properties we don't need if (is_array($prods) && count($prods) > 0) { foreach ($prods as $prod) { diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index b182f37f787..1ddab39dcbe 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -72,6 +72,7 @@ if ($setterminal > 0) { if ($setcurrency != "") { $_SESSION["takeposcustomercurrency"] = $setcurrency; + // We will recalculate amount for foreign currency at next call of invoice.php when $_SESSION["takeposcustomercurrency"] differs from invoice->multicurrency_code. } $_SESSION["urlfrom"] = '/takepos/index.php'; @@ -702,12 +703,12 @@ function TakeposPrintingTemp(){ } function OpenDrawer(){ - console.log("OpenDrawer call ajax url http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print"); + console.log("OpenDrawer call ajax url http://:8111/print"); $.ajax({ type: "POST", data: { token: 'notrequired' }, global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { + if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { echo "url: '".$conf->global->TAKEPOS_PRINT_SERVER."/printer/drawer.php',"; } else { echo "url: 'http://".$conf->global->TAKEPOS_PRINT_SERVER.":8111/print',"; @@ -780,7 +781,7 @@ function WeighingScale(){ $.ajax({ type: "POST", data: { token: 'notrequired' }, - url: 'global->TAKEPOS_PRINT_SERVER; ?>/scale/index.php', + url: '/scale/index.php', }) .done(function( editnumber ) { $("#poslines").load("invoice.php?action=updateqty&place="+place+"&idline="+selectedline+"&number="+editnumber, function() { @@ -798,7 +799,7 @@ $( document ).ready(function() { if ($_SESSION["takeposterminal"] == "") { print "ModalBox('ModalTerminal');"; } - if ($conf->global->TAKEPOS_CONTROL_CASH_OPENING) { + if (getDolGlobalString('TAKEPOS_CONTROL_CASH_OPENING')) { $sql = "SELECT rowid, status FROM ".MAIN_DB_PREFIX."pos_cash_fence WHERE"; $sql .= " entity = ".$conf->entity." AND "; $sql .= " date_creation > '".$db->idate(dol_get_first_hour(dol_now()))."'"; @@ -817,7 +818,7 @@ $( document ).ready(function() { global->{'CASHDESK_READER_KEYCODE_FOR_ENTER'.$_SESSION['takeposterminal']} > 0 ? $conf->global->{'CASHDESK_READER_KEYCODE_FOR_ENTER'.$_SESSION['takeposterminal']} : ''; +$keyCodeForEnter = getDolGlobalInt('CASHDESK_READER_KEYCODE_FOR_ENTER'.$_SESSION['takeposterminal']) > 0 ? getDolGlobalInt('CASHDESK_READER_KEYCODE_FOR_ENTER'.$_SESSION['takeposterminal']) : ''; ?>
@@ -1035,41 +1036,41 @@ $menus[$r++] = array('title'=>' $menus[$r++] = array('title'=>'
'.$langs->trans("Reduction").'
', 'action'=>'Reduction();'); $menus[$r++] = array('title'=>'
'.$langs->trans("Payment").'
', 'action'=>'CloseBill();'); -if ($conf->global->TAKEPOS_DIRECT_PAYMENT) { +if (getDolGlobalString('TAKEPOS_DIRECT_PAYMENT')) { $menus[$r++] = array('title'=>'
'.$langs->trans("DirectPayment").' ('.$langs->trans("Cash").')
', 'action'=>'DirectPayment();'); } // BAR RESTAURANT specific menu -if ($conf->global->TAKEPOS_BAR_RESTAURANT) { +if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) { if ($conf->global->TAKEPOS_ORDER_PRINTERS) { $menus[$r++] = array('title'=>'
'.$langs->trans("Order").'', 'action'=>'TakeposPrintingOrder();'); } //Button to print receipt before payment - if ($conf->global->TAKEPOS_BAR_RESTAURANT) { - if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { - if (filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { + if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) { + if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { + if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { $menus[$r++] = array('title'=>'
'.$langs->trans("Receipt").'
', 'action'=>'TakeposConnector(placeid);'); } else { $menus[$r++] = array('title'=>'
'.$langs->trans("Receipt").'
', 'action'=>'TakeposPrinting(placeid);'); } - } elseif ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { + } elseif (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") { $menus[$r++] = array('title'=>'
'.$langs->trans("Receipt").'
', 'action'=>'DolibarrTakeposPrinting(placeid);'); } else { $menus[$r++] = array('title'=>'
'.$langs->trans("Receipt").'
', 'action'=>'Print(placeid);'); } } - if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector" && $conf->global->TAKEPOS_ORDER_NOTES == 1) { + if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector" && getDolGlobalString('TAKEPOS_ORDER_NOTES') == 1) { $menus[$r++] = array('title'=>'
'.$langs->trans("OrderNotes").'
', 'action'=>'TakeposOrderNotes();'); } - if ($conf->global->TAKEPOS_SUPPLEMENTS) { + if (getDolGlobalString('TAKEPOS_SUPPLEMENTS')) { $menus[$r++] = array('title'=>'
'.$langs->trans("ProductSupplements").'
', 'action'=>'LoadProducts(\'supplements\');'); } } -if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { +if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { $menus[$r++] = array('title'=>'
'.$langs->trans("DOL_OPEN_DRAWER").'
', 'action'=>'OpenDrawer();'); } -if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { +if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") { $menus[$r++] = array( 'title' => '
'.$langs->trans("DOL_OPEN_DRAWER").'
', 'action' => 'DolibarrOpenDrawer();', @@ -1111,7 +1112,7 @@ if (!empty($conf->global->TAKEPOS_HIDE_HEAD_BAR)) { $menus[$r++] = array('title'=>'
'.$langs->trans("Logout").'
', 'action'=>'window.location.href=\''.DOL_URL_ROOT.'/user/logout.php\';'); } -if ($conf->global->TAKEPOS_WEIGHING_SCALE) { +if (!empty($conf->global->TAKEPOS_WEIGHING_SCALE)) { $menus[$r++] = array('title'=>'
'.$langs->trans("WeighingScale").'
', 'action'=>'WeighingScale();'); } @@ -1123,12 +1124,12 @@ if ($conf->global->TAKEPOS_WEIGHING_SCALE) { foreach ($menus as $menu) { $i++; if (count($menus) > 12 and $i == 12) { - echo ''; - echo ''; + echo ''; + echo ''; } elseif ($i > 12) { - echo ''; + echo ''; } else { - echo ''; + echo ''; } } @@ -1168,7 +1169,7 @@ if ($conf->global->TAKEPOS_WEIGHING_SCALE) { //echo ''; echo ''; } else { - if (!$conf->global->TAKEPOS_HIDE_CATEGORY_IMAGES) { + if (!getDolGlobalString('TAKEPOS_HIDE_CATEGORY_IMAGES')) { echo ''; } } @@ -1207,7 +1208,7 @@ if ($conf->global->TAKEPOS_WEIGHING_SCALE) { //echo ''; print ''; } else { - if ($conf->global->TAKEPOS_HIDE_PRODUCT_IMAGES) { + if (getDolGlobalString('TAKEPOS_HIDE_PRODUCT_IMAGES')) { echo ''; } else { print '
'; @@ -1215,7 +1216,7 @@ if ($conf->global->TAKEPOS_WEIGHING_SCALE) { } } ?> - global->TAKEPOS_HIDE_PRODUCT_IMAGES) { ?> +
diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 3f7e63d84cb..8cef291c2d7 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -70,10 +70,10 @@ if (empty($user->rights->takepos->run) && !defined('INCLUDE_PHONEPAGE_FROM_PUBLI * View */ -if (($conf->global->TAKEPOS_PHONE_BASIC_LAYOUT == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { +if ((getDolGlobalString('TAKEPOS_PHONE_BASIC_LAYOUT') == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { // DIRECT LINK TO THIS PAGE FROM MOBILE AND NO TERMINAL SELECTED if ($_SESSION["takeposterminal"] == "") { - if ($conf->global->TAKEPOS_NUM_TERMINALS == "1") { + if (getDolGlobalString('TAKEPOS_NUM_TERMINALS') == "1") { $_SESSION["takeposterminal"] = 1; } else { header("Location: ".DOL_URL_ROOT."/takepos/index.php"); @@ -94,6 +94,8 @@ if (($conf->global->TAKEPOS_PHONE_BASIC_LAYOUT == 1 && $conf->browser->layout == '/takepos/js/jquery.colorbox-min.js' ); $arrayofjs = array('/takepos/js/jquery.colorbox-min.js'); + $disablejs = 0; + $disablehead = 0; top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); } @@ -132,12 +134,19 @@ if ($pay == 'cheque') { } // Retrieve paiementid -$sql = "SELECT id FROM ".MAIN_DB_PREFIX."c_paiement"; -$sql .= " WHERE entity IN (".getEntity('c_paiement').")"; -$sql .= " AND code = '".$db->escape($paycode)."'"; -$resql = $db->query($sql); -$obj = $db->fetch_object($resql); -$paiementid = $obj->id; +$paiementid = 0; +if ($paycode) { + $sql = "SELECT id FROM ".MAIN_DB_PREFIX."c_paiement"; + $sql .= " WHERE entity IN (".getEntity('c_paiement').")"; + $sql .= " AND code = '".$db->escape($paycode)."'"; + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) { + $paiementid = $obj->id; + } + } +} $invoice = new Facture($db); if ($invoiceid > 0) { @@ -163,6 +172,14 @@ if ($invoice->socid > 0) { * Actions */ +// Change the currency of invoice if it was modified +if (!empty($conf->multicurrency->enabled) && !empty($_SESSION["takeposcustomercurrency"])) { + if ($invoice->multicurrency_code != $_SESSION["takeposcustomercurrency"]) { + $invoice->setMulticurrencyCode($_SESSION["takeposcustomercurrency"]); + } +} + + // Action to record a payment on a TakePOS invoice if ($action == 'valid' && $user->rights->facture->creer) { $bankaccount = 0; @@ -311,7 +328,7 @@ if ($action == 'valid' && $user->rights->facture->creer) { } } -if ($action == 'creditnote') { +if ($action == 'creditnote' && $user->rights->facture->creer) { $creditnote = new Facture($db); $creditnote->socid = $invoice->socid; $creditnote->date = dol_now(); @@ -459,10 +476,6 @@ if ($action == 'history' || $action == 'creditnote') { $invoice->fetch($placeid); } -if (!empty($conf->multicurrency->enabled) && $_SESSION["takeposcustomercurrency"] != "") { - $invoice->setMulticurrencyCode($_SESSION["takeposcustomercurrency"]); -} - if (($action == "addline" || $action == "freezone") && $placeid == 0) { $invoice->socid = $conf->global->$constforcompanyid; $invoice->date = dol_now(); @@ -631,8 +644,11 @@ if ($action == "delete") { if ($action == "updateqty") { foreach ($invoice->lines as $line) { if ($line->id == $idline) { - if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); - else $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $number, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit); + if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) { + dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); + } else { + $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $number, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit); + } } } @@ -640,12 +656,13 @@ if ($action == "updateqty") { } if ($action == "updateprice") { + $customer = new Societe($db); + $customer->fetch($invoice->socid); + foreach ($invoice->lines as $line) { if ($line->id == $idline) { $prod = new Product($db); $prod->fetch($line->fk_product); - $customer = new Societe($db); - $customer->fetch($invoice->socid); $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); $price_min = $datapriceofproduct['price_min']; $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); @@ -654,34 +671,50 @@ if ($action == "updateprice") { if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($line->remise_percent) / 100) < price2num($price_min)))) { echo $langs->trans("CantBeLessThanMinPrice"); } else { - if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); - else $result = $invoice->updateline($line->id, $line->desc, $number, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'TTC', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit); + if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) { + dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); + } else { + $result = $invoice->updateline($line->id, $line->desc, $number, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'TTC', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit); + } } } } + + // Reload data $invoice->fetch($placeid); } if ($action == "updatereduction") { + $customer = new Societe($db); + $customer->fetch($invoice->socid); + foreach ($invoice->lines as $line) { if ($line->id == $idline) { + dol_syslog("updatereduction Process line ".$line->id.' to apply discount of '.$number.'%'); + $prod = new Product($db); $prod->fetch($line->fk_product); - $customer = new Societe($db); - $customer->fetch($invoice->socid); + $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); $price_min = $datapriceofproduct['price_min']; $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); - $pu_ht = price2num($line->multicurrency_subprice / (1 + ($line->tva_tx / 100)), 'MU'); - //Check min price - if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($line->multicurrency_subprice) * (1 - price2num($number) / 100) < price2num($price_min)))) { + + $pu_ht = price2num($line->subprice / (1 + ($line->tva_tx / 100)), 'MU'); + + // Check min price + if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($line->subprice) * (1 - price2num($number) / 100) < price2num($price_min)))) { echo $langs->trans("CantBeLessThanMinPrice"); } else { - if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); - else $result = $invoice->updateline($line->id, $line->desc, $line->multicurrency_subprice, $line->qty, $number, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit); + if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) { + dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); + } else { + $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty, $number, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit); + } } } } + + // Reload data $invoice->fetch($placeid); } elseif ($action == 'update_reduction_global') { foreach ($invoice->lines as $line) { @@ -709,6 +742,7 @@ if ($action == "order" and $placeid != 0) { $catsprinter1 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_1); $catsprinter2 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_2); $catsprinter3 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_3); + $linestoprint = 0; foreach ($invoice->lines as $line) { if ($line->special_code == "4") { continue; @@ -830,25 +864,25 @@ if ($action == "valid" || $action == "history" || $action == 'creditnote') { } } $sectionwithinvoicelink .= '
'; - if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { - if (filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { + if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { + if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { $sectionwithinvoicelink .= ' '; } else { $sectionwithinvoicelink .= ' '; } - } elseif ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { + } elseif (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") { $sectionwithinvoicelink .= ' '; } else { $sectionwithinvoicelink .= ' '; - if ($conf->global->TAKEPOS_GIFT_RECEIPT) { + if (getDolGlobalString('TAKEPOS_GIFT_RECEIPT')) { $sectionwithinvoicelink .= ' '; } } - if ($conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) { + if (getDolGlobalString('TAKEPOS_EMAIL_TEMPLATE_INVOICE') && $conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) { $sectionwithinvoicelink .= ' '; } - if ($remaintopay <= 0 && $conf->global->TAKEPOS_AUTO_PRINT_TICKETS) { + if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS')) { $sectionwithinvoicelink .= ''; } } @@ -866,7 +900,7 @@ var selectedline=0; var selectedtext=""; var placeid= 0 ? $placeid : 0); ?>; $(document).ready(function() { - var idoflineadded = ; + var idoflineadded = ; $('.posinvoiceline').click(function(){ console.log("Click done on "+this.id); @@ -992,7 +1026,7 @@ function TakeposPrinting(id){ receipt=data.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, ''); $.ajax({ type: "POST", - url: 'http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print', + url: 'http://:8111/print', data: receipt }); }); @@ -1003,7 +1037,7 @@ function TakeposConnector(id){ $.get("/takepos/ajax/ajax.php?action=printinvoiceticket&term=&id="+id+"&token=", function(data, status) { $.ajax({ type: "POST", - url: 'global->TAKEPOS_PRINT_SERVER; ?>/printer/index.php', + url: '/printer/index.php', data: 'invoice='+data }); }); @@ -1058,6 +1092,7 @@ $( document ).ready(function() { $sql .= $db->order('datec', 'ASC'); $resql = $db->query($sql); if ($resql) { + $max_sale = 0; while ($obj = $db->fetch_object($resql)) { echo '$("#customerandsales").append(\''; echo 'jdate($obj->datec), '%H:%M', 'tzuser'))).'" onclick="place=\\\''; @@ -1148,10 +1183,10 @@ $( document ).ready(function() { // for tooltip and other js beautifiers must be reexecuted too. if (!empty($conf->use_javascript_ajax)) { print "\n".''."\n"; - print ''."\n"; + print ''."\n"; } -print ''."\n"; +print ''."\n"; print '
'; print ''; if ($sectionwithinvoicelink && ($mobilepage == "invoice" || $mobilepage == "")) { @@ -1164,10 +1199,10 @@ if ($sectionwithinvoicelink && ($mobilepage == "invoice" || $mobilepage == "")) print ''; print ''; -if ($_SESSION["basiclayout"] != 1) { +if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) { print ''; print ''; - if ($conf->global->TAKEPOS_SHOW_HT) { + if (getDolGlobalString('TAKEPOS_SHOW_HT')) { print '\n"; -if ($_SESSION["basiclayout"] == 1) { +if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) { if ($mobilepage == "cats") { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $categorie = new Categorie($db); @@ -1311,13 +1346,14 @@ if ($_SESSION["basiclayout"] == 1) { if ($placeid > 0) { //In Phone basic layout hide some content depends situation - if ($_SESSION["basiclayout"] == 1 && $mobilepage != "invoice" && $action != "order") { + if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1 && $mobilepage != "invoice" && $action != "order") { return; } if (is_array($invoice->lines) && count($invoice->lines)) { print ''."\n"; $tmplines = array_reverse($invoice->lines); + $htmlsupplements = array(); foreach ($tmplines as $line) { if ($line->fk_parent_line != false) { $htmlsupplements[$line->fk_parent_line] .= 'fk_parent_line] .= ''; $htmlsupplements[$line->fk_parent_line] .= ''; $htmlsupplements[$line->fk_parent_line] .= ''; @@ -1358,7 +1394,7 @@ if ($placeid > 0) { } $htmlforlines .= '" id="'.$line->id.'">'; $htmlforlines .= ''; - if ($conf->global->TAKEPOS_SHOW_HT) { + if (getDolGlobalString('TAKEPOS_SHOW_HT')) { $htmlforlines .= ''; } $htmlforlines .= ''."\n"; - $htmlforlines .= $htmlsupplements[$line->id]; + $htmlforlines .= empty($htmlsupplements[$line->id]) ? '' : empty($htmlsupplements[$line->id]); print $htmlforlines; } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 89cb19c129b..bffc0e17e04 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -209,7 +209,7 @@ input, select { margin-bottom: 1px; margin-top: 1px; } -#mainbody input.button:not(.buttongen):not(.bordertransp) { +#mainbody input.button:not(.buttongen):not(.bordertransp), #mainbody a.button:not(.buttongen):not(.bordertransp) { background: var(--butactionbg); color: #FFF !important; border-radius: 3px; @@ -2640,7 +2640,7 @@ table.login_table_securitycode tr td { } div.backgroundsemitransparent { - background:rgba(255,255,255,0.68); + background:rgba(255, 255, 255, 0.7); padding-left: 10px; padding-right: 10px; } @@ -3922,6 +3922,11 @@ table.noborder.paymenttable { box-shadow: 1px 1px 7px #CCC !important; } +.boxshadow { + -webkit-box-shadow: 0px 0px 5px #888; + box-shadow: 0px 0px 5px #888; +} + div.tabBar .noborder { -webkit-box-shadow: 0px 0px 0px #DDD !important; box-shadow: 0px 0px 0px #DDD !important; @@ -4525,6 +4530,9 @@ div#card-errors { .ui-dialog-content { } +.ui-dialog.ui-corner-all.ui-widget.ui-widget-content.ui-front.ui-dialog-buttons.ui-draggable { + z-index: 1002 !important; /* Default 101 with jquery, top menu have a z-index of 1000 */ +} /* ============================================================================== */ /* For content of image preview */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5ad564ea5c0..de04a9e08ea 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1507,10 +1507,10 @@ table[summary="list_of_modules"] .fa-cog { div.divphotoref { 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; @@ -1519,11 +1519,11 @@ table[summary="list_of_modules"] .fa-cog { width: calc(100% - 70px) !important; display: inline-block; } - + input.maxwidthinputfileonsmartphone { width: 175px; } - + .poweredbyimg { width: 48px; } @@ -1862,7 +1862,7 @@ div.login_block { div.backgroundsemitransparent { - background:rgba(255,255,255,0.6); + background:rgba(255, 255, 255, 0.7); padding-left: 10px; padding-right: 10px; } @@ -3090,11 +3090,11 @@ div.tabsElem a { } div.tabBar { color: #; - padding-top: 16px; - padding-left: 16px; - padding-right: 16px; - padding-bottom: 16px; - margin: 0px 0px 16px 0px; + padding-top: 21px; + padding-left: 24px; + padding-right: 24px; + padding-bottom: 18px; + margin: 0px 0px 18px 0px; -webkit-border-radius: 3px; border-radius: 3px; border-right: 1px solid #BBB; @@ -3439,9 +3439,9 @@ tr.liste_titre_filter td.liste_titre { } .liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd { - /*border-top-width: 1px; + border-top-width: 1px; border-top-color: rgb(); - border-top-style: solid;*/ + border-top-style: solid; } .liste_titre_add td, .liste_titre_add th, .liste_titre_add .tagtd { @@ -3830,7 +3830,7 @@ div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_se { background: rgb(); font-weight: ; - border-bottom: 1px solid #FDFFFF; + /* border-bottom: 1px solid #FDFFFF; */ color: rgb(); font-family: ; @@ -3943,6 +3943,11 @@ tr.liste_sub_total, tr.liste_sub_total td { box-shadow: 2px 2px 5px #CCC !important; } +.boxshadow { + -webkit-box-shadow: 0px 0px 5px #888; + box-shadow: 0px 0px 5px #888; +} + div.tabBar .noborder { -webkit-box-shadow: 0px 0px 0px #f4f4f4 !important; box-shadow: 0px 0px 0px #f4f4f4 !important; @@ -4469,6 +4474,9 @@ div#card-errors { font-size: px !important; } +.ui-dialog.ui-corner-all.ui-widget.ui-widget-content.ui-front.ui-dialog-buttons.ui-draggable { + z-index: 1002 !important; /* Default 101 with jquery, top menu have a z-index of 1000 */ +} /* ============================================================================== */ /* For content of image preview */ diff --git a/htdocs/theme/md/theme_vars.inc.php b/htdocs/theme/md/theme_vars.inc.php index 9e98a863737..fd37b6376dd 100644 --- a/htdocs/theme/md/theme_vars.inc.php +++ b/htdocs/theme/md/theme_vars.inc.php @@ -65,6 +65,9 @@ $colortext = '0,0,0'; $colortextlink = '0,0,120'; $fontsize = '14'; $fontsizesmaller = '11'; +$topMenuFontSize = '1.1em'; +$toolTipBgColor = 'rgba(255, 255, 255, 0.96)'; +$toolTipFontColor = '#333'; // text color $textSuccess = '#28a745'; @@ -83,9 +86,15 @@ $badgeInfo = '#17a2b8'; $badgeDark = '#343a40'; $badgeLight = '#f8f9fa'; +// badge color ajustement for color blind +$colorblind_deuteranopes_badgeSuccess = '#37de5d'; //! text color black +$colorblind_deuteranopes_badgeSuccess_textColor7 = '#000'; +$colorblind_deuteranopes_badgeWarning = '#e4e411'; +$colorblind_deuteranopes_badgeDanger = $badgeDanger; // currently not tested with a color blind people so use default color + /* default color for status : After a quick check, somme status can have oposite function according to objects * So this badges status uses default value according to theme eldy status img -* TODO: use color definition vars above for define badges color status X -> expemple $badgeStatusValidate, $badgeStatusClosed, $badgeStatusActive .... +* TODO: use color definition vars above for define badges color status X -> exemple $badgeStatusValidate, $badgeStatusClosed, $badgeStatusActive .... */ $badgeStatus0 = '#cbd3d3'; $badgeStatus1 = '#bc9526'; @@ -99,3 +108,9 @@ $badgeStatus8 = '#993013'; $badgeStatus9 = '#e7f0f0'; $badgeStatus10 = '#993013'; $badgeStatus11 = '#15a540'; + +// status color ajustement for color blind +$colorblind_deuteranopes_badgeStatus4 = $colorblind_deuteranopes_badgeStatus7 = $colorblind_deuteranopes_badgeSuccess; //! text color black +$colorblind_deuteranopes_badgeStatus_textColor4 = $colorblind_deuteranopes_badgeStatus_textColor7 = '#000'; +$colorblind_deuteranopes_badgeStatus1 = $colorblind_deuteranopes_badgeWarning; +$colorblind_deuteranopes_badgeStatus_textColor1 = '#000'; diff --git a/htdocs/user/agenda_extsites.php b/htdocs/user/agenda_extsites.php index b474bdfc678..928db5449d8 100644 --- a/htdocs/user/agenda_extsites.php +++ b/htdocs/user/agenda_extsites.php @@ -188,7 +188,7 @@ print '
'; // In phone version only show when it is invoice page -if ($mobilepage == "invoice" || $mobilepage == "") { +if (empty($mobilepage) || $mobilepage == "invoice") { print ''; } -if ($conf->global->TAKEPOS_BAR_RESTAURANT) { +if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) { $sql = "SELECT floor, label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place); $resql = $db->query($sql); $obj = $db->fetch_object($resql); @@ -1190,14 +1225,14 @@ if ($conf->global->TAKEPOS_BAR_RESTAURANT) { print $langs->trans("Products"); } print ''.$langs->trans('ReductionShort').''.$langs->trans('Qty').''; print '' . $langs->trans('TotalHTShort') . '
'; // In phone version only show when it is invoice page - if ($mobilepage == "invoice" || $mobilepage == "") { + if (empty($mobilepage) || $mobilepage == "invoice") { print '' . price($invoice->total_ht, 1, '', 1, -1, -1, $conf->currency) . ''; if (!empty($conf->multicurrency->enabled) && $_SESSION["takeposcustomercurrency"] != "" && $conf->currency != $_SESSION["takeposcustomercurrency"]) { //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency @@ -1213,9 +1248,9 @@ if ($_SESSION["basiclayout"] != 1) { print '
'; print ''.$langs->trans('TotalTTCShort').'
'; // In phone version only show when it is invoice page - if ($mobilepage == "invoice" || $mobilepage == "") { + if (empty($mobilepage) || $mobilepage == "invoice") { print ''.price($invoice->total_ttc, 1, '', 1, -1, -1, $conf->currency).''; - if (!empty($conf->multicurrency->enabled) && $_SESSION["takeposcustomercurrency"] != "" && $conf->currency != $_SESSION["takeposcustomercurrency"]) { + if (!empty($conf->multicurrency->enabled) && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) { //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; $multicurrency = new MultiCurrency($db); @@ -1231,7 +1266,7 @@ if ($_SESSION["basiclayout"] != 1) { print "
'.vatrate($line->remise_percent, true).''.$line->qty.''.price($line->total_ttc).''; - if ($_SESSION["basiclayout"] == 1) { + if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) { $htmlforlines .= ''.$line->qty." x "; } if (isset($line->product_type)) { @@ -1400,10 +1436,10 @@ if ($placeid > 0) { if (!empty($line->array_options['options_order_notes'])) { $htmlforlines .= "
(".$line->array_options['options_order_notes'].")"; } - if ($_SESSION["basiclayout"] == 1) { + if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) { $htmlforlines .= '
  '; } - if ($_SESSION["basiclayout"] != 1) { + if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) { $moreinfo = ''; $moreinfo .= $langs->transcountry("TotalHT", $mysoc->country_code).': '.price($line->total_ht); if ($line->vat_src_code) { @@ -1454,10 +1490,10 @@ if ($placeid > 0) { } $htmlforlines .= ''; $htmlforlines .= price($line->total_ht, 1, '', 1, -1, -1, $conf->currency); - if (!empty($conf->multicurrency->enabled) && $_SESSION["takeposcustomercurrency"] != "" && $conf->currency != $_SESSION["takeposcustomercurrency"]) { + if (!empty($conf->multicurrency->enabled) && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) { //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; $multicurrency = new MultiCurrency($db); @@ -1468,7 +1504,7 @@ if ($placeid > 0) { } $htmlforlines .= ''; $htmlforlines .= price($line->total_ttc, 1, '', 1, -1, -1, $conf->currency); - if (!empty($conf->multicurrency->enabled) && $_SESSION["takeposcustomercurrency"] != "" && $conf->currency != $_SESSION["takeposcustomercurrency"]) { + if (!empty($conf->multicurrency->enabled) && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) { //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; $multicurrency = new MultiCurrency($db); @@ -1478,7 +1514,7 @@ if ($placeid > 0) { $htmlforlines .= '
'; print ""; print ""; print ""; -print "'; +print "'; print "'; print ''; print ""; diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php index 0b179653487..0eaf3d533a9 100644 --- a/htdocs/user/bank.php +++ b/htdocs/user/bank.php @@ -366,12 +366,12 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac $payment_salary = new PaymentSalary($db); $salary = new Salary($db); - $sql = "SELECT s.rowid as sid, s.ref as sref, s.label, s.datesp, s.dateep, s.paye, SUM(ps.amount) as alreadypaid"; + $sql = "SELECT s.rowid as sid, s.ref as sref, s.label, s.datesp, s.dateep, s.paye, s.amount, SUM(ps.amount) as alreadypaid"; $sql .= " FROM ".MAIN_DB_PREFIX."salary as s"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."payment_salary as ps ON (s.rowid = ps.fk_salary)"; $sql .= " WHERE s.fk_user = ".$object->id; $sql .= " AND s.entity IN (".getEntity('salary').")"; - $sql .= " GROUP BY s.rowid, s.ref, s.label, s.datesp, s.dateep, s.paye"; + $sql .= " GROUP BY s.rowid, s.ref, s.label, s.datesp, s.dateep, s.paye, s.amount"; $sql .= " ORDER BY s.dateep DESC"; $resql = $db->query($sql); @@ -381,7 +381,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac print '
".$langs->trans("Parameter")."".$langs->trans("Name")."".$langs->trans("ExtSiteUrlAgenda").'
'." (".$langs->trans("Example").': http://yoursite/agenda/agenda.ics)
".$langs->trans("ExtSiteUrlAgenda").'
'." (".$langs->trans("Example").': https://externalcalendar/agenda/agenda.ics)
".$form->textwithpicto($langs->trans("FixTZ"), $langs->trans("FillFixTZOnlyIfRequired"), 1).''.$langs->trans("Color").'
'; print ''; - print ''; print '\n"; - print ''; + print ''; print ''; $i++; } @@ -560,7 +556,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac print_liste_field_titre("RIB"); print_liste_field_titre("IBAN"); print_liste_field_titre("BIC"); - print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch '); + print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', '', '', 'maxwidthsearch '); print "\n"; if ($account->id > 0) { diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 135e2072fdf..152c39f79ac 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1040,6 +1040,7 @@ if ($action == 'create' || $action == 'adduserldap') { // State if (empty($conf->global->USER_DISABLE_STATE)) { print ''; } @@ -1420,10 +1421,12 @@ if ($action == 'create' || $action == 'adduserldap') { if ($object->socid > 0) { $type = $langs->trans("External"); } + print ''; print $type; if ($object->ldap_sid) { print ' ('.$langs->trans("DomainUser").')'; } + print ''; print ''."\n"; // Ldap sid @@ -1448,8 +1451,12 @@ if ($action == 'create' || $action == 'adduserldap') { print ''.$langs->trans("None").''; } else { $huser = new User($db); - $huser->fetch($object->fk_user); - print $huser->getNomUrl(1); + if ($object->fk_user > 0) { + $huser->fetch($object->fk_user); + print $huser->getNomUrl(1); + } else { + print ''.$langs->trans("None").''; + } } print ''; print "\n"; @@ -1533,7 +1540,7 @@ if ($action == 'create' || $action == 'adduserldap') { // Salary print ''; print ''; print "\n"; } @@ -2363,6 +2370,7 @@ if ($action == 'create' || $action == 'adduserldap') { if (empty($conf->global->USER_DISABLE_STATE)) { print ''; print '\n"; @@ -222,8 +223,11 @@ if ($resql) { print ''; } print ''; - print ''; + print ''; print ''; + print ''; print ''; print "\n"; $i++; diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index 6073ca4c88f..0413fda69b0 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -42,9 +42,11 @@ if ($user->socid > 0) { $socid = $user->socid; } -$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); -$search_user = GETPOST('search_user', 'alpha'); $optioncss = GETPOST('optioncss', 'alpha'); +$contextpage = GETPOST('optioncss', 'aZ09'); +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); // Load mode employee $mode = GETPOST("mode", 'alpha'); @@ -94,7 +96,7 @@ if (!is_array($user_arbo) && $user_arbo < 0) { $data[] = array('rowid'=>0, 'fk_menu'=>-1, 'title'=>"racine", 'mainmenu'=>'', 'leftmenu'=>'', 'fk_mainmenu'=>'', 'fk_leftmenu'=>''); foreach ($fulltree as $key => $val) { $userstatic->id = $val['id']; - $userstatic->ref = $val['label']; + $userstatic->ref = $val['id']; $userstatic->login = $val['login']; $userstatic->firstname = $val['firstname']; $userstatic->lastname = $val['lastname']; @@ -146,6 +148,8 @@ if (!is_array($user_arbo) && $user_arbo < 0) { $newcardbutton = ''; $newcardbutton .= dolGetButtonTitle($langs->trans('NewUser'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/user/card.php?action=create'.($mode == 'employee' ? '&employee=1' : '').'&leftmenu=', '', $canadduser); + $morehtmlright = ''; + $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 : '')); $param = array('morecss'=>'marginleftonly btnTitleSelected'); $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, $param); diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php index 978c2d990b7..3acad0ac0c3 100644 --- a/htdocs/user/notify/card.php +++ b/htdocs/user/notify/card.php @@ -437,7 +437,7 @@ if ($result > 0) { } print ''; - if ($optioncss != '') { + if (isset($optioncss) && $optioncss != '') { print ''; } print ''; diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index b492e31177f..72f9b075be9 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -370,10 +370,12 @@ if ($action == 'edit') { print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo print '> '.$langs->trans("UsePersonalValue").''; print ''; diff --git a/htdocs/user/passwordforgotten.php b/htdocs/user/passwordforgotten.php index cb149f1e481..32fa93cb8a6 100644 --- a/htdocs/user/passwordforgotten.php +++ b/htdocs/user/passwordforgotten.php @@ -87,14 +87,14 @@ if (empty($reshook)) { // Validate new password if ($action == 'validatenewpassword' && $username && $passworduidhash) { $edituser = new User($db); - $result = $edituser->fetch('', $_GET["username"]); + $result = $edituser->fetch('', $username); if ($result < 0) { $message = '
'.dol_escape_htmltag($langs->trans("ErrorLoginDoesNotExists", $username)).'
'; } else { global $dolibarr_main_instance_unique_id; //print $edituser->pass_temp.'-'.$edituser->id.'-'.$dolibarr_main_instance_unique_id.' '.$passworduidhash; - if (dol_verifyHash($edituser->pass_temp.'-'.$edituser->id.'-'.$dolibarr_main_instance_unique_id, $passworduidhash)) { + if ($edituser->pass_temp && dol_verifyHash($edituser->pass_temp.'-'.$edituser->id.'-'.$dolibarr_main_instance_unique_id, $passworduidhash)) { // Clear session unset($_SESSION['dol_login']); $_SESSION['dol_loginmesg'] = $langs->trans('NewPasswordValidated'); // Save message for the session page @@ -128,7 +128,7 @@ if (empty($reshook)) { } if ($result <= 0 && $edituser->error == 'USERNOTFOUND') { - $message = ''; - } elseif (is_array($permsgroupbyentity[$entity])) { + } elseif (isset($permsgroupbyentity[$entity]) && is_array($permsgroupbyentity[$entity])) { if (in_array($obj->id, $permsgroupbyentity[$entity])) { // Permission granted by group if ($caneditperms) { print '
'; + print ''; print ''; @@ -389,16 +389,17 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac while ($i < $num && $i < $MAXLIST) { $objp = $db->fetch_object($resql); - $payment_salary->id = $objp->rowid; - $payment_salary->ref = $objp->ref; - $payment_salary->datep = $db->jdate($objp->datep); - $salary->id = $objp->sid; $salary->ref = $objp->sref ? $objp->sref : $objp->sid; $salary->label = $objp->label; $salary->datesp = $db->jdate($objp->datesp); $salary->dateep = $db->jdate($objp->dateep); $salary->paye = $objp->paye; + $salary->amount = $objp->amount; + + $payment_salary->id = $objp->rowid; + $payment_salary->ref = $objp->ref; + $payment_salary->datep = $db->jdate($objp->datep); print ''; print '\n"; print '\n"; - //print ''; + print ''; print ''; print ''; @@ -416,7 +417,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac $db->free($resql); if ($num <= 0) { - print '
'.$langs->trans("LastSalaries", ($num <= $MAXLIST ? "" : $MAXLIST)).''.$langs->trans("AllSalaries").''.$num.''; print '
'.$langs->trans("LastSalaries", ($num <= $MAXLIST ? "" : $MAXLIST)).''.$langs->trans("AllSalaries").''.$num.'
'; @@ -407,7 +408,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac print ''.dol_print_date($db->jdate($objp->datesp), 'day')."'.dol_print_date($db->jdate($objp->dateep), 'day')."'.price($objp->amount).''.price($objp->amount).''.$salary->getLibStatut(5, $objp->alreadypaid).'
'.$langs->trans("None").''; + print ''.$langs->trans("None").''; } print "
"; } else { @@ -424,9 +425,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac } } - /* - * Last holidays - */ + // Latest leave requests if (!empty($conf->holiday->enabled) && ($user->rights->holiday->readall || ($user->rights->holiday->read && $object->id == $user->id)) ) { @@ -478,9 +477,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac } } - /* - * Last expense report - */ + // Latest expense report if (!empty($conf->expensereport->enabled) && ($user->rights->expensereport->readall || ($user->rights->expensereport->lire && $object->id == $user->id)) ) { @@ -509,14 +506,13 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac $exp->id = $objp->rowid; $exp->ref = $objp->ref; - $exp->fk_type = $objp->fk_type; $exp->status = $objp->status; print '
'; print $exp->getNomUrl(1); print ''.dol_print_date($db->jdate($objp->date_debut), 'day')."'.price($objp->total_ttc).''.price($objp->total_ttc).''.$exp->LibStatut($objp->status, 5).'
'.$form->editfieldkey('State', 'state_id', '', $object, 0).''; + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($object->state_id, $object->country_code, 'state_id'); print '
'.$langs->trans("Salary").''; - print ($object->salary != '' ? img_picto('', 'salary', 'class="pictofixedwidth paddingright"').price($object->salary, '', $langs, 1, -1, -1, $conf->currency) : ''); + print ($object->salary != '' ? img_picto('', 'salary', 'class="pictofixedwidth paddingright"').''.price($object->salary, '', $langs, 1, -1, -1, $conf->currency) : '').''; print '
'.$form->editfieldkey('State', 'state_id', '', $object, 0).''; if ($caneditfield) { + print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($object->state_id, $object->country_code, 'state_id'); } else { print $object->state_label; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 37ce6544cd0..74137537e74 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -442,7 +442,7 @@ class User extends CommonObject if ($entity < 0) { if ((empty($conf->multicompany->enabled) || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) && (!empty($user->entity))) { - $sql .= " WHERE u.entity IN (0, ".$this->db->sanitize($conf->entity).")"; + $sql .= " WHERE u.entity IN (0, ".((int) $conf->entity).")"; } else { $sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database } @@ -451,7 +451,7 @@ class User extends CommonObject if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database } else { - $sql .= " WHERE u.entity IN (0, ".$this->db->sanitize(($entity != '' && $entity >= 0) ? $entity : $conf->entity).")"; // search in entity provided in parameter + $sql .= " WHERE u.entity IN (0, ".((int) (($entity != '' && $entity >= 0) ? $entity : $conf->entity)).")"; // search in entity provided in parameter } } @@ -2109,8 +2109,8 @@ class User extends CommonObject $outputlangs = new Translate("", $conf); if (isset($this->conf->MAIN_LANG_DEFAULT) - && $this->conf->MAIN_LANG_DEFAULT != 'auto') { // If user has defined its own language (rare because in most cases, auto is used) - $outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT); + && $this->conf->MAIN_LANG_DEFAULT != 'auto') { // If user has defined its own language (rare because in most cases, auto is used) + $outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT); } if ($this->conf->MAIN_LANG_DEFAULT) { @@ -2184,7 +2184,7 @@ class User extends CommonObject '', '', $trackid - ); + ); if ($mailfile->sendfile()) { return 1; @@ -3222,7 +3222,7 @@ class User extends CommonObject foreach ($this->users as $key => $val) { if (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath']) || preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath'])) { - unset($this->users[$key]); + unset($this->users[$key]); } } } @@ -3298,7 +3298,7 @@ class User extends CommonObject $i = 0; $cursor_user = $id_user; $useridfound = array($id_user); - while (!empty($this->parentof[$cursor_user])) { + while (!empty($this->parentof[$cursor_user]) && !empty($this->users[$this->parentof[$cursor_user]])) { if (in_array($this->parentof[$cursor_user], $useridfound)) { dol_syslog("The hierarchy of user has a recursive loop", LOG_WARNING); return -1; // Should not happen. Protection against looping hierarchy diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 083b1bcc18c..1f0bb2891c6 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -711,7 +711,7 @@ class UserGroup extends CommonObject * Use this->id,this->lastname, this->firstname * * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small) - * @param string $option On what the link point to ('nolink', ) + * @param string $option On what the link point to ('nolink', 'permissions') * @param integer $notooltip 1=Disable tooltip on picto and name * @param string $morecss Add more css on link * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking @@ -730,12 +730,16 @@ class UserGroup extends CommonObject $result = ''; $label = ''; $label .= '
'; - $label .= ''.$langs->trans("Group").'
'; + $label .= img_picto('', 'group').' '.$langs->trans("Group").'
'; $label .= ''.$langs->trans('Name').': '.$this->name; $label .= '
'.$langs->trans("Description").': '.$this->note; $label .= '
'; - $url = DOL_URL_ROOT.'/user/group/card.php?id='.$this->id; + if ($option == 'permissions') { + $url = DOL_URL_ROOT.'/user/group/perms.php?id='.$this->id; + } else { + $url = DOL_URL_ROOT.'/user/group/card.php?id='.$this->id; + } if ($option != 'nolink') { // Add param to save lastsearch_values or not diff --git a/htdocs/user/clicktodial.php b/htdocs/user/clicktodial.php index 0a9a65a2852..79450f2d811 100644 --- a/htdocs/user/clicktodial.php +++ b/htdocs/user/clicktodial.php @@ -150,7 +150,9 @@ if ($id > 0) { if (!empty($user->admin)) { print '
ClickToDial URL'; - $url = $conf->global->CLICKTODIAL_URL; + if (!empty($conf->global->CLICKTODIAL_URL)) { + $url = $conf->global->CLICKTODIAL_URL; + } if (!empty($object->clicktodial_url)) { $url = $object->clicktodial_url; } diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 0e60e70e42a..5c1e16e4a0c 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -428,6 +428,7 @@ if ($action == 'create') { * Group members */ + print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; print ''; print ''; @@ -440,7 +441,7 @@ if ($action == 'create') { if (!empty($object->members)) { foreach ($object->members as $useringroup) { print ''; - print ''; } print "
'.$langs->trans("Login").'
'; + print ''; print $useringroup->getNomUrl(-1, '', 0, 0, 24, 0, 'login'); if ($useringroup->admin && !$useringroup->entity) { print img_picto($langs->trans("SuperAdministrator"), 'redstar'); @@ -465,6 +466,7 @@ if ($action == 'create') { print '
'.$langs->trans("None").'
"; + print '
'; } print "
"; diff --git a/htdocs/user/group/list.php b/htdocs/user/group/list.php index 302d697c563..04fa0035418 100644 --- a/htdocs/user/group/list.php +++ b/htdocs/user/group/list.php @@ -35,6 +35,7 @@ $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', $search_group = GETPOST('search_group'); $optioncss = GETPOST('optioncss', 'alpha'); $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$contextpage = GETPOST('optioncss', 'aZ09'); // Defini si peux lire/modifier utilisateurs et permisssions $caneditperms = ($user->admin || $user->rights->user->user->creer); @@ -122,7 +123,7 @@ if (empty($reshook)) { llxHeader(); -$sql = "SELECT g.rowid, g.nom as name, g.note, g.entity, g.datec, COUNT(DISTINCT ugu.fk_user) as nb, COUNT(DISTINCT ugr.fk_id) as nbpermissions"; +$sql = "SELECT g.rowid, g.nom as name, g.note, g.entity, g.datec, g.tms as datem, COUNT(DISTINCT ugu.fk_user) as nb, COUNT(DISTINCT ugr.fk_id) as nbpermissions"; $sql .= " FROM ".MAIN_DB_PREFIX."usergroup as g"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_usergroup = g.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_rights as ugr ON ugr.fk_usergroup = g.rowid"; @@ -137,7 +138,7 @@ if (!empty($search_group)) { if ($sall) { $sql .= natural_search(array("g.nom", "g.note"), $sall); } -$sql .= " GROUP BY g.rowid, g.nom, g.note, g.entity, g.datec"; +$sql .= " GROUP BY g.rowid, g.nom, g.note, g.entity, g.datec, g.tms"; $sql .= $db->order($sortfield, $sortorder); $resql = $db->query($sql); @@ -168,7 +169,6 @@ if ($resql) { print ''; print ''; print ''; - print ''; print ''; print_barre_liste($text, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $nbtotalofrecords, 'object_group', 0, $newcardbutton, '', $limit, 0, 0, 1); @@ -197,6 +197,7 @@ if ($resql) { print_liste_field_titre("NbOfUsers", $_SERVER["PHP_SELF"], "nb", $param, "", '', $sortfield, $sortorder, 'center '); print_liste_field_titre("NbOfPermissions", $_SERVER["PHP_SELF"], "nbpermissions", $param, "", '', $sortfield, $sortorder, 'center '); print_liste_field_titre("DateCreationShort", $_SERVER["PHP_SELF"], "g.datec", $param, "", '', $sortfield, $sortorder, 'center '); + print_liste_field_titre("DateLastModification", $_SERVER["PHP_SELF"], "g.tms", $param, "", '', $sortfield, $sortorder, 'center '); print_liste_field_titre("", $_SERVER["PHP_SELF"]); print "
'.$mc->label.''.$obj->nb.''.$obj->nbpermissions.''; + print ''.$obj->nbpermissions.''; + print ''.dol_print_date($db->jdate($obj->datec), "dayhour").''.dol_print_date($db->jdate($obj->datem), "dayhour").'
'; - if (!empty($tmparray[$object->conf->MAIN_LANDING_PAGE])) { - print $langs->trans($tmparray[$object->conf->MAIN_LANDING_PAGE]); - } else { - print $object->conf->MAIN_LANDING_PAGE; + if (!empty($object->conf->MAIN_LANDING_PAGE)) { + if (!empty($tmparray[$object->conf->MAIN_LANDING_PAGE])) { + print $langs->trans($tmparray[$object->conf->MAIN_LANDING_PAGE]); + } else { + print $object->conf->MAIN_LANDING_PAGE; + } } //print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (! empty($object->conf->MAIN_LANDING_PAGE)?$object->conf->MAIN_LANDING_PAGE:''), 0, 0, 0, '', 1); print '
'; print img_picto($langs->trans("Active"), 'tick'); print ''; diff --git a/test/phpunit/FormAdminTest.php b/test/phpunit/FormAdminTest.php index 79019e1e7ed..7217f3b57e2 100644 --- a/test/phpunit/FormAdminTest.php +++ b/test/phpunit/FormAdminTest.php @@ -139,7 +139,7 @@ class FormAdminTest extends PHPUnit\Framework\TestCase $db=$this->savdb; $localobject=new FormAdmin($this->savdb); - $result=$localobject->select_paper_format('', 'paperformat_id', 'A4'); + $result=$localobject->select_paper_format('', 'paperformat_id', 'A4', 0, 1); $this->assertEquals($result, ''); print __METHOD__." result=".$result."\n"; diff --git a/test/phpunit/JsonLibTest.php b/test/phpunit/JsonLibTest.php index ddb62a90204..a8619ae08c5 100644 --- a/test/phpunit/JsonLibTest.php +++ b/test/phpunit/JsonLibTest.php @@ -161,6 +161,15 @@ class JsonLibTest extends PHPUnit\Framework\TestCase $this->savlangs=$langs; $this->savdb=$db; + // Try to decode a string encoded with serialize + $encoded = 'a:1:{s:7:"options";a:3:{s:3:"app";s:11:"Application";s:6:"system";s:6:"System";s:6:"option";s:6:"Option";}}'; + $decoded=json_decode($encoded, true); + $this->assertEquals(null, $decoded, 'test to json_decode() a string that was encoded with serialize()'); + + $encoded = 'rubishstring!aa{bcd'; + $decoded=json_decode($encoded, true); + $this->assertEquals(null, $decoded, 'test to json_decode() a string that was encoded with serialize()'); + // Do a test with an array starting with 0 $arraytotest=array(0=>array('key'=>1,'value'=>'PRODREF','label'=>'Product ref with é and special chars \\ \' "')); $arrayencodedexpected='[{"key":1,"value":"PRODREF","label":"Product ref with \u00e9 and special chars \\\\ \' \""}]'; diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 08d4ec88703..44b391148f5 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -321,6 +321,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase $test="XSS"; $result=testSqlAndScriptInject($test, 0); $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject lll'); + + $test="Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)"; + $result=testSqlAndScriptInject($test, 0); // result must be 0 + $this->assertEquals(0, $result, 'Error on testSqlAndScriptInject mmm'); } /** @@ -336,6 +340,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase $langs=$this->savlangs; $db=$this->savdb; + // Force default mode + $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 0; + $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 0; + $_COOKIE["id"]=111; $_GET["param1"]="222"; $_POST["param1"]="333"; @@ -358,6 +366,8 @@ class SecurityTest extends PHPUnit\Framework\TestCase $_POST["param12"]='aaa'; $_POST["param13"]='n n > < " XSS'; $_POST["param13b"]='n n > < " XSS'; + $_POST["param14"]="Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)"; + $_POST["param15"]=" src=>0xbeefed"; //$_POST["param13"]='javascript%26colon%26%23x3B%3Balert(1)'; //$_POST["param14"]='javascripT&javascript#x3a alert(1)'; @@ -475,7 +485,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase // Test with restricthtml we must remove html open/close tag and content but not htmlentities (we can decode html entities for ascii chars like n) $result=GETPOST("param6", 'restricthtml'); - print __METHOD__." result=".$result."\n"; + print __METHOD__." result param6=".$result."\n"; $this->assertEquals('">', $result); $result=GETPOST("param7", 'restricthtml'); @@ -494,6 +504,33 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals('n n > < " XSS', $result, 'Test 13b that HTML entities are decoded with restricthtml, but only for common alpha chars'); + $result=GETPOST("param14", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals("Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)", $result, 'Test 14'); + + $result=GETPOST("param15", 'restricthtml'); // src=>0xbeefed + print __METHOD__." result=".$result."\n"; + $this->assertEquals("0xbeefed", $result, 'Test 15a'); // The GETPOST return a harmull string + + // Test with restricthtml + MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES to test disabling of bad atrributes + $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML = 1; + + $result=GETPOST("param15", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('InvalidHTMLString', $result, 'Test 15b'); + + unset($conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML); + + // Test with restricthtml + MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES to test disabling of bad atrributes + $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = 1; + + $result=GETPOST("param15", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('0xbeefed', $result, 'Test 15b'); + + unset($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES); + + // Special test for GETPOST of backtopage, backtolist or backtourl parameter $_POST["backtopage"]='//www.google.com'; @@ -789,8 +826,8 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=dol_sanitizeFileName('bad file | evilaction'); $this->assertEquals('bad file _ evilaction', $result); - $result=dol_sanitizeFileName('bad file --evilparam'); - $this->assertEquals('bad file _evilparam', $result); + $result=dol_sanitizeFileName('bad file -evilparam --evilparam ---evilparam ----evilparam'); + $this->assertEquals('bad file _evilparam _evilparam _evilparam _evilparam', $result); } /**