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

This commit is contained in:
Laurent Destailleur
2026-02-08 15:53:06 +01:00
4 changed files with 106 additions and 18 deletions

View File

@@ -417,6 +417,11 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
if (!empty($_SESSION['assignedtouser'])) {
$listofuserid = json_decode($_SESSION['assignedtouser'], true);
}
if (!empty($_SESSION['assignedtoresource'])) {
$listofresourceid = json_decode($_SESSION['assignedtoresource'], true);
}
$i = 0;
foreach ($listofuserid as $key => $value) {
if ($i == 0) { // First entry
@@ -524,22 +529,95 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
// Creation of action/event
$idaction = $object->create($user);
$moreparam = '';
if ($idaction > 0) {
if (!$object->error) {
if (is_array($listofresourceid) && count($listofresourceid)) {
foreach ($listofresourceid as $resource_id => $val) {
$resource_type = 'dolresource';
$busy = 1;//GETPOSTINT('busy');
// Resources association
if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK')) {
$eventDateStart = $object->datep;
$eventDateEnd = $object->datef;
$isFullDayEvent = $object->fulldayevent;
if (empty($eventDateEnd)) {
if ($isFullDayEvent) {
$eventDateStartArr = dol_getdate($eventDateStart);
$eventDateStart = dol_mktime(0, 0, 0, $eventDateStartArr['mon'], $eventDateStartArr['mday'], $eventDateStartArr['year']);
$eventDateEnd = dol_mktime(23, 59, 59, $eventDateStartArr['mon'], $eventDateStartArr['mday'], $eventDateStartArr['year']);
}
}
$sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
$sql .= " FROM " . MAIN_DB_PREFIX . "element_resources as er";
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "resource as r ON r.rowid = er.resource_id AND er.resource_type = '" . $db->escape($resource_type) . "'";
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "actioncomm as ac ON ac.id = er.element_id AND er.element_type = '" . $db->escape($object->element) . "'";
$sql .= " WHERE er.resource_id = " . ((int) $resource_id);
$sql .= " AND er.busy = 1";
$sql .= " AND (";
// event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
$sql .= " (ac.datep <= '" . $db->idate($eventDateStart) . "' AND (ac.datep2 IS NULL OR ac.datep2 >= '" . $db->idate($eventDateStart) . "'))";
// event date end between ac.datep and ac.datep2
if (!empty($eventDateEnd)) {
$sql .= " OR (ac.datep <= '" . $db->idate($eventDateEnd) . "' AND (ac.datep2 >= '" . $db->idate($eventDateEnd) . "'))";
}
// event date start before ac.datep and event date end after ac.datep2
$sql .= " OR (";
$sql .= "ac.datep >= '" . $db->idate($eventDateStart) . "'";
if (!empty($eventDateEnd)) {
$sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '" . $db->idate($eventDateEnd) . "')";
}
$sql .= ")";
$sql .= ")";
$resql = $db->query($sql);
if (!$resql) {
$error++;
$object->error = $db->lasterror();
$object->errors[] = $object->error;
} else {
if ($db->num_rows($resql) > 0) {
// Resource already in use
$error++;
$object->error = $langs->trans('ErrorResourcesAlreadyInUse') . ' : ';
while ($obj = $db->fetch_object($resql)) {
$object->error .= '<br> - ' . $langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label . ' [' . $obj->ac_id . ']');
}
$object->errors[] = $object->error;
setEventMessages($object->error, null, 'errors');
}
$db->free($resql);
}
}
if (!$error) {
$res = $object->add_element_resource($resource_id, $resource_type, $busy, $val['mandatory']);
}
}
}
unset($_SESSION['assignedtoresource']);
// Category association
$categories = GETPOST('categories', 'array');
$object->setCategories($categories);
if (!$error) {
$categories = GETPOST('categories', 'array');
$object->setCategories($categories);
}
unset($_SESSION['assignedtouser']);
$moreparam = '';
if ($user->id != $object->userownerid) {
$moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view.
}
// Create reminders
if ($addreminder == 'on') {
if (!$error && $addreminder == 'on') {
$actionCommReminder = new ActionCommReminder($db);
$dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
@@ -610,7 +688,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
$donotclearsession = 1;
}
if ($eventisrecurring) {
if (!$error && $eventisrecurring) {
$dayoffset = 0;
$monthoffset = 0;
// We set first date of recurrence and offsets
if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) {
$firstdatearray = dol_get_first_day_week(GETPOSTINT("apday"), GETPOSTINT("apmonth"), GETPOSTINT("apyear"));

View File

@@ -693,7 +693,7 @@ class CommandeFournisseur extends CommonOrder
$objsearchpackage = $this->db->fetch_object($resqlsearchpackage);
if ($objsearchpackage) {
$line->fk_fournprice = $objsearchpackage->rowid;
$line->packaging = $objsearchpackage->packaging;
$line->packaging = (float) $objsearchpackage->packaging;
}
} else {
$this->error = $this->db->lasterror();
@@ -2060,14 +2060,14 @@ class CommandeFournisseur extends CommonOrder
// Predefine quantity according to packaging
if (getDolGlobalString('PRODUCT_USE_SUPPLIER_PACKAGING')) {
$prod = new Product($this->db);
$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', (empty($this->fk_soc) ? $this->socid : $this->fk_soc));
$prod->get_buyprice($fk_prod_fourn_price, (float) $qty, $fk_product, 'none', (empty($this->fk_soc) ? $this->socid : $this->fk_soc));
if ($qty < $prod->packaging) {
$qty = $prod->packaging;
$qty = (float) $prod->packaging;
} else {
if (!empty($prod->packaging) && ($qty % $prod->packaging) > 0) {
$coeff = intval($qty / $prod->packaging) + 1;
$qty = $prod->packaging * $coeff;
if (!empty($prod->packaging) && (fmod((float) $qty, (float) $prod->packaging) > 0.000001)) {
$coeff = intval((float) $qty / $prod->packaging) + 1;
$qty = (float) $prod->packaging * $coeff;
setEventMessages($langs->trans('QtyRecalculatedWithPackaging'), null, 'mesgs');
}
}
@@ -3020,7 +3020,7 @@ class CommandeFournisseur extends CommonOrder
if ($qty < $this->line->packaging) {
$qty = $this->line->packaging;
} else {
if (!empty($this->line->packaging) && ($qty % $this->line->packaging) > 0) {
if (!empty($this->line->packaging) && is_numeric($this->line->packaging) && (float) $this->line->packaging > 0 && (fmod((float) $qty, $this->line->packaging) > 0)) {
$coeff = intval($qty / $this->line->packaging) + 1;
$qty = $this->line->packaging * $coeff;
setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs');
@@ -3935,7 +3935,7 @@ class CommandeFournisseurLigne extends CommonOrderLine
$objsearchpackage = $this->db->fetch_object($resqlsearchpackage);
if ($objsearchpackage) {
$this->fk_fournprice = $objsearchpackage->rowid;
$this->packaging = $objsearchpackage->packaging;
$this->packaging = (float) $objsearchpackage->packaging;
}
} else {
$this->error = $this->db->lasterror();

View File

@@ -5,7 +5,8 @@
* Copyright (C) 2020-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2023 Alexandre Janniaux <alexandre.janniaux@gmail.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
* Copyright (C) 2024 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
* Copyright (C) 2026 Benjamin Falière <benjamin@faliere.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
@@ -974,8 +975,9 @@ class Thirdparties extends DolibarrApi
$sql = "SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line";
$sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
$sql .= " WHERE f.rowid = re.fk_facture_source AND re.fk_soc = ".((int) $id);
$sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = re.fk_facture_source";
$sql .= " WHERE re.fk_soc = ".((int) $id);
if ($filter == "available") {
$sql .= " AND re.fk_facture IS NULL AND re.fk_facture_line IS NULL";
}

View File

@@ -1713,8 +1713,10 @@ class Ticket extends CommonObject
$this->status = Ticket::STATUS_READ;
$this->db->begin();
$sql = "UPDATE ".MAIN_DB_PREFIX."ticket";
$sql .= " SET fk_statut = ".Ticket::STATUS_READ.", date_read = '".$this->db->idate(dol_now())."'";
$sql .= " SET fk_statut = ".((int) $this->status) .", date_read = '".$this->db->idate(dol_now())."'";
$sql .= " WHERE rowid = ".((int) $this->id);
dol_syslog(get_class($this)."::markAsRead");
@@ -1739,7 +1741,9 @@ class Ticket extends CommonObject
$this->status = $this->oldcopy->status;
$this->db->rollback();
$this->error = implode(',', $this->errors);
dol_syslog(get_class($this)."::markAsRead ".$this->error, LOG_ERR);
return -1;
}
@@ -2004,9 +2008,11 @@ class Ticket extends CommonObject
if ($this->status != Ticket::STATUS_CLOSED && $this->status != Ticket::STATUS_CANCELED) { // not closed
$this->db->begin();
$this->oldcopy = dol_clone($this);
$this->status = ($mode ? Ticket::STATUS_CANCELED : Ticket::STATUS_CLOSED);
$sql = "UPDATE ".MAIN_DB_PREFIX."ticket";
$sql .= " SET fk_statut=".($mode ? Ticket::STATUS_CANCELED : Ticket::STATUS_CLOSED).", progress=100, date_close='".$this->db->idate(dol_now())."'";
$sql .= " SET fk_statut=".$this->status.", progress=100, date_close='".$this->db->idate(dol_now())."'";
$sql .= " WHERE rowid = ".((int) $this->id);
dol_syslog(get_class($this)."::close mode=".$mode);