defmodule Mv.Membership.Member do use Ecto.Schema import Ecto.Changeset import EctoCommons.EmailValidator @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id schema "members" do field :first_name, :string field :last_name, :string field :email, :string field :phone_number, :string field :postal_code, :string field :birth_date, :date field :paid, :boolean, default: false field :join_date, :date field :exit_date, :date field :notes, :string field :city, :string field :street, :string field :house_number, :string timestamps(type: :utc_datetime) end @doc false def changeset(member, attrs) do member |> cast(attrs, [ :first_name, :last_name, :email, :birth_date, :paid, :phone_number, :join_date, :exit_date, :notes, :city, :street, :house_number, :postal_code ]) |> validate_required([:first_name, :last_name, :email]) |> validate_length(:first_name, min: 1) |> validate_length(:last_name, min: 1) |> validate_length(:email, min: 5, max: 254) |> validate_email(:email, checks: [:html_input, :pow]) |> validate_birth_date() |> validate_join_date() |> validate_exit_date() |> validate_phone_number() |> validate_postal_code() end def create_changeset(member, attrs, _metadata) do changeset(member, attrs) end def update_changeset(member, attrs, _metadata) do changeset(member, attrs) end defp validate_birth_date(changeset) do case get_field(changeset, :birth_date) do nil -> changeset birth_date -> if Date.compare(birth_date, Date.utc_today()) == :gt do add_error(changeset, :birth_date, "cannot be in the future") else changeset end end end defp validate_join_date(changeset) do case get_field(changeset, :join_date) do nil -> changeset join_date -> if Date.compare(join_date, Date.utc_today()) == :gt do add_error(changeset, :join_date, "cannot be in the future") else changeset end end end defp validate_exit_date(changeset) do join_date = get_field(changeset, :join_date) exit_date = get_field(changeset, :exit_date) if join_date && exit_date && Date.compare(exit_date, join_date) != :gt do add_error(changeset, :exit_date, "cannot be before join date") else changeset end end defp validate_phone_number(changeset) do case get_field(changeset, :phone_number) do nil -> changeset phone_number -> if Regex.match?(~r/^\+?[0-9\- ]{6,20}$/, phone_number) do changeset else add_error(changeset, :phone_number, "is not a valid phone number") end end end defp validate_postal_code(changeset) do case get_field(changeset, :postal_code) do nil -> changeset postal_code -> if Regex.match?(~r/^\d{5}$/, postal_code) do changeset else add_error(changeset, :postal_code, "must consist of 5 digits") end end end end