{"id":35793198,"url":"https://github.com/ringlesoft/laravel-process-approval","last_synced_at":"2026-01-07T09:03:48.429Z","repository":{"id":196947713,"uuid":"695586426","full_name":"ringlesoft/laravel-process-approval","owner":"ringlesoft","description":"Laravel Process Approval is a Laravel package that makes it easy to add approvals to your Laravel application. It allows you to define approval workflows for any model, and it provides a simple and easy-to-use API/UI for managing approvals.","archived":false,"fork":false,"pushed_at":"2025-12-15T08:03:54.000Z","size":321,"stargazers_count":527,"open_issues_count":1,"forks_count":56,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-12-16T10:56:45.152Z","etag":null,"topics":["approval-process","approvals","blade","laravel"],"latest_commit_sha":null,"homepage":"http://ringlesoft.com/packages/laravel-process-approval","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ringlesoft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-23T16:09:55.000Z","updated_at":"2025-12-14T11:58:13.000Z","dependencies_parsed_at":"2023-10-17T11:44:25.177Z","dependency_job_id":"1439bf84-74da-4c11-bbae-614dcf54c010","html_url":"https://github.com/ringlesoft/laravel-process-approval","commit_stats":null,"previous_names":["ringlesoft/laravel-process-approval"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/ringlesoft/laravel-process-approval","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ringlesoft%2Flaravel-process-approval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ringlesoft%2Flaravel-process-approval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ringlesoft%2Flaravel-process-approval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ringlesoft%2Flaravel-process-approval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ringlesoft","download_url":"https://codeload.github.com/ringlesoft/laravel-process-approval/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ringlesoft%2Flaravel-process-approval/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28234214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-07T02:00:05.975Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["approval-process","approvals","blade","laravel"],"created_at":"2026-01-07T09:02:38.415Z","updated_at":"2026-01-07T09:03:48.416Z","avatar_url":"https://github.com/ringlesoft.png","language":"PHP","funding_links":["https://www.buymeacoffee.com/ringunger","https://github.com/sponsors/ringlesoft"],"categories":["PHP"],"sub_categories":[],"readme":"# Laravel Process Approval\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/ringlesoft/laravel-process-approval.svg)](https://packagist.org/packages/ringlesoft/laravel-process-approval)\n[![Total Downloads](https://img.shields.io/packagist/dt/ringlesoft/laravel-process-approval.svg)](https://packagist.org/packages/ringlesoft/laravel-process-approval)\n[![PHP Version Require](https://poser.pugx.org/ringlesoft/laravel-process-approval/require/php)](https://packagist.org/ringlesoft/laravel-process-approval)\n[![Dependents](https://poser.pugx.org/ringlesoft/laravel-process-approval/dependents)](https://packagist.org/packages/ringlesoft/laravel-process-approval)\n***\n## Introduction\n\nThis package enables multi-level approval workflows for Eloquent models in your Laravel application. If you have models\nthat require review and approval from multiple approvers before execution, this package provides a flexible approval\nprocess to meet that need.\n\u003e Laravel 10.0 or later\n\nThe package relies on an existing `Role` management. This can be a custom role management or another package such as\nSpatie's `laravel permissions`.\n\n\u003cimg src=\"https://ringlesoft.com/images/packages/approvals2.png\" alt=\"Approvals Screenshot\" /\u003e\n\n## Installation\n\n#### 1. Install Using composer:\n\n```bash\ncomposer require ringlesoft/laravel-process-approval\n```\n\n#### 2. Publish Files (Optional)\n\nThis package provides publishable files that include configuration, migrations and views. You can publish these files\nusing the following command:\n\n```bash\nphp artisan vendor:publish --provider=\"RingleSoft\\LaravelProcessApproval\\LaravelProcessApprovalServiceProvider\" \n```\n\nYou can publish specific files by providing the ```--tag``` option within the publish command. Available options\nare ```approvals-migrations```, ```approvals-migrations-uuids```, ```approvals-config```, ```approvals-views```, ```approvals-translations```. \u003cbr\u003e For example:\n\n```bash\nphp artisan vendor:publish --provider=\"RingleSoft\\LaravelProcessApproval\\LaravelProcessApprovalServiceProvider\" --tag=\"approvals-migrations\" \n```\n\u003e **Note:** If you run `php artisan process-approval:install`, it will publish the selected migration set for you (bigint by default, UUIDs with `--uuids`).\n\n\n#### UUID Support (Optional)\n\nThis package supports UUID primary keys for all package tables and UUID-based polymorphic relations.\n\nIf you want to use UUIDs, it is recommended to use the `install` command (this publishes the correct migrations and updates\nthe published config):\n\n```bash\nphp artisan process-approval:install --uuids\n```\n\nIf you need to overwrite already published files, you can pass `--force`:\n\n```bash\nphp artisan process-approval:install --uuids --force\n```\n\nIf you prefer to publish migrations manually, a UUID migration tag is also available:\n\n```bash\nphp artisan vendor:publish --provider=\"RingleSoft\\LaravelProcessApproval\\LaravelProcessApprovalServiceProvider\" --tag=\"approvals-migrations-uuids\"\n```\n\n\u003e **Note**: If you manually publish migrations, make sure you set `load_migrations` in the config file to `false` to avoid running migrations twice. Running `process-approval:install` will set this variable to `false` for you.\n\n#### 3. Run migration:\n\nThe package comes with four migration files. Run artisan migrate command before you start using the package.\n\n```bash\nphp artisan migrate\n```\n\n#### 4. Create Approval flows and Steps\n\nThe package relies on Approval flows and steps on your default database. This is to enable multiple approval flows\nwithin the system. You can\nimplement your own way of creating and managing the flows. However, there are available command-line functions to help\nyou get started easily.\n\n##### i. Creating a new flow\n\nTo create a new flow, Run the following command on your terminal.\n\n```bash\n php artisan process-approval:flow add FundRequest\n```\n\n#### ii. Creating a step for the flow\n\n```bash\nphp artisan process-approval:step add  \n```\n\nThis will show a list of available Flows. Select the flow yow want to add steps to and then select the role and approval\naction.\n\n#### iii. Deleting a flow\n\n```bash\nphp artisan process-approval:flow remove  \n```\n\nThis will show a list of available flows. Select the step you want to delete and hit enter.\n\n#### iv. Deleting a step\n\n```bash\nphp artisan process-approval:step remove  \n```\n\nThis will show a list of available steps. Select the step you want to delete and hit enter.\n\n#### v. Listing all flows\n\n```bash\nphp artisan process-approval:flow list  \n```\n\nThis will show a list of all available flows and steps\n\n## Usage\n\n#### 1. Implement `ApprovableModel` on your approvable model\n\n```php\nclass FundRequest extends Model implements ApprovableModel\n{\n\n   // Your model content\n\n}\n```\n\n#### 2. Apply the  `Approvable` trait to the model\n\n```php\nclass FundRequest extends Model implements ApprovableModel\n{\n    use \\RingleSoft\\LaravelProcessApproval\\Traits\\Approvable;\n   // Your model content\n\n}\n```\n\n#### 3. Implement the `onApprovalCompleted()` method.\n\nThis package relies on one callback method in your model to commit the last approval and mark the approval process as\ncompleted. You should implement this method and return `true` to finalize the approval or `false` to roll back the last\napproval. This is useful in the case of performing specific tasks when the approval procedure is completed.\n\n```php\nclass FundRequest extends Model implements ApprovableModel\n{\n    use \\RingleSoft\\LaravelProcessApproval\\Traits\\Approvable;\n   // Your model content\n   \n    public function onApprovalCompleted(ProcessApproval $approval): bool\n    {\n        // Write logic to be executed when the approval process is completed\n        return true;\n    }\n}\n```\n\n#### 4. Place the `\u003cx-ringlesoft-approval-actions\u003e` component on the show page of your model and provide the model instance using the `model` parameter.\n\n```php\n    \u003cx-ringlesoft-approval-actions :model=\"$fundRequest\" /\u003e\n```\n\nCurrently, the UI is implemented using `tailwind`, `bootstrap` or vanilla `css`.\nYou can switch between the frameworks by modifying the `css_library` setting in the configuration file. Additionally, you have\nthe option to publish the views and customize them to meet your specific requirements.\n\n## Configuration\n\nYou can publish the configuration file of this package, `process_approval.php`, and modify the variables to align with\nyour specific requirements. If you wish to publish the files, use the following command:\n\n```bash\nphp artisan vendor:publish --provider=\"RingleSoft\\LaravelProcessApproval\\LaravelProcessApprovalServiceProvider\" --tag=\"approvals-config\"\n```\n\n### Configurable parameters\n\n- `roles_model` - Specify the full class name of the model related to roles table. (default is Spatie's laravel-permissions  (`Spatie\\Permissions\\Models\\Role`))\n- `users_model` - Specify the model that represents the authenticated users. (default is `App\\Models\\User`).\n- `models_path` - Specify the default namespace for models in your application. (default is `App\\Models`).\n- `approval_controller_middlewares` - Specify any middlewares you want to apply to the ApprovalController. (Normally it\n  should be  `['auth']`).\n- `css_library` - Specify the css library for styling the UI component (bootstrap/tailwind). (default\n  is `Tailwind CSS`).\n- `multi_tenancy_field` - Specify the multi-tenancy field in the users table. (default is `tenant_id`)\n- `use_uuids` - Enable UUID support for all package tables and UUID-based polymorphic relations (recommended for fresh installs).\n- `load_migrations` - If true, the package auto-loads vendor migrations. If you publish migrations into your app, make sure set this to `false`.\n\n### Model Submitting\n\nBy default, the model becomes ready for approval when it is marked as \"submitted\". This provides the opportunity for\nediting and other actions on the model before the approval procedure commences. This feature is particularly useful if\nyou wish to keep newly created models hidden from approvers until the creator submits them.\n\nIf you want the model to be auto-submitted upon creation, you can add the following property to the model:\n\n```php\npublic bool $autoSubmit = true;\n```\n\nOr define the method `enableAutoSubmit(): bool` in your model \u003cstrong\u003e(Recommended)\u003c/strong\u003e.\n\n```php\npublic function enableAutoSubmit(): bool\n{\n    // Your logic here\n    return true;\n}\n```\n\nOtherwise, the package will show a submit button on the show page of the model to enable the creator to submit the\nmodel.\n\n### Bypassing Approval Process\n\nIf you want to bypass the approval process for a particular model instance, you can define the method `bypassApprovalProcess(): bool` in your model and return `true`.\n\n```php\npublic function bypassApprovalProcess(): bool\n{\n    // Your logic here\n    return true;\n}\n````\n\n### Pausing Approval process\n\nSometimes you may wish to interrupt the approval procedure by adding your own actions before continuing with approvals.\nYou can pause approvals by adding a `pauseApprovals(): mixed` method to your Approvable Model.\n\n```php\npublic function pauseApprovals() {\n    // Your logic here\n    return true;\n}\n```\n\nIf this method returns true, the approval actions UI will disappear, and you will be able to implement your other\nlogics.\nIf the method returns `'ONLY_ACTIONS'` the existing approvals will be displayed but approval actions will be hidden and\ndisabled.\n\n### Approval Signatures\n\nIf you want to use signatures for users, add the `getSignature()` method to your User model and make it return the\nsignature of the user as image url.\n\n```php\nClass User extends Model {\n    ...\n    \n    public function getSignature(){\n        return $this-\u003esignature_path; // Return the path to user's signature\n    }\n}\n```\n\nIf not specified, the package will display `check` icon for approval and `times` icon for rejection.\n\n### Approval Summary\n\nIf you want to display a summary of the approval process (normally when listing the models) you can use\nthe `\u003cx-ringlesoft-approval-status-summary\u003e` component.\nThis component returns html code with icons representing every approval step: `check` icon representing `Approved`, `times`\nicon representing `Rejected` or `Discarded` and `exclamation` icon representing `Pending`.\n\n## Events\n\nThe package dispatches events during different stages of the approval workflow to allow hooking into the process.\n\n- `ProcessSubmittedEvent` - Dispatched when a new approvable model is submitted.\n- `ProcessApprovedEvent` - Dispatched when an approvable model is approved by an approver.\n- `ProcessRejectedEvent` - Dispatched when an approvable model is rejected by an approver.\n- `ProcessReturnedEvent` - Dispatched when an approvable model is returned back to the previous step by an approver.\n- `ProcessDiscardedEvent` - Dispatched when an approvable model is discarded by an approver.\n- `ProcessApprovalCompletedEvent` - Dispatched when the full approval workflow is completed (approved or discarded).\n- `ApprovalNotificationEvent` - Dispatched during approval actions with a notification message about what happened.\n\n### Showing Notifications\n\nTo display approval notifications, subscribe to the `ApprovalNotificationEvent` event.\n\n#### 1. Create a Listener:\n\nGenerate a listener for the event using artisan command:\n\n```bash\nphp artisan make:listener ApprovalNotificationListener --event=\\\\RingleSoft\\\\LaravelProcessApproval\\\\Events\\\\ApprovalNotificationEvent\n```\n\n#### 2. Implement Listener Logic:\nInside the generated ApprovalNotificationListener class, implement the logic within the `handle()` method. \nThis method will execute whenever the ApprovalNotificationEvent event is triggered. Customize the notification content and delivery method as per your application's requirements.\n\nExample listener implementation:\n\n```php\nclass ApprovalNotificationListener\n{\n    ...\n    /**\n     * Handle the event.\n     */\n    public function handle(ApprovalNotificationEvent $event): void\n    {\n        session()-\u003eflash('success', $event-\u003emessage);\n    }\n}\n```\n\n#### 3. Register Listener:\nRegister the listener in your `EventServiceProvider` class to link the `ApprovalNotificationEvent` event with your `ApprovalNotificationListener`:\n\n```php\nprotected $listen = [\n    ApprovalNotificationEvent::class =\u003e [\n        ApprovalNotificationListener::class,\n    ],\n];\n```\nUse your own approach to display notification from `session()`\n\n\n### Notifying Approvers\nTo notify approvers when a document is awaiting their approval, you can subscribe to the `ProcessSubmittedEvent` and `ProcessApprovedEvent` events and send notifications to them.\n\nHere is an example of how to send notifications to the next approvers within the `ProcessSubmittedListener` listener:\n```php\n    public function handle(ProcessSubmittedEvent $event): void\n    {\n        $nextApprovers = $event-\u003eapprovable-\u003egetNextApprovers();\n        foreach ($nextApprovers as $nextApprover) {\n            $nextApprover-\u003enotify(new AwaitingApprovalNotification($event-\u003eapprovable));\n        }\n    }\n```\n\n\n## Helper Methods\n\nThis package adds multiple helper methods to the approvable models. These include:\n\n### Filters\n\n- `approved()` [Static]: This returns a builder that filters the model entries that are only approved (\n  returns `Illuminate\\Database\\Eloquent\\Builder`)\n  Example:\n    ```php\n        FundRequest::approved()-\u003eget();\n    ```\n- `rejected()` [Static]:This returns a builder that filters the model entries that are only rejected (\n  returns `Illuminate\\Database\\Eloquent\\Builder`)\n  Example:\n    ```php\n        FundRequest::rejected()-\u003eget();\n    ```\n- `discarded()` [Static]:This returns a builder that filters the model entries that are only discarded (\n  returns `Illuminate\\Database\\Eloquent\\Builder`)\n  Example:\n    ```php\n        FundRequest::discarded()-\u003eget();\n    ```\n- `returned()` [Static]:This returns a builder that filters the model entries that are only returned (\n  returns `Illuminate\\Database\\Eloquent\\Builder`)\n  Example:\n    ```php\n        FundRequest::returned()-\u003eget();\n    ```\n\n- `submitted()` [Static]:This returns a builder that filters the model entries that are only submitted (\n  returns `Illuminate\\Database\\Eloquent\\Builder`)\n  Example:\n    ```php\n        FundRequest::submitted()-\u003eget();\n    ```\n  \n### Actions\n- `submit([user: Authenticatable|null = null]): bool|RedirectResponse|ProcessApproval`: Submits the model\n- `approve([comment = null], [user: Authenticatable|null = null]): bool|RedirectResponse|ProcessApproval`: Approves the\n  model\n- `reject([comment = null], [user: Authenticatable|null = null]): bool|ProcessApproval`: Rejects the model\n- `return([comment = null], [user: Authenticatable|null = null]): bool|ProcessApproval`: Returns the model to the previous step\n- `discard([comment = null], [user: Authenticatable|null = null]): bool|ProcessApproval`: Discards the model\n\n\n### Misc\n- `isApprovalCompleted(): bool`: Checks if the approval process for the model is completed\n- `isSubmitted(): bool`: Checks if the model has been submitted\n- `isRejected(): bool`: Checks if the model has been rejected\n- `isDiscarded(): bool`: Checks if the model has been discarded\n- `isReturned(): bool`: Checks if the model has been returned back to the previous step\n- `nextApprovalStep(): null|ProcessApprovalFlowStep`: Returns the next approval step for the model\n- `previousApprovalStep(): null|ProcessApprovalFlowStep`: Returns the previous approval step for the model\n- `canBeApprovedBy(user: Authenticatable|null): bool|null`: Checks if the model can currently be approved by the\n  specified user.\n- `onApprovalCompleted(approval: ProcessApproval): bool`: A callback method to be called when the approval process is\n  completed.\n  This method must be implemented and must return true for the last approval to be successful. Otherwise, the last\n  approval will be rolled back.\n- `getNextApprovers(): Collection`: Returns a list of users that are capable of approving the model at its current step.\n\n#### Relations\n- `approvals(): morphMany` - Returns all approvals of the model\n- `lastApproval(): morphOne` - Returns the last approval (`Models\\ProcessApproval`) of the model\n- `approvalStatus(): morphOne` - Returns the status object (`Models\\ProcessApprovalStatus`) of the model\n\n## Seeding\nIf you want to seed your approval flows to the database, this package provides a static method `makeApprovable(): bool` to create a new approval flow for a model. \nThis method can be used to seed the database with the necessary approval flows and steps for a model. \n\nThe method accepts two parameters:\n\n\n- `$steps`: An array defining the roles to be used as approval steps.\n- `$name`: (optional) The name of the approval flow.\n\n#### Basic usage:\nWhen the first parameter is a flat array of integers, the method creates a new approval flow with the array items as `role_id` and sets `ApprovalTypeEnum::APPROVE` as the default action for each step.\n```php\n    FundRequest::makeApprovable([1,2,3]);\n```\n#### Advanced usage:\n\nWhen the first parameter is an associative array of `[int =\u003e ApprovalTypeEnum, ...]`, the method creates a new approval flow with the array keys (`int`) as `role_id` and the values (`ApprovalTypeEnum`) as the corresponding action.\n```php\n    FundRequest::makeApprovable([\n        1 =\u003e ApprovalTypeEnum::APPROVE,\n        3 =\u003e ApprovalTypeEnum::CHECK\n    ]);\n```\n#### Complex usage:\nWhen the first parameter is an array of arrays, the method creates a new approval flow with steps that accepts `[role_id =\u003e int, action =\u003e ApprovalTypeEnum]` from the sub-arrays. \n```php\n    FundRequest::makeApprovable([\n                [\n                    'role_id' =\u003e 2,\n                    'action' =\u003e ApprovalTypeEnum::CHECK-\u003evalue\n                ],\n                [\n                    'role_id' =\u003e 1,\n                    'action' =\u003e ApprovalTypeEnum::CHECK-\u003evalue\n                ],\n                [\n                    'role_id' =\u003e 1,\n                    'action' =\u003e ApprovalTypeEnum::APPROVE-\u003evalue\n                ]\n            ]\n        );\n```\nThis option enables you to create a flow with multiple steps for the same role, each step having a different action or occurrence.\n\u003e **Note:** If you are using the Laravel's DatabaseSeeder, make sure to remove the `use WithoutModelEvents;` to be able to use the `makeApprovable()` method.\n\n## Multi-Tenancy\nThis package supports multi-tenancy by configuring a column in the users table. You can specify the column name using the `multi_tenancy_field` configuration option. \nWhen the logged-in user is has the `tenant_id` field set, the package will use that value to filter the approval steps.\nWith this you can have one approval flow with different steps for different tenants.\n\n## Testing\nTo test this package, switch to the `tests` branch and run `composer install` to install the dependencies and `vendor/bin/testbench package:test` to run the tests.\n\n## Contributing\nYou are welcome to contribute to this package. Please fork the repository and create a pull request.\n\n## License\n\nLaravel Process Approval is open-source software released under the MIT License.\n\n## Support\n- [Buy me a Coffee](https://www.buymeacoffee.com/ringunger)\n- [Github Sponsors](https://github.com/sponsors/ringlesoft)\n\n## Contacts\n\nFollow me on \u003ca href=\"https://x.com/ringunger\"\u003eX\u003c/a\u003e: \u003ca href=\"https://x.com/ringunger\"\u003e@ringunger\u003c/a\u003e\u003cbr\u003e\nEmail me: \u003ca href=\"mailto:ringunger@gmail.com\"\u003eringunger@gmail.com\u003c/a\u003e\u003cbr\u003e\nWebsite: [https://ringlesoft.com](https://ringlesoft.com/packages/laravel-process-approval)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fringlesoft%2Flaravel-process-approval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fringlesoft%2Flaravel-process-approval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fringlesoft%2Flaravel-process-approval/lists"}