Skip to content

Orders and Fulfilment ​

This page starts at the active Commandes menu in Builder.php and follows its distinct operator workflows through the Symfony annotations, Twig screens, browser actions, services/repositories, and local state. The evidence is the reviewed immutable axelites/logidav source snapshot at 88d9180215a5d489407498fe4905fdd38efd756d. It describes source behavior only; it does not establish the deployed version, configured permissions, carrier credentials, or successful provider/runtime behavior.

Menu path / active leafScreen route and source viewWhat the operator does next
Commandes → Impression des commandes → Chaulnes / Saint-Quentinsale_print_index(warehouseId 2 or 3) → SalePrintController::printSalesAction() → Sale/Print/printSales.html.twigSelect a server-built print list (all, urgent, multi-product, single SKU, label, or emplacement grouping). These are GET JSON lists for printing/handling; the controller methods do not mutate order state. Thiais/warehouse 1 is commented out in this menu snapshot.
Commandes → Expédition → En stock / Hors stocksale_list_processing_not_printed / sale_list_processing_not_printed_nostock → SaleController → processingNotPrinted.html.twig / processingNotPrintedNoStock.html.twigFilter and batch orders or lines. In-stock processing feeds print/dispatch actions; out-of-stock workflow records availability or transfers a selected line to the stock-zero queue.
Commandes → Expédition → Modes de livraison / Expéditions envoyéessale_list_sales_with_shipping_methods / sale_list_send_expedition → SaleController → listSalesWithShippingMethods.html.twig / sendExpedition.html.twigInspect assigned methods or already-sent shipments, filter/paginate/export; tracking details are read from sale-product state.
Commandes → Expédition → carrier labelsChronopost (chronopost_index), BRT Italie (brt_index), Geodis / Calberson (calberson_index, warehouses 1/2/3), GLS (gls_index), VIR (vir_index, étage and bas d’immeuble), Tamdis (tamdis_index), IDF labels (idf_expedition_index), SDEN (sden_index)Use each carrier screen’s table and print/validate/reset actions below. A generated ticket is local label/tracking state; it is not proof of physical delivery.
Commandes → Expédition → Suivi des expéditions / Import des fichiers d’expéditionssale_shipping_track_index / sales_import_files_indexTracking screen reads shipment tracking state. Import screen starts a CSV-specific console process and exposes token output; see Shipment Generation.
Commandes → Retrait → Tableau des retraitssale_rdv_list → SaleRdvController::listAction() → SaleRdv/list.html.twigUpdate appointment, prepare/print a withdrawal order or parcel labels, send selected lines to stock, or create a withdrawal shipment.
Commandes → Retrait → Livraison retraitsale_asir_group_livraison → AsirGroupMenzzoShippingLabelController::AsirGroupeSaleLivraisonAction() → AsirGroupBundle:Sale:asirGroupMenzzoShippingLabel.html.twigScan parcel QR codes, handle carrier labels and exceptions, group parcels into pallets/trucks, and close out a truck.
Commandes → Trusk → Expédition / Commandes HSsale_trusk_index / sale_trusk_hs_index → TruskController → Trusk/index.html.twig / Trusk/outOfStock.html.twigSchedule eligible lines, generate preparation/withdrawal paperwork and labels, cancel or validate selections; the HS screen is a separate queue using the Trusk search path.
Commandes → VIR → Commandes HSsale_vir_hs_index → VirController → Vir/outOfStock.html.twigReview the VIR out-of-stock queue and perform the validation workflow. The menu does not expose the older in-stock/asir VIR screens commented out in Builder.php.
Commandes → IDF / Monté à l’étage → Expéditionsale_idf_list_expedition_to_validate → IdfController → Idf/expeditionToValidate.html.twigReview unvalidated IDF lines and use print/validate; IDF labels menu entry is a different screen (idf_expedition_index).
Commandes → Recherche / Toutes les commandes → Toutes / Alfy / Disponibilité modifiéesale_list_search; all_sale_list with the menu’s store/type arguments; sale_product_updatet_dispo_indexSearch across orders, inspect all orders or the Alfy subset, or review sale lines whose availability changed.
Commandes → Stock 0 → Scan / Hors stockstock_0_scan; sale_list_processing_not_printed_nostock(storeId=null, stock0=1)Scan a stock-zero item or review the stock-zero order-line queue. This shares the out-of-stock template family but passes a distinct stock0 flag and uses separate print/remove-from-queue actions.

The family table names every active route family in these menu sections. Similar route names with a V2 suffix that are commented out are not treated as active menu entry points.

Order queues, search, and print-list selection ​

The processing pages are server-rendered Twig shells whose JavaScript calls paginated controller actions. sale_list_processing_not_printed checks the per-menu permission for its store and returns the processing queue. Its paginate endpoint (sale_list_paginate_processing_not_printed) passes store/source, DataTables search/order, and export options to mz.sale’s searchProcessingNotPrinted repository path. The no-stock route branches on stock0: ordinary unavailable items use mz.saleproduct::searchProcessingNotPrintedNoStock; stock-zero view passes storeId=null, stock0=1. The template’s controls call availability/date, label/scan, stock-zero transfer, and bulk actions. Access checks are visible on the initial screen action; do not infer that every AJAX action independently repeats the same check.

Menu actionMethod and URLHandler → view/outputImportant inputs / next state
Print-list screenGET /sale-print/print-sales/{warehouseId}SalePrintController::printSalesAction() → Sale/Print/printSales.html.twigwarehouseId is 2 (Chaulnes) or 3 (Saint-Quentin) from this menu. Screen checks sale_print_index/warehouse authorization.
Print-list dataGET /sale-print/get-all-sales-to-print, /get-urgent-sales-to-print, /get-sales-with-more-than-one-product, /get-sales-with-one-product-grouped-by-sku, /get-sales-with-one-product-grouped-by-label, /get-sales-with-one-product-grouped-by-emplacement-to-printMatching SalePrintController actions → JSON resultsBrowser sends carrier/warehouse selection; repository selection defines the list grouping. The GET data actions themselves do not set printed/shipped state.
Processing queueGET /sale/processing-not-printed/{storeId} then GET / POST /sale/paginate-processing-not-printed/{storeId}SaleController::processingNotPrintedAction() → Sale/processingNotPrinted.html.twig; paginate returns JSON/exportStore, source, filter/order columns. Controller applies menu access on the screen and a store-sensitive branch.
Out-of-stock / stock-zero queueGET /sale/processing-not-printed-nostock/{storeId}/{stock0} then GET / POST /sale/paginate-processing-not-printed-nostock/{storeId}processingNotPrintedNoStockAction() → Sale/processingNotPrintedNoStock.html.twig; paginate JSON/exportStore, stock0, source and table filters. The stock-zero menu passes stock0=1; the regular “Hors stock” menu uses its default.
Broad order searchGET /sale/search then GET / POST /sale/sale-search-paginateSaleController::searchAction() → Sale/search.html.twig; JSON/exportSearch only runs when table-column search values are present. The paginate action applies SalePolicy::canViewSale and returns selected order detail/status/method fields.
All orders / AlfyGET /sale/all-sale-list/{storeId}/{type} then GET / POST /sale/paginate-all-sale-list/{storeId}allSaleListAction() → Sale/allSaleList.html.twig; JSON/exportMenu passes store/type/source filters; Alfy passes type=alfy. Store/type-specific access branch and policy are source-visible.
Shipping methods / sentGET /sale/list-sales-with-shipping-methods → GET / POST /sale/paginate-list-sales-with-shipping-methods; GET /sale/sale-send-expedition → GET / POST /sale/paginate-sale-send-expeditionSaleController renders the two dedicated Twig tables and delegates searches to sale repository methodsFilter/order/export inputs; sent list formats existing tracking fields rather than confirming delivery.
Availability changedGET /changed-dispo/ (sale_product_updatet_dispo_index) → GET /changed-dispo/sale-product-update-dispo-index-paginate (sale_product_update_dispo_index_paginate); POST /changed-dispo/remove-sale-product-update-dispo (remove_sale_product_update_dispo)SaleProductUpdateDispoController renders the page, then lists/removes update rowsRoute family is for changed sale-line availability; source does not make this a general product availability audit.

The Sales Import and Stock Updates workflow pages explain the upstream sale/stock mutations that feed these queues. The queue screens alone do not establish an import schedule or a universal queue retry policy.

Carrier label screens and generation actions ​

Chronopost, BRT, Geodis, GLS, VIR, Tamdis, SDEN, and IDF share the operator pattern list → filter/select rows → print tickets → optionally validate or reset. Each list action checks its menu permission and renders a carrier-specific Twig page; each paginate route reads a carrier-specific sale-product/repository search. Print requests carry selected order IDs and sale-product/shipment IDs, plus a token for progress in the legacy Block channel. The named console commands are started through the legacy console/process layer; this repository does not establish that an external carrier accepted a request at runtime.

Menu familyList and table routesPrint / follow-up endpointsInputs and source-backed outcome
Chronopost (chronopost_index)GET /chronopost/; GET / POST /chronopost/paginatePOST /chronopost/print → menzzo:chronopost:print-ticketstoken, orderIds, shipIds; command uses SaleProductService, ChronopostService, and tracking synchronization.
BRT (brt_index)GET /brt/; /brt/paginatePOST /brt/print → menzzo:brt:print-tickets; POST /brt/reset-tickettoken, selected IDs, orderPalettesNumber, orderColisNumber; BRT service creates line shipments; reset clears selected ticket/tracking fields and logs the sale.
Geodis / Calberson (calberson_index)GET /geodis/{warehouse}; /geodis/paginatePOST /geodis/print → menzzo:calberson:print-tickets; /geodis/validate-tickets; /geodis/reset-ticketWarehouse 1/2/3 plus selected IDs, token, pallet/parcel counts. The command calls Geodis service handoff, persists label/slip files and pre-shipment records; validate uses a separate command.
GLS (gls_index)GET /gls/; /gls/paginatePOST /gls/print → menzzo:gls:print-ticketsToken and selected order/shipment IDs. Command uses GlsService/tracking services and persists local PDF/tracking/status fields.
VIR (vir_index, floor / building-foot)GET /vir/list/{realShippingMethod} with menu values VIR and VIR_BAS_IMMEUBLE; /vir/paginatePOST /vir/print → menzzo:vir:print-tickets; POST /vir/reset-ticketSelected IDs and nbColis; command uses VirService/ShipmentService, writes local ticket/tracking state and invokes the source’s dispatch path.
Tamdis (tamdis_index)GET /tamdis/; /tamdis/paginatePOST /tamdis/print → menzzo:tamdis:print-tickets; POST /tamdis/reset-ticketSelected IDs, token, parcel count. Command calls TamdisService::sendExpedition; reset removes ticket state and allocates replacement tracking.
SDEN (sden_index)GET /sden/; /sden/paginatePOST /sden/print → menzzo:sden:print-tickets; /sden/validate-tickets; /sden/reset-ticketSelected IDs, token, pallet/parcel counts. SDEN has explicit separate print, validation, and reset actions.
IDF labels (idf_expedition_index)GET /idf/idf-expedition; /idf/idf-expedition-paginatePOST /idf/print-tickets → menzzo:idf:print-ticketsSelected order/shipment IDs and nbColis; label print creates local ticket files/tracking. This is separate from the “IDF → Expédition” validation queue below.

SaleProduct, SaleProductShippingLabel, and sale logs carry the local line-level printed/shipped/carrier/tracking evidence. These fields describe Logidav state, not carrier proof-of-delivery. Where a print controller has no method restriction annotation, treat the route’s accepted verb as unspecified in source instead of inferring it from the button.

CSV shipment import and tracking review ​

The menu import page is GET /sale/sales-import-files-index → SaleController::salesImportFilesExpeditionAction() → Sale/salesImportFiles.html.twig (permission key commandes_sales_import_files_index). Its browser form posts folder/WSL settings to POST /sale/sales-create-shipment-by-cmd. The handler scans data/csv_import/<folder>/processing, chooses menzzo:sale:expedition-csv-chronopost, ...-gls, or generic menzzo:sale:expedition-csv based on filename, starts the legacy background process, and returns a token and filename. POST /sale/sales-import-get-tokens-output reads progress; /sale/sales-send-to-complete-folder moves a processed file to complete. See Shipment Generation for CSV parsing and Magento/local shipment changes. The source establishes neither installed schedule nor successful remote shipment acceptance.

