Compare commits
3 commits
faa07a8b4d
...
3f6fc4a86e
Author | SHA1 | Date | |
---|---|---|---|
3f6fc4a86e | |||
7bd09ec6aa | |||
b5584e1d8e |
8 changed files with 227 additions and 4 deletions
|
@ -68,11 +68,19 @@ class CategoryAdmin(admin.ModelAdmin):
|
|||
|
||||
|
||||
@admin.register(CloudProvider)
|
||||
class CloudProviderAdmin(admin.ModelAdmin):
|
||||
list_display = ("name", "slug", "logo_preview", "disable_listing", "is_featured")
|
||||
class CloudProviderAdmin(SortableAdminMixin, admin.ModelAdmin):
|
||||
list_display = (
|
||||
"name",
|
||||
"slug",
|
||||
"logo_preview",
|
||||
"disable_listing",
|
||||
"is_featured",
|
||||
"order",
|
||||
)
|
||||
search_fields = ("name", "description")
|
||||
prepopulated_fields = {"slug": ("name",)}
|
||||
inlines = [OfferingInline]
|
||||
ordering = ("order",)
|
||||
|
||||
def logo_preview(self, obj):
|
||||
if obj.logo:
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 5.1.5 on 2025-03-12 05:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("services", "0019_alter_websitefaq_options_websitefaq_order"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="cloudprovider",
|
||||
options={"ordering": ["order"]},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="cloudprovider",
|
||||
name="order",
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
|
@ -97,9 +97,13 @@ class CloudProvider(models.Model):
|
|||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
order = models.IntegerField(default=0)
|
||||
is_featured = models.BooleanField(default=False)
|
||||
disable_listing = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
ordering = ["order"]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
|
115
hub/services/templates/email/lead_confirmation.html
Normal file
115
hub/services/templates/email/lead_confirmation.html
Normal file
|
@ -0,0 +1,115 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Thank you for contacting Servala</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.header {
|
||||
background-color: #9A63EC;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
border-top: none;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
width: 30%;
|
||||
}
|
||||
td {
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h2>Thank you for contacting Servala!</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>Hello {{ name }},</p>
|
||||
|
||||
<p>Thank you for your interest in our services. We have received your inquiry and will get back to you shortly.</p>
|
||||
|
||||
<p>Here's a summary of the information you provided:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<td>{{ name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td>{{ email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Phone</th>
|
||||
<td>{{ phone }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Company</th>
|
||||
<td>{{ company }}</td>
|
||||
</tr>
|
||||
{% if service != 'General inquiry' %}
|
||||
<tr>
|
||||
<th>Service</th>
|
||||
<td>{{ service }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if provider != 'Not specified' %}
|
||||
<tr>
|
||||
<th>Provider</th>
|
||||
<td>{{ provider }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if plan != 'Not specified' %}
|
||||
<tr>
|
||||
<th>Plan</th>
|
||||
<td>{{ plan }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if message %}
|
||||
<tr>
|
||||
<th>Message</th>
|
||||
<td>{{ message }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
<p>Our team will review your inquiry and contact you as soon as possible.</p>
|
||||
|
||||
<p>Best regards,<br>Sir Vala and the Team</p>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<p>This is an automated message. Please do not reply directly to this email. You can reach us at <a href="mailto:hi@servala.com">hi@servala.com</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
22
hub/services/templates/email/lead_confirmation.txt
Normal file
22
hub/services/templates/email/lead_confirmation.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
Hello {{ name }},
|
||||
|
||||
Thank you for your interest in our services. We have received your inquiry and will get back to you shortly.
|
||||
|
||||
Here's a summary of the information you provided:
|
||||
|
||||
- Name: {{ name }}
|
||||
- Email: {{ email }}
|
||||
- Phone: {{ phone }}
|
||||
- Company: {{ company }}
|
||||
{% if service != 'General inquiry' %}- Service: {{ service }}{% endif %}
|
||||
{% if provider != 'Not specified' %}- Provider: {{ provider }}{% endif %}
|
||||
{% if plan != 'Not specified' %}- Plan: {{ plan }}{% endif %}
|
||||
{% if message %}- Message: {{ message }}{% endif %}
|
||||
|
||||
Our team will review your inquiry and contact you as soon as possible.
|
||||
|
||||
Best regards,
|
||||
Sir Vala and the Team
|
||||
|
||||
--
|
||||
This is an automated message. Please do not reply directly to this email. You can reach us at hi@servala.com.
|
|
@ -2,6 +2,10 @@ import logging
|
|||
import time
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib import messages
|
||||
from django.core.mail import send_mail
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.html import strip_tags
|
||||
from django.conf import settings
|
||||
|
||||
from hub.services.forms import LeadForm
|
||||
from hub.services.odoo import OdooAPI
|
||||
|
@ -130,6 +134,7 @@ def contact_form(request):
|
|||
|
||||
# Format the final message with all context
|
||||
formatted_context = "<br>".join(context_info)
|
||||
original_message = lead.message
|
||||
lead.message = (
|
||||
lead.message + "<br><br>" + formatted_context
|
||||
if lead.message
|
||||
|
@ -144,9 +149,45 @@ def contact_form(request):
|
|||
odoo_lead_id = odoo.create_lead(lead, lead_title)
|
||||
lead.odoo_lead_id = odoo_lead_id
|
||||
lead.save()
|
||||
|
||||
logger.info(f"Successfully created lead with Odoo ID: {odoo_lead_id}")
|
||||
|
||||
# Send confirmation email
|
||||
try:
|
||||
# Prepare context for email template
|
||||
email_context = {
|
||||
"name": lead.name,
|
||||
"email": lead.email,
|
||||
"company": lead.company or "Not provided",
|
||||
"phone": lead.phone or "Not provided",
|
||||
"message": original_message,
|
||||
"service": service_name or "General inquiry",
|
||||
"provider": offering_name or "Not specified",
|
||||
"plan": plan_name or "Not specified",
|
||||
}
|
||||
|
||||
# Render email content from template
|
||||
html_message = render_to_string(
|
||||
"email/lead_confirmation.html", email_context
|
||||
)
|
||||
plain_message = render_to_string(
|
||||
"email/lead_confirmation.txt", email_context
|
||||
)
|
||||
# Send the email
|
||||
send_mail(
|
||||
subject=f'Thank you for contacting Servala about {service_name or "our services"}',
|
||||
message=plain_message,
|
||||
html_message=html_message,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
recipient_list=[lead.email],
|
||||
fail_silently=False,
|
||||
)
|
||||
logger.info(f"Confirmation email sent to {lead.email}")
|
||||
except Exception as e:
|
||||
# Log error but don't stop the process
|
||||
logger.error(
|
||||
f"Failed to send confirmation email: {str(e)}", exc_info=True
|
||||
)
|
||||
|
||||
# Redirect to thank you page
|
||||
return redirect("services:thank_you")
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from hub.services.models import (
|
|||
def provider_list(request):
|
||||
providers = (
|
||||
CloudProvider.objects.filter(disable_listing=False)
|
||||
.order_by("name")
|
||||
.order_by("order")
|
||||
.prefetch_related("offerings", "consulting_partners")
|
||||
)
|
||||
|
||||
|
|
|
@ -184,6 +184,17 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = env.path("MEDIA_ROOT", default=BASE_DIR / "media")
|
||||
|
||||
|
||||
# Email settings using Mailgun EU region
|
||||
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
||||
EMAIL_HOST = "smtp.eu.mailgun.org"
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST_USER = env.str("EMAIL_HOST_USER", default="none")
|
||||
EMAIL_HOST_PASSWORD = env.str("EMAIL_HOST_PASSWORD", default="none")
|
||||
DEFAULT_FROM_EMAIL = env.str("DEFAULT_FROM_EMAIL", default="noreply@mail.servala.com")
|
||||
|
||||
|
||||
ODOO_CONFIG = {
|
||||
"url": env.str("ODOO_URL", default="http://localhost:8069"),
|
||||
"db": env.str("ODOO_DB", default="odoo"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue