feat(booking): materialize occurrence on POST bookings. Refs EventHub/EventHubBack#67
This commit is contained in:
@@ -45,12 +45,29 @@ trails() ->
|
||||
schema => #{type => string}
|
||||
}
|
||||
],
|
||||
requestBody => #{
|
||||
required => false,
|
||||
content => #{
|
||||
<<"application/json">> => #{
|
||||
schema => #{
|
||||
type => object,
|
||||
properties => #{
|
||||
occurrence_start => #{
|
||||
type => string,
|
||||
format => <<"date-time">>,
|
||||
description => <<"Required for recurring masters">>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responses => #{
|
||||
201 => #{
|
||||
description => <<"Booking created">>,
|
||||
content => #{<<"application/json">> => #{schema => BookingSchema}}
|
||||
},
|
||||
400 => #{description => <<"Event is full or not active">>},
|
||||
400 => #{description => <<"Event is full, not active, or occurrence_start missing/invalid">>},
|
||||
403 => #{description => <<"Access denied">>},
|
||||
404 => #{description => <<"Event not found">>},
|
||||
409 => #{description => <<"Already booked">>}
|
||||
@@ -111,29 +128,39 @@ create_booking(Req) ->
|
||||
case handler_utils:auth_user(Req) of
|
||||
{ok, UserId, Req1} ->
|
||||
EventId = cowboy_req:binding(id, Req1),
|
||||
case logic_booking:create_booking(UserId, EventId) of
|
||||
{ok, Booking} ->
|
||||
handler_utils:send_json(Req1, 201, booking_to_json(Booking));
|
||||
{error, already_booked} ->
|
||||
handler_utils:send_error(Req1, 409, <<"Already booked">>);
|
||||
{error, full} ->
|
||||
handler_utils:send_error(Req1, 400, <<"Event is full">>);
|
||||
{error, event_full} ->
|
||||
handler_utils:send_error(Req1, 400, <<"Event is full">>);
|
||||
{error, event_not_active} ->
|
||||
handler_utils:send_error(Req1, 400, <<"Event is not active">>);
|
||||
{error, personal_calendar} ->
|
||||
handler_utils:send_error(Req1, 403, <<"personal_calendar">>);
|
||||
{error, subscription_inactive} ->
|
||||
handler_utils:send_error(Req1, 403, <<"subscription_inactive">>);
|
||||
{error, own_event} ->
|
||||
handler_utils:send_error(Req1, 403, <<"Cannot book own event">>);
|
||||
{error, access_denied} ->
|
||||
handler_utils:send_error(Req1, 403, <<"Access denied">>);
|
||||
{error, not_found} ->
|
||||
handler_utils:send_error(Req1, 404, <<"Event not found">>);
|
||||
{error, _} ->
|
||||
handler_utils:send_error(Req1, 500, <<"Internal server error">>)
|
||||
{ok, Body, Req2} = cowboy_req:read_body(Req1),
|
||||
case parse_occurrence_start(Body) of
|
||||
{error, invalid_occurrence} ->
|
||||
handler_utils:send_error(Req2, 400, <<"Invalid occurrence_start">>);
|
||||
{ok, OccurrenceStart} ->
|
||||
case logic_booking:create_booking(UserId, EventId, OccurrenceStart) of
|
||||
{ok, Booking} ->
|
||||
handler_utils:send_json(Req2, 201, booking_to_json(Booking));
|
||||
{error, already_booked} ->
|
||||
handler_utils:send_error(Req2, 409, <<"Already booked">>);
|
||||
{error, full} ->
|
||||
handler_utils:send_error(Req2, 400, <<"Event is full">>);
|
||||
{error, event_full} ->
|
||||
handler_utils:send_error(Req2, 400, <<"Event is full">>);
|
||||
{error, event_not_active} ->
|
||||
handler_utils:send_error(Req2, 400, <<"Event is not active">>);
|
||||
{error, occurrence_start_required} ->
|
||||
handler_utils:send_error(Req2, 400, <<"occurrence_start required">>);
|
||||
{error, invalid_occurrence} ->
|
||||
handler_utils:send_error(Req2, 400, <<"Invalid occurrence_start">>);
|
||||
{error, personal_calendar} ->
|
||||
handler_utils:send_error(Req2, 403, <<"personal_calendar">>);
|
||||
{error, subscription_inactive} ->
|
||||
handler_utils:send_error(Req2, 403, <<"subscription_inactive">>);
|
||||
{error, own_event} ->
|
||||
handler_utils:send_error(Req2, 403, <<"Cannot book own event">>);
|
||||
{error, access_denied} ->
|
||||
handler_utils:send_error(Req2, 403, <<"Access denied">>);
|
||||
{error, not_found} ->
|
||||
handler_utils:send_error(Req2, 404, <<"Event not found">>);
|
||||
{error, _} ->
|
||||
handler_utils:send_error(Req2, 500, <<"Internal server error">>)
|
||||
end
|
||||
end;
|
||||
{error, Code, Message, Req1} ->
|
||||
handler_utils:send_error(Req1, Code, Message)
|
||||
@@ -167,4 +194,28 @@ list_bookings(Req) ->
|
||||
%% @private Формирует JSON-представление записи #booking{}.
|
||||
-spec booking_to_json(#booking{}) -> map().
|
||||
booking_to_json(Booking) ->
|
||||
handler_utils:booking_to_json(Booking).
|
||||
handler_utils:booking_to_json(Booking).
|
||||
|
||||
-spec parse_occurrence_start(binary()) ->
|
||||
{ok, calendar:datetime() | undefined} | {error, invalid_occurrence}.
|
||||
parse_occurrence_start(<<>>) ->
|
||||
{ok, undefined};
|
||||
parse_occurrence_start(Body) ->
|
||||
try jsx:decode(Body, [return_maps]) of
|
||||
Map when is_map(Map) ->
|
||||
case maps:get(<<"occurrence_start">>, Map, undefined) of
|
||||
undefined ->
|
||||
{ok, undefined};
|
||||
Iso when is_binary(Iso) ->
|
||||
case handler_utils:parse_datetime(Iso) of
|
||||
{ok, Dt} -> {ok, Dt};
|
||||
{error, _} -> {error, invalid_occurrence}
|
||||
end;
|
||||
_ ->
|
||||
{error, invalid_occurrence}
|
||||
end;
|
||||
_ ->
|
||||
{ok, undefined}
|
||||
catch
|
||||
_:_ -> {error, invalid_occurrence}
|
||||
end.
|
||||
Reference in New Issue
Block a user