Catalogue, vélos sérialisés et tags BLE : géolocaliser le stock d’un magasin de vélo

Un Trek Domane SL5 2025, c’est un SKU dans Sage. C’est aussi trois vélos physiques avec trois numéros de cadre distincts en stock magasin, dont un en occasion légèrement moins cher, un en exposition avec un tag Bluetooth fixé sous la selle, et un troisième entreposé en réserve. Cette nuance — un produit générique vs ses instances physiques — est le cœur du module catalogue de CRM Cycles, et c’est ce qui fait la différence avec un ERP classique au quotidien.

Double modèle : produit générique + produits sérialisés

Chaque produit « vélo » dans CRM Cycles vit à deux niveaux :

  • Le produit générique est la fiche modèle : nom, SKU, prix catalogue, fournisseur, marque, image, description, dimensions. Une seule fiche par modèle commercialisé.
  • Les produits sérialisés sont les instances physiques de ce modèle. Chacune a son propre numéro de série (gravé sur le cadre), son FNUCI, son état (neuf / très bon / bon / moyen / fatigué), son statut (en stock / réservé / vendu / en transfert / sinistré), son emplacement physique, et peut avoir un prix de vente individuel différent du prix catalogue.

La quantité en stock du produit générique n’est pas saisie manuellement : c’est le décompte automatique des exemplaires sérialisés au statut « En stock ». Schéma typique :

Produit générique : "Trek Domane SL5 2025" (3 en stock)
  ├── S/N TK2025-001 — En stock — 2 490 € (neuf)
  ├── S/N TK2025-002 — Vendu   — 2 490 € (parti chez le client X)
  └── S/N TK2025-003 — En stock — 2 390 € (occasion, état "bon")

Lors d’une vente, le commerçant choisit l’exemplaire sérialisé précis (par son numéro de série ou en scannant son code-barres / FNUCI). À la validation de la facture, le statut de cet exemplaire passe à « Vendu » et il bascule dans le parc du client (cf article précédent sur les fiches clients).

Les articles non-sérialisés (pièces détachées, accessoires, consommables) suivent le modèle classique : une quantité numérique, décrémentée à la vente — pas besoin d’individualiser un câble de frein.

Vélos sérialisés : cycle de vie + FNUCI

Chaque exemplaire sérialisé a son propre cycle de vie en machine à état :

Création (réception fournisseur, assemblage "vélo à la carte", ou acceptation reprise occasion)
    ↓
En stock → sélectionnable dans les ventes
    ↓
[Ajout à une commande validée] → Réservé (numéro de cadre verrouillé pour ce client)
    ↓
[Validation de la facture] → Vendu — entre dans le parc du client
    ↓ (si avoir ou retour)
En stock — retour au catalogue, retiré du parc client

Champ légal obligatoire depuis 2021 : le FNUCI (Fichier National Unique des Cycles Identifiés), gravé sur tout vélo neuf vendu en France. CRM Cycles le stocke sur chaque produit sérialisé et l’utilise dans le livre de police pour les rachats d’occasion (article à venir), dans les fiches PDF produit, et comme identifiant secondaire (à côté du n° de série constructeur) pour les recherches en SAV.

Marques : garantie pré-calculée, SAV pré-rempli

La fiche Marque de CRM Cycles n’est pas juste un libellé. Elle stocke les informations qui pilotent automatiquement les autres modules :

  • Durée de garantie vélo et durée de garantie cadre (en mois)
  • Conditions de garantie et exclusions (textes libres affichés sur les PDF)
  • Contact SAV du fabricant : nom, email, téléphone — utilisé sur le dossier SAV (réclamation auprès du fabricant)
  • URL d’enregistrement de garantie en ligne du fabricant

Concrètement, à l’ouverture d’un dossier SAV pour un Specialized de 2 ans, le système :

  • regarde la date d’achat sur la fiche vélo client
  • compare avec la durée de garantie Specialized configurée (24 mois sur le vélo, 60 mois sur le cadre)
  • pré-coche « Sous garantie : oui » et affiche les conditions/exclusions sur le formulaire
  • pré-remplit les coordonnées du SAV Specialized pour l’envoi du dossier

Plus besoin de chercher « c’est garanti combien de temps déjà Specialized ? » dans une feuille Excel ou sur le site fabricant.

Fournisseurs et Veloconnect : l’EDI standard du secteur

Veloconnect est le protocole EDI (échange de données informatisé) utilisé par les principaux grossistes cycles européens — Raleigh, Shimano Service, Bike Industries Schweiz et beaucoup d’autres. Quand un fournisseur de CRM Cycles est configuré Veloconnect (URL du service + identifiant + mot de passe fournis par le grossiste), trois interactions deviennent automatiques :

  1. Synchroniser le catalogue : import des produits du fournisseur avec leurs références, descriptions, prix nets et disponibilités. Met à jour les prix d’achat d’un coup pour toutes les pièces concernées.
  2. Envoyer les commandes en EDI : le bon de commande est transmis directement dans le système du fournisseur, sans email PDF à traiter à la main. Le commerçant clique « Envoyer », le fournisseur reçoit la commande dans son système, on gagne 24-48h de délai.
  3. Récupérer les accusés réception : le fournisseur confirme la commande et renvoie un numéro de référence. Le statut de la commande passe automatiquement de « Envoyée » à « Confirmée ».

