Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 20.0

This commit is contained in:
Laurent Destailleur
2025-02-26 22:51:29 +01:00
54 changed files with 341 additions and 163 deletions

103
ChangeLog
View File

@@ -2,6 +2,109 @@
English Dolibarr ChangeLog
--------------------------------------------------------------
***** ChangeLog for 20.0.4 compared to 20.0.3 *****
FIX: $this->origin_object can not be instance of CommandeFournisseur if it is already an instanceof CommonObject
FIX: 17.0 API endpoints "PUT": prevent overwriting all extrafields if only some are supplied in the request cf. PR #29237
FIX: 17.0 - collisions in cache for dol_getIdFromCode
FIX: #18713
FIX: 20.0 - PHP8 fatal when creating a reception unless corresponding PDF model is enabled
FIX: #21294 Stock import sql query
FIX: #26250 fatal error on kit
FIX: #28702
FIX: #29624 - substitution of __DATE_DELIVERY__
FIX: #32113
FIX: #32186
FIX: #32339 Delete a loan settlement is partial
FIX: #32387
FIX: #32477 Loan - Insurance amount need decimals
FIX: #32611
FIX: #32736 + avoid php warning
FIX: #32743
FIX: #32765 JS Error: Uncaught TypeError
FIX: #32801 VAT type is inverted in form VAT selector
FIX: #32840
FIX: #32843
FIX: #32880 - Tags are using a special rendering.
FIX: add other fields
FIX: autofill price with multicurrency on supplier doc
FIX: avoid phan error
FIX: avoid php8 warnings
FIX: avoid warning with the new Dolistore website
FIX: backport from develop to avoid php warning
FIX: Bad calculation of the theoretical stock. Did not take into account
FIX: bad dispatched quantities for batches on shipment card
FIX: Brian is in the kitchen
FIX: broken feature, compatibility with "Default search filters"
FIX: broken feature with check $pa_ht_isemptystring
FIX: Bug on select user on time.php (all project list)
FIX: can not delete files in task card
FIX: Check "$search_sale" only if it's an internal user
FIX: clean unique extrafields when create product combination
FIX: code not visible correctly into view of dictionary
FIX: compatibility between next_prev_filter and hook return
FIX: compatibility with multicompany
FIX: Complete path was started in #17243 for pdf_cannelle
FIX: Continue for eagle_proforma
FIX: country id is not saved when we provide country_code only
FIX: #CVE-2024-34051
FIX: delete supplier order when at least one line linked to customer order line
FIX: display error when loan can't be deleted
FIX: display full tree on shipment card when a kit contains a same component in other sub-kit
FIX: DROP INDEX IF EXISTS is not possible !
FIX: extrafields lost during creation from rec invoice
FIX: FEC import
FIX: Fiscal year - missing translation on status
FIX: Fix return value of hook sendMail when hook return -1 who must be return false in sendfile() function
FIX: GETPOST('private_message')
FIX: glob is better for search files with wildcard + avoid warning
FIX: if $force_entity = 0 ($force_entity != 'default') = false
FIX: Loan - Insurance amount need decimals
FIX: Many status on invoice linked object block
FIX: merge problem
FIX: missing company name if donation is linked to third party
FIX: missing default values if $objsrc or $soc fields are empty
FIX: missing edit extrafields inline for member card
FIX: missing quick edit for extrafields
FIX: more bugs and warnings
FIX: Multilangs : PDF lines description
FIX: Must not have both thirdparty and member.
FIX: ODT substitution when many HTML tags in string
FIX: on the road again
FIX: pdf_cannelle (supplier_invoice) add background - Complete #17243
FIX: Prices didn't update when clone a propale with update prices
FIX: product variants copy: also copy multiprice variations
FIX: refactorize (maybe broken feature for not received completely)
FIX: remove debug trace
FIX: remove socid when cloning a project without third parties
FIX: removes traces of <<<HEAD conflicts following the postponement of branch 13 modifications (#32014)
FIX: remove unused code
FIX: same broken feature for propal and invoice
FIX: select 2 no record found translate
FIX: selectcontact is loading all contacts if socid is empty and MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT is not set
FIX: selectcontact is loading all contacts when update event
FIX: select group and severity search fields on ticket list
FIX: send email to assigned user on ticket create
FIX: sql error with the new sql forge filter
FIX: sql "order by" is defined twice
FIX: status ticket update for new message
FIX: swap tests
FIX: switch on/off status of a page of the second website.
FIX: There were many status indicator in the invoice linked object block (propal card)
FIX: uniformize code
FIX: units used scale and scale is an integer
FIX: wrong alias table
FIX: wrong file path + avoid warning
FIX: wrong filter format
FIX: wrong "fournisseur" var value checking
FIX: wrong left margin
FIX: wrong message on update shipment
FIX: wrong ODT path for multicompany
FIX: wrong path for odt models
FIX: wrong search filter, empty product unit is "none"
FIX: wrong update function parameter
FIX: some wrong var type
FIX: some wrong var name
***** ChangeLog for 20.0.3 compared to 20.0.2 *****
FIX: 17.0 - missing error handling for FactureRec::fetch in card-rec.php
FIX: 17.0 - warnings due to uninitialized variables + delete code that doesn't apply to recurring invoices (AFAIK, there is no recurring credit note feature)

View File

@@ -36,7 +36,7 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/
"RPM_FEDORA"=>"rpmbuild",
"RPM_MANDRIVA"=>"rpmbuild",
"RPM_OPENSUSE"=>"rpmbuild",
"DEB"=>"dpkg",
"DEB"=>"dpkg,po2debconf", # need also debhelper
"FLATPACK"=>"flatpack",
"EXEDOLIWAMP"=>"ISCC.exe",
"SNAPSHOT"=>"tar"
@@ -85,8 +85,9 @@ if (! $ENV{"DESTIBETARC"} || ! $ENV{"DESTISTABLE"})
print "set DESTIBETARC=c:/tmp\n";
print "set DESTISTABLE=c:/tmp\n";
print "\n";
print "Example: DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild'\n";
print "Example: DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable'\n";
print "Example in .bashrc:\n";
print "export DESTIBETARC='/mnt/HDDATA1_LD/Mes Archives/Doli/dolibarr/lastbuild'\n";
print "export DESTISTABLE='/mnt/HDDATA1_LD/Mes Archives/Doli/dolibarr/stable'\n";
sleep 2;
exit 1;
}

