Skip to main content

Stock Updates

What It Does

This workflow maintains consistent stock quantities across Magento, Logidav, and all connected marketplaces (Amazon, Cdiscount, ManoMano). Every stock mutation -- whether triggered by a sale, a return, a container arrival, or a manual adjustment -- is journaled through ProductQtyLogService before the quantity is updated and propagated downstream.

How It Connects

Trigger

SourceEventDirection
Sale importOrder reaches processing or completeDecrement
Sale status updateStatus changes during reconciliationDecrement
Container arrivalNew stock received at warehouseIncrement
Refund / returnProduct physically returnedIncrement
Manual adjustmentAdmin stock correction via back-officeIncrement or decrement
Marketplace sync commandsScheduled cron syncBidirectional

Components

ComponentFile PathRole
ProductQtyLogServicesrc/AppBundle/Services/ProductQtyLogService.phpStock mutation journaling -- every qty change goes through this service
SaleServicesrc/AppBundle/Services/SaleService.phpTriggers mutations when importing or updating sales
Stock sync commandssrc/AppBundle/Command/Stock/Bidirectional stock synchronization with external systems

Step-by-Step Flow

Mutation Types

TypeTriggerDirectionExample
saleSale import or status updateDecrementOrder enters processing status
returnRefund processed with physical returnIncrementCustomer returns a product
containerContainer arrival at warehouseIncrementNew shipment of 500 units received
manualAdmin action in back-office+/-Stock correction after physical audit

Side Effects

Database

  • Writes a ProductQtyLog journal entry for every mutation (type, quantity delta, source sale/container, timestamp)
  • Updates the Product.qty field
  • All mutations are auditable via the journal

External Systems

  • Marketplace stock levels are updated on the next sync cron cycle, not immediately
  • Magento stock is synchronized bidirectionally via stock commands

:::info Propagation delay Stock changes are not instant on marketplaces. Marketplace sync commands run on their own cron schedules (typically every 15--30 minutes). During this window, marketplace stock may be stale. See Queue Model for sync timing details. :::

Failure Modes

:::danger Double-decrement bug If a sale is imported by menzzo:v2:sales and its status is updated by menzzo:v2:sales:update in overlapping time windows, stock can be decremented twice for the same order.

Mitigation: ProductQtyLogService checks for existing log entries before applying a mutation. However, this check is not transactional -- under high concurrency or if the EntityManager is in a dirty state, the guard can be bypassed.

Recovery: Query ProductQtyLog for duplicate entries on the same Sale + Product combination. If duplicates exist, manually correct the quantity and add a manual log entry. :::

:::warning Negative stock Logidav does not always block negative stock quantities. Depending on configuration, a product's quantity can go below zero. This is by design for pre-order scenarios but can mask real inventory problems. :::

:::warning Marketplace sync failure If a marketplace API is down or rate-limited during sync, the stock update is deferred to the next cycle. Persistent API failures can cause significant stock drift on marketplaces. :::

Debugging Path

  1. Check the journal -- query ProductQtyLog entries for the product in question. Each entry records the mutation type, delta, and source reference.
  2. Verify the sale status -- if the mutation was triggered by a sale, confirm the sale's current status and check SaleLog for status transitions.
  3. Compare Logidav vs Magento stock -- use the stock sync commands to pull the current Magento quantity and compare with Logidav's Product.qty.
  4. Check marketplace sync queues -- verify that the marketplace sync commands are running and not backed up. See Queue Debugging.
  5. Look for duplicates -- search ProductQtyLog for multiple entries with the same sale reference. This indicates the double-decrement issue.
  6. Inspect EntityManager state -- if mutations are missing, check logs for EntityManager errors during the import that may have prevented the journal write.
CommandPurpose
menzzo:v2:salesTriggers stock decrements on new order import
menzzo:v2:sales:updateTriggers stock decrements on status change
Stock sync commands (src/AppBundle/Command/Stock/)Bidirectional sync with Magento and marketplaces