diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 47ffeb5e28f8f..3296110422cca 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -6,7 +6,7 @@ repos:
rev: v4.5.0
hooks:
- id: no-commit-to-branch
- args: [--branch, develop, --pattern, \d+.0]
+ args: [--branch, develop, --pattern, \d+.0$]
- id: check-yaml
args: [--unsafe]
- id: check-json
diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
index 819d1fe21e8ac..6337b50f85fd3 100644
--- a/htdocs/accountancy/bookkeeping/list.php
+++ b/htdocs/accountancy/bookkeeping/list.php
@@ -1137,7 +1137,7 @@
print $form->selectDate($search_date_modification_start, 'search_date_modification_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
print '';
print '
';
- print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
+ print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
print '
';
print '';
}
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index 2b154d3639ad6..95f62289d5394 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -216,6 +216,7 @@
// one line tabpay = line into bank
// one line for bank record = tabbq
// one line for thirdparty record = tabtp
+ // Note: tabcompany is used to store the subledger account
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($result);
@@ -263,7 +264,8 @@
);
// Set accountancy code for user
- // $obj->accountancy_code is the accountancy_code of table u=user but it is defined only if a link with type 'user' exists)
+ // $obj->accountancy_code is the accountancy_code of table u=user (but it is defined only if
+ // a link with type 'user' exists and user as a subledger account)
$compta_user = (!empty($obj->accountancy_code) ? $obj->accountancy_code : '');
$tabuser[$obj->rowid] = array(
@@ -364,13 +366,25 @@
$userstatic->lastname = $tabuser[$obj->rowid]['lastname'];
$userstatic->statut = $tabuser[$obj->rowid]['status'];
$userstatic->accountancy_code = $tabuser[$obj->rowid]['accountancy_code'];
+ // For a payment of social contribution, we have a link sc + user.
+ // but we already fill the $tabpay[$obj->rowid]["soclib"] in the line 'sc'.
+ // If we fill it here to, we must concat
if ($userstatic->id > 0) {
- $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
+ if ($is_sc) {
+ $tabpay[$obj->rowid]["soclib"] .= ' '.$userstatic->getNomUrl(1, 'accountancy', 0);
+ } else {
+ $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
+ }
} else {
$tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment.
}
+
if ($compta_user) {
- $tabtp[$obj->rowid][$compta_user] += $amounttouse;
+ if ($is_sc) {
+ //$tabcompany[$obj->rowid][$compta_user] += $amounttouse;
+ } else {
+ $tabtp[$obj->rowid][$compta_user] += $amounttouse;
+ }
}
} elseif ($links[$key]['type'] == 'sc') {
$chargestatic->id = $links[$key]['url_id'];
diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php
index 73096056f9892..cf0a1451c4287 100644
--- a/htdocs/admin/mails.php
+++ b/htdocs/admin/mails.php
@@ -42,7 +42,7 @@
$usersignature = $user->signature;
// For action = test or send, we ensure that content is not html, even for signature, because for this we want a test with NO html.
-if ($action == 'test' || ($action == 'send' && $trackid = 'test')) {
+if ($action == 'test' || ($action == 'send' && $trackid == 'test')) {
$usersignature = dol_string_nohtmltag($usersignature, 2);
}
diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php
index cab81b801246c..0c79e261f3853 100644
--- a/htdocs/api/class/api_documents.class.php
+++ b/htdocs/api/class/api_documents.class.php
@@ -762,9 +762,52 @@ public function post($filename, $modulepart, $ref = '', $subdir = '', $fileconte
throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
}
- $result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1, 1);
+ $disablevirusscan = 0;
+ $src_file = $destfiletmp;
+ $dest_file = $destfile;
+
+ // Security:
+ // If we need to make a virus scan
+ if (empty($disablevirusscan) && file_exists($src_file)) {
+ $checkvirusarray = dolCheckVirus($src_file);
+ if (count($checkvirusarray)) {
+ dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.join(',', $checkvirusarray), LOG_WARNING);
+ throw new RestException(500, 'ErrorFileIsInfectedWithAVirus: '.join(',', $checkvirusarray));
+ }
+ }
+
+ // Security:
+ // Disallow file with some extensions. We rename them.
+ // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
+ if (isAFileWithExecutableContent($dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED)) {
+ // $upload_dir ends with a slash, so be must be sure the medias dir to compare to ends with slash too.
+ $publicmediasdirwithslash = $conf->medias->multidir_output[$conf->entity];
+ if (!preg_match('/\/$/', $publicmediasdirwithslash)) {
+ $publicmediasdirwithslash .= '/';
+ }
+
+ if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory
+ $dest_file .= '.noexe';
+ }
+ }
+
+ // Security:
+ // We refuse cache files/dirs, upload using .. and pipes into filenames.
+ if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) {
+ dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
+ throw new RestException(500, "Refused to deliver file ".$src_file);
+ }
+
+ // Security:
+ // We refuse cache files/dirs, upload using .. and pipes into filenames.
+ if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) {
+ dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
+ throw new RestException(500, "Refused to deliver file ".$dest_file);
+ }
+
+ $result = dol_move($destfiletmp, $dest_file, 0, $overwriteifexists, 1, 1);
if (!$result) {
- throw new RestException(500, "Failed to move file into '".$destfile."'");
+ throw new RestException(500, "Failed to move file into '".$dest_file."'");
}
return dol_basename($destfile);
diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php
index e7e86cf70fea6..30f4b23264d0a 100644
--- a/htdocs/categories/class/api_categories.class.php
+++ b/htdocs/categories/class/api_categories.class.php
@@ -268,7 +268,7 @@ public function delete($id)
}
if ($this->category->delete(DolibarrApiAccess::$user) <= 0) {
- throw new RestException(500, 'Error when delete category ' . $this->category->error);
+ throw new RestException(500, 'Error when delete category : ' . $this->category->error);
}
return array(
diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
index 1922fdb7691c8..7ffe0e0f3b8b2 100644
--- a/htdocs/comm/action/class/actioncomm.class.php
+++ b/htdocs/comm/action/class/actioncomm.class.php
@@ -2432,6 +2432,7 @@ public function sendEmailsReminder()
// Load event
$res = $this->fetch($actionCommReminder->fk_actioncomm);
+ if ($res > 0) $res = $this->fetch_thirdparty();
if ($res > 0) {
// PREPARE EMAIL
$errormesg = '';
diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
index 2dbaeaf056e09..408fa9899a6d8 100644
--- a/htdocs/comm/propal/class/propal.class.php
+++ b/htdocs/comm/propal/class/propal.class.php
@@ -2651,7 +2651,10 @@ public function closeProposal($user, $status, $note = '', $notrigger = 0)
}
$sql = "UPDATE ".MAIN_DB_PREFIX."propal";
- $sql .= " SET fk_statut = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."', date_signature='".$this->db->idate($date_signature)."', fk_user_signature=".$fk_user_signature;
+ $sql .= " SET fk_statut = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."'";
+ if ($status == self::STATUS_SIGNED) {
+ $sql .= ", date_signature='".$this->db->idate($now)."', fk_user_signature = ".($fk_user_signature);
+ }
$sql .= " WHERE rowid = ".((int) $this->id);
$resql = $this->db->query($sql);
diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index bf39beba029f8..ef7f802c61bf4 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -2508,7 +2508,7 @@
$productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
} else {
$generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
- $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
+ $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
}
if ($reliquat > $generic_product->stock_reel) {
diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php
index a923f3a082913..102e6c5f69770 100644
--- a/htdocs/compta/bank/card.php
+++ b/htdocs/compta/bank/card.php
@@ -80,7 +80,6 @@
$result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid);
-
/*
* Actions
*/
@@ -222,6 +221,7 @@
$object = new Account($db);
$object->fetch(GETPOST("id", 'int'));
+ $object->oldref = $object->ref;
$object->ref = dol_string_nospecial(trim(GETPOST('ref', 'alpha')));
$object->label = trim(GETPOST("label", 'alphanohtml'));
$object->courant = GETPOST("type");
diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php
index 8e5366d7301be..c7a8aab1144e4 100644
--- a/htdocs/compta/bank/class/account.class.php
+++ b/htdocs/compta/bank/class/account.class.php
@@ -266,6 +266,11 @@ class Account extends CommonObject
*/
public $ics_transfer;
+ /**
+ * @var string The previous ref in case of rename on update to rename attachment folders
+ */
+ public $oldref;
+
/**
@@ -897,6 +902,28 @@ public function update(User $user, $notrigger = 0)
}
}
+ if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
+ $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
+ $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity);
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $error++;
+ $this->error = $this->db->lasterror();
+ }
+
+ // We rename directory in order not to lose the attachments
+ $oldref = dol_sanitizeFileName($this->oldref);
+ $newref = dol_sanitizeFileName($this->ref);
+ $dirsource = $conf->bank->dir_output.'/'.$oldref;
+ $dirdest = $conf->bank->dir_output.'/'.$newref;
+ if (file_exists($dirsource)) {
+ dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
+ if (@rename($dirsource, $dirdest)) {
+ dol_syslog("Rename ok", LOG_DEBUG);
+ }
+ }
+ }
+
if (!$error && !$notrigger) {
// Call trigger
$result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php
index 853bd4d3bd68a..bc0b608173e77 100644
--- a/htdocs/compta/facture/card-rec.php
+++ b/htdocs/compta/facture/card-rec.php
@@ -91,7 +91,10 @@
$object = new FactureRec($db);
if (($id > 0 || $ref) && $action != 'create' && $action != 'add') {
$ret = $object->fetch($id, $ref);
- if (!$ret) {
+ if ($ret < 0) {
+ dol_print_error($db, $object->error, $object->errors);
+ exit;
+ } elseif (! $ret) {
setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
}
}
@@ -1248,6 +1251,7 @@ function showselectfksocieterib(){
if ($object->id > 0) {
$object->fetch_thirdparty();
+ $formconfirm = '';
// Confirmation de la suppression d'une ligne produit
if ($action == 'ask_deleteline') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
@@ -1372,14 +1376,10 @@ function showselectfksocieterib(){
}
print '';
print '';
- if ($object->type != Facture::TYPE_CREDIT_NOTE) {
- if ($action == 'editconditions') {
- $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
- } else {
- $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'none');
- }
+ if ($action == 'editconditions') {
+ $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
} else {
- print ' ';
+ $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'none');
}
print ' ';
@@ -1846,6 +1846,7 @@ function showselectfksocieterib(){
// List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db);
+ $morehtmlcenter = '';
$somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
print '';
diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
index ee61789b49a9e..b1c8dab0260bf 100644
--- a/htdocs/compta/facture/class/facture-rec.class.php
+++ b/htdocs/compta/facture/class/facture-rec.class.php
@@ -362,6 +362,7 @@ public function create($user, $facid, $notrigger = 0)
$sql .= ", ".(!empty($this->rule_for_lines_dates) ? ("'".$this->db->escape($this->rule_for_lines_dates)."'") : "NULL");
/** BACKPORT PR 32129 */
$sql .= ")";
+
if ($this->db->query($sql)) {
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."facture_rec");
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index c3ccaf15d193c..3ed0571fe84f3 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -5615,9 +5615,9 @@ public function sendEmailsRemindersOnInvoiceDueDate($nbdays = 0, $paymentmode =
$joinFileName = [];
$joinFileMime = [];
if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
- $joinFile[] = DOL_DATA_ROOT.$tmpinvoice->last_main_doc;
+ $joinFile[] = DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc;
$joinFileName[] = basename($tmpinvoice->last_main_doc);
- $joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.$tmpinvoice->last_main_doc);
+ $joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc);
}
// Mail Creation
diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
index e747c4380a4eb..ba8a652930428 100644
--- a/htdocs/compta/stats/cabyprodserv.php
+++ b/htdocs/compta/stats/cabyprodserv.php
@@ -506,7 +506,7 @@
// Quantity
print '';
- print $qty[$key];
+ print price($qty[$key], 1, $langs, 0, 0);
print ' ';
// Percent;
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 65ae29d376a71..7d480ac493cb8 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -476,6 +476,11 @@
$substitutionarray['__EMAIL__'] = $thirdparty->email;
$substitutionarray['__CHECK_READ__'] = ' ';
+ if ($oneemailperrecipient) {
+ $substitutionarray['__ONLINE_PAYMENT_URL__'] = '';
+ $substitutionarray['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
+ }
+
$parameters = array('mode'=>'formemail');
if (!empty($listofobjectthirdparties)) {
diff --git a/htdocs/core/ajax/selectobject.php b/htdocs/core/ajax/selectobject.php
index 079224c62a23e..f12b9b56b78d6 100644
--- a/htdocs/core/ajax/selectobject.php
+++ b/htdocs/core/ajax/selectobject.php
@@ -83,7 +83,11 @@
$searchkey = (($id && GETPOST($id, 'alpha')) ? GETPOST($id, 'alpha') : (($htmlname && GETPOST($htmlname, 'alpha')) ? GETPOST($htmlname, 'alpha') : ''));
// Add a security test to avoid to get content of all tables
-restrictedArea($user, $objecttmp->element, $id);
+if (!empty($objecttmp->module)) {
+ restrictedArea($user, $objecttmp->module, $id, $objecttmp->table_element, $objecttmp->element);
+} else {
+ restrictedArea($user, $objecttmp->element, $id);
+}
$arrayresult = $form->selectForFormsList($objecttmp, $htmlname, '', 0, $searchkey, '', '', '', 0, 1, 0, '', $filter);
diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php
index fb0f93086d283..21f226b9806e1 100644
--- a/htdocs/core/boxes/box_actions.php
+++ b/htdocs/core/boxes/box_actions.php
@@ -106,7 +106,7 @@ public function loadBox($max = 5)
$sql .= " AND s.rowid = ".((int) $user->socid);
}
if (empty($user->rights->agenda->allactions->read)) {
- $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id)." OR a.fk_user_done = ".((int) $user->id).")";
+ $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id).")";
}
$sql .= " ORDER BY a.datep ASC";
$sql .= $this->db->plimit($max, 0);
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index da861fbfb0d2e..4110c7ee731b5 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -875,7 +875,7 @@ public function sendfile()
}
} elseif ($this->sendmode == 'smtps') {
if (!is_object($this->smtps)) {
- $this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." Constructor of object CMailFile was not initialized without errors.";
+ $this->error = "Failed to send mail with smtps lib to HOST=".ini_get('SMTP').", PORT=".$conf->global->$keyforsmtpport." Constructor of object CMailFile was not initialized without errors.";
dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
return false;
}
@@ -1165,9 +1165,10 @@ public function sendfile()
$res = true;
if (!empty($this->error) || !empty($this->errors) || !$result) {
if (!empty($failedRecipients)) {
- $this->errors[] = 'Transport failed for the following addresses: "' . join('", "', $failedRecipients) . '".';
+ $this->error = 'Transport failed for the following addresses: "' . join('", "', $failedRecipients) . '".';
+ $this->errors[] = $this->error;
}
- dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
+ dol_syslog("CMailFile::sendfile: mail end error=". join(' ', $this->errors), LOG_ERR);
$res = false;
if (!empty($conf->global->MAIN_MAIL_DEBUG)) {
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index e366f24af9577..f2b173f60585c 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -2192,7 +2192,9 @@ public function load_previous_next_ref($filter, $fieldid, $nodbprefix = 0)
$sql = "SELECT MAX(te.".$fieldid.")";
$sql .= " FROM ".(empty($nodbprefix) ?$this->db->prefix():'').$this->table_element." as te";
if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
- $sql .= ",".$this->db->prefix()."usergroup_user as ug";
+ if (empty($user->admin) || !empty($user->entity) || $conf->entity != 1) {
+ $sql .= " INNER JOIN ".MAIN_DB_PREFIX."usergroup_user as ug ON ug.fk_user = te.rowid";
+ }
}
if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
$tmparray = explode('@', $this->ismultientitymanaged);
@@ -2229,7 +2231,6 @@ public function load_previous_next_ref($filter, $fieldid, $nodbprefix = 0)
if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
$sql .= " AND te.entity IS NOT NULL"; // Show all users
} else {
- $sql .= " AND ug.fk_user = te.rowid";
$sql .= " AND ug.entity IN (".getEntity('usergroup').")";
}
} else {
@@ -2262,7 +2263,9 @@ public function load_previous_next_ref($filter, $fieldid, $nodbprefix = 0)
$sql = "SELECT MIN(te.".$fieldid.")";
$sql .= " FROM ".(empty($nodbprefix) ?$this->db->prefix():'').$this->table_element." as te";
if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
- $sql .= ",".$this->db->prefix()."usergroup_user as ug";
+ if (empty($user->admin) || !empty($user->entity) || $conf->entity != 1) {
+ $sql .= " INNER JOIN ".MAIN_DB_PREFIX."usergroup_user as ug ON ug.fk_user = te.rowid";
+ }
}
if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
$tmparray = explode('@', $this->ismultientitymanaged);
@@ -2299,7 +2302,6 @@ public function load_previous_next_ref($filter, $fieldid, $nodbprefix = 0)
if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
$sql .= " AND te.entity IS NOT NULL"; // Show all users
} else {
- $sql .= " AND ug.fk_user = te.rowid";
$sql .= " AND ug.entity IN (".getEntity('usergroup').")";
}
} else {
@@ -3196,7 +3198,7 @@ public function getChildrenOfLine($id, $includealltree = 0)
while ($row = $this->db->fetch_row($resql)) {
$rows[] = $row[0];
if (!empty($includealltree)) {
- $rows = array_merge($rows, $this->getChildrenOfLine($row[0]), $includealltree);
+ $rows = array_merge($rows, $this->getChildrenOfLine($row[0], $includealltree));
}
}
}
@@ -4085,8 +4087,12 @@ public function fetchObjectLinked($sourceid = null, $sourcetype = '', $targetid
$classpath = 'adherents/class';
$module = 'adherent';
} elseif ($objecttype == 'contact') {
- $module = 'societe';
+ $module = 'societe';
+ } elseif ($objecttype == 'action') {
+ $module = 'agenda';
+ $subelement = 'actionComm';
}
+
// Set classfile
$classfile = strtolower($subelement);
$classname = ucfirst($subelement);
@@ -4917,8 +4923,8 @@ public function formAddObjectLine($dateSelector, $seller, $buyer, $defaulttpldir
* But for the moment we don't know if it's possible as we keep a method available on overloaded objects.
*
* @param string $action Action code
- * @param string $seller Object of seller third party
- * @param string $buyer Object of buyer third party
+ * @param Societe $seller Object of seller third party
+ * @param Societe $buyer Object of buyer third party
* @param int $selected Object line selected
* @param int $dateSelector 1=Show also date range input fields
* @param string $defaulttpldir Directory where to find the template
@@ -9460,6 +9466,7 @@ public function fetchLinesCommon($morewhere = '')
if ($resql) {
$num_rows = $this->db->num_rows($resql);
$i = 0;
+ $this->lines = array();
while ($i < $num_rows) {
$obj = $this->db->fetch_object($resql);
if ($obj) {
diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php
index 2d6cc4f571587..79e01f2f6868b 100644
--- a/htdocs/core/class/conf.class.php
+++ b/htdocs/core/class/conf.class.php
@@ -161,6 +161,7 @@ public function __construct()
$this->mailing = new stdClass();
$this->expensereport = new stdClass();
$this->productbatch = new stdClass();
+ $this->api = new stdClass();
}
/**
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index a56fec193b335..31e0d9ea0ee4e 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -865,12 +865,12 @@ public function get_form($addfileaction = 'addfile', $removefileaction = 'remove
// Complete substitution array with the url to make online payment
$paymenturl = '';
- $validpaymentmethod = array();
+ // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
+ $validpaymentmethod = getValidOnlinePaymentMethods('');
if (empty($this->substit['__REF__'])) {
$paymenturl = '';
} else {
- // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
- require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
$langs->loadLangs(array('paypal', 'other'));
$typeforonlinepayment = 'free';
if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') {
@@ -884,14 +884,15 @@ public function get_form($addfileaction = 'addfile', $removefileaction = 'remove
}
$url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
$paymenturl = $url;
-
- $validpaymentmethod = getValidOnlinePaymentMethods('');
}
if (count($validpaymentmethod) > 0 && $paymenturl) {
$langs->load('other');
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
$this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
+ } elseif (count($validpaymentmethod) > 0) {
+ $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__';
+ $this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__';
} else {
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
$this->substit['__ONLINE_PAYMENT_URL__'] = '';
diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
index 55486efd81329..4077704b45514 100644
--- a/htdocs/core/class/utils.class.php
+++ b/htdocs/core/class/utils.class.php
@@ -146,7 +146,13 @@ public function purgeFiles($choices = 'tempfilesold+logfiles', $nbsecondsold = 8
$result = dol_delete_dir_recursive($filesarray[$key]['fullname'], $startcount, 1, 0, $tmpcountdeleted);
- if (!in_array($filesarray[$key]['fullname'], array($conf->api->dir_temp, $conf->user->dir_temp))) { // The 2 directories $conf->api->dir_temp and $conf->user->dir_temp are recreated at end, so we do not count them
+ $recreatedDirs = array($conf->user->dir_temp);
+
+ if (isModEnabled('api')) {
+ $recreatedDirs[] = $conf->api->dir_temp;
+ }
+
+ if (!in_array($filesarray[$key]['fullname'], $recreatedDirs)) { // The 2 directories $conf->api->dir_temp and $conf->user->dir_temp are recreated at end, so we do not count them
$count += $result;
$countdeleted += $tmpcountdeleted;
}
@@ -528,7 +534,7 @@ public function dumpDatabase($compression = 'none', $type = 'auto', $usedefault
} elseif ($compression == 'zstd') {
fclose($handle);
}
- if ($ok && preg_match('/^-- (MySql|MariaDB)/i', $errormsg)) { // No error
+ if ($ok && preg_match('/^-- (MySql|MariaDB)/i', $errormsg) || preg_match('/^\/\*M?!999999/', $errormsg)) { // Start of file is ok, NOT an error
$errormsg = '';
} else {
// Renommer fichier sortie en fichier erreur
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 5ae46633aad3e..dc0c7b63fbc4e 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -1165,7 +1165,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
$publicmediasdirwithslash .= '/';
}
- if (strpos($upload_dir, $publicmediasdirwithslash) !== 0) { // We never add .noexe on files into media directory
+ if (strpos($upload_dir, $publicmediasdirwithslash) !== 0 || !getDolGlobalInt("MAIN_DOCUMENT_DISABLE_NOEXE_IN_MEDIAS_DIR")) { // We never add .noexe on files into media directory
$file_name .= '.noexe';
$successcode = 2;
}
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index dd1536e1245d3..7fe94ff83c444 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -1658,8 +1658,10 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename =
if (!empty($message)) {
// Test log level
$logLevels = array(LOG_EMERG=>'EMERG', LOG_ALERT=>'ALERT', LOG_CRIT=>'CRITICAL', LOG_ERR=>'ERR', LOG_WARNING=>'WARN', LOG_NOTICE=>'NOTICE', LOG_INFO=>'INFO', LOG_DEBUG=>'DEBUG');
+
if (!array_key_exists($level, $logLevels)) {
- throw new Exception('Incorrect log level');
+ dol_syslog('Error Bad Log Level '.$level, LOG_ERR);
+ $level = $logLevels[LOG_ERR];
}
if ($level > $conf->global->SYSLOG_LEVEL) {
return;
diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php
index e919bf2c8b6a7..fe9c18d4b2f07 100644
--- a/htdocs/core/lib/product.lib.php
+++ b/htdocs/core/lib/product.lib.php
@@ -446,7 +446,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_propale['nb'];
print ' ';
- print $product->stats_propale['qty'];
+ print price($product->stats_propale['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
@@ -465,7 +465,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_proposal_supplier['nb'];
print ' ';
- print $product->stats_proposal_supplier['qty'];
+ print price($product->stats_proposal_supplier['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
@@ -484,7 +484,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_commande['nb'];
print ' ';
- print $product->stats_commande['qty'];
+ print price($product->stats_commande['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
@@ -503,7 +503,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_commande_fournisseur['nb'];
print ' ';
- print $product->stats_commande_fournisseur['qty'];
+ print price($product->stats_commande_fournisseur['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
@@ -522,7 +522,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_facture['nb'];
print ' ';
- print $product->stats_facture['qty'];
+ print price($product->stats_facture['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
@@ -560,7 +560,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_facture_fournisseur['nb'];
print ' ';
- print $product->stats_facture_fournisseur['qty'];
+ print price($product->stats_facture_fournisseur['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
@@ -580,7 +580,7 @@ function show_stats_for_company($product, $socid)
print '';
print $product->stats_contrat['nb'];
print ' ';
- print $product->stats_contrat['qty'];
+ print price($product->stats_contrat['qty'], 1, $langs, 0, 0);
print ' ';
print '';
}
diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
index 0aacecc69daa0..e27941537152c 100644
--- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
+++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
@@ -176,7 +176,7 @@ public function getNextValue($objsoc, $object, $mode = 'next')
}
// Supplier invoices take invoice date instead of creation date for the mask
- $numFinal = get_next_value($db, $mask, 'facture_fourn', 'ref', '', $objsoc, $object->date);
+ $numFinal = get_next_value($db, $mask, 'facture_fourn', 'ref', '', $objsoc, is_object($object) ?$object->date :'');
return $numFinal;
}
diff --git a/htdocs/core/tpl/extrafields_list_search_input.tpl.php b/htdocs/core/tpl/extrafields_list_search_input.tpl.php
index f57101b81e6ef..3f90715cbea9e 100644
--- a/htdocs/core/tpl/extrafields_list_search_input.tpl.php
+++ b/htdocs/core/tpl/extrafields_list_search_input.tpl.php
@@ -47,7 +47,7 @@
if (in_array($typeofextrafield, array('link', 'sellist', 'text', 'html'))) {
$morecss = 'maxwidth200';
}
- echo $extrafields->showInputField($key, (empty($search_array_options[$search_options_pattern.$tmpkey]) ? '' : $search_array_options[$search_options_pattern.$tmpkey]), '', '', $search_options_pattern, $morecss, 0, $extrafieldsobjectkey, 1);
+ echo $extrafields->showInputField($key, (!isset($search_array_options[$search_options_pattern.$tmpkey]) ? '' : $search_array_options[$search_options_pattern.$tmpkey]), '', '', $search_options_pattern, $morecss, 0, $extrafieldsobjectkey, 1);
}
print '';
}
diff --git a/htdocs/core/tpl/extrafields_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php
index 7e58e10688292..da123939c6808 100644
--- a/htdocs/core/tpl/extrafields_list_search_param.tpl.php
+++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php
@@ -31,8 +31,24 @@
$param .= '&'.$search_options_pattern.$tmpkey.'_endmin='.dol_print_date($val['end'], '%M');
$val = '';
}
- if ($val != '') {
- $param .= '&'.$search_options_pattern.$tmpkey.'='.urlencode($val);
+ if ($val !== '') {
+ if (is_array($val)) {
+ foreach ($val as $val2) {
+ $param .= '&'.$search_options_pattern.$tmpkey.'[]='.urlencode($val2);
+ }
+ } else {
+ // test if we have checkbox type, we add the _multiselect needed into param
+ $tmpkey = preg_replace('/'.$search_options_pattern.'/', '', $key);
+ if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$tmpkey], array('checkbox', 'chkbxlst'))) {
+ $param .= '&'.$search_options_pattern.$tmpkey.'_multiselect='.urlencode($val);
+ }
+ // test if we have boolean type, we add the _booleand needed into param
+ if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$tmpkey], array('boolean'))) {
+ $param .= '&'.$search_options_pattern.$tmpkey.'_boolean='.urlencode($val);
+ }
+
+ $param .= '&'.$search_options_pattern.$tmpkey.'='.urlencode($val);
+ }
}
}
}
diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
index b89d7ea3cb7e3..569364a4dfd6e 100644
--- a/htdocs/cron/class/cronjob.class.php
+++ b/htdocs/cron/class/cronjob.class.php
@@ -1275,7 +1275,7 @@ public function run_jobs($userlogin)
$error++;
} else {
dol_syslog(get_class($this)."::run_jobs END");
- $this->lastoutput = dol_substr((empty($object->output) ? "" : $object->output."\n").$errmsg, 0, $this::MAXIMUM_LENGTH_FOR_LASTOUTPUT_FIELD, 'UTF-8', 1);
+ $this->lastoutput = dol_substr((empty($object->output) ? "" : $object->output."\n"), 0, $this::MAXIMUM_LENGTH_FOR_LASTOUTPUT_FIELD, 'UTF-8', 1);
$this->lastresult = var_export($result, true);
$retval = $this->lastresult;
}
diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
index 77e79c8d3a6bd..16a138e213872 100644
--- a/htdocs/expensereport/card.php
+++ b/htdocs/expensereport/card.php
@@ -541,8 +541,7 @@
// CONTENT
$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
$link = ''.$link.' ';
- $dateRefusEx = explode(" ", $object->date_refuse);
- $message = $langs->transnoentities("ExpenseReportWaitingForReApprovalMessage", $dateRefusEx[0], $object->detail_refuse, $expediteur->getFullName($langs), $link);
+ $message = $langs->transnoentities("ExpenseReportWaitingForReApprovalMessage", dol_print_date($object->date_refuse, 'day'), $object->detail_refuse, $expediteur->getFullName($langs), get_date_range($object->date_debut, $object->date_fin, '', $langs), $link);
// Rebuild pdf
/*
@@ -2211,7 +2210,11 @@
}
}
- if (!$thumbshown) {
+ if (!$thumbshown && $fileinfo['extension'] == 'pdf' && !empty($filepdf) && !empty($relativepath) && !empty($fileinfo['filename'])) {
+ $formFile = new FormFile($db);
+ $imgpreview = $formFile->showPreview([], $modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 0);
+ print $imgpreview;
+ } elseif (!$thumbshown) {
print img_mime($ecmfilesstatic->filename);
}
}
@@ -2859,7 +2862,7 @@
}
// Presend form
-$modelmail = 'expensereport';
+$modelmail = 'expensereport_send';
$defaulttopic = 'SendExpenseReportRef';
$diroutput = $conf->expensereport->dir_output;
$trackid = 'exp'.$object->id;
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index ecd8bb390f2b3..f535ac013a182 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -1372,6 +1372,8 @@ public function create($user, $notrigger = 0)
// We set order into draft status
$this->brouillon = 1;
+ $this->statut = self::STATUS_DRAFT; // deprecated
+ $this->status = self::STATUS_DRAFT;
$sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur (";
$sql .= "ref";
@@ -2945,7 +2947,7 @@ public function initAsSpecimen()
$sql .= $this->db->order("rowid", "ASC");
$sql .= $this->db->plimit(1);
$resql = $this->db->query($sql);
- if ($resql) {
+ if ($resql && $this->db->num_rows($resql)) {
$obj = $this->db->fetch_object($resql);
$prodid = $obj->rowid;
}
diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php
index 9144a61a982cf..7bff6c12eb819 100644
--- a/htdocs/fourn/commande/list.php
+++ b/htdocs/fourn/commande/list.php
@@ -856,10 +856,10 @@
$sql .= " AND cf.date_livraison <= '".$db->idate($search_date_delivery_end)."'";
}
if ($search_date_valid_start) {
- $sql .= " AND cf.date_commande >= '".$db->idate($search_date_valid_start)."'";
+ $sql .= " AND cf.date_valid >= '".$db->idate($search_date_valid_start)."'";
}
if ($search_date_valid_end) {
- $sql .= " AND cf.date_commande <= '".$db->idate($search_date_valid_end)."'";
+ $sql .= " AND cf.date_valid <= '".$db->idate($search_date_valid_end)."'";
}
if ($search_date_approve_start) {
$sql .= " AND cf.date_livraison >= '".$db->idate($search_date_approve_start)."'";
diff --git a/htdocs/fourn/facture/card-rec.php b/htdocs/fourn/facture/card-rec.php
index 38f0ca15f7f70..7d6e4c1b7727d 100644
--- a/htdocs/fourn/facture/card-rec.php
+++ b/htdocs/fourn/facture/card-rec.php
@@ -535,8 +535,8 @@
$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
// Update if prices fields are defined
- $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
- $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
+ $tva_tx = get_default_tva($object->thirdparty, $mysoc, $prod->id);
+ $tva_npr = get_default_npr($object->thirdparty, $mysoc, $prod->id);
if (empty($tva_tx)) {
$tva_npr = 0;
}
@@ -544,7 +544,7 @@
// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
$pqp = (GETPOST('pbq', 'int') ? GETPOST('pbq', 'int') : 0);
- $datapriceofproduct = $prod->getSellPrice($mysoc, $object->thirdparty, $pqp);
+ $datapriceofproduct = $prod->getSellPrice($object->thirdparty, $mysoc, $pqp);
$pu_ht = $datapriceofproduct['pu_ht'];
$pu_ttc = $datapriceofproduct['pu_ttc'];
@@ -659,8 +659,8 @@
$buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : ''); // If buying_price is '0', we must keep this value
// Local Taxes
- $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
- $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
+ $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
+ $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
$info_bits = 0;
if ($tva_npr) {
$info_bits |= 0x01;
@@ -1080,7 +1080,7 @@
$disableedit = 1;
$disablemove = 1;
$disableremove = 1;
- $object->printObjectLines('', $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice
+ $object->printObjectLines('', $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice
}
print "\n";
@@ -1569,7 +1569,7 @@
$canchangeproduct = 0;
$object->statut = $object->suspended;
- $object->printObjectLines($action, $mysoc, $object->thirdparty, $lineid, 0); // No date selector for template invoice
+ $object->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 0); // No date selector for template invoice
}
// Form to add new line
diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php
index 28dc2e2253dd0..a729dde5b753e 100644
--- a/htdocs/holiday/class/holiday.class.php
+++ b/htdocs/holiday/class/holiday.class.php
@@ -1061,6 +1061,13 @@ public function update($user = null, $notrigger = 0)
$error++; $this->errors[] = "Error ".$this->db->lasterror();
}
+ if (!$error) {
+ $result = $this->insertExtraFields();
+ if ($result < 0) {
+ $error++;
+ }
+ }
+
if (!$error) {
if (!$notrigger) {
// Call trigger
diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php
index b57983321a39d..36e3879e8857e 100644
--- a/htdocs/includes/odtphp/Segment.php
+++ b/htdocs/includes/odtphp/Segment.php
@@ -114,13 +114,13 @@ public function merge()
// Remove the IF tag
$this->xml = str_replace('[!-- IF '.$key.' --]', '', $this->xml);
// Remove everything between the ELSE tag (if it exists) and the ENDIF tag
- $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
+ $reg = '@(\[!--\sELSE\s' . preg_quote($key, '@') . '\s--\](.*))?\[!--\sENDIF\s' . preg_quote($key, '@') . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
$this->xml = preg_replace($reg, '', $this->xml);
}
// Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it
else {
// Find all conditional blocks for this variable: from IF to ELSE and to ENDIF
- $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
+ $reg = '@\[!--\sIF\s' . preg_quote($key, '@') . '\s--\](.*)(\[!--\sELSE\s' . preg_quote($key, '@') . '\s--\](.*))?\[!--\sENDIF\s' . preg_quote($key, '@') . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
preg_match_all($reg, $this->xml, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause
if (!empty($match[3])) $this->xml = str_replace($match[0], $match[3], $this->xml);
diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php
index 445bdf46a5ac5..f4d162c513a54 100644
--- a/htdocs/includes/odtphp/odf.php
+++ b/htdocs/includes/odtphp/odf.php
@@ -550,8 +550,8 @@ private function _moveRowSegments()
private function _parse($type = 'content')
{
// Search all tags found into condition to complete $this->vars, so we will proceed all tests even if not defined
- $reg='@\[!--\sIF\s([{}a-zA-Z0-9\.\,_]+)\s--\]@smU';
- $matches = array();
+ $reg='@\[!--\sIF\s([\[\]{}a-zA-Z0-9\.\,_]+)\s--\]@smU';
+ $matches = array();
preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
//var_dump($this->vars);exit;
@@ -572,7 +572,7 @@ private function _parse($type = 'content')
// Remove the IF tag
$this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml);
// Remove everything between the ELSE tag (if it exists) and the ENDIF tag
- $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
+ $reg = '@(\[!--\sELSE\s' . preg_quote($key, '@') . '\s--\](.*))?\[!--\sENDIF\s' . preg_quote($key, '@') . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
$this->contentXml = preg_replace($reg, '', $this->contentXml);
/*if ($sav != $this->contentXml)
{
@@ -585,7 +585,7 @@ private function _parse($type = 'content')
//dol_syslog("Var ".$key." is not defined, we remove the IF, ELSE and ENDIF ");
//$sav=$this->contentXml;
// Find all conditional blocks for this variable: from IF to ELSE and to ENDIF
- $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
+ $reg = '@\[!--\sIF\s' . preg_quote($key, '@') . '\s--\](.*)(\[!--\sELSE\s' . preg_quote($key, '@') . '\s--\](.*))?\[!--\sENDIF\s' . preg_quote($key, '@') . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy
preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause
if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml);
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index b57ee0a59c64d..e6ba240135bbe 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -1673,6 +1673,7 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr
}
// Refresh value of MAIN_IHM_PARAMS_REV before forging the parameter line.
if (GETPOST('dol_resetcache')) {
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
}
diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php
index 4b2ea3e93c0f3..e9ddf7ad87747 100644
--- a/htdocs/product/inventory/inventory.php
+++ b/htdocs/product/inventory/inventory.php
@@ -97,11 +97,10 @@
//$result = restrictedArea($user, 'mymodule', $id);
//Parameters Page
-$param = '&id='.$object->id;
+$paramwithsearch = '';
if ($limit > 0 && $limit != $conf->liste_limit) {
- $param .= '&limit='.urlencode($limit);
+ $paramwithsearch .= '&limit='.((int) $limit);
}
-$paramwithsearch = $param;
if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) {
@@ -265,6 +264,7 @@
$sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated';
$sql .= ' FROM '.MAIN_DB_PREFIX.'inventorydet as id';
$sql .= ' WHERE id.fk_inventory = '.((int) $object->id);
+ $sql .= $db->order('id.rowid', 'ASC');
$sql .= $db->plimit($limit, $offset);
$db->begin();
@@ -297,7 +297,7 @@
$inventoryline->pmp_expected = price2num(GETPOST('expectedpmp_'.$lineid, 'alpha'), 'MS');
$resultupdate = $inventoryline->update($user);
}
- } else {
+ } elseif (GETPOSTISSET('id_' . $lineid)) {
// Delete record
$result = $inventoryline->fetch($lineid);
if ($result > 0) {
@@ -415,7 +415,6 @@
-
/*
* View
*/
@@ -459,7 +458,7 @@
// Confirmation to close
if ($action == 'record') {
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $langs->trans('ConfirmFinish'), 'update', '', 0, 1);
+ $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&page='.$page.$paramwithsearch, $langs->trans('Close'), $langs->trans('ConfirmFinish'), 'update', '', 0, 1);
$action = 'view';
}
@@ -494,7 +493,7 @@
// Thirdparty
$morehtmlref.=' '.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1);
// Project
-if (!empty($conf->project->enabled))
+if (isModEnabled('project'))
{
$langs->load("projects");
$morehtmlref.=' '.$langs->trans('Project') . ' ';
@@ -583,13 +582,13 @@
// Save
if ($object->status == $object::STATUS_VALIDATED) {
if ($permissiontoadd) {
- print 'id.'&action=record&token='.newToken().'" title="'.dol_escape_htmltag($langs->trans("MakeMovementsAndClose")).'">'.$langs->trans("MakeMovementsAndClose").' '."\n";
+ print 'id.'&action=record&page='.$page.$paramwithsearch.'&token='.newToken().'" title="'.dol_escape_htmltag($langs->trans("MakeMovementsAndClose")).'">'.$langs->trans("MakeMovementsAndClose").' '."\n";
} else {
print ''.$langs->trans('MakeMovementsAndClose').' '."\n";
}
if ($permissiontoadd) {
- print 'id.'&action=confirm_cancel&token='.newToken().'">'.$langs->trans("Cancel").' '."\n";
+ print 'id.'&action=confirm_cancel&page='.$page.$paramwithsearch.'&token='.newToken().'">'.$langs->trans("Cancel").' '."\n";
}
}
}
@@ -990,7 +989,7 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele
$num = $db->num_rows($resql);
if (!empty($limit != 0) || $num > $limit || $page) {
- print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num >= $limit), '', '', $limit);
+ print_fleche_navigation($page, $_SERVER["PHP_SELF"], '&id='.$object->id.$paramwithsearch, ($num >= $limit), '', '', $limit);
}
$i = 0;
@@ -1046,8 +1045,9 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele
// Expected quantity = Quantity in stock when we start inventory
print '';
$valuetoshow = $obj->qty_stock;
+
// For inventory not yet close, we overwrite with the real value in stock now
- if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) {
+ if (($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) && !getDolGlobalString('DISABLE_QTY_OVERWRITE')) {
if (isModEnabled('productbatch') && $product_static->hasbatch()) {
$valuetoshow = $product_static->stock_warehouse[$obj->fk_warehouse]->detail_batch[$obj->batch]->qty;
} else {
@@ -1089,10 +1089,11 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele
//PMP Real
print ' ';
-
-
- if (!empty($obj->pmp_real)) $pmp_real = $obj->pmp_real;
- else $pmp_real = $product_static->pmp;
+ if (!empty($obj->pmp_real) || (string) $obj->pmp_real === '0') {
+ $pmp_real = $obj->pmp_real;
+ } else {
+ $pmp_real = $product_static->pmp;
+ }
$pmp_valuation_real = $pmp_real * $qty_view;
print ' ';
print ' ';
@@ -1206,38 +1207,38 @@ function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,sele
$(".paginationnext:last").click(function(e){
var form = $("#formrecord");
- var actionURL = "'.$_SERVER['PHP_SELF']."?page=".($page).$paramwithsearch.'";
+ var actionURL = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page).$paramwithsearch.'";
$.ajax({
url: actionURL,
data: form.serialize(),
cache: false,
success: function(result){
- window.location.href = "'.$_SERVER['PHP_SELF']."?page=".($page + 1).$paramwithsearch.'";
+ window.location.href = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page + 1).$paramwithsearch.'";
}});
});
$(".paginationprevious:last").click(function(e){
var form = $("#formrecord");
- var actionURL = "'.$_SERVER['PHP_SELF']."?page=".($page).$paramwithsearch.'";
+ var actionURL = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page).$paramwithsearch.'";
$.ajax({
url: actionURL,
data: form.serialize(),
cache: false,
success: function(result){
- window.location.href = "'.$_SERVER['PHP_SELF']."?page=".($page - 1).$paramwithsearch.'";
+ window.location.href = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page - 1).$paramwithsearch.'";
}});
});
$("#idbuttonmakemovementandclose").click(function(e){
var form = $("#formrecord");
- var actionURL = "'.$_SERVER['PHP_SELF']."?page=".($page).$paramwithsearch.'";
+ var actionURL = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page).$paramwithsearch.'";
$.ajax({
url: actionURL,
data: form.serialize(),
cache: false,
success: function(result){
- window.location.href = "'.$_SERVER['PHP_SELF']."?page=".($page - 1).$paramwithsearch.'&action=record";
+ window.location.href = "'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&page='.($page - 1).$paramwithsearch.'&action=record";
}});
});
});
@@ -1307,6 +1308,7 @@ function updateTotalValuation() {
}));
}
+
updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1);
+ $basePrice = ($object->price_base_type == 'HT') ? $object->price : $object->price_ttc;
+ $basePriceMin = ($object->price_base_type == 'HT') ? $object->price_min : $object->price_min_ttc;
+ $ret = $object->updatePrice($basePrice, $object->price_base_type, $user, $object->tva_tx, $basePriceMin, $level, $object->tva_npr, 1);
if ($ret < 0) {
setEventMessages($object->error, $object->errors, 'errors');
@@ -517,7 +519,9 @@
if ($action == 'disable_price_by_qty') {
// Disabling product price by quantity add a new price line with price_by_qty set to 0
$level = GETPOST('level', 'int');
- $ret = $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 0);
+ $basePrice = ($object->price_base_type == 'HT') ? $object->price : $object->price_ttc;
+ $basePriceMin = ($object->price_base_type == 'HT') ? $object->price_min : $object->price_min_ttc;
+ $ret = $object->updatePrice($basePrice, $object->price_base_type, $user, $object->tva_tx, $basePriceMin, $level, $object->tva_npr, 0);
if ($ret < 0) {
setEventMessages($object->error, $object->errors, 'errors');
diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php
index 4135c31e80a67..1ddf5f92f7615 100644
--- a/htdocs/product/stock/replenish.php
+++ b/htdocs/product/stock/replenish.php
@@ -196,9 +196,19 @@
}
$line->tva_tx = $productsupplier->vatrate_supplier;
+ $tva = $line->tva_tx / 100;
+
+ // If we use multicurrency
+ if (isModEnabled('multicurrency') && !empty($productsupplier->fourn_multicurrency_code) && $productsupplier->fourn_multicurrency_code != $conf->currency) {
+ $line->multicurrency_code = $productsupplier->fourn_multicurrency_code;
+ $line->fk_multicurrency = $productsupplier->fourn_multicurrency_id;
+ $line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice;
+ $line->multicurrency_total_ht = $line->multicurrency_subprice * $qty;
+ $line->multicurrency_total_tva = $line->multicurrency_total_ht * $tva;
+ $line->multicurrency_total_ttc = $line->multicurrency_total_ht + $line->multicurrency_total_tva;
+ }
$line->subprice = $productsupplier->fourn_pu;
$line->total_ht = $productsupplier->fourn_pu * $qty;
- $tva = $line->tva_tx / 100;
$line->total_tva = $line->total_ht * $tva;
$line->total_ttc = $line->total_ht + $line->total_tva;
$line->remise_percent = $productsupplier->remise_percent;
@@ -263,7 +273,8 @@
null,
null,
0,
- $line->fk_unit
+ $line->fk_unit,
+ $line->multicurrency_subprice ?? 0
);
}
if ($result < 0) {
@@ -274,9 +285,11 @@
} else {
$id = $result;
}
+ $i++;
} else {
$order->socid = $suppliersid[$i];
$order->fetch_thirdparty();
+ $order->multicurrency_code = $order->thirdparty->multicurrency_code;
// Trick to know which orders have been generated using the replenishment feature
$order->source = $order::SOURCE_ID_REPLENISHMENT;
diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php
index 01eb346cadbeb..06cfbfb1a3858 100644
--- a/htdocs/projet/element.php
+++ b/htdocs/projet/element.php
@@ -1245,8 +1245,8 @@
$filedir = $conf->fournisseur->commande->multidir_output[$element->entity].'/'.dol_sanitizeFileName($element->ref);
} elseif ($element_doc === 'invoice_supplier') {
$element_doc = 'facture_fournisseur';
- $filename = get_exdir($element->id, 2, 0, 0, $element, 'product').dol_sanitizeFileName($element->ref);
- $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref);
+ $filename = get_exdir($element->id, 2, 0, 0, $element, 'invoice_supplier').dol_sanitizeFileName($element->ref);
+ $filedir = $conf->fournisseur->facture->multidir_output[$element->entity].'/'.$filename;
}
print ''.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'
';
diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php
index c35cd9e83cb24..87764277b6586 100644
--- a/htdocs/projet/tasks/time.php
+++ b/htdocs/projet/tasks/time.php
@@ -658,7 +658,7 @@
// Update lineid into line of timespent
$sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id);
- $sql .= ' WHERE rowid IN ('.$db->sanitize(join(',', $toselect)).') AND fk_user = '.((int) $userid);
+ $sql .= ' WHERE rowid = '.((int) $timespent_id).' AND fk_user = '.((int) $userid);
$result = $db->query($sql);
if (!$result) {
$error++;
diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php
index 64688ef537a89..5257e2ab7a2d8 100644
--- a/htdocs/takepos/invoice.php
+++ b/htdocs/takepos/invoice.php
@@ -473,7 +473,10 @@ function fail($message)
// If we add a line and no invoice yet, we create the invoice
if (($action == "addline" || $action == "freezone") && $placeid == 0) {
$invoice->socid = getDolGlobalString($constforcompanyid);
- $invoice->date = dol_now('tzuserrel'); // We use the local date, only the day will be saved.
+
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $invoice->date = dol_get_first_hour(dol_now('tzuserrel')); // Invoice::create() needs a date with no hours
+
$invoice->module_source = 'takepos';
$invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ;
$invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity;