diff --git a/ChangeLog b/ChangeLog index a9a42c8d878..3dd00815d51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,62 @@ English Dolibarr ChangeLog -------------------------------------------------------------- + +***** ChangeLog for 16.0.0 compared to 15.0.0 ***** + +For users: +--------------- + +NEW: ... + + + Modules +NEW: Experimental module Event Organization Management +NEW: Experimental module Workstations Management +NEW: Experimental module Partnership Management + + +For developers: +--------------- + +NEW: + + + +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* verifCond('stringtoevaluate') now return false when string contains a bad syntax content instead of true. +* The deprecated mdethod thirdparty_doc_create() has been removed. You can use the generateDocument() instead. + + + +***** ChangeLog for 15.0.1 compared to 15.0.0 ***** +FIX: #19777 #20281 +FIX: bad position of extrafields for interventions +FIX: Blocking situation when a payment was deleted in bank. +FIX: creation of the shipment if order contains services +FIX: Drag and drop line of files on join files tab +FIX: Error management on mass action "Approve holiday" +FIX: error with php8 +FIX: in case of VAT refund, negative amount must be allowed +FIX: invoice pdf: lines originating from deposits were not detailed anymore +FIX: Invoice - When you create an invoice for a given thirdparty, fk_account is not retrieved from company card +FIX: list of visible type of event was not correctly filtered +FIX: Missing or bad permissions +FIX: Missing the field date start/end in export supplier invoice/order +FIX: On large proposal or invoice, fix n(n+1) sql into a n sql. +FIX: options should not exists on invoices +FIX: payment not completed when using Paypal. +FIX: permission to download files of expense report with readall. +FIX- Preview icon in documents list PDF in the admin page third-party +FIX: shipping list, e.shipping_method_id should be e.fk_shipping_method. +FIX: Show product photo on Supplier order Cornas model. +FIX: User name in ManufacturingOrder +FIX: viewimage.php blocks requests with multicompany from other enties +FIX: #yogosha9048 +FIX: #yogosha9054 +FIX: #yogosha9095 + + ***** ChangeLog for 15.0.0 compared to 14.0.0 ***** For users: @@ -10,6 +66,7 @@ For users: NEW: Online proposal signature NEW: Can define some max limit on expense report (per period, per type or expense, ...) +NEW: Provide a special pages for bookmarks and multicompany for a better use of some mobile applications (like DoliDroid) NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation. NEW: Add option to disable globaly some notifications emails. NEW: #18401 Add __NEWREF__ subtitute to get new object reference. diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 67f521806cb..a760a550bef 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -190,7 +190,7 @@ $arrayfields = array( 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), - 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), + 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { @@ -678,19 +678,28 @@ $formconfirm = ''; if ($action == 'export_file') { $form_question = array(); + // If 1 or not set, we check by default. + $checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE)); $form_question['notifiedexportdate'] = array( 'name' => 'notifiedexportdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedExportDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), + 'value' => $checked, ); + + $form_question['separator'] = array('name'=>'separator', 'type'=>'separator'); + + // If 0 or not set, we NOT check by default. + $checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE)); $form_question['notifiedvalidationdate'] = array( 'name' => 'notifiedvalidationdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedValidationDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) ? 'false' : 'true'), + 'value' => $checked, ); + $form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator'); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); } @@ -823,7 +832,7 @@ if (!empty($arrayfields['t.piece_num']['checked'])) { // Code journal if (!empty($arrayfields['t.code_journal']['checked'])) { print ''; - print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'maxwidth150'); + print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'small maxwidth150'); print ''; } // Date document @@ -845,10 +854,10 @@ if (!empty($arrayfields['t.doc_ref']['checked'])) { if (!empty($arrayfields['t.numero_compte']['checked'])) { print ''; print '
'; - print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'account'); + print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth150', 'account'); print '
'; print '
'; - print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'account'); + print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth150', 'account'); print '
'; print ''; } @@ -1125,24 +1134,25 @@ while ($i < min($num, $limit)) { // Other type } - print ''; - - print ''; - // Picto + Ref - print '
'; - + $labeltoshow = ''; + $labeltoshowalt = ''; if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { - print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); - print $documentlink; + $labeltoshow .= $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); + $labeltoshow .= $documentlink; + $labeltoshowalt .= $objectstatic->ref; } elseif ($line->doc_type == 'bank') { - print $objectstatic->getNomUrl(1); + $labeltoshow .= $objectstatic->getNomUrl(1); + $labeltoshowalt .= $objectstatic->ref; $bank_ref = strstr($line->doc_ref, '-'); - print " " . $bank_ref; + $labeltoshow .= " " . $bank_ref; + $labeltoshowalt .= " " . $bank_ref; } else { - print $line->doc_ref; + $labeltoshow .= $line->doc_ref; + $labeltoshowalt .= $line->doc_ref; } - print '
'; + print ''; + print $labeltoshow; print "\n"; if (!$i) { $totalarray['nbfield']++; @@ -1167,7 +1177,7 @@ while ($i < min($num, $limit)) { // Label operation if (!empty($arrayfields['t.label_operation']['checked'])) { - print ''.$line->label_operation.''; + print ''.dol_escape_htmltag($line->label_operation).''; if (!$i) { $totalarray['nbfield']++; } @@ -1228,7 +1238,7 @@ while ($i < min($num, $limit)) { // Exported operation date if (!empty($arrayfields['t.date_export']['checked'])) { - print ''.dol_print_date($line->date_export, 'dayhour').''; + print ''.dol_print_date($line->date_export, 'dayhour').''; if (!$i) { $totalarray['nbfield']++; } @@ -1236,7 +1246,7 @@ while ($i < min($num, $limit)) { // Validated operation date if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''.dol_print_date($line->date_validation, 'dayhour').''; + print ''.dol_print_date($line->date_validation, 'dayhour').''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/accountancy/closure/index.php b/htdocs/accountancy/closure/index.php index 6b578bcab71..f02eda61bf6 100644 --- a/htdocs/accountancy/closure/index.php +++ b/htdocs/accountancy/closure/index.php @@ -13,7 +13,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * */ /** diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index caf2bbe61d6..5bdb99330f6 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1719,8 +1719,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("MemberNature").''.$object->getmorphylib().''; print ''; - print ''; - // Company print ''.$langs->trans("Company").''.dol_escape_htmltag($object->company).''; @@ -1737,9 +1735,9 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($user->admin) { print ''; } - print 'trans("Hidden").''; + print ''.$langs->trans("Hidden").''; } - if ((!empty($object->pass) || !empty($object->pass_crypted)) && empty($object->user_id)) { + if (!empty($object->pass_indatabase) && empty($object->user_id)) { // Show warning only for old password still in clear (does not happen anymore) $langs->load("errors"); $htmltext = $langs->trans("WarningPasswordSetWithNoAccount"); print ' '.$form->textwithpicto('', $htmltext, 1, 'warning'); @@ -1778,7 +1776,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
'; print '
'; - print ''; + print '
'; // Tags / Categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { @@ -1853,18 +1851,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } print ''; - // VCard - /* - print ''; - */ - print "
'; - print $langs->trans("VCard").''; - print ''; - print img_picto($langs->trans("Download").' vcard', 'vcard.png', 'class="paddingrightonly"'); - print $langs->trans("Download"); - print img_picto($langs->trans("Download").' vcard', 'download', 'class="paddingleft"'); - print ''; - print '
\n"; print "
\n"; diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 5f578869e6e..7dccaa90eda 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -501,7 +501,7 @@ if ($rowid > 0) { // Login if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) { - print ''.$langs->trans("Login").' / '.$langs->trans("Id").''.$object->login.' '; + print ''.$langs->trans("Login").' / '.$langs->trans("Id").''.dol_escape_htmltag($object->login).''; } // Type @@ -512,25 +512,24 @@ if ($rowid > 0) { print ''; // Company - print ''.$langs->trans("Company").''.$object->company.''; + print ''.$langs->trans("Company").''.dol_escape_htmltag($object->company).''; // Civility - print ''.$langs->trans("UserTitle").''.$object->getCivilityLabel().' '; + print ''.$langs->trans("UserTitle").''.$object->getCivilityLabel().''; print ''; // Password if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) { - print ''.$langs->trans("Password").''.preg_replace('/./i', '*', $object->pass); + print ''.$langs->trans("Password").''; if ($object->pass) { print preg_replace('/./i', '*', $object->pass); } else { if ($user->admin) { - print $langs->trans("Crypted").': '.$object->pass_indatabase_crypted; - } else { - print $langs->trans("Hidden"); + print ''; } + print ''.$langs->trans("Hidden").''; } - if ((!empty($object->pass) || !empty($object->pass_crypted)) && empty($object->user_id)) { + if (!empty($object->pass_indatabase) && empty($object->user_id)) { // Show warning only for old password still in clear (does not happen anymore) $langs->load("errors"); $htmltext = $langs->trans("WarningPasswordSetWithNoAccount"); print ' '.$form->textwithpicto('', $htmltext, 1, 'warning'); @@ -546,15 +545,17 @@ if ($rowid > 0) { print " ".img_warning($langs->trans("Late")); } } else { - if (!$adht->subscription) { + if ($object->need_subscription == 0) { + print $langs->trans("SubscriptionNotNeeded"); + } elseif (!$adht->subscription) { print $langs->trans("SubscriptionNotRecorded"); - if ($object->statut > 0) { - print " ".img_warning($langs->trans("Late")); // Display a delay picto only if it is not a draft and is not canceled + if (Adherent::STATUS_VALIDATED == $object->statut) { + print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft, not excluded and not resiliated } } else { print $langs->trans("SubscriptionNotReceived"); - if ($object->statut > 0) { - print " ".img_warning($langs->trans("Late")); // Display a delay picto only if it is not a draft and is not canceled + if (Adherent::STATUS_VALIDATED == $object->statut) { + print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft, not excluded and not resiliated } } } @@ -563,18 +564,13 @@ if ($rowid > 0) { print ''; print ''; - print '
'; + print '
'; print '
'; + print ''; - // Birthday - print ''; - - // Public - print ''; - - // Categories + // Tags / Categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { print ''; print ''; } + // Birth Date + print ''; + + // Public + print ''; + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -663,8 +665,6 @@ if ($rowid > 0) { print dol_get_fiche_end(); - print ''; - /* * Action bar diff --git a/htdocs/adherents/tpl/linkedobjectblock.tpl.php b/htdocs/adherents/tpl/linkedobjectblock.tpl.php index 3acb14a4cdb..5928b706a8e 100644 --- a/htdocs/adherents/tpl/linkedobjectblock.tpl.php +++ b/htdocs/adherents/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 437d58aeac9..74d26e29da5 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -8,7 +8,7 @@ * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2021 Alexandre Spangaro + * Copyright (C) 2011-2022 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019-2020 Frédéric France @@ -201,7 +201,7 @@ $tabsql = array(); $tabsql[1] = "SELECT f.rowid as rowid, f.code, f.libelle, c.code as country_code, c.label as country, f.active FROM ".MAIN_DB_PREFIX."c_forme_juridique as f, ".MAIN_DB_PREFIX."c_country as c WHERE f.fk_pays=c.rowid"; $tabsql[2] = "SELECT d.rowid as rowid, d.code_departement as code, d.nom as libelle, d.fk_region as region_id, r.nom as region, c.code as country_code, c.label as country, d.active FROM ".MAIN_DB_PREFIX."c_departements as d, ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE d.fk_region=r.code_region and r.fk_pays=c.rowid and r.active=1 and c.active=1"; $tabsql[3] = "SELECT r.rowid as rowid, r.code_region as state_code, r.nom as libelle, r.fk_pays as country_id, c.code as country_code, c.label as country, r.active FROM ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE r.fk_pays=c.rowid and c.active=1"; -$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite FROM ".MAIN_DB_PREFIX."c_country AS c"; +$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite, c.eec FROM ".MAIN_DB_PREFIX."c_country AS c"; $tabsql[5] = "SELECT c.rowid as rowid, c.code as code, c.label, c.active FROM ".MAIN_DB_PREFIX."c_civility AS c"; $tabsql[6] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.type, a.active, a.module, a.color, a.position FROM ".MAIN_DB_PREFIX."c_actioncomm AS a"; $tabsql[7] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.accountancy_code as accountancy_code, c.code as country_code, c.label as country, a.fk_pays as country_id, a.active FROM ".MAIN_DB_PREFIX."c_chargesociales AS a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_pays=c.rowid and c.active=1"; @@ -1093,6 +1093,45 @@ if ($action == 'disable_favorite') { } } +// Is in EEC - Activate +if ($action == 'activate_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } +} + +// Is in EEC - Disable +if ($action == 'disable_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } +} /* * View @@ -1452,6 +1491,7 @@ if ($id) { if ($id == 4) { $tdsoffields .= ''; + $tdsoffields .= ''; } $tdsoffields .= ''; + print ''; } print ''; + print ''; } print ''; print ''; + print ''; if (!$conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail') { + print ''; } else { + print ''; } - print ''; + print ''; // Port @@ -305,7 +315,7 @@ if ($action == 'edit') { if (!$conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail') { print $langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike"); print ''; // STARTTLS - print ''; // SMTP_ALLOW_SELF_SIGNED_EMAILING - print ''; } diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index a5bcfb85fea..40656928824 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -406,7 +406,7 @@ print '

