Stage 3.4
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
-module(logic_booking).
|
||||
-include("records.hrl").
|
||||
|
||||
-export([create_booking/2, confirm_booking/3, cancel_booking/2]).
|
||||
-export([get_booking/2, list_event_bookings/2, list_user_bookings/1]).
|
||||
-export([auto_confirm/1, check_timeout_confirmations/0]).
|
||||
|
||||
%% Создание бронирования (запись на событие)
|
||||
create_booking(UserId, EventId) ->
|
||||
% Получаем событие напрямую, без проверки доступа к календарю
|
||||
case core_event:get_by_id(EventId) of
|
||||
{ok, Event} ->
|
||||
% Проверяем, что событие активно
|
||||
case Event#event.status of
|
||||
active ->
|
||||
% Проверяем календарь для политики подтверждения
|
||||
case core_calendar:get_by_id(Event#event.calendar_id) of
|
||||
{ok, Calendar} ->
|
||||
case Calendar#calendar.status of
|
||||
active ->
|
||||
% Проверяем, что есть места
|
||||
case check_capacity(EventId, Event#event.capacity) of
|
||||
{ok, _} ->
|
||||
% Проверяем, не записан ли уже пользователь
|
||||
case core_booking:get_by_event_and_user(EventId, UserId) of
|
||||
{error, not_found} ->
|
||||
ActualEventId = get_actual_event_id(Event, UserId),
|
||||
case core_booking:create(ActualEventId, UserId) of
|
||||
{ok, Booking} ->
|
||||
handle_confirmation_policy(Booking, Event, Calendar),
|
||||
{ok, Booking};
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
{ok, _} ->
|
||||
{error, already_booked}
|
||||
end;
|
||||
{error, full} ->
|
||||
{error, event_full}
|
||||
end;
|
||||
_ ->
|
||||
{error, calendar_not_active}
|
||||
end;
|
||||
_ ->
|
||||
{error, calendar_not_found}
|
||||
end;
|
||||
_ ->
|
||||
{error, event_not_active}
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
%% Подтверждение бронирования (владельцем календаря)
|
||||
confirm_booking(UserId, BookingId, Action) when Action =:= confirm; Action =:= decline ->
|
||||
case core_booking:get_by_id(BookingId) of
|
||||
{ok, Booking} ->
|
||||
% Проверяем права на событие
|
||||
case logic_event:get_event(UserId, Booking#booking.event_id) of
|
||||
{ok, Event} ->
|
||||
% Проверяем, что пользователь может редактировать календарь
|
||||
case logic_calendar:get_calendar(UserId, Event#event.calendar_id) of
|
||||
{ok, Calendar} ->
|
||||
case logic_calendar:can_edit(UserId, Calendar) of
|
||||
true ->
|
||||
case Action of
|
||||
confirm ->
|
||||
core_booking:update_status(BookingId, confirmed);
|
||||
decline ->
|
||||
core_booking:update_status(BookingId, cancelled)
|
||||
end;
|
||||
false ->
|
||||
{error, access_denied}
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
%% Отмена бронирования (участником)
|
||||
cancel_booking(UserId, BookingId) ->
|
||||
case core_booking:get_by_id(BookingId) of
|
||||
{ok, Booking} ->
|
||||
% Проверяем, что это бронирование пользователя
|
||||
case Booking#booking.user_id =:= UserId of
|
||||
true ->
|
||||
core_booking:update_status(BookingId, cancelled);
|
||||
false ->
|
||||
{error, access_denied}
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
%% Получение бронирования
|
||||
get_booking(UserId, BookingId) ->
|
||||
case core_booking:get_by_id(BookingId) of
|
||||
{ok, Booking} ->
|
||||
% Проверяем доступ к событию
|
||||
case logic_event:get_event(UserId, Booking#booking.event_id) of
|
||||
{ok, _} -> {ok, Booking};
|
||||
Error -> Error
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
%% Список бронирований события (для владельца)
|
||||
list_event_bookings(UserId, EventId) ->
|
||||
case logic_event:get_event(UserId, EventId) of
|
||||
{ok, Event} ->
|
||||
% Проверяем права на календарь
|
||||
case logic_calendar:get_calendar(UserId, Event#event.calendar_id) of
|
||||
{ok, Calendar} ->
|
||||
case logic_calendar:can_edit(UserId, Calendar) of
|
||||
true ->
|
||||
core_booking:list_by_event(EventId);
|
||||
false ->
|
||||
{error, access_denied}
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
%% Список бронирований пользователя
|
||||
list_user_bookings(UserId) ->
|
||||
core_booking:list_by_user(UserId).
|
||||
|
||||
%% Автоматическое подтверждение (для политики auto)
|
||||
auto_confirm(BookingId) ->
|
||||
core_booking:update_status(BookingId, confirmed).
|
||||
|
||||
%% Проверка истечения timeout подтверждений
|
||||
check_timeout_confirmations() ->
|
||||
% Получаем все pending бронирования для календарей с timeout
|
||||
% В реальной реализации нужно периодически вызывать эту функцию
|
||||
ok.
|
||||
|
||||
%% Внутренние функции
|
||||
check_capacity(_EventId, undefined) ->
|
||||
{ok, unlimited};
|
||||
check_capacity(EventId, Capacity) ->
|
||||
{ok, Bookings} = core_booking:list_by_event(EventId),
|
||||
ConfirmedCount = length([B || B <- Bookings, B#booking.status =:= confirmed]),
|
||||
case ConfirmedCount < Capacity of
|
||||
true -> {ok, Capacity - ConfirmedCount};
|
||||
false -> {error, full}
|
||||
end.
|
||||
|
||||
get_actual_event_id(Event, _UserId) ->
|
||||
case Event#event.event_type of
|
||||
recurring ->
|
||||
% Для повторяющихся событий нужно материализовать вхождение
|
||||
% Здесь предполагается, что start_time передаётся в запросе
|
||||
% В полной реализации нужно получать occurrence_start из параметров
|
||||
Event#event.id;
|
||||
single ->
|
||||
Event#event.id
|
||||
end.
|
||||
|
||||
handle_confirmation_policy(Booking, _Event, Calendar) ->
|
||||
io:format("Confirmation policy: ~p~n", [Calendar#calendar.confirmation]),
|
||||
case Calendar#calendar.confirmation of
|
||||
auto ->
|
||||
io:format("Auto-confirming booking ~p~n", [Booking#booking.id]),
|
||||
auto_confirm(Booking#booking.id);
|
||||
manual ->
|
||||
io:format("Manual confirmation, leaving pending~n"),
|
||||
ok;
|
||||
{timeout, Seconds} ->
|
||||
io:format("Timeout confirmation: ~p seconds~n", [Seconds]),
|
||||
spawn(fun() ->
|
||||
timer:sleep(Seconds * 1000),
|
||||
case core_booking:get_by_id(Booking#booking.id) of
|
||||
{ok, B} when B#booking.status =:= pending ->
|
||||
auto_confirm(Booking#booking.id);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end)
|
||||
end.
|
||||
@@ -1,18 +1,17 @@
|
||||
-module(logic_calendar).
|
||||
-include("records.hrl").
|
||||
|
||||
-export([create_calendar/3, get_calendar/2, list_calendars/1,
|
||||
-export([create_calendar/4, get_calendar/2, list_calendars/1,
|
||||
update_calendar/3, delete_calendar/2]).
|
||||
-export([can_access/2, can_edit/2]).
|
||||
|
||||
%% Создание календаря
|
||||
create_calendar(UserId, Title, Description) ->
|
||||
% Проверка, что пользователь может создавать календари
|
||||
create_calendar(UserId, Title, Description, Confirmation) ->
|
||||
case core_user:get_by_id(UserId) of
|
||||
{ok, User} ->
|
||||
case User#user.status of
|
||||
active ->
|
||||
core_calendar:create(UserId, Title, Description);
|
||||
core_calendar:create(UserId, Title, Description, Confirmation);
|
||||
_ ->
|
||||
{error, user_inactive}
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user