How Can We Help?
A matrix is a lookup table the pricing/costing engine consults during order entry:
given two inputs (a width and a height, an option answer and a dealer group, …) it returns a
value — a price, a size adjustment, a commission rate, an error or warning, or a pointer to
another matrix. This screen builds and edits those tables in a spreadsheet-style grid.
Matrices are referenced from series headers (Qty Discount), option choices, designs, and
rules.
A matrix has two parts: a Header (name, matrix type, units, series, and what its
two axes mean) and a cell grid (the value returned for each row/column
combination).
What, where, who, when, why
| What | The create/edit screen for matrix lookup tables: a Header (type, units, owning series, row/column axis definitions) and the generated cell grid of values. |
| Where | Administration → OJ Setup → Product Setup → Matrix. |
| Who | Pricing staff and the rules owner — matrices are referenced from series headers (Qty Discount), option choices, designs, and rules. |
| When | Whenever a value varies along two dimensions instead of being flat: size-based pricing, dealer-group×series discount grids, quantity breaks, commission tiers. A matrix replaces dozens of per-case rules with one editable table. |
| Why it matters | The pricing/costing engine consults these tables live during order entry; nothing else carries size- or group-dependent values. Editing a cell here reprices the next quote — and a wrong axis definition silently returns the wrong cell instead of erroring. |
Layout
Left rail: a “Filter by name…” box (live filter over id - description),
a Type filter, and the matrix list with a count underneath. Right: the collapsible
Header panel, the Matrix grid panel, and a bottom action bar:
New / Edit / Copy / Save / Cancel / Delete.
The Header panel
- ID (read-only) and Description.
- Type — the matrix type; it controls which axis types are allowed.
Commission-family types (Qty Discount, commissions, Sales Targets) enable the
Commission cell type. - Measure — units for dimensional axes; shown only when an axis is
dimensional. - Series — the owning series; also narrows series-scoped axes (opening class,
shape, opening) to that series. - Row Axis / Column Axis — each has a Type, plus an Option picker
for option axes or Start / End / Step for numeric/date axes. The column-type
list is filtered to combinations valid for the chosen matrix type and row
type. - Generate grid — builds the cell grid from the axis definition.
Axis types come in three flavors: enumerated (the rows/columns are an
existing list — option answers, opening class, shape, sealed unit, opening, SU family, grid,
partner/dealer, item type, series, price group), numeric / date (generated from
Start, End, Step), and None (a single wildcard row/column).
The cell grid
The first row and first column are band cells — the boundary each row/column stands
for (lower - upper for numeric axes, the entry’s description for enumerated
axes). The interior cells hold the returned values, color-tinted by cell type.
Right-click a cell to change its meaning:
| Cell type | Meaning |
|---|---|
| Price | A plain value (price, adjustment, …). |
| SubMatrix | The ID of another matrix to look up next (pick from a list). |
| +Row / +Column | The value is multiplied by the row / column band value. |
| Error / Warning | The ID of a message to raise (pick from a list). |
| Title | Display text. |
| Commission | A percentage rate — only on commission-family matrices; must be 0 or greater. |
The toolbar and context menu also offer Insert Row / Delete Row / Insert Column /
Delete Column to reshape the grid.
Worked example — a width × height price matrix
Slab doors are priced by united inches, in 6″ steps. A flat price can’t express
that; one matrix can:
| Step | Where | Value | Why |
|---|---|---|---|
| 1 | New → Description | “Slab Door $ by W×H” | The name dealers and pricing staff will recognize in the filter list. |
| 2 | Type | Price | A pricing lookup — the type controls which axis types and cell types are allowed. |
| 3 | Row Axis | Type = Width, Start 24, End 96, Step 6, Measure = Imperial |
Generates rows 24, 30, 36 … 96 — the numeric axis does the typing for you. |
| 4 | Column Axis | Type = Height, Start 60, End 96, Step 6 | Columns 60, 66 … 96; the column list was already filtered to combinations valid for a Price matrix with a Width row. |
| 5 | Generate grid, fill cells | 24×60 = 189.00 rising to 96×96 = 512.00 |
Each cell is the price returned for that band; the engine matches a 29⅝″ item into the 24–30 row. |
| 6 | Point something at it | Designs tab → the slab design’s Matrix combo |
A matrix nothing references prices nothing — the last step is always wiring it into a series, choice, design, or rule. |
Workflows
- Create a matrix: New → fill Description, pick Type and
Series → pick the Row Type (the column types re-filter to valid
combinations) and complete the axis → same for the column axis → Save once to
store the header → Generate grid → type values into the interior cells, adjust
bands, set cell types by right-clicking → Save (“Matrix saved.”). - Edit: select → Edit → change header and/or cells → Save. If you
change an axis type or option, regenerate the grid with Generate grid. - Copy: select → Copy → the header and grid are cloned with no ID → adjust
→ Save creates it as a new matrix. - Delete: select → Delete → confirm.
- Domain-drift warning: opening a matrix whose enumerated axis has changed since
it was built (an option answer added or deleted) pops a warning that the axis now has
n entries but the matrix was built with m — regenerate the grid to pick
up the change.
Special cases and cautions
- Lookup matrices (SQL-driven) and sub-matrices (derived from another
matrix via an operator) have no editable cells — the screen shows a read-only
explanation and Save is disabled. - Deleting is not blocked even if rules, options, or other matrices reference the
matrix — check usage first. - Saving is blocked when Description or Type is missing; when a numeric axis has Start ≥
End, Step ≤ 0, or non-numeric values; or when a dimensional band cell is not numeric.
A Commission cell only accepts a non-negative number. - The Dealer Group axis type is not currently wired — matrices built on it render
an empty grid. Avoid it for now.
Tables behind this screen
matrix_header (tenant) — one row per matrix: id, description, the matrix
type, the two axis definitions (axis type, option picker or start/end/step), units,
owning series, and flags marking lookup (SQL-driven) and sub-matrices. This is the Header
panel.
matrix (tenant) — one row per grid cell, keyed by a composite
(id, cell_no) where id is the header id. Each cell stores its
band bounds (rowL/rowU/colL/colU — member ids for enumerated axes, scaled
numbers for dimensional ones; the engine range-matches lower ≤ value ≤ upper), a cell type,
and a polymorphic price column (plain value, matrix id, message id, factor,
percent, or text, depending on the cell type). cell_no is the 1-based,
row-major layout ordinal — the engine never reads it, so reshaping rows and columns
in the editor is safe. Saving is a header upsert plus a delete-all/re-insert of the cells
in one transaction.
Matrix types — type_matrix
Global dictionary powering the Type combo and the list filter (all 28 rows;
ids 3 and 24–29 do not exist):
| id | Name | What it is |
|---|---|---|
| 1 | Valid Products | Pricing matrix for valid product combinations. |
| 2 | Options/Answers | Prices option answers. |
| 4 | Sealed Units | Sealed-unit pricing. |
| 5 | Standard Grids | Standard grid pricing. |
| 6 | Custom Grids | Custom grid pricing; adds the Spokes ↔ Radii axis pairing. |
| 7 | Grid Templates | Same Spokes ↔ Radii addition as type 6. |
| 8 | Couplers/Mullions | Profile pricing; adds the Length axis with restricted pairings. |
| 9 | Designs | Design pricing. |
| 10 | Standard Products | Standard-product pricing. |
| 11 | SubMatrix | Grids-type-code × grids-type-code matrix used as a SubMatrix target. |
| 12 | Matrix For V | Width-driven matrix (Width axis required). |
| 13 | Matrix For H | Mirror of 12 with Height. |
| 14 | Product Type | None × Product Type only. |
| 15 | Part Matrix | Part selection/pricing; full axis set. |
| 16 | Profile Matrix | Profile pricing; full axis set. |
| 17 | Area Matrix | Area pricing; values stored raw — not unit-scaled. |
| 18 | Segment Matrix | Segment (sub-routine) pricing; full axis set. |
| 19 | AnswerId Matrix | Returns an answer id; full axis set. |
| 20 | Qty Matrix | Quantity lookup. |
| 21 | Warning | Warning-message matrix. |
| 22 | Error | Error-message matrix. ⚠ No define rows → empty axis combos for new matrices. |
| 23 | Adjustments | Size-adjustment matrix — the only type whose Value cells are unit-scaled. ⚠ No define rows → empty axis combos. |
| 30 | Part Cost | Part costing. |
| 31 | Part Price | Part pricing. |
| 32 | Qty Discount | Commission-family type (Commission cells allowed). ⚠ No define rows → empty axis combos. |
| 33 | commissions | Commission rate matrix; Commission cells allowed. |
| 34 | Sales Targets | Sales-target matrix; Commission cells allowed. ⚠ No define rows → empty axis combos. |
| 35 | Price Include | None × Prod. Series only. |
Axis types — type_matrix_dictionary
Global dictionary powering the Row Type / Col Type combos. Kinds:
enumerated (the bands are an existing list), numeric (generated from
Start/End/Step — dimensional ones are unit-scaled), date, and
None.
| id | Name | Kind | Notes |
|---|---|---|---|
| 1 | Opening Class | enumerated, series-scoped | Opening types of the header series. Fully wired. |
| 2 | None | none | Single synthetic wildcard band; always matches. |
| 3 | Shape | enumerated, series-scoped | Shapes of the header series. Fully wired. |
| 4 | Options and Answers | enumerated | Answers of the option chosen in the Option combo; numeric instead when the option’s type ≥ 3. Fully wired. |
| 6 | SU Type | enumerated | Sealed-unit types. Fully wired. |
| 7 | User Def Opening Name | enumerated, series-scoped | The series’ opening/shape records (band shows the abbreviation). Fully wired. |
| 8 | SU Family | enumerated | Sealed-unit families. Fully wired. |
| 11 | Grids type-code | enumerated | Grid definitions. Fully wired. |
| 12 | Partner | enumerated | Partners; engine probes the current customer. Fully wired. |
| 13 | Partner Group ID | enumerated | ⚠ Editor gap: the engine honors this axis at runtime, but the screen cannot enumerate partner groups — the grid renders empty. |
| 14 | Design | enumerated (engine-only) | Runtime-only; the grid renders empty in the editor. |
| 15 | Std Product | enumerated (engine-only) | Runtime-only; grid renders empty. |
| 22 | Width | numeric, dimensional | Fully wired. |
| 23 | Height | numeric, dimensional | Fully wired. |
| 24 | UI | numeric, dimensional | United inches; imperial-only in practice. Fully wired. |
| 25 | Area | numeric, raw | Never unit-scaled. Fully wired. |
| 26 | No. Grid W | numeric, raw | Grid bars across. Fully wired. |
| 27 | No. Grid H | numeric, raw | Grid bars high. Fully wired. |
| 28 | Date | date | String-range compare, not numeric. Fully wired. |
| 29 | No. Spokes | numeric, raw | Fully wired. |
| 30 | No. Radii | numeric, raw | Fully wired. |
| 31 | Product Type | enumerated | Order-item types. Fully wired. |
| 32 | length | numeric, dimensional | Profile length. Fully wired. |
| 34 | Quantity | numeric, raw | Wired; meaningful mainly in cart contexts. |
| 35 | Volume | numeric, raw | Same cart-context caveat as 34. |
| 36 | Prod. Series | enumerated | Editor wired; the engine probe is a stub. |
| 40 | LeftTopOpening | — | Unused/dead — no editor domain, no engine case, not in define rows. |
| 41 | rightBotOpening | — | Effectively dead, though one stray define row offers it as a column type (commissions). |
| 42 | Pricing Category | enumerated | ⚠ The editor enumerates price groups, but the engine has no case for it — no runtime support. |
| 43 | Net List Ratio | numeric, raw | The realized net÷list discount factor (commission matrices). Fully wired. |
| 44 | Parent UI | numeric, dimensional | Frame UI. Fully wired. |
| 45 | Weight | numeric, raw | Engine-wired but in no define rows — not selectable in the editor. |
| 50 | Inertia | — | Engine-only; not selectable. |
| 51 | Tributary (Inertia) | — | Engine-only; not selectable. |
Cell types — type_matrix_cell
Global dictionary behind the right-click Cell Type submenu (all 8 rows):
| id | Name | Submenu label | What the engine does |
|---|---|---|---|
| 1 | Value | Price | Returns the cell value as the result. The only unit-scaled type, and only in Adjustments (type 23) matrices. |
| 2 | Matrix | SubMatrix | The value is another matrix id; the engine recurses into it. |
| 3 | Error | Error | The value is an error-message id; raises the message and returns 0. |
| 4 | Warning | Warning | Same, with a warning message. |
| 5 | Title | Title | Display text. |
| 6 | xC | +Column | Returns value × the column band value. |
| 7 | xR | +Row | Returns value × the row band value. |
| 8 | Commission | Commission | A percent rate (7.5 = 7.5%), never unit-scaled; authored only in matrix types 32/33/34. |
Allowed axis combinations — type_matrix_define
Global table of (matrix_type, row_type, col_type) rows — “for this matrix
type, this row axis may pair with this column axis”. It is what re-filters the Col
Type combo when you change the Row Type. Summary of the live combinations
(axis ids per the table above):
| Matrix type | Row types offered | Column rule |
|---|---|---|
| Most pricing types (1, 2, 4, 5, 9, 10, 15–21, 30, 31) | 1, 2, 3, 4, 6, 7, 11, 13, 14, 15, 22–28 | Nearly free pairing; exceptions: row 1 (Opening Class) excludes column 4 (Option), and row 28 (Date) excludes column 28 (no Date × Date). |
| 6, 7 (Custom Grids / Grid Templates) | Base set + 29, 30 | Spokes (29) pairs only with Radii (30) and vice versa; other rows pair freely. |
| 8 (Couplers/Mullions) | Base set + 32 (Length) | Length (32) pairs only with None (2), Partner Group (13), Date (28); those pair only within {2, 13, 28, 32}. |
| 11 (SubMatrix) | 11 only | 11 only — grids-type-code × grids-type-code. |
| 12 (Matrix For V) | 1, 2, 22 | Rows 1/2 → column Width (22) only; row 22 → columns 1/2 only. |
| 13 (Matrix For H) | 1, 2, 23 | Mirror of 12 with Height (23). |
| 14 (Product Type) | 2, 31 | 2 ↔ 31 only. |
| 33 (commissions) | 2, 4, 12, 13, 14, 15, 28, 34, 36, 42 | Restricted cross-product of the same set, each row excluding itself. (Live data quirk: row 2 offers column 41 instead of 42 — a seeding error, as 41 has no support.) |
| 35 (Price Include) | 2, 36 | 2 ↔ 36 only. |
| 22, 23, 32, 34 | — | No rows at all → empty axis combos for new matrices of these types. |
⚠ Cautions:
- Matrix types 22 (Error), 23 (Adjustments), 32 (Qty Discount), 34 (Sales
Targets) have no define rows — a new matrix of one of those types shows
empty Row/Col Type combos. Existing matrices of those types still load and work
fine. - The Dealer Group axis (13) has no editor support — the engine honors it, but
the grid renders empty. - The Pricing Category axis (42) has no engine support — the editor enumerates
it, but the runtime cannot probe it. - The
matrix_serieslink table is legacy — this screen uses the
header’s Series field directly and never reads or writes it.