Un bouton « Tester la connexion » sur la fiche fournisseur permet de vérifier instantanément que les credentials Veloconnect fonctionnent — utile lors du onboarding d’un nouveau grossiste.

Tags BLE : géolocaliser un vélo en showroom via Bluetooth

Sur les vélos en exposition (cas typique : un magasin de 200 m² avec 60 vélos pendus aux murs ou debout sur racks), retrouver un modèle précis peut prendre 5 minutes au commercial. Les tags BLE (Bluetooth Low Energy) résolvent ce problème : un petit émetteur fixé sur le cadre émet en continu un signal Bluetooth identifié par son adresse MAC. L’app mobile Radar CRM Cycles (iOS/Android) détecte ces signaux et les croise avec la base de données.

Les usages concrets :

  • Vérifier la présence du stock : le CRM affiche en temps réel chaque vélo comme « Présent » ou « Absent » du showroom. Si un vélo n’est plus détecté depuis quelques heures, alerte automatique.
  • Inventaire semi-automatique : l’app mobile détecte tous les tags au passage d’un commercial avec son téléphone, et signale les vélos non trouvés. L’inventaire annuel passe de 2 jours à 2 heures.
  • Localiser un vélo en mobilité : dans l’app Radar, l’intensité du signal Bluetooth indique la proximité — plus le signal est fort, plus on s’en approche. « Le Trek Domane est à votre droite, à 3 mètres. »
  • Identifier un vélo instantanément : en s’approchant du vélo avec l’app, la fiche produit s’affiche automatiquement. Pratique quand un client pointe un vélo sans connaître le nom.
  • Envoyer la fiche produit par email au client directement depuis l’app, sans repasser par le CRM. Le commercial conclut sa visite, le client repart avec un email contenant tous les détails techniques + prix.

Promotions et campagnes commerciales

Une campagne promo est définie par un nom, des dates de début/fin, et un statut (Active / Programmée / Terminée / Inactive). On y ajoute des produits filtrés par famille, catégorie, marque, fournisseur, millésime ou recherche libre, puis on définit le nouveau prix TTC pour chacun. Le système affiche en direct le pourcentage de réduction et la marge promo avec un code couleur : 🟢 vert si ≥ 10 %, 🟡 orange entre 0 et 10 %, 🔴 rouge en cas de perte. Garde-fou utile pour ne pas brader sous le prix d’achat lors d’un déstockage de fin de saison.

Pendant qu’une campagne est active, les prix promotionnels s’appliquent automatiquement à la création d’un devis, commande ou facture sur les produits concernés — comme les remises de groupe client (cf article précédent).

Sous le capot

  • Modèles Yii2 clés : Product (générique), ProductSerial (instances), Brand, Supplier, BleTag, Campaign. Relation 1-N Product hasMany ProductSerial, la quantité en stock du produit générique est une vue agrégée : SELECT COUNT(*) FROM product_serial WHERE product_id=X AND status='in_stock'.
  • FNUCI : champ fnuci sur ProductSerial, indexé en BDD pour les recherches rapides. Validateur de format (longueur fixe, caractères alphanumériques). Référencé aussi dans le livre de police pour les reprises occasion.
  • Intégration Veloconnect : classe VeloconnectClient qui parle HTTP+XML au service distant. Endpoints classiques : GetCatalog, OrderSubmit, OrderConfirm. Les credentials sont chiffrés en BDD (clé VELOCONNECT_KEY dans .env). Une commande envoyée crée un job en file d’attente Yii2 — retry automatique en cas d’échec réseau.
  • Tags BLE : stockés dans ble_tag avec une relation belongsTo ProductSerial (un tag suit un vélo précis). Les détections viennent de l’app Flutter Radar qui envoie un payload JSON POST /api/ble/detections avec liste des MAC vues + RSSI (force du signal). Côté serveur, un service met à jour le last_seen_at et calcule le statut « Présent / Absent » via une fenêtre de timeout (configurable).
  • Catalogue + filtres en cascade : jointures SQL classiques avec index composites sur (brand_id, category_id, supplier_id) pour que les filtres restent rapides même avec 5 000+ produits.

Ce qu’on gagne au quotidien

  • Pas de confusion entre modèle et exemplaire : deux Domane SL5 strictement identiques sur le papier mais l’un en occasion à -100 € sont deux exemplaires distincts traçables.
  • SAV pré-rempli : garantie automatiquement calculée selon la marque, coordonnées SAV fabricant à un clic.
  • Commandes fournisseurs sans email PDF : Veloconnect élimine la ressaisie côté grossiste, les commandes partent en 1 clic.
  • Inventaire en 2 heures au lieu de 2 jours : les tags BLE + l’app Radar passent en revue les 60 vélos d’un showroom en marchant calmement.
  • Pas de vélo vendu deux fois : le statut « Vendu » est par exemplaire physique, pas par SKU.

Le prochain article couvrira un module spécifique aux vélocistes : les reprises d’occasion et le livre de police — l’obligation légale française qui impose à tout commerçant rachetant des biens d’occasion de tenir un registre auditable des transactions.

Retour en haut