# `PhoenixKit.Migrations.Postgres.V102`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.165/lib/phoenix_kit/migrations/postgres/v102.ex#L1)

V102: Catalogue discount + smart catalogues.

Two related catalogue features shipped together:

## Discount

Mirrors the markup columns added in V89 (catalogue) and V97 (item override):

- `phoenix_kit_cat_catalogues.discount_percentage DECIMAL(7, 2)
  NOT NULL DEFAULT 0` — the catalogue-wide default discount applied on
  top of the post-markup sale price.
- `phoenix_kit_cat_items.discount_percentage DECIMAL(7, 2)` — nullable
  per-item override. `NULL` = inherit the catalogue's discount; any set
  value (including `0`) overrides the catalogue's discount for that item.

The pricing chain becomes `base → markup → discount`:

    sale_price   = base_price * (1 + effective_markup   / 100)
    final_price  = sale_price  * (1 -  effective_discount / 100)

## Smart catalogues

A smart catalogue's items reference *other* catalogues with a value +
unit (e.g. a "Delivery" item says "5% of Kitchen, 3% of Plumbing, plus
$20 flat of Hardware"). Consumers do the math; this module stores the
user's intent.

- `phoenix_kit_cat_catalogues.kind VARCHAR(20) NOT NULL DEFAULT 'standard'`
  — one of `'standard'` (existing behavior) or `'smart'` (items
  reference other catalogues).
- `phoenix_kit_cat_items.default_value DECIMAL(12, 4)` and
  `default_unit VARCHAR(20)` (both nullable) — per-item fallback that
  applies when a rule row has NULL `value`/`unit`.
- New table `phoenix_kit_cat_item_catalogue_rules` storing one row per
  (item, referenced_catalogue) pair, with nullable `value` + `unit`
  (inherit from item defaults) and a `position INT` for UI ordering.
  Unit vocabulary is open-ended VARCHAR; v1 uses `'percent'` and
  `'flat'`. Self- and smart-to-smart references are intentionally
  allowed — consumers handle cycles at math time.

All operations are idempotent.

# `down`

Rolls V102 back: drops the rules table and both sets of added columns
(discount + smart-catalogue).

**Lossy rollback:** all discount values, smart-catalogue rules, item
defaults, and the `kind` distinction are lost. Back up before rolling
back in production.

# `up`

---

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