grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026. -------------------------------------------------------------------------- */ /** @file * @brief */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } //! Consumable Class /** This class is used to manage the consumables. @see ConsumableItem @author Julien Dombre **/ class Consumable extends CommonDBChild { // From CommonDBTM static protected $forward_entity_to = array('Infocom'); public $no_form_page = true; static $rightname = 'consumable'; // From CommonDBChild static public $itemtype = 'ConsumableItem'; static public $items_id = 'consumableitems_id'; /** * @since version 0.84 **/ function getForbiddenStandardMassiveAction() { $forbidden = parent::getForbiddenStandardMassiveAction(); $forbidden[] = 'update'; return $forbidden; } /** * since version 0.84 * * @see CommonDBTM::getNameField() **/ static function getNameField() { return 'id'; } static function getTypeName($nb=0) { return _n('Consumable', 'Consumables', $nb); } function cleanDBonPurge() { global $DB; $query = "DELETE FROM `glpi_infocoms` WHERE (`items_id` = '".$this->fields['id']."' AND `itemtype` = '".$this->getType()."')"; $result = $DB->query($query); } function prepareInputForAdd($input) { $item = new ConsumableItem(); if ($item->getFromDB($input["consumableitems_id"])) { return array("consumableitems_id" => $item->fields["id"], "entities_id" => $item->getEntityID(), "date_in" => date("Y-m-d")); } return array(); } function post_addItem() { Infocom::cloneItem('ConsumableItem', $this->fields["consumableitems_id"], $this->fields['id'], $this->getType()); } /** * send back to stock **/ function backToStock(array $input, $history=1) { global $DB; $query = "UPDATE `".$this->getTable()."` SET `date_out` = NULL WHERE `id` = '".$input["id"]."'"; if ($result = $DB->query($query)) { return true; } return false; } /** * @since version 0.84 * * @see CommonDBTM::getPreAdditionalInfosForName **/ function getPreAdditionalInfosForName() { $ci = new ConsumableItem(); if ($ci->getFromDB($this->fields['consumableitems_id'])) { return $ci->getName(); } return ''; } /** * UnLink a consumable linked to a printer * * UnLink the consumable identified by $ID * * @param $ID consumable identifier * @param $itemtype itemtype of who we give the consumable (default '') * @param $items_id ID of the item giving the consumable (default 0) * * @return boolean **/ function out($ID, $itemtype='', $items_id=0) { global $DB; if (!empty($itemtype) && ($items_id > 0)) { $query = "UPDATE `".$this->getTable()."` SET `date_out` = '".date("Y-m-d")."', `itemtype` = '$itemtype', `items_id` = '$items_id' WHERE `id` = '$ID'"; if ($result = $DB->query($query)) { return true; } } return false; } /** * @since version 0.85 * * @see CommonDBTM::showMassiveActionsSubForm() **/ static function showMassiveActionsSubForm(MassiveAction $ma) { global $CFG_GLPI; $input = $ma->getInput(); switch ($ma->getAction()) { case 'give' : if (isset($input["entities_id"])) { Dropdown::showSelectItemFromItemtypes(array('itemtype_name' => 'give_itemtype', 'items_id_name' => 'give_items_id', 'entity_restrict' => $input["entities_id"], 'itemtypes' => $CFG_GLPI["consumables_types"])); echo "

