Coverage for src/backend/InvenTree/plugin/builtin/integration/part_notifications.py: 65%
24 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1"""Core set of Notifications as a Plugin."""
3from django.utils.translation import gettext_lazy as _
5import structlog
7import common.notifications
8import InvenTree.helpers_model
9from part.models import Part
10from plugin import InvenTreePlugin
11from plugin.mixins import EventMixin, SettingsMixin
13logger = structlog.get_logger('inventree')
16class PartNotificationsPlugin(SettingsMixin, EventMixin, InvenTreePlugin):
17 """Core notification methods for InvenTree."""
19 NAME = 'PartNotificationsPlugin'
20 TITLE = _('Part Notifications')
21 AUTHOR = _('InvenTree contributors')
22 DESCRIPTION = _('Notify users about part changes')
23 VERSION = '1.0.0'
25 SETTINGS = {
26 'ENABLE_PART_NOTIFICATIONS': {
27 'name': _('Send notifications'),
28 'description': _('Send notifications for part changes to subscribed users'),
29 'default': False,
30 'validator': bool,
31 }
32 }
34 def wants_process_event(self, event):
35 """Return whether given event should be processed or not."""
36 return event.startswith('part_part.')
38 def process_event(self, event, *args, **kwargs):
39 """Custom event processing."""
40 if not self.get_setting('ENABLE_PART_NOTIFICATIONS'):
41 return
42 part = Part.objects.get(pk=kwargs['id'])
43 part_action = event.split('.')[-1]
45 name = _('Changed part notification')
46 common.notifications.trigger_notification(
47 part,
48 'part.notification',
49 target_fnc=part.get_subscribers,
50 check_recent=False,
51 context={
52 'part': part,
53 'name': name,
54 'message': _(
55 f'The part `{part.name}` has been triggered with a `{part_action}` event'
56 ),
57 'link': InvenTree.helpers_model.construct_absolute_url(
58 part.get_absolute_url()
59 ),
60 'template': {
61 'html': 'email/part_event_notification.html',
62 'subject': name,
63 },
64 },
65 )