HOCO B2B
DesignScreen specificationsBack-office

Orders and delivery

Page specs BO-38 to BO-43 and BO-69: orders list, order detail, order on behalf, the orders-to-confirm queue, delivery board, carriers, and returns and after-sales claims.

These pages run the order cycle from submission to delivery, return and refund (cahier §4.4).

No order is ever confirmed automatically (ORD-14). Every order lands in BO-41, whatever its channel: reseller app, reseller web, assisted by a delegate, or entered by phone in the back-office. It arrives as SUBMITTED, or PENDING when on hold, and waits there until a person with orders.validate confirms it. Confirmation reserves the stock. Shipping deducts it. A cancellation or a return reception puts it back automatically (STK-03). Each status change reaches the reseller live and as a notification (ORD-15).

The lifecycle and its transition table are in OrderStatus. The UI never derives transitions itself. It renders the allowedActions that admin.orders.get returns.

IDScreenSectionTemplateReleaseDesignBuild
BO-38Orders listOrdersbespokeV1Day 18DSH-06
BO-39Order detail (controls, actions, history)OrdersbespokeV1Day 18DSH-06
BO-40New order on behalf of a resellerOrderstemplateV1Day 18DSH-06
BO-41Orders to confirm (new, on hold, assisted)OrderstemplateV1Day 18DSH-06
BO-42Delivery boardOrdersbespokeV1Day 18DSH-06
BO-43CarriersOrderstemplateV1Day 18DSH-06
BO-69Returns & after-sales claimsOrderstemplateV1Day 18DSH-13

BO-38 — Orders list

FieldValue
TemplateBespoke (List skeleton)
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-06
Route/orders
RequirementsORD-04 · ORD-05 · ORD-03 · ORD-09 · ANA-05
Permissions requiredorders.view (page) · orders.update (bulk « Passer en préparation ») · delivery.view (picking lists) · orders.export (export) · orders.create (« Nouvelle commande »)

Purpose. Find and follow every order at every stage, with the same filters the cahier lists (channel, delegate, reseller, wilaya, dates). It meets the acceptance « Une commande validée reçoit un numéro et apparaît dans le back-office » (cahier §12, §5.3). The confirmation work itself happens in BO-41.

Who uses it. Commercial admin, delivery manager, finance manager, stock manager, direction.

Entry points.

  • Commandes › Commandes.
  • Global search.
  • Dashboard cards and status segments (BO-04).
  • The Commandes tab of the reseller 360° (BO-11).
  • order.created toasts.

Layout

  • Header: « Commandes » with the count. Actions: « Nouvelle commande » (BO-40), « Exporter ». A link card « 12 commandes à confirmer » leads to BO-41; it is shown with orders.validate, in red when the oldest waits more than 2 h.
  • Status tabs (view), each with a counter:
    • « Toutes ».
    • « À confirmer » (SUBMITTED, PENDING; read-only here, rows open in BO-41).
    • « Validées », « En préparation », « Prêtes », « Expédiées », « Livrées ».
    • « Annulées et refusées », « Retournées ».
    • « Brouillons »: back-office drafts. Delegate drafts are read-only and labelled « Commande assistée en préparation ».
ColumnSource fieldSortableDefault visible
N° commandenumber (CMD-2026-000158, mono)YesYes
DatesubmittedAt (or createdAt for drafts)YesYes
Revendeurreseller.storeName + REV numberYesYes
Type de clientreseller.customerType at checkout (CustomerType pill)YesYes
Wilaya / communeDelivery address snapshotYesYes
Canalchannel (OrderChannel icon + label)YesYes
DéléguéAttributed delegate (source delegate for assisted orders)YesYes
ArticleslinesCount · totalQuantityNoYes
Montant TTCtotals.totalTtcYesYes
PaiementpaymentMethod (PaymentMethod)YesYes
Statutstatus (OrderStatus pill)YesYes
Confirmée parvalidatedBy.displayName + validatedAtYesNo
Délai de confirmationvalidatedAt − submittedAtYesNo
ContrôlesSummary icon: OK / warnings / blockingNoNo
1re commandeisFirstOrder badge (ORD-09)YesNo
Livraisondelivery.status (DeliveryStatus) + carrierYesNo
Factureinvoice.number + InvoiceStatus (needs finance.view)NoNo
Mis à jourupdatedAtYesNo
FilterControlURL parameter
Search (number, store name, phone)Textq
StatutMulti-select (preset by the tab)status
CanalMulti-select of OrderChannelchannel
DéléguéSelectdelegate
RevendeurSearch selectreseller
Type de clientMulti-select of CustomerTypecustomerType
Wilaya, CommuneSelectswilaya, commune
Mode de paiementMulti-selectpaymentMethod
Date de commandeDate rangefrom, to
Date de validationDate rangevalidatedFrom, validatedTo
Première commandeTogglefirstOrder=true
ContrôlesSelect: bloquant / avertissement / OKcontrols
Montant TTCMin–maxamountMin, amountMax
  • Default sort: submittedAt descending.
  • Bulk actions:
  • Row actions: « Ouvrir », « Copier le numéro », « Ouvrir le revendeur », « Bon de préparation », « Annuler » (when allowed).
  • Export: XLSX, CSV or PDF of the filters and visible columns, through admin.exports.create (type: "orders").

Data. admin.orders.list (page, pageSize, sort, order, filters above), admin.orders.transition, admin.deliveries.pickingList, admin.exports.create.

Actions. « Passer en préparation » on a selection asks « Passer 8 commandes en préparation ? Les bons de préparation pourront être imprimés. ». It is not optimistic, audits STATUS_CHANGE per order and notifies each reseller (push, in-app and live).

Rules.

  • Rows in SUBMITTED or PENDING show their age (« il y a 3 h ») and open in BO-41 for confirmation.
  • Bulk confirmation lives in BO-41 only, so that every confirmation is a deliberate act (ORD-14).
  • Amounts are TTC, as ordered. Revenue KPIs elsewhere are HT.
  • Drafts never count in totals or KPIs.

Real-time.

  • order.created shows the banner « 2 nouvelles commandes — Afficher » on « Toutes » and « À confirmer ». Rows are not inserted under the cursor.
  • order.status_changed updates the status pill of visible rows and the tab counters in place.

States.

  • Empty: « Aucune commande », with « Nouvelle commande ».
  • Filter with no result: reset link.
  • Picking lists: the bulk action is disabled with a tooltip when the selection contains orders not yet VALIDATED.

Acceptance criteria.

  • An order submitted from the reseller app appears within 5 s with its number, channel Application revendeur and status Envoyée (cahier §5.3 acceptance).
  • The tab counters equal the result counts of the matching status filters.
  • channel=DELEGATE_ASSISTED&firstOrder=true lists exactly the first orders prepared by delegates.
  • The « Passer en préparation » bulk action is refused, per order, for any order that is not VALIDATED, and the report names them.

BO-39 — Order detail (controls, actions, history)

FieldValue
TemplateBespoke (Detail skeleton)
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-06
Route/orders/[orderId] (?tab=)
RequirementsORD-05 · ORD-06 · STK-08 · ORD-12 · ORD-14 · ORD-10 · ORD-08 · FIN-05
Permissions requiredorders.view (page) · orders.validate (confirm, refuse, confirm an assisted order, override) · orders.update (put on hold, modify lines, fulfilment transitions, cancel, documents) · delivery.update (carrier, tracking, proof) · delivery.view (picking list) · finance.view (credit and invoice cards)

Purpose. Process one order end to end (cahier §4.4):

  • read the automatic controls (stock, prices, promotions, credit, address);
  • confirm it, put it on hold, refuse it with a reason, or modify it in a controlled way;
  • move it through preparation and shipping;
  • produce the invoice and delivery note;
  • see its full history.

Who uses it. Commercial admin (confirmation, modification, refusal), delivery manager (fulfilment), finance manager (credit context), direction (read).

Entry points. BO-38 and BO-41 rows, global search, toasts, the delivery-board drawer (BO-42), BO-11, and notifications.

Layout

  • Header:
    • CMD-2026-000158, the OrderStatus pill, and the AssistedConfirmation pill for assisted orders.
    • Badges: channel, « 1re commande ».
    • Submitted at, waiting time while SUBMITTED / PENDING.
    • Reseller: link to BO-11, with the CustomerType pill (« Prix Demi-gros »).
    • Source delegate.
    • Total TTC and payment method.
    • Primary actions from allowedActions, for example « Confirmer la commande », « Passer en préparation », « Expédier ».
    • « Plus » menu: « Mettre en attente », « Modifier les articles », « Refuser », « Annuler », « Bon de préparation », « Régénérer les documents ».
  • Main column, the lines table:
    • Image, product and variant, SKU, quantity.
    • Prix unitaire HT at checkout, at the reseller's customer type, with a strike-through and the promotion name when discounted.
    • Line discount, line total HT.
    • Line controls: available stock vs ordered, with « Disponible : 12 » in danger when short; current price vs order price, with « Prix actuel : 250,00 DA ».
    • Footer: Sous-total HT, Remises, Frais de livraison, TVA, Total TTC (shared Totals schema).
    • Order note from the reseller, and the delegate's note for assisted orders.
  • Side rail:
    • Contrôles card (below).
    • Revendeur card: status, customer type, phone, WhatsApp, open tickets. With finance.view: credit limit, used, available, overdue invoices.
    • Livraison card: address snapshot, mode, carrier, tracking, DeliveryStatus.
    • Paiement card: method, invoice number and status, allocated payments (needs finance.view).
  • Tabs:
    • Articles (default).
    • Historique: admin.orders.history. Status changes with actor, time and reason, and line changes (OrderChange: before → after, reason), newest first.
    • Livraison: delivery record, picking list, proof photo and recipient.
    • Documents: invoice FAC-… and delivery note BL-… PDFs (signed URLs), plus « Générer » / « Régénérer ».
    • Retours et SAV: return requests (RET-…) and after-sales claims linked to the order, with status and resolution; links to BO-69 and BO-56.

Controls panel

