Разработка:storages/orders — различия между версиями

Материал из DOF
Перейти к: навигация, поиск
(Подробный формат полей в таблице:)
Строка 6: Строка 6:
 
== Принцип работы ==
 
== Принцип работы ==
 
Приказы - единоличные, законченные, единовременные распоряжения пользователей системы, на выполнение значимых действий с данными в системе.  Реализуют протоколирование и исполнение как обычных приказов (приказ о зачислении, приказ о переводе), так и подразумеваемые приказы (выставление оценки, изменение статуса объекты).
 
Приказы - единоличные, законченные, единовременные распоряжения пользователей системы, на выполнение значимых действий с данными в системе.  Реализуют протоколирование и исполнение как обычных приказов (приказ о зачислении, приказ о переводе), так и подразумеваемые приказы (выставление оценки, изменение статуса объекты).
Не обязательно все действия в системе должны выполняться через приказы, однако нужно стремится реализовать как приказы все действия, которые необходимо протоколировать и для работы с которыми в будущем предполагается использовать цифровую подпись. При последующей реализации цифровой подписи, ею можно будет заверять только действия, оформленные в качестве приказов.
+
Не обязательно все действия в системе должны выполняться через приказы, однако нужно стремится реализовать как приказы все действия, которые необходимо протоколировать и для работы с которыми в будущем предполагается использовать индивидуальную цифровую подпись. При последующей реализации индивидуальной цифровой подписи, ею можно будет заверять только действия, оформленные в качестве приказов. Сейчас при обработки приказов вычисляются контрольные суммы данных (сигнатуры sha1), для затруднения несанкционированного изменения данных (требуется ключь, сохраненный в конфигурационном файле).
  
 
С программной точки зрения работа с приказами построена следующим образом:
 
С программной точки зрения работа с приказами построена следующим образом:
 
* Плагин, "желающий" реализовать собственный приказ наследует родительский класс приказа (dof_storage_orders_baseorder), объявленный в справочнике "приказ". Базовый класс содержит методы для наполнения приказа данными, исполнения приказа, получение из БД данных о ранее исполненном приказе. В дочернем классе эти методы переопределяются, в соответствии с логикой работы данного приказа.
 
