diff --git a/hub/services/admin.py b/hub/services/admin.py
index 9a67782..3ba72d8 100644
--- a/hub/services/admin.py
+++ b/hub/services/admin.py
@@ -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:
diff --git a/hub/services/migrations/0020_alter_cloudprovider_options_cloudprovider_order.py b/hub/services/migrations/0020_alter_cloudprovider_options_cloudprovider_order.py
new file mode 100644
index 0000000..ebf436d
--- /dev/null
+++ b/hub/services/migrations/0020_alter_cloudprovider_options_cloudprovider_order.py
@@ -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),
+ ),
+ ]
diff --git a/hub/services/models.py b/hub/services/models.py
index 0a70614..b547d71 100644
--- a/hub/services/models.py
+++ b/hub/services/models.py
@@ -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
diff --git a/hub/services/templates/email/lead_confirmation.html b/hub/services/templates/email/lead_confirmation.html
new file mode 100644
index 0000000..e30a7dc
--- /dev/null
+++ b/hub/services/templates/email/lead_confirmation.html
@@ -0,0 +1,115 @@
+
+
+
+
+ Thank you for contacting Servala
+
+
+
+
+
+
+
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
+
+
+
+
+
\ No newline at end of file
diff --git a/hub/services/templates/email/lead_confirmation.txt b/hub/services/templates/email/lead_confirmation.txt
new file mode 100644
index 0000000..bce2a5f
--- /dev/null
+++ b/hub/services/templates/email/lead_confirmation.txt
@@ -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.
\ No newline at end of file
diff --git a/hub/services/views/leads.py b/hub/services/views/leads.py
index 2e3ccda..7cb3967 100644
--- a/hub/services/views/leads.py
+++ b/hub/services/views/leads.py
@@ -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 = "
".join(context_info)
+ original_message = lead.message
lead.message = (
lead.message + "
" + 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")
diff --git a/hub/services/views/providers.py b/hub/services/views/providers.py
index 84d5df1..92eba64 100644
--- a/hub/services/views/providers.py
+++ b/hub/services/views/providers.py
@@ -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")
)
diff --git a/hub/settings.py b/hub/settings.py
index 36d89e5..226cf66 100644
--- a/hub/settings.py
+++ b/hub/settings.py
@@ -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"),