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

Cria modelos para APP de Cotações #111

Merged
merged 5 commits into from
Jul 4, 2023
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
5 changes: 3 additions & 2 deletions apps/cotacoes/.formatter.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
import_deps: [:ecto, :ecto_sql],
subdirectories: ["priv/*/migrations"],
inputs: ["*.{ex,exs}", "{lib,test}/**/*.{ex,exs}", "priv/*/seeds.exs"]
]
25 changes: 25 additions & 0 deletions apps/cotacoes/lib/cotacoes/models/cotacao.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule Cotacoes.Models.Cotacao do
use Database, :model

@type t :: %Cotacao{id: binary, data: Date.t(), link: binary, fonte: binary}

@required_fields ~w(data fonte)a
@optional_fields ~w(link)a

@primary_key false
schema "cotacao" do
field :data, :date, primary_key: true
field :fonte, :string, primary_key: true
field :link, :string
field :id, Database.Types.PublicId, autogenerate: true
end

@spec changeset(Cotacao.t(), map) :: changeset
def changeset(%Cotacao{} = cotacao, attrs) do
cotacao
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> foreign_key_constraint(:fonte)
|> unique_constraint(:data)
end
end
39 changes: 39 additions & 0 deletions apps/cotacoes/lib/cotacoes/models/cotacao_pescado.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule Cotacoes.Models.CotacaoPescado do
use Database, :model

@type t :: %CotacaoPescado{
id: binary,
cotacao_data: Date.t(),
pescado_codigo: binary,
fonte_nome: binary,
preco_minimo: integer,
preco_maximo: integer,
preco_mais_comum: integer,
preco_medio: integer
}

@required_fields ~w(cotacao_data pescado_codigo fonte_nome preco_minimo preco_maximo)a
@optional_fields ~w(preco_mais_comum preco_medio)a

@primary_key false
schema "cotacoes_pescados" do
field :id, Database.Types.PublicId, autogenerate: true
field :cotacao_data, :date, primary_key: true
field :pescado_codigo, :string, primary_key: true
field :fonte_nome, :string, primary_key: true
field :preco_minimo, :integer
field :preco_maximo, :integer
field :preco_mais_comum, :integer
field :preco_medio, :integer
end

@spec changeset(CotacaoPescado.t(), map) :: changeset
def changeset(%CotacaoPescado{} = cot_pescado, attrs) do
cot_pescado
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> foreign_key_constraint(:cotacao_data)
|> foreign_key_constraint(:pescado_codigo)
|> foreign_key_constraint(:fonte_nome)
end
end
22 changes: 22 additions & 0 deletions apps/cotacoes/lib/cotacoes/models/fonte.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Cotacoes.Models.Fonte do
use Database, :model

@type t :: %Fonte{id: binary, nome: binary, link: binary, descricao: binary}

@required_fields ~w(nome link)a
@optional_fields ~w(descricao)a

@primary_key {:nome, :string, autogenerate: false}
schema "fonte_cotacao" do
field :link, :string
field :descricao, :string
field :id, Database.Types.PublicId, autogenerate: true
end

@spec changeset(Fonte.t(), map) :: changeset
def changeset(%Fonte{} = fonte, attrs) do
fonte
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
end
end
22 changes: 22 additions & 0 deletions apps/cotacoes/lib/cotacoes/models/pescado.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Cotacoes.Models.Pescado do
use Database, :model

@type t :: %Pescado{id: binary, codigo: binary, descricao: binary, embalagem: binary}

@required_fields ~w(codigo)a
@optional_fields ~w(descricao embalagem)a

@primary_key {:codigo, :string, autogenerate: false}
schema "pescado" do
field :descricao, :string
field :embalagem, :string
field :id, Database.Types.PublicId, autogenerate: true
end

@spec changeset(Pescado.t(), map) :: changeset
def changeset(%Pescado{} = pescado, attrs) do
pescado
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
end
end
15 changes: 14 additions & 1 deletion apps/cotacoes/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ defmodule Cotacoes.MixProject do
lockfile: "../../mix.lock",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
deps: deps()
deps: deps(),
aliases: aliases(),
elixirc_paths: elixirc_paths(Mix.env())
]
end

