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:
parent
2f4cceaa6a
commit
2f98354f35
4 changed files with 175 additions and 3 deletions
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
122
core/templates/promocode_granted_email.html
Normal file
122
core/templates/promocode_granted_email.html
Normal 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">
|
||||
© {% now "Y" %} {{ project_name }}.
|
||||
{% blocktrans %}all rights reserved{% endblocktrans %}.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue