130 lines
3.1 KiB
Elixir
130 lines
3.1 KiB
Elixir
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
|