Reference → Variants — Reference

Variants — Reference

The Variants surface is the per-SKU plane for SGEN commerce products. It owns the relationship between a parent product and the concrete sellable units beneath it — size, color, material, or any other axis a product is sold along — together with the per-variant inventory and price that distinguish them.

This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or scoping a catalog import. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.


Overview

Variants lives under the Products module in SG-Admin, nested inside the product editor. The module renders three primary views — the variant table on the parent product, the per-variant detail form, and the variant-axis editor — and exposes a small set of write operations for create, update, archive, restock, and reprice.

The module is paired by convention: one half renders the views and prepares the parent-and-children data, the other half handles writes and returns AJAX responses. Engineers reading the SG-Admin source will see this split across two controller files; the reference below describes the combined surface as it appears to a calling integration.

A parent product without variants behaves as a single sellable unit. A parent product with variants becomes a non-sellable shell — every purchase passes through one of its child variants, which carry the actual SKU, inventory count, and price. The parent retains shared content (title, description, media) so variants do not duplicate it.

Where it lives in SG-Admin:

  • Sidebar: SG-Admin → Products → (open product) → Variants tab
  • URL prefix: /sg-admin/variants/
  • View templates: application/views/Admin/Products/Variants/
The module surface is intentionally small. Catalog-wide concerns (categories, tax classes, currency, the cart) live in adjacent surfaces — this page covers only the parent-child variant plane.
┌──────────────────────────────────────────────────────────────────────┐│ Product: Field Tee [ Variants tab ] │├──────────────────────────────────────────────────────────────────────┤│ Axes: Size (S, M, L, XL) · Color (Sand, Charcoal, Navy) ││ ││ SKU Size Color Price Stock ││ ───────────────── ───── ───────── ────────── ──────────────────││ FT-S-SAND S Sand $32.00 42 in stock ││ FT-S-CHARCOAL S Charcoal $32.00 18 in stock ││ FT-M-SAND M Sand $32.00 6 (low stock) ││ FT-M-NAVY M Navy $34.00 0 (out of stock) ││ FT-L-CHARCOAL L Charcoal $32.00 archived ││ FT-XL-SAND XL Sand $34.00 12 in stock ││ ││ [ + Add variant ] [ Edit axes ] [ Bulk restock ] [ Bulk reprice ]│└──────────────────────────────────────────────────────────────────────┘

Actions

The Variants surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.

List variants on a product

Returns the variant set for a parent product — one row per variant with SKU, axis values, price, inventory count, and status. Driven by the data-table contract used across SG-Admin modules. The view distinguishes active variants from archived; archived variants remain attached to the parent for historical attribution but are hidden from the storefront.

Edit axes

Sets the list of axes that distinguish variants on a parent product — typically one to three axes such as size, color, material. Each axis carries a name and a fixed list of allowed values. The axis editor is the upstream of the variant create flow — adding an axis or an axis value enlarges the matrix of variants the parent can carry.

Create variant

Adds a sellable child under a parent product. Required fields: SKU (unique site-wide), an axis value for each declared axis, price, and initial inventory. Optional fields: variant-specific media, weight, dimensions, barcode, supplier reference. The SKU uniqueness check spans the catalog, not the parent.

Create variant matrix

Bulk path used after axis edits. Generates the complete cartesian product of axis values into draft variants, with shared default price and zero inventory. Operators edit the drafts in place to set per-variant pricing and stock before publishing. Draft variants are not yet sellable.

Edit variant

Loads a variant into the detail form pre-populated. Submit replaces the stored variant with the posted values. Axis values are read-only post-creation; moving a variant to a different axis combination requires archiving the current variant and creating a new one to preserve historical order references.

Restock variant

A dedicated write path for inventory. Accepts a target count and a reason. Writes the new count, records the delta in the inventory ledger with the reason, and emits a Restock event. Used both for receiving new stock and for periodic counts.

Bulk restock

Same shape as restock, scoped to a multi-select on the variant list. Each affected variant gets its own ledger entry and event.

Reprice variant

Writes a new price. The prior price is retained in the price history for the variant. Effective immediately on the storefront.

Bulk reprice

Same shape, scoped to a multi-select. Supports flat-amount and percentage shifts. Each variant gets a price-history entry.

Archive variant

Marks the variant inactive without removing it. Archived variants disappear from storefront listings and from the cart's add path, but remain attached to the parent for historical reporting — past orders, sales reports, and the inventory ledger continue to resolve them.

Restore variant

Reverses an archive. The variant returns to the active set with its prior axis values, price, and inventory intact.

Permanent delete

