Урок 5. Практика разработки. Часть 2
Contents
Урок 5. Практика разработки. Часть 2#
В данном уроке мы рассмотрим:
Типы объектов
Состояния классов
Динамическое управление редактируемостью полей
Действия на перевод состояния
Типы объектов#
Сервис предоставляет набор стандартных возможностей, доступных для всех типизируемых классов. Основным назначением типа объекта является хранение настроек по документу, которые могут быть переопределены на проекте. Руководство разработчика: Тип объекта
Состояния#
Состояния класса позволяют управлять бизнес-логикой объекта. Руководство разработчика: Тип объекта # Переходы состояний
Практические задания#
Добавление атрибутов типа объекта и состояния#
В классе
Lbr_OutOrder
,Lbr_InOrder
иLbr_InAct
добавьте атрибуты:
name |
attribute-type |
caption |
Дополнительно |
---|---|---|---|
idState |
Long |
Состояние |
Ссылочный на объект, Ссылается на класс Btk_ClassState, не копируется при выполнении копирования |
idStateMC |
Number |
Номер состояния |
Не видимый, не копируется при выполнении копирования, является порядковым номером состояния ( |
idObjectType |
Long |
Тип |
Ссылочный на объект, Ссылается на класс Btk_ObjectType, хедлайн |
Запустите кодогенерацию по этим классам и запустите генератор таблиц для них
Добавление состояния для классов#
Откройте карточку класса
Lbr_InAct
(Настройка системы \ Сущности > Классы
) и добавьте состояния:
Системное имя |
Наименование |
Порядковый номер |
Стартовое состояния |
---|---|---|---|
Create |
Оформляется |
100 |
1 |
Executed |
Выполнен |
300 |
0 |
Для классов
Lbr_InOrder
иLbr_OutOrder
в api сделайте методregState
для регистрации аналогичных состояний и пропишите его в odm в тэгеdbData
. Руководство разработчика: Тип объекта # Регистрация состоянийЗапустите генерацию таблиц для данных классов, чтобы отработал скрипт регистрации состояний. При перезапуске скрипта необходимо увеличивать его версию.
Создание закладки для класса через справочник закладок#
Создайте закладку в справочнике закладок для позиций
Lbr_InActDet
.Системное имя -
Lbr_InActDetAvi.List_idInAct
Наименование -
Позиции
Имя выборки -
Lbr_InActDetAvi
Имя отображения -
List_idInAct
В детализации укажите класс
Lbr_InAct
. Руководство разработчика: Тип объекта # ЗакладкиДля классов
Lbr_InOrder
иLbr_OutOrder
в api сделайте методregTab
для регистрации закладок со своими позициями и пропишите его в odm. Руководство разработчика: Тип объекта # Регистрация закладокЗапустите генерацию таблиц для данных классов, чтобы отработал скрипт регистрации.
Данные закладки будут нужны для дальнейшей настройки на типе объекта.
Настройка типов объектов#
Создайте тип объекта с кодом, наименованием и кр. наименованием
Lbr_InAct
-Приходная накладная
через справочник типов объекта и установите на нем флаг по умолчанию, настройте для него закладку с позициями и переходы состояний. Доступные закладки для класса будут отображаться, если установить в фильтре флагОтображать неактивные
Для того, чтобы при создании объекта подставлялся тип по умолчанию, в
Lbr_InActApi
переопределите методinsert
и пропишите в конце вызов установки типа объекта по умолчаниюsetidObjectType(rop, Btk_ObjectTypeApi().getDefaultObjType(idClass))
В
Lbr_InAct.avm
отображенииCard
подключите закладки от типа объекта. Руководство разработчика: Тип объекта # Детализация виде закладокТам же у атрибута
idObjectTypeHL
измените тип редактора на выпадающий список сlookupQuery="gtk-Btk_ObjectTypeAvi#MainLookup"
В
Lbr_InActApi
создайте методregObjectType
для регистрации еще одного типаLbr_InAct_Add
-Дополнительная приходная накладная
, с параметромbpIsDefault = 0
. Там же пропишите регистрацию закладок для типа и переходов состояния, пропишите метод в odm. Запустите генерацию таблиц по данному классу. Руководство разработчика: Тип объекта # Регистрация подкласса, типа объекта, закладок для типа и переходов состоянийДля классов
Lbr_InOrder
иLbr_OutOrder
сделайте аналогичную настройку вavm
и вApi().insert
, также вApi
сделайте метод для регистрации типа по умолчанию с кодом и наименованием из класса. Там же пропишите регистрацию закладок для типа и переходов состояния, пропишите метод в odm, с зависимостями от предыдущих скриптовregTab
иregState
. Запустите генерацию таблиц по данным классам.
Так как тип объекта и его коллекции является классами с разделяемым режимом кеширования (Shared), то необходимо после любых изменений на них, сбрасывать Shared кэш
Разработка бизнес логики#
Внимание
Не используйте copyAro для получения значений атрибутивного состава rop, так как это увеличивает расход оперативной памяти, для получения значений атрибута следует применять rop.get(_.атрибут)
Вычисление заголовка с учетом типа объекта#
В
Api
классов-документов измените вычисление заголовкаcalcHeadLine
, заголовок должен быть в формате{(Краткое наименование из типа объекта).nvl(HL класса)} № {sNumDoc} от {dDoc в формате дд.мм.гггг}
.Для созданных ранее объектов пересчитайте заголовки, для этого в карточках классов, под молотком и ключом запустите операцию
Пересчитать заголовки и мнемокоды объектов класса
. Для проверки можно посмотреть данные столбца sheadline_dz в таблицах.
Динамическое управление редактируемостью полей#
В
Avi
документов для карточек переопределите сеттер состоянияsetidState
, в конце пропишите методы для корректного срабатыванияcheckWorkability
мастера и деталей, для того чтобы последующие задания работали корректно при переводе состояния:
//не обязательные действия
//завершение транзакции
session.commit()
//снятие блокировки
Btk_FormSessionApi().closeLockUnit()
//необходимые действия
//обновление карточки
selection.refreshItem()
//вызов checkWorkability в карточке
selection.checkWorkability()
//вызов checkWorkability в деталях
selection.cwaDetails()
Для реализации динамического управления редактируемостью в
Avi
позиций документов, для отображенийList_idDoc
иList_idInAct
переопределите методcheckWorkability
, напишите блокировку добавления, удаления, редактирования позиций, если номер состояния документа отличен от 100. Можно воспользоваться данными методами:
//переменная для управления редактируемостью
val bvRO = getVar("super$idStateMC").asNNumber.isDistinct(100.nn)
//для одного атрибута
selection.attrs("Имя атрибута").isReadOnly = bvRO
//для списка атрибутов
selection.attrs().foreach(_.isReadOnly = bvRO)
//для операций
selection.opers("Имя операции").isEnabled = !bvRO
В
Avi
документов для карточек переопределитеcheckWorkability
, напишите блокировку на редактирование всех полей, кромеidState
,idStateHL
иnSum
, если номер состояния документа отличен от 100
Действия на перевод состояния#
В Lbr_InActApi
:
Создайте метод проверки документа (например
validateDoc
), на вход будет rop документа.В нем пропишите вызов ошибки, если не будут выполнены какие либо условия (указаны ниже). Ошибку можно сделать одну общую с не выполненными условиями или отдельную по каждому условию. Вызов ошибки осуществляется методом
throw AppException("Текст ошибки")
. Перечень условий:Заполнены атрибуты документа (дата, организация, библиотекарь)
Наличие хотя бы одной записи в позициях
Заполнены атрибуты в позициях (книга, количество)
Переопределите сеттер состояния (
setidState
), в начале метода пропишите вызов метода проверки, если номер нового состояния будет >=300 и номер старого состояния < 300.В
Lbr_InOrderApi
иLbr_OutOrderApi
напишите аналогичную логику, только без проверки количества в позиции.
Проверка при удалении#
в Api
документов переопределите метод delete
и напишите в начале проверку, чтобы нельзя было удалить документ, если он находится не в состоянии Оформляется