From 5d6a7c79c6df85e78f41ccc94994dc16bc75e79c Mon Sep 17 00:00:00 2001 From: Horilla Date: Mon, 9 Dec 2024 11:12:17 +0530 Subject: [PATCH] [UPDT] HORILLA AUTOMATIONS: Add also sent_to field in mail automation --- horilla_automations/forms.py | 30 +++++++++ horilla_automations/models.py | 16 ++++- horilla_automations/signals.py | 35 +++++++++-- .../horilla_automations/automation_form.html | 63 ++++++++++--------- .../horilla_automations/mail_cc.html | 10 +++ horilla_automations/views/cbvs.py | 1 + horilla_widgets/forms.py | 1 + .../horilla_multiselect_widget.html | 4 +- .../multiselect_components/table.html | 2 +- horilla_widgets/widgets/select_widgets.py | 3 + 10 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 horilla_automations/templates/horilla_automations/mail_cc.html diff --git a/horilla_automations/forms.py b/horilla_automations/forms.py index 7f7872c70..63ad9cc99 100644 --- a/horilla_automations/forms.py +++ b/horilla_automations/forms.py @@ -5,10 +5,15 @@ horilla_automations/forms.py from typing import Any from django import forms +from django.utils.translation import gettext_lazy as _ from base.forms import ModelForm +from employee.filters import EmployeeFilter +from employee.models import Employee from horilla_automations.methods.methods import generate_choices from horilla_automations.models import MODEL_CHOICES, MailAutomation +from horilla_widgets.widgets.horilla_multi_select_field import HorillaMultiSelectField +from horilla_widgets.widgets.select_widgets import HorillaMultiSelectWidget class AutomationForm(ModelForm): @@ -23,6 +28,19 @@ class AutomationForm(ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.fields["also_sent_to"] = HorillaMultiSelectField( + queryset=Employee.objects.all(), + required=False, + widget=HorillaMultiSelectWidget( + filter_route_name="employee-widget-filter", + filter_class=EmployeeFilter, + filter_instance_contex_name="f", + filter_template_path="employee_filters.html", + instance=self.instance, + ), + label="Also Sent to", + help_text=_("The employees selected here will receive the email as Cc."), + ) if not self.data: mail_to = [] @@ -57,6 +75,18 @@ class AutomationForm(ModelForm): model = MailAutomation fields = "__all__" + def clean(self): + cleaned_data = super().clean() + if isinstance(self.fields["also_sent_to"], HorillaMultiSelectField): + self.errors.pop("also_sent_to", None) + + employee_data = self.fields["also_sent_to"].queryset.filter( + id__in=self.data.getlist("also_sent_to") + ) + cleaned_data["also_sent_to"] = employee_data + + return cleaned_data + def save(self, commit: bool = ...) -> Any: self.instance: MailAutomation = self.instance condition_querystring = self.cleaned_data["condition_querystring"] diff --git a/horilla_automations/models.py b/horilla_automations/models.py index 538cb4809..98326fbe8 100644 --- a/horilla_automations/models.py +++ b/horilla_automations/models.py @@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _trans from base.methods import eval_validate from base.models import HorillaMailTemplate +from employee.models import Employee from horilla.models import HorillaModel from horilla_views.cbv_methods import render_template @@ -36,13 +37,20 @@ class MailAutomation(HorillaModel): mail_to = models.TextField(verbose_name="Mail to") mail_details = models.CharField( max_length=250, - help_text="Fill mail template details(reciever/instance, `self` will be the person who trigger the automation)", + help_text=_trans( + "Fill mail template details(reciever/instance, `self` will be the person who trigger the automation)" + ), ) mail_detail_choice = models.TextField(default="", editable=False) trigger = models.CharField(max_length=10, choices=choices) # udpate the on_update logic to if and only if when # changes in the previous and current value mail_template = models.ForeignKey(HorillaMailTemplate, on_delete=models.CASCADE) + also_sent_to = models.ManyToManyField( + Employee, + blank=True, + verbose_name=_trans("Also Send to"), + ) template_attachments = models.ManyToManyField( HorillaMailTemplate, related_name="template_attachment", @@ -89,6 +97,12 @@ class MailAutomation(HorillaModel): "horilla_automations/mail_to.html", {"instance": self, "mappings": mappings} ) + def get_mail_cc_display(self): + employees = self.also_sent_to.all() + return render_template( + "horilla_automations/mail_cc.html", {"employees": employees} + ) + def detailed_url(self): return reverse("automation-detailed-view", kwargs={"pk": self.pk}) diff --git a/horilla_automations/signals.py b/horilla_automations/signals.py index 47b520192..c0d993843 100644 --- a/horilla_automations/signals.py +++ b/horilla_automations/signals.py @@ -40,12 +40,22 @@ def start_automation(): """ Automation signals """ + from base.models import HorillaMailTemplate from horilla_automations.methods.methods import get_model_class, split_query_string from horilla_automations.models import MailAutomation @receiver(post_delete, sender=MailAutomation) @receiver(post_save, sender=MailAutomation) - def automation_pre_create(sender, instance, **kwargs): + def automation_signal(sender, instance, **kwargs): + """ + signal method to handle automation post save + """ + start_connection() + track_previous_instance() + + @receiver(post_delete, sender=HorillaMailTemplate) + @receiver(post_save, sender=HorillaMailTemplate) + def template_signal(sender, instance, **kwargs): """ signal method to handle automation post save """ @@ -81,10 +91,10 @@ def start_automation(): ) previous_bulk_record = getattr(_thread_locals, "previous_bulk_record", None) - previous_queryset = None + previous_queryset_copy = [] if previous_bulk_record: - previous_queryset = previous_bulk_record["queryset"] - previous_queryset_copy = previous_bulk_record["queryset_copy"] + previous_queryset = previous_bulk_record.get("queryset", None) + previous_queryset_copy = previous_bulk_record.get("queryset_copy", []) bulk_thread = threading.Thread( target=_bulk_update_thread_handler, @@ -355,6 +365,19 @@ def send_mail(request, automation, instance): tos = list(filter(None, tos)) to = tos[:1] cc = tos[1:] + try: + also_sent_to = automation.also_sent_to.select_related( + "employee_work_info" + ).all() + + if also_sent_to.exists(): + cc.extend( + str(employee.get_mail()) + for employee in also_sent_to + if employee.get_mail() + ) + except Exception as e: + logger.error(e) email_backend = ConfiguredEmailBackend() display_email_name = email_backend.dynamic_from_email_with_display_name if request: @@ -384,7 +407,9 @@ def send_mail(request, automation, instance): ) template_bdy = template.Template(mail_template.body) - context = template.Context({"instance": mail_to_instance, "self": sender}) + context = template.Context( + {"instance": mail_to_instance, "self": sender, "model_instance": instance} + ) render_bdy = template_bdy.render(context) title_template = template.Template(automation.title) diff --git a/horilla_automations/templates/horilla_automations/automation_form.html b/horilla_automations/templates/horilla_automations/automation_form.html index 37414854c..1efc4d5b7 100644 --- a/horilla_automations/templates/horilla_automations/automation_form.html +++ b/horilla_automations/templates/horilla_automations/automation_form.html @@ -1,32 +1,39 @@
-{% include "generic/horilla_form.html" %} + {% include "generic/horilla_form.html" %} +
diff --git a/horilla_automations/templates/horilla_automations/mail_cc.html b/horilla_automations/templates/horilla_automations/mail_cc.html new file mode 100644 index 000000000..0834bedef --- /dev/null +++ b/horilla_automations/templates/horilla_automations/mail_cc.html @@ -0,0 +1,10 @@ +{% load i18n %} +{% if employees %} +
    + {% for employee in employees %} +
  1. {{employee}}
  2. + {% endfor %} +
+{% else %} + {% trans "Not Added" %} +{% endif %} \ No newline at end of file diff --git a/horilla_automations/views/cbvs.py b/horilla_automations/views/cbvs.py index 152604dc1..5f4a38384 100644 --- a/horilla_automations/views/cbvs.py +++ b/horilla_automations/views/cbvs.py @@ -162,6 +162,7 @@ class AutomationDetailedView(views.HorillaDetailedView): ("Model", "model"), ("Mail Templates", "mail_template"), ("Mail To", "get_mail_to_display"), + ("Mail Cc", "get_mail_cc_display"), ("Trigger", "trigger_display"), ] actions = [ diff --git a/horilla_widgets/forms.py b/horilla_widgets/forms.py index e2020d1fe..f02f21149 100644 --- a/horilla_widgets/forms.py +++ b/horilla_widgets/forms.py @@ -10,6 +10,7 @@ from django import forms from horilla_widgets.widgets.horilla_multi_select_field import HorillaMultiSelectField +orginal_template_name = forms.Select.option_template_name forms.Select.option_template_name = "horilla_widgets/horilla_select_option.html" diff --git a/horilla_widgets/templates/horilla_widgets/horilla_multiselect_widget.html b/horilla_widgets/templates/horilla_widgets/horilla_multiselect_widget.html index 5929e5209..dbbde06b0 100644 --- a/horilla_widgets/templates/horilla_widgets/horilla_multiselect_widget.html +++ b/horilla_widgets/templates/horilla_widgets/horilla_multiselect_widget.html @@ -118,7 +118,7 @@ .select2{ width: 100% !important; } - #slectContainer{{self.attrs.id}} .select2-container .select2-selection{ + #selectContainer{{self.attrs.id}} .select2-container .select2-selection{ padding: 5px !important; max-height: 70px !important; overflow: hidden; @@ -138,7 +138,7 @@ border-radius: 6px; } -
+