'; print '
'; -print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', 'folder'); +print load_fiche_titre($langs->trans("OtherSetup"), '', 'folder'); //print ''.$langs->trans("PasswordEncryption").': '; @@ -439,19 +439,24 @@ print '
'; print 'MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE = '.(empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE).'   ('.$langs->trans("Recommended").': 1)
'; print '
'; +print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN).'   ('.$langs->trans("Recommended").': 2)'."
"; +print '
'; + +print '
'; +print '
'; + + +print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', 'folder'); + print 'MAIN_RESTRICTHTML_ONLY_VALID_HTML = '.(empty($conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 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("Recommended").': 1)' : $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)."
"; print '
'; -print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN).'   ('.$langs->trans("Recommended").': 2)'."
"; -print '
'; - print 'MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL = '.(empty($conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)' : $conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL)."
"; print '
'; - print 'MAIN_EXEC_USE_POPEN = '; if (empty($conf->global->MAIN_EXEC_USE_POPEN)) { print ''.$langs->trans("Undefined").''; diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index c36f6ae1d1b..68f256e2009 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -203,6 +203,12 @@ if ($action == 'setvarother') { if (!($res > 0)) { $error++; } + + $param_auto_notify_close = GETPOST('TICKET_NOTIFY_AT_CLOSING', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_NOTIFY_AT_CLOSING', $param_auto_notify_close, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } } @@ -530,6 +536,21 @@ print $form->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, print ''; print ''; +// Auto notify contacts when closing the ticket +print ''; +print ''; +print ''; +print ''; + if (!$conf->use_javascript_ajax) { print ''; } diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index 818141e5cde..88a7db9b1d7 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -327,33 +327,6 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHelpMessageHelpAdmin"), 1, 'help'); print ''; - // Activate email creation to user - print ''; - print ''; - print ''; - print ''; - - // Texte de création d'un ticket - $mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody'); - print ''; - print ''; - // Url public interface $url_interface = $conf->global->TICKET_URL_PUBLIC_INTERFACE; print ''; + print '
'.$langs->trans("DateOfBirth").''.dol_print_date($object->birth, 'day').'
'.$langs->trans("Public").''.yn($object->public).'
'.$langs->trans("Categories").''; @@ -582,6 +578,12 @@ if ($rowid > 0) { print '
'.$langs->trans("DateOfBirth").''.dol_print_date($object->birth, 'day').'
'.$langs->trans("Public").''.yn($object->public).'
'; $tdsoffields .= ''; @@ -1496,6 +1536,7 @@ if ($id) { if ($id == 4) { print ''; if ($action != 'edit') { @@ -1569,6 +1610,7 @@ if ($id) { } if ($id == 4) { print ''; @@ -1592,10 +1634,10 @@ if ($id) { // Determines the name of the field in relation to the possible names // in data dictionaries - $showfield = 1; // By defaut + $showfield = 1; // By default $cssprefix = ''; $sortable = 1; - $valuetoshow = ucfirst($value); // By defaut + $valuetoshow = ucfirst($value); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate // Special cases @@ -1794,8 +1836,9 @@ if ($id) { print getTitleFieldOfList($newvaluetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $value : ''), ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $cssprefix); } } - // Favorite - Only activated on country dictionary + // Favorite & EEC - Only activated on country dictionary if ($id == 4) { + print getTitleFieldOfList($langs->trans("InEEC"), 0, $_SERVER["PHP_SELF"], "eec", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder, '', 0, $langs->trans("CountryIsInEEC")); print getTitleFieldOfList($langs->trans("Favorite"), 0, $_SERVER["PHP_SELF"], "favorite", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); } @@ -2089,10 +2132,19 @@ if ($id) { } $url .= '&'; - // Favorite + // Favorite & EEC // Only activated on country dictionary if ($id == 4) { print ''; + // Is in EEC + if ($iserasable) { + print ''.$actl[$obj->eec].''; + } else { + print $langs->trans("AlwaysActive"); + } + print ''; + // Favorite if ($iserasable) { print ''.$actl[$obj->favorite].''; } else { diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index fc8e24b9322..e5cb43d9e1f 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -50,7 +50,7 @@ $substitutionarrayfortest = array( //'__EMAIL__' => 'RecipientEMail', // Done into actions_sendmails '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails - '__LOGIN__' => 'RecipientLogin', + '__LOGIN__' => $user->login, '__LASTNAME__' => 'RecipientLastname', '__FIRSTNAME__' => 'RecipientFirstname', '__ADDRESS__'=> 'RecipientAddress', @@ -662,7 +662,7 @@ if ($action == 'edit') { print '
'.$langs->trans("MAIN_MAIL_EMAIL_DKIM_ENABLED").''; if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('swiftmailer'))) { if (function_exists('openssl_open')) { - print yn($conf->global->MAIN_MAIL_EMAIL_DKIM_ENABLED); + print yn(getDolGlobalInt('MAIN_MAIL_EMAIL_DKIM_ENABLED')); } else { print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; } @@ -887,7 +887,6 @@ if ($action == 'edit') { } setEventMessages($errormsg, null, 'errors'); - print $errormsg; } print '
'; } diff --git a/htdocs/admin/mails_emailing.php b/htdocs/admin/mails_emailing.php index 6b1aa3334b5..40af4c4ae2a 100644 --- a/htdocs/admin/mails_emailing.php +++ b/htdocs/admin/mails_emailing.php @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors')); $action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); if (!$user->admin) { accessforbidden(); @@ -40,17 +40,22 @@ if (!$user->admin) { $usersignature = $user->signature; // For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html. if ($action == 'test' || $action == 'send') { - $usersignature = dol_string_nohtmltag($usersignature); + $usersignature = dol_string_nohtmltag($usersignature, 2); } $substitutionarrayfortest = array( -'__LOGIN__' => $user->login, -'__ID__' => 'TESTIdRecord', -'__EMAIL__' => 'TESTEMail', -'__LASTNAME__' => 'TESTLastname', -'__FIRSTNAME__' => 'TESTFirstname', -'__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), -//'__PERSONALIZED__' => 'TESTPersonalized' // Hiden because not used yet + '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, + '__ID__' => 'RecipientIdRecord', + //'__EMAIL__' => 'RecipientEMail', // Done into actions_sendmails + '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', + '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails + '__LOGIN__' => $user->login, + '__LASTNAME__' => 'RecipientLastname', + '__FIRSTNAME__' => 'RecipientFirstname', + '__ADDRESS__'=> 'RecipientAddress', + '__ZIP__'=> 'RecipientZip', + '__TOWN_'=> 'RecipientTown', + '__COUNTRY__'=> 'RecipientCountry' ); complete_substitutions_array($substitutionarrayfortest, $langs); @@ -86,10 +91,10 @@ $trackid = (($action == 'testhtml') ? "testhtml" : "test"); $sendcontext = 'emailing'; // Force to use dedicated context of setup for emailing include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; -if ($action == 'presend' && GETPOST('trackid') == 'test') { +if ($action == 'presend' && GETPOST('trackid', 'alphanohtml') == 'test') { $action = 'test'; } -if ($action == 'presend' && GETPOST('trackid') == 'testhtml') { +if ($action == 'presend' && GETPOST('trackid', 'alphanohtml') == 'testhtml') { $action = 'testhtml'; } @@ -271,12 +276,15 @@ if ($action == 'edit') { // Host server - print '
'; + print '
'; print $langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike"); print ''; - print $langs->trans("SeeLocalSendMailSetup"); + print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ''; $mainserver = (!empty($conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING) ? $conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING : ''); $smtpserver = ini_get('SMTP') ?ini_get('SMTP') : $langs->transnoentities("Undefined"); if ($linuxlike) { @@ -287,17 +295,19 @@ if ($action == 'edit') { print ''; // SuperAdministrator access only if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) { - print ''; + print ''; print ''; - print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ' '.$langs->trans("SeeLinkToOnlineDocumentation").''; } else { $text = !empty($mainserver) ? $mainserver : $smtpserver; $htmltext = $langs->trans("ContactSuperAdminForChange"); print $form->textwithpicto($text, $htmltext, 1, 'superadmin'); print ''; } + print '
'; - print $langs->trans("SeeLocalSendMailSetup"); + print ''.$langs->trans("SeeLocalSendMailSetup").''; } else { $mainport = (!empty($conf->global->MAIN_MAIL_SMTP_PORT_EMAILING) ? $conf->global->MAIN_MAIL_SMTP_PORT_EMAILING : ''); $smtpport = ini_get('smtp_port') ?ini_get('smtp_port') : $langs->transnoentities("Undefined"); @@ -319,7 +329,7 @@ if ($action == 'edit') { if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) { print ''; print ''; - print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ''.$langs->trans("SeeLocalSendMailSetup").''; } else { $text = (!empty($mainport) ? $mainport : $smtpport); $htmltext = $langs->trans("ContactSuperAdminForChange"); @@ -360,7 +370,6 @@ if ($action == 'edit') { } // TLS - print '
'.$langs->trans("MAIN_MAIL_EMAIL_TLS").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) { if (function_exists('openssl_open')) { @@ -374,7 +383,6 @@ if ($action == 'edit') { print '
'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) { if (function_exists('openssl_open')) { @@ -388,7 +396,6 @@ if ($action == 'edit') { print '
'.$langs->trans("MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) { if (function_exists('openssl_open')) { @@ -414,6 +421,7 @@ if ($action == 'edit') { print ''.$langs->trans("EMailsDesc")."
\n"; print "

\n"; + print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; print ''; @@ -460,7 +468,7 @@ if ($action == 'edit') { print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; } } else { - print yn(0).' ('.$langs->trans("NotSupported").')'; + print ''.yn(0).' ('.$langs->trans("NotSupported").')'; } print ''; @@ -492,6 +500,7 @@ if ($action == 'edit') { } print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print '
'; print dol_get_fiche_end(); @@ -543,6 +552,7 @@ if ($action == 'edit') { // Run the test to connect if ($action == 'testconnect') { + print '
'; print load_fiche_titre($langs->trans("DoTestServerAvailability")); include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; @@ -573,16 +583,18 @@ if ($action == 'edit') { // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); + $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); $formmail->fromname = (GETPOSTISSET('fromname') ? GETPOST('fromname', 'restricthtml') : $conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->frommail = (GETPOSTISSET('frommail') ? GETPOST('frommail', 'restricthtml') : $conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); + $formmail->fromid = $user->id; + $formmail->fromalsorobot = 1; $formmail->withfromreadonly = 0; $formmail->withsubstit = 0; $formmail->withfrom = 1; $formmail->witherrorsto = 1; - $formmail->withto = (!GETPOST('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); - $formmail->withtocc = (!GETPOST(['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty - $formmail->withtoccc = (!GETPOST(['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withto = (GETPOSTISSET('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); + $formmail->withtocc = (GETPOSTISSET(['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withtoccc = (GETPOSTISSET(['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty $formmail->withtopic = (GETPOSTISSET('subject') ? GETPOST('subject') : $langs->trans("Test")); $formmail->withtopicreadonly = 0; $formmail->withfile = 2; @@ -601,7 +613,7 @@ if ($action == 'edit') { $formmail->param["returnurl"] = $_SERVER["PHP_SELF"]; // Init list of files - if (GETPOST("mode") == 'init') { + if (GETPOST("mode", "aZ09") == 'init') { $formmail->clear_attached_files(); } diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index b622ef192ce..c91af2fcc36 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -332,8 +332,8 @@ foreach ($TCurrency as &$currency) { print ''; print '1 '.$conf->currency.' = '; print ' '.$currency->code.' '; - print ' '; - print ''; + print ' '; + print ''; print ''; print '
'.$langs->trans("TicketsAutoNotifyClose").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_NOTIFY_AT_CLOSING'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_NOTIFY_AT_CLOSING", $arrval, $conf->global->TICKET_NOTIFY_AT_CLOSING); +} +print ''; +print $form->textwithpicto('', $langs->trans("TicketsAutoNotifyCloseHelp"), 1, 'help'); +print '
'.$langs->trans("TicketsDisableCustomerEmail").''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); - } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, $conf->global->TICKET_DISABLE_CUSTOMER_MAILS); - } - print ''; - print $form->textwithpicto('', $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); - print '
'.$langs->trans("TicketNewEmailBodyLabel").''; - print ''; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); - $doleditor->Create(); - print ''; - print $form->textwithpicto('', $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); - print '
'.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").''; @@ -364,8 +337,45 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help'); print '
'; + + print '

'; + + print_fiche_titre($langs->trans("Emails")); + + print '
'; + print ''; + + // Activate email creation to user + print ''; + print ''; + print ''; + + // Text of email after creatio of a ticket + $mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody'); + print ''; + print ''; + // Activate email notification when a new message is added - print ''; + print ''; print ''; - print ''; print ''; // Send notification when a new message is added to a email if a user is not assigned to the ticket - print ''; print ''; - print ''; + print ''; print '
'; + print $form->textwithpicto($langs->trans("TicketsDisableCustomerEmail"), $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, $conf->global->TICKET_DISABLE_CUSTOMER_MAILS); + } + print '
'; + print $form->textwithpicto($langs->trans("TicketNewEmailBodyLabel"), $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); + print ''; + print ''; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); + $doleditor->Create(); + print '
'.$langs->trans("TicketsPublicNotificationNewMessage").'
'; + print $form->textwithpicto($langs->trans("TicketsPublicNotificationNewMessage"), $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); + print ''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED'); @@ -374,19 +384,15 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->selectarray("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED", $arrval, $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED); } print ''; - print $form->textwithpicto('', $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); - print '
'.$langs->trans("TicketPublicNotificationNewMessageDefaultEmail").''; + print '
'; + print $form->textwithpicto($langs->trans("TicketPublicNotificationNewMessageDefaultEmail"), $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); print ''; print ''; - print $form->textwithpicto('', $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); - print '
'; print '
'; diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index a3c20d0dffc..bc627cc14f0 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -137,7 +137,8 @@ $dirtocompress = basename($fulldirtocompress); if ($compression == 'zip') { $file .= '.zip'; - $excludefiles = '/(\.back|\.old|\.log|\.pdf_preview-.*\.png|[\/\\\]temp[\/\\\]|documents[\/\\\]admin[\/\\\]documents[\/\\\])/i'; + + $excludefiles = '/(\.back|\.old|\.log|\.pdf_preview-.*\.png|[\/\\\]temp[\/\\\]|[\/\\\]admin[\/\\\]documents[\/\\\])/i'; //var_dump($fulldirtocompress); //var_dump($outputdir."/".$file);exit; diff --git a/htdocs/api/README.md b/htdocs/api/README.md index 7ab85cc26bb..1af112920ce 100644 --- a/htdocs/api/README.md +++ b/htdocs/api/README.md @@ -41,7 +41,7 @@ https://**yourdolibarr.tld**/mydolibarr/api/index.php/otherservice?DOLAPIKEY=**a Develop an API -------------- -The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples http://help.luracast.com/restler/examples/ +The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples https://restler3.luracast.com/examples/index.html Github contains also useful information : https://github.com/Luracast/Restler diff --git a/htdocs/asset/tpl/linkedobjectblock.tpl.php b/htdocs/asset/tpl/linkedobjectblock.tpl.php index 59df306c829..aef30995432 100644 --- a/htdocs/asset/tpl/linkedobjectblock.tpl.php +++ b/htdocs/asset/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php index 2737b425c9c..8a98c078bc5 100644 --- a/htdocs/bom/tpl/linkedobjectblock.tpl.php +++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 8833978e054..bbc92a83ef1 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -160,7 +160,7 @@ if ($action == 'create') { print ''; - print ''; + print ''; dol_set_focus('#titlebookmark'); // Url @@ -230,9 +230,9 @@ if ($id > 0 && !preg_match('/^add/i', $action)) { print ''; diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php index 32c2345a657..8dd6b008045 100644 --- a/htdocs/comm/action/class/cactioncomm.class.php +++ b/htdocs/comm/action/class/cactioncomm.class.php @@ -186,35 +186,55 @@ class CActionComm $qualified = 1; - // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto + // $obj->type can be 'system', 'systemauto', 'module', 'moduleauto', 'xxx', 'xxxauto' + // Note: type = system... than type of event is added among other standard events. + // type = module... then type of event is grouped into module defined into module = myobject@mymodule. Example: Event organization or external modules + // type = xxx... then type of event is added into list as a new flat value (not grouped). Example: Agefod external module if ($qualified && $onlyautoornot > 0 && preg_match('/^system/', $obj->type) && !preg_match('/^AC_OTH/', $obj->code)) { $qualified = 0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) } if ($qualified && !empty($obj->module)) { - if ($obj->module == 'invoice' && empty($conf->facture->enabled) && empty($user->facture->lire)) { - $qualified = 0; + //var_dump($obj->type.' '.$obj->module.' '); var_dump($user->rights->facture->lire); + $qualified = 0; + // Special cases + if ($obj->module == 'invoice' && !empty($conf->facture->enabled) && !empty($user->rights->facture->lire)) { + $qualified = 1; } - if ($obj->module == 'order' && empty($conf->commande->enabled) && empty($user->commande->lire)) { - $qualified = 0; + if ($obj->module == 'order' && !empty($conf->commande->enabled) && empty($user->rights->commande->lire)) { + $qualified = 1; } - if ($obj->module == 'propal' && empty($conf->propal->enabled) && empty($user->propale->lire)) { - $qualified = 0; + if ($obj->module == 'propal' && !empty($conf->propal->enabled) && !empty($user->rights->propale->lire)) { + $qualified = 1; } - if ($obj->module == 'invoice_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && empty($user->fournisseur->facture->lire)) || (!empty($conf->supplier_invoice->enabled) && empty($user->supplier_invoice->lire)))) { - $qualified = 0; + if ($obj->module == 'invoice_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && !empty($user->rights->fournisseur->facture->lire)) || (!empty($conf->rights->supplier_invoice->enabled) && !empty($user->rights->supplier_invoice->lire)))) { + $qualified = 1; } - if ($obj->module == 'order_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && empty($user->fournisseur->commande->lire)) || (empty($conf->supplier_order->enabled) && empty($user->supplier_order->lire)))) { - $qualified = 0; + if ($obj->module == 'order_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && !empty($user->rights->fournisseur->commande->lire)) || (empty($conf->rights->supplier_order->enabled) && !empty($user->rights->supplier_order->lire)))) { + $qualified = 1; } - if ($obj->module == 'shipping' && empty($conf->expedition->enabled) && empty($user->expedition->lire)) { - $qualified = 0; + if ($obj->module == 'shipping' && !empty($conf->expedition->enabled) && !empty($user->rights->expedition->lire)) { + $qualified = 1; } - if (preg_match('/@eventorganization/', $obj->module) && empty($conf->eventorganization->enabled) && empty($user->eventorganization->read)) { - $qualified = 0; + // For the generic case with type = 'module...' and module = 'myobject@mymodule' + $regs = array(); + if (preg_match('/^module/', $obj->type)) { + if (preg_match('/^(.+)@(.+)$/', $obj->module, $regs)) { + $tmpobject = $regs[1]; + $tmpmodule = $regs[2]; + //var_dump($user->$tmpmodule); + if ($tmpmodule && isset($conf->$tmpmodule) && !empty($conf->$tmpmodule->enabled) && (!empty($user->rights->$tmpmodule->read) || !empty($user->rights->$tmpmodule->lire) || !empty($user->rights->$tmpmodule->$tmpobject->read) || !empty($user->rights->$tmpmodule->$tmpobject->lire))) { + $qualified = 1; + } + } } - if (!preg_match('/^system/', $obj->type) && isset($conf->{$obj->module}) && empty($conf->{$obj->module}->enabled)) { - $qualified = 0; + // For the case type is not 'system...' neither 'module', we just check module is on + if (! in_array($obj->type, array('system', 'systemauto', 'module', 'moduleauto'))) { + $tmpmodule = $obj->module; + //var_dump($tmpmodule); + if ($tmpmodule && isset($conf->$tmpmodule) && !empty($conf->$tmpmodule->enabled)) { + $qualified = 1; + } } } diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index e8060bc314d..4142ff9a958 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -49,10 +49,11 @@ if (empty($conf->global->AGENDA_EXT_NB)) { } $MAXAGENDA = $conf->global->AGENDA_EXT_NB; -$filter = GETPOST("search_filter", 'alpha', 3) ?GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); -$filtert = GETPOST("search_filtert", "int", 3) ?GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); -$usergroup = GETPOST("search_usergroup", "int", 3) ?GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); -$showbirthday = empty($conf->use_javascript_ajax) ?GETPOST("showbirthday", "int") : 1; +$check_holiday = GETPOST('check_holiday', 'int'); +$filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); +$filtert = GETPOST("search_filtert", "int", 3) ? GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); +$usergroup = GETPOST("search_usergroup", "int", 3) ? GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); +$showbirthday = empty($conf->use_javascript_ajax) ? GETPOST("showbirthday", "int") : 1; // If not choice done on calendar owner (like on left menu link "Agenda"), we filter on user. if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) { @@ -207,16 +208,16 @@ if (GETPOST("viewperuser", 'alpha') || $mode == 'show_peruser') { } /* -if ($action == 'delete_action' && $user->rights->agenda->delete) { - $event = new ActionComm($db); - $event->fetch($actionid); - $event->fetch_optionals(); - $event->fetch_userassigned(); - $event->oldcopy = clone $event; + if ($action == 'delete_action' && $user->rights->agenda->delete) { + $event = new ActionComm($db); + $event->fetch($actionid); + $event->fetch_optionals(); + $event->fetch_userassigned(); + $event->oldcopy = clone $event; - $result = $event->delete(); -} -*/ + $result = $event->delete(); + } + */ /* @@ -579,10 +580,10 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on $s .= ''."\n"; // Local calendar - $s .= '
'.$langs->trans("LocalAgenda").'  
'; + $s .= '
'.$langs->trans("LocalAgenda").'  
'; // Holiday calendar - $s .= '
 
'; + $s .= '
 
'; // External calendars if (is_array($showextcals) && count($showextcals) > 0) { @@ -607,13 +608,13 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on foreach ($showextcals as $val) { $htmlname = md5($val['name']); - if (!empty($val['default'])) { + if (!empty($val['default']) || GETPOST('check_ext'.$htmlname, 'int')) { $default = "checked"; } else { $default = ''; } - $s .= '
 
'; + $s .= '
 
'; } } @@ -848,6 +849,7 @@ if ($resql) { $event->fk_project = $obj->fk_project; $event->socid = $obj->fk_soc; + $event->thirdparty_id = $obj->fk_soc; $event->contact_id = $obj->fk_contact; // Defined date_start_in_calendar and date_end_in_calendar property @@ -890,13 +892,13 @@ if ($resql) { $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz /* - print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
'; - print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
'; - print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
'; - print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
'; - print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
'; - print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
'; - */ + print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
'; + print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
'; + */ do { //if ($event->id==408) //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'gmt').' - '.dol_print_date($event->datep, 'dayhour', 'gmt').' '.dol_print_date($event->datef, 'dayhour', 'gmt').'
'; diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index adc9de9339e..613f06a6feb 100644 --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php @@ -30,7 +30,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 1470ee210e8..471363f74ec 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1369,7 +1369,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to build doc - $upload_dir = !empty($conf->propal->multidir_output[$object->entity])?$conf->propal->multidir_output[$object->entity]:$conf->propal->dir_output; + $upload_dir = !empty($conf->commande->multidir_output[$object->entity])?$conf->commande->multidir_output[$object->entity]:$conf->commande->dir_output; $permissiontoadd = $usercancreate; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 06f2e6c318d..0c43cc4ad2d 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3666,9 +3666,10 @@ class Commande extends CommonOrder * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $addlinktonotes Add link to notes + * @param string $target attribute target for link * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '') { global $conf, $langs, $user, $hookmanager; @@ -3737,6 +3738,11 @@ class Commande extends CommonOrder } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip"'; + + $target_value=array('_self', '_blank', '_parent', '_top'); + if (in_array($target, $target_value)) { + $linkclose .= ' target="'.dol_escape_htmltag($target).'"'; + } } $linkstart = '\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index d21717473ff..2385f2210a5 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -60,10 +60,11 @@ $newbankreceipt = GETPOST('newbankreceipt', 'alpha'); // Security check $fieldid = (!empty($ref) ? $ref : $id); -$fieldname = isset($ref) ? 'ref' : 'rowid'; +$fieldname = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) { $socid = $user->socid; } + $result = restrictedArea($user, 'banque', $fieldid, 'bank_account', '', '', $fieldname); if ($user->rights->banque->consolidate && $action == 'dvnext' && !empty($dvid)) { diff --git a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php index 0b22e31be4b..03b410466f0 100644 --- a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php b/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php index d222dfd21dc..d2ef4657586 100644 --- a/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php +++ b/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php index 610974e5528..8c859e6e689 100644 --- a/htdocs/compta/paiement/cheque/card.php +++ b/htdocs/compta/paiement/cheque/card.php @@ -41,12 +41,7 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -$fieldname = (!empty($ref) ? 'ref' : 'rowid'); -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_author', $fieldname); +$object = new RemiseCheque($db); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); @@ -63,11 +58,22 @@ if (empty($page) || $page == -1) { $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $offset = $limit * $page; -$dir = $conf->bank->dir_output.'/checkdeposits/'; +$upload_dir = $conf->bank->multidir_output[$object->entity ? $object->entity : $conf->entity]."/checkdeposits"; + $filterdate = dol_mktime(0, 0, 0, GETPOST('fdmonth'), GETPOST('fdday'), GETPOST('fdyear')); $filteraccountid = GETPOST('accountid', 'int'); -$object = new RemiseCheque($db); +// Security check +$fieldname = (!empty($ref) ? 'ref' : 'rowid'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_author', $fieldname); + +$usercanread = $user->rights->banque->cheque; +$usercancreate = $user->rights->banque->cheque; +$usercandelete = $user->rights->banque->cheque; + /* @@ -241,7 +247,9 @@ if ($action == 'builddoc' && $user->rights->banque->cheque) { $langs->load("other"); - $file = $dir.get_exdir($object->ref, 0, 1, 0, $object, 'cheque').GETPOST('file'); + $filetodelete = GETPOST('file', 'alpha'); + $file = $upload_dir.'/'.$filetodelete; + $ret = dol_delete_file($file, 0, 0, 0, $object); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); @@ -634,6 +642,12 @@ if ($action == 'new') { $i = 1; if ($num > 0) { while ($objp = $db->fetch_object($resql)) { + $paymentstatic->id = $objp->pid; + $paymentstatic->ref = $objp->pref; + + $accountlinestatic->id = $objp->rowid; + $accountlinestatic->ref = $objp->ref; + print ''; print ''; print ''; // Operation date @@ -643,8 +657,6 @@ if ($action == 'new') { print ''; // Link to payment print ''; // Link to bank transaction print '
'.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
'.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
'; if ($action == 'edit') { - print 'title).'">'; + print 'title).'">'; } else { - print $object->title; + print dol_escape_htmltag($object->title); } print '
'.$i.''.dol_print_date($db->jdate($objp->date), 'day').''.price($objp->amount).''; - $paymentstatic->id = $objp->pid; - $paymentstatic->ref = $objp->pref; if ($paymentstatic->id) { print $paymentstatic->getNomUrl(1); } else { @@ -653,8 +665,6 @@ if ($action == 'new') { print ''; - $accountlinestatic->id = $objp->rowid; - $accountlinestatic->ref = $objp->ref; if ($accountlinestatic->id > 0) { print $accountlinestatic->getNomUrl(1); } else { @@ -664,10 +674,10 @@ if ($action == 'new') { // Action button print ''; if ($object->statut == 0) { - print 'rowid.'">'.img_delete().''; + print 'rowid.'">'.img_delete().''; } if ($object->statut == 1 && $objp->statut != 2) { - print 'rowid.'">'.img_picto($langs->trans("RejectCheck"), 'disable').''; + print 'rowid.'">'.img_picto($langs->trans("RejectCheck"), 'disable').''; } if ($objp->statut == 2) { print '   '.img_picto($langs->trans('CheckRejected'), 'statut8').''; @@ -723,11 +733,13 @@ print ''; if ($action != 'new') { if ($object->statut == 1) { - $filename = dol_sanitizeFileName($object->ref); - $filedir = $dir.get_exdir($object->ref, 0, 1, 0, $object, 'checkdeposits'); + // Documents + $objref = dol_sanitizeFileName($object->ref); + $filedir = $upload_dir.'/'.$objref; $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - - print $formfile->showdocuments('remisecheque', $filename, $filedir, $urlsource, 1, 1); + $genallowed = $usercancreate; + $delallowed = $usercandelete; + print $formfile->showdocuments('remisecheque', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); print '
'; } diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php index c66edfc8fe1..6b1053240c8 100644 --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php @@ -615,6 +615,7 @@ class RemiseCheque extends CommonObject // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. $sav_charseSupprimert_output = $outputlangs->charset_output; + $result = $docmodel->write_file($this, $conf->bank->dir_output.'/checkdeposits', $this->ref, $outputlangs); if ($result > 0) { //$outputlangs->charset_output=$sav_charset_output; diff --git a/htdocs/compta/paiement_vat.php b/htdocs/compta/paiement_vat.php index 916a0bf5498..ce224735927 100644 --- a/htdocs/compta/paiement_vat.php +++ b/htdocs/compta/paiement_vat.php @@ -83,7 +83,7 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y } } - if ($amounts[key($amounts)] <= 0) { + if (empty($amounts[key($amounts)])) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors'); $action = 'create'; diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index caa04146264..6419e2b8970 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -139,7 +139,7 @@ class ChargeSociales extends CommonObject { $sql = "SELECT cs.rowid, cs.date_ech"; $sql .= ", cs.libelle as label, cs.fk_type, cs.amount, cs.fk_projet as fk_project, cs.paye, cs.periode, cs.import_key"; - $sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user"; + $sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user, note_public, note_private"; $sql .= ", c.libelle as type_label"; $sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; @@ -172,6 +172,8 @@ class ChargeSociales extends CommonObject $this->amount = $obj->amount; $this->fk_project = $obj->fk_project; $this->fk_user = $obj->fk_user; + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; $this->paye = $obj->paye; $this->periode = $this->db->jdate($obj->periode); $this->import_key = $this->import_key; diff --git a/htdocs/compta/sociales/info.php b/htdocs/compta/sociales/info.php index 546a4c711d0..4c49a3008c6 100644 --- a/htdocs/compta/sociales/info.php +++ b/htdocs/compta/sociales/info.php @@ -81,7 +81,7 @@ $object->info($id); $head = tax_prepare_head($object); -print dol_get_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, 'bill'); +print dol_get_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, $object->picto); $morehtmlref = '
'; // Label of social contribution @@ -115,7 +115,7 @@ print '
'; print '
'; -print ''; $formconfirm .= ''."\n"; @@ -5200,6 +5202,7 @@ class Form $out .= ''; $out .= ''; } else { + $out .= ''; if ($selected) { $projet = new Project($this->db); $projet->fetch($selected); @@ -5207,6 +5210,7 @@ class Form } else { $out .= " "; } + $out .= ''; } if (empty($nooutput)) { @@ -6676,7 +6680,7 @@ class Form // phpcs:enable global $langs; - $retstring = ''; + $retstring = ''; $hourSelected = 0; $minSelected = 0; @@ -6708,7 +6712,7 @@ class Form if ($typehour != 'text') { $retstring .= ' '.$langs->trans('HourShort'); } else { - $retstring .= ':'; + $retstring .= ':'; } // Minutes @@ -6736,7 +6740,7 @@ class Form $retstring .= ' '.$langs->trans('MinuteShort'); } - //$retstring.=" "; + $retstring.=""; if (!empty($nooutput)) { return $retstring; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 217bba55330..d8801d00dc7 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -360,8 +360,8 @@ class FormFile * This also set the property $this->numoffiles * * @param string $modulepart Module the files are related to ('propal', 'facture', 'facture_fourn', 'mymodule', 'mymodule:MyObject', 'mymodule_temp', ...) - * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module. - * @param string $filedir Directory to scan + * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into a subdir of module. + * @param string $filedir Directory to scan (must not end with a /). Example: '/mydolibarrdocuments/facture/FAYYMM-1234' * @param string $urlsource Url of origin page (for return) * @param int|string[] $genallowed Generation is allowed (1/0 or array list of templates) * @param int $delallowed Remove is allowed (1/0) @@ -1283,12 +1283,22 @@ class FormFile } print ''; print ''; - if (!$disablemove) { + if (empty($disablemove) && count($filearray) > 1) { print ''; } print "\n"; } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($filearray, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $filearray = dol_sort_array($filearray, $sortfield, $sortorder); + } + } + print ''; //print $url.' sortfield='.$sortfield.' sortorder='.$sortorder; print_liste_field_titre('Documents2', $url, "name", "", $param, '', $sortfield, $sortorder, 'left '); @@ -1301,21 +1311,11 @@ class FormFile print_liste_field_titre(''); // Action button print_liste_field_titre(''); - if (!$disablemove) { + if (empty($disablemove) && count($filearray) > 1) { print_liste_field_titre(''); } print "\n"; - // Get list of files stored into database for same relative directory - if ($relativedir) { - completeFileArrayWithDatabaseInfo($filearray, $relativedir); - - //var_dump($sortfield.' - '.$sortorder); - if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) - $filearray = dol_sort_array($filearray, $sortfield, $sortorder); - } - } - $nboffiles = count($filearray); if ($nboffiles > 0) { include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; @@ -1510,18 +1510,18 @@ class FormFile } print ""; - if (empty($disablemove)) { + if (empty($disablemove) && count($filearray) > 1) { if ($nboffiles > 1 && $conf->browser->layout != 'phone') { print ''; } else { - print 'browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>'; + print 'browser->layout != 'phone') ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>'; print ''; } } @@ -1531,7 +1531,7 @@ class FormFile print ''; print ''; print ''; - if (empty($disablemove)) { + if (empty($disablemove) && count($filearray) > 1) { print ''; } } @@ -1542,7 +1542,7 @@ class FormFile } if ($nboffiles == 0) { $colspan = '6'; - if (empty($disablemove)) { + if (empty($disablemove) && count($filearray) > 1) { $colspan++; // 6 columns or 7 } print '
'; +print '
'; dol_print_object_info($object); print '
'; diff --git a/htdocs/compta/sociales/note.php b/htdocs/compta/sociales/note.php new file mode 100644 index 00000000000..cf9d0cbdec5 --- /dev/null +++ b/htdocs/compta/sociales/note.php @@ -0,0 +1,135 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/compta/sociales/note.php + * \ingroup tax + * \brief Tab for notes on Taxes + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +if (!empty($conf->projet->enabled)) { + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} + +// Load translation files required by the page +$langs->loadLangs(array('compta', 'bills')); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$object = new ChargeSociales($db); +if ($id > 0) { + $object->fetch($id); +} + +// Security check +$socid = GETPOST('socid', 'int'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'tax', $object->id, 'chargesociales', 'charges'); + +$permissiontoread = $user->rights->tax->charges->lire; +$permissiontoadd = $user->rights->tax->charges->creer; +$permissionnote = $user->rights->tax->charges->creer; // Used by the include of actions_setnotes.inc.php + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once +} + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("SocialContribution").' - '.$langs->trans("Note"); +$help_url = 'EN:Module_Taxes_and_social_contributions|FR:Module Taxes et dividendes|ES:Módulo Impuestos y cargas sociales (IVA, impuestos)'; +llxHeader('', $title, $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = tax_prepare_head($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("SocialContribution"), -1, $object->picto); + + $morehtmlref = '
'; + // Label of social contribution + $morehtmlref .= $form->editfieldkey("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1); + // Project + if (!empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
'.$langs->trans('Project').' : '; + if (!empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title); + } + } else { + $morehtmlref .= ''; + } + } + $morehtmlref .= '
'; + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + //$object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); + + + print '
'; + print '
'; + + + $cssclass = "titlefield"; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + print '
'; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index cdbda7a17b8..5297026d5d3 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index af92138c5d5..5a4ec3bf02f 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1579,17 +1579,20 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ $nbok = 0; foreach ($toselect as $toselectid) { $result = $objecttmp->fetch($toselectid); - if ($result>0) { - if ($objecttmp->statut == Holiday::STATUS_VALIDATED && $user->id == $objecttmp->fk_validator) { + if ($result > 0) { + if ($objecttmp->statut != Holiday::STATUS_VALIDATED) { + setEventMessages($langs->trans('StatusOfRefMustBe', $objecttmp->ref, $langs->transnoentitiesnoconv('Validated')), null, 'warnings'); + continue; + } + if ($user->id == $objecttmp->fk_validator) { $objecttmp->oldcopy = dol_clone($objecttmp); $objecttmp->date_valid = dol_now(); $objecttmp->fk_user_valid = $user->id; $objecttmp->statut = Holiday::STATUS_APPROVED; - $db->begin(); - $verif = $objecttmp->approve($user); + if ($verif <= 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; @@ -1664,14 +1667,9 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ } } } - - if (!$error) { - $db->commit(); - $nbok++; - } else { - $db->rollback(); - $action = ''; - } + } else { + $langs->load("errors"); + setEventMessages($langs->trans('ErrorNotApproverForHoliday', $objecttmp->ref), null, 'errors'); } } else { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); @@ -1683,7 +1681,7 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ if (!$error) { if ($nbok > 1) { setEventMessages($langs->trans("RecordsApproved", $nbok), null, 'mesgs'); - } else { + } elseif ($nbok == 1) { setEventMessages($langs->trans("RecordAproved"), null, 'mesgs'); } $db->commit(); diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 9853faa8585..97a74e74916 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -81,8 +81,6 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'facturedet_rec' && $user->rights->facture->creer) { $perm = 1; - } elseif ($table_element_line == 'ecm_files' && $user->rights->ecm->creer) { - $perm = 1; } elseif ($table_element_line == 'emailcollector_emailcollectoraction' && $user->admin) { $perm = 1; } elseif ($table_element_line == 'bom_bomline' && $user->rights->bom->write) { @@ -97,10 +95,18 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'facture_fourn_det_rec' && $user->rights->fournisseur->facture->creer) { $perm = 1; - } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { - $perm = 1; - } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_ticket' && !empty($user->rights->ticket->write)) { - $perm = 1; + } elseif ($table_element_line == 'ecm_files') { // Used when of page "documents.php" + if (!empty($user->rights->ecm->creer)) { + $perm = 1; + } elseif ($fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { + $perm = 1; + } elseif ($fk_element == 'fk_ticket' && !empty($user->rights->ticket->write)) { + $perm = 1; + } elseif ($fk_element == 'fk_holiday' && !empty($user->rights->holiday->write)) { + $perm = 1; + } elseif ($fk_element == 'fk_soc' && !empty($user->rights->societe->creer)) { + $perm = 1; + } } elseif ($table_element_line == 'product_association' && $fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { $perm = 1; } elseif ($table_element_line == 'projet_task' && $fk_element == 'fk_projet' && $user->rights->projet->creer) { diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index c7d01cab586..f59441eb8d4 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -165,7 +165,7 @@ class Conf /** * Load setup values into conf object (read llx_const) for a specified entity - * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setValues is called. + * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setEntityValues is called. * * @param DoliDB $db Database handler * @param int $entity Entity to get diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 93c0a2445dc..4a2e65ba1f3 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -326,19 +326,19 @@ class DolEditor $out .= 'jQuery(document).ready(function() { jQuery(".buttonforacesave").click(function() { - console.log("We click on savefile button for component '.$this->htmlname.'"); - var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid"); + console.log("We click on savefile button for component '.dol_escape_js($this->htmlname).'"); + var aceEditor = window.ace.edit("'.dol_escape_js($this->htmlname).'aceeditorid"); if (aceEditor) { var cursorPos = aceEditor.getCursorPosition(); //console.log(cursorPos); if (cursorPos) { - jQuery("#'.$this->htmlname.'_x").val(cursorPos.column); - jQuery("#'.$this->htmlname.'_y").val(cursorPos.row); + jQuery("#'.dol_escape_js($this->htmlname).'_x").val(cursorPos.column); + jQuery("#'.dol_escape_js($this->htmlname).'_y").val(cursorPos.row); } //console.log(aceEditor.getSession().getValue()); // Inject content of editor into the original HTML field. - jQuery("#'.$this->htmlname.'").val(aceEditor.getSession().getValue()); - /*if (jQuery("#'.$this->htmlname.'").html().length > 0) return true; + jQuery("#'.dol_escape_js($this->htmlname).'").val(aceEditor.getSession().getValue()); + /*if (jQuery("#'.dol_escape_js($this->htmlname).'").html().length > 0) return true; else return false;*/ return true; } else { diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 7653fd24437..37b8d580d1c 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -642,14 +642,14 @@ class dolReceiptPrinter extends Printer case 'DOL_PRINT_OBJECT_LINES': foreach ($object->lines as $line) { if ($line->fk_product) { - $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1; + $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - strlen($line->subprice) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0); - $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); - $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n"); + $this->printer->text($line->ref . $spaces . $line->qty . str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT) . ' ' . str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT) . "\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n \n"); } else { - $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - 10 - 1; + $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - strlen($line->subprice) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0); - $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT).' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); } } break; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 0381749ccd3..428de442786 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -791,7 +791,7 @@ class Form // Warning: if you set submit button to disabled, post using 'Enter' will no more work if there is no another input submit. So we add a hidden button $ret .= ''; // Hidden button BEFORE so it is the one used when we submit with ENTER. - $ret .= 'use_javascript_ajax) ? '' : ' style="display: none"').' class="button small'.(empty($conf->use_javascript_ajax) ? '' : ' hideobject').' '.$name.' '.$name.'confirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; + $ret .= 'use_javascript_ajax) ? '' : ' style="display: none"').' class="button smallpaddingimp'.(empty($conf->use_javascript_ajax) ? '' : ' hideobject').' '.$name.' '.$name.'confirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; $ret .= ''; if (!empty($conf->use_javascript_ajax)) { @@ -4901,7 +4901,7 @@ class Form $more .= '
'; $more .= '
'.$input['label'].'
'; $more .= ''; $formconfirm .= '
'; $formconfirm .= $this->selectyesno("confirm", $newselectedchoice, 0, false, 0, 0, 'marginleftonly marginrightonly'); - $formconfirm .= ''; + $formconfirm .= ''; $formconfirm .= '
'; if ($i > 0) { print 'id.'">'.img_up('default', 0, 'imgupforline').''; } - if ($i < $nboffiles - 1) { + if ($i < ($nboffiles - 1)) { print 'id.'">'.img_down('default', 0, 'imgdownforline').''; } print '
'; @@ -2032,7 +2032,7 @@ class FormFile print '
'; print ''; - print ''; + print '
'; print ''; print_liste_field_titre( $langs->trans("Links"), @@ -2117,7 +2117,7 @@ class FormFile print ''; diff --git a/htdocs/core/lib/tax.lib.php b/htdocs/core/lib/tax.lib.php index 490b95cc92d..a0602dfd74e 100644 --- a/htdocs/core/lib/tax.lib.php +++ b/htdocs/core/lib/tax.lib.php @@ -66,11 +66,29 @@ function tax_prepare_head(ChargeSociales $object) $head[$h][2] = 'documents'; $h++; + + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/note.php?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + + $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/info.php?id='.$object->id; $head[$h][1] = $langs->trans("Info"); $head[$h][2] = 'info'; $h++; + complete_head_from_modules($conf, $langs, $object, $head, $h, 'tax', 'remove'); return $head; diff --git a/htdocs/core/modules/cheque/modules_chequereceipts.php b/htdocs/core/modules/cheque/modules_chequereceipts.php index dfdf0fbe363..e50a6877848 100644 --- a/htdocs/core/modules/cheque/modules_chequereceipts.php +++ b/htdocs/core/modules/cheque/modules_chequereceipts.php @@ -126,8 +126,7 @@ abstract class ModeleNumRefChequeReceipts } /** - * \class ModeleChequeReceipts - * \brief Classe mere des modeles de + * Class parent for templates of document generation */ abstract class ModeleChequeReceipts extends CommonDocGenerator { diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 2a78baa00c9..73494a6cb04 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -256,7 +256,7 @@ class modAccounting extends DolibarrModules $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'Chartofaccounts'; - $this->export_icon[$r] = 'accounting'; + $this->export_icon[$r] = $this->picto; $this->export_permission[$r] = array(array("accounting", "chartofaccount")); $this->export_fields_array[$r] = array('ac.rowid'=>'ChartofaccountsId', 'ac.pcg_version'=>'Chartofaccounts', 'aa.rowid'=>'ID', 'aa.account_number'=>"AccountAccounting", 'aa.label'=>"Label", 'aa.account_parent'=>"Accountparent", 'aa.pcg_type'=>"Pcgtype", 'aa.active'=>'Status'); $this->export_TypeFields_array[$r] = array('ac.rowid'=>'List:accounting_system:pcg_version', 'ac.pcg_version'=>'Text', 'aa.rowid'=>'Numeric', 'aa.account_number'=>"Text", 'aa.label'=>"Text", 'aa.account_parent'=>"Text", 'aa.pcg_type'=>'Text', 'aa.active'=>'Status'); diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 877dca880f7..ced58f9b6c4 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -33,7 +33,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; */ class modBarcode extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -94,6 +93,7 @@ class modBarcode extends DolibarrModules // Main menu entries $r = 0; + // A menu entry for the Tools top menu $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=tools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'mainmenu'=>'tools', @@ -111,6 +111,7 @@ class modBarcode extends DolibarrModules ); $r++; + // A menu entry for the left menu $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=admintools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 60d713d5fc4..290eea449f5 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -1,6 +1,7 @@ + * Copyright (C) 2022 Anthony Berton * * 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 @@ -98,7 +99,8 @@ class modCron extends DolibarrModules // Cronjobs $this->cronjobs = array( 0=>array('entity'=>0, 'label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'tempfilesold+logfiles', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>2, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>50, 'status'=>1, 'test'=>true), - 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), + 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>'in_array($conf->db->type, array(\'mysql\', \'mysqli\'))'), + 2=>array('entity'=>0, 'label'=>'MakeSendLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'sendDumpDatabase', 'parameters'=>',,,,,sql', 'comment'=>'MakeSendLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>604800, 'priority'=>91, 'status'=>0, 'test'=>'!empty($conf->global->MAIN_ALLOW_BACKUP_BY_EMAIL) && in_array($conf->db->type, array(\'mysql\', \'mysqli\'))'), // 1=>array('entity'=>0, 'label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24) ); diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index a733484d043..b81dffc0657 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2012-2014 Juanjo Menent + * Copyright (C) 2022 Ferran Marcet * * 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 @@ -480,7 +481,6 @@ class modSociete extends DolibarrModules 's.fax' => "Fax", 's.url' => "Url", 's.email' => "Email", - 's.skype' => "Skype", 's.fk_effectif' => "Staff", 's.fk_typent' => "ThirdPartyType", "s.fk_forme_juridique" => "JuridicalStatus", @@ -621,7 +621,6 @@ class modSociete extends DolibarrModules 's.fax' => "eg. +34987654321", 's.url' => "e.g. https://www.mybigcompany.com", 's.email' => "e.g. test@mybigcompany.com", - 's.skype' => "Skype name", 's.fk_effectif' => "1/2/3/5: represents one of the five ranges of employees", 's.fk_typent' => 'matches field "id" (1-9 etc.) OR "code" (TE_SMALL etc.) in table "'.MAIN_DB_PREFIX.'c_typent"', 's.fk_forme_juridique' => '1/2/3 etc...matches field "code" in table "'.MAIN_DB_PREFIX.'c_forme_juridique"', @@ -693,7 +692,6 @@ class modSociete extends DolibarrModules 's.phone_mobile' => "PhoneMobile", 's.fax' => "Fax", 's.email' => "Email", - 's.skype' => "Skype", 's.note_private' => "NotePrivate", 's.note_public' => "NotePublic" ); @@ -759,7 +757,6 @@ class modSociete extends DolibarrModules 's.phone_mobile' => "5551144", 's.fax' => "5551155", 's.email' => "johnsmith@email.com", - 's.skype' => "skype username", 's.note_private' => "My private note", 's.note_public' => "My public note" ); diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 0ae6b00b1c3..86841ce5932 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -109,7 +109,8 @@ class modTicket extends DolibarrModules 3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0), 4 => array('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', 'chaine', 0, 'Automatically mark ticket as read when created from backend', 0), 5 => array('TICKET_DELAY_BEFORE_FIRST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time before a first answer to a ticket (in hours). Display a warning in tickets list if not respected.', 0), - 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0) + 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0), + 7 => array('TICKET_NOTIFY_AT_CLOSING', 'chaine', '0', 'Default notify contacts when closing a module', 0), ); diff --git a/htdocs/core/modules/product/modules_product.class.php b/htdocs/core/modules/product/modules_product.class.php index fef12717e3b..4b00cbe132e 100644 --- a/htdocs/core/modules/product/modules_product.class.php +++ b/htdocs/core/modules/product/modules_product.class.php @@ -43,20 +43,18 @@ abstract class ModelePDFProduct extends CommonDocGenerator /** * Return list of active generation modules * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array List of templates */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable - global $conf; - $type = 'product'; $list = array(); include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $list = getListOfModels($db, $type, $maxfilenamelength); + $list = getListOfModels($dbs, $type, $maxfilenamelength); return $list; } } @@ -156,22 +154,22 @@ abstract class ModeleProductCode /** * Renvoi la liste des modeles de numérotation * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array List of numbers */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable $list = array(); $sql = ""; - $resql = $db->query($sql); + $resql = $dbs->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $dbs->num_rows($resql); $i = 0; while ($i < $num) { - $row = $db->fetch_row($resql); + $row = $dbs->fetch_row($resql); $list[$row[0]] = $row[1]; $i++; } diff --git a/htdocs/core/modules/project/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php index 716c88e1f92..776f2f9d1e6 100644 --- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php +++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php @@ -432,10 +432,12 @@ class pdf_baleine extends ModelePDFProjects $pdf->MultiCell($this->posxlabel - $this->posxref, 3, $outputlangs->convToOutputCharset($ref), 0, 'L'); // Workload $pdf->SetXY($this->posxworkload, $curY); + $pdf->SetFont('', '', $default_font_size - 2); // We use a smaller font $pdf->MultiCell($this->posxprogress - $this->posxworkload, 3, $planned_workload ? $planned_workload : '', 0, 'R'); // Progress $pdf->SetXY($this->posxprogress, $curY); $pdf->MultiCell($this->posxdatestart - $this->posxprogress, 3, $progress, 0, 'R'); + $pdf->SetFont('', '', $default_font_size - 1); // We restore font // Date start and end $pdf->SetXY($this->posxdatestart, $curY); @@ -640,9 +642,11 @@ class pdf_baleine extends ModelePDFProjects $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateStart")." : ".dol_print_date($object->date_start, 'day', false, $outputlangs, true), '', 'R'); - $posy += 6; - $pdf->SetXY($posx, $posy); - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateEnd")." : ".dol_print_date($object->date_end, 'day', false, $outputlangs, true), '', 'R'); + if ($object->date_end) { + $posy += 6; + $pdf->SetXY($posx, $posy); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateEnd")." : ".dol_print_date($object->date_end, 'day', false, $outputlangs, true), '', 'R'); + } if (is_object($object->thirdparty)) { $posy += 6; diff --git a/htdocs/core/modules/societe/modules_societe.class.php b/htdocs/core/modules/societe/modules_societe.class.php index 09f6cb9c29d..e8b0fbe9193 100644 --- a/htdocs/core/modules/societe/modules_societe.class.php +++ b/htdocs/core/modules/societe/modules_societe.class.php @@ -41,20 +41,19 @@ abstract class ModeleThirdPartyDoc extends CommonDocGenerator /** * Return list of active generation modules * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array List of templates */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable - global $conf; $type = 'company'; $list = array(); include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $list = getListOfModels($db, $type, $maxfilenamelength); + $list = getListOfModels($dbs, $type, $maxfilenamelength); return $list; } @@ -161,22 +160,22 @@ abstract class ModeleThirdPartyCode /** * Renvoie la liste des modeles de numérotation * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array|int List of numbers */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable $list = array(); $sql = ""; - $resql = $db->query($sql); + $resql = $dbs->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $dbs->num_rows($resql); $i = 0; while ($i < $num) { - $row = $db->fetch_row($resql); + $row = $dbs->fetch_row($resql); $list[$row[0]] = $row[1]; $i++; } @@ -401,26 +400,3 @@ abstract class ModeleAccountancyCode return $langs->trans("NotAvailable"); } } - - -/** - * Create a document onto disk according to template module. - * - * @param DoliDB $db Database handler - * @param Facture $object Object invoice - * @param string $message Message (not used, deprecated) - * @param string $modele Force template to use ('' to not force) - * @param Translate $outputlangs objet lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @return int <0 if KO, >0 if OK - * @deprecated Use the new function generateDocument of Objects class - * @see Societe::generateDocument() - */ -function thirdparty_doc_create(DoliDB $db, Societe $object, $message, $modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) -{ - dol_syslog(__METHOD__." is deprecated", LOG_WARNING); - - return $object->generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref); -} diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index fdc315a588d..8b48a63e34d 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -66,7 +66,7 @@ if (in_array($modulepart, array('product', 'produit', 'societe', 'user', 'ticket * Confirm form to delete a file */ -if ($action == 'deletefile') { +if ($action == 'deletefile' || $action == 'deletelink') { $langs->load("companies"); // Need for string DeleteFile+ConfirmDeleteFiles print $form->formconfirm( $_SERVER["PHP_SELF"].'?id='.$object->id.'&urlfile='.urlencode(GETPOST("urlfile")).'&linkid='.GETPOST('linkid', 'int').(empty($param) ? '' : $param), diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index b3a40ba3582..de034f652d3 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -212,14 +212,14 @@ if ($massaction == 'presend') { } if ($massaction == 'preenable') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, '', 0, 200, 500, 1); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, 'yes', 0, 200, 500, 1); } if ($massaction == 'predisable') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDisabling"), $langs->trans("ConfirmMassDisablingQuestion", count($toselect)), "disable", null, '', 0, 200, 500, 1); } if ($massaction == 'preapproveleave') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, '', 0, 200, 500, 1); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, 'yes', 0, 200, 500, 1); } // Allow Pre-Mass-Action hook (eg for confirmation dialog) diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index dfd83022393..e13328e0a2a 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -133,77 +133,28 @@ class InterfaceTicketEmail extends DolibarrTriggers $langs->load('ticket'); + $subject_admin = 'TicketNewEmailSubjectAdmin'; + $body_admin = 'TicketNewEmailBodyAdmin'; + $subject_customer = 'TicketNewEmailSubjectCustomer'; + $body_customer = 'TicketNewEmailBodyCustomer'; + $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer'; + // Send email to notification email if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) { $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; - if ($sendto) { - // Init to avoid errors - $filepath = array(); - $filename = array(); - $mimetype = array(); - - /* Send email to admin */ - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectAdmin'); - $message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id).'

'; - $message_admin .= '
  • '.$langs->trans('Title').' : '.$object->subject.'
  • '; - $message_admin .= '
  • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
  • '; - $message_admin .= '
  • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
  • '; - $message_admin .= '
  • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
  • '; - $message_admin .= '
  • '.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'
  • '; - // Extrafields - $extraFields = new ExtraFields($this->db); - $extraFields->fetch_name_optionals_label($object->table_element); - if (is_array($object->array_options) && count($object->array_options) > 0) { - foreach ($object->array_options as $key => $value) { - $key = substr($key, 8); // remove "options_" - $message_admin .= '
  • '.$langs->trans($extraFields->attributes[$object->element]['label'][$key]).' : '.$extraFields->showOutputField($key, $value, '', $object->table_element).'
  • '; - } - } - $message_admin .= '
'; - - if ($object->fk_soc > 0) { - $object->fetch_thirdparty(); - $message_admin .= '

'.$langs->trans('Company').' : '.$object->thirdparty->name.'

'; - } - - $message = $object->message; - if (!dol_textishtml($message)) { - $message = dol_nl2br($message); - } - $message_admin .= '

'.$langs->trans('Message').' :
'.$message.'

'; - $message_admin .= '

'.$langs->trans('SeeThisTicketIntomanagementInterface').'

'; - - $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; - $replyto = $from; - - $trackid = 'tic'.$object->id; - - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; - $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; - } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); - if ($mailfile->error) { - dol_syslog($mailfile->error, LOG_DEBUG); - } else { - $result = $mailfile->sendfile(); - } - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; - } + $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); } } // Send email to customer - if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { $sendto = ''; //if contact selected send to email's contact else send to email's thirdparty $contactid = GETPOST('contactid', 'alpha'); + $res = 0; if (!empty($contactid)) { $contact = new Contact($this->db); @@ -218,77 +169,7 @@ class InterfaceTicketEmail extends DolibarrTriggers } if ($sendto) { - // Init to avoid errors - $filepath = array(); - $filename = array(); - $mimetype = array(); - - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectCustomer'); - $message_customer = $langs->transnoentities('TicketNewEmailBodyCustomer', $object->track_id).'

'; - $message_customer .= '
  • '.$langs->trans('Title').' : '.$object->subject.'
  • '; - $message_customer .= '
  • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
  • '; - $message_customer .= '
  • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
  • '; - $message_customer .= '
  • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
  • '; - - // Extrafields - foreach ($this->attributes[$object->table_element]['label'] as $key => $value) { - $enabled = 1; - if ($enabled && isset($this->attributes[$object->table_element]['list'][$key])) { - $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); - } - $perms = 1; - if ($perms && isset($this->attributes[$object->table_element]['perms'][$key])) { - $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); - } - - $qualified = true; - if (empty($enabled)) { - $qualified = false; - } - if (empty($perms)) { - $qualified = false; - } - - if ($qualified) { - $message_customer .= '
  • '.$langs->trans($key).' : '.$value.'
  • '; - } - } - - $message_customer .= '
'; - - $message = $object->message; - if (!dol_textishtml($message)) { - $message = dol_nl2br($message); - } - $message_customer .= '

'.$langs->trans('Message').' :
'.$message.'

'; - $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id; - $message_customer .= '

'.$langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$url_public_ticket.'

'; - $message_customer .= '

'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'

'; - - $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; - $replyto = $from; - - $trackid = 'tic'.$object->id; - - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; - $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; - } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); - if ($mailfile->error) { - dol_syslog($mailfile->error, LOG_DEBUG); - } else { - $result = $mailfile->sendfile(); - if ($result) { - // update last_msg_sent date - $object->date_last_msg_sent = dol_now(); - $object->update($user); - } - } - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; - } + $this->composeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs, $conf); } } @@ -305,10 +186,226 @@ class InterfaceTicketEmail extends DolibarrTriggers case 'TICKET_CLOSE': dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + $langs->load('ticket'); + + $subject_admin = 'TicketCloseEmailSubjectAdmin'; + $body_admin = 'TicketCloseEmailBodyAdmin'; + $subject_customer = 'TicketCloseEmailSubjectCustomer'; + $body_customer = 'TicketCloseEmailBodyCustomer'; + $see_ticket_customer = 'TicketCloseEmailBodyInfosTrackUrlCustomer'; + + // Send email to notification email + if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) { + $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + if ($sendto) { + $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); + } + } + + // Send email to customer. + if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail'])) { + $linked_contacts = $object->listeContact(-1, 'thirdparty'); + $linked_contacts = array_merge($linked_contacts, $object->listeContact(-1, 'internal')); + if (empty($linked_contacts) && !empty($conf->global->TICKET_NOTIFY_AT_CLOSING) && !empty($object->fk_soc)) { + $object->fetch_thirdparty(); + $linked_contacts[] = $object->thirdparty->email; + } + + $contactid = GETPOST('contactid', 'int'); + $res = 0; + + if ($contactid > 0) { + $contact = new Contact($this->db); + $res = $contact->fetch($contactid); + if (! in_array($contact, $linked_contacts)) { + $error_msg = $langs->trans('Error'). ': '; + $error_msg .= $langs->transnoentities('TicketWrongContact'); + setEventMessages($error_msg, [], 'errors'); + $ok = 0; + break; + } + } + + $sendto = ''; + if ($res > 0 && !empty($contact->email) && !empty($contact->statut)) { + $sendto = $contact->email; + } elseif ( !empty($linked_contacts) && ($contactid == -2 || (GETPOST('massaction', 'alpha') == 'close' && GETPOST('confirm', 'alpha') == 'yes'))) { + // if sending to all contacts or sending to contacts while mass closing + $temp_emails = []; + foreach ($linked_contacts as $contact) { + $temp_emails[] = $contact['email']; + } + $sendto = implode(", ", $temp_emails); + unset($temp_emails); + unset($linked_contacts); + } + if ($sendto) { + $this->composeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs, $conf); + } + } + $ok = 1; break; } - return $ok; } + + /** + * Composes and sends a message concerning a ticket, to be sent to admin address. + * + * @param string $sendto Addresses to send the mail, format "first@address.net, second@address.net," etc. + * @param string $base_subject email subject. Non-translated string. + * @param string $body email body (first line). Non-translated string. + * @param Ticket $object the ticket thet the email refers to + * @param Translate $langs the translation object + * @return void + */ + private function composeAndSendAdminMessage($sendto, $base_subject, $body, Ticket $object, Translate $langs) + { + global $conf; + + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + /* Send email to admin */ + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject, $object->ref, $object->track_id); + $message_admin = $langs->transnoentities($body, $object->track_id).'
'; + $message_admin .= '
  • '.$langs->trans('Title').' : '.$object->subject.'
  • '; + $message_admin .= '
  • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
  • '; + $message_admin .= '
  • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
  • '; + $message_admin .= '
  • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
  • '; + $message_admin .= '
  • '.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'
  • '; + // Extrafields + $extraFields = new ExtraFields($this->db); + $extraFields->fetch_name_optionals_label($object->table_element); + if (is_array($object->array_options) && count($object->array_options) > 0) { + foreach ($object->array_options as $key => $value) { + $key = substr($key, 8); // remove "options_" + $message_admin .= '
  • '.$langs->trans($extraFields->attributes[$object->element]['label'][$key]).' : '.$extraFields->showOutputField($key, $value, '', $object->table_element).'
  • '; + } + } + if ($object->fk_soc > 0) { + $object->fetch_thirdparty(); + $message_admin .= '
  • '.$langs->trans('Company').' : '.$object->thirdparty->name.'
  • '; + } + $message_admin .= '
'; + + $message = $object->message; + if (!dol_textishtml($message)) { + $message = dol_nl2br($message); + } + $message_admin .= '

'.$langs->trans('Message').' :

'.$message.'


'; + $message_admin .= '

'.$langs->trans('SeeThisTicketIntomanagementInterface').'

'; + + $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + + $trackid = 'tic'.$object->id; + + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); + if ($mailfile->error) { + dol_syslog($mailfile->error, LOG_DEBUG); + } else { + $result = $mailfile->sendfile(); + } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } + + /** + * Composes and sends a message concerning a ticket, to be sent to customer addresses. + * + * @param string $sendto Addresses to send the mail, format "first@address.net, second@address.net, " etc. + * @param string $base_subject email subject. Non-translated string. + * @param string $body email body (first line). Non-translated string. + * @param string $see_ticket string indicating the ticket public address + * @param Ticket $object the ticket thet the email refers to + * @param Translate $langs the translation object + * @return void + */ + private function composeAndSendCustomerMessage($sendto, $base_subject, $body, $see_ticket, Ticket $object, Translate $langs) + { + global $conf, $user; + + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject); + $message_customer = $langs->transnoentities($body, $object->track_id).'
'; + $message_customer .= '
  • '.$langs->trans('Title').' : '.$object->subject.'
  • '; + $message_customer .= '
  • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
  • '; + $message_customer .= '
  • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
  • '; + $message_customer .= '
  • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
  • '; + + // Extrafields + if (is_array($this->attributes[$object->table_element]['label'])) { + foreach ($this->attributes[$object->table_element]['label'] as $key => $value) { + $enabled = 1; + if ($enabled && isset($this->attributes[$object->table_element]['list'][$key])) { + $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); + } + $perms = 1; + if ($perms && isset($this->attributes[$object->table_element]['perms'][$key])) { + $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); + } + + $qualified = true; + if (empty($enabled)) { + $qualified = false; + } + if (empty($perms)) { + $qualified = false; + } + + if ($qualified) { + $message_customer .= '
  • ' . $langs->trans($key) . ' : ' . $value . '
  • '; + } + } + } + + $message_customer .= '
'; + + $message = $object->message; + if (!dol_textishtml($message)) { + $message = dol_nl2br($message); + } + $message_customer .= '

'.$langs->trans('Message').' :

'.$message.'


'; + $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id; + $message_customer .= '

'.$langs->trans($see_ticket).' : '.$url_public_ticket.'

'; + $message_customer .= '

'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'

'; + + $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + + $trackid = 'tic'.$object->id; + + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); + if ($mailfile->error) { + dol_syslog($mailfile->error, LOG_DEBUG); + } else { + $result = $mailfile->sendfile(); + if ($result) { + // update last_msg_sent date + $object->fetch($object->id); + $object->date_last_msg_sent = dol_now(); + $object->update($user); + } + } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } } diff --git a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php index 8025f0c0293..8a2cffe05f3 100644 --- a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php @@ -18,17 +18,7 @@ /** * \file core/triggers/interface_99_modZapier_ZapierTriggers.class.php * \ingroup zapier - * \brief Example trigger. - * - * - * \remarks You can create other triggers by copying this one. - * - File name should be either: - * - interface_99_modZapier_MyTrigger.class.php - * - interface_99_all_MyTrigger.class.php - * - The file must stay in core/triggers - * - The class name must be InterfaceMytrigger - * - The constructor method must be named InterfaceMytrigger - * - The name property name must be MyTrigger + * \brief File for Zappier Triggers. */ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index fc208fd9ac3..7ee64ec2c6f 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -478,8 +478,12 @@ if ($num > 0) { if (empty($obj)) { break; } - if (isset($obj->test) && !verifCond($obj->test)) { - continue; // Discard line with test = false + + if (isset($obj->test)) { + $veriftest = verifCond($obj->test); + if (!$veriftest) { + continue; // Discard line with test = false + } } $object->id = $obj->rowid; diff --git a/htdocs/don/tpl/linkedobjectblock.tpl.php b/htdocs/don/tpl/linkedobjectblock.tpl.php index 4097e73d560..5d564d43f7a 100644 --- a/htdocs/don/tpl/linkedobjectblock.tpl.php +++ b/htdocs/don/tpl/linkedobjectblock.tpl.php @@ -19,7 +19,7 @@ * */ -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 2f9bf4c41e5..3c5ef15875f 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -327,7 +327,11 @@ class EcmFiles extends CommonObject $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); + if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $this->errors[] = 'Error DB_ERROR_RECORD_ALREADY_EXISTS : '.$this->db->lasterror(); + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + } dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); } diff --git a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php index 9f761c24bc6..127ea95a424 100644 --- a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php +++ b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 00693469948..163761c1f6f 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1208,6 +1208,7 @@ if ($action == 'create') { print ''; } else { if (! empty($conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) { + print ''; print ''; } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8490fa67753..b4bcea985cc 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -367,13 +367,15 @@ class Expedition extends CommonObject // Insert of lines $num = count($this->lines); for ($i = 0; $i < $num; $i++) { - if (!isset($this->lines[$i]->detail_batch)) { // no batch management - if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { - $error++; - } - } else { // with batch management - if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { - $error++; + if (empty($this->lines[$i]->product_type) || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + if (!isset($this->lines[$i]->detail_batch)) { // no batch management + if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { + $error++; + } + } else { // with batch management + if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { + $error++; + } } } } @@ -913,6 +915,7 @@ class Expedition extends CommonObject // Copy the rang of the order line to the expedition line $line->rang = $orderline->rang; + $line->product_type = $orderline->product_type; if (!empty($conf->stock->enabled) && !empty($orderline->fk_product)) { $fk_product = $orderline->fk_product; @@ -965,6 +968,8 @@ class Expedition extends CommonObject } $this->lines[$num] = $line; + + return 1; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2611,6 +2616,12 @@ class ExpeditionLigne extends CommonObjectLine */ public $product_desc; + /** + * Type of the product. 0 for product, 1 for service + * @var int + */ + public $product_type = 0; + /** * @var int rang of line */ diff --git a/htdocs/expedition/tpl/linkedobjectblock.tpl.php b/htdocs/expedition/tpl/linkedobjectblock.tpl.php index 26e4ebbb47d..2305b0d4fac 100644 --- a/htdocs/expedition/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expedition/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php index 6a36b62f924..f97099e57dc 100644 --- a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php index e5903ee5863..8da01bb4f8f 100644 --- a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 8a0e0de299e..d67516cb0dd 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -477,15 +477,15 @@ class CommandeFournisseur extends CommonOrder $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn AND pfp.fk_soc = ".((int) $this->socid); + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn AND l.qty >= pfp.quantity AND pfp.fk_soc = ".((int) $this->socid); } $sql .= " WHERE l.fk_commande = ".((int) $this->id); if ($only_product) { $sql .= ' AND p.fk_product_type = 0'; } if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql.= " AND l.qty >= pfp.quantity "; - $sql.= " GROUP BY l.rowid HAVING max_qty = MAX(pfp.quantity) "; + $sql.= " GROUP BY l.rowid"; + $sql.= " HAVING (max_qty = MAX(pfp.quantity) OR max_qty IS NULL)"; } $sql .= " ORDER BY l.rang, l.rowid"; //print $sql; @@ -3552,11 +3552,11 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn AND cd.qty >= pfp.quantity"; } $sql .= ' WHERE cd.rowid = '.((int) $rowid); if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " AND cd.qty >= pfp.quantity GROUP BY cd.rowid HAVING max_qty = MAX(pfp.quantity)"; + $sql .= " GROUP BY cd.rowid HAVING (max_qty = MAX(pfp.quantity) OR max_qty IS NULL)"; } $result = $this->db->query($sql); if ($result) { diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 922d9f25e29..ce101573677 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2015-2019 Ferran Marcet * Copyright (C) 2016-2021 Alexandre Spangaro * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2018-2022 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -245,7 +245,7 @@ class FactureFournisseur extends CommonInvoice public $multicurrency_total_ht; public $multicurrency_total_tva; public $multicurrency_total_ttc; - //! id of source var_dump($$this);invoice if replacement invoice or credit note + //! id of source invoice if replacement invoice or credit note /** * @var int ID */ diff --git a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php index 1efd78df372..192a39c9b06 100644 --- a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php index 3f728d99567..e9ec8accf30 100644 --- a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php @@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index d8643c0783b..a9bfe8ab4f2 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -1083,7 +1083,9 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { if (empty($include_users)) { print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays"); } else { - $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); // Will work only if supervisor has permission to approve so is inside include_users + // Defined default approver (the forced approved of user or the supervisor if no forced value defined) + // Note: This use will be set only if the deinfed approvr has permission to approve so is inside include_users + $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); if (!empty($conf->global->HOLIDAY_DEFAULT_VALIDATOR)) { $defaultselectuser = $conf->global->HOLIDAY_DEFAULT_VALIDATOR; // Can force default approver } diff --git a/htdocs/install/mysql/data/llx_c_availability.sql b/htdocs/install/mysql/data/llx_c_availability.sql index 7291c399da0..02a7b37fc91 100644 --- a/htdocs/install/mysql/data/llx_c_availability.sql +++ b/htdocs/install/mysql/data/llx_c_availability.sql @@ -25,10 +25,9 @@ -- Availability type -- -delete from llx_c_availability; -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (1, 'AV_NOW', 'Immediate', 1, 10); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (2, 'AV_1W', '1 week', 1, 20); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (3, 'AV_2W', '2 weeks', 1, 30); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (4, 'AV_3W', '3 weeks', 1, 40); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (5, 'AV_4W', '4 weeks', 1, 50); +INSERT INTO llx_c_availability (code,label,active,position) VALUES ('AV_NOW', 'Immediate', 1, 10); +INSERT INTO llx_c_availability (code,label,active,position) VALUES ('AV_1W', '1 week', 1, 20); +INSERT INTO llx_c_availability (code,label,active,position) VALUES ('AV_2W', '2 weeks', 1, 30); +INSERT INTO llx_c_availability (code,label,active,position) VALUES ('AV_3W', '3 weeks', 1, 40); +INSERT INTO llx_c_availability (code,label,active,position) VALUES ('AV_4W', '4 weeks', 1, 50); diff --git a/htdocs/install/mysql/data/llx_c_civilite.sql b/htdocs/install/mysql/data/llx_c_civilite.sql index 1288fb23cea..7c20e73ef7c 100644 --- a/htdocs/install/mysql/data/llx_c_civilite.sql +++ b/htdocs/install/mysql/data/llx_c_civilite.sql @@ -30,9 +30,8 @@ -- Civilities -- -delete from llx_c_civility; -insert into llx_c_civility (rowid, code, label, active) values (1 , 'MME', 'Madame', 1); -insert into llx_c_civility (rowid, code, label, active) values (3 , 'MR', 'Monsieur', 1); -insert into llx_c_civility (rowid, code, label, active) values (5 , 'MLE', 'Mademoiselle', 1); -insert into llx_c_civility (rowid, code, label, active) values (7 , 'MTRE', 'Maître', 1); -insert into llx_c_civility (rowid, code, label, active) values (8 , 'DR', 'Docteur', 1); +insert into llx_c_civility (code, label, active) values ('MME', 'Madame', 1); +insert into llx_c_civility (code, label, active) values ('MR', 'Monsieur', 1); +insert into llx_c_civility (code, label, active) values ('MLE', 'Mademoiselle', 1); +insert into llx_c_civility (code, label, active) values ('MTRE', 'Maître', 1); +insert into llx_c_civility (code, label, active) values ('DR', 'Docteur', 1); diff --git a/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql b/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql index 9f779ecf64b..80f59680df5 100644 --- a/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql +++ b/htdocs/install/mysql/data/llx_c_hrm_public_holiday.sql @@ -6,6 +6,7 @@ -- Copyright (C) 2005-2012 Regis Houssin -- Copyright (C) 2007 Patrick Raguin -- Copyright (C) 2019 Markus Welters +-- Copyright (C) 2022 Joachim Kueter -- -- 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 @@ -62,6 +63,24 @@ INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, m INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('ES-CONSTITUIZION', 0, 4, '', 0, 12, 6, 1); INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('ES-IMMACULE', 0, 4, '', 0, 12, 8, 1); +-- Germany (5) +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-NEUJAHR', 0, 5, '', 0, 1, 1, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-HL3KOEN--TLW', 0, 5, '', 0, 1, 6, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-INTFRAUENTAG--TLW', 0, 5, '', 0, 3, 8, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-KARFREITAG', 0, 5, 'goodfriday', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-OSTERMONTAG', 0, 5, 'eastermonday', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-TAGDERARBEIT', 0, 5, '', 0, 5, 1, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-HIMMELFAHRT', 0, 5, 'ascension', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-PFINGSTEN', 0, 5, 'pentecotemonday', 0, 0, 0, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-FRONLEICHNAM--TLW', 0, 5, 'fronleichnam', 0, 0, 0, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-MARIAEHIMMEL--TLW', 0, 5, '', 0, 8, 15, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-WELTKINDERTAG--TLW', 0, 5, '', 0, 9, 20, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-TAGDERDEUTEINHEIT', 0, 5, '', 0, 10, 3, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-REFORMATIONSTAG--TLW', 0, 5, '', 0, 10, 31, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-ALLERHEILIGEN--TLW', 0, 5, '', 0, 11, 1, 0); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-WEIHNACHTSTAG1', 0, 5, '', 0, 12, 25, 1); +INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('DE-WEIHNACHTSTAG2', 0, 5, '', 0, 12, 26, 1); + -- Austria (41) INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('AT-EASTER', 0, 41, 'eastermonday', 0, 0, 0, 1); INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('AT-ASCENSION', 0, 41, 'ascension', 0, 0, 0, 1); diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index fa8cb0197cc..b9a5e535d21 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -43,6 +43,8 @@ create table llx_commande_fournisseur_dispatch_extrafields ALTER TABLE llx_commande_fournisseur_dispatch_extrafields ADD INDEX idx_commande_fournisseur_dispatch_extrafields (fk_object); +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging double(24,8) DEFAULT 1; + UPDATE llx_accounting_system SET fk_country = NULL, active = 0 WHERE pcg_version = 'SYSCOHADA'; create table llx_c_shipment_package_type diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 517771ced4e..a632a32271b 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -566,7 +566,8 @@ INSERT INTO llx_c_socialnetworks (entity, code, label, url, icon, active) VALUES -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_customers_outstanding_bill_reached.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_customers_outstanding_bill_reached.php' AND entity = 1); -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_scheduled_jobs.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_scheduled_jobs.php' AND entity = 1); -ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64); +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; ALTER TABLE llx_projet ADD COLUMN fk_opp_status_end integer DEFAULT NULL; diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index 6d2d0ae3033..434d30bdfe4 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -84,6 +84,9 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'a UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'cameleo'; DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', 'amarok', 'cameleo'); +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; + -- For v14 diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index f744abffde4..3e0fa10ccd0 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -35,6 +35,9 @@ -- VMYSQL4.3 ALTER TABLE llx_partnership MODIFY COLUMN date_partnership_end date NULL; -- VPGSQL8.2 ALTER TABLE llx_partnership ALTER COLUMN date_partnership_end DROP NOT NULL; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; + ALTER TABLE llx_accounting_bookkeeping ADD COLUMN date_export datetime DEFAULT NULL; ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_project integer NOT NULL; diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index fd32936fb04..190a1708612 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -276,3 +276,12 @@ UPDATE llx_c_ticket_type SET use_default=1 WHERE code='OTHER' AND NOT EXISTS(SEL ALTER TABLE llx_user ADD COLUMN ref_employee varchar(50) DEFAULT NULL; ALTER TABLE llx_user ADD COLUMN national_registration_number varchar(50) DEFAULT NULL; + +ALTER TABLE llx_propal ADD last_main_doc VARCHAR(255) NULL AFTER model_pdf; + +UPDATE llx_c_country SET eec=0 WHERE eec IS NULL; +ALTER TABLE llx_c_country MODIFY COLUMN eec tinyint DEFAULT 0 NOT NULL; + + +ALTER TABLE llx_chargesociales ADD COLUMN note_private text; +ALTER TABLE llx_chargesociales ADD COLUMN note_public text; diff --git a/htdocs/install/mysql/tables/llx_c_country.sql b/htdocs/install/mysql/tables/llx_c_country.sql index d97c3b90371..7419b68c26d 100644 --- a/htdocs/install/mysql/tables/llx_c_country.sql +++ b/htdocs/install/mysql/tables/llx_c_country.sql @@ -24,8 +24,8 @@ create table llx_c_country rowid integer PRIMARY KEY, code varchar(2) NOT NULL, code_iso varchar(3) , - label varchar(128) NOT NULL, - eec integer , + label varchar(128) NOT NULL, + eec tinyint DEFAULT 0 NOT NULL, active tinyint DEFAULT 1 NOT NULL, favorite tinyint DEFAULT 0 NOT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_chargesociales.key.sql b/htdocs/install/mysql/tables/llx_chargesociales.key.sql new file mode 100644 index 00000000000..8815b87c65c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_chargesociales.key.sql @@ -0,0 +1,20 @@ +-- =================================================================== +-- Copyright (C) 2022 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- =================================================================== + + +--ALTER TABLE llx_chargesociales ADD INDEX idx_chargesociales (ref); diff --git a/htdocs/install/mysql/tables/llx_chargesociales.sql b/htdocs/install/mysql/tables/llx_chargesociales.sql index 220c85410ce..93640a930b3 100644 --- a/htdocs/install/mysql/tables/llx_chargesociales.sql +++ b/htdocs/install/mysql/tables/llx_chargesociales.sql @@ -3,6 +3,7 @@ -- Copyright (C) 2005-2009 Regis Houssin -- Copyright (C) 2017 Alexandre Spangaro -- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2022 Laurent Destailleur -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -40,6 +41,8 @@ create table llx_chargesociales paye smallint default 0 NOT NULL, periode date, fk_projet integer DEFAULT NULL, + note_private text, + note_public text, import_key varchar(14) )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index 25b295ec383..83b97c201ad 100644 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -50,8 +50,7 @@ create table llx_product_fournisseur_price import_key varchar(14), -- Import key delivery_time_days integer, supplier_reputation varchar(10), - packaging varchar(64), - + packaging varchar(64) DEFAULT NULL, fk_multicurrency integer, multicurrency_code varchar(3), multicurrency_tx double(24,8) DEFAULT 1, diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index c8b78d42fae..c27a0fb2910 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -77,7 +77,8 @@ create table llx_societe fk_stcomm integer DEFAULT 0 NOT NULL, -- commercial status note_private text, -- note_public text, -- - model_pdf varchar(255), + model_pdf varchar(255), + last_main_doc varchar(255), -- relative filepath+filename of last main generated document prefix_comm varchar(5), -- prefix commercial (deprecated) client tinyint DEFAULT 0, -- client 0/1/2 fournisseur tinyint DEFAULT 0, -- fournisseur 0/1 diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index a44c819aa78..fd5ff8461fe 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -219,12 +219,12 @@ ByPredefinedAccountGroups=By predefined groups ByPersonalizedAccountGroups=By personalized groups ByYear=By year NotMatch=Not Set -DeleteMvt=Delete some operation lines from accounting +DeleteMvt=Delete some lines from accounting DelMonth=Month to delete DelYear=Year to delete DelJournal=Journal to delete -ConfirmDeleteMvt=This will delete all operation lines of the accounting for the year/month and/or for a specific journal (At least one criterion is required). You will have to reuse the feature '%s' to have the deleted record back in the ledger. -ConfirmDeleteMvtPartial=This will delete the transaction from the accounting (all operation lines related to the same transaction will be deleted) +ConfirmDeleteMvt=This will delete all lines in accountancy for the year/month and/or for a specific journal (At least one criterion is required). You will have to reuse the feature '%s' to have the deleted record back in the ledger. +ConfirmDeleteMvtPartial=This will delete the transaction from the accounting (all lines related to the same transaction will be deleted) FinanceJournal=Finance journal ExpenseReportsJournal=Expense reports journal DescFinanceJournal=Finance journal including all the types of payments by bank account @@ -282,7 +282,7 @@ DescClosure=Consult here the number of movements by month who are not validated OverviewOfMovementsNotValidated=Step 1/ Overview of movements not validated. (Necessary to close a fiscal year) AllMovementsWereRecordedAsValidated=All movements were recorded as validated NotAllMovementsCouldBeRecordedAsValidated=Not all movements could be recorded as validated -ValidateMovements=Validate movements +ValidateMovements=Validate and lock record... DescValidateMovements=Any modification or deletion of writing, lettering and deletes will be prohibited. All entries for an exercise must be validated otherwise closing will not be possible ValidateHistory=Bind Automatically @@ -301,7 +301,7 @@ Accounted=Accounted in ledger NotYetAccounted=Not yet transferred to accounting ShowTutorial=Show Tutorial NotReconciled=Not reconciled -WarningRecordWithoutSubledgerAreExcluded=Warning, all operations without subledger account defined are filtered and excluded from this view +WarningRecordWithoutSubledgerAreExcluded=Warning, all lines without subledger account defined are filtered and excluded from this view ## Admin BindingOptions=Binding options @@ -329,8 +329,9 @@ ACCOUNTING_DISABLE_BINDING_ON_PURCHASES=Disable binding & transfer in accountanc ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS=Disable binding & transfer in accountancy on expense reports (expense reports will not be taken into account in accounting) ## Export -NotifiedExportDate=Flag exported lines as exported (modification of the lines will not be possible) -NotifiedValidationDate=Validate the exported entries (modification or deletion of the lines will not be possible) +NotifiedExportDate=Flag exported lines as Exported (to modify a line, you will need to delete the whole transaction and re-transfert it into accounting) +NotifiedValidationDate=Validate and Lock the exported entries (same effect than the "Closure" feature, modification and deletion of the lines will DEFINITELY not be possible) +DateValidationAndLock=Date validation and lock ConfirmExportFile=Confirmation of the generation of the accounting export file ? ExportDraftJournal=Export draft journal Modelcsv=Model of export diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index 4fd2220dea6..9705f8823b0 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -82,6 +82,8 @@ UseMenuModuleToolsToAddCronJobs=Go into menu "Home - Admin tools - JobDisabled=Job disabled MakeLocalDatabaseDumpShort=Local database backup MakeLocalDatabaseDump=Create a local database dump. Parameters are: compression ('gz' or 'bz' or 'none'), backup type ('mysql', 'pgsql', 'auto'), 1, 'auto' or filename to build, number of backup files to keep +MakeSendLocalDatabaseDumpShort=Send local database backup +MakeSendLocalDatabaseDump=Send local database backup by email. Parameters are: to, from, subject, message, filename (Name of file sent), filter ('sql' for backup of database only) WarningCronDelayed=Attention, for performance purpose, whatever is next date of execution of enabled jobs, your jobs may be delayed to a maximum of %s hours, before being run. DATAPOLICYJob=Data cleaner and anonymizer JobXMustBeEnabled=Job %s must be enabled diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 7ab5d41f285..86d11ec59ea 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -278,6 +278,7 @@ ErrorIsNotADraft=%s is not a draft ErrorExecIdFailed=Can't execute command "id" ErrorBadCharIntoLoginName=Unauthorized character in the login name ErrorRequestTooLarge=Error, request too large +ErrorNotApproverForHoliday=You are not the approver for leave %s # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 61b5c939d12..7610aa78e9e 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -94,7 +94,7 @@ LanguageDefDesc=Enter in this files, all the key and the translation for each la MenusDefDesc=Define here the menus provided by your module DictionariesDefDesc=Define here the dictionaries provided by your module PermissionsDefDesc=Define here the new permissions provided by your module -MenusDefDescTooltip=The menus provided by your module/application are defined into the array $this->menus into the module descriptor file. You can edit manually this file or use the embedded editor.

