787 lines
31 KiB
Python
787 lines
31 KiB
Python
from django.contrib.contenttypes.models import ContentType
|
|
from django.db.models import Q
|
|
from django.shortcuts import get_object_or_404
|
|
from drf_spectacular.utils import extend_schema, inline_serializer
|
|
from rest_framework import serializers, status
|
|
from rest_framework.pagination import LimitOffsetPagination
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
|
|
from common.models import Attachments, Comment, Profile, Tags, Teams, User
|
|
from common.permissions import HasOrgContext
|
|
from common.serializer import (
|
|
AttachmentsSerializer,
|
|
CommentSerializer,
|
|
LeadCommentSerializer,
|
|
ProfileSerializer,
|
|
TeamsSerializer,
|
|
)
|
|
from common.utils import COUNTRIES, INDCHOICES, LEAD_SOURCE, LEAD_STATUS
|
|
from contacts.models import Contact
|
|
from leads import swagger_params
|
|
from leads.models import Lead
|
|
from leads.serializer import (
|
|
LeadCreateSerializer,
|
|
LeadCreateSwaggerSerializer,
|
|
LeadDetailEditSwaggerSerializer,
|
|
LeadSerializer,
|
|
TagsSerializer,
|
|
)
|
|
from leads.tasks import send_email_to_assigned_user
|
|
|
|
|
|
class LeadListView(APIView, LimitOffsetPagination):
|
|
model = Lead
|
|
permission_classes = (IsAuthenticated, HasOrgContext)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
params = self.request.query_params
|
|
queryset = (
|
|
self.model.objects.filter(org=self.request.profile.org)
|
|
.exclude(status="converted")
|
|
.select_related("created_by")
|
|
.prefetch_related(
|
|
"tags",
|
|
"assigned_to",
|
|
)
|
|
).order_by("-id")
|
|
if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser:
|
|
queryset = queryset.filter(
|
|
Q(assigned_to__in=[self.request.profile])
|
|
| Q(created_by=self.request.profile.user)
|
|
)
|
|
|
|
if params:
|
|
if params.get("name"):
|
|
queryset = queryset.filter(
|
|
Q(first_name__icontains=params.get("name"))
|
|
& Q(last_name__icontains=params.get("name"))
|
|
)
|
|
if params.get("salutation"):
|
|
queryset = queryset.filter(
|
|
salutation__icontains=params.get("salutation")
|
|
)
|
|
if params.get("source"):
|
|
queryset = queryset.filter(source=params.get("source"))
|
|
if params.getlist("assigned_to"):
|
|
queryset = queryset.filter(
|
|
assigned_to__id__in=params.get("assigned_to")
|
|
)
|
|
if params.get("status"):
|
|
queryset = queryset.filter(status=params.get("status"))
|
|
if params.get("tags"):
|
|
queryset = queryset.filter(tags__in=params.get("tags"))
|
|
if params.get("city"):
|
|
queryset = queryset.filter(city__icontains=params.get("city"))
|
|
if params.get("email"):
|
|
queryset = queryset.filter(email__icontains=params.get("email"))
|
|
if params.get("rating"):
|
|
queryset = queryset.filter(rating=params.get("rating"))
|
|
if params.get("search"):
|
|
search = params.get("search")
|
|
queryset = queryset.filter(
|
|
Q(first_name__icontains=search)
|
|
| Q(last_name__icontains=search)
|
|
| Q(company_name__icontains=search)
|
|
| Q(email__icontains=search)
|
|
)
|
|
if params.get("created_at__gte"):
|
|
queryset = queryset.filter(
|
|
created_at__gte=params.get("created_at__gte")
|
|
)
|
|
if params.get("created_at__lte"):
|
|
queryset = queryset.filter(
|
|
created_at__lte=params.get("created_at__lte")
|
|
)
|
|
if params.get("close_date__gte"):
|
|
queryset = queryset.filter(
|
|
close_date__gte=params.get("close_date__gte")
|
|
)
|
|
if params.get("close_date__lte"):
|
|
queryset = queryset.filter(
|
|
close_date__lte=params.get("close_date__lte")
|
|
)
|
|
context = {}
|
|
queryset_open = queryset.exclude(status="closed")
|
|
results_leads_open = self.paginate_queryset(
|
|
queryset_open.distinct(), self.request, view=self
|
|
)
|
|
open_leads = LeadSerializer(results_leads_open, many=True).data
|
|
if results_leads_open:
|
|
offset = queryset_open.filter(id__gte=results_leads_open[-1].id).count()
|
|
if offset == queryset_open.count():
|
|
offset = None
|
|
else:
|
|
offset = 0
|
|
context["per_page"] = 10
|
|
page_number = (int(self.offset / 10) + 1,)
|
|
context["page_number"] = page_number
|
|
context["open_leads"] = {
|
|
"leads_count": self.count,
|
|
"open_leads": open_leads,
|
|
"offset": offset,
|
|
}
|
|
|
|
queryset_close = queryset.filter(status="closed")
|
|
results_leads_close = self.paginate_queryset(
|
|
queryset_close.distinct(), self.request, view=self
|
|
)
|
|
close_leads = LeadSerializer(results_leads_close, many=True).data
|
|
if results_leads_close:
|
|
offset = queryset_close.filter(id__gte=results_leads_close[-1].id).count()
|
|
if offset == queryset_close.count():
|
|
offset = None
|
|
else:
|
|
offset = 0
|
|
|
|
context["close_leads"] = {
|
|
"leads_count": self.count,
|
|
"close_leads": close_leads,
|
|
"offset": offset,
|
|
}
|
|
contacts = Contact.objects.filter(org=self.request.profile.org).values(
|
|
"id", "first_name"
|
|
)
|
|
|
|
context["contacts"] = contacts
|
|
context["status"] = LEAD_STATUS
|
|
context["source"] = LEAD_SOURCE
|
|
context["tags"] = TagsSerializer(
|
|
Tags.objects.filter(org=self.request.profile.org, is_active=True), many=True
|
|
).data
|
|
|
|
users = Profile.objects.filter(
|
|
is_active=True, org=self.request.profile.org
|
|
).values("id", "user__email")
|
|
context["users"] = users
|
|
context["countries"] = COUNTRIES
|
|
context["industries"] = INDCHOICES
|
|
return context
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
operation_id="leads_list",
|
|
parameters=swagger_params.lead_list_get_params,
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadListResponse",
|
|
fields={
|
|
"per_page": serializers.IntegerField(),
|
|
"page_number": serializers.IntegerField(),
|
|
"open_leads": serializers.DictField(),
|
|
"close_leads": serializers.DictField(),
|
|
"contacts": serializers.ListField(),
|
|
"status": serializers.ListField(),
|
|
"source": serializers.ListField(),
|
|
"tags": TagsSerializer(many=True),
|
|
"users": serializers.ListField(),
|
|
"countries": serializers.ListField(),
|
|
"industries": serializers.ListField(),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
context = self.get_context_data(**kwargs)
|
|
return Response(context)
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
operation_id="leads_create",
|
|
description="Leads Create",
|
|
parameters=swagger_params.organization_params,
|
|
request=LeadCreateSwaggerSerializer,
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadCreateResponse",
|
|
fields={
|
|
"error": serializers.BooleanField(),
|
|
"message": serializers.CharField(),
|
|
"account_id": serializers.CharField(required=False),
|
|
"contact_id": serializers.CharField(
|
|
required=False, allow_null=True
|
|
),
|
|
"opportunity_id": serializers.CharField(
|
|
required=False, allow_null=True
|
|
),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def post(self, request, *args, **kwargs):
|
|
data = request.data
|
|
serializer = LeadCreateSerializer(data=data, request_obj=request)
|
|
if serializer.is_valid():
|
|
lead_obj = serializer.save(
|
|
created_by=request.profile.user, org=request.profile.org
|
|
)
|
|
if data.get("tags", None):
|
|
tags = data.get("tags")
|
|
tag_objs = Tags.objects.filter(
|
|
id__in=tags, org=request.profile.org, is_active=True
|
|
)
|
|
lead_obj.tags.add(*tag_objs)
|
|
|
|
if data.get("contacts", None):
|
|
obj_contact = Contact.objects.filter(
|
|
id__in=data.get("contacts"), org=request.profile.org
|
|
)
|
|
lead_obj.contacts.add(*obj_contact)
|
|
|
|
recipients = list(lead_obj.assigned_to.all().values_list("id", flat=True))
|
|
send_email_to_assigned_user.delay(
|
|
recipients,
|
|
lead_obj.id,
|
|
str(request.profile.org.id),
|
|
)
|
|
|
|
if request.FILES.get("lead_attachment"):
|
|
attachment = Attachments()
|
|
attachment.created_by = request.profile.user
|
|
attachment.file_name = request.FILES.get("lead_attachment").name
|
|
attachment.content_object = lead_obj
|
|
attachment.attachment = request.FILES.get("lead_attachment")
|
|
attachment.org = request.profile.org
|
|
attachment.save()
|
|
|
|
if data.get("teams", None):
|
|
teams_list = data.get("teams")
|
|
teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org)
|
|
lead_obj.teams.add(*teams)
|
|
|
|
if data.get("assigned_to", None):
|
|
assinged_to_list = data.get("assigned_to")
|
|
profiles = Profile.objects.filter(
|
|
id__in=assinged_to_list, org=request.profile.org
|
|
)
|
|
lead_obj.assigned_to.add(*profiles)
|
|
|
|
if data.get("status") == "converted":
|
|
from leads.services import convert_lead_to_account
|
|
|
|
account, contact, opportunity = convert_lead_to_account(
|
|
lead_obj, request
|
|
)
|
|
|
|
if data.get("assigned_to", None):
|
|
assigned_to_list = data.getlist("assigned_to")
|
|
send_email_to_assigned_user.delay(
|
|
assigned_to_list,
|
|
lead_obj.id,
|
|
str(request.profile.org.id),
|
|
)
|
|
return Response(
|
|
{
|
|
"error": False,
|
|
"message": "Lead Converted Successfully",
|
|
"account_id": str(account.id),
|
|
"contact_id": str(contact.id) if contact else None,
|
|
"opportunity_id": str(opportunity.id) if opportunity else None,
|
|
},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
return Response(
|
|
{"error": False, "message": "Lead Created Successfully"},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
return Response(
|
|
{"error": True, "errors": serializer.errors},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
|
|
class LeadDetailView(APIView):
|
|
model = Lead
|
|
permission_classes = (IsAuthenticated, HasOrgContext)
|
|
|
|
def get_object(self, pk):
|
|
return get_object_or_404(Lead, id=pk, org=self.request.profile.org)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
params = self.request.query_params
|
|
context = {}
|
|
user_assgn_list = [
|
|
assigned_to.id for assigned_to in self.lead_obj.assigned_to.all()
|
|
]
|
|
if self.request.profile.user == self.lead_obj.created_by:
|
|
user_assgn_list.append(self.request.profile.user)
|
|
if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser:
|
|
if self.request.profile.id not in user_assgn_list:
|
|
return Response(
|
|
{
|
|
"error": True,
|
|
"errors": "You do not have Permission to perform this action",
|
|
},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
|
|
lead_content_type = ContentType.objects.get_for_model(Lead)
|
|
comments = Comment.objects.filter(
|
|
content_type=lead_content_type, object_id=self.lead_obj.id
|
|
).order_by("-id")
|
|
attachments = Attachments.objects.filter(
|
|
content_type=lead_content_type, object_id=self.lead_obj.id
|
|
).order_by("-id")
|
|
assigned_data = []
|
|
for each in self.lead_obj.assigned_to.all():
|
|
assigned_dict = {}
|
|
assigned_dict["id"] = each.id
|
|
assigned_dict["name"] = each.user.email
|
|
assigned_data.append(assigned_dict)
|
|
|
|
if self.request.user.is_superuser or self.request.profile.role == "ADMIN":
|
|
users_mention = list(
|
|
Profile.objects.filter(
|
|
is_active=True, org=self.request.profile.org
|
|
).values("user__email")
|
|
)
|
|
elif self.request.profile.user != self.lead_obj.created_by:
|
|
users_mention = [{"username": self.lead_obj.created_by.username}]
|
|
else:
|
|
users_mention = list(self.lead_obj.assigned_to.all().values("user__email"))
|
|
lead_content_type = ContentType.objects.get_for_model(Lead)
|
|
comments = Comment.objects.filter(
|
|
content_type=lead_content_type,
|
|
object_id=self.lead_obj.id,
|
|
org=self.request.profile.org,
|
|
).order_by("-id")
|
|
attachments = Attachments.objects.filter(
|
|
content_type=lead_content_type,
|
|
object_id=self.lead_obj.id,
|
|
org=self.request.profile.org,
|
|
).order_by("-id")
|
|
if self.request.profile.role == "ADMIN" or self.request.user.is_superuser:
|
|
users = Profile.objects.filter(
|
|
is_active=True, org=self.request.profile.org
|
|
).order_by("user__email")
|
|
else:
|
|
users = Profile.objects.filter(
|
|
role="ADMIN", org=self.request.profile.org
|
|
).order_by("user__email")
|
|
user_assgn_list = [
|
|
assigned_to.id
|
|
for assigned_to in self.lead_obj.get_assigned_users_not_in_teams
|
|
]
|
|
|
|
if self.request.profile.user == self.lead_obj.created_by:
|
|
user_assgn_list.append(self.request.profile.id)
|
|
if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser:
|
|
if self.request.profile.id not in user_assgn_list:
|
|
return Response(
|
|
{
|
|
"error": True,
|
|
"errors": "You do not have Permission to perform this action",
|
|
},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
team_ids = [user.id for user in self.lead_obj.get_team_users]
|
|
all_user_ids = [user.id for user in users]
|
|
users_excluding_team_id = set(all_user_ids) - set(team_ids)
|
|
users_excluding_team = Profile.objects.filter(id__in=users_excluding_team_id)
|
|
context.update(
|
|
{
|
|
"lead_obj": LeadSerializer(self.lead_obj).data,
|
|
"attachments": AttachmentsSerializer(attachments, many=True).data,
|
|
"comments": LeadCommentSerializer(comments, many=True).data,
|
|
"users_mention": users_mention,
|
|
"assigned_data": assigned_data,
|
|
}
|
|
)
|
|
context["users"] = ProfileSerializer(users, many=True).data
|
|
context["users_excluding_team"] = ProfileSerializer(
|
|
users_excluding_team, many=True
|
|
).data
|
|
context["source"] = LEAD_SOURCE
|
|
context["status"] = LEAD_STATUS
|
|
context["teams"] = TeamsSerializer(
|
|
Teams.objects.filter(org=self.request.profile.org), many=True
|
|
).data
|
|
context["countries"] = COUNTRIES
|
|
|
|
return context
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
operation_id="leads_retrieve",
|
|
parameters=swagger_params.organization_params,
|
|
description="Lead Detail",
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadDetailResponse",
|
|
fields={
|
|
"lead_obj": LeadSerializer(),
|
|
"attachments": AttachmentsSerializer(many=True),
|
|
"comments": LeadCommentSerializer(many=True),
|
|
"users_mention": serializers.ListField(),
|
|
"assigned_data": serializers.ListField(),
|
|
"users": ProfileSerializer(many=True),
|
|
"users_excluding_team": ProfileSerializer(many=True),
|
|
"source": serializers.ListField(),
|
|
"status": serializers.ListField(),
|
|
"teams": TeamsSerializer(many=True),
|
|
"countries": serializers.ListField(),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def get(self, request, pk, **kwargs):
|
|
self.lead_obj = self.get_object(pk)
|
|
context = self.get_context_data(**kwargs)
|
|
return Response(context)
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
operation_id="leads_comment_attachment",
|
|
parameters=swagger_params.organization_params,
|
|
request=LeadDetailEditSwaggerSerializer,
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadCommentAttachmentResponse",
|
|
fields={
|
|
"lead_obj": LeadSerializer(),
|
|
"attachments": AttachmentsSerializer(many=True),
|
|
"comments": LeadCommentSerializer(many=True),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def post(self, request, pk, **kwargs):
|
|
params = request.data
|
|
|
|
context = {}
|
|
self.lead_obj = Lead.objects.get(pk=pk)
|
|
if self.lead_obj.org != request.profile.org:
|
|
return Response(
|
|
{"error": True, "errors": "User company doesnot match with header...."},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser:
|
|
if not (
|
|
(self.request.profile.user == self.lead_obj.created_by)
|
|
or (self.request.profile in self.lead_obj.assigned_to.all())
|
|
):
|
|
return Response(
|
|
{
|
|
"error": True,
|
|
"errors": "You do not have Permission to perform this action",
|
|
},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
comment_serializer = CommentSerializer(data=params)
|
|
if comment_serializer.is_valid():
|
|
if params.get("comment"):
|
|
comment_serializer.save(
|
|
lead_id=self.lead_obj.id,
|
|
commented_by_id=self.request.profile.id,
|
|
)
|
|
|
|
if self.request.FILES.get("lead_attachment"):
|
|
attachment = Attachments()
|
|
attachment.created_by = User.objects.get(
|
|
id=self.request.profile.user.id
|
|
)
|
|
|
|
attachment.file_name = self.request.FILES.get("lead_attachment").name
|
|
attachment.content_object = self.lead_obj
|
|
attachment.attachment = self.request.FILES.get("lead_attachment")
|
|
attachment.org = self.request.profile.org
|
|
attachment.save()
|
|
|
|
lead_content_type = ContentType.objects.get_for_model(Lead)
|
|
comments = Comment.objects.filter(
|
|
content_type=lead_content_type,
|
|
object_id=self.lead_obj.id,
|
|
org=self.request.profile.org,
|
|
).order_by("-id")
|
|
attachments = Attachments.objects.filter(
|
|
content_type=lead_content_type,
|
|
object_id=self.lead_obj.id,
|
|
org=self.request.profile.org,
|
|
).order_by("-id")
|
|
context.update(
|
|
{
|
|
"lead_obj": LeadSerializer(self.lead_obj).data,
|
|
"attachments": AttachmentsSerializer(attachments, many=True).data,
|
|
"comments": LeadCommentSerializer(comments, many=True).data,
|
|
}
|
|
)
|
|
return Response(context)
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
parameters=swagger_params.organization_params,
|
|
request=LeadCreateSwaggerSerializer,
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadUpdateResponse",
|
|
fields={
|
|
"error": serializers.BooleanField(),
|
|
"message": serializers.CharField(),
|
|
"account_id": serializers.CharField(required=False),
|
|
"contact_id": serializers.CharField(
|
|
required=False, allow_null=True
|
|
),
|
|
"opportunity_id": serializers.CharField(
|
|
required=False, allow_null=True
|
|
),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def put(self, request, pk, **kwargs):
|
|
params = request.data
|
|
self.lead_obj = self.get_object(pk)
|
|
if self.lead_obj.org != request.profile.org:
|
|
return Response(
|
|
{
|
|
"error": True,
|
|
"errors": "User company does not match with header....",
|
|
},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
serializer = LeadCreateSerializer(
|
|
data=params,
|
|
instance=self.lead_obj,
|
|
request_obj=request,
|
|
)
|
|
if serializer.is_valid():
|
|
lead_obj = serializer.save()
|
|
previous_assigned_to_users = list(
|
|
lead_obj.assigned_to.all().values_list("id", flat=True)
|
|
)
|
|
lead_obj.tags.clear()
|
|
if params.get("tags"):
|
|
tags = params.get("tags")
|
|
tag_objs = Tags.objects.filter(
|
|
id__in=tags, org=request.profile.org, is_active=True
|
|
)
|
|
lead_obj.tags.add(*tag_objs)
|
|
|
|
assigned_to_list = list(
|
|
lead_obj.assigned_to.all().values_list("id", flat=True)
|
|
)
|
|
recipients = list(set(assigned_to_list) - set(previous_assigned_to_users))
|
|
send_email_to_assigned_user.delay(
|
|
recipients,
|
|
lead_obj.id,
|
|
str(request.profile.org.id),
|
|
)
|
|
if request.FILES.get("lead_attachment"):
|
|
attachment = Attachments()
|
|
attachment.created_by = request.profile.user
|
|
attachment.file_name = request.FILES.get("lead_attachment").name
|
|
attachment.content_object = lead_obj
|
|
attachment.attachment = request.FILES.get("lead_attachment")
|
|
attachment.org = request.profile.org
|
|
attachment.save()
|
|
|
|
lead_obj.contacts.clear()
|
|
if params.get("contacts"):
|
|
obj_contact = Contact.objects.filter(
|
|
id__in=params.get("contacts"), org=request.profile.org
|
|
)
|
|
lead_obj.contacts.add(*obj_contact)
|
|
|
|
lead_obj.teams.clear()
|
|
if params.get("teams"):
|
|
teams_list = params.get("teams")
|
|
teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org)
|
|
lead_obj.teams.add(*teams)
|
|
|
|
lead_obj.assigned_to.clear()
|
|
if params.get("assigned_to"):
|
|
assinged_to_list = params.get("assigned_to")
|
|
profiles = Profile.objects.filter(
|
|
id__in=assinged_to_list, org=request.profile.org
|
|
)
|
|
lead_obj.assigned_to.add(*profiles)
|
|
|
|
if params.get("status") == "converted":
|
|
from leads.services import convert_lead_to_account
|
|
|
|
account, contact, opportunity = convert_lead_to_account(
|
|
lead_obj, request
|
|
)
|
|
|
|
if params.get("assigned_to"):
|
|
assigned_to_list = params.get("assigned_to")
|
|
send_email_to_assigned_user.delay(
|
|
assigned_to_list,
|
|
lead_obj.id,
|
|
str(request.profile.org.id),
|
|
)
|
|
|
|
return Response(
|
|
{
|
|
"error": False,
|
|
"message": "Lead Converted Successfully",
|
|
"account_id": str(account.id),
|
|
"contact_id": str(contact.id) if contact else None,
|
|
"opportunity_id": str(opportunity.id) if opportunity else None,
|
|
},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
return Response(
|
|
{"error": False, "message": "Lead updated Successfully"},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
return Response(
|
|
{"error": True, "errors": serializer.errors},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
parameters=swagger_params.organization_params,
|
|
request=LeadDetailEditSwaggerSerializer,
|
|
description="Partial Lead Update",
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadPatchResponse",
|
|
fields={
|
|
"error": serializers.BooleanField(),
|
|
"message": serializers.CharField(),
|
|
"account_id": serializers.CharField(required=False),
|
|
"contact_id": serializers.CharField(
|
|
required=False, allow_null=True
|
|
),
|
|
"opportunity_id": serializers.CharField(
|
|
required=False, allow_null=True
|
|
),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def patch(self, request, pk, **kwargs):
|
|
"""Handle partial updates to a lead, including conversion."""
|
|
params = request.data
|
|
self.lead_obj = self.get_object(pk)
|
|
|
|
if self.lead_obj.org != request.profile.org:
|
|
return Response(
|
|
{
|
|
"error": True,
|
|
"errors": "User company does not match with header....",
|
|
},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
|
|
if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser:
|
|
if not (
|
|
(self.request.profile.user == self.lead_obj.created_by)
|
|
or (self.request.profile in self.lead_obj.assigned_to.all())
|
|
):
|
|
return Response(
|
|
{
|
|
"error": True,
|
|
"errors": "You do not have Permission to perform this action",
|
|
},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|
|
|
|
# Handle conversion if status is being set to converted
|
|
if params.get("status") == "converted" or params.get("is_converted"):
|
|
from leads.services import convert_lead_to_account
|
|
|
|
account, contact, opportunity = convert_lead_to_account(
|
|
self.lead_obj, request
|
|
)
|
|
|
|
return Response(
|
|
{
|
|
"error": False,
|
|
"message": "Lead Converted Successfully",
|
|
"account_id": str(account.id),
|
|
"contact_id": str(contact.id) if contact else None,
|
|
"opportunity_id": str(opportunity.id) if opportunity else None,
|
|
},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
|
|
# Handle regular partial updates
|
|
serializer = LeadCreateSerializer(
|
|
data=params,
|
|
instance=self.lead_obj,
|
|
request_obj=request,
|
|
partial=True,
|
|
)
|
|
if serializer.is_valid():
|
|
lead_obj = serializer.save()
|
|
|
|
# Handle M2M fields if present in request
|
|
if "tags" in params:
|
|
lead_obj.tags.clear()
|
|
tags = params.get("tags")
|
|
if tags:
|
|
tag_objs = Tags.objects.filter(
|
|
id__in=tags, org=request.profile.org, is_active=True
|
|
)
|
|
lead_obj.tags.add(*tag_objs)
|
|
|
|
if "contacts" in params:
|
|
lead_obj.contacts.clear()
|
|
contacts_list = params.get("contacts")
|
|
if contacts_list:
|
|
obj_contact = Contact.objects.filter(
|
|
id__in=contacts_list, org=request.profile.org
|
|
)
|
|
lead_obj.contacts.add(*obj_contact)
|
|
|
|
if "teams" in params:
|
|
lead_obj.teams.clear()
|
|
teams_list = params.get("teams")
|
|
if teams_list:
|
|
teams = Teams.objects.filter(
|
|
id__in=teams_list, org=request.profile.org
|
|
)
|
|
lead_obj.teams.add(*teams)
|
|
|
|
if "assigned_to" in params:
|
|
lead_obj.assigned_to.clear()
|
|
assigned_to_list = params.get("assigned_to")
|
|
if assigned_to_list:
|
|
profiles = Profile.objects.filter(
|
|
id__in=assigned_to_list, org=request.profile.org
|
|
)
|
|
lead_obj.assigned_to.add(*profiles)
|
|
|
|
return Response(
|
|
{"error": False, "message": "Lead updated Successfully"},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
return Response(
|
|
{"error": True, "errors": serializer.errors},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
@extend_schema(
|
|
tags=["Leads"],
|
|
parameters=swagger_params.organization_params,
|
|
description="Lead Delete",
|
|
responses={
|
|
200: inline_serializer(
|
|
name="LeadDeleteResponse",
|
|
fields={
|
|
"error": serializers.BooleanField(),
|
|
"message": serializers.CharField(),
|
|
},
|
|
)
|
|
},
|
|
)
|
|
def delete(self, request, pk, **kwargs):
|
|
self.object = self.get_object(pk)
|
|
if (
|
|
request.profile.role == "ADMIN"
|
|
or request.user.is_superuser
|
|
or request.profile.user == self.object.created_by
|
|
) and self.object.org == request.profile.org:
|
|
self.object.delete()
|
|
return Response(
|
|
{"error": False, "message": "Lead deleted Successfully"},
|
|
status=status.HTTP_200_OK,
|
|
)
|
|
return Response(
|
|
{"error": True, "errors": "you don't have permission to delete this lead"},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
)
|