Synchronization flows
Product sync (Optima → Magento)
Trigger: cron sisl_optima_sync_products (schedule dropdown, default every 1h) or manually from the Dashboard.
ProductSync.run()
├─ license.isValidNow()? ──── NO ──► abort with errors=["LICENSE INVALID"]
│ YES
▼
loop over pages, pageSize from config (200):
SyncClient.get('/v1/products?page=N&pageSize=200&tier=1')
│
▼
HMAC sign + retry 3x → microservice → SQL:
SELECT Twr_Kod, Twr_Nazwa, Twr_Jm, Twr_Ean,
CASE WHEN TwC_Typ=1 THEN TwC_Wartosc END AS PriceNet,
CASE WHEN TwC_Typ=2 THEN TwC_Wartosc END AS PriceGross
FROM CDN.Towary t LEFT JOIN CDN.TwrCeny c
ON c.TwC_TwrID = t.Twr_GIDNumer AND c.TwC_TwCNumer = @tier
WHERE t.Twr_GIDTyp = 16
OFFSET @offset ROWS FETCH NEXT @pageSize ROWS ONLY
│
▼
for each SKU:
├─ SKU prefix filter (optional)
├─ skip if it's a service (jm=GODZ, twr_typ != 0)
├─ skip if attribute sisl_optima_sync_disabled = 1
▼
upsert into catalog_product_entity:
- new → SKU + name + status (config) + visibility (config) + ean + jm + price (if sync_prices ON, otherwise 0)
- existing → only name + ean + jm (price only if sync_prices ON)
- description: never overwrites existing
Result: {"created": N, "updated": M, "skipped": K, "errors": [...]} saved in core_config_data (SyncState) and shown in the Dashboard.
Stock sync (Optima → Magento)
Trigger: cron sisl_optima_sync_stock (every 15 min by default) or manually.
StockSync.run()
└─ license gate ── as above
▼
SyncClient.get('/v1/stocks?warehouse=MAGAZYN&page=N&pageSize=500')
│
▼
microservice → SQL (real stock from PZ documents):
SELECT t.Twr_Kod AS Sku, m.Mag_Symbol AS Warehouse,
SUM(z.TwZ_Ilosc - z.TwZ_Quan) AS Available,
MAX(i.TwI_Rezerwacje) AS Reserved,
MAX(i.TwI_Zamowienia) AS OnOrder
FROM CDN.Towary t
JOIN CDN.Magazyny m ON m.Mag_Symbol = @warehouse
LEFT JOIN CDN.TwrZasoby z
ON z.TwZ_TwrId = t.Twr_GIDNumer AND z.TwZ_MagId = m.Mag_MagId
AND z.TwZ_TrSIdDost > 0 -- ONLY real documents, ignores synthetic entries
LEFT JOIN CDN.TwrIlosci i ON i.TwI_TwrId = t.Twr_GIDNumer
GROUP BY t.Twr_Kod, m.Mag_Symbol
▼
for each SKU:
rawQty = Available from Optima
effective = max(0, rawQty - stock_buffer)
inStock = effective > oos_threshold
StockRegistry.updateStockItemBySku(sku, {qty: effective, isInStock: inStock})
Source of truth: CDN.TwrZasoby filtered by TwZ_TrSIdDost > 0 (i.e., only stock backed by real PZ/PW/MM documents). This is exactly the same logic the Optima GUI uses in the "Stan handlowy" view.
Order forward (Magento → Optima)
Trigger: Magento event sales_order_place_after (observer in events.xml).
OrderPlaceAfter.execute(observer)
└─ license gate
└─ orders_enabled config gate
▼
OrderForward.send(order):
builds payload:
{
magentoOrderId, incrementId, createdAt, currency,
grandTotal, subtotal, tax, shippingTotal, shippingMethod, paymentMethod,
customer: {email, firstname, lastname, taxId, isCompany, magentoId},
billingAddress: {...},
shippingAddress: {...},
items: [{sku, name, qty, priceNet, priceGross, taxAmount, taxPercent}, ...]
}
▼
SyncClient.post('/v1/orders', payload)
▼
microservice:
- validates payload
- checks license + HMAC
- generates XML matching Optima Import (TraNag + TraElem + KntKarty)
- drops it into the folder watched by Optima (XML import in)
- returns {optimaInvoiceId} after async processing
Fail-soft: if sending fails (microservice offline, license invalid, etc.) — the order stays in Magento with no trace in Optima. The plugin logs a warning + writes a comment in the order status history. Cron retry can be added in v0.2.
License check
Trigger: cron sisl_optima_check_license (daily 03:00 by default).
LicenseChecker.checkNow()
builds request:
{
key: <license key from config>,
product: "sisl_optima",
host: <BASE_URL host>,
version: "0.1.0",
nonce: <16 bytes random hex>,
manifest_hash: <SHA256 of 8 critical files>
}
▼
POST https://license.sisl.pl/check
▼
SISL server:
- looks up license
- checks status (active / revoked / expired)
- checks valid_until
- checks host binding (first time: bind; later: must match)
- records manifest hash + compares to previous (logs drift)
- signs Ed25519 response with echoed nonce
▼
plugin:
- VERIFIES Ed25519 SIGNATURE (WITHOUT THIS, STATE IS NOT SAVED)
- checks nonce match (anti-replay)
- saves state to core_config_data (sisl_optima/license/state):
{valid, message, valid_until, checked_at, verified: true, was_valid}
Product lifecycle
| Action in Optima | What happens in Magento |
|---|---|
| You add a new SKU in the pricelist | Next ProductSync creates it in Magento (status=Enabled, price=0 if prices_enabled=No) |
| You change the price in pricelist 1 | StockSync DOES NOT touch it; ProductSync overwrites only if prices_enabled=Yes |
| You enter a PZ for 50 pcs | Next StockSync sets qty=50, in_stock=1 |
| You issue an FA (sale) for 5 pcs | TwrZasoby decrements; next StockSync sets qty=45 |
| You mark the item inactive | The plugin still syncs it (Twr_NieAktywny is not checked in v0.1 → todo for v0.2) |
| You delete the item | It stays in Magento (orphan); delete manually or wait for v0.2 |
Next: Diagnostics and errors →