This commit is contained in:
gitea 2025-02-26 12:26:30 +00:00
commit 0ecbee79f2
52 changed files with 1835 additions and 47939 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -34,6 +34,7 @@
<orderEntry type="library" name="popper.js" level="application" />
<orderEntry type="library" name="tempusdominus-bootstrap-4" level="application" />
<orderEntry type="library" name="chart.js" level="application" />
<orderEntry type="library" name="htmx.org" level="application" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="file://$PROJECT_DIR$" libraries="{@turf/turf, @zxing, apexcharts, bootstrap-icons, chart.js, fullcalendar, jquery, jquery-3.5.1, line, moment-timezone, moment.js, popper.js, quagga, sweetalert2, tempusdominus-bootstrap-4, tesseract.js}" />
<file url="file://$PROJECT_DIR$" libraries="{@turf/turf, @zxing, apexcharts, bootstrap-icons, chart.js, fullcalendar, htmx.org, jquery, jquery-3.5.1, line, moment-timezone, moment.js, popper.js, quagga, sweetalert2, tempusdominus-bootstrap-4, tesseract.js}" />
</component>
</project>

View File

@ -9,7 +9,7 @@ from import_export.resources import ModelResource
from .models import Car
# Define resource class
# # Define resource class
# class CarSerieResource(ModelResource):
# class Meta:
# model = models.CarSerie
@ -19,6 +19,15 @@ from .models import Car
# class CarSeriesAdmin(ExportMixin, admin.ModelAdmin):
# resource_class = CarSerieResource
class CarTrimResource(ModelResource):
class Meta:
model = models.CarTrim
@admin.register(models.CarTrim)
class CarTrimAdmin(ExportMixin, admin.ModelAdmin):
resource_class = CarTrimResource
admin.site.register(models.Dealer)
admin.site.register(models.Staff)
admin.site.register(models.Vendor)
@ -103,18 +112,18 @@ class CarSeriesAdmin(admin.ModelAdmin):
verbose_name = "Car Series"
@admin.register(models.CarTrim)
class CarTrimAdmin(admin.ModelAdmin):
# list_display = ('name',
# 'id_car_serie__name',
# 'id_car_serie__id_car_model__name',
# 'id_car_serie__id_car_model__id_car_make__name')
search_fields = ('name', 'arabic_name', 'id_car_serie__id_car_model__name')
list_filter = ('id_car_serie__id_car_model__id_car_make__is_sa_import',
'id_car_serie__id_car_model__id_car_make__name')
class Meta:
verbose_name = "Car Trim"
# @admin.register(models.CarTrim)
# class CarTrimAdmin(admin.ModelAdmin):
# list_display = ('name', 'arabic_name',
# 'id_car_serie__name',
# 'id_car_serie__id_car_model__name',
# 'id_car_serie__id_car_model__id_car_make__name')
# search_fields = ('name', 'arabic_name', 'id_car_serie__id_car_model__name')
# list_filter = ('id_car_serie__id_car_model__id_car_make__is_sa_import',
# 'id_car_serie__id_car_model__id_car_make__name')
#
# class Meta:
# verbose_name = "Car Trim"
@admin.register(models.CarSpecification)

View File

@ -2,51 +2,8 @@ from django.core.management.base import BaseCommand
from inventory.models import CarSerie
TRANSLATIONS = {
"Sedan": "سيدان",
"Coupe": "كوبيه",
"SUV 5 doors": "إس يو في - خمسة أبواب",
"Minivan": "ميني فان",
"Hatchback": "هاتشباك",
"Cabriolet": "سطح قابل للطي",
"Hatchback 5-doors": "هاتشباك - خمسة أبواب",
"Hatchback 5 doors": "هاتشباك - خمسة أبواب",
"Hatchback 3-doors": "هاتشباك - ثلاثة أبواب",
"Crossover": "كروس أوفر",
"Wagon": "واغن",
"SUV": "إس يو في",
"Wagon 5 doors": "واغن - خمسة أبواب",
"Roadster": "رودستر",
"SUV 5-doors": "إس يو في - خمسة أبواب",
"Wagon 5-doors": "واغن - خمسة أبواب",
"Sedan 4-doors": "سيدان - أربعة أبواب",
"Hatchback 3 doors": "هاتشباك - ثلاثة أبواب",
"Van": "فان",
"Pickup Double cabin": "بيك أب - غمارتين",
"Compactvan": "كومباكت فان",
"Pickup": "بيك أب",
"Microvan": "ميكروفان",
"Liftback": "ليفت باك",
"SUV 3-doors": "إس يو في - ثلاثة أبواب",
"Coupe 2-doors": "كوبيه - بابين",
"Pickup Single cabin": "بيك أب - غمارة واحدة",
"Crossover 5-doors": "كروس أوفر - خمسة أبواب",
"Coupe-Hardtop": "كوبيه هاردتوب",
"SUV 3 doors": "إس يو في - ثلاثة أبواب",
"Hardtop": "هاردتوب",
"Sedan 2-doors": "سيدان - بابين",
"Minivan 5-doors": "ميني فان - خمسة أبواب",
"Targa": "تارغا",
"SUV opened": "إس يو في مكشوف",
"Pickup One-and-a-half cabin": "بيك أب - غمارة ونصف",
"Sedan 2 doors": "سيدان - بابين",
"AMG Sedan 4-doors": "أي إم جي سيدان - أربعة أبواب",
"Cabriolet 2-doors": "سطح قابل للطي - بابين",
"Fastback": "فاست باك",
"Sedan-Hardtop": "سيدان هاردتوب",
"Regular Cab pickup 2-doors": "بيك أب كابينة عادية - بابين",
"Grand minivan 5-doors": "ميني فان كبير - خمسة أبواب",
"Sedan Long": "سيدان طويل",
"Speedster": "سبيدستر",
"Liftback 5-doors": "ليفت باك - خمسة أبواب",
}

View File

@ -0,0 +1,22 @@
# Generated by Django 5.1.6 on 2025-02-24 17:25
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0048_remove_dealersettings_bill_payable_account_and_more'),
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
]
operations = [
migrations.AddField(
model_name='carreservation',
name='reserved_for',
field=models.ForeignKey(default='dd747dc3-39bc-411f-a17d-c930a50220fe', on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL, verbose_name='Reserved For'),
preserve_default=False,
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 5.1.6 on 2025-02-25 01:05
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('inventory', '0049_carreservation_reserved_for'),
]
operations = [
migrations.RemoveField(
model_name='carreservation',
name='reserved_for',
),
]

View File

@ -538,9 +538,16 @@ class CarReservation(models.Model):
related_name="reservations",
verbose_name=_("Reserved By"),
)
# reserved_for = models.ForeignKey(
# CustomerModel,
# on_delete=models.CASCADE,
# related_name="reservations",
# verbose_name=_("Reserved For"),
# )
reserved_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Reserved At"))
reserved_until = models.DateTimeField(verbose_name=_("Reserved Until"))
@property
def is_active(self):
return self.reserved_until > now()

