Compare commits

...

14 Commits
21.0.1 ... 15.0

Author SHA1 Message Date
Laurent Destailleur
32f160355b Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 2025-11-24 16:03:52 +01:00
lvessiller-opendsi
30ecf80732 FIX keep user who validate proposal on update (#36257) 2025-11-14 15:53:31 +01:00
Frédéric FRANCE
5fa475a074 fix directory was always overwritten (#36148) 2025-11-07 18:43:26 +01:00
Laurent Destailleur
3209eb4bd8 Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 2025-11-03 13:46:49 +01:00
lvessiller-opendsi
5de1fcca2f FIX extra-field list depend on parent extra-filed list on direct edit (#35803) 2025-10-17 15:48:40 +02:00
lvessiller-opendsi
50afc9682b FIX create invoice from order using API and multi-entity (#35654)
* FIX create invoice from order using API and multi-entity

* FIX API not allow to access order in other entity on creating invoice from order

* Update api_invoices.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-10-06 13:56:50 +02:00
ldestailleur
a4601686a6 Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 2025-09-25 11:54:18 +02:00
lvessiller-opendsi
bcf6d6a7a2 FIX api orders : forward database error on failure (backpot commit d9e81cb) (#35478) 2025-09-25 11:47:51 +02:00
lvessiller-opendsi
e818bf732d FIX extra field list depend on parent list when editing a card (#35165) 2025-09-01 19:55:00 +02:00
ldestailleur
e18c5b9d68 Fix CI 2025-06-28 17:40:01 +02:00
ldestailleur
031acacdab Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 2025-06-28 17:04:21 +02:00
POTIER Mathieu
18725aec6b [FIX] loop interrupt if an error occurs in sendEmailsRemindersOnInvoiceDueDate (#34657) 2025-06-28 16:45:52 +02:00
ldestailleur
f256deb54b Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 2025-04-10 14:15:48 +02:00
ThomasNgr-OpenDSI
7fa3474ecd FIX : constant PAYMENTBYBANKTRANSFER_ADDDAYS was never saved (#33799) 2025-04-09 15:44:51 +02:00
9 changed files with 154 additions and 132 deletions

View File

@@ -103,7 +103,9 @@ if ($action == "set") {
if (!($res > 0)) { if (!($res > 0)) {
$error++; $error++;
} }
} elseif (!$error) { }
if (!$error) {
$db->commit(); $db->commit();
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else { } else {

View File

@@ -183,7 +183,6 @@ class Propal extends CommonObject
public $fin_validite; public $fin_validite;
public $user_author_id; public $user_author_id;
public $user_valid_id;
public $user_close_id; public $user_close_id;
/** /**
@@ -1382,7 +1381,7 @@ class Propal extends CommonObject
// Clear fields // Clear fields
$object->user_author = $user->id; $object->user_author = $user->id;
$object->user_valid = ''; $object->user_validation_id = 0;
$object->date = $now; $object->date = $now;
$object->datep = $now; // deprecated $object->datep = $now; // deprecated
$object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600); $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
@@ -1575,7 +1574,7 @@ class Propal extends CommonObject
$this->extraparams = (array) json_decode($obj->extraparams, true); $this->extraparams = (array) json_decode($obj->extraparams, true);
$this->user_author_id = $obj->fk_user_author; $this->user_author_id = $obj->fk_user_author;
$this->user_valid_id = $obj->fk_user_valid; $this->user_validation_id = $obj->fk_user_valid;
$this->user_close_id = $obj->fk_user_cloture; $this->user_close_id = $obj->fk_user_cloture;
//Incoterms //Incoterms
@@ -1677,7 +1676,7 @@ class Propal extends CommonObject
$sql .= " total_ttc=".(isset($this->total_ttc) ? $this->total_ttc : "null").","; $sql .= " total_ttc=".(isset($this->total_ttc) ? $this->total_ttc : "null").",";
$sql .= " fk_statut=".(isset($this->statut) ? $this->statut : "null").","; $sql .= " fk_statut=".(isset($this->statut) ? $this->statut : "null").",";
$sql .= " fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id : "null").","; $sql .= " fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id : "null").",";
$sql .= " fk_user_valid=".(isset($this->user_valid) ? $this->user_valid : "null").","; $sql .= " fk_user_valid = ".(!empty($this->user_validation_id) ? (int) $this->user_validation_id : "null").",";
$sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").",";
$sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").",";
$sql .= " fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : "null").","; $sql .= " fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : "null").",";
@@ -1963,7 +1962,7 @@ class Propal extends CommonObject
$this->ref = $num; $this->ref = $num;
$this->brouillon = 0; $this->brouillon = 0;
$this->statut = self::STATUS_VALIDATED; $this->statut = self::STATUS_VALIDATED;
$this->user_valid_id = $user->id; $this->user_validation_id = $user->id;
$this->datev = $now; $this->datev = $now;
$this->db->commit(); $this->db->commit();
@@ -3219,9 +3218,7 @@ class Propal extends CommonObject
$this->user_creation = $cuser; $this->user_creation = $cuser;
if ($obj->fk_user_valid) { if ($obj->fk_user_valid) {
$vuser = new User($this->db); $this->user_validation_id = $obj->fk_user_valid;
$vuser->fetch($obj->fk_user_valid);
$this->user_validation = $vuser;
} }
if ($obj->fk_user_signature) { if ($obj->fk_user_signature) {

View File

@@ -1164,7 +1164,7 @@ class Commande extends CommonOrder
} }
} }
} else { } else {
dol_print_error($this->db); $this->error = $this->db->lasterror();
$this->db->rollback(); $this->db->rollback();
return -1; return -1;
} }

View File

@@ -316,6 +316,7 @@ class Invoices extends DolibarrApi
* @return int * @return int
* @throws RestException 400 * @throws RestException 400
* @throws RestException 401 * @throws RestException 401
* @throws RestException 403 Access not allowed for login
* @throws RestException 404 * @throws RestException 404
* @throws RestException 405 * @throws RestException 405
*/ */
@@ -333,6 +334,9 @@ class Invoices extends DolibarrApi
if (empty($orderid)) { if (empty($orderid)) {
throw new RestException(400, 'Order ID is mandatory'); throw new RestException(400, 'Order ID is mandatory');
} }
if (!DolibarrApi::_checkAccessToResource('commande', $orderid)) {
throw new RestException(403, 'Access not allowed on order for login '.DolibarrApiAccess::$user->login);
}
$order = new Commande($this->db); $order = new Commande($this->db);
$result = $order->fetch($orderid); $result = $order->fetch($orderid);

View File

@@ -5116,7 +5116,9 @@ class Facture extends CommonInvoice
if ($resql) { if ($resql) {
while ($obj = $this->db->fetch_object($resql)) { while ($obj = $this->db->fetch_object($resql)) {
if (!$error) { // Create a loopError that is reset at each loop, this counter is added to the global counter at the end of loop
$loopError = 0;
// Load event // Load event
$res = $tmpinvoice->fetch($obj->id); $res = $tmpinvoice->fetch($obj->id);
if ($res > 0) { if ($res > 0) {
@@ -5162,21 +5164,21 @@ class Facture extends CommonInvoice
$to = $recipient->email; $to = $recipient->email;
} else { } else {
$errormesg = "Failed to send remind to thirdparty id=".$tmpinvoice->socid.". No email defined for user."; $errormesg = "Failed to send remind to thirdparty id=".$tmpinvoice->socid.". No email defined for user.";
$error++; $loopError++;
} }
} else { } else {
$errormesg = "Failed to load recipient with thirdparty id=".$tmpinvoice->socid; $errormesg = "Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
$error++; $loopError++;
} }
// Sender // Sender
$from = $conf->global->MAIN_MAIL_EMAIL_FROM; $from = $conf->global->MAIN_MAIL_EMAIL_FROM;
if (empty($from)) { if (empty($from)) {
$errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
$error++; $loopError++;
} }
if (!$error) { if (!$loopError) {
// Errors Recipient // Errors Recipient
$errors_to = $conf->global->MAIN_MAIL_ERRORS_TO; $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
@@ -5200,7 +5202,7 @@ class Facture extends CommonInvoice
$nbMailSend++; $nbMailSend++;
} else { } else {
$errormesg = $cMailFile->error.' : '.$to; $errormesg = $cMailFile->error.' : '.$to;
$error++; $loopError++;
} }
} }
@@ -5209,23 +5211,24 @@ class Facture extends CommonInvoice
} }
} else { } else {
$errorsMsg[] = 'Failed to fetch record invoice with ID = '.$obj->id; $errorsMsg[] = 'Failed to fetch record invoice with ID = '.$obj->id;
$error++; $loopError++;
}
} }
$error += $loopError;
} }
} else { } else {
$error++; $error++;
} }
if (!$error) { if ($error > 0) { // If there is at least an error, early return with specific message
$this->output .= 'Nb of emails sent : '.$nbMailSend;
$this->db->commit();
return 0;
} else {
$this->db->commit(); // We commit also on error, to have the error message recorded. $this->db->commit(); // We commit also on error, to have the error message recorded.
$this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error; $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error;
return $error; return $error;
} }
$this->output .= 'Nb of emails sent : '.$nbMailSend;
$this->db->commit();
return 0;
} }
} }

