Merge remote-tracking branch 'origin/main'

This commit is contained in:
Marwan Alwali 2025-02-09 20:25:37 +03:00
commit 7379bb9e4d
14 changed files with 364 additions and 160 deletions

View File

@ -1,3 +1,4 @@
from django.urls import reverse
from django_countries.widgets import CountrySelectWidget
from phonenumber_field.formfields import PhoneNumberField
from django.core.validators import MinLengthValidator
@ -35,8 +36,7 @@ from .models import (
# SaleQuotationCar,
AdditionalServices,
Staff,
Opportunity, Priority, Sources, Lead, Activity, Notes, CarModel,
SaleOrder
Opportunity, Priority, Sources, Lead, Activity, Notes, CarModel,SaleOrder,CarMake
)
from django_ledger import models as ledger_models
from django.forms import ModelMultipleChoiceField, ValidationError, DateInput,DateTimeInput
@ -650,6 +650,12 @@ class EmailForm(forms.Form):
class LeadForm(forms.ModelForm):
id_car_make = forms.ModelChoiceField(label="Make",
queryset=CarMake.objects.filter(is_sa_import=True),
widget=forms.Select(attrs={"class": "form-control form-control-sm","hx-get":"","hx-include":"#id_id_car_make","hx-select":"#div_id_id_car_model","hx-target":"#div_id_id_car_model","hx-swap":"outerHTML"}),
required=True
)
id_car_model = forms.ModelChoiceField(label="Model", queryset=CarModel.objects.none(),widget=forms.Select(attrs={"class": "form-control form-control-sm"}),required=True)
class Meta:
model = Lead
fields = [
@ -658,7 +664,9 @@ class LeadForm(forms.ModelForm):
'email',
'phone_number',
'address',
'car',
'id_car_make',
'id_car_model',
'year',
'source',
'channel',
'staff',
@ -666,8 +674,8 @@ class LeadForm(forms.ModelForm):
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
if "id_car_make" in self.fields:
queryset = self.fields["id_car_make"].queryset.filter(is_sa_import=True)
self.fields["id_car_make"].choices = [
@ -678,7 +686,7 @@ class ScheduleForm(forms.ModelForm):
scheduled_at = forms.DateTimeField(widget=DateTimeInput(attrs={'type': 'datetime-local'}))
class Meta:
model = Schedule
fields = ['purpose','scheduled_type', 'scheduled_at', 'notes']
fields = ['purpose','scheduled_type', 'scheduled_at','duration', 'notes']
class NoteForm(forms.ModelForm):

View File

@ -0,0 +1,14 @@
# Generated by Django 4.2.17 on 2025-02-06 10:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('inventory', '0002_alter_carregistration_car'),
('inventory', '0011_remove_lead_year_alter_schedule_customer'),
]
operations = [
]

View File

@ -0,0 +1,33 @@
# Generated by Django 4.2.17 on 2025-02-06 12:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('inventory', '0013_alter_carregistration_text2_and_more'),
]
operations = [
migrations.RemoveField(
model_name='lead',
name='car',
),
migrations.AddField(
model_name='lead',
name='id_car_make',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.carmake', verbose_name='Make'),
),
migrations.AddField(
model_name='lead',
name='id_car_model',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.carmodel', verbose_name='Model'),
),
migrations.AddField(
model_name='lead',
name='year',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Year'),
),
]

View File

