update in lead and schedule
This commit is contained in:
parent
90a84934d6
commit
f0f3712291
@ -1014,10 +1014,9 @@ class LeadForm(forms.ModelForm):
|
||||
|
||||
id_car_make = forms.ModelChoiceField(
|
||||
label=_("Make"),
|
||||
queryset=CarMake.objects.filter(is_sa_import=True),
|
||||
queryset=CarMake.objects.all(),
|
||||
widget=forms.Select(
|
||||
attrs={
|
||||
|
||||
"hx-get": "",
|
||||
"hx-include": "#id_id_car_make",
|
||||
"hx-select": "#div_id_id_car_model",
|
||||
@ -1059,13 +1058,15 @@ class LeadForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def filter_qs(self,**kwargs):
|
||||
dealer = kwargs['dealer']
|
||||
dealer_make_list = DealersMake.objects.filter(dealer=dealer).values_list("car_make",flat=True)
|
||||
if "id_car_make" in self.fields:
|
||||
queryset = self.fields["id_car_make"].queryset.filter(is_sa_import=True)
|
||||
queryset = self.fields["id_car_make"].queryset.filter(is_sa_import=True,pk__in=dealer_make_list)
|
||||
self.fields["id_car_make"].choices = [
|
||||
(obj.id_car_make, obj.get_local_name()) for obj in queryset
|
||||
]
|
||||
|
||||
|
||||
class ScheduleForm(forms.ModelForm):
|
||||
"""
|
||||
Represents a form for scheduling events, extending ModelForm to bind to the
|
||||
|
||||
@ -7,6 +7,6 @@ class Command(BaseCommand):
|
||||
|
||||
def handle(self, *args, **options):
|
||||
Service.objects.all().delete()
|
||||
Service.objects.create(name='Call', price=0,duration=datetime.timedelta(minutes=10),currency='SAR',description='15 min call')
|
||||
Service.objects.create(name='Meeting', price=0,duration=datetime.timedelta(minutes=30),currency='SAR',description='30 min meeting')
|
||||
Service.objects.create(name='Visit', price=0,duration=datetime.timedelta(minutes=30),currency='SAR',description='30 min visit')
|
||||
Service.objects.create(name='call', price=0,duration=datetime.timedelta(minutes=10),currency='SAR',description='15 min call')
|
||||
Service.objects.create(name='meeting', price=0,duration=datetime.timedelta(minutes=30),currency='SAR',description='30 min meeting')
|
||||
Service.objects.create(name='email', price=0,duration=datetime.timedelta(minutes=30),currency='SAR',description='30 min visit')
|
||||
@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.1.7 on 2025-05-07 14:32
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0010_organization_active'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='organization',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='organization_leads', to='inventory.organization'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='lead',
|
||||
name='customer',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='customer_leads', to='inventory.customer'),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.1.7 on 2025-05-08 10:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0011_lead_organization_alter_lead_customer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customer',
|
||||
name='dob',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='Date of Birth'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customer',
|
||||
name='national_id',
|
||||
field=models.CharField(blank=True, max_length=10, null=True, unique=True, verbose_name='National ID'),
|
||||
),
|
||||
]
|
||||
@ -173,7 +173,6 @@ class CarMake(models.Model, LocalizedNameMixin):
|
||||
class Meta:
|
||||
verbose_name = _("Make")
|
||||
|
||||
|
||||
class CarModel(models.Model, LocalizedNameMixin):
|
||||
id_car_model = models.AutoField(primary_key=True)
|
||||
id_car_make = models.ForeignKey(CarMake, models.DO_NOTHING, db_column="id_car_make")
|
||||
@ -927,9 +926,10 @@ class Staff(models.Model, LocalizedNameMixin):
|
||||
def add_group(self,group):
|
||||
try:
|
||||
self.user.groups.add(group)
|
||||
self.add_as_manager()
|
||||
if self.staff_type in ["accountant","manager"]:
|
||||
self.add_as_manager()
|
||||
except Exception as e:
|
||||
pass
|
||||
print(e)
|
||||
def add_as_manager(self):
|
||||
if self.staff_type in ["accountant","manager"]:
|
||||
EntityManagementModel.objects.get_or_create(
|
||||
@ -1049,10 +1049,10 @@ class Customer(models.Model):
|
||||
max_length=1,
|
||||
verbose_name=_("Gender"),
|
||||
)
|
||||
dob = models.DateField(verbose_name=_("Date of Birth"))
|
||||
dob = models.DateField(verbose_name=_("Date of Birth"), null=True, blank=True)
|
||||
email = models.EmailField(unique=True, verbose_name=_("Email"))
|
||||
national_id = models.CharField(
|
||||
max_length=10, unique=True, verbose_name=_("National ID")
|
||||
max_length=10, unique=True, verbose_name=_("National ID"), null=True,blank=True
|
||||
)
|
||||
phone_number = PhoneNumberField(
|
||||
region="SA", unique=True, verbose_name=_("Phone Number")
|
||||
@ -1095,6 +1095,8 @@ class Customer(models.Model):
|
||||
except Exception:
|
||||
pass
|
||||
customer.save()
|
||||
self.customer_model = customer
|
||||
self.save()
|
||||
return customer
|
||||
|
||||
def update_user_model(self):
|
||||
@ -1127,6 +1129,8 @@ class Customer(models.Model):
|
||||
)
|
||||
user.set_password("Tenhal@123")
|
||||
user.save()
|
||||
self.user = user
|
||||
self.save()
|
||||
return user
|
||||
def deactivate_account(self):
|
||||
self.active = False
|
||||
@ -1184,6 +1188,8 @@ class Organization(models.Model, LocalizedNameMixin):
|
||||
except Exception:
|
||||
pass
|
||||
customer.save()
|
||||
self.customer_model = customer
|
||||
self.save()
|
||||
return customer
|
||||
|
||||
def update_user_model(self):
|
||||
@ -1214,6 +1220,8 @@ class Organization(models.Model, LocalizedNameMixin):
|
||||
)
|
||||
user.set_password("Tenhal@123")
|
||||
user.save()
|
||||
self.user = user
|
||||
self.save()
|
||||
return user
|
||||
|
||||
def deactivate_account(self):
|
||||
@ -1258,12 +1266,13 @@ class Lead(models.Model):
|
||||
max_length=50, choices=[("customer", _("Customer")), ("organization", _("Organization"))], verbose_name=_("Lead Type")
|
||||
,default="customer")
|
||||
customer = models.ForeignKey(
|
||||
CustomerModel, on_delete=models.CASCADE, related_name="leads",
|
||||
Customer, on_delete=models.CASCADE, related_name="customer_leads",
|
||||
null=True,blank=True
|
||||
)
|
||||
organization = models.ForeignKey(
|
||||
Organization, on_delete=models.CASCADE, related_name="organization_leads",
|
||||
null=True,blank=True
|
||||
)
|
||||
# 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,
|
||||
@ -1347,30 +1356,16 @@ class Lead(models.Model):
|
||||
@property
|
||||
def full_name(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
def convert_to_customer(self,entity,lead):
|
||||
customer = entity.get_customers().filter(email=self.email).first()
|
||||
if entity and not customer:
|
||||
customer = entity.create_customer(
|
||||
commit=False,
|
||||
customer_model_kwargs={
|
||||
"customer_name": self.full_name,
|
||||
"address_1": self.address,
|
||||
"phone": self.phone_number,
|
||||
"email": self.email,
|
||||
}
|
||||
)
|
||||
|
||||
customer.additional_info.update({"info":self.to_dict()})
|
||||
if lead.lead_type == "organization":
|
||||
customer.additional_info.update({"type":"organization"})
|
||||
else:
|
||||
customer.additional_info.update({"type":"customer"})
|
||||
customer.save()
|
||||
self.customer = customer
|
||||
def convert_to_customer(self):
|
||||
self.status = Status.QUALIFIED
|
||||
self.save()
|
||||
return customer
|
||||
return self.get_customer_model()
|
||||
|
||||
def get_customer_model(self):
|
||||
if self.customer:
|
||||
return self.customer.customer_model
|
||||
if self.organization:
|
||||
return self.organization.customer_model
|
||||
def get_latest_schedule(self):
|
||||
return self.schedules.order_by('-scheduled_at').first()
|
||||
def get_latest_schedules(self):
|
||||
@ -1378,15 +1373,15 @@ class Lead(models.Model):
|
||||
def get_all_schedules(self):
|
||||
return self.schedules.all().order_by('-scheduled_at')
|
||||
def get_calls(self):
|
||||
return self.get_all_schedules().filter(scheduled_type='Call')
|
||||
return self.get_all_schedules().filter(scheduled_type='call')
|
||||
def get_meetings(self):
|
||||
return self.get_all_schedules().filter(scheduled_type='Meeting')
|
||||
return self.get_all_schedules().filter(scheduled_type='meeting')
|
||||
def get_emails(self):
|
||||
return Email.objects.filter(content_type__model="lead", object_id=self.id)
|
||||
return Email.objects.filter(content_type__model="lead", object_id=self.pk)
|
||||
def get_notes(self):
|
||||
return Notes.objects.filter(content_type__model="lead", object_id=self.id)
|
||||
return Notes.objects.filter(content_type__model="lead", object_id=self.pk)
|
||||
def get_activities(self):
|
||||
return Activity.objects.filter(content_type__model="lead", object_id=self.id)
|
||||
return Activity.objects.filter(content_type__model="lead", object_id=self.pk)
|
||||
|
||||
class Schedule(models.Model):
|
||||
PURPOSE_CHOICES = [
|
||||
|
||||
@ -150,7 +150,7 @@ from plans.quota import get_user_quota
|
||||
from django_tables2 import SingleTableView
|
||||
from django_tables2.export.views import ExportMixin
|
||||
from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
||||
|
||||
from django.db.models.functions import Lower
|
||||
from .models import SaleOrder
|
||||
from .services import (
|
||||
decodevin,
|
||||
@ -2494,6 +2494,7 @@ def UserGroupView(request, pk):
|
||||
if request.method == "POST":
|
||||
form = forms.UserGroupForm(request.POST)
|
||||
groups = request.POST.getlist("name")
|
||||
|
||||
staff.clear_groups()
|
||||
for i in groups:
|
||||
cg = models.CustomGroup.objects.get(id=int(i))
|
||||
@ -4601,13 +4602,7 @@ def lead_create(request):
|
||||
:return: An HTTP response object rendering the lead creation form or redirecting to the lead list page upon success.
|
||||
:rtype: HttpResponse
|
||||
"""
|
||||
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)
|
||||
)
|
||||
dealer = get_user_type(request)
|
||||
|
||||
if request.method == "POST":
|
||||
form = forms.LeadForm(request.POST)
|
||||
@ -4620,51 +4615,57 @@ def lead_create(request):
|
||||
try:
|
||||
if form.is_valid():
|
||||
instance = form.save(commit=False)
|
||||
dealer = get_user_type(request)
|
||||
instance.dealer = dealer
|
||||
instance.staff = form.cleaned_data.get("staff")
|
||||
|
||||
# creating customer in ledger
|
||||
customer = (
|
||||
dealer.entity.get_customers().filter(email=instance.email).first()
|
||||
)
|
||||
if not customer:
|
||||
customer = dealer.entity.create_customer(
|
||||
commit=False,
|
||||
customer_model_kwargs={
|
||||
"customer_name": instance.full_name,
|
||||
"address_1": instance.address,
|
||||
"phone": instance.phone_number,
|
||||
"email": instance.email,
|
||||
"sales_tax_rate": 0.15,
|
||||
},
|
||||
)
|
||||
customer_info = {
|
||||
"first_name": instance.first_name,
|
||||
"last_name": instance.last_name,
|
||||
"address": instance.address,
|
||||
"phone_number": str(instance.phone_number),
|
||||
"email": instance.email,
|
||||
"crn": form.cleaned_data["crn"],
|
||||
"vrn": form.cleaned_data["vrn"],
|
||||
}
|
||||
customer.additional_info.update({"customer_info": customer_info})
|
||||
customer.additional_info.update({"type": "lead"})
|
||||
customer.save()
|
||||
instance.customer = customer
|
||||
# try:
|
||||
# user = User.objects.get(email=customer.email)
|
||||
# user.first_name = instance.first_name
|
||||
# user.last_name = instance.last_name
|
||||
# user.save()
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
if instance.lead_type == "customer":
|
||||
customer = models.Customer.objects.filter(email=instance.email)
|
||||
if not customer:
|
||||
customer = models.Customer(
|
||||
dealer=dealer,
|
||||
address=instance.address,
|
||||
phone_number=instance.phone_number,
|
||||
email=instance.email,
|
||||
first_name=instance.first_name,
|
||||
last_name=instance.last_name,
|
||||
)
|
||||
customer.create_user_model()
|
||||
customer.create_customer_model()
|
||||
customer.save()
|
||||
instance.customer = customer
|
||||
|
||||
|
||||
if instance.lead_type == "organization":
|
||||
organization = models.Organization.objects.filter(email=instance.email)
|
||||
if not organization:
|
||||
organization = models.Organization(
|
||||
dealer=dealer,
|
||||
address=instance.address,
|
||||
phone_number=instance.phone_number,
|
||||
email=instance.email,
|
||||
name=instance.first_name + " " + instance.last_name,
|
||||
)
|
||||
organization.create_user_model()
|
||||
organization.create_customer_model()
|
||||
organization.save()
|
||||
instance.organization = organization
|
||||
|
||||
instance.save()
|
||||
messages.success(request, _("Lead created successfully"))
|
||||
return redirect("lead_list")
|
||||
else:
|
||||
messages.error(request, f"Lead was not created ... : {str(form.errors)}")
|
||||
except Exception as e:
|
||||
messages.error(request, f"Lead was not created ... : {str(e)}")
|
||||
|
||||
form = forms.LeadForm()
|
||||
form.filter_qs(dealer=dealer)
|
||||
|
||||
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)
|
||||
)
|
||||
return render(request, "crm/leads/lead_form.html", {"form": form})
|
||||
|
||||
|
||||
@ -4870,7 +4871,7 @@ def lead_convert(request, pk):
|
||||
if hasattr(lead, "opportunity"):
|
||||
messages.error(request, _("Lead is already converted to customer"))
|
||||
else:
|
||||
customer = lead.convert_to_customer(dealer.entity,lead)
|
||||
customer = lead.convert_to_customer()
|
||||
models.Opportunity.objects.create(dealer=dealer,customer=customer,lead=lead,probability=50,stage=models.Stage.PROSPECT,staff=lead.staff,status=models.Status.QUALIFIED)
|
||||
messages.success(request, _("Lead converted to customer successfully"))
|
||||
return redirect("lead_list")
|
||||
@ -4896,6 +4897,7 @@ def schedule_lead(request, pk):
|
||||
method and validity of the form submission.
|
||||
:rtype: HttpResponse
|
||||
"""
|
||||
|
||||
if not request.is_staff:
|
||||
messages.error(request, _("You do not have permission to schedule lead"))
|
||||
return redirect("lead_list")
|
||||
@ -4907,10 +4909,12 @@ def schedule_lead(request, pk):
|
||||
instance = form.save(commit=False)
|
||||
instance.lead = lead
|
||||
instance.scheduled_by = request.user
|
||||
instance.customer = lead.customer
|
||||
|
||||
instance.customer = lead.get_customer_model()
|
||||
|
||||
# Create AppointmentRequest
|
||||
service,_ = Service.objects.get_or_create(name=instance.scheduled_type,duration=datetime.timedelta(minutes=10),price=0)
|
||||
# service,_ = Service.objects.get_or_create(name=instance.scheduled_type,duration=datetime.timedelta(minutes=10),price=0)
|
||||
service = Service.objects.get(name=instance.scheduled_type)
|
||||
# service = Service.objects.filter(name=instance.scheduled_type).first()
|
||||
# if not service:
|
||||
# messages.error(request, "Service not found!")
|
||||
@ -5008,7 +5012,7 @@ def send_lead_email(request, pk, email_pk=None):
|
||||
|
||||
lead.status = models.Status.CONTACTED
|
||||
lead.save()
|
||||
# lead.convert_to_customer(dealer.entity)
|
||||
|
||||
|
||||
if request.method == "POST":
|
||||
email_pk = request.POST.get("email_pk")
|
||||
|
||||
@ -153,15 +153,15 @@
|
||||
{% for schedule in lead.get_latest_schedules %}
|
||||
<tr class="schedule-{{ schedule.pk }}">
|
||||
<td class="align-middle white-space-nowrap">
|
||||
{% if schedule.scheduled_type == "Call" %}
|
||||
{% if schedule.scheduled_type == "call" %}
|
||||
<a href="{% url 'appointment:get_user_appointments' %}">
|
||||
<span class="badge badge-phoenix badge-phoenix-primary text-primary {% if schedule.schedule_past_date %}badge-phoenix-danger text-danger{% endif %} fw-semibold"><span class="text-primary {% if schedule.schedule_past_date %}text-danger{% endif %}" data-feather="phone"></span>
|
||||
{{ schedule.scheduled_at }}</span></a>
|
||||
{% elif schedule.scheduled_type == "Meeting" %}
|
||||
{% elif schedule.scheduled_type == "meeting" %}
|
||||
<a href="{% url 'appointment:get_user_appointments' %}">
|
||||
<span class="badge badge-phoenix badge-phoenix-success text-success fw-semibold"><span class="text-success" data-feather="calendar"></span>
|
||||
{{ schedule.scheduled_at }}</span></a>
|
||||
{% elif schedule.scheduled_type == "Email" %}
|
||||
{% elif schedule.scheduled_type == "email" %}
|
||||
<a href="{% url 'appointment:get_user_appointments' %}">
|
||||
<span class="badge badge-phoenix badge-phoenix-warning text-warning fw-semibold"><span class="text-warning" data-feather="email"></span>
|
||||
{{ schedule.scheduled_at }}</span></a>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user