Aller au contenu principal

Personnalisation et Configuration

Ce guide explique comment personnaliser et configurer OmniCRM pour correspondre à votre identité de marque, vos exigences opérationnelles et vos besoins d'intégration.

Variables d'environnement (.env)

OmniCRM utilise des variables d'environnement pour configurer à la fois l'API backend et l'interface utilisateur frontend. Il existe deux fichiers .env distincts qui contrôlent différents aspects du système.

Configuration de l'API Backend (.env)

Situé à la racine du répertoire OmniCRM, ce fichier configure les connexions à la base de données et l'intégration CGRates.

Emplacement : /OmniCRM/.env

Configuration de la base de données :

# Base de données MySQL/MariaDB (données CRM)
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_USER=omnitouch
MYSQL_PASSWORD=your_database_password
MYSQL_DATABASE=crm
DB_SERVER=db

# Base de données PostgreSQL (données CGRates)
POSTGRES_USER=cgrates
POSTGRES_PASSWORD=cgrates_password
POSTGRES_DB=cgrates_db

Configuration CGRates :

# Identifiants API CGRates
CGRATES_API_USER=admin
CGRATES_API_PASS=secret
CGRATES_DB_USER=cgrates
CGRATES_DB_PASS=cgrates_password
CGRATES_DB_NAME=cgrates_db
CGRATES_DB_PORT=5432

Considérations de sécurité :

  • Ne jamais commettre de fichiers .env dans le contrôle de version - Utilisez .env.example comme modèle
  • Utilisez des mots de passe forts - Minimum 16 caractères avec des majuscules, des chiffres et des symboles
  • Faites tourner régulièrement les identifiants - Surtout pour les déploiements en production
  • Restreindre l'accès à la base de données - Utilisez le filtrage IP et les règles de pare-feu

Configuration de l'UI Frontend (.env)

Situé dans le répertoire OmniCRM-UI, ce fichier contrôle la marque, l'apparence, les intégrations et les fonctionnalités.

Emplacement : /OmniCRM/OmniCRM-UI/.env

Clés API et intégration :

# API Google Maps (pour l'autocomplétion d'adresse et la géocodage)
REACT_APP_GOOGLE_API_KEY=your_google_api_key

# Passerelle de paiement Stripe
REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx

# Désactiver le lancement automatique du navigateur lors de npm start
BROWSER=none

Informations sur la marque et l'entreprise :

# Marque de l'entreprise
REACT_APP_COMPANY_NAME="ShellFone"
REACT_APP_PORTAL_NAME="ShellManager"
REACT_APP_SELF_CARE_NAME="ShellCare"
REACT_APP_COMPANY_TAGLINE="Phones with Shells"

Ces valeurs apparaissent dans toute l'interface utilisateur :

  • COMPANY_NAME - Affiché dans les titres de page, les e-mails et les communications avec les clients
  • PORTAL_NAME - Nom du portail admin/personnel (par exemple, "ShellManager")
  • SELF_CARE_NAME - Nom du portail de libre-service client (par exemple, "ShellCare")
  • COMPANY_TAGLINE - Apparaît dans les écrans de connexion et les supports marketing

Localisation et paramètres régionaux :

# Langue et locale
# Langues prises en charge : ar, ch, en, fr, gr, it, ru, sp
REACT_APP_DEFAULT_LANGUAGE=en
REACT_APP_LOCALE="en-GB"

# Emplacement par défaut (pour l'autocomplétion d'adresse)
REACT_APP_DEFAULT_LOCATION="Sydney, Australia"
REACT_APP_DEFAULT_COUNTRY="Australia"

# Paramètres de devise
REACT_APP_CURRENCY_CODE="GBP"
REACT_APP_CURRENCY_SYMBOL="£"

Personnalisation du schéma de couleurs :

# Couleur primaire (couleur principale de la marque)
REACT_APP_PRIMARY_COLOR=#405189

# Options de couleur supplémentaires (exemples commentés)
# REACT_APP_SECONDARY_COLOR=#2bFFcf
# REACT_APP_TERTIARY_COLOR=#1a9fbf
# REACT_APP_SUCCESS_COLOR=#28a745
# REACT_APP_INFO_COLOR=#17a2b8
# REACT_APP_WARNING_COLOR=#ffc107
# REACT_APP_DANGER_COLOR=#dc3545

