rename ammo groups to packs
This commit is contained in:
parent
0cae7c2940
commit
6d26103784
@ -17,8 +17,8 @@ If you're multilingual, this project can use your translations! Visit
|
||||
functions as short as possible while keeping variable names descriptive! For
|
||||
instance, use inline `do:` blocks for short functions and make your aliases as
|
||||
short as possible without introducing ambiguity.
|
||||
- I.e. since there's only one `AmmoGroup` in the app, please alias
|
||||
`AmmoGroup.t()` instead of using `Cannery.Ammo.AmmoGroup.t()`
|
||||
- I.e. since there's only one `Pack` in the app, please alias
|
||||
`Pack.t()` instead of using `Cannery.Ammo.Pack.t()`
|
||||
- Use pipelines when possible. If only calling a single method, a pipeline isn't
|
||||
strictly necessary but still encouraged for future modification.
|
||||
- Please add typespecs to your functions! Even your private functions may be
|
||||
|
@ -4,7 +4,7 @@ defmodule Cannery.ActivityLog do
|
||||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Cannery.Ammo.{AmmoGroup, AmmoType}
|
||||
alias Cannery.Ammo.{Pack, AmmoType}
|
||||
alias Cannery.{Accounts.User, ActivityLog.ShotGroup, Repo}
|
||||
alias Ecto.{Multi, Queryable}
|
||||
|
||||
@ -29,9 +29,9 @@ defmodule Cannery.ActivityLog do
|
||||
def list_shot_groups(search \\ nil, type, %{id: user_id}) do
|
||||
from(sg in ShotGroup,
|
||||
as: :sg,
|
||||
left_join: ag in AmmoGroup,
|
||||
left_join: ag in Pack,
|
||||
as: :ag,
|
||||
on: sg.ammo_group_id == ag.id,
|
||||
on: sg.pack_id == ag.id,
|
||||
left_join: at in AmmoType,
|
||||
as: :at,
|
||||
on: ag.ammo_type_id == at.id,
|
||||
@ -92,14 +92,14 @@ defmodule Cannery.ActivityLog do
|
||||
|
||||
defp list_shot_groups_filter_type(query, _all), do: query
|
||||
|
||||
@spec list_shot_groups_for_ammo_group(AmmoGroup.t(), User.t()) :: [ShotGroup.t()]
|
||||
def list_shot_groups_for_ammo_group(
|
||||
%AmmoGroup{id: ammo_group_id, user_id: user_id},
|
||||
@spec list_shot_groups_for_pack(Pack.t(), User.t()) :: [ShotGroup.t()]
|
||||
def list_shot_groups_for_pack(
|
||||
%Pack{id: pack_id, user_id: user_id},
|
||||
%User{id: user_id}
|
||||
) do
|
||||
Repo.all(
|
||||
from sg in ShotGroup,
|
||||
where: sg.ammo_group_id == ^ammo_group_id,
|
||||
where: sg.pack_id == ^pack_id,
|
||||
where: sg.user_id == ^user_id
|
||||
)
|
||||
end
|
||||
@ -140,31 +140,31 @@ defmodule Cannery.ActivityLog do
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
@spec create_shot_group(attrs :: map(), User.t(), AmmoGroup.t()) ::
|
||||
@spec create_shot_group(attrs :: map(), User.t(), Pack.t()) ::
|
||||
{:ok, ShotGroup.t()} | {:error, ShotGroup.changeset() | nil}
|
||||
def create_shot_group(attrs, user, ammo_group) do
|
||||
def create_shot_group(attrs, user, pack) do
|
||||
Multi.new()
|
||||
|> Multi.insert(
|
||||
:create_shot_group,
|
||||
%ShotGroup{} |> ShotGroup.create_changeset(user, ammo_group, attrs)
|
||||
%ShotGroup{} |> ShotGroup.create_changeset(user, pack, attrs)
|
||||
)
|
||||
|> Multi.run(
|
||||
:ammo_group,
|
||||
fn _repo, %{create_shot_group: %{ammo_group_id: ammo_group_id, user_id: user_id}} ->
|
||||
ammo_group =
|
||||
:pack,
|
||||
fn _repo, %{create_shot_group: %{pack_id: pack_id, user_id: user_id}} ->
|
||||
pack =
|
||||
Repo.one(
|
||||
from ag in AmmoGroup,
|
||||
where: ag.id == ^ammo_group_id,
|
||||
from ag in Pack,
|
||||
where: ag.id == ^pack_id,
|
||||
where: ag.user_id == ^user_id
|
||||
)
|
||||
|
||||
{:ok, ammo_group}
|
||||
{:ok, pack}
|
||||
end
|
||||
)
|
||||
|> Multi.update(
|
||||
:update_ammo_group,
|
||||
fn %{create_shot_group: %{count: shot_group_count}, ammo_group: %{count: ammo_group_count}} ->
|
||||
ammo_group |> AmmoGroup.range_changeset(%{"count" => ammo_group_count - shot_group_count})
|
||||
:update_pack,
|
||||
fn %{create_shot_group: %{count: shot_group_count}, pack: %{count: pack_count}} ->
|
||||
pack |> Pack.range_changeset(%{"count" => pack_count - shot_group_count})
|
||||
end
|
||||
)
|
||||
|> Repo.transaction()
|
||||
@ -200,21 +200,20 @@ defmodule Cannery.ActivityLog do
|
||||
shot_group |> ShotGroup.update_changeset(user, attrs)
|
||||
)
|
||||
|> Multi.run(
|
||||
:ammo_group,
|
||||
fn repo, %{update_shot_group: %{ammo_group_id: ammo_group_id, user_id: user_id}} ->
|
||||
{:ok,
|
||||
repo.one(from ag in AmmoGroup, where: ag.id == ^ammo_group_id and ag.user_id == ^user_id)}
|
||||
:pack,
|
||||
fn repo, %{update_shot_group: %{pack_id: pack_id, user_id: user_id}} ->
|
||||
{:ok, repo.one(from ag in Pack, where: ag.id == ^pack_id and ag.user_id == ^user_id)}
|
||||
end
|
||||
)
|
||||
|> Multi.update(
|
||||
:update_ammo_group,
|
||||
:update_pack,
|
||||
fn %{
|
||||
update_shot_group: %{count: new_count},
|
||||
ammo_group: %{count: ammo_group_count} = ammo_group
|
||||
pack: %{count: pack_count} = pack
|
||||
} ->
|
||||
shot_diff_to_add = new_count - count
|
||||
new_ammo_group_count = ammo_group_count - shot_diff_to_add
|
||||
ammo_group |> AmmoGroup.range_changeset(%{"count" => new_ammo_group_count})
|
||||
new_pack_count = pack_count - shot_diff_to_add
|
||||
pack |> Pack.range_changeset(%{"count" => new_pack_count})
|
||||
end
|
||||
)
|
||||
|> Repo.transaction()
|
||||
@ -246,20 +245,19 @@ defmodule Cannery.ActivityLog do
|
||||
Multi.new()
|
||||
|> Multi.delete(:delete_shot_group, shot_group)
|
||||
|> Multi.run(
|
||||
:ammo_group,
|
||||
fn repo, %{delete_shot_group: %{ammo_group_id: ammo_group_id, user_id: user_id}} ->
|
||||
{:ok,
|
||||
repo.one(from ag in AmmoGroup, where: ag.id == ^ammo_group_id and ag.user_id == ^user_id)}
|
||||
:pack,
|
||||
fn repo, %{delete_shot_group: %{pack_id: pack_id, user_id: user_id}} ->
|
||||
{:ok, repo.one(from ag in Pack, where: ag.id == ^pack_id and ag.user_id == ^user_id)}
|
||||
end
|
||||
)
|
||||
|> Multi.update(
|
||||
:update_ammo_group,
|
||||
:update_pack,
|
||||
fn %{
|
||||
delete_shot_group: %{count: count},
|
||||
ammo_group: %{count: ammo_group_count} = ammo_group
|
||||
pack: %{count: pack_count} = pack
|
||||
} ->
|
||||
new_ammo_group_count = ammo_group_count + count
|
||||
ammo_group |> AmmoGroup.range_changeset(%{"count" => new_ammo_group_count})
|
||||
new_pack_count = pack_count + count
|
||||
pack |> Pack.range_changeset(%{"count" => new_pack_count})
|
||||
end
|
||||
)
|
||||
|> Repo.transaction()
|
||||
@ -273,29 +271,29 @@ defmodule Cannery.ActivityLog do
|
||||
@doc """
|
||||
Returns the number of shot rounds for an ammo group
|
||||
"""
|
||||
@spec get_used_count(AmmoGroup.t(), User.t()) :: non_neg_integer()
|
||||
def get_used_count(%AmmoGroup{id: ammo_group_id} = ammo_group, user) do
|
||||
[ammo_group]
|
||||
@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(ammo_group_id, 0)
|
||||
|> Map.get(pack_id, 0)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the number of shot rounds for multiple ammo groups
|
||||
"""
|
||||
@spec get_used_counts([AmmoGroup.t()], User.t()) ::
|
||||
%{optional(AmmoGroup.id()) => non_neg_integer()}
|
||||
def get_used_counts(ammo_groups, %User{id: user_id}) do
|
||||
ammo_group_ids =
|
||||
ammo_groups
|
||||
|> Enum.map(fn %{id: ammo_group_id} -> ammo_group_id end)
|
||||
@spec get_used_counts([Pack.t()], User.t()) ::
|
||||
%{optional(Pack.id()) => non_neg_integer()}
|
||||
def get_used_counts(packs, %User{id: user_id}) do
|
||||
pack_ids =
|
||||
packs
|
||||
|> Enum.map(fn %{id: pack_id} -> pack_id end)
|
||||
|
||||
Repo.all(
|
||||
from sg in ShotGroup,
|
||||
where: sg.ammo_group_id in ^ammo_group_ids,
|
||||
where: sg.pack_id in ^pack_ids,
|
||||
where: sg.user_id == ^user_id,
|
||||
group_by: sg.ammo_group_id,
|
||||
select: {sg.ammo_group_id, sum(sg.count)}
|
||||
group_by: sg.pack_id,
|
||||
select: {sg.pack_id, sum(sg.count)}
|
||||
)
|
||||
|> Map.new()
|
||||
end
|
||||
@ -303,28 +301,28 @@ defmodule Cannery.ActivityLog do
|
||||
@doc """
|
||||
Returns the last entered shot group date for an ammo group
|
||||
"""
|
||||
@spec get_last_used_date(AmmoGroup.t(), User.t()) :: Date.t() | nil
|
||||
def get_last_used_date(%AmmoGroup{id: ammo_group_id} = ammo_group, user) do
|
||||
[ammo_group]
|
||||
@spec get_last_used_date(Pack.t(), User.t()) :: Date.t() | nil
|
||||
def get_last_used_date(%Pack{id: pack_id} = pack, user) do
|
||||
[pack]
|
||||
|> get_last_used_dates(user)
|
||||
|> Map.get(ammo_group_id)
|
||||
|> Map.get(pack_id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the last entered shot group date for an ammo group
|
||||
"""
|
||||
@spec get_last_used_dates([AmmoGroup.t()], User.t()) :: %{optional(AmmoGroup.id()) => Date.t()}
|
||||
def get_last_used_dates(ammo_groups, %User{id: user_id}) do
|
||||
ammo_group_ids =
|
||||
ammo_groups
|
||||
|> Enum.map(fn %AmmoGroup{id: ammo_group_id, user_id: ^user_id} -> ammo_group_id end)
|
||||
@spec get_last_used_dates([Pack.t()], User.t()) :: %{optional(Pack.id()) => Date.t()}
|
||||
def get_last_used_dates(packs, %User{id: user_id}) do
|
||||
pack_ids =
|
||||
packs
|
||||
|> Enum.map(fn %Pack{id: pack_id, user_id: ^user_id} -> pack_id end)
|
||||
|
||||
Repo.all(
|
||||
from sg in ShotGroup,
|
||||
where: sg.ammo_group_id in ^ammo_group_ids,
|
||||
where: sg.pack_id in ^pack_ids,
|
||||
where: sg.user_id == ^user_id,
|
||||
group_by: sg.ammo_group_id,
|
||||
select: {sg.ammo_group_id, max(sg.date)}
|
||||
group_by: sg.pack_id,
|
||||
select: {sg.pack_id, max(sg.date)}
|
||||
)
|
||||
|> Map.new()
|
||||
end
|
||||
@ -367,9 +365,9 @@ defmodule Cannery.ActivityLog do
|
||||
|> Enum.map(fn %AmmoType{id: ammo_type_id, user_id: ^user_id} -> ammo_type_id end)
|
||||
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
left_join: sg in ShotGroup,
|
||||
on: ag.id == sg.ammo_group_id,
|
||||
on: ag.id == sg.pack_id,
|
||||
where: ag.ammo_type_id in ^ammo_type_ids,
|
||||
where: not (sg.count |> is_nil()),
|
||||
group_by: ag.ammo_type_id,
|
||||
|
@ -6,7 +6,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
|
||||
use Ecto.Schema
|
||||
import CanneryWeb.Gettext
|
||||
import Ecto.Changeset
|
||||
alias Cannery.{Accounts.User, Ammo, Ammo.AmmoGroup}
|
||||
alias Cannery.{Accounts.User, Ammo, Ammo.Pack}
|
||||
alias Ecto.{Changeset, UUID}
|
||||
|
||||
@derive {Jason.Encoder,
|
||||
@ -15,7 +15,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
|
||||
:count,
|
||||
:date,
|
||||
:notes,
|
||||
:ammo_group_id
|
||||
:pack_id
|
||||
]}
|
||||
@primary_key {:id, :binary_id, autogenerate: true}
|
||||
@foreign_key_type :binary_id
|
||||
@ -25,7 +25,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
|
||||
field :notes, :string
|
||||
|
||||
field :user_id, :binary_id
|
||||
field :ammo_group_id, :binary_id
|
||||
field :pack_id, :binary_id
|
||||
|
||||
timestamps()
|
||||
end
|
||||
@ -35,7 +35,7 @@ defmodule Cannery.ActivityLog.ShotGroup do
|
||||
count: integer,
|
||||
notes: String.t() | nil,
|
||||
date: Date.t() | nil,
|
||||
ammo_group_id: AmmoGroup.id(),
|
||||
pack_id: Pack.id(),
|
||||
user_id: User.id(),
|
||||
inserted_at: NaiveDateTime.t(),
|
||||
updated_at: NaiveDateTime.t()
|
||||
@ -48,46 +48,44 @@ defmodule Cannery.ActivityLog.ShotGroup do
|
||||
@spec create_changeset(
|
||||
new_shot_group(),
|
||||
User.t() | any(),
|
||||
AmmoGroup.t() | any(),
|
||||
Pack.t() | any(),
|
||||
attrs :: map()
|
||||
) :: changeset()
|
||||
def create_changeset(
|
||||
shot_group,
|
||||
%User{id: user_id},
|
||||
%AmmoGroup{id: ammo_group_id, user_id: user_id} = ammo_group,
|
||||
%Pack{id: pack_id, user_id: user_id} = pack,
|
||||
attrs
|
||||
) do
|
||||
shot_group
|
||||
|> change(user_id: user_id)
|
||||
|> change(ammo_group_id: ammo_group_id)
|
||||
|> change(pack_id: pack_id)
|
||||
|> cast(attrs, [:count, :notes, :date])
|
||||
|> validate_length(:notes, max: 255)
|
||||
|> validate_create_shot_group_count(ammo_group)
|
||||
|> validate_required([:date, :ammo_group_id, :user_id])
|
||||
|> validate_create_shot_group_count(pack)
|
||||
|> validate_required([:date, :pack_id, :user_id])
|
||||
end
|
||||
|
||||
def create_changeset(shot_group, _invalid_user, _invalid_ammo_group, attrs) do
|
||||
def create_changeset(shot_group, _invalid_user, _invalid_pack, attrs) do
|
||||
shot_group
|
||||
|> cast(attrs, [:count, :notes, :date])
|
||||
|> validate_length(:notes, max: 255)
|
||||
|> validate_required([:ammo_group_id, :user_id])
|
||||
|> validate_required([:pack_id, :user_id])
|
||||
|> add_error(:invalid, dgettext("errors", "Please select a valid user and ammo pack"))
|
||||
end
|
||||
|
||||
defp validate_create_shot_group_count(changeset, %AmmoGroup{count: ammo_group_count}) do
|
||||
defp validate_create_shot_group_count(changeset, %Pack{count: pack_count}) do
|
||||
case changeset |> Changeset.get_field(:count) do
|
||||
nil ->
|
||||
changeset |> Changeset.add_error(:ammo_left, dgettext("errors", "can't be blank"))
|
||||
|
||||
count when count > ammo_group_count ->
|
||||
count when count > pack_count ->
|
||||
changeset
|
||||
|> Changeset.add_error(:ammo_left, dgettext("errors", "Ammo left must be at least 0"))
|
||||
|
||||
count when count <= 0 ->
|
||||
error =
|
||||
dgettext("errors", "Ammo left can be at most %{count} rounds",
|
||||
count: ammo_group_count - 1
|
||||
)
|
||||
dgettext("errors", "Ammo left can be at most %{count} rounds", count: pack_count - 1)
|
||||
|
||||
changeset |> Changeset.add_error(:ammo_left, error)
|
||||
|
||||
@ -109,17 +107,16 @@ defmodule Cannery.ActivityLog.ShotGroup do
|
||||
|
||||
defp validate_update_shot_group_count(
|
||||
changeset,
|
||||
%__MODULE__{ammo_group_id: ammo_group_id, count: count},
|
||||
%__MODULE__{pack_id: pack_id, count: count},
|
||||
user
|
||||
) do
|
||||
%{count: ammo_group_count} = Ammo.get_ammo_group!(ammo_group_id, user)
|
||||
%{count: pack_count} = Ammo.get_pack!(pack_id, user)
|
||||
|
||||
new_shot_group_count = changeset |> Changeset.get_field(:count)
|
||||
shot_diff_to_add = new_shot_group_count - count
|
||||
|
||||
if shot_diff_to_add > ammo_group_count do
|
||||
error =
|
||||
dgettext("errors", "Count can be at most %{count} shots", count: ammo_group_count + count)
|
||||
if shot_diff_to_add > pack_count do
|
||||
error = dgettext("errors", "Count can be at most %{count} shots", count: pack_count + count)
|
||||
|
||||
changeset |> Changeset.add_error(:count, error)
|
||||
else
|
||||
|
@ -8,12 +8,12 @@ defmodule Cannery.Ammo do
|
||||
alias Cannery.{Accounts.User, Containers, Repo}
|
||||
alias Cannery.Containers.{Container, ContainerTag, Tag}
|
||||
alias Cannery.{ActivityLog, ActivityLog.ShotGroup}
|
||||
alias Cannery.Ammo.{AmmoGroup, AmmoType}
|
||||
alias Cannery.Ammo.{Pack, AmmoType}
|
||||
alias Ecto.{Changeset, Queryable}
|
||||
|
||||
@ammo_group_create_limit 10_000
|
||||
@ammo_group_preloads [:ammo_type]
|
||||
@ammo_type_preloads [:ammo_groups]
|
||||
@pack_create_limit 10_000
|
||||
@pack_preloads [:ammo_type]
|
||||
@ammo_type_preloads [:packs]
|
||||
|
||||
@doc """
|
||||
Returns the list of ammo_types.
|
||||
@ -169,14 +169,14 @@ defmodule Cannery.Ammo do
|
||||
sg_total_query =
|
||||
from sg in ShotGroup,
|
||||
where: not (sg.count |> is_nil()),
|
||||
group_by: sg.ammo_group_id,
|
||||
select: %{ammo_group_id: sg.ammo_group_id, total: sum(sg.count)}
|
||||
group_by: sg.pack_id,
|
||||
select: %{pack_id: sg.pack_id, total: sum(sg.count)}
|
||||
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
as: :ammo_group,
|
||||
from ag in Pack,
|
||||
as: :pack,
|
||||
left_join: sg_query in subquery(sg_total_query),
|
||||
on: ag.id == sg_query.ammo_group_id,
|
||||
on: ag.id == sg_query.pack_id,
|
||||
where: ag.ammo_type_id in ^ammo_type_ids,
|
||||
group_by: ag.ammo_type_id,
|
||||
where: not (ag.price_paid |> is_nil()),
|
||||
@ -225,7 +225,7 @@ defmodule Cannery.Ammo do
|
||||
|> Enum.map(fn %AmmoType{id: ammo_type_id, user_id: ^user_id} -> ammo_type_id end)
|
||||
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
where: ag.ammo_type_id in ^ammo_type_ids,
|
||||
where: ag.user_id == ^user_id,
|
||||
group_by: ag.ammo_type_id,
|
||||
@ -376,150 +376,150 @@ defmodule Cannery.Ammo do
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the list of ammo_groups for a user and type.
|
||||
Returns the list of packs for a user and type.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_ammo_groups_for_type(
|
||||
iex> list_packs_for_type(
|
||||
...> %AmmoType{id: 123, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
[%AmmoGroup{}, ...]
|
||||
[%Pack{}, ...]
|
||||
|
||||
iex> list_ammo_groups_for_type(
|
||||
iex> list_packs_for_type(
|
||||
...> %AmmoType{id: 123, user_id: 456},
|
||||
...> %User{id: 456},
|
||||
...> true
|
||||
...> )
|
||||
[%AmmoGroup{}, %AmmoGroup{}, ...]
|
||||
[%Pack{}, %Pack{}, ...]
|
||||
|
||||
"""
|
||||
@spec list_ammo_groups_for_type(AmmoType.t(), User.t()) :: [AmmoGroup.t()]
|
||||
@spec list_ammo_groups_for_type(AmmoType.t(), User.t(), show_used :: boolean()) ::
|
||||
[AmmoGroup.t()]
|
||||
def list_ammo_groups_for_type(ammo_type, user, show_used \\ false)
|
||||
@spec list_packs_for_type(AmmoType.t(), User.t()) :: [Pack.t()]
|
||||
@spec list_packs_for_type(AmmoType.t(), User.t(), show_used :: boolean()) ::
|
||||
[Pack.t()]
|
||||
def list_packs_for_type(ammo_type, user, show_used \\ false)
|
||||
|
||||
def list_ammo_groups_for_type(
|
||||
def list_packs_for_type(
|
||||
%AmmoType{id: ammo_type_id, user_id: user_id},
|
||||
%User{id: user_id},
|
||||
show_used
|
||||
) do
|
||||
from(ag in AmmoGroup,
|
||||
from(ag in Pack,
|
||||
as: :ag,
|
||||
where: ag.ammo_type_id == ^ammo_type_id,
|
||||
where: ag.user_id == ^user_id,
|
||||
preload: ^@ammo_group_preloads
|
||||
preload: ^@pack_preloads
|
||||
)
|
||||
|> list_ammo_groups_for_type_show_used(show_used)
|
||||
|> list_packs_for_type_show_used(show_used)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@spec list_ammo_groups_for_type_show_used(Queryable.t(), show_used :: boolean()) ::
|
||||
@spec list_packs_for_type_show_used(Queryable.t(), show_used :: boolean()) ::
|
||||
Queryable.t()
|
||||
def list_ammo_groups_for_type_show_used(query, false),
|
||||
def list_packs_for_type_show_used(query, false),
|
||||
do: query |> where([ag: ag], ag.count > 0)
|
||||
|
||||
def list_ammo_groups_for_type_show_used(query, _true), do: query
|
||||
def list_packs_for_type_show_used(query, _true), do: query
|
||||
|
||||
@doc """
|
||||
Returns the list of ammo_groups for a user and container.
|
||||
Returns the list of packs for a user and container.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_ammo_groups_for_container(
|
||||
iex> list_packs_for_container(
|
||||
...> %Container{id: 123, user_id: 456},
|
||||
...> :rifle,
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
[%AmmoGroup{}, ...]
|
||||
[%Pack{}, ...]
|
||||
|
||||
iex> list_ammo_groups_for_container(
|
||||
iex> list_packs_for_container(
|
||||
...> %Container{id: 123, user_id: 456},
|
||||
...> :all,
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
[%AmmoGroup{}, %AmmoGroup{}, ...]
|
||||
[%Pack{}, %Pack{}, ...]
|
||||
|
||||
"""
|
||||
@spec list_ammo_groups_for_container(
|
||||
@spec list_packs_for_container(
|
||||
Container.t(),
|
||||
AmmoType.t() | :all,
|
||||
User.t()
|
||||
) :: [AmmoGroup.t()]
|
||||
def list_ammo_groups_for_container(
|
||||
) :: [Pack.t()]
|
||||
def list_packs_for_container(
|
||||
%Container{id: container_id, user_id: user_id},
|
||||
type,
|
||||
%User{id: user_id}
|
||||
) do
|
||||
from(ag in AmmoGroup,
|
||||
from(ag in Pack,
|
||||
as: :ag,
|
||||
join: at in assoc(ag, :ammo_type),
|
||||
as: :at,
|
||||
where: ag.container_id == ^container_id,
|
||||
where: ag.user_id == ^user_id,
|
||||
where: ag.count > 0,
|
||||
preload: ^@ammo_group_preloads
|
||||
preload: ^@pack_preloads
|
||||
)
|
||||
|> list_ammo_groups_for_container_filter_type(type)
|
||||
|> list_packs_for_container_filter_type(type)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@spec list_ammo_groups_for_container_filter_type(Queryable.t(), AmmoType.class() | :all) ::
|
||||
@spec list_packs_for_container_filter_type(Queryable.t(), AmmoType.class() | :all) ::
|
||||
Queryable.t()
|
||||
defp list_ammo_groups_for_container_filter_type(query, :rifle),
|
||||
defp list_packs_for_container_filter_type(query, :rifle),
|
||||
do: query |> where([at: at], at.class == :rifle)
|
||||
|
||||
defp list_ammo_groups_for_container_filter_type(query, :pistol),
|
||||
defp list_packs_for_container_filter_type(query, :pistol),
|
||||
do: query |> where([at: at], at.class == :pistol)
|
||||
|
||||
defp list_ammo_groups_for_container_filter_type(query, :shotgun),
|
||||
defp list_packs_for_container_filter_type(query, :shotgun),
|
||||
do: query |> where([at: at], at.class == :shotgun)
|
||||
|
||||
defp list_ammo_groups_for_container_filter_type(query, _all), do: query
|
||||
defp list_packs_for_container_filter_type(query, _all), do: query
|
||||
|
||||
@doc """
|
||||
Returns a count of ammo_groups.
|
||||
Returns a count of packs.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_groups_count!(%User{id: 123})
|
||||
iex> get_packs_count!(%User{id: 123})
|
||||
3
|
||||
|
||||
iex> get_ammo_groups_count!(%User{id: 123}, true)
|
||||
iex> get_packs_count!(%User{id: 123}, true)
|
||||
4
|
||||
|
||||
"""
|
||||
@spec get_ammo_groups_count!(User.t()) :: integer()
|
||||
@spec get_ammo_groups_count!(User.t(), show_used :: boolean()) :: integer()
|
||||
def get_ammo_groups_count!(%User{id: user_id}, show_used \\ false) do
|
||||
from(ag in AmmoGroup,
|
||||
@spec get_packs_count!(User.t()) :: integer()
|
||||
@spec get_packs_count!(User.t(), show_used :: boolean()) :: integer()
|
||||
def get_packs_count!(%User{id: user_id}, show_used \\ false) do
|
||||
from(ag in Pack,
|
||||
as: :ag,
|
||||
where: ag.user_id == ^user_id,
|
||||
select: count(ag.id),
|
||||
distinct: true
|
||||
)
|
||||
|> get_ammo_groups_count_show_used(show_used)
|
||||
|> get_packs_count_show_used(show_used)
|
||||
|> Repo.one() || 0
|
||||
end
|
||||
|
||||
@spec get_ammo_groups_count_show_used(Queryable.t(), show_used :: boolean()) :: Queryable.t()
|
||||
defp get_ammo_groups_count_show_used(query, false),
|
||||
@spec get_packs_count_show_used(Queryable.t(), show_used :: boolean()) :: Queryable.t()
|
||||
defp get_packs_count_show_used(query, false),
|
||||
do: query |> where([ag: ag], ag.count > 0)
|
||||
|
||||
defp get_ammo_groups_count_show_used(query, _true), do: query
|
||||
defp get_packs_count_show_used(query, _true), do: query
|
||||
|
||||
@doc """
|
||||
Returns the count of ammo_groups for an ammo type.
|
||||
Returns the count of packs for an ammo type.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_groups_count_for_type(
|
||||
iex> get_packs_count_for_type(
|
||||
...> %AmmoType{id: 123, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
3
|
||||
|
||||
iex> get_ammo_groups_count_for_type(
|
||||
iex> get_packs_count_for_type(
|
||||
...> %AmmoType{id: 123, user_id: 456},
|
||||
...> %User{id: 456},
|
||||
...> true
|
||||
@ -527,31 +527,31 @@ defmodule Cannery.Ammo do
|
||||
5
|
||||
|
||||
"""
|
||||
@spec get_ammo_groups_count_for_type(AmmoType.t(), User.t()) :: non_neg_integer()
|
||||
@spec get_ammo_groups_count_for_type(AmmoType.t(), User.t(), show_used :: boolean()) ::
|
||||
@spec get_packs_count_for_type(AmmoType.t(), User.t()) :: non_neg_integer()
|
||||
@spec get_packs_count_for_type(AmmoType.t(), User.t(), show_used :: boolean()) ::
|
||||
non_neg_integer()
|
||||
def get_ammo_groups_count_for_type(
|
||||
def get_packs_count_for_type(
|
||||
%AmmoType{id: ammo_type_id} = ammo_type,
|
||||
user,
|
||||
show_used \\ false
|
||||
) do
|
||||
[ammo_type]
|
||||
|> get_ammo_groups_count_for_types(user, show_used)
|
||||
|> get_packs_count_for_types(user, show_used)
|
||||
|> Map.get(ammo_type_id, 0)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the count of ammo_groups for multiple ammo types.
|
||||
Returns the count of packs for multiple ammo types.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_groups_count_for_types(
|
||||
iex> get_packs_count_for_types(
|
||||
...> [%AmmoType{id: 123, user_id: 456}],
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
3
|
||||
|
||||
iex> get_ammo_groups_count_for_types(
|
||||
iex> get_packs_count_for_types(
|
||||
...> [%AmmoType{id: 123, user_id: 456}],
|
||||
...> %User{id: 456},
|
||||
...> true
|
||||
@ -559,75 +559,75 @@ defmodule Cannery.Ammo do
|
||||
5
|
||||
|
||||
"""
|
||||
@spec get_ammo_groups_count_for_types([AmmoType.t()], User.t()) ::
|
||||
@spec get_packs_count_for_types([AmmoType.t()], User.t()) ::
|
||||
%{optional(AmmoType.id()) => non_neg_integer()}
|
||||
@spec get_ammo_groups_count_for_types([AmmoType.t()], User.t(), show_used :: boolean()) ::
|
||||
@spec get_packs_count_for_types([AmmoType.t()], User.t(), show_used :: boolean()) ::
|
||||
%{optional(AmmoType.id()) => non_neg_integer()}
|
||||
def get_ammo_groups_count_for_types(ammo_types, %User{id: user_id}, show_used \\ false) do
|
||||
def get_packs_count_for_types(ammo_types, %User{id: user_id}, show_used \\ false) do
|
||||
ammo_type_ids =
|
||||
ammo_types
|
||||
|> Enum.map(fn %AmmoType{id: ammo_type_id, user_id: ^user_id} -> ammo_type_id end)
|
||||
|
||||
from(ag in AmmoGroup,
|
||||
from(ag in Pack,
|
||||
as: :ag,
|
||||
where: ag.user_id == ^user_id,
|
||||
where: ag.ammo_type_id in ^ammo_type_ids,
|
||||
group_by: ag.ammo_type_id,
|
||||
select: {ag.ammo_type_id, count(ag.id)}
|
||||
)
|
||||
|> get_ammo_groups_count_for_types_maybe_show_used(show_used)
|
||||
|> get_packs_count_for_types_maybe_show_used(show_used)
|
||||
|> Repo.all()
|
||||
|> Map.new()
|
||||
end
|
||||
|
||||
@spec get_ammo_groups_count_for_types_maybe_show_used(Queryable.t(), show_used :: boolean()) ::
|
||||
@spec get_packs_count_for_types_maybe_show_used(Queryable.t(), show_used :: boolean()) ::
|
||||
Queryable.t()
|
||||
defp get_ammo_groups_count_for_types_maybe_show_used(query, true), do: query
|
||||
defp get_packs_count_for_types_maybe_show_used(query, true), do: query
|
||||
|
||||
defp get_ammo_groups_count_for_types_maybe_show_used(query, _false) do
|
||||
defp get_packs_count_for_types_maybe_show_used(query, _false) do
|
||||
query |> where([ag: ag], not (ag.count == 0))
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the count of used ammo_groups for an ammo type.
|
||||
Returns the count of used packs for an ammo type.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_used_ammo_groups_count_for_type(
|
||||
iex> get_used_packs_count_for_type(
|
||||
...> %AmmoType{id: 123, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
3
|
||||
|
||||
"""
|
||||
@spec get_used_ammo_groups_count_for_type(AmmoType.t(), User.t()) :: non_neg_integer()
|
||||
def get_used_ammo_groups_count_for_type(%AmmoType{id: ammo_type_id} = ammo_type, user) do
|
||||
@spec get_used_packs_count_for_type(AmmoType.t(), User.t()) :: non_neg_integer()
|
||||
def get_used_packs_count_for_type(%AmmoType{id: ammo_type_id} = ammo_type, user) do
|
||||
[ammo_type]
|
||||
|> get_used_ammo_groups_count_for_types(user)
|
||||
|> get_used_packs_count_for_types(user)
|
||||
|> Map.get(ammo_type_id, 0)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the count of used ammo_groups for multiple ammo types.
|
||||
Returns the count of used packs for multiple ammo types.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_used_ammo_groups_count_for_types(
|
||||
iex> get_used_packs_count_for_types(
|
||||
...> [%AmmoType{id: 123, user_id: 456}],
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
%{123 => 3}
|
||||
|
||||
"""
|
||||
@spec get_used_ammo_groups_count_for_types([AmmoType.t()], User.t()) ::
|
||||
@spec get_used_packs_count_for_types([AmmoType.t()], User.t()) ::
|
||||
%{optional(AmmoType.id()) => non_neg_integer()}
|
||||
def get_used_ammo_groups_count_for_types(ammo_types, %User{id: user_id}) do
|
||||
def get_used_packs_count_for_types(ammo_types, %User{id: user_id}) do
|
||||
ammo_type_ids =
|
||||
ammo_types
|
||||
|> Enum.map(fn %AmmoType{id: ammo_type_id, user_id: ^user_id} -> ammo_type_id end)
|
||||
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
where: ag.user_id == ^user_id,
|
||||
where: ag.ammo_type_id in ^ammo_type_ids,
|
||||
where: ag.count == 0,
|
||||
@ -642,20 +642,20 @@ defmodule Cannery.Ammo do
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_groups_count_for_container(
|
||||
iex> get_packs_count_for_container(
|
||||
...> %Container{id: 123, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
3
|
||||
|
||||
"""
|
||||
@spec get_ammo_groups_count_for_container!(Container.t(), User.t()) :: non_neg_integer()
|
||||
def get_ammo_groups_count_for_container!(
|
||||
@spec get_packs_count_for_container!(Container.t(), User.t()) :: non_neg_integer()
|
||||
def get_packs_count_for_container!(
|
||||
%Container{id: container_id} = container,
|
||||
%User{} = user
|
||||
) do
|
||||
[container]
|
||||
|> get_ammo_groups_count_for_containers(user)
|
||||
|> get_packs_count_for_containers(user)
|
||||
|> Map.get(container_id, 0)
|
||||
end
|
||||
|
||||
@ -664,23 +664,23 @@ defmodule Cannery.Ammo do
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_groups_count_for_containers(
|
||||
iex> get_packs_count_for_containers(
|
||||
...> [%Container{id: 123, user_id: 456}],
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
%{123 => 3}
|
||||
|
||||
"""
|
||||
@spec get_ammo_groups_count_for_containers([Container.t()], User.t()) :: %{
|
||||
@spec get_packs_count_for_containers([Container.t()], User.t()) :: %{
|
||||
Container.id() => non_neg_integer()
|
||||
}
|
||||
def get_ammo_groups_count_for_containers(containers, %User{id: user_id}) do
|
||||
def get_packs_count_for_containers(containers, %User{id: user_id}) do
|
||||
container_ids =
|
||||
containers
|
||||
|> Enum.map(fn %Container{id: container_id, user_id: ^user_id} -> container_id end)
|
||||
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
where: ag.container_id in ^container_ids,
|
||||
where: ag.count > 0,
|
||||
group_by: ag.container_id,
|
||||
@ -728,7 +728,7 @@ defmodule Cannery.Ammo do
|
||||
|> Enum.map(fn %Container{id: container_id, user_id: ^user_id} -> container_id end)
|
||||
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
where: ag.container_id in ^container_ids,
|
||||
group_by: ag.container_id,
|
||||
select: {ag.container_id, sum(ag.count)}
|
||||
@ -737,27 +737,27 @@ defmodule Cannery.Ammo do
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the list of ammo_groups.
|
||||
Returns the list of packs.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_ammo_groups(%User{id: 123})
|
||||
[%AmmoGroup{}, ...]
|
||||
iex> list_packs(%User{id: 123})
|
||||
[%Pack{}, ...]
|
||||
|
||||
iex> list_ammo_groups("cool", %User{id: 123}, true)
|
||||
[%AmmoGroup{notes: "My cool ammo group"}, ...]
|
||||
iex> list_packs("cool", %User{id: 123}, true)
|
||||
[%Pack{notes: "My cool ammo group"}, ...]
|
||||
|
||||
"""
|
||||
@spec list_ammo_groups(search :: String.t() | nil, AmmoType.class() | :all, User.t()) ::
|
||||
[AmmoGroup.t()]
|
||||
@spec list_ammo_groups(
|
||||
@spec list_packs(search :: String.t() | nil, AmmoType.class() | :all, User.t()) ::
|
||||
[Pack.t()]
|
||||
@spec list_packs(
|
||||
search :: nil | String.t(),
|
||||
AmmoType.class() | :all,
|
||||
User.t(),
|
||||
show_used :: boolean()
|
||||
) :: [AmmoGroup.t()]
|
||||
def list_ammo_groups(search, type, %{id: user_id}, show_used \\ false) do
|
||||
from(ag in AmmoGroup,
|
||||
) :: [Pack.t()]
|
||||
def list_packs(search, type, %{id: user_id}, show_used \\ false) do
|
||||
from(ag in Pack,
|
||||
as: :ag,
|
||||
join: at in assoc(ag, :ammo_type),
|
||||
as: :at,
|
||||
@ -773,38 +773,38 @@ defmodule Cannery.Ammo do
|
||||
as: :t,
|
||||
where: ag.user_id == ^user_id,
|
||||
distinct: ag.id,
|
||||
preload: ^@ammo_group_preloads
|
||||
preload: ^@pack_preloads
|
||||
)
|
||||
|> list_ammo_groups_filter_on_type(type)
|
||||
|> list_ammo_groups_show_used(show_used)
|
||||
|> list_ammo_groups_search(search)
|
||||
|> list_packs_filter_on_type(type)
|
||||
|> list_packs_show_used(show_used)
|
||||
|> list_packs_search(search)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@spec list_ammo_groups_filter_on_type(Queryable.t(), AmmoType.class() | :all) :: Queryable.t()
|
||||
defp list_ammo_groups_filter_on_type(query, :rifle),
|
||||
@spec list_packs_filter_on_type(Queryable.t(), AmmoType.class() | :all) :: Queryable.t()
|
||||
defp list_packs_filter_on_type(query, :rifle),
|
||||
do: query |> where([at: at], at.class == :rifle)
|
||||
|
||||
defp list_ammo_groups_filter_on_type(query, :pistol),
|
||||
defp list_packs_filter_on_type(query, :pistol),
|
||||
do: query |> where([at: at], at.class == :pistol)
|
||||
|
||||
defp list_ammo_groups_filter_on_type(query, :shotgun),
|
||||
defp list_packs_filter_on_type(query, :shotgun),
|
||||
do: query |> where([at: at], at.class == :shotgun)
|
||||
|
||||
defp list_ammo_groups_filter_on_type(query, _all), do: query
|
||||
defp list_packs_filter_on_type(query, _all), do: query
|
||||
|
||||
@spec list_ammo_groups_show_used(Queryable.t(), show_used :: boolean()) :: Queryable.t()
|
||||
defp list_ammo_groups_show_used(query, true), do: query
|
||||
@spec list_packs_show_used(Queryable.t(), show_used :: boolean()) :: Queryable.t()
|
||||
defp list_packs_show_used(query, true), do: query
|
||||
|
||||
defp list_ammo_groups_show_used(query, _false) do
|
||||
defp list_packs_show_used(query, _false) do
|
||||
query |> where([ag: ag], not (ag.count == 0))
|
||||
end
|
||||
|
||||
@spec list_ammo_groups_show_used(Queryable.t(), search :: String.t() | nil) :: Queryable.t()
|
||||
defp list_ammo_groups_search(query, nil), do: query
|
||||
defp list_ammo_groups_search(query, ""), do: query
|
||||
@spec list_packs_show_used(Queryable.t(), search :: String.t() | nil) :: Queryable.t()
|
||||
defp list_packs_search(query, nil), do: query
|
||||
defp list_packs_search(query, ""), do: query
|
||||
|
||||
defp list_ammo_groups_search(query, search) do
|
||||
defp list_packs_search(query, search) do
|
||||
trimmed_search = String.trim(search)
|
||||
|
||||
query
|
||||
@ -843,60 +843,60 @@ defmodule Cannery.Ammo do
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the list of staged ammo_groups for a user.
|
||||
Returns the list of staged packs for a user.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_staged_ammo_groups(%User{id: 123})
|
||||
[%AmmoGroup{}, ...]
|
||||
iex> list_staged_packs(%User{id: 123})
|
||||
[%Pack{}, ...]
|
||||
|
||||
"""
|
||||
@spec list_staged_ammo_groups(User.t()) :: [AmmoGroup.t()]
|
||||
def list_staged_ammo_groups(%User{id: user_id}) do
|
||||
@spec list_staged_packs(User.t()) :: [Pack.t()]
|
||||
def list_staged_packs(%User{id: user_id}) do
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
where: ag.user_id == ^user_id,
|
||||
where: ag.staged == true,
|
||||
preload: ^@ammo_group_preloads
|
||||
preload: ^@pack_preloads
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single ammo_group.
|
||||
Gets a single pack.
|
||||
|
||||
Raises `KeyError` if the Ammo group does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_group!(123, %User{id: 123})
|
||||
%AmmoGroup{}
|
||||
iex> get_pack!(123, %User{id: 123})
|
||||
%Pack{}
|
||||
|
||||
iex> get_ammo_group!(456, %User{id: 123})
|
||||
iex> get_pack!(456, %User{id: 123})
|
||||
** (KeyError)
|
||||
|
||||
"""
|
||||
@spec get_ammo_group!(AmmoGroup.id(), User.t()) :: AmmoGroup.t()
|
||||
def get_ammo_group!(id, user) do
|
||||
[id] |> get_ammo_groups(user) |> Map.fetch!(id)
|
||||
@spec get_pack!(Pack.id(), User.t()) :: Pack.t()
|
||||
def get_pack!(id, user) do
|
||||
[id] |> get_packs(user) |> Map.fetch!(id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a group of ammo_groups by their ID.
|
||||
Gets a group of packs by their ID.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_ammo_groups([123, 456], %User{id: 123})
|
||||
%{123 => %AmmoGroup{}, 456 => %AmmoGroup{}}
|
||||
iex> get_packs([123, 456], %User{id: 123})
|
||||
%{123 => %Pack{}, 456 => %Pack{}}
|
||||
|
||||
"""
|
||||
@spec get_ammo_groups([AmmoGroup.id()], User.t()) ::
|
||||
%{optional(AmmoGroup.id()) => AmmoGroup.t()}
|
||||
def get_ammo_groups(ids, %User{id: user_id}) do
|
||||
@spec get_packs([Pack.id()], User.t()) ::
|
||||
%{optional(Pack.id()) => Pack.t()}
|
||||
def get_packs(ids, %User{id: user_id}) do
|
||||
Repo.all(
|
||||
from ag in AmmoGroup,
|
||||
from ag in Pack,
|
||||
where: ag.id in ^ids,
|
||||
where: ag.user_id == ^user_id,
|
||||
preload: ^@ammo_group_preloads,
|
||||
preload: ^@pack_preloads,
|
||||
select: {ag.id, ag}
|
||||
)
|
||||
|> Map.new()
|
||||
@ -908,17 +908,17 @@ defmodule Cannery.Ammo do
|
||||
## Examples
|
||||
|
||||
iex> get_percentage_remaining(
|
||||
...> %AmmoGroup{id: 123, count: 5, user_id: 456},
|
||||
...> %Pack{id: 123, count: 5, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
100
|
||||
|
||||
"""
|
||||
@spec get_percentage_remaining(AmmoGroup.t(), User.t()) :: non_neg_integer()
|
||||
def get_percentage_remaining(%AmmoGroup{id: ammo_group_id} = ammo_group, user) do
|
||||
[ammo_group]
|
||||
@spec get_percentage_remaining(Pack.t(), User.t()) :: non_neg_integer()
|
||||
def get_percentage_remaining(%Pack{id: pack_id} = pack, user) do
|
||||
[pack]
|
||||
|> get_percentages_remaining(user)
|
||||
|> Map.fetch!(ammo_group_id)
|
||||
|> Map.fetch!(pack_id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -927,26 +927,26 @@ defmodule Cannery.Ammo do
|
||||
## Examples
|
||||
|
||||
iex> get_percentages_remaining(
|
||||
...> [%AmmoGroup{id: 123, count: 5, user_id: 456}],
|
||||
...> [%Pack{id: 123, count: 5, user_id: 456}],
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
%{123 => 100}
|
||||
|
||||
"""
|
||||
@spec get_percentages_remaining([AmmoGroup.t()], User.t()) ::
|
||||
%{optional(AmmoGroup.id()) => non_neg_integer()}
|
||||
def get_percentages_remaining(ammo_groups, %User{id: user_id} = user) do
|
||||
original_counts = get_original_counts(ammo_groups, user)
|
||||
@spec get_percentages_remaining([Pack.t()], User.t()) ::
|
||||
%{optional(Pack.id()) => non_neg_integer()}
|
||||
def get_percentages_remaining(packs, %User{id: user_id} = user) do
|
||||
original_counts = get_original_counts(packs, user)
|
||||
|
||||
ammo_groups
|
||||
|> Map.new(fn %AmmoGroup{id: ammo_group_id, count: count, user_id: ^user_id} ->
|
||||
packs
|
||||
|> Map.new(fn %Pack{id: pack_id, count: count, user_id: ^user_id} ->
|
||||
percentage =
|
||||
case count do
|
||||
0 -> 0
|
||||
count -> round(count / Map.fetch!(original_counts, ammo_group_id) * 100)
|
||||
count -> round(count / Map.fetch!(original_counts, pack_id) * 100)
|
||||
end
|
||||
|
||||
{ammo_group_id, percentage}
|
||||
{pack_id, percentage}
|
||||
end)
|
||||
end
|
||||
|
||||
@ -956,17 +956,17 @@ defmodule Cannery.Ammo do
|
||||
## Examples
|
||||
|
||||
iex> get_original_count(
|
||||
...> %AmmoGroup{id: 123, count: 5, user_id: 456},
|
||||
...> %Pack{id: 123, count: 5, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
5
|
||||
|
||||
"""
|
||||
@spec get_original_count(AmmoGroup.t(), User.t()) :: non_neg_integer()
|
||||
def get_original_count(%AmmoGroup{id: ammo_group_id} = ammo_group, current_user) do
|
||||
[ammo_group]
|
||||
@spec get_original_count(Pack.t(), User.t()) :: non_neg_integer()
|
||||
def get_original_count(%Pack{id: pack_id} = pack, current_user) do
|
||||
[pack]
|
||||
|> get_original_counts(current_user)
|
||||
|> Map.fetch!(ammo_group_id)
|
||||
|> Map.fetch!(pack_id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -975,20 +975,20 @@ defmodule Cannery.Ammo do
|
||||
## Examples
|
||||
|
||||
iex> get_original_counts(
|
||||
...> [%AmmoGroup{id: 123, count: 5, user_id: 456}],
|
||||
...> [%Pack{id: 123, count: 5, user_id: 456}],
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
%{123 => 5}
|
||||
|
||||
"""
|
||||
@spec get_original_counts([AmmoGroup.t()], User.t()) ::
|
||||
%{optional(AmmoGroup.id()) => non_neg_integer()}
|
||||
def get_original_counts(ammo_groups, %User{id: user_id} = current_user) do
|
||||
used_counts = ActivityLog.get_used_counts(ammo_groups, current_user)
|
||||
@spec get_original_counts([Pack.t()], User.t()) ::
|
||||
%{optional(Pack.id()) => non_neg_integer()}
|
||||
def get_original_counts(packs, %User{id: user_id} = current_user) do
|
||||
used_counts = ActivityLog.get_used_counts(packs, current_user)
|
||||
|
||||
ammo_groups
|
||||
|> Map.new(fn %AmmoGroup{id: ammo_group_id, count: count, user_id: ^user_id} ->
|
||||
{ammo_group_id, count + Map.get(used_counts, ammo_group_id, 0)}
|
||||
packs
|
||||
|> Map.new(fn %Pack{id: pack_id, count: count, user_id: ^user_id} ->
|
||||
{pack_id, count + Map.get(used_counts, pack_id, 0)}
|
||||
end)
|
||||
end
|
||||
|
||||
@ -998,17 +998,17 @@ defmodule Cannery.Ammo do
|
||||
## Examples
|
||||
|
||||
iex> get_cpr(
|
||||
...> %AmmoGroup{id: 123, price_paid: 5, count: 5, user_id: 456},
|
||||
...> %Pack{id: 123, price_paid: 5, count: 5, user_id: 456},
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
1
|
||||
|
||||
"""
|
||||
@spec get_cpr(AmmoGroup.t(), User.t()) :: float() | nil
|
||||
def get_cpr(%AmmoGroup{id: ammo_group_id} = ammo_group, user) do
|
||||
[ammo_group]
|
||||
@spec get_cpr(Pack.t(), User.t()) :: float() | nil
|
||||
def get_cpr(%Pack{id: pack_id} = pack, user) do
|
||||
[pack]
|
||||
|> get_cprs(user)
|
||||
|> Map.get(ammo_group_id)
|
||||
|> Map.get(pack_id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@ -1017,22 +1017,22 @@ defmodule Cannery.Ammo do
|
||||
## Examples
|
||||
|
||||
iex> get_cprs(
|
||||
...> [%AmmoGroup{id: 123, price_paid: 5, count: 5, user_id: 456}],
|
||||
...> [%Pack{id: 123, price_paid: 5, count: 5, user_id: 456}],
|
||||
...> %User{id: 456}
|
||||
...> )
|
||||
%{123 => 1}
|
||||
|
||||
"""
|
||||
@spec get_cprs([AmmoGroup.t()], User.t()) :: %{optional(AmmoGroup.id()) => float()}
|
||||
def get_cprs(ammo_groups, %User{id: user_id} = current_user) do
|
||||
original_counts = get_original_counts(ammo_groups, current_user)
|
||||
@spec get_cprs([Pack.t()], User.t()) :: %{optional(Pack.id()) => float()}
|
||||
def get_cprs(packs, %User{id: user_id} = current_user) do
|
||||
original_counts = get_original_counts(packs, current_user)
|
||||
|
||||
ammo_groups
|
||||
|> Enum.reject(fn %AmmoGroup{price_paid: price_paid, user_id: ^user_id} ->
|
||||
packs
|
||||
|> Enum.reject(fn %Pack{price_paid: price_paid, user_id: ^user_id} ->
|
||||
price_paid |> is_nil()
|
||||
end)
|
||||
|> Map.new(fn %{id: ammo_group_id, price_paid: price_paid} ->
|
||||
{ammo_group_id, calculate_cpr(price_paid, Map.fetch!(original_counts, ammo_group_id))}
|
||||
|> Map.new(fn %{id: pack_id, price_paid: price_paid} ->
|
||||
{pack_id, calculate_cpr(price_paid, Map.fetch!(original_counts, pack_id))}
|
||||
end)
|
||||
end
|
||||
|
||||
@ -1042,41 +1042,41 @@ defmodule Cannery.Ammo do
|
||||
defp calculate_cpr(price_paid, total_count), do: price_paid / total_count
|
||||
|
||||
@doc """
|
||||
Creates multiple ammo_groups at once.
|
||||
Creates multiple packs at once.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_ammo_groups(%{field: value}, 3, %User{id: 123})
|
||||
{:ok, {3, [%AmmoGroup{}]}}
|
||||
iex> create_packs(%{field: value}, 3, %User{id: 123})
|
||||
{:ok, {3, [%Pack{}]}}
|
||||
|
||||
iex> create_ammo_groups(%{field: bad_value}, 3, %User{id: 123})
|
||||
iex> create_packs(%{field: bad_value}, 3, %User{id: 123})
|
||||
{:error, %Changeset{}}
|
||||
|
||||
"""
|
||||
@spec create_ammo_groups(attrs :: map(), multiplier :: non_neg_integer(), User.t()) ::
|
||||
{:ok, {count :: non_neg_integer(), [AmmoGroup.t()] | nil}}
|
||||
| {:error, AmmoGroup.changeset()}
|
||||
def create_ammo_groups(attrs, multiplier, %User{} = user) do
|
||||
@spec create_packs(attrs :: map(), multiplier :: non_neg_integer(), User.t()) ::
|
||||
{:ok, {count :: non_neg_integer(), [Pack.t()] | nil}}
|
||||
| {:error, Pack.changeset()}
|
||||
def create_packs(attrs, multiplier, %User{} = user) do
|
||||
attrs
|
||||
|> Map.new(fn {k, v} -> {to_string(k), v} end)
|
||||
|> do_create_ammo_groups(multiplier, user)
|
||||
|> do_create_packs(multiplier, user)
|
||||
end
|
||||
|
||||
defp do_create_ammo_groups(
|
||||
defp do_create_packs(
|
||||
%{"ammo_type_id" => ammo_type_id, "container_id" => container_id} = attrs,
|
||||
multiplier,
|
||||
user
|
||||
)
|
||||
when multiplier >= 1 and
|
||||
multiplier <= @ammo_group_create_limit and
|
||||
multiplier <= @pack_create_limit and
|
||||
ammo_type_id |> is_binary() and
|
||||
container_id |> is_binary() do
|
||||
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||
|
||||
changesets =
|
||||
Enum.map(1..multiplier, fn _count ->
|
||||
%AmmoGroup{}
|
||||
|> AmmoGroup.create_changeset(
|
||||
%Pack{}
|
||||
|> Pack.create_changeset(
|
||||
get_ammo_type!(ammo_type_id, user),
|
||||
Containers.get_container!(container_id, user),
|
||||
user,
|
||||
@ -1085,9 +1085,9 @@ defmodule Cannery.Ammo do
|
||||
end)
|
||||
|
||||
if changesets |> Enum.all?(fn %{valid?: valid} -> valid end) do
|
||||
{count, inserted_ammo_groups} =
|
||||
{count, inserted_packs} =
|
||||
Repo.insert_all(
|
||||
AmmoGroup,
|
||||
Pack,
|
||||
changesets
|
||||
|> Enum.map(fn changeset ->
|
||||
changeset
|
||||
@ -1097,7 +1097,7 @@ defmodule Cannery.Ammo do
|
||||
returning: true
|
||||
)
|
||||
|
||||
{:ok, {count, inserted_ammo_groups |> preload_ammo_group()}}
|
||||
{:ok, {count, inserted_packs |> preload_pack()}}
|
||||
else
|
||||
changesets
|
||||
|> Enum.reject(fn %{valid?: valid} -> valid end)
|
||||
@ -1106,15 +1106,15 @@ defmodule Cannery.Ammo do
|
||||
end
|
||||
end
|
||||
|
||||
defp do_create_ammo_groups(
|
||||
defp do_create_packs(
|
||||
%{"ammo_type_id" => ammo_type_id, "container_id" => container_id} = attrs,
|
||||
_multiplier,
|
||||
user
|
||||
)
|
||||
when is_binary(ammo_type_id) and is_binary(container_id) do
|
||||
changeset =
|
||||
%AmmoGroup{}
|
||||
|> AmmoGroup.create_changeset(
|
||||
%Pack{}
|
||||
|> Pack.create_changeset(
|
||||
get_ammo_type!(ammo_type_id, user),
|
||||
Containers.get_container!(container_id, user),
|
||||
user,
|
||||
@ -1125,79 +1125,79 @@ defmodule Cannery.Ammo do
|
||||
{:error, changeset}
|
||||
end
|
||||
|
||||
defp do_create_ammo_groups(invalid_attrs, _multiplier, user) do
|
||||
{:error, %AmmoGroup{} |> AmmoGroup.create_changeset(nil, nil, user, invalid_attrs)}
|
||||