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.
Datamodel
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 automaticaly called when the object is persisted.
-
You cannot invent any method name
-
You have to use one of the possible @overwritable-hook methods defined on DBObject class.
-
There are different methods which can be used, which are called at different stages of the creation/modification process.
Below we will list different methods which can be used to achieve the current usecase
-
OnInsert()
-
OnUpdate()
-
ComputeValues()
OnInsert()
OnInsert()
is
called just before the object is persisted. At the stage, the user
has submitted its data. The object is not yet stored in
Database.- class:WorkOrder
-
public function OnInsert() { parent::OnInsert(); $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 the Designer
OnUpdate()
With the OnInsert() method, if the Start Date is modified by the user later, the End Date will not be automatically recomputed.
If you want to achieve this, you can define the
OnUpdate()
function on the WorkOrder class on top of
the OnInsert()
.
OnUpdate()
is
called just before the object update. At the stage, the user has
submitted its data. The object is already existing in
Database.As they do the same code, you can group this code in a separate
method ComputeEndDate()
this one being freely named as
only your code need to call it.
- class:WorkOrder
-
public function ComputeEndDate() { $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())); } protected function OnInsert() { parent::OnInsert(); $this->ComputeEndDate(); } protected function OnUpdate() { parent::OnUpdate(); $this->ComputeEndDate(); }
ComputeValues()
There is another method which can be used to compute a field.
ComputeValues()
is called very often, before displaying the object and before
saving it in database.- class:WorkOrder
-
public function ComputeValues() { parent::ComputeValues(); $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())); }
Making "End date" read-only
Also the End Date is automatically computed, the user has the
feeling that he can/must set it manually. To prevent misleading
message, you can force the End Date field to be read_only when
editing a WorkOrder.
For this check: Force a
field to be read only