Smart-catalogue rule: one row per (item, referenced_catalogue) pair.
Lets an item in a smart catalogue declare "I apply value unit
to this other catalogue" (e.g. 5% of Kitchen, flat $20 of Hardware).
Both value and unit are nullable — when NULL, the rule inherits
the parent item's default_value / default_unit. That lets a user
set "5% across everything" once and only override specific catalogues.
The unit vocabulary is open-ended VARCHAR so consumers can add new
units without a migration. V1 recognizes "percent" and "flat";
anything else is stored verbatim and left to the consumer to validate.
See the Smart Catalogues guide for a worked example and the consumer-side math pattern.
Summary
Functions
Returns the effective {value, unit} for a rule, falling back to the
item's default_value / default_unit when the rule row has NULL.
Types
@type t() :: %PhoenixKitCatalogue.Schemas.CatalogueRule{ __meta__: term(), inserted_at: DateTime.t() | nil, item: term(), item_uuid: Ecto.UUID.t() | nil, position: integer(), referenced_catalogue: term(), referenced_catalogue_uuid: Ecto.UUID.t() | nil, unit: String.t() | nil, updated_at: DateTime.t() | nil, uuid: Ecto.UUID.t() | nil, value: Decimal.t() | nil }
Functions
@spec allowed_units() :: [String.t()]
@spec changeset(t() | Ecto.Changeset.t(t()), map()) :: Ecto.Changeset.t(t())
@spec effective(t(), PhoenixKitCatalogue.Schemas.Item.t() | map() | nil) :: {Decimal.t() | nil, String.t() | nil}
Returns the effective {value, unit} for a rule, falling back to the
item's default_value / default_unit when the rule row has NULL.
Each leg is independent: a rule can have its own value while
inheriting unit from the item default (or vice versa).
Returns {nil, nil} when nothing is set anywhere — which means
"applies but amount unspecified"; the consumer decides what to do.
Examples
# Rule with both legs nil → inherits both from item
rule = %CatalogueRule{value: nil, unit: nil}
item = %Item{default_value: Decimal.new("5"), default_unit: "percent"}
effective(rule, item)
#=> {Decimal.new("5"), "percent"}
# Rule overrides value, inherits unit
rule = %CatalogueRule{value: Decimal.new("10"), unit: nil}
effective(rule, item)
#=> {Decimal.new("10"), "percent"}