You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
9.5 KiB
367 lines
9.5 KiB
from generic_relations.relations import GenericRelatedField
|
|
from rest_framework import serializers
|
|
from rest_framework.serializers import ModelSerializer, ImageField, FileField, PrimaryKeyRelatedField, ListSerializer
|
|
|
|
from common.serializers import LocationSerializer, ContentTypeSerializer
|
|
from specializations.serializers import SpecializationSerializer
|
|
from users.models import User, Team
|
|
from users.serializers import UserSerializer, TeamSerializer
|
|
from .models import Project, Realty, BuildingClassfication, ConstructionType, Order, Stage, Portfolio, PortfolioPhoto, \
|
|
Answer, AnswerFile
|
|
|
|
|
|
class AnswerFileSerializer(ModelSerializer):
|
|
file = FileField()
|
|
|
|
class Meta:
|
|
model = AnswerFile
|
|
|
|
fields = (
|
|
'file',
|
|
'id',
|
|
'name',
|
|
# 'answer',
|
|
)
|
|
|
|
|
|
class PortfolioPhotoSerializer(ModelSerializer):
|
|
img = ImageField()
|
|
portfolio_id = PrimaryKeyRelatedField(read_only=True, source='portfolio')
|
|
|
|
class Meta:
|
|
model = PortfolioPhoto
|
|
|
|
fields = (
|
|
'id',
|
|
'img',
|
|
'portfolio_id',
|
|
)
|
|
|
|
|
|
class BuildingClassficationSerializer(ModelSerializer):
|
|
class Meta:
|
|
model = BuildingClassfication
|
|
|
|
fields = (
|
|
'id',
|
|
'name',
|
|
)
|
|
|
|
|
|
class NestedBuildingClassificationSerializerOnlyId(ModelSerializer):
|
|
class Meta:
|
|
model = BuildingClassfication
|
|
|
|
fields = (
|
|
'id',
|
|
)
|
|
|
|
|
|
class BuildingClassificationSerializeFlat(ModelSerializer):
|
|
children = NestedBuildingClassificationSerializerOnlyId(many=True)
|
|
parent = NestedBuildingClassificationSerializerOnlyId()
|
|
|
|
class Meta:
|
|
model = BuildingClassfication
|
|
|
|
fields = (
|
|
'id',
|
|
'name',
|
|
'children',
|
|
'parent')
|
|
|
|
|
|
class ConstructionTypeSerializer(ModelSerializer):
|
|
class Meta:
|
|
model = ConstructionType
|
|
|
|
fields = (
|
|
'id',
|
|
'name',
|
|
)
|
|
|
|
|
|
class RealtySerializer(ModelSerializer):
|
|
building_classification = BuildingClassficationSerializer()
|
|
construction_type = ConstructionTypeSerializer()
|
|
location = LocationSerializer()
|
|
user = UserSerializer()
|
|
|
|
class Meta:
|
|
model = Realty
|
|
|
|
fields = (
|
|
'id',
|
|
'name',
|
|
|
|
'building_classification',
|
|
'construction_type',
|
|
'location',
|
|
'user',
|
|
)
|
|
|
|
|
|
class StageListSerializer(ListSerializer):
|
|
def update(self, instance, validated_data):
|
|
# Maps for id->instance and id->data item.
|
|
# print("instance = ", instance)
|
|
# print("validated_data = ", validated_data)
|
|
obj_mapping = {obj.id: obj for obj in instance}
|
|
data_mapping = {item['id']: item for item in validated_data}
|
|
|
|
# Perform creations and updates.
|
|
# print("obj_mapping = ", obj_mapping)
|
|
# print("data_mapping = ", data_mapping)
|
|
ret = []
|
|
for obj_id, data in data_mapping.items():
|
|
obj = obj_mapping.get(obj_id, None)
|
|
if obj is None:
|
|
ret.append(self.child.create(data))
|
|
else:
|
|
ret.append(self.child.update(obj, data))
|
|
|
|
# Perform deletions.
|
|
for obj_id, obj in obj_mapping.items():
|
|
if obj_id not in data_mapping:
|
|
obj.delete()
|
|
|
|
return ret
|
|
|
|
|
|
class StageSerializer(ModelSerializer):
|
|
term = serializers.DateField(format="%d.%m.%Y", input_formats=['%d.%m.%Y', ])
|
|
|
|
def validate(self, data):
|
|
if 'pos' in data and data['pos'] > 1:
|
|
pos = data['pos'] - 1
|
|
stage_last = Stage.objects.filter(order=data['order'], pos=pos)
|
|
if stage_last:
|
|
stage_last = stage_last[0]
|
|
if stage_last.term > data['term']:
|
|
raise serializers.ValidationError({'term': 'Дата не должна быть меньше даты предыдущео этапа'})
|
|
return data
|
|
|
|
class Meta:
|
|
model = Stage
|
|
|
|
fields = (
|
|
'id',
|
|
'cost',
|
|
'cost_type',
|
|
'term',
|
|
'term_type',
|
|
'name',
|
|
'order',
|
|
'result',
|
|
'pos',
|
|
'status',
|
|
'is_paid',
|
|
'close_contractor',
|
|
'close_customer',
|
|
|
|
)
|
|
|
|
list_serializer_class = StageListSerializer
|
|
|
|
|
|
class OrderSerializer_(ModelSerializer):
|
|
contractor = UserSerializer()
|
|
stages = StageSerializer(many=True)
|
|
team = TeamSerializer()
|
|
project_id = PrimaryKeyRelatedField(read_only=True, source='project')
|
|
|
|
class Meta:
|
|
model = Order
|
|
|
|
fields = (
|
|
'created',
|
|
'id',
|
|
'secure',
|
|
'status',
|
|
|
|
'contractor',
|
|
'project_id',
|
|
'stages',
|
|
'team',
|
|
)
|
|
|
|
|
|
class AnswerSerializer_(ModelSerializer):
|
|
project_id = PrimaryKeyRelatedField(read_only=True, source='project')
|
|
portfolio_ids = PrimaryKeyRelatedField(read_only=True, source='portfolios', many=True)
|
|
|
|
content_type = ContentTypeSerializer()
|
|
files = AnswerFileSerializer(many=True)
|
|
|
|
author = GenericRelatedField({
|
|
User: UserSerializer(),
|
|
Team: TeamSerializer()
|
|
})
|
|
|
|
class Meta:
|
|
model = Answer
|
|
|
|
fields = (
|
|
'budget',
|
|
'created',
|
|
'currency',
|
|
'id',
|
|
'is_archive',
|
|
'object_id',
|
|
'portfolio_ids',
|
|
'project_id',
|
|
'rejected',
|
|
'secure_deal_only',
|
|
'term',
|
|
'term_type',
|
|
|
|
'author', # Generic related field
|
|
'content_type',
|
|
'files',
|
|
)
|
|
|
|
|
|
class ProjectSerializer(ModelSerializer):
|
|
answers = AnswerSerializer_(many=True)
|
|
customer = UserSerializer()
|
|
order = OrderSerializer_() # TODO: Can't serialize a reverse/reciprocal relation
|
|
realty = RealtySerializer()
|
|
specialization = SpecializationSerializer()
|
|
|
|
class Meta:
|
|
model = Project
|
|
|
|
fields = (
|
|
'answers',
|
|
'budget',
|
|
'budget_by_agreement',
|
|
'created',
|
|
'cro',
|
|
'currency',
|
|
'customer',
|
|
'deal_type',
|
|
'id',
|
|
'name',
|
|
'order',
|
|
'price_and_term_required',
|
|
'realty',
|
|
'specialization',
|
|
'state',
|
|
'term',
|
|
'term_type',
|
|
'text',
|
|
'work_type',
|
|
)
|
|
|
|
|
|
class OrderSerializer(ModelSerializer):
|
|
stages = StageSerializer(many=True, read_only=True)
|
|
project = ProjectSerializer(read_only=True)
|
|
has_user_review = serializers.SerializerMethodField(read_only=True)
|
|
contractor_name = serializers.SerializerMethodField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Order
|
|
|
|
fields = (
|
|
'id',
|
|
'contractor',
|
|
'team',
|
|
'created',
|
|
'project',
|
|
'secure',
|
|
'status',
|
|
'has_user_review',
|
|
'stages',
|
|
'project',
|
|
'contractor_name',
|
|
)
|
|
|
|
def get_contractor_name(self, obj):
|
|
if obj.contractor:
|
|
return obj.contractor.get_full_name() or obj.contractor.username
|
|
elif obj.team:
|
|
return obj.team.owner.get_full_name() or obj.team.owner.username
|
|
else:
|
|
return 'Исполнитель не определен'
|
|
|
|
def get_has_user_review(self, obj):
|
|
"Имеет отзывы"
|
|
curr_user = self.context['request'].user
|
|
if curr_user.is_customer():
|
|
return curr_user.customer_reviews.filter(project=obj.project).exists()
|
|
elif curr_user.is_contractor():
|
|
if obj.team is None and obj.contractor:
|
|
return curr_user.contractor_reviews.filter(project=obj.project).exists()
|
|
elif curr_user.team:
|
|
return curr_user.team.team_reviews.filter(project=obj.project).exists()
|
|
else:
|
|
return False
|
|
|
|
|
|
class PortfolioSerializer(ModelSerializer):
|
|
# answers = AnswerSerializer(many=True)
|
|
building_classification = BuildingClassficationSerializer()
|
|
construction_type = ConstructionTypeSerializer()
|
|
location = LocationSerializer()
|
|
photos = PortfolioPhotoSerializer(many=True)
|
|
specialization = SpecializationSerializer()
|
|
user = UserSerializer()
|
|
|
|
class Meta:
|
|
model = Portfolio
|
|
|
|
fields = (
|
|
# 'answers',
|
|
'building_classification',
|
|
'construction_type',
|
|
'location',
|
|
'photos',
|
|
'specialization',
|
|
'user',
|
|
|
|
'budget',
|
|
'currency',
|
|
'description',
|
|
'id',
|
|
'name',
|
|
'term',
|
|
'term_type',
|
|
'worksell',
|
|
)
|
|
|
|
|
|
class AnswerSerializer(ModelSerializer):
|
|
content_type = ContentTypeSerializer()
|
|
files = AnswerFileSerializer(many=True)
|
|
portfolios = PortfolioSerializer(many=True)
|
|
project = ProjectSerializer()
|
|
|
|
author = GenericRelatedField({
|
|
User: UserSerializer(),
|
|
Team: TeamSerializer()
|
|
})
|
|
|
|
class Meta:
|
|
model = Answer
|
|
|
|
fields = (
|
|
'budget',
|
|
'created',
|
|
'currency',
|
|
'id',
|
|
'is_archive',
|
|
'object_id',
|
|
'rejected',
|
|
'secure_deal_only',
|
|
'term',
|
|
'term_type',
|
|
|
|
'author', # Generic related field
|
|
'content_type',
|
|
'files',
|
|
'portfolios',
|
|
'project',
|
|
|
|
# 'candidates',
|
|
)
|
|
|