forked from shibao/cannery
		
	improve ActivityLog.get_used_count
This commit is contained in:
		@@ -287,16 +287,6 @@ defmodule Cannery.ActivityLog do
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @doc """
 | 
					 | 
				
			||||||
  Returns the number of shot rounds for a pack
 | 
					 | 
				
			||||||
  """
 | 
					 | 
				
			||||||
  @spec get_used_count(Pack.t(), User.t()) :: non_neg_integer()
 | 
					 | 
				
			||||||
  def get_used_count(%Pack{id: pack_id} = pack, user) do
 | 
					 | 
				
			||||||
    [pack]
 | 
					 | 
				
			||||||
    |> get_used_counts(user)
 | 
					 | 
				
			||||||
    |> Map.get(pack_id, 0)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @doc """
 | 
					  @doc """
 | 
				
			||||||
  Returns the number of shot rounds for multiple packs
 | 
					  Returns the number of shot rounds for multiple packs
 | 
				
			||||||
  """
 | 
					  """
 | 
				
			||||||
@@ -346,6 +336,9 @@ defmodule Cannery.ActivityLog do
 | 
				
			|||||||
    |> Map.new()
 | 
					    |> Map.new()
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @type get_used_count_option :: {:pack_id, Pack.id() | nil} | {:type_id, Type.id() | nil}
 | 
				
			||||||
 | 
					  @type get_used_count_options :: [get_used_count_option()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @doc """
 | 
					  @doc """
 | 
				
			||||||
  Gets the total number of rounds shot for a type
 | 
					  Gets the total number of rounds shot for a type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -353,20 +346,45 @@ defmodule Cannery.ActivityLog do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  ## Examples
 | 
					  ## Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      iex> get_used_count_for_type(123, %User{id: 123})
 | 
					      iex> get_used_count(%User{id: 123}, type_id: 123)
 | 
				
			||||||
      35
 | 
					      35
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      iex> get_used_count_for_type(456, %User{id: 123})
 | 
					      iex> get_used_count(%User{id: 123}, pack_id: 456)
 | 
				
			||||||
      ** (Ecto.NoResultsError)
 | 
					      50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  """
 | 
					  """
 | 
				
			||||||
  @spec get_used_count_for_type(Type.t(), User.t()) :: non_neg_integer()
 | 
					  @spec get_used_count(User.t(), get_used_count_options()) :: non_neg_integer()
 | 
				
			||||||
  def get_used_count_for_type(%Type{id: type_id} = type, user) do
 | 
					  def get_used_count(%User{id: user_id}, opts) do
 | 
				
			||||||
    [type]
 | 
					    from(sr in ShotRecord,
 | 
				
			||||||
    |> get_used_count_for_types(user)
 | 
					      as: :sr,
 | 
				
			||||||
    |> Map.get(type_id, 0)
 | 
					      left_join: p in Pack,
 | 
				
			||||||
 | 
					      on: sr.pack_id == p.id,
 | 
				
			||||||
 | 
					      on: p.user_id == ^user_id,
 | 
				
			||||||
 | 
					      as: :p,
 | 
				
			||||||
 | 
					      where: sr.user_id == ^user_id,
 | 
				
			||||||
 | 
					      where: not (sr.count |> is_nil()),
 | 
				
			||||||
 | 
					      select: sum(sr.count),
 | 
				
			||||||
 | 
					      distinct: true
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    |> get_used_count_type_id(Keyword.get(opts, :type_id))
 | 
				
			||||||
 | 
					    |> get_used_count_pack_id(Keyword.get(opts, :pack_id))
 | 
				
			||||||
 | 
					    |> Repo.one() || 0
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @spec get_used_count_pack_id(Queryable.t(), Pack.id() | nil) :: Queryable.t()
 | 
				
			||||||
 | 
					  defp get_used_count_pack_id(query, pack_id) when pack_id |> is_binary() do
 | 
				
			||||||
 | 
					    query |> where([sr: sr], sr.pack_id == ^pack_id)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  defp get_used_count_pack_id(query, _nil), do: query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @spec get_used_count_type_id(Queryable.t(), Type.id() | nil) :: Queryable.t()
 | 
				
			||||||
 | 
					  defp get_used_count_type_id(query, type_id) when type_id |> is_binary() do
 | 
				
			||||||
 | 
					    query |> where([p: p], p.type_id == ^type_id)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  defp get_used_count_type_id(query, _nil), do: query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @doc """
 | 
					  @doc """
 | 
				
			||||||
  Gets the total number of rounds shot for multiple types
 | 
					  Gets the total number of rounds shot for multiple types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@ defmodule CanneryWeb.TypeLive.Show do
 | 
				
			|||||||
          packs |> Ammo.get_original_counts(current_user),
 | 
					          packs |> Ammo.get_original_counts(current_user),
 | 
				
			||||||
          Ammo.get_packs_count(current_user, type_id: type.id, show_used: :only_used),
 | 
					          Ammo.get_packs_count(current_user, type_id: type.id, show_used: :only_used),
 | 
				
			||||||
          Ammo.get_packs_count(current_user, type_id: type.id, show_used: true),
 | 
					          Ammo.get_packs_count(current_user, type_id: type.id, show_used: true),
 | 
				
			||||||
          type |> ActivityLog.get_used_count_for_type(current_user),
 | 
					          ActivityLog.get_used_count(current_user, type_id: type.id),
 | 
				
			||||||
          type |> Ammo.get_historical_count_for_type(current_user)
 | 
					          type |> Ammo.get_historical_count_for_type(current_user)
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -188,24 +188,24 @@ defmodule Cannery.ActivityLogTest do
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test "get_used_count/2 returns accurate used count", %{
 | 
					    test "get_used_count/2 returns accurate used count for pack_id", %{
 | 
				
			||||||
      pack: pack,
 | 
					      pack: pack,
 | 
				
			||||||
      type: type,
 | 
					      type: type,
 | 
				
			||||||
      container: container,
 | 
					      container: container,
 | 
				
			||||||
      current_user: current_user
 | 
					      current_user: current_user
 | 
				
			||||||
    } do
 | 
					    } do
 | 
				
			||||||
      {1, [another_pack]} = pack_fixture(type, container, current_user)
 | 
					      {1, [another_pack]} = pack_fixture(type, container, current_user)
 | 
				
			||||||
      assert 0 = another_pack |> ActivityLog.get_used_count(current_user)
 | 
					      assert 0 = ActivityLog.get_used_count(current_user, pack_id: another_pack.id)
 | 
				
			||||||
      assert 5 = pack |> ActivityLog.get_used_count(current_user)
 | 
					      assert 5 = ActivityLog.get_used_count(current_user, pack_id: pack.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      shot_record_fixture(%{count: 15}, current_user, pack)
 | 
					      shot_record_fixture(%{count: 15}, current_user, pack)
 | 
				
			||||||
      assert 20 = pack |> ActivityLog.get_used_count(current_user)
 | 
					      assert 20 = ActivityLog.get_used_count(current_user, pack_id: pack.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      shot_record_fixture(%{count: 10}, current_user, pack)
 | 
					      shot_record_fixture(%{count: 10}, current_user, pack)
 | 
				
			||||||
      assert 30 = pack |> ActivityLog.get_used_count(current_user)
 | 
					      assert 30 = ActivityLog.get_used_count(current_user, pack_id: pack.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      {1, [another_pack]} = pack_fixture(type, container, current_user)
 | 
					      {1, [another_pack]} = pack_fixture(type, container, current_user)
 | 
				
			||||||
      assert 0 = another_pack |> ActivityLog.get_used_count(current_user)
 | 
					      assert 0 = ActivityLog.get_used_count(current_user, pack_id: another_pack.id)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test "get_used_counts/2 returns accurate used counts", %{
 | 
					    test "get_used_counts/2 returns accurate used counts", %{
 | 
				
			||||||
@@ -294,17 +294,17 @@ defmodule Cannery.ActivityLogTest do
 | 
				
			|||||||
      assert %{^another_pack_id => ~D[2022-11-09]} = last_used_shot_records
 | 
					      assert %{^another_pack_id => ~D[2022-11-09]} = last_used_shot_records
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test "get_used_count_for_type/2 gets accurate used round count for type",
 | 
					    test "get_used_count/2 gets accurate used round count for type_id",
 | 
				
			||||||
         %{type: type, pack: pack, current_user: current_user} do
 | 
					         %{type: type, pack: pack, current_user: current_user} do
 | 
				
			||||||
      another_type = type_fixture(current_user)
 | 
					      another_type = type_fixture(current_user)
 | 
				
			||||||
      assert 0 = another_type |> ActivityLog.get_used_count_for_type(current_user)
 | 
					      assert 0 = ActivityLog.get_used_count(current_user, type_id: another_type.id)
 | 
				
			||||||
      assert 5 = type |> ActivityLog.get_used_count_for_type(current_user)
 | 
					      assert 5 = ActivityLog.get_used_count(current_user, type_id: type.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      shot_record_fixture(%{count: 5}, current_user, pack)
 | 
					      shot_record_fixture(%{count: 5}, current_user, pack)
 | 
				
			||||||
      assert 10 = type |> ActivityLog.get_used_count_for_type(current_user)
 | 
					      assert 10 = ActivityLog.get_used_count(current_user, type_id: type.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      shot_record_fixture(%{count: 1}, current_user, pack)
 | 
					      shot_record_fixture(%{count: 1}, current_user, pack)
 | 
				
			||||||
      assert 11 = type |> ActivityLog.get_used_count_for_type(current_user)
 | 
					      assert 11 = ActivityLog.get_used_count(current_user, type_id: type.id)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test "get_used_count_for_types/2 gets accurate used round count for types", %{
 | 
					    test "get_used_count_for_types/2 gets accurate used round count for types", %{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@ defmodule CanneryWeb.ExportControllerTest do
 | 
				
			|||||||
        "price_paid" => pack.price_paid,
 | 
					        "price_paid" => pack.price_paid,
 | 
				
			||||||
        "lot_number" => pack.lot_number,
 | 
					        "lot_number" => pack.lot_number,
 | 
				
			||||||
        "staged" => pack.staged,
 | 
					        "staged" => pack.staged,
 | 
				
			||||||
        "used_count" => pack |> ActivityLog.get_used_count(current_user),
 | 
					        "used_count" => ActivityLog.get_used_count(current_user, pack_id: pack.id),
 | 
				
			||||||
        "original_count" => pack |> Ammo.get_original_count(current_user),
 | 
					        "original_count" => pack |> Ammo.get_original_count(current_user),
 | 
				
			||||||
        "cpr" => pack |> Ammo.get_cpr(current_user),
 | 
					        "cpr" => pack |> Ammo.get_cpr(current_user),
 | 
				
			||||||
        "percentage_remaining" => pack |> Ammo.get_percentage_remaining(current_user)
 | 
					        "percentage_remaining" => pack |> Ammo.get_percentage_remaining(current_user)
 | 
				
			||||||
@@ -92,7 +92,7 @@ defmodule CanneryWeb.ExportControllerTest do
 | 
				
			|||||||
        "dram_equivalent" => type.dram_equivalent,
 | 
					        "dram_equivalent" => type.dram_equivalent,
 | 
				
			||||||
        "average_cost" => type |> Ammo.get_average_cost_for_type(current_user),
 | 
					        "average_cost" => type |> Ammo.get_average_cost_for_type(current_user),
 | 
				
			||||||
        "round_count" => type |> Ammo.get_round_count_for_type(current_user),
 | 
					        "round_count" => type |> Ammo.get_round_count_for_type(current_user),
 | 
				
			||||||
        "used_count" => type |> ActivityLog.get_used_count_for_type(current_user),
 | 
					        "used_count" => ActivityLog.get_used_count(current_user, type_id: type.id),
 | 
				
			||||||
        "pack_count" => Ammo.get_packs_count(current_user, type_id: type.id),
 | 
					        "pack_count" => Ammo.get_packs_count(current_user, type_id: type.id),
 | 
				
			||||||
        "total_pack_count" =>
 | 
					        "total_pack_count" =>
 | 
				
			||||||
          Ammo.get_packs_count(current_user, type_id: type.id, show_used: true)
 | 
					          Ammo.get_packs_count(current_user, type_id: type.id, show_used: true)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user