View File

@ -46,6 +46,7 @@ urlpatterns = [
# path("user/<int:pk>/settings/", views.UserSettingsView.as_view(), name="user_settings"),
path("dealer/<int:pk>/settings/", views.DealerSettingsView, name="dealer_settings"),
path("dashboards/manager/", views.ManagerDashboard.as_view(), name="manager_dashboard"),
path("dashboards/sales/", views.SalesDashboard.as_view(), name="sales_dashboard"),
path("test/", views.TestView.as_view(), name="test"),
path('cars/inventory/table/', views.CarListViewTable.as_view(), name="car_table"),
path("export/format/", TableExport, name="export"),

View File

@ -318,15 +318,6 @@ class TestView(TemplateView):
class ManagerDashboard(LoginRequiredMixin, TemplateView):
template_name = "dashboards/manager.html"
def dispatch(self, request, *args, **kwargs):
if (
# not any(hasattr(request.user, attr) for attr in ["dealer", "subdealer"])
not request.user.is_authenticated
):
# messages.error(request, _("You are not associated with any dealer."))
return redirect("welcome")
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
dealer = get_user_type(self.request)
@ -355,7 +346,7 @@ class ManagerDashboard(LoginRequiredMixin, TemplateView):
sold_percentage = sold_cars / total_cars * 100
qs = models.Car.objects.values('id_car_make__name').annotate(count=Count('id')).order_by('id_car_make__name')
car_by_make = list(qs)
print(qs)
context["dealer"] = dealer
context["total_cars"] = total_cars
context["total_reservations"] = total_reservations
@ -378,6 +369,57 @@ class ManagerDashboard(LoginRequiredMixin, TemplateView):
return context
class SalesDashboard(LoginRequiredMixin, TemplateView):
template_name = "dashboards/sales.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
dealer = get_user_type(self.request)
staff = getattr(self.request.user, "staff", None)
total_cars = models.Car.objects.filter(dealer=dealer).count()
total_reservations = models.CarReservation.objects.filter(
reserved_by=self.request.user,
reserved_until__gte=timezone.now()
).count()
# new_leads = models.Lead.objects.filter(dealer=dealer, status=models.Status.NEW).count()
pending_leads = models.Lead.objects.filter(dealer=dealer, dealer__staff__assigned=staff, status=models.Status.PENDING).count()
# canceled_leads = models.Lead.objects.filter(dealer=dealer, status=models.Status.CANCELED).count()
available_cars = models.Car.objects.filter(dealer=dealer, status=models.CarStatusChoices.AVAILABLE).count()
sold_cars = models.Car.objects.filter(dealer=dealer, status=models.CarStatusChoices.SOLD).count()
reserved_cars = models.Car.objects.filter(dealer=dealer, status=models.CarStatusChoices.RESERVED).count()
hold_cars = models.Car.objects.filter(dealer=dealer, status=models.CarStatusChoices.HOLD).count()
damaged_cars = models.Car.objects.filter(dealer=dealer, status=models.CarStatusChoices.DAMAGED).count()
transfer_cars = models.Car.objects.filter(dealer=dealer, status=models.CarStatusChoices.TRANSFER).count()
reserved_percentage = reserved_cars / total_cars * 100
sold_percentage = sold_cars / total_cars * 100
qs = models.Car.objects.values('id_car_make__name').annotate(count=Count('id')).order_by('id_car_make__name')
car_by_make = list(qs)
context["dealer"] = dealer
context["staff"] = staff
context["total_cars"] = total_cars
context["total_reservations"] = total_reservations
# context["total_cost_price"] = total_cost_price
# context["total_selling_price"] = total_selling_price
# context["total_profit"] = total_profit
# context['new_leads'] = new_leads
# context['pending_leads'] = pending_leads
# context['canceled_leads'] = canceled_leads
context['reserved_percentage'] = reserved_percentage
context['sold_percentage'] = sold_percentage
context['available_cars'] = available_cars
context['sold_cars'] = sold_cars
context['reserved_cars'] = reserved_cars
context['hold_cars'] = hold_cars
context['damaged_cars'] = damaged_cars
context['transfer_cars'] = transfer_cars
context['car'] = json.dumps(car_by_make)
return context
class WelcomeView(TemplateView):
template_name = "welcome.html"

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
static/.DS_Store vendored

Binary file not shown.

BIN
static/assets/.DS_Store vendored Normal file

Binary file not shown.

BIN
static/assets/fonts/.DS_Store vendored Normal file

Binary file not shown.

321
static/css/line.css Normal file

File diff suppressed because one or more lines are too long

BIN
static/fonts/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

2
static/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
static/vendors/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
static/vendors/htmx.min.js vendored Normal file

File diff suppressed because one or more lines are too long

88
static/vendors/turf.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -38,8 +38,8 @@
<link href="{% static 'vendors/simplebar/simplebar.min.css' %}" rel="stylesheet">
<link href="{% static 'vendors/flatpickr/flatpickr.min.css' %}" rel="stylesheet">
<link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.8/css/line.css">
<link href="{% static 'css/custom.css' %}" rel="stylesheet">
<link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.8/css/line.css">
{% if LANGUAGE_CODE == 'en' %}
<link href="{% static 'css/theme.min.css' %}" type="text/css" rel="stylesheet" id="style-default">
<link href="{% static 'css/user.min.css' %}" type="text/css" rel="stylesheet" id="user-style-default">
@ -48,11 +48,17 @@
<link href="{% static 'css/user-rtl.min.css' %}" type="text/css" rel="stylesheet" id="user-style-rtl">
{% endif %}
<script src="{% static 'js/main.js' %}"></script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"
integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/echarts.js' %}"></script>
<!--<style>
.btn{
padding-top: 4px;
padding-right: 16px;
padding-left: 16px;
padding-bottom: 4px;
}
</style>-->
{% block customCSS %}
{% endblock %}
</head>
@ -72,7 +78,7 @@
{% block body %}
{% endblock body%}
<div class="my-3"></div>
{% include 'footer.html' %}
</div>
@ -97,7 +103,7 @@
<script src="{% static 'vendors/feather-icons/feather.min.js' %}"></script>
<script src="{% static 'vendors/dayjs/dayjs.min.js' %}"></script>
<script src="{% static 'js/phoenix.js' %}"></script>
<script src="{% static 'js/apexcharts.js' %}"></script>
<script src="{% static 'vendors/echarts/echarts.min.js' %}"></script>
<script src="{% static 'js/crm-analytics.js' %}"></script>
<script src="{% static 'js/travel-agency-dashboard.js' %}"></script>
@ -105,7 +111,8 @@
<script src="{% static 'js/projectmanagement-dashboard.js' %}"></script>
<script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script>
<script src="{% static 'vendors/turf.min.js' %}"></script>
<script src="{% static 'vendors/htmx.min.js' %}"></script>
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
<script src="{% static 'vendors/flatpickr/flatpickr.min.js' %}"></script>

View File

@ -111,45 +111,54 @@
<table class="table table-sm fs-9 mb-0">
<thead>
<tr>
<th class="sort white-space-nowrap align-middle ps-0 pe-3" scope="col" data-sort="order" style="width:30%;">{% trans 'Type'|upper %}</th>
<th class="sort align-middle text-end pe-7" scope="col" data-sort="total" style="width:10%;">{% trans 'Total'|upper %}</th>
<th class="sort align-middle white-space-nowrap pe-3" scope="col" data-sort="payment_status" style="width:20%;">{% trans 'Payment Status'|upper %}</th>
<th class="sort align-middle white-space-nowrap text-start pe-3" scope="col" data-sort="fulfilment_status" style="width:20%;">{% trans 'Fulfilment Status'|upper %}</th>
<th class="sort white-space-nowrap align-middle ps-0 pe-3" scope="col" data-sort="order">{% trans 'Type'|upper %}</th>
<th class="sort align-middle text-end pe-7" scope="col" data-sort="total">{% trans 'Total'|upper %}</th>
<th class="sort align-middle white-space-nowrap pe-3" scope="col" data-sort="payment_status">{% trans 'Payment Status'|upper %}</th>
<th class="sort align-middle text-end pe-0" scope="col" data-sort="date">{% trans 'Date'|upper %}</th>
<th class="sort text-end align-middle pe-0 ps-5" scope="col"></th>
</tr>
</thead>
<tbody class="list" id="customer-order-table-body">
{% for estimate in estimates %}
{% for estimate in estimates %}
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="order align-middle white-space-nowrap ps-0">
<p class="fw-semibold mb-0" >{{ estimate.estimate_number }}</p>
<p class="fw-semibold mb-0" >{{ _("Quotation") }}-<span class="fs-10 fw-medium">{{ estimate.estimate_number }}</span></p>
</td>
<td class="total align-middle text-end fw-semibold pe-7 text-body-highlight">{{ estimate.revenue_estimate|currency_format }}</td>
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary">
</td>
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">{{ estimate.created }}</td>
<td class="align-middle white-space-nowrap text-end pe-0 ps-5">
<div class="btn-reveal-trigger position-static">
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
<div class="dropdown-menu dropdown-menu-end py-2"><a class="dropdown-item" href="#!">View</a><a class="dropdown-item" href="#!">Export</a>
<div class="dropdown-divider"></div><a class="dropdown-item text-danger" href="#!">Remove</a>
</div>
</div>
</td>
</tr>
{% endfor %}
{% for invoice in invoices %}
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="order align-middle white-space-nowrap ps-0">
<p class="fw-semibold mb-0" >{{ _("Invoice") }}-<span class="fs-10 fw-medium">{{ invoice.invoice_number }}</span></p>
</td>
<td class="total align-middle text-end fw-semibold pe-7 text-body-highlight">{{ invoice.amount_paid|currency_format }}</td>
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary">
{% if invoice.is_paid %}
<span class="badge badge-phoenix fs-10 badge-phoenix-success">
<span class="badge-label">Paid</span>
<span class="badge-label">{{ _("Paid") }}</span>
<span class="ms-1" data-feather="check" style="height:12.8px;width:12.8px;"></span>
</span>
{% endif %}
</td>
<td class="fulfilment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary">
{% if estimate.status == 'draft' %}
<span class="badge badge-phoenix badge-phoenix-warning">{% trans "Draft" %}</span>
{% elif estimate.status == 'in_review' %}
<span class="badge badge-phoenix badge-phoenix-info">{% trans "In Review" %}</span>
{% elif estimate.status == 'approved' %}
<span class="badge badge-phoenix badge-phoenix-success">{% trans "Approved" %}</span>
{% elif estimate.status == 'declined' %}
<span class="badge badge-phoenix badge-phoenix-danger">{% trans "Declined" %}</span>
{% elif estimate.status == 'canceled' %}
<span class="badge badge-phoenix badge-phoenix-danger">{% trans "Canceled" %}</span>
{% elif estimate.status == 'completed' %}
<span class="badge badge-phoenix badge-phoenix-success">{% trans "Completed" %}</span>
{% elif estimate.status == 'void' %}
<span class="badge badge-phoenix badge-phoenix-secondary">{% trans "Void" %}</span>
{% endif %}
</td>
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">{{ estimate.created }}</td>
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">{{ invoice.created }}</td>
<td class="align-middle white-space-nowrap text-end pe-0 ps-5">
<div class="btn-reveal-trigger position-static">
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>

View File

@ -1,7 +1,7 @@
{% extends 'base.html' %}
{% load i18n static custom_filters %}
{% load i18n static custom_filters django_ledger%}
{% block content %}
<script src="{% static 'js/echarts.js' %}"></script>
<div class="row justify-content-between">
<div class="col-12 col-lg-6">

View File

@ -0,0 +1,406 @@
{% extends 'base.html' %}
{% load i18n static custom_filters django_ledger%}
{% block content %}
<div class="row justify-content-between">
<div class="col-12 col-lg-6">
<div class="row g-2">
<h3 class="fs-4 fs-md-4 fs-xl-4 fw-black mb-4">
<span class="text-gradient-info me-3">{{ staff }}</span>
</h3>
<div class="card mb-3">
<div class="bg-holder" style="background-image:url({% static 'images/bg/38.png' %});background-position:left bottom;background-size:auto;"></div>
<div class="card-body d-flex justify-content-between position-relative">
<div class="col-sm-7 col-md-8 col-xxl-8 mb-md-3 mb-lg-0">
<h3 class="mb-3">{{ _("Inventory by Status")}}</h3>
<div class="row g-0">
<div class="col-6 col-xl-4">
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-bottom border-end border-translucent">
<div class="d-flex align-items-center mb-1"><span class="fa-solid fa-square fs-11 me-2 text-success" data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Available") }}</span></div>
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ available_cars }}</h3>
</div>
</div>
<div class="col-6 col-xl-4">
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-bottom border-end-md-0 border-end-xl border-translucent">
<div class="d-flex align-items-center mb-1"><span class="fa-solid fa-square fs-11 me-2 text-warning" data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Sold")}}</span></div>
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ sold_cars }}</h3>
</div>
</div>
<div class="col-6 col-xl-4">
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-bottom border-end border-end-md border-end-xl-0 border-translucent">
<div class="d-flex align-items-center mb-1"><span class="fa-solid fa-square fs-11 me-2 text-danger" data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Reserved") }}</span></div>
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ reserved_cars }}</h3>
</div>
</div>
<div class="col-6 col-xl-4">
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-end-xl border-bottom border-bottom-xl-0 border-translucent">
<div class="d-flex align-items-center mb-1"><span class="fa-solid fa-square fs-11 me-2 text-primary" data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Transfer") }}</span></div>
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ transfer_cars }}</h3>
</div>
</div>
<div class="col-6 col-xl-4">
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-end border-translucent">
<div class="d-flex align-items-center mb-1"><span class="fa-solid fa-square fs-11 me-2 text-warning-light" data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Hold") }}</span></div>
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ hold_cars }}</h3>
</div>
</div>
<div class="col-6 col-xl-4">
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100">
<div class="d-flex align-items-center mb-1"><span class="fa-solid fa-square fs-11 me-2 text-secondary-dark" data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Damaged") }}</span></div>
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ damaged_cars }}</h3>
</div>
</div>
</div>
</div>
<div class="col-sm-5 col-md-4 col-xxl-4 my-3 my-sm-0">
<div class="position-relative d-flex flex-center mb-sm-4 mb-xl-0 echart-cars-by-status-container mt-sm-7 mt-lg-4 mt-xl-0">
<div id="echart-cars-by-status" style="min-height:245px;width:100%"></div>
<div class="position-absolute rounded-circle bg-primary-subtle top-50 start-50 translate-middle d-flex flex-center" style="height:100px; width:100px;">
<h3 class="mb-0 text-primary-dark fw-bolder" data-label="data-label"></h3>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row g-2">
<div class="col-12 mb-8">
<div class="mb-3">
<h3>{{ _("New Leads and Customers")}}</h3>
<p class="text-body-tertiary mb-0">{{ _("Payment received across all channels")}}</p>
</div>
<div class="row g-6">
<div class="col-xl-6 mb-2 mb-sm-0">
<div class="d-flex align-items-center"><span class="me-2 text-info" data-feather="users" style="min-height:24px; width:24px"></span>
<h4 class="text-body-tertiary mb-0">{{ _("New Customers")}} :
<span class="text-body-emphasis"> 42</span>
</h4>
<span class="badge badge-phoenix fs-10 badge-phoenix-success d-inline-flex align-items-center ms-2">
<span class="badge-label d-inline-block lh-base">+24.5%</span>
<span class="ms-1 fa-solid fa-caret-up d-inline-block lh-1"></span>
</span>
</div>
<div class="pb-0 pt-4">
<div class="echarts-new-users" style="min-height:110px;width:100%;"></div>
</div>
</div>
<div class="col-md-6">
<div class="d-flex align-items-center"><span class="me-2 text-primary" data-feather="zap" style="height:24px; width:24px"></span>
<h4 class="text-body-tertiary mb-0">{{ _("New Leads")}} :<span class="text-body-emphasis"> 45</span></h4>
<span class="badge badge-phoenix fs-10 badge-phoenix-success d-inline-flex align-items-center ms-2">
<span class="badge-label d-inline-block lh-base">+30.5%</span>
<span class="ms-1 fa-solid fa-caret-up d-inline-block lh-1"></span>
</span>
</div>
<div class="pb-0 pt-4">
<div class="echarts-new-leads" style="min-height:110px;width:100%;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6">
<div class="row g-3 pe-xxl-3">
<div class="col-12 col-xl-6 col-xxl-12">
<div class="row">
<div class="col-6 col-xl-12 col-xxl-6 border-bottom border-end border-end-xl-0 border-end-xxl pb-4 pt-4 pt-xl-0 pt-xxl-4 pe-4 pe-sm-5 pe-xl-0 pe-xxl-5">
<h4 class="text-body mb-4">{% trans 'inventory'|upper %}</h4>
<div class="d-md-flex flex-between-center">
<div id="car-chart-by-make" class="order-sm-0 order-md-1" style="height:64px;width: 128px;"></div>
<div class="mt-4 mt-md-0">
<h1 class="text-body-highlight mb-2">{{ total_cars }}</h1>
<span class="badge badge-phoenix badge-phoenix-primary me-2 fs-10"> <span class="fs-10 text-body-secondary me-1">{{ _("As of")}}</span>{% now "SHORT_DATETIME_FORMAT" %}</span>
</div>
</div>
</div>
<div class="col-6 col-xl-12 col-xxl-6 border-bottom py-4 ps-4 ps-sm-5 ps-xl-0 ps-xxl-5">
<h4 class="text-body mb-4">{% trans 'inventory value'|upper %}</h4>
<div class="d-md-flex flex-between-center">
<div class="d-md-flex align-items-center gap-2 order-sm-0 order-md-1 fa-2x align-items-center">
<i class="fas fa-money-check-alt fs-4 text-success-light dark__text-opacity-75"></i>
<div class="d-flex d-md-block gap-2 align-items-center mt-1 mt-md-0">
<p class="fs-9 mb-0 mb-md-2 text-body-tertiary text-nowrap"></p>
<h4 class="text-body-highlight mb-0"></h4>
</div>
</div>
<div class="mt-3 mt-md-0">
<h3 class="text-body-highlight mb-2">{{ total_selling_price|currency_format }} {{ CURRENCY }}</h3>
</div>
</div>
</div>
<div class="col-6 col-xl-12 col-xxl-6 border-bottom-xl border-bottom-xxl-0 border-end border-end-xl-0 border-end-xxl py-4 pe-4 pe-sm-5 pe-xl-0 pe-xxl-5">
<h4 class="text-body mb-4">{% trans "Profits"|upper %}</h4>
<div class="d-md-flex flex-between-center">
<div class="d-md-flex align-items-center gap-2 order-sm-0 order-md-1">
<span class="fa-solid fa-money-bill-trend-up fs-4 text-warning-light dark__text-opacity-75" data-bs-theme="light"></span>
<div class="d-flex d-md-block gap-2 align-items-center mt-1 mt-md-0">
<p class="fs-9 mb-0 mb-md-2 text-body-tertiary text-nowrap"></p>
<h4 class="text-body-highlight mb-0"></h4>
</div>
</div>
<div class="mt-3 mt-md-0">
<h3 class="text-body-highlight mb-2">{{ total_profit|currency_format }} {{ CURRENCY }}</h3>
</div>
</div>
</div>
<div class="col-6 col-xl-12 col-xxl-6 py-4 ps-4 ps-sm-5 ps-xl-0 ps-xxl-5">
<h5 class="text-body mb-4">{{ _("Canceled Invoices")}}</h5>
<div class="d-md-flex flex-between-center">
<div class="chart-cancel-booking order-sm-0 order-md-1" style="height:54px; width:78px"></div>
<div class="mt-3 mt-md-0">
<h3 class="text-body-highlight mb-2">120.00</h3>
<span class="badge badge-phoenix badge-phoenix-danger me-2 fs-10"> <span class="fa-solid fa-plus me-1"></span>5.76%</span>
<span class="fs-9 text-body-secondary d-block d-sm-inline mt-1">{{ _("From last month")}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6 col-xxl-12 mb-3">
<div class="card h-100">
<div class="card-header pb-3">
<div class="row justify-content-between g-3">
<div class="col-auto">
<h3 class="text-body-highlight">{{ _("Gross Profit")}}</h3>
<p class="mb-0">Annual income according to the board</p>
</div>
</div>
</div>
<div class="card-body">
<div class="row align-items-center h-100 gy-5">
<div class="col-12 col-md-auto col-xl-12 col-xxl-auto order-md-1 order-xl-0 order-xxl-1 px-md-8 px-xl-6">
<div class="echart-gross-profit mx-auto mt-3 mt-md-0 mt-xl-3 mt-xxl-0" style="width: 250px; height: 250px"></div>
</div>
<div class="col-12 col-md-auto col-xl-12 col-xxl-auto flex-1 h-md-100">
<div class="d-flex flex-column justify-content-between h-md-100 h-xl-auto h-xxl-100">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex gap-2">
<div class="bullet-item bg-primary-light" data-bs-theme="light"></div>
<div>
<h6 class="mb-0 text-body fw-semibold mb-2">Flight</h6>
<h5 class="mb-0 text-body">$162,791,400</h5>
</div>
</div>
<div class="d-flex align-items-center gap-2 text-primary">
<span class="fw-bold" data-feather="trending-up" style="width: 24px; height: 24px"></span>
<p class="mb-0 fw-bold">15.50%</p>
</div>
</div>
<hr />
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex gap-2">
<div class="bullet-item bg-info-light" data-bs-theme="light"></div>
<div>
<h6 class="mb-0 text-body fw-semibold mb-2">Flight (Package)</h6>
<h5 class="mb-0 text-body">$135,659,500</h5>
</div>
</div>
<div class="d-flex align-items-center gap-2 text-danger">
<span class="fw-bold" data-feather="trending-down" style="width: 24px; height: 24px"></span>
<p class="mb-0 fw-bold">11.09%</p>
</div>
</div>
<hr />
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex gap-2">
<div class="bullet-item bg-warning-light" data-bs-theme="light"></div>
<div>
<h6 class="mb-0 text-body fw-semibold mb-2">Hotel</h6>
<h5 class="mb-0 text-body">$271,319,000</h5>
</div>
</div>
<div class="d-flex align-items-center gap-2 text-warning">
<span class="fw-bold" data-feather="trending-up" style="width: 24px; height: 24px"></span>
<p class="mb-0 fw-bold">29.98%</p>
</div>
</div>
<hr />
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex gap-2">
<div class="bullet-item bg-success-light" data-bs-theme="light"></div>
<div>
<h6 class="mb-0 text-body fw-semibold mb-2">Hotel (Package)</h6>
<h5 class="mb-0 text-body">$162,791,400</h5>
</div>
</div>
<div class="d-flex align-items-center gap-2 text-success">
<span class="fw-bold" data-feather="trending-up" style="width: 24px; height: 24px"></span>
<p class="mb-0 fw-bold">03.90%</p>
</div>
</div>
<hr class="d-none" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
/* Car Chart By Make */
const getColor = (name, dom = document.documentElement) => {
return getComputedStyle(dom).getPropertyValue(`--phoenix-${name}`).trim();
};
const handleTooltipPosition = ([pos, , dom, , size]) => {
// only for mobile device
if (window.innerWidth <= 540) {
const tooltipHeight = dom.offsetHeight;
const obj = {top: pos[1] - tooltipHeight - 20};
obj[pos[0] < size.viewSize[0] / 2 ? 'left' : 'right'] = 5;
return obj;
}
return null; // else default behaviour
};
const carData = {{ car|safe }}
const carNames = carData.map(item => item.id_car_make__name);
const carCounts = carData.map(item => item.count);
const car_chart = echarts.init(document.getElementById('car-chart-by-make'));
option = {
color: getColor("danger"),
tooltip: {
trigger: 'axis',
position: (...params) => handleTooltipPosition(params),
padding: [7, 10],
axisPointer: {
type: 'none'
},
},
extraCssText: 'z-index: 1000',
responsive: true,
xAxis: [
{
type: 'category',
boundaryGap: false,
data: carNames,
axisLine: {
show: true,
lineStyle: {color: getColor('secondary-bg')}
},
axisTick: {
show: false
},
}
],
yAxis: [
{
show: false,
type: 'value',
}
],
series: [
{
type: 'bar',
barWidth: 3,
backgroundStyle: {
borderRadius: [0.5, 0.5, 0, 0],
},
data: carCounts
},
],
grid: {
bottom: 0,
top: 0,
left: 10,
right: 10,
containLabel: false
}
};
car_chart.setOption(option);
/* Car Status Chart */
const chartElContainer = document.querySelector('.echart-cars-by-status-container');
const car_status = echarts.init(document.getElementById('echart-cars-by-status'));
const chartLabel = chartElContainer.querySelector('[data-label]');
const data = [
{value: {{available_cars}}, name: '{{ _("Available") }}'},
{value: {{sold_cars}}, name: '{{ _("Sold")}}'},
{value: {{reserved_cars}}, name: '{{ _("Reserved") }}'},
{value: {{transfer_cars}}, name: '{{ _("Transfer") }}'},
{value: {{hold_cars}}, name: '{{ _("Hold") }}'},
{value: {{damaged_cars}}, name: '{{ _("Damaged") }}'}
];
const totalCars = data.reduce((acc, val) => val.value + acc, 0);
if (chartLabel) {
chartLabel.innerHTML = totalCars;
}
option = {
color: [
getColor('success'),
getColor('warning'),
getColor('danger'),
getColor('primary'),
getColor('warning-lighter'),
getColor('secondary-dark')
],
tooltip: {
trigger: 'item',
padding: [7, 10],
backgroundColor: getColor('body-highlight-bg'),
borderColor: getColor('border-color'),
textStyle: {color: getColor('light-text-emphasis')},
borderWidth: 1,
transitionDuration: 0,
extraCssText: 'z-index: 1000'
},
responsive: true,
maintainAspectRatio: false,
series: [
{
name: '',
type: 'pie',
radius: ['55%', '90%'],
startAngle: 90,
avoidLabelOverlap: false,
itemStyle: {
borderColor: getColor('body-bg'),
borderWidth: 3
},
label: {
show: false
},
emphasis: {
label: {
show: false
}
},
labelLine: {
show: false
},
data
}
],
grid: {
bottom: 0,
top: 0,
left: 0,
right: 0,
containLabel: false
}
};
car_status.setOption(option);
});
</script>
{% endblock %}

