defmodule Bacen.STA.Protocol do @moduledoc """ The protocol message schema for Sisbacen's server. This message is responsible to create a new protocol into Sisbacen's server to allow the application to send one of the ACCS/CCS messages for given protocol. It has the following XML examples: ```xml ACCS001 1235345hfdsahgdasd214312 1234 202105072230.xml ``` ```xml ACCS001 1235345hfdsahgdasd214312 1234 202105072230.xml bla bla bla ``` ```xml ACCS001 1235345hfdsahgdasd214312 1234 202105072230.xml bla bla bla 12345 dependencia 1 operador 1 ``` """ use Ecto.Schema import Ecto.Changeset @typedoc """ The Bacen's CCS protocol type """ @type t :: %__MODULE__{} @parameters_fields ~w(file_type hash file_size file_name observation)a @parameters_required_fields ~w(file_type hash file_size file_name)a @sender_fields ~w(unity dependency operator)a @primary_key false embedded_schema do embeds_one :parameters, Parameters, primary_key: false do field :file_type, :string, source: :IdentificadorDocumento field :hash, :string, source: :Hash field :file_size, :integer, source: :Tamanho field :file_name, :string, source: :NomeArquivo field :observation, :string, source: :Observacao embeds_one :senders, Senders, primary_key: false, source: :Destinatarios do embeds_many :sender, Sender, primary_key: false, source: :Destinatario do field :unity, :string, source: :Unidade field :dependency, :string, source: :Dependencia field :operator, :string, source: :Operador end end end end @doc """ Create new valid protocol xml from given attributes """ @spec new(map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()} def new(attrs \\ %{}) do %__MODULE__{} |> changeset(attrs) |> apply_action(:insert) end @doc false def changeset(schema = %__MODULE__{}, attrs) when is_map(attrs) do schema |> cast(attrs, []) |> cast_embed(:parameters, with: ¶meters_changeset/2, required: true) end @doc false def parameters_changeset(parameters, attrs) when is_map(attrs) do parameters |> cast(attrs, @parameters_fields) |> validate_required(@parameters_required_fields) |> validate_length(:hash, is: 64) |> cast_embed(:senders, with: &senders_changeset/2) end @doc false def senders_changeset(senders, attrs) when is_map(attrs) do senders |> cast(attrs, []) |> cast_embed(:sender, with: &sender_changeset/2) end @doc false def sender_changeset(sender, attrs) when is_map(attrs) do sender |> cast(attrs, @sender_fields) |> validate_required(@sender_fields) end end