forked from shibao/cannery
		
	add deletion check for containers
This commit is contained in:
		| @@ -27,6 +27,8 @@ If you're multilingual, this project can use your translations! Visit | |||||||
|   - Typespec arguments can be named like `@spec function(arg_name :: type()) :: |   - Typespec arguments can be named like `@spec function(arg_name :: type()) :: | ||||||
|     return_type()`. Please use these for generic types, such as `map()` when the |     return_type()`. Please use these for generic types, such as `map()` when the | ||||||
|     input data isn't immediately obvious. |     input data isn't immediately obvious. | ||||||
|  |   - Please define all typespecs for a function together in one place, instead of | ||||||
|  |     each function. | ||||||
| - When making new models, please take inspiration from the existing models in | - When making new models, please take inspiration from the existing models in | ||||||
|   regards to layout of sections, typespec design, and formatting. |   regards to layout of sections, typespec design, and formatting. | ||||||
| - With Elixir convention, for methods that raise on error please name them like | - With Elixir convention, for methods that raise on error please name them like | ||||||
|   | |||||||
| @@ -3,8 +3,9 @@ defmodule Cannery.Containers do | |||||||
|   The Containers context. |   The Containers context. | ||||||
|   """ |   """ | ||||||
|  |  | ||||||
|  |   import CanneryWeb.Gettext | ||||||
|   import Ecto.Query, warn: false |   import Ecto.Query, warn: false | ||||||
|   alias Cannery.{Accounts.User, Repo, Tags.Tag} |   alias Cannery.{Accounts.User, Ammo.AmmoGroup, Repo, Tags.Tag} | ||||||
|   alias Cannery.Containers.{Container, ContainerTag} |   alias Cannery.Containers.{Container, ContainerTag} | ||||||
|   alias Ecto.Changeset |   alias Ecto.Changeset | ||||||
|  |  | ||||||
| @@ -88,7 +89,36 @@ defmodule Cannery.Containers do | |||||||
|   """ |   """ | ||||||
|   @spec delete_container(Container.t()) :: |   @spec delete_container(Container.t()) :: | ||||||
|           {:ok, Container.t()} | {:error, Changeset.t(Container.t())} |           {:ok, Container.t()} | {:error, Changeset.t(Container.t())} | ||||||
|   def delete_container(container), do: container |> Repo.delete() |   def delete_container(container) do | ||||||
|  |     Repo.one( | ||||||
|  |       from ag in AmmoGroup, | ||||||
|  |         where: ag.container_id == ^container.id, | ||||||
|  |         select: count(ag.id) | ||||||
|  |     ) | ||||||
|  |     |> case do | ||||||
|  |       0 -> | ||||||
|  |         container |> Repo.delete() | ||||||
|  |  | ||||||
|  |       amount -> | ||||||
|  |         error_string = | ||||||
|  |           dngettext( | ||||||
|  |             "errors", | ||||||
|  |             "There is still %{amount} ammo group in this container!", | ||||||
|  |             "There are still %{amount} ammo groups in this container!", | ||||||
|  |             amount | ||||||
|  |           ) | ||||||
|  |  | ||||||
|  |         container | ||||||
|  |         |> change_container() | ||||||
|  |         |> Changeset.add_error( | ||||||
|  |           :ammo_groups, | ||||||
|  |           error_string, | ||||||
|  |           amount: amount, | ||||||
|  |           count: amount | ||||||
|  |         ) | ||||||
|  |         |> Changeset.apply_action(:delete) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|   @doc """ |   @doc """ | ||||||
|   Deletes a container. |   Deletes a container. | ||||||
| @@ -100,7 +130,10 @@ defmodule Cannery.Containers do | |||||||
|  |  | ||||||
|   """ |   """ | ||||||
|   @spec delete_container!(Container.t()) :: Container.t() |   @spec delete_container!(Container.t()) :: Container.t() | ||||||
|   def delete_container!(container), do: container |> Repo.delete!() |   def delete_container!(container) do | ||||||
|  |     {:ok, container} = container |> delete_container() | ||||||
|  |     container | ||||||
|  |   end | ||||||
|  |  | ||||||
|   @doc """ |   @doc """ | ||||||
|   Returns an `%Changeset{}` for tracking container changes. |   Returns an `%Changeset{}` for tracking container changes. | ||||||
|   | |||||||
| @@ -5,8 +5,7 @@ defmodule CanneryWeb.ContainerLive.Index do | |||||||
|  |  | ||||||
|   use CanneryWeb, :live_view |   use CanneryWeb, :live_view | ||||||
|   import CanneryWeb.ContainerLive.ContainerCard |   import CanneryWeb.ContainerLive.ContainerCard | ||||||
|   alias Cannery.Containers |   alias Cannery.{Containers, Containers.Container} | ||||||
|   alias Cannery.Containers.Container |  | ||||||
|  |  | ||||||
|   @impl true |   @impl true | ||||||
|   def mount(_params, session, socket) do |   def mount(_params, session, socket) do | ||||||
| @@ -38,8 +37,32 @@ defmodule CanneryWeb.ContainerLive.Index do | |||||||
|  |  | ||||||
|   @impl true |   @impl true | ||||||
|   def handle_event("delete", %{"id" => id}, socket) do |   def handle_event("delete", %{"id" => id}, socket) do | ||||||
|     Containers.get_container!(id) |> Containers.delete_container!() |     socket = | ||||||
|     {:noreply, socket |> display_containers()} |       socket.assigns.containers | ||||||
|  |       |> Enum.find(fn %{id: container_id} -> id == container_id end) | ||||||
|  |       |> case do | ||||||
|  |         nil -> | ||||||
|  |           socket |> put_flash(:error, "Could not find that container") | ||||||
|  |  | ||||||
|  |         container -> | ||||||
|  |           container | ||||||
|  |           |> Containers.delete_container() | ||||||
|  |           |> case do | ||||||
|  |             {:ok, container} -> | ||||||
|  |               socket | ||||||
|  |               |> put_flash(:info, "#{container.name} has been deleted") | ||||||
|  |               |> display_containers() | ||||||
|  |  | ||||||
|  |             {:error, %{action: :delete, errors: [ammo_groups: _error], valid?: false} = changeset} -> | ||||||
|  |               ammo_groups_error = changeset |> changeset_errors(:ammo_groups) |> Enum.join(", ") | ||||||
|  |               socket |> put_flash(:error, "Could not delete container: #{ammo_groups_error}") | ||||||
|  |  | ||||||
|  |             {:error, changeset} -> | ||||||
|  |               socket |> put_flash(:error, changeset |> changeset_errors()) | ||||||
|  |           end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |     {:noreply, socket} | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   defp display_containers(%{assigns: %{current_user: current_user}} = socket) do |   defp display_containers(%{assigns: %{current_user: current_user}} = socket) do | ||||||
|   | |||||||
| @@ -26,8 +26,24 @@ defmodule CanneryWeb.ContainerLive.Show do | |||||||
|  |  | ||||||
|   @impl true |   @impl true | ||||||
|   def handle_event("delete", _, socket) do |   def handle_event("delete", _, socket) do | ||||||
|     socket.assigns.container |> Containers.delete_container!() |     socket = | ||||||
|     {:noreply, socket |> push_redirect(to: Routes.container_index_path(socket, :index))} |       socket.assigns.container | ||||||
|  |       |> Containers.delete_container() | ||||||
|  |       |> case do | ||||||
|  |         {:ok, container} -> | ||||||
|  |           socket | ||||||
|  |           |> put_flash(:info, "#{container.name} has been deleted") | ||||||
|  |           |> push_redirect(to: Routes.container_index_path(socket, :index)) | ||||||
|  |  | ||||||
|  |         {:error, %{action: :delete, errors: [ammo_groups: _error], valid?: false} = changeset} -> | ||||||
|  |           ammo_groups_error = changeset |> changeset_errors(:ammo_groups) |> Enum.join(", ") | ||||||
|  |           socket |> put_flash(:error, "Could not delete container: #{ammo_groups_error}") | ||||||
|  |  | ||||||
|  |         {:error, changeset} -> | ||||||
|  |           socket |> put_flash(:error, changeset |> changeset_errors()) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |     {:noreply, socket} | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   defp page_title(:show), do: "Show Container" |   defp page_title(:show), do: "Show Container" | ||||||
|   | |||||||
| @@ -55,9 +55,10 @@ defmodule CanneryWeb.ErrorHelpers do | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   @doc """ |   @doc """ | ||||||
|   Displays all errors from a changeset |   Displays all errors from a changeset, or just for a single key | ||||||
|   """ |   """ | ||||||
|   @spec changeset_errors(Changeset.t()) :: String.t() |   @spec changeset_errors(Changeset.t()) :: String.t() | ||||||
|  |   @spec changeset_errors(Changeset.t(), key :: atom()) :: [String.t()] | nil | ||||||
|   def changeset_errors(changeset) do |   def changeset_errors(changeset) do | ||||||
|     changeset |     changeset | ||||||
|     |> changeset_error_map() |     |> changeset_error_map() | ||||||
| @@ -66,6 +67,10 @@ defmodule CanneryWeb.ErrorHelpers do | |||||||
|     end) |     end) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def changeset_errors(changeset, key) do | ||||||
|  |     changeset |> changeset_error_map() |> Map.get(key) | ||||||
|  |   end | ||||||
|  |  | ||||||
|   @doc """ |   @doc """ | ||||||
|   Displays all errors from a changeset in a key value map |   Displays all errors from a changeset in a key value map | ||||||
|   """ |   """ | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ | |||||||
| ## Run `mix gettext.extract` to bring this file up to | ## Run `mix gettext.extract` to bring this file up to | ||||||
| ## date. Leave `msgstr`s empty as changing them here has no | ## date. Leave `msgstr`s empty as changing them here has no | ||||||
| ## effect: edit them in PO (`.po`) files instead. | ## effect: edit them in PO (`.po`) files instead. | ||||||
|  |  | ||||||
| ## From Ecto.Changeset.cast/4 | ## From Ecto.Changeset.cast/4 | ||||||
| msgid "can't be blank" | msgid "can't be blank" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -93,3 +92,10 @@ msgstr "" | |||||||
|  |  | ||||||
| msgid "must be equal to %{number}" | msgid "must be equal to %{number}" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #, elixir-format, ex-autogen | ||||||
|  | #: lib/cannery/containers.ex:104 | ||||||
|  | msgid "There is still %{amount} ammo group in this container!" | ||||||
|  | msgid_plural "There are still %{amount} ammo groups in this container!" | ||||||
|  | msgstr[0] "" | ||||||
|  | msgstr[1] "" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user