---
title: Product Configurator
description: Sell configurable products — the customer builds the item from options (size, colour, material, add-ons) and TSync prices it and puts the configured line on the quote or invoice.
product: TSync Intelligence 11.3.6
language: en
canonical: https://docs.tsync.pro/modules/tsync-product-configurator/
source: https://docs.tsync.pro/llms.txt
---

# Product Configurator

The **Product Configurator** (`/admin/tsync_product_configurator`) lets you sell **configurable products** —
items the customer builds from choices (size, colour, material, options) instead of a single fixed SKU. You
define the choices once, set rules for which combinations are allowed and how the price changes, and TSync
turns a selection into a concrete product variant.

## Sell a configured product — step by step

This is what you do every day. The rest of the page is the setup behind it; this is the actual use.

It works the same whatever you configure — a window, a door, a piece of furniture, a machine, a service
package, or anything else you have defined as a configurable model. The steps are identical; only the options
you see differ.

**a) Open the configurator from the document**

Go to **Sales → Estimates → New estimate** (it works the same on invoices, proposals and credit notes, if you
ticked them in Settings). Pick the customer, then press the **"Configure product"** button above the item list.
The **"Product configurator"** window opens.

> The button appears only on the document types enabled in **Configurator → Settings**, and only if you have
> permission to configure. If you see it on an estimate but not on an invoice, that is the default: configuring
> belongs to the quote stage, and the line reaches the invoice through estimate-to-invoice conversion.

**b) Choose the model and the options**

First pick the **model** from a searchable list — type a few letters instead of scrolling through hundreds. Once
chosen, its options appear, exactly the ones defined for that model. What they are depends on what you sell:

| If you sell… | the options might be… |
|---|---|
| joinery | size, glass type, hardware, frame colour |
| furniture | size, style, main material, secondary material |
| equipment | power, voltage, accessories, extended warranty |
| services | plan, number of users, duration, SLA |

As you choose, the **price computes itself** from model + options + the pricing rules. It is **never typed by
hand.** Rules can also hide or forbid options that make no sense together, so an impossible combination cannot
be picked by mistake.

If the add button stays greyed out, hover it: it **tells you what is still missing** rather than leaving you to
guess.

**c) Add the line to the document**

Press **"Add to document"** and the line lands on the estimate with the configuration description, the
**computed price** and a **unique code (SKU)**. The window closes itself; you can configure another product for
the same document.

Every configured line is a product in its own right: two units in different materials are two lines, with two
SKUs and two prices.

## Open it

**Configurator** in the sidebar, or `/admin/tsync_product_configurator` (it opens the dashboard).

## The pieces

- **Templates** — a configurable product (e.g. *Window*, *T-shirt*, *Office desk*). Everything below hangs
  off a template.
- **Attributes** — the choices a customer makes (e.g. *Size*, *Colour*, *Glass type*).
- **Values** — the options inside an attribute (e.g. *Small / Medium / Large*). You can import values in bulk.
- **Variants** — the concrete combinations that result, each with its own code and price.
- **Rules** — the logic: *if* a choice is made, *then* allow/forbid another, add a surcharge, set a default,
  show/hide an option… The rule engine is safe and predictable (no free-form code), so the same selection
  always gives the same result.

## Build a configurable product, in short

1. **Templates** → create a template for the product.
2. **Attributes** → add the choices (Size, Colour…).
3. **Values** → add the options for each attribute (and import a long list if needed).
4. **Rules** → set what's allowed and how the price adjusts.
5. **Variants** → review the combinations that the choices + rules produce.

## Load many models at once (CSV import)

When you have dozens of models to enter — or when your list will be corrected a few more times — do not do them
one at a time. The **Models** page has an **Import CSV** button.

The file needs **one required column: `code`**. Everything else takes a sensible default, so a two-column file
(`code`, `name`) already produces working, configurable models. The import page lists every column and its
default.

**Press "Simulate" first.** It writes nothing: it shows you, row by row, what would be created, what would be
updated and what would be skipped, with notes. Only once the report looks the way you expect do you press
**Import**.

**You can re-upload the same file any time.** Models are matched on `code`, so a corrected file **updates** the
existing models rather than creating a second set beside them. That is exactly why it is worth starting with
approximate data and refining it.

A few things to know:

- **Lists use `;`** — for example `invoice;estimate` or `2250;2050;1900`.
- **A code used by two rows is refused**, not guessed. If your file has two different models sharing a code, the
  import names them and writes neither: if it wrote them, the second would silently replace the first.
- **`valid_sizes`** restricts a model's valid sizes. Left empty, every size stays valid. Each import
  **replaces** the list, so a size you remove from the file really does disappear.

## Test a rule before you trust it

Rules get complicated quickly — *"this glass type is only available above 1200 mm, and it adds 12 %"*. Rather
than saving a rule and hoping, use **Simulate**: pick a combination of values and TSync shows you what the
engine decides for it — which options stay available, which are forced or forbidden, and what the price becomes.

Because the engine is deterministic (there is no free-form code in a rule), what the simulation shows is exactly
what a customer will get.

