diff --git a/lib/mv_web/live/statistics_live.ex b/lib/mv_web/live/statistics_live.ex index edd416b..7264259 100644 --- a/lib/mv_web/live/statistics_live.ex +++ b/lib/mv_web/live/statistics_live.ex @@ -6,6 +6,8 @@ defmodule MvWeb.StatisticsLive do """ use MvWeb, :live_view + require Logger + import MvWeb.LiveHelpers, only: [current_actor: 1] alias Mv.Statistics alias Mv.MembershipFees.MembershipFeeType @@ -171,8 +173,15 @@ defmodule MvWeb.StatisticsLive do {:noreply, push_patch(socket, to: ~p"/statistics")} end - def handle_event("change_fee_type", %{"fee_type_id" => id}, socket) do - {:noreply, push_patch(socket, to: ~p"/statistics?fee_type_id=#{id}")} + def handle_event("change_fee_type", %{"fee_type_id" => id}, socket) when is_binary(id) do + trimmed = String.trim(id) + + to = + if trimmed == "", + do: ~p"/statistics", + else: ~p"/statistics" <> "?" <> URI.encode_query(%{"fee_type_id" => trimmed}) + + {:noreply, push_patch(socket, to: to)} end attr :joins_exits_by_year, :list, required: true @@ -187,11 +196,15 @@ defmodule MvWeb.StatisticsLive do sum = row.joins + row.exits bar_pct = - if max_total > 0 and sum > 0, do: Float.round(sum / max_total * 100, 1), else: 0 + if max_total > 0 and sum > 0 do + min(100.0, Float.round(sum / max_total * 100, 1)) + else + 0 + end seg_scale = max(sum, 1) - joins_pct = row.joins / seg_scale * 100 - exits_pct = row.exits / seg_scale * 100 + joins_pct = min(100.0, row.joins / seg_scale * 100) + exits_pct = min(100.0, row.exits / seg_scale * 100) %{ year: row.year, @@ -323,13 +336,25 @@ defmodule MvWeb.StatisticsLive do if Decimal.compare(sum_positive, 0) == :gt, do: sum_positive, else: Decimal.new(1) paid_pct = - row.paid |> Decimal.div(seg_scale) |> Decimal.mult(100) |> Decimal.to_float() + row.paid + |> Decimal.div(seg_scale) + |> Decimal.mult(100) + |> Decimal.to_float() + |> min(100.0) unpaid_pct = - row.unpaid |> Decimal.div(seg_scale) |> Decimal.mult(100) |> Decimal.to_float() + row.unpaid + |> Decimal.div(seg_scale) + |> Decimal.mult(100) + |> Decimal.to_float() + |> min(100.0) suspended_pct = - row.suspended |> Decimal.div(seg_scale) |> Decimal.mult(100) |> Decimal.to_float() + row.suspended + |> Decimal.div(seg_scale) + |> Decimal.mult(100) + |> Decimal.to_float() + |> min(100.0) %{ year: row.year, @@ -458,7 +483,8 @@ defmodule MvWeb.StatisticsLive do defp bar_pct(value, max) do scale = if Decimal.compare(max, 0) == :gt, do: max, else: Decimal.new(1) - value |> Decimal.div(scale) |> Decimal.mult(100) |> Decimal.to_float() + pct = value |> Decimal.div(scale) |> Decimal.mult(100) |> Decimal.to_float() + min(100.0, pct) end attr :cycle_totals, :map, required: true @@ -512,12 +538,19 @@ defmodule MvWeb.StatisticsLive do defp load_fee_types(socket) do actor = current_actor(socket) - fee_types = - MembershipFeeType - |> Ash.Query.sort(name: :asc) - |> Ash.read!(domain: Mv.MembershipFees, actor: actor) + case MembershipFeeType + |> Ash.Query.sort(name: :asc) + |> Ash.read(domain: Mv.MembershipFees, actor: actor) do + {:ok, fee_types} -> + assign(socket, :membership_fee_types, fee_types) - assign(socket, :membership_fee_types, fee_types) + {:error, reason} -> + Logger.warning("StatisticsLive: failed to load fee types: #{inspect(reason)}") + + socket + |> put_flash(:error, gettext("Fee types could not be loaded.")) + |> assign(:membership_fee_types, []) + end end defp load_statistics(socket) do