".Html::submit(_x('button', 'Give'), array('name' => 'massiveaction')); return true; } } return parent::showMassiveActionsSubForm($ma); } /** * @since version 0.85 * * @see CommonDBTM::processMassiveActionsForOneItemtype() **/ static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item, array $ids) { switch ($ma->getAction()) { case 'backtostock' : foreach ($ids as $id) { if ($item->can($id, UPDATE)) { if ($item->backToStock(array("id" => $id))) { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); } else { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } return; case 'give' : $input = $ma->getInput(); if (($input["give_items_id"] > 0) && !empty($input['give_itemtype'])) { foreach ($ids as $key) { if ($item->can($key, UPDATE)) { if ($item->out($key, $input['give_itemtype'],$input["give_items_id"])) { $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK); } else { $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } Event::log($item->fields['consumableitems_id'], "consumables", 5, "inventory", //TRANS: %s is the user login sprintf(__('%s gives a consumable'), $_SESSION["glpiname"])); } else { $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); } return; } parent::processMassiveActionsForOneItemtype($ma, $item, $ids); } /** * count how many consumable for the consumable item $tID * * @param $tID integer consumable item identifier. * * @return integer : number of consumable counted. **/ static function getTotalNumber($tID) { global $DB; $query = "SELECT `id` FROM `glpi_consumables` WHERE `consumableitems_id` = '$tID'"; $result = $DB->query($query); return $DB->numrows($result); } /** * count how many old consumable for the consumable item $tID * * @param $tID integer consumable item identifier. * * @return integer : number of old consumable counted. **/ static function getOldNumber($tID) { global $DB; $query = "SELECT `id` FROM `glpi_consumables` WHERE (`consumableitems_id` = '$tID' AND `date_out` IS NOT NULL)"; $result = $DB->query($query); return $DB->numrows($result); } /** * count how many consumable unused for the consumable item $tID * * @param $tID integer consumable item identifier. * * @return integer : number of consumable unused counted. **/ static function getUnusedNumber($tID) { global $DB; $query = "SELECT `id` FROM `glpi_consumables` WHERE (`consumableitems_id` = '$tID' AND `date_out` IS NULL)"; $result = $DB->query($query); return $DB->numrows($result); } /** * Get the consumable count HTML array for a defined consumable type * * @param $tID integer consumable item identifier. * @param $alarm_threshold integer threshold alarm value. * @param $nohtml integer Return value without HTML tags. (default 0) * * @return string to display **/ static function getCount($tID, $alarm_threshold, $nohtml=0) { // Get total $total = self::getTotalNumber($tID); if ($total != 0) { $unused = self::getUnusedNumber($tID); $old = self::getOldNumber($tID); $highlight = ""; if ($unused <= $alarm_threshold) { $highlight = "class='tab_bg_1_2'"; } //TRANS: For consumable. %1$d is total number, %2$d is unused number, %3$d is old number $tmptxt = sprintf(__('Total: %1$d, New: %2$d, Used: %3$d'), $total, $unused, $old); if ($nohtml) { $out = $tmptxt; } else { $out = "
".$tmptxt."
"; } } else { if ($nohtml) { $out = __('No consumable'); } else { $out = "
".__('No consumable')."
"; } } return $out; } /** * Check if a Consumable is New (not used, in stock) * * @param $cID integer consumable ID. **/ static function isNew($cID) { global $DB; $query = "SELECT `id` FROM `glpi_consumables` WHERE (`id` = '$cID' AND `date_out` IS NULL)"; $result = $DB->query($query); return ($DB->numrows($result) == 1); } /** * Check if a consumable is Old (used, not in stock) * * @param $cID integer consumable ID. **/ static function isOld($cID) { global $DB; $query = "SELECT `id` FROM `glpi_consumables` WHERE (`id` = '$cID' AND `date_out` IS NOT NULL)"; $result = $DB->query($query); return ($DB->numrows($result) == 1); } /** * Get the localized string for the status of a consumable * * @param $cID integer consumable ID. * * @return string : dict value for the consumable status. **/ static function getStatus($cID) { if (self::isNew($cID)) { return _nx('consumable', 'New', 'New',1); } else if (self::isOld($cID)) { return _nx('consumable', 'Used', 'Used',1); } } /** * Print out a link to add directly a new consumable from a consumable item. * * @param $consitem ConsumableItem object * * @return Nothing (displays) **/ static function showAddForm(ConsumableItem $consitem) { global $CFG_GLPI; $ID = $consitem->getField('id'); if (!$consitem->can($ID, UPDATE)) { return false; } if ($ID > 0) { echo "
"; echo "
"; echo ""; echo ""; echo "
"; echo "\n"; Dropdown::showNumber('to_add', array('value' => 1, 'min' => 1, 'max' => 100)); echo " "; echo "
"; Html::closeForm(); echo "
"; } } /** * Print out the consumables of a defined type * * @param $consitem ConsumableItem object * @param $show_old boolean show old consumables or not. (default 0) * * @return Nothing (displays) **/ static function showForConsumableItem(ConsumableItem $consitem, $show_old=0) { global $DB, $CFG_GLPI; $tID = $consitem->getField('id'); if (!$consitem->can($tID, READ)) { return false; } if (isset($_GET["start"])) { $start = $_GET["start"]; } else { $start = 0; } $canedit = $consitem->can($tID, UPDATE); $rand = mt_rand(); $where = ""; if (!$show_old) { // NEW $where = " AND `date_out` IS NULL ORDER BY `date_in`, `id`"; } else { //OLD $where = " AND `date_out` IS NOT NULL ORDER BY `date_out` DESC, `date_in`, `id`"; } $number = countElementsInTable("glpi_consumables", "`consumableitems_id` = '$tID' $where"); $query = "SELECT `glpi_consumables`.* FROM `glpi_consumables` WHERE `consumableitems_id` = '$tID' $where LIMIT ".intval($start)."," . intval($_SESSION['glpilist_limit']); $result = $DB->query($query); echo "
"; // Display the pager Html::printAjaxPager(Consumable::getTypeName(Session::getPluralNumber()), $start, $number); if ($canedit && $number) { Html::openMassiveActionsForm('mass'.__CLASS__.$rand); $actions = []; if ($consitem->can($tID, PURGE)) { $actions['delete'] = _x('button', 'Delete permanently'); } $actions['Infocom'.MassiveAction::CLASS_ACTION_SEPARATOR.'activate'] = __('Enable the financial and administrative information'); if ($show_old) { $actions['Consumable'.MassiveAction::CLASS_ACTION_SEPARATOR.'backtostock'] = __('Back to stock'); } else { $actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'give'] = _x('button', 'Give'); } $entparam = array('entities_id' => $consitem->getEntityID()); if ($consitem->isRecursive()) { $entparam = array('entities_id' => getSonsOf('glpi_entities', $consitem->getEntityID())); } $massiveactionparams = array('num_displayed' => min($_SESSION['glpilist_limit'], $number), 'specific_actions' => $actions, 'container' => 'mass'.__CLASS__.$rand, 'extraparams' => $entparam); Html::showMassiveActions($massiveactionparams); echo "\n"; } echo ""; if (!$show_old) { echo ""; } else { // Old echo ""; } if ($number) { $i = 0; $header_begin = ""; $header_top = ''; $header_bottom = ''; $header_end = ''; if ($canedit) { $header_begin .= ""; } $header_end .= ""; $header_end .= ""; $header_end .= ""; if ($show_old) { $header_end .= ""; $header_end .= ""; } $header_end .= ""; $header_end .= ""; echo $header_begin.$header_top.$header_end; while ($data = $DB->fetch_assoc($result)) { $date_in = Html::convDate($data["date_in"]); $date_out = Html::convDate($data["date_out"]); echo ""; if ($canedit) { echo ""; } echo ""; echo ""; echo ""; if ($show_old) { echo ""; echo ""; } echo ""; echo ""; } echo $header_begin.$header_bottom.$header_end; } echo "
"; echo self::getCount($tID, -1); echo "
".__('Used consumables')."
"; $header_top .= Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand); $header_bottom .= Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand); $header_end .= "".__('ID').""._x('item', 'State')."".__('Add date')."".__('Use date')."".__('Given to')."".__('Financial and administrative information')."
"; Html::showMassiveActionCheckBox(__CLASS__, $data["id"]); echo "".$data["id"]."".self::getStatus($data["id"])."".$date_in."".$date_out.""; if ($item = getItemForItemtype($data['itemtype'])) { if ($item->getFromDB($data['items_id'])) { echo $item->getLink(); } } echo ""; Infocom::showDisplayLink('Consumable', $data["id"]); echo "
"; if ($canedit && $number) { $massiveactionparams['ontop'] = false; Html::showMassiveActions($massiveactionparams); Html::closeForm(); } echo "
"; } /** * Show the usage summary of consumables by user **/ static function showSummary() { global $DB; if (!Consumable::canView()) { return false; } $query = "SELECT COUNT(*) AS count, `consumableitems_id`, `itemtype`, `items_id` FROM `glpi_consumables` WHERE `date_out` IS NOT NULL AND `consumableitems_id` IN (SELECT `id` FROM `glpi_consumableitems` ". getEntitiesRestrictRequest("WHERE", "glpi_consumableitems").") GROUP BY `itemtype`, `items_id`, `consumableitems_id`"; $used = array(); if ($result = $DB->query($query)) { if ($DB->numrows($result)) { while ($data = $DB->fetch_assoc($result)) { $used[$data['itemtype'].'####'.$data['items_id']][$data["consumableitems_id"]] = $data["count"]; } } } $query = "SELECT COUNT(*) AS count, `consumableitems_id` FROM `glpi_consumables` WHERE `date_out` IS NULL AND `consumableitems_id` IN (SELECT `id` FROM `glpi_consumableitems` ". getEntitiesRestrictRequest("WHERE", "glpi_consumableitems").") GROUP BY `consumableitems_id`"; $new = array(); if ($result = $DB->query($query)) { if ($DB->numrows($result)) { while ($data = $DB->fetch_assoc($result)) { $new[$data["consumableitems_id"]] = $data["count"]; } } } $types = array(); $query = "SELECT * FROM `glpi_consumableitems` ". getEntitiesRestrictRequest("WHERE","glpi_consumableitems"); if ($result = $DB->query($query)) { if ($DB->numrows($result)) { while ($data = $DB->fetch_assoc($result)) { $types[$data["id"]] = $data["name"]; } } } asort($types); $total = array(); if (count($types) > 0) { // Produce headline echo "
"; // Type echo ""; foreach ($types as $key => $type) { echo ""; $total[$key] = 0; } echo ""; echo ""; // new echo ""; $tot = 0; foreach ($types as $id_type => $type) { if (!isset($new[$id_type])) { $new[$id_type] = 0; } echo ""; $total[$id_type] += $new[$id_type]; $tot += $new[$id_type]; } echo ""; echo ""; foreach ($used as $itemtype_items_id => $val) { echo ""; $tot = 0; foreach ($types as $id_type => $type) { if (!isset($val[$id_type])) { $val[$id_type] = 0; } echo ""; $total[$id_type] += $val[$id_type]; $tot += $val[$id_type]; } echo ""; echo ""; } echo ""; $tot = 0; foreach ($types as $id_type => $type) { $tot += $total[$id_type]; echo ""; } echo ""; echo ""; echo "
".__('Give to')."$type".__('Total')."
".__('In stock')."".$new[$id_type]."".$tot."
"; list($itemtype,$items_id) = explode('####',$itemtype_items_id); $item = new $itemtype(); if ($item->getFromDB($items_id)) { //TRANS: %1$s is a type name - %2$s is a name printf(__('%1$s - %2$s'), $item->getTypeName(1), $item->getNameID()); } echo "".$val[$id_type]."".$tot."
".__('Total')."".$total[$id_type]."".$tot."
"; } else { echo "
".__('No consumable found')."
"; } } function getTabNameForItem(CommonGLPI $item, $withtemplate=0) { if (!$withtemplate && Consumable::canView()) { $nb = 0; switch ($item->getType()) { case 'ConsumableItem' : if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForConsumableItem($item); } return self::createTabEntry(self::getTypeName(Session::getPluralNumber()), $nb); } } return ''; } /** * @param $item string ConsumableItem object **/ static function countForConsumableItem(ConsumableItem $item) { $restrict = "`glpi_consumables`.`consumableitems_id` = '".$item->getField('id') ."'"; return countElementsInTable(array('glpi_consumables'), $restrict); } static function displayTabContentForItem(CommonGLPI $item, $tabnum=1, $withtemplate=0) { switch ($item->getType()) { case 'ConsumableItem' : self::showAddForm($item); self::showForConsumableItem($item); self::showForConsumableItem($item, 1); return true; } } function getRights($interface='central') { $ci = new ConsumableItem(); return $ci->getRights($interface); } }