mirror of
https://github.com/inventree/InvenTree.git
synced 2026-10-14 14:11:55 +00:00
Notify context (#11481)
* Pass extra HTML context through to "notify_responsible" * Supply additional context * Update template * Add unit test for email template --------- Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
1 parent
de962f5144
commit
31bc5a043c
4 files changed
+96
-3
No files matched your search
@@ -345,6 +345,7 @@ def notify_responsible(
|
||||
instance,
|
||||
sender,
|
||||
content: NotificationBody = InvenTreeNotificationBodies.NewOrder,
|
||||
html_context: Optional[dict] = None,
|
||||
exclude=None,
|
||||
extra_users: Optional[list] = None,
|
||||
):
|
||||
@@ -357,6 +358,7 @@ def notify_responsible(
|
||||
instance: The newly created instance
|
||||
sender: Sender model reference
|
||||
content (NotificationBody, optional): _description_. Defaults to InvenTreeNotificationBodies.NewOrder.
|
||||
html_context: Optional HTML context to include in the notification. Defaults to None.
|
||||
exclude (User, optional): User instance that should be excluded. Defaults to None.
|
||||
extra_users (list, optional): List of extra users to notify. Defaults to None.
|
||||
"""
|
||||
@@ -370,7 +372,14 @@ def notify_responsible(
|
||||
if extra_users:
|
||||
users.extend(extra_users)
|
||||
|
||||
notify_users(users, instance, sender, content=content, exclude=exclude)
|
||||
notify_users(
|
||||
users,
|
||||
instance,
|
||||
sender,
|
||||
content=content,
|
||||
html_context=html_context,
|
||||
exclude=exclude,
|
||||
)
|
||||
|
||||
|
||||
def notify_users(
|
||||
@@ -378,6 +387,7 @@ def notify_users(
|
||||
instance,
|
||||
sender,
|
||||
content: NotificationBody = InvenTreeNotificationBodies.NewOrder,
|
||||
html_context: Optional[dict] = None,
|
||||
exclude=None,
|
||||
):
|
||||
"""Notify all passed users or groups.
|
||||
@@ -390,6 +400,7 @@ def notify_users(
|
||||
instance: The newly created instance
|
||||
sender: Sender model reference
|
||||
content (NotificationBody, optional): _description_. Defaults to InvenTreeNotificationBodies.NewOrder.
|
||||
html_context (dict, optional): Optional HTML context to include in the notification. Defaults to None.
|
||||
exclude (User, optional): User instance that should be excluded. Defaults to None.
|
||||
"""
|
||||
# Setup context for notification parsing
|
||||
@@ -401,7 +412,9 @@ def notify_users(
|
||||
}
|
||||
|
||||
# Setup notification context
|
||||
# Extra HTML context is included, but cannot override the standard keys
|
||||
context = {
|
||||
**(html_context or {}),
|
||||
'instance': instance,
|
||||
'name': content.name.format(**content_context),
|
||||
'message': content.message.format(**content_context),
|
||||
@@ -409,8 +422,7 @@ def notify_users(
|
||||
'template': {'subject': content.name.format(**content_context)},
|
||||
}
|
||||
|
||||
tmp = content.template
|
||||
if tmp:
|
||||
if tmp := content.template:
|
||||
context['template']['html'] = tmp.format(**content_context)
|
||||
|
||||
# Create notification
|
||||
|
||||
@@ -1322,6 +1322,7 @@ class PurchaseOrder(TotalPriceMixin, Order):
|
||||
PurchaseOrder,
|
||||
exclude=user,
|
||||
content=InvenTreeNotificationBodies.ItemsReceived,
|
||||
html_context={'order': self, 'stock_items': stock_items},
|
||||
extra_users=notify_users,
|
||||
)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from decimal import Decimal
|
||||
import django.core.exceptions as django_exceptions
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core import mail
|
||||
from django.test import TestCase
|
||||
|
||||
from djmoney.money import Money
|
||||
@@ -22,6 +23,7 @@ from InvenTree.unit_test import (
|
||||
)
|
||||
from order.status_codes import PurchaseOrderStatus
|
||||
from part.models import Part
|
||||
from plugin import registry
|
||||
from stock.models import StockItem, StockLocation
|
||||
from users.models import Owner
|
||||
|
||||
@@ -556,6 +558,68 @@ class OrderTest(ExchangeRateMixin, PluginRegistryMixin, TestCase):
|
||||
# However *no* notification should have been generated for the creating user
|
||||
self.assertFalse(messages.filter(user__pk=3).exists())
|
||||
|
||||
def test_received_email_notification(self):
|
||||
"""Test the email notification sent when items are received against a PurchaseOrder.
|
||||
|
||||
- The responsible user should receive an email
|
||||
- The email should list the received stock items
|
||||
"""
|
||||
user = get_user_model().objects.get(pk=4)
|
||||
user.email = 'sam@demo.inventree.org'
|
||||
user.save()
|
||||
|
||||
# Enable email notifications for the responsible user
|
||||
plugin = registry.get_plugin('inventree-email-notification')
|
||||
self.assertIsNotNone(plugin)
|
||||
plugin.set_user_setting('NOTIFY_BY_EMAIL', True, user)
|
||||
|
||||
po = PurchaseOrder.objects.get(pk=1)
|
||||
po.responsible = Owner.create(obj=user)
|
||||
po.save()
|
||||
po.place_order()
|
||||
|
||||
# Ignore any emails sent when the order was placed
|
||||
common.models.NotificationEntry.objects.all().delete()
|
||||
mail.outbox.clear()
|
||||
|
||||
location = StockLocation.objects.get(pk=1)
|
||||
line_1 = PurchaseOrderLineItem.objects.get(pk=1)
|
||||
line_2 = PurchaseOrderLineItem.objects.get(pk=3)
|
||||
|
||||
stock_items = po.receive_line_items(
|
||||
location,
|
||||
[
|
||||
{'line_item': line_1, 'quantity': 15},
|
||||
{'line_item': line_2, 'quantity': 37},
|
||||
],
|
||||
user=get_user_model().objects.get(pk=1),
|
||||
)
|
||||
|
||||
self.assertEqual(stock_items.count(), 2)
|
||||
|
||||
# Exactly one email should have been sent, to the responsible user
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
email = mail.outbox[0]
|
||||
|
||||
self.assertEqual(email.to, [user.email])
|
||||
self.assertIn('Items Received', email.subject)
|
||||
|
||||
html = email.alternatives[0][0]
|
||||
|
||||
# Order information
|
||||
self.assertIn('Items have been received against a purchase order', html)
|
||||
self.assertIn(po.get_absolute_url(), html)
|
||||
|
||||
# Table of received items
|
||||
self.assertIn('<th>Part</th>', html)
|
||||
self.assertIn('<th>Quantity</th>', html)
|
||||
self.assertIn('<th>Location</th>', html)
|
||||
|
||||
for item in stock_items:
|
||||
self.assertIn(f'<td>{item.part.name}</td>', html)
|
||||
self.assertIn(f'<td>{item.quantity}</td>', html)
|
||||
self.assertIn(f'<td>{item.location.pathstring}</td>', html)
|
||||
|
||||
def test_metadata(self):
|
||||
"""Unit tests for the metadata field."""
|
||||
for model in [PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderExtraLine]:
|
||||
|
||||
@@ -9,3 +9,19 @@
|
||||
<p>{% trans "Click on the following link to view this order" %}: <a href='{{ link }}'>{{ link }}</a></p>
|
||||
{% endif %}
|
||||
{% endblock title %}
|
||||
|
||||
{% block body %}
|
||||
<tr style="height: 3rem; border-bottom: 1px solid">
|
||||
<th>{% trans "Part" %}</th>
|
||||
<th>{% trans "Quantity" %}</th>
|
||||
<th>{% trans "Location" %}</th>
|
||||
</tr>
|
||||
|
||||
{% for item in stock_items %}
|
||||
<tr>
|
||||
<td>{{ item.part.name }}</td>
|
||||
<td>{{ item.quantity }}</td>
|
||||
<td>{{ item.location.pathstring }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endblock body %}
|
||||
Reference in new issue
Block a user