inital commit

This commit is contained in:
2026-04-10 20:51:43 -05:00
parent cd1f2eae29
commit 562a8525d0
85 changed files with 4820 additions and 2 deletions

114
booking/serializers.py Normal file
View File

@@ -0,0 +1,114 @@
from rest_framework import serializers
from adventrues.models import AdventureOffering
from equipment.models import EquipmentItem
from marketing.models import ListingClick
from marketing.services import listing_click_valid_for_booking
from .models import Booking, BookingEventLog
from .services import create_booking_request, quote_booking
class BookingEventLogSerializer(serializers.ModelSerializer):
actor_email = serializers.EmailField(source="actor.email", read_only=True)
class Meta:
model = BookingEventLog
fields = ("id", "from_status", "to_status", "note", "actor_email", "created_at")
class BookingSerializer(serializers.ModelSerializer):
customer_email = serializers.EmailField(source="customer.email", read_only=True)
vendor_slug = serializers.CharField(source="vendor.slug", read_only=True)
equipment_public_id = serializers.CharField(source="equipment_item.public_id", read_only=True)
adventure_public_id = serializers.CharField(source="adventure_offering.public_id", read_only=True)
events = BookingEventLogSerializer(many=True, read_only=True)
class Meta:
model = Booking
fields = (
"id",
"customer_email",
"vendor_slug",
"equipment_item",
"equipment_public_id",
"adventure_public_id",
"starts_at",
"ends_at",
"status",
"total_price",
"customer_notes",
"vendor_notes",
"events",
"listing_click",
"created_at",
"updated_at",
)
read_only_fields = ("status", "total_price", "created_at", "updated_at", "events", "listing_click")
class BookingCreateSerializer(serializers.Serializer):
equipment_item_id = serializers.PrimaryKeyRelatedField(
queryset=EquipmentItem.objects.filter(is_active=True),
required=False,
allow_null=True,
)
adventure_offering_id = serializers.PrimaryKeyRelatedField(
queryset=AdventureOffering.objects.filter(is_active=True),
required=False,
allow_null=True,
)
starts_at = serializers.DateTimeField()
ends_at = serializers.DateTimeField()
customer_notes = serializers.CharField(required=False, allow_blank=True)
participants_count = serializers.IntegerField(required=False, min_value=1, default=1)
marketing_click_id = serializers.IntegerField(required=False, allow_null=True)
def validate(self, attrs):
equipment_item = attrs.get("equipment_item_id")
adventure_offering = attrs.get("adventure_offering_id")
if bool(equipment_item) == bool(adventure_offering):
raise serializers.ValidationError("Provide exactly one target: equipment_item_id or adventure_offering_id.")
click_id = attrs.get("marketing_click_id")
listing_click = None
if click_id is not None:
listing_click = ListingClick.objects.filter(pk=click_id).first()
if not listing_click:
raise serializers.ValidationError({"marketing_click_id": "Invalid marketing_click_id."})
if not listing_click_valid_for_booking(
click=listing_click,
equipment_item=equipment_item,
adventure_offering=adventure_offering,
):
raise serializers.ValidationError(
{"marketing_click_id": "Click does not match this listing or is outside the attribution window."}
)
attrs["_listing_click"] = listing_click
try:
quote_booking(
equipment_item=equipment_item,
adventure_offering=adventure_offering,
starts_at=attrs["starts_at"],
ends_at=attrs["ends_at"],
participants_count=attrs.get("participants_count", 1),
)
except Exception as exc:
raise serializers.ValidationError(str(exc)) from exc
return attrs
def create(self, validated_data):
try:
booking = create_booking_request(
customer=self.context["request"].user,
starts_at=validated_data["starts_at"],
ends_at=validated_data["ends_at"],
equipment_item=validated_data.get("equipment_item_id"),
adventure_offering=validated_data.get("adventure_offering_id"),
participants_count=validated_data.get("participants_count", 1),
customer_notes=validated_data.get("customer_notes", ""),
listing_click=validated_data.get("_listing_click"),
)
except Exception as exc:
raise serializers.ValidationError({"non_field_errors": [str(exc)]}) from exc
return booking