Skip to main content

Magento PlentyONE Suite v4.2 - Self-Healing Stock Status, Safer Order Sync & Auth Resilience

· 7 min read
Byte8 Team
PlentyONE Connector Development Team

Magento PlentyONE Suite v4.2 closes a class of silent-lost-sales bugs and makes manual operations behave the way operators expect. The headline: stock status now heals itself. Under Magento 2.4.7+ MSI, the indexed stock status is an event-driven cache that a reindex deliberately never rebuilds - one missed salability event and an in-stock product stays "out of stock" forever, with no error anywhere. v4.2 detects and repairs that drift automatically. On the order side, manual exports act immediately (no more settling-period defer for the admin button), booked PlentyONE orders are protected from address churn, and the import pipeline stops flagging clean orders, duplicating tracking numbers, and erroring on order types it was never meant to handle. Rounding it out: the API client recovers from revoked refresh tokens on its own, and manufacturer sync gets its own collection watermark.

Legacy metapackage

This release corresponds to Mage2Plenty v3.14 on the legacy softcommerce/mage2plenty-os metapackage - same fixes, Byte8 module namespaces and versions.

Stock status that heals itself

A getkapp-class incident drove this work: products with stock in PlentyONE, correct quantities in Magento, zero reservations - and no add-to-cart button. Every layer agreed the product was sellable except the one the storefront reads: cataloginventory_stock_status.

Under MSI (Magento 2.4.7+) that table is an event-driven salability cache. Its only writers are a source-item save and the async reservation consumer; the legacy reindex deliberately preserves the existing value. Miss one salability-recovery event and the product is stranded - and the connector's quantity-unchanged skip guard ensured it never got the source-item save that would heal it. v4.2 attacks this from three sides:

  • The skip guard got smarter. The stock import now skips only when quantity is unchanged and the source-item status is consistent with it. A drifted status falls through to a real save, letting MSI re-derive the truth.
  • A new stock-status reconciler (plenty:stock:status:reconcile, with --dry-run) detects stock-managed products whose indexed status contradicts their actual salability - quantity, reservations, min-qty and backorders all considered - and heals them via a values-unchanged source-item re-save, so core MSI computes the authoritative, reservation-aware result. Products legitimately suppressed by reservations are left alone. An hourly cron (plenty_stock_status_reconcile, enabled by default, config-gated) runs it as a standing safety net.
  • A --force escape hatch on plenty:stock:import bypasses the skip guard on demand, and the admin Refresh Stock button now always forces - an explicit refresh re-asserts stock even when nothing changed numerically.

Stock consistency checks: portable everywhere

Consistency queries are now table-prefix aware and use portable aggregation, so installations with a database table prefix or strict SQL modes run the drift and reconcile checks without errors.

Order export, on your command

  • The admin export button means now. The settling-period deferral exists so cron doesn't export orders mid-payment-transition - but it also silently deferred explicit admin exports. The order-view Export button and the sales-grid Mass Export action now run in forced mode: they bypass the scheduler-only guards and run the duplicate-search protection, exporting immediately.
  • New --no-force flag on plenty:order:export does the opposite: it runs the export with exact scheduled-run semantics (settling defer, processing claim) - invaluable for reproducing cron behaviour from the shell.
  • Booked orders keep their addresses. Scheduled re-exports of an already-exported order no longer touch its addresses or address relations - the churn that could re-link a live order's delivery address mid-fulfilment is gone. Half-created orders (created in PlentyONE but relations never landed) still complete on retry, and a forced export can still deliberately push a corrected address.

