Features: 1) Add slug field to BrandFilter with filtering and ordering support; 2) Implement send_promocode_created_email task using a new email template; 3) Create signal to notify users upon promocode creation.

Fixes: None;

Extra: Refactor imports in `signals.py` and `emailing.py`; Add formatting and responsive styles for email template.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-09-09 16:27:04 +03:00
parent 2f4cceaa6a
commit 2f98354f35
4 changed files with 175 additions and 3 deletions

View file

@ -473,12 +473,14 @@ class CategoryFilter(FilterSet):
class BrandFilter(FilterSet):
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
name = CharFilter(method="filter_name", label=_("Name"))
slug = CharFilter(field_name="slug", lookup_expr="exact", label=_("Slug"))
categories = CaseInsensitiveListFilter(field_name="categories__uuid", lookup_expr="exact", label=_("Categories"))
order_by = OrderingFilter(
fields=(
("priority", "priority"),
("uuid", "uuid"),
("slug", "slug"),
("name", "name"),
("?", "random"),
)
@ -486,7 +488,7 @@ class BrandFilter(FilterSet):
class Meta:
model = Brand
fields = ["uuid", "name"]
fields = ["uuid", "name", "slug", "priority"]
def filter_name(self, queryset, _name, value):
search_results = process_query(query=value, request=self.request)["brands"]

View file

@ -18,7 +18,7 @@ from core.utils import (
generate_human_readable_id,
resolve_translations_for_elasticsearch,
)
from core.utils.emailing import send_order_created_email, send_order_finished_email
from core.utils.emailing import send_order_created_email, send_order_finished_email, send_promocode_created_email
from evibes.utils.misc import create_object
from vibes_auth.models import User
@ -155,3 +155,9 @@ def update_category_name_lang(instance, created, **_kwargs):
pass
resolve_translations_for_elasticsearch(instance, "name")
resolve_translations_for_elasticsearch(instance, "description")
@receiver(post_save, sender=PromoCode)
def send_promocode_creation_email(instance, created, **_kwargs):
if created:
send_promocode_created_email.delay(instance.uuid)

View file

@ -0,0 +1,122 @@
{% load tz static i18n filters conditions %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% blocktrans %}promocode granted{% endblocktrans %}</title>
<style>
* {
box-sizing: border-box;
}
body, table, td, a {
text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
table {
}
body {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
}
img {
max-width: 100%;
height: auto;
}
.email-container {
max-width: 600px;
margin: 0 auto;
}
.content-cell {
border: 3px solid #000000;
padding: 20px;
font-family: Arial, sans-serif;
}
.header {
background-color: #000000;
padding: 20px;
text-align: center;
}
.header img {
width: 120px;
height: auto;
}
.footer {
background-color: #000000;
padding: 10px;
text-align: center;
font-size: 12px;
color: #888;
}
.order-table {
width: 100%;
margin-top: 20px;
border-collapse: collapse;
}
.order-table th, .order-table td {
border: 1px solid #ddd;
padding: 8px;
}
.order-table th {
background-color: #f4f4f4;
}
@media only screen and (max-width: 600px) {
.email-container {
width: 100% !important;
}
}
</style>
<link rel="icon" href="{% static 'favicon.png' %}" sizes="192x192">
</head>
<body>
<table>
<tr>
<td>
<table class="email-container">
<tr>
<td class="header">
<img src="{% static 'logo.png' %}"
alt="{% blocktrans %}logo{% endblocktrans %}" width="120">
</td>
</tr>
<tr>
<td class="content-cell">
<h2>{% blocktrans %}promocode granted{% endblocktrans %}</h2>
<p>{% blocktrans %}hello {{ user_first_name }},{% endblocktrans %}</p>
<p>{% blocktrans %}Thank you for staying with us! We have granted you with a promocode
for {% endblocktrans %}{% if promocode.discount_type == "amount" %}
{{ promocode.discount_amount }}{{ currency }}{% else %}{{ promocode.discount_percent }}
%{% endif %}</p>
<p>{% blocktrans %}if you have any questions, feel free to contact our support at
{{ contact_email }}.{% endblocktrans %}</p>
<p>{% blocktrans %}best regards,<br>the {{ project_name }} team{% endblocktrans %}</p>
</td>
</tr>
<tr>
<td class="footer">
&copy; {% now "Y" %} {{ project_name }}.
{% blocktrans %}all rights reserved{% endblocktrans %}.
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

View file

@ -3,13 +3,14 @@ from datetime import datetime
from celery.app import shared_task
from celery.utils.log import get_task_logger
from constance import config
from django.conf import settings
from django.core import mail
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
from django.utils.translation import activate
from django.utils.translation import gettext_lazy as _
from core.models import Order, OrderProduct
from core.models import Order, OrderProduct, PromoCode
from core.utils.constance import set_email_settings
logger = get_task_logger(__name__)
@ -165,3 +166,44 @@ def send_order_finished_email(order_pk: str) -> tuple[bool, str]:
send_thank_you_email(shipped_ops)
return True, str(order.uuid)
@shared_task(queue="default")
def send_promocode_created_email(promocode_pk: str) -> tuple[bool, str]:
try:
promocode = PromoCode.objects.get(pk=promocode_pk)
except PromoCode.DoesNotExist:
return False, f"Promocode not found with the given pk: {promocode_pk}"
if not promocode.user:
return True, "The promocode has no user"
activate(promocode.user.language)
set_email_settings()
connection = mail.get_connection()
email = EmailMessage(
_(f"{config.PROJECT_NAME} | promocode granted"),
render_to_string(
template_name="promocode_granted_email.html",
context={
"promocode": promocode,
"user_first_name": "" or promocode.user.first_name,
"project_name": config.PROJECT_NAME,
"contact_email": config.EMAIL_FROM,
"today": datetime.today(),
"currency": settings.CURRENCY_CODE,
},
),
to=[promocode.user.email],
from_email=f"{config.PROJECT_NAME} <{config.EMAIL_FROM}>",
connection=connection,
)
email.content_subtype = "html"
result = email.send()
logger.debug(
"Promocode %s: Tried to send email to %s, resulted with %s", promocode.pk, promocode.user.email, result
)
return True, str(promocode.uuid)