La couleur primaire est appliquée à :

  • En-têtes de navigation
  • Boutons d'action
  • Liens et mises en évidence
  • États actifs
  • Éléments de marque

Intégrations d'applications Web :

Configurez jusqu'à 6 applications Web à accès rapide qui apparaissent dans le tableau de bord admin :

# Application Web 1 : GitHub
REACT_APP_WEB_APP_1_NAME="GitHub"
REACT_APP_WEB_APP_1_URL="https://github.com"
REACT_APP_WEB_APP_1_ICON_PATH="resources/webapp_icons/github.png"

# Application Web 2 : Xero
REACT_APP_WEB_APP_2_NAME="Xero"
REACT_APP_WEB_APP_2_URL="https://go.xero.com/"
REACT_APP_WEB_APP_2_ICON_PATH="resources/webapp_icons/xero.png"

# Application Web 3-6 : Intégrations supplémentaires
# (Configurer de manière similaire avec NAME, URL et ICON_PATH)

Surveillance et analyses :

# Intégration du tableau de bord Grafana
REACT_APP_GRAFANA_URLS=url1,url2,url3
REACT_APP_GRAFANA_LABELS=label1,label2,label3
REACT_APP_GRAFANA_API_KEY=your-api-key

Drapeaux de fonctionnalités :

# URL de support et de documentation
REACT_APP_FAQS_URL=https://docs.yourcompany.com/faqs
REACT_APP_SUPPORT_URL=https://support.yourcompany.com

# Connexion sociale (Google, Facebook, etc.)
REACT_APP_ALLOW_SOCIAL_LOGINS=yes

Personnalisation du logo et de l'image de démarrage

OmniCRM vous permet de remplacer les images de marque par défaut par le logo de votre entreprise et des écrans de démarrage sans modifier le code.

Les logos sont stockés dans /OmniCRM-UI/src/assets/images/omnitouch/ et utilisent un système de secours :

Logos par défaut (toujours présents) :

  • DefaultLogoDark.png - Logo thème sombre (utilisé sur des fonds clairs)
  • DefaultLogoLight.png - Logo thème clair (utilisé sur des fonds sombres)

