Version: 4.x

# How-to: Events

## Example 1​

We have an order with a date, a number and a marker of whether it is closed.

``CLASS Order 'Order';isClosed 'Closed' = DATA BOOLEAN (Order);date 'Date' = DATA DATE (Order);number 'Number' = DATA INTEGER (Order);``

We need to make it so that orders are closed automatically at the end of the day.

### Solution​

``// Option 1WHEN SET(date(Order o) < currentDate()) DO    isClosed(o) <- TRUE;// Option 2WHEN CHANGED(currentDate()) AND date(Order o) < currentDate() DO    isClosed(o) <- TRUE;``

In the first case, the event will only be executed in one transaction at the time the expression inside the `SET` operator operator changes. That is, at the moment when the order date becomes smaller than the current date. However, if the user manually changes the order date to one greater than the current date and saves, the system will automatically execute this event and close the order. Therefore, the second option is preferable, since it will only come into effect when the current date changes at midnight.

## Example 2​

Similar to Example 1, but the order contains lines for the quantity, price and total.

``CLASS OrderDetail 'Order line';order 'Order' = DATA Order (OrderDetail) NONULL DELETE;quantity 'Qty' = DATA NUMERIC[15,3] (OrderDetail);price 'Price' = DATA NUMERIC[14,2] (OrderDetail);sum 'Amount' = DATA NUMERIC[16,2] (OrderDetail);``

We need to make it so that when the price or quantity changes, their product is automatically recorded as the total amount.

### Solution​

``WHEN LOCAL (CHANGED(quantity(OrderDetail d)) OR CHANGED(price(d)))            AND NOT CHANGED(sum(d)) DO {    sum(d) <- NUMERIC[16,2](quantity(d) * price(d));}``

Events of type `LOCAL` count all property changes relative not to the state of the database but to the values at the time of the previous occurrence of this event (or rather, the end of its handling). We need to check that `sum` has not changed, to avoid erasing changes made by previous changes. For example, if order lines have been imported from a file, in which the quantity, price and amount are recorded, then this event will no longer take effect.

## Example 3​

Similar to Example 2, but a book is specified for the order line. Each book also has a default price.

``CLASS Book 'Book';name 'Name' = DATA ISTRING (Book);price 'Price' = DATA NUMERIC[14,2] (Book);book 'Book' = DATA Book (OrderDetail);nameBook 'Book' (OrderDetail d) = name(book(d));FORM order    OBJECTS o = Order PANEL    PROPERTIES(o) date, number    OBJECTS d = OrderDetail    PROPERTIES(d) nameBook, quantity, price, sum    FILTERS order(d) == o;``

We need to make sure that when the book is changed, the price is automatically appended to the order line. This event should only work on the order edit form.

### Solution​

``WHEN LOCAL FORMS order SETCHANGED(book(OrderDetail d)) DO {    price(d) <- price(book(d));}``

In this case, the event will be triggered only when the book is changed or set. When a book is dropped, the price will not change.

Without the `FORMS` block, this event would be triggered by any change to the order line book. For example, when an order was imported in any other form.

## Example 4​

``CLASS OrderLog 'Order deletion log';date 'Order date' = DATA DATE (OrderLog);number 'Order number' = DATA INTEGER (OrderLog);dateTime 'Date' = DATA DATETIME (OrderLog);user 'User' = DATA User (OrderLog);WHEN DROPPED(Order o IS Order) DO {    NEW l = OrderLog {        date(l) <- PREV(date(o));        number(l) <- PREV(number(o));        dateTime(l) <- currentDateTime();        user(l) <- currentUser();    }}``
When deleting an order and triggering an event with the `DROPPED` modifier, it is important to remember that the object no longer exists and all properties that take it as input will give `NULL` values. Therefore, we need to access them not directly, but through the `PREV` operator.