View File

@@ -1000,7 +1000,7 @@ class AccountancyExport
// We need to keep the 10 latest number of invoices doc_ref not the beginning part that is the useless almost same part
// $tab['num_piece3'] = str_pad(self::trunc($line->piece_num, 10), 10);
$tab['num_piece3'] = substr(self::trunc($line->doc_ref, 20), -10);
$tab['num_piece3'] = str_pad(substr(self::trunc($line->doc_ref, 20), -10), 10);
$tab['reserved'] = str_repeat(' ', 10); // position 159
$tab['currency_amount'] = str_repeat(' ', 13); // position 169
// get document file

View File

@@ -614,7 +614,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled
$deschelp .= '<div class="info hideonsmartphone">'.$desc."<br></div>\n";
}
if (getDolGlobalString('MAIN_SETUP_MODULES_INFO')) { // Show a custom message
if (getDolGlobalString('MAIN_SETUP_MODULES_INFO')) { // Show a custom message. A good usage for SaaS with option MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING.
$deschelp .= '<div class="info">'.$langs->trans(getDolGlobalString('MAIN_SETUP_MODULES_INFO'))."<br></div>\n";
}
if ($deschelp) {

View File

@@ -292,7 +292,7 @@ class BOM extends CommonObject
* @param int $notrigger false=launch triggers after, true=disable triggers
* @return int Return integer <0 if KO, Id of created object if OK
*/
public function create(User $user, $notrigger = 1)
public function create(User $user, $notrigger = 0)
{
if ($this->efficiency <= 0 || $this->efficiency > 1) {
$this->efficiency = 1;
@@ -546,7 +546,7 @@ class BOM extends CommonObject
* @param int $notrigger 0=launch triggers after, 1=disable triggers
* @return int Return integer <0 if KO, >0 if OK
*/
public function update(User $user, $notrigger = 1)
public function update(User $user, $notrigger = 0)
{
if ($this->efficiency <= 0 || $this->efficiency > 1) {
$this->efficiency = 1;

View File

@@ -461,6 +461,12 @@ if ($filtert > 0 || $usergroup > 0) {
if ($usergroup > 0) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element";
}
// Add table from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql .= " WHERE a.entity IN (".getEntity('agenda').")";
// Condition on actioncode
if (!empty($actioncode)) {

View File

@@ -1922,7 +1922,7 @@ if ($action == 'create') {
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
$warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
}
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->warehouse_id)) {
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->fk_warehouse)) {
$warehouse_id = $user->fk_warehouse;
}
}

View File

@@ -1836,7 +1836,7 @@ if ($action == 'create' && $usercancreate) {
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
$warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
}
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->warehouse_id)) {
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->fk_warehouse)) {
$warehouse_id = $user->fk_warehouse;
}
}

View File