@ -0,0 +1,14 @@
# Generated by Django 4.2.17 on 2025-02-09 08:16
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('inventory', '0012_merge_20250206_1308'),
('inventory', '0014_remove_lead_car_lead_id_car_make_lead_id_car_model_and_more'),
]
operations = [
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.2.17 on 2025-02-09 08:23
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0015_merge_20250209_1116'),
]
operations = [
migrations.AddField(
model_name='schedule',
name='duration',
field=models.DurationField(default=datetime.timedelta(seconds=300)),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.17 on 2025-02-09 11:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0016_schedule_duration'),
]
operations = [
migrations.AddField(
model_name='car',
name='hash',
field=models.CharField(blank=True, max_length=64, null=True, verbose_name='Hash'),
),
]

View File

@ -1,38 +1,21 @@
# from datetime import timezone
from django.utils import timezone
import itertools
from uuid import uuid4
from django.conf import settings
from django.db import models, transaction
from django.db.models import Sum, F, Count
from decimal import Decimal
import hashlib
from django.db import models
from datetime import timedelta
from django.contrib.auth.models import User, UserManager
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from django_ledger.models import (
VendorModel,
EntityModel,
EntityUnitModel,
ItemModel,
AccountModel,
ItemModelAbstract,
UnitOfMeasureModel,
CustomerModel,
ItemModelQuerySet,
)
from django_ledger.io.io_core import get_localdate
from django.db.models import Sum
from decimal import Decimal, InvalidOperation
from django.core.exceptions import ValidationError
from phonenumber_field.modelfields import PhoneNumberField
from django.utils.timezone import now
from sqlalchemy.orm.base import object_state
from .utilities.financials import get_financial_value, get_total, get_total_financials
from django.db.models import FloatField
from .mixins import LocalizedNameMixin
from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel
from django_countries.fields import CountryField
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
@ -403,6 +386,11 @@ class Car(models.Model):
remarks = models.TextField(blank=True, null=True, verbose_name=_("Remarks"))
mileage = models.IntegerField(blank=True, null=True, verbose_name=_("Mileage"))
receiving_date = models.DateTimeField(verbose_name=_("Receiving Date"))
hash = models.CharField(max_length=64, blank=True, null=True, verbose_name=_("Hash"))
def save(self, *args, **kwargs):
self.hash = self.get_hash
super(Car, self).save(*args, **kwargs)
class Meta:
verbose_name = _("Car")
@ -424,6 +412,12 @@ class Car(models.Model):
def get_car_group(self):
return f"{self.id_car_make.get_local_name} {self.id_car_model.get_local_name}"
@property
def get_hash(self):
hash_object = hashlib.sha256()
hash_object.update(f"{self.id_car_make.name}{self.id_car_model.name}".encode('utf-8'))
return hash_object.hexdigest()
def to_dict(self):
return {
"vin": self.vin,
@ -437,6 +431,7 @@ class Car(models.Model):
"remarks": self.remarks,
"mileage": self.mileage,
"receiving_date": self.receiving_date.strftime('%Y-%m-%d %H:%M:%S'),
'hash': self.get_hash,
"id": self.id,
}
@ -1097,26 +1092,26 @@ class Lead(models.Model):
CustomerModel, on_delete=models.CASCADE, related_name="leads",
null=True,blank=True
)
car = models.ForeignKey(
Car, on_delete=models.DO_NOTHING, blank=True, null=True, verbose_name=_("Car")
# car = models.ForeignKey(
# Car, on_delete=models.DO_NOTHING, blank=True, null=True, verbose_name=_("Car")
# )
id_car_make = models.ForeignKey(
CarMake,
on_delete=models.DO_NOTHING,
blank=True,
null=True,
verbose_name=_("Make"),
)
id_car_model = models.ForeignKey(
CarModel,
on_delete=models.DO_NOTHING,
blank=True,
null=True,
verbose_name=_("Model"),
)
year = models.PositiveSmallIntegerField(
verbose_name=_("Year"), blank=True, null=True
)
# id_car_make = models.ForeignKey(
# CarMake,
# on_delete=models.DO_NOTHING,
# blank=True,
# null=True,
# verbose_name=_("Make"),
# )
# id_car_model = models.ForeignKey(
# CarModel,
# on_delete=models.DO_NOTHING,
# blank=True,
# null=True,
# verbose_name=_("Model"),
# )
# year = models.PositiveSmallIntegerField(
# verbose_name=_("Year"), blank=True, null=True
# )
source = models.CharField(
max_length=50, choices=Sources.choices, verbose_name=_("Source")
)
@ -1168,14 +1163,16 @@ class Lead(models.Model):
"email": str(self.email),
"address": str(self.address),
"phone_number": str(self.phone_number),
"car": self.car.to_dict(),
"make": str(self.id_car_make.name),
"model": str(self.id_car_model.name),
"created_at": str(self.created.strftime("%Y-%m-%d")),
}
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
def convert_to_customer(self,entity):
if entity and not entity.get_customers().filter(email=self.email).exists():
customer = entity.get_customers().filter(email=self.email).first()
if entity and not customer:
customer = entity.create_customer(
customer_model_kwargs={
"customer_name": self.full_name,
@ -1183,12 +1180,13 @@ class Lead(models.Model):
"phone": self.phone_number,
"email": self.email,
}
)
customer.additional_info = {}
customer.additional_info.update({"info":self.to_dict()})
self.customer = customer
customer.save()
self.save()
)
customer.additional_info = {}
customer.additional_info.update({"info":self.to_dict()})
self.customer = customer
customer.save()
self.save()
def get_latest_schedule(self):
return self.schedules.order_by('-scheduled_at').first()
@ -1218,6 +1216,7 @@ class Schedule(models.Model):
purpose = models.CharField(max_length=200, choices=PURPOSE_CHOICES)
scheduled_at = models.DateTimeField()
scheduled_type = models.CharField(max_length=200, choices=ScheduledType,default='Call')
duration = models.DurationField(default=timedelta(minutes=5))
notes = models.TextField(blank=True, null=True)
status = models.CharField(max_length=200, choices=ScheduleStatusChoices, default='Scheduled')
created_at = models.DateTimeField(auto_now_add=True)
@ -1226,8 +1225,9 @@ class Schedule(models.Model):
def __str__(self):
return f"Scheduled {self.purpose} with {self.lead.full_name} on {self.scheduled_at}"
@property
def schedule_past_date(self):
if self.scheduled_at < timezone.now():
if self.scheduled_at < now():
return True
return False

