Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live Movement Form #130

Merged
merged 1 commit into from
May 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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