diff --git a/inventory/forms.py b/inventory/forms.py index 1d849a31..6a6c0ff3 100644 --- a/inventory/forms.py +++ b/inventory/forms.py @@ -658,9 +658,7 @@ class LeadForm(forms.ModelForm): 'email', 'phone_number', 'address', - 'id_car_make', - 'id_car_model', - 'year', + 'car', 'source', 'channel', 'staff', diff --git a/inventory/models.py b/inventory/models.py index 08626367..82143e22 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -1096,23 +1096,26 @@ class Lead(models.Model): CustomerModel, on_delete=models.CASCADE, related_name="leads", null=True,blank=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 + 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 + # ) source = models.CharField( max_length=50, choices=Sources.choices, verbose_name=_("Source") ) @@ -1152,28 +1155,26 @@ class Lead(models.Model): def __str__(self): return f"{self.first_name} {self.last_name}" - + @property def is_converted(self): return bool(self.customer) - + def to_dict(self): - return { + return { "first_name": str(self.first_name), - "last_name": str(self.last_name), + "last_name": str(self.last_name), "email": str(self.email), "address": str(self.address), "phone_number": str(self.phone_number), - "id_car_make": str(self.id_car_make.name), - "id_car_model": str(self.id_car_model.name), - "year": str(self.year), + "car": self.car.to_dict(), "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 CustomerModel.objects.filter(email=self.email).exists(): + if entity and not entity.get_customers().filter(email=self.email).exists(): customer = entity.create_customer( customer_model_kwargs={ "customer_name": self.full_name, @@ -1184,10 +1185,10 @@ class Lead(models.Model): ) customer.additional_info = {} customer.additional_info.update({"info":self.to_dict()}) + self.customer = customer customer.save() - self.customer = customer self.save() - + def get_latest_schedule(self): return self.schedules.order_by('-scheduled_at').first() @@ -1205,27 +1206,33 @@ class Schedule(models.Model): ('Meeting', 'Meeting'), ('Email', 'Email'), ] + ScheduleStatusChoices = [ + ('Scheduled', 'Scheduled'), + ('Completed', 'Completed'), + ('Canceled', 'Canceled'), + ] lead = models.ForeignKey(Lead, on_delete=models.CASCADE, related_name='schedules') - customer = models.ForeignKey(CustomerModel, on_delete=models.CASCADE, related_name='schedules') + customer = models.ForeignKey(CustomerModel, on_delete=models.CASCADE, related_name='schedules',null=True,blank=True) scheduled_by = models.ForeignKey(Staff, on_delete=models.CASCADE) purpose = models.CharField(max_length=200, choices=PURPOSE_CHOICES) scheduled_at = models.DateTimeField() scheduled_type = models.CharField(max_length=200, choices=ScheduledType,default='Call') 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) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"Scheduled {self.purpose} with {self.customer.customer_name} on {self.scheduled_at}" - + def schedule_past_date(self): if self.scheduled_at < timezone.now(): return True return False - + class Meta: ordering = ['-scheduled_at'] - + class LeadStatusHistory(models.Model): lead = models.ForeignKey( @@ -1260,7 +1267,7 @@ class Opportunity(models.Model): Dealer, on_delete=models.CASCADE, related_name="opportunities" ) customer = models.ForeignKey( - Customer, on_delete=models.CASCADE, related_name="opportunities" + CustomerModel, on_delete=models.CASCADE, related_name="opportunities" ) car = models.ForeignKey( Car, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_("Car") diff --git a/inventory/urls.py b/inventory/urls.py index 7b69370d..ca4c7280 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -116,6 +116,11 @@ urlpatterns = [ views.OpportunityCreateView.as_view(), name="opportunity_create", ), + path( + "crm/opportunities//create/", + views.OpportunityCreateView.as_view(), + name="opportunity_create", + ), path( "crm/opportunities//", views.OpportunityDetailView.as_view(), diff --git a/inventory/views.py b/inventory/views.py index db387c04..0015b501 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -2999,9 +2999,13 @@ def add_note_to_lead(request, pk): def lead_convert(request, pk): lead = get_object_or_404(models.Lead, pk=pk) dealer = get_user_type(request) + if lead.is_converted: + messages.error(request, "Lead is already converted to customer.") + return redirect("opportunity_create",pk=lead.pk) + lead.convert_to_customer(dealer.entity) messages.success(request, "Lead converted to customer successfully!") - return redirect("lead_list") + return redirect("opportunity_create",pk=lead.pk) def schedule_lead(request, pk): lead = get_object_or_404(models.Lead, pk=pk) @@ -3010,7 +3014,6 @@ def schedule_lead(request, pk): if form.is_valid(): instance = form.save(commit=False) instance.lead = lead - instance.customer = lead.customer if hasattr(request.user, "staff"): instance.scheduled_by = request.user.staff instance.save() @@ -3019,24 +3022,24 @@ def schedule_lead(request, pk): else: messages.error(request, f"Invalid form data: {str(form.errors)}") return redirect("lead_list") - - form = forms.ScheduleForm() + + form = forms.ScheduleForm() return render(request, "crm/leads/schedule_lead.html", {"lead": lead, "form": form}) def send_lead_email(request, pk): lead = get_object_or_404(models.Lead, pk=pk) dealer = get_user_type(request) lead.convert_to_customer(dealer.entity) - + if request.method == "POST": send_email( "manager@tenhal.com", request.POST.get("to"), request.POST.get("subject"), request.POST.get("message"), - ) + ) messages.success(request, "Email sent successfully!") - return redirect("lead_list") + return redirect("lead_list") msg = f""" السلام عليكم Dear {lead.full_name}, @@ -3088,10 +3091,16 @@ class OpportunityCreateView(CreateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) dealer = get_user_type(self.request) - context["customer"] = models.Customer.objects.filter(dealer=dealer) - context["cars"] = models.Car.objects.filter(dealer=dealer) return context + def get_initial(self): + initial = super().get_initial() + if self.kwargs.get('pk',None): + 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): dealer = get_user_type(self.request) form.instance.dealer = dealer