View File

@ -694,7 +694,8 @@ def update_item_model_cost(sender, instance, created, **kwargs):
product = entity.get_items_all().filter(name=instance.car.vin).first()
product.default_amount = instance.selling_price
product.additional_info = {}
if not isinstance(product.additional_info, dict):
product.additional_info = {}
product.additional_info.update({"car_finance":instance.to_dict()})
product.additional_info.update({"additional_services": [service.to_dict() for service in instance.additional_services.all()]})
product.save()

View File

@ -319,10 +319,10 @@ def number_to_words_arabic(number):
return ' '.join(words)
@register.filter(name='num2words')
def num2words(number, language='en'):
"""Template filter to convert a number to words in the specified language."""
if language == 'ar':
return number_to_words_arabic(number)
else:
return number_to_words_english(number)
# @register.filter(name='num2words')
# def num2words(number, language='en'):
# """Template filter to convert a number to words in the specified language."""
# if language == 'ar':
# return number_to_words_arabic(number)
# else:
# return number_to_words_english(number)

View File

@ -88,7 +88,7 @@ urlpatterns = [
path(
"crm/leads/<int:pk>/view/", views.LeadDetailView.as_view(), name="lead_detail"
),
path("crm/leads/create/", views.LeadCreateView.as_view(), name="lead_create"),
path("crm/leads/create/", views.lead_create, name="lead_create"),
path(
"crm/leads/<int:pk>/update/", views.LeadUpdateView.as_view(), name="lead_update"
),
@ -196,7 +196,6 @@ urlpatterns = [
),
path("cars/add/", views.CarCreateView.as_view(), name="car_add"),
path("ajax/", views.AjaxHandlerView.as_view(), name="ajax_handler"),
path("cars/get-car-models/", views.get_car_models, name="get_car_models"),
path(
"cars/<int:car_pk>/add-color/", views.CarColorCreate.as_view(), name="add_color"
),

View File

@ -1,3 +1,6 @@
from django.db.models import Func
from appointment.models import Appointment,AppointmentRequest,Service,StaffMember
from datetime import timedelta
from calendar import month_name
from random import randint
from rich import print
@ -115,6 +118,11 @@ logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
class Hash(Func):
function = 'get_hash'
def switch_language(request):
language = request.GET.get("language", "en")
referer = request.META.get("HTTP_REFERER", "/")
@ -2339,12 +2347,13 @@ def create_estimate(request):
items = data.get("item", [])
quantities = data.get("quantity", [])
if not all([items, quantities]):
return JsonResponse(
{"status": "error", "message": "Items and Quantities are required"},
status=400,
)
)
if isinstance(quantities, list):
if "0" in quantities:
return JsonResponse(
@ -2355,7 +2364,17 @@ def create_estimate(request):
return JsonResponse(
{"status": "error", "message": "Quantity must be greater than zero"}
)
if isinstance(items, list):
for item, quantity in zip(items, quantities):
if int(quantity) > models.Car.objects.filter(hash=item).count():
return JsonResponse(
{"status": "error", "message": "Quantity must be less than or equal to the number of cars in stock"},
)
else:
if int(quantities) > models.Car.objects.filter(hash=item).count():
return JsonResponse(
{"status": "error", "message": "Quantity must be less than or equal to the number of cars in stock"},
)
estimate = entity.create_estimate(
estimate_title=title, customer_model=customer, contract_terms=terms
)
@ -2375,18 +2394,20 @@ def create_estimate(request):
]
items_txs = []
for item in items_list:
item_instance = ItemModel.objects.get(pk=item.get("item_id"))
car_instance = models.Car.objects.get(vin=item_instance.name)
items_txs.append(
{
"item_number": item_instance.item_number,
"quantity": Decimal(item.get("quantity")),
"unit_cost": car_instance.finances.selling_price,
"unit_revenue": car_instance.finances.selling_price,
"total_amount": (car_instance.finances.total_vat)
* int(item.get("quantity")),
}
)
# item_instance = ItemModel.objects.get(pk=item.get("item_id"))
car_instance = ItemModel.objects.filter(additional_info__car_info__hash=item.get("item_id")).all()
# car_instance = models.Car.objects.get(vin=item_instance.name)
for i in car_instance[:int(quantities[0])]:
items_txs.append(
{
"item_number": i.item_number,
"quantity": 1,
"unit_cost": i.additional_info.get('car_finance').get("selling_price"),
"unit_revenue": i.additional_info.get('car_finance').get("selling_price"),
"total_amount": (i.additional_info.get('car_finance').get("total_vat"))
}
)
estimate_itemtxs = {
item.get("item_number"): {
@ -2416,14 +2437,18 @@ def create_estimate(request):
)
if isinstance(items, list):
for item in items:
item_instance = ItemModel.objects.get(pk=item)
instance = models.Car.objects.get(vin=item_instance.name)
for item in estimate_itemtxs.keys():
item_instance = ItemModel.objects.get(item_number=item)
instance = models.Car.objects.get(name=item_instance.name)
reserve_car(instance, request)
# for item in items:
# item_instance = ItemModel.objects.filter(additioinal_info__car_info__hash=item).first()
# instance = models.Car.objects.get(hash=item)
# reserve_car(instance, request)
else:
item_instance = ItemModel.objects.get(pk=items)
instance = models.Car.objects.get(vin=item_instance.name)
item_instance = ItemModel.objects.get(additioinal_info__car_info__hash=items)
instance = models.Car.objects.get(hash=item)
response = reserve_car(instance, request)
url = reverse("estimate_detail", kwargs={"pk": estimate.pk})
@ -2439,22 +2464,21 @@ def create_estimate(request):
entity_slug=entity.slug, user_model=entity.admin
)
form.fields["customer"].queryset = entity.get_customers().filter(active=True)
car_list = models.Car.objects.filter(
dealer=dealer, finances__selling_price__gt=0
).exclude(status="reserved")
car_list = models.Car.objects.filter(dealer=dealer).exclude(status="reserved").values_list(
'id_car_make__name', 'id_car_model__name','hash').distinct()
context = {
"form": form,
"items": [
{
"car": x,
"product": entity.get_items_all()
.filter(item_role=ItemModel.ITEM_ROLE_PRODUCT, name=x.vin)
.first(),
'make':x[0],
'model':x[1],
'hash': x[2]
}
for x in car_list
],
}
return render(request, "sales/estimates/estimate_form.html", context)
@ -2940,28 +2964,25 @@ class LeadDetailView(DetailView):
return context
class LeadCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin):
model = models.Lead
form_class = forms.LeadForm
template_name = "crm/leads/lead_form.html"
success_message = "Lead created successfully!"
success_url = reverse_lazy("lead_list")
def form_valid(self, form):
dealer = get_user_type(self.request)
form.instance.dealer = dealer
return super().form_valid(form)
def get_car_models(request):
make_id = request.GET.get("id_car_make")
if make_id:
car_models = models.CarModel.objects.filter(id_car_make=make_id).values(
"id_car_model", "name", "arabic_name"
)
return JsonResponse(list(car_models), safe=False)
return JsonResponse([], safe=False)
def lead_create(request):
form = forms.LeadForm()
make = request.GET.get("id_car_make",None)
if make:
form.fields['id_car_model'].queryset = models.CarModel.objects.filter(id_car_make=int(make))
if request.method == "POST":
form = forms.LeadForm(request.POST)
form.fields['id_car_model'].queryset = models.CarModel.objects.filter(id_car_make=int(request.POST['id_car_make']))
if form.is_valid():
instance = form.save(commit=False)
dealer = get_user_type(request)
instance = form.save(commit=False)
instance.dealer = dealer
instance.save()
messages.success(request, "Lead created successfully!")
return redirect("lead_list")
return render(request, "crm/leads/lead_form.html", {"form": form})
class LeadUpdateView(UpdateView):
model = models.Lead
@ -2969,6 +2990,10 @@ class LeadUpdateView(UpdateView):
template_name = "crm/leads/lead_form.html"
success_url = reverse_lazy("lead_list")
def get_form(self, form_class=None):
form = super().get_form(form_class)
form.fields["id_car_model"].queryset = form.instance.id_car_make.carmodel_set.all()
return form
def LeadDeleteView(request,pk):
lead = get_object_or_404(models.Lead, pk=pk)
@ -3030,12 +3055,14 @@ def lead_convert(request, pk):
if lead.is_converted:
messages.error(request, "Lead is already converted to customer.")
return redirect("opportunity_create",pk=lead.pk)
if not models.Car.objects.filter(id_car_make=lead.id_car_make,id_car_model=lead.id_car_model).first():
messages.error(request, "Cannot convert lead to customer. Car model not found.")
return redirect("lead_list")
lead.convert_to_customer(dealer.entity)
messages.success(request, "Lead converted to customer successfully!")
return redirect("opportunity_create",pk=lead.pk)
@login_required
def schedule_lead(request, pk):
lead = get_object_or_404(models.Lead, pk=pk)
@ -3046,8 +3073,33 @@ def schedule_lead(request, pk):
instance.lead = lead
if hasattr(request.user, "staff"):
instance.scheduled_by = request.user.staff
# Save the Schedule instance
instance.save()
messages.success(request, "Lead scheduled successfully!")
# Create AppointmentRequest
service = Service.objects.filter(name=instance.scheduled_type).first()
if not service:
messages.error(request, "Service not found!")
return redirect("lead_list")
appointment_request = AppointmentRequest.objects.create(
date=instance.scheduled_at.date(),
start_time=instance.scheduled_at.time(),
end_time=(instance.scheduled_at + instance.duration).time(),
service=service,
staff_member=StaffMember.objects.first()
)
# Create Appointment
Appointment.objects.create(
client=request.user, # Replace with the appropriate client
appointment_request=appointment_request,
phone="123-456-7890", # Replace with actual phone number
address="123 Main St", # Replace with actual address
)
messages.success(request, "Lead scheduled and appointment created successfully!")
return redirect("lead_list")
else:
messages.error(request, f"Invalid form data: {str(form.errors)}")
@ -3130,9 +3182,9 @@ class OpportunityCreateView(CreateView):
def get_initial(self):
initial = super().get_initial()
if self.kwargs.get('pk',None):
lead = models.Lead.objects.get(pk=self.kwargs.get('pk'))
lead = models.Lead.objects.get(pk=self.kwargs.get('pk'))
initial['customer'] = lead.customer
initial['car'] = lead.car
return initial
def form_valid(self, form):

