SLA by Service Subcategory
Prerequisite: You must be familiar with the Syntax used in Tutorials and have already created an extension.
- learning:
- How to change the way SLA/SLT are computed
- level:
- Intermediate
- domains:
- XML, Lifecycle
- min version:
- 2.3.0
This tutorial will explain
-
How deadlines for TTO (Time To Own) and TTR (Time To Resolve) are computed for a particular Ticket
-
How you can change the logic
How does it work?
Before changing, let's understand how it works in the standard Datamodel.
Datamodel
Computation
1. Computing TTO & TTR
When a UserRequest or Incident is created or modified, iTop retrieve all associated stopwatches (Time-To-Own and Time-To-Resolve by default) and for each:
-
Start or Stop the stopwatches,
-
Compute Dealines associated to each stopwatch (if any)
-
Update stopwatch sub-items values
1.2 Computing Deadlines
How to know when a particular goal TTO or TTR will be reached?
-
TTO and TTR both rely on the same query to retrieve applicable SLTs, with a
metric
parameter (TTO or TTR) as an SLT is flagged TTO or TTR -
They can also rely on the CoverageWindow and Holidays with SLAs based on working hours
1.2.1 Retrieve applicable SLT
The SLT will tell iTop what is the delay to apply to the current UserRequest or Incident for TTO or TTR
The query to retrieve the SLTs is defined as a constant
- itop-design
-
<constants> <constant id="RESPONSE_TICKET_SLT_QUERY" xsi:type="string" _delta="redefine"><![CDATA[
SELECT SLT AS slt /* In standard model, SLTs can be reuse on different SLAs */ JOIN lnkSLAToSLT AS l1 ON l1.slt_id=slt.id JOIN SLA AS sla ON l1.sla_id=sla.id /* In standard model, SLA is defined on the relationship between a CustomerContract and a Service */ JOIN lnkCustomerContractToService AS l2 ON l2.sla_id=sla.id JOIN CustomerContract AS sc ON l2.customercontract_id=sc.id /* We get the SLT applicable for the :metric (TTO or TTR) */ WHERE slt.metric = :metric /* We get the SLT applicable for the service requested in the Ticket (:this) */ AND l2.service_id = :this->service_id /* We get the SLT applicable for the customer defined in the Ticket (:this) */ AND sc.org_id = :this->org_id /* We get the SLT applicable for the type of Ticket (UserRequest or Incident) */ AND slt.request_type = :request_type /* We get the SLT applicable for the Ticket priority */ AND slt.priority = :this->priority
]]></constant> </constants>
:request_type
is hardcoded to incident- ComputeSLT($oTicket, $sMetric = 'TTO')
-
[...] $sType=get_class($oTicket); if ($sType == 'Incident') $sRequestType = 'incident'; else $sRequestType = $oTicket->Get('request_type'); [...]
Changing
This tutorial describe a particular customized datamodel in which “SLA are defined by ServiceSubcategory”, but the same logic would apply with a different datamodel.
The datamodel
In the standard datamodel
-
Different SLA can be applied on each Service delivered to a Customer: one SLA for Service A and another SLA for Service B.
-
Different customers can have different SLA applied for the same Service. On Service A: one SLA for Customer 1 and another SLA for Customer 2.
-
An SLA is made of SLTs
-
An SLT can be reuse by multiple SLAs.
Let's see what is required to replace the SLA standard logic by a new one where “SLA are defined by ServiceSubcategory, independently of the Customers”
1. Remove the SLA from lnkCustomerContractToService
-
Removing
customercontracts_list
from class SLA through Combodo as this requires XML injection. Do not do it with standard Designer UI as it would delete the lnk class as well -
Comment or delete the SLA::CheckToWrite() method
<class id="SLA" _created_in="itop-service-mgmt" _delta="must_exist"> <fields> <field id="customercontracts_list" xsi:type="AttributeLinkedSetIndirect" _delta="delete"/> </fields> <methods> <method id="DoCheckToWrite" _delta="delete"/> </methods> <presentation> <details _delta="redefine"> <items> <item id="col:col0"> <items> <item id="name"> <rank>10</rank> </item> <item id="org_id"> <rank>20</rank> </item> <item id="description"> <rank>30</rank> </item> </items> <rank>10</rank> </item> <item id="slts_list"> <rank>20</rank> </item> </items> </details> </presentation> </class>
-
For removing
sla_id
fromlnkCustomerContractToService
class, check this Tutorial: Remove a field from Ticket.
2. Add the SLA on ServiceSubcategory
For adding sla_id
on
ServiceSubcategory
class, start with this:
- itop-design / classes
-
<class id="ServiceSubcategory" _delta="if_exists"> <fields> <field id="sla_id" xsi:type="AttributeExternalKey" _delta="define"> <sql>sla_id</sql> <target_class>SLA</target_class> <!-- We don't want to delete the Service Subcategory automatically, if SLA is deleted --> <on_target_delete>DEL_MANUAL</on_target_delete> <!-- Better not forcing SLA to be set, unless you have no Service Subcategory created --> <is_null_allowed>true</is_null_allowed> </field> </fields> </class>
Then complete presentation and dictionnary with the help of this Tutorial: Add a field to the Server class
3. Force the Service Subcategory to be provided
If you want to be able to set deadlines at Ticket creation, then
the Service Subcategory must be provided. It is not mandatory in
the standard datamodel, so we need to change this and make it
mandatory.
For this check this Tutorial: Force a field to be
always mandatory
Applicable SLT
The constant id=“RESPONSE_TICKET_SLT_QUERY” must be overwritten:
-
in the ITSM Designer
-
or within an extension.
Here is the new value to set for the constant:
SELECT SLT AS slt /* Unchanged: We get SLTs for SLA */ JOIN lnkSLAToSLT AS l1 ON l1.slt_id=slt.id JOIN SLA AS sla ON l1.sla_id=sla.id /* Specific: SLA is defined on ServiceSubcategory */ JOIN ServiceSubcategory AS ss ON ss.sla_id=sla.id /* Unchanged: We get the SLT applicable for the :metric (TTO or TTR) */ WHERE slt.metric = :metric /* Specific: We get the SLA on the service sub-category requested in the Ticket (:this) */ AND ss.id = :this->servicesubcategory_id /* Specific: We do not consider the customer */ /* Unchanged: We get the SLT applicable for the type of Ticket (UserRequest or Incident) */ AND slt.request_type = :request_type /* Unchanged: We get the SLT applicable for the Ticket priority */ AND slt.priority = :this->priority
Extension: SLA considering business hours
If you have installed this extension: SLA considering business hours and
changed in the datamodel the place where the CoverageWindow is
defined (ExternalKey in class
lnkCustomerContractToService) then you will have to change
accordingly the coverage_oql
parameter in the
Configuration File of your iTop instance.
See the configuration of the extension for details.