@@ -767,7 +767,7 @@ class PaymentVarious extends CommonObject
*/
public function info($id)
{
$sql = 'SELECT v.rowid, v.datec, v.fk_user_author';
$sql = 'SELECT v.rowid, v.datec, v.fk_user_author, fk_user_modif, tms';
$sql .= ' FROM '.MAIN_DB_PREFIX.'payment_various as v';
$sql .= ' WHERE v.rowid = '.((int) $id);
@@ -780,6 +780,7 @@ class PaymentVarious extends CommonObject
$this->id = $obj->rowid;
$this->user_creation = $obj->fk_user_author;
$this->user_creation_id = $obj->fk_user_author;
$this->user_modification_id = $obj->fk_user_modif;
$this->date_creation = $this->db->jdate($obj->datec);
$this->date_modification = $this->db->jdate($obj->tms);

View File

@@ -129,7 +129,7 @@ if ($object->id) {
$morehtmlref .= '</div>';
$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlstatus = $morehtmlright;
$morehtmlstatus = '';
dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
print '<div class="fichecenter">';

View File

@@ -145,10 +145,14 @@ $result = restrictedArea($user, 'facture', $object->id, $objecttype);
/*
* Actions
*/
if (GETPOST('cancel', 'alpha')) {
$action = 'list';
$massaction = '';
if ($action != 'updateline') {
$action = 'list';
$massaction = '';
} else {
$action = '';
$cancel = '';
}
}
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
$massaction = '';

View File

@@ -2006,7 +2006,7 @@ if (empty($reshook)) {
$line->fk_prev_id = $line->id;
$line->fetch_optionals();
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) {
$line->situation_percent = $line->get_allprev_progress($object->id);; // get good progress including credit note
$line->situation_percent = 0; // New situation percent must be 0 (No cumulative)
} else {
$line->situation_percent = $line->get_prev_progress($object->id); // get good progress including credit note
}

View File

@@ -2496,10 +2496,12 @@ class Facture extends CommonInvoice
if (isset($this->retained_warranty)) {
$this->retained_warranty = (float) $this->retained_warranty;
}
// Check parameters
// Put here code to add control on parameters values
if (!isset($this->user_creation_id) && isset($this->fk_user_author) ) {
$this->user_creation_id = $this->fk_user_author;
}
if (!isset($this->user_validation_id) && isset($this->fk_user_valid) ) {
$this->user_validation_id = $this->fk_user_valid;
}
// Update request
$sql = "UPDATE ".MAIN_DB_PREFIX."facture SET";
@@ -2524,7 +2526,8 @@ class Facture extends CommonInvoice
$sql .= " total_ttc=".(isset($this->total_ttc) ? (float) $this->total_ttc : "null").",";
$sql .= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '') ? (float) $this->revenuestamp : "null").",";
$sql .= " fk_statut=".(isset($this->status) ? (int) $this->status : "null").",";
$sql .= " fk_user_valid=".(isset($this->fk_user_valid) ? (int) $this->fk_user_valid : "null").",";
$sql .= " fk_user_author=".(isset($this->user_creation_id) ? ((int) $this->user_creation_id) : "null").",";
$sql .= " fk_user_valid=".(isset($this->user_validation_id) ? (int) $this->user_validation_id : "null").",";
$sql .= " fk_facture_source=".(isset($this->fk_facture_source) ? (int) $this->fk_facture_source : "null").",";
$sql .= " fk_projet=".(isset($this->fk_project) ? (int) $this->fk_project : "null").",";
$sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? (int) $this->cond_reglement_id : "null").",";
@@ -3871,7 +3874,12 @@ class Facture extends CommonInvoice
$fk_prev_id = 'null';
}
if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '' || $situation_percent == null) {
$situation_percent = 100;
// INVOICE_USE_SITUATION = 2 - Lines situation percent on new lines must be 0 (No cumulative)
if ($this->type == Facture::TYPE_SITUATION && getDolGlobalInt('INVOICE_USE_SITUATION') == 2 && (int) $situation_percent < 100) {
$situation_percent = 0;
} else {
$situation_percent = 100;
}
}
if (empty($ref_ext)) {
$ref_ext = '';
@@ -5061,11 +5069,12 @@ class Facture extends CommonInvoice
//Avoid php warning Warning: mt_rand(): max(0) is smaller than min(1) when no product exists
if (empty($num_prods)) {
$num_prods = 1;
$prodids[$num_prods] = 1;
}
// Initialize parameters
$this->id = 0;
$this->entity = 1;
$this->entity = $conf->entity;
$this->ref = 'SPECIMEN';
$this->specimen = 1;
$this->socid = 1;

View File

@@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2020 Maxime Kohlhaas <maxime@atm-consulting.fr>
* Copyright (C) 2023 Ferran Marcet <fmarcet@2byte.es>
/* Copyright (C) 2020 Maxime Kohlhaas <maxime@atm-consulting.fr>
* Copyright (C) 2023 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
*
* 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
@@ -56,11 +57,25 @@ $socid = GETPOSTINT('socid');
// Category
$selected_cat = GETPOSTINT('search_categ');
if ($selected_cat == -1) {
$selected_cat = 0;
}
$subcat = false;
if (GETPOST('subcat', 'alpha') === 'yes') {
$subcat = true;
}
// Security check
if ($user->socid > 0) {
$socid = $user->socid;
}
if (isModEnabled('comptabilite')) {
$result = restrictedArea($user, 'compta', '', '', 'resultat');
}
if (isModEnabled('accounting')) {
$result = restrictedArea($user, 'accounting', '', '', 'comptarapport');
}
// Hook
$hookmanager->initHooks(array('supplierturnoverbythirdpartylist'));
@@ -148,12 +163,24 @@ $commonparams['sortorder'] = $sortorder;
$commonparams['sortfield'] = $sortfield;
$headerparams = array();
$headerparams['date_startyear'] = $date_startyear;
$headerparams['date_startmonth'] = $date_startmonth;
$headerparams['date_startday'] = $date_startday;
$headerparams['date_endyear'] = $date_endyear;
$headerparams['date_endmonth'] = $date_endmonth;
$headerparams['date_endday'] = $date_endday;
if (!empty($date_startyear)) {
$headerparams['date_startyear'] = $date_startyear;
}
if (!empty($date_startmonth)) {
$headerparams['date_startmonth'] = $date_startmonth;
}
if (!empty($date_startday)) {
$headerparams['date_startday'] = $date_startday;
}
if (!empty($date_endyear)) {
$headerparams['date_endyear'] = $date_endyear;
}
if (!empty($date_endmonth)) {
$headerparams['date_endmonth'] = $date_endmonth;
}
if (!empty($date_endday)) {
$headerparams['date_endday'] = $date_endday;
}
$tableparams = array();
$tableparams['search_categ'] = $selected_cat;
@@ -173,16 +200,7 @@ foreach ($allparams as $key => $value) {
$paramslink .= '&'.$key.'='.$value;
}
// Security check
if ($user->socid > 0) {
$socid = $user->socid;
}
if (isModEnabled('comptabilite')) {
$result = restrictedArea($user, 'compta', '', '', 'resultat');
}
if (isModEnabled('accounting')) {
$result = restrictedArea($user, 'accounting', '', '', 'comptarapport');
}
/*
@@ -203,6 +221,9 @@ if ($modecompta == "BOOKKEEPINGCOLLECTED") {
$modecompta = "RECETTES-DEPENSES";
}
$namelink = '';
$builddate = dol_now();
// Show report header
if ($modecompta == "CREANCES-DETTES") {
$name = $langs->trans("PurchaseTurnover").', '.$langs->trans("ByThirdParties");
@@ -223,7 +244,6 @@ if ($modecompta == "CREANCES-DETTES") {
// TODO
}
$builddate = dol_now();
$period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
$period .= ' - ';
$period .= $form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver');
@@ -235,7 +255,7 @@ if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) {
$exportlink = '';
report_header($name, '', $period, $periodlink, $description, $builddate, $exportlink, $tableparams, $calcmode);
report_header($name, $namelink, $period, $periodlink, $description, $builddate, $exportlink, $tableparams, $calcmode);
if (isModEnabled('accounting')) {
if ($modecompta != 'BOOKKEEPING') {

View File

@@ -395,10 +395,6 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql .= $db->order($sortfield, $sortorder);
//print $sql;
// Count total nb of records
$nbtotalofrecords = '';
if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
@@ -410,7 +406,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
}
}
// Complete request and execute it with limit
// Complete request and execute it with order and limit
$sql .= $db->order($sortfield, $sortorder);
if ($limit) {
$sql .= $db->plimit($limit + 1, $offset);

View File

@@ -701,7 +701,7 @@ abstract class CommonObject
public $user_creation;
/**
* @var int User id author/creation
* @var int|null User id author/creation
*/
public $user_creation_id;
@@ -5487,16 +5487,12 @@ abstract class CommonObject
}
$this->tpl['label'] .= $discount->getNomUrl(0, 'discount');
} elseif (!empty($line->fk_product)) {
$productstatic = new Product($this->db);
$productstatic->id = $line->fk_product;
$productstatic->ref = $line->ref;
$productstatic->type = $line->fk_product_type;
if (empty($productstatic->ref)) {
if (empty($line->product)) {
$line->fetch_product();
$productstatic = $line->product;
}
$productstatic = $line->product;
$this->tpl['label'] .= $productstatic->getNomUrl(1);
$this->tpl['label'] .= (is_object($productstatic) ? $productstatic->getNomUrl(1) : $line->ref);
$this->tpl['label'] .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
// Dates
if ($line->product_type == 1 && ($date_start || $date_end)) {
@@ -10059,9 +10055,9 @@ abstract class CommonObject
/**
* Create object in the database
*
* @param User $user User that creates
* @param int<0,1> $notrigger 0=launch triggers after, 1=disable triggers
* @return int<-1,max> Return integer <0 if KO, Id of created object if OK
* @param User $user User that creates
* @param int<0,1> $notrigger 0=launch triggers after, 1=disable triggers
* @return int<-1,max> Return integer <0 if KO, Id of created object if OK
*/
public function createCommon(User $user, $notrigger = 0)
{
@@ -10080,6 +10076,7 @@ abstract class CommonObject
if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) {
$fieldvalues['date_creation'] = $this->db->idate($now);
}
// For backward compatibility, if a property ->fk_user_creat exists and not filled.
if (array_key_exists('fk_user_creat', $fieldvalues) && !($fieldvalues['fk_user_creat'] > 0)) {
$fieldvalues['fk_user_creat'] = $user->id;
$this->fk_user_creat = $user->id;

View File

@@ -58,8 +58,11 @@ class FileUpload
$this->element = $element;
$pathname = str_replace('/class', '', $element_prop['classpath']);
$filename = dol_sanitizeFileName($element_prop['classfile']);
$dir_output = dol_sanitizePathName($element_prop['dir_output']);
$savingDocMask = '';
//print 'fileupload.class.php: element='.$element.' pathname='.$pathname.' filename='.$filename.' dir_output='.$dir_output."\n";
@@ -75,6 +78,11 @@ class FileUpload
$object_ref = dol_sanitizeFileName($object->ref);
// add object reference as file name prefix if const MAIN_DISABLE_SUGGEST_REF_AS_PREFIX is not enabled
if (!getDolGlobalInt('MAIN_DISABLE_SUGGEST_REF_AS_PREFIX')) {
$savingDocMask = $object_ref.'-__file__';
}
// Special cases to forge $object_ref used to forge $upload_dir
if ($element == 'invoice_supplier') {
$object_ref = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$object_ref;
@@ -100,6 +108,7 @@ class FileUpload
'script_url' => $_SERVER['PHP_SELF'],
'upload_dir' => $dir_output.'/'.$object_ref.'/',
'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/',
'saving_doc_mask' => $savingDocMask,
'param_name' => 'files',
// Set the following option to 'POST', if your server does not support
// DELETE requests. This is a parameter sent to the client:
@@ -425,6 +434,14 @@ class FileUpload
if ($validate) {
if (dol_mkdir($this->options['upload_dir']) >= 0) {
// add object reference as file name prefix if const MAIN_DISABLE_SUGGEST_REF_AS_PREFIX is not enabled
$fileNameWithoutExt = preg_replace('/\.[^\.]+$/', '', $file->name);
$savingDocMask = $this->options['saving_doc_mask'];
if ($savingDocMask && strpos($savingDocMask, $fileNameWithoutExt) !== 0) {
$fileNameWithPrefix = preg_replace('/__file__/', $file->name, $savingDocMask);
$file->name = $fileNameWithPrefix;
}
$file_path = dol_sanitizePathName($this->options['upload_dir']).dol_sanitizeFileName($file->name);
$append_file = !$this->options['discard_aborted_uploads'] && dol_is_file($file_path) && $file->size > dol_filesize($file_path);

View File

@@ -4596,7 +4596,7 @@ class Form
if (depositPercent.length > 0) {
$("#' . $htmlname . '_deposit_percent_container").show().find("#' . $htmlname . '_deposit_percent").val(depositPercent);
} else {
$("#' . $htmlname . '_deposit_percent_container").hide();
$("#' . $htmlname . '_deposit_percent_container").hide().find("#' . $htmlname . '_deposit_percent").val(0);
}
return true;

View File

@@ -3296,7 +3296,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
} elseif (isModEnabled("service")) {
$original_file = $conf->service->multidir_output[$entity].'/'.$original_file;
}
} elseif ($modulepart == 'product_batch' || $modulepart == 'produitlot') {
} elseif ($modulepart == 'product_batch' || $modulepart == 'productlot') {
// Wrapping pour les lots produits
if (empty($entity) || (empty($conf->productbatch->multidir_output[$entity]))) {
return array('accessallowed' => 0, 'error' => 'Value entity must be provided');

View File

@@ -13502,7 +13502,7 @@ function forgeSQLFromUniversalSearchCriteria($filter, &$errorstr = '', $noand =
$ret = ($noand ? "" : " AND ").($nopar ? "" : '(').preg_replace_callback('/'.$regexstring.'/i', 'dolForgeCriteriaCallback', $filter).($nopar ? "" : ')');
if (is_object($db)) {
$ret = str_replace('__NOW__', $db->idate(dol_now()), $ret);
$ret = str_replace('__NOW__', "'".$db->idate(dol_now())."'", $ret);
}
if (is_object($user)) {
$ret = str_replace('__USER_ID__', (string) $user->id, $ret);
@@ -13733,8 +13733,10 @@ function dolForgeCriteriaCallback($matches)
$tmpescaped = 'NULL';
} elseif (is_int($tmpescaped)) {
$tmpescaped = (int) $tmpescaped;
} else {
} elseif (is_numeric((string) $tmpescaped)) { // it can be a float with a .
$tmpescaped = (float) $tmpescaped;
} else {
$tmpescaped = preg_replace('/[^a-z0-9_]/i', '', $tmpescaped); // it can be a name of field or a substitution variable like '__NOW__'
}
}

View File

@@ -176,7 +176,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1, $o
if ($mode == 1) {
$out .= "hash('".$securekeyseed."' + '".$type."' + $type + '_ref)";
} else {
$out .= '&securekey='.dol_hash($securekeyseed.$type.$ref.(!isModEnabled('multicompany') ? '' : $object->entity), '0');
$out .= '&securekey='.dol_hash($securekeyseed.$type.$ref.(!isModEnabled('multicompany') ? '' : $obj->entity), '0');
}
}

View File

@@ -182,7 +182,7 @@ class modAdherent extends DolibarrModules
$this->const[$r][0] = "MEMBER_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/members";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/members";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -438,8 +438,8 @@ class modAdherent extends DolibarrModules
// ODT template
/*
$src=DOL_DOCUMENT_ROOT.'/install/doctemplates/orders/template_order.odt';
$dirodt=DOL_DATA_ROOT.'/doctemplates/orders';
$src=DOL_DOCUMENT_ROOT.'/install/doctemplates/members/template_member.odt';
$dirodt=DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/members';
$dest=$dirodt.'/template_order.odt';
if (file_exists($src) && ! file_exists($dest)) {

View File

@@ -127,7 +127,7 @@ class modBom extends DolibarrModules
$this->const = array(
1 => array('BOM_ADDON_PDF', 'chaine', 'generic_bom_odt', 'Name of PDF model of BOM', 0),
2 => array('BOM_ADDON', 'chaine', 'mod_bom_standard', 'Name of numbering rules of BOM', 0),
3 => array('BOM_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/boms', '', 0)
3 => array('BOM_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT'.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/boms', '', 0)
);
// Some keys to add into the overwriting translation tables
@@ -479,7 +479,7 @@ class modBom extends DolibarrModules
// ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/boms/template_bom.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/boms';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/boms';
$dest = $dirodt.'/template_bom.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -94,7 +94,7 @@ class modCommande extends DolibarrModules
$r++;
$this->const[$r][0] = "COMMANDE_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/orders";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/orders";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
@@ -459,7 +459,7 @@ class modCommande extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/orders/template_order.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/orders';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/orders';
$dest = $dirodt.'/template_order.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -87,7 +87,7 @@ class modContrat extends DolibarrModules
$this->const[$r][0] = "CONTRACT_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/contracts";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/contracts";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -230,7 +230,7 @@ class modContrat extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/contracts/template_contract.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/contracts';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/contracts';
$dest = $dirodt.'/template_contract.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -99,7 +99,7 @@ class modExpedition extends DolibarrModules
$this->const[$r][0] = "EXPEDITION_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/shipments";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/shipments";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -120,7 +120,7 @@ class modExpedition extends DolibarrModules
$this->const[$r][0] = "DELIVERY_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/deliveries";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/deliveries";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -343,7 +343,7 @@ class modExpedition extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/shipments/template_shipment.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/shipments';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/shipments';
$dest = $dirodt.'/template_shipment.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -95,7 +95,7 @@ class modFacture extends DolibarrModules
$this->const[$r][0] = "FACTURE_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/invoices";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/invoices";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -773,7 +773,7 @@ class modFacture extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/invoices/template_invoice.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/invoices';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/invoices';
$dest = $dirodt.'/template_invoice.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -117,7 +117,7 @@ class modFournisseur extends DolibarrModules
// Add ability ODT for Supplier orders
$this->const[$r][0] = "SUPPLIER_ORDER_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/supplier_orders";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/supplier_orders";
$this->const[$r][3] = '';
$this->const[$r][4] = 0;
$r++;
@@ -125,7 +125,7 @@ class modFournisseur extends DolibarrModules
// Add ability ODT for Supplier Invoices
$this->const[$r][0] = "SUPPLIER_INVOICE_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/supplier_invoices";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -972,7 +972,7 @@ class modFournisseur extends DolibarrModules
//ODT template for Supplier Orders
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_orders';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/supplier_orders';
$dest = $dirodt.'/template_supplier_order.odt';
if (file_exists($src) && !file_exists($dest)) {
@@ -993,7 +993,7 @@ class modFournisseur extends DolibarrModules
//ODT template for Supplier Invoice
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_invoices/template_supplier_invoices.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_invoices';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/supplier_invoices';
$dest = $dirodt.'/template_supplier_invoices.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -111,7 +111,7 @@ class modHoliday extends DolibarrModules
$this->const[$r][0] = "HOLIDAY_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/holiday";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/holiday";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -308,7 +308,7 @@ class modHoliday extends DolibarrModules
//ODT template
/*$src=DOL_DOCUMENT_ROOT.'/install/doctemplates/holiday/template_holiday.odt';
$dirodt=DOL_DATA_ROOT.'/doctemplates/holiday';
$dirodt=DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/holiday';
$dest=$dirodt.'/template_order.odt';
if (file_exists($src) && ! file_exists($dest))

View File

@@ -138,7 +138,7 @@ class modMrp extends DolibarrModules
$this->const = array(
//1=>array('MRP_MO_ADDON_PDF', 'chaine', 'vinci', 'Name of default PDF model of MO', 0),
2=>array('MRP_MO_ADDON', 'chaine', 'mod_mo_standard', 'Name of numbering rules of MO', 0),
3=>array('MRP_MO_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/mrps', '', 0)
3=>array('MRP_MO_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT'.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/mrps', '', 0)
);
// Some keys to add into the overwriting translation tables
@@ -442,7 +442,7 @@ class modMrp extends DolibarrModules
// ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/mrps/template_mo.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/mrps';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/mrps';
$dest = $dirodt.'/template_mo.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -92,7 +92,7 @@ class modProjet extends DolibarrModules
$this->const[$r][0] = "PROJECT_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/projects";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/projects";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -113,7 +113,7 @@ class modProjet extends DolibarrModules
$this->const[$r][0] = "PROJECT_TASK_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/tasks";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/tasks";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -379,7 +379,7 @@ class modProjet extends DolibarrModules
//ODT template for project
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/projects/template_project.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/projects';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/projects';
$dest = $dirodt.'/template_project.odt';
if (file_exists($src) && !file_exists($dest)) {
@@ -395,7 +395,7 @@ class modProjet extends DolibarrModules
//ODT template for tasks
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tasks/template_task_summary.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/tasks';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/tasks';
$dest = $dirodt.'/template_task_summary.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -99,7 +99,7 @@ class modPropale extends DolibarrModules
$this->const[$r][0] = "PROPALE_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/proposals";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/proposals";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -489,7 +489,7 @@ class modPropale extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/proposals/template_proposal.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/proposals';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/proposals';
$dest = $dirodt.'/template_proposal.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -91,7 +91,7 @@ class modReception extends DolibarrModules
$this->const[$r][0] = "RECEPTION_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/receptions";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/receptions";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -266,7 +266,7 @@ class modReception extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/reception/template_reception.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/reception';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/reception';
$dest = $dirodt.'/template_reception.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -101,7 +101,7 @@ class modSociete extends DolibarrModules
$this->const[$r][0] = "COMPANY_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/thirdparties";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/thirdparties";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
@@ -947,7 +947,7 @@ class modSociete extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/thirdparties/template_thirdparty.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/thirdparties';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/thirdparties';
$dest = $dirodt.'/template_thirdparty.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -96,14 +96,14 @@ class modStock extends DolibarrModules
$r++;
$this->const[$r][0] = "STOCK_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/stocks";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/stocks";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
$r++;
$this->const[$r][0] = "MOUVEMENT_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/stocks/movements";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/stocks/movements";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
@@ -538,7 +538,7 @@ class modStock extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/stocks/template_warehouse.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/stocks';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/stocks';
$dest = $dirodt.'/template_warehouse.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -92,7 +92,7 @@ class modSupplierProposal extends DolibarrModules
$this->const[$r][0] = "SUPPLIER_PROPOSAL_ADDON_PDF_ODT_PATH";
$this->const[$r][1] = "chaine";
$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/supplier_proposals";
$this->const[$r][2] = "DOL_DATA_ROOT".($conf->entity > 1 ? '/'.$conf->entity : '')."/doctemplates/supplier_proposals";
$this->const[$r][3] = "";
$this->const[$r][4] = 0;
@@ -163,7 +163,7 @@ class modSupplierProposal extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_proposals/template_supplier_proposal.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_proposals';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/supplier_proposals';
$dest = $dirodt.'/template_supplier_proposal.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -110,7 +110,7 @@ class modTicket extends DolibarrModules
$this->const = array(
1 => array('TICKET_ENABLE_PUBLIC_INTERFACE', 'chaine', '0', 'Enable ticket public interface', 0),
2 => array('TICKET_ADDON', 'chaine', 'mod_ticket_simple', 'Ticket ref module', 0),
3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0),
3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT'.($conf->entity > 1 ? '/'.$conf->entity : '').'/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),
@@ -414,7 +414,7 @@ class modTicket extends DolibarrModules
//ODT template
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tickets/template_ticket.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/tickets';
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/tickets';
$dest = $dirodt.'/template_ticket.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -269,13 +269,14 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$pdf = pdf_getInstance($this->format);
$default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
$heightforinfotot = 50; // Height reserved to output the info and total part
$pdf->SetAutoPageBreak(1, 0);
$heightforinfotot = 40; // Height reserved to output the info and total part
$heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
$heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS')) {
$heightforfooter += 6;
}
$pdf->SetAutoPageBreak(1, 0);
if (class_exists('TCPDF')) {
$pdf->setPrintHeader(false);
@@ -328,6 +329,8 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$tab_height = $this->page_hauteur - $tab_top - $heightforfooter - $heightforfreetext;
$nexY = $tab_top - 1;
// Incoterm
$height_incoterms = 0;
if (isModEnabled('incoterm')) {
@@ -337,7 +340,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$pdf->SetFont('', '', $default_font_size - 1);
$pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
$nexY = $pdf->GetY();
$nexY = max($pdf->GetY(), $nexY);
$height_incoterms = $nexY - $tab_top;
// Rect takes a length in 3rd parameter
@@ -360,6 +363,8 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$pagenb = $pdf->getPage();
if (!empty($notetoshow)) {
$tab_top -= 2;
$tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
$pageposbeforenote = $pagenb;
@@ -368,8 +373,6 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
$notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
$tab_top -= 2;
$pdf->startTransaction();
$pdf->SetFont('', '', $default_font_size - 1);
@@ -484,21 +487,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders
// Use new auto column system
$this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
$nexY = $tab_top + $this->tabTitleHeight;
$pageposbeforeprintlines = $pdf->getPage();
$pagenb = $pageposbeforeprintlines;
// Show square
if ($pagenb == $pageposbeforeprintlines) {
$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
} else {
$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
}
$nexY = $tab_top + $this->tabTitleHeight;
// Loop on each lines
for ($i = 0; $i < $nblines; $i++) {
$curY = $nexY;
@@ -547,20 +540,20 @@ class pdf_cornas extends ModelePDFSuppliersOrders
}
// Description of product line
$curX = $this->posxdesc - 1;
$showpricebeforepagebreak = 1;
if ($this->getColumnStatus('desc')) {
$pdf->startTransaction();
$this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
$pageposafter = $pdf->getPage();
if ($pageposafter > $pageposbefore) { // There is a pagebreak
$pdf->rollbackTransaction(true);
$pageposafter = $pageposbefore;
$pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
$this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
$pageposafter = $pdf->getPage();
$posyafter = $pdf->GetY();
if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
@@ -587,8 +580,10 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$posYAfterDescription = $pdf->GetY();
}
$nexY = $pdf->GetY();
$nexY = max($pdf->GetY(), $posYAfterImage);
$pageposafter = $pdf->getPage();
$pdf->setPage($pageposbefore);
$pdf->setTopMargin($this->marge_haute);
$pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
@@ -790,6 +785,14 @@ class pdf_cornas extends ModelePDFSuppliersOrders
}
}
// Show square
if ($pagenb == $pageposbeforeprintlines) {
$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
} else {
$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
}
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
// Affiche zone infos
$posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
@@ -1143,9 +1146,10 @@ class pdf_cornas extends ModelePDFSuppliersOrders
* @param int $hidetop Hide top bar of array
* @param int $hidebottom Hide bottom bar of array
* @param string $currency Currency code
* @param Translate $outputlangsbis Langs object bis
* @return void
*/
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
{
global $conf;

View File

@@ -998,9 +998,10 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
* @param int $hidetop Hide top bar of array
* @param int $hidebottom Hide bottom bar of array
* @param string $currency Currency code
* @param Translate $outputlangsbis Langs object bis
* @return void
*/
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
{
global $conf;

View File

@@ -773,13 +773,16 @@ if ($object->id > 0 || !empty($object->ref)) {
print '</td>'; // Dispatch column
print '<td></td>'; // Warehouse column
$sql = "SELECT ed.rowid, ed.qty, ed.fk_entrepot,";
$sql .= " eb.batch, eb.eatby, eb.sellby, cd.fk_product";
$sql .= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."expeditiondet_batch as eb on ed.rowid = eb.fk_expeditiondet";
$sql .= " JOIN ".MAIN_DB_PREFIX."commandedet as cd on ed.fk_elementdet = cd.rowid";
$sql .= " WHERE ed.fk_elementdet =".(int) $objp->rowid;
$sql .= " AND ed.fk_expedition =".(int) $object->id;
$sql = "SELECT ed.rowid";
$sql .= ", cd.fk_product";
$sql .= ", ".$db->ifsql('eb.rowid IS NULL', 'ed.qty', 'eb.qty')." as qty";
$sql .= ", ed.fk_entrepot";
$sql .= ", eb.batch, eb.eatby, eb.sellby";
$sql .= " FROM ".$db->prefix()."expeditiondet as ed";
$sql .= " LEFT JOIN ".$db->prefix()."expeditiondet_batch as eb on ed.rowid = eb.fk_expeditiondet";
$sql .= " INNER JOIN ".$db->prefix()."commandedet as cd on ed.fk_origin_line = cd.rowid";
$sql .= " WHERE ed.fk_origin_line = ".(int) $objp->rowid;
$sql .= " AND ed.fk_expedition = ".(int) $object->id;
$sql .= " ORDER BY ed.rowid, ed.fk_elementdet";
$resultsql = $db->query($sql);

View File

@@ -35,7 +35,7 @@ if (!defined('DOL_APPLICATION_TITLE')) {
define('DOL_APPLICATION_TITLE', 'Dolibarr');
}
if (!defined('DOL_VERSION')) {
define('DOL_VERSION', '20.0.4'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
define('DOL_VERSION', '20.0.5'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
}
if (!defined('EURO')) {

View File

@@ -1684,8 +1684,13 @@ class CommandeFournisseur extends CommonOrder
// End call triggers
}
$this->db->commit();
return $this->id;
if (!$error) {
$this->db->commit();
return $this->id;
} else {
$this->db->rollback();
return -4;
}
} else {
$this->error = $this->db->lasterror();
$this->db->rollback();

View File

@@ -1962,6 +1962,7 @@ if ($action == 'create') {
$formconfirm = '';
$text = '';
// Confirmation de la suppression de la commande
if ($action == 'delete') {

View File

@@ -722,6 +722,7 @@ if (empty($reshook)) {
unset($_POST['date_end_fill']);
unset($_POST['situations']);
unset($_POST['progress']);
unset($_POST['fourn_ref']);
} else {
setEventMessages($object->error, $object->errors, 'errors');
}
@@ -864,6 +865,7 @@ if (empty($reshook)) {
unset($_POST['date_endyear']);
unset($_POST['situations']);
unset($_POST['progress']);
unset($_POST['fourn_ref']);
} else {
setEventMessages($object->error, $object->errors, 'errors');
}

View File

@@ -910,7 +910,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
// Proprietes particulieres a facture avoir
@@ -1013,7 +1013,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
// Source facture
$object->fac_rec = $fac_recid;
@@ -1080,7 +1080,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
// Auto calculation of date due if not filled by user
@@ -1122,7 +1122,7 @@ if (empty($reshook)) {
$object->origin_id = GETPOSTINT('originid');
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
$classname = ucfirst($subelement);
if ($classname == 'Fournisseur.commande') {
$classname = 'CommandeFournisseur';
@@ -1150,7 +1150,7 @@ if (empty($reshook)) {
// Add lines
if ($id > 0) {
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
$classname = ucfirst($subelement);
if ($classname == 'Fournisseur.commande') {
$classname = 'CommandeFournisseur';
@@ -2121,7 +2121,7 @@ if ($action == 'create') {
$subelement = 'fournisseur.commande';
}
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
$classname = ucfirst($subelement);
if ($classname == 'Fournisseur.commande') {
$classname = 'CommandeFournisseur';

View File

@@ -284,6 +284,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$sql_skill .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank AS sr";
$sql_skill .= " JOIN ".MAIN_DB_PREFIX."hrm_skill AS s ON sr.fk_skill = s.rowid";
$sql_skill .= " AND sr.fk_object = ".((int) $id);
$sql_skill .= " AND sr.objecttype = '".$db->escape($objecttype)."'";
$result = $db->query($sql_skill);
$numSkills = $db->num_rows($result);
$TSkillsJob = array();

View File

@@ -214,13 +214,13 @@ function testSqlAndScriptInject($val, $type)
// List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/Events
$inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)[a-z]*\s*=/i', $val); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $val);
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|bounce|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $val);
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $val);
$inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)[a-z]*\s*=/i', $val);
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)[a-z]*\s*=/i', $val);
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)[a-z]*\s*=/i', $val);
// More not into the previous list
$inj += preg_match('/on(repeat|begin|finish|beforeinput)[a-z]*\s*=/i', $val);
$inj += preg_match('/on(repeat|begin|finish)[a-z]*\s*=/i', $val);
// We refuse html into html because some hacks try to obfuscate evil strings by inserting HTML into HTML.
// Example: <img on<a>error=alert(1) or <img onerror<>=alert(1) to bypass test on onerror=
@@ -228,13 +228,13 @@ function testSqlAndScriptInject($val, $type)
// List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/Events
$inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)[a-z]*\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $tmpval);
$inj += preg_match('/on(abort|after|animation|auxclick|before|blur|bounce|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)[a-z]*\s*=/i', $tmpval);
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $tmpval);
$inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)[a-z]*\s*=/i', $tmpval);
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)[a-z]*\s*=/i', $tmpval);
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)[a-z]*\s*=/i', $tmpval);
// More not into the previous list
$inj += preg_match('/on(repeat|begin|finish|beforeinput)[a-z]*\s*=/i', $tmpval);
$inj += preg_match('/on(repeat|begin|finish)[a-z]*\s*=/i', $tmpval);
//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ...
$inj += preg_match('/&#58;|&#0000058|&#x3A/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'

View File

@@ -496,7 +496,7 @@ class modMyModule extends DolibarrModules
}
if ($myTmpObjectArray['includerefgeneration']) {
$src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_myobjects.odt';
$dirodt = DOL_DATA_ROOT.'/doctemplates/'.$moduledir;
$dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/'.$moduledir;
$dest = $dirodt.'/template_myobjects.odt';
if (file_exists($src) && !file_exists($dest)) {

View File

@@ -657,7 +657,7 @@ if (empty($conf->use_javascript_ajax)) {
'2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')',
'3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')',
);
print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
print $form->selectarray("activate_usesearchtoselectproduct", $arrval, getDolGlobalString('PRODUIT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth400');
print '</td>';
}
print '</tr>';

View File

@@ -5198,8 +5198,6 @@ class Product extends CommonObject
*/
public function getChildsArbo($id, $firstlevelonly = 0, $level = 1, $parents = array())
{
global $alreadyfound;
if (empty($id)) {
return array();
}
@@ -5216,9 +5214,6 @@ class Product extends CommonObject
dol_syslog(get_class($this).'::getChildsArbo id='.$id.' level='.$level. ' parents='.(is_array($parents) ? implode(',', $parents) : $parents), LOG_DEBUG);
if ($level == 1) {
$alreadyfound = array($id => 1); // We init array of found object to start of tree, so if we found it later (should not happened), we stop immediately
}
// Protection against infinite loop
if ($level > 30) {
return array();
@@ -5227,14 +5222,16 @@ class Product extends CommonObject
$res = $this->db->query($sql);
if ($res) {
$prods = array();
if ($this->db->num_rows($res) > 0) {
$parents[] = $id;
}
while ($rec = $this->db->fetch_array($res)) {
if (!empty($alreadyfound[$rec['rowid']])) {
if (in_array($rec['id'], $parents)) {
dol_syslog(get_class($this).'::getChildsArbo the product id='.$rec['rowid'].' was already found at a higher level in tree. We discard to avoid infinite loop', LOG_WARNING);
if (in_array($rec['id'], $parents)) {
continue; // We discard this child if it is already found at a higher level in tree in the same branch.
}
continue; // We discard this child if it is already found at a higher level in tree in the same branch.
}
$alreadyfound[$rec['rowid']] = 1;
$prods[$rec['rowid']] = array(
0 => $rec['rowid'],
1 => $rec['qty'],
@@ -5248,7 +5245,6 @@ class Product extends CommonObject
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty'],2=>$rec['fk_product_type']);
//$prods[$this->db->escape($rec['label'])]= array(0=>$rec['id'],1=>$rec['qty']);
if (empty($firstlevelonly)) {
$parents[] = $rec['rowid'];
$listofchilds = $this->getChildsArbo($rec['rowid'], 0, $level + 1, $parents);
foreach ($listofchilds as $keyChild => $valueChild) {
$prods[$rec['rowid']]['childs'][$keyChild] = $valueChild;

View File

@@ -139,7 +139,7 @@ class Task extends CommonObjectLine
public $timespent_old_duration;
public $timespent_date;
public $timespent_datehour; // More accurate start date (same than timespent_date but includes hours, minutes and seconds)
public $timespent_withhour; // 1 = we entered also start hours for timesheet line
public $timespent_withhour; // 0 or 1 = we have entered also start hours for timesheet line
public $timespent_fk_user;
public $timespent_thm;
public $timespent_note;
@@ -1467,10 +1467,9 @@ class Task extends CommonObjectLine
$timespent->fk_user = $this->timespent_fk_user;
$timespent->fk_product = $this->timespent_fk_product;
$timespent->note = $this->timespent_note;
$timespent->datec = $this->db->idate($now);
$timespent->datec = $now;
$result = $timespent->create($user);
if ($result > 0) {
$ret = $result;
$this->timespent_id = $result;

View File

@@ -175,7 +175,6 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_year = '';
$search_note = '';
$search_duration = '';
$search_value = '';
$search_date_startday = '';
$search_date_startmonth = '';
$search_date_startyear = '';
@@ -249,6 +248,7 @@ if ($action == 'addtimespent' && $user->hasRight('projet', 'time')) {
$object->timespent_withhour = 1;
} else {
$object->timespent_date = dol_mktime(12, 0, 0, GETPOSTINT("timemonth"), GETPOSTINT("timeday"), GETPOSTINT("timeyear"));
$object->timespent_withhour = 0;
}
$object->timespent_fk_user = GETPOSTINT("userid");
$object->timespent_fk_product = GETPOSTINT("fk_product");
@@ -299,6 +299,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us
$object->timespent_withhour = 1;
} else {
$object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timelinemonth"), GETPOST("timelineday"), GETPOST("timelineyear"));
$object->timespent_withhour = 0;
}
$object->timespent_fk_user = GETPOSTINT("userid_line");
$object->timespent_fk_product = GETPOSTINT("fk_product");
@@ -328,6 +329,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us
$object->timespent_withhour = 1;
} else {
$object->timespent_date = dol_mktime(12, 0, 0, GETPOSTINT("timelinemonth"), GETPOSTINT("timelineday"), GETPOSTINT("timelineyear"));
$object->timespent_withhour = 0;
}
$object->timespent_fk_user = GETPOSTINT("userid_line");
$object->timespent_fk_product = GETPOSTINT("fk_product");

View File

@@ -1441,7 +1441,7 @@ print '</form>';
$db->free($resql);
$hidegeneratedfilelistifempty = 1;
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
if ($massaction == 'builddoc' || $action == 'remove_file' || !empty($show_files)) {
$hidegeneratedfilelistifempty = 0;
}

View File

@@ -201,6 +201,13 @@ class SecurityTest extends CommonClassTest
$result = testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject bbb');
$test='<marquee onbeforeintput="alert(1)">';
$result=testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject onbeforeintput');
$test='<marquee onbounce="alert(1)">';
$result=testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject onbounce');
$test = '<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>';
$result = testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ccc');
@@ -1094,6 +1101,7 @@ class SecurityTest extends CommonClassTest
$this->assertEquals('358080.38', $result);
global $leftmenu; // Used into strings to eval
$conf->global->MAIN_FEATURES_LEVEL = 1;
$leftmenu = 'AAA';
$result = dol_eval('$conf->currency && preg_match(\'/^(AAA|BBB)/\',$leftmenu)', 1, 1, '1');
@@ -1116,7 +1124,7 @@ class SecurityTest extends CommonClassTest
print "result16 = ".$result."\n";
$this->assertFalse($result);
$string = '(isModEnabled("agenda") || isModEnabled("resource")) && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 0 && preg_match(\'/^(admintools|all|XXX)/\', $leftmenu)';
$string = '(isModEnabled("user") || isModEnabled("resource")) && getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 0 && preg_match(\'/^(admintools|all|XXX)/\', $leftmenu)';
$result = dol_eval($string, 1, 1, '1');
print "result17 = ".$result."\n";
$this->assertTrue($result);