Expand All @@ -21,6 +23,9 @@ defmodule Cotacoes.MixProject do
]
end

defp elixirc_paths(e) when e in ~w(dev test)a, do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]

defp deps do
[
{:ecto_sql, "~> 3.4"},
Expand All @@ -29,4 +34,12 @@ defmodule Cotacoes.MixProject do
{:database, in_umbrella: true}
]
end

defp aliases do
[
"ecto.setup": ["ecto.create", "ecto.migrate"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"]
]
end
end
14 changes: 14 additions & 0 deletions apps/cotacoes/priv/repo/migrations/20230704182529_cria_pescado.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule Database.Repo.Migrations.CriaPescado do
use Ecto.Migration

def change do
create table(:pescado, primary_key: false) do
add :id, :string
add :codigo, :string, primary_key: true, null: false
add :descricao, :string
add :embalagem, :string
end

create unique_index(:pescado, [:codigo])
end
end
14 changes: 14 additions & 0 deletions apps/cotacoes/priv/repo/migrations/20230704182916_cria_fonte.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule Database.Repo.Migrations.CriaFonte do
use Ecto.Migration

def change do
create table(:fonte_cotacao, primary_key: false) do
add :id, :string
add :nome, :string, primary_key: true, null: false
add :descricao, :string
add :link, :string, null: false
end

create unique_index(:fonte_cotacao, [:nome, :link])
end
end
18 changes: 18 additions & 0 deletions apps/cotacoes/priv/repo/migrations/20230704182917_cria_cotacao.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule Database.Repo.Migrations.CriaCotacao do
use Ecto.Migration

def change do
create table(:cotacao, primary_key: false) do
add :id, :string
add :data, :date, primary_key: true, null: false
add :link, :string

add :fonte, references(:fonte_cotacao, column: :nome, type: :string),
primary_key: true,
null: false
end

create index(:cotacao, [:fonte])
create unique_index(:cotacao, [:data])
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Database.Repo.Migrations.CriaCotacoesPescados do
use Ecto.Migration

def change do
create table(:cotacoes_pescados, primary_key: false) do
add :id, :string
add :cotacao_data, references(:cotacao, column: :data, type: :date), primary_key: true
add :pescado_codigo, references(:pescado, column: :codigo, type: :string), primary_key: true
add :fonte_nome, references(:fonte_cotacao, column: :nome, type: :string), primary_key: true
add :preco_minimo, :integer
add :preco_maximo, :integer
add :preco_mais_comum, :integer
add :preco_medio, :integer
end

create index(:cotacoes_pescados, [:cotacao_data])
create index(:cotacoes_pescados, [:pescado_codigo])
create index(:cotacoes_pescados, [:fonte_nome])
create unique_index(:cotacoes_pescados, [:cotacao_data, :pescado_codigo, :fonte_nome])
end
end
70 changes: 70 additions & 0 deletions apps/cotacoes/test/cotacoes/models/cotacao_pescado_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
defmodule Cotacoes.Models.CotacaoPescadoTest do
use Database.DataCase, async: true

import Cotacoes.Factory

alias Cotacoes.Models.CotacaoPescado

@moduletag :unit

test "changeset valido com campos obrigatorios" do
cotacao = insert(:cotacao)
fonte = insert(:fonte)
pescado = insert(:pescado)

attrs = %{
cotacao_data: cotacao.data,
fonte_nome: fonte.nome,
pescado_codigo: pescado.codigo,
preco_minimo: 1000,
preco_maximo: 2000
}

changeset = CotacaoPescado.changeset(%CotacaoPescado{}, attrs)

assert changeset.valid?
assert get_change(changeset, :cotacao_data) == cotacao.data
assert get_change(changeset, :fonte_nome) == fonte.nome
assert get_change(changeset, :pescado_codigo) == pescado.codigo
assert get_change(changeset, :preco_minimo) == 1000
assert get_change(changeset, :preco_maximo) == 2000
end

test "changeset valido com campos opcionais" do
cotacao = insert(:cotacao)
fonte = insert(:fonte)
pescado = insert(:pescado)

attrs = %{
cotacao_data: cotacao.data,
fonte_nome: fonte.nome,
pescado_codigo: pescado.codigo,
preco_minimo: 1000,
preco_maximo: 2000,
preco_medio: 1500,
preco_mais_comum: 1750
}

changeset = CotacaoPescado.changeset(%CotacaoPescado{}, attrs)

assert changeset.valid?
assert get_change(changeset, :cotacao_data) == cotacao.data
assert get_change(changeset, :fonte_nome) == fonte.nome
assert get_change(changeset, :pescado_codigo) == pescado.codigo
assert get_change(changeset, :preco_minimo) == 1000
assert get_change(changeset, :preco_maximo) == 2000
assert get_change(changeset, :preco_medio) == 1500
assert get_change(changeset, :preco_mais_comum) == 1750
end

test "changeset invalido sem campos obrigatorios" do
changeset = CotacaoPescado.changeset(%CotacaoPescado{}, %{})

refute changeset.valid?
assert Keyword.get(changeset.errors, :cotacao_data)
assert Keyword.get(changeset.errors, :fonte_nome)
assert Keyword.get(changeset.errors, :pescado_codigo)
assert Keyword.get(changeset.errors, :preco_maximo)
assert Keyword.get(changeset.errors, :preco_minimo)
end
end
40 changes: 40 additions & 0 deletions apps/cotacoes/test/cotacoes/models/cotacao_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule Cotacoes.Models.CotacaoTest do
use Database.DataCase, async: true

import Cotacoes.Factory

alias Cotacoes.Models.Cotacao

@moduletag :unit

test "changeset valido com campos obrigatorios" do
fonte = insert(:fonte)
attrs = %{data: Date.utc_today(), fonte: fonte.nome}

changeset = Cotacao.changeset(%Cotacao{}, attrs)

assert changeset.valid?
assert get_change(changeset, :data) == Date.utc_today()
assert get_change(changeset, :fonte) == fonte.nome
end

test "changeset valido com campos opcionais" do
fonte = insert(:fonte)
attrs = %{data: Date.utc_today(), fonte: fonte.nome, link: "https://example.com"}

changeset = Cotacao.changeset(%Cotacao{}, attrs)

assert changeset.valid?
assert get_change(changeset, :data) == Date.utc_today()
assert get_change(changeset, :fonte) == fonte.nome
assert get_change(changeset, :link) == "https://example.com"
end

test "changeset invalido sem campos obrigatorios" do
changeset = Cotacao.changeset(%Cotacao{}, %{})

refute changeset.valid?
assert Keyword.get(changeset.errors, :data)
assert Keyword.get(changeset.errors, :fonte)
end
end
36 changes: 36 additions & 0 deletions apps/cotacoes/test/cotacoes/models/fonte_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule Cotacoes.Models.FonteTest do
use Database.DataCase, async: true

alias Cotacoes.Models.Fonte

@moduletag :unit

test "changeset valido com campos obrigatorios" do
attrs = %{nome: "nome", link: "https://example.com"}

changeset = Fonte.changeset(%Fonte{}, attrs)

assert changeset.valid?
assert get_change(changeset, :nome) == "nome"
assert get_change(changeset, :link) == "https://example.com"
end

test "changeset valido com campos opcionais" do
attrs = %{nome: "nome", link: "https://example.com", descricao: "descricao"}

changeset = Fonte.changeset(%Fonte{}, attrs)

assert changeset.valid?
assert get_change(changeset, :nome) == "nome"
assert get_change(changeset, :link) == "https://example.com"
assert get_change(changeset, :descricao) == "descricao"
end

test "changeset invalido sem campos obrigatorios" do
changeset = Fonte.changeset(%Fonte{}, %{})

refute changeset.valid?
assert Keyword.get(changeset.errors, :nome)
assert Keyword.get(changeset.errors, :link)
end
end
Loading
Loading