Перейти к основному содержимому
Версия: 5.x

How-to: NEWSESSION

Пример 1

Условие

Есть заказ, для которого задана номер и признак того, является ли он проведенным.

CLASS Order 'Заказ';

isPosted 'Проведен' = DATA BOOLEAN (Order);
number 'Номер' = DATA INTEGER (Order);

FORM orders
OBJECTS o = Order
PROPERTIES(o) READONLY isPosted, number
;

Нужно создать действие, которое проведет его в отдельной сессии изменений, и добавить его на форму со списком заказов.

Решение

post 'Провести' (Order o)  {
NEWSESSION {
isPosted(o) <- TRUE;
APPLY;
}
}

EXTEND FORM orders
PROPERTIES(o) post TOOLBAR
;

Если не "оборачивать" действие по установлению свойства isPosted в оператор NEWSESSION, то во время выполнения оператора APPLY в базу данных будут записаны также другие изменения, возможно сделанные на форме orders.

Пример 2

Условие

Аналогично Примеру 1, только для заказа определена форма его редактирования.

FORM order
OBJECTS o = Order PANEL
PROPERTIES(o) isPosted, number

EDIT Order OBJECT o
;

Нужно создать действие, которое создаст новый заказ и откроет форму по его редактированию. Это действие нужно добавить на форму со списком заказов.

Решение

newOrder ()  {
NEWSESSION {
NEW o = Order {
number(o) <- (GROUP MAX number(Order oo)) (+) 1;
SHOW order OBJECTS o = o;
}
}
}

EXTEND FORM orders
// Вариант 1
PROPERTIES() newOrder DRAW o TOOLBAR

// Вариант 2
PROPERTIES(o) NEWSESSION NEW
;

Если не использовать оператор NEWSESSION, то объект нового заказа будет создан в сессии изменений формы orders. При этом если пользователь закроет форму не сохранив, то изменения "останутся" в сессии изменений формы, и созданный заказ будет отображен в форме со списком заказов.

Пример 3

Условие

Аналогично Примеру 2, только для заказа доступна возможность отметки.

selected 'Отм' = DATA LOCAL BOOLEAN (Order);
EXTEND FORM orders
PROPERTIES(o) selected
;

Нужно создать действие, которое удалит отмеченные заказы и сразу сохранит изменения в базу данных (без необходимости нажимать пользователю кнопку Сохранить).

Решение

deleteSelectedOrders 'Удалить отмеченные заказы' ()  {
NEWSESSION NESTED(selected) {
DELETE Order o WHERE selected(o);
ASK 'Вы собираетесь удалить ' + (GROUP SUM 1 IF DROPPED(o IS Order)) + ' заказов. Продолжить ?' DO {
APPLY;
}
}
}

EXTEND FORM orders
PROPERTIES() deleteSelectedOrders DRAW o TOOLBAR
;

По умолчанию, в новой сессии не учитываются изменения, сделанные в "верхней" сессии. Для того, чтобы свойство selected было доступно в новой сессии нужно использовать конструкцию NESTED. Без нее в свойстве selected всегда будет NULL. Кроме того, вместо указания конкретных свойств можно использовать конструкцию NESTED LOCAL. В этом случае будут доступны изменения всех локальных свойств верхней сессии.

Пример 4

Условие

Аналогично Примеру 2, только добавлена логика платежей по заказу.

CLASS Payment 'Платеж';

date 'Дата' = DATA DATE (Payment);
sum 'Сумма' = DATA NUMERIC[14,2] (Payment);

order 'Заказ' = DATA Order (Payment);

Нужно создать кнопку на форме, которая откроет отдельную форму по редактированию платежей в этом заказе.

Решение

FORM orderPayments 'Платежи по заказу'
OBJECTS o = Order PANEL // Не добавляем свойств, чтобы этот объект не был вообще виден на форме

OBJECTS p = Payment
PROPERTIES(p) date, sum, NEW, DELETE
FILTERS order(p) == o
;

editPayments 'Редактировать платежи' (Order o) {
NESTEDSESSION {
SHOW orderPayments OBJECTS o = o;
}
}

EXTEND FORM order
PROPERTIES(o) editPayments
;

При использовании оператора NESTEDSESSION все изменения, сделанные в "верхней" сессии изменений, будут доступны во вложенной сессии. Если пользователь закроет форму, не нажав ОК, то все изменения, сделанные непосредственно в форме, пропадут. Если пользователь нажмет ОК, то изменения будут записаны не в базу данных, а в "верхнюю" сессию изменений. В базу данных они запишутся вместе с изменениями сделанными в основной форме orders.

Использовать NEWSESSION в данном случае нельзя хотя бы потому, что при создании нового заказа, которого еще нет в базе данных, форма orderPayments не сможет увидеть этого заказа (так как во вложенной сессии не видны изменения "верхней"), и поведение будет непредсказуемым.

Если вообще не использовать никакого оператора по управлению сессиями, то если пользователь изменит что-то на форме orderPayments и нажмет кнопку Закрыть, изменения все равно "сохранятся", хотя он может ожидать другого поведения.