defmodule Ami.RecentActivity do use Ecto.Schema import Ecto.{ Changeset, Query } alias Ami.{ Repo, Community, CoursePeriod, User } schema "recent_activities" do @timestamps_opts [type: :naive_datetime_usec] field(:activity_time, :utc_datetime_usec) field(:update_count, :integer) belongs_to(:community, Community) belongs_to(:course_period, CoursePeriod) belongs_to(:user, User) end def track(%{"id" => community_id, "user_id" => user_id}) do case Repo.all( from( ra in __MODULE__, where: ra.community_id == ^community_id and ra.user_id == ^user_id, limit: 1 ) ) do [] -> create_activity(%{community_id: community_id, user_id: user_id}) [activity] -> update_activity(activity) end AmiWeb.Endpoint.broadcast!("community_activity_room:#{community_id}", "new_track", %{ "communityId" => community_id }) end def track(%{"course_period_id" => course_period_id, "user_id" => user_id}) do case Repo.all( from( ra in __MODULE__, where: ra.course_period_id == ^course_period_id and ra.user_id == ^user_id, limit: 1 ) ) do [] -> create_activity(%{course_period_id: course_period_id, user_id: user_id}) [activity] -> update_activity(activity) end AmiWeb.Endpoint.broadcast!("studygroup_activity_room:#{course_period_id}", "new_track", %{ "coursePeriodId" => course_period_id }) end def create_activity(%{community_id: _community_id, user_id: _user_id} = params) do %__MODULE__{} |> cast(params, [:community_id, :user_id]) |> cast(%{activity_time: DateTime.utc_now()}, [:activity_time]) |> Repo.insert() end def create_activity(%{course_period_id: _course_period_id, user_id: _user_id} = params) do %__MODULE__{} |> cast(params, [:course_period_id, :user_id]) |> cast(%{activity_time: DateTime.utc_now()}, [:activity_time]) |> Repo.insert() end def update_activity(activity) do change(activity, activity_time: DateTime.utc_now(), update_count: activity.update_count + 1) |> Repo.update() end def member_of_the_month(%{community: community_id}) do start_period = Timex.beginning_of_month(Timex.shift(DateTime.utc_now(), months: -1)) end_period = Timex.end_of_month(Timex.shift(DateTime.utc_now(), months: -1)) from( r in Ami.RecentActivity, where: r.community_id == ^community_id, where: r.activity_time >= ^start_period and r.activity_time <= ^end_period, order_by: [desc: r.update_count, desc: r.activity_time], select: r.user_id, limit: 1 ) |> Repo.all() |> List.first() end def member_of_the_month(%{course_period: course_period_id}) do start_period = Timex.beginning_of_month(Timex.shift(DateTime.utc_now(), months: -1)) end_period = Timex.end_of_month(Timex.shift(DateTime.utc_now(), months: -1)) from( r in Ami.RecentActivity, where: r.course_period_id == ^course_period_id, where: r.activity_time >= ^start_period and r.activity_time <= ^end_period, order_by: [desc: r.update_count, desc: r.activity_time], select: r.user_id, limit: 1 ) |> Repo.all() |> List.first() end def active_members_count(%Community{} = community) do from( r in Ami.RecentActivity, where: r.community_id == ^community.id, select: count(r.user_id, :distinct) ) |> Repo.one() end def active_members_count(%CoursePeriod{} = course_period) do from( r in Ami.RecentActivity, where: r.course_period_id == ^course_period.id, select: count(r.user_id, :distinct) ) |> Repo.one() end end