from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from account.serializers.common import UserShortSerializer from establishment import models from establishment import serializers as model_serializers from establishment.models import ContactPhone from gallery.models import Image from location.models import Address from location.serializers import AddressDetailSerializer, TranslatedField from main.models import Currency from main.serializers import AwardSerializer from utils.decorators import with_base_attributes from utils.serializers import TimeZoneChoiceField def phones_handler(phones_list, establishment): """ create or update phones for establishment 35016 string """ ContactPhone.objects.filter(establishment=establishment).delete() for new_phone in phones_list: ContactPhone.objects.create(establishment=establishment, phone=new_phone) class EstablishmentListCreateSerializer(model_serializers.EstablishmentBaseSerializer): """Establishment create serializer""" type_id = serializers.PrimaryKeyRelatedField( source='establishment_type', queryset=models.EstablishmentType.objects.all(), write_only=True ) address_id = serializers.PrimaryKeyRelatedField( source='address', queryset=models.Address.objects.all(), write_only=True ) phones = model_serializers.ContactPhonesSerializer(read_only=True, many=True, ) emails = model_serializers.ContactEmailsSerializer(read_only=True, many=True, ) socials = model_serializers.SocialNetworkRelatedSerializers(read_only=True, many=True, ) type = model_serializers.EstablishmentTypeBaseSerializer(source='establishment_type', read_only=True) address_id = serializers.PrimaryKeyRelatedField(write_only=True, source='address', queryset=Address.objects.all()) tz = TimeZoneChoiceField() phones_list = serializers.ListField( child=serializers.CharField(max_length=20), allow_empty=True, write_only=True, ) class Meta: model = models.Establishment fields = [ 'id', 'name', 'transliterated_name', 'index_name', 'website', 'phones', 'emails', 'price_level', 'toque_number', 'type_id', 'type', 'socials', 'image_url', 'slug', # TODO: check in admin filters 'is_publish', 'guestonline_id', 'lastable_id', 'tags', 'tz', 'address_id', 'phones_list', ] def create(self, validated_data): phones_list = validated_data.pop('phones_list') instance = super().create(validated_data) phones_handler(phones_list, instance) return instance class EstablishmentRUDSerializer(model_serializers.EstablishmentBaseSerializer): """Establishment create serializer""" type_id = serializers.PrimaryKeyRelatedField( source='establishment_type', queryset=models.EstablishmentType.objects.all(), write_only=True ) address = AddressDetailSerializer() phones = model_serializers.ContactPhonesSerializer(read_only=False, many=True, ) emails = model_serializers.ContactEmailsSerializer(read_only=False, many=True, ) socials = model_serializers.SocialNetworkRelatedSerializers(read_only=False, many=True, ) type = model_serializers.EstablishmentTypeBaseSerializer(source='establishment_type') phones_list = serializers.ListField( child=serializers.CharField(max_length=20), allow_empty=True, write_only=True, ) class Meta: model = models.Establishment fields = [ 'id', 'name', 'website', 'phones', 'emails', 'price_level', 'toque_number', 'type_id', 'type', 'socials', 'image_url', # TODO: check in admin filters 'is_publish', 'address', 'tags', 'phones_list', ] def update(self, instance, validated_data): phones_list = validated_data.pop('phones_list') instance = super().update(instance, validated_data) phones_handler(phones_list, instance) return instance class SocialChoiceSerializers(serializers.ModelSerializer): """SocialChoice serializers.""" class Meta: model = models.SocialChoice fields = '__all__' class SocialNetworkSerializers(serializers.ModelSerializer): """Social network serializers.""" class Meta: model = models.SocialNetwork fields = [ 'id', 'establishment', 'network', 'url', ] class PlatesSerializers(model_serializers.PlateSerializer): """Plates serializers.""" currency_id = serializers.PrimaryKeyRelatedField( source='currency', queryset=Currency.objects.all(), write_only=True ) class Meta: """Meta class.""" model = models.Plate fields = model_serializers.PlateSerializer.Meta.fields + [ 'name', 'currency_id', 'menu' ] class ContactPhoneBackSerializers(model_serializers.PlateSerializer): """ContactPhone serializers.""" class Meta: model = models.ContactPhone fields = [ 'id', 'establishment', 'phone' ] class ContactEmailBackSerializers(model_serializers.PlateSerializer): """ContactEmail serializers.""" class Meta: model = models.ContactEmail fields = [ 'id', 'establishment', 'email' ] class PositionBackSerializer(serializers.ModelSerializer): """Position Back serializer.""" name_translated = TranslatedField() class Meta: model = models.Position fields = [ 'id', 'name_translated', 'priority', 'index_name', ] # TODO: test decorator @with_base_attributes class EmployeeBackSerializers(serializers.ModelSerializer): """Employee serializers.""" public_mark = serializers.SerializerMethodField() positions = serializers.SerializerMethodField() establishment = serializers.SerializerMethodField() awards = AwardSerializer(many=True, read_only=True) def get_public_mark(self, obj): """Get last list actual public_mark""" qs = obj.establishmentemployee_set.actual().order_by('-from_date') \ .values('establishment__public_mark').first() return qs['establishment__public_mark'] if qs else None def get_positions(self, obj): """Get last list actual positions""" est_id = obj.establishmentemployee_set.actual(). \ order_by('-from_date').first() if not est_id: return None qs = obj.establishmentemployee_set.actual() \ .filter(establishment_id=est_id.establishment_id) \ .prefetch_related('position').values('position') positions = models.Position.objects.filter(id__in=[q['position'] for q in qs]) return [PositionBackSerializer(p).data for p in positions] def get_establishment(self, obj): """Get last actual establishment""" est = obj.establishmentemployee_set.actual().order_by('-from_date') \ .first() if not est: return None return { "id": est.establishment.id, "slug": est.establishment.slug } class Meta: model = models.Employee fields = [ 'id', 'name', 'last_name', 'user', 'public_mark', 'positions', 'awards', 'establishment', 'sex', 'birth_date', 'email', 'phone', 'toque_number' ] class EstablishmentEmployeeBackSerializer(serializers.ModelSerializer): """Establishment Employee serializer.""" employee = EmployeeBackSerializers() position = PositionBackSerializer() class Meta: model = models.EstablishmentEmployee fields = [ 'id', 'employee', 'from_date', 'to_date', 'position', 'status', ] class EstablishmentBackOfficeGallerySerializer(serializers.ModelSerializer): """Serializer class for model EstablishmentGallery.""" class Meta: """Meta class""" model = models.EstablishmentGallery fields = [ 'id', 'is_main', ] @property def request_kwargs(self): """Get url kwargs from request.""" return self.context.get('request').parser_context.get('kwargs') def validate(self, attrs): """Override validate method.""" establishment_pk = self.request_kwargs.get('pk') establishment_slug = self.request_kwargs.get('slug') search_kwargs = {'pk': establishment_pk} if establishment_pk else {'slug': establishment_slug} image_id = self.request_kwargs.get('image_id') establishment_qs = models.Establishment.objects.filter(**search_kwargs) image_qs = Image.objects.filter(id=image_id) if not establishment_qs.exists(): raise serializers.ValidationError({'detail': _('Establishment not found')}) if not image_qs.exists(): raise serializers.ValidationError({'detail': _('Image not found')}) establishment = establishment_qs.first() image = image_qs.first() if image in establishment.gallery.all(): raise serializers.ValidationError({'detail': _('Image is already added.')}) attrs['establishment'] = establishment attrs['image'] = image return attrs class EstablishmentCompanyListCreateSerializer(model_serializers.CompanyBaseSerializer): """Serializer for linking page w/ advertisement.""" class Meta(model_serializers.CompanyBaseSerializer.Meta): """Meta class.""" model_serializers.CompanyBaseSerializer.Meta.extra_kwargs.update({ 'establishment': {'required': False} }) def create(self, validated_data): """Overridden create method.""" validated_data['establishment'] = self.context.get('view').get_object() return super().create(validated_data) class EstablishmentNoteBaseSerializer(serializers.ModelSerializer): """Serializer for model EstablishmentNote.""" user_detail = UserShortSerializer(read_only=True, source='user') class Meta: """Meta class.""" model = models.EstablishmentNote fields = [ 'id', 'created', 'modified', 'text', 'user', 'user_detail', 'establishment', ] extra_kwargs = { 'created': {'read_only': True}, 'modified': {'read_only': True}, 'establishment': {'required': False, 'write_only': True}, 'user': {'required': False, 'write_only': True}, } @property def serializer_view(self): """Return view instance.""" return self.context.get('view') class EstablishmentNoteListCreateSerializer(EstablishmentNoteBaseSerializer): """Serializer for List|Create action for model EstablishmentNote.""" def create(self, validated_data): """Overridden create method.""" validated_data['user'] = self.user validated_data['establishment'] = self.establishment return super().create(validated_data) @property def user(self): """Return user instance from view.""" if self.serializer_view: return self.serializer_view.request.user @property def establishment(self): """Return establishment instance from view.""" if self.serializer_view: return self.serializer_view.get_object() class EstablishmentAdminListSerializer(UserShortSerializer): """Establishment admin serializer.""" class Meta: model = UserShortSerializer.Meta.model fields = [ 'id', 'username', 'email' ]