main.itop-tickets.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. // Copyright (C) 2010-2012 Combodo SARL
  3. //
  4. // This file is part of iTop.
  5. //
  6. // iTop is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // iTop is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with iTop. If not, see <http://www.gnu.org/licenses/>
  18. /**
  19. * Base class for computing TTO or TTR on a ticket
  20. */
  21. class ResponseTicketSLT
  22. {
  23. /**
  24. * Determines the shortest SLT, for this ticket, for the given metric. Returns null is no SLT was found
  25. * @param string $sMetric Type of metric 'TTO', 'TTR', etc as defined in the SLT class
  26. * @return hash Array with 'SLT' => name of the SLT selected, 'value' => duration in seconds of the SLT metric, null if no SLT applies to this ticket
  27. */
  28. protected static function ComputeSLT($oTicket, $sMetric = 'TTO')
  29. {
  30. $iDeadline = null;
  31. if (MetaModel::IsValidClass('SLT'))
  32. {
  33. $sType=get_class($oTicket);
  34. if ($sType == 'Incident')
  35. {
  36. $sRequestType = 'incident';
  37. }
  38. else
  39. {
  40. $sRequestType = $oTicket->Get('request_type');
  41. }
  42. $aArgs = $oTicket->ToArgs();
  43. $aArgs['metric'] = $sMetric;
  44. $aArgs['request_type'] = $sRequestType;
  45. //echo "<p>Managing:".$sMetric."-".$this->Get('request_type')."-".$this->Get('importance')."</p>\n";
  46. $oSLTSet = new DBObjectSet(DBObjectSearch::FromOQL(RESPONSE_TICKET_SLT_QUERY),
  47. array(),
  48. $aArgs
  49. );
  50. $iMinDuration = PHP_INT_MAX;
  51. $sSLTName = '';
  52. while($oSLT = $oSLTSet->Fetch())
  53. {
  54. $iDuration = (int)$oSLT->Get('value');
  55. $sUnit = $oSLT->Get('unit');
  56. switch($sUnit)
  57. {
  58. case 'days':
  59. $iDuration = $iDuration * 24; // 24 hours in 1 days
  60. // Fall though
  61. case 'hours':
  62. $iDuration = $iDuration * 60; // 60 minutes in 1 hour
  63. // Fall though
  64. case 'minutes':
  65. $iDuration = $iDuration * 60;
  66. }
  67. if ($iDuration < $iMinDuration)
  68. {
  69. $iMinDuration = $iDuration;
  70. $sSLTName = $oSLT->GetName();
  71. }
  72. }
  73. if ($iMinDuration == PHP_INT_MAX)
  74. {
  75. $iDeadline = null;
  76. }
  77. else
  78. {
  79. // Store $sSLTName to keep track of which SLT has been used
  80. $iDeadline = $iMinDuration;
  81. }
  82. }
  83. return $iDeadline;
  84. }
  85. }
  86. /**
  87. * Compute the TTO of a ticket - null if the class 'SLT' does not exist
  88. */
  89. class ResponseTicketTTO extends ResponseTicketSLT implements iMetricComputer
  90. {
  91. public static function GetDescription()
  92. {
  93. return "Time to own a ticket";
  94. }
  95. public function ComputeMetric($oObject)
  96. {
  97. $iRes = $this->ComputeSLT($oObject, 'TTO');
  98. return $iRes;
  99. }
  100. }
  101. /**
  102. * Compute the TTR of a ticket - null if the class 'SLT' does not exist
  103. */
  104. class ResponseTicketTTR extends ResponseTicketSLT implements iMetricComputer
  105. {
  106. public static function GetDescription()
  107. {
  108. return "Time to resolve a ticket";
  109. }
  110. public function ComputeMetric($oObject)
  111. {
  112. $iRes = $this->ComputeSLT($oObject, 'TTR');
  113. return $iRes;
  114. }
  115. }
  116. class _Ticket extends cmdbAbstractObject
  117. {
  118. public function UpdateImpactedItems()
  119. {
  120. $oContactsSet = $this->Get('contacts_list');
  121. $oCIsSet = $this->Get('functionalcis_list');
  122. $aCIsToImpactCode = array();
  123. $aSources = array();
  124. $aExcluded = array();
  125. $oCIsSet->Rewind();
  126. while ($oLink = $oCIsSet->Fetch())
  127. {
  128. $iKey = $oLink->Get('functionalci_id');
  129. $aCIsToImpactCode[$iKey] = $oLink->Get('impact_code');
  130. if ($oLink->Get('impact_code') == 'manual')
  131. {
  132. $oObj = MetaModel::GetObject('FunctionalCI', $iKey);
  133. $aSources[$iKey] = $oObj;
  134. }
  135. else if ($oLink->Get('impact_code') == 'not_impacted')
  136. {
  137. $oObj = MetaModel::GetObject('FunctionalCI', $iKey);
  138. $aExcluded[$iKey] = $oObj;
  139. }
  140. }
  141. $aContactsToRoleCode = array();
  142. $oContactsSet->Rewind();
  143. while ($oLink = $oContactsSet->Fetch())
  144. {
  145. $iKey = $oLink->Get('contact_id');
  146. $aContactsToRoleCode[$iKey] = $oLink->Get('role_code');
  147. if ($oLink->Get('role_code') == 'do_not_notify')
  148. {
  149. $oObj = MetaModel::GetObject('Contact', $iKey);
  150. $aExcluded[$iKey] = $oObj;
  151. }
  152. }
  153. $oNewCIsSet = DBObjectSet::FromScratch('lnkFunctionalCIToTicket');
  154. foreach($aCIsToImpactCode as $iKey => $sImpactCode)
  155. {
  156. if ($sImpactCode != 'computed')
  157. {
  158. $oNewLink = new lnkFunctionalCIToTicket();
  159. $oNewLink->Set('functionalci_id', $iKey);
  160. $oNewLink->Set('impact_code', $sImpactCode);
  161. $oNewCIsSet->AddObject($oNewLink);
  162. }
  163. }
  164. $oNewContactsSet = DBObjectSet::FromScratch('lnkContactToTicket');
  165. foreach($aContactsToRoleCode as $iKey => $sImpactCode)
  166. {
  167. if ($sImpactCode != 'computed')
  168. {
  169. $oNewLink = new lnkContactToTicket();
  170. $oNewLink->Set('contact_id', $iKey);
  171. $oNewLink->Set('role_code', $sImpactCode);
  172. $oNewContactsSet->AddObject($oNewLink);
  173. }
  174. }
  175. $oContactsSet = DBObjectSet::FromScratch('lnkContactToTicket');
  176. $oGraph = MetaModel::GetRelatedObjectsDown('impacts', $aSources, 10, true /* bEnableRedundancy */, $aExcluded);
  177. $oIterator = new RelationTypeIterator($oGraph, 'Node');
  178. foreach ($oIterator as $oNode)
  179. {
  180. if ( ($oNode instanceof RelationObjectNode) && ($oNode->GetProperty('is_reached')) && (!$oNode->GetProperty('source')))
  181. {
  182. $oObj = $oNode->GetProperty('object');
  183. $iKey = $oObj->GetKey();
  184. $sRootClass = MetaModel::GetRootClass(get_class($oObj));
  185. switch ($sRootClass)
  186. {
  187. case 'FunctionalCI':
  188. // Only link FunctionalCIs which are not already linked to the ticket
  189. if (!array_key_exists($iKey, $aCIsToImpactCode) || ($aCIsToImpactCode[$iKey] != 'not_impacted'))
  190. {
  191. $oNewLink = new lnkFunctionalCIToTicket();
  192. $oNewLink->Set('functionalci_id', $iKey);
  193. $oNewLink->Set('impact_code', 'computed');
  194. $oNewCIsSet->AddObject($oNewLink);
  195. }
  196. break;
  197. case 'Contact':
  198. // Only link Contacts which are not already linked to the ticket
  199. if (!array_key_exists($iKey, $aContactsToRoleCode) || ($aCIsToImpactCode[$iKey] != 'do_not_notify'))
  200. {
  201. $oNewLink = new lnkContactToTicket();
  202. $oNewLink->Set('contact_id', $iKey);
  203. $oNewLink->Set('role_code', 'computed');
  204. $oNewContactsSet->AddObject($oNewLink);
  205. }
  206. break;
  207. }
  208. }
  209. }
  210. $this->Set('functionalcis_list', $oNewCIsSet);
  211. $this->Set('contacts_list', $oNewContactsSet);
  212. }
  213. public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
  214. {
  215. parent::DisplayBareRelations($oPage, $bEditMode);
  216. if (!$bEditMode)
  217. {
  218. $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/fraphael.js');
  219. $oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/jquery.contextMenu.css');
  220. $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.contextMenu.js');
  221. $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/simple_graph.js');
  222. $oPage->AddAjaxTab(Dict::S('Ticket:ImpactAnalysis'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=ticket_impact&class='.get_class($this).'&id='.$this->GetKey(), true);
  223. }
  224. }
  225. }
  226. ?>