Logos personnalisés (optionnels, prennent la priorité lorsqu'ils sont présents) :

  • logoSm.png - Petit logo pour la barre latérale réduite (recommandé : 100x100px)
  • logoDark.png - Logo sombre de taille normale pour les en-têtes (recommandé : 200x50px)
  • logoLight.png - Logo clair de taille normale pour les écrans d'authentification (recommandé : 200x50px)

Comment fonctionne le secours de logo :

Le système tente de charger d'abord les logos personnalisés. Si un fichier de logo personnalisé n'existe pas, il revient au logo par défaut :

// Dans Header.js
const tryImport = (filename) => {
try {
return require(`../assets/images/omnitouch/${filename}`);
} catch (err) {
return null; // Retourne au défaut
}
};

const userLogoSm = tryImport("logoSm.png");
const userLogoDark = tryImport("logoDark.png");
const userLogoLight = tryImport("logoLight.png");

Où apparaissent les logos :

  • logoSm.png - Barre latérale réduite, navigation mobile, affichages de petit en-tête
  • logoDark.png - Barre d'en-tête principale (mode clair), en-tête du tableau de bord admin
  • logoLight.png - Écrans de connexion/enregistrement, fonds sombres, carrousel d'authentification

Remplacer les logos :

  1. Créez vos fichiers de logo :

    • Utilisez le format PNG pour le support de la transparence
    • Correspondre aux dimensions recommandées ci-dessus
    • Assurez-vous que les logos sont clairs à la fois en résolution normale et en haute résolution
  2. Ajoutez à OmniCRM :

    # Copiez vos fichiers de logo dans le répertoire d'images omnitouch
    cp /path/to/your/logoSm.png OmniCRM-UI/src/assets/images/omnitouch/
    cp /path/to/your/logoDark.png OmniCRM-UI/src/assets/images/omnitouch/
    cp /path/to/your/logoLight.png OmniCRM-UI/src/assets/images/omnitouch/
  3. Reconstruisez l'UI :

    cd OmniCRM-UI
    npm run build
  4. Vérifiez les changements :

    • Vérifiez l'en-tête en mode clair (devrait afficher logoDark.png)
    • Vérifiez l'en-tête en mode sombre (devrait afficher logoLight.png)
    • Vérifiez la barre latérale réduite (devrait afficher logoSm.png)
    • Vérifiez l'écran de connexion (devrait afficher logoLight.png)

Meilleures pratiques de conception de logo :

  • Contraste - Assurez-vous que les logos sont visibles sur des fonds clairs et sombres
  • Simplicité - Les logos doivent être reconnaissables à des tailles réduites
  • Format - Utilisez PNG avec des fonds transparents
  • Retina - Fournir une résolution 2x pour les écrans haute DPI
  • Cohérence - Utilisez les mêmes couleurs de marque dans toutes les variantes de logo

Écrans de démarrage et arrière-plans d'authentification

Les écrans d'authentification (connexion, enregistrement, réinitialisation de mot de passe) utilisent un arrière-plan carrousel avec des images personnalisables.

Emplacement : /OmniCRM-UI/src/pages/AuthenticationInner/authCarousel.js

Configuration par défaut :

import logoLight from "../../assets/images/logo-light.png";

// Logo affiché sur les écrans d'authentification
<img src={logoLight} alt="" height="18" />

Personnaliser les écrans d'authentification :

  1. Remplacez logo-light.png dans /OmniCRM-UI/src/assets/images/
  2. Ajoutez un CSS d'arrière-plan personnalisé à la classe .auth-one-bg
  3. Modifiez les citations du carrousel dans authCarousel.js pour correspondre à votre voix de marque

Exemple de personnalisation :

/* Ajoutez à votre CSS personnalisé */
.auth-one-bg {
background-image: url('/assets/images/custom-auth-bg.jpg');
background-size: cover;
background-position: center;
}

Fichier de configuration CRM (crm_config.yaml)

Le fichier crm_config.yaml est la configuration centrale pour l'API OmniCRM, contrôlant les intégrations, le provisionnement, les modèles d'e-mails et les services externes.

Emplacement : /OmniCRM/OmniCRM-API/crm_config.yaml

Configuration de la base de données

database:
username: omnitouch
password: omnitouch2024
server: localhost

Remarque : Cela doit correspondre à vos identifiants de base de données .env. Dans les déploiements conteneurisés, le serveur est généralement db (nom du service Docker).

Types de service

Définissez les types de service valides pour votre déploiement :

service_types:
- omnicharge
- mobile
- fixed
- fixed-voice
- hotspot
- dongle

Ceux-ci sont utilisés dans tout le système pour :

  • Catégorisation des produits
  • Filtrage des addons (les addons correspondent aux types de service)
  • Flux de travail de provisionnement
  • Rapports et analyses

Intégration HSS (Home Subscriber Server)

Pour les opérateurs de réseau mobile avec intégration HSS :

hss:
hss_peers:
- 'http://10.179.2.140:8080'
apn_list: "1,2,3,4,5,6"

Configuration :

  • hss_peers - Liste des points de terminaison HSS pour le provisionnement des abonnés
  • apn_list - Liste d'IDs APN séparés par des virgules disponibles pour le provisionnement

Configuration du modèle d'e-mail Mailjet

OmniCRM utilise Mailjet pour les e-mails transactionnels. Chaque type d'e-mail a sa propre configuration de modèle :

mailjet:
api_key: your_mailjet_api_key
api_secret: your_mailjet_api_secret

# E-mail de bienvenue client
api_crmCommunicationCustomerWelcome:
from_email: "support@yourcompany.com"
from_name: "Votre support d'entreprise"
template_id: 5977509
subject: "Bienvenue chez YourCompany"

# E-mail de facture client
api_crmCommunicationCustomerInvoice:
from_email: "billing@yourcompany.com"
from_name: "Votre facturation d'entreprise"
template_id: 6759851
subject: "Votre facture - "

# Rappel de facture
api_crmCommunicationCustomerInvoiceReminder:
from_email: "billing@yourcompany.com"
from_name: "Votre facturation d'entreprise"
template_id: 5977570
subject: "Rappel de paiement de facture"

# E-mail de bienvenue utilisateur (Personnel/Admin)
api_crmCommunicationUserWelcome:
from_email: "admin@yourcompany.com"
from_name: "Votre admin d'entreprise"
template_id: 6118112
subject: "Bienvenue dans l'équipe"

# Demande de réinitialisation de mot de passe
api_crmCommunicationUserPasswordReset:
from_email: "security@yourcompany.com"
from_name: "Votre sécurité d'entreprise"
template_id: 6735666
subject: "Demande de réinitialisation de mot de passe"

# Confirmation de succès de réinitialisation de mot de passe
api_crmCommunicationUserPasswordResetSuccess:
from_email: "security@yourcompany.com"
from_name: "Votre sécurité d'entreprise"
template_id: 6118378
subject: "Réinitialisation de mot de passe réussie"

# Notification de changement de mot de passe
api_crmCommunicationUserPasswordChange:
from_email: "security@yourcompany.com"
from_name: "Votre sécurité d'entreprise"
template_id: 6118423
subject: "Mot de passe changé"

# Vérification de l'e-mail
api_crmCommunicationEmailVerification:
from_email: "verify@yourcompany.com"
from_name: "Votre vérification d'entreprise"
template_id: 6267350
subject: "Vérifiez votre adresse e-mail"

# Notification d'expiration de solde
api_crmCommunicationsBalanceExpired:
from_email: "alerts@yourcompany.com"
from_name: "Vos alertes d'entreprise"
template_id: 7238252
subject: "Solde de service expiré"

# Alerte de solde faible
api_crmCommunicationsBalanceLow:
from_email: "alerts@yourcompany.com"
from_name: "Vos alertes d'entreprise"
template_id: 7238263
subject: "Alerte de solde faible"

Création de modèles Mailjet :

  1. Connectez-vous au tableau de bord Mailjet (<https://app.mailjet.com>)
  2. Accédez à TransactionnelModèles
  3. Créez un nouveau modèle ou clonez un modèle existant
  4. Notez l'ID du modèle (valeur numérique)
  5. Ajoutez des variables de modèle correspondant à la structure de données OmniCRM
  6. Mettez à jour crm_config.yaml avec l'ID du modèle

Variables de modèle disponibles :

Chaque type d'e-mail reçoit des variables spécifiques. Exemples courants :

  • {{customer_name}} - Nom du client ou de l'utilisateur
  • {{service_name}} - Nom du service ou du produit
  • {{invoice_id}} - Numéro de facture
  • {{invoice_amount}} - Montant total de la facture
  • {{due_date}} - Date d'échéance du paiement
  • {{reset_link}} - URL de réinitialisation de mot de passe
  • {{verification_link}} - URL de vérification de l'e-mail
  • {{balance}} - Solde actuel du compte
  • {{expiry_date}} - Date d'expiration du solde ou du service

Configuration de provisionnement

provisioning:
failure_list: ['admin@yourcompany.com', 'ops@yourcompany.com']

But :

  • failure_list - Adresses e-mail notifiées lorsque le provisionnement Ansible échoue
  • Les notifications incluent le nom du playbook, les détails de l'erreur et les informations sur le client
  • Permet à l'équipe des opérations de répondre rapidement aux problèmes de provisionnement

Configuration de la facture

invoice:
template_filename: 'yourcompany_invoice_template.html'

But :

Spécifie quel modèle HTML Jinja2 utiliser pour la génération de factures PDF.

Emplacement du modèle : /OmniCRM-API/invoice_templates/

Voir la section Génération de PDF de facture ci-dessous pour des détails sur la création de modèles personnalisés.

URL de base CRM

crm:
base_url: 'http://localhost:5000'

But :

  • Utilisé par les playbooks Ansible pour effectuer des rappels API
  • Utilisé dans les modèles d'e-mails pour générer des liens vers le CRM
  • Doit être l'URL accessible publiquement de votre API (pas de noms de conteneur internes)

Exemples :

  • Développement : http://localhost:5000
  • Production : https://api.yourcompany.com
  • Docker : http://omnicrm-api:5000 (communication interne entre conteneurs)

Configuration OCS et CGRates

ocs:
ocsApi: 'http://10.179.2.142:8080/api'
ocsTenant: 'mnc380.mcc313.3gppnetwork.org'
cgrates: 'localhost:2080'

Configuration :

  • ocsApi - Point de terminaison API OCS pour la gestion des abonnés
  • ocsTenant - Identifiant de locataire pour les déploiements OCS multi-locataires
  • cgrates - Point de terminaison API JSON-RPC CGRates (hôte:port)

Configuration SMSC (Passerelle SMS)

smsc:
source_msisdn: 'YourCompany'
smsc_url: 'http://10.179.2.216/SMSc/'
api_key: 'your_smsc_api_key'

But :

  • Envoyer des notifications SMS aux clients (solde faible, alertes de service, codes 2FA)
  • source_msisdn - ID de l'expéditeur affiché aux destinataires (alphanumérique ou numéro de téléphone)
  • smsc_url - Point de terminaison API de la passerelle SMSC
  • api_key - Authentification pour l'API SMSC

Clé secrète JWT

jwt_secret: '2b93110f723db60172c8e9a1eaa80027a9a9c3f05b44e50dc3fcf38dba68d87e'

Sécurité :

  • Utilisé pour signer et vérifier les jetons d'authentification
  • DOIT être changé de la valeur par défaut en production
  • Générez une chaîne aléatoire sécurisée (minimum 64 caractères)
  • Ne jamais partager ou commettre dans le contrôle de version

Génération d'un nouveau secret JWT :

# Générer une clé aléatoire cryptographiquement sécurisée
python3 -c "import secrets; print(secrets.token_hex(32))"

Configuration de paiement Stripe

stripe:
secret_key: 'sk_live_xxxxxxxxxx'
publishable_key: 'pk_live_xxxxxxxxxx'
currency: 'aud'
statement_descriptor_suffix: 'YOURCOMPANY'

Configuration :

  • secret_key - Clé API secrète Stripe (côté serveur, à garder confidentielle)
  • publishable_key - Clé publique Stripe (côté client, sûr à exposer)
  • currency - Code de devise ISO 4217 (aud, usd, gbp, eur, etc.)
  • statement_descriptor_suffix - Apparaît sur les relevés de carte de crédit des clients

Utilisation du descripteur de relevé :

  • Affiché sur les relevés bancaires des clients comme "YOURCOMPANY"
  • Maximum 22 caractères
  • Aide les clients à identifier les frais
  • Utilisé également dans les noms de fichiers PDF de facture (par exemple, YOURCOMPANY_12345.pdf)

Clés API et filtrage IP

Définissez des clés API avec accès basé sur les rôles et restrictions IP :

api_keys:
"YOUR_API_KEY_1":
roles: ["admin"]
ips: ["127.0.0.1", "::1"]
"YOUR_API_KEY_2":
roles: ["customer_service_agent_1"]
ips: ["127.0.0.1", "::1", "10.0.1.0/24"]

# Liste blanche IP (autonome, sans clé API)
ip_whitelist:
"10.179.2.142":
roles: ["admin"]

But :

  • Permettre aux systèmes externes de s'authentifier via la clé API
  • Restreindre l'accès par adresse IP
  • Accorder des rôles spécifiques aux consommateurs d'API
  • Utile pour les intégrations (systèmes de facturation, surveillance, automatisation)

Meilleures pratiques de sécurité :

  • Utilisez des clés API longues et aléatoires (minimum 32 caractères)
  • Restreindre les IP à des sources connues uniquement
  • Accorder les rôles minimaux nécessaires
  • Faire tourner les clés API régulièrement
  • Surveiller l'utilisation des clés API dans les journaux

Génération de PDF de facture

OmniCRM génère des factures PDF professionnelles à l'aide de modèles HTML Jinja2 et du rendu PDF WeasyPrint.

Comment fonctionne la génération de PDF

  1. Sélection de modèle :
    • Le nom du fichier modèle est spécifié dans crm_config.yaml sous invoice.template_filename
    • Le modèle est chargé depuis le répertoire /OmniCRM-API/invoice_templates/
  2. Préparation des données :
    • Les données de la facture (ID, dates, montants, statut) sont récupérées depuis la base de données
    • Les informations sur le client (nom, adresse) sont récupérées
    • La liste des transactions est compilée (tous les frais/crédits sur la facture)
  3. Rendu du modèle :
    • Jinja2 rend le modèle HTML avec les données de la facture
    • Les variables comme {{ invoice_number }}, {{ total_amount }}, etc. sont remplacées
    • Le HTML rendu est enregistré dans invoice_templates/rendered/ pour le débogage
  4. Génération de PDF :
    • WeasyPrint convertit le HTML rendu en PDF
    • Le PDF prend en charge le style CSS, les images, les sauts de page, les en-têtes/pieds de page
    • Les données binaires PDF sont générées en mémoire
  5. Mise en cache :
    • Le PDF est encodé en Base64 et stocké dans la table Invoice_PDF_Cache
    • Un hachage SHA256 est calculé pour la vérification de l'intégrité
    • Les demandes ultérieures retournent le PDF mis en cache (livraison instantanée)
  6. Invalidation du cache :
    • Le cache est invalidé lorsque la facture est modifiée, annulée ou remboursée
    • Les changements de modèle n'invalident pas automatiquement les caches existants

Structure du modèle de facture

Les modèles de facture sont des fichiers HTML Jinja2 avec des variables et de la logique intégrées.

Emplacement du modèle : /OmniCRM-API/invoice_templates/yourcompany_invoice_template.html

Variables disponibles :

{
'invoice_number': 12345,
'date': '2025-01-04',
'client': {
'name': 'John Smith',
'address': {
'address_line_1': '123 Main St',
'city': 'Sydney',
'state': 'NSW',
'zip_code': '2000',
'country': 'Australia'
}
},
'transaction_list': [
[
{
'transaction_id': 1,
'title': 'Mobile Service - Monthly Fee',
'retail_cost': 30.00,
'wholesale_cost': 10.00,
'created': '2025-01-01'
},
{
'transaction_id': 2,
'title': 'Data Addon - 5GB',
'retail_cost': 15.00,
'wholesale_cost': 5.00,
'created': '2025-01-15'
}
]
],
'total_amount': 45.00,
'due_date': '2025-01-31',
'start_date': '2025-01-01',
'end_date': '2025-01-31',
'paid': False,
'void': False
}

Extrait de modèle d'exemple :

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Facture {{ invoice_number }}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.invoice-details {
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
th {
background-color: #405189;
color: white;
}
.total {
text-align: right;
font-size: 18px;
font-weight: bold;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="header">
<img src="file:///path/to/logo.png" alt="Logo de l'entreprise" height="60">
<h1>FACTURE</h1>
</div>

<div class="invoice-details">
<p><strong>Numéro de facture :</strong> {{ invoice_number }}</p>
<p><strong>Date :</strong> {{ date }}</p>
<p><strong>Date d'échéance :</strong> {{ due_date }}</p>
<p><strong>Période de facturation :</strong> {{ start_date }} à {{ end_date }}</p>
</div>

<div class="customer-details">
<h3>Facturer à :</h3>
<p>{{ client.name }}</p>
<p>{{ client.address.address_line_1 }}</p>
<p>{{ client.address.city }}, {{ client.address.state }} {{ client.address.zip_code }}</p>
<p>{{ client.address.country }}</p>
</div>

<table>
<thead>
<tr>
<th>Description</th>
<th>Date</th>
<th>Montant</th>
</tr>
</thead>
<tbody>
{% for transaction in transaction_list[0] %}
<tr>
<td>{{ transaction.title }}</td>
<td>{{ transaction.created }}</td>
<td>${{ "%.2f"|format(transaction.retail_cost) }}</td>
</tr>
{% endfor %}
</tbody>
</table>

<div class="total">
<p>Montant total dû : ${{ "%.2f"|format(total_amount) }}</p>
</div>

{% if paid %}
<div style="text-align: center; color: green; font-weight: bold;">
PAYÉ
</div>
{% endif %}

{% if void %}
<div style="text-align: center; color: red; font-weight: bold;">
ANNULÉ
</div>
{% endif %}
</body>
</html>

Meilleures pratiques pour les modèles :

  • Utilisez des chemins absolus pour les images - file:///absolute/path/to/image.png
  • CSS en ligne - WeasyPrint ne charge pas de manière fiable les feuilles de style externes
  • Testez avec des données d'exemple - Utilisez invoice_templates/rendered/ pour inspecter le HTML
  • Sauts de page - Utilisez <div style="page-break-after: always;"></div> pour les factures multi-pages
  • En-têtes et pieds de page - Utilisez des règles CSS @page pour les éléments répétitifs
  • Formatage de la devise - Utilisez des filtres Jinja2 : {{ "%.2f"|format(amount) }}

Création d'un modèle de facture personnalisé

  1. Copiez le modèle d'exemple :

    cd /OmniCRM/OmniCRM-API/invoice_templates
    cp norfone_invoice_template.html yourcompany_invoice_template.html
  2. Modifiez le modèle :

    • Remplacez le nom de l'entreprise, le logo, les informations de contact
    • Ajustez le style (couleurs, polices, mise en page) pour correspondre à la marque
    • Ajoutez ou supprimez des sections selon les besoins (détails fiscaux, instructions de paiement, etc.)
  3. Mettez à jour la configuration :

    Modifiez crm_config.yaml :

    invoice:
    template_filename: 'yourcompany_invoice_template.html'
  4. Testez la génération de factures :

    • Créez une facture test dans le CRM
    • Téléchargez le PDF et vérifiez le formatage
    • Vérifiez invoice_templates/rendered/{invoice_id}.html pour le débogage
  5. Invalidation des anciens caches (si nécessaire) :

    Si vous avez changé le modèle et souhaitez régénérer les factures existantes :

    -- Effacer tous les PDF mis en cache (force la régénération)
    DELETE FROM Invoice_PDF_Cache;

Système de mise en cache PDF

Pour améliorer les performances, OmniCRM met en cache les PDF générés :

Comportement du cache :

  • Première demande - Le PDF est généré, mis en cache et retourné
  • Demandes ultérieures - Le PDF mis en cache est retourné immédiatement (pas de régénération)
  • Invalidation du cache - Se produit lorsque la facture est modifiée, annulée ou remboursée
  • Nettoyage du cache - Les anciens caches sont automatiquement purgés après 30 jours d'inactivité

Stockage du cache :

  • PDF encodé en Base64 stocké dans la table Invoice_PDF_Cache
  • Hachage de contenu SHA256 pour la vérification de l'intégrité
  • Inclut le nom de fichier, l'horodatage de création, l'horodatage de dernier accès

Gestion manuelle du cache :

# Dans l'API OmniCRM ou le shell Python
from services.invoice_service import cleanup_old_pdf_cache, invalidate_invoice_cache
from utils.db_helpers import get_db_session

session = get_db_session()

# Nettoyer les caches de plus de 30 jours
result = cleanup_old_pdf_cache(session, days_old=30)
print(result) # {'status': 'success', 'deleted_count': 15}

# Invalider le cache d'une facture spécifique
invalidate_invoice_cache(session, invoice_id='12345')

Points de terminaison API :

Générez/téléchargez le PDF de la facture :

GET /invoice/pdf/{invoice_id}

Réponse : Téléchargement du fichier PDF avec le nom de fichier provenant du descripteur de relevé Stripe

En-têtes de cache :

  • Première demande : réponse plus lente (temps de génération)
  • Demandes mises en cache : réponse instantanée
  • Le succès ou l'échec du cache est transparent pour l'utilisateur

Dépannage

Échec de la génération de PDF :

  • Vérifiez que WeasyPrint est installé : pip install weasyprint
  • Vérifiez que le nom du modèle correspond à crm_config.yaml
  • Vérifiez invoice_templates/rendered/ pour les erreurs de rendu HTML
  • Consultez les journaux API pour les erreurs de modèle Jinja2

Images n'apparaissant pas dans le PDF :

  • Utilisez des chemins de fichiers absolus : file:///full/path/to/image.png
  • Assurez-vous que les fichiers image existent et sont lisibles
  • Vérifiez le format de l'image (PNG et JPEG fonctionnent le mieux)
  • Vérifiez que les chemins d'image ne contiennent pas de caractères spéciaux

Problèmes de style :

  • Intégrez tout le CSS (les feuilles de style externes ne sont pas prises en charge)
  • Évitez les fonctionnalités CSS complexes (flexbox, grid peuvent ne pas se rendre correctement)
  • Testez d'abord avec des mises en page simples, ajoutez de la complexité progressivement
  • Utilisez des tables pour la mise en page au lieu de divs lorsque cela est possible

Le cache ne s'invalide pas :

  • Vérifiez que invalidate_invoice_cache() est appelé lorsque la facture est modifiée
  • Vérifiez que les mises à jour de transaction déclenchent l'invalidation du cache
  • Supprimez manuellement de la table Invoice_PDF_Cache si nécessaire

Liste de vérification de configuration

Utilisez cette liste de vérification lors du déploiement d'OmniCRM :

Configuration Backend

  • [ ] Copiez .env.example dans .env
  • [ ] Définissez des mots de passe de base de données forts
  • [ ] Configurez les identifiants CGRates
  • [ ] Mettez à jour crm_config.yaml avec vos paramètres :
    • [ ] Connexion à la base de données
    • [ ] Types de service
    • [ ] Clés API Mailjet et IDs de modèle
    • [ ] E-mails de notification d'échec de provisionnement
    • [ ] Nom de fichier de modèle de facture
    • [ ] URL de base CRM (accessible publiquement)
    • [ ] Points de terminaison OCS/CGRates
    • [ ] Configuration SMSC
    • [ ] Générez une nouvelle clé secrète JWT
    • [ ] Clés Stripe (live, pas test)
    • [ ] Clés API et filtrage IP

Configuration Frontend

  • [ ] Copiez OmniCRM-UI/.env.example dans OmniCRM-UI/.env
  • [ ] Définissez la clé API Google Maps
  • [ ] Définissez la clé publique Stripe
  • [ ] Mettez à jour la marque de l'entreprise :
    • [ ] Nom de l'entreprise
    • [ ] Nom du portail
    • [ ] Nom de libre-service
    • [ ] Slogan de l'entreprise
  • [ ] Configurez la localisation :
    • [ ] Langue par défaut
    • [ ] Locale
    • [ ] Emplacement et pays par défaut
    • [ ] Code et symbole de devise
  • [ ] Définissez la couleur primaire de la marque
  • [ ] Configurez les intégrations d'applications Web (optionnel)
  • [ ] Ajoutez des URL de support et de FAQ (optionnel)

Actifs de marque

  • [ ] Créez des fichiers de logo (logoSm.png, logoDark.png, logoLight.png)
  • [ ] Téléchargez les logos dans OmniCRM-UI/src/assets/images/omnitouch/
  • [ ] Créez un modèle HTML de facture personnalisé
  • [ ] Téléchargez le modèle de facture dans OmniCRM-API/invoice_templates/
  • [ ] Mettez à jour crm_config.yaml avec le nom de fichier du modèle de facture
  • [ ] Testez la génération de PDF de facture
  • [ ] Reconstruisez l'UI : npm run build

Sécurité

  • [ ] Changez tous les mots de passe par défaut
  • [ ] Générez un secret JWT unique
  • [ ] Utilisez des clés Stripe de production (pas de clés de test)
  • [ ] Faites tourner les clés API Mailjet
  • [ ] Activez les règles de pare-feu
  • [ ] Configurez le filtrage IP pour l'accès API
  • [ ] Configurez des certificats SSL/TLS
  • [ ] Activez HTTPS pour tous les points de terminaison
  • [ ] Passez en revue les paramètres CORS
  • [ ] Implémentez une limitation de taux
  • [ ] Configurez des procédures de sauvegarde et de récupération

Tests

  • [ ] Testez le flux d'enregistrement client
  • [ ] Testez le provisionnement de service de bout en bout
  • [ ] Vérifiez que les notifications par e-mail sont envoyées correctement
  • [ ] Testez la génération de factures et le téléchargement de PDF
  • [ ] Vérifiez le traitement des paiements (Stripe)
  • [ ] Vérifiez l'authentification des utilisateurs et 2FA
  • [ ] Testez l'usurpation d'identité et l'enregistrement des audits
  • [ ] Vérifiez que les données d'utilisation se synchronisent depuis OCS
  • [ ] Testez la création et le renouvellement de l'ActionPlan
  • [ ] Confirmez que l'allocation d'inventaire fonctionne correctement

Déploiement

  • [ ] Construisez des images Docker ou déployez sur des serveurs
  • [ ] Démarrez les conteneurs de base de données (MySQL, PostgreSQL)
  • [ ] Démarrez CGRates
  • [ ] Démarrez l'API OmniCRM
  • [ ] Démarrez l'UI OmniCRM
  • [ ] Configurez le proxy inverse (nginx, traefik)
  • [ ] Configurez la surveillance (Grafana, Prometheus)
  • [ ] Configurez l'agrégation des journaux
  • [ ] Configurez des sauvegardes automatisées
  • [ ] Documentez l'architecture de déploiement
  • [ ] Formez le personnel à l'utilisation du système

Documentation connexe