Skip to main content
Version: 3.x

GroupPrice

Version
3.x
Updated
View markdown

Per-customer-group price overrides for a single price field, serialised into one column.

Storage kind: column · Column: text

Use it to let a shop owner say "this price, but different for these customer groups". It always accompanies a price property rather than standing alone — overridePropertyName names the field it overrides, and the form borrows that field's label so the two read as one control.

Settings

SettingMeaning
overridePropertyNameThe price property this overrides. Its label is borrowed for display
unitUnit shown alongside the values

The stored value

A JSON array of {group_id, price} entries, posted from a hidden input that the property's own JS maintains:

[{"group_id": 3, "price": "89.00"}, {"group_id": 7, "price": "72.50"}]

group_id is cast to int and price is normalised from the localised decimal mark to a dot on the way in, so the stored text is canonical regardless of the operator's locale.

Reading is forgiving in one specific way: getOverrides() drops entries whose customer group no longer exists rather than showing a row with no name. The stale entries stay in the column until the next save, which then writes them out. So the column can legitimately contain groups that are gone, and a consumer reading it directly has to tolerate that — do not assume every group_id resolves.

The list cell shows a count ("2 overrides"), not the values.

Notes

  • It was varchar(1024) and is now text. The blob outgrew the column, and a fixed width on a serialised list is a limit nobody can predict from the form.
  • A malformed value used to be silently discarded. json_decode() answers null for anything that is not valid JSON, and iterating null only raised a warning — so a failed edit, an older browser or a custom template could make the whole set store as empty, losing overrides a shop owner had entered with nothing to see. A non-array is now treated as empty explicitly.
  • There is no check() override: the property does not validate the set beyond the coercion above. An override for a group that does not exist is accepted and simply ignored on read.
  • Because the whole set lives in one column, there is no way to query "which products have an override for group 7" in SQL without parsing JSON in the query. That is the trade this shape makes.

@see calculationoverride.md — the same shape for calculations @see number.md — the price property being overridden @see ../../admin-guide/commerce/set-up-customer-groups.md — the groups these override for @see ../../admin-guide/pricing/where-prices-come-from.md — where an override lands in the price chain