Guide Complet du Cycle de Vie du Produit
Ce guide fournit un aperçu complet du cycle de vie du produit dans OmniCRM, de la création d'une définition de produit à la fourniture de services, en passant par l'ajout d'options supplémentaires et la déprovisionnement. Nous aborderons la stratégie de tarification, l'intégration d'Ansible et fournirons des exemples concrets tout au long.
Aperçu : Le Voyage du Produit au Service
Le cycle de vie d'un produit dans OmniCRM suit ces étapes :
- Définition du Produit - L'administrateur crée un modèle de produit avec des règles de tarification et de provisionnement.
- Création du Service - Le client commande le produit, le système provisionne l'instance de service.
- Cycle de Vie du Service - Le client utilise le service, ajoute des options supplémentaires/compléments, modifie le service.
- Déprovisionnement - Le service est résilié, les ressources sont libérées.
Comprendre la Tarification : Gros vs Détail
Chaque produit et service dans OmniCRM a deux dimensions de tarification : gros et détail.
Coût de Gros
Le coût de gros représente le coût réel de la fourniture du service :
- Coûts d'infrastructure et de bande passante
- Frais de licence
- Coûts d'équipement
- Dépenses opérationnelles
Coût de Détail
Le coût de détail est le montant facturé au client.
Coûts de Mise en Place
Les coûts de gros et de détail ont des variantes de coûts de mise en place pour les frais de provisionnement uniques :
wholesale_setup_cost- Votre coût pour le provisionnementretail_setup_cost- Montant facturé au client pour l'activation
Exemple :
{
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00
}
Étape 1 : Création d'une Définition de Produit
Les produits sont des modèles qui définissent ce qui est provisionné et comment les clients sont facturés.
Création d'un Produit de Carte SIM Mobile
Créons un produit de carte SIM mobile prépayée avec 20 Go de données par mois.
Étape 1 : Naviguer vers la Gestion des Produits
Depuis l'interface admin, allez à Produits → Créer Produit.
Étape 2 : Définir les Informations de Base
{
"product_name": "Prepaid Mobile 20GB",
"product_slug": "prepaid-mobile-20gb",
"category": "standalone",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-sim-card",
"comment": "Prepaid mobile SIM with 20GB data, unlimited calls & texts"
}
Explications des Champs :
product_name- Nom visible par le client affiché dans le catalogue.product_slug- Identifiant sécurisé pour l'URL utilisé dans les appels API et les liens.category- "standalone" signifie que cela crée un nouveau service (vs option supplémentaire/pack).service_type- Regroupe les produits connexes, utilisé pour le filtrage des options supplémentaires.enabled- Doit être vrai pour que le produit soit commandable.icon- Icône FontAwesome affichée dans l'interface utilisateur.comment- Notes internes pour référence du personnel.
Étape 3 : Définir la Tarification
{
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00,
"contract_days": 30
}
Détails de la Tarification :
- Revenu mensuel par client : £15.00
- Coût mensuel de livraison : £5.00
- Marge bénéficiaire mensuelle : £10.00 (200 % de majoration, 67 % de marge)
- Profit de mise en place : -£1.00 (subventionné pour attirer les clients)
- Durée du contrat : 30 jours (renouvellement mensuel)
Étape 4 : Définir l'Éligibilité du Client
{
"residential": true,
"business": false,
"customer_can_purchase": true,
"available_from": "2025-01-01T00:00:00Z",
"available_until": null
}
- Les clients résidentiels peuvent commander.
- Les clients professionnels ne peuvent pas (ligne de produit différente).
- Achat en libre-service activé.
- Disponible à partir du 1er janvier 2025.
- Pas de date de fin (offre continue).
Étape 5 : Configurer le Renouvellement Automatique
{
"auto_renew": "prompt",
"allow_auto_renew": true
}
"prompt"- Demander au client s'il souhaite un renouvellement automatique lors de l'achat."true"- Renouveler automatiquement sans demander."false"- Ne jamais renouveler automatiquement (recharge manuelle uniquement).allow_auto_renew: true- Le client peut activer/désactiver le renouvellement automatique plus tard.
Étape 6 : Spécifier les Exigences d'Inventaire
Les exigences d'inventaire définissent quelles ressources physiques ou virtuelles doivent être allouées lors du provisionnement de ce produit. C'est une étape critique qui relie votre catalogue de produits à votre système de gestion des stocks .
{
"inventory_items_list": "['SIM Card', 'Mobile Number']"
}
Qu'est-ce que les Articles d'Inventaire ?
Les articles d'inventaire sont des ressources traçables stockées dans le système d'inventaire d'OmniCRM. Chaque article a :
- Type - Défini par le Modèle d'Inventaire (par exemple, "SIM Card", "Mobile Number", "Modem").
- Attributs uniques - Numéros de série, adresses MAC, numéros de téléphone, etc.
- État - En Stock, Assigné, Désaffecté, etc.
- Emplacement - Emplacement physique ou logique.
Comment Fonctionnent les Exigences d'Inventaire :
La inventory_items_list est une liste Python (sous forme de chaîne) contenant les noms des types d'inventaire. Chaque nom doit correspondre exactement à un nom de
Modèle d'Inventaire existant.
Exemple d'Exigences d'Inventaire :
# Produit de carte SIM mobile
inventory_items_list: "['SIM Card', 'Mobile Number']"
# Service Internet fixe
inventory_items_list: "['Modem Router', 'Static IP Address']"
# Service numérique (pas d'articles physiques)
inventory_items_list: "[]"
# Sans fil fixe avec CPE
inventory_items_list: "['Fixed Wireless CPE', 'IPv4 Address', 'IPv6 Prefix']"
Le Processus de Sélection d'Inventaire
Lorsqu'un utilisateur provisionne un produit avec des exigences d'inventaire, le système impose un processus de sélection obligatoire :
1. Bouton de Provisionnement Cliqué
Après avoir sélectionné le produit, l'utilisateur clique sur "Provisionner". Au lieu de provisionner immédiatement, le système vérifie inventory_items_list.
2. La Boîte de Dialogue de Sélection d'Inventaire Apparaît
Si l'inventaire est requis, une boîte de dialogue modale apparaît avec un menu déroulant séparé pour chaque type d'inventaire :
3. Filtrage de l'Inventaire Disponible
Le menu déroulant pour chaque type d'inventaire ne montre que les articles qui sont :
- Type Correct - Correspond exactement au nom du modèle d'inventaire.
- Statut Disponible -
item_stateest "New" ou "In Stock" (pas "Assigned" ou "Damaged"). - Non Assigné -
service_idetcustomer_idsont NULL. - En Stock à l'Emplacement - Filtré éventuellement par emplacement d'entrepôt/magasin.
Exemple d'Options de Menu Déroulant :
Pour le type d'inventaire "SIM Card", le menu déroulant pourrait afficher :
Chaque option affiche :
- ID d'inventaire ou numéro de référence.
- Identifiant principal (
itemtext1- par exemple, ICCID pour SIM, numéro pour téléphone). - Emplacement actuel (
item_location).
4. Sélection Requise pour Procéder
Règle Critique : Le provisionnement NE PEUT PAS se poursuivre sans sélectionner tous les articles d'inventaire requis.
- Le bouton "Continuer" est désactivé jusqu'à ce que tous les menus déroulants aient des sélections.
- L'utilisateur doit sélectionner un article pour chaque type d'inventaire.
- Le système valide les sélections avant de continuer.
5. Inventaire Sélectionné Transféré à Ansible
Une fois que l'utilisateur clique sur "Continuer", les ID d'inventaire sélectionnés sont passés au playbook Ansible en tant que variables :
# L'utilisateur a sélectionné :
# - ID d'inventaire de la carte SIM : 5001
# - ID d'inventaire du numéro de mobile : 5002
# Variables passées à Ansible :
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001, # ID d'inventaire
"Mobile Number": 5002, # ID d'inventaire
"access_token": "eyJ..."
}
Remarque : Le nom de la variable correspond exactement au type d'inventaire. Le playbook utilise hostvars[inventory_hostname]['SIM Card'] pour accéder à l'ID d'inventaire.
6. Le Playbook Récupère les Détails Complets de l'Inventaire
Le playbook Ansible utilise l'ID d'inventaire pour récupérer les détails complets :
- name: Get SIM Card details from inventory
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_sim
- name: Extract ICCID and IMSI
set_fact:
iccid: "{{ api_response_sim.json.itemtext1 }}"
imsi: "{{ api_response_sim.json.itemtext2 }}"
Maintenant, le playbook a tous les détails de la SIM (ICCID, IMSI, etc.) pour provisionner l'abonné dans le HSS.
7. État de l'Inventaire Changé en "Assigné"
Après la création de l'enregistrement de service, le playbook met à jour l'inventaire pour le lier au service :
- name: Assign SIM Card to Service
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body:
{
"service_id": "{{ service_creation_response.json.service_id }}",
"customer_id": "{{ customer_id }}",
"item_state": "Assigned"
}
Important : L'attribution de l'inventaire se produit pendant l'exécution du playbook en tant que tâche spécifique, PAS lorsque le bouton de provisionnement est cliqué. Cela signifie :
- Risque de Double Attribution : Entre le clic sur "Provisionner" et l'attribution de l'inventaire, un autre utilisateur pourrait théoriquement sélectionner le même article d'inventaire.
- Meilleure Pratique : Pour les opérations à volume élevé, mettez en œuvre un verrouillage de l'inventaire ou utilisez des transactions de base de données.
- Rollback en Cas d'Échec : Si le playbook échoue avant l'attribution de l'inventaire, l'inventaire reste non attribué et disponible pour réutilisation.
Pourquoi Ne Pas Attribuer Plus Tôt ?
L'inventaire n'est pas attribué lorsque "Provisionner" est cliqué parce que :
- ID de Service Nécessaire : L'
service_idn'existe pas tant que le service n'est pas créé dans le playbook. - Simplicité de Rollback : Si le provisionnement échoue tôt (par exemple, l'échec de la création de compte OCS), l'inventaire n'a pas besoin d'être nettoyé.
- Flexibilité : Le playbook peut décider de ne pas attribuer l'inventaire en fonction de la logique conditionnelle.
Gestion des Échecs de Provisionnement :
Lorsqu'un provisionnement échoue après que l'inventaire a été attribué, le bloc de secours doit libérer l'inventaire :
rescue:
- name: Release inventory on failure
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body:
{
"service_id": null,
"customer_id": null,
"item_state": "In Stock"
}
when: service_id is defined # Seulement si le service a été créé
Cela garantit que l'inventaire n'est pas laissé dans un état "Assigné" pour un service inexistant ou échoué.
Lorsque la Liste d'Inventaire est Vide
Si inventory_items_list: "[]" (liste vide), le sélecteur d'inventaire est complètement ignoré et le provisionnement se poursuit immédiatement. Cela est courant pour :
- Produits numériques - Licences logicielles, comptes VPN.
- Options supplémentaires de service - Recharges de données qui ne nécessitent pas de nouveau matériel.
- Services virtuels - Qui ne consomment pas de ressources traçables.
Exemple : Un addon "5GB Data Boost" a inventory_items_list: "[]" car il ajoute simplement un solde à un service existant sans nécessiter de nouveau matériel.
Configuration du Modèle d'Inventaire
Avant d'utiliser un type d'inventaire dans inventory_items_list, vous devez créer le Modèle d'Inventaire :
- Naviguez vers Administration → Inventaire → Modèles.
- Créez un modèle avec le nom exact (par exemple, "SIM Card").
- Définissez les champs :
itemtext1_label: "ICCID".itemtext2_label: "IMSI".itemtext3_label: "PUK Code".
- Ajoutez des articles d'inventaire de ce type en stock.
Pour des détails complets sur la création et la gestion des modèles d'inventaire, voir Gestion des Inventaires .
Plusieurs Articles du Même Type
Bien que la inventory_items_list soit un tableau, avoir des types en double (par exemple, "['SIM Card', 'SIM Card']") est non recommandé car cela peut causer de la confusion dans l'interface utilisateur et le nommage des variables du playbook.
Pour les scénarios nécessitant plusieurs articles similaires :
Option 1 : Créer des noms de modèles d'inventaire distincts
# Service de téléphone Dual-SIM
inventory_items_list: "['Primary SIM Card', 'Secondary SIM Card', 'Mobile Number']"
Créez des modèles séparés : "Primary SIM Card" et "Secondary SIM Card" avec les mêmes champs mais des noms différents.
Option 2 : Utiliser un seul article d'inventaire groupé
# Kit Dual-SIM
inventory_items_list: "['Dual SIM Kit', 'Mobile Number']"
Où le modèle d'inventaire "Dual SIM Kit" a des champs pour les deux SIM (itemtext1: ICCID principal, itemtext2: ICCID secondaire, etc.).
Scénarios d'Inventaire Courants
Service Mobile :
inventory_items_list: "['SIM Card', 'Mobile Number']"
- Carte SIM : Physique ou eSIM avec ICCID/IMSI.
- Numéro Mobile : Numéro de téléphone (MSISDN).
Internet Fixe :
inventory_items_list: "['Modem Router', 'Static IP Address']"
- Modem Routeur : Dispositif CPE avec adresse MAC.
- Adresse IP Statique : IPv4 du pool d'adresses.
Sans Fil Fixe :
inventory_items_list: "['Fixed Wireless CPE', 'IPv4 Address', 'IPv6 Prefix']"
- CPE : Équipement client (antenne, modem).
- IPv4 : Adresse IP publique.
- Préfixe IPv6 : préfixe /56 ou /64.
Remarque : Les rendez-vous et la planification ne sont pas des articles d'inventaire. Utilisez des systèmes de planification/calendrier séparés pour les rendez-vous d'installation.
Service VoIP :
inventory_items_list: "['DID Number']"
- Numéro DID : Numéro de téléphone de composition directe.
Remarque : Les noms d'utilisateur SIP, les mots de passe et les configurations de compte sont générés par programme par le playbook de provisionnement, pas sélectionnés dans l'inventaire.
GPON/Fibre :
inventory_items_list: "['ONT Device', 'GPON Port', 'IPv4 Address', 'Fiber Drop Cable']"
- Dispositif ONT : Terminal de réseau optique avec numéro de série.
- Port GPON : Port spécifique sur OLT avec connexion fibre.
- Adresse IPv4 : IP publique ou privée.
- Câble de Fibre : Câble de fibre physique de la rue aux locaux (suivi pour la gestion des actifs).
Location d'Équipement :
inventory_items_list: "['Rental Modem']"
- Suit quel modem est avec quel client.
- Important pour récupérer l'équipement lors de l'annulation.
Pourquoi les Exigences d'Inventaire Comptent
1. Prévenir la Double Attribution
Sans suivi d'inventaire, vous pourriez accidentellement :
- Attribuer la même carte SIM à deux clients.
- Allouer la même adresse IP à plusieurs services.
- Expédier le même numéro de série d'équipement à différents emplacements.
Le sélecteur d'inventaire garantit que chaque article est attribué à un seul service.
2. Piste de Vérification
L'attribution d'inventaire crée une piste de vérification complète :
- Quelle carte SIM est avec quel client.
- Quand a-t-elle été attribuée.
- Quel service utilise quel numéro de téléphone.
- Historique de l'équipement (qui l'a eu, quand, pour quel service).
3. Planification des Ressources
Suivez les niveaux d'inventaire :
- Alertez lorsque les cartes SIM sont en faible quantité.
- Réapprovisionnez avant rupture de stock.
- Planifiez les horaires des techniciens en fonction de la disponibilité du CPE.
- Gérez l'allocation de l'espace d'adresses IP.
4. Suivi des Coûts
Liez le coût de gros à un article spécifique :
- Suivez le coût de chaque carte SIM.
- Calculez la dépréciation de l'équipement.
- Identifiez les articles perdus ou volés.
- COGS (Coût des Biens Vendus) précis.
5. Déprovisionnement
Lorsque le service est annulé, l'inventaire peut être :
- Libéré en stock (cartes SIM, modems).
- Retiré (équipement endommagé).
- Retourné au fournisseur (équipement de location).
- Conservé pour une période de grâce (numéros de téléphone avant libération).
Résolution des Problèmes de Sélecteur d'Inventaire
Problème : Message "Aucun inventaire disponible" apparaît.
Causes :
- Aucun article d'inventaire du type requis n'existe dans la base de données.
- Tous les articles sont déjà "Assignés" à d'autres services.
- Les articles sont marqués comme "Endommagés" ou "Hors Service".
- Le nom du modèle d'inventaire ne correspond pas exactement (sensible à la casse).
Solution :
- Vérifiez que le modèle d'inventaire existe : Administration → Inventaire → Modèles.
- Vérifiez que le nom du modèle correspond exactement (y compris les espaces, la casse).
- Ajoutez des articles d'inventaire de ce type : Administration → Inventaire → Ajouter un Article.
- Vérifiez que les articles sont dans l'état "New" ou "In Stock".
- Vérifiez que les articles ne sont pas déjà attribués (
service_iddoit être NULL).
Problème : Le sélecteur d'inventaire n'apparaît pas.
Causes :
inventory_items_listest vide :"[]".inventory_items_listest NULL ou non défini.- La catégorie de produit est "addon" et hérite de l'inventaire du service parent.
Solution :
- Si l'inventaire est nécessaire, définissez
inventory_items_list: "['Type1', 'Type2']". - Vérifiez que la définition du produit est enregistrée correctement.
- Vérifiez que la réponse API pour le produit inclut inventory_items_list.
Problème : Le playbook échoue avec "inventaire non trouvé".
Causes :
- Le playbook fait référence à un nom de variable incorrect.
- L'ID d'inventaire n'est pas passé correctement.
- L'inventaire a été supprimé entre la sélection et le provisionnement.
Solution :
- Vérifiez que le playbook utilise la bonne variable :
hostvars[inventory_hostname]['SIM Card']. - Vérifiez que la variable est un entier :
{{ hostvars[inventory_hostname]['SIM Card'] | int }}. - Ajoutez une gestion des erreurs dans le playbook pour l'inventaire manquant.
Voir Gestion des Inventaires pour des détails complets sur la création de modèles, l'ajout d'articles et la gestion des niveaux de stock.
Étape 7 : Définir les Caractéristiques et Conditions
Les caractéristiques et conditions sont du contenu marketing et légal visible par le client qui aide les clients à comprendre ce qu'ils achètent et les obligations impliquées.
{
"features_list": "20GB High-Speed Data. Unlimited Calls & Texts. EU Roaming Included. No Contract. 30-Day Expiry",
"terms": "Credit expires after 30 days. Data, calls, and texts valid only within expiry period. Fair use policy applies. See website for full terms."
}
Objectif et Valeur Commerciale
Liste des Caractéristiques - Marketing & Ventes :
La liste des caractéristiques remplit plusieurs fonctions commerciales critiques :
- Différenciation du Produit - Aide les clients à comparer rapidement les produits et à choisir le bon.
- "Prepaid Mobile 20GB" vs "Prepaid Mobile 50GB" - les caractéristiques montrent clairement la différence.
- Sans caractéristiques, les clients ne voient que le prix, manquant la proposition de valeur.
- Communication Marketing - Points de vente clés affichés en évidence.
- "EU Roaming Included" attire les voyageurs internationaux.
- "No Contract" attire les clients réticents à l'engagement.
- Les caractéristiques influencent les décisions d'achat.
- Attentes des Clients - Établit des attentes claires sur ce qui est inclus.
- Réduit les appels de support ("Cela inclut-il des appels ?" → clairement listé).
- Empêche les malentendus et les demandes de remboursement.
- Renforce la confiance par la transparence.
- Libre-Service - Permet aux clients de sélectionner eux-mêmes les produits appropriés.
- Le client lit les caractéristiques, comprend l'offre, fait un choix éclairé.
- Réduit le besoin d'explications du personnel de vente.
- Accélère le processus d'achat.
- SEO et Découvrabilité - Les caractéristiques peuvent être indexées pour la recherche.
- Le client recherche "forfait mobile appels illimités" → le produit apparaît.
- Améliore la recherche dans le catalogue de produits.
Conditions et Termes - Légal & Conformité :
Les conditions servent des objectifs légaux et opérationnels :
- Protection Légale - Protège l'entreprise des litiges et de la responsabilité.
- "Le crédit expire après 30 jours" - le client ne peut pas demander de remboursement au 31ème jour.
- "La politique d'utilisation équitable s'applique" - empêche les abus (partage de la connexion mobile avec tout le bureau).
- Crée un accord contraignant.
- Gestion des Attentes - Prévenir l'insatisfaction des clients.
- "Valide uniquement pendant la période d'expiration" - le client connaît la date limite d'utilisation.
- "Ne peut pas être remboursé" (pour les options supplémentaires) - empêche les achats frauduleux.
- Réduit les rétrofacturations et les plaintes.
- Conformité Réglementaire - Répond aux exigences légales.
- Les lois sur la protection des consommateurs exigent des conditions claires.
- Les réglementations en matière de télécommunications imposent la divulgation.
- Les termes GDPR/de confidentialité peuvent être référencés.
- Limites Opérationnelles - Définit la portée et les limitations du service.
- "Sous réserve de la couverture réseau" - non responsable des zones mortes.
- "La vitesse peut varier" - gère les attentes sur les vitesses "jusqu'à".
- "L'équipement doit être retourné" - assure la récupération de l'équipement loué.
- Piste de Vérification - Prouve que le client a été informé.
- Le client a accepté les conditions lors de l'achat.
- Le système enregistre l'horodatage d'acceptation.
- Défendable en cas de litiges ou de procédures judiciaires.
Exemple Concret :
Le client achète un forfait "Appels et SMS Illimités", puis l'utilise pour du télémarketing (10 000 appels/jour). Sans conditions :
- Client : "Vous avez dit illimité !"
- Fournisseur : "Nous voulions dire usage personnel..."
- Client : "Ce n'est pas ce que vous avez annoncé !"
- Résultat : Litige, plainte potentielle auprès du régulateur, dommage à la marque.
Avec des conditions : "La politique d'utilisation équitable s'applique. Le service est uniquement pour un usage personnel. L'utilisation commerciale est interdite."
- Le fournisseur : Montre les conditions acceptées par le client.
- Le client ne peut pas prétendre à l'ignorance.
- Base légale pour suspendre le service.
- Litige résolu en faveur du fournisseur.
Format de la Liste des Caractéristiques :
Comprendre le format correct est critique car un formatage incorrect casse l'affichage de l'interface utilisateur. Les caractéristiques peuvent apparaître comme une longue chaîne au lieu de points de puces, ou ne pas s'afficher du tout.
Le champ features_list peut être formaté de deux manières :
Option 1 : Chaîne Séparée par des Points (Recommandé)
Les caractéristiques sont séparées par un point et un espace (". "). L'interface utilisateur se divise sur ce délimiteur et rend chaque caractéristique comme un point de puce.
Pourquoi ce format ?
- Simple à éditer - il suffit de taper les caractéristiques avec des points entre elles.
- Aucun caractère spécial à échapper.
- Fonctionne de manière fiable à travers tous les composants de l'interface utilisateur.
- Facile à mettre à jour sans casser la syntaxe JSON.
Correct vs Incorrect :
Option 2 : Chaîne de Tableau JSON
"['20GB High-Speed Data', 'Unlimited Calls & Texts', 'EU Roaming Included']"
L'interface utilisateur peut également analyser les tableaux JSON. Notez qu'il s'agit d'une chaîne contenant du JSON, pas d'un tableau JSON réel dans la base de données.
Pourquoi ce format existe-t-il ?
- Permet des caractéristiques avec des points en elles (par exemple, "Jusqu'à 100 Mbps. Sous réserve de disponibilité.").
- La génération programmatique à partir de scripts/API est plus facile.
- Importé de catalogues de produits externes qui utilisent des tableaux.
Important : Cela doit être une syntaxe de liste Python valide sous forme de chaîne. Guillemets simples autour de chaque élément, guillemets doubles autour de toute la chaîne.
Quel Format Utiliser ?
- Séparé par des points - Pour la création manuelle de produits dans l'interface utilisateur (plus simple, moins sujet aux erreurs).
- Tableau JSON - Pour la création de produits basée sur API/script (plus robuste pour des caractéristiques complexes).
Les deux formats produisent une sortie identique dans l'interface utilisateur - ils affectent simplement la manière dont vous saisissez les données.
Où les Caractéristiques Apparaissent dans l'UI :
1. Catalogue de Produits (Vue Client)
Lorsque les clients parcourent les produits disponibles, les caractéristiques sont affichées sous forme de points de puce sur chaque carte produit :
2. Page de Détails du Produit
En cliquant sur "Voir les Détails", toutes les informations sur le produit sont affichées, y compris :
- Nom du produit et icône.
- Tarification (coût mensuel, coût de mise en place).
- Liste complète des caractéristiques (points de puce).
- Conditions et termes (voir ci-dessous).
- Disponibilité et éligibilité.
3. Confirmation de Provisionnement
Lors du provisionnement, les caractéristiques sont affichées pour que l'utilisateur les examine avant de confirmer :
Caractéristiques : • 20GB High-Speed Data • Unlimited Calls & Texts • EU Roaming Included • No Contract • 30-Day Expiry
Coût : £15.00/mois Mise en place : £0.00
[Annuler] [Confirmer & Provisionner]
4. Détails du Service (Après Provisionnement)
Après que le service est actif, les caractéristiques sont affichées sur la page de détails du service pour référence du client.
Format des Conditions et Termes :
Le champ terms est du texte brut qui peut inclure des sauts de ligne :
Où les Termes Apparaissent dans l'UI :
1. Page de Détails du Produit
Les termes sont affichés dans une section repliée qui s'étend lorsqu'on clique :
2. Confirmation de Commande
Lors du provisionnement, une case à cocher exige que l'utilisateur accepte les termes :
Le bouton [Provisionner] est désactivé jusqu'à ce qu'il soit coché.
3. Factures
Les termes du service peuvent être inclus sur les factures comme notes de bas de page pour plus de clarté.
Meilleures Pratiques :
- Caractéristiques : Gardez concis (moins de 50 caractères chacun), concentrez-vous sur les principaux avantages.
- Termes : Incluez les exigences légales critiques, les politiques d'expiration, les politiques d'utilisation équitable.
- Les Deux : Mettez à jour lorsque le produit change pour tenir les clients informés.
Étape 8 : Lier le Playbook de Provisionnement Ansible
{
"provisioning_play": "play_local_mobile_sim",
"provisioning_json_vars": "{
\"days\": 30,
\"data_gb\": 20,
\"voice_minutes\": \"unlimited\",
\"sms_count\": \"unlimited\"
}"
}
provisioning_play- Nom du playbook Ansible (sans extension .yaml).provisioning_json_vars- Variables par défaut passées au playbook.- Le playbook doit exister à :
OmniCRM-API/Provisioners/plays/play_local_mobile_sim.yaml.
Définition Complète du Produit
{
"product_name": "Prepaid Mobile 20GB",
"product_slug": "prepaid-mobile-20gb",
"category": "standalone",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-sim-card",
"comment": "Prepaid mobile SIM with 20GB data, unlimited calls & texts",
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00,
"contract_days": 30,
"residential": true,
"business": false,
"customer_can_purchase": true,
"available_from": "2025-01-01T00:00:00Z",
"available_until": null,
"auto_renew": "prompt",
"allow_auto_renew": true,
"inventory_items_list": "['SIM Card', 'Mobile Number']",
"features_list": "[
'20GB High-Speed Data',
'Unlimited Calls & Texts',
'EU Roaming Included',
'No Contract',
'30-Day Expiry'
]",
"terms": "Credit expires after 30 days. Data, calls, and texts valid only within expiry period. Fair use policy applies.",
"provisioning_play": "play_local_mobile_sim",
"provisioning_json_vars": "{
\"days\": 30,
\"data_gb\": 20,
\"voice_minutes\": \"unlimited\",
\"sms_count\": \"unlimited\"
}"
}
Création d'un Produit d'Addon
Les addons améliorent ou modifient les services existants. Ils se présentent sous deux types : addons virtuels (pas de ressources physiques) et addons matériels (nécessitent de l'inventaire).
Exemple 1 : Addon Virtuel (5GB Data Boost)
Un addon numérique qui ajoute des données à un service mobile existant :
{
"product_name": "5GB Data Boost",
"product_slug": "5gb-data-boost",
"category": "addon",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-plus",
"comment": "Add 5GB extra data to existing mobile service",
"retail_cost": 5.00,
"wholesale_cost": 1.50,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 0.00,
"contract_days": 0,
"residential": true,
"business": true,
"customer_can_purchase": true,
"auto_renew": "false",
"allow_auto_renew": false,
"inventory_items_list": "[]",
"relies_on_list": "",
"features_list": "5GB High-Speed Data. Valid for 7 Days",
"terms": "Data expires after 7 days or when exhausted. Cannot be refunded.",
"provisioning_play": "play_topup_charge_then_action",
"provisioning_json_vars": "{
\"data_gb\": 5,
\"days\": 7
}"
}
Exemple 2 : Addon Matériel (Location de Modem)
Un addon qui fournit un équipement physique pour un service de fibre existant :
{
"product_name": "WiFi 6 Modem Rental",
"product_slug": "wifi6-modem-rental",
"category": "addon",
"service_type": "internet",
"enabled": true,
"icon": "fa-solid fa-router",
"comment": "Add WiFi 6 modem to fiber service - rental",
"retail_cost": 10.00,
"wholesale_cost": 3.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 45.00,
"contract_days": 30,
"residential": true,
"business": true,
"customer_can_purchase": true,
"auto_renew": "true",
"allow_auto_renew": true,
"inventory_items_list": "['Rental Modem']",
"relies_on_list": "",
"features_list": "WiFi 6 (802.11ax). Dual-band 2.4GHz + 5GHz. Up to 40 devices. Parental controls",
"terms": "Equipment rental. Must be returned on service cancellation or £150 replacement fee applies. Equipment remains property of provider.",
"provisioning_play": "play_addon_assign_modem",
"provisioning_json_vars": "{
\"device_type\": \"modem_router\",
\"requires_configuration\": true
}"
}
Différences Clés pour les Addons :
category: "addon"- Appliqué à un service existant, pas autonome.contract_days: 0(virtuel) ou30(location récurrente) - Fréquence de facturation.inventory_items_list: "[]"(virtuel) ou"['Rental Modem']"(matériel) - Ressources physiques.auto_renew: "false"(unique) ou"true"(location) - Comportement récurrent.relies_on_list: ""- Vide signifie s'applique à tout service de typeservice_typecorrespondant.
Pourquoi les Addons Matériels Ont Besoin d'Inventaire :
Les addons matériels nécessitent inventory_items_list parce que :
- Suivre l'Équipement - Savoir quel modem est avec quel client.
- Prévenir les Ruptures de Stock - Impossible de provisionner l'addon s'il n'y a pas de modems en stock.
- Récupération - Lorsque le client annule, savoir quel équipement récupérer.
- Suivi des Coûts - Lier le coût de gros à un numéro de série spécifique.
- Dépréciation - Suivre la valeur de l'équipement pendant la période de location.
- Garantie - Identifier les unités défectueuses par numéro de série.
Flux de Provisionnement des Addons avec Inventaire :
Lorsqu'un client ajoute "WiFi 6 Modem Rental" à son service de fibre :
- Addon Sélectionné - Le client clique sur "Ajouter au Service".
- Sélecteur d'Inventaire Apparaît - Comme pour les services autonomes :
- Paiement Traité - £10.00 de location mensuelle facturée.
- Modem Assigné - Inventaire mis à jour :
service_id: Lié au service de fibre.customer_id: Lié au client.item_state: "Assigné".
- Expédition Déclenchée - Système de réalisation notifié pour expédier le modem.
- Installation - Le client reçoit le modem, le branche sur l'ONT.
- Facturation Récurrente - £10/mois facturé jusqu'à l'annulation de l'addon.
Déprovisionnement des Addons Matériels :
Lorsque le client annule la location du modem :
- Annulation Initiée - Le client clique sur "Retirer l'Addon".
- Processus de Retour Démarré :
- E-mail envoyé avec des instructions de retour.
- Étiquette d'expédition prépayée générée.
- Période de grâce de 14 jours avant pénalité.
- Équipement Retourné :
- Inventaire mis à jour :
item_state= "In Stock" (après remise à neuf). - Ou
item_state= "Damaged" (si défectueux). - Lié au prochain client une fois remis à neuf.
- Inventaire mis à jour :
- Pas de Retour :
- Après 14 jours, des frais de remplacement de £150 sont facturés.
- Inventaire marqué :
item_state= "Lost". - Coût de gros (£45) + valeur de remplacement récupérée.
Tarification des Addons :
Les addons peuvent être tarifés différemment des services autonomes :
- Les addons virtuels n'ont généralement pas de coûts de mise en place.
- Les addons matériels peuvent avoir des coûts de mise en place de gros pour l'équipement.
- Les addons de location récurrents utilisent
contract_dayspour la fréquence de facturation.
Étape 2 : Le Processus de Provisionnement
Lorsque le client commande le produit "Prepaid Mobile 20GB", OmniCRM orchestre le provisionnement via Ansible.
Diagramme de Flux de Provisionnement
Client Commande → Sélection d'Inventaire → Job de Provisionnement Créé ↓ ↓ Paiement Autorisé ← Variables Assemblées ← Playbook Ansible Exécuté ↓ ↓ Enregistrement de Service Créé → Configuration du Compte OCS → Inventaire Assigné → Service Actif
Flux de Provisionnement Étape par Étape
1. Le Client Initie la Commande
Depuis la page client :
- Le personnel clique sur "Ajouter un Service".
- Sélectionne "Prepaid Mobile 20GB" dans le carrousel de produits.
- Détails du produit et tarification affichés.
2. Sélection d'Inventaire
Le système demande l'inventaire requis :
- Carte SIM - Le menu déroulant montre les cartes SIM disponibles en stock.
- Exemple : "SIM-00123 - ICCID: 8944..."
- Numéro Mobile - Le menu déroulant montre les numéros de téléphone disponibles.
- Exemple : "+44 7700 900123"
Le personnel ou le client sélectionne des articles dans l'inventaire disponible.
3. Confirmation de Tarification
Le système affiche la tarification finale :
- Coût de mise en place : £0.00 (activation gratuite).
- Coût mensuel : £15.00.
- Montant dû aujourd'hui : £15.00 (premier mois).
- Date de renouvellement : 30 jours à partir d'aujourd'hui.
Si l'invite de renouvellement automatique est activée, le client choisit :
- Renouveler automatiquement ce service tous les 30 jours.
4. Bouton de Provisionnement Cliqué
Lorsque "Provisionner" est cliqué, l'API :
- Crée un enregistrement
Provisionavec le statut "En Cours" (status=1). - Fusionne les variables du produit + demande + sélections d'inventaire.
- Génère un fil d'arrière-plan pour exécuter le playbook Ansible.
- Retourne
provision_idà l'interface utilisateur pour le suivi du statut.
5. Variables Assemblées
Le système fusionne les variables de plusieurs sources :
Du Produit :
{
"days": 30,
"data_gb": 20,
"voice_minutes": "unlimited",
"sms_count": "unlimited"
}
De la Demande :
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001,
"Mobile Number": 5002
}
Ajoutées par le Système :
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"initiating_user": 7
}
Variables Finales Passées à Ansible :
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001,
"Mobile Number": 5002,
"days": 30,
"data_gb": 20,
"voice_minutes": "unlimited",
"sms_count": "unlimited",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"initiating_user": 7
}
6. Exécution du Playbook Ansible
Le playbook play_local_mobile_sim.yaml s'exécute avec ces variables.
Comprendre le Playbook de Provisionnement Ansible
Examinons un vrai playbook de provisionnement pour comprendre ce qui se passe en coulisses.
Exemple de Playbook de Provisionnement de Carte SIM Mobile
Emplacement :
OmniCRM-API/Provisioners/plays/play_local_mobile_sim.yaml
Structure de Haut Niveau :
- name: Mobile SIM Provisioning
hosts: localhost
gather_facts: no
become: False
tasks:
- name: Main block
block:
# 1. Charger la configuration
# 2. Récupérer les détails du produit depuis l'API
# 3. Récupérer les détails du client depuis l'API
# 4. Récupérer les détails de l'inventaire depuis l'API
# 5. Créer un compte dans OCS (CGRateS)
# 6. Ajouter des soldes et des allocations à OCS
# 7. Créer un enregistrement de service dans le CRM
# 8. Assigner l'inventaire au service
# 9. Enregistrer les transactions
# 10. Envoyer des notifications de bienvenue
rescue:
# Rollback en cas d'échec
# - Supprimer le compte OCS
# - Libérer l'inventaire
# - Enregistrer l'erreur
Détails du Playbook :
Tâche 1 : Charger la Configuration
- name: Include vars of crm_config
ansible.builtin.include_vars:
file: "../../crm_config.yaml"
name: crm_config
Charge la configuration système, y compris :
- URL et identifiants OCS/CGRateS.
- URL de base CRM.
- Configuration du locataire.
Tâche 2 : Récupérer les Détails du Produit
- name: Get Product information from CRM API
uri:
url: "{{ crm_config.crm.base_url }}/crm/product/product_id/{{ product_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
return_content: yes
register: api_response_product
Ce que Cela Fait :
- Appelle
GET /crm/product/product_id/42. - Récupère la définition complète du produit.
- Stocke dans la variable
api_response_product.
Pourquoi : Même si nous avons provisioning_json_vars du produit, nous récupérons le produit complet pour obtenir :
- La tarification la plus récente (peut avoir changé depuis le début de la commande).
- Le nom du produit pour le nommage du service.
- La liste des caractéristiques pour la documentation.
- Les coûts de gros pour le suivi des marges.
Tâche 3 : Définir les Faits du Paquet
- name: Set package facts
set_fact:
package_name: "{{ api_response_product.json.product_name }}"
monthly_cost: "{{ api_response_product.json.retail_cost }}"
setup_cost: "{{ api_response_product.json.retail_setup_cost }}"
Extrait les valeurs couramment utilisées dans des variables simples pour la lisibilité.
Tâche 4 : Récupérer les Détails de l'Inventaire
- name: Get SIM information from CRM API
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_sim
- name: Set IMSI from Inventory response
set_fact:
imsi: "{{ api_response_sim.json.itemtext2 }}"
iccid: "{{ api_response_sim.json.itemtext1 }}"
Ce que Cela Fait :
- Recherche l'ID d'inventaire de la carte SIM 5001.
- Récupère les détails de la SIM :
itemtext1= ICCID (numéro de carte SIM).itemtext2= IMSI (identité de l'abonné).
- Fait de même pour l'inventaire du numéro mobile (récupère le numéro de téléphone).
Pourquoi Cela Compte :
- L'IMSI est nécessaire pour provisionner l'abonné dans le HSS (Home Subscriber Server).
- L'ICCID est enregistré dans les notes de service pour le dépannage.
- Le numéro de téléphone (MSISDN) est affiché au client et utilisé pour le routage.
Tâche 5 : Générer un UUID de Service
- name: Generate UUID Fact
set_fact:
uuid: "{{ 99999999 | random | to_uuid }}"
- name: Set Service UUID
set_fact:
service_uuid: "Local_Mobile_SIM_{{ uuid[0:8] }}"
Ce que Cela Fait :
- Génère un UUID aléatoire.
- Crée un service_uuid comme
Local_Mobile_SIM_a3f2c1d8.
Pourquoi :
- Le UUID de service est l'identifiant unique dans OCS/CGRateS.
- Utilisé pour toutes les opérations de facturation.
- Doit être globalement unique à travers tous les services.
Tâche 6 : Créer un Compte OCS
- name: Create account in OCS
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
headers:
Content-Type: "application/json"
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"ActionPlanIds": [],
"ExtraOptions": {
"AllowNegative": false,
"Disabled": false
},
"ReloadScheduler": true
}]
}
register: ocs_create_response
Ce que Cela Fait :
- Appelle l'API JSON-RPC de CGRateS.
- Crée un nouveau compte avec service_uuid.
- Définit le compte comme actif (non désactivé).
- Empêche le solde négatif (mode prépayé).
Pourquoi :
- Le compte OCS est où toutes les opérations de facturation se produisent.
- Les soldes (données, voix, SMS, argent) sont stockés ici.
- L'utilisation est suivie et évaluée en temps réel.
Tâche 7 : Ajouter un Solde de Données
- name: Add 20GB Data Balance
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"BalanceType": "*data",
"Balance": {
"ID": "DATA_20GB_Monthly",
"Value": 21474836480,
"ExpiryTime": "+720h",
"Weight": 10,
"DestinationIDs": "*any"
}
}]
}
Ce que Cela Fait :
- Ajoute un solde de données de 20 Go au compte.
- Valeur : 21474836480 octets (20 * 1024 * 1024 * 1024).
- Expire dans 720 heures (30 jours).
- Poids 10 (poids plus élevé consommé en premier).
Tâche 8 : Ajouter Voix Illimitée & SMS
- name: Add Unlimited Voice
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Account": "{{ service_uuid }}",
"BalanceType": "*voice",
"Balance": {
"ID": "VOICE_Unlimited",
"Value": 999999999,
"ExpiryTime": "+720h"
}
}]
}
- Ajoute 999 999 999 secondes de voix (essentiellement illimité).
- Expire dans 30 jours.
Tâche 9 : Créer un Enregistrement de Service dans le CRM
- name: Add Service via API
uri:
url: "{{ crm_config.crm.base_url }}/crm/service/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"product_id": "{{ product_id }}",
"service_name": "Mobile - {{ phone_number }}",
"service_type": "mobile",
"service_uuid": "{{ service_uuid }}",
"service_status": "Active",
"service_provisioned_date": "{{ provision_datetime }}",
"retail_cost": "{{ monthly_cost }}",
"wholesale_cost": "{{ api_response_product.json.wholesale_cost }}",
"icon": "fa-solid fa-sim-card"
}
register: service_creation_response
Ce que Cela Crée :
- Enregistrement de service lié au client.
- Lien vers OCS via
service_uuid. - Stocke les coûts de détail et de gros.
- Définit le statut sur "Actif".
- Retourne
service_idpour les opérations suivantes.
Tâche 10 : Assigner l'Inventaire au Service
- name: Assign SIM Card to Service
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"service_id": "{{ service_creation_response.json.service_id }}",
"customer_id": "{{ customer_id }}",
"item_state": "Assigned"
}
Ce que Cela Fait :
- Met à jour l'enregistrement d'inventaire de la carte SIM.
- Définit
service_idpour lier la SIM au service. - Change l'état de "In Stock" à "Assigned".
- Répète pour l'inventaire du numéro mobile.
Pourquoi :
- Suit quelle SIM est attribuée à quel client.
- Empêche la double attribution de l'inventaire.
- Permet le reporting et l'audit de l'inventaire.
Tâche 11 : Enregistrer la Transaction de Coût de Mise en Place
- name: Add Setup Cost Transaction
uri:
url: "{{ crm_config.crm.base_url }}/crm/transaction/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_creation_response.json.service_id }}",
"title": "{{ package_name }} - Setup",
"description": "Activation fee",
"retail_cost": "{{ setup_cost }}",
"wholesale_cost": "{{ api_response_product.json.wholesale_setup_cost }}"
}
Ce que Cela Fait :
- Enregistre des frais de mise en place de £0.00 au client (détail).
- Enregistre un coût de gros de £1.00.
- Crée un enregistrement de transaction pour la facturation.
Tâche 12 : Bloc de Secours (Gestion des Erreurs)
rescue:
- name: Remove account in OCS on failure
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.RemoveAccount",
"params": [{
"Account": "{{ service_uuid }}"
}]
}
- name: Fail the provisioning
fail:
msg: "Provisioning failed, rolled back OCS account"
Ce que Cela Fait :
- Si une tâche échoue, le bloc de secours s'exécute.
- Supprime le compte OCS qui a été partiellement créé.
- Libère l'inventaire en "In Stock".
- Échoue le job de provisionnement avec un message d'erreur.
Pourquoi :
- Empêche les comptes orphelins dans OCS.
- Assure un rollback propre en cas d'erreurs.
- Maintient la cohérence des données.
Provisionnement Complet : Ce Qui a Été Créé
Après un provisionnement réussi, le système a :
1. Compte OCS (CGRateS) :
- ID de Compte :
Local_Mobile_SIM_a3f2c1d8. - Soldes :
- 20 Go de données (expire dans 30 jours).
- Voix illimitée (999M secondes, expire dans 30 jours).
- SMS illimités (999M messages, expire dans 30 jours).
2. Enregistrement de Service CRM :
- ID de Service : 1234.
- Client : John Doe (customer_id: 123).
- Produit : Prepaid Mobile 20GB (product_id: 42).
- Nom du Service : "Mobile - +44 7700 900123".
- UUID de Service :
Local_Mobile_SIM_a3f2c1d8. - Statut : Actif.
- Coût Mensuel : £15.00 (détail), £5.00 (gros).
- Profit : £10.00/mois.
3. Assignations d'Inventaire :
- Carte SIM 5001 : Assignée au service 1234, client 123.
- Numéro Mobile 5002 : Assigné au service 1234, client 123.
4. Enregistrements de Transaction :
- Transaction de coût de mise en place créée.
- Charge du premier mois enregistrée.
5. Le Client Peut Maintenant :
- Voir le service dans le portail de libre-service.
- Voir le solde de 20 Go de données.
- Passer des appels et envoyer des SMS.
- Recharger ou ajouter des addons.
- Voir l'utilisation en temps réel.
Étape 3 : Ajout d'Addons et de Recharges
Après qu'un service est actif, les clients peuvent acheter des addons pour améliorer leur service.
Flux de Provisionnement des Addons
Disons que le client a utilisé 18 Go de son allocation de 20 Go et souhaite acheter l'addon "5GB Data Boost".
1. Le Client Navigue vers le Service
- Ouvre la page de service "Mobile - +44 7700 900123".
- Voit l'utilisation actuelle : 18 Go sur 20 Go utilisés (90 %).
- Clique sur "Ajouter un Addon" ou "Recharger".
2. Le Système Filtre les Addons Disponibles
Montre uniquement les addons où :
category = "addon".service_type = "mobile"(correspond au type de service).residential = true(si le client est résident).enabled = true.
Le client voit : "5GB Data Boost - £5.00".
3. Le Client Sélectionne l'Addon
- Clique sur "5GB Data Boost".
- Confirme l'achat pour £5.00.
- Le système capture l'autorisation de paiement.
4. Provisionnement de l'Addon Initié
Le système appelle play_topup_charge_then_action.yaml avec les variables :
{
"product_id": 43, # Produit 5GB Data Boost
"customer_id": 123,
"service_id": 1234, # Service existant
"access_token": "eyJ...",
"data_gb": 5, # À partir de provisioning_json_vars
"days": 7 # À partir de provisioning_json_vars
}
Différence Clé par Rapport à Autonome :
service_idest inclus (service existant à modifier).- Aucun inventaire requis.
- Pas de création de service (modifie l'existant).
Examen du Playbook de Provisionnement des Addons
Tâche 1 : Récupérer les Détails du Service
- name: Get Service information from CRM API
uri:
url: "http://localhost:5000/crm/service/service_id/{{ service_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_service
- name: Set service facts
set_fact:
service_uuid: "{{ api_response_service.json.service_uuid }}"
customer_id: "{{ api_response_service.json.customer_id }}"
Pourquoi :
- Besoin de
service_uuidpour ajouter un solde au bon compte OCS. - Vérifie que le service existe et est actif.
- Assure que le service appartient au client.
Tâche 2 : Facturer le Client
- name: Get Customer's Default Payment Method
uri:
url: "http://localhost:5000/crm/stripe/customer_id/{{ customer_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_stripe
- name: Get default card ID
set_fact:
customer_stripe_id: "{{ api_response_stripe.json | json_query(query) }}"
vars:
query: "data[?default_payment_method==`true`].customer_stripe_id | [0]"
- name: Charge card
uri:
url: "http://localhost:5000/crm/stripe/charge_card/{{ customer_stripe_id }}"
method: POST
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"retail_cost": 5.00,
"description": "5GB Data Boost",
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_id }}",
"product_id": "{{ product_id }}",
"wholesale_cost": 1.50,
"invoice": true
}
register: charge_response
- name: Assert payment successful
assert:
that:
- charge_response.status == 200
Ce que Cela Fait :
- Trouve la méthode de paiement par défaut du client sur Stripe.
- Facture £5.00 à la carte.
- Enregistre un coût de gros de £1.50 pour le suivi des marges.
- Crée une transaction liée au service.
- Ajoute à la prochaine facture.
- Échoue le provisionnement si le paiement échoue.
Pourquoi Facturer D'abord :
- Aucun crédit livré jusqu'à ce que le paiement soit confirmé.
- Empêche la fraude.
- Associe le paiement à la provision de l'addon.
Tâche 3 : Ajouter un Solde de Données à OCS
- name: Add 5GB Data Balance
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Account": "{{ service_uuid }}",
"BalanceType": "*data",
"Balance": {
"ID": "DATA_5GB_Boost_{{ uuid }}",
"Value": 5368709120,
"ExpiryTime": "+168h",
"Weight": 20
}
}]
}
Ce que Cela Fait :
- Ajoute 5 Go (5368709120 octets) au compte.
- Expire dans 168 heures (7 jours).
- Poids 20 (poids plus élevé consommé en premier - boost avant l'allocation mensuelle).
Solde du Client Après l'Addon :
- Mensuel d'origine : 2 Go restants (expire dans 25 jours).
- Nouveau boost : 5 Go (expire dans 7 jours).
- Total disponible : 7 Go.
- Ordre d'utilisation : Boost consommé en premier, puis mensuel.
Tâche 4 : Enregistrer la Transaction
- name: Add Addon Transaction
uri:
url: "http://localhost:5000/crm/transaction/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_id }}",
"title": "5GB Data Boost",
"description": "Additional 5GB data valid for 7 days",
"retail_cost": 5.00,
"wholesale_cost": 1.50
}
Ce que Cela Fait :
- Enregistre une charge de £5.00 au client.
- Enregistre un coût de gros de £1.50.
- Lie la transaction au service pour le reporting.
Résumé Complet du Flux d'Addon
- Le client sélectionne l'addon dans la liste filtrée.
- Paiement autorisé et facturé.
- Solde de données ajouté au compte OCS.
- Transaction enregistrée dans le CRM.
- Le client voit immédiatement le solde mis à jour : 7 Go disponibles.
Suivi Financier :
- Charge mensuelle du service : £15 détail, £5 gros.
- Achat d'addon : £5 détail, £1.50 gros.
Renouvellement Automatique : Addons Récurrents
Certains addons peuvent être configurés pour se renouveler automatiquement (forfaits de données mensuels, abonnements, etc.).
Configuration du Produit :
{
"product_name": "Monthly 10GB Data Plan",
"category": "addon",
"retail_cost": 10.00,
"contract_days": 30,
"auto_renew": "true",
"provisioning_play": "play_topup_charge_then_action"
}
Le Provisionnement Crée un Plan d'Action :
- name: Create ActionPlan for Auto-Renewal
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV1.SetActionPlan",
"params": [{
"Id": "ServiceID_{{ service_uuid }}__ProductID_{{ product_id }}__MonthlyRenewal",
"ActionPlan": [{
"ActionsId": "Action_{{ product_slug }}",
"Years": "*any",
"Months": "*any",
"MonthDays": "*any",
"WeekDays": "*any",
"Time": "00:00:00",
"Weight": 10
}],
"Overwrite": false,
"ReloadScheduler": true
}]
}
Ce que Cela Fait :
- Crée une tâche planifiée dans OCS.
- Exécute
Action_{{ product_slug }}tous les 30 jours. - L'action facture le client et réapplique le solde de données.
- Continue jusqu'à ce que le client annule.
Gestion des Clients :
- Le client voit "Prochain Renouvellement : 1er Février 2025 - £10.00" dans la vue du service.
- Peut cliquer sur "Annuler le Renouvellement Automatique" pour arrêter les frais futurs.
- Peut cliquer sur "Renouveler Maintenant" pour appliquer immédiatement l'allocation du mois suivant.
Étape 4 : Déprovisionnement des Services
Lorsqu'un client annule un service, le système doit retirer proprement toutes les ressources.
Déprovisionnement des Déclencheurs
Le déprovisionnement peut être déclenché par :
- Annulation du client - Le client clique sur "Annuler le Service".
- Action administrative - Le personnel marque le service pour désactivation.
- Non-paiement - Le service expire en raison d'un manque de renouvellement.
- Fin de contrat - Le contrat à durée fixe atteint sa date de fin.
Flux de Déprovisionnement
1. Le Client Initie l'Annulation
- Navigue vers le service.
- Clique sur "Annuler le Service".
- Le système demande : "Êtes-vous sûr ? Tout solde restant sera perdu."
- Le client confirme.
2. Période de Grâce (Optionnelle)
Certains opérateurs mettent en œuvre une période de grâce :
- Service marqué "Annulation en Attente".
- Reste actif pendant 7 à 30 jours.
- Le client peut inverser l'annulation pendant la période de grâce.
- Déprovisionnement automatique après la période de grâce.
3. Job de Déprovisionnement Créé
Le système crée un job de provisionnement avec :
{
"action": "deprovision",
"service_id": 1234,
"customer_id": 123,
"service_uuid": "Local_Mobile_SIM_a3f2c1d8"
}
Appelle le playbook spécifié dans service.deprovisioning_play ou le bloc de secours du playbook original.
4. Playbook de Déprovisionnement Ansible
- name: Deprovision Mobile Service
hosts: localhost
tasks:
- name: Disable OCS Account
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Account": "{{ service_uuid }}",
"ExtraOptions": { "Disabled": true }
}]
}
- name: Remove ActionPlans (stop auto-renewals)
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV1.RemoveActionPlan",
"params": [{
"Id": "ServiceID_{{ service_uuid }}__*"
}]
}
- name: Update Service Status in CRM
uri:
url: "http://localhost:5000/crm/service/{{ service_id }}"
method: PATCH
body:
{
"service_status": "Deactivated",
"service_deactivate_date": "{{ current_datetime }}"
}
- name: Release Inventory to Stock
uri:
url: "http://localhost:5000/crm/inventory/inventory_id/{{ sim_card_id }}"
method: PATCH
body:
{
"service_id": null,
"customer_id": null,
"item_state": "Decommissioned"
}
Ce que Cela Fait :
- Désactive le compte OCS - Arrête toutes les facturations, utilisation bloquée.
- Supprime les ActionPlans - Annule les renouvellements automatiques.
- Met à Jour le Service CRM - Statut "Désactivé", date enregistrée.
- Libère l'inventaire - SIM marquée "Désaffectée", disponible pour réutilisation (après remise à neuf).
5. Post-Déprovisionnement
Le système effectue le nettoyage :
- Le client ne voit plus le service dans le portail de libre-service.
- Le service reste dans le CRM pour le reporting historique.
- Transactions et factures préservées pour la comptabilité.
- L'inventaire peut être remis à neuf et réutilisé.
- Le compte OCS peut être archivé après la période de conservation.
Déprovisionnement Partiel vs Complet
Déprovisionnement Partiel (Suspension) :
- Utilisé pour non-paiement ou suspension temporaire.
- Compte OCS désactivé mais non supprimé.
- Soldes préservés.
- Peut être réactivé lorsque le paiement est reçu.
- name: