WorkPackage - Задача / Пакет работ

Поля

КлючТипНазвание
idintegerID
created_atDateTimeДата создания
updated_atDateTimeДата обновления
status_updated_atDateTimeДата обновления статуса задачи
subjectstringТема
descriptionstring | nullОписание
schedule_manuallybooleanРучное планирование
ignore_non_working_daysbooleanИгнорирование не рабочих дней при планировании
start_datedate | nullДата начала задачи
due_datedate | nullДата завершения задачи
durationinteger | nullПродолжительность задачи в днях
done_ratiointeger% выполнения задачи
estimated_hoursfloat | nullЗапланированное время выполнения
remaining_hoursfloat | nullОставшееся время
derived_estimated_hoursfloat | null
derived_remaining_hoursfloat | null
story_pointsinteger | nullОценка в SP
external_idstring | nullВнешний ID
type_idintegerТип задачи
project_idintegerПроект
status_idintegerСтатус
status_symsymbolКод статуса
category_idinteger | nullКатегория
priority_idintegerПриоритет
version_idinteger | nullВерсия/Спринт
author_idintegerАвтор
assigned_to_idinteger | nullИсполнитель
responsible_idinteger | nullОтветственный
parent_idinteger | 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