Impact analysis enhancement:

- Some of the "context" rules are marked as "default=yes"
- Only the "default" context rules are used for the initial display of the impact analysis graph AND are used to compute the impacted items of a ticket.

SVN:trunk[3713]
This commit is contained in:
Denis Flaven
2015-09-03 16:56:44 +00:00
parent 5425f55af7
commit be3bce26ed
6 changed files with 46 additions and 10 deletions

View File

@@ -999,7 +999,7 @@ class DisplayableGraph extends SimpleGraph
*/
function GetAsJSON($sContextKey)
{
$aContextDefs = $this->GetContextDefinitions($sContextKey, false);
$aContextDefs = static::GetContextDefinitions($sContextKey, false);
$aData = array('nodes' => array(), 'edges' => array(), 'groups' => array());
$iGroupIdx = 0;
@@ -1055,7 +1055,7 @@ class DisplayableGraph extends SimpleGraph
*/
function RenderAsPDF(PDFPage $oPage, $sComments = '', $sContextKey, $xMin = -1, $xMax = -1, $yMin = -1, $yMax = -1)
{
$aContextDefs = $this->GetContextDefinitions($sContextKey, false); // No need to develop the parameters
$aContextDefs = static::GetContextDefinitions($sContextKey, false); // No need to develop the parameters
$oPdf = $oPage->get_tcpdf();
$aBB = $this->GetBoundingBox();
@@ -1219,7 +1219,7 @@ class DisplayableGraph extends SimpleGraph
* @param array $aContextParams Arguments for the queries (via ToArgs()) if $bDevelopParams == true
* @return multitype:multitype:string
*/
public function GetContextDefinitions($sContextKey, $bDevelopParams = true, $aContextParams = array())
public static function GetContextDefinitions($sContextKey, $bDevelopParams = true, $aContextParams = array())
{
$aLevels = explode('/', $sContextKey);
$sLeafClass = $aLevels[2];
@@ -1246,6 +1246,7 @@ class DisplayableGraph extends SimpleGraph
}
catch(Exception $e)
{
IssueLog::Warning('Invalid OQL query: '.$sOQL.' in the parameter '.$sContextKey);
unset($aContextDefs[$sKey]);
}
}
@@ -1262,7 +1263,7 @@ class DisplayableGraph extends SimpleGraph
*/
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects = array(), $sObjClass = null, $iObjKey = null, $sContextKey, $aContextParams = array())
{
$aContextDefs = $this->GetContextDefinitions($sContextKey, true, $aContextParams);
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
$aExcludedByClass = array();
foreach($aExcludedObjects as $oObj)
{
@@ -1310,7 +1311,7 @@ EOF
$aAdditionalContexts = array();
foreach($aContextDefs as $sKey => $aDefinition)
{
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql']);
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));
}
$sDirection = utils::ReadParam('d', 'horizontal');

View File

@@ -828,11 +828,13 @@
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed', 'rejected')) AND (L.impact_code != 'not_impacted') AND (C.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt/images/change-ongoing.png</icon>
<default>yes</default>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed')) AND (L.impact_code != 'not_impacted') AND (C.id != :this->id) AND (DATE_ADD(C.end_date, INTERVAL 3 DAY) < NOW())]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt/images/change-done.png</icon>
<default>no</default>
</item>
</items>
</down>
@@ -846,11 +848,13 @@
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed', 'rejected')) AND (L.impact_code != 'not_impacted') AND (C.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt/images/change-ongoing.png</icon>
<default>yes</default>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed')) AND (L.impact_code != 'not_impacted') AND (C.id != :this->id) AND (DATE_ADD(C.end_date, INTERVAL 3 DAY) < NOW())]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt/images/change-done.png</icon>
<default>no</default>
</item>
</items>
</down>
@@ -864,11 +868,13 @@
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed', 'rejected')) AND (L.impact_code != 'not_impacted') AND (C.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt/images/change-ongoing.png</icon>
<default>yes</default>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed')) AND (L.impact_code != 'not_impacted') AND (C.id != :this->id) AND (DATE_ADD(C.end_date, INTERVAL 3 DAY) < NOW())]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt/images/change-done.png</icon>
<default>no</default>
</item>
</items>
</down>
@@ -886,11 +892,13 @@
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed', 'rejected')) AND (L.impact_code != 'not_impacted')]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt/images/change-ongoing.png</icon>
<default>yes</default>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status IN ('closed')) AND (L.impact_code != 'not_impacted') AND (DATE_ADD(C.end_date, INTERVAL 3 DAY) < NOW())]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt/images/change-done.png</icon>
<default>no</default>
</item>
</items>
</down>
@@ -900,11 +908,13 @@
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status NOT IN ('closed', 'rejected')) AND (L.impact_code != 'not_impacted')]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt/images/change-ongoing.png</icon>
<default>yes</default>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[SELECT FCI, C FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Change AS C ON L.ticket_id = C.id WHERE (C.outage = 'yes') AND (C.status IN ('closed')) AND (L.impact_code != 'not_impacted') AND (DATE_ADD(C.end_date, INTERVAL 3 DAY) < NOW())]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt/images/change-done.png</icon>
<default>no</default>
</item>
</items>
</up>

View File

