Current section

Files

Jump to
invoicex lib invoicex document invoice.ex
Raw

lib/invoicex/document/invoice.ex

defmodule Invoicex.Document.Invoice do
@moduledoc """
Stores invoice data.
"""
use Ecto.Schema
alias Ecto.Changeset
alias Invoicex.Document
alias Invoicex.Document.{Buyer, Group, Item, Number, Seller}
alias Invoicex.Ecommerce.Trader
alias Invoicex.Enum.InvoiceType
alias Invoicex.Extra.{Note, Reason}
@required_fields [:title, :trader_id, :type]
@fields [
:custom_number,
:description,
:due_date,
:expected_payment_date,
:footer,
:is_archived,
:is_paid,
:issue_date,
:pdf_path
] ++ @required_fields
@messages %{
empty: "Expected at least one group or item",
invalid: "Invalid order of group(s) and/or item(s)"
}
@schema_prefix Invoicex.schema_prefix()
schema "invoices" do
belongs_to(:trader, Trader)
embeds_many(:correct_reasons, Reason)
embeds_many(:edit_reasons, Reason)
embeds_many(:groups, Group)
embeds_many(:items, Item)
embeds_many(:notes, Note)
embeds_one(:buyer, Buyer)
embeds_one(:number, Number)
embeds_one(:seller, Seller)
field(:custom_number, :string)
field(:description, :string)
field(:due_date, :date)
field(:expected_payment_date, :date)
field(:footer, :string)
field(:is_archived, :boolean, default: false)
field(:is_paid, :boolean, default: false)
field(:issue_date, :date)
field(:list, {:array, :map}, virtual: true)
field(:pdf_path, :string)
field(:title, :string)
field(:total, :map, virtual: true)
field(:type, InvoiceType)
timestamps()
end
@doc false
def changeset(invoice \\ %__MODULE__{}, attrs \\ %{}) do
invoice
|> Changeset.cast(attrs, @fields)
|> Changeset.assoc_constraint(:trader)
|> Changeset.cast_embed(:buyer, required: true)
|> Changeset.cast_embed(:correct_reasons)
|> Changeset.cast_embed(:edit_reasons)
|> Changeset.cast_embed(:groups)
|> Changeset.cast_embed(:items)
|> Changeset.cast_embed(:notes)
|> validate_number()
|> Changeset.cast_embed(:seller, required: true)
|> custom_validates()
|> Changeset.validate_required(@required_fields)
end
defp custom_validates(changeset) do
list = Document.build_list(changeset)
Document.validate_orders(changeset, list, @messages)
end
defp validate_number(changeset) do
type = Changeset.get_change(changeset, :type)
Changeset.cast_embed(
changeset,
:number,
required: true,
with: &Number.changeset(&1, &2, type)
)
end
end