Products
The catalogue, assembled from Akeneo. A product here is the marketing view; the finance view of the same item arrives separately from NetSuite as ns_items, and the two are joined on the SKU.
A product is a catalogue item: its name, brand, category, attributes, the domains it is live on and the SKUs it is sold as. It comes from Akeneo and is replaced wholesale on every run.
Two views of the same item
products and its tables | ns_items | |
|---|---|---|
| From | Akeneo PIM | NetSuite |
| Answers | What it is, what it is called, where it is sold | What it costs, what it is worth, which GL accounts it books to |
| Read at | /entities/products | /entities/products/netsuite |
Neither is the other's copy. The calculation rule builder reads products and never ns_items, which is why ns_items.weight and weightunit do not appear as rule filters.
ns_items.weight is a number in an unknown unit. Its unit identifier carries at least four distinct values across the catalogue, so the weights are not even in one unit. Do not convert or compare them until that identifier is mapped.
Where it comes from
app/jobs/akeneo/getproducts.php consumes the akeneo_getproducts batch type, writes the catalogue into _new tables, and akeneo_getproducts_swap swaps them in. Sibling jobs fill the surrounding data with a mixture of upserts and guarded swaps, as described in Akeneo: getbrands.php, getcategories.php, getattributes.php and getproductskus.php.
Every one of those swaps is guarded on row count and refuses when the new table holds fewer rows than the live one, so a truncated Akeneo response leaves yesterday's catalogue in place rather than emptying it.
productids is what keeps a product's id stable. The catalogue table is replaced on every run, so an auto-increment inside it would renumber every product nightly. Instead the job looks the product's cid up in productids, inserts it there if it is new, and uses that id. Anything referring to a product by id therefore keeps referring to the same product.
akeneo/getproductsreset.php cancels the open batches and re-queues a full reload.
Tables
| Table | Holds |
|---|---|
products | One row per product: name, brand, main category, top-level category, and the flags activated, isengravable, isbundle, inadshop |
productids | The stable cid to id mapping that survives the swap |
productdomains | One row per product per domain: local name, slug, SKU, whether it is activated there, and the live date |
productskus | The SKUs a product is sold as |
productbrands, productbrandlanguages | Brands and their translations |
productcategories, productcategoriestoplevel | The Akeneo taxonomy |
productattributes, productattributegroups and their language tables | Attribute definitions, groups and translations; per-product values are in the product JSON attributes |
ns_items | The NetSuite item: cost, value, quantity on hand, GL accounts |
productprices, productstock | The per-SKU feeds, see prices and stock |
Most of these are not defined in install.php: they are created by the job that fills them, so a schema change to one is made there.
Where to look, and where to change
/entities/products carries four views:
| Tab | Shows |
|---|---|
| (default) | The Akeneo catalogue |
| NetSuite | ns_items, the finance view |
| SKUs | The SKUs per product, with whether each is validated |
| Bundles | The products marked as a bundle |
A product name links to its detail view, which shows one product with its attributes and domains.
Nothing here is editable in CCC. The catalogue is Akeneo's and the item is NetSuite's: correct it upstream and let the next run bring it through. Two related settings are CCC's own and are editable: the private-label brands at /configuration/productprivatelabel and the size options at /configuration/productsizes.
Related
- Akeneo
- Categories
- Prices and stock
- Classifications, where
privatelabeland the bundle flags are used
Evidence
Import, the stable id table and the guarded swap from app/jobs/akeneo/getproducts.php and its four sibling jobs. productdomains fields from the INSERT in that job. Views from app/http/entities/products.php and templates/main/entities/products.tpl. The rule builder joining products rather than ns_items, and the weight unit, from AGENTS.md, Models and database. Tables created outside install.php from the same. Basis: code-checked against the current implementation.
- Type
object - Status
active - Updated
2026-09-14 - Created
2026-09-13 - Covers
entities/products