Урок 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 и напишите в начале проверку, чтобы нельзя было удалить документ, если он находится не в состоянии Оформляется