diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php
index 7f7da4ee7c7..37b873544a0 100644
--- a/htdocs/comm/action/card.php
+++ b/htdocs/comm/action/card.php
@@ -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 .= '
- ' . $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"));
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index 82519e19a97..07bc22e5ac2 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -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();
diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
index 468595a3561..78ea0db9ee7 100644
--- a/htdocs/societe/class/api_thirdparties.class.php
+++ b/htdocs/societe/class/api_thirdparties.class.php
@@ -5,7 +5,8 @@
* Copyright (C) 2020-2024 Frédéric France
* Copyright (C) 2023 Alexandre Janniaux
* Copyright (C) 2024 MDW
- * Copyright (C) 2024 Jon Bendtsen
+ * Copyright (C) 2024 Jon Bendtsen
+ * Copyright (C) 2026 Benjamin Falière
*
* 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";
}
diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php
index 839b4e89efa..06e293519d9 100644
--- a/htdocs/ticket/class/ticket.class.php
+++ b/htdocs/ticket/class/ticket.class.php
@@ -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);