Compare commits

...

5 Commits

12 changed files with 83 additions and 48 deletions

View File

@ -46,3 +46,19 @@ application = ProtocolTypeRouter(
),
}
)
try:
from django.conf import settings
from django.contrib.sites.models import Site
if not settings.DEBUG:
site = Site.objects.get(id=settings.SITE_ID)
if site.domain != settings.PRODUCTION_DOMAIN:
site.domain = settings.PRODUCTION_DOMAIN
site.name = settings.SITE_NAME
site.save()
except Exception as e:
# Log error but don't crash the app
if settings.DEBUG:
print(f"Site configuration error in WSGI: {e}")

View File

@ -43,14 +43,14 @@ class Command(BaseCommand):
)
# Assign quotas to plans
PlanQuota.objects.create(plan=basic_plan, quota=users_quota, value=99999)
PlanQuota.objects.create(plan=basic_plan, quota=cars_quota, value=99999)
PlanQuota.objects.create(plan=basic_plan, quota=users_quota, value=10000000)
PlanQuota.objects.create(plan=basic_plan, quota=cars_quota, value=10000000)
PlanQuota.objects.create(plan=pro_plan, quota=users_quota, value=99999)
PlanQuota.objects.create(plan=pro_plan, quota=cars_quota, value=99999)
PlanQuota.objects.create(plan=pro_plan, quota=users_quota, value=10000000)
PlanQuota.objects.create(plan=pro_plan, quota=cars_quota, value=10000000)
PlanQuota.objects.create(plan=enterprise_plan, quota=users_quota, value=99999)
PlanQuota.objects.create(plan=enterprise_plan, quota=cars_quota, value=99999)
PlanQuota.objects.create(plan=enterprise_plan, quota=users_quota, value=10000000)
PlanQuota.objects.create(plan=enterprise_plan, quota=cars_quota, value=10000000)
# PlanQuota.objects.create(plan=pro_plan, quota=project_quota, value=50)
# PlanQuota.objects.create(plan=pro_plan, quota=storage_quota, value=100)
@ -61,13 +61,13 @@ class Command(BaseCommand):
enterprise_pricing = Pricing.objects.create(name="1 Year", period=365)
PlanPricing.objects.create(
plan=basic_plan, pricing=basic_pricing, price=Decimal("2500.00")
plan=basic_plan, pricing=basic_pricing, price=Decimal("2997.00")
)
PlanPricing.objects.create(
plan=pro_plan, pricing=pro_pricing, price=Decimal("4500.00")
plan=pro_plan, pricing=pro_pricing, price=Decimal("5395.00")
)
PlanPricing.objects.create(
plan=enterprise_plan, pricing=enterprise_pricing, price=Decimal("8500.00")
plan=enterprise_plan, pricing=enterprise_pricing, price=Decimal("9590.00")
)
# # Create quotas

View File

@ -169,8 +169,7 @@ class DealerSlugMiddleware:
"/ar/help_center/",
"/en/help_center/",
]
print("------------------------------------")
print(request.path in paths)
if request.path in paths:
return None

View File

