mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-02-25 17:04:51 +01:00
Fix AttributeError when serializing transactions with null categories. The to_representation method now checks for None before accessing category properties, returning None instead of crashing. Fixes issue where API returns 500 error when retrieving transactions without assigned categories.
123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
from drf_spectacular.utils import extend_schema_field
|
|
from rest_framework import serializers
|
|
from django.utils.translation import gettext_lazy as _
|
|
from apps.transactions.models import (
|
|
TransactionCategory,
|
|
TransactionTag,
|
|
TransactionEntity,
|
|
)
|
|
|
|
|
|
@extend_schema_field(
|
|
{
|
|
"oneOf": [{"type": "string"}, {"type": "integer"}, {"type": "null"}],
|
|
"description": "TransactionCategory ID or name. If the name doesn't exist, a new one will be created. Can be null if no category is assigned.",
|
|
}
|
|
)
|
|
class TransactionCategoryField(serializers.Field):
|
|
def to_representation(self, value):
|
|
if value is None:
|
|
return None
|
|
return {"id": value.id, "name": value.name}
|
|
|
|
def to_internal_value(self, data):
|
|
if data is None:
|
|
return None
|
|
if isinstance(data, int):
|
|
try:
|
|
return TransactionCategory.objects.get(pk=data)
|
|
except TransactionCategory.DoesNotExist:
|
|
raise serializers.ValidationError(
|
|
_("Category with this ID does not exist.")
|
|
)
|
|
elif isinstance(data, str):
|
|
try:
|
|
category = TransactionCategory.objects.get(name=data)
|
|
except TransactionCategory.DoesNotExist:
|
|
category = TransactionCategory(name=data)
|
|
category.save()
|
|
return category
|
|
raise serializers.ValidationError(
|
|
_("Invalid category data. Provide an ID or name.")
|
|
)
|
|
|
|
@staticmethod
|
|
def get_schema():
|
|
return {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"description": "TransactionCategory ID or name",
|
|
},
|
|
}
|
|
|
|
|
|
@extend_schema_field(
|
|
{
|
|
"type": "array",
|
|
"items": {"oneOf": [{"type": "string"}, {"type": "integer"}]},
|
|
"description": "TransactionTag ID or name. If the name doesn't exist, a new one will be created",
|
|
}
|
|
)
|
|
class TransactionTagField(serializers.Field):
|
|
def to_representation(self, value):
|
|
return [{"id": tag.id, "name": tag.name} for tag in value.all()]
|
|
|
|
def to_internal_value(self, data):
|
|
tags = []
|
|
for item in data:
|
|
if isinstance(item, int):
|
|
try:
|
|
tag = TransactionTag.objects.get(pk=item)
|
|
except TransactionTag.DoesNotExist:
|
|
raise serializers.ValidationError(
|
|
_("Tag with this ID does not exist.")
|
|
)
|
|
elif isinstance(item, str):
|
|
try:
|
|
tag = TransactionTag.objects.get(name=item)
|
|
except TransactionTag.DoesNotExist:
|
|
tag = TransactionTag(name=item)
|
|
tag.save()
|
|
else:
|
|
raise serializers.ValidationError(
|
|
_("Invalid tag data. Provide an ID or name.")
|
|
)
|
|
tags.append(tag)
|
|
return tags
|
|
|
|
|
|
@extend_schema_field(
|
|
{
|
|
"type": "array",
|
|
"items": {"oneOf": [{"type": "string"}, {"type": "integer"}]},
|
|
"description": "TransactionEntity ID or name. If the name doesn't exist, a new one will be created",
|
|
}
|
|
)
|
|
class TransactionEntityField(serializers.Field):
|
|
def to_representation(self, value):
|
|
return [{"id": entity.id, "name": entity.name} for entity in value.all()]
|
|
|
|
def to_internal_value(self, data):
|
|
entities = []
|
|
for item in data:
|
|
if isinstance(item, int):
|
|
try:
|
|
entity = TransactionEntity.objects.get(pk=item)
|
|
except TransactionEntity.DoesNotExist:
|
|
raise serializers.ValidationError(
|
|
_("Entity with this ID does not exist.")
|
|
)
|
|
elif isinstance(item, str):
|
|
try:
|
|
entity = TransactionEntity.objects.get(name=item)
|
|
except TransactionEntity.DoesNotExist:
|
|
entity = TransactionEntity(name=item)
|
|
entity.save()
|
|
else:
|
|
raise serializers.ValidationError(
|
|
_("Invalid entity data. Provide an ID or name.")
|
|
)
|
|
entities.append(entity)
|
|
return entities
|