Laravel Process Approval

repository·master·Indexed 20 days ago

https://github.com/ringlesoft/laravel-process-approval

A flexible, multi-level approval workflow system for Eloquent models. It enables developers to define custom flows and steps requiring specific roles to approve or reject models. Features include UUID support, multi-tenancy, Blade components for approval actions and status summaries, and a comprehensive set of Artisan commands for managing flows and steps.

Tokens
8.2K
Snippets
32
Records
39
Agent score
68%

What's inside laravel-process-approval

  1. Configure UUID support and migrations

    master

    The package supports UUID primary keys and polymorphic relations. For fresh installs, it is recommended to use the process-approval:install command, which handles publishing migrations and updating the configuration automatically.

    To install with UUID support:

    php artisan process-approval:install --uuids

    If you need to overwrite existing published files, add the --force flag:

    php artisan process-approval:install --uuids --force

    Note: If you choose to publish migrations manually using vendor:publish, you must set load_migrations to false in your process_approval.php config file to prevent duplicate migration attempts.

  2. Control model submission and bypassing

    master

    Auto-submitting models

    By default, models require manual submission. To make a model automatically ready for approval upon creation, define the enableAutoSubmit() method in your model:

    public function enableAutoSubmit(): bool
    {
        return true;
    }

    Alternatively, set public bool $autoSubmit = true;.

    Bypassing approval

    To skip the approval process for a specific instance, implement:

    public function bypassApprovalProcess(): bool
    {
        return true;
    }
  3. Seed approval flows using makeApprovable()

    master

    Use the makeApprovable() static method to define approval flows in your database (e.g., in a Seeder).

    Note: If using DatabaseSeeder, ensure you remove use WithoutModelEvents; so the method can execute.

    Usage Patterns:

    1. Basic (Flat array of role IDs): Creates steps where every role performs the default APPROVE action.
    2. Intermediate (Associative array): Maps role_id to a specific ApprovalTypeEnum action.
    3. Complex (Array of arrays): Allows multiple steps for the same role with different actions (e.g., a 'CHECK' step followed by an 'APPROVE' step for the same role ID).
    // Basic: roles 1, 2, and 3 must approve
    FundRequest::makeApprovable([1, 2, 3]);
    
    // Advanced: role 1 approves, role 3 checks
    FundRequest::makeApprovable([
        1 => ApprovalTypeEnum::APPROVE,
        3 => ApprovalTypeEnum::CHECK
    ]);
    
    // Complex: multiple steps for the same role
    FundRequest::makeApprovable([
        ['role_id' => 2, 'action' => ApprovalTypeEnum::CHECK->value],
        ['role_id' => 1, 'action' => ApprovalTypeEnum::CHECK->value],
        ['role_id' => 1, 'action' => ApprovalTypeEnum::APPROVE->value]
    ]);
  4. Handle approval notifications via events

    master

    The package dispatches ApprovalNotificationEvent whenever an approval action occurs. You can subscribe to this event to show flash messages or notifications to the user.

    1. Generate a listener:
      php artisan make:listener ApprovalNotificationListener --event=\\RingleSoft\\LaravelProcessApproval\\Events\\ApprovalNotificationEvent
    2. Implement the logic in the handle() method:
      public function handle(ApprovalNotificationEvent $event): void
      {
          session()->flash('success', $event->message);
      }
    3. Register the listener in your EventServiceProvider:
      protected $listen = [
          ApprovalNotificationEvent::class => [
              ApprovalNotificationListener::class,
          ],
      ];
    class ApprovalNotificationListener
    {
        /**
         * Handle the event.
         */
        public function handle(ApprovalNotificationEvent $event): void
        {
            session()->flash('success', $event->message);
        }
    }
  5. Make an Eloquent model approvable

    master

    To enable approval workflows on a model, you must implement the ApprovableModel interface and use the Approvable trait.

    You must also implement the onApprovalCompleted(ProcessApproval $approval): bool method. This method is called when the final approval in the sequence is granted. Return true to finalize the process or false to roll back the last approval.

    use RingleSoft\LaravelProcessApproval\Interfaces\ApprovableModel;
    use RingleSoft\LaravelProcessApproval\Traits\Approvable;
    use RingleSoft\LaravelProcessApproval\Models\ProcessApproval;
    
    class FundRequest extends Model implements ApprovableModel
    {
        use Approvable;
    
        public function onApprovalCompleted(ProcessApproval $approval): bool
        {
            // Logic to execute when the entire process is finished
            return true;
        }
    }
  6. Pause the approval process

    master

    You can interrupt the approval workflow by implementing pauseApprovals() in your model:

    • Return true: The approval actions UI disappears entirely. Use this to perform custom logic before allowing approvals to resume.
    • Return 'ONLY_ACTIONS': The existing approvals are displayed, but the action buttons (approve/reject) are hidden and disabled.
    public function pauseApprovals()
    {
        // Return true to hide UI, or 'ONLY_ACTIONS' to disable buttons
        return true;
    }
  7. Configure multi-tenancy for approval flows

    master

    The package supports multi-tenancy by allowing different approval flows for different tenants.

    1. Ensure your users table has a tenant identifier column (e.g., tenant_id).
    2. Configure the multi_tenancy_field option in the package configuration to match your column name.
    3. When a user is logged in, the package uses their tenant_id value to filter and apply the correct approval steps.
  8. Configure process_approval.php parameters

    master

    Publish the configuration file using:

    php artisan vendor:publish --provider="RingleSoft\LaravelProcessApproval\LaravelProcessApprovalServiceProvider" --tag="approvals-config"

    Available configuration keys:

    • roles_model: Full class name of the role model (default: Spatie\Permissions\Models\Role).
    • users_model: Model representing authenticated users (default: App\Models\User).
    • models_path: Default namespace for models (default: App\Models).
    • approval_controller_middlewares: Middlewares for ApprovalController (e.g., ['auth']).
    • css_library: UI styling library (tailwind or bootstrap).
    • multi_tenancy_field: Field in the users table for multi-tenancy (default: tenant_id).
    • use_uuids: Enable UUID support for package tables.
    • load_migrations: If true, package auto-loads vendor migrations. Set to false if you have published migrations manually.
  9. Install the Process Approval package

    master

    Use the process-approval:install command to initialize the package. This command publishes the configuration file, copies the necessary database migrations to your database/migrations directory, and updates your config/process_approval.php file.

    UUID Support

    If your application uses UUIDs for primary keys (specifically for users, roles, and your approvable models), you should use the --uuids flag. If you do not provide this flag, the command will prompt you to confirm whether you want to use UUIDs.

    php artisan process-approval:install
    
    # To use UUIDs for primary keys:
    php artisan process-approval:install --uuids
    
    # To overwrite existing configuration and migrations:
    php artisan process-approval:install --force