Information

  • Here you will find a description of programmable events, their function, and how they can be created.

General

Information

  • The objective of the use of programmable events is to control the system behavior as far and flexibly as possible and.
  • Programmable events are to call any function required (in Python, Jython, or Java) by fixed parameters.
  • In the long run, programmable events are to replace customizing exits by more powerful and simpler structures.

Details

  • There are two types of events: data-driven events and time-controlled events.
    • Data-driven events are events which are run when data is written.
    • Time-controlled events are executed at a particular point in time, independent of other activities.
  • All programmable events are saved in DT312 Events.
    • If this table does not exist or if the framework cannot be started for another reason (e.g. because the Jython interface does not work), the server will not be started. In such a case, a log entry will be written which indicates that the event framework could not be loaded, the respective migration packet is to be run and that, should the error still occur, the PLANTA customer service is to be notified.
  • Both event types have the same parameters, e.g. UUID, function type, parameter, and type-specific parameters. For a list and description of the individual parameters, see here.
    • As far as the selected language in which event functions are written is concerned (function type),
      • Java events are only to be defined for system-oriented application.
      • Python events have access to the full range of Python functionality. However, they require a running server (i.e. no plain web application).
      • Jython events can be run in web applications and on regular servers.
  • For the management of events, PLANTA provides the following modules in the system customizer:

Note

  • No programmable events are started while the server runs in special modes (import, export, migration, and during scheduling).

Data-Driven Events

Information

  • Data-driven events (or data events) can be defined for every database table.
  • Data-driven events receive the event itself as a parameter (for meta information on the event behavior) as well as the object to be saved (which can be manipulated by the event). This object is either a DtpRecord (in Python) or a Pojo object, as it has been defined in the target folder (in Java and Jython).
    • DtpRecords and Java-Pojo objects present different views on the same database records.
  • Please note that data-driven events can only be defined for a table as a whole and not for a particular event.
    • Whether the event is then to be actually executed must be checked by the event function itself (via the name of the property to be changed) or via the Condition parameter.
  • Here you can find information on further parameters for data-driven events.

Event Types

Information

  • The following event types are available for data-driven events:
    • pre-insert/pre-update/pre-delete
      • These event types are executed for insertion/update/deletion processes before saving.
    • post-insert/post-update/post-delete
      • These event types are executed for insertion/update/deletion processes after saving.
    • pre-save/post-save
      • These event types are executed for insertion/update processes before or after saving.
        • A pre-save-event is both a pre-insert and a pre-update event.
        • A post-save-event is both a post-insert and a post-update event.
    • On-change
      • This event type is run before saving whenever a data field is changed. Particularities are explained here.
  • Pre-functions are executed before saving and allow you to change the record to be saved again or to abort saving (via the return value).
  • Post-functions are executed after the records have been saved. They serve to adjust a record (or other objects) after saving has been completed successfully.

Notes

  • Pre-event-methods and on-change-event-methods can return a boolean value. The change is only carried out if this value is not False.
  • Post-delete events currently do not work in Python (further information).

Particularities of On-Change-Events

Information

  • On-Change-Events are data-driven events which are carried out each time a data field is changed - i.e. before saving.
  • They therefore resemble value ranges but are more flexible since they are triggered by both Jython and Python just like any other event.
  • Methods which are called by on-change-events (Jython or Python) have the name of the property which is to be changed as a parameter in addition to the usual data-event parameters (the event itself as well as the pojo object to be changed or the DtpRecord to be changed) as well as the old and new value of the property.

Processing of Data-Driven Events



Information

  • Data-driven events are run within the client or web session which has caused the event to be saved.
  • Data-driven events are each opened with a DtpRecord (for Python events) or with the pojo object (for Java & Jython) which is to be saved. They correspond exactly to the existing DtpRecord class or to the pojo objects as they have been defined in the target directory.

