Skip to content

Commit

Permalink
Live Movement Form
Browse files Browse the repository at this point in the history
  • Loading branch information
maennchen committed May 28, 2022
1 parent 5cef1e8 commit 6c5e4ad
Show file tree
Hide file tree
Showing 22 changed files with 528 additions and 469 deletions.
7 changes: 6 additions & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
[
import_deps: [:ecto, :phoenix, :absinthe],
locals_without_parens: [
# Phoenix.LiveViewTest
assert_redirect: 1,
refute_redirected: 2
],
import_deps: [:ecto, :phoenix, :phoenix_live_view, :absinthe],
inputs: [
"{mix,.formatter}.exs",
"*.{ex,exs}",
Expand Down
1 change: 1 addition & 0 deletions lib/athena.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Athena do
quote do
use Ecto.Schema

import Athena.ChangesetHelper
import Ecto.Changeset

alias Ecto.Changeset
Expand Down
28 changes: 28 additions & 0 deletions lib/athena/changeset_helper.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Athena.ChangesetHelper do
@moduledoc false

import Ecto.Changeset

alias Ecto.Changeset

@spec fill_uuid(changeset :: Changeset.t()) :: Changeset.t()
def fill_uuid(changeset) do
changeset
|> fetch_field!(:id)
|> case do
nil -> put_change(changeset, :id, Ecto.UUID.generate())
id when is_binary(id) -> changeset
end
end

@spec validate_one_required(changeset :: Changeset.t(), fields :: [atom()]) :: Changeset.t()
def validate_one_required(changeset, [first_field | _] = fields) do
fields
|> Enum.map(&get_field(changeset, &1))
|> Enum.reject(&is_nil/1)
|> case do
[] -> add_error(changeset, first_field, "at least field is required", fields: fields)
[_ | _] -> changeset
end
end
end
15 changes: 10 additions & 5 deletions lib/athena/inventory/event.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ defmodule Athena.Inventory.Event do
schema "events" do
field :name, :string

has_many :locations, Location
has_many :item_groups, ItemGroup
has_many :items, through: [:item_groups, :items]
has_many :movements, through: [:item_groups, :items, :movements]
has_many :stock_entries, StockEntry
has_many :locations, Location, preload_order: [asc: :name]
has_many :item_groups, ItemGroup, preload_order: [asc: :name]
has_many :items, through: [:item_groups, :items], preload_order: [asc: :name]

has_many :movements,
through: [:item_groups, :items, :movements],
preload_order: [asc: :inserted_at]

has_many :stock_entries, StockEntry, preload_order: [asc: :item_id, asc: :location_id]

timestamps()
end
Expand All @@ -39,5 +43,6 @@ defmodule Athena.Inventory.Event do
do:
event
|> cast(attrs, [:name])
|> fill_uuid()
|> validate_required([:name])
end
5 changes: 3 additions & 2 deletions lib/athena/inventory/item.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ defmodule Athena.Inventory.Item do

belongs_to :item_group, ItemGroup
has_one :event, through: [:item_group, :event]
has_many :movements, Movement
has_many :stock_entries, StockEntry
has_many :movements, Movement, preload_order: [asc: :inserted_at]
has_many :stock_entries, StockEntry, preload_order: [asc: :location_id]

timestamps()
end
Expand All @@ -38,6 +38,7 @@ defmodule Athena.Inventory.Item do
def changeset(item, attrs) do
item
|> cast(attrs, [:name, :unit, :inverse, :item_group_id])
|> fill_uuid()
|> validate_required([:name, :unit, :inverse, :item_group_id])
|> foreign_key_constraint(:item_group_id)
end
Expand Down
7 changes: 4 additions & 3 deletions lib/athena/inventory/item_group.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ defmodule Athena.Inventory.ItemGroup do
field :name, :string

belongs_to :event, Event
has_many :items, Item
has_many :movements, through: [:items, :movements]
has_many :stock_entries, StockEntry
has_many :items, Item, preload_order: [asc: :name]
has_many :movements, through: [:items, :movements], preload_order: [asc: :inserted_at]
has_many :stock_entries, StockEntry, preload_order: [asc: :item_id, asc: :location_id]

timestamps()
end
Expand All @@ -36,6 +36,7 @@ defmodule Athena.Inventory.ItemGroup do
do:
item_group
|> cast(attrs, [:name, :event_id])
|> fill_uuid()
|> validate_required([:name, :event_id])
|> foreign_key_constraint(:event_id)
end
14 changes: 11 additions & 3 deletions lib/athena/inventory/location.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ defmodule Athena.Inventory.Location do
field :name, :string

belongs_to :event, Event
has_many :movements_in, Movement, foreign_key: :destination_location_id
has_many :movements_out, Movement, foreign_key: :source_location_id
has_many :stock_entries, StockEntry

has_many :movements_in, Movement,
foreign_key: :destination_location_id,
preload_order: [asc: :inserted_at]

has_many :movements_out, Movement,
foreign_key: :source_location_id,
preload_order: [asc: :inserted_at]

has_many :stock_entries, StockEntry, preload_order: [asc: :item_id]

timestamps()
end
Expand All @@ -35,6 +42,7 @@ defmodule Athena.Inventory.Location do
do:
location
|> cast(attrs, [:name, :event_id])
|> fill_uuid()
|> validate_required([:name, :event_id])
|> foreign_key_constraint(:event_id)
end
32 changes: 20 additions & 12 deletions lib/athena/inventory/movement.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,32 @@ defmodule Athena.Inventory.Movement do
end

@doc false
def changeset(movement, attrs) do
def changeset(
movement,
attrs,
opts \\ %{location_required: true, validate_amount_positive: false}
)

def changeset(movement, attrs, %{validate_amount_positive: true} = opts) do
movement
|> changeset(attrs, %{opts | validate_amount_positive: false})
|> validate_number(:amount, greater_than: 0, less_than: 1000)
end

def changeset(movement, attrs, %{location_required: true} = opts) do
movement
|> changeset(attrs, %{opts | location_required: false})
|> validate_one_required([:source_location_id, :destination_location_id])
end

def changeset(movement, attrs, %{location_required: false, validate_amount_positive: false}) do
movement
|> cast(attrs, [:amount, :item_id, :source_location_id, :destination_location_id])
|> fill_uuid()
|> validate_required([:amount, :item_id])
|> validate_number(:amount, greater_than: -100, less_than: 1000)
|> foreign_key_constraint(:item_id)
|> foreign_key_constraint(:source_location_id)
|> foreign_key_constraint(:destination_location_id)
|> validate_one_required([:source_location_id, :destination_location_id])
end

defp validate_one_required(changeset, [first_field | _] = fields) do
fields
|> Enum.map(&get_field(changeset, &1))
|> Enum.reject(&is_nil/1)
|> case do
[] -> add_error(changeset, first_field, "at least field is required", fields: fields)
[_ | _] -> changeset
end
end
end
57 changes: 0 additions & 57 deletions lib/athena_web/frontend/controller/movement_controller.ex

This file was deleted.

Loading

0 comments on commit 6c5e4ad

Please sign in to comment.