## What happens after a configured line is on a document

A configured line is not a normal product line. It carries the customer's choices, so somebody has to decide
**how it will actually be delivered** — and until they do, the line sits in the configurator's **review queue**.

Open **Configurator → Review** from the document, or `/admin/tsync_product_configurator/review/invoice/123`
(it works for invoices, estimates, proposals and credit notes). Reviewing needs the *decide* permission —
being able to build templates is not the same as being able to commit the company to producing something.

For each line you choose one of four outcomes:

| Decision | What TSync does |
|---|---|
| **Launch production** | Resolves the template's bill of materials for the chosen options, scales it by the line quantity, and creates a **production order**. If the Production module is not installed, the line is marked *in production* with a note that fulfilment is manual — it is never silently dropped. |
| **Order materials** | First checks **availability** of every resolved material against the template's default warehouse, then raises what is missing. You see the shortfall before you commit. |
| **Sell from stock** | Marks the line **fulfilled** from existing stock — no production, no purchasing. |
| **Reject** | Sends the line back. **A reason is required** — a rejection with no reason is refused, because the person who configured it needs to know what to change. |

Every decision is recorded against the line, so a document always answers *"who decided this, and what did they
decide"*.

### The whole road, from order to invoice

To see where the configurator joins the rest of the system, here is the end-to-end cycle of a made-to-order
product — the same stages whether you build joinery, furniture or machinery:

**Estimate with a configured line** → **Send to production** (from the review queue) → a **production order**
carrying the bill of materials resolved for the chosen options → **manufacturing**, with materials coming off
stock as they are consumed → **completion**, with the finished product entering stock under its own lot →
**delivery** → **invoice**.

Every step leaves a trace, so you always know where each order is. For the manufacturing side — recipes,
production orders, work centres, quality control and lots — see the [Production](tsync-production.md) guide.


### If you build TO ORDER

By default, **"Launch into production" is blocked while any material is missing**. That is the right rule if
you keep material on the shelf: a run that cannot be finished must not start.

But if you **build to order** — configure and manufacture per order — you never hold all the material
*before* somebody orders, and the block stops your normal flow. Turn on **Configurator → Settings →
Production → "Produce to order"**.

With it on, a shortage shows a warning listing what is missing, the button stays available, and launching
creates the production order **with the shortage noted on it**. Order the materials in parallel with the
button beside it; production consumes them provisionally until they arrive.

With it off, an attempt to launch on a shortage is **refused and tells you which material is missing** —
not just a greyed-out button.

## Bills of materials

A template can carry a **bill of materials** whose quantities depend on the chosen options — that is what makes
*Launch production* and *Order materials* possible. The BOM is resolved per configuration, not per template, so
a 2400 mm window and a 900 mm window consume different amounts from the same definition.
### A material the customer chooses — the slot line

Most BOM lines name a fixed material: two of these, three metres of that. A **slot** line names an **option**
instead. The quantity is fixed by the model — a sofa, say, takes 11 running metres of fabric, while a door takes one
sheet of veneer — but *which* material is
whatever the customer picks, and its cost follows the article behind that choice.

That is what makes the material cost move when somebody switches from one fabric to another. Without a slot
line the bill of materials has no fabric in it at all, and every fabric costs the same, which is a very
convincing way to be wrong.

In an imported sheet a slot row carries **`attribute_code`** (for example `material_principal`) in the
`material_code` column's place, with `component_type` set to `slot`. It creates no article: the article is
whatever gets chosen. A slot row without an attribute code, or naming an option this installation does not
have, is **reported by name** in the import result and skipped — never imported as a line that would quietly
cost nothing.

### Checking the numbers

The bill of materials now shows, per line, the **unit price** used and the **line cost**, beside the quantity —
on the availability review and in the preview. A line with no recorded price shows a dash, not a zero: "not
priced" and "free" are different facts, and a zero would send somebody to renegotiate a price that was never
entered.

## Where the labour cost comes from

A model's price has two halves: the **materials**, which come from its bill of materials, and the **labour**,
which comes from a **production routing**.

On the model's form, **Production routing (labour)** lists the routings you have defined in the Production
module, each with what it costs — so you can pick the right labour class without opening them one by one. Leave
it empty and the labour cost is 0, which is what every model does today.

The number follows however your install costs work. If you price operations by the clock, it is setup plus
cycle time at the work centre's hourly rate, adjusted for its efficiency. If you have switched on fixed prices
per operation, that price is used instead — the two are alternative answers, never added together.

> Until this release the labour cost was **always 0.00**, for every model, because nothing supplied it. The
> margin shown beside it was therefore wrong by the whole cost of labour. If you have been reading those
> margins, they change once you attach routings — the old ones were not conservative, they were incomplete.

**Mapping many models at once:** the CSV import accepts a `routing_id` or a `routing_code` column. Leaving the
column empty leaves each model's routing **as it is** — unlike the other columns, an empty cell here does not
clear what you picked in the form.

## How to read a configured line's code (SKU)

Every configured line gets a **unique code**. It is not a random number: it is built from a **pattern you
define**, so that anyone in production or the warehouse knows from the code alone exactly what to make — without
having to ask.