View File

@ -1,52 +1,96 @@
from django_ledger.models.invoice import InvoiceModel
from django_ledger.utils import accruable_net_summary
from decimal import Decimal
from django_ledger.models import EstimateModel,EntityModel
from django_ledger.models import EstimateModel,EntityModel,ItemModel
from rich import print
from datetime import date
from inventory.models import VatRate
from inventory.models import Car, Dealer, VatRate,Lead,CarMake,CarModel,Schedule
from inventory.utils import CarFinanceCalculator
from appointment.models import Appointment,AppointmentRequest,Service,StaffMember
from django.contrib.auth import get_user_model
from django_ledger.io.io_core import get_localdate
from datetime import datetime, timedelta
from django.utils import timezone
import hashlib
User = get_user_model()
def run():
# estimate = EstimateModel.objects.first()
# calculator = CarFinanceCalculator(estimate)
# finance_data = calculator.get_finance_data()
def run():
# print(Service.objects.first().pk)
# print(Appointment.objects.first().client)
# print(finance_data)
# entity = EntityModel.objects.get(name="ismail")
# bs_report = entity.get_balance_sheet_statement(
# to_date=date(2025, 1, 1),
# save_pdf=False,
# filepath='./'
# )
# ic_report = entity.get_income_statement(
# from_date=date(2022, 1, 1),
# to_date=date(2022, 12, 31),
# save_pdf=False,
# filepath='./'
# appointment = Appointment.objects.create(
# client_name="John Doe",
# client_email="john@example.com",
# service="Haircut",
# date_time="2023-10-15 10:00:00",
# status="pending")
# make = CarMake.objects.first()
# Lead.objects.create(
# first_name="John",
# last_name="Doe",
# email="john@example.com",
# phone_number="123-456-7890",
# address="123 Main St",
# id_car_make=make,
# id_car_model=make.carmodel_set.first(),
# year="2022",
# source="website",
# channel="online",
# staff="John Doe",
# priority="high",
# )
# # print(bs_report)
# print(ic_report.get_report_data())
# estimate = EstimateModel.objects.first()
# calculator = CarFinanceCalculator(estimate)
# finance_data = calculator.get_finance_data()
# schedult = Schedule.objects.create(
# name="John Doe",
# email="john@example.com",
# phone_number="123-456-7890",
# address="123 Main St",
# id_car_make=make,
# id_car_model=make.carmodel_set.first(),
# year="2022",
# source="website",
# channel="online",
# staff="John Doe",
# priority="high",
# )
# now = timezone.now()
# end_time = now + timedelta(minutes=10)
# service = Service.objects.first()
# appointment_request = AppointmentRequest.objects.create(
# date=now.date(),
# start_time=now.time(),
# end_time=end_time.time(),
# service=service,
# staff_member=StaffMember.objects.first(),
# )
# invoice_itemtxs = {
# i.get("item_number"): {
# "unit_cost": i.get("total_price"),
# "quantity": i.get("quantity"),
# "total_amount": i.get("total_vat"),
# }
# for i in finance_data.get("cars")
# }
# invoice = InvoiceModel.objects.first()
entity = EntityModel.objects.filter(name="ismail").first()
invoice_qs = InvoiceModel.objects.for_entity(
entity_slug=entity.slug,
user_model=entity.admin,
).unpaid()
print(accruable_net_summary(invoice_qs))
# appointment = Appointment.objects.create(
# client=User.objects.first(),
# appointment_request=appointment_request,
# phone="123-456-7890",
# address="123 Main St",
# )
dealer = Dealer.objects.get(user__email="ismail.mosa.ibrahim@gmail.com")
entity = dealer.entity
car_list = Car.objects.filter(dealer=dealer).all()
# context = {
# "items": [
# {
# "car": x,
# "product": entity.get_items_all()
# .filter(item_role=ItemModel.ITEM_ROLE_PRODUCT, name=x.vin)
# .first(),
# }
# for x in car_list
# ],
# }
for i in car_list:
hash_object = hashlib.sha256()
hash_object.update(f"{i.id_car_make.name}{i.id_car_model.name}".encode('utf-8'))
print(hash_object.hexdigest() , i.id_car_make.name, i.id_car_model.name)

