Compare commits
6 Commits
e564d13acf
...
92a2fd7067
| Author | SHA1 | Date | |
|---|---|---|---|
| 92a2fd7067 | |||
| cc1c70a19e | |||
| d3dcb85fa3 | |||
| f4f0e842b8 | |||
| f51ce25790 | |||
| 5416a9f90b |
@ -12,12 +12,9 @@ find ./haikalbot -type d -iname "__pycache__"|xargs rm -rf
|
|||||||
echo "Apply Base Migrate"
|
echo "Apply Base Migrate"
|
||||||
python3 manage.py migrate
|
python3 manage.py migrate
|
||||||
|
|
||||||
|
echo "Apply makemigrations"
|
||||||
python3 manage.py makemigrations
|
python3 manage.py makemigrations
|
||||||
|
|
||||||
echo "Apply Appointment Migratinos"
|
|
||||||
python3 manage.py makemigrations appointment
|
|
||||||
|
|
||||||
echo "Apply Final Migrate"
|
echo "Apply Final Migrate"
|
||||||
python3 manage.py migrate
|
python3 manage.py migrate
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from django.core.cache import cache
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from luhnchecker.luhn import Luhn
|
from luhnchecker.luhn import Luhn
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from appointment.models import Service
|
# from appointment.models import Service
|
||||||
from django.core.validators import MinLengthValidator
|
from django.core.validators import MinLengthValidator
|
||||||
from django import forms
|
from django import forms
|
||||||
from plans.models import PlanPricing
|
from plans.models import PlanPricing
|
||||||
@ -121,12 +121,12 @@ class StaffForm(forms.ModelForm):
|
|||||||
widget=forms.EmailInput(attrs={"class": "form-control form-control-sm"}),
|
widget=forms.EmailInput(attrs={"class": "form-control form-control-sm"}),
|
||||||
)
|
)
|
||||||
|
|
||||||
service_offered = forms.ModelMultipleChoiceField(
|
# service_offered = forms.ModelMultipleChoiceField(
|
||||||
label=_("Services Offered"),
|
# label=_("Services Offered"),
|
||||||
widget=forms.CheckboxSelectMultiple(attrs={"class": "form-check-input"}),
|
# widget=forms.CheckboxSelectMultiple(attrs={"class": "form-check-input"}),
|
||||||
queryset=Service.objects.all(),
|
# # queryset=Service.objects.all(),
|
||||||
required=False,
|
# required=False,
|
||||||
)
|
# )
|
||||||
# phone_number = SaudiPhoneNumberField(
|
# phone_number = SaudiPhoneNumberField(
|
||||||
# required=False,
|
# required=False,
|
||||||
# widget=forms.TextInput(
|
# widget=forms.TextInput(
|
||||||
|
|||||||
@ -47,3 +47,4 @@ class Command(BaseCommand):
|
|||||||
codename="can_approve_estimatemodel",
|
codename="can_approve_estimatemodel",
|
||||||
content_type=ContentType.objects.get_for_model(EstimateModel),
|
content_type=ContentType.objects.get_for_model(EstimateModel),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -43,31 +43,31 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Assign quotas to plans
|
# Assign quotas to plans
|
||||||
PlanQuota.objects.create(plan=basic_plan, quota=users_quota, value=4)
|
PlanQuota.objects.create(plan=basic_plan, quota=users_quota, value=99999)
|
||||||
PlanQuota.objects.create(plan=basic_plan, quota=cars_quota, value=4)
|
PlanQuota.objects.create(plan=basic_plan, quota=cars_quota, value=99999)
|
||||||
|
|
||||||
PlanQuota.objects.create(plan=pro_plan, quota=users_quota, value=5)
|
PlanQuota.objects.create(plan=pro_plan, quota=users_quota, value=99999)
|
||||||
PlanQuota.objects.create(plan=pro_plan, quota=cars_quota, value=5)
|
PlanQuota.objects.create(plan=pro_plan, quota=cars_quota, value=99999)
|
||||||
|
|
||||||
PlanQuota.objects.create(plan=enterprise_plan, quota=users_quota, value=10)
|
PlanQuota.objects.create(plan=enterprise_plan, quota=users_quota, value=99999)
|
||||||
PlanQuota.objects.create(plan=enterprise_plan, quota=cars_quota, value=10)
|
PlanQuota.objects.create(plan=enterprise_plan, quota=cars_quota, value=99999)
|
||||||
|
|
||||||
# PlanQuota.objects.create(plan=pro_plan, quota=project_quota, value=50)
|
# PlanQuota.objects.create(plan=pro_plan, quota=project_quota, value=50)
|
||||||
# PlanQuota.objects.create(plan=pro_plan, quota=storage_quota, value=100)
|
# PlanQuota.objects.create(plan=pro_plan, quota=storage_quota, value=100)
|
||||||
|
|
||||||
# Define pricing
|
# Define pricing
|
||||||
basic_pricing = Pricing.objects.create(name="Monthly", period=30)
|
basic_pricing = Pricing.objects.create(name="3 Months", period=90)
|
||||||
pro_pricing = Pricing.objects.create(name="Monthly", period=30)
|
pro_pricing = Pricing.objects.create(name="6 Months", period=180)
|
||||||
enterprise_pricing = Pricing.objects.create(name="Monthly", period=30)
|
enterprise_pricing = Pricing.objects.create(name="1 Year", period=365)
|
||||||
|
|
||||||
PlanPricing.objects.create(
|
PlanPricing.objects.create(
|
||||||
plan=basic_plan, pricing=basic_pricing, price=Decimal("9.99")
|
plan=basic_plan, pricing=basic_pricing, price=Decimal("2500.00")
|
||||||
)
|
)
|
||||||
PlanPricing.objects.create(
|
PlanPricing.objects.create(
|
||||||
plan=pro_plan, pricing=pro_pricing, price=Decimal("19.99")
|
plan=pro_plan, pricing=pro_pricing, price=Decimal("4500.00")
|
||||||
)
|
)
|
||||||
PlanPricing.objects.create(
|
PlanPricing.objects.create(
|
||||||
plan=enterprise_plan, pricing=enterprise_pricing, price=Decimal("29.99")
|
plan=enterprise_plan, pricing=enterprise_pricing, price=Decimal("8500.00")
|
||||||
)
|
)
|
||||||
|
|
||||||
# # Create quotas
|
# # Create quotas
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from django.urls import reverse
|
|||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.db.models.signals import post_save, post_delete
|
from django.db.models.signals import post_save, post_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from appointment.models import Service
|
# from appointment.models import Service
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|||||||
@ -276,7 +276,7 @@ urlpatterns = [
|
|||||||
),
|
),
|
||||||
# #######################
|
# #######################
|
||||||
# #######################
|
# #######################
|
||||||
path("crm/calender/", views.EmployeeCalendarView.as_view(), name="calendar_list"),
|
# path("crm/calender/", views.EmployeeCalendarView.as_view(), name="calendar_list"),
|
||||||
#######################################################
|
#######################################################
|
||||||
# Vendor URLs
|
# Vendor URLs
|
||||||
#######################################################
|
#######################################################
|
||||||
|
|||||||
@ -196,7 +196,7 @@ from django_ledger.views.mixins import (
|
|||||||
from . import models, forms, tables
|
from . import models, forms, tables
|
||||||
from django_tables2 import SingleTableView
|
from django_tables2 import SingleTableView
|
||||||
from django_tables2.export.views import ExportMixin
|
from django_tables2.export.views import ExportMixin
|
||||||
from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
# from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
||||||
from .services import (
|
from .services import (
|
||||||
decodevin,
|
decodevin,
|
||||||
get_make,
|
get_make,
|
||||||
@ -3734,7 +3734,6 @@ class UserUpdateView(
|
|||||||
# self.object.staff_member.services_offered.add(service)
|
# self.object.staff_member.services_offered.add(service)
|
||||||
|
|
||||||
staff = form.save(commit=False)
|
staff = form.save(commit=False)
|
||||||
print(form.cleaned_data)
|
|
||||||
# staff.name = form.cleaned_data["name"]
|
# staff.name = form.cleaned_data["name"]
|
||||||
staff.arabic_name = form.cleaned_data["arabic_name"]
|
staff.arabic_name = form.cleaned_data["arabic_name"]
|
||||||
staff.phone_number = form.cleaned_data["phone_number"]
|
staff.phone_number = form.cleaned_data["phone_number"]
|
||||||
@ -9012,40 +9011,40 @@ class PnLAPIView(DjangoLedgerSecurityMixIn, EntityUnitMixIn, View):
|
|||||||
return JsonResponse({"message": _("Unauthorized")}, status=401)
|
return JsonResponse({"message": _("Unauthorized")}, status=401)
|
||||||
|
|
||||||
|
|
||||||
class EmployeeCalendarView(LoginRequiredMixin, ListView):
|
# class EmployeeCalendarView(LoginRequiredMixin, ListView):
|
||||||
"""
|
# """
|
||||||
Provides a view for displaying the employee's calendar in a list format.
|
# Provides a view for displaying the employee's calendar in a list format.
|
||||||
|
|
||||||
Displays a list of appointments for logged-in users. This view ensures that
|
# Displays a list of appointments for logged-in users. This view ensures that
|
||||||
only appointments relevant to the logged-in user as a dealer or staff member
|
# only appointments relevant to the logged-in user as a dealer or staff member
|
||||||
are displayed. Supports search functionality to filter displayed appointments
|
# are displayed. Supports search functionality to filter displayed appointments
|
||||||
based on provided query parameters.
|
# based on provided query parameters.
|
||||||
|
|
||||||
:ivar template_name: Path to the HTML template used to render the view.
|
# :ivar template_name: Path to the HTML template used to render the view.
|
||||||
:type template_name: str
|
# :type template_name: str
|
||||||
:ivar model: Model object to interact with appointments data.
|
# :ivar model: Model object to interact with appointments data.
|
||||||
:type model: Appointment
|
# :type model: Appointment
|
||||||
:ivar context_object_name: Name of the context variable that contains the
|
# :ivar context_object_name: Name of the context variable that contains the
|
||||||
list of appointments in the template.
|
# list of appointments in the template.
|
||||||
:type context_object_name: str
|
# :type context_object_name: str
|
||||||
"""
|
# """
|
||||||
|
|
||||||
template_name = "crm/employee_calendar.html"
|
# template_name = "crm/employee_calendar.html"
|
||||||
model = Appointment
|
# model = Appointment
|
||||||
context_object_name = "appointments"
|
# context_object_name = "appointments"
|
||||||
|
|
||||||
def get_queryset(self):
|
# def get_queryset(self):
|
||||||
query = self.request.GET.get("q")
|
# query = self.request.GET.get("q")
|
||||||
staff = getattr(self.request, "staff", None)
|
# staff = getattr(self.request, "staff", None)
|
||||||
if staff:
|
# if staff:
|
||||||
appointments = Appointment.objects.filter(
|
# appointments = Appointment.objects.filter(
|
||||||
appointment_request__staff_member=staff,
|
# appointment_request__staff_member=staff,
|
||||||
ppointment_request__date__gt=timezone.now(),
|
# ppointment_request__date__gt=timezone.now(),
|
||||||
)
|
# )
|
||||||
appointments = Appointment.objects.filter(
|
# appointments = Appointment.objects.filter(
|
||||||
appointment_request__date__gt=timezone.now()
|
# appointment_request__date__gt=timezone.now()
|
||||||
)
|
# )
|
||||||
return apply_search_filters(appointments, query)
|
# return apply_search_filters(appointments, query)
|
||||||
|
|
||||||
|
|
||||||
def apply_search_filters(queryset, query):
|
def apply_search_filters(queryset, query):
|
||||||
@ -9809,7 +9808,7 @@ def payment_callback(request, dealer_slug):
|
|||||||
UserPlan.objects.create(
|
UserPlan.objects.create(
|
||||||
user=order.user,
|
user=order.user,
|
||||||
plan=order.plan,
|
plan=order.plan,
|
||||||
expire=datetime.now().date() + timedelta(days=order.get_plan_pricing().pricing.period)
|
expire=datetime.now().date() + timedelta(days=order.get_plan_pricing().pricing.period + 30)
|
||||||
)
|
)
|
||||||
logger.info(f"Created new UserPlan for user {order.user} with plan {order.plan}.")
|
logger.info(f"Created new UserPlan for user {order.user} with plan {order.plan}.")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -26,6 +26,4 @@ python3 manage.py tenhal_plan
|
|||||||
|
|
||||||
python3 manage.py set_custom_permissions
|
python3 manage.py set_custom_permissions
|
||||||
|
|
||||||
python3 manage.py initial_services_offered
|
|
||||||
|
|
||||||
echo "Done"
|
echo "Done"
|
||||||
Binary file not shown.
@ -9305,10 +9305,8 @@ msgstr "سعر البيع"
|
|||||||
|
|
||||||
#: inventory/models.py:705 templates/inventory/car_detail.html:267
|
#: inventory/models.py:705 templates/inventory/car_detail.html:267
|
||||||
#: templates/ledger/reports/car_sale_report.html:237
|
#: templates/ledger/reports/car_sale_report.html:237
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Agreed Price"
|
|
||||||
msgid "Marked Price"
|
msgid "Marked Price"
|
||||||
msgstr "السعر المتفق عليه"
|
msgstr "سعر العرض"
|
||||||
|
|
||||||
#: inventory/models.py:711 templates/ledger/reports/car_sale_report.html:238
|
#: inventory/models.py:711 templates/ledger/reports/car_sale_report.html:238
|
||||||
#: templates/sales/estimates/estimate_detail.html:259
|
#: templates/sales/estimates/estimate_detail.html:259
|
||||||
|
|||||||
155
requirements_dev1.txt
Normal file
155
requirements_dev1.txt
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
annotated-types==0.7.0
|
||||||
|
anyio==4.9.0
|
||||||
|
arrow==1.3.0
|
||||||
|
asgiref==3.9.1
|
||||||
|
attrs==25.3.0
|
||||||
|
autobahn==24.4.2
|
||||||
|
Automat==25.4.16
|
||||||
|
Babel==2.15.0
|
||||||
|
beautifulsoup4==4.13.4
|
||||||
|
blessed==1.21.0
|
||||||
|
cattrs==25.1.1
|
||||||
|
certifi==2025.7.9
|
||||||
|
cffi==1.17.1
|
||||||
|
channels==4.2.2
|
||||||
|
charset-normalizer==3.4.2
|
||||||
|
click==8.2.1
|
||||||
|
colorama==0.4.6
|
||||||
|
constantly==23.10.4
|
||||||
|
crispy-bootstrap5==2025.6
|
||||||
|
cryptography==45.0.5
|
||||||
|
cssbeautifier==1.15.4
|
||||||
|
daphne==4.2.1
|
||||||
|
defusedxml==0.7.1
|
||||||
|
diff-match-patch==20241021
|
||||||
|
distro==1.9.0
|
||||||
|
Django==5.2.4
|
||||||
|
django-allauth==65.10.0
|
||||||
|
django-appconf==1.1.0
|
||||||
|
django-appointment==3.8.0
|
||||||
|
django-background-tasks==1.2.8
|
||||||
|
django-bootstrap5==25.1
|
||||||
|
django-ckeditor==6.7.3
|
||||||
|
django-cors-headers==4.7.0
|
||||||
|
django-countries==7.6.1
|
||||||
|
django-crispy-forms==2.4
|
||||||
|
django-debug-toolbar==5.2.0
|
||||||
|
django-easy-audit==1.3.7
|
||||||
|
django-extensions==4.1
|
||||||
|
django-filter==25.1
|
||||||
|
django-imagekit==5.0.0
|
||||||
|
django-import-export==4.3.8
|
||||||
|
django-js-asset==3.1.2
|
||||||
|
django-ledger==0.7.6.1
|
||||||
|
django-manager-utils==3.1.5
|
||||||
|
django-next-url-mixin==0.4.0
|
||||||
|
django-ordered-model==3.7.4
|
||||||
|
django-phonenumber-field==8.0.0
|
||||||
|
django-picklefield==3.3
|
||||||
|
django-plans==2.0.0
|
||||||
|
django-prometheus==2.4.1
|
||||||
|
django-q2==1.8.0
|
||||||
|
django-query-builder==3.2.0
|
||||||
|
django-schema-graph==3.1.0
|
||||||
|
django-sequences==3.0
|
||||||
|
django-tables2==2.7.5
|
||||||
|
django-treebeard==4.7.1
|
||||||
|
django-widget-tweaks==1.5.0
|
||||||
|
djangorestframework==3.16.0
|
||||||
|
djhtml==3.0.8
|
||||||
|
djlint==1.36.4
|
||||||
|
docopt==0.6.2
|
||||||
|
EditorConfig==0.17.1
|
||||||
|
Faker==37.4.0
|
||||||
|
fleming==0.7.0
|
||||||
|
fonttools==4.58.5
|
||||||
|
fpdf==1.7.2
|
||||||
|
fpdf2==2.8.3
|
||||||
|
greenlet==3.2.3
|
||||||
|
gunicorn==23.0.0
|
||||||
|
h11==0.16.0
|
||||||
|
h2==4.2.0
|
||||||
|
hpack==4.1.0
|
||||||
|
httpcore==1.0.9
|
||||||
|
httpx==0.28.1
|
||||||
|
hyperframe==6.1.0
|
||||||
|
hyperlink==21.0.0
|
||||||
|
icalendar==6.3.1
|
||||||
|
idna==3.10
|
||||||
|
incremental==24.7.2
|
||||||
|
jiter==0.10.0
|
||||||
|
jsbeautifier==1.15.4
|
||||||
|
json5==0.12.0
|
||||||
|
jsonpatch==1.33
|
||||||
|
jsonpointer==3.0.0
|
||||||
|
jwt==1.4.0
|
||||||
|
langchain==0.3.26
|
||||||
|
langchain-core==0.3.68
|
||||||
|
langchain-ollama==0.3.4
|
||||||
|
langchain-text-splitters==0.3.8
|
||||||
|
langsmith==0.4.4
|
||||||
|
luhnchecker==0.0.12
|
||||||
|
Markdown==3.8.2
|
||||||
|
markdown-it-py==3.0.0
|
||||||
|
mdurl==0.1.2
|
||||||
|
num2words==0.5.14
|
||||||
|
numpy==2.3.1
|
||||||
|
ofxtools==0.9.5
|
||||||
|
ollama==0.5.1
|
||||||
|
openai==1.93.3
|
||||||
|
opencv-python==4.11.0.86
|
||||||
|
orjson==3.10.18
|
||||||
|
packaging==24.2
|
||||||
|
pandas==2.3.1
|
||||||
|
pathspec==0.12.1
|
||||||
|
phonenumbers==8.13.42
|
||||||
|
pilkit==3.0
|
||||||
|
pillow==10.4.0
|
||||||
|
priority==1.3.0
|
||||||
|
prometheus_client==0.22.1
|
||||||
|
psycopg2-binary==2.9.10
|
||||||
|
pyasn1==0.6.1
|
||||||
|
pyasn1_modules==0.4.2
|
||||||
|
pycparser==2.22
|
||||||
|
pydantic==2.11.7
|
||||||
|
pydantic_core==2.33.2
|
||||||
|
Pygments==2.19.2
|
||||||
|
pyOpenSSL==25.1.0
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-slugify==8.0.4
|
||||||
|
python-stdnum==2.1
|
||||||
|
pytz==2025.2
|
||||||
|
pyvin==0.0.2
|
||||||
|
PyYAML==6.0.2
|
||||||
|
pyzbar==0.1.9
|
||||||
|
redis==6.2.0
|
||||||
|
regex==2024.11.6
|
||||||
|
requests==2.32.4
|
||||||
|
requests-toolbelt==1.0.0
|
||||||
|
rich==14.0.0
|
||||||
|
ruff==0.12.2
|
||||||
|
service-identity==24.2.0
|
||||||
|
setuptools==80.9.0
|
||||||
|
six==1.17.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
soupsieve==2.7
|
||||||
|
SQLAlchemy==2.0.41
|
||||||
|
sqlparse==0.5.3
|
||||||
|
suds==1.2.0
|
||||||
|
swapper==1.3.0
|
||||||
|
tablib==3.8.0
|
||||||
|
tenacity==9.1.2
|
||||||
|
text-unidecode==1.3
|
||||||
|
tqdm==4.67.1
|
||||||
|
Twisted==25.5.0
|
||||||
|
txaio==25.6.1
|
||||||
|
types-python-dateutil==2.9.0.20250708
|
||||||
|
typing-inspection==0.4.1
|
||||||
|
typing_extensions==4.14.1
|
||||||
|
tzdata==2025.2
|
||||||
|
urllib3==2.5.0
|
||||||
|
uvicorn==0.35.0
|
||||||
|
uvicorn-worker==0.3.0
|
||||||
|
wcwidth==0.2.13
|
||||||
|
zope.interface==7.2
|
||||||
|
zstandard==0.23.0
|
||||||
@ -372,7 +372,11 @@
|
|||||||
hideLoading();
|
hideLoading();
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
notify("success","{% trans'Account created successfully'%}");
|
<<<<<<< HEAD
|
||||||
|
notify("success","{% trans 'Account created successfully'%}");
|
||||||
|
=======
|
||||||
|
notify("success","Account created successfully");
|
||||||
|
>>>>>>> d3dcb85fa378e156b77550e8ab833ad10ffad51f
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = "{% url 'account_login' %}";
|
window.location.href = "{% url 'account_login' %}";
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|||||||
@ -68,7 +68,7 @@
|
|||||||
<div class="col-12 col-sm-auto d-flex align-items-center justify-content-around flex-wrap mt-3 mt-sm-0">
|
<div class="col-12 col-sm-auto d-flex align-items-center justify-content-around flex-wrap mt-3 mt-sm-0">
|
||||||
<div class="text-center mx-3 mb-2 mb-sm-0">
|
<div class="text-center mx-3 mb-2 mb-sm-0">
|
||||||
<h6 class="mb-2 text-body-secondary">{% trans 'Total users'|capfirst %}</h6>
|
<h6 class="mb-2 text-body-secondary">{% trans 'Total users'|capfirst %}</h6>
|
||||||
<h4 class="fs-7 text-body-highlight mb-2">{{ dealer.staff_count }} / {{ allowed_users }}</h4>
|
<h4 class="fs-7 text-body-highlight mb-2">{{ dealer.staff_count }}</h4>
|
||||||
<div class="progress" style="height: 5px; width: 100px;">
|
<div class="progress" style="height: 5px; width: 100px;">
|
||||||
<div class="progress-bar bg-success"
|
<div class="progress-bar bg-success"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
@ -80,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-center mx-3 mb-2 mb-sm-0">
|
<div class="text-center mx-3 mb-2 mb-sm-0">
|
||||||
<h6 class="mb-2 text-body-secondary">{% trans 'Total cars'|capfirst %}</h6>
|
<h6 class="mb-2 text-body-secondary">{% trans 'Total cars'|capfirst %}</h6>
|
||||||
<h4 class="fs-7 text-body-highlight mb-2">{{ cars_count }} / {{ allowed_cars }}</h4>
|
<h4 class="fs-7 text-body-highlight mb-2">{{ cars_count }}</h4>
|
||||||
<div class="progress" style="height: 5px; width: 100px;">
|
<div class="progress" style="height: 5px; width: 100px;">
|
||||||
<div class="progress-bar bg-info"
|
<div class="progress-bar bg-info"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
@ -150,56 +150,56 @@
|
|||||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||||
<h3 class="mb-0">{{ dealer.user.userplan.plan|capfirst }}</h3>
|
<h3 class="mb-0">{{ dealer.user.userplan.plan|capfirst }}</h3>
|
||||||
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
||||||
<span class="badge bg-success-subtle text-success">{{ _("Active") }}</span>
|
<span class="badge bg-success-subtle text-success">{{ _("Active") }}</span>
|
||||||
{% elif dealer.user.userplan and dealer.user.userplan.is_expired %}
|
{% elif dealer.user.userplan and dealer.user.userplan.is_expired %}
|
||||||
<span class="badge bg-danger-subtle text-danger">{{ _("Expired") }}</span>
|
<span class="badge bg-danger-subtle text-danger">{{ _("Expired") }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-warning-subtle text-warning">{{ _("No Active Plan") }}</span>
|
<span class="badge bg-warning-subtle text-warning">{{ _("No Active Plan") }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<p class="fs-9 text-body-secondary">
|
<p class="fs-9 text-body-secondary">
|
||||||
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
{% if dealer.user.userplan and not dealer.user.userplan.is_expired %}
|
||||||
{% trans 'Active until' %}: {{ dealer.user.userplan.expire }} <small>{% trans 'Days left' %}: {{ dealer.user.userplan.days_left }}</small>
|
{% trans 'Active until' %}: {{ dealer.user.userplan.expire }} <small>{% trans 'Days left' %}: {{ dealer.user.userplan.days_left }}</small>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans 'Please subscribe or renew your plan to continue using our services.' %}
|
{% trans 'Please subscribe or renew your plan to continue using our services.' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<div class="d-flex align-items-end mb-3">
|
<div class="d-flex align-items-end mb-3">
|
||||||
<h4 class="fw-bolder me-1">
|
<h4 class="fw-bolder me-1">
|
||||||
{{ dealer.user.userplan.plan.planpricing_set.first.price }} <span class="icon-saudi_riyal"></span>
|
{{ dealer.user.userplan.plan.planpricing_set.first.price }} <span class="icon-saudi_riyal"></span>
|
||||||
</h4>
|
</h4>
|
||||||
<h5 class="fs-9 fw-normal text-body-tertiary ms-1">{{ _("Per month") }}</h5>
|
<h5 class="fs-9 fw-normal text-body-tertiary ms-1">{{ _("Per month") }}</h5>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-unstyled mb-4">
|
<ul class="list-unstyled mb-4">
|
||||||
{% for line in dealer.user.userplan.plan.description|splitlines %}
|
{% for line in dealer.user.userplan.plan.description|splitlines %}
|
||||||
<li class="d-flex align-items-center mb-1">
|
<li class="d-flex align-items-center mb-1">
|
||||||
<span class="uil uil-check-circle text-success me-2"></span>
|
<span class="uil uil-check-circle text-success me-2"></span>
|
||||||
<span class="text-body-secondary">{{ line }}</span>
|
<span class="text-body-secondary">{{ line }}</span>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% comment %} <div class="d-flex justify-content-end gap-2">
|
{% comment %} <div class="d-flex justify-content-end gap-2">
|
||||||
{% if dealer.user.userplan.is_expired %}
|
{% if dealer.user.userplan.is_expired %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if dealer.user.userplan.plan.name != "Enterprise" %}
|
{% if dealer.user.userplan.plan.name != "Enterprise" %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not dealer.user.userplan %}
|
{% if not dealer.user.userplan %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-success"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-success"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
<div class="d-flex justify-content-end gap-2">
|
<div class="d-flex justify-content-end gap-2">
|
||||||
{% if not dealer.user.userplan %}
|
{% if not dealer.user.userplan %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
||||||
class="btn btn-outline-primary"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
class="btn btn-outline-primary"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
||||||
{% elif dealer.user.userplan.is_expired %}
|
{% elif dealer.user.userplan.is_expired %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
||||||
class="btn btn-outline-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
class="btn btn-outline-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
||||||
{% elif dealer.user.userplan.plan.name != "Enterprise" %}
|
{% elif dealer.user.userplan.plan.name != "Enterprise" %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
<a href="{% url 'pricing_page' request.dealer.slug %}"
|
||||||
class="btn btn-outline-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
class="btn btn-outline-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -221,8 +221,8 @@
|
|||||||
aria-valuemax="100"></div>
|
aria-valuemax="100"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
||||||
<span>{{ _("Used") }}: {{ dealer.staff_count }}</span>
|
<span>{{ _("Used") }}: {{ dealer.staff_count }}</span>
|
||||||
<span>{{ _("Limit") }}: {{ allowed_users }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
@ -236,8 +236,8 @@
|
|||||||
aria-valuemax="100"></div>
|
aria-valuemax="100"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
<div class="d-flex justify-content-between text-body-secondary fs-9 mt-2">
|
||||||
<span>{{ _("Used") }}: {{ cars_count }}</span>
|
<span>{{ _("Used") }}: {{ cars_count }}</span>
|
||||||
<span>{{ _("Limit") }}: {{ allowed_cars }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<small class="text-body-secondary mt-auto">{{ _("Contact support to increase your limits") }}</small>
|
<small class="text-body-secondary mt-auto">{{ _("Contact support to increase your limits") }}</small>
|
||||||
@ -258,22 +258,22 @@
|
|||||||
<div class="d-flex align-items-center mb-3">
|
<div class="d-flex align-items-center mb-3">
|
||||||
<span class="fas fa-location-dot me-3 text-primary"></span>
|
<span class="fas fa-location-dot me-3 text-primary"></span>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-0">{% trans 'Address' %}</h6>
|
<h6 class="mb-0">{% trans 'Address' %}</h6>
|
||||||
<p class="mb-0 text-body-secondary">{{ dealer.address }}</p>
|
<p class="mb-0 text-body-secondary">{{ dealer.address }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center mb-3">
|
<div class="d-flex align-items-center mb-3">
|
||||||
<span class="fas fa-envelope me-3 text-info"></span>
|
<span class="fas fa-envelope me-3 text-info"></span>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-0">{% trans 'Email' %}</h6>
|
<h6 class="mb-0">{% trans 'Email' %}</h6>
|
||||||
<p class="mb-0 text-body-secondary">{{ dealer.user.email }}</p>
|
<p class="mb-0 text-body-secondary">{{ dealer.user.email }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<span class="fas fa-phone me-3 text-success"></span>
|
<span class="fas fa-phone me-3 text-success"></span>
|
||||||
<div>
|
<div>
|
||||||
<h6 class="mb-0">{% trans 'Phone' %}</h6>
|
<h6 class="mb-0">{% trans 'Phone' %}</h6>
|
||||||
<p class="mb-0 text-body-secondary" dir="ltr">{{ dealer.phone_number }}</p>
|
<p class="mb-0 text-body-secondary" dir="ltr">{{ dealer.phone_number }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -285,11 +285,11 @@
|
|||||||
<h5 class="mb-3">{{ _("VAT Information") }}</h5>
|
<h5 class="mb-3">{{ _("VAT Information") }}</h5>
|
||||||
<form action="{% url 'dealer_vat_rate_update' request.dealer.slug %}"
|
<form action="{% url 'dealer_vat_rate_update' request.dealer.slug %}"
|
||||||
method="post">
|
method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ vatform|crispy }}
|
{{ vatform|crispy }}
|
||||||
<button class="btn btn-phoenix-primary mt-3" type="submit">
|
<button class="btn btn-phoenix-primary mt-3" type="submit">
|
||||||
<i class="fa-solid fa-pen-to-square me-1"></i>{% trans 'Update VAT' %}
|
<i class="fa-solid fa-pen-to-square me-1"></i>{% trans 'Update VAT' %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -304,21 +304,21 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="mb-4">{{ _("Makes you are selling") }}</h5>
|
<h5 class="mb-4">{{ _("Makes you are selling") }}</h5>
|
||||||
<div class="d-flex flex-wrap gap-3 mb-4">
|
<div class="d-flex flex-wrap gap-3 mb-4">
|
||||||
{% for make in car_makes %}
|
{% for make in car_makes %}
|
||||||
<div class="text-center p-2 border rounded-3">
|
<div class="text-center p-2 border rounded-3">
|
||||||
{% if make.logo %}
|
{% if make.logo %}
|
||||||
<img src="{{ make.logo.url }}"
|
<img src="{{ make.logo.url }}"
|
||||||
alt="{{ make.get_local_name }}"
|
alt="{{ make.get_local_name }}"
|
||||||
class="rounded"
|
class="rounded"
|
||||||
style="height: 48px;
|
style="height: 48px;
|
||||||
width: auto;
|
width: auto;
|
||||||
background-color:white" />
|
background-color:white" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="fs-8 text-body-secondary mt-1 mb-0">{{ make.get_local_name }}</p>
|
<p class="fs-8 text-body-secondary mt-1 mb-0">{{ make.get_local_name }}</p>
|
||||||
</div>
|
</div>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<p class="text-body-secondary">{{ _("No car makes selected.") }}</p>
|
<p class="text-body-secondary">{{ _("No car makes selected.") }}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-phoenix-warning"
|
<a class="btn btn-phoenix-warning"
|
||||||
href="{% url 'assign_car_makes' request.dealer.slug %}"><span class="fas fa-plus me-2"></span>{{ _("Select Makes") }}</a>
|
href="{% url 'assign_car_makes' request.dealer.slug %}"><span class="fas fa-plus me-2"></span>{{ _("Select Makes") }}</a>
|
||||||
@ -331,4 +331,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -238,10 +238,10 @@
|
|||||||
class="btn btn-phoenix-primary btn-sm mt-1 me-3 mb-3">{% trans "Edit" %}
|
class="btn btn-phoenix-primary btn-sm mt-1 me-3 mb-3">{% trans "Edit" %}
|
||||||
<span class="fas fa-solid fa-pencil ms-1"></span>
|
<span class="fas fa-solid fa-pencil ms-1"></span>
|
||||||
</a>
|
</a>
|
||||||
<a href="{% url 'transfer' car.slug %}"
|
{% comment %} <a href="{% url 'transfer' car.slug %}"
|
||||||
class="btn btn-phoenix-danger btn-sm">
|
class="btn btn-phoenix-danger btn-sm">
|
||||||
{% trans "Sell to another dealer"|capfirst %}
|
{% trans "Sell to another dealer"|capfirst %}
|
||||||
</a>
|
</a> TODO: for future {% endcomment %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-danger">{% trans "Cannot Edit, Car in Transfer." %}</span>
|
<span class="badge bg-danger">{% trans "Cannot Edit, Car in Transfer." %}</span>
|
||||||
@ -267,7 +267,7 @@
|
|||||||
<th>{% trans "Marked Price"|capfirst %}</th>
|
<th>{% trans "Marked Price"|capfirst %}</th>
|
||||||
<td>{{ car.marked_price|floatformat:2 }}</td>
|
<td>{{ car.marked_price|floatformat:2 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
{% if not car.get_transfer %}
|
{% if not car.get_transfer %}
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
<p class="text-muted">{% trans 'Report Date' %}: {{ current_time }}</p>
|
<p class="text-muted">{% trans 'Report Date' %}: {{ current_time }}</p>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<section id="filters" class="mb-5 p-4 rounded border border-primary">
|
<section id="filters" class="mb-5 p-4 rounded border border-primary">
|
||||||
<h2 class="section-heading mb-4">
|
<h2 class="section-heading mb-4">
|
||||||
{% trans 'Filters' %} <i class="fas fa-sliders-h ms-2"></i>
|
{% trans 'Filters' %} <i class="fas fa-sliders-h ms-2"></i>
|
||||||
</h2>
|
</h2>
|
||||||
@ -58,7 +58,8 @@
|
|||||||
<option value="">{% trans 'All Makes' %}</option>
|
<option value="">{% trans 'All Makes' %}</option>
|
||||||
{% for make in makes %}
|
{% for make in makes %}
|
||||||
<option value="{{ make }}" {% if make == selected_make %}selected{% endif %}>{{ make }}</option>
|
<option value="{{ make }}" {% if make == selected_make %}selected{% endif %}>{{ make }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<label for="model-select" class="form-label">{% trans 'Model' %}</label>
|
<label for="model-select" class="form-label">{% trans 'Model' %}</label>
|
||||||
@ -111,7 +112,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
<!---->
|
||||||
|
{% comment %} 'cars_sold': cars_sold,
|
||||||
|
'current_time': current_time,
|
||||||
|
'dealer': dealer,
|
||||||
|
'total_revenue_from_cars': total_revenue_from_cars,
|
||||||
|
'total_revenue_from_additonals':total_revenue_from_additonals,
|
||||||
|
'total_revenue_collected': total_revenue_collected,
|
||||||
|
'total_vat_on_cars':total_vat_on_cars,
|
||||||
|
'total_vat_from_additonals':total_vat_from_additonals,
|
||||||
|
'total_vat_collected':total_vat_collected,
|
||||||
|
'total_discount': total_discount,
|
||||||
|
'makes': makes,
|
||||||
|
'models': models_qs,
|
||||||
|
'series': series,
|
||||||
|
'years': years,
|
||||||
|
'selected_make': selected_make,
|
||||||
|
'selected_model': selected_model,
|
||||||
|
'selected_serie': selected_serie,
|
||||||
|
'selected_year': selected_year, {% endcomment %}
|
||||||
|
<!---->
|
||||||
<section id="summary" class="mb-5">
|
<section id="summary" class="mb-5">
|
||||||
<h2 class="section-heading mb-4 border-start border-5 border-primary p-2">{% trans 'Report Summary' %}</h2>
|
<h2 class="section-heading mb-4 border-start border-5 border-primary p-2">{% trans 'Report Summary' %}</h2>
|
||||||
<div class="row g-4">
|
<div class="row g-4">
|
||||||
@ -267,13 +287,13 @@
|
|||||||
<span>{{ car.discount }} <span class="icon-saudi_riyal"></span></span>
|
<span>{{ car.discount }} <span class="icon-saudi_riyal"></span></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="fs-9 text-nowrap">
|
<td class="fs-9 text-nowrap">
|
||||||
<span >{{ car.final_price }} <span class="icon-saudi_riyal"></span></span>
|
<span>{{ car.final_price }} <span class="icon-saudi_riyal"></span></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="fs-9 text-nowrap">
|
<td class="fs-9 text-nowrap">
|
||||||
<span>{{ car.vat_amount|floatformat:2 }} <span class="icon-saudi_riyal"></span></span>
|
<span>{{ car.vat_amount|floatformat:2 }} <span class="icon-saudi_riyal"></span></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="fs-9 text-nowrap">
|
<td class="fs-9 text-nowrap">
|
||||||
<span >{{ car.get_additional_services.total|floatformat:2 }} <span class="icon-saudi_riyal"></span></span>
|
<span>{{ car.get_additional_services.total|floatformat:2 }} <span class="icon-saudi_riyal"></span></span>
|
||||||
</td>
|
</td>
|
||||||
<td class="fs-9 text-nowrap">
|
<td class="fs-9 text-nowrap">
|
||||||
<span>{{ car.get_additional_services.services_vat|floatformat:2 }}<span class="icon-saudi_riyal"></span></span>
|
<span>{{ car.get_additional_services.services_vat|floatformat:2 }}<span class="icon-saudi_riyal"></span></span>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user