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.