From 8111dd63784887ea37b351fa2644359a34b9493d Mon Sep 17 00:00:00 2001 From: ismail Date: Wed, 25 Jun 2025 17:06:38 +0300 Subject: [PATCH] add crm dealer slug --- inventory/urls.py | 85 +++++----- inventory/views.py | 152 ++++++++++-------- templates/components/activity_modal.html | 2 +- templates/components/task_modal.html | 2 +- templates/crm/leads/lead_detail.html | 20 +-- templates/crm/leads/lead_list.html | 16 +- templates/crm/leads/lead_send.html | 4 +- templates/crm/leads/schedule_lead.html | 2 +- .../opportunity_confirm_delete.html | 2 +- .../crm/opportunities/opportunity_detail.html | 14 +- .../crm/opportunities/opportunity_form.html | 2 +- .../crm/opportunities/opportunity_list.html | 8 +- .../partials/opportunity_grid.html | 4 +- templates/customers/customer_list.html | 8 +- templates/customers/note_form.html | 2 +- templates/customers/view_customer.html | 12 +- templates/dashboards/manager.html | 4 +- templates/header.html | 10 +- .../organizations/organization_list.html | 8 +- templates/partials/task.html | 2 +- 20 files changed, 188 insertions(+), 171 deletions(-) diff --git a/inventory/urls.py b/inventory/urls.py index 5b6f9adb..75cf7332 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -86,146 +86,149 @@ urlpatterns = [ # path('dealers//delete/', views.DealerDeleteView.as_view(), name='dealer_delete'), # CRM URLs path( - "customers/create/", views.CustomerCreateView.as_view(), name="customer_create" + "/customers/create/", views.CustomerCreateView.as_view(), name="customer_create" ), - path("customers/", views.CustomerListView.as_view(), name="customer_list"), + path("/customers/", views.CustomerListView.as_view(), name="customer_list"), path( - "customers//", + "/customers//", views.CustomerDetailView.as_view(), name="customer_detail", ), path( - "customers//add-note/", + "/customers//add-note/", views.add_note_to_customer, name="add_note_to_customer", ), path( - "customers//update/", + "/customers//update/", views.CustomerUpdateView.as_view(), name="customer_update", ), path( - "customers//delete/", views.delete_customer, name="customer_delete" + "/customers//delete/", views.delete_customer, name="customer_delete" ), path( - "customers//opportunities/create/", + "/customers//opportunities/create/", views.OpportunityCreateView.as_view(), name="create_opportunity", ), - path("crm/leads/create/", views.lead_create, name="lead_create"), + ######################################## + #####Lead + ######################################## + path("/crm/leads/create/", views.lead_create, name="lead_create"), path( - "crm/leads//view/", + "/crm/leads//view/", views.LeadDetailView.as_view(), name="lead_detail", ), - path("update-lead-actions/", views.update_lead_actions, name="update_lead_actions"), - path("crm/leads/lead_tracking/", views.lead_tracking, name="lead_tracking"), - path("crm/leads/lead_view/", views.lead_view, name="lead_view"), - path("crm/leads/", views.LeadListView.as_view(), name="lead_list"), + path("/update-lead-actions/", views.update_lead_actions, name="update_lead_actions"), + path("/crm/leads/lead_tracking/", views.lead_tracking, name="lead_tracking"), + path("/crm/leads/lead_view/", views.lead_view, name="lead_view"), + path("/crm/leads/", views.LeadListView.as_view(), name="lead_list"), path( - "crm/leads//update/", + "/crm/leads//update/", views.LeadUpdateView.as_view(), name="lead_update", ), - path("crm/leads//delete/", views.LeadDeleteView, name="lead_delete"), + path("/crm/leads//delete/", views.LeadDeleteView, name="lead_delete"), path( - "crm/leads//lead-convert/", views.lead_convert, name="lead_convert" + "/crm/leads//lead-convert/", views.lead_convert, name="lead_convert" ), path( - "crm/leads//delete-note/", views.delete_note, name="delete_note_to_lead" + "/crm/leads//delete-note/", views.delete_note, name="delete_note_to_lead" ), path( - "crm//update-note/", + "/crm//update-note/", views.update_note, name="update_note", ), path( - "crm///add-note/", + "/crm///add-note/", views.add_note, name="add_note", ), path( - "crm//update-task/", + "/crm//update-task/", views.update_task, name="update_task", ), path( - "crm///add-task/", + "/crm///add-task/", views.add_task, name="add_task", ), path( - "crm///add-activity/", + "/crm///add-activity/", views.add_activity, name="add_activity", ), path( - "crm/leads//send_lead_email/", + "/crm/leads//send_lead_email/", views.send_lead_email, name="send_lead_email", ), path( - "crm/leads//send_lead_email/", + "/crm/leads//send_lead_email/", views.send_lead_email, name="send_lead_email_with_template", ), path( - "crm/leads//schedule/", + "/crm/leads//schedule/", views.schedule_lead, name="schedule_lead", ), path( - "crm/leads/schedule//cancel/", + "/crm/leads/schedule//cancel/", views.schedule_cancel, name="schedule_cancel", ), path( - "crm/leads//transfer/", + "/crm/leads//transfer/", views.lead_transfer, name="lead_transfer", ), path( - "crm/opportunities//add_note/", + "/crm/opportunities//add_note/", views.add_note_to_opportunity, name="add_note_to_opportunity", ), path( - "crm/opportunities/create/", + "/crm/opportunities/create/", views.OpportunityCreateView.as_view(), name="opportunity_create", ), path( - "crm/opportunities//create/", + "/crm/opportunities//create/", views.OpportunityCreateView.as_view(), name="lead_opportunity_create", ), path( - "crm/opportunities//create/", + "/crm/opportunities//create/", views.OpportunityCreateView.as_view(), name="opportunity_create", ), path( - "crm/opportunities//", + "/crm/opportunities//", views.OpportunityDetailView.as_view(), name="opportunity_detail", ), path( - "crm/opportunities//edit/", + "/crm/opportunities//edit/", views.OpportunityUpdateView.as_view(), name="update_opportunity", ), path( - "crm/opportunities/", + "/crm/opportunities/", views.OpportunityListView.as_view(), name="opportunity_list", ), path( - "crm/opportunities//delete/", + "/crm/opportunities//delete/", views.delete_opportunity, name="delete_opportunity", ), path( - "crm/opportunities//opportunity_update_status/", + "/crm/opportunities//opportunity_update_status/", views.opportunity_update_status, name="opportunity_update_status", ), @@ -495,25 +498,25 @@ urlpatterns = [ ), # Organization URLs path( - "organizations/create/", + "/organizations/create/", views.OrganizationCreateView.as_view(), name="organization_create", ), path( - "organizations/", views.OrganizationListView.as_view(), name="organization_list" + "/organizations/", views.OrganizationListView.as_view(), name="organization_list" ), path( - "organizations//", + "/organizations//", views.OrganizationDetailView.as_view(), name="organization_detail", ), path( - "organizations//update/", + "/organizations//update/", views.OrganizationUpdateView.as_view(), name="organization_update", ), path( - "organizations//delete/", + "/organizations//delete/", views.OrganizationDeleteView, name="organization_delete", ), diff --git a/inventory/views.py b/inventory/views.py index fe8643e4..6c0b3b16 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -2200,7 +2200,7 @@ class CustomerDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView @login_required -def add_note_to_customer(request, slug): +def add_note_to_customer(request,dealer_slug, slug): """ This function allows authenticated users to add a note to a specific customer. The note creation is handled by a form, which is validated after submission. If the form @@ -2217,6 +2217,7 @@ def add_note_to_customer(request, slug): POST request, it renders the note form template with context including the form and customer. """ + # get_object_or_404(models.Dealer, slug=dealer_slug) customer = get_object_or_404(models.Customer, slug=slug) if request.method == "POST": form = forms.NoteForm(request.POST) @@ -2226,9 +2227,9 @@ def add_note_to_customer(request, slug): note.created_by = request.user note.save() - return redirect("customer_detail", slug=customer.slug) - else: - form = forms.NoteForm() + return redirect("customer_detail", dealer_slug=dealer_slug,slug=customer.slug) + + form = forms.NoteForm() return render( request, "customers/note_form.html", {"form": form, "customer": customer} ) @@ -2324,6 +2325,8 @@ class CustomerCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView form.instance.customer_model = customer return super().form_valid(form) + def get_success_url(self): + return reverse_lazy("customer_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView): @@ -2361,10 +2364,11 @@ class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView form.instance.update_user_model() form.instance.update_customer_model() return super().form_valid(form) - + def get_success_url(self): + return reverse_lazy("customer_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) @login_required -def delete_customer(request, slug): +def delete_customer(request, dealer_slug ,slug): """ Deletes a customer from the system and deactivates the corresponding user account. @@ -2383,7 +2387,7 @@ def delete_customer(request, slug): customer = get_object_or_404(models.Customer, slug=slug) customer.deactivate_account() messages.success(request, _("Customer deactivated successfully")) - return redirect("customer_list") + return redirect("customer_list", dealer_slug=dealer_slug) class VendorListView(LoginRequiredMixin, ListView): @@ -3087,7 +3091,6 @@ class OrganizationDetailView(LoginRequiredMixin, DetailView): template_name = "organizations/organization_detail.html" context_object_name = "organization" - class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView): """ # Handles the creation of a new organization via a web form. This view allows the @@ -3136,6 +3139,9 @@ class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, Create return super().form_valid(form) + def get_success_url(self): + return reverse_lazy("organization_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) + class OrganizationUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView): """ @@ -3167,9 +3173,11 @@ class OrganizationUpdateView(LoginRequiredMixin, PermissionRequiredMixin, Update form.instance.update_customer_model() return super().form_valid(form) + def get_success_url(self): + return reverse_lazy("organization_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) @login_required -def OrganizationDeleteView(request, slug): +def OrganizationDeleteView(request,dealer_slug, slug): """ Handles the deletion of an organization based on the provided primary key (pk). Looks up the organization and its corresponding user by email, attempts to delete both, and provides @@ -3186,7 +3194,7 @@ def OrganizationDeleteView(request, slug): organization = get_object_or_404(models.Organization, slug=slug) organization.deactivate_account() messages.success(request, _("Organization Deactivated successfully")) - return redirect("organization_list") + return redirect(reverse_lazy("organization_list", kwargs={"dealer_slug": dealer_slug})) class RepresentativeListView(LoginRequiredMixin, ListView): @@ -5130,7 +5138,7 @@ class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView): @login_required @permission_required("inventory.add_lead", raise_exception=True) -def lead_create(request): +def lead_create(request,dealer_slug): """ Handles the creation of a new lead in the inventory system. @@ -5146,7 +5154,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 """ - dealer = get_user_type(request) + dealer = get_object_or_404(models.Dealer,slug=dealer_slug) if request.method == "POST": form = forms.LeadForm(request.POST) @@ -5201,7 +5209,7 @@ def lead_create(request): instance.next_action = LeadStatus.NEW instance.save() messages.success(request, _("Lead created successfully")) - return redirect("lead_list") + return redirect("lead_list", dealer_slug=dealer.slug) else: messages.error( request, f"Lead was not created ... : {str(form.errors)}" @@ -5234,7 +5242,7 @@ def lead_create(request): form.fields["staff"].queryset = form.fields["staff"].queryset.filter( dealer=dealer, staff_type="sales" ) - print(form.fields["staff"].queryset) + if hasattr(request.user.staffmember, "staff"): form.initial["staff"] = request.user.staffmember.staff form.fields["staff"].widget.attrs["disabled"] = True @@ -5248,8 +5256,8 @@ def lead_create(request): return render(request, "crm/leads/lead_form.html", {"form": form}) -def lead_tracking(request): - dealer = get_user_type(request) +def lead_tracking(request,dealer_slug): + dealer = get_object_or_404(models.Dealer,slug=dealer_slug) new = models.Lead.objects.filter(dealer=dealer, status="new") follow_up = models.Lead.objects.filter( dealer=dealer, next_action__in=["call", "meeting"] @@ -5268,7 +5276,7 @@ def lead_tracking(request): # @require_POST -def update_lead_actions(request): +def update_lead_actions(request,dealer_slug): try: lead_id = request.POST.get("lead_id") current_action = request.POST.get("current_action") @@ -5350,11 +5358,13 @@ class LeadUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView): "id_car_model" ].queryset = form.instance.id_car_make.carmodel_set.all() return form + def get_success_url(self): + return reverse_lazy("lead_list",kwargs={"dealer_slug":self.kwargs.get("dealer_slug")}) @login_required @permission_required("inventory.delete_lead", raise_exception=True) -def LeadDeleteView(request, slug): +def LeadDeleteView(request,dealer_slug, slug): """ Handles the deletion of a Lead along with its associated customer and potentially a related user account in the system. Ensures proper permissions and login @@ -5373,11 +5383,11 @@ def LeadDeleteView(request, slug): print(e) lead.delete() messages.success(request, _("Lead deleted successfully")) - return redirect("lead_list") + return redirect("lead_list",dealer_slug=dealer_slug) @login_required -def add_note_to_lead(request, slug): +def add_note_to_lead(request,dealer_slug, slug): """ Adds a note to a specific lead. This view is accessible only to authenticated users. The function handles the POST request to create a new note associated @@ -5402,14 +5412,14 @@ def add_note_to_lead(request, slug): note.created_by = request.user note.save() messages.success(request, _("Note added successfully")) - return redirect("lead_detail", slug=lead.slug) + return redirect("lead_detail",dealer_slug=dealer_slug, slug=lead.slug) else: form = forms.NoteForm() return render(request, "crm/note_form.html", {"form": form, "lead": lead}) @login_required -def add_note_to_opportunity(request, slug): +def add_note_to_opportunity(request,dealer_slug, slug): """ Add a note to a specific opportunity identified by its primary key. @@ -5424,7 +5434,7 @@ def add_note_to_opportunity(request, slug): :return: A redirect response to the detailed view of the opportunity. """ opportunity = get_object_or_404(models.Opportunity, slug=slug) - dealer = get_user_type(request) + dealer = get_object_or_404(models.Dealer,slug=dealer_slug) if request.method == "POST": notes = request.POST.get("notes") if not notes: @@ -5437,11 +5447,11 @@ def add_note_to_opportunity(request, slug): note=notes, ) messages.success(request, _("Note added successfully")) - return redirect("opportunity_detail", slug=opportunity.slug) + return redirect("opportunity_detail", dealer_slug=dealer_slug,slug=opportunity.slug) @login_required -def delete_note(request, pk): +def delete_note(request,dealer_slug, pk): """ Deletes a specific note created by the currently logged-in user and redirects to the lead detail page. If the note does not exist or the user is not the creator, @@ -5460,12 +5470,12 @@ def delete_note(request, pk): lead = models.Lead.objects.get(pk=lead_pk) note.delete() messages.success(request, _("Note deleted successfully.")) - return redirect("lead_detail", slug=lead.slug) + return redirect("lead_detail", dealer_slug=dealer_slug,slug=lead.slug) @login_required @permission_required("inventory.change_lead", raise_exception=True) -def lead_convert(request, slug): +def lead_convert(request,dealer_slug, slug): """ Converts a lead into a customer and creates a corresponding opportunity. @@ -5483,7 +5493,7 @@ def lead_convert(request, slug): :rtype: HttpResponse """ lead = get_object_or_404(models.Lead, slug=slug) - dealer = get_user_type(request) + dealer = get_object_or_404(models.Dealer,slug=dealer_slug) if hasattr(lead, "opportunity"): messages.error(request, _("Lead is already converted to customer")) else: @@ -5497,12 +5507,12 @@ def lead_convert(request, slug): staff=lead.staff, ) messages.success(request, _("Lead converted to customer successfully")) - return redirect("lead_list") + return redirect("lead_list",dealer_slug=dealer_slug) @login_required @permission_required("inventory.add_lead", raise_exception=True) -def schedule_lead(request, slug): +def schedule_lead(request, dealer_slug,slug): """ Handles the scheduling of a lead for an appointment. @@ -5523,8 +5533,8 @@ def schedule_lead(request, slug): if not request.is_staff: messages.error(request, _("You do not have permission to schedule lead")) - return redirect("lead_list") - dealer = get_user_type(request) + return redirect("lead_list", dealer_slug=dealer_slug) + dealer = get_object_or_404(models.Dealer, slug=dealer_slug) lead = get_object_or_404(models.Lead, slug=slug, dealer=dealer) if request.method == "POST": form = forms.ScheduleForm(request.POST) @@ -5547,7 +5557,7 @@ def schedule_lead(request, slug): ) except ValidationError as e: messages.error(request, str(e)) - return redirect("schedule_lead", slug=lead.slug) + return redirect("schedule_lead", dealer_slug=lead.dealer.slug, slug=lead.slug) client = get_object_or_404(User, email=lead.email) # Create Appointment @@ -5564,17 +5574,17 @@ def schedule_lead(request, slug): if lead.opportunity: return redirect("opportunity_detail", slug=lead.opportunity.slug) except models.Lead.opportunity.RelatedObjectDoesNotExist: - return redirect("lead_list") + return redirect("lead_list", dealer_slug=lead.dealer.slug) else: messages.error(request, f"Invalid form data: {str(form.errors)}") - return redirect("schedule_lead", slug=lead.slug) + return redirect("schedule_lead", dealer_slug=dealer_slug,slug=lead.slug) form = forms.ScheduleForm() return render(request, "crm/leads/schedule_lead.html", {"lead": lead, "form": form}) @login_required @permission_required("inventory.change_lead", raise_exception=True) -def lead_transfer(request, slug): +def lead_transfer(request,dealer_slug, slug): """ Handles the transfer of a lead to a different staff member. This view is accessible only to authenticated users with the 'inventory.change_lead' permission. If the @@ -5586,6 +5596,7 @@ def lead_transfer(request, slug): :param pk: The primary key of the lead to be transferred. :return: An HTTP redirect response to the lead list view. """ + dealer = get_object_or_404(models.Dealer, slug=dealer_slug) lead = get_object_or_404(models.Lead, slug=slug) if request.method == "POST": form = forms.LeadTransferForm(request.POST) @@ -5595,11 +5606,11 @@ def lead_transfer(request, slug): messages.success(request, _("Lead transferred successfully")) else: messages.error(request, f"Invalid form data: {str(form.errors)}") - return redirect("lead_list") + return redirect("lead_list", dealer_slug=dealer.slug) @login_required -def send_lead_email(request, slug, email_pk=None): +def send_lead_email(request,dealer_slug, slug, email_pk=None): """ Handles sending emails related to a lead. Supports creating drafts, sending emails, and rendering an email composition page. Changes on the lead or email objects, such as marking a lead as contacted @@ -5619,9 +5630,9 @@ def send_lead_email(request, slug, email_pk=None): or email composition rendering, a response object is returned to render the respective page. Type: HttpResponse """ + dealer = get_object_or_404(models.Dealer, slug=dealer_slug) lead = get_object_or_404(models.Lead, slug=slug) status = request.GET.get("status") - dealer = get_user_type(request) if status == "draft": models.Email.objects.create( content_object=lead, @@ -5643,17 +5654,17 @@ def send_lead_email(request, slug, email_pk=None): try: if lead.opportunity: response = HttpResponse( - redirect("opportunity_detail", slug=lead.opportunity.slug) + redirect("opportunity_detail", dealer_slug=dealer_slug,slug=lead.opportunity.slug) ) response["HX-Redirect"] = reverse( "opportunity_detail", args=[lead.opportunity.slug] ) else: - response = HttpResponse(redirect("lead_detail", slug=lead.slug)) - response["HX-Redirect"] = reverse("lead_detail", args=[lead.slug]) + response = HttpResponse(redirect("lead_detail", dealer_slug=dealer_slug,slug=lead.slug)) + response["HX-Redirect"] = reverse("lead_detail", dealer_slug=dealer_slug,slug=lead.slug) return response except models.Lead.opportunity.RelatedObjectDoesNotExist: - return redirect("lead_list") + return redirect("lead_list",dealer_slug=dealer.slug) if request.method == "POST": email_pk = request.POST.get("email_pk") @@ -5677,7 +5688,6 @@ def send_lead_email(request, slug, email_pk=None): request.POST.get("subject"), request.POST.get("message"), ) - dealer = get_user_type(request) models.Activity.objects.create( dealer=dealer, content_object=lead, @@ -5688,9 +5698,9 @@ def send_lead_email(request, slug, email_pk=None): messages.success(request, _("Email sent successfully")) try: if lead.opportunity: - return redirect("opportunity_detail", slug=lead.opportunity.slug) + return redirect("opportunity_detail", dealer_slug=dealer_slug,slug=lead.opportunity.slug) except models.Lead.opportunity.RelatedObjectDoesNotExist: - return redirect("lead_list") + return redirect("lead_list",dealer_slug=dealer_slug) msg = f""" السلام عليكم Dear {lead.full_name}, @@ -5784,7 +5794,7 @@ class OpportunityCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin) def get_initial(self): initial = super().get_initial() - dealer = get_user_type(self.request) + dealer = get_object_or_404(models.Dealer,slug=self.kwargs.get("dealer_slug")) if self.kwargs.get("slug", None): lead = models.Lead.objects.get(slug=self.kwargs.get("slug"), dealer=dealer) initial["lead"] = lead @@ -5792,7 +5802,7 @@ class OpportunityCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin) return initial def form_valid(self, form): - dealer = get_user_type(self.request) + dealer = get_object_or_404(models.Dealer,slug=self.kwargs.get("dealer_slug")) instance = form.save(commit=False) instance.dealer = dealer instance.staff = instance.lead.staff @@ -5802,7 +5812,7 @@ class OpportunityCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin) return super().form_valid(form) def get_success_url(self): - return reverse_lazy("opportunity_detail", kwargs={"slug": self.object.slug}) + return reverse_lazy("opportunity_detail", kwargs={"dealer_slug":self.kwargs.get("dealer_slug"),"slug": self.object.slug}) class OpportunityUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): @@ -5834,7 +5844,7 @@ class OpportunityUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView) success_message = "Opportunity updated successfully." def get_success_url(self): - return reverse_lazy("opportunity_detail", kwargs={"slug": self.object.slug}) + return reverse_lazy("opportunity_detail", kwargs={"dealer_slug":self.kwargs.get("dealer_slug"),"slug": self.object.slug}) class OpportunityDetailView(LoginRequiredMixin, DetailView): @@ -5861,7 +5871,7 @@ class OpportunityDetailView(LoginRequiredMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) form = forms.OpportunityStatusForm() - url = reverse("opportunity_update_status", args=[self.object.slug]) + url = reverse("opportunity_update_status", kwargs={"dealer_slug": self.kwargs["dealer_slug"], "slug": self.object.slug}) form.fields["status"].widget.attrs["hx-get"] = url form.fields["stage"].widget.attrs["hx-get"] = url form.fields["stage"].initial = self.object.stage @@ -5955,7 +5965,7 @@ class OpportunityListView(LoginRequiredMixin, ListView): @login_required -def delete_opportunity(request, pk): +def delete_opportunity(request,dealer_slug, pk): """ Deletes an opportunity object from the database and redirects to the opportunity list view. If the opportunity with the specified primary key is not found, a 404 @@ -5968,14 +5978,15 @@ def delete_opportunity(request, pk): :return: An HTTP response redirecting to the opportunity list view. :rtype: HttpResponse """ + get_object_or_404(models.Dealer, slug=dealer_slug) opportunity = get_object_or_404(models.Opportunity, pk=pk) opportunity.delete() messages.success(request, _("Opportunity deleted successfully")) - return redirect("opportunity_list") + return redirect("opportunity_list",dealer_slug=dealer_slug) @login_required -def opportunity_update_status(request, slug): +def opportunity_update_status(request,dealer_slug, slug): """ Update the status and/or stage of a specific Opportunity instance. This is a view function, which is generally tied to a URL endpoint in a Django application. @@ -6009,7 +6020,7 @@ def opportunity_update_status(request, slug): opportunity.stage = stage opportunity.save() messages.success(request, _("Opportunity status updated successfully")) - response = HttpResponse(redirect("opportunity_detail", slug=opportunity.slug)) + response = HttpResponse(redirect("opportunity_detail",dealer_slug=dealer_slug, slug=opportunity.slug)) response["HX-Refresh"] = "true" return response @@ -8160,7 +8171,7 @@ def DealerSettingsView(request, slug): @login_required -def schedule_cancel(request, pk): +def schedule_cancel(request,dealer_slug, pk): """ Cancel a schedule by updating its status to "Canceled". The function is protected by a login requirement, ensuring only authenticated users can execute it. It @@ -8174,6 +8185,7 @@ def schedule_cancel(request, pk): :return: An HTTP response object with a 200 status code upon successful execution. :rtype: HttpResponse """ + get_object_or_404(models.Dealer, slug=dealer_slug) schedule = get_object_or_404(models.Schedule, pk=pk) schedule.status = "Canceled" schedule.save() @@ -8850,14 +8862,14 @@ def notifications_history(request): # return render(request, 'activity_history.html') -def add_activity(request, content_type, slug): +def add_activity(request,dealer_slug, content_type, slug): try: model = apps.get_model(f"inventory.{content_type}") except LookupError: raise Http404("Model not found") obj = get_object_or_404(model, slug=slug) - dealer = get_user_type(request) + dealer = get_object_or_404(models.Dealer, slug=dealer_slug) if request.method == "POST": form = forms.ActivityForm(request.POST) if form.is_valid(): @@ -8872,17 +8884,17 @@ def add_activity(request, content_type, slug): messages.success(request, _("Activity added successfully")) else: messages.error(request, _("Activity form is not valid")) - return redirect(f"{content_type}_detail", slug=slug) + return redirect(f"{content_type}_detail",dealer_slug=dealer_slug, slug=slug) -def add_task(request, content_type, slug): +def add_task(request,dealer_slug, content_type, slug): try: model = apps.get_model(f"inventory.{content_type}") except LookupError: raise Http404("Model not found") obj = get_object_or_404(model, slug=slug) - dealer = get_user_type(request) + dealer = get_object_or_404(models.Dealer, slug=dealer_slug) if request.method == "POST": form = forms.StaffTaskForm(request.POST) if form.is_valid(): @@ -8895,12 +8907,11 @@ def add_task(request, content_type, slug): task.save() messages.success(request, _("Task added successfully")) else: - print(form.errors) messages.error(request, _("Task form is not valid")) - return redirect(f"{content_type}_detail", slug=slug) + return redirect(f"{content_type}_detail",dealer_slug=dealer_slug, slug=slug) -def update_task(request, pk): +def update_task(request,dealer_slug, pk): task = get_object_or_404(models.Tasks, pk=pk) if request.method == "POST": @@ -8912,14 +8923,14 @@ def update_task(request, pk): return render(request, "partials/task.html", {"task": task}) -def add_note(request, content_type, slug): +def add_note(request,dealer_slug, content_type, slug): try: model = apps.get_model(f"inventory.{content_type}") except LookupError: raise Http404("Model not found") + dealer = get_object_or_404(models.Dealer,slug=dealer_slug) obj = get_object_or_404(model, slug=slug) - dealer = get_user_type(request) if request.method == "POST": form = forms.NoteForm(request.POST) if form.is_valid(): @@ -8931,20 +8942,19 @@ def add_note(request, content_type, slug): note.save() messages.success(request, _("Note added successfully")) else: - print(form.errors) messages.error(request, _("Note form is not valid")) - return redirect(f"{content_type}_detail", slug=slug) + return redirect(f"{content_type}_detail",dealer_slug=dealer_slug, slug=slug) -def update_note(request, pk): +def update_note(request,dealer_slug, pk): note = get_object_or_404(models.Notes, pk=pk) lead = get_object_or_404(models.Lead, pk=note.content_object.id) - dealer = get_user_type(request) + dealer = get_object_or_404(models.Dealer,slug=dealer_slug) if request.method == "POST": note.note = request.POST.get("note") note.save() messages.success(request, _("Note updated successfully")) - return redirect("lead_detail", slug=lead.slug) + return redirect("lead_detail",dealer_slug=dealer_slug, slug=lead.slug) else: messages.error(request, _("Note form is not valid")) notes = models.Notes.objects.filter( diff --git a/templates/components/activity_modal.html b/templates/components/activity_modal.html index cd677fc6..76b9b572 100644 --- a/templates/components/activity_modal.html +++ b/templates/components/activity_modal.html @@ -10,7 +10,7 @@
@@ -456,7 +456,7 @@
{{opportunity.get_all_notes}}
@@ -504,7 +504,7 @@

Emails

diff --git a/templates/crm/opportunities/opportunity_list.html b/templates/crm/opportunities/opportunity_list.html index 13b82df5..9ff9261f 100644 --- a/templates/crm/opportunities/opportunity_list.html +++ b/templates/crm/opportunities/opportunity_list.html @@ -19,7 +19,7 @@ type="text" placeholder="{% trans 'Search opportunities...' %}" name="search" - hx-get="{% url 'opportunity_list' %}" + hx-get="{% url 'opportunity_list' request.dealer.slug %}" hx-trigger="keyup changed delay:500ms" hx-target="#opportunities-grid" hx-select="#opportunities-grid" @@ -36,7 +36,7 @@ +
{{task.title}}