Skip to main content

Sales Import

What It Does

This workflow ingests orders from Menzzo Magento 2 into Logidav and keeps order statuses synchronized between both systems. It runs continuously via two cron-scheduled commands -- one for new orders and one for status reconciliation -- ensuring that Logidav always reflects the current state of the Magento order book.

How It Connects

Trigger

CommandSchedulePurpose
menzzo:v2:salesEvery 10 minutesImport new orders
menzzo:v2:sales:updateEvery 30 minutesSynchronize statuses

Components

ComponentFile PathRole
SaleCommandsrc/AppBundle/Command/Sale/V2/SaleCommand.phpImports new orders from Magento
UpdateSaleCommandsrc/AppBundle/Command/Sale/V2/UpdateSaleCommand.phpReconciles statuses with Magento
SaleServicesrc/AppBundle/Services/SaleService.phpUpsert logic for orders and line items
ProductQtyLogServicesrc/AppBundle/Services/ProductQtyLogService.phpJournals stock mutations triggered by imports

Step-by-Step Flow: New Order Import

:::info Key concept: cursor-based import The import uses a simple cursor (last Magento entity_id). Each successfully imported order advances the cursor. This is fast but means skipped orders require manual replay. :::

Step-by-Step Flow: Status Synchronization

:::tip 48-hour delta pass The status sync includes a 48-hour lookback window that catches out-of-band status changes. This compensates for late payment events and other asynchronous updates from Magento. :::

Side Effects

Database Persistence

  • Creates or updates Sale and SaleProduct entities
  • Advances the Magento cursor (last imported entity_id)
  • Writes SaleLog entries for every status change detected during sync

Stock Mutations

  • Decrements stock via ProductQtyLogService::productChangeLog(..., 'sale') when an order reaches processing or complete
  • Mutations happen during both initial import and status update -- see Stock Updates for double-decrement risks

Customer Actions

  • Manages delivery appointments for eligible orders
  • Attempts to send RETRAIT (pickup) email (currently disabled -- sendRetraitEmail() returns immediately)

Failure Modes

:::warning Cursor offset menzzo:v2:sales advances the cursor after each successfully imported order. If an order fails, it is skipped and processing continues. Skipped orders are not retried automatically and require manual replay. :::

:::warning Non-idempotent replay SaleService::addOrder() performs an upsert. Replaying an order payload is not a no-op: it can update the status, add missing line items, or trigger additional stock mutations. Always check ProductQtyLogService logs before replaying. :::

:::danger Upstream status drift If Magento status changes arrive late (e.g., delayed payment confirmation), the 48h delta pass will eventually pick them up. However, in the window between the missed event and the delta pass, Logidav and Magento are out of sync. :::

:::warning Deadlocks and EntityManager errors The import degrades deadlocks and EntityManager errors to warnings and continues processing the batch. Check logs for degraded errors that may indicate data inconsistency. :::

Debugging Path

  1. Missing orders -- check the cursor value via SaleService::getLastMagentoId(). If orders were skipped, the cursor will have advanced past them.
  2. Incorrect status -- query SaleLog entries for the affected sale to see what status transitions were recorded.
  3. Inconsistent stock -- inspect ProductQtyLogService logs for the sale's products. Look for duplicate mutations.
  4. Concurrency issues -- check LockableTrait logs for blocked executions.
  5. Manual replay -- re-run the command with the appropriate cursor or force a specific order ID.
CommandPurpose
menzzo:v2:salesPrimary order import
menzzo:v2:sales:updateStatus synchronization
menzzo:v2:sales:paymentPayment processing
sale:expedition:importExpedition data import
menzzo:lengow:sales --marketplace=<account>Import Lengow V3 marketplace orders for accounts 5622, 6395, and 17220

Marketplace Connector Imports

Lengow marketplace imports follow the same final persistence model as Magento imports: the connector-specific command normalizes the remote order and calls SaleService::addOrder(). The main V3 entry point is src/ErpBundle/Command/Lengow/V3/LengowSalesCommand.php, and the import logic lives in src/ErpBundle/Services/Lengow/V3/LengowService.php.

Key differences from Magento:

  • duplicate detection uses Lengow marketplace_order_id plus source = Lengow;
  • V3 imports are account-scoped with --marketplace=5622, --marketplace=6395, or --marketplace=17220;
  • imported sales keep lengow_marketplace, lengow_account_id, and full orderinfo.lengow_order_info for feedback and diagnosis;
  • product resolution is connector-specific, including the Mosaikasa 17220 caveat where the merchant product id must match mz_product.ean_bis;
  • failed product/order normalization is held as status = holded and monitored through Lengow issue views and alerts.

See Lengow Integration for the full flow, menu views, status feedback, and retired V2 feed notes.