Tasks and inbox
Tasks tell people that something waits for them. Workflows create them when a record enters a state; applications can assign their own. Everybody sees their open tasks in the inbox.
- Candidates of a task are the users who may complete it. They are resolved from the actors when the task is created; four eyes excludes people before they ever see the task. API clients are never candidates.
- New tasks are notified to their candidates (after the commit), with a link to the record.
- Tasks belong to the current tenant.
Decisions
Section titled “Decisions”When a record enters a state, the actors of the transitions out of the state get one task, e.g. “Decide: PO-17 (Submitted)”. It links to the record, where the transitions are run; leaving the state completes it with the transition that ran.
State::make('draft')->inbox(false): no decision for this state (the default for the initial and final states).Transition::make('cancel')->inbox(false): the actors of this transition are not asked, e.g. the requester who may only withdraw their request.- Optional transitions switched off by the tenant do not count.
Tasks defined on a state (several approvals in parallel) are described in Tasks in parallel.
The page inbox is part of Access::pages():
public function pages(): array{ return [Dashboard::class, ...Access::pages()];}- Every logged in user of the panel may open it. It appears at the top of the navigation when a resource of the panel has workflows or the user has tasks, with the number of open tasks as badge.
- Open tasks are listed with the earliest due date first; overdue tasks are marked.
- Take over marks who works on a task; the other candidates see it as taken and cannot complete it until it is given back.
- Complete with an outcome, the fields of the task and a comment (up to 2000 characters). Decisions have no outcome buttons: they open the record.
- Every action checks again that the user is a candidate of the open task.
- A released configuration of the tenant assigns open tasks again (e.g. a new approver gets the open decisions).
Tasks of applications
Section titled “Tasks of applications”$uuid = service('tasks')->assign( 'Check the contract', [$userId], description: 'Contract 2026-17 expires next month.', link: '/admin/contracts/…', dueDays: 3, outcomes: ['renew' => 'Renew', 'end' => 'Let it end'],);Users are internal ids in the current tenant; without outcomes the task has one outcome “Done”. The link must be a path of the application. Completing such a task only records the outcome; react to it in your application where needed.
In code
Section titled “In code”Method of service('tasks') |
Purpose |
|---|---|
assign($title, $users, …) |
creates a task of the application |
inbox($userId) |
open tasks of the user |
countFor($userId) |
number of open tasks |
find($uuid) |
one task |
forRecord($subject, $recordId) |
tasks of a record (table name and internal id) |
claim($uuid, $userId), release($uuid, $userId) |
take over, give back |
complete($uuid, $userId, $outcome, $input, $comment) |
complete; tasks of workflows run the workflow checks and automatic transitions |
Refusals throw Anvil\Tasks\TaskException with $reason: not_found,
not_candidate, claimed, closed, outcome, decision, four_eyes,
validation (with $errors).
Reminders
Section titled “Reminders”php spark anvil:tick (every minute) reminds the candidates of tasks
whose due date has passed, once per task and in all tenants. Workflow
durations and deadlines are processed by the same
command.
Completing a task writes task.completed with the outcome; the comment
and the form data are stored with the task.