[Refactor] Notification plugins (#9735)

* Refactor notification concept

- Notifications handled by plugins

* Cleanup

* Only send email if template provided in context

* Logic cleanup

* Fix log_error call

* Refactor error logging

- Ensure plugin slug is correctly attached
- Consistent format
- Logic fixes

* More robust plugin lookup

* Refactor calls to tringger_notification

* Tweak for build stock notification

* Low stock notification refactor

- Actually *use* the notification system
- Fix for email template

* Check stock only when build is issued

* Updated documentation

* Add PluginUserSetting class

- Allows plugins to define per-user settings

* Add API endpoints for PluginUserSetting model

* Placeholder for user-plugin-settings page

* Refactoring frontend code

* Placeholder panel

* Adds user interface for changing user-specific plugin settings

* Tweaks

* Remove old model

* Update documentation

* Playwright tests

* Update API version

* Fix unit test

* Fix removed arg

* Fixes for email notifications

- Track status of sending notifications
- Add helper "activate" method for plugin class
- Update unit tests

* Fix barcode tests

* More unit test fixes

* Test fixes

* Fix for settings models with extra fields

* Enhance unit test

* Remove old test file

* Check for null target_fnc

* Improve DB query efficiency

- Provide a flat list of active keys to plugin.is_active
- Prevents DB fetching (in certain circumstances)
- Add registry.active_plugins() method

* Bump query limit up for test

- In practice, this API endpoint is ~10 queries

* Handle potential errors

* Increase query limit for API test

* Increase query limit for some tests

* Bump API version

* Tweak unit test

* Tweak unit test

* Increased allowed queries

* fix user plugin settings

* Fix for unit test

* Update debug msg

* Tweak API

* Fix endpoint

* Remove "active plugin keys" code

* Restore previous behaviour

* Fix unit tests

* Tweak unit test

* Update src/backend/InvenTree/build/tasks.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/backend/InvenTree/plugin/base/integration/NotificationMixin.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Func updates

* Format

* Add notification settings

* Refactor plugin settings groups

* Fix func type

* Adjust message

* Additional unit tests

* Additional playwright tests

* Additional playwright test

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Oliver
2025-07-26 13:05:59 +10:00
committed by GitHub
co-authored by Copilot Matthias Mair
parent f862867e2b
commit 1085625af4
60 changed files with 1329 additions and 972 deletions
+45
View File
@@ -0,0 +1,45 @@
---
title: Notification Mixin
---
## NotificationMixin
The `NotificationMixin` class provides a plugin with the ability to send notifications to users when certain events occur in the system.
Any notification which is generated by the InvenTree core system can be sent to users via a custom plugin which implements this mixin class.
### send_notification
The `send_notification` method is used to send a notification to users:
::: plugin.base.integration.NotificationMixin.NotificationMixin.send_notification
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
summary: False
members: []
extra:
show_sources: True
### filter_targets
If desired, the plugin can implement the `filter_targets` method to filter the list of users who will receive the notification. This allows for more granular control over which users are notified based on specific criteria.
::: plugin.base.integration.NotificationMixin.NotificationMixin.filter_targets
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
summary: False
members: []
extra:
show_sources: True
## Built-in Notifications
The following built-in notifications plugins are available:
- [UI Notifications](../builtin/ui_notification.md)
- [Email Notifications](../builtin/email_notification.md)
- [Slack Notifications](../builtin/slack_notification.md)
+58 -2
View File
@@ -9,13 +9,69 @@ The *SettingsMixin* allows the plugin to save and load persistent settings to th
- Plugin settings are stored against the individual plugin, and thus do not have to be unique
- Plugin settings are stored using a "key:value" pair
Use the class constant `SETTINGS` for a dict of settings that should be added as global database settings.
## Plugin Settings
Use the class attribute `SETTINGS` for a dict of settings that should be added as global database settings.
The dict must be formatted similar to the following sample that shows how to use validator choices and default.
Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters.
### Example Plugin
### get_setting
Use the `get_setting` method to retrieve a setting value based on the provided key.
::: plugin.base.integration.SettingsMixin.SettingsMixin.get_setting
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
summary: False
members: []
### set_setting
Use the `set_setting` method to set a value for a specific setting key.
::: plugin.base.integration.SettingsMixin.SettingsMixin.set_setting
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
summary: False
members: []
## User Settings
Plugins may also define user-specific settings, which allow users to customize the behavior of the plugin on a per-user basis.
To add user-specific settings, use the `USER_SETTINGS` class attribute in a similar way to the `SETTINGS` attribute.
### get_user_setting
Use the `get_user_setting` method to retrieve a user-specific setting value based on the provided key and user.
::: plugin.base.integration.SettingsMixin.SettingsMixin.get_user_setting
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
summary: False
members: []
### set_user_setting
Use the `set_user_setting` method to set a value for a specific user setting key.
::: plugin.base.integration.SettingsMixin.SettingsMixin.set_user_setting
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
summary: False
members: []
## Example Plugin
Below is a simple example of how a plugin can implement settings: