> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnilinker.pl/llms.txt
> Use this file to discover all available pages before exploring further.

# Field mappings

> Choose which ERP field fills which Omnilinker field, and transform values on the way in.

A field mapping connects one field in your ERP to one field in Omnilinker, for example the Wapro column
`INDEKS_KATALOGOWY` to the product's **SKU**. When a product or brand arrives from the ERP, Omnilinker reads the ERP
fields named in your mappings, applies any default value and transform, and writes the result to the catalog.

Mappings belong to a connection and an entity type. You edit them on the connection's **Field Mappings** tab.

<Note>
  Only **Product** and **Brand** mappings change how data is imported. For price levels, product prices, warehouses
  and stock the provider uses a fixed set of fields. Their default mappings are listed below so you can see which ERP
  columns are read, but editing them has no effect.
</Note>

## Open the field mappings

1. Open **ERP Integration** > **Connections**, and choose **Details** on the connection.
2. Open the **Field Mappings** tab.
3. Choose the entity type in the **Entity Type** list at the top of the tab.

The table shows one row per mapping: **ERP Field**, **Catalog Field**, **Required**, **Default Value**, **Transform**,
**Sync Direction** and **Hash**. To change mappings you need the **Manage Field Mappings** permission.

## Apply the provider's default mappings

Start from the provider's defaults rather than typing every mapping.

<Steps>
  <Step title="Choose the entity type">
    Pick **Product** in the **Entity Type** list.
  </Step>

  <Step title="Load the defaults">
    Click **Load Provider Defaults**. A window lists the provider's mappings for that entity type, with a **Status**
    column: **New** for mappings you do not have yet, **Will Update** for ERP fields you already map.
  </Step>

  <Step title="Choose which to apply">
    New mappings are selected for you. Existing ones are not, so your changes are kept unless you select them. Use
    **Select All** or **Deselect All** if needed. Open **Mapping Descriptions** to read what each ERP field holds.
  </Step>

  <Step title="Apply them">
    Click **Apply Selected**. The mappings are added to the table, marked **New** or **Modified**. They are not saved
    yet.
  </Step>

  <Step title="Save">
    Click **Save All**.
  </Step>
</Steps>

Repeat for **Brand**.

Mappings added this way get **From ERP Only** as their **Sync Direction** and are included in the hash check.

