Compute WorkOrder End Date
Prerequisite: You must be familiar with the Syntax used in Tutorials
- learning:
- Automatically compute a field value on creation, on update or always
- level:
- Beginner
- domains:
- XML, PHP, Automation
- methods:
- ComputeValues, OnInsert, OnUpdate
- min version:
- 2.1.0
Goal
In this usecase, we want to automatically compute the end
date
of a WorkOrder to its start date
+ a fixed
delay of 2 hours.
Implementation
-
To do it with the Designer you must have
Designer PHP developer
profile. -
To do it with an extension, you must have already created an extension.
Prerequisite
By default on a WorkOrder the End date is mandatory, so we change this logic, as it is useless to require the user to enter a data which will be set automatically just after.
with the Designer
in an iTop extension
- itop_design / classes
-
<class id="WorkOrder" _delta="must_exist"> <fields> <field id="end_date"> <!-- allowing ticket_id to be empty, as it will be computed --> <is_null_allowed _delta="redefine">true</is_null_allowed> </field> </fields> </class>
Computation options
Computation is not something which can be done with XML. For this we need to add a PHP method on the class WorkOrder to compute the end_date. And we want this method to be automatically called when the object is persisted.
-
You can decide when this method should be called amongst the existing events
-
You can call the callback method as you like, also the Designer proposed name is a good base
Below we will list different (Event | callback method) which can be used to achieve the current usecase
Event | Possible callback method name (it's free) |
Before create or update (EVENT_DB_BEFORE_WRITE) | EvtBeforeWrite(Combodo\iTop\Service\Events\EventData $oEventData) |
Recompute object values (EVENT_DB_COMPUTE_VALUES) | EvtComputeValues(Combodo\iTop\Service\Events\EventData $oEventData) |
Before create or update
with the Designer
Callback method
At creation or on modification, if the Start Date is modified by the user, the End Date must be automatically recomputed, just before being checked, then written to Database.
- class:WorkOrder
-
public function EvtBeforeWrite(Combodo\iTop\Service\Events\EventData $oEventData) { $oStartDate = new DateTime($this->Get('start_date')); $oEndDate = clone $oStartDate; $iDuration = 2*3600 ; // 2 hours in seconds $oEndDate->modify( '+'.$iDuration.' seconds'); $this->Set('end_date',$oEndDate->Format(AttributeDateTime::GetInternalFormat())); }
with an extension
- itop_design version="3.1" | classes
-
<class id="WorkOrder"> <event_listeners> <event_listener id="EvtBeforeWrite" _delta="define"> <!-- Id of the event does not have to be the same as the callback method, but why not --> <event>EVENT_DB_BEFORE_WRITE</event> <rank>10</rank> <callback>EvtBeforeWrite</callback> <!-- The callback must be the name of an existing class method. The name is free. Signature is imposed --> </event_listener> </event_listeners>
Combodo\iTop\Service\Events\EventData $oEventData
?Combodo\iTop\Service\Events\EventData $oEventData
In which case, you can call it like this $this->EvtBeforeWrite(null);
Recompute object values
There is another event which can be used to compute a field.
Exactly the same logic as above
Callback method
- class:WorkOrder
-
public function EvtComputeValues(Combodo\iTop\Service\Events\EventData $oEventData) { $oStartDate = new DateTime($this->Get('start_date')); $oEndDate = clone $oStartDate; $iDuration = 2*3600 ; // 2 hours in seconds $oEndDate->modify( '+'.$iDuration.' seconds'); $this->Set('end_date',$oEndDate->Format(AttributeDateTime::GetInternalFormat())); }
Adding a listener to the event
- itop_design version="3.1" | classes
-
<class id="WorkOrder"> <event_listeners> <event_listener id="EvtComputeValues" _delta="define"> <!-- Id of the event does not have to be the same as the callback method, but why not --> <event>EVENT_DB_COMPUTE_VALUES</event> <rank>10</rank> <callback>EvtComputeValues</callback> </event_listener> </event_listeners>
Making a field read-only
Here we want to prevent any user to enter the “End date” (end_date) of a WorkOrder, because just above we have forced it's value by computation.
If we don't do it, the user has the feeling that he can/must set it manually, also it's entry will eventually be overwritten.
Callback method
This time we create 2 methods, one for controlling the creation form and one for the modification form
- class:WorkOrder
-
public function evtSetInitialAttributeFlags(Combodo\iTop\Service\Events\EventData $oEventData) { $this->ForceInitialAttributeFlags('end_date', OPT_ATT_READONLY); } public function evtSetAttributeFlags(Combodo\iTop\Service\Events\EventData $oEventData) { $this->ForceAttributeFlags('end_date', OPT_ATT_READONLY); }
Adding listeners to the events
Then we do the plumbing, by listing to the event and specifying the callback method declared above
- itop_design version="3.1" | classes
-
<class id="WorkOrder"> <event_listeners> <event_listener id="evtSetInitialFlags" _delta="define"> <!-- Id of the event does not have to be the same as the callback method, but why not --> <event>EVENT_DB_SET_INITIAL_ATTRIBUTES_FLAGS</event> <rank>10</rank> <callback>evtSetInitialFlags</callback> </event_listener> <event_listener id="evtSetAttributeFlags" _delta="define"> <event>EVENT_DB_SET_ATTRIBUTES_FLAGS</event> <rank>10</rank> <callback>evtSetAttributeFlags</callback> </event_listener> </event_listeners>
FYI: Old methods now deprecated.