* Плагин, "желающий" реализовать собственный приказ наследует родительский класс приказа (dof_storage_orders_baseorder), объявленный в справочнике "приказ". Базовый класс содержит методы для наполнения приказа данными, исполнения приказа, получение из БД данных о ранее исполненном приказе. В дочернем классе эти методы переопределяются, в соответствии с логикой работы данного приказа.
* Плагин, использующий приказы, должен реализовать метод order($code,$id=null), который возвращает объект нового или существующего приказа.
+
* Для унификации, плагин, использующий приказы, должен реализовать метод order($code,$id=null), который возвращает объект нового или существующего приказа.
* В момент исполнения приказа, объект приказа должен запротоколировать все данные приказа любым способом (стандартный, но не обязательный, способ - запись сериализованного объекта вместе с остальной информацией о приказе) и выполнить действия, предполагаемые приказом.
+
* При сохранении приказа, данные сохраняются в справочник orders в сериализованном виде, или в другие справочники (для этого в классе приказа переопределяются методы load() и save(), которые сохраняют/читают часть данных в других справочниках и убирают/добавляют их в поле data. При сохранении указывается ответственный сотрудник (подготовивший приказ) и отдел, к которому приказ относится.
* Справочник "приказы" содержит метод, для получения записанного в БД приказа, при этом на основании информации из БД инициализируется соотествующий объект, который загружает собственные данные любым способом.
+
* До исполнения приказа его необходимо подписать с помощью метода sign(), при этом формируется хешь от всех данных приказа (включая отсутствующие в sdata) и записывается в поле signature. Подпись приказа всегда персональная.
 +
* Подписанный приказ можно исполнить методом execute(). При этом выполняются все действия, сопутствующие исполнению приказа. При необходимости, часть данных из sdata в другие справочники может переноситься именно на этом этапе, тогда переопределенная функция load() должна уметь их получить. Исполненный приказ помечается как исполненный. Это конечное состояние, удалить исполненный приказ нельзя, его действие можно отменить только другим, противоположным по эффекту приказом (если такой предусмотрен).
 +
* Справочник "приказы" содержит метод, для получения записанного в БД приказа, при этом на основании информации из БД инициализируется соотествующий объект, который загружает собственные данные любым способом. Для этого используются методы order() в плагинах, реализовавших соответствующие типы приказов.
  
Данные приказа представляют собой сложно-структурированный объект, элементами которого могут быть другие объекты и массивы. После исполнения приказа эти данные могут протоколироваться как в сериализованном виде, так и в реляционном, в виде составных частей записей в БД. Следует стремится к тому, чтобы формат этого объекта соответствовал формату входных данных для шаблона, отображающего приказ в виде документа ODF.
+
Данные приказа представляют собой сложно-структурированный объект (тип object), элементами которого могут быть скалярные значение, другие объекты и массивы. После исполнения приказа эти данные могут протоколироваться как в сериализованном виде, так и в реляционном, в виде составных частей записей в БД. Следует стремится к тому, чтобы формат этого объекта соответствовал формату входных данных для шаблона, отображающего приказ в виде документа ODF и в других форматах. Для этого формат объекта планируется совместимым с шаблонизатором [[Разработка:modlibs/templater]], с тем, чтобы приказы можно было распечатывать без дополнительной обработки.
 
 
Данные приказа представляют собой объект (тип object) поля которого содержат либо скалярные значения, либо массивы объектов (списки). Формат объекта планируется совместимым с шаблонизатором [[Разработка:modlibs/templater]], с тем, чтобы приказы можно было распечатывать без дополнительной обработки.
 
  
 
==Таблица в базе данных==
 
==Таблица в базе данных==
Строка 47: Строка 47:
 
* get_id() - получить id текущего объекта
 
* get_id() - получить id текущего объекта
 
* set_id() - установить id. Не может вызываться напрямую, только через методы save() и load()
 
* set_id() - установить id. Не может вызываться напрямую, только через методы save() и load()
* load($id,$withoutdata=true) - проверить наличие объекта совместимого типа в БД и сопоставиться с ним. Если требуется - вернуть содержимое объекта
+
* load($id,$withoutdata=true) - проверить наличие объекта совместимого типа в БД и сопоставиться с ним. Если требуется - собрать и вернуть данные объекта. Возвращается объект из справочника orders, с убранными полями sdata, plugintype, plugincode, code, signature и добавленным полем data, куда помещены десериализованные данные из sdata.  Если данные необходимо сохранять данные в других справочниках, в дочернем классе переопределяется метод load(), а родительский метод вызывается через parent::
* save(object $data) - сохранить данные приказа в БД
+
* save(object $data) - сохранить данные приказа в БД. Перед сохранением убираются поля, которые нельзя изменять напрямую (plugintype, plugincode, code, exdate, changedate, status, sdata, signerid, signature, signdate, data). Данные из data сериализуются в sdata. Если часть данных после сохранения или исполнения хранится в других справочниках, метод должен быть переопределен, а родительский вызывать через parent::. При этом, для корректности цифровой подписи необходимо обеспечить получение полей в той же последовательности, в которой они были сохранены.
* execute() - исполнить текущий приказ и пометить его как исполненный
+
* execute() - исполнить текущий приказ и пометить его как исполненный, если он был корректно подписан. Как правило переопределять не требуется, так как все сопутсвующие действия можно поместить в execute_actions().
* change_status() - изменить поле статус объекта в БД (для внутреннего пользования)
+
* execute_actions() - исполнить действия, сопутствующие выполнению приказа (вызывается после проверки подписи в execute()).  Если данные переписываются в другие справочники, они должны быть записаны так, чтобы функция load() прочитала все поля в точности в той же последовательности, как они были в сериализованном виде, иначе подпись не сойдется.
 +
* save_notice() - сохранить заметки о приказе (не считается изменением приказа и не влияет на подпись)
 +
* sign() - подписать объект по id
 +
* is_signed() - проверить подпись по id
 +
* make_sign() - сфоормировать строку подпись по объекту, возвращенному load()
 +
* check_sign() - проверить корректность подписи по объекту, возвращенному load()
 
=== Пример использования ===
 
=== Пример использования ===

Версия 22:24, 13 мая 2009

Плагин
Название orders
Тип storages


Принцип работы

Приказы - единоличные, законченные, единовременные распоряжения пользователей системы, на выполнение значимых действий с данными в системе. Реализуют протоколирование и исполнение как обычных приказов (приказ о зачислении, приказ о переводе), так и подразумеваемые приказы (выставление оценки, изменение статуса объекты). Не обязательно все действия в системе должны выполняться через приказы, однако нужно стремится реализовать как приказы все действия, которые необходимо протоколировать и для работы с которыми в будущем предполагается использовать индивидуальную цифровую подпись. При последующей реализации индивидуальной цифровой подписи, ею можно будет заверять только действия, оформленные в качестве приказов. Сейчас при обработки приказов вычисляются контрольные суммы данных (сигнатуры sha1), для затруднения несанкционированного изменения данных (требуется ключь, сохраненный в конфигурационном файле).

С программной точки зрения работа с приказами построена следующим образом:

  • Плагин, "желающий" реализовать собственный приказ наследует родительский класс приказа (dof_storage_orders_baseorder), объявленный в справочнике "приказ". Базовый класс содержит методы для наполнения приказа данными, исполнения приказа, получение из БД данных о ранее исполненном приказе. В дочернем классе эти методы переопределяются, в соответствии с логикой работы данного приказа.
  • Для унификации, плагин, использующий приказы, должен реализовать метод order($code,$id=null), который возвращает объект нового или существующего приказа.
  • При сохранении приказа, данные сохраняются в справочник orders в сериализованном виде, или в другие справочники (для этого в классе приказа переопределяются методы load() и save(), которые сохраняют/читают часть данных в других справочниках и убирают/добавляют их в поле data. При сохранении указывается ответственный сотрудник (подготовивший приказ) и отдел, к которому приказ относится.
  • До исполнения приказа его необходимо подписать с помощью метода sign(), при этом формируется хешь от всех данных приказа (включая отсутствующие в sdata) и записывается в поле signature. Подпись приказа всегда персональная.
  • Подписанный приказ можно исполнить методом execute(). При этом выполняются все действия, сопутствующие исполнению приказа. При необходимости, часть данных из sdata в другие справочники может переноситься именно на этом этапе, тогда переопределенная функция load() должна уметь их получить. Исполненный приказ помечается как исполненный. Это конечное состояние, удалить исполненный приказ нельзя, его действие можно отменить только другим, противоположным по эффекту приказом (если такой предусмотрен).
  • Справочник "приказы" содержит метод, для получения записанного в БД приказа, при этом на основании информации из БД инициализируется соотествующий объект, который загружает собственные данные любым способом. Для этого используются методы order() в плагинах, реализовавших соответствующие типы приказов.

Данные приказа представляют собой сложно-структурированный объект (тип object), элементами которого могут быть скалярные значение, другие объекты и массивы. После исполнения приказа эти данные могут протоколироваться как в сериализованном виде, так и в реляционном, в виде составных частей записей в БД. Следует стремится к тому, чтобы формат этого объекта соответствовал формату входных данных для шаблона, отображающего приказ в виде документа ODF и в других форматах. Для этого формат объекта планируется совместимым с шаблонизатором Разработка:modlibs/templater, с тем, чтобы приказы можно было распечатывать без дополнительной обработки.

Таблица в базе данных

orders - список зарегистрированных и исполненных приказов, с информацией о плагине, реализующем объект приказа, исполнителе, дате исполнения, специальном поле для сериализованного объекта приказа.

Подробный формат полей в таблице:

  • plugintype - тип плагина, в котором реализован приказ
  • plugincode - код плагина, в котором реализован приказ
  • code - код типа приказа (уникален внутри одного плагина)
  • departmentid - id отдела, внутри которого издан приказ
  • ownerid - id персоны, подготовившей приказ
  • signerid - id персоны, подписавшей приказ
  • date - дата приказа (которой он пройдет по документам)
  • signdate
  • exdate - дата исполнения приказа в системе
  • changedate - дата последнего изменения приказа
  • status - статус приказа
  • sdata - сериализованные данные приказа (если нужны)
  • signature - сигнатура приказа (sha от signerid, ключевого слова из конфига,signdate,date и сериализованной data)
  • notice - заметки

Дополнительные методы:

  • Получить объект ранее запротоколированного приказа по id

API

dof_storage_orders_baseorder

Класс является базовым классом для типов приказов, объявляемых в плагинах. Дочерние классы должны именоваться по шаблону dof_типплагина_кодплагина_order_кодприказа.

  • plugintype(),plugincode(),code() - получить идентификационную информацию о типе документа (должны быть объявлены в дочерних классах и возвращать строки).
  • baseptype(), basepcode() - идентификация плагина storages/orders, если объекту понадобиться обратиться к справочнику orders.
  • get_id() - получить id текущего объекта
  • set_id() - установить id. Не может вызываться напрямую, только через методы save() и load()
  • load($id,$withoutdata=true) - проверить наличие объекта совместимого типа в БД и сопоставиться с ним. Если требуется - собрать и вернуть данные объекта. Возвращается объект из справочника orders, с убранными полями sdata, plugintype, plugincode, code, signature и добавленным полем data, куда помещены десериализованные данные из sdata. Если данные необходимо сохранять данные в других справочниках, в дочернем классе переопределяется метод load(), а родительский метод вызывается через parent::
  • save(object $data) - сохранить данные приказа в БД. Перед сохранением убираются поля, которые нельзя изменять напрямую (plugintype, plugincode, code, exdate, changedate, status, sdata, signerid, signature, signdate, data). Данные из data сериализуются в sdata. Если часть данных после сохранения или исполнения хранится в других справочниках, метод должен быть переопределен, а родительский вызывать через parent::. При этом, для корректности цифровой подписи необходимо обеспечить получение полей в той же последовательности, в которой они были сохранены.
  • execute() - исполнить текущий приказ и пометить его как исполненный, если он был корректно подписан. Как правило переопределять не требуется, так как все сопутсвующие действия можно поместить в execute_actions().
  • execute_actions() - исполнить действия, сопутствующие выполнению приказа (вызывается после проверки подписи в execute()). Если данные переписываются в другие справочники, они должны быть записаны так, чтобы функция load() прочитала все поля в точности в той же последовательности, как они были в сериализованном виде, иначе подпись не сойдется.
  • save_notice() - сохранить заметки о приказе (не считается изменением приказа и не влияет на подпись)
  • sign() - подписать объект по id
  • is_signed() - проверить подпись по id
  • make_sign() - сфоормировать строку подпись по объекту, возвращенному load()
  • check_sign() - проверить корректность подписи по объекту, возвращенному load()

Пример использования