cannery/lib/cannery/ammo/type.ex

235 lines
6.1 KiB
Elixir
Raw Normal View History

2023-03-30 21:53:52 -04:00
defmodule Cannery.Ammo.Type do
2022-01-22 21:40:29 -05:00
@moduledoc """
An ammunition type.
Contains statistical information about the ammunition.
"""
2021-09-02 23:31:14 -04:00
use Ecto.Schema
import Ecto.Changeset
alias Cannery.Accounts.User
2023-03-29 22:54:55 -04:00
alias Cannery.Ammo.Pack
2022-01-31 20:08:01 -05:00
alias Ecto.{Changeset, UUID}
2021-09-02 23:31:14 -04:00
2022-11-09 23:33:50 -05:00
@derive {Jason.Encoder,
only: [
:name,
:desc,
2023-03-31 22:34:48 -04:00
:class,
2022-11-09 23:33:50 -05:00
:bullet_type,
:bullet_core,
:caliber,
:case_material,
:powder_type,
:grains,
:pressure,
:primer_type,
:firing_type,
2023-03-31 22:34:48 -04:00
:manufacturer,
:upc,
2022-11-09 23:33:50 -05:00
:tracer,
:incendiary,
:blank,
:corrosive,
2023-03-31 22:34:48 -04:00
:cartridge,
:jacket_type,
:powder_grains_per_charge,
:muzzle_velocity,
:wadding,
:shot_type,
:shot_material,
:shot_size,
:unfired_length,
:brass_height,
:chamber_size,
:load_grains,
:shot_charge_weight,
:dram_equivalent
2022-11-09 23:33:50 -05:00
]}
2021-09-02 23:31:14 -04:00
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
2023-03-30 21:53:52 -04:00
schema "types" do
2022-02-05 16:22:02 -05:00
field :name, :string
field :desc, :string
2023-04-10 20:12:02 -04:00
field :class, Ecto.Enum, values: [:rifle, :shotgun, :pistol], default: :rifle
2023-03-23 22:07:25 -04:00
# common fields
2022-02-05 16:22:02 -05:00
field :bullet_core, :string
2023-03-23 22:07:25 -04:00
# also gauge for shotguns
2022-02-05 16:22:02 -05:00
field :caliber, :string
2021-09-02 23:31:14 -04:00
field :case_material, :string
field :powder_type, :string
2022-02-05 16:22:02 -05:00
field :grains, :integer
field :pressure, :string
field :primer_type, :string
2022-02-16 00:10:18 -05:00
field :firing_type, :string
2023-03-23 22:07:25 -04:00
field :manufacturer, :string
field :upc, :string
2022-05-06 22:54:05 -04:00
field :tracer, :boolean, default: false
field :incendiary, :boolean, default: false
field :blank, :boolean, default: false
field :corrosive, :boolean, default: false
2022-02-05 16:22:02 -05:00
2023-03-23 22:07:25 -04:00
# rifle/pistol fields
# https://shootersreference.com/reloadingdata/bullet_abbreviations/
field :bullet_type, :string
2023-03-23 22:07:25 -04:00
field :cartridge, :string
field :jacket_type, :string
field :powder_grains_per_charge, :integer
field :muzzle_velocity, :integer
2021-09-02 23:31:14 -04:00
2023-03-23 22:07:25 -04:00
# shotgun fields
field :wadding, :string
field :shot_type, :string
field :shot_material, :string
field :shot_size, :string
field :unfired_length, :string
field :brass_height, :string
field :chamber_size, :string
field :load_grains, :integer
field :shot_charge_weight, :string
field :dram_equivalent, :string
2023-03-23 22:07:25 -04:00
field :user_id, :binary_id
2023-03-29 22:54:55 -04:00
has_many :packs, Pack
2022-02-05 01:59:09 -05:00
2021-09-02 23:31:14 -04:00
timestamps()
end
@type t :: %__MODULE__{
2022-01-31 20:08:01 -05:00
id: id(),
2022-02-05 16:22:02 -05:00
name: String.t(),
desc: String.t() | nil,
2023-03-28 23:08:40 -04:00
class: class(),
bullet_type: String.t() | nil,
bullet_core: String.t() | nil,
caliber: String.t() | nil,
case_material: String.t() | nil,
powder_type: String.t() | nil,
grains: integer() | nil,
pressure: String.t() | nil,
primer_type: String.t() | nil,
2022-02-16 00:10:18 -05:00
firing_type: String.t() | nil,
2023-03-31 22:34:48 -04:00
manufacturer: String.t() | nil,
upc: String.t() | nil,
tracer: boolean(),
incendiary: boolean(),
blank: boolean(),
corrosive: boolean(),
cartridge: String.t() | nil,
jacket_type: String.t() | nil,
powder_grains_per_charge: integer() | nil,
muzzle_velocity: integer() | nil,
2023-03-23 22:07:25 -04:00
wadding: String.t() | nil,
shot_type: String.t() | nil,
shot_material: String.t() | nil,
shot_size: String.t() | nil,
unfired_length: String.t() | nil,
brass_height: String.t() | nil,
chamber_size: String.t() | nil,
load_grains: integer() | nil,
shot_charge_weight: String.t() | nil,
dram_equivalent: String.t() | nil,
user_id: User.id(),
2023-03-29 22:54:55 -04:00
packs: [Pack.t()] | nil,
2022-01-31 20:08:01 -05:00
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
2023-03-30 21:53:52 -04:00
@type new_type :: %__MODULE__{}
2022-01-31 20:08:01 -05:00
@type id :: UUID.t()
2023-03-30 21:53:52 -04:00
@type changeset :: Changeset.t(t() | new_type())
2023-03-28 23:08:40 -04:00
@type class :: :rifle | :shotgun | :pistol | nil
2022-01-31 20:08:01 -05:00
@spec changeset_fields() :: [atom()]
defp changeset_fields,
do: [
2022-02-05 16:22:02 -05:00
:name,
:desc,
2023-03-28 23:08:40 -04:00
:class,
2022-02-05 16:22:02 -05:00
:bullet_type,
:bullet_core,
:caliber,
:case_material,
:powder_type,
2022-02-05 16:22:02 -05:00
:grains,
:pressure,
:primer_type,
2022-02-16 00:10:18 -05:00
:firing_type,
2023-03-31 22:34:48 -04:00
:manufacturer,
:upc,
:tracer,
:incendiary,
:blank,
:corrosive,
:cartridge,
:jacket_type,
:powder_grains_per_charge,
:muzzle_velocity,
2023-03-23 22:07:25 -04:00
:wadding,
:shot_type,
:shot_material,
:shot_size,
:unfired_length,
:brass_height,
:chamber_size,
:load_grains,
:shot_charge_weight,
2023-03-31 22:34:48 -04:00
:dram_equivalent
]
2023-03-19 23:46:42 -04:00
@spec string_fields() :: [atom()]
defp string_fields,
do: [
:name,
2023-03-31 22:34:48 -04:00
:desc,
2023-03-19 23:46:42 -04:00
:bullet_type,
:bullet_core,
:caliber,
:case_material,
:powder_type,
:pressure,
:primer_type,
:firing_type,
2023-03-31 22:34:48 -04:00
:manufacturer,
:upc,
:cartridge,
:jacket_type,
2023-03-23 22:07:25 -04:00
:wadding,
:shot_type,
:shot_material,
:shot_size,
:unfired_length,
:brass_height,
:chamber_size,
:shot_charge_weight,
2023-03-31 22:34:48 -04:00
:dram_equivalent
2023-03-19 23:46:42 -04:00
]
@doc false
2023-03-30 21:53:52 -04:00
@spec create_changeset(new_type(), User.t(), attrs :: map()) :: changeset()
def create_changeset(type, %User{id: user_id}, attrs) do
2023-03-19 23:46:42 -04:00
changeset =
2023-03-30 21:53:52 -04:00
type
2023-03-19 23:46:42 -04:00
|> change(user_id: user_id)
|> cast(attrs, changeset_fields())
string_fields()
|> Enum.reduce(changeset, fn field, acc -> acc |> validate_length(field, max: 255) end)
|> validate_required([:name, :user_id])
end
@doc false
2023-03-30 21:53:52 -04:00
@spec update_changeset(t() | new_type(), attrs :: map()) :: changeset()
def update_changeset(type, attrs) do
2023-03-19 23:46:42 -04:00
changeset =
2023-03-30 21:53:52 -04:00
type
2023-03-19 23:46:42 -04:00
|> cast(attrs, changeset_fields())
string_fields()
|> Enum.reduce(changeset, fn field, acc -> acc |> validate_length(field, max: 255) end)
2022-07-01 19:53:44 -04:00
|> validate_required(:name)
2021-09-02 23:31:14 -04:00
end
end