defmodule SimpleshopTheme.Orders.Order do use Ecto.Schema import Ecto.Changeset @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id @payment_statuses ~w(pending paid failed refunded) @fulfilment_statuses ~w(unfulfilled submitted processing shipped delivered failed cancelled) def fulfilment_statuses, do: @fulfilment_statuses schema "orders" do field :order_number, :string field :stripe_session_id, :string field :stripe_payment_intent_id, :string field :payment_status, :string, default: "pending" field :customer_email, :string field :shipping_address, :map, default: %{} field :subtotal, :integer field :total, :integer field :currency, :string, default: "gbp" field :metadata, :map, default: %{} # Fulfilment field :fulfilment_status, :string, default: "unfulfilled" field :provider_order_id, :string field :provider_status, :string field :fulfilment_error, :string field :tracking_number, :string field :tracking_url, :string field :submitted_at, :utc_datetime field :shipped_at, :utc_datetime field :delivered_at, :utc_datetime has_many :items, SimpleshopTheme.Orders.OrderItem timestamps(type: :utc_datetime) end def changeset(order, attrs) do order |> cast(attrs, [ :order_number, :stripe_session_id, :stripe_payment_intent_id, :payment_status, :customer_email, :shipping_address, :subtotal, :total, :currency, :metadata ]) |> validate_required([:order_number, :subtotal, :total, :currency]) |> validate_inclusion(:payment_status, @payment_statuses) |> validate_number(:subtotal, greater_than_or_equal_to: 0) |> validate_number(:total, greater_than_or_equal_to: 0) |> unique_constraint(:order_number) |> unique_constraint(:stripe_session_id) end def fulfilment_changeset(order, attrs) do order |> cast(attrs, [ :fulfilment_status, :provider_order_id, :provider_status, :fulfilment_error, :tracking_number, :tracking_url, :submitted_at, :shipped_at, :delivered_at ]) |> validate_inclusion(:fulfilment_status, @fulfilment_statuses) end end