View File

@ -32,7 +32,7 @@
<div class="text-danger">{{ error }}</div>
{% endfor %}
<div class="d-flex mb-3">
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "cancel"|capfirst %}</a>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "Cancel"|capfirst %}</a>
<button class="btn btn-primary" type="submit">
<i class="fa-solid fa-floppy-disk"></i>
{{ _("Save") }}

View File

@ -32,7 +32,7 @@
<div class="text-danger">{{ error }}</div>
{% endfor %}
<div class="d-flex mb-3">
<a href="{% url 'group_detail' group.pk %}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "cancel"|capfirst %}</a>
<a href="{% url 'group_detail' group.pk %}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "Cancel"|capfirst %}</a>
<button class="btn btn-primary" type="submit">
<i class="fa-solid fa-floppy-disk"></i>
{{ _("Save") }}

View File

@ -32,7 +32,7 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<a class="nav-link" href="{% url 'sales_dashboard' %}">
<div class="d-flex align-items-center"><span class="nav-link-text">{{ _("Sales") }}</span></div>
</a>
</li>

View File

@ -312,15 +312,17 @@
{% if reservation.is_active %}
<form method="post" action="{% url 'reservations' reservation.id %}">
{% csrf_token %}
<button type="submit" name="action" value="renew" class="btn btn-sm btn-phoenix-success">
{% trans "Renew" %}
</button>
<button type="submit" name="action" value="cancel" class="btn btn-sm btn-phoenix-secondary">
{% trans "Cancel" %}
</button>
<div class="btn-group">
<button type="submit" name="action" value="renew" class="btn btn-sm btn-phoenix-success px-3 py-1">
{% trans "Renew" %}
</button>
<button type="submit" name="action" value="cancel" class="btn btn-sm btn-phoenix-secondary px-3 py-1">
{% trans "Cancel" %}
</button>
</div>
</form>
{% else %}
<span class="badge bg-danger" style="width: 120px;">
<span class="badge badge-phoenix badge-phoenix-danger fs-10">
{% trans "Expired" %}
</span>
{% endif %}

