update
This commit is contained in:
parent
7cfd98528e
commit
761cd2e338
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -232,7 +232,7 @@ wmi_manufacturer_mapping = {
|
|||||||
"LJS": "Yaxing Coach",
|
"LJS": "Yaxing Coach",
|
||||||
"LJU": "Lotus Geely",
|
"LJU": "Lotus Geely",
|
||||||
"LJX": "JMC Ford",
|
"LJX": "JMC Ford",
|
||||||
"LJ1": "Nio",
|
"LJ1": "JAC",
|
||||||
"LJ8": "Zotye",
|
"LJ8": "Zotye",
|
||||||
"LKC": "Changhe",
|
"LKC": "Changhe",
|
||||||
"LKL": "Higer Bus",
|
"LKL": "Higer Bus",
|
||||||
@ -317,6 +317,7 @@ wmi_manufacturer_mapping = {
|
|||||||
"LZ4": "Shangyang",
|
"LZ4": "Shangyang",
|
||||||
"L1N": "XPeng",
|
"L1N": "XPeng",
|
||||||
"L2C": "Chery",
|
"L2C": "Chery",
|
||||||
|
"L3H": "Victory",
|
||||||
"L4F": "Suzhou Eagle",
|
"L4F": "Suzhou Eagle",
|
||||||
"L5C": "KangDi",
|
"L5C": "KangDi",
|
||||||
"L5K": "Yongkang",
|
"L5K": "Yongkang",
|
||||||
@ -1524,6 +1525,7 @@ def decode_vin_haikalna(vin):
|
|||||||
'modelYear': year,
|
'modelYear': year,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
print(data)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@ -1534,3 +1536,4 @@ def decode_vin_haikalna(vin):
|
|||||||
# vin_number = 'LMXA14AF7PZ356070'
|
# vin_number = 'LMXA14AF7PZ356070'
|
||||||
# decoded_vin = decode_vin_haikalna(vin_number)
|
# decoded_vin = decode_vin_haikalna(vin_number)
|
||||||
# print(decoded_vin)
|
# print(decoded_vin)
|
||||||
|
# LJ11PCBC2P1317660
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
# Generated by Django 5.1.4 on 2025-01-02 23:56
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='subscriptionplan',
|
||||||
|
options={'verbose_name': 'Subscription Plan', 'verbose_name_plural': 'Subscription Plans'},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='max_users',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='opportunity',
|
||||||
|
name='assigned_at',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='Assigned At'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='opportunity',
|
||||||
|
name='assigned_to',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='deals_assigned', to='inventory.staff'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='billing_cycle',
|
||||||
|
field=models.CharField(choices=[('monthly', 'Monthly'), ('annual', 'Annual')], default='monthly', help_text='Billing cycle for the subscription', max_length=10),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='last_payment_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Date of the last payment made', null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='next_payment_date',
|
||||||
|
field=models.DateField(blank=True, help_text='Date of the next payment due', null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='created_at',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='custom_features',
|
||||||
|
field=models.JSONField(blank=True, help_text='Additional features specific to this plan', null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='max_inventory_size',
|
||||||
|
field=models.PositiveIntegerField(default=50, help_text='Maximum number of cars in inventory'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='support_level',
|
||||||
|
field=models.CharField(choices=[('basic', 'Basic Support'), ('priority', 'Priority Support'), ('dedicated', 'Dedicated Support')], default='basic', help_text='Level of support provided', max_length=50),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='updated_at',
|
||||||
|
field=models.DateTimeField(auto_now=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='end_date',
|
||||||
|
field=models.DateField(help_text='Date when the subscription ends'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='plan',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscriptions', to='inventory.subscriptionplan'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='start_date',
|
||||||
|
field=models.DateField(help_text='Date when the subscription starts'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='max_users',
|
||||||
|
field=models.PositiveIntegerField(default=1, help_text='Maximum number of users allowed'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='subscriptionplan',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(help_text='Name of the subscription plan', max_length=100, unique=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# Generated by Django 5.1.4 on 2025-01-01 16:25
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('django_ledger', '0017_alter_accountmodel_unique_together_and_more'),
|
|
||||||
('inventory', '0021_opportunitylog'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='opportunitylog',
|
|
||||||
name='user',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='opportunitylog',
|
|
||||||
name='staff',
|
|
||||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='inventory.staff', verbose_name='Staff'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='carfinance',
|
|
||||||
name='additional_services',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='additional_finances', to='django_ledger.itemmodel'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='customer',
|
|
||||||
name='is_lead',
|
|
||||||
field=models.BooleanField(default=False, verbose_name='Is Lead'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -502,28 +502,64 @@ class TimestampedModel(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class Subscription(models.Model):
|
class Subscription(models.Model):
|
||||||
plan = models.CharField(max_length=255) # e.g. "basic", "premium"
|
plan = models.ForeignKey("SubscriptionPlan", on_delete=models.CASCADE, related_name="subscriptions")
|
||||||
start_date = models.DateField()
|
start_date = models.DateField(help_text="Date when the subscription starts")
|
||||||
end_date = models.DateField()
|
end_date = models.DateField(help_text="Date when the subscription ends")
|
||||||
max_users = models.IntegerField() # maximum number of users per account
|
|
||||||
users = models.ManyToManyField(User, through='SubscriptionUser') # many-to-many relationship with User model
|
users = models.ManyToManyField(User, through='SubscriptionUser') # many-to-many relationship with User model
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
|
billing_cycle = models.CharField(
|
||||||
|
max_length=10,
|
||||||
|
choices=[('monthly', 'Monthly'), ('annual', 'Annual')],
|
||||||
|
default='monthly',
|
||||||
|
help_text="Billing cycle for the subscription"
|
||||||
|
)
|
||||||
|
last_payment_date = models.DateField(null=True, blank=True, help_text="Date of the last payment made")
|
||||||
|
next_payment_date = models.DateField(null=True, blank=True, help_text="Date of the next payment due")
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Subscription")
|
||||||
|
verbose_name_plural = _("Subscriptions")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.plan
|
return self.plan.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def total_subscribers(self):
|
||||||
|
return self.users.count()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionUser(models.Model):
|
class SubscriptionUser(models.Model):
|
||||||
subscription = models.ForeignKey(Subscription, on_delete=models.CASCADE)
|
subscription = models.ForeignKey(Subscription, on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Subscription User")
|
||||||
|
verbose_name_plural = _("Subscription Users")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.subscription} - {self.user}"
|
return f"{self.subscription} - {self.user}"
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionPlan(models.Model):
|
class SubscriptionPlan(models.Model):
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=100, unique=True, help_text=_("Name of the subscription plan"))
|
||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
price = models.DecimalField(max_digits=10, decimal_places=2)
|
price = models.DecimalField(max_digits=10, decimal_places=2)
|
||||||
max_users = models.IntegerField() # maximum number of users per account
|
max_users = models.PositiveIntegerField(help_text=_("Maximum number of users allowed"), default=1)
|
||||||
|
max_inventory_size = models.PositiveIntegerField(help_text=_("Maximum number of cars in inventory"), default=50)
|
||||||
|
support_level = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[('basic', 'Basic Support'), ('priority', 'Priority Support'), ('dedicated', 'Dedicated Support')],
|
||||||
|
default='basic',
|
||||||
|
help_text="Level of support provided"
|
||||||
|
)
|
||||||
|
custom_features = models.JSONField(blank=True, null=True, help_text=_("Additional features specific to this plan"))
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _("Subscription Plan")
|
||||||
|
verbose_name_plural = _("Subscription Plans")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name} - {self.price}"
|
return f"{self.name} - {self.price}"
|
||||||
|
|
||||||
@ -731,6 +767,8 @@ class Opportunity(models.Model):
|
|||||||
created_by = models.ForeignKey(Staff, on_delete=models.SET_NULL, null=True, related_name="deals_created")
|
created_by = models.ForeignKey(Staff, on_delete=models.SET_NULL, null=True, related_name="deals_created")
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At"))
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At"))
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At"))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At"))
|
||||||
|
assigned_to = models.ForeignKey(Staff, on_delete=models.CASCADE, related_name="deals_assigned")
|
||||||
|
assigned_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Assigned At"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Opportunity")
|
verbose_name = _("Opportunity")
|
||||||
@ -746,6 +784,7 @@ class Notes(models.Model):
|
|||||||
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="notes_created")
|
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="notes_created")
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At"))
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At"))
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At"))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Notes")
|
verbose_name = _("Notes")
|
||||||
verbose_name_plural = _("Notes")
|
verbose_name_plural = _("Notes")
|
||||||
@ -1053,3 +1092,5 @@ class UserActivityLog(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.user.email} - {self.action} - {self.timestamp}"
|
return f"{self.user.email} - {self.action} - {self.timestamp}"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -53,7 +53,7 @@ def decode_vin(vin):
|
|||||||
"model": v.Model,
|
"model": v.Model,
|
||||||
"modelYear": v.ModelYear,
|
"modelYear": v.ModelYear,
|
||||||
}
|
}
|
||||||
|
print(data)
|
||||||
return data if all([x for x in data.values()]) else None
|
return data if all([x for x in data.values()]) else None
|
||||||
|
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ def elm(vin):
|
|||||||
"model": response["data"]["model"],
|
"model": response["data"]["model"],
|
||||||
"modelYear": response["data"]["modelYear"],
|
"modelYear": response["data"]["modelYear"],
|
||||||
}
|
}
|
||||||
|
print(data)
|
||||||
return data if all([x for x in data.values()]) else None
|
return data if all([x for x in data.values()]) else None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -105,7 +105,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Cash Account
|
# Create Cash Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="101",
|
code="1101",
|
||||||
role=roles.ASSET_CA_CASH,
|
role=roles.ASSET_CA_CASH,
|
||||||
name=_("Cash"),
|
name=_("Cash"),
|
||||||
balance_type="debit",
|
balance_type="debit",
|
||||||
@ -115,7 +115,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Accounts Receivable Account
|
# Create Accounts Receivable Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="102",
|
code="1102",
|
||||||
role=roles.ASSET_CA_RECEIVABLES,
|
role=roles.ASSET_CA_RECEIVABLES,
|
||||||
name=_("Accounts Receivable"),
|
name=_("Accounts Receivable"),
|
||||||
balance_type="debit",
|
balance_type="debit",
|
||||||
@ -125,7 +125,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Inventory Account
|
# Create Inventory Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="103",
|
code="1103",
|
||||||
role=roles.ASSET_CA_INVENTORY,
|
role=roles.ASSET_CA_INVENTORY,
|
||||||
name=_("Inventory"),
|
name=_("Inventory"),
|
||||||
balance_type="debit",
|
balance_type="debit",
|
||||||
@ -135,7 +135,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Accounts Payable Account
|
# Create Accounts Payable Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="101",
|
code="2101",
|
||||||
role=roles.LIABILITY_CL_ACC_PAYABLE,
|
role=roles.LIABILITY_CL_ACC_PAYABLE,
|
||||||
name=_("Accounts Payable"),
|
name=_("Accounts Payable"),
|
||||||
balance_type="credit",
|
balance_type="credit",
|
||||||
@ -144,7 +144,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Equity Account
|
# Create Equity Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="101",
|
code="3101",
|
||||||
role=roles.EQUITY_CAPITAL,
|
role=roles.EQUITY_CAPITAL,
|
||||||
name=_("Partners Current"),
|
name=_("Partners Current"),
|
||||||
balance_type="credit",
|
balance_type="credit",
|
||||||
@ -154,7 +154,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Sales Revenue Account
|
# Create Sales Revenue Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="101",
|
code="4101",
|
||||||
role=roles.INCOME_OPERATIONAL,
|
role=roles.INCOME_OPERATIONAL,
|
||||||
name=_("Sales Revenue"),
|
name=_("Sales Revenue"),
|
||||||
balance_type="credit",
|
balance_type="credit",
|
||||||
@ -164,7 +164,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Cost of Goods Sold Account
|
# Create Cost of Goods Sold Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="101",
|
code="5101",
|
||||||
role=roles.COGS,
|
role=roles.COGS,
|
||||||
name=_("Cost of Goods Sold"),
|
name=_("Cost of Goods Sold"),
|
||||||
balance_type="debit",
|
balance_type="debit",
|
||||||
@ -174,7 +174,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
# Create Rent Expense Account
|
# Create Rent Expense Account
|
||||||
entity.create_account(
|
entity.create_account(
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
code="101",
|
code="6101",
|
||||||
role=roles.EXPENSE_OPERATIONAL,
|
role=roles.EXPENSE_OPERATIONAL,
|
||||||
name=_("Rent Expense"),
|
name=_("Rent Expense"),
|
||||||
balance_type="debit",
|
balance_type="debit",
|
||||||
|
|||||||
@ -90,7 +90,7 @@ urlpatterns = [
|
|||||||
path('sales/quotations/<int:pk>/mark_quotation/', views.mark_quotation, name='mark_quotation'),
|
path('sales/quotations/<int:pk>/mark_quotation/', views.mark_quotation, name='mark_quotation'),
|
||||||
path('sales/quotations/<int:pk>/post_quotation/', views.post_quotation, name='post_quotation'),
|
path('sales/quotations/<int:pk>/post_quotation/', views.post_quotation, name='post_quotation'),
|
||||||
path('sales/quotations/<int:pk>/invoice_detail/', views.invoice_detail, name='invoice_detail'),
|
path('sales/quotations/<int:pk>/invoice_detail/', views.invoice_detail, name='invoice_detail'),
|
||||||
|
path('subscriptions', views.SubscriptionPlans.as_view(), name='subscriptions'),
|
||||||
#Payment URLs
|
#Payment URLs
|
||||||
# path('sales/quotations/<int:pk>/payment/', views.PaymentCreateView.as_view(), name='payment_create'),
|
# path('sales/quotations/<int:pk>/payment/', views.PaymentCreateView.as_view(), name='payment_create'),
|
||||||
path('sales/quotations/<int:pk>/payment/', views.payment_create, name='payment_create'),
|
path('sales/quotations/<int:pk>/payment/', views.payment_create, name='payment_create'),
|
||||||
|
|||||||
@ -1468,14 +1468,14 @@ def payment_invoice(request, pk):
|
|||||||
|
|
||||||
def payment_create(request, pk):
|
def payment_create(request, pk):
|
||||||
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
||||||
dealer = request.user.dealer
|
dealer = get_user_type(request)
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = forms.PaymentForm(request.POST)
|
form = forms.PaymentForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.instance.quotation = quotation
|
form.instance.quotation = quotation
|
||||||
insatnce = form.save()
|
insatnce = form.save()
|
||||||
|
|
||||||
dealer = request.user.dealer
|
dealer = dealer
|
||||||
entity = dealer.entity
|
entity = dealer.entity
|
||||||
customer = (
|
customer = (
|
||||||
entity.get_customers()
|
entity.get_customers()
|
||||||
@ -2359,3 +2359,9 @@ class ItemServiceListView(ListView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.request.entity.get_items_services()
|
return self.request.entity.get_items_services()
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionPlans(ListView):
|
||||||
|
model = models.SubscriptionPlan
|
||||||
|
template_name = 'subscriptions/subscription_plan.html'
|
||||||
|
context_object_name = 'plans'
|
||||||
|
|||||||
BIN
static/.DS_Store
vendored
BIN
static/.DS_Store
vendored
Binary file not shown.
@ -1,8 +1,9 @@
|
|||||||
.color-div {
|
.color-div {
|
||||||
width: 22px;
|
width: 64px;
|
||||||
height: 22px;
|
height: 16px;
|
||||||
border-radius: 50%;
|
padding: 2px 4px;
|
||||||
border: 1px solid #ccc;
|
border-radius: 1px;
|
||||||
|
border: 1px outset #CBD0DDFd;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
|
|||||||
BIN
static/images/.DS_Store
vendored
BIN
static/images/.DS_Store
vendored
Binary file not shown.
BIN
static/images/car_make/Dongfeng.png
Normal file
BIN
static/images/car_make/Dongfeng.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
BIN
static/images/car_make/Forthing.png
Normal file
BIN
static/images/car_make/Forthing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
BIN
static/images/logos/.DS_Store
vendored
BIN
static/images/logos/.DS_Store
vendored
Binary file not shown.
BIN
static/images/logos/car_make/Dongfeng.png
Normal file
BIN
static/images/logos/car_make/Dongfeng.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
BIN
static/images/logos/car_make/Forthing.png
Normal file
BIN
static/images/logos/car_make/Forthing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
BIN
static/images/logos/car_make/changan.png
Normal file
BIN
static/images/logos/car_make/changan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
static/images/logos/car_make/haval.png
Normal file
BIN
static/images/logos/car_make/haval.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@ -30,6 +30,7 @@
|
|||||||
<link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300;400;600;700;800;900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300;400;600;700;800;900&display=swap" rel="stylesheet">
|
||||||
<link href="{% static 'vendors/simplebar/simplebar.min.css' %}" rel="stylesheet">
|
<link href="{% static 'vendors/simplebar/simplebar.min.css' %}" rel="stylesheet">
|
||||||
<link href="{% static 'css/sweetalert2.min.css' %}" rel="stylesheet">
|
<link href="{% static 'css/sweetalert2.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 rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.8/css/line.css">
|
||||||
<link href="{% static 'css/custom.css' %}" rel="stylesheet">
|
<link href="{% static 'css/custom.css' %}" rel="stylesheet">
|
||||||
{% if LANGUAGE_CODE == 'en' %}
|
{% if LANGUAGE_CODE == 'en' %}
|
||||||
@ -80,6 +81,7 @@
|
|||||||
<script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script>
|
<script src="{% static 'vendors/mapbox-gl/mapbox-gl.js' %}"></script>
|
||||||
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
|
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
|
||||||
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
||||||
|
<script src="{% static 'vendors/flatpickr/flatpickr.min.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
|
||||||
@ -104,7 +106,7 @@
|
|||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
const Toast = Swal.mixin({
|
/*const Toast = Swal.mixin({
|
||||||
toast: true,
|
toast: true,
|
||||||
position: "top-end",
|
position: "top-end",
|
||||||
showConfirmButton: false,
|
showConfirmButton: false,
|
||||||
@ -114,7 +116,7 @@ const Toast = Swal.mixin({
|
|||||||
toast.onmouseenter = Swal.stopTimer;
|
toast.onmouseenter = Swal.stopTimer;
|
||||||
toast.onmouseleave = Swal.resumeTimer;
|
toast.onmouseleave = Swal.resumeTimer;
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
function notify(tag,msg){
|
function notify(tag,msg){
|
||||||
Toast.fire({
|
Toast.fire({
|
||||||
icon: tag,
|
icon: tag,
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
{% block vendors %}<a class="nav-link active">{{ _("Customers")|capfirst }}</a>{% endblock %}
|
{% block vendors %}<a class="nav-link active">{{ _("Customers")|capfirst }}</a>{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="pt-5 pb-9">
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2 class="mb-4">{{ _("Customers")|capfirst }}</h2>
|
<h2 class="mb-4">{{ _("Customers")|capfirst }}</h2>
|
||||||
<div class="row g-3 justify-content-between mb-4">
|
<div class="row g-3 justify-content-between mb-4">
|
||||||
@ -186,6 +185,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
BIN
templates/dealers/.DS_Store
vendored
BIN
templates/dealers/.DS_Store
vendored
Binary file not shown.
@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<h6 class="mb-2 text-body-secondary">{% trans 'Total users'|capfirst %}</h6>
|
<h6 class="mb-2 text-body-secondary">{% trans 'Total users'|capfirst %}</h6>
|
||||||
<h4 class="fs-7 text-body-highlight mb-0">{{ dealer.total_count }} / {{ dealer.get_active_plan.max_users }}</h4>
|
<h4 class="fs-7 text-body-highlight mb-0">{{ dealer.total_count }} / {{ dealer.get_active_plan.plan.max_users }}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<h6 class="mb-2 text-body-secondary">{% trans 'Subscription' %}</h6>
|
<h6 class="mb-2 text-body-secondary">{% trans 'Subscription' %}</h6>
|
||||||
@ -123,11 +123,11 @@
|
|||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
<div class="mb-5 mb-md-0 mb-lg-5 me-3">
|
<div class="mb-5 mb-md-0 mb-lg-5 me-3">
|
||||||
<div class="d-sm-flex d-md-block d-lg-flex align-items-center mb-3">
|
<div class="d-sm-flex d-md-block d-lg-flex align-items-center mb-3">
|
||||||
<h3 class="mb-0">{{ dealer.get_active_plan.plan|capfirst }}</h3><span class="badge ms-sm-3 ms-md-0 ms-lg-3 fs-10 text-bg-warning">{% trans 'most valuable'|upper %}</span>
|
<h3 class="mb-0">{{ dealer.get_active_plan.plan.name|capfirst }}</h3><span class="badge ms-sm-3 ms-md-0 ms-lg-3 fs-10 text-bg-warning">{% trans 'most valuable'|upper %}</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="fs-9 text-body-tertiary">{% trans 'Active until' %}: {{ dealer.get_active_plan.end_date|date}}</p>
|
<p class="fs-9 text-body-tertiary">{% trans 'Active until' %}: {{ dealer.get_active_plan.end_date|date}}</p>
|
||||||
<div class="d-flex align-items-end mb-md-5 mb-lg-0">
|
<div class="d-flex align-items-end mb-md-5 mb-lg-0">
|
||||||
<h4 class="fw-bolder me-1">{{ dealer.get_plan.price }} {% trans 'SAR' %}</h4>
|
<h4 class="fw-bolder me-1">{{ dealer.get_active_plan.plan.price|floatformat }} {% trans 'SAR' %}</h4>
|
||||||
<h5 class="fs-9 fw-normal text-body-tertiary ms-1">Per month</h5>
|
<h5 class="fs-9 fw-normal text-body-tertiary ms-1">Per month</h5>
|
||||||
</div>
|
</div>
|
||||||
</div><img class="d-dark-none" src="{% static 'images/spot-illustrations/star.png' %}" width="54" height="54" alt="" /><img class="d-light-none" src="{% static 'images/spot-illustrations/star-dark.png' %}" width="54" height="54" alt="" />
|
</div><img class="d-dark-none" src="{% static 'images/spot-illustrations/star.png' %}" width="54" height="54" alt="" /><img class="d-light-none" src="{% static 'images/spot-illustrations/star-dark.png' %}" width="54" height="54" alt="" />
|
||||||
@ -136,7 +136,7 @@
|
|||||||
<div class="col-sm-8 col-md-12">
|
<div class="col-sm-8 col-md-12">
|
||||||
<div class="d-sm-flex d-md-block d-lg-flex justify-content-end align-items-end h-100">
|
<div class="d-sm-flex d-md-block d-lg-flex justify-content-end align-items-end h-100">
|
||||||
<div class="list-unstyled mb-0 border-start-sm border-start-md-0 border-start-lg ps-sm-5 ps-md-0 ps-lg-5 border-warning-subtle">
|
<div class="list-unstyled mb-0 border-start-sm border-start-md-0 border-start-lg ps-sm-5 ps-md-0 ps-lg-5 border-warning-subtle">
|
||||||
<div class="d-flex align-items-center"><span class="uil uil-check-circle text-success me-2"></span><span class="text-body-tertiary fw-semibold">{{ dealer.get_plan.description}}</span></div>
|
<div class="d-flex align-items-center"><span class="uil uil-check-circle text-success me-2"></span><span class="text-body-tertiary fw-semibold">{{ dealer.get_active_plan.plan.description}}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,15 +4,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<style>
|
|
||||||
.color-circle {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: #fff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Main Container -->
|
<!-- Main Container -->
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@ -196,7 +188,7 @@
|
|||||||
<span>{{ color.exterior.get_local_name }}</span>
|
<span>{{ color.exterior.get_local_name }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="align-middle">
|
<td class="align-middle">
|
||||||
<div class="text-end color-circle" style="background-color: rgb({{ color.exterior.rgb }});"></div>
|
<div class="text-end color-div" style="background-color: rgb({{ color.exterior.rgb }});"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -205,10 +197,11 @@
|
|||||||
<span>{{ color.interior.get_local_name }}</span>
|
<span>{{ color.interior.get_local_name }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="align-middle">
|
<td class="align-middle">
|
||||||
<div class="text-end color-circle" style="background-color: rgb({{ color.interior.rgb }});"></div>
|
<div class="text-end color-div" style="background-color: rgb({{ color.interior.rgb }});"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %} {% else %}
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
{% trans "No colors available for this car." %}
|
{% trans "No colors available for this car." %}
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %} {% load i18n static custom_filters %} {% block content %}
|
||||||
{% load i18n static custom_filters %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<style>
|
<style>
|
||||||
#video {
|
#video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -12,33 +9,276 @@
|
|||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
max-width: 95%;
|
max-width: 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
{% include 'partials/form_errors.html' %}
|
{% include 'partials/form_errors.html' %}
|
||||||
|
|
||||||
<!-- JavaScript Section -->
|
<!-- JavaScript Section -->
|
||||||
<script src="https://unpkg.com/@zxing/library@latest"></script>
|
<script src="https://unpkg.com/@zxing/library@latest"></script>
|
||||||
<script src='https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js'></script>
|
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<div class="container-lg">
|
<div class="container-lg">
|
||||||
|
<form method="post" id="carForm" class="form needs-validation" novalidate>
|
||||||
|
{% csrf_token %}
|
||||||
|
<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">
|
||||||
|
<!-- VIN -->
|
||||||
|
<div class="col-lg-12 col-xl-12">
|
||||||
|
<div class="card h-100 border-1 rounded shadow">
|
||||||
|
<div class="card-body">
|
||||||
|
<label class="form-label" for="{{ form.vin.id_for_label }}">
|
||||||
|
{% trans 'VIN' %}:
|
||||||
|
</label>
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-phoenix-warning fs-8 rounded-start"
|
||||||
|
id="scan-vin-btn"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#scannerModal">
|
||||||
|
<span class="fas fa-camera"></span>
|
||||||
|
</button>
|
||||||
|
<input type="text"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
id="{{ form.vin.id_for_label }}" name="{{ form.vin.html_name }}" />
|
||||||
|
<button type="button" class="btn btn-sm btn-phoenix-primary rounded-end" id="decodeVinBtn">
|
||||||
|
{% trans 'Search' %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% if form.vin.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.vin.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Year Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body" id="year-container">
|
||||||
|
<label class="form-label" for="{{ form.year.id_for_label }}">
|
||||||
|
{% trans 'Year' %}:
|
||||||
|
</label>
|
||||||
|
<span class="text-success fw-bold" id="year-check"></span>
|
||||||
|
<input type="number"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
id="{{ form.year.id_for_label }}"
|
||||||
|
name="{{ form.year.html_name }}" />
|
||||||
|
{% if form.year.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.year.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Makes Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div id="make-container" class="card-body">
|
||||||
|
<div class="status"></div>
|
||||||
|
<label class="form-label" for="{{ form.id_car_make.id_for_label }}">
|
||||||
|
{% trans 'make'|capfirst %}:
|
||||||
|
</label>
|
||||||
|
<span class="text-success fw-bold" id="make-check"></span>
|
||||||
|
{{ form.id_car_make|add_class:"form-select form-select-sm" }} {% if form.id_car_make.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.id_car_make.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Models Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div id="model-container" class="card-body">
|
||||||
|
<label class="form-label" for="{{ form.id_car_model.id_for_label }}">
|
||||||
|
{% trans 'model'|capfirst %}:
|
||||||
|
</label>
|
||||||
|
<span class="text-success fw-bold" id="model-check"></span>
|
||||||
|
<select class="form-select form-select-sm"
|
||||||
|
id="{{ form.id_car_model.id_for_label }}"
|
||||||
|
name="{{ form.id_car_model.html_name }}">
|
||||||
|
<option value="">{% trans 'Select' %}</option>
|
||||||
|
</select>
|
||||||
|
{% if form.id_car_model.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.id_car_model.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Series Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body" id="serie-container">
|
||||||
|
<label class="form-label" for="{{ form.id_car_serie.id_for_label }}">
|
||||||
|
{% trans 'Series' %}:
|
||||||
|
</label>
|
||||||
|
<select class="form-select form-select-sm"
|
||||||
|
id="{{ form.id_car_serie.id_for_label }}"
|
||||||
|
name="{{ form.id_car_serie.html_name }}">
|
||||||
|
<option value="">{% trans 'Select' %}</option>
|
||||||
|
</select>
|
||||||
|
{% if form.id_car_serie.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.id_car_serie.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Trims Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body" id="trim-container">
|
||||||
|
<label class="form-label" for="{{ form.id_car_trim.id_for_label }}">
|
||||||
|
{% trans 'trim'|capfirst %}:
|
||||||
|
</label>
|
||||||
|
<select class="form-select form-select-sm"
|
||||||
|
id="{{ form.id_car_trim.id_for_label }}"
|
||||||
|
name="{{ form.id_car_trim.html_name }}">
|
||||||
|
<option value="">{% trans 'Select' %}</option>
|
||||||
|
</select>
|
||||||
|
{% if form.id_car_trim.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.id_car_trim.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-4">
|
||||||
|
<!-- Vendor Field -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="{{ form.vendor.id_for_label }}" class="form-label">
|
||||||
|
{% trans 'Vendor' %}:
|
||||||
|
</label>
|
||||||
|
{{ form.vendor|add_class:"form-select form-select-sm" }}
|
||||||
|
</div>
|
||||||
|
{% if form.vendor.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.vendor.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Stock Type Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<label class="form-label" for="{{ form.stock_type.id_for_label }}">
|
||||||
|
{% trans 'Stock Type'|capfirst %}:
|
||||||
|
</label>
|
||||||
|
{{ form.stock_type|add_class:"form-select form-select-sm" }} {% if form.stock_type.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.stock_type.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Mileage Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<label class="form-label" for="{{ form.mileage.id_for_label }}">
|
||||||
|
{% trans 'Mileage'|capfirst %}:
|
||||||
|
</label>
|
||||||
|
{{ form.mileage|add_class:"form-control form-control-sm" }} {% if form.mileage.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.mileage.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Receiving Date Field -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="{{ form.receiving_date.id_for_label }}" class="form-label">
|
||||||
|
{% trans 'Receiving Date' %}:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
class="form-control form-control-sm datetimepicker flatpickr-input"
|
||||||
|
id="{{ form.receiving_date.id_for_label }}"
|
||||||
|
type="text"
|
||||||
|
placeholder="dd/mm/yyyy hour : minute"
|
||||||
|
data-options='{"enableTime":true,"dateFormat":"d/m/y H:i","disableMobile":false}'
|
||||||
|
readonly="readonly"
|
||||||
|
/>
|
||||||
|
{% if form.receiving_date.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.receiving_date.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Remarks Card -->
|
||||||
|
<div class="col-lg-4 col-xl-3">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<label class="label" for="{{ form.remarks.id_for_label }}">
|
||||||
|
{% trans 'Remarks'|capfirst %}:
|
||||||
|
</label>
|
||||||
|
{{ form.remarks|add_class:"form-control form-control-sm" }} {% if form.remarks.errors %}
|
||||||
|
<div class="text-danger small">
|
||||||
|
{{ form.remarks.errors|striptags }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Specifications Buttons -->
|
||||||
|
<div class="row g-1">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-danger me-1"
|
||||||
|
id="specification-btn"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#specificationsModal"
|
||||||
|
disabled>{% trans 'specifications'|capfirst %}
|
||||||
|
</button>
|
||||||
|
<!--<div class="form-group">-->
|
||||||
|
<button type="submit" name="add_another" value="true" class="btn btn-sm btn-success me-1">
|
||||||
|
{% trans "Save and Add Another" %}
|
||||||
|
</button>
|
||||||
|
<button type="submit" name="go_to_stats" value="true" class="btn btn-sm btn-primary">
|
||||||
|
{% trans "Save and Go to Inventory" %}
|
||||||
|
</button>
|
||||||
|
<!--</div>-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
<!-- Specification Modal -->
|
<!-- Specification Modal -->
|
||||||
<div class="modal fade" id="specificationsModal"
|
<div class="modal fade" id="specificationsModal" tabindex="-1" aria-labelledby="specificationsModalLabel">
|
||||||
tabindex="-1"
|
|
||||||
aria-labelledby="specificationsModalLabel">
|
|
||||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||||
<div class="modal-content rounded-top-2">
|
<div class="modal-content rounded-top-2">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title"
|
<h5 class="modal-title" id="specificationsModalLabel">
|
||||||
id="specificationsModalLabel">
|
|
||||||
{% trans 'specifications'|capfirst %}
|
{% trans 'specifications'|capfirst %}
|
||||||
</h5>
|
</h5>
|
||||||
<button type="button"
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
|
||||||
class="btn-close"
|
|
||||||
data-bs-dismiss="modal"
|
|
||||||
aria-label="{% trans 'Close' %}">
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div id="specificationsContent"></div>
|
<div id="specificationsContent"></div>
|
||||||
@ -67,291 +307,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- CAR FORM -->
|
<!-- CAR FORM -->
|
||||||
|
|
||||||
<form method="post" id="carForm" class="form needs-validation" novalidate>
|
|
||||||
{% csrf_token %}
|
|
||||||
<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">
|
|
||||||
|
|
||||||
<!-- VIN -->
|
|
||||||
<div class="col-lg-12 col-xl-12">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.vin.id_for_label }}">
|
|
||||||
{% trans 'VIN' %}:
|
|
||||||
</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-warning fs-6 rounded-start"
|
|
||||||
id="scan-vin-btn"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#scannerModal">
|
|
||||||
<span class="fa-solid fa-camera"></span>
|
|
||||||
</button>
|
|
||||||
<input type="text"
|
|
||||||
class="form-control form-control-sm"
|
|
||||||
id="{{ form.vin.id_for_label }}"
|
|
||||||
name="{{ form.vin.html_name }}">
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-sm btn-primary rounded-end"
|
|
||||||
id="decodeVinBtn">
|
|
||||||
{% trans 'Search' %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{% if form.vin.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.vin.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Year Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body" id="year-container">
|
|
||||||
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.year.id_for_label }}">
|
|
||||||
{% trans 'Year' %}:
|
|
||||||
</label>
|
|
||||||
<span class="text-success fw-bold" id="year-check"></span>
|
|
||||||
<input type="number"
|
|
||||||
class="form-control form-control-sm"
|
|
||||||
id="{{ form.year.id_for_label }}"
|
|
||||||
name="{{ form.year.html_name }}">
|
|
||||||
{% if form.year.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.year.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Makes Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div id="make-container" class="card-body">
|
|
||||||
<div class="status"></div>
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.id_car_make.id_for_label }}">
|
|
||||||
{% trans 'make'|capfirst %}:
|
|
||||||
</label>
|
|
||||||
<span class="text-success fw-bold" id="make-check"></span>
|
|
||||||
{{ form.id_car_make|add_class:"form-select form-select-sm" }}
|
|
||||||
{% if form.id_car_make.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.id_car_make.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Models Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div id="model-container" class="card-body">
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.id_car_model.id_for_label }}">
|
|
||||||
{% trans 'model'|capfirst %}:
|
|
||||||
</label>
|
|
||||||
<span class="text-success fw-bold" id="model-check"></span>
|
|
||||||
<select class="form-select form-select-sm"
|
|
||||||
id="{{ form.id_car_model.id_for_label }}"
|
|
||||||
name="{{ form.id_car_model.html_name }}">
|
|
||||||
<option value="">{% trans 'Select' %}</option>
|
|
||||||
</select>
|
|
||||||
{% if form.id_car_model.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.id_car_model.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Series Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body" id="serie-container">
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.id_car_serie.id_for_label }}">
|
|
||||||
{% trans 'Series' %}:
|
|
||||||
</label>
|
|
||||||
<select class="form-select form-select-sm"
|
|
||||||
id="{{ form.id_car_serie.id_for_label }}"
|
|
||||||
name="{{ form.id_car_serie.html_name }}">
|
|
||||||
<option value="">{% trans 'Select' %}</option>
|
|
||||||
</select>
|
|
||||||
{% if form.id_car_serie.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.id_car_serie.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Trims Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body" id="trim-container">
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.id_car_trim.id_for_label }}">
|
|
||||||
{% trans 'trim'|capfirst %}:
|
|
||||||
</label>
|
|
||||||
<select class="form-select form-select-sm"
|
|
||||||
id="{{ form.id_car_trim.id_for_label }}"
|
|
||||||
name="{{ form.id_car_trim.html_name }}">
|
|
||||||
<option value="">{% trans 'Select' %}</option>
|
|
||||||
</select>
|
|
||||||
{% if form.id_car_trim.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.id_car_trim.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row g-4">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Vendor Field -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="{{ form.vendor.id_for_label }}"
|
|
||||||
class="form-label">
|
|
||||||
{% trans 'Vendor' %}:
|
|
||||||
</label>
|
|
||||||
{{ form.vendor|add_class:"form-select form-select-sm" }}
|
|
||||||
</div>
|
|
||||||
{% if form.vendor.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.vendor.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Stock Type Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.stock_type.id_for_label }}">
|
|
||||||
{% trans 'Stock Type'|capfirst %}:
|
|
||||||
</label>
|
|
||||||
{{ form.stock_type|add_class:"form-select form-select-sm" }}
|
|
||||||
{% if form.stock_type.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.stock_type.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Mileage Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
<label class="form-label"
|
|
||||||
for="{{ form.mileage.id_for_label }}">
|
|
||||||
{% trans 'Mileage'|capfirst %}:
|
|
||||||
</label>
|
|
||||||
{{ form.mileage|add_class:"form-control form-control-sm" }}
|
|
||||||
{% if form.mileage.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.mileage.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Receiving Date Field -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="{{ form.receiving_date.id_for_label }}"
|
|
||||||
class="form-label">
|
|
||||||
{% trans 'Receiving Date' %}:
|
|
||||||
</label>
|
|
||||||
{{ form.receiving_date|add_class:"form-control form-control-sm" }}
|
|
||||||
{% if form.receiving_date.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.receiving_date.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Remarks Card -->
|
|
||||||
<div class="col-lg-4 col-xl-3">
|
|
||||||
<div class="card h-100 border-1 rounded shadow">
|
|
||||||
<div class="card-body">
|
|
||||||
<label class="label"
|
|
||||||
for="{{ form.remarks.id_for_label }}">
|
|
||||||
{% trans 'Remarks'|capfirst %}:
|
|
||||||
</label>
|
|
||||||
{{ form.remarks|add_class:"form-control form-control-sm" }}
|
|
||||||
{% if form.remarks.errors %}
|
|
||||||
<div class="text-danger small">
|
|
||||||
{{ form.remarks.errors|striptags }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Specifications Buttons -->
|
|
||||||
<div class="row g-1">
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-sm btn-danger me-1"
|
|
||||||
id="specification-btn"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#specificationsModal"
|
|
||||||
disabled>{% trans 'specifications'|capfirst %}
|
|
||||||
</button>
|
|
||||||
<!--<div class="form-group">-->
|
|
||||||
<button type="submit"
|
|
||||||
name="add_another"
|
|
||||||
value="true"
|
|
||||||
class="btn btn-sm btn-success me-1">
|
|
||||||
{% trans "Save and Add Another" %}
|
|
||||||
</button>
|
|
||||||
<button type="submit"
|
|
||||||
name="go_to_stats"
|
|
||||||
value="true"
|
|
||||||
class="btn btn-sm btn-primary">
|
|
||||||
{% trans "Save and Go to Inventory" %}
|
|
||||||
</button>
|
|
||||||
<!--</div>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
let cookieValue = null;
|
let cookieValue = null;
|
||||||
if (document.cookie && document.cookie !== '') {
|
if (document.cookie && document.cookie !== "") {
|
||||||
const cookies = document.cookie.split(';');
|
const cookies = document.cookie.split(";");
|
||||||
for (let cookie of cookies) {
|
for (let cookie of cookies) {
|
||||||
cookie = cookie.trim();
|
cookie = cookie.trim();
|
||||||
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
if (cookie.substring(0, name.length + 1) === name + "=") {
|
||||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -361,36 +326,25 @@ function getCookie(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const csrfToken = getCookie("token");
|
||||||
|
|
||||||
|
const vinInput = document.getElementById("{{ form.vin.id_for_label }}");
|
||||||
const csrfToken = getCookie('token');
|
const decodeVinBtn = document.getElementById("decodeVinBtn");
|
||||||
|
const makeSelect = document.getElementById("{{ form.id_car_make.id_for_label }}");
|
||||||
const vinInput = document.getElementById('{{ form.vin.id_for_label }}');
|
const modelSelect = document.getElementById("{{ form.id_car_model.id_for_label }}");
|
||||||
const stockTypeSelect = document.getElementById('{{ form.stock_type.id_for_label }}');
|
const yearSelect = document.getElementById("{{ form.year.id_for_label }}");
|
||||||
const mileageInput = document.getElementById('{{ form.mileage.id_for_label }}');
|
const serieSelect = document.getElementById("{{ form.id_car_serie.id_for_label }}");
|
||||||
const remarksInput = document.getElementById('{{ form.remarks.id_for_label }}');
|
const trimSelect = document.getElementById("{{ form.id_car_trim.id_for_label }}");
|
||||||
const decodeVinBtn = document.getElementById('decodeVinBtn');
|
const showSpecificationButton = document.getElementById("specification-btn");
|
||||||
const makeSelect = document.getElementById('{{ form.id_car_make.id_for_label }}');
|
const specificationsContent = document.getElementById("specificationsContent");
|
||||||
const modelSelect = document.getElementById('{{ form.id_car_model.id_for_label }}');
|
|
||||||
const yearSelect = document.getElementById('{{ form.year.id_for_label }}');
|
|
||||||
const serieSelect = document.getElementById('{{ form.id_car_serie.id_for_label }}');
|
|
||||||
const trimSelect = document.getElementById('{{ form.id_car_trim.id_for_label }}');
|
|
||||||
const showSpecificationButton = document.getElementById('specification-btn');
|
|
||||||
const specificationsContent = document.getElementById('specificationsContent');
|
|
||||||
const makeBg = document.getElementById('make-container');
|
|
||||||
const modelBg = document.getElementById('model-container');
|
|
||||||
const yearBg = document.getElementById('year-container');
|
|
||||||
const serieBg = document.getElementById('serie-container');
|
|
||||||
const trimBg = document.getElementById('trim-container');
|
|
||||||
/*const saveCarBtn = document.getElementById('saveCarBtn');*/
|
|
||||||
|
|
||||||
const ajaxUrl = "{% url 'ajax_handler' %}";
|
const ajaxUrl = "{% url 'ajax_handler' %}";
|
||||||
|
|
||||||
const closeButton = document.querySelector(".btn-close");
|
const closeButton = document.querySelector(".btn-close");
|
||||||
const scanVinBtn = document.getElementById("scan-vin-btn");
|
const scanVinBtn = document.getElementById("scan-vin-btn");
|
||||||
const videoElement = document.getElementById('video');
|
const videoElement = document.getElementById("video");
|
||||||
const resultDisplay = document.getElementById('result');
|
const resultDisplay = document.getElementById("result");
|
||||||
const fallbackButton = document.getElementById('ocr-fallback-btn');
|
const fallbackButton = document.getElementById("ocr-fallback-btn");
|
||||||
let codeReader;
|
let codeReader;
|
||||||
codeReader = new ZXing.BrowserMultiFormatReader();
|
codeReader = new ZXing.BrowserMultiFormatReader();
|
||||||
let currentStream = null;
|
let currentStream = null;
|
||||||
@ -422,9 +376,9 @@ async function decodeVin() {
|
|||||||
try {
|
try {
|
||||||
const response = await fetch(`${ajaxUrl}?action=decode_vin&vin_no=${vinNumber}`, {
|
const response = await fetch(`${ajaxUrl}?action=decode_vin&vin_no=${vinNumber}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
'X-CSRFToken': csrfToken
|
"X-CSRFToken": csrfToken,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
@ -432,55 +386,54 @@ async function decodeVin() {
|
|||||||
await updateFields(data.data);
|
await updateFields(data.data);
|
||||||
} else {
|
} else {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
notify("error",data.error)
|
notify("error", data.error);
|
||||||
/* alert(data.error || "{% trans 'Failed to decode VIN.' %}");*/
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error decoding VIN:", error);
|
console.error("Error decoding VIN:", error);
|
||||||
hideLoading();
|
hideLoading();
|
||||||
notify("error","{% trans 'An error occurred while decoding the VIN.' %}")
|
notify("error", "{% trans 'An error occurred while decoding the VIN.' %}");
|
||||||
/*alert("{% trans 'An error occurred while decoding the VIN.' %}");*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateFields(vinData) {
|
async function updateFields(vinData) {
|
||||||
console.log(vinData)
|
console.log(vinData);
|
||||||
if (vinData.make_id) {
|
if (vinData.make_id) {
|
||||||
makeSelect.value = vinData.make_id;
|
makeSelect.value = vinData.make_id;
|
||||||
document.getElementById("make-check").innerHTML = '✓';
|
document.getElementById("make-check").innerHTML = "✓";
|
||||||
await loadModels(vinData.make_id);
|
await loadModels(vinData.make_id);
|
||||||
}
|
}
|
||||||
if (vinData.model_id) {
|
if (vinData.model_id) {
|
||||||
modelSelect.value = vinData.model_id;
|
modelSelect.value = vinData.model_id;
|
||||||
document.getElementById("model-check").innerHTML = '✓';
|
document.getElementById("model-check").innerHTML = "✓";
|
||||||
await loadSeries(vinData.model_id, vinData.year);
|
await loadSeries(vinData.model_id, vinData.year);
|
||||||
}
|
}
|
||||||
if (vinData.year) {
|
if (vinData.year) {
|
||||||
yearSelect.value = vinData.year;
|
yearSelect.value = vinData.year;
|
||||||
document.getElementById("year-check").innerHTML = '✓';
|
document.getElementById("year-check").innerHTML = "✓";
|
||||||
}
|
}
|
||||||
/*checkFormCompletion();*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the scanner
|
// Start the scanner
|
||||||
async function startScanner() {
|
async function startScanner() {
|
||||||
codeReader.decodeFromVideoDevice(null, videoElement, async(result, err) => {
|
codeReader
|
||||||
let res = await result
|
.decodeFromVideoDevice(null, videoElement, async (result, err) => {
|
||||||
|
let res = await result;
|
||||||
if (result) {
|
if (result) {
|
||||||
vinInput.value = result.text;
|
vinInput.value = result.text;
|
||||||
closeModal();
|
closeModal();
|
||||||
await decodeVin();
|
await decodeVin();
|
||||||
}
|
}
|
||||||
}).catch(console.error);
|
})
|
||||||
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
function captureAndOCR() {
|
function captureAndOCR() {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement("canvas");
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext("2d");
|
||||||
canvas.width = videoElement.videoWidth;
|
canvas.width = videoElement.videoWidth;
|
||||||
canvas.height = videoElement.videoHeight;
|
canvas.height = videoElement.videoHeight;
|
||||||
context.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
context.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
||||||
Tesseract.recognize(canvas.toDataURL('image/png'), 'eng')
|
Tesseract.recognize(canvas.toDataURL("image/png"), "eng")
|
||||||
.then(({ data: { text } }) => {
|
.then(({ data: { text } }) => {
|
||||||
const vin = text.match(/[A-HJ-NPR-Z0-9]{17}/);
|
const vin = text.match(/[A-HJ-NPR-Z0-9]{17}/);
|
||||||
if (vin) vinInput.value = vin[0];
|
if (vin) vinInput.value = vin[0];
|
||||||
@ -501,83 +454,76 @@ function stopScanner() {
|
|||||||
function resetDropdown(dropdown, placeholder) {
|
function resetDropdown(dropdown, placeholder) {
|
||||||
dropdown.innerHTML = `<option value="">${placeholder}</option>`;
|
dropdown.innerHTML = `<option value="">${placeholder}</option>`;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
function checkFormCompletion() {
|
|
||||||
const isFormComplete = vinInput.value.length === 17 && stockTypeSelect.value;
|
|
||||||
saveCarBtn.disabled = !isFormComplete;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
async function loadModels(makeId) {
|
async function loadModels(makeId) {
|
||||||
resetDropdown(modelSelect, '{% trans "Select" %}');
|
resetDropdown(modelSelect, '{% trans "Select" %}');
|
||||||
const response = await fetch(`${ajaxUrl}?action=get_models&make_id=${makeId}`, {
|
const response = await fetch(`${ajaxUrl}?action=get_models&make_id=${makeId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
'X-CSRFToken': csrfToken
|
"X-CSRFToken": csrfToken,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
data.forEach((model) => {
|
data.forEach((model) => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement("option");
|
||||||
option.value = model.id_car_model;
|
option.value = model.id_car_model;
|
||||||
option.textContent = document.documentElement.lang === 'en' ? model.name : model.arabic_name;
|
option.textContent = document.documentElement.lang === "en" ? model.name : model.arabic_name;
|
||||||
modelSelect.appendChild(option);
|
modelSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function loadSeries(modelId, year) {
|
async function loadSeries(modelId, year) {
|
||||||
resetDropdown(serieSelect, '{% trans "Select" %}');
|
resetDropdown(serieSelect, '{% trans "Select" %}');
|
||||||
resetDropdown(trimSelect, '{% trans "Select" %}');
|
resetDropdown(trimSelect, '{% trans "Select" %}');
|
||||||
specificationsContent.innerHTML = '';
|
specificationsContent.innerHTML = "";
|
||||||
const response = await fetch(`${ajaxUrl}?action=get_series&model_id=${modelId}&year=${year}`, {
|
const response = await fetch(`${ajaxUrl}?action=get_series&model_id=${modelId}&year=${year}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
'X-CSRFToken': csrfToken
|
"X-CSRFToken": csrfToken,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
data.forEach((serie) => {
|
data.forEach((serie) => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement("option");
|
||||||
option.value = serie.id_car_serie;
|
option.value = serie.id_car_serie;
|
||||||
option.textContent = document.documentElement.lang === 'en' ? serie.name : serie.name;
|
option.textContent = document.documentElement.lang === "en" ? serie.name : serie.name;
|
||||||
serieSelect.appendChild(option);
|
serieSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTrims(serie_id, model_id) {
|
async function loadTrims(serie_id, model_id) {
|
||||||
resetDropdown(trimSelect, '{% trans "Select" %}');
|
resetDropdown(trimSelect, '{% trans "Select" %}');
|
||||||
specificationsContent.innerHTML = '';
|
specificationsContent.innerHTML = "";
|
||||||
const response = await fetch(`${ajaxUrl}?action=get_trims&serie_id=${serie_id}&model_id=${model_id}`, {
|
const response = await fetch(`${ajaxUrl}?action=get_trims&serie_id=${serie_id}&model_id=${model_id}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
'X-CSRFToken': csrfToken
|
"X-CSRFToken": csrfToken,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
data.forEach((trim) => {
|
data.forEach((trim) => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement("option");
|
||||||
option.value = trim.id_car_trim;
|
option.value = trim.id_car_trim;
|
||||||
option.textContent = document.documentElement.lang === 'en' ? trim.name : trim.name;
|
option.textContent = document.documentElement.lang === "en" ? trim.name : trim.name;
|
||||||
trimSelect.appendChild(option);
|
trimSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
showSpecificationButton.disabled = !this.value;
|
showSpecificationButton.disabled = !this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadSpecifications(trimId) {
|
async function loadSpecifications(trimId) {
|
||||||
specificationsContent.innerHTML = '';
|
specificationsContent.innerHTML = "";
|
||||||
const response = await fetch(`${ajaxUrl}?action=get_specifications&trim_id=${trimId}`, {
|
const response = await fetch(`${ajaxUrl}?action=get_specifications&trim_id=${trimId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
'X-CSRFToken': csrfToken
|
"X-CSRFToken": csrfToken,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
data.forEach((spec) => {
|
data.forEach((spec) => {
|
||||||
const parentDiv = document.createElement('div');
|
const parentDiv = document.createElement("div");
|
||||||
parentDiv.innerHTML = `<strong>${spec.parent_name}</strong>`;
|
parentDiv.innerHTML = `<strong>${spec.parent_name}</strong>`;
|
||||||
spec.specifications.forEach((s) => {
|
spec.specifications.forEach((s) => {
|
||||||
const specDiv = document.createElement('div');
|
const specDiv = document.createElement("div");
|
||||||
specDiv.innerHTML = `• ${s.s_name}: ${s.s_value} ${s.s_unit}`;
|
specDiv.innerHTML = `• ${s.s_name}: ${s.s_value} ${s.s_unit}`;
|
||||||
parentDiv.appendChild(specDiv);
|
parentDiv.appendChild(specDiv);
|
||||||
});
|
});
|
||||||
@ -585,34 +531,35 @@ async function loadSpecifications(trimId){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
scanVinBtn.addEventListener('click', () => {
|
scanVinBtn.addEventListener("click", () => {
|
||||||
resultDisplay.textContent = "";
|
resultDisplay.textContent = "";
|
||||||
startScanner();
|
startScanner();
|
||||||
});
|
});
|
||||||
|
|
||||||
fallbackButton.addEventListener('click', () => {
|
fallbackButton.addEventListener("click", () => {
|
||||||
captureAndOCR();
|
captureAndOCR();
|
||||||
});
|
});
|
||||||
|
|
||||||
serieSelect.addEventListener('change', () => {
|
serieSelect.addEventListener("change", () => {
|
||||||
const serie_id = serieSelect.value;
|
const serie_id = serieSelect.value;
|
||||||
const model_id = modelSelect.value;
|
const model_id = modelSelect.value;
|
||||||
if (serie_id && model_id) loadTrims(serie_id, model_id);
|
if (serie_id && model_id) loadTrims(serie_id, model_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
trimSelect.addEventListener('change', () => {
|
trimSelect.addEventListener("change", () => {
|
||||||
const trimId = trimSelect.value;
|
const trimId = trimSelect.value;
|
||||||
showSpecificationButton.disabled = !trimId;
|
showSpecificationButton.disabled = !trimId;
|
||||||
if (trimId) loadSpecifications(trimId);
|
if (trimId) loadSpecifications(trimId);
|
||||||
});
|
});
|
||||||
|
|
||||||
closeButton.addEventListener('click', closeModal);
|
closeButton.addEventListener("click", closeModal);
|
||||||
/*stockTypeSelect.addEventListener('change', checkFormCompletion);
|
makeSelect.addEventListener("change", (e) => {
|
||||||
mileageInput.addEventListener('input', checkFormCompletion);
|
loadModels(e.target.value, modelSelect.value);
|
||||||
remarksInput.addEventListener('input', checkFormCompletion);*/
|
});
|
||||||
makeSelect.addEventListener("change", (e) => {loadModels(e.target.value, modelSelect.value)})
|
modelSelect.addEventListener("change", (e) => {
|
||||||
modelSelect.addEventListener("change", (e) => {loadSeries(e.target.value, yearSelect.value)})
|
loadSeries(e.target.value, yearSelect.value);
|
||||||
decodeVinBtn.addEventListener('click', decodeVin);
|
});
|
||||||
|
decodeVinBtn.addEventListener("click", decodeVin);
|
||||||
});
|
});
|
||||||
function showLoading() {
|
function showLoading() {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
@ -621,7 +568,7 @@ async function loadSpecifications(trimId){
|
|||||||
allowOutsideClick: false,
|
allowOutsideClick: false,
|
||||||
didOpen: () => {
|
didOpen: () => {
|
||||||
Swal.showLoading();
|
Swal.showLoading();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,11 +579,9 @@ async function loadSpecifications(trimId){
|
|||||||
function notify(tag, msg) {
|
function notify(tag, msg) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
icon: tag,
|
icon: tag,
|
||||||
titleText: msg
|
titleText: msg,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -25,12 +25,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body px-lg-5 position-relative">
|
<div class="card-body px-lg-5 position-relative">
|
||||||
<br><br><h3 class="mb-2">{{ cars.first.id_car_make.get_local_name }}<span class="ms-2 text-body-tertiary fw-semibold">{{ cars.first.id_car_model.get_local_name }}</span></h3>
|
<br>
|
||||||
|
<div class="row align-items-center g-3 g-sm-5 text-start text-sm-start">
|
||||||
|
<div class="col-12 col-sm-auto ">
|
||||||
|
<div class="avatar avatar-3xl avatar-bordered mb-3">
|
||||||
|
<img class="rounded-circle" src="{{ cars.first.id_car_make.logo.url }}" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-auto flex-1">
|
||||||
|
<h3 class="mb-2">{{ cars.first.id_car_make.get_local_name }}<span class="ms-2 text-body-tertiary fw-semibold">{{ cars.first.id_car_model.get_local_name }}</span></h3>
|
||||||
<p class="text-body-tertiary fw-semibold">{{ cars.first.id_car_serie.name }}, <span class="fs-10">{{ cars.first.id_car_trim.name }}</span></p>
|
<p class="text-body-tertiary fw-semibold">{{ cars.first.id_car_serie.name }}, <span class="fs-10">{{ cars.first.id_car_trim.name }}</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row g-3 justify-content-between mt-4">
|
<div class="row g-3 justify-content-between mt-4">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="table-list" id="inventoryTable">
|
<div class="table-list" id="inventoryTable">
|
||||||
@ -54,9 +64,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="align-middle white-space-nowrap text-center fw-bold text-body-tertiary">
|
<td class="align-middle white-space-nowrap text-center fw-bold text-body-tertiary">
|
||||||
{% if car.stock_type == "new" %}
|
{% if car.stock_type == "new" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-success"><span class="badge-label">{{_("New")}}</span><span class="ms-1" data-feather="plus" style="height:13px;width:13px;"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-success"><span class="badge-label">{{_("New")}}</span></span>
|
||||||
{% elif car.status == "used" %}
|
{% elif car.status == "used" %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-info"><span class="badge-label">{{_("Used")}}</span><span class="ms-1" data-feather="plus" style="height:13px;width:13px;"></span></span>
|
<span class="badge badge-phoenix badge-phoenix-info"><span class="badge-label">{{_("Used")}}</span></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="align-middle white-space-nowrap text-start fw-bold">{{ car.vin }}</td>
|
<td class="align-middle white-space-nowrap text-start fw-bold">{{ car.vin }}</td>
|
||||||
@ -64,12 +74,12 @@
|
|||||||
{% if car.colors.exists %}
|
{% if car.colors.exists %}
|
||||||
<td class="align-middle white-space-nowrap text-body fs-9 text-start">
|
<td class="align-middle white-space-nowrap text-body fs-9 text-start">
|
||||||
<div class="d-flex flex-column align-items-center">
|
<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><span>{{ car.colors.first.exterior.get_local_name }}</span>
|
<span class="color-div" style="background: linear-gradient(90deg, rgba({{ car.colors.first.exterior.rgb }},1) 40%, rgba({{ car.colors.first.exterior.rgb }},0.35) 100%);" title="{{ car.colors.first.exterior.get_local_name }}"></span><span>{{ car.colors.first.exterior.get_local_name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="align-middle white-space-nowrap text-body fs-9 text-start">
|
<td class="align-middle white-space-nowrap text-body fs-9 text-start">
|
||||||
<div class="d-flex flex-column align-items-center">
|
<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><span>{{ car.colors.first.interior.get_local_name }}</span>
|
<span class="color-div" style="background: linear-gradient(90deg, rgba({{ car.colors.first.interior.rgb }},1) 40%, rgba({{ car.colors.first.interior.rgb }},0.35) 100%);" title="{{ car.colors.first.interior.get_local_name }}"></span><span>{{ car.colors.first.interior.get_local_name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
{% load static %}
|
|
||||||
146
templates/subscriptions/subscription_plan.html
Normal file
146
templates/subscriptions/subscription_plan.html
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="mb-7">Pricing</h2>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12 col-xxl-9 mb-1">
|
||||||
|
<div class="tabs mb-7">
|
||||||
|
<div class="tab-content" id="pills-tabContent">
|
||||||
|
<div class="tab-pane fade show active" id="pills-month" role="tabpanel" aria-labelledby="pills-month-tab">
|
||||||
|
<div class="row g-3">
|
||||||
|
{% for plan in plans %}
|
||||||
|
<div class="col-12 col-md-6 col-lg-12 col-xl-6">
|
||||||
|
<div class="h-100">
|
||||||
|
<input class="card-form-check-input d-none"
|
||||||
|
type="radio"
|
||||||
|
name="pricingMonthly"
|
||||||
|
id="subscription_{{ plan.id }}"
|
||||||
|
checked="checked" />
|
||||||
|
<div class="position-relative h-100">
|
||||||
|
<label class="stretched-link" for="subscription_{{ plan.id }}"></label>
|
||||||
|
<div class="card h-100 overflow-hidden cursor-pointer">
|
||||||
|
<div class="bg-holder d-dark-none"
|
||||||
|
style="background-image:url({% static 'images/bg/8.png' %});background-position:left bottom;background-size:auto;bottom:-1px;">
|
||||||
|
</div>
|
||||||
|
<div class="bg-holder d-light-none"
|
||||||
|
style="background-image:url({% static 'images/bg/8-dark.png' %});background-position:left bottom;background-size:auto;bottom:-1px;">
|
||||||
|
</div>
|
||||||
|
<div class="card-body d-flex flex-column justify-content-between position-relative">
|
||||||
|
<div class="d-flex justify-content-between">
|
||||||
|
<div class="mb-5 mb-md-0 mb-lg-5 me-3">
|
||||||
|
<div class="d-sm-flex align-items-center mb-3">
|
||||||
|
<h3 class="mb-0">{{ plan.name }}</h3>
|
||||||
|
</div>
|
||||||
|
<p class="fs-9 text-body-tertiary">For individuals who are interested
|
||||||
|
<br> in giving it a shot first.
|
||||||
|
</p>
|
||||||
|
<div class="d-flex align-items-end mb-md-5 mb-lg-0">
|
||||||
|
<h4 class="fw-bolder me-1">{{ plan.price|floatformat }} {% trans 'SAR' %}</h4>
|
||||||
|
<h5 class="fs-9 fw-normal text-body-tertiary ms-1">{{ _("Per month")}}</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<img class="d-dark-none opacity-50"
|
||||||
|
src="{% static 'images/spot-illustrations/dark_21.png' %}"
|
||||||
|
width="auto"
|
||||||
|
height="120"
|
||||||
|
alt="" />
|
||||||
|
<img class="d-light-none opacity-50"
|
||||||
|
src="{% static 'images/spot-illustrations/21.png' %}"
|
||||||
|
width="auto"
|
||||||
|
height="120"
|
||||||
|
alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="row flex-1 justify-content-end">
|
||||||
|
<div class="col-sm-8 col-md-12">
|
||||||
|
<div class="d-sm-flex d-md-block d-lg-flex justify-content-end align-items-end h-100">
|
||||||
|
<ul class="list-unstyled mb-0 border-start-sm border-start-md-0 border-start-lg ps-sm-5 ps-md-0 ps-lg-5 border-translucent">
|
||||||
|
<li class="d-flex align-items-center">
|
||||||
|
<span class="uil uil-check-circle text-success me-2"></span>
|
||||||
|
<span class="text-body-tertiary fw-semibold">{{ _("Max Users")}}: {{ plan.max_users }}</span>
|
||||||
|
</li>
|
||||||
|
<li class="d-flex align-items-center">
|
||||||
|
<span class="uil uil-check-circle text-success me-2"></span>
|
||||||
|
<span class="text-body-tertiary fw-semibold">{{ _("Inventory Size")}}: {{ plan.max_inventory_size }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="d-grid d-sm-flex">
|
||||||
|
<button class="btn btn-lg btn-phoenix-primary d-sm-flex align-items-center mb-3 mb-sm-0 me-sm-3 px-sm-8">{{ _("Subscribe") }}
|
||||||
|
{{ _("Now") }}<span class="fas fa-angle-right ms-1"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col col-xxl-3 mt-8">
|
||||||
|
<h3 class="fw-semibold mb-3">Included in our all packages</h3>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3"><span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Timeline</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Advanced Search</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Custom fields</p>
|
||||||
|
<span class="badge badge-phoenix badge-phoenix-primary ms-2">New</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Task dependencies</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">20TB of additional space </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Bandwidth of Upto 1 Gbps</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Private teams & projects</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-xxl-12">
|
||||||
|
<div class="rounded-3 py-2 px-3 bg-body-emphasis d-flex align-items-center mb-3">
|
||||||
|
<span class="fas fa-check text-primary me-3 fs-9"></span>
|
||||||
|
<p class="mb-0 text-body-secondary">Customer Support and Training</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
@ -1,137 +1,538 @@
|
|||||||
<!DOCTYPE html>
|
<div class="brand-container">
|
||||||
<html lang="en">
|
<div class="brand-title"><h1>All Brands</h1></div>
|
||||||
<head>
|
<div class="brand-list-box">
|
||||||
<meta charset="UTF-8">
|
<div class="brand-grid-box">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<a href="/en-sa/changan/" class="ka" point-cid="6" point-crgn="pinpaiquyu" point-cpos="1" point-dtype="brand">
|
||||||
<title>Car Inventory</title>
|
<div class="brand-item">
|
||||||
<!-- Bootstrap CSS -->
|
<div>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
<img
|
||||||
<!-- Font Awesome for Icons -->
|
class="brand-logo lazyload"
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
|
alt="Changan"
|
||||||
<!-- Custom CSS -->
|
src=""
|
||||||
<style>
|
data-original=""
|
||||||
.color-circle {
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/107/w360_yichecar_997687110728096.png.webp"
|
||||||
width: 22px;
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
height: 22px;
|
onerror="loadImageError(this)"
|
||||||
border-radius: 50%;
|
/>
|
||||||
border: 1px solid #ccc;
|
<div class="brand-name">Changan</div>
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.table-hover tbody tr:hover {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
}
|
|
||||||
.badge {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
.table-responsive {
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
.table thead th {
|
|
||||||
background-color: #007bff;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.table tbody td {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container my-5">
|
|
||||||
<h1 class="text-center mb-4">Car Inventory</h1>
|
|
||||||
|
|
||||||
<!-- Search and Filter Section -->
|
|
||||||
<div class="row mb-4 g-3">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
|
||||||
<input type="text" class="form-control" placeholder="Search by VIN, Make, or Model">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
</a>
|
||||||
<select class="form-select">
|
<a href="/en-sa/haval/" class="ka" point-cid="20" point-crgn="pinpaiquyu" point-cpos="2" point-dtype="brand">
|
||||||
<option>All Years</option>
|
<div class="brand-item">
|
||||||
<option>2023</option>
|
<div>
|
||||||
<option>2022</option>
|
<img
|
||||||
<option>2021</option>
|
class="brand-logo lazyload"
|
||||||
</select>
|
alt="Haval"
|
||||||
</div>
|
src="https://global-img.bitauto.com/usercenter/car/20240703/44/w360_yichecar_997687404468507.png.webp"
|
||||||
<div class="col-md-3">
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/44/w360_yichecar_997687404468507.png"
|
||||||
<button class="btn btn-primary w-100"><i class="fas fa-filter"></i> Filter</button>
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/44/w360_yichecar_997687404468507.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Haval</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
<!-- Car Listing Table -->
|
<a href="/en-sa/geely/" class="ka" point-cid="8" point-crgn="pinpaiquyu" point-cpos="3" point-dtype="brand">
|
||||||
<div class="table-responsive">
|
<div class="brand-item">
|
||||||
<table class="table table-hover table-bordered">
|
<div>
|
||||||
<thead>
|
<img
|
||||||
<tr>
|
class="brand-logo lazyload"
|
||||||
<th>#</th>
|
alt="Geely"
|
||||||
<th>Image</th>
|
src="https://global-img.bitauto.com/usercenter/car/20240703/924/w360_yichecar_997687792422555.png.webp"
|
||||||
<th>Make & Model</th>
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/924/w360_yichecar_997687792422555.png"
|
||||||
<th>Year</th>
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/924/w360_yichecar_997687792422555.png.webp"
|
||||||
<th>VIN</th>
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
<th>Exterior Color</th>
|
onerror="loadImageError(this)"
|
||||||
<th>Interior Color</th>
|
/>
|
||||||
<th>Location</th>
|
<div class="brand-name">Geely</div>
|
||||||
<th>Status</th>
|
</div>
|
||||||
<th>Actions</th>
|
</div>
|
||||||
</tr>
|
</a>
|
||||||
</thead>
|
<a href="/en-sa/mg/" class="ka" point-cid="11" point-crgn="pinpaiquyu" point-cpos="4" point-dtype="brand">
|
||||||
<tbody>
|
<div class="brand-item">
|
||||||
<!-- Example Row -->
|
<div>
|
||||||
<tr>
|
<img
|
||||||
<td>1</td>
|
class="brand-logo lazyload"
|
||||||
<td><img src="https://via.placeholder.com/100" alt="Car Image" class="img-thumbnail" style="width: 100px;"></td>
|
alt="MG"
|
||||||
<td>Toyota Camry</td>
|
src="https://global-img.bitauto.com/usercenter/car/20240703/688/w360_yichecar_997688268839543.png.webp"
|
||||||
<td>2023</td>
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/688/w360_yichecar_997688268839543.png"
|
||||||
<td>1HGCM82633A123456</td>
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/688/w360_yichecar_997688268839543.png.webp"
|
||||||
<td><span class="color-circle" style="background-color: #0000ff;"></span> Blue</td>
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
<td><span class="color-circle" style="background-color: #ffffff;"></span> White</td>
|
onerror="loadImageError(this)"
|
||||||
<td>Main Showroom</td>
|
/>
|
||||||
<td><span class="badge bg-success">Available</span></td>
|
<div class="brand-name">MG</div>
|
||||||
<td>
|
</div>
|
||||||
<a href="#" class="btn btn-sm btn-outline-primary"><i class="fas fa-eye"></i> View</a>
|
</div>
|
||||||
<a href="#" class="btn btn-sm btn-outline-warning"><i class="fas fa-edit"></i> Edit</a>
|
</a>
|
||||||
</td>
|
<a href="/en-sa/jetour/" class="ka" point-cid="13" point-crgn="pinpaiquyu" point-cpos="5" point-dtype="brand">
|
||||||
</tr>
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
<!-- Add more rows here -->
|
<img
|
||||||
<tr>
|
class="brand-logo lazyload"
|
||||||
<td>2</td>
|
alt="Jetour"
|
||||||
<td><img src="https://via.placeholder.com/100" alt="Car Image" class="img-thumbnail" style="width: 100px;"></td>
|
src="https://global-img.bitauto.com/usercenter/car/20240703/194/w360_yichecar_997687619404924.png.webp"
|
||||||
<td>Honda Accord</td>
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/194/w360_yichecar_997687619404924.png"
|
||||||
<td>2022</td>
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/194/w360_yichecar_997687619404924.png.webp"
|
||||||
<td>1HGCM82633A654321</td>
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
<td><span class="color-circle" style="background-color: #ff0000;"></span> Red</td>
|
onerror="loadImageError(this)"
|
||||||
<td><span class="color-circle" style="background-color: #000000;"></span> Black</td>
|
/>
|
||||||
<td>Downtown Showroom</td>
|
<div class="brand-name">Jetour</div>
|
||||||
<td><span class="badge bg-warning">Reserved</span></td>
|
</div>
|
||||||
<td>
|
</div>
|
||||||
<a href="#" class="btn btn-sm btn-outline-primary"><i class="fas fa-eye"></i> View</a>
|
</a>
|
||||||
<a href="#" class="btn btn-sm btn-outline-warning"><i class="fas fa-edit"></i> Edit</a>
|
<a href="/en-sa/gac/" class="ka" point-cid="7" point-crgn="pinpaiquyu" point-cpos="6" point-dtype="brand">
|
||||||
</td>
|
<div class="brand-item">
|
||||||
</tr>
|
<div>
|
||||||
</tbody>
|
<img
|
||||||
</table>
|
class="brand-logo lazyload"
|
||||||
|
alt="GAC"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/162/w360_yichecar_997687216275363.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/162/w360_yichecar_997687216275363.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/162/w360_yichecar_997687216275363.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">GAC</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/yusheng/" class="ka" point-cid="33" point-crgn="pinpaiquyu" point-cpos="7" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Yusheng"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240807/299/w360_yichecar_299640729984747.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240807/299/w360_yichecar_299640729984747.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240807/299/w360_yichecar_299640729984747.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Yusheng</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/forthing/" class="ka" point-cid="4" point-crgn="pinpaiquyu" point-cpos="8" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Forthing"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/409/w360_yichecar_997687040947420.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/409/w360_yichecar_997687040947420.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/409/w360_yichecar_997687040947420.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Forthing</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/baic/" class="ka" point-cid="1" point-crgn="pinpaiquyu" point-cpos="9" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="BAIC"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20241030/63/w360_yichecar_024988706367037.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20241030/63/w360_yichecar_024988706367037.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20241030/63/w360_yichecar_024988706367037.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">BAIC</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/chery/" class="ka" point-cid="12" point-crgn="pinpaiquyu" point-cpos="10" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Chery"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/868/w360_yichecar_997687986893381.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/868/w360_yichecar_997687986893381.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/868/w360_yichecar_997687986893381.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Chery</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/byd/" class="ka" point-cid="2" point-crgn="pinpaiquyu" point-cpos="11" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="BYD"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/505/w360_yichecar_997687250517674.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/505/w360_yichecar_997687250517674.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/505/w360_yichecar_997687250517674.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">BYD</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/dongfeng/" class="ka" point-cid="3" point-crgn="pinpaiquyu" point-cpos="12" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Dongfeng"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/681/w360_yichecar_997687168186887.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/681/w360_yichecar_997687168186887.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/681/w360_yichecar_997687168186887.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Dongfeng</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/bestune/" class="ka" point-cid="17" point-crgn="pinpaiquyu" point-cpos="13" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Bestune"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/546/w360_yichecar_997688154683139.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/546/w360_yichecar_997688154683139.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/546/w360_yichecar_997688154683139.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Bestune</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/maxus/" class="ka" point-cid="14" point-crgn="pinpaiquyu" point-cpos="14" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Maxus"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240710/201/w360_yichecar_057920920137249.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240710/201/w360_yichecar_057920920137249.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240710/201/w360_yichecar_057920920137249.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Maxus</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/baojun/" class="ka" point-cid="32" point-crgn="pinpaiquyu" point-cpos="15" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Baojun"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/818/w360_yichecar_997687281803661.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/818/w360_yichecar_997687281803661.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/818/w360_yichecar_997687281803661.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Baojun</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/neta/" class="ka" point-cid="24" point-crgn="pinpaiquyu" point-cpos="16" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Neta"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/529/w360_yichecar_997687752999461.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/529/w360_yichecar_997687752999461.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/529/w360_yichecar_997687752999461.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Neta</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/tank/" class="ka" point-cid="22" point-crgn="pinpaiquyu" point-cpos="17" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Tank"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240722/823/w360_yichecar_163707482354378.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240722/823/w360_yichecar_163707482354378.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240722/823/w360_yichecar_163707482354378.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Tank</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/xpeng/" class="ka" point-cid="30" point-crgn="pinpaiquyu" point-cpos="18" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="XPeng"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/485/w360_yichecar_997687648521261.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/485/w360_yichecar_997687648521261.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/485/w360_yichecar_997687648521261.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">XPeng</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/hongqi/" class="ka" point-cid="19" point-crgn="pinpaiquyu" point-cpos="19" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Hongqi"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/92/w360_yichecar_997688109274189.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/92/w360_yichecar_997688109274189.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/92/w360_yichecar_997688109274189.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Hongqi</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/gwm/" class="ka" point-cid="5" point-crgn="pinpaiquyu" point-cpos="20" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="GWM"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/420/w360_yichecar_997687442036944.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/420/w360_yichecar_997687442036944.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/420/w360_yichecar_997687442036944.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">GWM</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/lynk-co/" class="ka" point-cid="9" point-crgn="pinpaiquyu" point-cpos="21" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Lynk & Co"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240704/973/w360_yichecar_005902597375718.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240704/973/w360_yichecar_005902597375718.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240704/973/w360_yichecar_005902597375718.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Lynk & Co</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/jac/" class="ka" point-cid="10" point-crgn="pinpaiquyu" point-cpos="22" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="JAC"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/316/w360_yichecar_997688231624563.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/316/w360_yichecar_997688231624563.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/316/w360_yichecar_997688231624563.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">JAC</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/seres/" class="ka" point-cid="15" point-crgn="pinpaiquyu" point-cpos="23" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Seres"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/836/w360_yichecar_997687683665359.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/836/w360_yichecar_997687683665359.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/836/w360_yichecar_997687683665359.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Seres</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/jmc/" class="ka" point-cid="16" point-crgn="pinpaiquyu" point-cpos="24" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="JMC"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/647/w360_yichecar_000268964703865.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/647/w360_yichecar_000268964703865.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/647/w360_yichecar_000268964703865.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">JMC</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/vgv/" class="ka" point-cid="18" point-crgn="pinpaiquyu" point-cpos="25" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="VGV"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/216/w360_yichecar_997687821602652.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/216/w360_yichecar_997687821602652.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/216/w360_yichecar_997687821602652.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">VGV</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/skywell/" class="ka" point-cid="21" point-crgn="pinpaiquyu" point-cpos="26" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Skywell"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/195/w360_yichecar_997687919565147.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/195/w360_yichecar_997687919565147.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/195/w360_yichecar_997687919565147.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Skywell</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/dayun/" class="ka" point-cid="23" point-crgn="pinpaiquyu" point-cpos="27" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Dayun"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20241105/147/w360_yichecar_078641814765350.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20241105/147/w360_yichecar_078641814765350.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20241105/147/w360_yichecar_078641814765350.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Dayun</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/soueast/" class="ka" point-cid="25" point-crgn="pinpaiquyu" point-cpos="28" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Soueast"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/759/w360_yichecar_997687575999642.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/759/w360_yichecar_997687575999642.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/759/w360_yichecar_997687575999642.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Soueast</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/landian/" class="ka" point-cid="26" point-crgn="pinpaiquyu" point-cpos="29" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Landian"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/967/w360_yichecar_997688196701500.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/967/w360_yichecar_997688196701500.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/967/w360_yichecar_997688196701500.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Landian</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/haima/" class="ka" point-cid="27" point-crgn="pinpaiquyu" point-cpos="30" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Haima"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/178/w360_yichecar_000219417844615.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/178/w360_yichecar_000219417844615.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/178/w360_yichecar_000219417844615.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Haima</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/jmev/" class="ka" point-cid="28" point-crgn="pinpaiquyu" point-cpos="31" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="JMEV"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/748/w360_yichecar_997688074818713.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/748/w360_yichecar_997688074818713.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/748/w360_yichecar_997688074818713.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">JMEV</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/voyah/" class="ka" point-cid="29" point-crgn="pinpaiquyu" point-cpos="32" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="Voyah"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/500/w360_yichecar_997687950085351.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/500/w360_yichecar_997687950085351.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/500/w360_yichecar_997687950085351.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">Voyah</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a href="/en-sa/swm/" class="ka" point-cid="31" point-crgn="pinpaiquyu" point-cpos="33" point-dtype="brand">
|
||||||
|
<div class="brand-item">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="brand-logo lazyload"
|
||||||
|
alt="SWM"
|
||||||
|
src="https://global-img.bitauto.com/usercenter/car/20240703/205/w360_yichecar_997687520525767.png.webp"
|
||||||
|
data-original="https://global-img.bitauto.com/usercenter/car/20240703/205/w360_yichecar_997687520525767.png"
|
||||||
|
data-webp="https://global-img.bitauto.com/usercenter/car/20240703/205/w360_yichecar_997687520525767.png.webp"
|
||||||
|
data-errimg="https://global-img.bitauto.com/yc-static/yc-pc/haiwai-pc/assets/images/loaded_error_icon.png"
|
||||||
|
onerror="loadImageError(this)"
|
||||||
|
/>
|
||||||
|
<div class="brand-name">SWM</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="show-more-warp" style="display: none;">
|
||||||
|
<div class="view-more ka" point-ctitle="chakangengduo" point-crgn="pinpaiquyu">Show All Brands <em class="yc-icon-index yc-i-down_arrow_icon arrow-icon"></em></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Pagination -->
|
|
||||||
<nav aria-label="Page navigation" class="mt-4">
|
|
||||||
<ul class="pagination justify-content-center">
|
|
||||||
<li class="page-item disabled">
|
|
||||||
<a class="page-link" href="#" tabindex="-1" aria-disabled="true"><i class="fas fa-chevron-left"></i></a>
|
|
||||||
</li>
|
|
||||||
<li class="page-item active"><a class="page-link" href="#">1</a></li>
|
|
||||||
<li class="page-item"><a class="page-link" href="#">2</a></li>
|
|
||||||
<li class="page-item"><a class="page-link" href="#">3</a></li>
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="#"><i class="fas fa-chevron-right"></i></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bootstrap JS -->
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user