View File

@ -135,13 +135,14 @@
</div>
</td>
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="">{{ lead.car.id_car_make.get_local_name }} - {{ lead.car.id_car_model.get_local_name }} {{ lead.year }}</a></td>
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="">{{ lead.id_car_make.get_local_name }} - {{ lead.id_car_model.get_local_name }} {{ lead.year }}</a></td>
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="">{{ lead.email }}</a></td>
<td class="align-middle white-space-nowrap fw-semibold"><a class="text-body-highlight" href="tel:{{ lead.phone_number }}">{{ lead.phone_number }}</a></td>
<td class="align-middle white-space-nowrap fw-semibold">
{% if lead.get_latest_schedule %}
<a href="{% url 'appointment:get_user_appointments' %}">
{% if lead.get_latest_schedule.scheduled_type == "Call" %}
<span class="badge badge-phoenix badge-phoenix-primary text-primary fw-semibold"><span class="text-primary" data-feather="phone"></span>
<span class="badge badge-phoenix badge-phoenix-primary text-primary {% if lead.get_latest_schedule.schedule_past_date %}badge-phoenix-danger text-danger{% endif %} fw-semibold"><span class="text-primary {% if lead.get_latest_schedule.schedule_past_date %}text-danger{% endif %}" data-feather="phone"></span>
{{ lead.get_latest_schedule.scheduled_at }}</span>
{% elif lead.get_latest_schedule.scheduled_type == "Meeting" %}
<span class="badge badge-phoenix badge-phoenix-success text-success fw-semibold"><span class="text-success" data-feather="calendar"></span>
@ -150,6 +151,7 @@
<span class="badge badge-phoenix badge-phoenix-warning text-warning fw-semibold"><span class="text-warning" data-feather="email"></span>
{{ lead.get_latest_schedule.scheduled_at }}</span>
{% endif %}
</a>
{% endif %}
</td>
<td class="align-middle white-space-nowrap text-body-tertiary text-opacity-85 fw-semibold text-body-highlight">{{ lead.staff|upper }}</td>

View File

@ -18,7 +18,7 @@
<div class="mb-2 col-sm-2">
<select class="form-control item" name="item[]" required>
{% for item in items %}
<option value="{{ item.product.pk }}">{{ item.car.id_car_model }}</option>
<option value="{{ item.hash }}">{{ item.make }} {{item.model}}</option>
{% endfor %}
</select>
</div>