editing email
This commit is contained in:
parent
a8a48697b3
commit
d8387d341e
Binary file not shown.
@ -213,4 +213,14 @@ WHATSAPP_ENABLED = os.getenv("WHATSAPP_ENABLED", "true").lower() == "true"
|
|||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
LOGIN_URL = 'login'
|
LOGIN_URL = 'login'
|
||||||
LOGIN_REDIRECT_URL = 'dashboard'
|
LOGIN_REDIRECT_URL = 'dashboard'
|
||||||
LOGOUT_REDIRECT_URL = 'index'
|
LOGOUT_REDIRECT_URL = 'index'
|
||||||
|
|
||||||
|
# Site URL for Emails
|
||||||
|
HOST_FQDN = os.getenv("HOST_FQDN", "")
|
||||||
|
if HOST_FQDN:
|
||||||
|
if not HOST_FQDN.startswith(("http://", "https://")):
|
||||||
|
SITE_URL = f"https://{HOST_FQDN}"
|
||||||
|
else:
|
||||||
|
SITE_URL = HOST_FQDN
|
||||||
|
else:
|
||||||
|
SITE_URL = "http://127.0.0.1:8000"
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -10,6 +10,7 @@ from django.contrib import messages
|
|||||||
from .whatsapp_utils import send_whatsapp_message_detailed
|
from .whatsapp_utils import send_whatsapp_message_detailed
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from .mail import send_html_email
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
class ProfileInline(admin.StackedInline):
|
class ProfileInline(admin.StackedInline):
|
||||||
@ -81,12 +82,12 @@ class PlatformProfileAdmin(admin.ModelAdmin):
|
|||||||
email = request.POST.get('email')
|
email = request.POST.get('email')
|
||||||
if email:
|
if email:
|
||||||
try:
|
try:
|
||||||
send_mail(
|
send_html_email(
|
||||||
subject="Test Email from Platform",
|
subject="Test Email from Platform",
|
||||||
message="This is a test email to verify your platform's email configuration.",
|
message="This is a test email to verify your platform's email configuration. If you see the logo and nice formatting, it works!",
|
||||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
||||||
recipient_list=[email],
|
recipient_list=[email],
|
||||||
fail_silently=False,
|
title="Test Email",
|
||||||
|
request=request
|
||||||
)
|
)
|
||||||
messages.success(request, f"Success: Test email sent to {email}.")
|
messages.success(request, f"Success: Test email sent to {email}.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -129,4 +130,4 @@ admin.site.register(Parcel, ParcelAdmin)
|
|||||||
admin.site.register(Country)
|
admin.site.register(Country)
|
||||||
admin.site.register(Governate)
|
admin.site.register(Governate)
|
||||||
admin.site.register(City)
|
admin.site.register(City)
|
||||||
admin.site.register(PlatformProfile, PlatformProfileAdmin)
|
admin.site.register(PlatformProfile, PlatformProfileAdmin)
|
||||||
|
|||||||
59
core/mail.py
59
core/mail.py
@ -1,9 +1,57 @@
|
|||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail, EmailMultiAlternatives
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.utils.html import strip_tags
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def send_html_email(subject, message, recipient_list, title=None, action_url=None, action_text=None, request=None):
|
||||||
|
"""
|
||||||
|
Sends a styled HTML email using the platform template.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from .models import PlatformProfile
|
||||||
|
platform = PlatformProfile.objects.first()
|
||||||
|
if not platform:
|
||||||
|
# Create a dummy platform object if none exists, to avoid errors
|
||||||
|
class DummyPlatform:
|
||||||
|
name = "Platform"
|
||||||
|
logo = None
|
||||||
|
address = ""
|
||||||
|
platform = DummyPlatform()
|
||||||
|
|
||||||
|
# Determine site URL
|
||||||
|
site_url = settings.SITE_URL if hasattr(settings, 'SITE_URL') else 'http://127.0.0.1:8000'
|
||||||
|
if request:
|
||||||
|
site_url = f"{request.scheme}://{request.get_host()}"
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'platform': platform,
|
||||||
|
'title': title or subject,
|
||||||
|
'message': message,
|
||||||
|
'action_url': action_url,
|
||||||
|
'action_text': action_text,
|
||||||
|
'site_url': site_url,
|
||||||
|
}
|
||||||
|
|
||||||
|
html_content = render_to_string('emails/base_email.html', context)
|
||||||
|
text_content = strip_tags(html_content)
|
||||||
|
|
||||||
|
msg = EmailMultiAlternatives(subject, text_content, settings.DEFAULT_FROM_EMAIL, recipient_list)
|
||||||
|
msg.attach_alternative(html_content, "text/html")
|
||||||
|
msg.send()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to send HTML email: {e}")
|
||||||
|
# Fallback to plain text
|
||||||
|
try:
|
||||||
|
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list)
|
||||||
|
return True
|
||||||
|
except Exception as e2:
|
||||||
|
logger.error(f"Failed to send fallback email: {e2}")
|
||||||
|
return False
|
||||||
|
|
||||||
def send_contact_message(name, email, message):
|
def send_contact_message(name, email, message):
|
||||||
"""
|
"""
|
||||||
Sends a contact form message to the platform admins.
|
Sends a contact form message to the platform admins.
|
||||||
@ -25,14 +73,13 @@ def send_contact_message(name, email, message):
|
|||||||
|
|
||||||
recipient_list = settings.CONTACT_EMAIL_TO or [settings.DEFAULT_FROM_EMAIL]
|
recipient_list = settings.CONTACT_EMAIL_TO or [settings.DEFAULT_FROM_EMAIL]
|
||||||
|
|
||||||
send_mail(
|
# Use HTML email for contact form too, for consistency
|
||||||
|
return send_html_email(
|
||||||
subject=subject,
|
subject=subject,
|
||||||
message=full_message,
|
message=full_message,
|
||||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
||||||
recipient_list=recipient_list,
|
recipient_list=recipient_list,
|
||||||
fail_silently=False,
|
title="New Contact Message"
|
||||||
)
|
)
|
||||||
return True
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to send contact message: {e}")
|
logger.error(f"Failed to send contact message: {e}")
|
||||||
return False
|
return False
|
||||||
86
core/templates/emails/base_email.html
Normal file
86
core/templates/emails/base_email.html
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 20px auto;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 3px solid #0d6efd; /* Bootstrap primary blue */
|
||||||
|
}
|
||||||
|
.header img {
|
||||||
|
max-height: 80px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
padding: 30px;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #0d6efd;
|
||||||
|
color: #ffffff !important;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
h1, h2, h3 {
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
{% if platform.logo %}
|
||||||
|
<img src="{{ site_url }}{{ platform.logo.url }}" alt="{{ platform.name }}">
|
||||||
|
{% else %}
|
||||||
|
<h1>{{ platform.name }}</h1>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
{% if title %}
|
||||||
|
<h2>{{ title }}</h2>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ message|safe|linebreaks }}
|
||||||
|
|
||||||
|
{% if action_url %}
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<a href="{{ action_url }}" class="button">{{ action_text|default:"Click here" }}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<p>© {% now "Y" %} {{ platform.name }}. All rights reserved.</p>
|
||||||
|
{% if platform.address %}
|
||||||
|
<p>{{ platform.address }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -8,6 +8,7 @@ urlpatterns = [
|
|||||||
path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'),
|
path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'),
|
||||||
path('register/', views.register, name='register'),
|
path('register/', views.register, name='register'),
|
||||||
path('register/verify/', views.verify_registration, name='verify_registration'),
|
path('register/verify/', views.verify_registration, name='verify_registration'),
|
||||||
|
|
||||||
path('dashboard/', views.dashboard, name='dashboard'),
|
path('dashboard/', views.dashboard, name='dashboard'),
|
||||||
path('shipment-request/', views.shipment_request, name='shipment_request'),
|
path('shipment-request/', views.shipment_request, name='shipment_request'),
|
||||||
path('accept-parcel/<int:parcel_id>/', views.accept_parcel, name='accept_parcel'),
|
path('accept-parcel/<int:parcel_id>/', views.accept_parcel, name='accept_parcel'),
|
||||||
@ -21,9 +22,9 @@ urlpatterns = [
|
|||||||
path('ajax/get-cities/', views.get_cities, name='get_cities'),
|
path('ajax/get-cities/', views.get_cities, name='get_cities'),
|
||||||
path('privacy-policy/', views.privacy_policy, name='privacy_policy'),
|
path('privacy-policy/', views.privacy_policy, name='privacy_policy'),
|
||||||
path('terms-conditions/', views.terms_conditions, name='terms_conditions'),
|
path('terms-conditions/', views.terms_conditions, name='terms_conditions'),
|
||||||
path('contact/', views.contact_view, name='contact'),
|
path('contact/', views.contact, name='contact'),
|
||||||
|
|
||||||
path('profile/', views.profile_view, name='profile'),
|
path('profile/', views.profile_view, name='profile'),
|
||||||
path('profile/edit/', views.edit_profile_view, name='edit_profile'),
|
path('profile/edit/', views.edit_profile, name='edit_profile'),
|
||||||
path('profile/verify-otp/', views.verify_otp_view, name='verify_otp'),
|
path('profile/verify-otp/', views.verify_otp_view, name='verify_otp'),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from django.shortcuts import render, redirect, get_object_or_404
|
|||||||
from django.contrib.auth import login, authenticate, logout
|
from django.contrib.auth import login, authenticate, logout
|
||||||
from django.contrib.auth.forms import AuthenticationForm
|
from django.contrib.auth.forms import AuthenticationForm
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from .models import Parcel, Profile, Country, Governate, City, OTPVerification, PlatformProfile
|
from .models import Parcel, Profile, Country, Governate, City, OTPVerification, PlatformProfile
|
||||||
from .forms import UserRegistrationForm, ParcelForm, ContactForm, UserProfileForm
|
from .forms import UserRegistrationForm, ParcelForm, ContactForm, UserProfileForm
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
@ -21,7 +22,7 @@ from .whatsapp_utils import (
|
|||||||
notify_status_change,
|
notify_status_change,
|
||||||
send_whatsapp_message
|
send_whatsapp_message
|
||||||
)
|
)
|
||||||
from .mail import send_contact_message
|
from .mail import send_contact_message, send_html_email
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
tracking_id = request.GET.get('tracking_id')
|
tracking_id = request.GET.get('tracking_id')
|
||||||
@ -59,12 +60,12 @@ def register(request):
|
|||||||
send_whatsapp_message(phone, f"Your verification code is: {code}")
|
send_whatsapp_message(phone, f"Your verification code is: {code}")
|
||||||
messages.info(request, _("Verification code sent to WhatsApp."))
|
messages.info(request, _("Verification code sent to WhatsApp."))
|
||||||
else:
|
else:
|
||||||
send_mail(
|
send_html_email(
|
||||||
_('Verification Code'),
|
subject=_('Verification Code'),
|
||||||
f'Your verification code is: {code}',
|
message=f'Your verification code is: {code}',
|
||||||
settings.DEFAULT_FROM_EMAIL,
|
recipient_list=[user.email],
|
||||||
[user.email],
|
title=_('Welcome to Masar!'),
|
||||||
fail_silently=False,
|
request=request
|
||||||
)
|
)
|
||||||
messages.info(request, _("Verification code sent to email."))
|
messages.info(request, _("Verification code sent to email."))
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ def verify_registration(request):
|
|||||||
def dashboard(request):
|
def dashboard(request):
|
||||||
# Ensure profile exists
|
# Ensure profile exists
|
||||||
profile, created = Profile.objects.get_or_create(user=request.user)
|
profile, created = Profile.objects.get_or_create(user=request.user)
|
||||||
|
|
||||||
if profile.role == 'shipper':
|
if profile.role == 'shipper':
|
||||||
parcels = Parcel.objects.filter(shipper=request.user).order_by('-created_at')
|
parcels = Parcel.objects.filter(shipper=request.user).order_by('-created_at')
|
||||||
return render(request, 'core/shipper_dashboard.html', {'parcels': parcels})
|
return render(request, 'core/shipper_dashboard.html', {'parcels': parcels})
|
||||||
@ -136,7 +137,7 @@ def shipment_request(request):
|
|||||||
if profile.role != 'shipper':
|
if profile.role != 'shipper':
|
||||||
messages.error(request, _("Only shippers can request shipments."))
|
messages.error(request, _("Only shippers can request shipments."))
|
||||||
return redirect('dashboard')
|
return redirect('dashboard')
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ParcelForm(request.POST)
|
form = ParcelForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -159,7 +160,7 @@ def accept_parcel(request, parcel_id):
|
|||||||
if profile.role != 'car_owner':
|
if profile.role != 'car_owner':
|
||||||
messages.error(request, _("Only car owners can accept shipments."))
|
messages.error(request, _("Only car owners can accept shipments."))
|
||||||
return redirect('dashboard')
|
return redirect('dashboard')
|
||||||
|
|
||||||
parcel = get_object_or_404(Parcel, id=parcel_id, status='pending', payment_status='paid')
|
parcel = get_object_or_404(Parcel, id=parcel_id, status='pending', payment_status='paid')
|
||||||
parcel.carrier = request.user
|
parcel.carrier = request.user
|
||||||
parcel.status = 'picked_up'
|
parcel.status = 'picked_up'
|
||||||
@ -230,7 +231,7 @@ def payment_success(request):
|
|||||||
messages.success(request, _("Payment successful! Your shipment is now active."))
|
messages.success(request, _("Payment successful! Your shipment is now active."))
|
||||||
else:
|
else:
|
||||||
messages.warning(request, _("Payment status is pending or failed. Please check your dashboard."))
|
messages.warning(request, _("Payment status is pending or failed. Please check your dashboard."))
|
||||||
|
|
||||||
return redirect('dashboard')
|
return redirect('dashboard')
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -263,7 +264,7 @@ def privacy_policy(request):
|
|||||||
def terms_conditions(request):
|
def terms_conditions(request):
|
||||||
return render(request, 'core/terms_conditions.html')
|
return render(request, 'core/terms_conditions.html')
|
||||||
|
|
||||||
def contact_view(request):
|
def contact(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ContactForm(request.POST)
|
form = ContactForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -287,7 +288,7 @@ def profile_view(request):
|
|||||||
return render(request, 'core/profile.html', {'profile': request.user.profile})
|
return render(request, 'core/profile.html', {'profile': request.user.profile})
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def edit_profile_view(request):
|
def edit_profile(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = UserProfileForm(request.POST, request.FILES, instance=request.user.profile)
|
form = UserProfileForm(request.POST, request.FILES, instance=request.user.profile)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -310,11 +311,11 @@ def edit_profile_view(request):
|
|||||||
'city_id': data['city'].id if data['city'] else None,
|
'city_id': data['city'].id if data['city'] else None,
|
||||||
}
|
}
|
||||||
request.session['pending_profile_update'] = safe_data
|
request.session['pending_profile_update'] = safe_data
|
||||||
|
|
||||||
# 3. Generate OTP
|
# 3. Generate OTP
|
||||||
code = ''.join(random.choices(string.digits, k=6))
|
code = ''.join(random.choices(string.digits, k=6))
|
||||||
OTPVerification.objects.create(user=request.user, code=code, purpose='profile_update')
|
OTPVerification.objects.create(user=request.user, code=code, purpose='profile_update')
|
||||||
|
|
||||||
# 4. Send OTP
|
# 4. Send OTP
|
||||||
method = data.get('otp_method', 'email')
|
method = data.get('otp_method', 'email')
|
||||||
if method == 'whatsapp':
|
if method == 'whatsapp':
|
||||||
@ -326,19 +327,19 @@ def edit_profile_view(request):
|
|||||||
# Default to email
|
# Default to email
|
||||||
# Send to the NEW email address (from the form), not the old one
|
# Send to the NEW email address (from the form), not the old one
|
||||||
target_email = data['email']
|
target_email = data['email']
|
||||||
send_mail(
|
send_html_email(
|
||||||
_('Verification Code'),
|
subject=_('Verification Code'),
|
||||||
f'Your verification code is: {code}',
|
message=f'Your verification code is: {code}',
|
||||||
settings.DEFAULT_FROM_EMAIL,
|
recipient_list=[target_email],
|
||||||
[target_email],
|
title=_('Profile Update Verification'),
|
||||||
fail_silently=False,
|
request=request
|
||||||
)
|
)
|
||||||
messages.info(request, _("Verification code sent to email."))
|
messages.info(request, _("Verification code sent to email."))
|
||||||
|
|
||||||
return redirect('verify_otp')
|
return redirect('verify_otp')
|
||||||
else:
|
else:
|
||||||
form = UserProfileForm(instance=request.user.profile)
|
form = UserProfileForm(instance=request.user.profile)
|
||||||
|
|
||||||
return render(request, 'core/edit_profile.html', {'form': form})
|
return render(request, 'core/edit_profile.html', {'form': form})
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -390,4 +391,4 @@ def verify_otp_view(request):
|
|||||||
except OTPVerification.DoesNotExist:
|
except OTPVerification.DoesNotExist:
|
||||||
messages.error(request, _("Invalid code."))
|
messages.error(request, _("Invalid code."))
|
||||||
|
|
||||||
return render(request, 'core/verify_otp.html')
|
return render(request, 'core/verify_otp.html')
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from django.conf import settings
|
|||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from .models import PlatformProfile
|
from .models import PlatformProfile
|
||||||
|
from .mail import send_html_email
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -149,12 +150,11 @@ Please proceed to payment to make it visible to drivers."""
|
|||||||
# Email
|
# Email
|
||||||
if parcel.shipper.email:
|
if parcel.shipper.email:
|
||||||
try:
|
try:
|
||||||
send_mail(
|
send_html_email(
|
||||||
subject='Shipment Request Received - ' + parcel.tracking_number,
|
subject='Shipment Request Received - ' + parcel.tracking_number,
|
||||||
message=message,
|
message=message,
|
||||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
||||||
recipient_list=[parcel.shipper.email],
|
recipient_list=[parcel.shipper.email],
|
||||||
fail_silently=False
|
title='Shipment Request Received'
|
||||||
)
|
)
|
||||||
logger.info(f"Shipment created email sent to {parcel.shipper.email}")
|
logger.info(f"Shipment created email sent to {parcel.shipper.email}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -176,12 +176,11 @@ Your shipment is now visible to available drivers."""
|
|||||||
# Email Shipper
|
# Email Shipper
|
||||||
if parcel.shipper.email:
|
if parcel.shipper.email:
|
||||||
try:
|
try:
|
||||||
send_mail(
|
send_html_email(
|
||||||
subject='Payment Successful - ' + parcel.tracking_number,
|
subject='Payment Successful - ' + parcel.tracking_number,
|
||||||
message=shipper_msg,
|
message=shipper_msg,
|
||||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
||||||
recipient_list=[parcel.shipper.email],
|
recipient_list=[parcel.shipper.email],
|
||||||
fail_silently=False
|
title='Payment Successful'
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to send payment email to {parcel.shipper.email}: {e}")
|
logger.error(f"Failed to send payment email to {parcel.shipper.email}: {e}")
|
||||||
@ -205,12 +204,11 @@ Status: {parcel.get_status_display()}"""
|
|||||||
|
|
||||||
if parcel.shipper.email:
|
if parcel.shipper.email:
|
||||||
try:
|
try:
|
||||||
send_mail(
|
send_html_email(
|
||||||
subject='Driver Assigned - ' + parcel.tracking_number,
|
subject='Driver Assigned - ' + parcel.tracking_number,
|
||||||
message=msg,
|
message=msg,
|
||||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
||||||
recipient_list=[parcel.shipper.email],
|
recipient_list=[parcel.shipper.email],
|
||||||
fail_silently=True
|
title='Driver Assigned'
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@ -227,12 +225,11 @@ New Status: {parcel.get_status_display()}"""
|
|||||||
|
|
||||||
if parcel.shipper.email:
|
if parcel.shipper.email:
|
||||||
try:
|
try:
|
||||||
send_mail(
|
send_html_email(
|
||||||
subject='Shipment Update - ' + parcel.tracking_number,
|
subject='Shipment Update - ' + parcel.tracking_number,
|
||||||
message=msg,
|
message=msg,
|
||||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
||||||
recipient_list=[parcel.shipper.email],
|
recipient_list=[parcel.shipper.email],
|
||||||
fail_silently=True
|
title='Shipment Update'
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user