Results come with admin.orders.get and are recomputed on every read and again at confirmation. « Relancer les contrôles » simply refetches.

ControlChecksSeverity
StockEach line's quantity ≤ available stock of the variant (warehouse rules of BO-33)Blocking when short (STK-08)
PrixEach line's unit price = the variant's current price for the reseller's customer typeWarning (PRICE_CHANGED); the order keeps its checkout price
PromotionsEach applied promotion is still valid (dates, cap, target)Warning; the discount stays as ordered
CréditWith payment method CREDIT: order total ≤ available credit; account not blockedBlocking when exceeded or blocked (FIN-05)
AdresseComplete address, commune in the reference, valid phoneBlocking when incomplete
MinimumsMinimum amount, quantities, steps and maxima (ORD-02)Warning (already enforced at checkout)
CompteReseller ACTIVE and not SUSPENDEDBlocking

Each control shows OK (success), a warning or a block (danger), with its detail: « Câble X14 : 40 commandés, 25 disponibles ».

Actions

ActionOffered when (per allowedActions)EndpointConfirmation (FR)ReasonOptimisticAuditNotifies
« Confirmer la commande »SUBMITTED, PENDING (not awaiting the reseller)admin.orders.validate« Confirmer CMD-2026-000158 ? Le stock sera réservé et le revendeur sera informé. »—NoVALIDATE + STATUS_CHANGEReseller: push, in-app and live (« Votre commande CMD-… est confirmée »)
« Confirmer malgré les alertes » (override)Same, with at least one blocking controladmin.orders.validate with override: { controls, reason }« Certains contrôles ont échoué : Stock (2 lignes), Crédit (dépassement de 18 400,00 DA). Je confirme la commande malgré ces alertes. » (checkbox)Required, at least 10 charactersNoVALIDATE + OVERRIDE (failed controls snapshot and reason)Reseller as above. Finance is notified when the credit control was overridden.
« Mettre en attente »SUBMITTEDadmin.orders.transition (PENDING). Assumption — the transition table must allow it (see contract notes).« Mettre la commande en attente ? Elle restera dans la file à confirmer. »Required (shown to the reseller: « Commande en attente : … »)NoSTATUS_CHANGEReseller (push, in-app, live)
« Confirmer pour le revendeur »Assisted order awaiting the reselleradmin.orders.confirmAssisted« Le revendeur a confirmé par téléphone ? Indiquez avec qui et quand. »Required (person and time)NoVALIDATE (CONFIRMED_BY_ADMIN)Reseller and source delegate
« Refuser »SUBMITTED, PENDINGadmin.orders.refuse« Refuser la commande CMD-2026-000158 ? Cette action est définitive et le revendeur sera informé du motif. »ORDER_REFUSAL_REASON + comment (required for « Autre »)NoREJECT + STATUS_CHANGEReseller; source delegate for assisted orders
« Modifier les articles »SUBMITTED, PENDING, VALIDATED (before PREPARING)admin.orders.modifyA diff dialog: « 2 lignes modifiées : Câble X14 40 → 25 ; Chargeur N5 supprimé. Nouveau total : 45 600,00 DA. »RequiredNoUPDATE (OrderChange per line)Reseller: push, in-app and live (« Votre commande a été modifiée »)
« Passer en préparation »VALIDATEDadmin.orders.transition (PREPARING)——NoSTATUS_CHANGEReseller
« Marquer prête »PREPARINGadmin.orders.transition (READY)——NoSTATUS_CHANGEReseller
« Expédier »READYadmin.deliveries.update (mode, carrier, tracking, driver), then admin.orders.transition (SHIPPED)The shipping dialog of BO-42—NoSTATUS_CHANGEReseller, with tracking
« Marquer livrée »SHIPPEDadmin.deliveries.proofThe proof dialog of BO-42—NoSTATUS_CHANGEReseller
« Annuler »SUBMITTED → READY (per the table)admin.orders.cancel« Annuler la commande ? Les quantités réservées seront remises en stock automatiquement. »ORDER_CANCEL_REASON + commentNoSTATUS_CHANGEReseller; source delegate
« Générer » / « Régénérer les documents »Per the billing settingadmin.orders.documentsRegenerating: « Régénérer la facture FAC-… ? L'ancienne version reste dans l'historique. »—NoUPDATE—
« Bon de préparation »VALIDATED → READYadmin.deliveries.pickingList—————