If Omnilinker says **No default mappings available for this provider and entity type.**, add the mappings yourself
from [Wapro default mappings](#wapro-default-mappings).

## Add or edit a mapping

<Steps>
  <Step title="Open the mapping window">
    Click **Add Mapping**, or the edit icon on a row.
  </Step>

  <Step title="Pick the fields">
    In **ERP Field**, pick a field or type its name. In **Catalog Field**, pick the Omnilinker field or type its name.
    Fields that Omnilinker requires carry a **Required** badge.
  </Step>

  <Step title="Set the options">
    Fill in the options described in [Mapping options](#mapping-options).
  </Step>

  <Step title="Add it to the table">
    Click **Add** (or **Save** when editing).
  </Step>

  <Step title="Save">
    Click **Save All** at the bottom of the tab.
  </Step>
</Steps>

Changes you make on this tab are held until you save them. While you have unsaved changes, the tab shows
**Unsaved Changes**. **Save All** stores them. **Discard Changes** reverts them. The delete icon on a row removes the
mapping, also only once you click **Save All**.

Saved mappings take effect within about a minute.

## Mapping options

| Option                    | What it does                                                                                                       |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Default Value**         | Used when the ERP field is empty or missing. Up to 500 characters.                                                 |
| **Required Field**        | If the ERP field is empty and there is no default value, the change fails with a message naming the missing field. |
| **Sync Direction**        | **Bidirectional**, **From ERP Only**, **To ERP Only** or **No Sync**. See the note below.                          |
| **Transform Expression**  | Changes the value on its way in. See [Transforms](#transforms). Up to 1000 characters.                             |
| **Include in hash check** | Whether a change to this field counts as a change in hash scan mode. See [Change detection](#change-detection).    |
| **Priority**              | Order of the field in the hash, 0–100. Shown when **Include in hash check** is ticked.                             |

<Warning>
  **Sync Direction** does not filter anything yet. Every product and brand mapping is applied to data coming from the
  ERP, even one set to **No Sync** or **To ERP Only**. To stop an ERP field from reaching Omnilinker, delete its
  mapping.
</Warning>

### Required fields

Every product needs an SKU and a name. Map an ERP field to **Sku** and to **Name**. Without them, product changes
fail. Brands need **Name**.

## Transforms

A transform changes the value of an ERP field before Omnilinker stores it. Chain several with semicolons. They run
left to right, so `TRIM;UPPERCASE;PREFIX:SKU-` first trims spaces, then upper-cases, then adds the prefix. The
**Transform Reference** section of the mapping window lists them too.

| Transform         | What it does                                                             | Example                                  |
| ----------------- | ------------------------------------------------------------------------ | ---------------------------------------- |
| `UPPERCASE`       | Converts text to upper case                                              | `hello` → `HELLO`                        |
| `LOWERCASE`       | Converts text to lower case                                              | `HELLO` → `hello`                        |
| `TRIM`            | Removes leading and trailing spaces                                      | `" text "` → `"text"`                    |
| `PREFIX:xxx`      | Adds text before the value                                               | `PREFIX:SKU-` turns `123` into `SKU-123` |
| `SUFFIX:xxx`      | Adds text after the value                                                | `SUFFIX:-PL` turns `123` into `123-PL`   |
| `ROUND:n`         | Rounds a number to *n* decimal places                                    | `ROUND:2` turns `3.14159` into `3.14`    |
| `MULTIPLY:n`      | Multiplies a number by *n*                                               | `MULTIPLY:100` turns `1.5` into `150`    |
| `DIVIDE:n`        | Divides a number by *n*                                                  | `DIVIDE:100` turns `150` into `1.5`      |
| `REPLACE:old:new` | Replaces every `old` with `new`                                          | `REPLACE:-:_` turns `a-b` into `a_b`     |
| `DEFAULT:value`   | Uses `value` when an earlier transform in the chain left the value empty | `REPLACE:-:;DEFAULT:N/A`                 |

Things to know:

* Transform names are not case-sensitive. Prefix and suffix text keeps its case.
* Numbers in `ROUND`, `MULTIPLY` and `DIVIDE` use a dot as the decimal separator, for example `MULTIPLY:0.01`.
* `REPLACE` splits on colons, so it cannot replace a colon.
* An unknown transform, or one that does not fit the value (such as `ROUND` on text), leaves the value unchanged.
* The **Default Value** is applied before the transforms, so transforms also apply to it.
* An empty ERP field with no **Default Value** skips the transforms entirely. To fill empty fields, use
  **Default Value** rather than `DEFAULT:`.

## Change detection

In [hash scan mode](/erp/sync-configuration#change-tracking-mode) the agent decides whether a product or brand
changed by comparing a fingerprint (hash) of its fields with the last one it sent. Only fields with
**Include in hash check** ticked go into the fingerprint. A change to an unticked field alone is not sent until
another, hashed field changes.

The **Hash** column shows a filled dot and the priority for hashed fields, and an empty dot for the others.

Adding a field to the hash, or removing one, changes every fingerprint. The next hash scan then sends all products
again. This is safe, but on a large catalog it takes a while.

In WFM\_INT change tracking mode the hash settings only affect the weekly reconciliation pass.

## Wapro default mappings

These are the Wapro provider's default mappings. "Applied" says whether editing the mapping changes the import.

### Product

Applied: yes.

| ERP field            | Omnilinker field            | Required | Notes                                                                                 |
| -------------------- | --------------------------- | -------- | ------------------------------------------------------------------------------------- |
| `INDEKS_KATALOGOWY`  | `Sku`                       | Yes      | The product's catalog index. It is also the product's identity across warehouses.     |
| `KOD_KRESKOWY`       | `Gtin`                      |          | Primary barcode (EAN)                                                                 |
| `NAZWA_CALA`         | `Name`                      | Yes      | Full name. When it is empty, the agent sends the short name `NAZWA` instead.          |
| `PRODUCENT`          | `BrandId`                   |          | Manufacturer name. Omnilinker links the product to the brand of that name.            |
| `RODZAJ`             | `ProductType`               |          | Article kind. The agent sends `Bundle` for a Zestaw and `Simple` for everything else. |
| `CENA_ZAKUPU_NETTO`  | `PurchasePrice.NetAmount`   |          | Net purchase price                                                                    |
| `CENA_ZAKUPU_BRUTTO` | `PurchasePrice.GrossAmount` |          | Gross purchase price                                                                  |
| `VAT_SPRZEDAZY`      | `PurchasePrice.VatRate`     |          | VAT rate. A percentage such as `23` is converted for you.                             |
| `WYMIAR_G`           | `Dimensions.Height`         |          | Height                                                                                |
| `WYMIAR_W`           | `Dimensions.Width`          |          | Width                                                                                 |
| `WYMIAR_S`           | `Dimensions.Length`         |          | Depth                                                                                 |
| `JED_WYMIARU`        | `Dimensions.Unit`           |          | Dimension unit                                                                        |
| `WAGA`               | `Weight.AmountInGrams`      |          | Weight. Copied as it is, without unit conversion.                                     |
| `JED_WAGI`           | `Weight.Unit`               |          | Weight unit                                                                           |

If a product's brand has not reached Omnilinker yet, the product is saved without a brand. The link is added the next
time the product syncs after the brand arrives.

### Brand

Applied: yes. Wapro has no separate brand list. The agent builds brands from the distinct `PRODUCENT` values on
articles, ignoring differences in upper and lower case.

| ERP field   | Omnilinker field | Required |
| ----------- | ---------------- | -------- |
| `PRODUCENT` | `Name`           | Yes      |

### Price level

Applied: no (fixed).

| ERP field              | Omnilinker field | Notes            |
| ---------------------- | ---------------- | ---------------- |
| `NAZWA` (table `CENA`) | `Name`           | Price level name |

### Product price

Applied: no (fixed).

| ERP field                             | Omnilinker field | Notes                            |
| ------------------------------------- | ---------------- | -------------------------------- |
| `CENA_NETTO` (table `CENA_ARTYKULU`)  | `NetAmount`      | Net sale price                   |
| `CENA_BRUTTO` (table `CENA_ARTYKULU`) | `GrossAmount`    | Gross sale price                 |
| `SYM_WAL` (table `CENA_ARTYKULU`)     | `Currency`       | Empty means PLN                  |
| `VAT_SPRZEDAZY` (table `ARTYKUL`)     | `VatRate`        | Empty, `ZW` or `NP` means no VAT |

### Warehouse

Applied: no (fixed).

| ERP field                         | Omnilinker field | Notes                                         |
| --------------------------------- | ---------------- | --------------------------------------------- |
| `SYMBOL` (table `MAGAZYN`)        | `Code`           |                                               |
| `NAZWA` (table `MAGAZYN`)         | `Name`           |                                               |
| `NIEAKTYWNY` (table `MAGAZYN`)    | `IsActive`       | Inverted: an inactive warehouse is not active |
| `STAN_MAGAZYNU` (table `MAGAZYN`) | `State`          | Working or stocktake (`Praca` / `Remanent`)   |

### Stock

Applied: no (fixed). Available stock is calculated as on hand minus quantity on open documents minus reserved.

| ERP field         | Omnilinker field | Notes                      |
| ----------------- | ---------------- | -------------------------- |
| `STAN`            | `OnHand`         | On-hand quantity           |
| `ZAREZERWOWANO`   | `Reserved`       | Reserved quantity          |
| `ILOSC_EDYTOWANA` | `Edited`         | Quantity on open documents |
| `STAN_MINIMALNY`  | `MinLevel`       | Minimum stock level        |
| `STAN_MAKSYMALNY` | `MaxLevel`       | Maximum stock level        |

## Troubleshooting

<AccordionGroup>
  <Accordion title="Product changes fail with a required-field message">
    A mapping marked **Required Field** had no value and no default. Check that the ERP field has data, add a
    **Default Value**, or clear **Required Field**. The message on the **Sync Logs** tab names the field.
  </Accordion>

  <Accordion title="A field I changed in Omnilinker went back to the ERP value">
    The ERP overwrites every mapped field each time the product changes there. Change the value in the ERP instead, or
    delete the mapping so the ERP stops supplying that field.
  </Accordion>

  <Accordion title="A change in the ERP did not arrive">
    In hash scan mode, check that the field is included in the hash check. See [Change detection](#change-detection).
  </Accordion>
</AccordionGroup>

See also [Troubleshooting](/erp/troubleshooting).