The separate Suivi des expéditions page uses sale_shipping_track_index and its paginate route to inspect stored tracking histories. It is not the CSV importer and does not prove a live carrier status feed unless the corresponding synchronizer path ran; see Shipment Generation.

Withdrawal appointments and parcel handling ​

GET /rdv/list computes the next Trusk working/available dates through TruskService and SaleRdvRepository, then renders the withdrawal dashboard with shipping methods and the available-date list. sale_rdv_list_paginate builds rows from SaleRdv records and the unshipped SaleProduct lines named by each RDV’s stored sale-item IDs. The table shows SKU, quantity, availability, appointment, customer and order fields, and provides row selection, message history, shipping-label print, preparation/withdrawal PDFs, date-edit controls, and shipment creation.

Button or operator actionMethod and URLHandler/state transition
Update appointmentPOST /rdv/update-rdv-date (sale_rdv_update_date)Form rdv_id, rdv_date, optional rdv_time, is_trusk, and CSRF token. SaleRdvController::updateRdvDateAction() validates the date/token and calls SaleRdvService::updateAndNotify; update failures return an error result/log. Calendar data is read through /rdv/calendar-config/{rdvId}.
Print withdrawal orderPOST /rdv/rdv-print-withdrawal-pdforder_ids; renders Sale/deliveryPdf.html.twig to PDF and logs the print.
Print preparation recapPOST /rdv/sale-rdv-print-preparation-pdfall, date or date range; selects unshipped or ranged RDVs and renders the preparation document.
Print parcel labelsPOST /rdv/rdv-shipping-labelorder_ids, optional sp_ids, and per-sale-product colisNumber. Generates local PDFs, assigns/reuses tracking IDs, stores per-parcel SaleProductShippingLabel rows and ticket file paths, and logs the printed SKUs.
Create one withdrawal shipmentPOST /rdv/sale-rdv-retrait-expeid_order, selected saleProductIds, optional send_mail and Lengow context. Requires the order to be processing and at least one selected line. Calls Magento shipment creation; on success marks selected lines shipped with carrier RETRAIT, writes delivered-history/log state and advances RDV/order completion state. A false/unknown shipment response throws instead of claiming success.
Create a batch shipmentPOST /rdv/sale-rdv-retrait-expe-masssaleRdvs, selected items, token; launches legacy menzzo:sale:expedition and returns/polls Block progress.
Put selected lines back in stockPOST /rdv/sale-rdv-send-to-stocksp_ids or session orders_rdv_sp_ids; calls setSaleProductAsInStock. Empty selection returns status=KO; caught errors also return KO.
Pickup → delivery offer / free deliveryPOST /rdv/api/pickup/send-offer-rdv/{rdvId} / /rdv/api/pickup/send-free-delivery-rdv/{rdvId}Both delegate to PickupToDeliveryService; menu source shows these actions from the same pickup screen, but provider outcome is not established here.

The handoff is local RDV/order state plus a Magento shipment request, not merely printing a label. SaleRdv.isShipped and SaleProduct shipment/tracking fields are updated after a successful path. This differs from the standalone label endpoint, which stores local labels before any confirmed shipment.

Asir Group “Livraison retrait”: scan, pallet, truck ​

The active menu route opens /erp/asirgroup/asir-sale-livraison with the AsirGroupMenzzoShippingLabelController screen. The controller’s AJAX actions divide into these route families:

UI stageEndpoints and principal inputsState touched / failure boundary
Scan and classify parcel/erp/asirgroup/qrcode-asir (json QR payload; optional pallet/parcel flags), /find-parcel-or-pallet?code=…, /is-parcel-conform?sale_product_id=…&parcel_id=…, /scan-retrait-parcel (qr_code, expected sale-product ID)Resolve SaleProduct and parcel labels, detect mismatches/non-conformance, attach scan state, and log the sale. Invalid/missing QR/product/label produces an error response; read the controller response before treating the scan as accepted.
Print or reprint carrier/expedition labels/print-asir-carrier-tickets (token, qrc); /print-expedition-ticket (token, scannedQRCodes); /print-asir-cancelation-label (saleProductId); /reprintLabel (saleProductId)Carrier-label action starts menzzo:asir-group:sale:expedition:generate-carier-labels; expedition-ticket action computes package weight/volume, generates a pallet ID/PDF and associates labels; cancellation/reprint uses the selected line’s ticket state.
Record exceptions/set-is-non-complaint, /set-as-badly-packaged-parcel accept scanned json; /non-conform and /non-conform-paginate review exception rows; /non-conform-parcel-img loads or stores parcel image detailsUpdates parcel/SaleProduct shipping-label records and SaleLog; UI distinguishes non-conformity from “badly packaged.” These flags are operational annotations, not proof of carrier claim resolution.
Group into pallet/open-pallet, /list-opened-pallets, /list-automatically-opened-pallets, /add-parcel-to-pallet (sale_product_id, parcel_id, pallet_id), /close-pallet, /recap-pallet, /print-pallet, /reopen-palletPalletService/PalletSaleProductService associate labels/parcels, prevent/validate selected transitions, and generate pallet print data.
Load and depart truck/open-truck (carrier, selected warehouse), /list-opened-trucks, /add-parcel-or-pallet-to-truck (data, truck_id), /get-products-in-truck-id, /get-unscanned-products-in-truck-id, /set-truck-as-departed (truckId)TruckService and pallet/parcel services accumulate truck contents; departure action updates shipment state and SaleLog and checks scanned/unscanned contents. A truck list being “open” is not departure confirmation.

These action annotations often omit @Method, so source does not constrain all of them to GET or POST even when the Twig/JavaScript sends a particular verb. The core persisted records are parcel-level SaleProductShippingLabel, SaleProduct shipment/ticket state, pallet/truck relations, and sale logs. The separate “AsirGroup carrier ticket” command is an external handoff path; its success must be checked through the returned token/log and provider evidence before calling it complete.

Trusk, VIR, and IDF specialist queues ​

Trusk opens /trusk/ and paginates with /trusk/paginate-trusk. The controller uses SaleRepository::searchTrusk; rows include line/product availability and derived package counts. Main UI actions include /trusk/sale-trusk-update-rdv (POST: sale/product IDs, date, floor, elevator, time range and Trusk flag), /trusk/trusk-print-withdrawal-pdf, /trusk/sale-trusk-print-preparation-pdf, /trusk/shipping-label, /trusk/cancel, and /trusk/sale-trusk-mark-as-validated. Scheduling updates local appointment/line state and sale logs; cancellation calls TruskService::cancel; label generation creates local tracking/parcel labels and PDFs. The second menu leaf, /trusk/out-of-stock, uses a separate Twig table and paginate-trusk-hs; it shares the search routine with filters, and is the explicit HS queue. The V2 Trusk page in comments is not this menu entry.

VIR HS opens /vir/out-of-stock and paginates at /vir/paginate-vir-hs. Its selected-line validation route /vir/validate-vir-sales updates validated quantity/tracking fields and produces a CSV through VirService::createFileVir. Do not confuse that with the two carrier-label screens /vir/list/VIR and /vir/list/VIR_BAS_IMMEUBLE, whose /vir/print action starts the label-generation path.

IDF validation opens /idf/list-idf-expeditions-to-validate, paginates at /idf/paginate-idf-expedition-to-validate, then posts selected IDs to /idf/print-tickets and /idf/validate-idf-sales. The validate action updates the selected SaleProduct state (shippedAt, printed/shipped flags, carrier IDF), logs the sale and marks it sent. The separate IDF labels list route /idf/idf-expedition is in the generic carrier table, not the validation queue. Both paths belong to the same controller but have different templates and persistence effects.

Evidence gaps and access limits ​

  • The source shows menu/controller permission checks on screen entry points. Effective user roles, runtime menu visibility, action-level authorization on every AJAX endpoint, and the production deployment revision were not inspected.
  • Carrier command invocation, generated local files/state, and selected service calls were traced statically. Provider acceptance, shipment delivery, scheduled execution, and currently valid credentials are not established.
  • Some route annotations omit an HTTP-method constraint; the corresponding browser call is in JavaScript, but the server-side accepted method remains broader in source.
  • The out-of-stock and withdrawal action families can change order, product, parcel, and tracking state. Follow the linked Stock Updates, Sales Import, and Shipment Generation pages for their separate upstream/import contracts; those pages do not replace the UI action paths documented here.

Source entry points ​

Internal developer documentation for Menzzo systems.