PhoenixKitCatalogue.Schemas.CatalogueRule (PhoenixKitCatalogue v0.1.14)

Copy Markdown View Source

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

t()

@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

allowed_units()

@spec allowed_units() :: [String.t()]

changeset(rule, attrs)

@spec changeset(t() | Ecto.Changeset.t(t()), map()) :: Ecto.Changeset.t(t())

effective(catalogue_rule, item)

@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"}