Перейти к основному содержимому

Простое руководство по рабочему процессу

Создадим действительно простой пример workflow для объектов product.

Создание класса и кастомных отображений (layouts)

Я создал очень простой класс product (sku, локализованное имя, локализованная картинка и локализованное описание, цена и количество).

Пример класса product

Далее я добавил четыре пользовательских макета (custom layouts), которые позже назначу для конкретных статусов.

  • newProduct layout с ID = 1

Custom layout для нового product

  • fillContents layout с ID = 2

Пользовательский макет заполнения содержимого

  • updatePicture layout с ID = 3

Пользовательский макет обновления изображения

  • validateQtyPrice layout с ID = 4

Пользовательский макет валидации количества и цены

Объявление workflow

Теперь создадим базовую конфигурацию в config/config.yaml

pimcore:  
workflows:
workflow:
label: 'Product Workflow'
type: 'state_machine'
supports:
- 'Pimcore\Model\DataObject\Product'
places:
#TODO
transitions:
#TODO

Как видно, workflow называется Product Workflow, пока мы не добавили места (places) и переходы (transitions). Workflow доступен только для экземпляров объектов типа Pimcore\Model\DataObject\Product. Мы используем тип workflow state_machine, поэтому один переход может начинаться из нескольких мест.

Определение мест (places)

Сейчас самое подходящее время определить места для продуктов.

Каких целей я хочу достичь? Предположим, что наши новые продукты интегрируются с внешней системой и новые позиции приходят в Pimcore как пустые объекты только с SKU.

Мне нужно иметь возможность решать, какие продукты будут использоваться в Pimcore, а остальные — отвергать. Чтобы удовлетворить это требование, мне нужно сделать (как минимум) три места.

  • new - для самых новых продуктов
  • rejected - для продуктов, которые я не собираюсь использовать в будущем. Также я хотел бы иметь возможность добавить здесь заметку с причиной.
  • update content - для продуктов, которые я хотел бы публиковать
(...)  
places:
new:
label: 'New product'
color: '#377ea9'
permissions:
- objectLayout: 1
rejected:
label: 'Rejected product'
color: '#28a013'
update_content:
label: 'Update Content'
title: 'Updating content step'
color: '#d9ef36'
permissions:
- objectLayout: 2

(...)

Как видно, я использовал ключ objectLayout, чтобы определить, какой пользовательский макет будет использоваться для статуса new.

Определение первых переходов (transitions)

Как администратор, я могу решить, какой продукт можно обрабатывать, а какой — нет.

Для этого мне нужно добавить некоторые действия (transitions).

  • reject product - чтобы менять статус для продуктов, которые я не хочу использовать
  • start processing - чтобы переместить продукт в шаг обработки
(...)  
transitions:
reject_product:
from: new
to: rejected
options:
label: 'Reject the product'
notes:
commentEnabled: true
commentRequired: true
start_processing:
from: new
to: update_content
options:
label: 'Start processing the product'
(...)

Дополнительные статусы, действия и определения

Добавим ещё 4 места для обновления контента

  • updating the content
  • updating the picture
  • updating the price and stock
  • mark content as a ready - вернуть продукт обратно администратору

Добавим несколько новых строк в конфигурационный файл:

  
(...)
places:
(...)
update_picture:
label: 'Update Product Picture'
title: 'Update the product picture'
color: '#d9ef36'
permissions:
- objectLayout: 3
validate_stock_and_price:
label: 'Validate Stock + Price'
title: 'Check the quantity and the price'
color: '#d9ef36'
permissions:
- objectLayout: 4
content_prepared:
label: 'Content Prepared'
title: 'Content ready to publish'
color: '#28a013'
(...)

transitions:
(...)
content_updated:
from: update_content
to: update_picture
options:
label: 'Content up-to-date'
notes:
commentEnabled: true
commentRequired: false
picture_updated:
from: update_picture
to: validate_stock_and_price
options:
label: 'Picture up-to-date'
notes:
commentEnabled: true
commentRequired: false
content_ready:
from: validate_stock_and_price
to: content_prepared
options:
label: 'Content is ready to publish'
(...)


Последние действия: публикация или откат

На финальной стадии workflow я бы хотел иметь три варианта:

  • Опубликовать продукт (с дополнительным полем "timeWorked")
  • Запустить workflow с начала
  • Отклонить продукт (с заметкой)

Мы уже сделали переходы reject и start_processing; единственное, что нужно — добавить дополнительное место в from для этих переходов. Это возможно, потому что у нас активирован тип workflow = state_machine. Вот изменённые определения переходов:

  
(...)
transitions:
reject_product:
from: [new, content_prepared]
to: rejected
options:
label: 'Reject the product'
notes:
commentEnabled: true
commentRequired: true
start_processing:
from: [new, content_prepared]
to: update_content
options:
label: 'Start processing the product'
notes:
commentEnabled: true
commentRequired: false
(...)

Последнее, что нам нужно — публикация: место accepted и переход publish — доступен только определённой роли.

(...)  
places:
(...)
accepted:
label: 'Accepted product'
color: '#28a013'
(...)

И переход с дополнительным полем "timeWorked":

(...)  
transitions:
(...)
publish:
from: content_prepared
to: accepted
guard: "is_fully_authenticated() and is_granted('ROLE_PIMCORE_ADMIN')"
options:
label: 'Publish the product'
notes:
commentEnabled: true
commentRequired: true
additionalFields:
- name: 'timeWorked'
fieldType: 'input'
title: 'Time Spent'
required: true
(...)

Workflow в действии

Ниже показано, как выглядит workflow, который я только что подготовил.

StatusScreenshot
Начальный статус, когда новый объект попадает в системуНачальное место
Обновление содержимогоОбновление содержимого
Обновление изображенияОбновление изображения
Валидация цены и наличияВалидация
Содержимое готовоСодержимое готово
Публикация продуктаПубликация продукта

Проверка истории

Во вкладке "Notes & Events" содержится список с каждым действием, выполненным над объектом через модуль Workflow.

Notes & Events - заметки workflow


Вы можете предложить улучшение документации или задать вопрос в комментариях.
Если вам нужна полноценная консультация — вы можете заказать её на нашем сайте.