Skip to main content

Lengow Integration

Lengow is the marketplace connector used by Logidav for several marketplace channels. The active V3 flow imports marketplace orders into Sale / SaleProduct, stores the Lengow account and marketplace on the sale, and sends shipment or action feedback back to Lengow when Logidav changes the order.

Accounts

Account / feedLabelStatusNotes
5622Lengow MenzzoActive V3Configured under lengow in app/config/parameters.yml.dist; imported with menzzo:lengow:sales --marketplace=5622.
6395Lengow CotecosyActive V3Configured under lengow; imported with menzzo:lengow:sales --marketplace=6395.
17220MosaikasaActive V3New V3 account. It should reuse the V3 command, menu views, and lengow parameter structure. Product resolution has a special mz_product.ean_bis path.
113959Lengow Menzzo AuchanRetired V2Old V2 feed. Do not restore /erp/lengow/v2/all/113959 or the menzzo:lengow:v2:sales --feedId=113959 cron unless the retirement is intentionally reversed.

The V3 service is registered as mz.lengow.shopping in src/ErpBundle/Resources/config/services.yml and implemented by src/ErpBundle/Services/Lengow/V3/LengowService.php. The V2 service is mz.erp.lengow.v2, implemented by src/ErpBundle/Services/Lengow/V2/LengowService.php, and should be treated as historical for feed 113959.

Command Flow

src/ErpBundle/Command/Lengow/V3/LengowSalesCommand.php is the entry point. It first checks mz.sale->canImportSales(), requires --marketplace, selects the account with LengowService::setLengowAccount(), and defaults --importFrom to 10 days ago for V3 imports.

The token refresh path is the same command with --refreshToken=1. It calls LengowService::getToken() and stores the returned token in Config under MZ_LENGOW_REFRESH_TOKEN_<account> through LengowSalesCommand::refreshToken(). The request helper in LengowService::execute() still obtains a token through getToken() before calling api_url, so token refresh is both an operational cron path and the place to verify account credentials.

Order Import Details

LengowService::getOrders() calls orders/?account_id=<account>&lengow_status=waiting_shipment&imported_from=<date> and follows next pagination. Each order is skipped when a local sale already exists with saleId = marketplace_order_id and source = Lengow.

For each non-canceled cart line, the service builds the line item payload expected by SaleService::addOrder():

Lengow dataLogidav target
marketplace_order_idorder_id, increment_id, duplicate key
lengow_statusSale status, mapped by the service status table
marketplaceSale::lengowMarketplace
selected accountSale::lengowAccountId
billing/delivery blocksSale billing and shipping address fields
packages[0].cartSaleProduct rows
full Lengow orderorderinfo.lengow_order_info

After parent::addOrder(), LengowService::addOrder() writes the Lengow marketplace/account fields and recalculates the real shipping method with setRealShippingMethodForLengow().

Product Resolution

The normal V3 product resolution logic lives in src/ErpBundle/Services/Lengow/V3/LengowService.php inside the cart loop:

Lengow merchant product fieldResolution path
field = skuMatch mz_product_info.mpn for storeId = 3, then fall back to mz_product.cotecosySku.
field = id with numeric idMatch the Magento feed id through mz.product->getProductByFeedId().
field = id with string idTry mz_product_info.mpn, then mz_product.cotecosySku, then mz_product.sku.
Empty merchant id with marketplace product idTry mz_product_info.mpn, then mz_product.cotecosySku.
Account 17220Mosaikasa-specific caveat: match the Lengow merchant product id against mz_product.ean_bis instead of the normal EAN/feed-id path. Keep this branch account-scoped so Menzzo and Cotecosy imports keep their existing resolution behavior.

If no product can be found, the import catches the exception, sends a MARKETPLACE notification, logs the throwable through mz.log->notifyDevelopmentTeam(), and marks the order status as holded so it remains visible in operational views.

Status and Feedback to Lengow

Outbound feedback is centralized in LengowService::setActionToOrder(). It rebuilds the Lengow account from orderinfo.lengow_order_info, logs the outgoing body under the Lengow log directory, and posts to orders/actions/ with:

  • marketplace_order_id
  • account_id
  • marketplace
  • action_type
  • optional action-specific fields such as tracking_number, tracking_url, and carrier

