> ## 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.

# Wapro

> What the Wapro provider reads from your Wapro Mag database, what it writes, and what to grant its SQL login.

The Wapro provider connects Omnilinker to Wapro Mag, the warehouse and sales system from Asseco. It is the only ERP
provider available today. It runs inside the ERP Sync agent on your network and talks to the Wapro SQL Server database
directly, because Wapro Mag has no web API.

## Supported versions

The provider lists **Wapro Mag 10+** and **WF-Mag** as its supported versions. The agent reports the Wapro version it
finds in the database on the connection's **Agent** tab, under **ERP version**.

## What the provider reads

The provider only reads your business data. It never changes articles, prices, stock or warehouses.

| Data                 | Wapro source                                                                                                | Notes                                                                                                                    |
| -------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Products             | Articles (`ARTYKUL`)                                                                                        | Only articles marked active for external systems (`AKTYWNY_DLA_SYS_ZEW = 1`) and not marked removed (`FLAGA_STANU = 5`). |
| Brands               | The manufacturer field on articles (`PRODUCENT`)                                                            | Wapro has no brand list. Each distinct manufacturer name becomes a brand, ignoring upper and lower case.                 |
| Product type         | Article kind (`RODZAJ`)                                                                                     | A Zestaw becomes a bundle product. Everything else becomes a simple product.                                             |
| Price levels         | The `Api_V_Price` view                                                                                      | Derived levels (calculated from another level) are never used.                                                           |
| Product prices       | Article prices (`CENA_ARTYKULU`)                                                                            | Net and gross price per product and price level. Needs WFM\_INT change tracking.                                         |
| Warehouses           | `MAGAZYN`                                                                                                   | Needs WFM\_INT change tracking to sync. The list is also uploaded for mapping in either mode.                            |
| Stock                | Stock columns on articles (`STAN`, `ZAREZERWOWANO`, `ILOSC_EDYTOWANA`, `STAN_MINIMALNY`, `STAN_MAKSYMALNY`) | One quantity per product and warehouse. Needs WFM\_INT change tracking.                                                  |
| Bundle composition   | Product definitions (`DEFINICJA_PRODUKTU`, `PRODUKT_WARIANT`)                                               | See [Bundles](#bundles-zestaw).                                                                                          |
| Units and categories | `JEDNOSTKA`, `KATEGORIA_ARTYKULU`                                                                           | Uploaded as reference data. Not used in Omnilinker yet.                                                                  |
| Companies            | `FIRMA`                                                                                                     | Lets you pick the company in the agent's settings.                                                                       |
| Wapro version        | `WAPRODBSTATE`, `aktywnosc_wfs`                                                                             | Used to detect Wapro upgrades.                                                                                           |

The field-by-field defaults are on [Field mappings](/erp/field-mappings#wapro-default-mappings).

### What it does not do

The provider does not write to Wapro. The capabilities Omnilinker shows for Wapro include **Write Products** and
**Delete Products**, but these are not implemented. Creating, changing or deleting a product in Omnilinker never
changes Wapro. Price and stock write-back are not available either.

Orders are not synced in either direction.

## How products are identified

In Wapro, every warehouse has its own row for the same article. Omnilinker treats all rows with the same catalog index
(`INDEKS_KATALOGOWY`) as one product, and uses that index as the product's SKU. Leading and trailing spaces are
ignored.

* Articles with an empty catalog index cannot be identified and are skipped.
* The product's details (name, barcode, dimensions and so on) come from one warehouse's row. Set
  **Primary source warehouse ID** on the connection to choose which warehouse. If you leave it unset, the agent uses
  the row with the lowest article ID. See [Sync configuration](/erp/sync-configuration#connection-wide-sync-settings).
* Stock is sent per warehouse.
* Prices are taken from the same row as the product's details.

### What counts as a deleted product

Omnilinker deletes the matching catalog product when an article is deleted in Wapro, marked removed, or no longer
marked active for external systems.

## Multi-company databases

A Wapro database can hold several companies. Enter the company's ID (`ID_FIRMY`) in the agent's settings under
**Company ID (optional, for multi-company databases)**. The agent then reads only that company's warehouses, price
levels and articles. Leave it blank for a single-company database. See [Setup wizard](/erp/setup-wizard).

## Change detection

The provider supports both change tracking modes. See
[Change tracking mode](/erp/sync-configuration#change-tracking-mode) for how to switch.

* **Hash scan** reads products and brands on a schedule and compares fingerprints. It needs read access only and
  writes nothing to the database. It does not sync prices, warehouses or stock.
* **WFM\_INT change tracking** uses Wapro's own integration framework, `WFM_INT`. Wapro's triggers record every change
  to the tracked tables, including changes made directly with SQL, and the agent reads those records about once a
  minute.

### What the agent writes to your database

With **WFM\_INT change tracking**, the agent writes to Wapro's `WFM_INT` framework tables. It never writes to your
business tables. Before registering, it asks for explicit consent in the tray app:
**I consent to Omnilinker registering change tracking in the WFM\_INT framework tables**.

When you click **Enable Change Tracking**, the agent does this in a single transaction:

1. Adds one row to `WFM_INT_SYSTEM` with the description `OMNILINKER`. This registers Omnilinker as a consumer of
   change records.
2. Adds one subscription row to `WFM_INT_SYSTEM_TABLICE` for each tracked table: `ARTYKUL`, `CENA`, `CENA_ARTYKULU`,
   `MAGAZYN`, `KOD_KRESKOWY`, `KATEGORIA_ARTYKULU` and `KATEGORIA_ARTYKULU_TREE`.
3. Adds one row for every existing record of those tables to the matching `WFM_INT_<table>` table, marked as new.
   This is what makes the first sync send everything. On a large database this is a large insert, so run it outside
   busy hours.

Registering again is safe. It only adds what is missing.

After registration:

* Wapro's own triggers add or update a row in `WFM_INT_<table>` for Omnilinker whenever a tracked record changes,
  just as they do for any other registered consumer.
* After the agent has saved a batch of changes in its outbox, it marks those rows as processed (it sets
  `StatusObiektu` to `0`). It only updates rows that belong to the `OMNILINKER` registration.

When you click **Disable Change Tracking** in the tray app, the agent deletes its subscription rows, its rows in each
`WFM_INT_<table>` table and its `WFM_INT_SYSTEM` row, again in one transaction. Rows of other consumers are never
touched. Switching the connection back to **Hash scan** in the web app alone stops the agent reading the change
records but leaves the registration in place.

The agent also runs read-only health checks. It reads trigger metadata (`sys.triggers`) for the `WFM_INT` triggers on
the tracked tables, the server's `nested triggers` setting (`sys.configurations`), and counts articles currently
locked for editing (`ARTYKUL.SEMAFOR`).

### Health requirements for WFM\_INT

* **Wapro's `WFM_INT` triggers must be enabled** on the tracked tables. A disabled trigger means changes to that table
  are not recorded.
* **The SQL Server `nested triggers` option must be on (`1`).** Wapro relies on triggers firing other triggers.
* **Articles locked for editing** in Wapro are picked up once the lock is released.

### Wapro upgrades

A Wapro upgrade recreates the change-tracking triggers, and changes made while it runs are not recorded. The agent
watches the Wapro version and hotfix history. When they change, it checks change tracking again and runs a
reconciliation pass. While an upgrade is running, the agent may meet missing tables or columns. It then pauses the
affected data stream and tries again later, without marking the changes as read.

## Reconciliation

With **WFM\_INT change tracking**, the agent still runs the hash scan, as a safety net:

* weekly, and
* after it detects a Wapro upgrade.

It re-sends any product or brand whose fingerprint differs from what Omnilinker last received. Brands are sent by this
pass, so a new manufacturer name can take up to a week to appear as a brand.

## Bundles (Zestaw)

An article whose kind is Zestaw becomes a bundle product in the catalog. Its components come from the Wapro product
definition:

* The agent reads bundle compositions when it starts and then every 6 hours. Changes to a composition are not tracked
  by `WFM_INT`, so this is a full read each time.
* If a bundle has several variants, the agent uses the default one that is not blocked, or otherwise the variant with
  the lowest ID.
* Quantities of the same component are added up.
* Components are matched by their catalog index. Components with an empty index are left out.
* A bundle with no components in Wapro has its components cleared in Omnilinker.
* A bundle is skipped until the bundle product and all its components have reached Omnilinker.
* A bundle cannot contain another bundle. Such a bundle is skipped.

How bundle prices are stored depends on **Bundle (Zestaw) price source** on the connection. See
[Bundle pricing](/erp/sync-configuration#bundle-pricing).

## SQL Server login

The agent connects with the SQL Server login you enter in its settings, or with Windows authentication.

* **Hash scan** needs read access to the Wapro database, for example the `db_datareader` role.
* **WFM\_INT change tracking** additionally needs `INSERT` and `DELETE` on `WFM_INT_SYSTEM` and
  `WFM_INT_SYSTEM_TABLICE`, and `INSERT`, `UPDATE` and `DELETE` on the seven `WFM_INT_<table>` tables listed above.

The exact `GRANT` statements are in [Requirements](/erp/requirements#sql-server-login).

If you grant read access object by object instead of through `db_datareader`, the agent reads these objects:
`ARTYKUL`, `CENA`, `CENA_ARTYKULU`, `MAGAZYN`, `KOD_KRESKOWY`, `KATEGORIA_ARTYKULU`, `JEDNOSTKA`, `FIRMA`,
`DEFINICJA_PRODUKTU`, `PRODUKT_WARIANT`, `Api_V_Price`, `WAPRODBSTATE`, `aktywnosc_wfs`, `WFM_INT_SYSTEM`,
`WFM_INT_SYSTEM_TABLICE` and the `WFM_INT_<table>` tables.

## Known limitations

* Read-only: nothing is written back to Wapro. See [What it does not do](#what-it-does-not-do).
* Product prices, warehouses and stock need WFM\_INT change tracking.
* In WFM\_INT mode, brands are updated only by the weekly reconciliation pass.
* Only the primary barcode (`KOD_KRESKOWY` on the article) is synced. Additional barcodes and categories are not.
* Wapro's price trigger does not record a change of currency alone, so a price whose only change is its currency is
  not sent until something else about it changes.
* Changes made while a Wapro upgrade runs are only caught by the reconciliation pass that follows it.
* Prices and stock skipped because their price level or warehouse was not mapped are applied at their next change,
  not when you add the mapping. See [Reference items](/erp/reference-items#what-happens-to-unmapped-items).
* Articles with an empty catalog index are not synced.

## Related pages

<CardGroup cols={2}>
  <Card title="Requirements" icon="list-checks" href="/erp/requirements">
    Network, SQL Server login and permissions.
  </Card>

  <Card title="Field mappings" icon="arrow-left-right" href="/erp/field-mappings">
    Wapro's default field mappings.
  </Card>

  <Card title="Sync configuration" icon="settings" href="/erp/sync-configuration">
    Change tracking mode, intervals and bundle pricing.
  </Card>

  <Card title="Reference items" icon="list" href="/erp/reference-items">
    Map Wapro price levels and warehouses.
  </Card>
</CardGroup>
