edit styles

This commit is contained in:
Marwan Alwali 2024-12-12 11:00:55 +03:00
parent b227d9ff5b
commit 7597eb5391
23 changed files with 601 additions and 567 deletions

View File

@ -232,9 +232,17 @@ CRISPY_TEMPLATE_PACK = "bootstrap5"
OPENAI_API_KEY = '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'
# ELM API KEYS
APP_ID = '367974ed'
APP_KEY = '046b0412c1b4d3f8c39ec6375d6f3030'
CLIENT_ID = '94142c27-2536-47e9-8e28-9ca7728b9442'
# vehicle-info
# c2729afb
# 6d397471920412d672af1b8a02ca52ea
# option-info
# 367974ed
# 046b0412c1b4d3f8c39ec6375d6f3030
ELM_APP_ID = 'c2729afb'
ELM_APP_KEY = '6d397471920412d672af1b8a02ca52ea'
ELM_CLIENT_ID = '94142c27-2536-47e9-8e28-9ca7728b9442'
LOGGING = {
'version': 1,

View File

@ -16,6 +16,7 @@ admin.site.register(models.CarSpecificationValue)
admin.site.register(models.ExteriorColors)
admin.site.register(models.InteriorColors)
admin.site.register(models.CarLocation)
admin.site.register(models.CarReservation)
@admin.register(models.CarMake)
class CarMakeAdmin(admin.ModelAdmin):

View File

@ -53,14 +53,22 @@ class CarForm(forms.ModelForm, AddClassMixin, ):
def __init__(self, *args, **kwargs):
dealer = kwargs.pop('dealer', None)
super().__init__(*args, **kwargs)
# if dealer:
# self.fields['branch'].queryset = Branch.objects.filter(dealer=dealer)
if 'id_car_make' in self.fields:
queryset = self.fields['id_car_make'].queryset
queryset = self.fields['id_car_make'].queryset.filter(is_sa_import=True)
self.fields['id_car_make'].choices = [
(obj.id_car_make, obj.get_local_name()) for obj in queryset
]
if 'id_car_model' in self.fields:
queryset = self.fields['id_car_model'].queryset
self.fields['id_car_model'].choices = [
(obj.id_car_model, obj.get_local_name()) for obj in queryset
]
if 'vendor' in self.fields:
queryset = self.fields['vendor'].queryset
self.fields['vendor'].choices = [
(obj.pk, obj.get_local_name()) for obj in queryset
]
class CarUpdateForm(forms.ModelForm, AddClassMixin):

View File

@ -204,25 +204,52 @@ class Car(models.Model):
@property
def selling_price(self):
finance = self.finances.first()
finance = self.finances
return finance.selling_price if finance else Decimal('0.00')
@property
def discount_amount(self):
finance = self.finances.first()
finance = self.finances
return finance.discount_amount if finance else Decimal('0.00')
@property
def vat_amount(self):
finance = self.finances.first()
finance = self.finances
return finance.vat_amount if finance else Decimal('0.00')
@property
def total(self):
finance = self.finances.first()
finance = self.finances
return finance.total if finance else Decimal('0.00')
# class CarData(models.Model):
# vin = models.CharField(max_length=17, unique=True, verbose_name=_("VIN"))
# make = models.CharField(max_length=255, verbose_name=_("Make"))
# make_ar = models.CharField(max_length=255, verbose_name=_("Make Arabic"))
# model = models.CharField(max_length=255, verbose_name=_("Model"))
# model_ar = models.CharField(max_length=255, verbose_name=_("Model Arabic"))
# year = models.IntegerField(verbose_name=_("Year"))
# series = models.CharField(max_length=255,verbose_name=_("Series"))
# trim = models.CharField(max_length=255,verbose_name=_("Trim"))
# status = models.CharField(
# max_length=10,
# choices=CarStatusChoices,
# default=CarStatusChoices.AVAILABLE,
# verbose_name=_("Status")
# )
# stock_type = models.CharField(
# max_length=10,
# choices=CarStockTypeChoices,
# default=CarStockTypeChoices.NEW,
# verbose_name=_("Stock Type")
# )
# remarks = models.TextField(blank=True, null=True, verbose_name=_("Remarks"))
# mileage = models.IntegerField(blank=True, null=True, verbose_name=_("Mileage"))
# receiving_date = models.DateTimeField(verbose_name=_("Receiving Date"))
class CarReservation(models.Model):
car = models.ForeignKey('Car', on_delete=models.CASCADE, related_name='reservations', verbose_name=_("Car"))
reserved_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reservations', verbose_name=_("Reserved By"))

View File

@ -12,8 +12,9 @@ from .models import Car,CarMake,CarModel
def get_make(item):
data = CarMake.objects.filter(name__iexact=item).first()
data = CarMake.objects.filter(name__iexact=item).first()
return data
def get_model(item,make):
data = make.carmodel_set.filter(name__iexact=item).first()
if not data:
@ -37,7 +38,6 @@ def decodevin(vin):
return None
def decode_vin(vin):
v = VIN(vin)
data = {}
@ -51,20 +51,12 @@ def decode_vin(vin):
return data if all([x for x in data.values()]) else None
# vehicle-info
# c2729afb
# 6d397471920412d672af1b8a02ca52ea
# option-info
# 367974ed
# 046b0412c1b4d3f8c39ec6375d6f3030
def elm(vin):
headers = {
"Content-Type": "application/json",
"app-id": "c2729afb",
"app-key": "6d397471920412d672af1b8a02ca52ea",
"client-id": "94142c27-2536-47e9-8e28-9ca7728b9442",
"app-id": settings.ELM_APP_ID,
"app-key": settings.ELM_APP_KEY,
"client-id": settings.ELM_CLIENT_ID,
}
url = (
"https://vehicle-maintenance.api.elm.sa/api/v1/vehicles/vehicle-info?vin=" + vin
@ -83,25 +75,3 @@ def elm(vin):
return data if all([x for x in data.values()]) else None
def translate(content, *args, **kwargs):
client = OpenAI(api_key=settings.OPENAI_API_KEY)
completion = client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": "You are a translation assistant that translates English to Arabic.",
},
{"role": "user", "content": content},
],
temperature=0.3,
)
translation = completion.choices[0].message.content.strip()
return translation
def calculate_stock_value():
cars = Car.objects.all()
total_value = sum(car.selling_price for car in cars)
return total_value

View File