LengowService::onSaleProductsShipped() listens to SaleProductsShippedEvent for sales whose source is Lengow. It collects tracking data, normalizes carrier-specific edge cases, and sends action_type = ship through setActionToOrder().

src/ErpBundle/Command/Lengow/V3/UpdateLengowStatusCommand.php checks Lengow actions updated yesterday with getActionsUpdatedOnDate(), reloads each order, maps Lengow statuses (shipped / closed to complete, waiting_shipment to processing, canceled to canceled), and stores any mismatch in Sale::lengowErrorMessage.

Error and Holded Path

There are two operational error buckets:

BucketHow it is setWhere to look
status = holdedImport failed while resolving or creating an order line.src/ErpBundle/Services/Lengow/V3/LengowService.php, lengow_sales_issues view, daily issue email.
lengowErrorMessage IS NOT NULLLogidav status does not match the mapped Lengow status after action status refresh.src/ErpBundle/Command/Lengow/V3/UpdateLengowStatusCommand.php, src/ErpBundle/Command/Lengow/V3/LengowOrderIssueAlertCommand.php.

src/ErpBundle/Command/Lengow/V3/LengowOrderIssueAlertCommand.php sends the daily anomaly email for source = Lengow sales in holded status and sales with a non-empty lengowErrorMessage.

Back-office Views

The V3 menu is built in src/AppBundle/Menu/Builder.php under the Lengow store menu. Each account should expose the same V3 views:

ViewRouteMeaning
Commandes expédiées (à facturer)lengow_pending_invoice_salesShipped sales waiting for invoicing.
Commandes facturéeslengow_shipped_salesInvoiced / completed sales.
Commandes à expédierlengow_pending_salesImported sales waiting for shipment work.
Commandes avec statut différentlengow_sales_issuesStatus mismatches detected by the Lengow status update job.
Toutes les commandeslengow_all_salesFull account-scoped sales list.

Mosaikasa account 17220 should be nested under Lengow and reuse the V3 submenus like account 5622. Retired V2 feed 113959 should not remain reachable from the menu.

Operational Commands

Run these locally or through cron only when you intend to contact Lengow. They call external APIs.

# Refresh credentials for one V3 account.
php bin/console menzzo:lengow:sales --refreshToken=1 --marketplace=5622
php bin/console menzzo:lengow:sales --refreshToken=1 --marketplace=6395
php bin/console menzzo:lengow:sales --refreshToken=1 --marketplace=17220

# Import waiting-shipment orders.
php bin/console menzzo:lengow:sales --marketplace=5622
php bin/console menzzo:lengow:sales --marketplace=6395
php bin/console menzzo:lengow:sales --marketplace=17220

# Replay from a specific date.
php bin/console menzzo:lengow:sales --marketplace=17220 --importFrom=2026-05-01

# Refresh status mismatch markers and send issue summary emails.
php bin/console menzzo:lengow:update-status
php bin/console menzzo:lengow:send-order-issues-alert

:::warning External systems The commands above call Lengow and can mutate local sales or send outbound action feedback. Do not run them against production or external services without explicit operational approval. :::

Retired V2 Feed

The legacy V2 importer is src/ErpBundle/Command/Lengow/V2/LengowSalesCommand.php and the V2 service is src/ErpBundle/Services/Lengow/V2/LengowService.php. Feed 113959 used the old XML endpoint and stored sales with source = LengowV2.

For current work, treat feed 113959 as retired:

  • remove or keep removed the menzzo:lengow:v2:sales --feedId=113959 cron entry;
  • remove or keep removed /erp/lengow/v2/all/113959 from the menu;
  • keep historical documentation only for incident investigation on old LengowV2 sales.
AreaPath
V3 commandsrc/ErpBundle/Command/Lengow/V3/LengowSalesCommand.php
V3 servicesrc/ErpBundle/Services/Lengow/V3/LengowService.php
V3 status updatesrc/ErpBundle/Command/Lengow/V3/UpdateLengowStatusCommand.php
V3 issue emailsrc/ErpBundle/Command/Lengow/V3/LengowOrderIssueAlertCommand.php
Back-office menusrc/AppBundle/Menu/Builder.php
Back-office routessrc/ErpBundle/Controller/SaleController.php
Account parametersapp/config/parameters.yml.dist
Retired V2 importersrc/ErpBundle/Command/Lengow/V2/LengowSalesCommand.php