update and fixes
This commit is contained in:
parent
50c1d82e4c
commit
8399554b48
@ -2,7 +2,7 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from . import models
|
from . import models
|
||||||
from django_ledger import models as ledger_models
|
from django_ledger import models as ledger_models
|
||||||
|
from django.contrib import messages
|
||||||
# from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
# from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
||||||
# from appointment import models as appointment_models
|
# from appointment import models as appointment_models
|
||||||
from import_export.admin import ExportMixin
|
from import_export.admin import ExportMixin
|
||||||
@ -72,7 +72,7 @@ admin.site.register(models.UserActivityLog)
|
|||||||
admin.site.register(models.DealersMake)
|
admin.site.register(models.DealersMake)
|
||||||
admin.site.register(models.ExtraInfo)
|
admin.site.register(models.ExtraInfo)
|
||||||
admin.site.register(models.Ticket)
|
admin.site.register(models.Ticket)
|
||||||
admin.site.register(models.UserRegistration)
|
# admin.site.register(models.UserRegistration)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Car)
|
@admin.register(models.Car)
|
||||||
@ -175,3 +175,93 @@ class CarOptionAdmin(admin.ModelAdmin):
|
|||||||
# class ItemTransactionModelAdmin(admin.ModelAdmin):
|
# class ItemTransactionModelAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.UserRegistration)
|
||||||
|
class UserRegistrationAdmin(admin.ModelAdmin):
|
||||||
|
# Fields to display in the list view
|
||||||
|
list_display = [
|
||||||
|
'name',
|
||||||
|
'arabic_name',
|
||||||
|
'email',
|
||||||
|
'crn',
|
||||||
|
'vrn',
|
||||||
|
'phone_number',
|
||||||
|
'is_created',
|
||||||
|
'created_at',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Filters in the right sidebar
|
||||||
|
list_filter = [
|
||||||
|
'is_created',
|
||||||
|
'created_at',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Searchable fields
|
||||||
|
search_fields = [
|
||||||
|
'name', 'arabic_name', 'email', 'crn', 'vrn', 'phone_number'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Read-only fields in detail view
|
||||||
|
readonly_fields = [
|
||||||
|
'created_at', 'updated_at', 'is_created', 'password'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Organize form layout
|
||||||
|
fieldsets = [
|
||||||
|
('Account Information', {
|
||||||
|
'fields': ('name', 'arabic_name', 'email', 'phone_number')
|
||||||
|
}),
|
||||||
|
('Business Details', {
|
||||||
|
'fields': ('crn', 'vrn', 'address')
|
||||||
|
}),
|
||||||
|
('Status', {
|
||||||
|
'fields': ('is_created', 'password', 'created_at', 'updated_at'),
|
||||||
|
'classes': ('collapse',)
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Custom action to create accounts
|
||||||
|
actions = ['create_dealer_accounts']
|
||||||
|
|
||||||
|
@admin.action(description='Create dealer account(s) for selected registrations')
|
||||||
|
def create_dealer_accounts(self, request, queryset):
|
||||||
|
created_count = 0
|
||||||
|
already_created_count = 0
|
||||||
|
failed_count = 0
|
||||||
|
|
||||||
|
for registration in queryset:
|
||||||
|
try:
|
||||||
|
if not registration.is_created:
|
||||||
|
registration.create_account() # Your existing method
|
||||||
|
created_count += 1
|
||||||
|
else:
|
||||||
|
already_created_count += 1
|
||||||
|
except Exception as e:
|
||||||
|
self.message_user(
|
||||||
|
request,
|
||||||
|
f"Error creating account for {registration.name}: {str(e)}",
|
||||||
|
level=messages.ERROR
|
||||||
|
)
|
||||||
|
failed_count += 1
|
||||||
|
|
||||||
|
# Show summary message
|
||||||
|
if created_count > 0:
|
||||||
|
self.message_user(
|
||||||
|
request,
|
||||||
|
f"Successfully created {created_count} account(s).",
|
||||||
|
level=messages.SUCCESS
|
||||||
|
)
|
||||||
|
if already_created_count > 0:
|
||||||
|
self.message_user(
|
||||||
|
request,
|
||||||
|
f"{already_created_count} registration(s) were already created.",
|
||||||
|
level=messages.INFO
|
||||||
|
)
|
||||||
|
if failed_count > 0:
|
||||||
|
self.message_user(
|
||||||
|
request,
|
||||||
|
f"Failed to create {failed_count} account(s). Check logs.",
|
||||||
|
level=messages.ERROR
|
||||||
|
)
|
||||||
@ -9,7 +9,7 @@ from plans.models import PlanPricing
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from inventory.validators import SaudiPhoneNumberValidator
|
from inventory.validators import SaudiPhoneNumberValidator
|
||||||
from .models import CustomGroup, Status, Stage, UserRegistration
|
from .models import CustomGroup, Status, Stage
|
||||||
from .mixins import AddClassMixin
|
from .mixins import AddClassMixin
|
||||||
from django_ledger.forms.invoice import (
|
from django_ledger.forms.invoice import (
|
||||||
InvoiceModelCreateForm as InvoiceModelCreateFormBase,
|
InvoiceModelCreateForm as InvoiceModelCreateFormBase,
|
||||||
@ -57,6 +57,7 @@ from .models import (
|
|||||||
Tasks,
|
Tasks,
|
||||||
Recall,
|
Recall,
|
||||||
Ticket,
|
Ticket,
|
||||||
|
UserRegistration
|
||||||
)
|
)
|
||||||
from django_ledger import models as ledger_models
|
from django_ledger import models as ledger_models
|
||||||
from django.forms import (
|
from django.forms import (
|
||||||
@ -363,6 +364,7 @@ class CarForm(
|
|||||||
"receiving_date",
|
"receiving_date",
|
||||||
"vendor",
|
"vendor",
|
||||||
]
|
]
|
||||||
|
required_fields = ["vin","id_car_make", "id_car_model", "id_car_serie", "id_car_trim", "vendor"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"id_car_make": forms.Select(attrs={"class": "form-select form-select-sm"}),
|
"id_car_make": forms.Select(attrs={"class": "form-select form-select-sm"}),
|
||||||
"receiving_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
"receiving_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
||||||
@ -1259,19 +1261,8 @@ class OpportunityForm(forms.ModelForm):
|
|||||||
label=_("Expected Closing Date"), widget=forms.DateInput(attrs={"type": "date"})
|
label=_("Expected Closing Date"), widget=forms.DateInput(attrs={"type": "date"})
|
||||||
)
|
)
|
||||||
|
|
||||||
probability = forms.IntegerField(
|
car = forms.ModelChoiceField(
|
||||||
label=_("Probability (%)"),
|
queryset=Car.objects.all(), label=_("Car"), required=True
|
||||||
widget=forms.NumberInput(
|
|
||||||
attrs={
|
|
||||||
"type": "range",
|
|
||||||
"min": "0",
|
|
||||||
"max": "100",
|
|
||||||
"step": "1",
|
|
||||||
"class": "form-range",
|
|
||||||
"oninput": "this.nextElementSibling.value = this.value",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
initial=50, # Default value
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -1280,23 +1271,17 @@ class OpportunityForm(forms.ModelForm):
|
|||||||
"lead",
|
"lead",
|
||||||
"car",
|
"car",
|
||||||
"stage",
|
"stage",
|
||||||
"probability",
|
|
||||||
"amount",
|
|
||||||
"expected_revenue",
|
|
||||||
"expected_close_date",
|
"expected_close_date",
|
||||||
]
|
]
|
||||||
widgets = {
|
|
||||||
"expected_revenue": forms.NumberInput(attrs={"readonly": "readonly"}),
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
# def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
# super().__init__(*args, **kwargs)
|
||||||
# Add a visible number input to display the current value
|
# # Add a visible number input to display the current value
|
||||||
self.fields["probability"].widget.attrs["class"] = (
|
# self.fields["probability"].widget.attrs["class"] = (
|
||||||
"d-none" # Hide the default input
|
# "d-none" # Hide the default input
|
||||||
)
|
# )
|
||||||
if self.instance and self.instance.pk:
|
# if self.instance and self.instance.pk:
|
||||||
self.fields["probability"].initial = self.instance.probability
|
# self.fields["probability"].initial = self.instance.probability
|
||||||
|
|
||||||
|
|
||||||
class OpportunityStageForm(forms.ModelForm):
|
class OpportunityStageForm(forms.ModelForm):
|
||||||
@ -2259,6 +2244,8 @@ class TicketResolutionForm(forms.ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class CarDealershipRegistrationForm(forms.ModelForm):
|
class CarDealershipRegistrationForm(forms.ModelForm):
|
||||||
|
# Add additional fields for the registration form
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserRegistration
|
model = UserRegistration
|
||||||
fields = "__all__"
|
fields = ("name","arabic_name", "email","phone_number", "crn", "vrn", "address")
|
||||||
@ -49,7 +49,18 @@ from plans.models import UserPlan
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from imagekit.models import ImageSpecField
|
from imagekit.models import ImageSpecField
|
||||||
from imagekit.processors import ResizeToFill
|
from imagekit.processors import ResizeToFill
|
||||||
|
from encrypted_model_fields.fields import (
|
||||||
|
EncryptedCharField,
|
||||||
|
EncryptedTextField,
|
||||||
|
EncryptedEmailField,
|
||||||
|
EncryptedIntegerField,
|
||||||
|
EncryptedDateField,
|
||||||
|
EncryptedDateTimeField,
|
||||||
|
EncryptedBooleanField,
|
||||||
|
EncryptedJSONField,
|
||||||
|
SearchableEncryptedCharField,
|
||||||
|
SearchableEncryptedEmailField,
|
||||||
|
)
|
||||||
# from plans.models import AbstractPlan
|
# from plans.models import AbstractPlan
|
||||||
# from simple_history.models import HistoricalRecords
|
# from simple_history.models import HistoricalRecords
|
||||||
from plans.models import Invoice
|
from plans.models import Invoice
|
||||||
@ -1339,7 +1350,7 @@ class Dealer(models.Model, LocalizedNameMixin):
|
|||||||
)
|
)
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
||||||
phone_number = models.CharField(
|
phone_number = EncryptedCharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
verbose_name=_("Phone Number"),
|
verbose_name=_("Phone Number"),
|
||||||
validators=[SaudiPhoneNumberValidator()],
|
validators=[SaudiPhoneNumberValidator()],
|
||||||
@ -1707,18 +1718,18 @@ class Customer(models.Model):
|
|||||||
max_length=1,
|
max_length=1,
|
||||||
verbose_name=_("Gender"),
|
verbose_name=_("Gender"),
|
||||||
)
|
)
|
||||||
dob = models.DateField(verbose_name=_("Date of Birth"), null=True, blank=True)
|
dob = EncryptedDateField(verbose_name=_("Date of Birth"), null=True, blank=True)
|
||||||
email = models.EmailField(verbose_name=_("Email"))
|
email = SearchableEncryptedEmailField(verbose_name=_("Email"))
|
||||||
national_id = models.CharField(
|
national_id = EncryptedCharField(
|
||||||
max_length=10, unique=True, verbose_name=_("National ID"), null=True, blank=True
|
max_length=10, unique=True, verbose_name=_("National ID"), null=True, blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
phone_number = models.CharField(
|
phone_number = EncryptedCharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
verbose_name=_("Phone Number"),
|
verbose_name=_("Phone Number"),
|
||||||
validators=[SaudiPhoneNumberValidator()],
|
validators=[SaudiPhoneNumberValidator()],
|
||||||
)
|
)
|
||||||
address = models.CharField(
|
address = EncryptedCharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
active = models.BooleanField(default=True, verbose_name=_("Active"))
|
||||||
@ -2294,22 +2305,48 @@ class Schedule(models.Model):
|
|||||||
related_name="schedules",
|
related_name="schedules",
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
verbose_name=_("Customer"),
|
||||||
)
|
)
|
||||||
scheduled_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
scheduled_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
purpose = models.CharField(max_length=200, choices=PURPOSE_CHOICES)
|
purpose = models.CharField(
|
||||||
scheduled_at = models.DateTimeField()
|
max_length=200,
|
||||||
start_time = models.TimeField(verbose_name=_("Start Time"), null=True, blank=True)
|
choices=PURPOSE_CHOICES,
|
||||||
end_time = models.TimeField(verbose_name=_("End Time"), null=True, blank=True)
|
verbose_name=_("Purpose"),
|
||||||
|
help_text=_("What is the purpose of this schedule?"),
|
||||||
|
)
|
||||||
|
scheduled_at = models.DateTimeField(verbose_name=_("Scheduled Date"))
|
||||||
|
start_time = models.TimeField(
|
||||||
|
verbose_name=_("Start Time"), null=True, blank=True, help_text=_("HH:MM")
|
||||||
|
)
|
||||||
|
end_time = models.TimeField(
|
||||||
|
verbose_name=_("End Time"), null=True, blank=True, help_text=_("HH:MM")
|
||||||
|
)
|
||||||
scheduled_type = models.CharField(
|
scheduled_type = models.CharField(
|
||||||
max_length=200, choices=ScheduledType, default="Call"
|
max_length=200,
|
||||||
|
choices=ScheduledType,
|
||||||
|
default="Call",
|
||||||
|
verbose_name=_("Scheduled Type"),
|
||||||
|
help_text=_("What type of schedule is this?"),
|
||||||
)
|
)
|
||||||
completed = models.BooleanField(default=False, verbose_name=_("Completed"))
|
completed = models.BooleanField(
|
||||||
notes = models.TextField(blank=True, null=True)
|
default=False,
|
||||||
|
verbose_name=_("Completed"),
|
||||||
|
help_text=_("Has this schedule been completed?"),
|
||||||
|
)
|
||||||
|
notes = models.TextField(blank=True, null=True, verbose_name=_("Notes"))
|
||||||
status = models.CharField(
|
status = models.CharField(
|
||||||
max_length=200, choices=ScheduleStatusChoices, default="Scheduled"
|
max_length=200,
|
||||||
|
choices=ScheduleStatusChoices,
|
||||||
|
default="Scheduled",
|
||||||
|
verbose_name=_("Status"),
|
||||||
|
help_text=_("What is the status of this schedule?"),
|
||||||
|
)
|
||||||
|
created_at = models.DateTimeField(
|
||||||
|
auto_now_add=True, verbose_name=_("Created Date"), help_text=_("When was this schedule created?")
|
||||||
|
)
|
||||||
|
updated_at = models.DateTimeField(
|
||||||
|
auto_now=True, verbose_name=_("Updated Date"), help_text=_("When was this schedule last updated?")
|
||||||
)
|
)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Scheduled {self.purpose} on {self.scheduled_at}"
|
return f"Scheduled {self.purpose} on {self.scheduled_at}"
|
||||||
@ -2414,10 +2451,11 @@ class Opportunity(models.Model):
|
|||||||
"Lead",
|
"Lead",
|
||||||
related_name="opportunity",
|
related_name="opportunity",
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name=_("Lead"),
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
probability = models.PositiveIntegerField(validators=[validate_probability])
|
probability = models.PositiveIntegerField(validators=[validate_probability],null=True, blank=True)
|
||||||
amount = models.DecimalField(
|
amount = models.DecimalField(
|
||||||
max_digits=10,
|
max_digits=10,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
@ -3873,7 +3911,7 @@ class UserRegistration(models.Model):
|
|||||||
crn = models.CharField(_("Commercial Registration Number"), max_length=10, unique=True)
|
crn = models.CharField(_("Commercial Registration Number"), max_length=10, unique=True)
|
||||||
vrn = models.CharField(_("Vehicle Registration Number"), max_length=15, unique=True)
|
vrn = models.CharField(_("Vehicle Registration Number"), max_length=15, unique=True)
|
||||||
address = models.TextField(_("Address"))
|
address = models.TextField(_("Address"))
|
||||||
password = models.CharField(_("Password"), max_length=255)
|
password = models.CharField(_("Password"), max_length=255,null=True,blank=True)
|
||||||
is_created = models.BooleanField(default=False)
|
is_created = models.BooleanField(default=False)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
@ -3884,16 +3922,37 @@ class UserRegistration(models.Model):
|
|||||||
return self.email
|
return self.email
|
||||||
|
|
||||||
def create_account(self):
|
def create_account(self):
|
||||||
from django_q.tasks import async_task
|
|
||||||
from .tasks import create_user_dealer
|
from .tasks import create_user_dealer
|
||||||
|
|
||||||
password = User.objects.make_random_password()
|
if self.is_created or User.objects.filter(email=self.email).exists():
|
||||||
|
logger.info(f"Account already created or exists: {self.email}")
|
||||||
|
return False
|
||||||
|
|
||||||
if self.is_created:
|
password = make_random_password()
|
||||||
return
|
|
||||||
dealer = create_user_dealer(self.email,password,self.name,self.arabic_name,self.phone,self.crn,self.vrn,self.address)
|
|
||||||
|
|
||||||
if dealer:
|
try:
|
||||||
self.is_created = True
|
logger.info(f"Creating user account {self.email}")
|
||||||
self.password = password
|
dealer = create_user_dealer(
|
||||||
self.save()
|
email=self.email,
|
||||||
|
password=password,
|
||||||
|
name=self.name,
|
||||||
|
arabic_name=self.arabic_name,
|
||||||
|
phone=self.phone_number,
|
||||||
|
crn=self.crn,
|
||||||
|
vrn=self.vrn,
|
||||||
|
address=self.address
|
||||||
|
)
|
||||||
|
|
||||||
|
if dealer:
|
||||||
|
self.is_created = True
|
||||||
|
self.password = password
|
||||||
|
self.save()
|
||||||
|
logger.info(f"User account created successfully: {self.email}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error(f"Failed to create dealer account: {self.email}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error creating account for {self.email}: {e}")
|
||||||
|
return False
|
||||||
@ -310,20 +310,22 @@ def create_item_model(sender, instance, created, **kwargs):
|
|||||||
"""
|
"""
|
||||||
entity = instance.dealer.entity
|
entity = instance.dealer.entity
|
||||||
|
|
||||||
if created:
|
coa = entity.get_default_coa()
|
||||||
coa = entity.get_default_coa()
|
uom = entity.get_uom_all().filter(name="Unit").first()
|
||||||
uom = entity.get_uom_all().get(name="Unit")
|
if not uom:
|
||||||
|
uom = entity.create_uom(name="Unit", unit_abbr="unit")
|
||||||
|
|
||||||
if not instance.item_model:
|
if not instance.item_model:
|
||||||
inventory = entity.create_item_product(
|
inventory = entity.create_item_product(
|
||||||
name=instance.vin,
|
name=instance.vin,
|
||||||
item_type=ItemModel.ITEM_TYPE_MATERIAL,
|
item_type=ItemModel.ITEM_TYPE_MATERIAL,
|
||||||
uom_model=uom,
|
uom_model=uom,
|
||||||
coa_model=coa,
|
coa_model=coa,
|
||||||
)
|
)
|
||||||
instance.item_model = inventory
|
instance.item_model = inventory
|
||||||
inventory.save()
|
instance.save()
|
||||||
else:
|
|
||||||
|
if instance.marked_price:
|
||||||
instance.item_model.default_amount = instance.marked_price
|
instance.item_model.default_amount = instance.marked_price
|
||||||
instance.item_model.save()
|
instance.item_model.save()
|
||||||
|
|
||||||
@ -1391,11 +1393,35 @@ def handle_car_image(sender, instance, created, **kwargs):
|
|||||||
|
|
||||||
@receiver(post_save, sender=models.UserRegistration)
|
@receiver(post_save, sender=models.UserRegistration)
|
||||||
def handle_user_registration(sender, instance, created, **kwargs):
|
def handle_user_registration(sender, instance, created, **kwargs):
|
||||||
if instance.is_created:
|
if created:
|
||||||
send_email(
|
send_email(
|
||||||
"Account Created",
|
settings.DEFAULT_FROM_EMAIL,
|
||||||
f"Your account has been created and you can login with your email and password: {instance.password}",
|
instance.email,
|
||||||
settings.DEFAULT_FROM_EMAIL,
|
"Account Registration",
|
||||||
[instance.email],
|
"""
|
||||||
fail_silently=False,
|
Thank you for registering with us. We will contact you shortly to complete your application.
|
||||||
)
|
شكرا لمراسلتنا. سوف نتصل بك قريبا لاستكمال طلبك.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
if instance.is_created:
|
||||||
|
logger.info(f"User account created: {instance.email}, sending email")
|
||||||
|
send_email(
|
||||||
|
settings.DEFAULT_FROM_EMAIL,
|
||||||
|
instance.email,
|
||||||
|
"Account Created",
|
||||||
|
f"""
|
||||||
|
Dear {instance.name},
|
||||||
|
|
||||||
|
Your account has been created and you can login with your email {instance.email} and password: {instance.password}.
|
||||||
|
Please login to the website to complete your profile and start using our services.
|
||||||
|
|
||||||
|
Thank you for choosing us.
|
||||||
|
|
||||||
|
عزيزي {instance.name},
|
||||||
|
|
||||||
|
لقد تم إنشاء حسابك والآن يمكنك تسجيل الدخول باستخدام بريدك الإلكتروني {instance.email} وكلمة المرور: {instance.password}.
|
||||||
|
يرجى تسجيل الدخول إلى الموقع لاستكمال الملف الشخصي والبدء في استخدام خدماتنا.
|
||||||
|
|
||||||
|
شكرا لاختيارك لنا.
|
||||||
|
""")
|
||||||
|
|||||||
@ -1440,13 +1440,13 @@ class CarListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
qs = super().get_queryset()
|
qs = super().get_queryset()
|
||||||
qs = qs.filter(dealer=dealer)
|
qs = qs.filter(dealer=dealer)
|
||||||
# status = self.request.GET.get("status")
|
# status = self.request.GET.get("status")
|
||||||
|
# status = self.request.GET.get("status")
|
||||||
search = self.request.GET.get("search")
|
search = self.request.GET.get("search")
|
||||||
make = self.request.GET.get("make", None)
|
make = self.request.GET.get("make", None)
|
||||||
model = self.request.GET.get("model", None)
|
model = self.request.GET.get("model", None)
|
||||||
year = self.request.GET.get("year", None)
|
year = self.request.GET.get("year", None)
|
||||||
car_status = self.request.GET.get("car_status", None)
|
car_status = self.request.GET.get("car_status", None)
|
||||||
print("ALLLLLLLLL:::",make,model)
|
print(car_status)
|
||||||
|
|
||||||
if car_status:
|
if car_status:
|
||||||
qs = qs.filter(status=car_status)
|
qs = qs.filter(status=car_status)
|
||||||
if search:
|
if search:
|
||||||
@ -6331,9 +6331,14 @@ def lead_create(request, dealer_slug):
|
|||||||
form.filter_qs(dealer=dealer)
|
form.filter_qs(dealer=dealer)
|
||||||
|
|
||||||
if make := request.GET.get("id_car_make", None):
|
if make := request.GET.get("id_car_make", None):
|
||||||
form.fields["id_car_model"].queryset = models.CarModel.objects.filter(
|
qs = models.CarModel.objects.filter(
|
||||||
id_car_make=int(make)
|
id_car_make=int(make)
|
||||||
)
|
)
|
||||||
|
form.fields["id_car_model"].queryset = qs
|
||||||
|
form.fields["id_car_model"].choices = [
|
||||||
|
(obj.id_car_model, obj.get_local_name()) for obj in qs
|
||||||
|
]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dealer_make_list = models.DealersMake.objects.filter(dealer=dealer).values_list(
|
dealer_make_list = models.DealersMake.objects.filter(dealer=dealer).values_list(
|
||||||
"car_make", flat=True
|
"car_make", flat=True
|
||||||
@ -6367,7 +6372,11 @@ def lead_create(request, dealer_slug):
|
|||||||
]
|
]
|
||||||
|
|
||||||
if first_make := qs.first():
|
if first_make := qs.first():
|
||||||
form.fields["id_car_model"].queryset = first_make.carmodel_set.all()
|
qs = first_make.carmodel_set.all()
|
||||||
|
form.fields["id_car_model"].queryset = qs
|
||||||
|
form.fields["id_car_model"].choices = [
|
||||||
|
(obj.id_car_model, obj.get_local_name()) for obj in qs
|
||||||
|
]
|
||||||
|
|
||||||
return render(request, "crm/leads/lead_form.html", {"form": form})
|
return render(request, "crm/leads/lead_form.html", {"form": form})
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 368 KiB |
@ -282,7 +282,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#exampleModal">
|
data-bs-target="#exampleModal">
|
||||||
<i class="fa-solid fa-user-plus me-2"></i> Reassign Lead
|
<i class="fa-solid fa-user-plus me-2"></i> {%trans "Reassign Lead"%}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-phoenix-primary btn-sm"
|
<button class="btn btn-phoenix-primary btn-sm"
|
||||||
@ -301,7 +301,7 @@
|
|||||||
method="post">
|
method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="exampleModalLabel">Reassign Lead To Another Employee</h5>
|
<h5 class="modal-title" id="exampleModalLabel">{%trans "Reassign Lead To Another Employee"%}</h5>
|
||||||
<button class="btn btn-close p-1"
|
<button class="btn btn-close p-1"
|
||||||
type="button"
|
type="button"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
@ -581,25 +581,25 @@
|
|||||||
scope="col"
|
scope="col"
|
||||||
data-sort="subject"
|
data-sort="subject"
|
||||||
style="width:31%;
|
style="width:31%;
|
||||||
min-width:350px">Subject</th>
|
min-width:350px">{{ _("Subject") }}</th>
|
||||||
<th class="sort align-middle pe-3 text-uppercase"
|
<th class="sort align-middle pe-3 text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="sent"
|
data-sort="sent"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:130px">Sent by</th>
|
min-width:130px">{{ _("Sent by") }}</th>
|
||||||
<th class="sort align-middle text-start text-uppercase"
|
<th class="sort align-middle text-start text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="date"
|
data-sort="date"
|
||||||
style="min-width:165px">Date</th>
|
style="min-width:165px">{{ _("Date") }}</th>
|
||||||
<th class="sort align-middle pe-0 text-uppercase"
|
<th class="sort align-middle pe-0 text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:100px">Action</th>
|
min-width:100px">{{ _("Action") }}</th>
|
||||||
<th class="sort align-middle text-end text-uppercase"
|
<th class="sort align-middle text-end text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="status"
|
data-sort="status"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:100px">Status</th>
|
min-width:100px">{{ _("Status") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list" id="all-email-table-body">
|
<tbody class="list" id="all-email-table-body">
|
||||||
@ -619,10 +619,10 @@
|
|||||||
<td class="sent align-middle white-space-nowrap text-start fw-bold text-body-tertiary py-2">{{ email.from_email }}</td>
|
<td class="sent align-middle white-space-nowrap text-start fw-bold text-body-tertiary py-2">{{ email.from_email }}</td>
|
||||||
<td class="date align-middle white-space-nowrap text-body py-2">{{ email.created|naturalday }}</td>
|
<td class="date align-middle white-space-nowrap text-body py-2">{{ email.created|naturalday }}</td>
|
||||||
<td class="align-middle white-space-nowrap ps-3">
|
<td class="align-middle white-space-nowrap ps-3">
|
||||||
<a class="text-body" href=""><span class="fa-solid fa-phone text-primary me-2"></span>Call</a>
|
<a class="text-body" href=""><span class="fa-solid fa-phone text-primary me-2"></span>{%trans "Call"%</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="status align-middle fw-semibold text-end py-2">
|
<td class="status align-middle fw-semibold text-end py-2">
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-success">sent</span>
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success">{%trans "sent"%}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -670,25 +670,25 @@
|
|||||||
scope="col"
|
scope="col"
|
||||||
data-sort="subject"
|
data-sort="subject"
|
||||||
style="width:31%;
|
style="width:31%;
|
||||||
min-width:350px">Subject</th>
|
min-width:350px">{% trans "Subject" %}</th>
|
||||||
<th class="sort align-middle pe-3 text-uppercase"
|
<th class="sort align-middle pe-3 text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="sent"
|
data-sort="sent"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:130px">Sent by</th>
|
min-width:130px">{% trans "Sent by" %}</th>
|
||||||
<th class="sort align-middle text-start text-uppercase"
|
<th class="sort align-middle text-start text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="date"
|
data-sort="date"
|
||||||
style="min-width:165px">Date</th>
|
style="min-width:165px">{% trans "Date" %}</th>
|
||||||
<th class="sort align-middle pe-0 text-uppercase"
|
<th class="sort align-middle pe-0 text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:100px">Action</th>
|
min-width:100px">{% trans "Action" %}</th>
|
||||||
<th class="sort align-middle text-end text-uppercase"
|
<th class="sort align-middle text-end text-uppercase"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="status"
|
data-sort="status"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:100px">Status</th>
|
min-width:100px">{% trans "Status" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list" id="drafts-email-table-body">
|
<tbody class="list" id="drafts-email-table-body">
|
||||||
@ -777,20 +777,20 @@
|
|||||||
scope="col"
|
scope="col"
|
||||||
data-sort="subject"
|
data-sort="subject"
|
||||||
style="width:31%;
|
style="width:31%;
|
||||||
min-width:100px">Name</th>
|
min-width:100px">{%trans "Name"%}</th>
|
||||||
<th class="sort align-middle pe-3 text"
|
<th class="sort align-middle pe-3 text"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="sent"
|
data-sort="sent"
|
||||||
style="width:15%;
|
style="width:15%;
|
||||||
min-width:400px">Note</th>
|
min-width:400px">{%trans "Note"%}</th>
|
||||||
<th class="sort align-middle text-start"
|
<th class="sort align-middle text-start"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="date"
|
data-sort="date"
|
||||||
style="min-width:100px">Due Date</th>
|
style="min-width:100px">{%trans "Due Date"%}</th>
|
||||||
<th class="sort align-middle text-start"
|
<th class="sort align-middle text-start"
|
||||||
scope="col"
|
scope="col"
|
||||||
data-sort="date"
|
data-sort="date"
|
||||||
style="min-width:100px">Completed</th>
|
style="min-width:100px">{%trans "Completed"%}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list taskTable" id="all-tasks-table-body">
|
<tbody class="list taskTable" id="all-tasks-table-body">
|
||||||
@ -802,9 +802,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row align-items-center justify-content-between py-2 pe-0 fs-9 mt-3">
|
<div class="row align-items-center justify-content-between py-2 pe-0 fs-9 mt-3">
|
||||||
<div class="col-auto d-flex">
|
<div class="col-auto d-flex">
|
||||||
<a class="nav-link px-3 d-block"
|
|
||||||
href="{% url 'appointment:get_user_appointments' %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("View in Calendar") }}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -686,7 +686,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane fade"
|
<div class="tab-pane fade"
|
||||||
id="tab-emails"
|
id="tab-emails"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
@ -694,7 +694,7 @@
|
|||||||
<h2 class="mb-4">Emails</h2>
|
<h2 class="mb-4">Emails</h2>
|
||||||
{% if perms.inventory.change_opportunity %}
|
{% if perms.inventory.change_opportunity %}
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
|
|
||||||
{% if opportunity.lead %}
|
{% if opportunity.lead %}
|
||||||
<button class="btn btn-phoenix-primary btn-sm"
|
<button class="btn btn-phoenix-primary btn-sm"
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@ -62,7 +62,7 @@
|
|||||||
{% if form.stage.errors %}<div class="invalid-feedback d-block">{{ form.stage.errors }}</div>{% endif %}
|
{% if form.stage.errors %}<div class="invalid-feedback d-block">{{ form.stage.errors }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<!-- Amount Field -->
|
<!-- Amount Field -->
|
||||||
<div class="mb-4">
|
{% comment %} <div class="mb-4">
|
||||||
<label class="form-label" for="{{ form.amount.id_for_label }}">
|
<label class="form-label" for="{{ form.amount.id_for_label }}">
|
||||||
{{ form.amount.label }}
|
{{ form.amount.label }}
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
@ -72,9 +72,9 @@
|
|||||||
{{ form.amount|add_class:"form-control" }}
|
{{ form.amount|add_class:"form-control" }}
|
||||||
</div>
|
</div>
|
||||||
{% if form.amount.errors %}<div class="invalid-feedback d-block">{{ form.amount.errors }}</div>{% endif %}
|
{% if form.amount.errors %}<div class="invalid-feedback d-block">{{ form.amount.errors }}</div>{% endif %}
|
||||||
</div>
|
</div> {% endcomment %}
|
||||||
<!-- Probability Field -->
|
<!-- Probability Field -->
|
||||||
<div class="mb-4">
|
{% comment %} <div class="mb-4">
|
||||||
<label class="form-label" for="{{ form.probability.id_for_label }}">
|
<label class="form-label" for="{{ form.probability.id_for_label }}">
|
||||||
{{ form.probability.label }}
|
{{ form.probability.label }}
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
@ -106,10 +106,10 @@
|
|||||||
{% if form.expected_revenue.errors %}
|
{% if form.expected_revenue.errors %}
|
||||||
<div class="invalid-feedback d-block">{{ form.expected_revenue.errors }}</div>
|
<div class="invalid-feedback d-block">{{ form.expected_revenue.errors }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div> {% endcomment %}
|
||||||
<!-- Closing Date -->
|
<!-- Closing Date -->
|
||||||
<div class="mb-5">
|
<div class="mb-5">
|
||||||
<label class="form-label" for="{{ form.closing_date.id_for_label }}">{{ form.closing_date.label }}</label>
|
<label class="form-label" for="{{ form.expected_close_date.id_for_label }}">{{ form.expected_close_date.label }}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
{{ form.expected_close_date|add_class:"form-control" }}
|
{{ form.expected_close_date|add_class:"form-control" }}
|
||||||
<span class="input-group-text"><span class="far fa-calendar"></span></span>
|
<span class="input-group-text"><span class="far fa-calendar"></span></span>
|
||||||
|
|||||||
@ -75,7 +75,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h2>
|
<h2>
|
||||||
Upload Cars CSV <i class="fa-solid fa-file-csv text-primary"></i>
|
{% trans 'Upload Cars CSV' %} <i class="fa-solid fa-file-csv text-primary"></i>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
<a href="{% static 'sample/cars_sample.csv' %}"
|
<a href="{% static 'sample/cars_sample.csv' %}"
|
||||||
|
|||||||
@ -194,11 +194,12 @@
|
|||||||
{% if perms.inventory.add_carregistration %}
|
{% if perms.inventory.add_carregistration %}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-phoenix-success"
|
class="btn btn-sm btn-phoenix-success"
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#mainModal"
|
|
||||||
hx-get="{% url 'add_registration' request.dealer.slug car.slug %}"
|
hx-get="{% url 'add_registration' request.dealer.slug car.slug %}"
|
||||||
hx-target=".main-modal-body"
|
hx-target=".main-modal-body"
|
||||||
hx-swap="innerHTML">{% trans 'Add' %}</button>
|
hx-swap="innerHTML"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#mainModal"
|
||||||
|
>{% trans 'Add' %}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -214,10 +215,10 @@
|
|||||||
{{ car.location.showroom.get_local_name }}
|
{{ car.location.showroom.get_local_name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.inventory.add_cartransfer %}
|
{% if perms.inventory.add_cartransfer %}
|
||||||
<a href="{% url 'update_car_location' car.slug car.location.pk %}"
|
{% comment %} <a href="{% url 'update_car_location' car.slug car.location.pk %}"
|
||||||
class="btn btn-phoenix-danger btn-sm">
|
class="btn btn-phoenix-danger btn-sm">
|
||||||
{% trans "transfer"|capfirst %}
|
{% trans "transfer"|capfirst %}
|
||||||
</a>
|
</a> {% endcomment %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "No location available." %}
|
{% trans "No location available." %}
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
</style>
|
</style>
|
||||||
{% endblock customCSS %}
|
{% endblock customCSS %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if cars or request.GET.q %}
|
|
||||||
<div class="container-fluid" id="projectSummary">
|
<div class="container-fluid" id="projectSummary">
|
||||||
<div class="row g-3 justify-content-between align-items-end mb-4">
|
<div class="row g-3 justify-content-between align-items-end mb-4">
|
||||||
<div class="col-12 col-sm-auto">
|
<div class="col-12 col-sm-auto">
|
||||||
@ -105,7 +105,7 @@
|
|||||||
<input class="form-control search-input search"
|
<input class="form-control search-input search"
|
||||||
name="search"
|
name="search"
|
||||||
type="search"
|
type="search"
|
||||||
placeholder="Search"
|
placeholder="{% trans 'Search' %}"
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
hx-get="{% url 'car_list' request.dealer.slug %}"
|
hx-get="{% url 'car_list' request.dealer.slug %}"
|
||||||
hx-trigger="keyup changed delay:500ms"
|
hx-trigger="keyup changed delay:500ms"
|
||||||
@ -169,17 +169,17 @@
|
|||||||
hx-get="{% url 'car_list' request.dealer.slug %}"
|
hx-get="{% url 'car_list' request.dealer.slug %}"
|
||||||
hx-include=".make,.model,.year,.car_status"
|
hx-include=".make,.model,.year,.car_status"
|
||||||
hx-indicator=".htmx-indicator"
|
hx-indicator=".htmx-indicator"
|
||||||
hx-target=".table-responsive"
|
hx-target=".table-responsive1"
|
||||||
hx-select=".table-responsive"
|
hx-select=".table-responsive1"
|
||||||
hx-swap="outerHTML show:window:top"
|
hx-swap="outerHTML show:window:top"
|
||||||
class="btn btn-sm btn-phoenix-primary ms-1"
|
class="btn btn-sm btn-phoenix-primary ms-1"
|
||||||
hx-on::before-request="filter_before_request()"
|
hx-on::before-request="filter_before_request()"
|
||||||
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
|
hx-on::after-request="filter_after_request()">{{ _("Search") }}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-responsive scrollbar">
|
<div class="table-responsive1 scrollbar">
|
||||||
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9">
|
<div class="d-flex flex-wrap align-items-center justify-content-between py-3 pe-0 fs-9">
|
||||||
<div class="d-flex"
|
<div class="d-flex"
|
||||||
hx-boost="true"
|
hx-boost="false"
|
||||||
hx-push-url="false"
|
hx-push-url="false"
|
||||||
hx-include=".make,.model,.year,.car_status"
|
hx-include=".make,.model,.year,.car_status"
|
||||||
hx-target=".table-responsive"
|
hx-target=".table-responsive"
|
||||||
@ -301,10 +301,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
{% url "car_add" request.dealer.slug as create_car_url %}
|
|
||||||
{% include "empty-illustration-page.html" with value="car" url=create_car_url %}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block customJS%}
|
{% block customJS%}
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@ -169,7 +169,7 @@
|
|||||||
class="form-control form-control-sm"
|
class="form-control form-control-sm"
|
||||||
required
|
required
|
||||||
placeholder="email@example.com"
|
placeholder="email@example.com"
|
||||||
value="{{ request.dealer.email }}">
|
value="{{ request.dealer.user.email }}">
|
||||||
</div>
|
</div>
|
||||||
<label class="form-label" for="phone">{{ _("Phone Number") }}</label>
|
<label class="form-label" for="phone">{{ _("Phone Number") }}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|||||||
@ -1,5 +1,15 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
<div class="form-group" id="form-{{ name }}">
|
<div class="form-group" id="form-{{ name }}">
|
||||||
<label for="{{ name }}">{{ name|capfirst }}</label>
|
{% if name == "make" %}
|
||||||
|
<label for="{{ name }}">{% trans "Make" %}</label>
|
||||||
|
{% elif name == "model" %}
|
||||||
|
<label for="{{ name }}">{% trans "Model" %}</label>
|
||||||
|
{% elif name == "serie" %}
|
||||||
|
<label for="{{ name }}">{% trans "Serie" %}</label>
|
||||||
|
{% elif name == "trim" %}
|
||||||
|
<label for="{{ name }}">{% trans "Trim" %}</label>
|
||||||
|
{% endif %}
|
||||||
<select class="form-control"
|
<select class="form-control"
|
||||||
name="{{ name }}"
|
name="{{ name }}"
|
||||||
id="{{ name }}"
|
id="{{ name }}"
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-body-highlight">
|
<tr class="bg-body-highlight">
|
||||||
<th scope="col">{% trans "Name" %}</th>
|
<th scope="col">{% trans "Name" %}</th>
|
||||||
<th scope="col">{% trans "Quatnity" %}</th>
|
<th scope="col">{% trans "Quantity" %}</th>
|
||||||
<th scope="col">{% trans "Unit Cost" %}</th>
|
<th scope="col">{% trans "Unit Cost" %}</th>
|
||||||
<th scope="col">{% trans "Is Data Uploaded ?" %}</th>
|
<th scope="col">{% trans "Is Data Uploaded ?" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -128,9 +128,9 @@
|
|||||||
<h2 class="mb-7">{{ _("Pricing") }}</h2>
|
<h2 class="mb-7">{{ _("Pricing") }}</h2>
|
||||||
<div class="row g-3 mb-7 mb-lg-11">
|
<div class="row g-3 mb-7 mb-lg-11">
|
||||||
{% for plan in plan_list %}
|
{% for plan in plan_list %}
|
||||||
|
|
||||||
<div class="col-lg-4" onclick="window.location='{% url "account_signup" %}';">
|
<div class="col-lg-4" onclick="window.location='{% url "account_signup" %}';">
|
||||||
|
|
||||||
<input type="radio"
|
<input type="radio"
|
||||||
class="btn-check"
|
class="btn-check"
|
||||||
name="selected_plan"
|
name="selected_plan"
|
||||||
@ -144,7 +144,7 @@
|
|||||||
<h3 class="h6 mb-3">
|
<h3 class="h6 mb-3">
|
||||||
{{ plan.planpricing_set.first.price }}
|
{{ plan.planpricing_set.first.price }}
|
||||||
<span class="icon-saudi_riyal"></span>
|
<span class="icon-saudi_riyal"></span>
|
||||||
<span class="fs-8 fw-normal">/ {{ _("Per month") }}</span>
|
<span class="fs-8 fw-normal">/{{plan.planpricing_set.first.pricing.period}} {{ _("month") }}</span>
|
||||||
</h3>
|
</h3>
|
||||||
<h5 class="mb-3 h6">{{ _("Included") }}</h5>
|
<h5 class="mb-3 h6">{{ _("Included") }}</h5>
|
||||||
<ul class="fa-ul ps-3 m-0">
|
<ul class="fa-ul ps-3 m-0">
|
||||||
@ -158,9 +158,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user