View File

@ -12,11 +12,11 @@
<script src="https://unpkg.com/@zxing/library@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js"></script>
<div class="row">
<div class=" container-fluid m-0">
<form method="post" id="carForm" class="form needs-validation" novalidate>
{% csrf_token %}
{% include 'partials/form_errors.html' %}
<div class="d-flex flex-column min-vh-100">
<div class="d-flex flex-column">
<div class="d-flex flex-column flex-sm-grow-1 p-0">
<div class="row g-4">
@ -34,13 +34,13 @@
</div>
<div class="input-group input-group-sm my-2">
<button type="button"
class="btn btn-warning rounded-start"
class="btn btn-phoenix-warning rounded-start"
id="scan-vin-btn"
data-bs-toggle="modal"
data-bs-target="#scannerModal">
<span class="fas fa-camera fs-9"></span>
</button>
<button type="button" class="btn btn-sm btn-primary rounded-end ms-1" id="decodeVinBtn">
<button type="button" class="btn btn-sm btn-phoenix-primary rounded-end ms-1" id="decodeVinBtn">
<span class="fas fa-search fs-9 fw-bolder"></span>
</button>
</div>
@ -190,8 +190,8 @@
</div>
</div>
</div>
<!--Specifications Buttons-->
<div class="btn-group mt-3">
<!--Save Buttons-->
<div class="btn-group">
<button type="submit" name="add_another" value="true" class="btn btn-sm btn-phoenix-success me-1">
{% trans "Save and Add Another" %}
</button>

