first commit
This commit is contained in:
commit
e6c52820cd
227 changed files with 16156 additions and 0 deletions
136
Templates/crm/add_client.html
Normal file
136
Templates/crm/add_client.html
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
{% extends 'layouts/base.html' %}
|
||||
|
||||
{% block title %}Suite Consultance - Ajouter un client{% endblock %}
|
||||
{% block module_name %}crm{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2 text-crm">Ajouter un nouveau client</h1>
|
||||
<a href="{{ url_for('crm') }}" class="btn btn-outline-crm">
|
||||
<i class="fas fa-arrow-left"></i> Retour au CRM
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ url_for('add_client') }}">
|
||||
<div class="row g-3">
|
||||
<!-- Informations client -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3">Informations client</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="client_name" class="form-label">Nom du client *</label>
|
||||
<input type="text" class="form-control" id="client_name" name="client_name" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="telephone" class="form-label">Téléphone</label>
|
||||
<input type="tel" class="form-control" id="telephone" name="telephone">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="adresse" class="form-label">Adresse</label>
|
||||
<input type="text" class="form-control" id="adresse" name="adresse">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations projet -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3 mt-3">Informations projet</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="project_name" class="form-label">Nom du projet *</label>
|
||||
<input type="text" class="form-control" id="project_name" name="project_name" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="project_type" class="form-label">Type de projet</label>
|
||||
<input type="text" class="form-control" id="project_type" name="project_type">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="deadline" class="form-label">Date limite</label>
|
||||
<input type="date" class="form-control" id="deadline" name="deadline">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="budget" class="form-label">Budget</label>
|
||||
<input type="text" class="form-control" id="budget" name="budget">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="project_description" class="form-label">Description du projet</label>
|
||||
<textarea class="form-control" id="project_description" name="project_description" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="features" class="form-label">Fonctionnalités (séparées par des virgules)</label>
|
||||
<textarea class="form-control" id="features" name="features" rows="3" placeholder="Fonctionnalité 1, Fonctionnalité 2, ..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations complémentaires -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3 mt-3">Informations complémentaires</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="payment_terms" class="form-label">Conditions de paiement</label>
|
||||
<input type="text" class="form-control" id="payment_terms" name="payment_terms">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="contact_info" class="form-label">Informations de contact</label>
|
||||
<input type="text" class="form-control" id="contact_info" name="contact_info">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="additional_info" class="form-label">Informations additionnelles</label>
|
||||
<textarea class="form-control" id="additional_info" name="additional_info" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-3">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> Enregistrer le client
|
||||
</button>
|
||||
<a href="{{ url_for('crm') }}" class="btn btn-outline-secondary">
|
||||
Annuler
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
129
Templates/crm/add_prospect.html
Normal file
129
Templates/crm/add_prospect.html
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
{% extends 'layouts/base.html' %}
|
||||
|
||||
{% block title %}Suite Consultance - Ajouter un prospect{% endblock %}
|
||||
{% block module_name %}crm{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2 text-crm">Ajouter un nouveau prospect</h1>
|
||||
<a href="{{ url_for('crm') }}" class="btn btn-outline-crm">
|
||||
<i class="fas fa-arrow-left"></i> Retour au CRM
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ url_for('add_prospect') }}">
|
||||
<div class="row g-3">
|
||||
<!-- Informations de base -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3">Informations de base</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Nom du prospect *</label>
|
||||
<input type="text" class="form-control" id="name" name="name" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="company" class="form-label">Entreprise</label>
|
||||
<input type="text" class="form-control" id="company" name="company">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="phone" class="form-label">Téléphone</label>
|
||||
<input type="tel" class="form-control" id="phone" name="phone">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Source et statut -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3 mt-3">Qualification</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="source" class="form-label">Source du prospect</label>
|
||||
<select class="form-select" id="source" name="source">
|
||||
<option value="">-- Sélectionner une source --</option>
|
||||
<option value="Site web">Site web</option>
|
||||
<option value="Recommandation">Recommandation</option>
|
||||
<option value="Réseaux sociaux">Réseaux sociaux</option>
|
||||
<option value="Salon professionnel">Salon professionnel</option>
|
||||
<option value="Publicité">Publicité</option>
|
||||
<option value="Autre">Autre</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">Statut</label>
|
||||
<select class="form-select" id="status" name="status">
|
||||
<option value="Nouveau">Nouveau</option>
|
||||
<option value="Contacté">Contacté</option>
|
||||
<option value="Qualifié">Qualifié</option>
|
||||
<option value="Proposition">Proposition</option>
|
||||
<option value="Non intéressé">Non intéressé</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="last_contact" class="form-label">Dernier contact</label>
|
||||
<input type="date" class="form-control" id="last_contact" name="last_contact" value="{{ today }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="tags" class="form-label">Tags (séparés par des virgules)</label>
|
||||
<input type="text" class="form-control" id="tags" name="tags" placeholder="ex: web, urgent, pme">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations supplémentaires -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3 mt-3">Informations supplémentaires</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="notes" class="form-label">Notes</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="next_action" class="form-label">Action suivante</label>
|
||||
<textarea class="form-control" id="next_action" name="next_action" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-3">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> Enregistrer le prospect
|
||||
</button>
|
||||
<a href="{{ url_for('crm') }}" class="btn btn-outline-secondary">
|
||||
Annuler
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
183
Templates/crm/client_details.html
Normal file
183
Templates/crm/client_details.html
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
{% extends 'layouts/base.html' %}
|
||||
|
||||
{% block title %}Suite Consultance - Détails du client{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2">Détails du client: {{ client.client_name }}</h1>
|
||||
<div>
|
||||
<a href="{{ url_for('crm') }}" class="btn btn-outline-secondary me-2">
|
||||
<i class="fas fa-arrow-left"></i> Retour au CRM
|
||||
</a>
|
||||
<div class="btn-group">
|
||||
<a href="{{ url_for('create_proposition') }}?client_id={{ client.client_name|lower|replace(' ', '_') }}" class="btn btn-success">
|
||||
<i class="fas fa-file-contract"></i> Nouvelle proposition
|
||||
</a>
|
||||
<a href="{{ url_for('create_devis') }}?client_id={{ client.client_name|lower|replace(' ', '_') }}" class="btn btn-warning">
|
||||
<i class="fas fa-file-invoice-dollar"></i> Nouveau devis
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<!-- Informations principales -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Informations du client</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Nom</h6>
|
||||
<p>{{ client.client_name }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Email</h6>
|
||||
<p>{{ client.email or 'Non spécifié' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Téléphone</h6>
|
||||
<p>{{ client.telephone or 'Non spécifié' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Adresse</h6>
|
||||
<p>{{ client.adresse or 'Non spécifiée' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Détails du projet -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Détails du projet</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Nom du projet</h6>
|
||||
<p>{{ client.project_name }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Type de projet</h6>
|
||||
<p>{{ client.project_type or 'Non spécifié' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Date limite</h6>
|
||||
<p>{{ client.deadline or 'Non spécifiée' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Budget</h6>
|
||||
<p>{{ client.budget or 'Non spécifié' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Description du projet</h6>
|
||||
<p>{{ client.project_description or 'Aucune description disponible' }}</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Fonctionnalités</h6>
|
||||
{% if client.features %}
|
||||
<ul>
|
||||
{% for feature in client.features %}
|
||||
<li>{{ feature.description }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>Aucune fonctionnalité spécifiée</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Conditions de paiement</h6>
|
||||
<p>{{ client.payment_terms or 'Non spécifiées' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Informations de contact</h6>
|
||||
<p>{{ client.contact_info or 'Non spécifiées' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Informations additionnelles</h6>
|
||||
<p>{{ client.additional_info or 'Aucune information additionnelle' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<!-- Documents liés -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Documents liés</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Propositions</h6>
|
||||
<ul class="list-group">
|
||||
{% if client.propositions %}
|
||||
{% for proposition in client.propositions %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
{{ proposition.name }}
|
||||
<a href="{{ url_for('download_file', filename='propositions/' + proposition.filename) }}" class="btn btn-sm btn-outline-primary">
|
||||
<i class="fas fa-download"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<li class="list-group-item">Aucune proposition</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Devis</h6>
|
||||
<ul class="list-group">
|
||||
{% if client.devis %}
|
||||
{% for devis in client.devis %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
{{ devis.name }}
|
||||
<a href="{{ url_for('download_file', filename='devis/' + devis.filename) }}" class="btn btn-sm btn-outline-primary">
|
||||
<i class="fas fa-download"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<li class="list-group-item">Aucun devis</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Actions</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="{{ url_for('list_client_projects', client_id=client.client_name|lower|replace(' ', '_')) }}" class="btn btn-outline-primary me-2">
|
||||
<i class="fas fa-diagram-project"></i> Projets
|
||||
</a>
|
||||
<a href="{{ url_for('add_client_project', client_id=client.client_name|lower|replace(' ', '_')) }}" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> Nouveau projet
|
||||
</a>
|
||||
<button class="btn btn-outline-primary">
|
||||
<i class="fas fa-edit"></i> Modifier les informations
|
||||
</button>
|
||||
<a href="" class="btn btn-outline-danger">
|
||||
<i class="fas fa-trash-alt"></i> Supprimer le client
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
283
Templates/crm/crm.html
Normal file
283
Templates/crm/crm.html
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
{% extends 'layouts/base.html' %}
|
||||
|
||||
{% block title %}Suite Consultance - CRM{% endblock %}
|
||||
{% block module_name %}crm{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2 text-crm">Gestion de la Relation Client (CRM)</h1>
|
||||
<a href="{{ url_for('add_client') }}" class="btn btn-crm">
|
||||
<i class="fas fa-plus"></i> Ajouter un client
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs mb-4" id="crmTab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="clients-tab" data-bs-toggle="tab" data-bs-target="#clients-tab-pane" type="button" role="tab" aria-controls="clients-tab-pane" aria-selected="true">
|
||||
<i class="fas fa-user-tie"></i> Clients
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="prospects-tab" data-bs-toggle="tab" data-bs-target="#prospects-tab-pane" type="button" role="tab" aria-controls="prospects-tab-pane" aria-selected="false">
|
||||
<i class="fas fa-user-plus"></i> Prospects
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="dashboard-tab" data-bs-toggle="tab" data-bs-target="#dashboard-tab-pane" type="button" role="tab" aria-controls="dashboard-tab-pane" aria-selected="false">
|
||||
<i class="fas fa-chart-pie"></i> Tableau de bord
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="crmTabContent">
|
||||
<!-- Onglet Clients -->
|
||||
<div class="tab-pane fade show active" id="clients-tab-pane" role="tabpanel" aria-labelledby="clients-tab" tabindex="0">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<th>Email</th>
|
||||
<th>Téléphone</th>
|
||||
<th>Projet</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if clients %}
|
||||
{% for client in clients %}
|
||||
<tr>
|
||||
<td>{{ client.name }}</td>
|
||||
<td>{{ client.email }}</td>
|
||||
<td>{{ client.phone }}</td>
|
||||
<td>{{ client.company }}</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ url_for('client_details', client_id=client.name|lower|replace(' ', '_')) }}" class="btn btn-sm btn-info" title="Détails">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('create_proposition') }}?client_id={{ client.name|lower|replace(' ', '_') }}" class="btn btn-sm btn-success" title="Créer une proposition">
|
||||
<i class="fas fa-file-contract"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('create_devis') }}?client_id={{ client.name|lower|replace(' ', '_') }}" class="btn btn-sm btn-warning" title="Créer un devis">
|
||||
<i class="fas fa-file-invoice-dollar"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun client trouvé</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Onglet Prospects -->
|
||||
<div class="tab-pane fade" id="prospects-tab-pane" role="tabpanel" aria-labelledby="prospects-tab" tabindex="0">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="mb-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<a href="{{ url_for('add_prospect') }}" class="btn btn-outline-primary">
|
||||
<i class="fas fa-plus"></i> Ajouter un prospect
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{ url_for('send_bulk_email') }}" class="btn btn-outline-primary me-2">
|
||||
<i class="fas fa-envelope"></i> Campagne d'emails
|
||||
</a>
|
||||
<a href="{{ url_for('email_templates') }}" class="btn btn-outline-info me-2">
|
||||
<i class="fas fa-file-alt"></i> Templates
|
||||
</a>
|
||||
<a href="{{ url_for('email_config') }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-cog"></i> Configuration
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<th>Email</th>
|
||||
<th>Téléphone</th>
|
||||
<th>Statut</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if prospects %}
|
||||
{% for prospect in prospects %}
|
||||
<tr>
|
||||
<td>{{ prospect.name }}</td>
|
||||
<td>{{ prospect.email }}</td>
|
||||
<td>{{ prospect.phone }}</td>
|
||||
<td>
|
||||
<span class="badge bg-{{ prospect.status|lower == 'nouveau' and 'primary' or (prospect.status|lower == 'contacté' and 'info' or (prospect.status|lower == 'qualifié' and 'success' or (prospect.status|lower == 'proposition' and 'warning' or 'secondary'))) }}">
|
||||
{{ prospect.status }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{{ url_for('prospect_details', prospect_id=prospect.id) }}" class="btn btn-sm btn-info" title="Détails">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('edit_prospect', prospect_id=prospect.id) }}" class="btn btn-sm btn-primary" title="Modifier">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('convert_prospect', prospect_id=prospect.id) }}" class="btn btn-sm btn-success" title="Convertir en client" onclick="return confirm('Êtes-vous sûr de vouloir convertir ce prospect en client ?');">
|
||||
<i class="fas fa-user-check"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun prospect trouvé</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Onglet Tableau de bord -->
|
||||
<div class="tab-pane fade" id="dashboard-tab-pane" role="tabpanel" aria-labelledby="dashboard-tab" tabindex="0">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Répartition clients/prospects</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="clientProspectChart" width="400" height="300"></canvas>
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-6 text-center">
|
||||
<div class="h4 mb-0">{{ dashboard_stats.total_clients }}</div>
|
||||
<div class="small text-muted">Total Clients</div>
|
||||
</div>
|
||||
<div class="col-md-6 text-center">
|
||||
<div class="h4 mb-0">{{ dashboard_stats.total_prospects }}</div>
|
||||
<div class="small text-muted">Total Prospects</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Statut des prospects</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="prospectStatusChart" width="400" height="300"></canvas>
|
||||
<div class="row mt-3">
|
||||
{% for status, count in dashboard_stats.prospect_status.items() %}
|
||||
<div class="col-md-4 text-center mb-2">
|
||||
<div class="h5 mb-0">{{ count }}</div>
|
||||
<div class="small text-muted">{{ status }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Graphique répartition clients/prospects
|
||||
const clientProspectCtx = document.getElementById('clientProspectChart').getContext('2d');
|
||||
const clientProspectChart = new Chart(clientProspectCtx, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['Clients', 'Prospects'],
|
||||
datasets: [{
|
||||
data: [{{ dashboard_stats.total_clients }}, {{ dashboard_stats.total_prospects }}],
|
||||
backgroundColor: [
|
||||
'rgba(54, 162, 235, 0.7)',
|
||||
'rgba(255, 99, 132, 0.7)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(54, 162, 235, 1)',
|
||||
'rgba(255, 99, 132, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Graphique statut des prospects
|
||||
const prospectStatusCtx = document.getElementById('prospectStatusChart').getContext('2d');
|
||||
const prospectStatusChart = new Chart(prospectStatusCtx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [{% for status in dashboard_stats.prospect_status %}'{{ status }}',{% endfor %}],
|
||||
datasets: [{
|
||||
label: 'Nombre de prospects',
|
||||
data: [{% for status, count in dashboard_stats.prospect_status.items() %}{{ count }},{% endfor %}],
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.7)',
|
||||
'rgba(54, 162, 235, 0.7)',
|
||||
'rgba(255, 206, 86, 0.7)',
|
||||
'rgba(75, 192, 192, 0.7)',
|
||||
'rgba(153, 102, 255, 0.7)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(255, 99, 132, 1)',
|
||||
'rgba(54, 162, 235, 1)',
|
||||
'rgba(255, 206, 86, 1)',
|
||||
'rgba(75, 192, 192, 1)',
|
||||
'rgba(153, 102, 255, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
precision: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
132
Templates/crm/edit_prospect.html
Normal file
132
Templates/crm/edit_prospect.html
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
{% extends 'layouts/base.html' %}
|
||||
|
||||
{% block title %}Suite Consultance - Modifier un prospect{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2">Modifier le prospect: {{ prospect.name }}</h1>
|
||||
<a href="{{ url_for('prospect_details', prospect_id=prospect.id) }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Retour aux détails
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ url_for('edit_prospect', prospect_id=prospect.id) }}">
|
||||
<div class="row g-3">
|
||||
<!-- Informations de base -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3">Informations de base</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Nom du prospect *</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="{{ prospect.name }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="company" class="form-label">Entreprise</label>
|
||||
<input type="text" class="form-control" id="company" name="company" value="{{ prospect.company }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email" value="{{ prospect.email }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="phone" class="form-label">Téléphone</label>
|
||||
<input type="tel" class="form-control" id="phone" name="phone" value="{{ prospect.phone }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Source et statut -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3 mt-3">Qualification</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="source" class="form-label">Source du prospect</label>
|
||||
<select class="form-select" id="source" name="source">
|
||||
<option value="">-- Sélectionner une source --</option>
|
||||
<option value="Site web" {% if prospect.source == 'Site web' %}selected{% endif %}>Site web</option>
|
||||
<option value="Recommandation" {% if prospect.source == 'Recommandation' %}selected{% endif %}>Recommandation</option>
|
||||
<option value="Réseaux sociaux" {% if prospect.source == 'Réseaux sociaux' %}selected{% endif %}>Réseaux sociaux</option>
|
||||
<option value="Salon professionnel" {% if prospect.source == 'Salon professionnel' %}selected{% endif %}>Salon professionnel</option>
|
||||
<option value="Publicité" {% if prospect.source == 'Publicité' %}selected{% endif %}>Publicité</option>
|
||||
<option value="Autre" {% if prospect.source == 'Autre' %}selected{% endif %}>Autre</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">Statut</label>
|
||||
{# Compatibilité enum/chaîne pour le statut #}
|
||||
{% set s = prospect.status %}
|
||||
{% if not (s is string) %}{% set s = s.value %}{% endif %}
|
||||
<select class="form-select" id="status" name="status">
|
||||
<option value="Nouveau" {% if s == 'Nouveau' %}selected{% endif %}>Nouveau</option>
|
||||
<option value="Contacté" {% if s == 'Contacté' %}selected{% endif %}>Contacté</option>
|
||||
<option value="Relancé" {% if s == 'Relancé' %}selected{% endif %}>Relancé</option>
|
||||
<option value="Qualifié" {% if s == 'Qualifié' %}selected{% endif %}>Qualifié</option>
|
||||
<option value="Proposition" {% if s == 'Proposition' %}selected{% endif %}>Proposition</option>
|
||||
<option value="Non intéressé" {% if s == 'Non intéressé' %}selected{% endif %}>Non intéressé</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="last_contact" class="form-label">Dernier contact</label>
|
||||
<input type="date" class="form-control" id="last_contact" name="last_contact" value="{{ prospect.last_contact }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="tags" class="form-label">Tags (séparés par des virgules)</label>
|
||||
<input type="text" class="form-control" id="tags" name="tags" value="{{ prospect.tags|join(', ') }}" placeholder="ex: web, urgent, pme">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations supplémentaires -->
|
||||
<div class="col-12">
|
||||
<h5 class="border-bottom pb-2 mb-3 mt-3">Informations supplémentaires</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="notes" class="form-label">Notes</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="3">{{ prospect.notes }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="mb-3">
|
||||
<label for="next_action" class="form-label">Action suivante</label>
|
||||
<textarea class="form-control" id="next_action" name="next_action" rows="2">{{ prospect.next_action }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-3">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> Enregistrer les modifications
|
||||
</button>
|
||||
<a href="{{ url_for('prospect_details', prospect_id=prospect.id) }}" class="btn btn-outline-secondary">
|
||||
Annuler
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
199
Templates/crm/prospect_details.html
Normal file
199
Templates/crm/prospect_details.html
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
{% extends 'layouts/base.html' %}
|
||||
|
||||
{% block title %}Suite Consultance - Détails du prospect{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2">Détails du prospect: {{ prospect.name }}</h1>
|
||||
<div>
|
||||
<a href="{{ url_for('crm') }}#prospects" class="btn btn-outline-secondary me-2">
|
||||
<i class="fas fa-arrow-left"></i> Retour au CRM
|
||||
</a>
|
||||
<div class="btn-group">
|
||||
<a href="{{ url_for('edit_prospect', prospect_id=prospect.id) }}" class="btn btn-primary">
|
||||
<i class="fas fa-edit"></i> Modifier
|
||||
</a>
|
||||
<a href="{{ url_for('convert_prospect', prospect_id=prospect.id) }}" class="btn btn-success" onclick="return confirm('Êtes-vous sûr de vouloir convertir ce prospect en client ?');">
|
||||
<i class="fas fa-user-check"></i> Convertir en client
|
||||
</a>
|
||||
{% with entity_type='prospect', entity_id=prospect.id %}
|
||||
{% include "partials/task_quick_add_button.html" %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<!-- Informations principales -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Informations du prospect</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Nom</h6>
|
||||
<p>{{ prospect.name }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Entreprise</h6>
|
||||
<p>{{ prospect.company or 'Non spécifiée' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Email</h6>
|
||||
<p>{{ prospect.email or 'Non spécifié' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Téléphone</h6>
|
||||
<p>{{ prospect.phone or 'Non spécifié' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Source</h6>
|
||||
<p>{{ prospect.source or 'Non spécifiée' }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Statut</h6>
|
||||
<p>
|
||||
<span class="badge bg-{{ prospect.status|lower == 'nouveau' and 'primary' or (prospect.status|lower == 'contacté' and 'info' or (prospect.status|lower == 'qualifié' and 'success' or (prospect.status|lower == 'proposition' and 'warning' or 'secondary'))) }}">
|
||||
{{ prospect.status }}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Date de création</h6>
|
||||
<p>{{ prospect.created_at }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<h6 class="fw-bold">Dernier contact</h6>
|
||||
<p>{{ prospect.last_contact }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Tags</h6>
|
||||
{% if prospect.tags %}
|
||||
{% for tag in prospect.tags %}
|
||||
<span class="badge bg-secondary me-1">{{ tag }}</span>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>Aucun tag</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notes et actions -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Notes et actions</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-4">
|
||||
<h6 class="fw-bold">Notes</h6>
|
||||
<p>{{ prospect.notes or 'Aucune note disponible' }}</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Action suivante</h6>
|
||||
<p>{{ prospect.next_action or 'Aucune action prévue' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<!-- Documents liés -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Documents liés</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<h6 class="fw-bold">Propositions</h6>
|
||||
<ul class="list-group">
|
||||
{% if prospect.linked_docs and prospect.linked_docs.propositions %}
|
||||
{% for proposition in prospect.linked_docs.propositions %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
{{ proposition.name }}
|
||||
<a href="{{ url_for('download_file', filename='propositions/' + proposition.filename) }}" class="btn btn-sm btn-outline-primary">
|
||||
<i class="fas fa-download"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<li class="list-group-item">Aucune proposition</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historique des emails récents -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Derniers emails</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if email_history and email_history|length > 0 %}
|
||||
<ul class="list-group">
|
||||
{% for email in email_history[:5] %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<span class="fw-bold">{{ email.subject }}</span>
|
||||
<br>
|
||||
<small class="text-muted">{{ email.timestamp|datetime }}</small>
|
||||
</div>
|
||||
<span class="badge bg-{% if email.success %}success{% else %}danger{% endif %}">
|
||||
{% if email.success %}Envoyé{% else %}Échec{% endif %}
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if email_history|length > 5 %}
|
||||
<div class="mt-2 text-center">
|
||||
<a href="{{ url_for('prospect_email_history', prospect_id=prospect.id) }}" class="btn btn-sm btn-outline-primary">
|
||||
Voir tout l'historique
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p class="text-center">Aucun email envoyé à ce prospect.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">Actions</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="{{ url_for('send_prospect_email', prospect_id=prospect.id) }}" class="btn btn-outline-primary">
|
||||
<i class="fas fa-envelope"></i> Envoyer un email
|
||||
</a>
|
||||
<a href="{{ url_for('prospect_email_history', prospect_id=prospect.id) }}" class="btn btn-outline-info">
|
||||
<i class="fas fa-history"></i> Historique des emails
|
||||
</a>
|
||||
<a href="{{ url_for('edit_prospect', prospect_id=prospect.id) }}" class="btn btn-outline-primary">
|
||||
<i class="fas fa-edit"></i> Modifier les informations
|
||||
</a>
|
||||
<a href="{{ url_for('delete_prospect', prospect_id=prospect.id) }}" class="btn btn-outline-danger delete-confirm">
|
||||
<i class="fas fa-trash-alt"></i> Supprimer le prospect
|
||||
</a>
|
||||
<a href="{{ url_for('convert_prospect', prospect_id=prospect.id) }}" class="btn btn-success" onclick="return confirm('Êtes-vous sûr de vouloir convertir ce prospect en client ?');">
|
||||
<i class="fas fa-user-check"></i> Convertir en client
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue