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);