from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from apps.bookings.models import Booking, BookingStatus from apps.bookings.services import validate_booking_request from apps.salons.models import Service, StaffProfile class BookingSerializer(serializers.ModelSerializer): salon_name = serializers.CharField(source="salon.name", read_only=True) service_name = serializers.CharField(source="service.name", read_only=True) staff_name = serializers.SerializerMethodField() class Meta: model = Booking fields = [ "id", "salon", "salon_name", "service", "service_name", "staff", "staff_name", "start_time", "end_time", "status", "price_amount", "currency", "notes", "created_at", ] read_only_fields = ["id", "salon", "price_amount", "currency", "created_at"] def get_staff_name(self, obj): if not obj.staff: return None first = obj.staff.user.first_name or "" last = obj.staff.user.last_name or "" return (first + " " + last).strip() or obj.staff.user.email def validate(self, attrs): if not self.instance or "status" not in attrs: return attrs new_status = attrs["status"] old_status = self.instance.status if new_status == old_status: return attrs user = self.context["request"].user role = getattr(user, "role", None) if new_status == BookingStatus.CONFIRMED and role not in {"manager", "staff", "admin"}: raise serializers.ValidationError({"status": _("Only staff or managers can confirm bookings.")}) if new_status == BookingStatus.COMPLETED and role not in {"manager", "staff", "admin"}: raise serializers.ValidationError({"status": _("Only staff or managers can complete bookings.")}) if new_status == BookingStatus.CANCELLED and role not in {"manager", "staff", "admin", "customer"}: raise serializers.ValidationError({"status": _("You are not allowed to cancel this booking.")}) return attrs class BookingCreateSerializer(serializers.ModelSerializer): class Meta: model = Booking fields = ["service", "staff", "start_time", "end_time", "notes"] extra_kwargs = {"staff": {"required": True}} def validate(self, attrs): service: Service = attrs["service"] staff = attrs.get("staff") validate_booking_request(service, staff, attrs["start_time"], attrs["end_time"]) return attrs def create(self, validated_data): request = self.context["request"] service = validated_data["service"] return Booking.objects.create( salon=service.salon, customer=request.user, service=service, staff=validated_data.get("staff"), start_time=validated_data["start_time"], end_time=validated_data["end_time"], notes=validated_data.get("notes", ""), price_amount=service.price_amount, currency=service.currency, )