247 lines
7.3 KiB
Python
247 lines
7.3 KiB
Python
from drf_spectacular.utils import extend_schema_field
|
|
from rest_framework import serializers
|
|
|
|
from accounts.models import Account, AccountEmail, AccountEmailLog
|
|
from common.serializer import (
|
|
AttachmentsSerializer,
|
|
OrganizationSerializer,
|
|
ProfileSerializer,
|
|
TagsSerializer,
|
|
TeamsSerializer,
|
|
UserSerializer,
|
|
)
|
|
from contacts.serializer import ContactSerializer
|
|
|
|
|
|
# Note: Removed unused serializer properties that were computed but never used by frontend:
|
|
# - get_team_users, get_team_and_assigned_users, get_assigned_users_not_in_teams
|
|
# - created_on_arrow (frontend computes its own humanized timestamps)
|
|
|
|
|
|
class AccountSerializer(serializers.ModelSerializer):
|
|
"""Serializer for reading Account data"""
|
|
|
|
created_by = UserSerializer()
|
|
org = OrganizationSerializer()
|
|
tags = TagsSerializer(read_only=True, many=True)
|
|
assigned_to = ProfileSerializer(read_only=True, many=True)
|
|
contacts = ContactSerializer(read_only=True, many=True)
|
|
teams = TeamsSerializer(read_only=True, many=True)
|
|
account_attachment = AttachmentsSerializer(read_only=True, many=True)
|
|
country_display = serializers.SerializerMethodField()
|
|
cases = serializers.SerializerMethodField()
|
|
tasks = serializers.SerializerMethodField()
|
|
opportunities = serializers.SerializerMethodField()
|
|
|
|
@extend_schema_field(str)
|
|
def get_country_display(self, obj):
|
|
return obj.get_country_display() if obj.country else None
|
|
|
|
@extend_schema_field(list)
|
|
def get_cases(self, obj):
|
|
"""Return cases linked to this account"""
|
|
return [{"id": str(c.id), "name": c.name} for c in obj.accounts_cases.all()]
|
|
|
|
@extend_schema_field(list)
|
|
def get_tasks(self, obj):
|
|
"""Return tasks linked to this account"""
|
|
return [{"id": str(t.id), "title": t.title} for t in obj.accounts_tasks.all()]
|
|
|
|
@extend_schema_field(list)
|
|
def get_opportunities(self, obj):
|
|
"""Return opportunities linked to this account"""
|
|
return [
|
|
{
|
|
"id": str(o.id),
|
|
"name": o.name,
|
|
"stage": o.stage,
|
|
"amount": str(o.amount) if o.amount else "0",
|
|
}
|
|
for o in obj.opportunities.all()
|
|
]
|
|
|
|
class Meta:
|
|
model = Account
|
|
fields = (
|
|
"id",
|
|
# Core Account Information
|
|
"name",
|
|
"email",
|
|
"phone",
|
|
"website",
|
|
# Business Information
|
|
"industry",
|
|
"number_of_employees",
|
|
"annual_revenue",
|
|
"currency",
|
|
# Address
|
|
"address_line",
|
|
"city",
|
|
"state",
|
|
"postcode",
|
|
"country",
|
|
"country_display",
|
|
# Assignment
|
|
"assigned_to",
|
|
"teams",
|
|
"contacts",
|
|
# Tags
|
|
"tags",
|
|
# Notes
|
|
"description",
|
|
# Related
|
|
"account_attachment",
|
|
"cases",
|
|
"tasks",
|
|
"opportunities",
|
|
# System
|
|
"created_by",
|
|
"created_at",
|
|
"is_active",
|
|
"org",
|
|
)
|
|
|
|
|
|
class EmailSerializer(serializers.ModelSerializer):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
class Meta:
|
|
model = AccountEmail
|
|
fields = (
|
|
"message_subject",
|
|
"message_body",
|
|
"timezone",
|
|
"scheduled_date_time",
|
|
"scheduled_later",
|
|
"created_at",
|
|
"from_email",
|
|
"rendered_message_body",
|
|
)
|
|
|
|
def validate_message_body(self, message_body):
|
|
count = 0
|
|
for i in message_body:
|
|
if i == "{":
|
|
count += 1
|
|
elif i == "}":
|
|
count -= 1
|
|
if count < 0:
|
|
raise serializers.ValidationError(
|
|
"Brackets do not match, Enter valid tags."
|
|
)
|
|
if count != 0:
|
|
raise serializers.ValidationError(
|
|
"Brackets do not match, Enter valid tags."
|
|
)
|
|
return message_body
|
|
|
|
|
|
class EmailLogSerializer(serializers.ModelSerializer):
|
|
email = EmailSerializer()
|
|
|
|
class Meta:
|
|
model = AccountEmailLog
|
|
fields = ["email", "contact", "is_sent"]
|
|
|
|
|
|
class AccountWriteSerializer(serializers.ModelSerializer):
|
|
"""Serializer for API documentation of Account write operations"""
|
|
|
|
class Meta:
|
|
model = Account
|
|
fields = [
|
|
"name",
|
|
"phone",
|
|
"email",
|
|
"website",
|
|
"industry",
|
|
"number_of_employees",
|
|
"annual_revenue",
|
|
"address_line",
|
|
"city",
|
|
"state",
|
|
"postcode",
|
|
"country",
|
|
"description",
|
|
]
|
|
|
|
|
|
class AccountCreateSerializer(serializers.ModelSerializer):
|
|
"""Serializer for creating/updating Account data"""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
request_obj = kwargs.pop("request_obj", None)
|
|
kwargs.pop("account", None) # Remove unused 'account' parameter passed by views
|
|
super().__init__(*args, **kwargs)
|
|
if request_obj:
|
|
self.org = request_obj.profile.org
|
|
|
|
def validate_name(self, name):
|
|
if self.instance:
|
|
if self.instance.name != name:
|
|
if not Account.objects.filter(name__iexact=name, org=self.org).exists():
|
|
return name
|
|
raise serializers.ValidationError(
|
|
"Account already exists with this name"
|
|
)
|
|
return name
|
|
if not Account.objects.filter(name__iexact=name, org=self.org).exists():
|
|
return name
|
|
raise serializers.ValidationError("Account already exists with this name")
|
|
|
|
class Meta:
|
|
model = Account
|
|
fields = (
|
|
# Core Account Information
|
|
"name",
|
|
"email",
|
|
"phone",
|
|
"website",
|
|
# Business Information
|
|
"industry",
|
|
"number_of_employees",
|
|
"annual_revenue",
|
|
"currency",
|
|
# Address
|
|
"address_line",
|
|
"city",
|
|
"state",
|
|
"postcode",
|
|
"country",
|
|
# Notes
|
|
"description",
|
|
# Status
|
|
"is_active",
|
|
)
|
|
|
|
def create(self, validated_data):
|
|
# Default currency from org if not provided and has annual_revenue
|
|
if not validated_data.get("currency") and validated_data.get("annual_revenue"):
|
|
request = self.context.get("request")
|
|
if request and hasattr(request, "profile") and request.profile.org:
|
|
validated_data["currency"] = request.profile.org.default_currency
|
|
return super().create(validated_data)
|
|
|
|
|
|
class AccountDetailEditSwaggerSerializer(serializers.Serializer):
|
|
comment = serializers.CharField()
|
|
account_attachment = serializers.FileField()
|
|
|
|
|
|
class AccountCommentEditSwaggerSerializer(serializers.Serializer):
|
|
comment = serializers.CharField()
|
|
|
|
|
|
class EmailWriteSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = AccountEmail
|
|
fields = (
|
|
"from_email",
|
|
"recipients",
|
|
"message_subject",
|
|
"scheduled_later",
|
|
"timezone",
|
|
"scheduled_date_time",
|
|
"message_body",
|
|
)
|