# `UnitPrice`

A price per an amount of a quantity, a choice by the quantity's kind, as the UK's Price Marking Order prices goods by weight, volume, length and area: shown `£2.50/1 kg`. Neither the price nor the amount is below 0.

[Money and banking](types.md#money-and-banking); not ordered; since Jadpo 0.1.0.

## Make one

Pick one of its variants and give its fields, `UnitPrice.per_mass { price: ...  per: ... }`.

## Variants

| Variant | Fields |
|---|---|
| `per_mass` | `price`: [`Money`](type-money.md), `per`: [`Mass`](type-mass.md) |
| `per_volume` | `price`: [`Money`](type-money.md), `per`: [`Volume`](type-volume.md) |
| `per_length` | `price`: [`Money`](type-money.md), `per`: [`Length`](type-length.md) |
| `per_area` | `price`: [`Money`](type-money.md), `per`: [`Area`](type-area.md) |

## Text, JSON and storage

It has no single text form, so `text.from` and `text.parse` don't take it. JSON sends an object of its variant's name, as `tag`, and the variant's fields.

| JSON |
|---|
| `{"tag":"per_mass","price":{"amount":250,"currency":"GBP"},"per":{"value":"1","unit":"kg"}}` |
| `{"tag":"per_volume","price":{"amount":180,"currency":"GBP"},"per":{"value":"0.001","unit":"cubic_metre"}}` |
| `{"tag":"per_length","price":{"amount":399,"currency":"GBP"},"per":{"value":"1","unit":"metre"}}` |

It is stored in 4 columns, each named for the field, `_` and its suffix. This is `{"tag":"per_volume","price":{"amount":180,"currency":"GBP"},"per":{"value":"0.001","unit":"cubic_metre"}}`:

| Column | Type | Holds |
|---|---|---|
| `<field>_kind` | `text` | `'per_volume'` |
| `<field>_price` | `bigint` | `180` |
| `<field>_price_currency` | `char(3)` | `'GBP'` |
| `<field>_per` | `numeric(38, 9)` | `0.001` |

## Shown to people

`text.format(value, locale:)` shows it to people in their locale.

With `locale: Locale.en_gb`:

| Value | Shown |
|---|---|
| `{"tag":"per_mass","price":{"amount":250,"currency":"GBP"},"per":{"value":"1","unit":"kg"}}` | `£2.50/1 kg` |
| `{"tag":"per_volume","price":{"amount":180,"currency":"GBP"},"per":{"value":"0.001","unit":"cubic_metre"}}` | `£1.80/0.001 m³` |
| `{"tag":"per_length","price":{"amount":399,"currency":"GBP"},"per":{"value":"1","unit":"metre"}}` | `£3.99/1 m` |

## Operations

It has the contract's own operations: `text.format`, `json.read`, `json.write` and `==`. It isn't ordered, so `<` and sorting don't take it. [Every standard type meets one contract](../topics/every-standard-type-meets-one-contract.md) says how they work.
