Расширена статистика для разделов #22

This commit is contained in:
2026-05-28 13:49:08 +03:00
parent 2dac5e5102
commit 1986fd4694
20 changed files with 1189 additions and 71 deletions
+58 -4
View File
@@ -3,8 +3,10 @@
-export([create/3, get_by_id/1, get_active_by_user/1, list_by_user/1, list_all/0]).
-export([update_status/2, check_expired/0]).
-export([list_subscriptions/0, create_subscription/1, update_subscription/2, delete_subscription/1]).
-export([count_subscription/0]).
-export([count_subscriptions/0]).
-export([count_subscriptions_by_date/2]).
-export([count_subscriptions_by_plan/0, count_subscriptions_by_status/0,
count_trial_subscriptions/0, get_ending_paid_subscriptions/1]).
-define(TRIAL_DAYS, 30).
@@ -291,8 +293,8 @@ parse_iso_datetime(Other) -> Other.
%%% @doc Количество подписок.
%%% @end
%%%-------------------------------------------------------------------
-spec count_subscription() -> non_neg_integer().
count_subscription() ->
-spec count_subscriptions() -> non_neg_integer().
count_subscriptions() ->
mnesia:table_info(subscription, size).
%%%-------------------------------------------------------------------
@@ -314,4 +316,56 @@ count_subscriptions_by_date(From, To) ->
end, [], Filtered),
lists:sort(Counts).
date_part({{Y,M,D}, _}) -> {Y,M,D}.
date_part({{Y,M,D}, _}) -> {Y,M,D}.
%%%-------------------------------------------------------------------
%%% @doc Подсчёт подписок по планам.
%%% @end
%%%-------------------------------------------------------------------
-spec count_subscriptions_by_plan() -> [{atom(), non_neg_integer()}].
count_subscriptions_by_plan() ->
Subs = mnesia:dirty_match_object(#subscription{_ = '_'}),
lists:foldl(fun(#subscription{plan = Plan}, Acc) ->
case lists:keyfind(Plan, 1, Acc) of
false -> [{Plan, 1} | Acc];
{Plan, C} -> lists:keyreplace(Plan, 1, Acc, {Plan, C+1})
end
end, [], Subs).
%%%-------------------------------------------------------------------
%%% @doc Подсчёт подписок по статусам.
%%% @end
%%%-------------------------------------------------------------------
-spec count_subscriptions_by_status() -> [{atom(), non_neg_integer()}].
count_subscriptions_by_status() ->
Subs = mnesia:dirty_match_object(#subscription{_ = '_'}),
lists:foldl(fun(#subscription{status = Status}, Acc) ->
case lists:keyfind(Status, 1, Acc) of
false -> [{Status, 1} | Acc];
{Status, C} -> lists:keyreplace(Status, 1, Acc, {Status, C+1})
end
end, [], Subs).
%%%-------------------------------------------------------------------
%%% @doc Количество пробных подписок (trial_used = false).
%%% @end
%%%-------------------------------------------------------------------
-spec count_trial_subscriptions() -> non_neg_integer().
count_trial_subscriptions() ->
Match = #subscription{trial_used = false, _ = '_'},
length(mnesia:dirty_match_object(Match)).
%%%-------------------------------------------------------------------
%%% @doc Платные подписки (trial_used = true), истекающие в течение Days дней.
%%% @end
%%%-------------------------------------------------------------------
-spec get_ending_paid_subscriptions(Days :: non_neg_integer()) -> [#subscription{}].
get_ending_paid_subscriptions(Days) ->
NowSec = calendar:datetime_to_gregorian_seconds(calendar:universal_time()),
ThresholdSec = NowSec + Days * 86400,
Match = #subscription{status = active, trial_used = true, _ = '_'},
ActivePaid = mnesia:dirty_match_object(Match),
lists:filter(fun(#subscription{expires_at = Exp}) ->
ExpSec = calendar:datetime_to_gregorian_seconds(Exp),
ExpSec >= NowSec andalso ExpSec =< ThresholdSec
end, ActivePaid).