@ -1001,15 +1001,25 @@ def car_created_notification(sender, instance, created, **kwargs):
if created:
accountants = (
models.CustomGroup.objects.filter(
dealer=instance.dealer, name__in=["Manager", "Accountant"]
dealer=instance.dealer, name__in=["Accountant"]
)
.first()
.group.user_set.all()
.distinct()
)
for accountant in accountants:
managers = (
models.CustomGroup.objects.filter(
dealer=instance.dealer, name__in=["Manager"]
)
.first()
.group.user_set.all()
.distinct()
)
recipients = accountants.union(managers)
for recipient in recipients:
models.Notification.objects.create(
user=accountant,
user=recipient,
message=_(
"""
New Car {car_make}-{car_model}-{year}-{vin} has been added to the inventory.

View File

@ -1924,12 +1924,15 @@ def handle_payment(request, order):
"last_name": last_name,
"phone": phone,
}
total = int(round(order.total())) * 100
try:
total = int((order.total() + order.tax * order.total() / 100) * 100)
except (AttributeError, TypeError):
raise ValueError("Order total or tax is invalid")
payload = json.dumps(
{
"amount": total,
"currency": "SAR",
"description": f"payment issued for {'email'}",
"description": f"payment issued for {email}",
"callback_url": callback_url,
"source": {
"type": "creditcard",

View File

@ -52,7 +52,7 @@ from django.forms import CharField, HiddenInput, ValidationError
from django.shortcuts import HttpResponse
from django.db.models import Sum, F, Count
from django.db.models.functions import ExtractMonth
from django.db.models.functions import ExtractMonth,Round
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.models import User, Group
from django.db.models import Value
@ -690,6 +690,7 @@ def sales_dashboard(request,dealer_slug):
created__date__gte=start_date,
created__date__lte=end_date
)
total_leads=leads_filtered.count()
# ----------------------------------------------------
@ -747,6 +748,7 @@ def sales_dashboard(request,dealer_slug):
'total_new_cars_in_inventory': total_new_cars_in_inventory,
'total_used_cars_in_inventory': total_used_cars_in_inventory,
'aging_inventory_count': aging_inventory_count,
'total_leads':total_leads
}
return render(request, 'dashboards/sales_dashboard.html', context)
@ -9734,8 +9736,12 @@ def ledger_unpost_all_journals(request, dealer_slug, entity_slug, pk):
@permission_required("inventory.change_dealer", raise_exception=True)
def pricing_page(request, dealer_slug):
dealer=get_object_or_404(models.Dealer, slug=dealer_slug)
vat = models.VatRate.objects.filter(dealer=dealer).first()
if not dealer.active_plan:
plan_list = PlanPricing.objects.all()
plan_list = PlanPricing.objects.annotate(
price_with_tax=Round(F('price') * vat.rate + F('price'), 2)
).all()
form = forms.PaymentPlanForm()
return render(request, "pricing_page.html", {"plan_list": plan_list, "form": form})
else:
@ -9784,7 +9790,6 @@ def payment_callback(request, dealer_slug):
logger.info(f"Received payment callback for dealer_slug: {dealer_slug}, payment_id: {payment_id}, status: {payment_status}")
order = Order.objects.filter(user=dealer.user, status=1).first() # Status 1 = NEW
print(order)
if payment_status == "paid":
logger.info(f"Payment successful for transaction ID {payment_id}. Processing order completion.")
@ -9805,10 +9810,11 @@ def payment_callback(request, dealer_slug):
logger.debug(f"Billing info already exists for user {dealer.user}.")
if not hasattr(order.user, 'userplan'):
print(order.get_plan_pricing().pricing.period)
UserPlan.objects.create(
user=order.user,
plan=order.plan,
expire=datetime.now().date() + timedelta(days=order.get_plan_pricing().pricing.period + 30)
expire=datetime.now().date() + timedelta(days=order.get_plan_pricing().pricing.period)
)
logger.info(f"Created new UserPlan for user {order.user} with plan {order.plan}.")
else:

View File

@ -305,7 +305,7 @@
return true
}
function validate_sa_phone_number(phone_number) {
const phone_numberRegex = /^05[0-10]{7}$/;
const phone_numberRegex = /^05[0-9]{8}$/;
return phone_numberRegex.test(phone_number) && phone_numberRegex !== '';
}
function getAllFormData() {
@ -372,11 +372,7 @@
hideLoading();
const data = await response.json();
if (response.ok) {
<<<<<<< HEAD
notify("success","{% trans 'Account created successfully'%}");
=======
notify("success","Account created successfully");
>>>>>>> d3dcb85fa378e156b77550e8ab833ad10ffad51f
setTimeout(() => {
window.location.href = "{% url 'account_login' %}";
}, 1000);

View File

@ -77,7 +77,7 @@
<div class="col-md-6">
<div class="card h-100 shadow-sm border-0">
<div class="card-header bg-white border-bottom-0">
<h5 class="fw-bold mb-0 text-dark">{% trans "Top Lead Sources" %}</h5>
<h5 class="fw-bold mb-0 text-dark">{% trans "Top Lead Sources" %}&nbsp;&nbsp;&nbsp;&nbsp;{% trans "Total Leads: " %}{{total_leads}}</h5>
</div>
<div class="card-body d-flex align-items-center justify-content-center"
style="height: 400px">

View File

@ -269,6 +269,7 @@
</tr>
<tr>
{% if perms.inventory.add_car%}
<td colspan="2">
{% if not car.get_transfer %}
<a href="{% url 'car_finance_update' request.dealer.slug car.slug %}"
@ -277,11 +278,14 @@
<span class="badge bg-danger">{% trans "Cannot Edit, Car in Transfer." %}</span>
{% endif %}
</td>
{% endif %}
</tr>
{% else %}
{% if perms.inventory.add_car%}
<p>{% trans "No finance details available." %}</p>
<a href="{% url 'car_finance_update' request.dealer.slug car.slug %}"
class="btn btn-phoenix-success btn-sm mb-3">{% trans "Add" %}</a>
{% endif %}
{% endif %}
</table>
</div>

View File

@ -98,7 +98,6 @@
<th scope="col">{% trans 'Status' %}</th>
<th scope="col">{% trans 'PO Amount' %}</th>
<th scope="col">{% trans 'Date Fulfilled' %}</th>
<th scope="col">{% trans 'Created By' %}</th>
<th scope="col">{% trans 'Cars Purchased' %}</th>
<th scope="col">{% trans 'Vendor' %}</th>
</tr>
@ -117,7 +116,6 @@
{% trans 'Not fulfilled' %}
{% endif %}
</td>
<td>{% firstof po.created_by.get_full_name 'staff' %}</td>
<td>{{ po.po_quantity }}</td>
<td>{{ po.vendors_str }}</td>
</tr>

View File

@ -100,7 +100,7 @@
id="plan_{{ forloop.counter }}"
value="{{ pp.id }}"
data-name="{{ pp.plan.name }}"
data-price="{{ pp.price }}"
data-price="{{ pp.price_with_tax }}"
autocomplete="off"
{% if forloop.first %}checked{% endif %}>
<label class="btn w-100 p-0 pricing-card" for="plan_{{ forloop.counter }}">
@ -108,7 +108,7 @@
<div class="card-body p-4">
<h4 class="mb-3">{{ pp.plan.name|capfirst }}</h4>
<h5 class="mb-4">
{{ pp.price }} <span class="icon-saudi_riyal"></span><span class="fs-6 fw-normal">/ {{ pp.pricing.period }}</span> {% trans "days" %}
{{pp.price_with_tax}} <span class="icon-saudi_riyal"></span><span class="fs-6 fw-normal">/ {{ pp.pricing.period }}</span> {% trans "days" %}
</h5>
<h5>{{ _("Include Haikal's") }}</h5>
<ul class="fa-ul ps-3">
@ -146,8 +146,8 @@
id="first_name"
class="form-control form-control-sm"
required
placeholder="{{ _("First Name") }}"
value="{{ request.user.first_name }}">
placeholder='{{ _("First Name") }}'
value="{{ request.dealer.first_name }}">
</div>
<label class="form-label" for="last_name">{{ _("Last Name") }}</label>
<div class="input-group">
@ -157,8 +157,8 @@
id="last_name"
class="form-control form-control-sm"
required
placeholder="{{ _("Last Name") }}"
value="{{ request.user.last_name }}">
placeholder='{{ _("Last Name") }}'
value="{{ request.dealer.last_name }}">
</div>
<label class="form-label" for="email">{{ _("Email Address") }}</label>
<div class="input-group">
@ -169,7 +169,7 @@
class="form-control form-control-sm"
required
placeholder="email@example.com"
value="{{ request.user.email }}">
value="{{ request.dealer.email }}">
</div>
<label class="form-label" for="phone">{{ _("Phone Number") }}</label>
<div class="input-group">
@ -179,19 +179,22 @@
id="phone"
class="form-control form-control-sm"
dir="ltr"
placeholder="{{ _("Phone Number") }}"
value="{{ request.dealer.phone_number.raw_input }}"
maxlength="10"
pattern="^05\d{8}$"
inputmode="numeric"
placeholder='{{ _("Phone Number") }}'
value="{{ request.dealer.phone_number }}"
required>
</div>
<label class="form-label" for="company">{{ _("Company") }}</label>
<div class="input-group">
<span class="input-group-text"><i class="fas fa-building"></i></span>
<input type="text"
name="company"
id="company"
class="form-control form-control-sm"
placeholder="{{ _("Company") }}"
value="{{ request.dealer.get_local_name }}">
name="company"
id="company"
class="form-control form-control-sm"
placeholder='{{ _("Company") }}'
value="{{ request.dealer.name }}">
</div>
</div>
</div>
@ -212,7 +215,7 @@
name="card_name"
id="card_name"
class="form-control form-control-sm"
placeholder="{{ _("Cardholder Name") }}"
placeholder='{{ _("Cardholder Name") }}'
required>
<div class="invalid-feedback" id="card_name_feedback">
{{ _("Please enter the cardholder name") }}
@ -225,7 +228,7 @@
name="card_number"
id="card_number"
class="form-control form-control-sm"
placeholder="{{ _("Card Number") }}"
placeholder='{{ _("Card Number") }}'
maxlength="19"
pattern="^\d{4}\s\d{4}\s\d{4}\s\d{4}$"
inputmode="numeric"
@ -242,7 +245,7 @@
name="card_expiry"
id="card_expiry"
class="form-control form-control-sm"
placeholder="{{ _("Expiry Date") }}"
placeholder='{{ _("Expiry Date") }}'
maxlength="5"
pattern="^(0[1-9]|1[0-2])\/\d{2}$"
inputmode="numeric"
@ -259,7 +262,7 @@
name="card_cvv"
id="card_cvv"
class="form-control form-control-sm"
placeholder="{{ _("CVV") }}"
placeholder='{{ _("CVV") }}'
maxlength="3"
pattern="^\d{3}$"
inputmode="numeric"

View File

@ -122,9 +122,9 @@
<div class="row d-flex justify-content-center align-items-center mt-5 mb-3 ms-6 ps-3">
<div class="row">
<div class="col">
{% if not items %}
{% if not items.car %}
{% url "car_add" request.dealer.slug as create_car_url %}
{% include "message-illustration.html" with value1="Please add at least one car before creating a quotation." value2="Add car" message_image="images/logos/no-content-new.jpg" url=create_car_url %}
{% include "message-illustration.html" with value1="Please add at least one car or complete the car info before creating a quotation." value2="Add car" message_image="images/logos/no-content-new.jpg" url=create_car_url %}
{% endif %}
</div>
<div class="col">