Rules

  • Explicit confirmation (ORD-14):
    • Only a person with orders.validate moves an order from SUBMITTED / PENDING to VALIDATED. No job, rule or control result does it.
    • Assisted orders first need the reseller's confirmation, or « Confirmer pour le revendeur » (ORD-08), and then the back-office confirmation. The UI offers « Confirmer pour le revendeur et confirmer la commande » as two chained calls, each audited.
  • Overrides (STK-08):
    • Confirming beyond available stock or credit requires orders.validate, the explicit checkbox and a reason.
    • The override is logged as OVERRIDE with the failed controls. The stock may then go below 0 for the variant (shown as « Dérogation » in BO-33).
    • When the credit policy is « bloquer » (BO-64), the credit override is not offered. Finance must raise the limit first (BO-46).
  • Transitions: only those in allowedActions are rendered. They follow the OrderStatus transition table and the user's permissions (ORD-04). A stale screen trying another gets 409 ORDER_TRANSITION_NOT_ALLOWED and reloads.
  • Prices are frozen at checkout at the reseller's customer type (PRC-02).
    • In a controlled modification, unchanged lines keep their price, while added lines take the variant's current price for the reseller's type and the promotions valid now.
    • No manual unit-price override in V1. Assumption — confirm.
  • History (ORD-06): every modification and status change is historised with actor, time and reason, and notified.
  • Stock: reserved at VALIDATED and deducted at SHIPPED (default settings). A cancellation releases or re-enters quantities automatically (STK-03).
  • Concurrency: the order carries version. A second person confirming the same order gets 409 VERSION_CONFLICT, with « Déjà confirmée par Karim B. à 10:42 ».
  • Sensitive data: purchase prices and margins are never shown on this page (ACL-04).

Real-time.

  • order.status_changed for this order shows a banner « Cette commande vient de passer à Validée (par Samir K.) » and refreshes.
  • When a modification form is open, the change is shown before saving and saving is blocked until reload.

States.

  • Draft (back-office): editable in BO-40, with a « Brouillon » banner.
  • Assisted order awaiting the reseller: banner « En attente de la confirmation du revendeur — expire le 12/11 à 09:12 » (72 h).
  • Refused or cancelled: read-only with the reason. A returned order links to its return.
  • Delegate draft: read-only.
  • Control service error: the panel shows « Contrôles indisponibles », and confirmation is disabled.

Acceptance criteria

  • An order whose controls all pass is still SUBMITTED until someone clicks « Confirmer la commande ». No job or rule confirms it.
  • Confirming with a blocking stock control is impossible without the override checkbox and a reason. With them, the order becomes VALIDATED and the activity log shows VALIDATE and OVERRIDE with the failed controls.
  • The reseller app shows the new status within 5 s of confirmation (live event) and receives a push notification (ORD-15).
  • Modifying a line from 40 to 25 records an OrderChange with before/after and reason, re-runs the controls and notifies the reseller.
  • Refusing requires a ORDER_REFUSAL_REASON item. The reseller sees the refusal reason in the app.
  • Cancelling a VALIDATED order releases its reserved quantities with no manual action (BO-33 shows them available again).
  • Only the actions listed in allowedActions are visible for each status.

BO-40 — New order on behalf of a reseller

FieldValue
TemplateForm (four steps)
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-06
Route/orders/new (?reseller=) · drafts open as /orders/[orderId]/edit
RequirementsORD-11 · ORD-02 · PRC-02 · ORD-14
Permissions requiredorders.create · orders.update (draft line edits through admin.orders.modify) · orders.validate (optional « Envoyer et confirmer ») · finance.view (credit details)

Purpose. Enter an order taken by phone or WhatsApp for a reseller (cahier §4.4; ORD-11), priced exactly as the reseller would see it: the price of their customer type plus promotions.

Who uses it. Commercial admin.

Entry points. « Nouvelle commande » on BO-38 and BO-11 (reseller preselected).

