
Oro Workflow
- 4 installs
- 2 repo stars
- Updated July 22, 2026
- netresearch/orocommerce-skill
Helps with automation & workflows tasks.
About
oro-workflow is a Claude Code skill for automation & workflows. It helps solo builders move faster with AI-assisted coding.
- oro-workflow
- Automation & Workflows
- AI-coding skill
Oro Workflow by the numbers
- 4 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #1,780 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/netresearch/orocommerce-skill --skill oro-workflowAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 22, 2026 |
| Repository | netresearch/orocommerce-skill ↗ |
What it does
Helps with automation & workflows tasks.
Files
OroCommerce v6.1 Workflow Configuration Skill
File Locations
- Workflow definitions:
Resources/config/oro/workflows.yml - Operations:
Resources/config/oro/operations.yml
Basic Workflow Structure
Each workflow requires label, entity, start_step, steps, and transitions:
workflows:
document_approval:
label: Document Approval
entity: Acme\Bundle\DemoBundle\Entity\Document
start_step: submitted
steps:
submitted:
label: Submitted
allowed_transitions: [approve, reject]
approved:
label: Approved
allowed_transitions: [publish, reject]
rejected:
label: Rejected
allowed_transitions: [resubmit]
published:
label: Published
transitions:
approve:
label: Approve
step_to: approved
message: Document approved
reject:
label: Reject
step_to: rejected
resubmit:
label: Resubmit
step_to: submitted
publish:
label: Publish
step_to: publishedSteps without allowed_transitions are terminal states. Step names must be unique across all active workflows on the same entity.
Transition Definitions with Conditions and Actions
transition_definitions:
approve_definition:
preconditions:
'@and':
- '@eq': [$is_manager, true]
- '@gte': [$document_priority, 3]
actions:
- '@assign_value': [$approved_at, $.now]
- '@call_method':
object: $entity
method: markApproved
transitions:
approve:
label: Approve
step_to: approved
definition: approve_definitionPreconditions block the transition if false. Actions execute only on success. See references/condition-expressions.md for the full expression list.
Checkout Workflow Customization
Customize checkout by importing and overriding b2b_flow_checkout:
workflows:
custom_checkout:
import:
- workflow: b2b_flow_checkout
label: Custom Checkout
metadata:
is_checkout_workflow: trueCRITICAL: Preserve is_checkout_workflow: true in metadata. Without it, checkout breaks silently. Override individual steps or transitions by redeclaring them under the same key.
Key Pitfalls
1. Step/transition name uniqueness: Names must be unique across ALL active workflows on the same entity type. Use prefixes: document_pending, order_pending.
2. Import path correctness: Reference the original workflow name exactly. Typos silently fail without error.
3. Condition syntax: Conditions use @ prefix for functions and $ prefix for attributes. Missing either causes parsing errors:
- '@eq': [$is_manager, true] # Correct
- 'eq': [$is_manager, true] # Wrong — no @ prefix
- '@eq': [is_manager, true] # Wrong — missing $ prefixSee Also
references/workflow-patterns.md— Attributes, operations, event-triggered transitions, scopes, common patterns, testing/debugging, WorkflowManager APIreferences/condition-expressions.md— Full expression reference- v6.1 notes | v7.0 notes
Workflow Condition and Action Expressions — OroCommerce v6.1
This reference covers all built-in expression functions available in workflow conditions (preconditions, postconditions, condition on transitions) and actions in workflow definitions.
Accessing Data
$attribute_name: Workflow attribute (e.g.,$is_manager,$document_priority)$entity: The entity the workflow is managing$.now: Current datetime$.user: Currently authenticated user$entity.property: Entity property access (uses Symfony PropertyAccess)
Boolean Expressions (Conditions)
Used in preconditions, postconditions, condition on transitions.
@and — Logical AND
All sub-expressions must be true.
'@and':
- '@eq': [$is_manager, true]
- '@gte': [$priority, 3]@or — Logical OR
At least one sub-expression must be true.
'@or':
- '@eq': [$status, pending]
- '@eq': [$status, draft]@not — Logical NOT
Inverts the result of a sub-expression.
'@not':
- '@empty': [$notes]@eq — Equal
'@eq': [$status, approved]
'@eq': [$amount, 100]Compares types strictly. null == 0 is false; use @null for null checks.
@not_eq — Not Equal
'@not_eq': [$status, rejected]@gt — Greater Than
'@gt': [$priority, 2]@gte — Greater Than or Equal
'@gte': [$priority, 3]@lt — Less Than
'@lt': [$priority, 5]@lte — Less Than or Equal
'@lte': [$amount, 1000]@empty — Is Empty
True if value is empty (null, empty string, empty array).
'@empty': [$notes]@not_empty — Is Not Empty
True if value is not empty.
'@not_empty': [$approval_notes]@blank — Is Blank
Similar to @empty but treats whitespace-only strings as blank.
'@blank': [$field]@null — Is Null
True if value is null. Stricter than @empty.
'@null': [$deleted_at]@in — Value In List
True if first value is in the list.
'@in': [$status, [approved, published, archived]]@contains — String or Array Contains
For strings: substring check. For arrays: element check.
'@contains': [$notes, 'urgent']
'@contains': [$tags, admin]Action Expressions
Used under actions: to modify state or trigger side effects.
@assign_value — Assign to Attribute
Set an attribute to a value (can be expression).
- '@assign_value': [$approved_at, $.now]
- '@assign_value': [$approver, $.user]
- '@assign_value': [$status, approved]Attributes must be defined in the workflow's attributes: section.
@unset_value — Remove Attribute
Clear an attribute value (set to null).
- '@unset_value': [$temporary_flag]@call_method — Call Object Method
Invoke a method on an entity or service.
- '@call_method':
object: $entity
method: markApproved
method_parameters: [$.user, $.now]object: Entity or attribute to call method onmethod: Method name (string)method_parameters: List of parameters (positional)
@create_entity — Create and Store Entity
Instantiate and persist a new entity.
- '@create_entity':
class: Acme\Bundle\DemoBundle\Entity\DocumentApproval
attribute: $.approval_record
data:
document: $entity
approver: $.user
approved_at: $.nowclass: Full class name of entity to createattribute: Workflow attribute to store instance in (optional)data: Mapping of entity properties to values
The entity is persisted immediately.
@remove_entity — Delete Entity
Remove entity from database.
- '@remove_entity':
target: $entity@create_datetime — Create DateTime
Create a datetime attribute.
- '@create_datetime':
attribute: $.approval_date
timezone: UTC
datetime: 2025-01-15T10:30:00@format_string — Format String
Format using sprintf-style patterns.
- '@assign_value':
- $formatted_id
- '@format_string':
- 'DOC-%s-%d'
- [$entity.id, $.timestamp]@trans — Translate String
Translate using Symfony translation catalog.
- '@assign_value':
- $message
- '@trans':
id: 'acme.document.approved_message'
domain: 'messages'@fetch_entity — Fetch by ID/Condition
Retrieve entity from database.
- '@fetch_entity':
entity_name: Acme\Bundle\DemoBundle\Entity\Document
where:
id: $parent_document_id
attribute: $.parent@fetch_entities — Fetch Multiple Entities
Retrieve collection of entities.
- '@fetch_entities':
entity_name: Acme\Bundle\DemoBundle\Entity\Document
where:
status: approved
order_by:
created_at: DESC
attribute: $.related_docsCommon Patterns
Check If User Has Role
'@and':
- '@not_empty': [$.user]
- '@contains': [$.user.roles, ROLE_ADMIN]Set Multiple Attributes Conditionally
actions:
- '@if':
conditions:
- '@eq': [$status, approved]
actions:
- '@assign_value': [$approved_at, $.now]
- '@assign_value': [$approver, $.user]Create Related Record
actions:
- '@create_entity':
class: Acme\Bundle\DemoBundle\Entity\Audit
data:
entity: $entity
action: 'approved'
user: $.user
timestamp: $.nowBranch Logic (Conditional Actions)
- '@if':
conditions:
- '@eq': [$priority, high]
actions:
- '@call_method':
object: '@acme_demo.notifier'
method: notifyManager
method_parameters: [$.user]Debugging Expressions
If expressions fail silently:
1. Check attribute names match definitions (case-sensitive) 2. Verify @ and $ prefix presence 3. Use simpler expressions first (@eq before complex @and) 4. Inspect workflow history in UI for execution logs 5. Check application logs for expression parsing errors
Expressions are parsed at workflow load time. Invalid YAML syntax will prevent the workflow from loading at all.
Workflow — v6.1 Notes
Key Changes from v5.1
- Workflow import syntax introduced (allows checkout customization without full redefinition)
- Event-triggered transitions stabilized
- Condition expression functions expanded
- Checkout workflow marked with
is_checkout_workflow: truemetadata
Cache and Loading
Workflows are cached after first load. After modifying workflows.yml:
bin/console cache:clear
bin/console oro:workflow:definitions:loadRun oro:workflow:definitions:load in production as part of deployment.
Known Limitations
1. No workflow inheritance: Cannot extend a workflow without importing (import is override-based) 2. No conditional step visibility: All steps are always visible; hide via UI permissions instead 3. No async actions: Actions execute synchronously during transition; use events for async 4. No rollback: If an action fails, the transition partially completes; use transactions in services
Workflow — v7.0 Notes
v7.0 is not yet released. This file will be updated when v7.0 stabilizes.
Expected Changes
- TBD
Workflow Patterns Reference
Workflow Attributes (Variables)
Attributes persist across steps and enable dynamic data storage during workflow execution. Define under attributes: at workflow root:
workflows:
document_approval:
attributes:
is_manager:
label: Is Manager
type: bool
property_path: entity.isManager
document_priority:
label: Priority
type: integer
property_path: entity.priority
approved_at:
label: Approved At
type: datetime
approval_notes:
label: Approval Notes
type: stringAttributes with property_path map to entity properties. Others are calculated or collected via forms. Attributes are referenced in conditions with $ prefix: $is_manager, $document_priority.
Transition Forms
Collect user input during transitions by adding a form to the transition. The form data becomes available as attributes:
transitions:
reject:
label: Reject
step_to: rejected
form_type: Acme\Bundle\DemoBundle\Form\RejectDocumentType
form_options:
data_class: ~The form type should collect fields that map to attributes defined at workflow root. OroCommerce automatically populates attributes from form submission.
Operations (operations.yml)
Operations define single-action user-triggered buttons or menu items. Place in Resources/config/oro/operations.yml:
operations:
document_bulk_export:
label: Export Documents
entity: Acme\Bundle\DemoBundle\Entity\Document
button_options:
icon: download
actions:
- '@call_method':
object: '@acme_demo.document.exporter'
method: export
method_parameters: [$entity]Operations are useful for one-off actions that don't fit into a workflow. They respect ACL permissions automatically.
Event-Triggered Transitions
Oro does not support an inline trigger: event key in workflow YAML. To trigger transitions programmatically based on events, use a Symfony event listener or subscriber that calls WorkflowManager::transit():
use Oro\Bundle\WorkflowBundle\Model\WorkflowManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AutoApproveSubscriber implements EventSubscriberInterface
{
public function __construct(private WorkflowManager $workflowManager) {}
#[\Override]
public static function getSubscribedEvents(): array
{
return ['oro.workflow.transition.post_transition' => 'onPostTransition'];
}
public function onPostTransition(object $event): void
{
$entity = $event->getWorkflowItem()->getEntity();
if ($entity->getPriority() <= 1) {
$workflowItem = $this->workflowManager->getWorkflowItem($entity);
$this->workflowManager->transit($workflowItem, 'auto_approve_low_priority');
}
}
}Register the subscriber as a tagged service (kernel.event_subscriber).
Workflow Scopes and Activation
Scope determines when a workflow is active. Scopes include default, frontend, and custom. A workflow is active on an entity if: 1. Its entity matches 2. Its scope matches the current context 3. No other active workflow exists on the same entity
workflows:
document_approval:
scopes:
- default # Backend workflow
customer_registration:
scopes:
- frontend # Storefront workflowOnly one workflow per scope per entity can be active. The last loaded workflow wins; order workflows via bundle dependencies.
Common Patterns
Conditional transitions: Use @eq, @and, @or to gate transitions:
transitions:
ship_order:
label: Ship
step_to: shipped
condition:
'@and':
- '@eq': [$payment_received, true]
- '@not_empty': [$tracking_number]Entity creation: Actions can create related entities:
actions:
- '@create_entity':
class: Acme\Bundle\DemoBundle\Entity\DocumentApproval
attribute: $.approval_record
data:
document: $entity
approver: $.user
approved_at: $.nowPHP method calls: Transition actions can invoke entity methods:
actions:
- '@call_method':
object: $entity
method: setApprovedAt
method_parameters: [$.now]Testing and Debugging
Use the OroWorkflow UI in the backend to visualize workflow transitions. For debugging:
- Check
workflow_itemandworkflow_steptables in the database - Use
WorkflowManager::getWorkflowItem()to inspect current state - Enable query logging to see how workflows filter entities
WorkflowManager PHP API
$workflowItem = $this->workflowManager->getWorkflowItem($entity);
if ($workflowItem?->getCurrentStep()?->getName() === 'approved') { ... }Additional Pitfalls
- Form type instantiation: Form types in transitions must be fully qualified class names and instantiable without constructor arguments (or with service injection via DI).
- Query building: Workflows don't filter entities by their step automatically. Use
WorkflowManagerto check step programmatically. - Cache invalidation: After modifying
workflows.yml, clear the cache:
bin/console cache:clear
bin/console oro:workflow:definitions:load