Important

  • It is recommended that the pre-function itself do not carry out any save-actions since they are opened after the transaction has already been started and the saving procedure would then be triggered again.
    • In case, contrary to the recommendation, pre-functions carry out save-actions, there is a mechanism which aborts infinite loops after ten recursions.
  • Pre-functions are designed for two purposes:
    • to check whether saving is actually permitted (by return value). If this is False, saving will be aborted. This does not lead to a rollback or exception since the changes for possible corrections are to be retained. 
      • When saving from Python, dtp_record.save() simply returns 0 or false. The handling lies within the responsibility of event itself or the saving function.
      • If there are multiple pre-events, no further events will be carried out after an event has returned false. (This is the default handling approach of "and” operators, e.g. in Java, Python, or C.)
    • Adjust settings once more. Each change made here will later be written automatically.
  • Saving in Post-Events is less critical since the transaction has already been abandoned here. However, infinite loops are generally possible here as well. They will also be aborted after 10 recursions.

Changed properties

  • A particular functionality for events is the option to retrieve all changed fields of the DtpRecord or the changed properties of the pojo object including the original value of a field. Original values are saved as soon as an object has been updated (e.g. DataItem.setvalue()).
  • Original values are reset as soon as all post-events have been run (see chart above).

To learn how you can create data-driven events, please refer to the description of the Data-Driven Events MOD009D60 module.

Time-Controlled Events

Information

  • Time-controlled events are executed at a defined point in time regardless of saving.
  • Since the events are not linked to records, they receive the event as a parameter but no DtpRecord and no pojo object.
  • Here you can find information on further parameters for time-controlled events.

Processing of Time-Controlled Events

Information

  • Time-controlled events are also executed when no client sessions are registered on the server.
  • Consequentially, time-controlled events are executed directly in the global server session. Realizing them via the java.util.Timer standard Java-class assures that each event runs in its own Java thread and thus (e.g. in an infinite loop within the event function or similar) does not block the server.
  • When starting the server, all already existing time-controlled events are scheduled for start (as far as they are active and their Status permits it).
  • Currently, only Jython or Java functions for time-controlled events are accepted.
    • Since the events are currently run in the global server session, the variables of the user session, which are deemed a given in customizing, are missing here. Code which would normally calculate the user rights by means of the user variable does not run within events.
  • Time-controlled events can have four statuses (specified in the Status parameter):
    • 0 Waiting: The event is currently scheduled to run (again) at a later point in time.
    • 1 Is executed: The function assigned to the event (Java or Jython) is currently running.
    • 2 Terminated: The event has been terminated without errors and will not be run again.
    • 3 Failed: An error has occurred during the last execution. The event will be executed again after server restart.
  • When starting the server, all active time-controlled events are scanned.
  • Events with Terminated or Is running status are not executed again.
  • All events with Waiting and Failed status are now started and enter their life-cycle:


Scheduling of Time-Controlled Events

Information

  • Events have a start date and a start time and support different intervals of recurrence.
  • Possible interval modes (are specified in the Recurs parameter)
IntervalDescription
OnceThe event is executed once at the planned point in time and does not recur.
HourlyThe event recurs every hour.
DailyThe event recurs every day.
WeeklyThe event recurs every seven days.
MonthlyThe event recurs the next month on the same week day, e.g. on the first Monday or on the last Friday of a month.
Yearly

The event recurs on the same date in the following year. Events on 02/29 only recur in leap years

User-definedA user-defined interval is specified. This allows for a more detailed configuration.
  • In User Defined mode, the user has the following configuration options:
    • The number and unit of the interval of recursion in one of the existing units: minutes / hours / days / weeks / months / years
    • On which weekdays the event may be executed
    • When the event is to be terminated (multiple selection not possible): never / at a defined point in time / after a defined number of executions

Implementation

  • The get_next_scheduled_execution_time Jython scheduling function is located at <server directory>/jython/server/events/event.py.
  • It is called upon server start in order to schedule all time-controlled events once and every time a time-controlled event has been executed.
    • It returns a java.util.Date which specifies the point in time at which the event is to be executed again.
    • If it returns the None function, the event switches to the "Terminated" status and will not be executed again.
  • The get_next_event_execution function is called from the customizing name space under <server directory>/jython/customizing/events by get_next_scheduled_execution_time.
  • It carries out the calculation of the next time of execution according to the configuration.
    • If the event has never been executed before, the configured start time is used to calculate the time of execution.
    • If the event has at least one history entry, the planned time of the last event will be used.

Sequence of event execution

To learn how you can create time-controlled events, please refer to the description of the Time-Controlled Events MOD009DA6 module.

Startup Events

Information

  • Startup events are only run once upon server start regardless of the saving procedure.
  • Since the events are not linked to records, they receive the event as a parameter but no DtpRecord and no pojo object.
  • They can be understood as streamlined time-controlled events (i.e. time-controlled events without information on when they are to be run).

Startup Event Process

Information

  • Startup events are executed automatically as soon as the PLANTA Server has been restarted and initialized.
  • Like time-controlled events, startup events are also executed in the global server session.
  • They are executed one by one according to the Position column of the Events table.
  • Any errors when executing startup events are noted in the log file.
  • As with time-controlled events, only Jython or Java functions are currently accepted for startup events. Startup events of the "Python" type are not executed.
    • However, there is the option of executing a Python module via the customizing.events.module.run_module Jython function, which is then executed in a clientless session (as with time-controlled events).

To learn how you can create startup events, please refer to the description of the Startup Events MOD009DU6 module.

Session Startup Events

Information

  • Session startup events behave similarly to (server) startup events, but are executed each time a user logs on to a new session (not a clientless session).
  • They each have only one parameter, the event itself.

Session Startup Event Process

Information

  • Session startup events are executed automatically as soon as a user has logged into a client or web client, as soon as the user menu is available (at this point, any Python code can be executed).
  • Unlike (server) startup events, session startup events can also execute Python functions in addition to Jython or Java functions.
  • Session startup events are executed within their session, the name of the logged-in user is available as a property of the event.
  • They are executed one by one according to the Position column of the Events table.
  • Any errors when executing startup events are noted in the log file.

Extension of Python Functionalities

  • In the course of the implementation of programmable events, the Python API has been extended by the following functions:
    • In  DtpRecord:
      • get_changed_dis : Returns a list of all data items the values of which have been changed.
      • get_dis : Returns a list of all data items of the record.
    • In  DataItem:
      • has_been_updated : Returns true if this data item has been updated.
      • get_original_value  : Returns the saved, initial value. If the data item has not been updated, the current value is applicable..
      • get_original_tech_value  : Returns the saved, initial technical value (analoguously to  get_tech_value).