@@ -1755,6 +1755,7 @@
<oql><![CDATA[SELECT FCI, I FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Incident AS I ON L.ticket_id = I.id WHERE (I.status NOT IN ('closed', 'resolved')) AND (L.impact_code != 'not_impacted') AND (I.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-incident-mgmt-itil/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</down>
@@ -1768,6 +1769,7 @@
<oql><![CDATA[SELECT FCI, I FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Incident AS I ON L.ticket_id = I.id WHERE (I.status NOT IN ('closed', 'resolved')) AND (L.impact_code != 'not_impacted') AND (I.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-incident-mgmt-itil/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</down>
@@ -1781,6 +1783,7 @@
<oql><![CDATA[SELECT FCI, I FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Incident AS I ON L.ticket_id = I.id WHERE (I.status NOT IN ('closed', 'resolved')) AND (L.impact_code != 'not_impacted') AND (I.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-incident-mgmt-itil/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</down>
@@ -1798,6 +1801,7 @@
<oql><![CDATA[SELECT FCI, I FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Incident AS I ON L.ticket_id = I.id WHERE (I.status NOT IN ('closed', 'resolved')) AND (L.impact_code != 'not_impacted')]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-incident-mgmt-itil/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</down>
@@ -1807,6 +1811,7 @@
<oql><![CDATA[SELECT FCI, I FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN Incident AS I ON L.ticket_id = I.id WHERE (I.status NOT IN ('closed', 'resolved')) AND (L.impact_code != 'not_impacted')]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-incident-mgmt-itil/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</up>

View File

@@ -1855,7 +1855,8 @@
<oql><![CDATA[SELECT FCI, R FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN UserRequest AS R ON L.ticket_id = R.id WHERE (R.status NOT IN ('closed', 'resolved')) AND (R.request_type='incident') AND (L.impact_code != 'not_impacted') AND (R.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-request-mgmt/images/incident-red.png</icon>
</item>
<default>yes</default>
</item>
</items>
</down>
</impacts>
@@ -1868,6 +1869,7 @@
<oql><![CDATA[SELECT FCI, R FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN UserRequest AS R ON L.ticket_id = R.id WHERE (R.status NOT IN ('closed', 'resolved')) AND (R.request_type='incident') AND (L.impact_code != 'not_impacted') AND (R.id != :this->id)]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-request-mgmt/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</down>
@@ -1885,6 +1887,7 @@
<oql><![CDATA[SELECT FCI, R FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN UserRequest AS R ON L.ticket_id = R.id WHERE (R.status NOT IN ('closed', 'resolved')) AND (R.request_type='incident') AND (L.impact_code != 'not_impacted')]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-request-mgmt/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</down>
@@ -1894,6 +1897,7 @@
<oql><![CDATA[SELECT FCI, R FROM FunctionalCI AS FCI JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id JOIN UserRequest AS R ON L.ticket_id = R.id WHERE (R.status NOT IN ('closed', 'resolved')) AND (R.request_type='incident') AND (L.impact_code != 'not_impacted')]]></oql>
<dict>Tickets:Related:OpenIncidents</dict>
<icon>itop-request-mgmt/images/incident-red.png</icon>
<default>yes</default>
</item>
</items>
</up>

View File

@@ -133,6 +133,7 @@ class _Ticket extends cmdbAbstractObject
public function UpdateImpactedItems()
{
require_once(APPROOT.'core/displayablegraph.class.inc.php');
$oContactsSet = $this->Get('contacts_list');
$oCIsSet = $this->Get('functionalcis_list');
@@ -195,11 +196,24 @@ class _Ticket extends cmdbAbstractObject
}
$oContactsSet = DBObjectSet::FromScratch('lnkContactToTicket');
$oGraph = MetaModel::GetRelatedObjectsDown('impacts', $aSources, 10, true /* bEnableRedundancy */, $aExcluded);
$sContextKey = 'itop-tickets/relation_context/'.get_class($this).'/impacts/down';
$aContextDefs = DisplayableGraph::GetContextDefinitions($sContextKey, true, array('this' => $this));
$aDefaultContexts = array();
foreach($aContextDefs as $sKey => $aDefinition)
{
// Add the default context queries to the computation
if (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes'))
{
$aDefaultContexts[] = $aDefinition['oql'];
}
}
$oGraph = MetaModel::GetRelatedObjectsDown('impacts', $aSources, 10, true /* bEnableRedundancy */, $aExcluded, $aDefaultContexts);
$oIterator = new RelationTypeIterator($oGraph, 'Node');
foreach ($oIterator as $oNode)
{
if ( ($oNode instanceof RelationObjectNode) && ($oNode->GetProperty('is_reached')) && (!$oNode->GetProperty('source')))
if ( ($oNode instanceof RelationObjectNode) && ($oNode->GetProperty('is_reached')) && (!$oNode->GetProperty('source')) && ($oNode->GetProperty('context_root_causes', null) == null) )
{
$oObj = $oNode->GetProperty('object');
$iKey = $oObj->GetKey();
@@ -237,7 +251,8 @@ class _Ticket extends cmdbAbstractObject
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
{
parent::DisplayBareRelations($oPage, $bEditMode);
if (!$bEditMode)
// Display the impact analysis for tickets not in 'closed' or 'resolved' status... and not in edition
if ((!$bEditMode) && (!in_array($this->Get('status'), array('resolved', 'closed'))))
{
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/fraphael.js');
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/jquery.contextMenu.css');

View File

@@ -445,7 +445,8 @@ $(function()
sHtml += '&nbsp;'+this.options.labels.additional_context_info+' <select id="'+sId+'_contexts" name="contexts" class="multiselect" multiple size="1">';
for(var k in this.options.additional_contexts)
{
sHtml += '<option value="'+k+'" selected>'+this.options.additional_contexts[k].label+'</option>';
sSelected = (this.options.additional_contexts[k]['default']) ? 'selected' : '';
sHtml += '<option value="'+k+'" '+sSelected+'>'+this.options.additional_contexts[k].label+'</option>';
}
sHtml += '</select>'
}