Order import: quieter, and correct where it counts

  • Statuses are per-order again. One problematic order in an import batch used to paint every clean sibling "warning" - hundreds of false warnings that buried real problems. Each order's status now reflects only its own messages (backed by a new per-entity status resolution in module-core).
  • Unsupported order types skip instead of erroring. PlentyONE reorders, offers, repairs and similar document types fell through to contact resolution and hard-errored ("PO order address not found") on every run. Two new guards limit import to the supported types (sale, delivery, returns, credit note, warranty) and skip contact-less orders gracefully - marked SKIPPED with a notice, not an error.
  • Tracking numbers import once. Orders with multiple shipping packages re-inserted already-imported tracking numbers on every run - unbounded duplicate rows in sales_shipment_track and repeated customer-facing tracking entries. The duplicate check now compares against all existing numbers, blank PlentyONE package numbers are ignored, and the idempotent-skip message dropped from warning to notice.
  • Credit memos survive shipping mismatches. When PlentyONE reports shipping cost the Magento order doesn't carry (e.g. a small-order fee booked as shipping), the whole credit memo was rejected. The shipping refund is now capped to what Magento actually holds as refundable.
  • Unassigned-variation lines ship. PlentyONE order lines with no linked variation (type 9 - manual lines, deleted variations) carry the Magento SKU as an order-item property; the shipment generator now falls back to that SKU whenever the variation lookup fails, and - since PlentyONE drops the warehouse assignment on such lines - resolves the ship-from source via the order's reservation, then the main warehouse mapping. Delivery orders previously dropped such lines silently, leaving Magento orders stuck partially shipped.

API client: self-healing authentication

PlentyONE now rotates refresh tokens, and a revoked token used to be terminal: OAuth2 token endpoints reject it with HTTP 400 invalid_grant, the client only treated 401 as an auth failure, and every sync failed until someone ran a manual re-login. The client now falls back to a credential login on any refresh failure, accepts both snake_case and camelCase token-response formats, refuses to overwrite stored credentials with an empty response, and never discards its stored refresh token unless the response carries a new one.

Manufacturer sync: own watermark

Manufacturer collection shared the attribute table's incremental watermark, so manufacturers created in PlentyONE after the last attribute change were never picked up - the Hersteller list silently went stale. Manufacturer collect now tracks its own watermark.

Release Summary

ModuleVersionBumpKey Changes
module-core3.1.0 → 3.2.0minorPer-entity overall status resolution in MessageCollector
module-plenty-core3.0.1 → 3.0.2patchCredential-login fallback when token refresh fails with HTTP 400
module-plenty-item4.1.0 → 4.1.1patchManufacturer collection uses its own watermark
module-plenty-order3.1.0 → 3.2.0minor--no-force CLI option; admin exports bypass settling defer; address churn guard; per-order import status; unsupported-type skip; tracking dedup; credit-memo shipping cap; unassigned-variation shipment fallback
module-plenty-stock3.0.1 → 3.1.0minorStock-status reconciler (CLI + hourly cron); smarter skip guard + --force; prefix-aware/portable queries
module-plenty-category4.0.0 → 4.0.1patchInternal maintenance

Metapackage: byte8/magento-plentyone-suite 4.1.0 → 4.2.0

Upgrade Guide

composer require byte8/magento-plentyone-suite:^4.2

bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

No schema changes in this release. Behaviours worth noting on upgrade:

  • A new hourly cron is on by default. plenty_stock_status_reconcile (hourly at :20) heals stranded stock statuses automatically; disable or reschedule under Stock Settings → Stock Status Reconcile if needed.
  • The admin "Out of Stock" toggle no longer sticks for stock-managed products: the next stock import re-asserts PlentyONE's state (the toggle also flips the MSI source item, which the import now treats as drift). Stop sales by zeroing stock in PlentyONE, not via the Magento toggle.
  • Admin order exports act immediately - they bypass the settling-period defer and will update an already-exported order's addresses. That's the intended semantics of an explicit operator action; scheduled runs remain fully guarded.
  • Existing false "warning" orders don't reflag - the per-order status fix applies from the next import run; historic statuses clear as orders are re-processed.
  • Tracking duplicates stop accumulating, but rows created before the upgrade remain - clean sales_shipment_track once if your install was affected.

Resources


Questions about the upgrade? Reach out to us at support@byte8.io.