Hard-removes a variant. Available only after archive, only when the variant has zero past order references. The presence of any historical sale blocks permanent delete — archive is the terminal state for previously-sold variants.


Data model

The Variants surface spans three related records — the parent product, the variant, and the axis definition that joins them.

Variant record:

FieldTypeNotes
idintegerPrimary key. Stable across edits.
product_idintegerForeign key to parent product. Cannot change after creation.
skustringUnique site-wide. Editable with care — past orders carry historical SKU.
axis_valuesobjectMap of axis name to selected value. Read-only after creation.
pricedecimalPer-variant. May differ from parent default.
compare_at_pricedecimalOptional. Used for sale-price displays.
inventory_countintegerCurrent sellable stock. Updated by restock and order events.
inventory_policyenumtrack, track-allow-oversell, untracked.
weightdecimalOptional. Shipping calculations.
dimensionsobjectOptional. L × W × H.
barcodestringOptional. UPC, EAN, ISBN, etc.
mediaarrayOptional. Variant-specific image references; falls back to parent media when empty.
statusenumactive, archived, draft.
created_attimestampSet on create, immutable.
updated_attimestampTouched on any edit.
Axis definition (on the parent product):
FieldTypeNotes
namestringAxis name shown in the storefront and admin.
valuesarrayFixed list. Adding a value is non-destructive; removing a value requires no active variant references it.
display_orderintegerOrder in which axes appear in the storefront selector.
Inventory ledger entry:
FieldTypeNotes
variant_idintegerForeign key.
deltaintegerSigned. Positive for restock, negative for orders.
reasonstringFree-text label or order reference.
operator_idintegerOptional. Set when the change was operator-driven.
created_attimestampSet on insert, immutable.
PARENT PRODUCT├── id, title, description, media (shared)├── axes[]│ ├── { name: "Size", values: ["S","M","L","XL"] }│ └── { name: "Color", values: ["Sand","Charcoal","Navy"] }│└── variants[]├── VARIANT sku=FT-S-SAND axis_values={Size:S, Color:Sand} price, stock├── VARIANT sku=FT-M-NAVY axis_values={Size:M, Color:Navy} price, stock└── VARIANT...↓ each variantINVENTORY LEDGER(delta · reason · timestamp)

Permissions

Access to the Variants surface is gated at two layers.

Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Variants surface.

Layer 2 — per-action capability. Within SG-Admin, each Variants action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:

CapabilityAdministratorEditorViewer
List variants
Edit axes
Create variant
Create variant matrix
Edit variant
Restock variant
Bulk restock
Reprice variant
Bulk reprice
Archive variant
Restore variant
Permanent delete
Custom roles defined under Settings → Roles override the default map. The capability slugs are stable; the role slugs are configurable.

Referential rules. Permanent delete is blocked when the variant has any historical order reference. Axis-value removal is blocked when any active variant references the value. SKU edits are allowed but warned — past orders retain the historical SKU on the order line, so renaming live affects future fulfilment paperwork only.

Audit. Every write — variant create, edit, restock, reprice, archive, restore, delete, axis edit — emits an Activity Log entry. The log records the acting operator, the target variant or axis, and the change shape. Inventory deltas additionally write to the dedicated inventory ledger described above, which is queryable independently of the Activity Log.

VARIANT OPERATION REQUEST│▼┌───────────────────────────┐│ Admin gate │ unauth → reject└─────────────┬─────────────┘│ authed▼┌───────────────────────────┐│ Capability check │ role lacks cap → reject│ (per action) │└─────────────┬─────────────┘│ allowed▼┌───────────────────────────┐│ Referential rules │ permanent delete with orders → reject│ │ axis value with variants → reject└─────────────┬─────────────┘│ passes▼action executes│▼Activity Log entry + Inventory ledger (where applicable)

Related references

  • Products — Reference. Owns the parent product record. Shared content (title, description, media) lives there; variants inherit from it.
  • Inventory — Reference. Aggregates per-variant inventory ledger entries into stock counts, low-stock alerts, and movement reports.
  • Orders — Reference. Order lines carry the variant identifier and the historical SKU at time of purchase. Variant edits do not retroactively change order records.
  • Pricing — Reference. Per-variant price overrides interact with site-wide price rules (sale schedules, customer-group pricing) defined here.
  • Media — Reference. Variant-specific media references resolve against the same Media library used by parent products.
  • Reports — Reference. Sales-by-variant and stock-on-hand reports read directly from the variant record and its inventory ledger.
For the corresponding customer-facing walkthrough — adding sizes to a product, taking a colorway off sale, restocking after a delivery — see the Products section of the customer docs at /docs/products/variants.
On this page