diff --git a/CHANGELOG.md b/CHANGELOG.md
index 56e3eba5..9edf9edb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,8 @@
- Add "Cannery" to page titles
- Don't show true/false column for ammo types if all values are false
- Fix ammo type firing type display
-
+- Show original count, current value, and percentage remaining for ammo groups
+- Show shot history for an ammo group
# 0.1.0
- Initial release!
diff --git a/lib/cannery/ammo.ex b/lib/cannery/ammo.ex
index 01b4e130..6800c59a 100644
--- a/lib/cannery/ammo.ex
+++ b/lib/cannery/ammo.ex
@@ -162,10 +162,12 @@ defmodule Cannery.Ammo do
@spec list_ammo_groups_for_type(AmmoType.t(), User.t()) :: [AmmoGroup.t()]
def list_ammo_groups_for_type(%AmmoType{id: ammo_type_id, user_id: user_id}, %User{id: user_id}) do
Repo.all(
- from am in AmmoGroup,
- where: am.ammo_type_id == ^ammo_type_id,
- where: am.user_id == ^user_id,
- order_by: am.id
+ from ag in AmmoGroup,
+ left_join: sg in assoc(ag, :shot_groups),
+ where: ag.ammo_type_id == ^ammo_type_id,
+ where: ag.user_id == ^user_id,
+ preload: [shot_groups: sg],
+ order_by: ag.id
)
end
@@ -182,12 +184,18 @@ defmodule Cannery.Ammo do
@spec list_ammo_groups(User.t(), include_empty :: boolean()) :: [AmmoGroup.t()]
def list_ammo_groups(%User{id: user_id}, include_empty \\ false) do
if include_empty do
- from am in AmmoGroup, where: am.user_id == ^user_id, order_by: am.id
+ from ag in AmmoGroup,
+ left_join: sg in assoc(ag, :shot_groups),
+ where: ag.user_id == ^user_id,
+ preload: [shot_groups: sg],
+ order_by: ag.id
else
- from am in AmmoGroup,
- where: am.user_id == ^user_id,
- where: not (am.count == 0),
- order_by: am.id
+ from ag in AmmoGroup,
+ left_join: sg in assoc(ag, :shot_groups),
+ where: ag.user_id == ^user_id,
+ where: not (ag.count == 0),
+ preload: [shot_groups: sg],
+ order_by: ag.id
end
|> Repo.all()
end
@@ -204,10 +212,12 @@ defmodule Cannery.Ammo do
@spec list_staged_ammo_groups(User.t()) :: [AmmoGroup.t()]
def list_staged_ammo_groups(%User{id: user_id}) do
Repo.all(
- from am in AmmoGroup,
- where: am.user_id == ^user_id,
- where: am.staged == true,
- order_by: am.id
+ from ag in AmmoGroup,
+ left_join: sg in assoc(ag, :shot_groups),
+ where: ag.user_id == ^user_id,
+ where: ag.staged == true,
+ preload: [shot_groups: sg],
+ order_by: ag.id
)
end
@@ -226,8 +236,42 @@ defmodule Cannery.Ammo do
"""
@spec get_ammo_group!(AmmoGroup.id(), User.t()) :: AmmoGroup.t()
- def get_ammo_group!(id, %User{id: user_id}),
- do: Repo.one!(from am in AmmoGroup, where: am.id == ^id and am.user_id == ^user_id)
+ def get_ammo_group!(id, %User{id: user_id}) do
+ Repo.one!(
+ from ag in AmmoGroup,
+ left_join: sg in assoc(ag, :shot_groups),
+ where: ag.id == ^id,
+ where: ag.user_id == ^user_id,
+ preload: [shot_groups: sg]
+ )
+ end
+
+ @doc """
+ Returns the number of shot rounds for an ammo group
+ """
+ @spec get_used_count(AmmoGroup.t()) :: non_neg_integer()
+ def get_used_count(%AmmoGroup{} = ammo_group) do
+ ammo_group
+ |> Repo.preload(:shot_groups)
+ |> Map.get(:shot_groups)
+ |> Enum.map(fn %{count: count} -> count end)
+ |> Enum.sum()
+ end
+
+ @doc """
+ Calculates the percentage remaining of an ammo group out of 100
+ """
+ @spec get_percentage_remaining(AmmoGroup.t()) :: non_neg_integer()
+ def get_percentage_remaining(%AmmoGroup{count: 0}), do: 0
+
+ def get_percentage_remaining(%AmmoGroup{count: count} = ammo_group) do
+ ammo_group = ammo_group |> Repo.preload(:shot_groups)
+
+ shot_group_sum =
+ ammo_group.shot_groups |> Enum.map(fn %{count: count} -> count end) |> Enum.sum()
+
+ round(count / (count + shot_group_sum) * 100)
+ end
@doc """
Creates a ammo_group.
diff --git a/lib/cannery_web/live/ammo_group_live/index.html.heex b/lib/cannery_web/live/ammo_group_live/index.html.heex
index 3377f6cc..c2fab220 100644
--- a/lib/cannery_web/live/ammo_group_live/index.html.heex
+++ b/lib/cannery_web/live/ammo_group_live/index.html.heex
@@ -33,7 +33,7 @@
<%= gettext("Price paid") %>
- <%= gettext("Notes") %>
+ <%= gettext("% left") %>
|
<%= gettext("Range") %>
@@ -68,7 +68,7 @@
|
- <%= ammo_group.notes %>
+ <%= "#{ammo_group |> Ammo.get_percentage_remaining()}%" %>
|
diff --git a/lib/cannery_web/live/ammo_group_live/show.html.heex b/lib/cannery_web/live/ammo_group_live/show.html.heex
index c20e836f..119e6932 100644
--- a/lib/cannery_web/live/ammo_group_live/show.html.heex
+++ b/lib/cannery_web/live/ammo_group_live/show.html.heex
@@ -9,6 +9,16 @@
<%= @ammo_group.count %>
+
+ <%= gettext("Original count:") %>
+ <%= @ammo_group.count + Ammo.get_used_count(@ammo_group) %>
+
+
+
+ <%= gettext("Percentage left:") %>
+ <%= "#{@ammo_group |> Ammo.get_percentage_remaining()}%" %>
+
+
<%= if @ammo_group.notes do %>
<%= gettext("Notes:") %>
@@ -18,11 +28,20 @@
<%= if @ammo_group.price_paid do %>
- <%= gettext("Price paid:") %>
+ <%= gettext("Original cost:") %>
<%= gettext("$%{amount}",
amount: @ammo_group.price_paid |> :erlang.float_to_binary(decimals: 2)
) %>
+
+
+ <%= gettext("Current value:") %>
+ <%= gettext("$%{amount}",
+ amount:
+ (@ammo_group.price_paid * Ammo.get_percentage_remaining(@ammo_group) / 100)
+ |> :erlang.float_to_binary(decimals: 2)
+ ) %>
+
<% end %>
@@ -84,6 +103,47 @@
<%= gettext("This ammo group is not in a container") %>
<% end %>
+
+ <%= unless @ammo_group.shot_groups |> Enum.empty?() do %>
+
+
+
+ <%= gettext("Rounds used") %>
+
+
+
+
+
+
+
+ <%= gettext("Rounds shot") %>
+ |
+
+ <%= gettext("Notes") %>
+ |
+
+ <%= gettext("Date") %>
+ |
+
+
+
+ <%= for shot_group <- @ammo_group.shot_groups do %>
+
+
+ <%= shot_group.count %>
+ |
+
+ <%= shot_group.notes %>
+ |
+
+ <%= shot_group.date |> display_date() %>
+ |
+
+ <% end %>
+
+
+
+ <% end %>
<%= case @live_action do %>
diff --git a/priv/gettext/actions.pot b/priv/gettext/actions.pot
index fb98e755..ae84f44e 100644
--- a/priv/gettext/actions.pot
+++ b/priv/gettext/actions.pot
@@ -161,13 +161,13 @@ msgstr ""
#, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_group_live/index.html.heex:85
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:67
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:86
#: lib/cannery_web/live/range_live/index.html.heex:36
msgid "Record shots"
msgstr ""
#, elixir-autogen, elixir-format
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:31
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:50
msgid "Ammo Details"
msgstr ""
@@ -177,7 +177,7 @@ msgid "Add another container!"
msgstr ""
#, elixir-autogen, elixir-format
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:61
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:80
msgid "Move containers"
msgstr ""
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index 61885faa..bbe52eb1 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -358,7 +358,7 @@ msgstr ""
#, elixir-autogen, elixir-format
#: lib/cannery_web/components/add_shot_group_component.html.heex:30
#: lib/cannery_web/live/ammo_group_live/form_component.html.heex:41
-#: lib/cannery_web/live/ammo_group_live/index.html.heex:36
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:122
#: lib/cannery_web/live/range_live/form_component.html.heex:29
#: lib/cannery_web/live/range_live/index.html.heex:67
msgid "Notes"
@@ -366,7 +366,7 @@ msgstr ""
#, elixir-autogen, elixir-format
#: lib/cannery_web/components/ammo_group_card.ex:35
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:14
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:24
msgid "Notes:"
msgstr ""
@@ -390,7 +390,6 @@ msgstr ""
#, elixir-autogen, elixir-format
#: lib/cannery_web/components/ammo_group_card.ex:42
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:21
msgid "Price paid:"
msgstr ""
@@ -447,7 +446,7 @@ msgid "Steel"
msgstr ""
#, elixir-autogen, elixir-format
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:79
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:98
msgid "Stored in"
msgstr ""
@@ -473,7 +472,7 @@ msgid "The self-hosted firearm tracker website"
msgstr ""
#, elixir-autogen, elixir-format
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:84
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:103
msgid "This ammo group is not in a container"
msgstr ""
@@ -538,6 +537,7 @@ msgid "Range day"
msgstr ""
#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:125
#: lib/cannery_web/live/range_live/index.html.heex:70
msgid "Date"
msgstr ""
@@ -553,13 +553,13 @@ msgid "No ammo staged"
msgstr ""
#, elixir-autogen, elixir-format
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:58
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:77
#: lib/cannery_web/live/range_live/index.html.heex:33
msgid "Stage for range"
msgstr ""
#, elixir-autogen, elixir-format
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:57
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:76
#: lib/cannery_web/live/range_live/index.html.heex:32
msgid "Unstage from range"
msgstr ""
@@ -613,6 +613,7 @@ msgid "Rounds left"
msgstr ""
#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:119
#: lib/cannery_web/live/range_live/index.html.heex:64
msgid "Rounds shot"
msgstr ""
@@ -646,7 +647,8 @@ msgstr ""
#, elixir-autogen, elixir-format
#: lib/cannery_web/components/ammo_group_card.ex:43
#: lib/cannery_web/live/ammo_group_live/index.html.heex:64
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:22
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:32
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:39
#: lib/cannery_web/live/ammo_type_live/show.html.heex:82
msgid "$%{amount}"
msgstr ""
@@ -760,3 +762,33 @@ msgstr ""
#: lib/cannery_web/live/ammo_type_live/show.html.heex:88
msgid "No cost information"
msgstr ""
+
+#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/index.html.heex:36
+msgid "% left"
+msgstr ""
+
+#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:38
+msgid "Current value:"
+msgstr ""
+
+#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:31
+msgid "Original cost:"
+msgstr ""
+
+#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:13
+msgid "Original count:"
+msgstr ""
+
+#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:18
+msgid "Percentage left:"
+msgstr ""
+
+#, elixir-autogen, elixir-format
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:111
+msgid "Rounds used"
+msgstr ""
diff --git a/priv/gettext/prompts.pot b/priv/gettext/prompts.pot
index 4713a48a..1ffdbd15 100644
--- a/priv/gettext/prompts.pot
+++ b/priv/gettext/prompts.pot
@@ -98,7 +98,7 @@ msgstr ""
#, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_group_live/index.html.heex:120
-#: lib/cannery_web/live/ammo_group_live/show.html.heex:47
+#: lib/cannery_web/live/ammo_group_live/show.html.heex:66
#: lib/cannery_web/live/ammo_type_live/index.html.heex:68
msgid "Are you sure you want to delete this ammo?"
msgstr ""
|