View File

@ -17,7 +17,7 @@
<div class="row justify-content-between">
<div class="col-6 col-md-4 col-xxl-2 text-center border-translucent border-start-xxl border-end-xxl-0 border-bottom-xxl-0 border-end border-bottom pb-4 pb-xxl-0 "><i class="fa-solid fa-landmark-dome fs-5 lh-1 text-primary"></i>
<h1 class="fs-5 pt-3">{% currency_symbol %}{{ tx_digest.group_balance.GROUP_ASSETS | currency_format }}</h1>
<p class="fs-9 mb-0">{{ _("Assets") }}</p>
<p class="fs-9 mb-0">{{ _("Assets") }}nmnmnmnmnmnm</p>
</div>
<div class="col-6 col-md-4 col-xxl-2 text-center border-translucent border-start-xxl border-end-xxl-0 border-bottom-xxl-0 border-end-md border-bottom pb-4 pb-xxl-0"><i class="fa-solid fa-weight-hanging fs-5 lh-1 text-primary"></i>
<h1 class="fs-5 pt-3">{% currency_symbol %}{{ tx_digest.group_balance.GROUP_LIABILITIES | currency_format }}</h1>

View File

@ -12,10 +12,14 @@
</ul>
<div class="d-flex">
<a href="{% url 'organization_update' organization.pk %}" class="btn btn-sm btn-warning me-2">{% trans "Edit" %}</a>
<form method="post" action="{% url 'organization_delete' organization.pk %}">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-danger">{% trans "Delete" %}</button>
</form>
<button class="btn btn-phoenix-danger btn-sm delete-btn"
data-url="{% url 'organization_delete' organization.pk %}"
data-message="Are you sure you want to delete this organization?"
data-bs-toggle="modal" data-bs-target="#deleteModal">
{% trans 'Delete' %}<i class="fas fa-trash ms-1"></i>
</button>
</div>
</div>
{% include 'modal/delete_modal.html' %}
{% endblock %}

