-module(handler_bookings). -include("records.hrl"). -export([init/2]). init(Req, Opts) -> handle(Req, Opts). handle(Req, _Opts) -> case cowboy_req:method(Req) of <<"POST">> -> create_booking(Req); <<"GET">> -> list_bookings(Req); _ -> send_error(Req, 405, <<"Method not allowed">>) end. %% POST /v1/events/:id/bookings - создание бронирования (запись на событие) create_booking(Req) -> case handler_auth:authenticate(Req) of {ok, UserId, Req1} -> EventId = cowboy_req:binding(id, Req1), case logic_booking:create_booking(UserId, EventId) of {ok, Booking} -> Response = booking_to_json(Booking), send_json(Req1, 201, Response); {error, already_booked} -> send_error(Req1, 409, <<"Already booked">>); {error, event_full} -> send_error(Req1, 400, <<"Event is full">>); {error, event_not_active} -> send_error(Req1, 400, <<"Event is not active">>); {error, access_denied} -> send_error(Req1, 403, <<"Access denied">>); {error, not_found} -> send_error(Req1, 404, <<"Event not found">>); {error, _} -> send_error(Req1, 500, <<"Internal server error">>) end; {error, Code, Message, Req1} -> send_error(Req1, Code, Message) end. %% GET /v1/events/:id/bookings - список бронирований события (для владельца) list_bookings(Req) -> case handler_auth:authenticate(Req) of {ok, UserId, Req1} -> EventId = cowboy_req:binding(id, Req1), case logic_booking:list_event_bookings(UserId, EventId) of {ok, Bookings} -> Response = [booking_to_json(B) || B <- Bookings], send_json(Req1, 200, Response); {error, access_denied} -> send_error(Req1, 403, <<"Access denied">>); {error, not_found} -> send_error(Req1, 404, <<"Event not found">>); {error, _} -> send_error(Req1, 500, <<"Internal server error">>) end; {error, Code, Message, Req1} -> send_error(Req1, Code, Message) end. %% Вспомогательные функции booking_to_json(Booking) -> #{ id => Booking#booking.id, event_id => Booking#booking.event_id, user_id => Booking#booking.user_id, status => Booking#booking.status, confirmed_at => case Booking#booking.confirmed_at of undefined -> null; Dt -> datetime_to_iso8601(Dt) end, created_at => datetime_to_iso8601(Booking#booking.created_at), updated_at => datetime_to_iso8601(Booking#booking.updated_at) }. datetime_to_iso8601({{Year, Month, Day}, {Hour, Minute, Second}}) -> iolist_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0BZ", [Year, Month, Day, Hour, Minute, Second])). send_json(Req, Status, Data) -> Body = jsx:encode(Data), cowboy_req:reply(Status, #{<<"content-type">> => <<"application/json">>}, Body, Req), {ok, Body, []}. send_error(Req, Status, Message) -> Body = jsx:encode(#{error => Message}), cowboy_req:reply(Status, #{<<"content-type">> => <<"application/json">>}, Body, Req), {ok, Body, []}.