WorkPackage - Задача / Пакет работ
Поля
Ключ | Тип | Название |
---|---|---|
id | integer | ID |
created_at | DateTime | Дата создания |
updated_at | DateTime | Дата обновления |
status_updated_at | DateTime | Дата обновления статуса задачи |
subject | string | Тема |
description | string | null | Описание |
schedule_manually | boolean | Ручное планирование |
ignore_non_working_days | boolean | Игнорирование не рабочих дней при планировании |
start_date | date | null | Дата начала задачи |
due_date | date | null | Дата завершения задачи |
duration | integer | null | Продолжительность задачи в днях |
done_ratio | integer | % выполнения задачи |
estimated_hours | float | null | Запланированное время выполнения |
remaining_hours | float | null | Оставшееся время |
derived_estimated_hours | float | null | |
derived_remaining_hours | float | null | |
story_points | integer | null | Оценка в SP |
external_id | string | null | Внешний ID |
type_id | integer | Тип задачи |
project_id | integer | Проект |
status_id | integer | Статус |
status_sym | symbol | Код статуса |
category_id | integer | null | Категория |
priority_id | integer | Приоритет |
version_id | integer | null | Версия/Спринт |
author_id | integer | Автор |
assigned_to_id | integer | null | Исполнитель |
responsible_id | integer | null | Ответственный |
parent_id | integer | null | Родительская задача |
Связи
- type: Type - тип задачи
- type_sym: Symbol - код типа задачи
- project: Project - проект
- status: Status - статус задачи
- status_sym: Symbol - код типа задачи
- category: Category | null - категория задачи
- priority: IssuePriority - приоритет задачи
- version: Version | null - версия/Спринт задачи
- author: User - автор задачи
- assigned_to: User | null - исполнитель задачи
- responsible: User | null - ответственный задачи
- parent: WorkPackage | null - родительская задача
- time_entries: TimeEntry[] - записи времени по задаче
- relations: Relation[] - связи с задачами
Дополнительные поля
Дополнительные поля настраиваются в рамках Типа задачи и поэтому требуется проверять наличие доп. поля в задаче во избежание ошибок:
# Проверка что в задаче доступно допю поле
respond_to?(:cf_my_field)
Примитивные доп. поля
К ним относятся следующие типы:
- Целое число (integer)
- Текст (string)
- Длинный текст (string)
- Дробное число (float)
- Дата
- Дата/Время
- Логическое значение (boolean)
# Обращение к доп полю по Symbol: cf_<symbol>
self.cf_string_field = 'test' # string_field - символьный код доп. поля
# Обращение к доп полю по ID:
self.cf_99 = true # 99 - это ID кастомного поля
Списочные доп. поля
К ним относятся следующие типы:
- Пользователь (User)
- Версия/Спринт (Version)
- Список (CustomOption)
# Получение списка доступных значений доп поля по коду доп поля
options = CustomOption.by_cf(:my_field)
# Получение доступных значений доп поля по ID доп поля
options = CustomOption.by_cf(99)
# Получение доступных значений доп поля по доп поля
cf = WorkPackageCustomField.find(:my_field)
options = CustomOption.by_cf(cf)
options = cf.custom_options
# Присвоение конкретного значения доп поля по коду
self.cf_my_field = CustomOption.by_cf(:my_field).where(symbol: 'value_code').first
# Получение значения CustomOption для доп поля задачи
cf_value = self.cf_my_field_option # cf_value: CustomOption
# Работа с множественными полями
add_value = CustomOption.by_cf(:my_field).where(symbol: 'value_code').first
# 1. Добавление значения
self.cf_array_field_add(add_value)
# 2. Удаление значения
self.cf_array_field_remove(add_value)
# 3. Присвоение массива
self.cf_array_field = <array of CustomOption>
Методы
-
<field>_changed? - изменилось ли указанное поле
-
closed? - задача находится на закрывающем статусе
-
blocked? - задача заблокирована другой открытой задачей
-
readonly_status? - задача находится на readonly-статусе
-
overdue? - задача просрочена. ```ruby !due_date.nil? && (due_date < Time.zone.today) && !closed?
-
milestone? / is_milestone? - задача имеет тип milestone (Веха)
-
duration_in_hours(): integer - продолжительность задачи в часах.
-
visible?(user: User = User.current) - Доступна задача для данного/тек. пользователя
-
visible_relations(user: User) - Видимые связи для указанного пользователя
-
add_relation - создание связи
-
work_package.add_relation(to_id: 10, relation_type: 'relates', send_notifications: false, description: 'Description') work_package.add_relation(to: WorkPackage.find(10), relation_type: 'relates')
Методы работы с иерархией задач
- parent: WorkPackage | null - Родительская задача
- children: WorkPackage[] - подзадачи
Фильтры
- visible(user: User = User.current) - выбрать задачи видимые для указанного/текущего пользователя
- in_status(status: Status | integer ) - выбрать задачи находящиеся в указанном статусе
- for_projects(projects: Project[]) - выбрать задачи из указанных проектов
- changed_since(since: DateTime) - выбрать задачи измененные после указанного момента
- with_status_open - выбрать задачи находящиеся на открытом статусе
- with_status_closed - выбрать задачи находящиеся на закрытом статусе
- with_limit(limit: integer) - ограничение выборки
- on_active_project - выбрать задачи из активных проектов
- with_author(author: User) - выбрать задачи, автор которых является указанный пользователь
- without_version - задачи без версии/спринта
Статические методы
- create_perform - создание задачи
Работа со связями между задачами
# добавление
work_package.add_relation(to_id: 10, relation_type: 'relates', send_notifications: false, description: 'Description')
work_package.add_relation(to: WorkPackage.find(10), relation_type: 'relates')
# проверка ошибок
> relation = work_package.add_relation(...)
> relations.errors.any?
> relations.errors.full_messages
# получение и обработка
work_package.relations.count
work_package.relations.visible.count
work_package.relations.blocks.count
work_package.relations.relates.each \{ ... \}
# удаление
work_package.relations.select \{ |r| r.relation_type == 'blocks' \}.each \{ |r| r.destroy \}
TODO - не нашел в коде :
:ancestor_hierarchies, :self_and_ancestors, :descendant_hierarchies,
:self_and_descendants, :root?, :child?, :leaf?, :root, :leaves, :depth, :level, :ancestors,
:ancestor_ids, :self_and_ancestors_ids, :child_ids, :descendants, :self_and_descendant_ids,
:descendant_ids, :self_and_siblings, :siblings, :sibling_ids, :parent_of?, :root_of?,
:ancestor_of?, :descendant_of?, :child_of?, :family_of?, :add_child