Note: Once defined (and module re-activated), menus are also visible into the menu editor available to administrator users on %s. +MenusDefDescTooltip=The menus provided by your module/application are defined into the array $this->menus into the module descriptor file. You can edit manually this file or use the embedded editor.

Note: Once defined (and the module re-activated), the menus are also visible into the menu editor available to administrator users on %s. DictionariesDefDescTooltip=The dictionaries provided by your module/application are defined into the array $this->dictionaries into the module descriptor file. You can edit manually this file or use the embedded editor.

Note: Once defined (and module re-activated), dictionaries are also visible into the setup area to administrator users on %s. PermissionsDefDescTooltip=The permissions provided by your module/application are defined into the array $this->rights into the module descriptor file. You can edit manually this file or use the embedded editor.

Note: Once defined (and module re-activated), permissions are visible into the default permissions setup %s. HooksDefDesc=Define in the module_parts['hooks'] property, in the module descriptor, the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code). @@ -110,7 +110,7 @@ DropTableIfEmpty=(Destroy table if empty) TableDoesNotExists=The table %s does not exists TableDropped=Table %s deleted InitStructureFromExistingTable=Build the structure array string of an existing table -UseAboutPage=Disable the about page +UseAboutPage=Do not generate the About page UseDocFolder=Disable the documentation folder UseSpecificReadme=Use a specific ReadMe ContentOfREADMECustomized=Note: The content of the README.md file has been replaced with the specific value defined into setup of ModuleBuilder. @@ -138,10 +138,12 @@ CSSViewClass=CSS for read form CSSListClass=CSS for list NotEditable=Not editable ForeignKey=Foreign key -TypeOfFieldsHelp=Type of fields:
varchar(99), double(24,8), real, text, html, datetime, timestamp, integer, integer:ClassName:relativepath/to/classfile.class.php[:1[:filter]] ('1' means we add a + button after the combo to create the record, 'filter' can be 'status=1 AND fk_user = __USER_ID AND entity IN (__SHARED_ENTITIES__)' for example) +TypeOfFieldsHelp=Type of fields:
varchar(99), double(24,8), real, text, html, datetime, timestamp, integer, integer:ClassName:relativepath/to/classfile.class.php[:1[:filter]]
'1' means we add a + button after the combo to create the record
'filter' is a sql condition, example: 'status=1 AND fk_user=__USER_ID__ AND entity IN (__SHARED_ENTITIES__)' AsciiToHtmlConverter=Ascii to HTML converter AsciiToPdfConverter=Ascii to PDF converter TableNotEmptyDropCanceled=Table not empty. Drop has been canceled. ModuleBuilderNotAllowed=The module builder is available but not allowed to your user. ImportExportProfiles=Import and export profiles ValidateModBuilderDesc=Put 1 if this field need to be validated with $this->validateField() or 0 if validation required +WarningDatabaseIsNotUpdated=Warning: The database is not updated automatically, you must destroy tables and disable-enable the module to have tables recreated +LinkToParentMenu=Parent menu (fk_xxxxmenu) \ No newline at end of file diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 960bf02eb46..0fa5567cf11 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -346,7 +346,7 @@ UseProductFournDesc=Add a feature to define the product description defined by t ProductSupplierDescription=Vendor description for the product UseProductSupplierPackaging=Use packaging on supplier prices (recalculate quantities according to packaging set on supplier price when adding/updating line in supplier documents) PackagingForThisProduct=Packaging -PackagingForThisProductDesc=On supplier order, you will automaticly order this quantity (or a multiple of this quantity). Cannot be less than minimum buying quantity +PackagingForThisProductDesc=You will automaticaly buy a multiple of this quantity. Can't be lower than the minimum purchase quantity QtyRecalculatedWithPackaging=The quantity of the line were recalculated according to supplier packaging #Attributes diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index 9dfc4874cc5..310ac8dd7f6 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -142,6 +142,9 @@ TicketsDelayBeforeFirstAnswer=A new ticket should receive a first answer before TicketsDelayBeforeFirstAnswerHelp=If a new ticket has not received an answer after this time period (in hours), an important warning icon will be displayed in the list view. TicketsDelayBetweenAnswers=An unresolved ticket should not be unactive during (hours): TicketsDelayBetweenAnswersHelp=If an unresolved ticket that has already received an answer has not had further interaction after this time period (in hours), a warning icon will be displayed in the list view. +TicketsAutoNotifyClose=Automatically notify thirdparty when closing a ticket +TicketsAutoNotifyCloseHelp=When closing a ticket, you will be proposed to send a message to one of thirdparty's contacts. On mass closing, a message will be sent to one contact of the thirdparty linked to the ticket. +TicketWrongContact=Provided contact is not part of current ticket contacts. Email not sent. # # Index & list page @@ -158,6 +161,8 @@ OrderByDateAsc=Sort by ascending date OrderByDateDesc=Sort by descending date ShowAsConversation=Show as conversation list MessageListViewType=Show as table list +ConfirmMassTicketClosingSendEmail=Automatically send emails when closing tickets +ConfirmMassTicketClosingSendEmailQuestion=Do you want to notify thirdparties when closing these tickets ? # # Ticket card @@ -245,6 +250,9 @@ TicketChangeStatus=Change status TicketConfirmChangeStatus=Confirm the status change: %s ? TicketLogStatusChanged=Status changed: %s to %s TicketNotNotifyTiersAtCreate=Not notify company at create +NotifyThirdpartyOnTicketClosing=Contacts to notify while closing the ticket +TicketNotifyAllTiersAtClose=All related contacts +TicketNotNotifyTiersAtClose=No related contact Unread=Unread TicketNotCreatedFromPublicInterface=Not available. Ticket was not created from public interface. ErrorTicketRefRequired=Ticket reference name is required @@ -279,6 +287,7 @@ TicketNewEmailBodyInfosTicket=Information for monitoring the ticket TicketNewEmailBodyInfosTrackId=Ticket tracking number: %s TicketNewEmailBodyInfosTrackUrl=You can view the progress of the ticket by clicking the link above. TicketNewEmailBodyInfosTrackUrlCustomer=You can view the progress of the ticket in the specific interface by clicking the following link +TicketCloseEmailBodyInfosTrackUrlCustomer=You can consult the history of this ticket by clicking the following link TicketEmailPleaseDoNotReplyToThisEmail=Please do not reply directly to this email! Use the link to reply into the interface. TicketPublicInfoCreateTicket=This form allows you to record a support ticket in our management system. TicketPublicPleaseBeAccuratelyDescribe=Please accurately describe the problem. Provide the most information possible to allow us to correctly identify your request. @@ -300,6 +309,10 @@ NewUser=New user NumberOfTicketsByMonth=Number of tickets per month NbOfTickets=Number of tickets # notifications +TicketCloseEmailSubjectCustomer=Ticket closed +TicketCloseEmailBodyCustomer=This is an automatic message to notify you that ticket %s has just been closed. +TicketCloseEmailSubjectAdmin=Ticket closed - Réf %s (public ticket ID %s) +TicketCloseEmailBodyAdmin=A ticket with ID #%s has just been closed, see information: TicketNotificationEmailSubject=Ticket %s updated TicketNotificationEmailBody=This is an automatic message to notify you that ticket %s has just been updated TicketNotificationRecipient=Notification recipient diff --git a/htdocs/modulebuilder/admin/setup.php b/htdocs/modulebuilder/admin/setup.php index e5ccb0c3966..01a02d0c7dd 100644 --- a/htdocs/modulebuilder/admin/setup.php +++ b/htdocs/modulebuilder/admin/setup.php @@ -120,7 +120,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { print '
'; print ''; - print '
'; print ''.img_edit().''; // id= is included into $param if ($permissiontodelete) { - print '   '.img_delete().''; // id= is included into $param + print '   '.img_delete().''; // id= is included into $param } else { print ' '; } diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 752f57dfdf9..0c9a1b2531a 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1250,7 +1250,7 @@ class FormMail extends Form * Return templates of email with type = $type_template or type = 'all'. * This search into table c_email_templates. Used by the get_form function. * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param string $type_template Get message for model/type=$type_template, type='all' also included. * @param User $user Get template public or limited to this user * @param Translate $outputlangs Output lang object @@ -1259,7 +1259,7 @@ class FormMail extends Form * @param string $label Label of template * @return ModelMail|integer One instance of ModelMail or -1 if error */ - public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '') + public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '') { global $conf, $langs; @@ -1279,18 +1279,18 @@ class FormMail extends Form } $sql = "SELECT rowid, module, label, type_template, topic, joinfiles, content, content_lines, lang"; - $sql .= " FROM ".$db->prefix().'c_email_templates'; - $sql .= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')"; + $sql .= " FROM ".$dbs->prefix().'c_email_templates'; + $sql .= " WHERE (type_template='".$dbs->escape($type_template)."' OR type_template='all')"; $sql .= " AND entity IN (".getEntity('c_email_templates').")"; $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // Get all public or private owned if ($active >= 0) { $sql .= " AND active = ".((int) $active); } if ($label) { - $sql .= " AND label = '".$db->escape($label)."'"; + $sql .= " AND label = '".$dbs->escape($label)."'"; } if (!($id > 0) && $languagetosearch) { - $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')"; + $sql .= " AND (lang = '".$dbs->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$dbs->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')"; } if ($id > 0) { $sql .= " AND rowid=".(int) $id; @@ -1299,22 +1299,22 @@ class FormMail extends Form $sql .= " AND position=0"; } if ($languagetosearch) { - $sql .= $db->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or '' + $sql .= $dbs->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or '' } else { - $sql .= $db->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined + $sql .= $dbs->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined } - //$sql .= $db->plimit(1); + //$sql .= $dbs->plimit(1); //print $sql; - $resql = $db->query($sql); + $resql = $dbs->query($sql); if (!$resql) { - dol_print_error($db); + dol_print_error($dbs); return -1; } // Get first found while (1) { - $obj = $db->fetch_object($resql); + $obj = $dbs->fetch_object($resql); if ($obj) { // If template is for a module, check module is enabled; if not, take next template @@ -1386,7 +1386,8 @@ class FormMail extends Form } } - $db->free($resql); + $dbs->free($resql); + return $ret; } diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 2fa329406fb..6a039aa7ab3 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2021 Regis Houssin + * Copyright (C) 2022 Anthony Berton * * 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 @@ -847,8 +848,13 @@ class Utils $resarray = $utils->executeCLI($command, $outfile); if ($resarray['result'] != '0') { $this->error = $resarray['error'].' '.$resarray['output']; + $this->errors[] = $this->error; } $result = ($resarray['result'] == 0) ? 1 : 0; + if ($result < 0 && empty($this->errors)) { + $this->error = $langs->trans("ErrorFailToGenerateFile", $FILENAMEDOC); + $this->errors[] = $this->error; + } // Build PDF doc $command = $conf->global->MODULEBUILDER_ASCIIDOCTORPDF.' '.$destfile.' -n -o '.$dirofmoduledoc.'/'.$FILENAMEDOCPDF; @@ -856,8 +862,13 @@ class Utils $resarray = $utils->executeCLI($command, $outfile); if ($resarray['result'] != '0') { $this->error = $resarray['error'].' '.$resarray['output']; + $this->errors[] = $this->error; } $result = ($resarray['result'] == 0) ? 1 : 0; + if ($result < 0 && empty($this->errors)) { + $this->error = $langs->trans("ErrorFailToGenerateFile", $FILENAMEDOCPDF); + $this->errors[] = $this->error; + } chdir($currentdir); } else { @@ -868,8 +879,6 @@ class Utils return 1; } else { $error++; - $langs->load("errors"); - $this->error = $langs->trans("ErrorFailToGenerateFile", $outputfiledoc); } } else { $error++; @@ -1176,4 +1185,112 @@ class Utils return 1; } + + /** + * Make a send last backup of database or fil in param + * CAN BE A CRON TASK + * + * @param string $sendto Recipients emails + * @param string $from Sender email + * @param string $subject Topic/Subject of mail + * @param string $message Message + * @param string $filename List of files to attach (full path of filename on file system) + * @param string $filter Filter file send + * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) + */ + public function sendBackup($sendto = '', $from = '', $subject = '', $message = '', $filename = '', $filter = '') + { + global $conf, $langs; + + $filepath = ''; + $output = ''; + $error = 0; + + if (!empty($from)) { + $from = dol_escape_htmltag($from); + } elseif (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { + $from = dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_MAIL); + } else { + $error++; + } + + if (!empty($sendto)) { + $sendto = dol_escape_htmltag($sendto); + } elseif (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { + $from = dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_MAIL); + } else { + $error++; + } + + if (!empty($subject)) { + $subject = dol_escape_htmltag($subject); + } else { + $subject = dol_escape_htmltag($langs->trans('MakeSendLocalDatabaseDumpShort')); + } + + if (empty($message)) { + $message = dol_escape_htmltag($langs->trans('MakeSendLocalDatabaseDumpShort')); + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if ($filename) { + if (dol_is_file($conf->admin->dir_output.'/backup/'.$filename)) { + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filename); + } + } else { + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filter); + } + if ($tmpfiles) { + foreach ($tmpfiles as $key => $val) { + if ($key == 'fullname') { + $filepath = array($val); + $filesize = dol_filesize($val); + } + if ($key == 'type') { + $mimetype = array($val); + } + if ($key == 'relativename') { + $filename = array($val); + } + } + } + + if ($filepath) { + if ($filesize > 100000000) { + $output = 'Sorry, last backup file is too large to be send by email'; + $error++; + } + } else { + $output = 'No backup file found'; + $error++; + } + + if (!$error) { + include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1); + if ($mailfile->error) { + $error++; + $output = $mailfile->error; + } + } + + if (!$error) { + $result = $mailfile->sendfile(); + if ($result <= 0) { + $error++; + $output = $mailfile->error; + } + } + + dol_syslog(__METHOD__, LOG_DEBUG); + + $this->error = $error; + $this->output = $output; + + if ($result == true) { + return 0; + } else { + return $result; + } + } } diff --git a/htdocs/core/filemanagerdol/browser/default/frmupload.php b/htdocs/core/filemanagerdol/browser/default/frmupload.php index c82581cc51c..7ab5ee3bffa 100644 --- a/htdocs/core/filemanagerdol/browser/default/frmupload.php +++ b/htdocs/core/filemanagerdol/browser/default/frmupload.php @@ -65,6 +65,7 @@ function SetCurrentFolder( resourceType, folderPath ) function OnSubmit() { + console.log("Click on OnSubmit"); if ( document.getElementById('NewFile').value.length == 0 ) { alert( 'Please select a file from your computer' ); @@ -80,6 +81,8 @@ function OnSubmit() function OnUploadCompleted( errorNumber, data ) { + console.log("errorNumber = "+errorNumber); + // Reset the Upload Worker Frame. window.parent.frames['frmUploadWorker'].location = 'javascript:void(0)' ; @@ -106,7 +109,7 @@ function OnUploadCompleted( errorNumber, data ) alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + data + '"' ); break; case 202: - alert( 'Invalid file' ); + alert( 'Invalid file (Bad extension)' ); break; default: alert( 'Error on file upload. Error number: ' + errorNumber ); diff --git a/htdocs/core/filemanagerdol/connectors/php/commands.php b/htdocs/core/filemanagerdol/connectors/php/commands.php index b4fb1224f4c..6db2c3c1b25 100644 --- a/htdocs/core/filemanagerdol/connectors/php/commands.php +++ b/htdocs/core/filemanagerdol/connectors/php/commands.php @@ -203,12 +203,17 @@ function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '') $oFile = isset($_FILES['NewFile']) ? $_FILES['NewFile'] : $_FILES['upload']; + // $resourceType should be 'Image'; + $detectHtml = 0; + // Map the virtual path to the local server path. $sServerDir = ServerMapFolder($resourceType, $currentFolder, $sCommand); // Get the uploaded file name. $sFileName = $oFile['name']; - $sFileName = SanitizeFileName($sFileName); + + //$sFileName = SanitizeFileName($sFileName); + $sFileName = dol_sanitizeFileName($sFileName); $sOriginalFileName = $sFileName; @@ -216,6 +221,8 @@ function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '') $sExtension = substr($sFileName, (strrpos($sFileName, '.') + 1)); $sExtension = strtolower($sExtension); + //var_dump($Config); + /* if (isset($Config['SecureImageUploads'])) { if (($isImageValid = IsImageValid($oFile['tmp_name'], $sExtension)) === false) { $sErrorNumber = '202'; @@ -228,6 +235,14 @@ function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '') $sErrorNumber = '202'; } } + */ + + include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; + $isImageValid = image_format_supported($sFileName) > 0 ? true : false; + if (!$isImageValid) { + $sErrorNumber = '202'; + } + // Check if it is an allowed extension. if (!$sErrorNumber && IsAllowedExt($sExtension, $resourceType)) { @@ -241,7 +256,8 @@ function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '') $sFileName = RemoveExtension($sOriginalFileName).'('.$iCounter.').'.$sExtension; $sErrorNumber = '201'; } else { - move_uploaded_file($oFile['tmp_name'], $sFilePath); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_move_uploaded_file($oFile['tmp_name'], $sFilePath, 0, 0); if (is_file($sFilePath)) { if (isset($Config['ChmodOnUpload']) && !$Config['ChmodOnUpload']) { diff --git a/htdocs/core/filemanagerdol/connectors/php/io.php b/htdocs/core/filemanagerdol/connectors/php/io.php index c9fce179799..ba027727db3 100644 --- a/htdocs/core/filemanagerdol/connectors/php/io.php +++ b/htdocs/core/filemanagerdol/connectors/php/io.php @@ -408,7 +408,8 @@ EOF; } $rpl = array('\\' => '\\\\', '"' => '\\"'); - echo 'window.parent.OnUploadCompleted('.$errorNumber.',"'.strtr($fileUrl, $rpl).'","'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");'; + echo 'console.log('.$errorNumber.');'; + echo 'window.parent.OnUploadCompleted('.$errorNumber.', "'.strtr($fileUrl, $rpl).'", "'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");'; echo ''; exit; } diff --git a/htdocs/core/filemanagerdol/connectors/php/upload.php b/htdocs/core/filemanagerdol/connectors/php/upload.php index bd9b9218155..b9296d68bcf 100644 --- a/htdocs/core/filemanagerdol/connectors/php/upload.php +++ b/htdocs/core/filemanagerdol/connectors/php/upload.php @@ -22,11 +22,12 @@ * This is the "File Uploader" for PHP. */ -require 'config.php'; +require 'config.php'; // This include the main.inc.php require 'util.php'; require 'io.php'; require 'commands.php'; + /** * SendError * @@ -63,6 +64,7 @@ if (!IsAllowedType($sType)) { } + // @CHANGE //FileUpload( $sType, $sCurrentFolder, $sCommand ) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 084eb277b27..af5671437ae 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8297,7 +8297,7 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = * Verify if condition in string is ok or not * * @param string $strToEvaluate String with condition to check - * @return boolean True or False. Note: It returns also True if $strToEvaluate is '' + * @return boolean True or False. Note: It returns also True if $strToEvaluate is ''. False if error */ function verifCond($strToEvaluate) { @@ -8310,8 +8310,10 @@ function verifCond($strToEvaluate) if (isset($strToEvaluate) && $strToEvaluate !== '') { //$str = 'if(!('.$strToEvaluate.')) $rights = false;'; //dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition - $rep = dol_eval($strToEvaluate, 1, 1, '1'); // The dol_eval must contains all the global $xxx used into a condition - $rights = ($rep ? true : false); + //var_dump($strToEvaluate); + $rep = dol_eval($strToEvaluate, 1, 1, '1'); // The dol_eval must contains all the global $xxx for all variables $xxx found into the string condition + $rights = (($rep && strpos($rep, 'Bad string syntax to evaluate') === false) ? true : false); + //var_dump($rights); } return $rights; } @@ -8323,7 +8325,7 @@ function verifCond($strToEvaluate) * @param string $s String to evaluate * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). * @param int $hideerrors 1=Hide errors - * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():";' + * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s^$_->&|=!?():"\',/' and restrict use of (, 2=Accept also ';' and no restriction on (. * @return mixed Nothing or return result of eval */ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1') @@ -8338,22 +8340,23 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object global $soc; // For backward compatibility - // Test on dangerous char (used for RCE), we allow only characters to make PHP variable testing. + // Test on dangerous char (used for RCE), we allow only characters to make PHP variable testing if ($onlysimplestring == '1') { - //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=!?():"', '/').']/i', $s)) { + // We must accept: '1 && getDolGlobalInt("doesnotexist1") && $conf->global->MAIN_FEATURES_LEVEL' + // We must accept: '$conf->barcode->enabled && preg_match(\'/^(AAA|BBB)/\',$leftmenu)' + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_->&|=!?():"\',/', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { dol_syslog('Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s); return ''; } - // TODO We can exclude all () that is not ...($db) and getDolGlobalInt( and getDolGlobalString( + // TODO We can exclude all () that is not '($db)' and 'getDolGlobalInt(' and 'getDolGlobalString(' and 'preg_match(' // ... } } elseif ($onlysimplestring == '2') { - //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=!?():";', '/').']/i', $s)) { + // We must accept: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found" + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_->&|=!?():"\',/;[]', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { @@ -8363,20 +8366,35 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' } } if (strpos($s, '::') !== false) { - return 'Bad string syntax to evaluate (double : char is forbidden): '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (double : char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (double : char is forbidden): '.$s); + return ''; + } } if (strpos($s, '`') !== false) { - return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (backtick char is forbidden): '.$s); + return ''; + } } if (strpos($s, '.') !== false) { - return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (dot char is forbidden): '.$s); + return ''; + } } // We block use of php exec or php file functions $forbiddenphpstrings = array('$$'); $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST')); - $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI"); + $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI", 'verifCond'); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func")); @@ -8391,7 +8409,12 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' if (strpos($s, '__forbiddenstring__') !== false) { dol_syslog('Bad string syntax to evaluate: '.$s, LOG_WARNING); - return 'Bad string syntax to evaluate: '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate: '.$s; + } else { + dol_syslog('Bad string syntax to evaluate: '.$s); + return ''; + } } //print $s."
\n"; @@ -10119,7 +10142,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $class = 'butAction'; if ($actionType == 'danger' || $actionType == 'delete') { $class = 'butActionDelete'; - if (strpos($url, 'token=') === false) $url .= '&token='.newToken(); + if (!empty($url) && strpos($url, 'token=') === false) $url .= '&token='.newToken(); } $attr = array( @@ -10130,6 +10153,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = if (empty($html)) { $html = $label; + $attr['title'] = ''; // if html not set, leave label on title is redundant } else { $attr['aria-label'] = $label; } @@ -10143,6 +10167,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $attr['id'] = $id; } + // Override attr if (!empty($params['attr']) && is_array($params['attr'])) { foreach ($params['attr'] as $key => $value) { @@ -10156,6 +10181,11 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = } } + // automatic add tooltip when title is detected + if (!empty($attr['title']) && !empty($attr['class']) && strpos($attr['class'], 'classfortooltip') === false) { + $attr['class'].= ' classfortooltip'; + } + // Js Confirm button if ($userRight && !empty($params['confirm'])) { if (!is_array($params['confirm'])) { diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 90a67991413..15162c8b273 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -1561,8 +1561,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $disabledtask = 1; } - // Form to add new time - print '
'; + // Select hour + print ''; $tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask); print $tableCell; print '
'.$langs->trans("UseAboutPage").''; + print ''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('MODULEBUILDER_USE_ABOUT'); } else { diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 60f23cbee1a..b3a7ce9dfaf 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -955,6 +955,21 @@ if ($dirins && $action == 'initobject' && $module && GETPOST('createtablearray', if ($fieldname == 'entity') { $index = 1; } + // css + $css = ''; + $cssview = ''; + $csslist = ''; + if (preg_match('/^fk_/', $fieldname)) { + $css = 'maxwidth500 widthcentpercentminusxx'; + } + if ($fieldname == 'label') { + $css = 'minwidth300'; + $cssview = 'wordbreak'; + } + if (in_array($fieldname, array('note_public', 'note_private'))) { + $cssview = 'wordbreak'; + } + $string .= "'".$obj->Field."' =>array('type'=>'".$type."', 'label'=>'".$label."',"; if ($default != '') { @@ -972,6 +987,15 @@ if ($dirins && $action == 'initobject' && $module && GETPOST('createtablearray', if ($index) { $string .= ", 'index'=>".$index; } + if ($css) { + $string .= ", 'css'=>".$css; + } + if ($cssview) { + $string .= ", 'cssview'=>".$cssview; + } + if ($csslist) { + $string .= ", 'csslist'=>".$csslist; + } $string .= "),\n"; $string .= "
"; $i += 5; @@ -1307,33 +1331,33 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors'); } - } - if (!$error) { - $addfieldentry = array( - 'name'=>GETPOST('propname', 'aZ09'), - 'label'=>GETPOST('proplabel', 'alpha'), - 'type'=>GETPOST('proptype', 'alpha'), - 'arrayofkeyval'=>GETPOST('proparrayofkeyval', 'restricthtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' - 'visible'=>GETPOST('propvisible', 'int'), - 'enabled'=>GETPOST('propenabled', 'int'), - 'position'=>GETPOST('propposition', 'int'), - 'notnull'=>GETPOST('propnotnull', 'int'), - 'index'=>GETPOST('propindex', 'int'), - 'searchall'=>GETPOST('propsearchall', 'int'), - 'isameasure'=>GETPOST('propisameasure', 'int'), - 'comment'=>GETPOST('propcomment', 'alpha'), - 'help'=>GETPOST('prophelp', 'alpha'), - 'css'=>GETPOST('propcss', 'aZ09'), - 'cssview'=>GETPOST('propcssview', 'aZ09'), - 'csslist'=>GETPOST('propcsslist', 'aZ09'), - 'default'=>GETPOST('propdefault', 'restricthtml'), - 'noteditable'=>intval(GETPOST('propnoteditable', 'int')), - 'validate' => GETPOST('propvalidate', 'int') - ); + if (!$error) { + $addfieldentry = array( + 'name'=>GETPOST('propname', 'aZ09'), + 'label'=>GETPOST('proplabel', 'alpha'), + 'type'=>GETPOST('proptype', 'alpha'), + 'arrayofkeyval'=>GETPOST('proparrayofkeyval', 'restricthtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' + 'visible'=>GETPOST('propvisible', 'int'), + 'enabled'=>GETPOST('propenabled', 'int'), + 'position'=>GETPOST('propposition', 'int'), + 'notnull'=>GETPOST('propnotnull', 'int'), + 'index'=>GETPOST('propindex', 'int'), + 'searchall'=>GETPOST('propsearchall', 'int'), + 'isameasure'=>GETPOST('propisameasure', 'int'), + 'comment'=>GETPOST('propcomment', 'alpha'), + 'help'=>GETPOST('prophelp', 'alpha'), + 'css'=>GETPOST('propcss', 'alpha'), // Can be 'maxwidth500 widthcentpercentminusxx' for example + 'cssview'=>GETPOST('propcssview', 'alpha'), + 'csslist'=>GETPOST('propcsslist', 'alpha'), + 'default'=>GETPOST('propdefault', 'restricthtml'), + 'noteditable'=>intval(GETPOST('propnoteditable', 'int')), + 'validate' => GETPOST('propvalidate', 'int') + ); - if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) { - $addfieldentry['arrayofkeyval'] = json_decode($addfieldentry['arrayofkeyval'], true); + if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) { + $addfieldentry['arrayofkeyval'] = json_decode($addfieldentry['arrayofkeyval'], true); + } } } @@ -1346,8 +1370,8 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && // Edit the class file to write properties if (!$error) { $moduletype = 'external'; - $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype); + if (is_numeric($object) && $object <= 0) { $error++; } @@ -1366,6 +1390,8 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && if (!$error) { setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null); + setEventMessages($langs->trans('WarningDatabaseIsNotUpdated'), null); + clearstatcache(true); // Make a redirect to reload all data @@ -1940,6 +1966,11 @@ if ($module == 'initmodule') { $head2[$h][2] = 'description'; $h++; + $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : ''); + $head2[$h][1] = $langs->trans("Objects"); + $head2[$h][2] = 'objects'; + $h++; + $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=languages&module='.$module.($forceddirread ? '@'.$dirread : ''); $head2[$h][1] = $langs->trans("Languages"); $head2[$h][2] = 'languages'; @@ -1950,11 +1981,6 @@ if ($module == 'initmodule') { $head2[$h][2] = 'dictionaries'; $h++; - $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : ''); - $head2[$h][1] = $langs->trans("Objects"); - $head2[$h][2] = 'objects'; - $h++; - $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=permissions&module='.$module.($forceddirread ? '@'.$dirread : ''); $head2[$h][1] = $langs->trans("Permissions"); $head2[$h][2] = 'permissions'; @@ -2287,7 +2313,7 @@ if ($module == 'initmodule') { print ''; print ''; - print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, ' aaa '); print_liste_field_titre("Table", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("SQL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); @@ -2537,8 +2563,9 @@ if ($module == 'initmodule') { $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php'; $realpathtoapi = $dirread.'/'.$pathtoapi; } - $urloflist = $dirread.'/'.$pathtolist; - $urlofcard = $dirread.'/'.$pathtocard; + + $urloflist = dol_buildpath('/'.$pathtolist, 1); + $urlofcard = dol_buildpath('/'.$pathtocard, 1); print '
'; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoclass).($realpathtoclass ? '' : '').''; @@ -2699,7 +2726,7 @@ if ($module == 'initmodule') { print '
'; print '
'; print ''; - print ''; print ''; print ''; print ''; - print ''; + print ''; print ''; // We must use $reflectorpropdefault['fields'] to get list of fields because $tmpobjet->fields may have been @@ -2736,7 +2763,7 @@ if ($module == 'initmodule') { if (!empty($properties)) { // Line to add a property print ''; - print ''; + print ''; print ''; print ''; print ''; @@ -2758,7 +2785,7 @@ if ($module == 'initmodule') { //print ''; print ''; print ''; - print ''; @@ -2803,7 +2830,7 @@ if ($module == 'initmodule') { print ''; - print ''; print ''; - print ''; @@ -2884,8 +2911,8 @@ if ($module == 'initmodule') { print ''; print ''; @@ -2945,7 +2972,7 @@ if ($module == 'initmodule') { print dol_escape_htmltag($propcomment); print ''; print ''; - print ''; print_liste_field_titre("Type", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("fk_menu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("LinkToParentMenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("mainmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("leftmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("URL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("RelativeURL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("LanguageFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right '); + print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("Permission", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Target", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder); print_liste_field_titre("UserType", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right '); @@ -3124,15 +3151,15 @@ if ($module == 'initmodule') { print dol_escape_htmltag($menu['langs']); print ''; - print ''; - print ''; - print ''; @@ -3834,8 +3861,10 @@ if ($module == 'initmodule') { $FILENAMEDOCPDF = $modulelowercase.'.pdf'; $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC; $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC; + $outputfiledocrel = $modulelowercase.'/doc/'.$FILENAMEDOC; $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF; $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF; + $outputfiledocrelpdf = $modulelowercase.'/doc/'.$FILENAMEDOCPDF; // HTML print ' '.$langs->trans("PathToModuleDocumentation", "HTML").' : '; @@ -3848,6 +3877,7 @@ if ($module == 'initmodule') { print ''; print ''; print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')'; + print ' '.img_picto($langs->trans("Delete"), 'delete').''; } print '
'; @@ -3862,6 +3892,7 @@ if ($module == 'initmodule') { print ''; print ''; print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')'; + print ' '.img_picto($langs->trans("Delete"), 'delete').''; } print '
'; @@ -3928,8 +3959,11 @@ if ($module == 'initmodule') { $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP; print ''.$outputfilezip.''; print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfilezip), 'dayhour').')'; + print ' '.img_picto($langs->trans("Delete"), 'delete').''; } - print '
'; + print ''; + + print '
'; print '
'; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index ac934439934..4e88703b454 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -108,11 +108,11 @@ class MyObject extends CommonObject 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>2, 'validate'=>1), 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1), 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty', 'validate'=>1), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>1, 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx'), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>1, 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx'), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1), - 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1), - 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1, 'cssview'=>'wordbreak'), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1, 'cssview'=>'wordbreak'), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501), //'date_validation ' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502), @@ -122,7 +122,7 @@ class MyObject extends CommonObject 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'notnull'=>0, 'position'=>600), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000), 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'notnull'=>-1, 'position'=>1010), - 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 9=>'Canceled'), 'validate'=>1), + 'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 9=>'Canceled'), 'validate'=>1), ); /** diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 13e34593bba..874d964ad6e 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -305,7 +305,7 @@ class modMyModule extends DolibarrModules /* BEGIN MODULEBUILDER LEFTMENU MYOBJECT $this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=mymodule', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode - 'type'=>'left', // This is a Top menu entry + 'type'=>'left', // This is a Left menu entry 'titre'=>'MyObject', 'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth valignmiddle"'), 'mainmenu'=>'mymodule', @@ -432,7 +432,7 @@ class modMyModule extends DolibarrModules $sql = array(); // Document templates - $moduledir = 'mymodule'; + $moduledir = dol_sanitizeFileName('mymodule'); $myTmpObjects = array(); $myTmpObjects['MyObject'] = array('includerefgeneration'=>0, 'includedocgeneration'=>0); @@ -441,8 +441,8 @@ class modMyModule extends DolibarrModules continue; } if ($myTmpObjectArray['includerefgeneration']) { - $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/mymodule/template_myobjects.odt'; - $dirodt = DOL_DATA_ROOT.'/doctemplates/mymodule'; + $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_myobjects.odt'; + $dirodt = DOL_DATA_ROOT.'/doctemplates/'.$moduledir; $dest = $dirodt.'/template_myobjects.odt'; if (file_exists($src) && !file_exists($dest)) { diff --git a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php index 2f0ecd06774..21cb16c3644 100644 --- a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php +++ b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index e29057c5423..37ece327185 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -28,8 +28,6 @@ * - interface_99_all_MyTrigger.class.php * - The file must stay in core/triggers * - The class name must be InterfaceMytrigger - * - The constructor method must be named InterfaceMytrigger - * - The name property name must be MyTrigger */ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; diff --git a/htdocs/modulebuilder/template/myobject_agenda.php b/htdocs/modulebuilder/template/myobject_agenda.php index 5eb4f6e3028..b40092f93a7 100644 --- a/htdocs/modulebuilder/template/myobject_agenda.php +++ b/htdocs/modulebuilder/template/myobject_agenda.php @@ -132,15 +132,24 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->mymodule->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id; } -$permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->rights->mymodule->myobject->read; + $permissiontoadd = $user->rights->mymodule->myobject->write; +} else { + $permissiontoread = 1; + $permissiontoadd = 1; +} // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; //$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (!$permissiontoread) accessforbidden(); +if (empty($conf->mymodule->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* @@ -187,7 +196,7 @@ if ($object->id > 0) { $head = myobjectPrepareHead($object); - print dol_get_fiche_head($head, 'agenda', '', -1, $object->picto); + print dol_get_fiche_head($head, 'agenda', $langs->trans("MyObject"), -1, $object->picto); // Object card // ------------------------------------------------------------ diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 531d463eea1..6d5c807c3f0 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -122,12 +122,23 @@ if (empty($action) && empty($id) && empty($ref)) { // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->rights->mymodule->myobject->read; + $permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php + $permissiontodelete = $user->rights->mymodule->myobject->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); + $permissionnote = $user->rights->mymodule->myobject->write; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $user->rights->mymodule->myobject->write; // Used by the include of actions_dellink.inc.php +} else { + $permissiontoread = 1; + $permissiontoadd = 1; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php + $permissiontodelete = 1; + $permissionnote = 1; + $permissiondellink = 1; +} -$permissiontoread = $user->rights->mymodule->myobject->read; -$permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php -$permissiontodelete = $user->rights->mymodule->myobject->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); -$permissionnote = $user->rights->mymodule->myobject->write; // Used by the include of actions_setnotes.inc.php -$permissiondellink = $user->rights->mymodule->myobject->write; // Used by the include of actions_dellink.inc.php $upload_dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object->entity : 1].'/myobject'; // Security check (enable the most restrictive one) @@ -135,8 +146,8 @@ $upload_dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object- //if ($user->socid > 0) $socid = $user->socid; //$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (!$permissiontoread) accessforbidden(); +if (empty($conf->mymodule->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* @@ -230,6 +241,11 @@ llxHeader('', $title, $help_url); // Part to create if ($action == 'create') { + if (empty($permissiontoadd)) { + accessforbidden($langs->trans('NotEnoughPermissions'), 0, 1); + exit; + } + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("MyObject")), '', 'object_'.$object->picto); print ''; diff --git a/htdocs/modulebuilder/template/myobject_contact.php b/htdocs/modulebuilder/template/myobject_contact.php index d2de342c861..64f5ebba976 100644 --- a/htdocs/modulebuilder/template/myobject_contact.php +++ b/htdocs/modulebuilder/template/myobject_contact.php @@ -78,15 +78,24 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals -$permission = $user->rights->mymodule->myobject->write; +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->rights->mymodule->myobject->read; + $permission = $user->rights->mymodule->myobject->write; +} else { + $permissiontoread = 1; + $permission = 1; +} // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; //$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (!$permissiontoread) accessforbidden(); +if (empty($conf->mymodule->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* @@ -152,7 +161,7 @@ if ($object->id) { */ $head = myobjectPrepareHead($object); - print dol_get_fiche_head($head, 'contact', '', -1, $object->picto); + print dol_get_fiche_head($head, 'contact', $langs->trans("MyObject"), -1, $object->picto); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php index 3db0271dd01..d1040364182 100644 --- a/htdocs/modulebuilder/template/myobject_document.php +++ b/htdocs/modulebuilder/template/myobject_document.php @@ -124,15 +124,24 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->mymodule->multidir_output[$object->entity ? $object->entity : $conf->entity]."/myobject/".get_exdir(0, 0, 0, 1, $object); } -$permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->rights->mymodule->myobject->read; + $permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php +} else { + $permissiontoread = 1; + $permission = 1; +} // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; //$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (!$permissiontoread) accessforbidden(); +if (empty($conf->mymodule->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* @@ -159,7 +168,7 @@ if ($object->id) { */ $head = myobjectPrepareHead($object); - print dol_get_fiche_head($head, 'document', '', -1, $object->picto); + print dol_get_fiche_head($head, 'document', $langs->trans("MyObject"), -1, $object->picto); // Build file list diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index ee4d4b73026..589f4052724 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -178,13 +178,17 @@ $object->fields = dol_sort_array($object->fields, 'position'); //$arrayfields['anotherfield'] = array('type'=>'integer', 'label'=>'AnotherField', 'checked'=>1, 'enabled'=>1, 'position'=>90, 'csslist'=>'right'); $arrayfields = dol_sort_array($arrayfields, 'position'); -$permissiontoread = $user->rights->mymodule->myobject->read; -$permissiontoadd = $user->rights->mymodule->myobject->write; -$permissiontodelete = $user->rights->mymodule->myobject->delete; - -// Security check -if (empty($conf->mymodule->enabled)) { - accessforbidden('Module not enabled'); +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->rights->mymodule->myobject->read; + $permissiontoadd = $user->rights->mymodule->myobject->write; + $permissiontodelete = $user->rights->mymodule->myobject->delete; +} else { + $permissiontoread = 1; + $permissiontoadd = 1; + $permissiontodelete = 1; } // Security check (enable the most restrictive one) @@ -193,9 +197,8 @@ if ($user->socid > 0) accessforbidden(); //$socid = 0; if ($user->socid > 0) $socid = $user->socid; //$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, 0, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (!$permissiontoread) accessforbidden(); - +if (empty($conf->mymodule->enabled)) accessforbidden('Module not enabled'); +if (!$permissiontoread) accessforbidden(); /* diff --git a/htdocs/modulebuilder/template/myobject_note.php b/htdocs/modulebuilder/template/myobject_note.php index 6733919289b..bda60f90d52 100644 --- a/htdocs/modulebuilder/template/myobject_note.php +++ b/htdocs/modulebuilder/template/myobject_note.php @@ -101,23 +101,35 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->mymodule->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id; } -$permissionnote = $user->rights->mymodule->myobject->write; // Used by the include of actions_setnotes.inc.php -$permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php + +// There is several ways to check permission. +// Set $enablepermissioncheck to 1 to enable a minimum low level of checks +$enablepermissioncheck = 0; +if ($enablepermissioncheck) { + $permissiontoread = $user->rights->mymodule->myobject->read; + $permissiontoadd = $user->rights->mymodule->myobject->write; + $permissionnote = $user->rights->mymodule->myobject->write; // Used by the include of actions_setnotes.inc.php +} else { + $permissiontoread = 1; + $permissiontoadd = 1; + $permissionnote = 1; +} // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; //$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (!$permissiontoread) accessforbidden(); +if (empty($conf->mymodule->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* * Actions */ -$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } @@ -134,14 +146,15 @@ $form = new Form($db); //$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; $help_url = ''; -llxHeader('', $langs->trans('MyObject'), $help_url); +$title = $langs->trans('MyObject').' - '.$langs->trans("Notes"); +llxHeader('', $title, $help_url); if ($id > 0 || !empty($ref)) { $object->fetch_thirdparty(); $head = myobjectPrepareHead($object); - print dol_get_fiche_head($head, 'note', '', -1, $object->picto); + print dol_get_fiche_head($head, 'note', $langs->trans("MyObject"), -1, $object->picto); // Object card // ------------------------------------------------------------ diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index 2da1672e089..21ebd1ec5f5 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -113,8 +113,8 @@ class Mo extends CommonObject 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>500, '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,), - 'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax100'), - 'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1, 'csslist'=>'tdoverflowmax100'), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', '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', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1, 'csslist'=>'tdoverflowmax100'), 'date_start_planned' => array('type'=>'datetime', 'label'=>'DateStartPlannedMo', 'enabled'=>1, 'visible'=>1, 'position'=>55, 'notnull'=>-1, 'index'=>1, 'help'=>'KeepEmptyForAsap'), 'date_end_planned' => array('type'=>'datetime', 'label'=>'DateEndPlannedMo', 'enabled'=>1, 'visible'=>1, 'position'=>56, 'notnull'=>-1, 'index'=>1,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,), diff --git a/htdocs/mrp/tpl/linkedobjectblock.tpl.php b/htdocs/mrp/tpl/linkedobjectblock.tpl.php index 5dbe583fd21..ff9aa269678 100644 --- a/htdocs/mrp/tpl/linkedobjectblock.tpl.php +++ b/htdocs/mrp/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index 0dc9f7ce63a..1ebf33d3925 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -493,20 +493,20 @@ class MultiCurrency extends CommonObject /** * Get id of currency from code * - * @param DoliDB $db object db + * @param DoliDB $dbs object db * @param string $code code value search * * @return int 0 if not found, >0 if OK */ - public static function getIdFromCode($db, $code) + public static function getIdFromCode($dbs, $code) { global $conf; - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE code = '".$db->escape($code)."' AND entity = ".$conf->entity; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE code = '".$dbs->escape($code)."' AND entity = ".((int) $conf->entity); dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $db->query($sql); - if ($resql && $obj = $db->fetch_object($resql)) { + $resql = $dbs->query($sql); + if ($resql && $obj = $dbs->fetch_object($resql)) { return $obj->rowid; } else { return 0; @@ -516,38 +516,38 @@ class MultiCurrency extends CommonObject /** * Get id and rate of currency from code * - * @param DoliDB $db Object db + * @param DoliDB $dbs Object db * @param string $code Code value search * @param integer $date_document Date from document (propal, order, invoice, ...) * * @return array [0] => id currency * [1] => rate */ - public static function getIdAndTxFromCode($db, $code, $date_document = '') + public static function getIdAndTxFromCode($dbs, $code, $date_document = '') { global $conf; $sql1 = "SELECT m.rowid, mc.rate FROM ".MAIN_DB_PREFIX."multicurrency m"; $sql1 .= ' LEFT JOIN '.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)'; - $sql1 .= " WHERE m.code = '".$db->escape($code)."'"; + $sql1 .= " WHERE m.code = '".$dbs->escape($code)."'"; $sql1 .= " AND m.entity IN (".getEntity('multicurrency').")"; $sql2 = ''; if (!empty($conf->global->MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE) && !empty($date_document)) { // Use last known rate compared to document date $tmparray = dol_getdate($date_document); - $sql2 .= " AND mc.date_sync <= '".$db->idate(dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], true))."'"; + $sql2 .= " AND mc.date_sync <= '".$dbs->idate(dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], true))."'"; } $sql3 = " ORDER BY mc.date_sync DESC LIMIT 1"; dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $db->query($sql1.$sql2.$sql3); + $resql = $dbs->query($sql1.$sql2.$sql3); - if ($resql && $obj = $db->fetch_object($resql)) { + if ($resql && $obj = $dbs->fetch_object($resql)) { return array($obj->rowid, $obj->rate); } else { if (!empty($conf->global->MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE)) { - $resql = $db->query($sql1.$sql3); - if ($resql && $obj = $db->fetch_object($resql)) { + $resql = $dbs->query($sql1.$sql3); + if ($resql && $obj = $dbs->fetch_object($resql)) { return array($obj->rowid, $obj->rate); } } @@ -746,7 +746,7 @@ class CurrencyRate extends CommonObjectLine */ public function __construct(DoliDB $db) { - $this->db = &$db; + $this->db = $db; return 1; } diff --git a/htdocs/multicurrency/multicurrency_rate.php b/htdocs/multicurrency/multicurrency_rate.php index 73cff1b4502..46742995bec 100644 --- a/htdocs/multicurrency/multicurrency_rate.php +++ b/htdocs/multicurrency/multicurrency_rate.php @@ -250,6 +250,7 @@ if (!in_array($action, array("updateRate", "deleteRate"))) { print ''; print ''; + print '
'; print '
'.$langs->trans("Property"); + print ''.$langs->trans("Property"); print ' ('.$langs->trans("SeeExamples").')'; print ''; @@ -2725,7 +2752,7 @@ if ($module == 'initmodule') { //print ''.$langs->trans("Disabled").''.$form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")).''.$langs->trans("Comment").'
'; + print ''; print ''; print '
'; + print ''; print dol_escape_htmltag($propname); print ''; @@ -2818,7 +2845,7 @@ if ($module == 'initmodule') { print ''; print ''; print ''; @@ -2874,7 +2901,7 @@ if ($module == 'initmodule') { print ''; print ''; print ''; + print ''; print ''; print ''; print ''; if ($proparrayofkeyval) { - print ''; - print dol_escape_htmltag(json_encode($proparrayofkeyval)); + print ''; + print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE)); print ''; } print ''; + print ''; if ($propname != 'rowid') { print ''.img_edit().''; print ''.img_delete().''; @@ -3079,14 +3106,14 @@ if ($module == 'initmodule') { print '
'; + print ''; print dol_escape_htmltag($menu['position']); print ''; + print ''; print dol_escape_htmltag($menu['enabled']); print ''; + print ''; print dol_escape_htmltag($menu['perms']); print '
'; print ' '; @@ -265,10 +266,12 @@ if (!in_array($action, array("updateRate", "deleteRate"))) { print ''; print '
'.$langs->trans('Date').''; print ''; - print ''; + print ''; print '
'; + print ''; + print ''; print '
'; @@ -404,7 +407,7 @@ if ($resql) { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } - print '
'; + print '
'; print ''."\n"; // Lines with input filters @@ -426,7 +429,7 @@ if ($resql) { // rate if (!empty($arrayfields['cr.rate']['checked'])) { print ''; } diff --git a/htdocs/opensurvey/results.php b/htdocs/opensurvey/results.php index 5b564f617fd..f372e847455 100644 --- a/htdocs/opensurvey/results.php +++ b/htdocs/opensurvey/results.php @@ -53,7 +53,7 @@ $nblines = $object->fetch_lines(); // Return to the results if (GETPOST('retoursondage')) { - header('Location: results.php?id='.GETPOST('id', 'int')); + header('Location: results.php?id='.(GETPOSTISSET('id_sondage') ? GETPOST('id_sondage', 'aZ09') : GETPOST('id', 'int'))); exit; } @@ -588,6 +588,7 @@ if (GETPOST('ajoutsujet')) { $tmparray = array('checkbox'=>$langs->trans("CheckBox"), 'yesno'=>$langs->trans("YesNoList"), 'foragainst'=>$langs->trans("PourContreList")); print $langs->trans("Type").' '.$form->selectarray("typecolonne", $tmparray, GETPOST('typecolonne')).'

