feat(events): add booking_occupancy on event JSON for studio grid
Expose free|pending|confirmed so commercial calendar can aggregate slots by occupancy without N GET /bookings calls.
This commit is contained in:
@@ -339,10 +339,14 @@ parse_datetime_binary(Str) ->
|
|||||||
Dt.
|
Dt.
|
||||||
|
|
||||||
occurrence_to_json(Master, Occurrence) ->
|
occurrence_to_json(Master, Occurrence) ->
|
||||||
|
%% Virtual row: occupancy by master event id (materialized instances use event_to_json).
|
||||||
#{
|
#{
|
||||||
master_id => Master#event.id,
|
master_id => Master#event.id,
|
||||||
start_time => handler_utils:datetime_to_iso8601(Occurrence),
|
start_time => handler_utils:datetime_to_iso8601(Occurrence),
|
||||||
duration => Master#event.duration,
|
duration => Master#event.duration,
|
||||||
title => Master#event.title,
|
title => Master#event.title,
|
||||||
is_virtual => true
|
is_virtual => true,
|
||||||
}.
|
specialist_id => Master#event.specialist_id,
|
||||||
|
calendar_id => Master#event.calendar_id,
|
||||||
|
booking_occupancy => handler_utils:booking_occupancy(Master)
|
||||||
|
}.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
parse_datetime/1,
|
parse_datetime/1,
|
||||||
datetime_to_iso8601/1,
|
datetime_to_iso8601/1,
|
||||||
event_to_json/1,
|
event_to_json/1,
|
||||||
|
booking_occupancy/1,
|
||||||
user_to_json/1,
|
user_to_json/1,
|
||||||
review_to_json/1,
|
review_to_json/1,
|
||||||
review_to_json/2,
|
review_to_json/2,
|
||||||
@@ -300,6 +301,8 @@ audit_reason(#{<<"reason">> := R}) when is_binary(R) -> R;
|
|||||||
audit_reason(_) -> <<>>.
|
audit_reason(_) -> <<>>.
|
||||||
|
|
||||||
%% @doc Преобразует #event{} в JSON-карту.
|
%% @doc Преобразует #event{} в JSON-карту.
|
||||||
|
%% Добавляет booking_occupancy: free | pending | confirmed
|
||||||
|
%% (confirmed > pending > free; cancelled/expired и past-pending → не занятость).
|
||||||
-spec event_to_json(#event{}) -> map().
|
-spec event_to_json(#event{}) -> map().
|
||||||
event_to_json(Event) ->
|
event_to_json(Event) ->
|
||||||
LocationJson = case Event#event.location of
|
LocationJson = case Event#event.location of
|
||||||
@@ -337,9 +340,29 @@ event_to_json(Event) ->
|
|||||||
attachments => Event#event.attachments,
|
attachments => Event#event.attachments,
|
||||||
edit_history => Event#event.edit_history,
|
edit_history => Event#event.edit_history,
|
||||||
created_at => datetime_to_iso8601(Event#event.created_at),
|
created_at => datetime_to_iso8601(Event#event.created_at),
|
||||||
updated_at => datetime_to_iso8601(Event#event.updated_at)
|
updated_at => datetime_to_iso8601(Event#event.updated_at),
|
||||||
|
booking_occupancy => booking_occupancy(Event)
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
%% @doc Активная занятость слота для сетки commercial (Studio aggregate).
|
||||||
|
-spec booking_occupancy(#event{}) -> free | pending | confirmed.
|
||||||
|
booking_occupancy(#event{id = EventId, start_time = Start}) ->
|
||||||
|
{ok, Bookings} = core_booking:list_by_event(EventId),
|
||||||
|
Now = calendar:universal_time(),
|
||||||
|
lists:foldl(
|
||||||
|
fun(#booking{status = confirmed}, _Acc) ->
|
||||||
|
confirmed;
|
||||||
|
(#booking{status = pending}, Acc) ->
|
||||||
|
case Start > Now of
|
||||||
|
true when Acc =/= confirmed -> pending;
|
||||||
|
_ -> Acc
|
||||||
|
end;
|
||||||
|
(_, Acc) ->
|
||||||
|
Acc
|
||||||
|
end,
|
||||||
|
free,
|
||||||
|
Bookings).
|
||||||
|
|
||||||
%% @doc Преобразует #user{} в JSON-карту.
|
%% @doc Преобразует #user{} в JSON-карту.
|
||||||
-spec user_to_json(#user{}) -> map().
|
-spec user_to_json(#user{}) -> map().
|
||||||
user_to_json(User) ->
|
user_to_json(User) ->
|
||||||
|
|||||||
Reference in New Issue
Block a user