View File

@@ -490,6 +490,11 @@ abstract class CommonObject
*/ */
public $date_modification; // Date last change (tms field) public $date_modification; // Date last change (tms field)
/**
* @var int|null User id of validation
*/
public $user_validation_id;
public $next_prev_filter; public $next_prev_filter;
/** /**
@@ -8048,7 +8053,7 @@ abstract class CommonObject
$("#"+child_list).hide(); $("#"+child_list).hide();
//Show mother lists //Show mother lists
} else if ($("#"+parent_list).val() != 0){ } else if ($("#"+parent_list).val() != 0){
$("#"+parent_list).show(); showOptions'.$type.'(child_list, parent_list, orig_select[child_list]);
} }
//Show the child list if the parent list value is selected //Show the child list if the parent list value is selected
$("select[name=\""+parent_list+"\"]").click(function() { $("select[name=\""+parent_list+"\"]").click(function() {

View File

@@ -1180,4 +1180,39 @@ $(document).ready(function() {
} }
}); });
// Code to manage the js for combo list with dependencies (called by extrafields_view.tpl.php)
function showOptions(child_list, parent_list) {
var parentInput = $("select[name="+parent_list+"]");
if (parentInput.length === 0) { // when parent extra-field is in view mode and the child is edited directly on card (on line edit)
parentInput = $("input[name="+parent_list+"]");
}
if (parentInput.length > 0) {
var val = parentInput.val();
var parentVal = parent_list + ":" + val;
if (val > 0) {
$("select[name=\""+child_list+"\"] option[parent]").prop("disabled", true).hide(); // hide not work with select2 element so disabled it
$("select[name=\""+child_list+"\"] option[parent=\""+parentVal+"\"]").prop('disabled', false).show(); // show not work with select2 element so enabled it
} else {
$("select[name=\""+child_list+"\"] option").prop("disabled", false).show(); // show not work with select2 element so enabled it
}
}
}
function setListDependencies() {
console.log("setListDependencies");
jQuery("select option[parent]").parent().each(function() {
var child_list = $(this).attr("name");
var parent = $(this).find("option[parent]:first").attr("parent");
var infos = parent.split(":");
var parent_list = infos[0];
showOptions(child_list, parent_list);
/* Activate the handler to call showOptions on each future change */
$("select[name=\""+parent_list+"\"]").change(function() {
showOptions(child_list, parent_list);
});
});
}
// End of lib_head.js.php // End of lib_head.js.php

