|
1 | | -# AApproval |
| 1 | +# AApproval - Laravel Approval Workflow Package |
| 2 | + |
| 3 | +AApproval provides a powerful and flexible approval workflow system for create/update/delete operations in Laravel applications. This package is backend-only and does not include any frontend components. |
| 4 | + |
| 5 | +## 🚀 Features |
| 6 | + |
| 7 | +- **Multi-Step Approval System**: Support for complex approval processes with multiple steps |
| 8 | +- **Flexible Approver Types**: Role, permission, and user-based approval mechanisms |
| 9 | +- **Trait-Based Integration**: Easily integrate with your existing models |
| 10 | +- **Automatic Workflow**: Automatically captures model operations and routes them to approval process |
| 11 | +- **Full Customization**: Define different approval flows for each model |
| 12 | +- **Laravel Authorization Integration**: Compatible with Laravel's existing authorization system |
| 13 | + |
| 14 | +## 📋 Requirements |
| 15 | + |
| 16 | +- PHP 8.1 or higher |
| 17 | +- Laravel 11.0 or higher |
| 18 | +- Spatie Laravel Permission package (recommended) |
| 19 | + |
| 20 | +## 📦 Installation |
| 21 | + |
| 22 | +Install the package via Composer: |
| 23 | + |
| 24 | +```bash |
| 25 | +composer require aurorawebsoftware/aapproval |
| 26 | +``` |
| 27 | + |
| 28 | +Publish the configuration file: |
| 29 | + |
| 30 | +```bash |
| 31 | +php artisan vendor:publish --tag=aapproval-config |
| 32 | +``` |
| 33 | + |
| 34 | +Publish migration files and run them: |
| 35 | + |
| 36 | +```bash |
| 37 | +php artisan vendor:publish --tag=aapproval-migrations |
| 38 | +php artisan migrate |
| 39 | +``` |
| 40 | + |
| 41 | +## ⚙️ Configuration |
| 42 | + |
| 43 | +Define approval flows for each model in `config/approvals.php`: |
| 44 | + |
| 45 | +```php |
| 46 | +<?php |
| 47 | + |
| 48 | +return [ |
| 49 | + 'flows' => [ |
| 50 | + 'App\\Models\\Invoice' => [ |
| 51 | + [ |
| 52 | + 'name' => 'Manager Approval', |
| 53 | + 'type' => 'role', |
| 54 | + 'identifier' => ['manager'] |
| 55 | + ], |
| 56 | + [ |
| 57 | + 'name' => 'Finance Approval', |
| 58 | + 'type' => 'role', |
| 59 | + 'identifier' => ['finance'] |
| 60 | + ], |
| 61 | + [ |
| 62 | + 'name' => 'GM Approval', |
| 63 | + 'type' => 'user', |
| 64 | + 'identifier' => [1] // User IDs |
| 65 | + ], |
| 66 | + ], |
| 67 | + |
| 68 | + 'App\\Models\\PurchaseOrder' => [ |
| 69 | + [ |
| 70 | + 'name' => 'Department Head Approval', |
| 71 | + 'type' => 'permission', |
| 72 | + 'identifier' => ['approve-purchase-orders'] |
| 73 | + ], |
| 74 | + ], |
| 75 | + ], |
| 76 | + |
| 77 | + // Permission name for direct approval bypass |
| 78 | + 'permission_name' => 'approval_direct', |
| 79 | +]; |
| 80 | +``` |
| 81 | + |
| 82 | +### Approver Types |
| 83 | + |
| 84 | +1. **Role Based**: `'type' => 'role'` |
| 85 | + - Uses Spatie Laravel Permission package |
| 86 | + - Specify role names in `identifier` array |
| 87 | + |
| 88 | +2. **Permission Based**: `'type' => 'permission'` |
| 89 | + - Uses Spatie Laravel Permission package |
| 90 | + - Specify permission names in `identifier` array |
| 91 | + |
| 92 | +3. **User Based**: `'type' => 'user'` |
| 93 | + - For specific users |
| 94 | + - Specify user IDs in `identifier` array |
| 95 | + |
| 96 | +### Direct Approval Permission |
| 97 | + |
| 98 | +You can customize the permission name for bypassing approval workflow in the config file. Users with this permission can perform direct operations without going through approval process: |
| 99 | + |
| 100 | +```php |
| 101 | +'permission_name' => 'approval_direct', // or any custom permission name |
| 102 | +``` |
| 103 | + |
| 104 | +## 🔧 Usage |
| 105 | + |
| 106 | +### Adding Trait to Model |
| 107 | + |
| 108 | +Add the `HasApprovals` trait to the model you want to use the approval system with: |
| 109 | + |
| 110 | +```php |
| 111 | +<?php |
| 112 | + |
| 113 | +namespace App\Models; |
| 114 | + |
| 115 | +use Illuminate\Database\Eloquent\Model; |
| 116 | +use Aurorawebsoftware\AApproval\Traits\HasApprovals; |
| 117 | + |
| 118 | +class Invoice extends Model |
| 119 | +{ |
| 120 | + use HasApprovals; |
| 121 | + |
| 122 | + protected $fillable = [ |
| 123 | + 'number', |
| 124 | + 'amount', |
| 125 | + 'description', |
| 126 | + // ... other fields |
| 127 | + ]; |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +### Direct Operation Permission |
| 132 | + |
| 133 | +For some users to perform direct operations bypassing the approval process: |
| 134 | + |
| 135 | +```php |
| 136 | +// Grant general direct approval permission (configured in config file) |
| 137 | +$user->givePermissionTo(config('approvals.permission_name', 'approval_direct')); |
| 138 | + |
| 139 | +// Grant direct approval permission for specific model |
| 140 | +$user->givePermissionTo(config('approvals.permission_name', 'approval_direct') . ':App\\Models\\Invoice'); |
| 141 | +``` |
| 142 | + |
| 143 | +### Managing Approval Requests |
| 144 | + |
| 145 | +```php |
| 146 | +use Aurorawebsoftware\AApproval\Models\ApprovalRequest; |
| 147 | +use Aurorawebsoftware\AApproval\Models\ApprovalStep; |
| 148 | + |
| 149 | +// List pending approval requests |
| 150 | +$pendingRequests = ApprovalRequest::where('status', 'pending')->get(); |
| 151 | + |
| 152 | +// Find steps that a specific user can approve |
| 153 | +$user = auth()->user(); |
| 154 | +$approvableSteps = ApprovalStep::where('status', 'pending') |
| 155 | + ->get() |
| 156 | + ->filter(function ($step) use ($user) { |
| 157 | + return $step->canUserApprove($user); |
| 158 | + }); |
| 159 | + |
| 160 | +// Approve steps |
| 161 | +foreach ($approvableSteps as $step) { |
| 162 | + try { |
| 163 | + $step->approve($user); |
| 164 | + echo "Step approved: " . $step->name; |
| 165 | + } catch (\Exception $e) { |
| 166 | + echo "Approval error: " . $e->getMessage(); |
| 167 | + } |
| 168 | +} |
| 169 | +``` |
| 170 | +## 🎯 Example Scenario |
| 171 | + |
| 172 | +```php |
| 173 | +// 1. Define approval flow for Invoice model (in config/approvals.php) |
| 174 | +'App\\Models\\Invoice' => [ |
| 175 | + ['name' => 'Manager Approval', 'type' => 'role', 'identifier' => ['manager']], |
| 176 | + ['name' => 'Finance Approval', 'type' => 'role', 'identifier' => ['finance']], |
| 177 | +] |
| 178 | + |
| 179 | +// 2. Try to create new invoice |
| 180 | +$invoice = new Invoice(); |
| 181 | +$invoice->number = 'INV-001'; |
| 182 | +$invoice->amount = 5000; |
| 183 | +$invoice->save(); // This enters approval process, invoice is not created yet |
| 184 | + |
| 185 | +// 3. Manager role user approves |
| 186 | +$managerStep = ApprovalStep::where('status', 'pending') |
| 187 | + ->whereHas('approvalRequest', function($q) { |
| 188 | + $q->where('model_type', 'App\\Models\\Invoice'); |
| 189 | + }) |
| 190 | + ->first(); |
| 191 | + |
| 192 | +$managerUser = User::role('manager')->first(); |
| 193 | +$managerStep->approve($managerUser); |
| 194 | + |
| 195 | +// 4. Finance role user approves |
| 196 | +$financeStep = ApprovalStep::where('status', 'pending') |
| 197 | + ->where('approval_request_id', $managerStep->approval_request_id) |
| 198 | + ->first(); |
| 199 | + |
| 200 | +$financeUser = User::role('finance')->first(); |
| 201 | +$financeStep->approve($financeUser); |
| 202 | + |
| 203 | +// 5. After all steps are approved, invoice is automatically created |
| 204 | +``` |
| 205 | + |
| 206 | +## 📄 License |
| 207 | + |
| 208 | +This project is licensed under the MIT License. See [LICENSE](LICENSE.md) file for details. |
| 209 | + |
| 210 | +⭐ Don't forget to star the project if you like it! |
0 commit comments