Erpy for Craft CMS

Field mapping

The connector fills in everything canonical already. Mapping is for the rest — your custom fields, and the places where your ERP tenant does not match the connector's assumptions.

Erpy → Connections → your connection → Mapping. Rules are per connection, per entity, per direction.

A rule

A rule reads a source out of the document and writes it to a target, optionally through one or more transforms, with a default when the source is empty.

The source can be any path in the canonical document — and that includes raw., the untouched ERP payload the connector received. If your ERP sends a field no connector knows about, raw. is how you reach it.

raw.Item_Group_Code   →   productType        transform: trim | upper
raw.Web_Description   →   myRichTextField    transform: striptags
unitPrice             →   myPriceField       transform: round:2

The overlay: a mapping can correct the connector

A rule whose target is a canonical field — sku, unitPrice, customerCode — is not a Craft mapping at all. It overwrites what the connector read, before the document reaches Commerce, and coerces the value to the property's declared type.

This is the escape hatch that makes the whole add-on model work. A connector that guessed the wrong field name on your tenant is a mapping rule, not a support ticket and a release cycle. It is essential for the ERPs whose API is configured per customer — AFAS, Priority, Unit4, a published Business Central page.

Canonical rules are applied by the overlay and then deliberately skipped by the Craft-field pass, so sku is never also looked for as a Craft field on your product.

Transforms

The vocabulary is small and non-Turing-complete on purpose. A mapping screen that can run arbitrary code is a mapping screen that can take a site down at 3am.

Chain them with |, and pass an argument after :.

trimTrim whitespace
upper lower ucfirst titleCase
slugSlugify
striptagsStrip HTML
int number abs round:2Numbers
bool notYes/no — and an ERP expresses "no" as an alarming number of things
prefix: suffix: truncate:255
replace:find:replaceFind and replace
date:Y-m-dFormat as a date
join:, split:, first countLists
jsonEncode the value
default:Fall back to a value when empty
nullif:Treat a particular value as empty

nullif: earns its place more often than it looks like it should. ERPs are full of sentinel values — a 0001-01-01 date, a 0 customer code, an N/A description — that mean "empty" and will otherwise be written into Commerce as if they were data.

Per-entity options

Each entity's mapping screen carries its own switches — "create missing products", and so on. They live with the rules because they are the same kind of decision: what this connection should do with this entity, on this site.

A variant Erpy creates has to be told to track inventory

If you let Erpy create variants that do not exist in Commerce yet, note that a new variant does not track inventory by default — and a variant that does not track inventory is skipped by the first stock sync. Erpy sets the flag on variants it creates for exactly this reason. If you are creating variants some other way and their stock never arrives, that is the thing to check.

Preview before you trust it

The mapping screen's preview reads a real page from the ERP and shows what each rule produces, against real values. Do that before a first full run — a round:2 on a field that turns out to be a string is much cheaper to find here than in 40,000 product saves.