forked from shibao/cannery
		
	improve Ammo.get_round_count
This commit is contained in:
		@@ -185,25 +185,49 @@ defmodule Cannery.Ammo do
 | 
			
		||||
    |> Map.new()
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @type get_round_count_option :: {:type_id, Type.id() | nil} | {:container_id, Container.id()}
 | 
			
		||||
  @type get_round_count_options :: [get_round_count_option()]
 | 
			
		||||
 | 
			
		||||
  @doc """
 | 
			
		||||
  Gets the total number of rounds for a type
 | 
			
		||||
 | 
			
		||||
  ## Examples
 | 
			
		||||
 | 
			
		||||
      iex> get_round_count_for_type(
 | 
			
		||||
      ...>   %Type{id: 123, user_id: 456},
 | 
			
		||||
      ...>   %User{id: 456}
 | 
			
		||||
      ...> )
 | 
			
		||||
      iex> get_round_count(%User{id: 456}, type_id: 123)
 | 
			
		||||
      35
 | 
			
		||||
 | 
			
		||||
      iex> get_round_count(%User{id: 456}, container_id: 123)
 | 
			
		||||
      25
 | 
			
		||||
 | 
			
		||||
  """
 | 
			
		||||
  @spec get_round_count_for_type(Type.t(), User.t()) :: non_neg_integer()
 | 
			
		||||
  def get_round_count_for_type(%Type{id: type_id} = type, user) do
 | 
			
		||||
    [type]
 | 
			
		||||
    |> get_round_count_for_types(user)
 | 
			
		||||
    |> Map.get(type_id, 0)
 | 
			
		||||
  @spec get_round_count(User.t()) :: non_neg_integer()
 | 
			
		||||
  @spec get_round_count(User.t(), get_round_count_options()) :: non_neg_integer()
 | 
			
		||||
  def get_round_count(%User{id: user_id}, opts \\ []) do
 | 
			
		||||
    from(p in Pack,
 | 
			
		||||
      as: :p,
 | 
			
		||||
      where: p.user_id == ^user_id,
 | 
			
		||||
      select: sum(p.count),
 | 
			
		||||
      distinct: true
 | 
			
		||||
    )
 | 
			
		||||
    |> get_round_count_type_id(Keyword.get(opts, :type_id))
 | 
			
		||||
    |> get_round_count_container_id(Keyword.get(opts, :container_id))
 | 
			
		||||
    |> Repo.one() || 0
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @spec get_round_count_type_id(Queryable.t(), Type.id() | nil) :: Queryable.t()
 | 
			
		||||
  defp get_round_count_type_id(query, type_id) when type_id |> is_binary() do
 | 
			
		||||
    query |> where([p: p], p.type_id == ^type_id)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp get_round_count_type_id(query, _nil), do: query
 | 
			
		||||
 | 
			
		||||
  @spec get_round_count_container_id(Queryable.t(), Container.id() | nil) :: Queryable.t()
 | 
			
		||||
  defp get_round_count_container_id(query, container_id) when container_id |> is_binary() do
 | 
			
		||||
    query |> where([p: p], p.container_id == ^container_id)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp get_round_count_container_id(query, _nil), do: query
 | 
			
		||||
 | 
			
		||||
  @doc """
 | 
			
		||||
  Gets the total number of rounds for multiple types
 | 
			
		||||
 | 
			
		||||
@@ -670,25 +694,6 @@ defmodule Cannery.Ammo do
 | 
			
		||||
    query |> where([p: p], not (p.count == 0))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @doc """
 | 
			
		||||
  Returns number of rounds in a container.
 | 
			
		||||
 | 
			
		||||
  ## Examples
 | 
			
		||||
 | 
			
		||||
      iex> get_round_count_for_container(
 | 
			
		||||
      ...>   %Container{id: 123, user_id: 456},
 | 
			
		||||
      ...>   %User{id: 456}
 | 
			
		||||
      ...> )
 | 
			
		||||
      5
 | 
			
		||||
 | 
			
		||||
  """
 | 
			
		||||
  @spec get_round_count_for_container!(Container.t(), User.t()) :: non_neg_integer()
 | 
			
		||||
  def get_round_count_for_container!(%Container{id: container_id} = container, user) do
 | 
			
		||||
    [container]
 | 
			
		||||
    |> get_round_count_for_containers(user)
 | 
			
		||||
    |> Map.get(container_id, 0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  @doc """
 | 
			
		||||
  Returns number of ammo packs in multiple containers.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
 | 
			
		||||
      <span class="rounded-lg title text-lg">
 | 
			
		||||
        <%= gettext("Rounds:") %>
 | 
			
		||||
        <%= @container |> Ammo.get_round_count_for_container!(@current_user) %>
 | 
			
		||||
        <%= Ammo.get_round_count(@current_user, container_id: @container.id) %>
 | 
			
		||||
      </span>
 | 
			
		||||
    <% end %>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,15 +59,12 @@ defmodule CanneryWeb.ExportController do
 | 
			
		||||
    containers =
 | 
			
		||||
      Containers.list_containers(current_user)
 | 
			
		||||
      |> Enum.map(fn container ->
 | 
			
		||||
        pack_count = Ammo.get_packs_count(current_user, container_id: container.id)
 | 
			
		||||
        round_count = container |> Ammo.get_round_count_for_container!(current_user)
 | 
			
		||||
 | 
			
		||||
        container
 | 
			
		||||
        |> Jason.encode!()
 | 
			
		||||
        |> Jason.decode!()
 | 
			
		||||
        |> Map.merge(%{
 | 
			
		||||
          "pack_count" => pack_count,
 | 
			
		||||
          "round_count" => round_count
 | 
			
		||||
          "pack_count" => Ammo.get_packs_count(current_user, container_id: container.id),
 | 
			
		||||
          "round_count" => Ammo.get_round_count(current_user, container_id: container.id)
 | 
			
		||||
        })
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -122,7 +122,7 @@ defmodule CanneryWeb.ContainerLive.Show do
 | 
			
		||||
    socket
 | 
			
		||||
    |> assign(
 | 
			
		||||
      container: container,
 | 
			
		||||
      round_count: container |> Ammo.get_round_count_for_container!(current_user),
 | 
			
		||||
      round_count: Ammo.get_round_count(current_user, container_id: container.id),
 | 
			
		||||
      packs_count: Ammo.get_packs_count(current_user, container_id: container.id),
 | 
			
		||||
      packs: packs,
 | 
			
		||||
      original_counts: original_counts,
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@ defmodule CanneryWeb.TypeLive.Show do
 | 
			
		||||
      cprs: packs |> Ammo.get_cprs(current_user),
 | 
			
		||||
      last_used_dates: packs |> ActivityLog.get_last_used_dates(current_user),
 | 
			
		||||
      avg_cost_per_round: type |> Ammo.get_average_cost_for_type(current_user),
 | 
			
		||||
      rounds: type |> Ammo.get_round_count_for_type(current_user),
 | 
			
		||||
      rounds: Ammo.get_round_count(current_user, type_id: type.id),
 | 
			
		||||
      original_counts: original_counts,
 | 
			
		||||
      used_rounds: used_rounds,
 | 
			
		||||
      historical_round_count: historical_round_count,
 | 
			
		||||
 
 | 
			
		||||
@@ -170,7 +170,7 @@ msgstr ""
 | 
			
		||||
"Ungültige Nummer an Kopien. Muss zwischen 1 and %{max} liegen. War "
 | 
			
		||||
"%{multiplier}"
 | 
			
		||||
 | 
			
		||||
#: lib/cannery/ammo.ex:980
 | 
			
		||||
#: lib/cannery/ammo.ex:985
 | 
			
		||||
#, elixir-autogen, elixir-format
 | 
			
		||||
msgid "Invalid multiplier"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 
 | 
			
		||||
@@ -153,7 +153,7 @@ msgstr ""
 | 
			
		||||
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: lib/cannery/ammo.ex:980
 | 
			
		||||
#: lib/cannery/ammo.ex:985
 | 
			
		||||
#, elixir-autogen, elixir-format
 | 
			
		||||
msgid "Invalid multiplier"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 
 | 
			
		||||
@@ -152,7 +152,7 @@ msgstr ""
 | 
			
		||||
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: lib/cannery/ammo.ex:980
 | 
			
		||||
#: lib/cannery/ammo.ex:985
 | 
			
		||||
#, elixir-autogen, elixir-format
 | 
			
		||||
msgid "Invalid multiplier"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 
 | 
			
		||||
@@ -168,7 +168,7 @@ msgstr "No se ha podido procesar el número de copias"
 | 
			
		||||
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
 | 
			
		||||
msgstr "Número inválido de copias, debe ser entre 1 y %{max}. Fue %{multiplier"
 | 
			
		||||
 | 
			
		||||
#: lib/cannery/ammo.ex:980
 | 
			
		||||
#: lib/cannery/ammo.ex:985
 | 
			
		||||
#, elixir-autogen, elixir-format
 | 
			
		||||
msgid "Invalid multiplier"
 | 
			
		||||
msgstr "Multiplicador inválido"
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,7 @@ msgstr "Impossible d'analyser le nombre de copies"
 | 
			
		||||
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
 | 
			
		||||
msgstr "Nombre de copies invalide, doit être 1 et %{max}. Été %{multiplier}"
 | 
			
		||||
 | 
			
		||||
#: lib/cannery/ammo.ex:980
 | 
			
		||||
#: lib/cannery/ammo.ex:985
 | 
			
		||||
#, elixir-autogen, elixir-format
 | 
			
		||||
msgid "Invalid multiplier"
 | 
			
		||||
msgstr "Multiplicateur invalide"
 | 
			
		||||
 
 | 
			
		||||
@@ -168,7 +168,7 @@ msgstr ""
 | 
			
		||||
msgid "Invalid number of copies, must be between 1 and %{max}. Was %{multiplier}"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: lib/cannery/ammo.ex:980
 | 
			
		||||
#: lib/cannery/ammo.ex:985
 | 
			
		||||
#, elixir-autogen, elixir-format
 | 
			
		||||
msgid "Invalid multiplier"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 
 | 
			
		||||
@@ -343,24 +343,24 @@ defmodule Cannery.AmmoTest do
 | 
			
		||||
      assert %{^another_type_id => 25.0} = average_costs
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "get_round_count_for_type/2 gets accurate round count for type",
 | 
			
		||||
    test "get_round_count/2 gets accurate round count for type",
 | 
			
		||||
         %{type: type, current_user: current_user, container: container} do
 | 
			
		||||
      another_type = type_fixture(current_user)
 | 
			
		||||
      assert 0 = Ammo.get_round_count_for_type(another_type, current_user)
 | 
			
		||||
      assert 0 = Ammo.get_round_count(current_user, type_id: another_type.id)
 | 
			
		||||
 | 
			
		||||
      {1, [first_pack]} = pack_fixture(%{count: 1}, type, container, current_user)
 | 
			
		||||
 | 
			
		||||
      assert 1 = Ammo.get_round_count_for_type(type, current_user)
 | 
			
		||||
      assert 1 = Ammo.get_round_count(current_user, type_id: type.id)
 | 
			
		||||
 | 
			
		||||
      {1, [pack]} = pack_fixture(%{count: 50}, type, container, current_user)
 | 
			
		||||
 | 
			
		||||
      assert 51 = Ammo.get_round_count_for_type(type, current_user)
 | 
			
		||||
      assert 51 = Ammo.get_round_count(current_user, type_id: type.id)
 | 
			
		||||
 | 
			
		||||
      shot_record_fixture(%{count: 26}, current_user, pack)
 | 
			
		||||
      assert 25 = Ammo.get_round_count_for_type(type, current_user)
 | 
			
		||||
      assert 25 = Ammo.get_round_count(current_user, type_id: type.id)
 | 
			
		||||
 | 
			
		||||
      shot_record_fixture(%{count: 1}, current_user, first_pack)
 | 
			
		||||
      assert 24 = Ammo.get_round_count_for_type(type, current_user)
 | 
			
		||||
      assert 24 = Ammo.get_round_count(current_user, type_id: type.id)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "get_round_count_for_types/2 gets accurate round counts for types", %{
 | 
			
		||||
@@ -635,18 +635,18 @@ defmodule Cannery.AmmoTest do
 | 
			
		||||
      assert %{^another_container_id => 1} = packs_count
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "get_round_count_for_container!/2 gets accurate total round count for container",
 | 
			
		||||
    test "get_round_count/2 gets accurate total round count for container_id",
 | 
			
		||||
         %{type: type, current_user: current_user, container: container} do
 | 
			
		||||
      {1, [first_pack]} = pack_fixture(%{count: 5}, type, container, current_user)
 | 
			
		||||
 | 
			
		||||
      assert 5 = container |> Ammo.get_round_count_for_container!(current_user)
 | 
			
		||||
      assert 5 = Ammo.get_round_count(current_user, container_id: container.id)
 | 
			
		||||
 | 
			
		||||
      {25, _packs} = pack_fixture(%{count: 5}, 25, type, container, current_user)
 | 
			
		||||
 | 
			
		||||
      assert 130 = container |> Ammo.get_round_count_for_container!(current_user)
 | 
			
		||||
      assert 130 = Ammo.get_round_count(current_user, container_id: container.id)
 | 
			
		||||
 | 
			
		||||
      shot_record_fixture(%{count: 5}, current_user, first_pack)
 | 
			
		||||
      assert 125 = container |> Ammo.get_round_count_for_container!(current_user)
 | 
			
		||||
      assert 125 = Ammo.get_round_count(current_user, container_id: container.id)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "get_round_count_for_containers/2 gets accurate total round count for containers",
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@ defmodule CanneryWeb.ExportControllerTest do
 | 
			
		||||
        "shot_charge_weight" => type.shot_charge_weight,
 | 
			
		||||
        "dram_equivalent" => type.dram_equivalent,
 | 
			
		||||
        "average_cost" => type |> Ammo.get_average_cost_for_type(current_user),
 | 
			
		||||
        "round_count" => type |> Ammo.get_round_count_for_type(current_user),
 | 
			
		||||
        "round_count" => Ammo.get_round_count(current_user, type_id: type.id),
 | 
			
		||||
        "used_count" => ActivityLog.get_used_count(current_user, type_id: type.id),
 | 
			
		||||
        "pack_count" => Ammo.get_packs_count(current_user, type_id: type.id),
 | 
			
		||||
        "total_pack_count" =>
 | 
			
		||||
@@ -113,7 +113,7 @@ defmodule CanneryWeb.ExportControllerTest do
 | 
			
		||||
        ],
 | 
			
		||||
        "type" => container.type,
 | 
			
		||||
        "pack_count" => Ammo.get_packs_count(current_user, container_id: container.id),
 | 
			
		||||
        "round_count" => container |> Ammo.get_round_count_for_container!(current_user)
 | 
			
		||||
        "round_count" => Ammo.get_round_count(current_user, container_id: container.id)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ideal_shot_record = %{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user