'; print ''; + print ''; print '     '; print ''; print '

'."\n"; @@ -663,6 +664,7 @@ $nbcolonnes = substr_count($object->sujet, ',') + 1; print ''."\n"; print ''; +print ''; print '
'."\n"; @@ -851,7 +853,7 @@ while ($compteur < $num) { print '
'."\n"; + print ''."\n"; } //demande de confirmation pour modification de ligne @@ -1021,7 +1023,7 @@ while ($compteur < $num) { if ($compteur == $i) { print ''."\n"; } } diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 2d7d99a9ab3..eeeaa094f29 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -144,33 +144,17 @@ if ($action == 'other') { $value = GETPOST('activate_usesearchtoselectproduct', 'alpha'); $res = dolibarr_set_const($db, "PRODUIT_USE_SEARCH_TO_SELECT", $value, 'chaine', 0, '', $conf->entity); - $value = GETPOST('activate_useProdFournDesc', 'alpha'); - $res = dolibarr_set_const($db, "PRODUIT_FOURN_TEXTS", $value, 'chaine', 0, '', $conf->entity); - $value = GETPOST('activate_FillProductDescAuto', 'alpha'); $res = dolibarr_set_const($db, "PRODUIT_AUTOFILL_DESC", $value, 'chaine', 0, '', $conf->entity); - if ($value) { - $sql_test = "SELECT count(desc_fourn) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; - $resql = $db->query($sql_test); - if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') { // if the field does not exist, we create it - $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN desc_fourn text"; - $resql_new = $db->query($sql_new); - } - } + $value = GETPOST('PRODUIT_FOURN_TEXTS', 'alpha'); + $res = dolibarr_set_const($db, "PRODUIT_FOURN_TEXTS", $value, 'chaine', 0, '', $conf->entity); - $value = GETPOST('activate_useProdSupplierPackaging', 'alpha'); + $value = GETPOST('PRODUCT_USE_SUPPLIER_PACKAGING', 'alpha'); $res = dolibarr_set_const($db, "PRODUCT_USE_SUPPLIER_PACKAGING", $value, 'chaine', 0, '', $conf->entity); - if ($value) { - $sql_test = "SELECT count(packaging) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; - $resql = $db->query($sql_test); - if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') { // if the field does not exist, we create it - $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN packaging double(24,8) DEFAULT 1"; - $resql_new = $db->query($sql_new); - } - } } + if ($action == 'specimen') { // For products $modele = GETPOST('module', 'alpha'); @@ -250,12 +234,22 @@ if ($action == 'set') { } } -//if ($action == 'other') -//{ -// $value = GETPOST('activate_units', 'alpha'); -// $res = dolibarr_set_const($db, "PRODUCT_USE_UNITS", $value, 'chaine', 0, '', $conf->entity); -// if (! $res > 0) $error++; -//} +// To enable a constant whithout javascript +if (preg_match('/set_(.+)/', $action, $reg)) { + $keyforvar = $reg[1]; + if ($keyforvar) { + $value = 1; + $res = dolibarr_set_const($db, $keyforvar, $value, 'chaine', 0, '', $conf->entity); + } +} + +// To disable a constant whithout javascript +if (preg_match('/del_(.+)/', $action, $reg)) { + $keyforvar = $reg[1]; + if ($keyforvar) { + $res = dolibarr_del_const($db, $keyforvar, $conf->entity); + } +} if ($action) { if (!$error) { @@ -590,7 +584,7 @@ print ''; if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print ''; print ''; - print ''; + print ''; print ''; } @@ -604,16 +598,18 @@ print ''; if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { print ''; - print ''; - print ''; + print ''; print ''; print ''; - print ''; - print ''; + print ''; print ''; } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 8e61663d339..839a9f18ba2 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -272,7 +272,7 @@ class Product extends CommonObject public $fk_default_bom; /** - * We must manage lot/batch number, sell-by date and so on : '1':yes '0':no + * We must manage lot/batch number, sell-by date and so on : '0':no, '1':yes, '2": yes with unique serial number * * @var int */ @@ -1979,7 +1979,10 @@ class Product extends CommonObject $sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code,"; $sql .= " pfp.packaging"; $sql .= " FROM ".$this->db->prefix()."product_fournisseur_price as pfp"; - $sql .= " WHERE pfp.fk_product = ".((int) $product_id); + $sql .= " WHERE 1 = 1"; + if ($product_id > 0) { + $sql .= " AND pfp.fk_product = ".((int) $product_id); + } if ($fourn_ref != 'none') { $sql .= " AND pfp.ref_fourn = '".$this->db->escape($fourn_ref)."'"; } diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index b743dffbc53..c840ff3438a 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -349,7 +349,7 @@ $next_day = $next['mday']; $title = $langs->trans("TimeSpent"); -$projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess, (empty($usertoprocess->id) ? 2 : 0), 1); // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project +$projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess, (empty($usertoprocess->id) ? 2 : 0), 1); // Return all project i have permission on (assigned to me+public). I want my tasks and some of my task may be on a public projet that is not my project if ($id) { $project->fetch($id); @@ -476,12 +476,12 @@ if ($usertoprocess->id != $user->id) { $titleassigntask = $langs->transnoentities("AssignTaskToUser", $usertoprocess->getFullName($langs)); } print '
'; -print img_picto('', 'projecttask'); +print img_picto('', 'projecttask', 'class="pictofixedwidth"'); $formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, '', '', 'all', $usertoprocess); print '
'; print ' '; print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'rowid', 0, 'maxwidth150onsmartphone'); -print ''; +print ''; print ''; print '
'; @@ -596,10 +596,10 @@ $extrafieldsobjectkey = 'projet_task'; $extrafieldsobjectprefix = 'efpt.'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; if (!empty($arrayfields['t.planned_workload']['checked'])) { - print ''; + print ''; } if (!empty($arrayfields['t.progress']['checked'])) { - print ''; + print ''; } if (!empty($arrayfields['timeconsumed']['checked'])) { print ''; - print ''; + print ''; } print ''; + print ''; } if (!empty($arrayfields['t.progress']['checked'])) { - print ''; + print ''; } if (!empty($arrayfields['timeconsumed']['checked'])) { print ''; - print ''; + print ''; } for ($idw = 0; $idw < 7; $idw++) { $dayinloopfromfirstdaytoshow = dol_time_plus_duree($firstdaytoshow, $idw, 'd'); // $firstdaytoshow is a date with hours = 0 @@ -691,7 +692,7 @@ for ($idw = 0; $idw < 7; $idw++) { $cssonholiday .= 'onholidayafternoon '; } - print ''; } diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index 9e8d3a6ce8e..2301017edd9 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page $langs->loadLangs(array('projects', 'other')); +$hookmanager->initHooks(array('projectcarddocument')); $action = GETPOST('action', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index c0afe5d1370..9b0544bccf6 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -62,6 +62,8 @@ if (GETPOST('actioncode', 'array')) { } $search_agenda_label = GETPOST('search_agenda_label'); +$hookmanager->initHooks(array('projectcardinfo')); + // Security check $id = GETPOST("id", 'int'); $socid = 0; diff --git a/htdocs/projet/tasks/stats/index.php b/htdocs/projet/tasks/stats/index.php index 70c093f46e3..2ca72552fa4 100644 --- a/htdocs/projet/tasks/stats/index.php +++ b/htdocs/projet/tasks/stats/index.php @@ -180,7 +180,7 @@ print '

'; print '
'; print '
'; - print ''; + print ''; print '
'."\n"; if ($user->rights->opensurvey->write) { - print ''."\n"; + print ''."\n"; } // Name @@ -1012,7 +1014,7 @@ while ($compteur < $num) { // Button edit at end of line if ($compteur != $ligneamodifier && ($user->rights->opensurvey->write)) { - print ''; print ''; - print ''; + print ''; print '
'.$langs->trans("MultiPricesNumPrices").'
'.$langs->trans("UseProductFournDesc").''; - print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1); + print ''.$langs->trans("UseProductSupplierPackaging").''; + print ajax_constantonoff("PRODUCT_USE_SUPPLIER_PACKAGING", array(), $conf->entity, 0, 0, 0, 0); + //print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1); print '
'.$langs->trans("UseProductSupplierPackaging").''; - print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1); + print ''.$langs->trans("UseProductFournDesc").''; + print ajax_constantonoff("PRODUIT_FOURN_TEXTS", array(), $conf->entity, 0, 0, 0, 0); + //print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1); print '
'.$langs->trans("PlannedWorkload").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").'trans("ProgressDeclared")).'">'.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").'
'; @@ -608,7 +608,7 @@ if (!empty($arrayfields['timeconsumed']['checked'])) { print ''.$langs->trans("Everybody").''; print ''; print '
'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '
'.$usertoprocess->getNomUrl(-2).''.dol_trunc($usertoprocess->firstname, 10).'' : '').'
'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '
'.$usertoprocess->getNomUrl(-2).''.dol_trunc($usertoprocess->firstname, 10).'' : '').'
'.$langs->trans("HourStart").''; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 6cb4a8600fc..591abb44181 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -119,6 +119,7 @@ $extrafields = new ExtraFields($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); +// Definition of fields for list $arrayfields = array(); /*$arrayfields=array( // Project @@ -441,7 +442,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // Show navigation bar $nav = ''.img_previous($langs->trans("Previous"))."\n"; -$nav .= " ".dol_print_date(dol_mktime(0, 0, 0, $first_month, $first_day, $first_year), "%Y").", ".$langs->trans("WeekShort")." ".$week." \n"; +$nav .= ' '.dol_print_date(dol_mktime(0, 0, 0, $first_month, $first_day, $first_year), "%Y").", ".$langs->trans("WeekShort")." ".$week." \n"; $nav .= ''.img_next($langs->trans("Next"))."\n"; $nav .= ' '.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, 1).' '; $nav .= ' '; @@ -652,10 +653,10 @@ $extrafieldsobjectkey = 'projet_task'; $extrafieldsobjectprefix = 'efpt.'; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; if (!empty($arrayfields['t.planned_workload']['checked'])) { - print ''.$langs->trans("PlannedWorkload").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").'
'; @@ -664,7 +665,7 @@ if (!empty($arrayfields['timeconsumed']['checked'])) { print ''.$langs->trans("Everybody").''; print ''; print '
'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '
'.$usertoprocess->getNomUrl(-2).''.dol_trunc($usertoprocess->firstname, 10).'' : '').'
'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '
'.$usertoprocess->getNomUrl(-2).''.dol_trunc($usertoprocess->firstname, 10).'' : '').'
'; + print ''; print dol_print_date($dayinloopfromfirstdaytoshow, '%a'); print '
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').'
'; -print ''; +print ''; print ''; print ''; print ''; @@ -191,14 +191,14 @@ foreach ($data_all_year as $val) { while ($year && $oldyear > $year + 1) { // If we have empty year $oldyear--; - print ''; - print ''; + print ''; + print ''; print ''; print ''; } - print ''; - print ''; + print ''; + print ''; print ''; print ''; $oldyear = $year; diff --git a/htdocs/public/opensurvey/studs.php b/htdocs/public/opensurvey/studs.php index a1c9efed6c3..21fe3d9d7a1 100644 --- a/htdocs/public/opensurvey/studs.php +++ b/htdocs/public/opensurvey/studs.php @@ -285,10 +285,11 @@ print '
'."\n"; // show title of survey $titre = str_replace("\\", "", $object->title); -print ''.dol_htmlentities($titre).'