@ -11,16 +11,22 @@ from . import models
@receiver(post_save, sender=models.Car)
def create_car_location(sender, instance, created, **kwargs):
"""
Signal to create or update the car's location when a car instance is saved.
"""
if created:
models.CarLocation.objects.create(
car=instance,
owner=instance.dealer,
showroom=instance.dealer,
description=f"Initial location set for car {instance.vin}."
)
print("Car Location created")
Signal to create or update the car's location when a car instance is saved.
"""
try:
if created:
if instance.dealer is None:
raise ValueError(f"Cannot create CarLocation for car {instance.vin}: dealer is missing.")
models.CarLocation.objects.create(
car=instance,
owner=instance.dealer,
showroom=instance.dealer,
description=f"Initial location set for car {instance.vin}."
)
print("Car Location created")
except Exception as e:
print(f"Failed to create CarLocation for car {instance.vin}: {e}")
@receiver(post_save, sender=models.CarReservation)
@ -34,7 +40,7 @@ def update_car_status_on_reservation(sender, instance, created, **kwargs):
@receiver(post_delete, sender=models.CarReservation)
def update_car_status_on_reservation_delete(sender, instance, **kwargs):
car = instance.car
if not car.get_current_reservation():
if not car.is_reserved():
car.status = models.CarStatusChoices.AVAILABLE
car.save()

View File

@ -52,7 +52,7 @@ urlpatterns = [
path('cars/<int:pk>/update/', views.CarUpdateView.as_view(), name='car_update'),
path('cars/<int:pk>/delete/', views.CarDeleteView.as_view(), name='car_delete'),
path('cars/<int:car_pk>/finance/create/', views.CarFinanceCreateView.as_view(), name='car_finance_create'),
path('cars/finance/update/<int:pk>/', views.CarFinanceUpdateView.as_view(), name='car_finance_update'),
path('cars/finance/<int:pk>/update/', views.CarFinanceUpdateView.as_view(), name='car_finance_update'),
path('cars/add/', views.CarCreateView.as_view(), name='car_add'),
path('ajax/', views.AjaxHandlerView.as_view(), name='ajax_handler'),
path('cars/<int:car_pk>/add-color/', views.CarColorCreate.as_view(), name='add_color'),

View File

@ -138,7 +138,7 @@ class AjaxHandlerView(LoginRequiredMixin, View):
vin_data = {}
decoding_method = ''
manufacturer_name = model_name = year_model = None
# manufacturer_name = model_name = year_model = None
if not (result :=decodevin(vin_no)):
return JsonResponse({'success': False, 'error': 'VIN not found in all sources.'}, status=404)

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-11 21:41+0300\n"
"POT-Creation-Date: 2024-12-12 01:35+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -20,8 +20,8 @@ msgstr ""
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#: api/models.py:6 inventory/models.py:126
#: templates/inventory/car_detail.html:61 templates/inventory/car_form.html:83
#: templates/inventory/car_inventory.html:53
#: templates/inventory/car_detail.html:85 templates/inventory/car_form.html:83
#: templates/inventory/car_inventory.html:51
#: templates/inventory/car_list.html:67 templates/inventory/car_list.html:69
msgid "VIN"
msgstr "رقم الهيكل"
@ -42,7 +42,7 @@ msgid "SAR"
msgstr "ريال سعودي"
#: inventory/forms.py:114 inventory/models.py:341
#: templates/inventory/car_detail.html:135
#: templates/inventory/car_detail.html:158
msgid "Custom Date"
msgstr "تاريخ البطاقة الجمركية"
@ -72,10 +72,8 @@ msgid "Damaged"
msgstr "تالف"
#: inventory/models.py:117
#, fuzzy
#| msgid "Reserve"
msgid "Reserved"
msgstr "حجز"
msgstr "محجوزة"
#: inventory/models.py:121
msgid "New"
@ -90,7 +88,7 @@ msgid "Dealer"
msgstr "المعرض"
#: inventory/models.py:140 inventory/models.py:458
#: templates/inventory/car_detail.html:108
#: templates/inventory/car_detail.html:131
#: templates/inventory/car_form.html:230
#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:359
#: venv/lib/python3.11/site-packages/django_ledger/models/vendor.py:191
@ -99,16 +97,16 @@ msgstr "المعرض"
msgid "Vendor"
msgstr "المورد"
#: inventory/models.py:148 templates/inventory/car_inventory.html:55
#: inventory/models.py:148
msgid "Make"
msgstr "الصانع"
#: inventory/models.py:156 templates/inventory/car_inventory.html:56
#: inventory/models.py:156
msgid "Model"
msgstr "الموديل"
#: inventory/models.py:158 templates/inventory/car_form.html:118
#: templates/inventory/car_inventory.html:54
#: templates/inventory/car_inventory.html:52
msgid "Year"
msgstr "السنة"
@ -121,7 +119,8 @@ msgid "Trim"
msgstr "الفئة"
#: inventory/models.py:179 inventory/models.py:500
#: templates/inventory/car_detail.html:86 templates/inventory/car_list.html:163
#: templates/inventory/car_detail.html:109
#: templates/inventory/car_list.html:163
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_table.html:10
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/card_estimate.html:12
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:12
@ -131,25 +130,25 @@ msgstr "الفئة"
msgid "Status"
msgstr "الحالة"
#: inventory/models.py:185 templates/inventory/car_detail.html:90
#: inventory/models.py:185 templates/inventory/car_detail.html:113
#: templates/inventory/car_form.html:248 templates/inventory/car_list.html:177
msgid "Stock Type"
msgstr "نوع المخزون"
#: inventory/models.py:187 inventory/models.py:499
#: templates/inventory/car_detail.html:113
#: templates/inventory/car_detail.html:136
#: templates/inventory/car_form.html:301 templates/inventory/car_list.html:200
#: templates/sales/quotation_detail.html:23
msgid "Remarks"
msgstr "ملاحظات"
#: inventory/models.py:188 templates/inventory/car_detail.html:94
#: inventory/models.py:188 templates/inventory/car_detail.html:117
#: templates/inventory/car_form.html:265 templates/inventory/car_list.html:191
#: templates/inventory/car_list.html:192
msgid "Mileage"
msgstr "عدد الكيلومترات"
#: inventory/models.py:189 templates/inventory/car_detail.html:98
#: inventory/models.py:189 templates/inventory/car_detail.html:121
#: templates/inventory/car_form.html:283
msgid "Receiving Date"
msgstr "تاريخ الاستلام"
@ -164,39 +163,31 @@ msgstr "السيارة"
msgid "Cars"
msgstr "السيارات"
#: inventory/models.py:228 templates/inventory/car_detail.html:277
#: inventory/models.py:228 templates/inventory/car_detail.html:304
msgid "Reserved By"
msgstr "محجوز بواسطة"
#: inventory/models.py:229
#, fuzzy
#| msgid "Reserved By"
msgid "Reserved At"
msgstr "محجوز بواسطة"
msgstr "تاريخ الحجز"
#: inventory/models.py:230
#, fuzzy
#| msgid "Reserved By"
msgid "Reserved Until"
msgstr "محجوز بواسطة"
msgstr "محجوز حتى"
#: inventory/models.py:238
#, fuzzy
#| msgid "Registration"
#: inventory/models.py:238 templates/inventory/car_detail.html:38
msgid "Car Reservation"
msgstr "التسجيل"
msgstr "حجز السيارة"
#: inventory/models.py:239
#, fuzzy
#| msgid "Registrations"
msgid "Car Reservations"
msgstr "تسجيل السيارات"
msgstr "حجوزات السيارات"
#: inventory/models.py:245 templates/inventory/car_detail.html:179
#: inventory/models.py:245 templates/inventory/car_detail.html:204
msgid "Cost Price"
msgstr "سعر التكلفة"
#: inventory/models.py:246 templates/inventory/car_detail.html:183
#: inventory/models.py:246 templates/inventory/car_detail.html:208
#: templates/sales/sales_order_detail.html:25
msgid "Selling Price"
msgstr "سعر البيع"
@ -206,28 +197,26 @@ msgid "Profit Margin"
msgstr "هامش الربح"
#: inventory/models.py:253
#, fuzzy
#| msgid "VAT Amount"
msgid "Vat Amount"
msgstr "مبلغ ضريبة القيمة المضافة"
#: inventory/models.py:255 templates/inventory/car_detail.html:203
#: inventory/models.py:255 templates/inventory/car_detail.html:228
msgid "Discount Amount"
msgstr "مبلغ الخصم"
#: inventory/models.py:257 templates/inventory/car_detail.html:191
#: inventory/models.py:257 templates/inventory/car_detail.html:216
msgid "Registration Fee"
msgstr "رسوم التسجيل"
#: inventory/models.py:259 templates/inventory/car_detail.html:187
#: inventory/models.py:259 templates/inventory/car_detail.html:212
msgid "Administration Fee"
msgstr "الرسوم الادارية"
#: inventory/models.py:261 templates/inventory/car_detail.html:195
#: inventory/models.py:261 templates/inventory/car_detail.html:220
msgid "Transportation Fee"
msgstr "رسوم النقل"
#: inventory/models.py:263 templates/inventory/car_detail.html:199
#: inventory/models.py:263 templates/inventory/car_detail.html:224
msgid "Custom Card Fee"
msgstr "رسوم البطاقة الجمركية"
@ -276,12 +265,12 @@ msgstr "اللون"
msgid "Colors"
msgstr "الألوان"
#: inventory/models.py:340 templates/inventory/car_detail.html:131
#: inventory/models.py:340 templates/inventory/car_detail.html:154
msgid "Custom Number"
msgstr "رقم البطاقة الجمركية"
#: inventory/models.py:344 templates/inventory/car_detail.html:16
#: templates/inventory/car_detail.html:141
#: inventory/models.py:344 templates/inventory/car_detail.html:23
#: templates/inventory/car_detail.html:164
msgid "Custom Card"
msgstr "البطاقة الجمركية"
@ -324,28 +313,20 @@ msgstr "وصف اختياري حول وضع السيارة في صالة الع
#: inventory/models.py:380 inventory/models.py:501 inventory/models.py:563
#: templates/sales/quotation_list.html:17
#, fuzzy
#| msgid "Created"
msgid "Created At"
msgstr "تاريخ الإنشاء"
#: inventory/models.py:384
#, fuzzy
#| msgid "Updated"
msgid "Last Updated"
msgstr "تم التحديث"
msgstr "آخر تحديث"
#: inventory/models.py:388
#, fuzzy
#| msgid "actions"
msgid "Car Location"
msgstr "الإجراءات"
msgstr "موقع السيارة"
#: inventory/models.py:389
#, fuzzy
#| msgid "actions"
msgid "Car Locations"
msgstr "الإجراءات"
msgstr "مواقف السيارات"
#: inventory/models.py:403
msgid "Plate Number"
@ -484,10 +465,8 @@ msgid "Draft"
msgstr "مسودة"
#: inventory/models.py:493
#, fuzzy
#| msgid "Confirm"
msgid "Confirmed"
msgstr "تأكيد"
msgstr "مؤكد"
#: inventory/models.py:494
#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:342
@ -506,8 +485,6 @@ msgid "Amount"
msgstr "المبلغ"
#: inventory/models.py:502
#, fuzzy
#| msgid "Updated"
msgid "Updated At"
msgstr "تم التحديث"
@ -520,10 +497,8 @@ msgid "Cannot cancel a confirmed quotation."
msgstr "لا يمكن إلغاء عرض تقديري تم تأكيده."
#: inventory/models.py:527 inventory/models.py:562
#, fuzzy
#| msgid "Duration"
msgid "Quotation"
msgstr "المدة"
msgstr "عزرص سعر"
#: inventory/models.py:535
#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1068
@ -561,7 +536,7 @@ msgid "You are not associated with any dealer."
msgstr "أنت غير مرتبط بأي معرض."
#: inventory/views.py:221 templates/header.html:33 templates/index.html:20
#: templates/inventory/car_inventory.html:5
#: templates/inventory/car_inventory.html:4
#: templates/inventory/car_inventory.html:7
msgid "inventory"
msgstr "المخزون"
@ -784,7 +759,7 @@ msgstr "حفظ"
#: templates/inventory/add_colors.html:56
#: templates/inventory/add_custom_card.html:8
#: templates/inventory/car_confirm_delete.html:14
#: templates/inventory/car_detail.html:301
#: templates/inventory/car_detail.html:328
#: templates/inventory/car_finance_form.html:41
#: templates/inventory/color_palette.html:107
#: templates/inventory/reserve_car.html:30
@ -800,7 +775,7 @@ msgid "Cancel"
msgstr "إلغاء"
#: templates/customers/customer_list.html:20
#: templates/inventory/car_inventory.html:31
#: templates/inventory/car_inventory.html:30
#: templates/inventory/car_list.html:70
msgid "search"
msgstr "بحث"
@ -826,8 +801,8 @@ msgid "actions"
msgstr "الإجراءات"
#: templates/customers/customer_list.html:59
#: templates/inventory/car_detail.html:124
#: templates/inventory/car_inventory.html:75
#: templates/inventory/car_detail.html:147
#: templates/inventory/car_inventory.html:78
msgid "view"
msgstr "عرض"
@ -840,7 +815,7 @@ msgid "Are you sure you want to delete this customer?"
msgstr "هل أنت متأكد أنك تريد حذف هذا العميل؟"
#: templates/customers/view_customer.html:26
#: templates/vendors/view_vendor.html:29
#: templates/inventory/car_detail.html:47 templates/vendors/view_vendor.html:29
#: venv/lib/python3.11/site-packages/django/forms/widgets.py:802
msgid "No"
msgstr "لا"
@ -857,7 +832,7 @@ msgid "Customer Details"
msgstr "تفاصيل العميل"
#: templates/customers/view_customer.html:61
#: templates/inventory/car_detail.html:329
#: templates/inventory/car_detail.html:359
#: templates/vendors/view_vendor.html:66
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/includes/card_customer.html:28
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:83
@ -899,7 +874,7 @@ msgid "Delete"
msgstr "حذف"
#: templates/customers/view_customer.html:72
#: templates/inventory/car_detail.html:331
#: templates/inventory/car_detail.html:361
msgid "Back to List"
msgstr "العودة إلى القائمة"
@ -1107,7 +1082,7 @@ msgstr "أفضل السيارات مبيعاً"
msgid "View your best-selling cars."
msgstr "عرض السيارات الأكثر مبيعاً."
#: templates/index.html:151 templates/inventory/car_detail.html:74
#: templates/index.html:151 templates/inventory/car_detail.html:97
#: templates/inventory/car_form.html:159 templates/inventory/car_list.html:97
msgid "model"
msgstr "الموديل"
@ -1175,70 +1150,86 @@ msgstr "إضافة لون"
msgid "Select exterior and interior colors for"
msgstr "اختر الألوان الخارجية والداخلية لـ"
#: templates/inventory/car_detail.html:6 templates/inventory/car_detail.html:58
#: templates/inventory/car_detail.html:5 templates/inventory/car_detail.html:82
#: templates/sales/quotation_detail.html:27
msgid "Car Details"
msgstr "تفاصيل السيارة"
#: templates/inventory/car_detail.html:37
#: templates/inventory/car_detail.html:117 templates/inventory/car_form.html:37
#: templates/inventory/car_detail.html:42
msgid "Are you sure you want to reserve this car?"
msgstr "هل أنت متأكد أنك تريد حجز هذه السيارة؟"
#: templates/inventory/car_detail.html:51
#: templates/inventory/car_detail.html:346
#: templates/inventory/reserve_car.html:29
msgid "Reserve"
msgstr "حجز"
#: templates/inventory/car_detail.html:65
#: templates/inventory/car_detail.html:140 templates/inventory/car_form.html:37
#: templates/inventory/car_form.html:322 templates/inventory/car_list.html:47
#: templates/inventory/car_list.html:221
msgid "specifications"
msgstr "المواصفات"
#: templates/inventory/car_detail.html:65 templates/inventory/car_list.html:119
#: templates/inventory/car_detail.html:89 templates/inventory/car_list.html:119
msgid "year"
msgstr "السنة"
#: templates/inventory/car_detail.html:69 templates/inventory/car_form.html:140
#: templates/inventory/car_detail.html:93 templates/inventory/car_form.html:140
#: templates/inventory/car_list.html:79
msgid "make"
msgstr "الصانع"
#: templates/inventory/car_detail.html:78 templates/inventory/car_list.html:130
#: templates/inventory/car_detail.html:101
#: templates/inventory/car_list.html:130
msgid "series"
msgstr "السلسلة"
#: templates/inventory/car_detail.html:82 templates/inventory/car_form.html:204
#: templates/inventory/car_list.html:141
#: templates/inventory/car_detail.html:105
#: templates/inventory/car_form.html:204 templates/inventory/car_list.html:141
msgid "trim"
msgstr "الفئة"
#: templates/inventory/car_detail.html:103
#: templates/inventory/car_detail.html:126
msgid "Branch"
msgstr "الفرع"
#: templates/inventory/car_detail.html:147
#: templates/inventory/car_detail.html:166
#: templates/inventory/car_detail.html:170
#: templates/inventory/car_detail.html:191
msgid "Add"
msgstr "إضافة"
#: templates/inventory/car_detail.html:153
#: templates/inventory/car_detail.html:176
#: templates/inventory/car_inventory.html:55
msgid "Showroom Location"
msgstr "موقع صالة العرض"
#: templates/inventory/car_detail.html:157
#: templates/inventory/car_detail.html:180
#: templates/inventory/car_inventory.html:72
msgid "Our Showroom"
msgstr "معرضنا"
#: templates/inventory/car_detail.html:163
#, fuzzy
#| msgid "No options available."
msgid "No location available."
msgstr "لا توجد سيارات متاحة."
#: templates/inventory/car_detail.html:186
#: templates/inventory/transfer_car.html:23
msgid "transfer"
msgstr "نقل"
#: templates/inventory/car_detail.html:175
#: templates/inventory/car_detail.html:188
msgid "No location available."
msgstr "لا يوجد موقع متاح."
#: templates/inventory/car_detail.html:199
msgid "Financial Details"
msgstr "التفاصيل المالية"
#: templates/inventory/car_detail.html:207
#: templates/inventory/car_detail.html:232
#: templates/sales/quotation_detail.html:66
#: templates/sales/sales_order_detail.html:26
msgid "VAT Amount"
msgstr "مبلغ ضريبة القيمة المضافة"
#: templates/inventory/car_detail.html:211
#: templates/inventory/car_detail.html:236
#: templates/inventory/inventory_stats.html:61
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:98
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:127
@ -1257,48 +1248,48 @@ msgstr "مبلغ ضريبة القيمة المضافة"
msgid "Total"
msgstr "الإجمالي"
#: templates/inventory/car_detail.html:218
#: templates/inventory/car_detail.html:243
msgid "Edit Finance Details"
msgstr "تعديل التفاصيل المالية"
#: templates/inventory/car_detail.html:222
#: templates/inventory/car_detail.html:247
msgid "No finance details available."
msgstr "لا توجد تفاصيل مالية متاحة."
#: templates/inventory/car_detail.html:225
#: templates/inventory/car_detail.html:250
msgid "Add Finance Details"
msgstr "إضافة التفاصيل المالية"
#: templates/inventory/car_detail.html:231
#: templates/inventory/car_detail.html:256
msgid "Colors Details"
msgstr "تفاصيل الألوان"
#: templates/inventory/car_detail.html:237
#: templates/inventory/car_detail.html:262
msgid "Exterior"
msgstr "الخارجي"
#: templates/inventory/car_detail.html:246
#: templates/inventory/car_detail.html:273
msgid "Interior"
msgstr "الداخلي"
#: templates/inventory/car_detail.html:258
#: templates/inventory/car_detail.html:286
msgid "No colors available for this car."
msgstr "لا تتوفر ألوان لهذه السيارة."
#: templates/inventory/car_detail.html:265
#: templates/inventory/car_detail.html:292
msgid "Get Colors"
msgstr "الحصول على الألوان"
#: templates/inventory/car_detail.html:272
#: templates/inventory/car_detail.html:299
msgid "Reservations Details"
msgstr "تفاصيل الحجز"
#: templates/inventory/car_detail.html:278
#: templates/inventory/car_detail.html:305
msgid "Expires At"
msgstr "ينتهي في"
#: templates/inventory/car_detail.html:279
#: templates/inventory/car_inventory.html:57
#: templates/inventory/car_detail.html:306
#: templates/inventory/car_inventory.html:56
#: templates/sales/quotation_list.html:18
#: templates/vendors/vendors_list.html:37
#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/account_txs_table.html:29
@ -1327,31 +1318,21 @@ msgstr "ينتهي في"
msgid "Actions"
msgstr "الإجراءات"
#: templates/inventory/car_detail.html:295
#: templates/inventory/car_detail.html:322
msgid "Renew"
msgstr "تجديد"
#: templates/inventory/car_detail.html:305
#: templates/inventory/car_detail.html:334
msgid "Expired"
msgstr "ينتهي في"
#: templates/inventory/car_detail.html:315
#: templates/inventory/reserve_car.html:29
msgid "Reserve"
msgstr "حجز"
#: templates/inventory/car_detail.html:327
#: templates/inventory/transfer_car.html:23
msgid "transfer"
msgstr "نقل"
#: templates/inventory/car_detail.html:416
#: templates/inventory/car_detail.html:440
#: templates/inventory/car_list.html:542
#: templates/partials/specifications_modal.html:11
msgid "No specifications available."
msgstr "لا توجد مواصفات متاحة."
#: templates/inventory/car_detail.html:420
#: templates/inventory/car_detail.html:444
#: templates/inventory/car_list.html:546
msgid "Error loading specifications."
msgstr "حدث خطأ أثناء تحميل المواصفات."
@ -1427,7 +1408,15 @@ msgstr "فشل في فك تشفير رقم الهيكل"
msgid "An error occurred while decoding the VIN."
msgstr "حدث خطأ أثناء فك تشفير الهيكل"
#: templates/inventory/car_inventory.html:80
#: templates/inventory/car_inventory.html:53
msgid "Exterior Color"
msgstr "اللون الخارجي"
#: templates/inventory/car_inventory.html:54
msgid "Interior Color"
msgstr "اللون الداخلي"
#: templates/inventory/car_inventory.html:84
msgid "No cars available."
msgstr "لا توجد سيارات متاحة."
@ -1487,10 +1476,8 @@ msgstr "خطأ في تحميل الخيارات."
#: templates/inventory/car_location_form.html:4
#: templates/inventory/car_location_form.html:12
#, fuzzy
#| msgid "actions"
msgid "Manage Car Location"
msgstr "الإجراءات"
msgstr "إدارة موقع السيارة"
#: templates/inventory/color_palette.html:74
msgid "Update Color"
@ -6989,10 +6976,3 @@ msgid ""
"Message Django's middlewares"
msgstr ""
#~ msgid "Location"
#~ msgstr "الموقع"
#, fuzzy
#~| msgid "Net Income"
#~ msgid "Sales Income"
#~ msgstr "صافي الدخل"

View File

@ -36,6 +36,7 @@ small, .small {
}
.btn {
text-transform: uppercase;
border-radius: 5px;
}
</style>
@ -47,11 +48,7 @@ small, .small {
{% block content %}
<!-- Main content goes here -->
{% endblock %}
<!-- JavaScript Files -->
<script type="text/javascript" src="{% static 'js/main.js' %}"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {

View File

@ -1,113 +1,130 @@
{% extends "base.html" %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block title %}{% trans "customers" %}{% endblock title %}
{% block customers %}<a class="nav-link active">{% trans "customers"|capfirst %}</a>{% endblock %}
{% block title %}{% trans "Customers" %}{% endblock title %}
{% block customers %}
<a class="nav-link active fw-bold">
{% trans "Customers"|capfirst %}
<span class="visually-hidden">(current)</span>
</a>
{% endblock %}
{% block content %}
<div class="d-flex flex-column min-vh-100">
<div class="d-flex flex-column flex-sm-grow-1 ms-sm-14 p-4">
<main class="d-grid gap-4 p-1">
<div class="row g-4">
<div class="col-lg-6 col-xl-12">
<div class="container-fluid p-2">
<form method="get">
<div class="input-group input-group-sm">
<button id="inputGroup-sizing-sm"
class="btn btn-sm btn-secondary rounded-start" type="submit">
{% trans 'search'|capfirst %}
</button>
<input type="text"
name="q"
class="form-control form-control-sm rounded-end"
value="{{ request.GET.q }}"
aria-describedby="inputGroup-sizing-sm"/>
<!-- Clear Button -->
{% if request.GET.q %}
<a href="{% url request.resolver_match.view_name %}"
class="btn btn-sm btn-outline-danger ms-1 rounded">
<i class="bi bi-x-lg"></i>
</a>
{% endif %}
<main class="d-grid gap-4 p-1">
<!-- Search Bar -->
<div class="row g-4">
<div class="col-12">
<div class="container-fluid p-2">
<form method="get">
<div class="input-group input-group-sm">
<button class="btn btn-sm btn-secondary rounded-start" type="submit">
{% trans "search" %}
</button>
<input type="text"
name="q"
class="form-control form-control-sm rounded-end"
value="{{ request.GET.q }}"
placeholder="{% trans 'Search customers...' %}" />
{% if request.GET.q %}
<a href="{% url request.resolver_match.view_name %}"
class="btn btn-sm btn-outline-danger ms-1 rounded">
<i class="bi bi-x-lg"></i>
</a>
{% endif %}
</div>
</form>
</div>
</div>
</div>
</form>
</div>
<table class="table table-hover table-responsive-sm">
<thead>
<tr>
<th>{% trans 'first name'|capfirst %}</th>
<th>{% trans 'middle name'|capfirst %}</th>
<th>{% trans 'last name'|capfirst %}</th>
<th>{% trans 'national ID'|capfirst %}</th>
<th>{% trans 'actions'|capfirst %}</th>
</tr>
</thead>
<tbody>
{% for customer in customers %}
<tr>
<td>{{ customer.first_name }}</td>
<td>{{ customer.middle_name }}</td>
<td>{{ customer.last_name }}</td>
<td>{{ customer.national_id }}</td>
<td>
<a class="btn btn-sm btn-success"
href="{% url 'customer_detail' customer.id %}">
{% trans 'view'|capfirst %}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Optional: Pagination -->
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination pagination-sm justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item py-0">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active"><a class="page-link" href="?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %} {% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</div>
</main>
<!-- Customer Table -->
<div class="row g-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">{% trans "Customers List" %}</h5>
</div>
<div class="card-body p-0">
<table class="table table-hover table-sm mb-0">
<thead class="table-light">
<tr>
<th>{% trans "First Name" %}</th>
<th>{% trans "Middle Name" %}</th>
<th>{% trans "Last Name" %}</th>
<th>{% trans "National ID" %}</th>
<th class="text-center">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for customer in customers %}
<tr>
<td>{{ customer.first_name }}</td>
<td>{{ customer.middle_name }}</td>
<td>{{ customer.last_name }}</td>
<td>{{ customer.national_id }}</td>
<td class="text-center">
<a href="{% url 'customer_detail' customer.id %}"
class="btn btn-sm btn-success">
{% trans "view" %}
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="5" class="text-center text-muted">
{% trans "No customers found." %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if is_paginated %}
<div class="card-footer bg-light">
<nav aria-label="Page navigation">
<ul class="pagination pagination-sm justify-content-center mb-0">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="{% trans 'Previous' %}">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&laquo;</span>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="{% trans 'Next' %}">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&raquo;</span>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endif %}
</div>
</div>
</div>
</main>
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -1,49 +1,81 @@
<!-- templates/cars/car_detail.html -->
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% load custom_filters %}
{% block title %}{{ _("Car Details") }}{% endblock %}
{% block content %}
<style>
.color-circle{
width: 32px;
height: 32px;
border-radius: 50px;
border-style: solid;
border-color: #000;
}
</style>
<div class="container mt-2 p-1">
<!-- Custom Card Modal -->
<div class="modal fade" id="customCardModal" tabindex="-1" aria-labelledby="customCardModalLabel" aria-hidden="true">
<!-- Custom Card Modal -->
<div class="modal fade" id="customCardModal" tabindex="-1" aria-labelledby="customCardModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light" id="customCardModalLabel">{% trans 'Custom Card' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Content will be loaded here via AJAX -->
</div>
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light" id="customCardModalLabel">{% trans 'Custom Card' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Content will be loaded here via AJAX -->
</div>
</div>
</div>
</div>
</div>
<!-- Reservation Modal -->
<div class="modal fade" id="reserveModal" tabindex="-1" aria-labelledby="reserveModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light" id="reserveModalLabel">{% trans 'Car Reservation' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% trans 'Are you sure you want to reserve this car?' %}
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-sm btn-danger"
data-bs-dismiss="modal">
{% trans 'No' %}
</button>
<form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-success btn-sm">{% trans "Yes" %}</button>
</form>
</div>
</div>
</div>
</div>
<!-- Specification Modal -->
<div class="modal fade"
id="specificationsModal"
tabindex="-1"
aria-labelledby="specificationsModalLabel"
aria-hidden="true">
<div class="modal fade" id="specificationsModal" tabindex="-1" aria-labelledby="specificationsModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content glossy-modal">
<div class="modal-header bg-primary text-light">
<h5 class="modal-title"
id="specificationsModalLabel">
{% trans 'specifications'|upper %}
<h5 class="modal-title" id="specificationsModalLabel">
{% trans 'specifications'|upper %}
</h5>
<button type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close">
</button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="specificationsContent"></div>
<div class="d-grid gap-2">
<button type="button"
class="btn btn-sm btn-danger"
data-bs-dismiss="modal">
{% trans 'Close' %}
</button>
</div>
</div>
</div>
</div>
@ -55,7 +87,10 @@
<main class="d-grid gap-4">
<div class="row g-4">
<div class="col-lg-6 col-xl-6">
<p class="fs-5">{% trans 'Car Details' %}</p>
<div class="card rounded shadow">
<p class="card-header bg-primary text-white rounded-top fw-bold">{% trans 'Car Details' %}</p>
<div class="card-body">
<table class="table table-sm table-responsive align-middle">
<tr>
<th>{% trans "VIN" %}</th>
@ -67,8 +102,7 @@
</tr>
<tr>
<th>{% trans "make" %}</th>
<td>{{ car.id_car_make.get_local_name }}</td>
<td>{{ car.id_car_make.get_local_name }}</td>
</tr>
<tr>
<th>{% trans "model" %}</th>
@ -116,143 +150,160 @@
<tr>
<th>{% trans 'specifications' %}</th>
<td>
<button type="button"
class="btn btn-primary btn-sm"
id="specification-btn"
data-bs-toggle="modal"
<button type="button"
class="btn btn-primary btn-sm"
id="specification-btn"
data-bs-toggle="modal"
data-bs-target="#specificationsModal">
{% trans 'view' %}
{% trans 'view' %}
</button>
</td>
</tr>
{% if car.custom_cards.exists %}
{% for custom_card in car.custom_cards.all %}
<tr>
<th>{% trans "Custom Number" %}</th>
<td>{{ custom_card.custom_number }}</td>
</tr>
<tr>
<th>{% trans "Custom Date" %}</th>
<td>{{ custom_card.custom_date|date }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<th>{% trans "Custom Card" %}</th>
<td>
<button type="button"
class="btn btn-sm btn-success"
data-bs-toggle="modal"
data-bs-target="#customCardModal">
{% trans 'Add' %}
</button>
</td>
</tr>
{% endif %}
<tr>
<th>{% trans 'Showroom Location' %}</th>
<td>
{% if car.location %}
{% if car.location.is_owner_showroom %}
{% trans 'Our Showroom' %}
{% else %}
{{ car.location.showroom.get_local_name }}
{% endif %}
<a href="{% url 'transfer' car.location.pk %}" class="btn btn-danger btn-sm">{% trans "transfer" %}</a>
{% else %}
{% trans "No location available." %}
<a href="{% url 'add_car_location' car.pk %}"
class="btn btn-success btn-sm mb-3 ms-2">
{% if car.custom_cards %}
<tr>
<th>{% trans "Custom Number" %}</th>
<td>{{ car.custom_cards.custom_number }}</td>
</tr>
<tr>
<th>{% trans "Custom Date" %}</th>
<td>{{ car.custom_cards.custom_date|date }}</td>
</tr>
{% else %}
<tr>
<th>{% trans "Custom Card" %}</th>
<td>
<button type="button"
class="btn btn-sm btn-success"
data-bs-toggle="modal"
data-bs-target="#customCardModal">
{% trans 'Add' %}
</button>
</td>
</tr>
{% endif %}
<tr>
<th>{% trans 'Showroom Location' %}</th>
<td>
{% if car.location %}
{% if car.location.is_owner_showroom %}
{% trans 'Our Showroom' %}
{% else %}
{{ car.location.showroom.get_local_name }}
{% endif %}
<a href="{% url 'transfer' car.location.pk %}"
class="btn btn-danger btn-sm">
{% trans "transfer" %}
</a>
{% else %} {% trans "No location available." %}
<a href="{% url 'add_car_location' car.pk %}"
class="btn btn-success btn-sm ms-2">
{% trans "Add" %}
</a>
</td>
{% endif %}
</tr>
</a>
</td>
{% endif %}
</tr>
</table>
<div>
<a href="{% url 'car_update' car.pk %}" class="btn btn-warning btn-sm">{% trans "Edit" %}</a>
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-xl-6">
<p class="fs-5">{% trans 'Financial Details' %}</p>
{% if car.finances.exists %} {% for finance in car.finances.all %}
<table class="table table-sm table-responsive mb-3 align-middle">
<div class="card rounded shadow">
<p class="card-header bg-primary text-white rounded-top fw-bold">{% trans 'Financial Details' %}</p>
<div class="card-body">
{% if car.finances %}
<table class="table table-sm table-responsive align-middle">
<tr>
<th>{% trans "Cost Price" %}</th>
<td>{{ finance.cost_price }}</td>
<td>{{ car.finances.cost_price }}</td>
</tr>
<tr>
<th>{% trans "Selling Price" %}</th>
<td>{{ finance.selling_price }}</td>
<td>{{ car.finances.selling_price }}</td>
</tr>
<tr>
<tr>
<td><small class="ms-5">{% trans "Administration Fee" %}</small></td>
<td><small>{{ finance.administration_fee }}</small></td>
<td><small>{{ car.finances.administration_fee }}</small></td>
</tr>
<tr>
<tr>
<td><small class="ms-5">{% trans "Registration Fee" %}</small></td>
<td><small>{{ finance.registration_fee }}</small></td>
<td><small>{{ car.finances.registration_fee }}</small></td>
</tr>
<tr>
<td><small class="ms-5">{% trans "Transportation Fee" %}</small></td>
<td><small>{{ finance.transportation_fee }}</small></td>
<tr>
<td><small class="ms-5">{% trans "Transportation Fee" %}</small></td>
<td><small>{{ car.finances.transportation_fee }}</small></td>
</tr>
<tr>
<td><small class="ms-5">{% trans "Custom Card Fee" %}</small></td>
<td><small>{{ finance.custom_card_fee }}</small></td>
<tr>
<td><small class="ms-5">{% trans "Custom Card Fee" %}</small></td>
<td><small>{{ car.finances.custom_card_fee }}</small></td>
</tr>
<tr>
<tr>
<th>{% trans "Discount Amount" %}</th>
<td>{{ finance.discount_amount }} - </td>
<td>{{ car.finances.discount_amount }} -</td>
</tr>
<tr>
<th>{% trans "VAT Amount" %}</th>
<td>{{ finance.vat_amount }}</td>
<td>{{ car.finances.vat_amount }}</td>
</tr>
<tr>
<th>{% trans "Total" %}</th>
<td>{{ car.total }}</td>
<td>{{ car.finances.total }}</td>
</tr>
<tr>
<tr>
<td colspan="2">
<a href="{% url 'car_finance_update' finance.pk %}"
class="btn btn-warning btn-sm mb-3">
<a href="{% url 'car_finance_update' car.finances.pk %}"
class="btn btn-warning btn-sm mb-3">
{% trans "Edit Finance Details" %}
</a>
{% endfor %}
{% else %}
<p>{% trans "No finance details available." %}</p>
<a href="{% url 'car_finance_create' car.pk %}"
class="btn btn-success btn-sm mb-3">
</a>
{% else %}
<p>{% trans "No finance details available." %}</p>
<a href="{% url 'car_finance_create' car.pk %}"
class="btn btn-success btn-sm mb-3">
{% trans "Add Finance Details" %}
</a>
</a>
</td>
</tr>
{% endif %}
</table>
<p class="fs-5 mt-2">{% trans 'Colors Details' %}</p>
</tr>
{% endif %}
</table>
</div>
</div>
<div class="card rounded shadow mt-3">
<p class="card-header bg-primary text-white rounded-top fw-bold">{% trans 'Colors Details' %}</p>
<div class="card-body">
<table class="table table-sm table-responsive align-middle">
<tbody class=" align-middle">
<tbody class="align-middle">
{% if car.colors.exists %}
{% for color in car.colors.all %}
<tr>
<th>{% trans 'Exterior' %}</th>
<th>{% trans 'Exterior' %}</th>
<td>
<span>{{ color.exterior.get_local_name }}</span>
</td>
<td class="align-middle">
<div class="text-end" style="width: 32px; height: 32px; background-color: rgb({{ color.exterior.rgb }}); border-radius: 50px; border-style: solid; border-color: #000;"></div>
<div class="text-end color-circle"
style="background-color: rgb({{ color.exterior.rgb }});">
</div>
</td>
</tr>
<tr>
<th>{% trans 'Interior' %}</th>
<tr>
<th>{% trans 'Interior' %}</th>
<td>
<span>{{ color.interior.get_local_name }}</span>
</td>
<td class="align-middle">
<div class="text-end" style="width: 32px; height: 32px; background-color: rgb({{ color.interior.rgb }}); border-radius: 50px; border-style: solid; border-color: #000;"></div>
<div class="text-end color-circle"
style="background-color: rgb({{ color.interior.rgb }});">
</div>
</td>
</tr>
{% endfor %}
{% endfor %}
{% else %}
<tr>
<td colspan="2">
@ -261,78 +312,82 @@
</tr>
<tr>
<td colspan="2">
<a href="{% url 'add_color' car.pk %}"
class="btn btn-success btn-sm">
{% trans "Get Colors" %}
<a href="{% url 'add_color' car.pk %}" class="btn btn-success btn-sm">
{% trans "Get Colors" %}
</a>
</td>
</tr>
{% endif %}
{% endif %}
</tbody>
</table>
<p class="fs-5 mt-2">{% trans 'Reservations Details' %}</p>
{% if car.is_reserved %}
</div>
</div>
<div class="card rounded shadow mt-3">
<p class="card-header bg-primary text-white rounded-top fw-bold">{% trans 'Reservations Details' %}</p>
<div class="card-body">
{% if car.is_reserved %}
<table class="table table-sm table-responsive align-middle">
<thead>
<thead>
<tr>
<th>{% trans "Reserved By" %}</th>
<th>{% trans "Expires At" %}</th>
<th>{% trans 'Actions' %}</th>
<th>{% trans "Reserved By" %}</th>
<th>{% trans "Expires At" %}</th>
<th>{% trans 'Actions' %}</th>
</tr>
</thead>
<tbody>
</thead>
<tbody>
{% for reservation in car.reservations.all %}
<tr>
<td>{{ reservation.reserved_by.username }}</td>
<td>{{ reservation.reserved_until }}</td>
<td>
{% 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-success">
<small>{% trans "Renew" %}</small>
</button>
<button type="submit"
name="action"
value="cancel"
class="btn btn-sm btn-secondary">
<small>{% trans "Cancel" %}</small>
</button>
</form>
{% else %}
<span class="badge bg-danger" style="width: 120px;">{% trans "Expired" %}</span>
{% endif %}
</td>
<td>{{ reservation.reserved_by.username }}</td>
<td>{{ reservation.reserved_until }}</td>
<td>
{% 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-success">
<small>{% trans "Renew" %}</small>
</button>
<button type="submit"
name="action"
value="cancel"
class="btn btn-sm btn-secondary">
<small>{% trans "Cancel" %}</small>
</button>
</form>
{% else %}
<span class="badge bg-danger"
style="width: 120px;">
{% trans "Expired" %}
</span>
{% endif %}
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td>
<form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-success btn-sm">{% trans "Reserve" %}</button>
</form>
{% endif %}
</td>
</tr>
</tbody>
{% else %}
<tr>
<td>
<a class="btn btn-sm btn-success me-1"
data-bs-toggle="modal"
data-bs-target="#reserveModal">
{{ _("Reserve") }}
</a>
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="">
<!-- Actions -->
<a href="{% url 'car_update' car.pk %}" class="btn btn-warning btn-sm">{% trans "Edit" %}</a>
<div class="d-grid gap-2">
<a href="{% url 'inventory_stats' %}" class="btn btn-secondary btn-sm">{% trans "Back to List" %}</a>
</div>
</div>
</main>
</div>
</div>
@ -358,33 +413,28 @@
const csrfToken = getCookie("csrftoken");
const ajaxUrl = "{% url 'ajax_handler' %}";
const modal = document.getElementById('customCardModal');
const modalBody = modal.querySelector('.modal-body');
const modal = document.getElementById("customCardModal");
const modalBody = modal.querySelector(".modal-body");
// When the modal is triggered, load the form
modal.addEventListener('show.bs.modal', function () {
const url = "{% url 'add_custom_card' car.pk %}";
// When the modal is triggered, load the form
modal.addEventListener("show.bs.modal", function () {
const url = "{% url 'add_custom_card' car.pk %}";
fetch(url)
.then(response => response.text())
.then(html => {
modalBody.innerHTML = html;
})
.catch(error => {
modalBody.innerHTML = '<p class="text-danger">Error loading form. Please try again later.</p>';
console.error('Error loading form:', error);
});
fetch(url)
.then((response) => response.text())
.then((html) => {
modalBody.innerHTML = html;
})
.catch((error) => {
modalBody.innerHTML = '<p class="text-danger">Error loading form. Please try again later.</p>';
console.error("Error loading form:", error);
});
});
modal.addEventListener("hidden.bs.modal", function () {
modalBody.innerHTML = "";
});
modal.addEventListener('hidden.bs.modal', function () {
modalBody.innerHTML = '';
});
const showSpecificationButton = document.getElementById("specification-btn");
const specificationsContent = document.getElementById("specificationsContent");

View File

@ -1,47 +1,19 @@
{% extends 'base.html' %}
{% load crispy_forms_filters %}
{% load i18n %}
{% load custom_filters %}
{% block title %}
{% trans 'Edit Car' %}
{% endblock %}
{% block content %}
<div class="container p-4">
<h4 class="mb-4">
{% trans 'Edit Car' %}
</h4>
<!-- Display Validation Errors -->
{% if form.errors %}
<div class="alert alert-danger">
<ul class="mb-0">
{% for field in form %}
{% for error in field.errors %}
<li><strong>{{ field.label }}:</strong> {{ error }}</li>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<form method="post" class="needs-validation" novalidate>
{% csrf_token %}
{{ form|crispy }}
{% extends 'base.html' %} {% load crispy_forms_filters %} {% load i18n %} {% load custom_filters %} {% block title %} {% trans 'Edit Car' %} {% endblock %} {% block content %}
<div class="container">
<div class="card rounded shadow mt-3">
<p class="card-header bg-primary text-white rounded-top fw-bold">{% trans 'Edit Car' %}</p>
<div class="card-body">
<form method="post" class="needs-validation" novalidate>
{% csrf_token %} {{ form|crispy }}
<!-- Save and Back Buttons -->
<div class="d-flex justify-content-center mt-4 ms-2">
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger">{% trans "Back" %}</a>
<button type="submit" class="btn btn-success ms-2">
{% trans 'Save' %}
</button>
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger">{% trans "Back" %}</a>
<button type="submit" class="btn btn-sm btn-success ms-2">
{% trans 'Save' %}
</button>
</div>
</form>
</form>
</div>
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -13,39 +13,23 @@
height: 22px;
border-radius: 50%;
border: 1px solid #ccc;
margin: auto;
text-align: center;
vertical-align: middle;
line-height: 22px;
}
</style>
<div class="d-flex flex-column min-vh-100">
<div class="d-flex flex-column flex-sm-grow-1 ms-sm-14 p-1">
<div class="container mt-3">
<div class="d-flex flex-column min-vh-100 flex-sm-grow-1 ms-sm-14 p-1">
<main class="d-grid gap-4 p-1">
<div class="row g-4">
<div class="col-lg-6 col-xl-12">
<div class="container-fluid p-2">
<form method="get" class="mb-3">
<div class="input-group input-group-sm">
<button id="inputGroup-sizing-sm"
class="btn btn-sm btn-secondary rounded-start" type="submit">
{% trans 'search'|capfirst %}
</button>
<input type="text"
name="q"
class="form-control form-control-sm rounded-end"
value="{{ request.GET.q }}"
aria-describedby="inputGroup-sizing-sm" />
<!-- Clear Button -->
{% if request.GET.q %}
<a href="{% url 'inventory_list' %}"
class="btn btn-sm btn-outline-danger ms-1 rounded">
<i class="bi bi-x-lg"></i>
</a>
{% endif %}
</div>
</form>
</div>
<table class="table table-responsive table-sm align-middle">
<div class="card rounded shadow">
<p class="card-header bg-primary text-white rounded-top fw-bold">
{{ cars.id_car_make.get_local_name }} -
{{ cars.id_car_model.get_local_name }}
</p>
<div class="card-body">
<table class="table table-responsive table-hover table-sm align-middle">
<thead>
<tr>
<th>{% trans "VIN" %}</th>
@ -62,11 +46,25 @@
<td>{{ car.vin }}</td>
<td>{{ car.year }}</td>
{% if car.colors.exists %}
<td><span>{{ car.colors.first.exterior.get_local_name }}<div class="color-div" style="background-color: rgb({{ car.colors.first.exterior.rgb }});"></div></span></td>
<td>{{ car.colors.first.interior.get_local_name }}<div class="color-div" style="background-color: rgb({{ car.colors.first.interior.rgb }});"></div></td>
<td>
<div class="d-flex flex-column align-items-center">
<span class="color-div"
style="background-color: rgb({{ car.colors.first.exterior.rgb }});"
title="{{ car.colors.first.exterior.get_local_name }}">
</span>
</div>
</td>
<td>
<div class="d-flex flex-column align-items-center">
<span class="color-div"
style="background-color: rgb({{ car.colors.first.interior.rgb }});"
title="{{ car.colors.first.interior.get_local_name }}">
</span>
</div>
</td>
{% else %}
<td><div class="color-div"><i class="bi bi-x-lg fs-6"></i></div></td>
<td><div class="color-div"><i class="bi bi-x-lg fs-6"></i></div></td>
<td><span class="color-div">{% trans 'No Color' %}</span></td>
<td><span class="color-div">{% trans 'No Color' %}</span></td>
{% endif %}
{% if car.location.is_owner_showroom %}
<td> {% trans 'Our Showroom' %}</td>
@ -143,6 +141,8 @@
</ul>
</nav>
{% endif %}
</div>
</div>
</div>
</div>
</main>

View File

@ -51,8 +51,8 @@
</td>
<td>{{ vendor.address }}</td>
<td>
<a href="{% url 'vendor_detail' vendor.id %}" class="btn btn-warning btn-sm">
{{ _("View")|capfirst }}
<a href="{% url 'vendor_detail' vendor.id %}" class="btn btn-success btn-sm">
{{ _("view")|capfirst }}
</a>
</td>
</tr>

View File

@ -39,9 +39,7 @@
<!-- Vendor Details -->
<div class="container mt-4">
<div class="card shadow rounded">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">{% trans "Vendor Details" %}</h4>
</div>
<p class="card-header bg-primary text-white mb-0 fs-5">{% trans "Vendor Details" %}</p>
<div class="card-body">
<ul class="list-group list-group-flush">
<li class="list-group-item">