View File

@ -11,7 +11,7 @@
{{ form|crispy }}
<div class="d-flex mb-3">
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6">{% trans "cancel"|capfirst %}</a>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6">{% trans "Cancel"|capfirst %}</a>
<button class="btn btn-primary" type="submit">
<!--<i class="bi bi-save"></i> -->
{{ _("Save") }}

View File

@ -150,9 +150,9 @@
{% elif estimate.status == 'approved' %}
<span class="badge text-bg-success">{% trans "Approved" %}</span>
{% elif estimate.status == 'completed' %}
<span class="badge text-bg-success">{% trans "completed" %}</span>
<span class="badge text-bg-success">{% trans "Completed" %}</span>
{% elif estimate.status == 'canceled' %}
<span class="badge text-bg-danger">{% trans "canceled" %}</span>
<span class="badge text-bg-danger">{% trans "Canceled" %}</span>
{% endif %}
</div>
</div>

View File

@ -103,7 +103,7 @@
<div class="d-flex bg-success-subtle rounded flex-center me-3 mb-sm-3 mb-md-0 mb-xl-3 mb-xxl-0" style="width:32px; height:32px"><span class="text-success-dark" data-feather="dollar-sign" style="width:24px; height:24px"></span></div>
<div>
<p class="fw-bold mb-1">{% trans 'Paid Amount' %}</p>
<h4 class="fw-bolder text-nowrap {% if invoice.is_paid %}text-success{% endif %}">{{invoice.amount_paid}}&nbsp;{{ _("SAR") }}</h4>
<h4 class="fw-bolder text-nowrap {% if invoice.is_paid %}text-success{% endif %}">{{invoice.amount_paid}}&nbsp;{{ CURRENCY }}</h4>
<h6 class="fw-bolder text-nowrap">{{ _("Owned") }} <span class="fw-semibold text-nowrap text-success">{{invoice.get_amount_open|floatformat}}&nbsp;{{ _("SAR") }}</span></h6>
<div class="progress" style="height:17px">
<div class="progress-bar fw-semibold bg-{% if invoice.get_progress_percent < 100 %}secondary{% else %}success{% endif %} rounded-2" role="progressbar" style="width: {{invoice.get_progress_percent}}%" aria-valuenow="{{invoice.get_progress_percent}}" aria-valuemin="0" aria-valuemax="100">{{invoice.get_progress_percent}}%</div>

View File

@ -33,7 +33,7 @@
<div class="text-danger">{{ error }}</div>
{% endfor %}
<div class="d-flex mb-3">
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "cancel"|capfirst %}</a>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "Cancel"|capfirst %}</a>
<button class="btn btn-primary" type="submit">
<i class="fa-solid fa-floppy-disk"></i>
{{ _("Save") }}

