Skip to content

Product Synchronization

Matt MacDougall edited this page Sep 9, 2026 · 1 revision

Product synchronization

Product import reads NetSuite items and builds rows for Magento's catalog and advanced-pricing importers. Configure field ownership first, import a small representative sample, and inspect the actual storefront and price indexes.

Search and product types

Scheduled item search includes inventory items, assembly items, kits, non-inventory items, and item groups changed within the import window. Mapper selection is based on the returned record class and matrix custom fields.

NetSuite record Store representation at this commit
Inventory item Simple product
Non-inventory item Simple product through the default mapper
Assembly item Simple product through the default mapper, unless the matrix custom fields select the configurable mapper
Matrix parent with populated child field Configurable product
Matrix child Simple product
Kit item Bundle with fixed price, dynamic SKU/weight, and components shipped together
Item group Simple product; member-price calculation has a source defect, so validate before use

The older book's assembly-to-bundle and always-dynamic-bundle descriptions do not describe this mapper dispatch. Sources: mapper selection, item search, kit mapper, item-group mapper.

Attribute mapping

Under Product synchronization > Field Mapping, define the NetSuite field, mapping type, and Magento attribute. Map SKU explicitly. Map the intended product name rather than relying on fallback names. The mapper raises InventoryItem doesn't have SKU set. when no SKU is produced.

Mapping option Input and behavior
Standard Field SOAP property such as itemId, displayName, or another valid property of the actual record class.
Custom Field - simple Custom field script ID; simple values, dates, or a referenced value's name.
Custom Field - list Custom list/reference resolution to values usable by the store attribute.
Custom Field - checkbox Configured value when checked; unchecked values resolve to null.
Constant Magento Value Exposed in the form, but its option value does not match the mapper/template checks at this commit. See Known limitations.

Example mapping:

NetSuite field Mapping type Magento attribute
itemId Standard Field sku
displayName Standard Field name
custitem_store_description Custom Field - simple description

The custom field above is an example, not a required pre-existing field. Create and use the actual field IDs from your account.

Mapped dropdown and multiselect attributes can have options added during import. Create the attributes themselves and put them in the selected attribute set. A comma-separated list of NetSuite field names can feed one attribute; the base mapper joins values with spaces. The old netsuite_product_fields_merge event is not dispatched here. Customize the current mapper through a plugin if needed.

Keep store-owned attributes unmapped, but distinguish optional field mapping from built-in handling of SKU, prices, type, website/default data, relationships, and images. Those other paths still manage their respective data.

Default product data

New products use configured visibility, enabled status, tax class, website, store, and attribute set. Defaults include visibility 4, status 1, tax class 0, website/store 1, and attribute set 4. Existing values are used where the base mapper finds them, with fallback rules for empty values.

The default eligibility event starts with is_importable.flag=true; there is no universal built-in "export this product to Magento" checkbox filter. A customization can change the flag. Existing linked products judged non-importable are mapped as disabled; an unlinked non-importable item is ignored. Configure and test this policy before a broad import.

Prices

The base price is read from the configured NetSuite price level for a quantity of one or less. If no usable base price is found, the simple/kit mappers can produce 0.00. Validate prices before making imported products visible.

Special-price modes are Disabled (0), Update Only (1), and Replace (2). Configure a special-price level. Replace can clear an existing value when its configured input is empty. Configurable parent pricing is cleared so variations provide their prices.

Tier rows use quantities greater than one. At this commit, the tier loop is not restricted to the selected base price level, and emitted rows use All Websites [USD]. Validate projects with several price levels or another base currency; do not infer general multi-currency or customer-specific pricing support. Customer-group price-level mapping is separate from these tier-import details.

Configurable products

The mapper consumes two existing NetSuite custom fields:

  • custitem_magento_matrix_children: comma-separated NetSuite child internal IDs.
  • custitem_magento_matrix_attrs: comma-separated NetSuite matrix attribute field IDs, each present in the product field map.

The historical matrix setup page refers to SaveDataForMagento2.js. That script is not in this repository. Have the NetSuite implementation supply and validate field population before importing matrix parents, including after CSV imports or mass updates.

The importer resolves missing children and builds configurable variations. Unmapped matrix attributes cause an error; missing matrix attributes can skip a record. Disabled children or children without websites are removed from the relevant configurable links.

Related products, upsells, categories, and images

Related and upsell settings name NetSuite custom fields containing comma-separated product internal IDs. The prefetch layer resolves them into store relationships. There is no equivalent configurable cross-sell field in this version.

There is no dedicated category-tree synchronization. Keep category ownership in the store unless you implement and validate a project-specific mapping. Images have their own workflow and destructive gallery reconciliation: read Product images.

Initial import and relinking

For an existing catalog, start with a relink dry run:

bin/magento netsuite:utils:relinkbysku dry-run --netsuite-sku-field=itemId

dry-run is a positional argument, not --dry-run. The command changes netsuite_internal_id links when run without that argument. It does not rebuild configurable relationships. Review its proposed matches and preserve existing links before applying it.

For a small explicit set of NetSuite items:

bin/magento netsuite:utils:importsingleproduct --id=123,124 -vvv

The IDs above are examples. --sku refers to existing store SKUs whose NetSuite IDs are already linked. --delete-existing deletes and recreates products and can include associated configurable children. It is not a routine update option.

The package has no netsuite:utils:importproducts bulk bootstrap command. For a large initial catalog, agree a bounded import list/window, validate the subset, and use the supported import path or a reviewed project-specific bootstrap. Increasing the general lookback also affects other enabled import flows.

Sources: base data and attributes, product mapping, simple pricing, matrix relationships, manual import, relink command.

Clone this wiki locally