Layout.

  1. Revendeur:
    • Search by name, REV or phone.
    • Card with status, account status, customer type (« Les prix Demi-gros s'appliquent »), delegate, and credit available (needs finance.view).
    • A SUSPENDED reseller, or an account not yet validated, cannot be chosen (« Compte non validé »).
  2. Articles:
    • A variant search with scanner support. Each result shows the reseller's price HT and TTC, and the availability En stock / En rupture plus the available quantity (back-office only).
    • Lines show quantity steppers that respect minimum, multiple and maximum, the unit price, the applied promotion and the line total.
    • Issues come from the server (Issue list: stock, minimums).
  3. Livraison et paiement:
    • The reseller's addresses (the default is preselected). A missing address links to « Modifier la fiche revendeur » (BO-12).
    • Payment method: the methods enabled for this reseller, with credit availability.
    • Note pour le revendeur.
  4. Récapitulatif:
    • Totals, the controls panel (as BO-39), and the channel BACK_OFFICE.
    • Primary « Envoyer la commande ». Secondary « Envoyer et confirmer » (with orders.validate).

Data.

Actions.

  • « Envoyer la commande »: « Envoyer la commande de 45 600,00 DA TTC pour Boutique Nour ? Elle rejoindra les commandes à confirmer. ». The order gets its CMD- number and lands in BO-41. The reseller is notified (push, in-app: « HOCO a enregistré une commande pour vous »). Audited CREATE and STATUS_CHANGE.
  • « Envoyer et confirmer »: the same, followed by the BO-39 confirmation dialog. It is two explicit steps by the same person; the override rules apply.
  • « Enregistrer le brouillon » keeps the DRAFT in BO-38 « Brouillons ».
  • « Supprimer le brouillon » cancels the draft.

Rules.

  • Prices, promotions, stock and credit are evaluated by the server exactly as for a reseller checkout (ORD-02, PRC-02). The UI never computes a price.
  • Like every order, it waits for an explicit confirmation (ORD-14).
  • The order is attributed to the reseller's assigned delegate for reporting. The channel is BACK_OFFICE.

Real-time. None.

States.

  • Price changed while drafting: warning line « Prix mis à jour : 245,00 → 250,00 DA ».
  • Out-of-stock variant: addable with the warning « Stock insuffisant — confirmation par dérogation uniquement ».
  • Unsaved draft: guarded.

Acceptance criteria.

  • For a Super-gros reseller, every line shows the variant's Super-gros price, and the totals equal what the reseller app would show for the same cart.
  • « Envoyer la commande » produces a SUBMITTED order with channel Back-office that appears in BO-41 within 5 s.
  • A suspended reseller cannot be selected.
  • Drafts never appear in BO-41 or in KPIs.

BO-41 — Orders to confirm (new, on hold, assisted)

FieldValue
TemplateList (queue with a preview panel)
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-06
Route/orders/to-confirm (?view=, ?id= selected)
RequirementsORD-14 · ORD-08 · ORD-05 · STK-08
Permissions requiredorders.validate (page, confirm, refuse, confirm an assisted order) · orders.update (put on hold, modify, cancel)

Purpose. The single queue where every order waits for its human confirmation (§1b.2): new orders (SUBMITTED), orders on hold (PENDING) and assisted orders, oldest first, with their controls, so a person can confirm, hold or refuse each one quickly.

Who uses it. Commercial admin, many times a day. The super admin.

Entry points.

  • Commandes › Commandes à confirmer (live badge).
  • The Commandes à confirmer card of BO-04.
  • The order.created toast (« Confirmer »).
  • The BO-38 link card.

Layout.

  • Tabs (view), each with a live counter:
    • « Toutes ».
    • « Nouvelles » (SUBMITTED).
    • « En attente » (PENDING, on hold by the back-office or by a failed control).
    • « Assistées »: assisted orders, both PENDING awaiting the reseller (AWAITING_RESELLER) and those the reseller has confirmed.
    • « Dérogation requise »: at least one blocking control.
  • Left, the queue, oldest first. Each row:
ColumnSource fieldDefault visible
AttenteTime since submittedAt (amber after 1 h, red after 2 h; setting orders.confirmationAlertMinutes)Yes
N°numberYes
RevendeurStore name, wilaya, CustomerType pill, « 1re commande » badgeYes
CanalOrderChannel icon (and the source delegate for assisted orders)Yes
Montant TTCtotals.totalTtcYes
PaiementpaymentMethodYes
ContrôlesOK / warnings / blocking icons, by controlYes
StatutSUBMITTED / PENDING + AssistedConfirmation pill + hold reasonYes
ExpireFor assisted orders awaiting the reseller: countdown to 72 hYes
  • Right, the preview panel of the selected order:
    • lines with prices and stock check;
    • the controls panel of BO-39;
    • reseller summary (customer type, credit with finance.view, last orders);
    • notes.
  • Decision bar: « Confirmer », « Mettre en attente », « Refuser », « Modifier » (opens BO-39 in edit mode), « Ouvrir le détail ».
  • Filters: channel, wilaya, delegate, paymentMethod, controls, customerType.
  • Keyboard: J / K next or previous, C confirm, H hold, R refuse, O open the detail.
  • Bulk action: « Confirmer la sélection ».
    • Only rows whose controls are all OK can be selected; the other checkboxes are disabled with a tooltip.
    • One confirmation dialog for all, then one admin.orders.validate per order with its own Idempotency-Key, and a per-order report.

Data.

Actions. The confirmation, override, hold, refusal and assisted confirmation dialogs are exactly those of BO-39, with the same audit entries and notifications. Bulk confirmation asks: « Confirmer 6 commandes (184 300,00 DA TTC) ? Toutes ont passé les contrôles. Le stock sera réservé et chaque revendeur sera informé. »

Rules.

  • Nothing leaves this queue except a confirmation (→ VALIDATED), a refusal (→ REFUSED) or a cancellation (→ CANCELLED, by the reseller while SUBMITTED / PENDING, or by the back-office). Expiry is the only automatic exit: an assisted order not confirmed by the reseller within 72 h becomes EXPIRED and is cancelled. Assumption — confirm the expiry outcome in the lifecycle page.
  • Orders that need a decision (a blocking control) cannot be bulk-confirmed. They need the per-order override.
  • Hold: an order on hold stays in the queue with its reason, and its waiting time keeps counting from submission.
  • Concurrency: two users working the queue never confirm twice. The second gets 409 and the row disappears with « Déjà traitée par … ».

Real-time.

  • order.created inserts the new order at the end of the queue (oldest first) with a highlight, bumps the counters and badge, and plays no sound. Assumption — an optional sound is off by default.
  • order.status_changed removes rows that left SUBMITTED / PENDING (confirmed elsewhere, cancelled by the reseller, expired). A selected row that disappears shows « Cette commande a été traitée par … » and moves to the next.

States.

  • Empty queue: « Aucune commande à confirmer. » (success tone), with the median confirmation delay of the day.
  • Control service error: confirmation disabled for that order.
  • Stream lost: the queue polls every 30 s, and the banner shows.

Acceptance criteria.

  • Orders from the reseller app, the reseller web, a delegate (after the reseller's confirmation) and BO-40 all appear here, and none reaches VALIDATED without a confirmation action (ORD-14).
  • A new order appears within 5 s with its controls, and the badge and BO-04 card increase by 1.
  • Confirming removes the order from the queue in every open tab within 5 s.
  • Bulk confirmation is impossible for an order with a blocking control.
  • An assisted order shows its countdown. After 72 h without the reseller's confirmation, it leaves the queue as expired.
  • Pressing C on an order with all controls OK opens the confirmation dialog, and Enter confirms it.

BO-42 — Delivery board

FieldValue
TemplateBespoke
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-06
Route/delivery (?display=board or table, ?mode=screen)
RequirementsDLV-01 · DLV-02 · DLV-03 · DLV-06 · STK-03
Permissions requireddelivery.view (board, picking lists) · orders.update (status moves through admin.orders.transition) · delivery.update (mode, carrier, tracking, driver, proof, failure) · finance.create (record a cash-on-delivery collection)

Purpose. Run preparation, shipping and delivery for confirmed orders (cahier §3 « Responsable livraison : préparation, expédition, affectation transporteur et preuve de livraison »; §4.4).

Who uses it. Delivery manager, all day, on desktop and on a warehouse screen. Commercial admin reads it.

Entry points. Commandes › Livraisons (badge « à préparer »), BO-39 Livraison, and the delivery cards.

Layout

  • Toolbar:
    • Filters: Wilaya (wilaya), Transporteur (carrier), Mode (mode, DeliveryMode), Entrepôt (warehouse), Paiement à la livraison (cod=true), Confirmée entre (validatedFrom / validatedTo), search (q: CMD, BL, store).
    • « Board / Tableau » switch, « Mode écran », « Imprimer les bons de préparation ».
  • Columns (DeliveryStatus), each with a count and the total of cash to collect:
    • « À préparer » (TO_PREPARE, orders VALIDATED);
    • « En préparation » (PREPARING);
    • « Prêtes » (READY);
    • « Expédiées » (SHIPPED);
    • « Livrées » (DELIVERED, last 3 days, then hidden);
    • « Échecs » (FAILED).
  • Card:
    • CMD number, store name, commune / wilaya.
    • Lines and units (« 6 lignes · 140 pièces »).
    • Amount TTC, and « À encaisser : 45 600,00 DA » for cash on delivery.
    • Carrier or driver, tracking.
    • Age since confirmation: amber after 24 h, red after 48 h. Assumption — SLA to confirm.
    • Flags: « 1re commande », « Dérogation stock ».
    • Sorted oldest first in each column.
  • Card drawer (click, without leaving the board):
    • picking list (lines, SKU, quantity, warehouse location if any);
    • address and contact (call, WhatsApp);
    • delivery fields;
    • proof (photo, recipient);
    • status history;
    • « Ouvrir la commande » (BO-39).
  • « Mode écran » (warehouse TV, large screens): only the first three columns, large cards, auto-refresh, no drawers.

Transitions

Moves are by drag-and-drop or by the card's « Déplacer vers… » menu (the tablet and keyboard alternative). Drop zones that the transition table does not allow are greyed with a tooltip; backward moves are not allowed.

MoveEndpoint(s)Dialog and required inputsEffect
À préparer → En préparationadmin.orders.transition (PREPARING)None; option « Imprimer le bon de préparation » (admin.deliveries.pickingList)Reseller notified « Votre commande est en préparation »
En préparation → Prêteadmin.orders.transition (READY)Optional: Nombre de colis, Poids (kg) (admin.deliveries.update)—
Prête → Expédiéeadmin.deliveries.update, then admin.orders.transition (SHIPPED)« Expédier CMD-… » with Mode (OWN_FLEET → Livreur and Téléphone required; CARRIER → Transporteur and N° de suivi required; PICKUP → no shipping, go to « Livrée »)Stock deducted (default setting); the invoice and delivery note are generated per the billing setting; reseller notified with the tracking link
Expédiée → Livréeadmin.deliveries.proof« Preuve de livraison » with Nom du destinataire (required), Photo (DELIVERY_PROOF; required except for PICKUP), Livrée le (default now). For cash on delivery with finance.create: Montant encaissé, chaining admin.payments.record.Order DELIVERED; reseller notified; may trigger the reseller's ACTIVE status
Expédiée → Échecadmin.deliveries.update (status: FAILED, reason). Assumption — see contract notes.Motif: « Absent », « Refusée à la livraison », « Adresse introuvable », « Injoignable », « Autre » + commentThe order stays SHIPPED; card in « Échecs »
Échec → Expédiée (« Nouvelle tentative »)admin.deliveries.updateNew date, driver or trackingAttempt counter +1
Échec → Retour au dépôtadmin.orders.transition (RETURNED)« Retourner la commande au dépôt ? Un retour RET-… sera créé ; la réception remettra les quantités en stock. »A return is created in BO-69 (IN_TRANSIT). Assumption — the server creates it. Reception restocks automatically.

Every move audits STATUS_CHANGE (or UPDATE). None is optimistic: the card moves after the server answers, and shows a spinner meanwhile.

Bulk actions (selection on the board or table):

  • « Imprimer les bons de préparation » (combined PDF).
  • « Passer en préparation ».
  • « Expédier » with one mode and driver for OWN_FLEET. CARRIER requires a tracking number per card, so it is not available in bulk.

Data. admin.deliveries.list (columns with cards and counts), the operations above, admin.carriers.crud (GET for pickers), files.createUpload (proof photo).

Rules

  • Only confirmed orders enter the board: VALIDATED appears as « À préparer » (ORD-14).
  • Moves follow the order transition table. A stale board attempting a disallowed move gets 409 ORDER_TRANSITION_NOT_ALLOWED, and the card snaps back.
  • Delivery fees come from the order (DLV-06 policy at checkout). The board never recomputes them.
  • Proof (DLV-03): the photo is a private file, read through signed URLs.
  • Stock: deduction at SHIPPED; re-entry only at return reception in BO-69, automatically (STK-03).

Real-time. order.status_changed moves cards between columns (animated) for changes made by others, with « Mis à jour par Samir K. » on the card for 5 s. A newly confirmed order appears in « À préparer » within 5 s.

States.

  • Empty column: « Rien à préparer » (success tone).
  • Drag on touch screens: a long press starts the drag, or use the menu.
  • Failed proof upload: the dialog keeps its input and offers « Réessayer ».
  • Stream lost: polls every 30 s, with the banner.

Acceptance criteria

  • Confirming an order in BO-41 makes its card appear in « À préparer » within 5 s.
  • Moving a card to « Expédiée » with mode Société de livraison is impossible without a carrier and a tracking number. Afterwards the stock of its variants is deducted, and the reseller is notified with the tracking link.
  • « Livrée » requires the recipient name and, except for pickup, a photo. The proof shows in BO-39 Livraison.
  • A failed delivery returned to the depot creates a return in BO-69. Its reception puts the quantities back in stock without manual adjustment.
  • Every move is possible without drag-and-drop through « Déplacer vers… ».

BO-43 — Carriers

FieldValue
TemplateList (with drawer)
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-06
Route/delivery/carriers
RequirementsDLV-04 · DLV-02
Permissions requireddelivery.administer

Purpose. Maintain the list of delivery companies, API-capable or manual (cahier §11 « Livraison : connexion aux agences disposant d'une API ; sinon gestion manuelle structurée »).

Who uses it. Delivery manager, super admin.

Entry points. Commandes › Transporteurs, and « Gérer les transporteurs » in the shipping dialog.

Layout.

  • Table: Nom, Contact, Téléphone, Wilayas desservies (count), Intégration API (« Manuel » / « API — V2 »), Modèle d'URL de suivi, Actif, Expéditions (30 j).
  • Drawer:
    • Nom: required, unique.
    • Téléphone, Email.
    • Wilayas desservies: multi-select, or « Toutes ».
    • URL de suivi: a template with the placeholder {tracking}, which must contain it, e.g. https://suivi.exemple.dz/{tracking}.
    • Intégration API: disabled toggle, labelled « V2 » (DLV-05).
    • Notes.
    • Actif.

Data. admin.carriers.crud.

Actions. Create and edit (audited). There is no delete: carriers are deactivated (« Désactiver ce transporteur ? Il ne sera plus proposé à l'expédition ; les envois en cours ne changent pas. »).

Rules.

  • The shipping dialog offers only active carriers serving the order's wilaya.
  • The tracking link sent to the reseller is the URL template with the tracking number.

Real-time. None.

States. First use: « Ajoutez vos transporteurs (Yalidine, ZR Express…) ou utilisez Livreur HOCO ». Assumption — the carrier names are examples.

Acceptance criteria.

  • A deactivated carrier disappears from the shipping dialog.
  • A tracking URL template without {tracking} is refused.
  • The reseller's notification contains the resolved tracking link.

BO-69 — Returns & after-sales claims

FieldValue
TemplateList (with a return detail)
ReleaseV1
Design dayDay 18 — DES-18
Build taskDSH-13
Route/orders/returns · /orders/returns/[returnId] (?view=)
RequirementsORD-13 · SUP-04 · STK-03 · FIN-08
Permissions requiredorders.view (page) · orders.validate (approve or reject a return) · stock.update (record the reception) · support.view (after-sales tab) · finance.view (credit-note amounts)

Purpose. Handle returns in V1 (§1b.9–10) and keep the after-sales claims (SAV) that relate to orders in view. A return goes through four steps:

  1. A reseller requests it on a delivered order (returns.create), or it comes from an after-sales resolution RETURN, or from a delivery refused at the door.
  2. The back-office approves or rejects it.
  3. The goods travel back.
  4. Reception re-enters the accepted quantities into stock automatically (RETURN movements) and issues a credit note.

The after-sales claims themselves are resolved in BO-56.

Who uses it.

  • Commercial admin: decides returns.
  • Stock manager / warehouse: records receptions.
  • Finance manager: reads the credit notes.

Entry points.

  • Commandes › Retours et SAV (badge).
  • BO-39 Retours et SAV tab.
  • BO-56 (a RETURN resolution creates a return).
  • BO-42 (« Retour au dépôt »).
  • BO-11 Tickets et SAV.

Layout.

  • Tabs (view):
    • « À décider » (REQUESTED).
    • « À réceptionner » (APPROVED, IN_TRANSIT).
    • « Reçus » (RECEIVED).
    • « Avoirs émis » (REFUNDED).
    • « Refusés » (REJECTED).
    • « Réclamations SAV »: tickets of type AFTER_SALES, with issue, lines, status and resolution. A row opens BO-56.
ColumnSource fieldSortableDefault visible
N° retournumber (RET-2026-000012)YesYes
DaterequestedAtYes (default ascending in « À décider »)Yes
RevendeurStore name + CustomerType pillYesYes
Commandeorder.number (link to BO-39)YesYes
Origine« Demande revendeur », « Résolution SAV TKT-… », « Refus à la livraison »NoYes
ArticlesLines and quantitiesNoYes
MotifReason (and AfterSalesIssue for SAV)NoYes
Statutstatus (ReturnStatus)YesYes
Montant de l'avoirCredit note total TTC (needs finance.view)YesNo
AvoirCredit note number + PDFNoNo
  • Return detail (page): header with RET number, ReturnStatus pill, reseller, order, origin and dates. Then:
    • Lines: variant, quantity delivered, quantity requested, Quantité acceptée (decision), Reçue, Remise en stock.
    • Reseller's reason and photos (gallery).
    • Linked ticket.
    • Timeline of status changes.
    • The credit note: number, amount, PDF.

Decision (REQUESTED, with orders.validate), through admin.returns.decide:

  • « Accepter le retour »: per line Quantité acceptée (≤ requested; default = requested). Confirmation « Accepter le retour de 3 articles ? Le revendeur sera informé et pourra renvoyer la marchandise. ». The return becomes APPROVED, then IN_TRANSIT. The reseller is notified (push, in-app, live through events.stream). Audited VALIDATE.
  • « Refuser »: a reason is required and shown to the reseller (e.g. « Délai de retour dépassé »). The return becomes REJECTED. Audited REJECT, and the reseller is notified.

Reception (APPROVED / IN_TRANSIT, with stock.update), through admin.returns.receive:

  • Header: Entrepôt de retour (the default warehouse is preselected) and Reçu le (default now).
  • Per line:
    • Quantité reçue, at most the accepted quantity.
    • Article défectueux — ne pas remettre en stock: a checkbox, preset for SAV issues DEFECTIVE and DAMAGED. Assumption — defective items are credited but not restocked.
    • Commentaire.
  • Confirmation: « Enregistrer la réception ? 3 articles seront remis en stock automatiquement et un avoir de 8 750,00 DA TTC sera émis. »
  • Effects:
    • RETURN stock movements are posted automatically for the restocked quantities (BO-34).
    • The CreditNote is issued (FIN-08). The return becomes RECEIVED, then REFUNDED once the credit note exists.
    • The order becomes RETURNED when all its delivered quantities came back.
    • Audited UPDATE + CREATE (credit note). The reseller is notified (« Retour reçu — avoir AV-… émis »).

Data. admin.returns.list, admin.returns.get, admin.returns.decide, admin.returns.receive, admin.tickets.list (type=AFTER_SALES), files.downloadUrl.

Rules.

  • Eligibility: a return can only concern delivered quantities of a DELIVERED order. Per line, Σ returned ≤ delivered.
  • No manual restock step: reception does it (STK-03). Nobody adjusts stock by hand for a return.
  • Credit note amount = Σ received quantities × the order's unit price TTC after discounts. Delivery fees are not credited unless the whole order is returned. Assumption — confirm.
  • Credit notes reduce the reseller's balance in finance (BO-44).
  • Concurrency: a return decided or received elsewhere answers 409.
  • Number format: the credit note number shown here (AV-…) is illustrative. Assumption — its format is not in the canonical list.

Real-time. The admin stream has no return event in V1. The page polls every 60 s while visible. order.status_changed refreshes returns linked to that order.

States.

  • Empty: « Aucun retour à traiter ».
  • Photos still uploading from the reseller: « Photos en cours d'envoi ».
  • Reception refused (409): the return was cancelled by the reseller meanwhile.

Acceptance criteria.

  • A reseller's return request on a delivered order appears under « À décider » with its lines, reason and photos.
  • Approving with a reduced quantity limits the reception to that quantity.
  • Recording the reception of 3 units creates RETURN movements of +3 (BO-34) and a credit note, and moves the return to REFUNDED, with no manual stock action (ORD-13).
  • A line marked defective is credited but not restocked.
  • An after-sales claim resolved as RETURN in BO-56 creates a return here, linked to the ticket.

On this page