View File

@ -25,7 +25,7 @@
<div class="text-danger">{{ error }}</div>
{% endfor %}
<div class="d-flex mb-3">
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "cancel"|capfirst %}</a>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6"><i class="fa-solid fa-ban"></i> {% trans "Cancel" %}</a>
<button class="btn btn-primary" type="submit">
<i class="fa-solid fa-floppy-disk"></i>
{{ _("Save") }}

View File

@ -35,7 +35,7 @@
<div class="text-danger">{{ error }}</div>
{% endfor %}
<div class="d-flex mb-3">
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6">{% trans "cancel"|capfirst %}</a>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-phoenix-primary me-2 px-6">{% trans "Cancel"|capfirst %}</a>
<button class="btn btn-primary" type="submit">
<!--<i class="bi bi-save"></i> -->
{{ _("Save") }}

187
test.txt
View File

@ -64,4 +64,189 @@ send_mail(
</div>
</div>
</div>
</div>
</div>
"Sedan": "سيدان",
"Coupe": "كوبيه",
"SUV 5 doors": "إس يو في - خمسة أبواب",
"Minivan": "ميني فان",
"Hatchback": "هاتشباك",
"Cabriolet": "سطح قابل للطي",
"Hatchback 5-doors": "هاتشباك - خمسة أبواب",
"Hatchback 5 doors": "هاتشباك - خمسة أبواب",
"Hatchback 3-doors": "هاتشباك - ثلاثة أبواب",
"Crossover": "كروس أوفر",
"Wagon": "واغن",
"SUV": "إس يو في",
"Wagon 5 doors": "واغن - خمسة أبواب",
"Roadster": "رودستر",
"SUV 5-doors": "إس يو في - خمسة أبواب",
"Wagon 5-doors": "واغن - خمسة أبواب",
"Sedan 4-doors": "سيدان - أربعة أبواب",
"Hatchback 3 doors": "هاتشباك - ثلاثة أبواب",
"Van": "فان",
"Pickup Double cabin": "بيك أب - غمارتين",
"Compactvan": "كومباكت فان",
"Pickup": "بيك أب",
"Microvan": "ميكروفان",
"Liftback": "ليفت باك",
"SUV 3-doors": "إس يو في - ثلاثة أبواب",
"Coupe 2-doors": "كوبيه - بابين",
"Pickup Single cabin": "بيك أب - غمارة واحدة",
"Crossover 5-doors": "كروس أوفر - خمسة أبواب",
"Coupe-Hardtop": "كوبيه هاردتوب",
"SUV 3 doors": "إس يو في - ثلاثة أبواب",
"Hardtop": "هاردتوب",
"Sedan 2-doors": "سيدان - بابين",
"Minivan 5-doors": "ميني فان - خمسة أبواب",
"Targa": "تارغا",
"SUV opened": "إس يو في مكشوف",
"Pickup One-and-a-half cabin": "بيك أب - غمارة ونصف",
"Sedan 2 doors": "سيدان - بابين",
"AMG Sedan 4-doors": "أي إم جي سيدان - أربعة أبواب",
"Cabriolet 2-doors": "سطح قابل للطي - بابين",
"Fastback": "فاست باك",
"Sedan-Hardtop": "سيدان هاردتوب",
"Regular Cab pickup 2-doors": "بيك أب كابينة عادية - بابين",
"Grand minivan 5-doors": "ميني فان كبير - خمسة أبواب",
"Sedan Long": "سيدان طويل",
"Speedster": "سبيدستر",
"Liftback 5-doors": "ليفت باك - خمسة أبواب",
"AMG roadster 2-doors": "أي إم جي رودستر - بابين",
"SUV 2-doors": "إس يو في - بابين",
"Hybrid Sedan 4-doors": "سيدان هجينة - أربعة أبواب",
"JDM Sedan 4-doors": "جي دي إم سيدان - أربعة أبواب",
"wagon 3-doors": "واغن - ثلاثة أبواب",
"wagon (5 doors)": "واغن - خمسة أبواب",
"AMG crossover 5-doors": "أي إم جي كروس أوفر - خمسة أبواب",
"Kingswood Estate wagon": "عربة كينجسوود إستيت",
"SUV 5 doors L": "سيارات الدفع الرباعي 5 أبواب L",
"Limousine Sedan": "ليموزين سيدان",
"Z28 Coupe 2-doors": "Z28 كوبيه 2 أبواب",
"S Coupe 2-doors": "S كوبيه 2 أبواب",
"Combi wagon 5-doors": "كومبي واجن 5 أبواب",
"Sportback hatchback 5-doors": "سبورتباك هاتشباك 5 أبواب",
"RS hatchback 3-doors": "RS هاتشباك 3 أبواب",
"Pickup 4-doors": "بيك أب 4 أبواب",
"Trans Am Coupe 2-doors": "ترانس آم كوبيه 2 أبواب",
"Break wagon": "كسر عربة",
"Pickup Double cabin Crew Cab": "بيك أب كابينة طاقم المقصورة المزدوجة",
"Allroad quattro wagon 5-doors": "أولرود كواترو واجن 5 أبواب",
"GTI hatchback 5-doors": "GTI هاتشباك 5 أبواب",
"WRX STI Sedan 4-doors": "WRX STI سيدان 4 أبواب",
"Combi wagon": "عربة كومبي",
"GT hatchback 5-doors": "GT هاتشباك 5 أبواب",
"RS Coupe 2-doors": "RS كوبيه 2 أبواب",
"Sport Sedan Hardtop": "الرياضة سيدان السقف الصلب",
"Xtracab pickup 2-doors": "بيك اب إكستراكاب 2 أبواب",
"CC cabriolet": "CC كابريوليه",
"Sport Sedan Hardtop 4-doors": "سبورت سيدان هاردتوب 4 أبواب",
"Phaeton": "فايتون",
"Hatchback 5 doors Sportback": "هاتشباك 5 أبواب سبورتباك",
"Minivan Grand": "ميني فان جراند",
"Cross hatchback 5-doors": "عبر هاتشباك 5 أبواب",
"Volante cabriolet": "فولانتي كابريوليه",
"Turbo Coupe 2-doors": "توربو كوبيه 2 أبواب",
"Sport Coupe Coupe": "سبورت كوبيه كوبيه",
"Classic pickup 2-doors": "بيك أب كلاسيكي 2 أبواب",
"GT hatchback 3-doors": "GT هاتشباك 3 أبواب",
"Spyder cabriolet": "سبايدر كابريوليه",
"ST hatchback 3-doors": "ST هاتشباك 3 أبواب",
"SUV 5 doors X": "سيارات الدفع الرباعي 5 أبواب X",
"Pickup Single cabin Regular Cab": "بيك أب كابينة واحدة الكابينة العادية",
"Single Cab pickup 2-doors": "بيك اب كابينة واحدة 2 أبواب",
"Cabrio cabriolet": "كابريو كابريوليه",
"Sportback hatchback": "سبورت باك هاتشباك",
"Wagon minivan": "عربة ميني فان",
"WRX Sedan 4-doors": "WRX سيدان 4 أبواب",
"Convertible cabriolet": "كابريوليه قابلة للتحويل",
"OPC hatchback 3-doors": "OPC هاتشباك 3 أبواب",
"Grand minivan": "الميني فان الكبرى",
"Spider cabriolet": "العنكبوت كابريوليه",
"Athlete Sedan 4-doors": "رياضي سيدان 4 أبواب",
"Combi RS wagon 5-doors": "كومبي RS واجن 5 أبواب",
"V8 Coupe 2-doors": "V8 كوبيه 2 أبواب",
"Sportvan minivan": "ميني فان سبورت فان",
"Coupe Coupe": "كوبيه كوبيه",
"Hybrid hatchback 5-doors": "هاتشباك هجينة 5 أبواب",
"Extended Cab pickup 2-doors": "بيك أب كابينة ممتدة 2 أبواب",
"Hybrid crossover 5-doors": "كروس أوفر هجين 5 أبواب",
"JDM Hardtop": "JDM Hardtop",
"US-Spec. Sedan 4-doors": "مواصفات الولايات المتحدة. سيدان 4 أبواب",
"Sport hatchback 3-doors": "هاتشباك رياضية 3 أبواب",
"Combi Scout wagon 5-doors": "كومبي سكاوت واجن 5 أبواب",
"Formula Coupe 2-doors": "فورمولا كوبيه 2 أبواب",
"Stingray roadster": "ستينغراي رودستر",
"wagon 5-doors Shooting Brake": "عربة 5 أبواب اطلاق النار الفرامل",
"Minivan SWB": "ميني فان SWB",
"Roadster Spider": "رودستر سبايدر",
"Sedan L": "سيدان L",
"SUV 5 doors Long": "سيارات الدفع الرباعي 5 أبواب طويلة",
"Coupe RS": "كوبيه RS",
"Extended Cab pickup 4-doors": "بيك أب كابينة ممتدة 4 أبواب",
"Gran Coupe Sedan": "غران كوبيه سيدان",
"Van wagon": "فان واغن",
"Double Cab pickup": "بيك أب مزدوج الكابينة",
"Stepway hatchback 5-doors": "ستيبوي هاتشباك 5 أبواب",
"US-spec Coupe": "كوبيه ذات مواصفات أمريكية",
"RS liftback 5-doors": "RS Liftback 5 أبواب",
"Carrera Coupe 2-doors": "كاريرا كوبيه 2 أبواب",
"Van 4-doors": "فان 4 أبواب",
"F-150 RegularCab pickup 2-doors": "F-150 RegularCab بيك اب 2 أبواب",
"F-150 SuperCab pickup 4-doors": "F-150 SuperCab بيك أب 4 أبواب",
"Classic Coupe 2-doors": "كلاسيك كوبيه 2 أبواب",
"Royal Sedan 4-doors": "رويال سيدان 4 أبواب",
"Grandtour wagon": "عربة جراندتور",
"Esprit Coupe 2-doors": "إسبريت كوبيه 2 أبواب",
"XKR cabriolet 2-doors": "XKR كابريوليه 2 أبواب",
"XKR Coupe 2-doors": "XKR كوبيه 2 أبواب",
"Soft top SUV 3-doors": "سيارات الدفع الرباعي ذات السقف الناعم 3 أبواب",
"US-spec minivan 5-doors": "ميني فان 5 أبواب بمواصفات أمريكية",
"Absolute minivan 5-doors": "ميني فان مطلق 5 أبواب",
"Si Sedan 4-doors": "سي سيدان 4 أبواب",
"Sport SUV 3-doors": "سبورت SUV 3 أبواب",
"Hard top SUV": "سيارات الدفع الرباعي ذات السقف الصلب",
"Station Wagon wagon": "عربة ستيشن واغن",
"Custom Coupe Hardtop 2-doors": "مخصص كوبيه Hardtop 2 أبواب",
"Limousine Pullman": "ليموزين بولمان",
"Hatchback 4 doors": "هاتشباك 4 أبواب",
"Hatchback 5 doors GT": "هاتشباك 5 أبواب جي تي",
"SUV 5 doors EV": "سيارات الدفع الرباعي 5 أبواب EV",
"Cabriolet Volante": "كابريوليه فولانتي",
"Cabriolet Spider": "كابريوليه العنكبوت",
"Pickup Double cabin Double Cab": "بيك أب كابينة مزدوجة الكابينة",
"Compactvan Stepway": "كومباكت فان ستيبواي",
"wagon 5 doors Scout": "عربة 5 أبواب الكشافة",
"Axio Sedan 4-doors": "أكسيو سيدان 4 أبواب",
"hatchback": "هاتشباك",
"R Coupe 2-doors": "R كوبيه 2 أبواب",
"SC Cupra hatchback 3-doors": "SC كوبرا هاتشباك 3 أبواب",
"GT hatchback": "جي تي هاتشباك",
"King Cab pickup 2-doors": "كينج كاب بيك أب 2 أبواب",
"R hatchback 3-doors": "R هاتشباك 3 أبواب",
"Sport Sedan 4-doors": "سبورت سيدان 4 أبواب",
"Caravan wagon 5-doors": "كارافان واجن 5 أبواب",
"Kombi minivan 4-doors": "ميني فان كومبي 4 أبواب",
"Variant wagon 5-doors": "عربة متغيرة 5 أبواب",
"Sports Tourer wagon 5-doors": "عربة رياضية سياحية 5 أبواب",
"Gran Turismo liftback": "ارتداد Gran Turismo",
"Shooting Brake wagon 5-doors": "عربة فرامل الرماية 5 أبواب",
"AMG Shooting Brake wagon 5-doors": "AMG عربة الفرامل الرماية 5 أبواب",
"F-100 RegularCab pickup 2-doors": "F-100 RegularCab بيك أب 2 أبواب",
"Grand minivan 4-doors": "ميني فان جراند 4 أبواب",
"Regular pickup 2-doors": "بيك أب عادي 2 أبواب",
"Combi minivan": "ميني فان كومبي",
"Classic Sedan": "سيارة سيدان كلاسيكية",
"Turbo hatchback 3-doors": "توربو هاتشباك 3 أبواب",
"Spyder roadster 2-doors": "سبايدر رودستر 2 أبواب",
"Turbo cabriolet 2-doors": "توربو كابريوليه 2 أبواب",
"GT3 Coupe 2-doors": "GT3 كوبيه 2 أبواب",
"Trans Am T-Roof targa 2-doors": "ترانس آم تي روف تارجا 2 أبواب",
"OPC minivan 5-doors": "ميني فان OPC 5 أبواب",
"Hardtop 2-doors": "Hardtop 2 أبواب",
"JP-spec Sedan 4-doors": "جي بي مواصفات سيدان 4 أبواب",