# `PhoenixKitCatalogue.Schemas.CatalogueRule`
[🔗](https://github.com/BeamLabEU/phoenix_kit_catalogue/blob/0.1.14/lib/phoenix_kit_catalogue/schemas/catalogue_rule.ex#L1)

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](smart_catalogues.md) for a worked
example and the consumer-side math pattern.

# `t`

```elixir
@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
}
```

# `allowed_units`

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

# `changeset`

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

# `effective`

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
