Skip to content

Quickstart

This walks through a two-step Purchase Order approval: a Manager signs off first, then Finance. It assumes you've finished Installation.

1. Prepare approver roles

Approval Flows resolves role-based steps through spatie/laravel-permission out of the box. Create the roles and assign them to users:

use Spatie\Permission\Models\Role;

Role::firstOrCreate(['name' => 'manager']);
Role::firstOrCreate(['name' => 'finance']);

$manager->assignRole('manager');
$cfo->assignRole('finance');

Not using spatie/laravel-permission? Assign steps to explicit users instead, or plug in your own resolver — see Approver resolution.

2. Add the trait to your model

use Talivio\ApprovalFlows\Concerns\HasApprovals;

class PurchaseOrder extends Model
{
    use HasApprovals;
}

3. Define the flow and its steps

A flow is bound to a model type via model_type. Steps run in sort_order.

use Talivio\ApprovalFlows\Models\ApprovalFlow;

$flow = ApprovalFlow::create([
    'name' => 'Purchase Order approval',
    'model_type' => \App\Models\PurchaseOrder::class,
    'is_active' => true,
]);

$flow->steps()->create([
    'sort_order' => 0,
    'name' => 'Manager sign-off',
    'approver_type' => 'role',
    'approver_role' => 'manager',
    'mode' => 'any',
]);

$flow->steps()->create([
    'sort_order' => 1,
    'name' => 'Finance sign-off',
    'approver_type' => 'role',
    'approver_role' => 'finance',
    'mode' => 'all', // every finance approver must sign
]);

You can do all of this from the bundled Approval Flows resource in your panel instead of code — the fields map one-to-one.

4. Submit a record

$po = PurchaseOrder::create([/* ... */]);

$po->submitForApproval();

This creates an Approval on the flow's first step and notifies the managers. submitForApproval() records the submitter as the currently authenticated user; pass one explicitly if you're submitting on someone's behalf:

$po->submitForApproval(submitter: $user);

5. Approve from the Inbox

Managers open the Approval Inbox page in the panel and approve. Once any manager signs (mode any), the run advances to the Finance step and notifies finance. Once all finance approvers sign (mode all), the run is approved.

6. React to the result

Listen for completion to run your own side effect:

use Talivio\ApprovalFlows\Events\ApprovalCompleted;

Event::listen(ApprovalCompleted::class, function (ApprovalCompleted $event) {
    $event->approval->approvable->update(['status' => 'approved']);
});

Checking status anywhere

The trait exposes convenient helpers:

$po->approvalStatus();     // ApprovalStatus enum or null
$po->isPendingApproval();  // bool
$po->isApproved();         // bool
$po->latestApproval();     // the most recent Approval model

Next: Defining flows for the full field reference, or Events & hooks to wire up side effects.