From 40da41959bffc677d940c1cd77245a7ddee3af9b Mon Sep 17 00:00:00 2001 From: rocheparadox Date: Sun, 31 Oct 2021 11:26:41 +0530 Subject: [PATCH] Created part.tasks file and moved notify_low_stock function to the same from InvenTree.tasks. The argument type is changed from StockItem to Part Added trans to headers of table in email template of low_stock_notification.html added is_part_low_on_stock() function to the part model to check if the part's stock has fallen below the minimum quantity used offload_task function to run the low stock notification function asynchronously --- InvenTree/InvenTree/tasks.py | 27 ------------- InvenTree/part/models.py | 3 ++ InvenTree/part/tasks.py | 39 +++++++++++++++++++ InvenTree/stock/models.py | 7 +++- .../stock/low_stock_notification.html | 8 ++-- 5 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 InvenTree/part/tasks.py diff --git a/InvenTree/InvenTree/tasks.py b/InvenTree/InvenTree/tasks.py index e623d7a98c..4fa7409326 100644 --- a/InvenTree/InvenTree/tasks.py +++ b/InvenTree/InvenTree/tasks.py @@ -310,30 +310,3 @@ def send_email(subject, body, recipients, from_email=None, html_message=None): fail_silently=False, html_message=html_message ) - - -def notify_low_stock(stock_item): - """ - Notify users who have starred a part when its stock quantity falls below the minimum threshold - """ - - from allauth.account.models import EmailAddress - starred_users = EmailAddress.objects.filter(user__starred_parts__part=stock_item.part) - - if len(starred_users) > 0: - logger.info(f"Notify users regarding low stock of {stock_item.part.name}") - context = { - 'part_name': stock_item.part.name, - # Part url can be used to open the page of part in application from the email. - # It can be facilitated when the application base url is accessible programmatically. - # 'part_url': f'{application_base_url}/part/{stock_item.part.id}', - - # quantity is in decimal field datatype. Since the same datatype is used in models, - # it is not converted to number/integer, - 'part_quantity': stock_item.quantity, - 'minimum_quantity': stock_item.part.minimum_stock - } - subject = _(f'Attention! {stock_item.part.name} is low on stock') - html_message = render_to_string('stock/low_stock_notification.html', context) - recipients = starred_users.values_list('email', flat=True) - send_email(subject, '', recipients, html_message=html_message) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 5cd9fa3180..050b46058a 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -1988,6 +1988,9 @@ class Part(MPTTModel): def related_count(self): return len(self.get_related_parts()) + def is_part_low_on_stock(self): + return self.total_stock <= self.minimum_stock + def attach_file(instance, filename): """ Function for storing a file for a PartAttachment diff --git a/InvenTree/part/tasks.py b/InvenTree/part/tasks.py new file mode 100644 index 0000000000..667e70f1a9 --- /dev/null +++ b/InvenTree/part/tasks.py @@ -0,0 +1,39 @@ +# Author: Roche Christopher +# Created at 10:26 AM on 31/10/21 + +import logging + +from django.utils.translation import ugettext_lazy as _ +from django.template.loader import render_to_string + +from InvenTree import tasks as inventree_tasks +from part.models import Part + +logger = logging.getLogger("inventree") + + +def notify_low_stock(part: Part): + """ + Notify users who have starred a part when its stock quantity falls below the minimum threshold + """ + + from allauth.account.models import EmailAddress + starred_users_email = EmailAddress.objects.filter(user__starred_parts__part=part) + + if len(starred_users_email) > 0: + logger.info(f"Notify users regarding low stock of {part.name}") + context = { + 'part_name': part.name, + # Part url can be used to open the page of part in application from the email. + # It can be facilitated when the application base url is accessible programmatically. + # 'part_url': f'{application_base_url}/part/{stock_item.part.id}', + + # quantity is in decimal field datatype. Since the same datatype is used in models, + # it is not converted to number/integer, + 'part_quantity': part.total_stock, + 'minimum_quantity': part.minimum_stock + } + subject = _(f'Attention! {part.name} is low on stock') + html_message = render_to_string('stock/low_stock_notification.html', context) + recipients = starred_users_email.values_list('email', flat=True) + inventree_tasks.send_email(subject, '', recipients, html_message=html_message) diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index b4746e0879..69b061d25a 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -1659,8 +1659,11 @@ def after_save_stock_item(sender, instance: StockItem, **kwargs): starred the part """ - if instance.quantity <= instance.part.minimum_stock: - inventree_tasks.notify_low_stock(instance) + if instance.part.is_part_low_on_stock(): + inventree_tasks.offload_task( + 'part.tasks.notify_low_stock', + instance.part + ) class StockItemAttachment(InvenTreeAttachment): diff --git a/InvenTree/stock/templates/stock/low_stock_notification.html b/InvenTree/stock/templates/stock/low_stock_notification.html index 04ada64e18..3126cd11c1 100644 --- a/InvenTree/stock/templates/stock/low_stock_notification.html +++ b/InvenTree/stock/templates/stock/low_stock_notification.html @@ -5,13 +5,13 @@ - + - - - + + +
Part low on stock{% trans "Part low on stock" %}
Part NameAvailable QuantityMinimum Quantity{% trans "Part Name" %}{% trans "Available Quantity" %}{% trans "Minimum Quantity" %}