Add order status email notifications and templates
Introduces email notifications for order status changes (created, cancelled, completed, paid, missing payment, refund events) and adds corresponding HTML email templates. Refactors notification tasks to use only the order object and updates model logic to trigger notifications on relevant status changes.
This commit is contained in:
@@ -270,6 +270,15 @@ class Order(models.Model):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
is_new = self.pk is None
|
is_new = self.pk is None
|
||||||
|
old_status = None
|
||||||
|
|
||||||
|
# Track old status for change detection
|
||||||
|
if not is_new:
|
||||||
|
try:
|
||||||
|
old_instance = Order.objects.get(pk=self.pk)
|
||||||
|
old_status = old_instance.status
|
||||||
|
except Order.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
# CRITICAL: Set currency from site configuration ONLY at creation time
|
# CRITICAL: Set currency from site configuration ONLY at creation time
|
||||||
# Once set, currency should NEVER change to maintain order integrity
|
# Once set, currency should NEVER change to maintain order integrity
|
||||||
@@ -285,9 +294,19 @@ class Order(models.Model):
|
|||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
# Send email notification for new orders
|
# Send email notification for new orders
|
||||||
if is_new and self.user:
|
if is_new:
|
||||||
from .tasks import notify_order_successfuly_created
|
from .tasks import notify_order_successfuly_created
|
||||||
notify_order_successfuly_created.delay(order=self, user=self.user)
|
notify_order_successfuly_created.delay(order=self)
|
||||||
|
|
||||||
|
# Send email notification when status changes to CANCELLED
|
||||||
|
if not is_new and old_status != self.OrderStatus.CANCELLED and self.status == self.OrderStatus.CANCELLED:
|
||||||
|
from .tasks import notify_order_cancelled
|
||||||
|
notify_order_cancelled.delay(order=self)
|
||||||
|
|
||||||
|
# Send email notification when status changes to COMPLETED
|
||||||
|
if not is_new and old_status != self.OrderStatus.COMPLETED and self.status == self.OrderStatus.COMPLETED:
|
||||||
|
from .tasks import notify_order_completed
|
||||||
|
notify_order_completed.delay(order=self)
|
||||||
|
|
||||||
def cancel_order(self):
|
def cancel_order(self):
|
||||||
"""Cancel the order if possible"""
|
"""Cancel the order if possible"""
|
||||||
@@ -352,7 +371,7 @@ class Carrier(models.Model):
|
|||||||
self.shipping_method == self.SHIPPING.STORE):
|
self.shipping_method == self.SHIPPING.STORE):
|
||||||
|
|
||||||
if hasattr(self, 'order') and self.order:
|
if hasattr(self, 'order') and self.order:
|
||||||
notify_Ready_to_pickup.delay(order=self.order, user=self.order.user)
|
notify_Ready_to_pickup.delay(order=self.order)
|
||||||
|
|
||||||
def get_price(self, order=None):
|
def get_price(self, order=None):
|
||||||
if self.shipping_method == self.SHIPPING.ZASILKOVNA:
|
if self.shipping_method == self.SHIPPING.ZASILKOVNA:
|
||||||
@@ -381,7 +400,7 @@ class Carrier(models.Model):
|
|||||||
self.returning = False
|
self.returning = False
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
notify_zasilkovna_sended.delay(order=self.order, user=self.order.user)
|
notify_zasilkovna_sended.delay(order=self.order)
|
||||||
|
|
||||||
elif self.shipping_method == self.SHIPPING.DEUTSCHEPOST:
|
elif self.shipping_method == self.SHIPPING.DEUTSCHEPOST:
|
||||||
# Import here to avoid circular imports
|
# Import here to avoid circular imports
|
||||||
@@ -400,7 +419,7 @@ class Carrier(models.Model):
|
|||||||
self.state = self.STATE.READY_TO_PICKUP
|
self.state = self.STATE.READY_TO_PICKUP
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
notify_Ready_to_pickup.delay(order=self.order, user=self.order.user)
|
notify_Ready_to_pickup.delay(order=self.order)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValidationError("Tato metoda dopravy nepodporuje objednání přepravy.")
|
raise ValidationError("Tato metoda dopravy nepodporuje objednání přepravy.")
|
||||||
@@ -707,7 +726,7 @@ class Refund(models.Model):
|
|||||||
self.order.save(update_fields=["status", "updated_at"])
|
self.order.save(update_fields=["status", "updated_at"])
|
||||||
|
|
||||||
|
|
||||||
notify_refund_accepted.delay(order=self.order, user=self.order.user)
|
notify_refund_accepted.delay(order=self.order)
|
||||||
|
|
||||||
|
|
||||||
def generate_refund_pdf_for_customer(self):
|
def generate_refund_pdf_for_customer(self):
|
||||||
|
|||||||
@@ -22,147 +22,161 @@ def delete_expired_orders():
|
|||||||
|
|
||||||
# Zásilkovna
|
# Zásilkovna
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_zasilkovna_sended(order = None, user = None, **kwargs):
|
def notify_zasilkovna_sended(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_order_sended:", kwargs)
|
print("Additional kwargs received in notify_zasilkovna_sended:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Your order has been shipped",
|
subject="Your order has been shipped",
|
||||||
template_path="email/order_sended.html",
|
template_path="email/shipping/zasilkovna/zasilkovna_sended.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Shop
|
# Shop
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_Ready_to_pickup(order = None, user = None, **kwargs):
|
def notify_Ready_to_pickup(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_order_sended:", kwargs)
|
print("Additional kwargs received in notify_Ready_to_pickup:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Your order is ready for pickup",
|
subject="Your order is ready for pickup",
|
||||||
template_path="email/order_ready_pickup.html",
|
template_path="email/shipping/ready_to_pickup/ready_to_pickup.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# -- NOTIFICATIONS ORDER --
|
# -- NOTIFICATIONS ORDER --
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_order_successfuly_created(order = None, user = None, **kwargs):
|
def notify_order_successfuly_created(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_order_successfuly_created:", kwargs)
|
print("Additional kwargs received in notify_order_successfuly_created:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Your order has been successfully created",
|
subject="Your order has been successfully created",
|
||||||
template_path="email/order_created.html",
|
template_path="email/order_created.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_order_payed(order = None, user = None, **kwargs):
|
def notify_order_payed(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_order_paid:", kwargs)
|
print("Additional kwargs received in notify_order_payed:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Your order has been paid",
|
subject="Your order has been paid",
|
||||||
template_path="email/order_paid.html",
|
template_path="email/order_paid.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_about_missing_payment(order = None, user = None, **kwargs):
|
def notify_about_missing_payment(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_about_missing_payment:", kwargs)
|
print("Additional kwargs received in notify_about_missing_payment:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Payment missing for your order",
|
subject="Payment missing for your order",
|
||||||
template_path="email/order_missing_payment.html",
|
template_path="email/order_missing_payment.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# -- NOTIFICATIONS REFUND --
|
# -- NOTIFICATIONS REFUND --
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_refund_items_arrived(order = None, user = None, **kwargs):
|
def notify_refund_items_arrived(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_refund_items_arrived:", kwargs)
|
print("Additional kwargs received in notify_refund_items_arrived:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Your refund items have arrived",
|
subject="Your refund items have arrived",
|
||||||
template_path="email/order_refund_items_arrived.html",
|
template_path="email/order_refund_items_arrived.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Refund accepted, retuning money
|
# Refund accepted, returning money
|
||||||
@shared_task
|
@shared_task
|
||||||
def notify_refund_accepted(order = None, user = None, **kwargs):
|
def notify_refund_accepted(order = None, **kwargs):
|
||||||
if not order or not user:
|
if not order:
|
||||||
raise ValueError("Order and User must be provided for notification.")
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
if kwargs:
|
if kwargs:
|
||||||
print("Additional kwargs received in notify_refund_accepted:", kwargs)
|
print("Additional kwargs received in notify_refund_accepted:", kwargs)
|
||||||
|
|
||||||
send_email_with_context(
|
send_email_with_context(
|
||||||
recipients=user.email,
|
recipients=order.email,
|
||||||
subject="Your refund has been accepted",
|
subject="Your refund has been accepted",
|
||||||
template_path="email/order_refund_accepted.html",
|
template_path="email/order_refund_accepted.html",
|
||||||
context={
|
context={
|
||||||
"user": user,
|
|
||||||
"order": order,
|
"order": order,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# -- NOTIFICATIONS ORDER STATUS --
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def notify_order_cancelled(order = None, **kwargs):
|
||||||
|
if not order:
|
||||||
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
pass
|
if kwargs:
|
||||||
|
print("Additional kwargs received in notify_order_cancelled:", kwargs)
|
||||||
|
|
||||||
|
send_email_with_context(
|
||||||
|
recipients=order.email,
|
||||||
|
subject="Your order has been cancelled",
|
||||||
|
template_path="email/order_cancelled.html",
|
||||||
|
context={
|
||||||
|
"order": order,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
#
|
@shared_task
|
||||||
|
def notify_order_completed(order = None, **kwargs):
|
||||||
|
if not order:
|
||||||
|
raise ValueError("Order must be provided for notification.")
|
||||||
|
|
||||||
|
if kwargs:
|
||||||
|
print("Additional kwargs received in notify_order_completed:", kwargs)
|
||||||
|
|
||||||
|
send_email_with_context(
|
||||||
|
recipients=order.email,
|
||||||
|
subject="Your order has been completed",
|
||||||
|
template_path="email/order_completed.html",
|
||||||
|
context={
|
||||||
|
"order": order,
|
||||||
|
})
|
||||||
|
|||||||
50
backend/commerce/templates/email/order_cancelled.html
Normal file
50
backend/commerce/templates/email/order_cancelled.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<h3 style="color:#d9534f; font-size:18px; margin-top:0;">Order Cancelled</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Your order has been cancelled.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Information</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Total Amount:</td>
|
||||||
|
<td style="padding:8px;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Cancellation Date:</td>
|
||||||
|
<td style="padding:8px;">{{ order.updated_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% if order.payment.status == 'paid' %}
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Refund Information</h4>
|
||||||
|
<p>Since your order was already paid, you will receive a refund of {{ order.total_price }} {{ order.get_currency }}. The refund will be processed within 3-5 business days.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
If you have any questions, please contact our support team.
|
||||||
|
</p>
|
||||||
49
backend/commerce/templates/email/order_completed.html
Normal file
49
backend/commerce/templates/email/order_completed.html
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<h3 style="color:#5cb85c; font-size:18px; margin-top:0;">✓ Order Completed</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Great news! Your order has been completed and delivered. Thank you for your purchase!</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Information</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Total Amount:</td>
|
||||||
|
<td style="padding:8px;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Completed:</td>
|
||||||
|
<td style="padding:8px;">{{ order.updated_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; padding:15px; background-color:#f0f8f0; border-left:4px solid #5cb85c;">
|
||||||
|
<strong>We hope you enjoyed your purchase!</strong> If you have any feedback or need to return an item, please let us know.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
Thank you for shopping with us!
|
||||||
|
</p>
|
||||||
50
backend/commerce/templates/email/order_created.html
Normal file
50
backend/commerce/templates/email/order_created.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<h3 style="color:#333; font-size:18px; margin-top:0;">Order Confirmation</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Thank you for your order! Your order has been successfully created and is being prepared for shipment.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Details</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Summary</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:right; padding:8px;">Subtotal:</td>
|
||||||
|
<td style="text-align:right; padding:8px; font-weight:bold;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Shipping Address</h4>
|
||||||
|
<p style="margin:0;">
|
||||||
|
{{ order.first_name }} {{ order.last_name }}<br>
|
||||||
|
{{ order.address }}<br>
|
||||||
|
{{ order.postal_code }} {{ order.city }}<br>
|
||||||
|
{{ order.country }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% if order.note %}
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Special Instructions</h4>
|
||||||
|
<p style="margin:0;">{{ order.note }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
We will notify you as soon as your order ships. If you have any questions, please contact us.
|
||||||
|
</p>
|
||||||
50
backend/commerce/templates/email/order_missing_payment.html
Normal file
50
backend/commerce/templates/email/order_missing_payment.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<h3 style="color:#d9534f; font-size:18px; margin-top:0;">⚠ Payment Reminder</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>We haven't received payment for your order yet. Your order is being held and may be cancelled if payment is not completed soon.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Details</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Amount Due:</td>
|
||||||
|
<td style="padding:8px;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Created:</td>
|
||||||
|
<td style="padding:8px;">{{ order.created_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; padding:15px; background-color:#f9f9f9; border-left:4px solid #d9534f;">
|
||||||
|
<strong>Please complete your payment as soon as possible to avoid order cancellation.</strong>
|
||||||
|
If you have questions or need assistance, contact us right away.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
Thank you for your business!
|
||||||
|
</p>
|
||||||
45
backend/commerce/templates/email/order_paid.html
Normal file
45
backend/commerce/templates/email/order_paid.html
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<h3 style="color:#333; font-size:18px; margin-top:0;">✓ Payment Received</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Thank you! Your payment has been successfully received and processed. Your order is now confirmed and will be prepared for shipment.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Information</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Amount Paid:</td>
|
||||||
|
<td style="padding:8px;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px; font-weight:bold;">Payment Date:</td>
|
||||||
|
<td style="padding:8px;">{{ order.payment.created_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
Your order will be prepared and shipped as soon as possible. You will receive a shipping notification with tracking details.
|
||||||
|
</p>
|
||||||
53
backend/commerce/templates/email/order_refund_accepted.html
Normal file
53
backend/commerce/templates/email/order_refund_accepted.html
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<h3 style="color:#5cb85c; font-size:18px; margin-top:0;">✓ Refund Processed</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Excellent! Your refund has been approved and processed. The funds will appear in your account within 3-5 business days, depending on your financial institution.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Refund Details</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Original Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Refund Amount:</td>
|
||||||
|
<td style="padding:8px;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Processing Date:</td>
|
||||||
|
<td style="padding:8px;">{{ order.updated_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px; font-weight:bold;">Status:</td>
|
||||||
|
<td style="padding:8px; color:#5cb85c; font-weight:bold;">✓ Completed</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Refunded Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Refund</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; padding:15px; background-color:#f0f8f0; border-left:4px solid #5cb85c;">
|
||||||
|
<strong>Timeline:</strong> Your refund should appear in your account within 3-5 business days. Some banks may take longer during weekends or holidays.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
Thank you for giving us the opportunity to serve you. If you need anything else, please don't hesitate to contact us.
|
||||||
|
</p>
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<h3 style="color:#333; font-size:18px; margin-top:0;">Return Items Received</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Thank you! We have received your returned items from order #{{ order.id }}. Our team is now inspecting the items and processing your refund.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Information</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Total Refund Amount:</td>
|
||||||
|
<td style="padding:8px;">{{ order.total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px; font-weight:bold;">Received Date:</td>
|
||||||
|
<td style="padding:8px;">{{ order.updated_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Returned Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Refund</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; padding:15px; background-color:#f9f9f9; border-left:4px solid #5bc0de;">
|
||||||
|
<strong>What's Next?</strong> We'll inspect the items and confirm the refund within 2-3 business days. You'll receive another confirmation email when your refund has been processed.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
If you have any questions about your return, please contact us.
|
||||||
|
</p>
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<h3 style="color:#5cb85c; font-size:18px; margin-top:0;">✓ Your Order is Ready for Pickup!</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Excellent news! Your order is now ready for pickup. You can collect your package at your convenience during store hours.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Pickup Information</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Ready Since:</td>
|
||||||
|
<td style="padding:8px;">{{ order.carrier.updated_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:8px; font-weight:bold;">Pickup Location:</td>
|
||||||
|
<td style="padding:8px;">Our Store</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; padding:15px; background-color:#f0f8f0; border-left:4px solid #5cb85c;">
|
||||||
|
<strong>What to Bring:</strong> Please bring a valid ID and your order confirmation (this email). Your package is being held for you and will be released upon presentation of these documents.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
Thank you for your business! If you have any questions, please don't hesitate to contact us.
|
||||||
|
</p>
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<h3 style="color:#5cb85c; font-size:18px; margin-top:0;">📦 Your Package is on its Way!</h3>
|
||||||
|
|
||||||
|
<p>Dear {{ order.first_name }} {{ order.last_name }},</p>
|
||||||
|
|
||||||
|
<p>Great news! Your order has been shipped via Zásilkovna and is on its way to you.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Shipping Information</h4>
|
||||||
|
<table width="100%" cellpadding="8" cellspacing="0" style="border-collapse:collapse;">
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Order ID:</td>
|
||||||
|
<td style="padding:8px;">{{ order.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Carrier:</td>
|
||||||
|
<td style="padding:8px;">Zásilkovna</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom:1px solid #ddd;">
|
||||||
|
<td style="padding:8px; font-weight:bold;">Shipped Date:</td>
|
||||||
|
<td style="padding:8px;">{{ order.carrier.updated_at|date:"d.m.Y H:i" }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Delivery Instructions</h4>
|
||||||
|
<p>Your package will be delivered to your selected Zásilkovna pickup point. You will receive an SMS/email notification from Zásilkovna when the package arrives at the pickup point.</p>
|
||||||
|
|
||||||
|
<h4 style="color:#333; margin-top:20px; margin-bottom:10px;">Order Items</h4>
|
||||||
|
<table width="100%" cellpadding="10" cellspacing="0" border="1" style="border-collapse:collapse; border-color:#ddd;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background-color:#f9f9f9;">
|
||||||
|
<th style="text-align:left; padding:10px; border:1px solid #ddd;">Product</th>
|
||||||
|
<th style="text-align:center; padding:10px; border:1px solid #ddd;">Qty</th>
|
||||||
|
<th style="text-align:right; padding:10px; border:1px solid #ddd;">Price</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in order.items.all %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:10px; border:1px solid #ddd;">{{ item.product.name }}</td>
|
||||||
|
<td style="text-align:center; padding:10px; border:1px solid #ddd;">{{ item.quantity }}</td>
|
||||||
|
<td style="text-align:right; padding:10px; border:1px solid #ddd;">{{ item.get_total_price }} {{ order.get_currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; padding:15px; background-color:#f9f9f9; border-left:4px solid #5cb85c;">
|
||||||
|
<strong>Delivery Address:</strong><br>
|
||||||
|
{{ order.first_name }} {{ order.last_name }}<br>
|
||||||
|
{{ order.address }}<br>
|
||||||
|
{{ order.postal_code }} {{ order.city }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="margin-top:20px; color:#666;">
|
||||||
|
You can track your package on the Zásilkovna website. If you have any questions, please contact us.
|
||||||
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user