View File

@@ -257,6 +257,7 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l
} else { } else {
//var_dump($tmpkeyextra.'-'.$value.'-'.$object->table_element); //var_dump($tmpkeyextra.'-'.$value.'-'.$object->table_element);
print $extrafields->showOutputField($tmpkeyextra, $value, '', $object->table_element); print $extrafields->showOutputField($tmpkeyextra, $value, '', $object->table_element);
print '<input type="hidden" value="' . $value . '" name="options_' . $tmpkeyextra . '" id="options_' . $tmpkeyextra . '"/>'; // it's needed when to get parent value when extra-field list depend on parent extra-field list
} }
print '</td>'; print '</td>';
@@ -271,31 +272,6 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l
print ' print '
<script> <script>
jQuery(document).ready(function() { jQuery(document).ready(function() {
function showOptions(child_list, parent_list)
{
var val = $("select[name="+parent_list+"]").val();
var parentVal = parent_list + ":" + val;
if(val > 0) {
$("select[name=\""+child_list+"\"] option[parent]").hide();
$("select[name=\""+child_list+"\"] option[parent=\""+parentVal+"\"]").show();
} else {
$("select[name=\""+child_list+"\"] option").show();
}
}
function setListDependencies() {
jQuery("select option[parent]").parent().each(function() {
var child_list = $(this).attr("name");
var parent = $(this).find("option[parent]:first").attr("parent");
var infos = parent.split(":");
var parent_list = infos[0];
showOptions(child_list, parent_list);
/* Activate the handler to call showOptions on each future change */
$("select[name=\""+parent_list+"\"]").change(function() {
showOptions(child_list, parent_list);
});
});
}
setListDependencies(); setListDependencies();
}); });
</script>'."\n"; </script>'."\n";

View File

@@ -84,6 +84,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
// Load object // Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
$upload_dir = $conf->eventorganization->multidir_output[isset($object->entity) ? $object->entity : 1];
if ($id > 0 || !empty($ref)) { if ($id > 0 || !empty($ref)) {
$upload_dir = $conf->eventorganization->multidir_output[$object->entity ? $object->entity : $conf->entity]."/conferenceorbooth/".get_exdir(0, 0, 0, 1, $object); $upload_dir = $conf->eventorganization->multidir_output[$object->entity ? $object->entity : $conf->entity]."/conferenceorbooth/".get_exdir(0, 0, 0, 1, $object);
} }
@@ -93,7 +94,6 @@ $permissiontoadd = $user->rights->eventorganization->write; // Used by the inclu
$permissiontodelete = $user->rights->eventorganization->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); $permissiontodelete = $user->rights->eventorganization->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
$permissionnote = $user->rights->eventorganization->write; // Used by the include of actions_setnotes.inc.php $permissionnote = $user->rights->eventorganization->write; // Used by the include of actions_setnotes.inc.php
$permissiondellink = $user->rights->eventorganization->write; // Used by the include of actions_dellink.inc.php $permissiondellink = $user->rights->eventorganization->write; // Used by the include of actions_dellink.inc.php
$upload_dir = $conf->eventorganization->multidir_output[isset($object->entity) ? $object->entity : 1];
// Security check // Security check
if ($user->socid > 0) { if ($user->socid > 0) {