You write the pattern in **Configurator → Settings → SKU pattern**, and a model can carry its own (the **SKU
pattern** field on the model form) when it needs a different shape. It is written as a string of tokens:

| Token | What it puts in the code |
|---|---|
| `{TEMPLATE}` | the configurable model (the product) |
| `{MODEL}` | the chosen model's code |
| `{SIZE}` | the chosen size |
| `{STYLE}` | the chosen style |
| `{MP_CODE}` / `{MP_NAME}` | main material — code or name |
| `{MS_CODE}` / `{MS_NAME}` | secondary material — code or name |
| `{ATTR_CODE}` / `{ATTR_VALUE}` | any other attribute and its value |
| `{DATE}` · `{SEQ}` · `{HASH}` | the date, a sequence number, a short fingerprint of the configuration |

A token the configuration has no value for **simply disappears** — it does not survive as an odd word in the
middle of the code. That is what lets one pattern serve a model with four options and a model with two.

**Two examples, from the same pattern** `PCFG-{MODEL}-{SIZE}-{STYLE}-{MP_NAME}`:

```
PCFG-F2-1200-DUB-TERMOPAN     a window: model F2, 1200 mm, DUB opening, TERMOPAN glazing
PCFG-D1-1900-S1-CATANIA       a furniture unit: model D1, 1900 mm, style S1, CATANIA material
```

Read it as: `PCFG` = a product from the configurator, then each part is one choice made in the configurator
window, in the order set by the pattern. Anyone in production knows from the code what to build.

Settings also control how the code looks: the **separator** (`-` by default), the **maximum length**, whether it
is written in **upper case**, and whether diacritics and Cyrillic are **transliterated** into Latin letters
(recommended — a code carrying accented or Cyrillic letters causes trouble on labels, in exports and in search).
TSync also enforces **uniqueness**: two different configurations can never get the same code.

## On documents and the client portal

When you add an item that is configured, a **configurator picker** opens so you (or the customer, if the
**client-portal configurator** is enabled in **Settings**) make the choices and the resulting variant +
price drop onto the document. Turn the portal configurator on/off in the module **Settings**.

## What is ordered most, and what it cost at the time

**Configurator → Variante folosite** in the sidebar opens **Configured demand**
(`/admin/tsync_product_configurator/variants`) — the page that turns everything your team has configured into
a stock decision you can make *before* a season, not after it.

It answers two questions together:

- **what gets ordered most**, and
- **how the cost moved** while it was being ordered.

### It counts quantity, not appearances

The measure is **quantity ordered**. One line for a single unit and one line for forty are not the same demand,
even though each is one configuration on one document. If you have been reading a "times used" figure
somewhere and planning stock from it, expect a different — and more useful — ranking here.

### Choose how the rows are grouped

Three groupings, switched at the top of the page:

| Group by | One row is |
|---|---|
| **Configuration** | one exact combination of choices — the default |
| **Model** | everything built from one model, whatever the options |
| **Variant** | the concrete stored variant, with its own code |

Filter by search (SKU, name, model code), model, document type and a date range. **Exclude rejected** is on by
default: a line the customer turned down is withdrawn interest, not demand, and counting it is the error that
fills a warehouse.

### Reading the table

Each row shows **what was configured**, the **quantity**, how many **times** it was configured, the **average
cost**, the **cost range**, the **value** and when it was **last ordered**. Every column with a heading you can
press sorts the whole set, and the totals above the table are for **everything that matches your filters** —
not just the page you are looking at.

Open a row and it unfolds into every individual use behind it: the document, the date, the quantity, the
status, and **the cost that use carried at the time**.

### Two things about the cost figure, worth knowing before you act on it

**The average is weighted by quantity.** One piece at 900 and forty at 1000 average to **997.56**, not 950. The
plain average looks defensible and is wrong in exactly the direction that makes a purchase decision look
justified afterwards.

**A use records its own cost when it is created.** Rows entered before your install started doing that were
filled in from the variant's *current* cost, which is not what it cost back then — those are marked
**approx.**, and a note at the top of the page appears when the whole install is still in that state. A cost
trend that mixed the two silently would draw a flat line and present it as evidence that prices were stable.

### The same data as reports

Three reports are registered in the reports console (**Reports** in the sidebar), so you can filter, chart,
export to CSV/XLSX, save a view or e-mail it on a schedule:

| Report | What it gives you |
|---|---|
| **Top configurations by quantity** | which exact configurations were ordered most, ranked by quantity |
| **Demand by model, per month** | quantity per model per month — the shape a pre-season stock decision is made from |
| **Configuration cost over time** | quantity-weighted average cost per configuration per month, with a **cost basis** column saying whether the figure is a real per-use snapshot or a filled-in current cost |

Your role needs permission to view configurator reports for them to appear.

### Settings

Module **Settings** carries three defaults for this page: the **default period** in days (90 unless you change
it), the **default grouping**, and whether **rejected lines are excluded** from demand. They set what the page
opens with; every one of them can still be changed on the page itself for a single look.