'."\n"; +print ''.dol_htmlentities($titre).''; // show description of survey if ($object->description) { + print '

'."\n"; print dol_htmlentitiesbr($object->description); print '
'."\n"; } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 9765af89f7e..81d24c9f7c3 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -243,7 +243,7 @@ if (!empty($conf->paypal->enabled)) { $fulltag = $FULLTAG; $payerID = $PAYPALPAYERID; // Set by newpayment.php - $paymentType = $_SESSION['PaymentType']; + $paymentType = $_SESSION['PaymentType']; // Value can be 'Mark', 'Sole', 'Sale' for example $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; // From env @@ -404,10 +404,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } dol_syslog("FinalPaymentAmt=".$FinalPaymentAmt." paymentTypeId=".$paymentTypeId." paymentType=".$paymentType." currencyCodeType=".$currencyCodeType, LOG_DEBUG, 0, '_payment'); @@ -781,10 +790,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -874,12 +892,29 @@ if ($ispaymentok) { $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; $paymentTypeId = 0; - if ($paymentmethod == 'paybox') $paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS; - if ($paymentmethod == 'paypal') $paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS; - if ($paymentmethod == 'stripe') $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; + if ($paymentmethod == 'paybox') { + $paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS; + } + if ($paymentmethod == 'paypal') { + $paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS; + } + if ($paymentmethod == 'stripe') { + $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; + } if (empty($paymentTypeId)) { - if (empty($paymentType)) $paymentType = 'CB'; + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + + if (empty($paymentType)) { + $paymentType = 'CB'; + } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -984,10 +1019,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -1089,10 +1133,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -1270,10 +1323,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) diff --git a/htdocs/reception/tpl/linkedobjectblock.tpl.php b/htdocs/reception/tpl/linkedobjectblock.tpl.php index c8ff1196c0f..1bfecac3f1d 100644 --- a/htdocs/reception/tpl/linkedobjectblock.tpl.php +++ b/htdocs/reception/tpl/linkedobjectblock.tpl.php @@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf)) { ?> - + initHooks(array('thirdpartydao')); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 66a75ef7050..3453d0e0579 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -912,6 +912,7 @@ $form = new Form($db);
'.$langs->trans("Year").''.$langs->trans("NbOfTasks").'
0 ? '&userid='.$userid : '').'">'.$oldyear.'
0 ? '&userid='.$userid : '').'">'.$oldyear.'0
0 ? '&userid='.$userid : '').'">'.$year.'
0 ? '&userid='.$userid : '').'">'.$year.''.$val['nb'].'