Initial commit - TimeTrack Pro

- Structure projet complete
- Schema BDD (3 tables: Clients, Projets, Temps)
- 6 modules VBA documentes
- Scripts SQL de creation
- Plan d'implementation pour agent
- Base Access avec tables creees (Phase 1 complete)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
StillHammer 2025-12-30 10:53:11 +07:00
commit fe30e811a3
14 changed files with 2378 additions and 0 deletions

View File

@ -0,0 +1,5 @@
{
"enabledMcpjsonServers": [
"vba-mcp-pro"
]
}

32
.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
# Access lock files
*.laccdb
*.ldb
# Backups
.vba_backups/
*.bak
# Windows
Thumbs.db
Desktop.ini
# Temp files
*.tmp
~$*
# Scripts temporaires
scripts/create_db.ps1
# Windows reserved names
nul
con
prn
aux
# IDE
.vscode/
.idea/
# Python
__pycache__/
*.pyc

15
.mcp.json Normal file
View File

@ -0,0 +1,15 @@
{
"mcpServers": {
"vba-mcp-pro": {
"command": "python",
"args": [
"-m",
"vba_mcp_pro.server"
],
"cwd": "C:\\Users\\alexi\\Documents\\projects\\vba-mcp-monorepo",
"env": {
"PYTHONPATH": "C:\\Users\\alexi\\Documents\\projects\\vba-mcp-monorepo\\packages\\core\\src;C:\\Users\\alexi\\Documents\\projects\\vba-mcp-monorepo\\packages\\lite\\src;C:\\Users\\alexi\\Documents\\projects\\vba-mcp-monorepo\\packages\\pro\\src"
}
}
}
}

218
CLAUDE.md Normal file
View File

@ -0,0 +1,218 @@
# TimeTrack Pro - Instructions pour Claude
## Projet
TimeTrack Pro - Gestionnaire de temps Access, vitrine du VBA MCP Server.
## Status: En attente de developpement
## MCP VBA Server
Ce projet utilise **VBA MCP Server v0.6.0+** pour l'automatisation.
### Outils Disponibles pour Access
| Outil | Description | Usage |
|-------|-------------|-------|
| `run_access_query` | Execute SQL (SELECT, INSERT, UPDATE, DELETE, CREATE) | Creation tables, requetes |
| `list_access_tables` | Liste tables avec schema | Verification structure |
| `list_access_queries` | Liste requetes sauvegardees | Voir QueryDefs |
| `get_worksheet_data` | Lit donnees d'une table | Lecture avec filtres |
| `set_worksheet_data` | Ecrit donnees dans table | Insert mode append/replace |
| `inject_vba` | Injecte module VBA | Ajouter les 6 modules |
| `validate_vba` | Valide syntaxe VBA | Verifier avant injection |
| `create_backup` | Cree backup du fichier | Avant modifications |
| `restore_backup` | Restaure depuis backup | En cas d'erreur |
| `list_backups` | Liste les backups | Voir historique |
### Chemin du fichier
```
C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb
```
---
## Structure du Projet
```
timetrack-pro/
├── README.md # Documentation principale
├── PLAN.md # Plan projet (6 phases, 12h)
├── DATABASE.md # Schema BDD complet
├── VBA_MODULES.md # 6 modules VBA documentes
├── CLAUDE.md # CE FICHIER
├── db/
│ └── TimeTrackPro.accdb # Base Access
├── docs/
│ └── MCP_VBA_GUIDE.md # Guide utilisation MCP
└── scripts/
├── 01_create_tables.sql
├── 02_create_queries.sql
├── 03_sample_data.sql
└── modules/
```
---
## Workflow de Developpement
### Phase 1: Structure BDD (MCP VBA)
```python
# 1. Creer backup si fichier existe
create_backup("db/TimeTrackPro.accdb")
# 2. Creer les tables
run_access_query("db/TimeTrackPro.accdb", sql="""
CREATE TABLE tbl_Clients (
ClientID AUTOINCREMENT PRIMARY KEY,
Nom TEXT(100) NOT NULL,
Email TEXT(100),
Telephone TEXT(20),
Notes MEMO,
DateCreation DATETIME DEFAULT Now()
)
""")
run_access_query("db/TimeTrackPro.accdb", sql="""
CREATE TABLE tbl_Projets (
ProjetID AUTOINCREMENT PRIMARY KEY,
ClientID LONG NOT NULL,
Nom TEXT(100) NOT NULL,
Description MEMO,
TauxHoraire CURRENCY DEFAULT 0,
Actif YESNO DEFAULT True,
DateCreation DATETIME DEFAULT Now()
)
""")
run_access_query("db/TimeTrackPro.accdb", sql="""
CREATE TABLE tbl_Temps (
TempsID AUTOINCREMENT PRIMARY KEY,
ProjetID LONG NOT NULL,
Date DATETIME NOT NULL,
Duree DOUBLE NOT NULL,
Description MEMO,
DateCreation DATETIME DEFAULT Now()
)
""")
# 3. Verifier
list_access_tables("db/TimeTrackPro.accdb")
```
### Phase 2: Donnees de Test (MCP VBA)
```python
# Inserer clients
run_access_query("db/TimeTrackPro.accdb", sql="""
INSERT INTO tbl_Clients (Nom, Email, Telephone, Notes)
VALUES ('Acme Corporation', 'contact@acme.com', '01 23 45 67 89', 'Client principal')
""")
# Ou en batch avec set_worksheet_data
data = [
["Acme Corporation", "contact@acme.com", "0123456789", "Client 1"],
["Tech Solutions", "info@techsol.fr", "0198765432", "Client 2"],
]
set_worksheet_data("db/TimeTrackPro.accdb", "tbl_Clients", data,
columns=["Nom", "Email", "Telephone", "Notes"], mode="append")
```
### Phase 3: Modules VBA (MCP VBA)
```python
# Valider puis injecter chaque module
# Le code complet est dans VBA_MODULES.md
validate_vba(code_mod_config, file_type="access")
inject_vba("db/TimeTrackPro.accdb", "mod_Config", code_mod_config)
validate_vba(code_mod_utils, file_type="access")
inject_vba("db/TimeTrackPro.accdb", "mod_Utils", code_mod_utils)
# ... pour chaque module
```
### Phase 4-6: Formulaires et UI (Manuel dans Access)
Les formulaires doivent etre crees dans Access UI:
- frm_Accueil
- frm_Clients
- frm_Projets
- frm_SaisieTemps
- frm_Historique
---
## Commandes Rapides
### Lire donnees
```python
get_worksheet_data("db/TimeTrackPro.accdb", "tbl_Clients")
get_worksheet_data("db/TimeTrackPro.accdb", "tbl_Temps", where_clause="Date > #2025-01-01#")
```
### Executer requete
```python
run_access_query("db/TimeTrackPro.accdb", sql="SELECT * FROM tbl_Projets WHERE Actif = True")
run_access_query("db/TimeTrackPro.accdb", query_name="qry_TempsByClient")
```
### Ajouter entree temps
```python
run_access_query("db/TimeTrackPro.accdb", sql="""
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (1, #2025-01-15#, 3.5, 'Travail effectue')
""")
```
### Modifier donnees
```python
run_access_query("db/TimeTrackPro.accdb", sql="""
UPDATE tbl_Projets SET TauxHoraire = 80 WHERE ProjetID = 1
""")
```
### Supprimer donnees
```python
run_access_query("db/TimeTrackPro.accdb", sql="""
DELETE FROM tbl_Temps WHERE TempsID = 5
""")
```
---
## Limitations MCP VBA
| Ce qui marche | Ce qui ne marche pas |
|---------------|---------------------|
| CREATE/ALTER TABLE | Creer formulaires |
| INSERT/UPDATE/DELETE | Creer rapports |
| Injection VBA modules | Creer macros Access (UI) |
| Lecture/ecriture donnees | Design visuel |
| Requetes SQL | Slicers/filtres visuels |
---
## Fichiers Cles
| Fichier | Quand l'utiliser |
|---------|------------------|
| `scripts/01_create_tables.sql` | Creer la structure |
| `scripts/03_sample_data.sql` | Peupler avec donnees test |
| `VBA_MODULES.md` | Code VBA a injecter |
| `DATABASE.md` | Reference schema |
| `docs/MCP_VBA_GUIDE.md` | Guide etape par etape |
---
## Contact
Alexis Trouve - alexistrouve.pro@gmail.com

235
DATABASE.md Normal file
View File

@ -0,0 +1,235 @@
# TimeTrack Pro - Schema Base de Donnees
## Vue d'ensemble
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ tbl_Clients │ │ tbl_Projets │ │ tbl_Temps │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ ClientID (PK) │──┐ │ ProjetID (PK) │──┐ │ TempsID (PK) │
│ Nom │ │ │ ClientID (FK) │◄─┘ │ ProjetID (FK) │◄─┘
│ Email │ │ │ Nom │ │ Date │
│ Telephone │ └───►│ Description │ │ Duree │
│ Notes │ │ TauxHoraire │ │ Description │
│ DateCreation │ │ Actif │ │ DateCreation │
└─────────────────┘ │ DateCreation │ └─────────────────┘
└─────────────────┘
```
---
## Table: tbl_Clients
Stocke les informations des clients.
| Champ | Type | Taille | Requis | Description |
|-------|------|--------|--------|-------------|
| ClientID | AutoNumber | Long | PK | Identifiant unique |
| Nom | Text | 100 | Oui | Nom du client |
| Email | Text | 100 | Non | Adresse email |
| Telephone | Text | 20 | Non | Numero de telephone |
| Notes | Memo | - | Non | Notes diverses |
| DateCreation | DateTime | - | Oui | Date de creation (auto) |
### SQL Creation
```sql
CREATE TABLE tbl_Clients (
ClientID AUTOINCREMENT PRIMARY KEY,
Nom TEXT(100) NOT NULL,
Email TEXT(100),
Telephone TEXT(20),
Notes MEMO,
DateCreation DATETIME DEFAULT Now()
);
```
---
## Table: tbl_Projets
Stocke les projets lies aux clients.
| Champ | Type | Taille | Requis | Description |
|-------|------|--------|--------|-------------|
| ProjetID | AutoNumber | Long | PK | Identifiant unique |
| ClientID | Long | - | FK | Reference vers tbl_Clients |
| Nom | Text | 100 | Oui | Nom du projet |
| Description | Memo | - | Non | Description du projet |
| TauxHoraire | Currency | - | Non | Taux horaire en euros |
| Actif | Yes/No | - | Oui | Projet actif ou archive |
| DateCreation | DateTime | - | Oui | Date de creation (auto) |
### SQL Creation
```sql
CREATE TABLE tbl_Projets (
ProjetID AUTOINCREMENT PRIMARY KEY,
ClientID LONG NOT NULL,
Nom TEXT(100) NOT NULL,
Description MEMO,
TauxHoraire CURRENCY DEFAULT 0,
Actif YESNO DEFAULT True,
DateCreation DATETIME DEFAULT Now(),
CONSTRAINT FK_Projets_Clients
FOREIGN KEY (ClientID) REFERENCES tbl_Clients(ClientID)
);
```
---
## Table: tbl_Temps
Stocke les entrees de temps.
| Champ | Type | Taille | Requis | Description |
|-------|------|--------|--------|-------------|
| TempsID | AutoNumber | Long | PK | Identifiant unique |
| ProjetID | Long | - | FK | Reference vers tbl_Projets |
| Date | DateTime | - | Oui | Date de l'entree |
| Duree | Double | - | Oui | Duree en heures (decimales) |
| Description | Memo | - | Non | Description du travail |
| DateCreation | DateTime | - | Oui | Date de creation (auto) |
### SQL Creation
```sql
CREATE TABLE tbl_Temps (
TempsID AUTOINCREMENT PRIMARY KEY,
ProjetID LONG NOT NULL,
Date DATETIME NOT NULL,
Duree DOUBLE NOT NULL,
Description MEMO,
DateCreation DATETIME DEFAULT Now(),
CONSTRAINT FK_Temps_Projets
FOREIGN KEY (ProjetID) REFERENCES tbl_Projets(ProjetID)
);
```
---
## Requetes Sauvegardees
### qry_TempsByProjet
Total des heures par projet.
```sql
SELECT
p.Nom AS Projet,
c.Nom AS Client,
SUM(t.Duree) AS TotalHeures,
SUM(t.Duree * p.TauxHoraire) AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
GROUP BY p.Nom, c.Nom
ORDER BY c.Nom, p.Nom;
```
### qry_TempsByClient
Total des heures par client.
```sql
SELECT
c.Nom AS Client,
COUNT(DISTINCT p.ProjetID) AS NbProjets,
SUM(t.Duree) AS TotalHeures,
SUM(t.Duree * p.TauxHoraire) AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
GROUP BY c.Nom
ORDER BY c.Nom;
```
### qry_TempsPeriode
Entrees de temps sur une periode (parametree).
```sql
SELECT
t.Date,
c.Nom AS Client,
p.Nom AS Projet,
t.Duree,
t.Description,
t.Duree * p.TauxHoraire AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
WHERE t.Date BETWEEN [DateDebut] AND [DateFin]
ORDER BY t.Date DESC;
```
### qry_ProjetsActifs
Liste des projets actifs avec client.
```sql
SELECT
p.ProjetID,
p.Nom AS Projet,
c.Nom AS Client,
p.TauxHoraire,
p.DateCreation
FROM tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID
WHERE p.Actif = True
ORDER BY c.Nom, p.Nom;
```
### qry_StatsGlobales
Statistiques globales pour tableau de bord.
```sql
SELECT
(SELECT COUNT(*) FROM tbl_Clients) AS NbClients,
(SELECT COUNT(*) FROM tbl_Projets WHERE Actif = True) AS NbProjetsActifs,
(SELECT SUM(Duree) FROM tbl_Temps WHERE Date >= DateSerial(Year(Date()), Month(Date()), 1)) AS HeuresMoisCourant,
(SELECT SUM(Duree) FROM tbl_Temps) AS TotalHeures;
```
---
## Index Recommandes
```sql
-- Index sur les cles etrangeres
CREATE INDEX idx_Projets_ClientID ON tbl_Projets (ClientID);
CREATE INDEX idx_Temps_ProjetID ON tbl_Temps (ProjetID);
-- Index sur les champs de recherche frequents
CREATE INDEX idx_Temps_Date ON tbl_Temps (Date);
CREATE INDEX idx_Projets_Actif ON tbl_Projets (Actif);
```
---
## Donnees de Test
```sql
-- Clients
INSERT INTO tbl_Clients (Nom, Email) VALUES ('Acme Corp', 'contact@acme.com');
INSERT INTO tbl_Clients (Nom, Email) VALUES ('Tech Solutions', 'info@techsol.fr');
INSERT INTO tbl_Clients (Nom, Email) VALUES ('Freelance Direct', 'hello@freelance.io');
-- Projets
INSERT INTO tbl_Projets (ClientID, Nom, TauxHoraire, Actif) VALUES (1, 'Site Web', 75, True);
INSERT INTO tbl_Projets (ClientID, Nom, TauxHoraire, Actif) VALUES (1, 'Maintenance', 60, True);
INSERT INTO tbl_Projets (ClientID, Nom, TauxHoraire, Actif) VALUES (2, 'API Backend', 85, True);
INSERT INTO tbl_Projets (ClientID, Nom, TauxHoraire, Actif) VALUES (3, 'Consulting', 100, True);
-- Temps
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description) VALUES (1, #2025-01-02#, 3.5, 'Design maquettes');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description) VALUES (1, #2025-01-03#, 4.0, 'Integration HTML/CSS');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description) VALUES (3, #2025-01-02#, 6.0, 'Developpement endpoints');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description) VALUES (4, #2025-01-03#, 2.0, 'Reunion strategie');
```
---
**Version:** 1.0
**Date:** 2025-12-30

168
PLAN.md Normal file
View File

@ -0,0 +1,168 @@
# TimeTrack Pro - Plan de Projet
## 1. Vision
**Objectif:** Outil de suivi des heures par client/projet, propre et fonctionnel, qui demontre la capacite a livrer un produit fini.
**Public cible:** Freelances, petites equipes, usage personnel.
**Differenciateur:** Genere via MCP VBA Server = double vitrine (outil + technologie).
---
## 2. Perimetre V1
### Inclus
| Fonctionnalite | Description |
|----------------|-------------|
| Gestion clients | CRUD complet (Creer, Lire, Modifier, Supprimer) |
| Gestion projets | Lies aux clients, avec taux horaire |
| Saisie temps | Entrees rapides avec date, duree, notes |
| Calculs auto | Totaux par projet, client, periode |
| Rapports | Recapitulatif exportable PDF/Excel |
| Navigation | Interface propre et intuitive |
### Hors Perimetre (V2 eventuelle)
- Multi-utilisateurs
- Facturation automatique
- Synchro cloud / API externe
- Dashboard graphique avance
---
## 3. Modele de Donnees
### Tables
| Table | Champs |
|-------|--------|
| tbl_Clients | ClientID (PK), Nom, Email, Telephone, Notes, DateCreation |
| tbl_Projets | ProjetID (PK), ClientID (FK), Nom, Description, TauxHoraire, Actif, DateCreation |
| tbl_Temps | TempsID (PK), ProjetID (FK), Date, Duree, Description, DateCreation |
### Relations
```
tbl_Clients (1) ──── (N) tbl_Projets
tbl_Projets (1) ──── (N) tbl_Temps
```
---
## 4. Interfaces (Formulaires)
| Formulaire | Fonction |
|------------|----------|
| frm_Accueil | Navigation principale, stats rapides |
| frm_Clients | Liste + ajout/edition clients |
| frm_Projets | Liste + ajout/edition projets (filtrable par client) |
| frm_SaisieTemps | Saisie rapide : date, projet, duree, note |
| frm_Historique | Liste des entrees avec filtres (date, client, projet) |
---
## 5. Rapports
| Rapport | Contenu |
|---------|---------|
| rpt_RecapPeriode | Total heures par projet/client sur une periode choisie |
| rpt_DetailClient | Detail des heures pour un client specifique |
**Export:** PDF ou Excel
---
## 6. Architecture VBA
### Modules
| Module | Responsabilite |
|--------|----------------|
| mod_Config | Constantes, parametres globaux |
| mod_Navigation | Ouverture/fermeture formulaires |
| mod_DataAccess | Fonctions CRUD generiques |
| mod_Calculs | Totaux, moyennes, agregations |
| mod_Export | Generation PDF/Excel |
| mod_Utils | Helpers (dates, validation, formatage) |
### Principes
1. **Pas de code dans les formulaires** (ou minimal)
2. **Nommage explicite:** `GetTotalHeuresByProjet()`, `OpenFormClient()`
3. **Commentaires en-tete** de chaque fonction
4. **Gestion d'erreurs** coherente
---
## 7. Phases de Developpement
| Phase | Contenu | Methode | Duree |
|-------|---------|---------|-------|
| 1 | Structure BDD + relations | MCP VBA | 1h |
| 2 | Formulaires de base (CRUD) | Access UI | 3h |
| 3 | Saisie temps + calculs | MCP VBA + UI | 2h |
| 4 | Rapports + export | Access UI + VBA | 2h |
| 5 | UI polish + navigation | Access UI | 2h |
| 6 | Tests + documentation | Manuel | 2h |
**Total estime:** ~12h
---
## 8. Livrables Finaux
- [ ] Fichier `.accdb` fonctionnel
- [ ] README avec screenshots
- [ ] Code source commente (via MCP VBA)
- [ ] (Bonus) GIF de demo
---
## 9. Criteres de Succes
- [ ] L'outil fonctionne sans bugs visibles
- [ ] Le code est lisible et structure
- [ ] Un utilisateur peut saisir du temps en < 30 secondes
- [ ] Le rapport est exportable et presentable
- [ ] Utilisation personnelle (dogfooding)
---
## 10. Stack Technique
| Composant | Technologie |
|-----------|-------------|
| Base de donnees | Microsoft Access (.accdb) |
| Langage | VBA (Visual Basic for Applications) |
| Automatisation | VBA MCP Server v0.6.0 |
| Export | PDF via Access, Excel via VBA |
---
## 11. Approche MCP VBA
### Ce qui sera automatise (MCP)
```
run_access_query → Creation tables, relations, requetes
inject_vba → Tous les modules VBA
get/set_data → Tests et population de donnees
```
### Ce qui sera manuel (Access UI)
```
Formulaires → Design visuel des interfaces
Rapports → Mise en page des rapports
Controles → Positionnement, formatage
```
---
**Auteur:** Alexis Trouve
**Date:** 2025-12-30
**Version:** 1.0

77
README.md Normal file
View File

@ -0,0 +1,77 @@
# TimeTrack Pro
Gestionnaire de temps Access - Vitrine MCP VBA
## Vision
Outil de suivi des heures par client/projet, propre et fonctionnel, qui demontre la capacite a livrer un produit fini via MCP VBA.
**Public cible:** Freelances, petites equipes
**Differenciateur:** Genere via MCP VBA Server
## Status
| Phase | Description | Status |
|-------|-------------|--------|
| 1 | Structure BDD + relations | En attente |
| 2 | Formulaires de base (CRUD) | En attente |
| 3 | Saisie temps + calculs | En attente |
| 4 | Rapports + export | En attente |
| 5 | UI polish + navigation | En attente |
| 6 | Tests + documentation | En attente |
## Fonctionnalites V1
- [x] Gestion clients (CRUD)
- [x] Gestion projets (lies aux clients)
- [x] Saisie des entrees de temps
- [x] Calcul automatique des totaux
- [x] Rapport recapitulatif exportable
- [x] Interface propre et navigable
## Hors Perimetre (V2)
- Multi-utilisateurs
- Facturation
- Synchro cloud / API
- Dashboard graphique
## Structure
```
timetrack-pro/
├── README.md # Ce fichier
├── PLAN.md # Plan de projet detaille
├── DATABASE.md # Schema de base de donnees
├── VBA_MODULES.md # Documentation modules VBA
├── db/ # Fichiers Access
│ └── TimeTrackPro.accdb
└── scripts/ # Scripts SQL et VBA
├── 01_create_tables.sql
├── 02_create_queries.sql
└── modules/
├── mod_Config.bas
├── mod_Navigation.bas
├── mod_DataAccess.bas
├── mod_Calculs.bas
├── mod_Export.bas
└── mod_Utils.bas
```
## Quick Start
```bash
# Avec VBA MCP Server
1. Creer base Access vide
2. Executer scripts SQL via run_access_query
3. Injecter modules VBA via inject_vba
4. Creer formulaires dans Access UI
```
## Auteur
Alexis Trouve - alexistrouve.pro@gmail.com
## License
Proprietary - Demo Project

826
VBA_MODULES.md Normal file
View File

@ -0,0 +1,826 @@
# TimeTrack Pro - Documentation Modules VBA
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ FORMULAIRES │
│ frm_Accueil frm_Clients frm_Projets frm_Temps etc. │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ mod_Navigation │
│ OpenFormClients(), CloseAllForms(), etc. │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ mod_DataAccess │
│ GetClients(), SaveProjet(), DeleteTemps(), etc. │
└─────────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌───────────────────┐ ┌───────────────┐ ┌───────────────┐
│ mod_Calculs │ │ mod_Export │ │ mod_Utils │
│ TotalHeures() │ │ ExportPDF() │ │ FormatDate() │
│ MontantProjet() │ │ ExportExcel() │ │ ValidEmail() │
└───────────────────┘ └───────────────┘ └───────────────┘
┌───────────────────────────────┐
│ mod_Config │
│ APP_NAME, VERSION, etc. │
└───────────────────────────────┘
```
---
## mod_Config
Constantes et parametres globaux de l'application.
```vba
'===============================================================================
' Module: mod_Config
' Description: Constantes et parametres globaux de TimeTrack Pro
' Auteur: Alexis Trouve
' Date: 2025-12-30
'===============================================================================
Option Compare Database
Option Explicit
' Application
Public Const APP_NAME As String = "TimeTrack Pro"
Public Const APP_VERSION As String = "1.0.0"
' Chemins
Public Const EXPORT_PATH As String = "C:\TimeTrack\Exports\"
Public Const BACKUP_PATH As String = "C:\TimeTrack\Backups\"
' Formats
Public Const DATE_FORMAT As String = "dd/mm/yyyy"
Public Const TIME_FORMAT As String = "0.00"
Public Const CURRENCY_FORMAT As String = "#,##0.00 €"
' Valeurs par defaut
Public Const DEFAULT_TAUX_HORAIRE As Currency = 50
Public Const DEFAULT_DUREE As Double = 1
' Messages
Public Const MSG_CONFIRM_DELETE As String = "Voulez-vous vraiment supprimer cet element ?"
Public Const MSG_SAVE_SUCCESS As String = "Enregistrement reussi."
Public Const MSG_ERROR_GENERIC As String = "Une erreur s'est produite."
'-------------------------------------------------------------------------------
' Fonction: GetAppTitle
' Description: Retourne le titre complet de l'application
'-------------------------------------------------------------------------------
Public Function GetAppTitle() As String
GetAppTitle = APP_NAME & " v" & APP_VERSION
End Function
'-------------------------------------------------------------------------------
' Fonction: EnsureFoldersExist
' Description: Cree les dossiers necessaires s'ils n'existent pas
'-------------------------------------------------------------------------------
Public Sub EnsureFoldersExist()
On Error Resume Next
MkDir EXPORT_PATH
MkDir BACKUP_PATH
On Error GoTo 0
End Sub
```
---
## mod_Navigation
Gestion de la navigation entre formulaires.
```vba
'===============================================================================
' Module: mod_Navigation
' Description: Fonctions de navigation entre formulaires
' Auteur: Alexis Trouve
' Date: 2025-12-30
'===============================================================================
Option Compare Database
Option Explicit
'-------------------------------------------------------------------------------
' Sub: OpenFormAccueil
' Description: Ouvre le formulaire d'accueil
'-------------------------------------------------------------------------------
Public Sub OpenFormAccueil()
DoCmd.OpenForm "frm_Accueil"
End Sub
'-------------------------------------------------------------------------------
' Sub: OpenFormClients
' Description: Ouvre le formulaire de gestion des clients
' Params: Optional clientID - ID du client a selectionner
'-------------------------------------------------------------------------------
Public Sub OpenFormClients(Optional ByVal clientID As Long = 0)
DoCmd.OpenForm "frm_Clients"
If clientID > 0 Then
Forms!frm_Clients.Recordset.FindFirst "ClientID = " & clientID
End If
End Sub
'-------------------------------------------------------------------------------
' Sub: OpenFormProjets
' Description: Ouvre le formulaire de gestion des projets
' Params: Optional clientID - Filtrer par client
'-------------------------------------------------------------------------------
Public Sub OpenFormProjets(Optional ByVal clientID As Long = 0)
Dim strFilter As String
If clientID > 0 Then
strFilter = "ClientID = " & clientID
DoCmd.OpenForm "frm_Projets", , , strFilter
Else
DoCmd.OpenForm "frm_Projets"
End If
End Sub
'-------------------------------------------------------------------------------
' Sub: OpenFormSaisieTemps
' Description: Ouvre le formulaire de saisie de temps
' Params: Optional projetID - Pre-selectionner un projet
'-------------------------------------------------------------------------------
Public Sub OpenFormSaisieTemps(Optional ByVal projetID As Long = 0)
DoCmd.OpenForm "frm_SaisieTemps"
If projetID > 0 Then
Forms!frm_SaisieTemps!cboProjet = projetID
End If
End Sub
'-------------------------------------------------------------------------------
' Sub: OpenFormHistorique
' Description: Ouvre le formulaire d'historique des temps
'-------------------------------------------------------------------------------
Public Sub OpenFormHistorique()
DoCmd.OpenForm "frm_Historique"
End Sub
'-------------------------------------------------------------------------------
' Sub: CloseCurrentForm
' Description: Ferme le formulaire actif
'-------------------------------------------------------------------------------
Public Sub CloseCurrentForm()
DoCmd.Close acForm, Screen.ActiveForm.Name
End Sub
'-------------------------------------------------------------------------------
' Sub: CloseAllForms
' Description: Ferme tous les formulaires ouverts
'-------------------------------------------------------------------------------
Public Sub CloseAllForms()
Dim frm As Form
For Each frm In Forms
DoCmd.Close acForm, frm.Name
Next frm
End Sub
'-------------------------------------------------------------------------------
' Sub: RefreshCurrentForm
' Description: Rafraichit le formulaire actif
'-------------------------------------------------------------------------------
Public Sub RefreshCurrentForm()
Screen.ActiveForm.Requery
End Sub
```
---
## mod_DataAccess
Fonctions CRUD pour l'acces aux donnees.
```vba
'===============================================================================
' Module: mod_DataAccess
' Description: Fonctions CRUD pour acces aux donnees
' Auteur: Alexis Trouve
' Date: 2025-12-30
'===============================================================================
Option Compare Database
Option Explicit
'===============================================================================
' CLIENTS
'===============================================================================
'-------------------------------------------------------------------------------
' Function: GetClients
' Description: Retourne un recordset de tous les clients
'-------------------------------------------------------------------------------
Public Function GetClients() As DAO.Recordset
Set GetClients = CurrentDb.OpenRecordset( _
"SELECT * FROM tbl_Clients ORDER BY Nom", dbOpenDynaset)
End Function
'-------------------------------------------------------------------------------
' Function: GetClientByID
' Description: Retourne un client par son ID
'-------------------------------------------------------------------------------
Public Function GetClientByID(ByVal clientID As Long) As DAO.Recordset
Set GetClientByID = CurrentDb.OpenRecordset( _
"SELECT * FROM tbl_Clients WHERE ClientID = " & clientID, dbOpenDynaset)
End Function
'-------------------------------------------------------------------------------
' Function: SaveClient
' Description: Sauvegarde un client (insert ou update)
' Returns: ID du client
'-------------------------------------------------------------------------------
Public Function SaveClient(ByVal nom As String, _
Optional ByVal email As String = "", _
Optional ByVal telephone As String = "", _
Optional ByVal notes As String = "", _
Optional ByVal clientID As Long = 0) As Long
Dim sql As String
If clientID = 0 Then
' INSERT
sql = "INSERT INTO tbl_Clients (Nom, Email, Telephone, Notes, DateCreation) " & _
"VALUES ('" & EscapeSQL(nom) & "', '" & EscapeSQL(email) & "', " & _
"'" & EscapeSQL(telephone) & "', '" & EscapeSQL(notes) & "', Now())"
CurrentDb.Execute sql, dbFailOnError
SaveClient = DMax("ClientID", "tbl_Clients")
Else
' UPDATE
sql = "UPDATE tbl_Clients SET " & _
"Nom = '" & EscapeSQL(nom) & "', " & _
"Email = '" & EscapeSQL(email) & "', " & _
"Telephone = '" & EscapeSQL(telephone) & "', " & _
"Notes = '" & EscapeSQL(notes) & "' " & _
"WHERE ClientID = " & clientID
CurrentDb.Execute sql, dbFailOnError
SaveClient = clientID
End If
End Function
'-------------------------------------------------------------------------------
' Sub: DeleteClient
' Description: Supprime un client (et ses projets/temps en cascade)
'-------------------------------------------------------------------------------
Public Sub DeleteClient(ByVal clientID As Long)
' Supprimer temps des projets du client
CurrentDb.Execute "DELETE FROM tbl_Temps WHERE ProjetID IN " & _
"(SELECT ProjetID FROM tbl_Projets WHERE ClientID = " & clientID & ")"
' Supprimer projets du client
CurrentDb.Execute "DELETE FROM tbl_Projets WHERE ClientID = " & clientID
' Supprimer client
CurrentDb.Execute "DELETE FROM tbl_Clients WHERE ClientID = " & clientID
End Sub
'===============================================================================
' PROJETS
'===============================================================================
'-------------------------------------------------------------------------------
' Function: GetProjets
' Description: Retourne les projets (optionnellement filtres par client)
'-------------------------------------------------------------------------------
Public Function GetProjets(Optional ByVal clientID As Long = 0, _
Optional ByVal actifsOnly As Boolean = True) As DAO.Recordset
Dim sql As String
sql = "SELECT p.*, c.Nom AS ClientNom FROM tbl_Projets p " & _
"INNER JOIN tbl_Clients c ON p.ClientID = c.ClientID WHERE 1=1"
If clientID > 0 Then
sql = sql & " AND p.ClientID = " & clientID
End If
If actifsOnly Then
sql = sql & " AND p.Actif = True"
End If
sql = sql & " ORDER BY c.Nom, p.Nom"
Set GetProjets = CurrentDb.OpenRecordset(sql, dbOpenDynaset)
End Function
'-------------------------------------------------------------------------------
' Function: SaveProjet
' Description: Sauvegarde un projet
'-------------------------------------------------------------------------------
Public Function SaveProjet(ByVal clientID As Long, _
ByVal nom As String, _
Optional ByVal description As String = "", _
Optional ByVal tauxHoraire As Currency = 0, _
Optional ByVal actif As Boolean = True, _
Optional ByVal projetID As Long = 0) As Long
Dim sql As String
If projetID = 0 Then
sql = "INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif, DateCreation) " & _
"VALUES (" & clientID & ", '" & EscapeSQL(nom) & "', '" & EscapeSQL(description) & "', " & _
tauxHoraire & ", " & IIf(actif, "True", "False") & ", Now())"
CurrentDb.Execute sql, dbFailOnError
SaveProjet = DMax("ProjetID", "tbl_Projets")
Else
sql = "UPDATE tbl_Projets SET " & _
"ClientID = " & clientID & ", " & _
"Nom = '" & EscapeSQL(nom) & "', " & _
"Description = '" & EscapeSQL(description) & "', " & _
"TauxHoraire = " & tauxHoraire & ", " & _
"Actif = " & IIf(actif, "True", "False") & " " & _
"WHERE ProjetID = " & projetID
CurrentDb.Execute sql, dbFailOnError
SaveProjet = projetID
End If
End Function
'-------------------------------------------------------------------------------
' Sub: DeleteProjet
' Description: Supprime un projet et ses entrees de temps
'-------------------------------------------------------------------------------
Public Sub DeleteProjet(ByVal projetID As Long)
CurrentDb.Execute "DELETE FROM tbl_Temps WHERE ProjetID = " & projetID
CurrentDb.Execute "DELETE FROM tbl_Projets WHERE ProjetID = " & projetID
End Sub
'===============================================================================
' TEMPS
'===============================================================================
'-------------------------------------------------------------------------------
' Function: GetTemps
' Description: Retourne les entrees de temps avec filtres
'-------------------------------------------------------------------------------
Public Function GetTemps(Optional ByVal projetID As Long = 0, _
Optional ByVal clientID As Long = 0, _
Optional ByVal dateDebut As Date = 0, _
Optional ByVal dateFin As Date = 0) As DAO.Recordset
Dim sql As String
sql = "SELECT t.*, p.Nom AS ProjetNom, c.Nom AS ClientNom, " & _
"t.Duree * p.TauxHoraire AS Montant " & _
"FROM (tbl_Temps t " & _
"INNER JOIN tbl_Projets p ON t.ProjetID = p.ProjetID) " & _
"INNER JOIN tbl_Clients c ON p.ClientID = c.ClientID WHERE 1=1"
If projetID > 0 Then
sql = sql & " AND t.ProjetID = " & projetID
End If
If clientID > 0 Then
sql = sql & " AND p.ClientID = " & clientID
End If
If dateDebut > 0 Then
sql = sql & " AND t.Date >= #" & Format(dateDebut, "yyyy-mm-dd") & "#"
End If
If dateFin > 0 Then
sql = sql & " AND t.Date <= #" & Format(dateFin, "yyyy-mm-dd") & "#"
End If
sql = sql & " ORDER BY t.Date DESC"
Set GetTemps = CurrentDb.OpenRecordset(sql, dbOpenDynaset)
End Function
'-------------------------------------------------------------------------------
' Function: SaveTemps
' Description: Sauvegarde une entree de temps
'-------------------------------------------------------------------------------
Public Function SaveTemps(ByVal projetID As Long, _
ByVal dateEntree As Date, _
ByVal duree As Double, _
Optional ByVal description As String = "", _
Optional ByVal tempsID As Long = 0) As Long
Dim sql As String
If tempsID = 0 Then
sql = "INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description, DateCreation) " & _
"VALUES (" & projetID & ", #" & Format(dateEntree, "yyyy-mm-dd") & "#, " & _
duree & ", '" & EscapeSQL(description) & "', Now())"
CurrentDb.Execute sql, dbFailOnError
SaveTemps = DMax("TempsID", "tbl_Temps")
Else
sql = "UPDATE tbl_Temps SET " & _
"ProjetID = " & projetID & ", " & _
"Date = #" & Format(dateEntree, "yyyy-mm-dd") & "#, " & _
"Duree = " & duree & ", " & _
"Description = '" & EscapeSQL(description) & "' " & _
"WHERE TempsID = " & tempsID
CurrentDb.Execute sql, dbFailOnError
SaveTemps = tempsID
End If
End Function
'-------------------------------------------------------------------------------
' Sub: DeleteTemps
' Description: Supprime une entree de temps
'-------------------------------------------------------------------------------
Public Sub DeleteTemps(ByVal tempsID As Long)
CurrentDb.Execute "DELETE FROM tbl_Temps WHERE TempsID = " & tempsID
End Sub
'===============================================================================
' HELPERS
'===============================================================================
'-------------------------------------------------------------------------------
' Function: EscapeSQL
' Description: Echappe les apostrophes pour SQL
'-------------------------------------------------------------------------------
Private Function EscapeSQL(ByVal text As String) As String
EscapeSQL = Replace(text, "'", "''")
End Function
```
---
## mod_Calculs
Fonctions de calcul et agregation.
```vba
'===============================================================================
' Module: mod_Calculs
' Description: Fonctions de calcul et agregation
' Auteur: Alexis Trouve
' Date: 2025-12-30
'===============================================================================
Option Compare Database
Option Explicit
'-------------------------------------------------------------------------------
' Function: GetTotalHeuresProjet
' Description: Total des heures pour un projet
'-------------------------------------------------------------------------------
Public Function GetTotalHeuresProjet(ByVal projetID As Long) As Double
GetTotalHeuresProjet = Nz(DSum("Duree", "tbl_Temps", "ProjetID = " & projetID), 0)
End Function
'-------------------------------------------------------------------------------
' Function: GetTotalHeuresClient
' Description: Total des heures pour un client
'-------------------------------------------------------------------------------
Public Function GetTotalHeuresClient(ByVal clientID As Long) As Double
Dim sql As String
sql = "SELECT SUM(t.Duree) AS Total FROM tbl_Temps t " & _
"INNER JOIN tbl_Projets p ON t.ProjetID = p.ProjetID " & _
"WHERE p.ClientID = " & clientID
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset(sql)
GetTotalHeuresClient = Nz(rs!Total, 0)
rs.Close
End Function
'-------------------------------------------------------------------------------
' Function: GetTotalHeuresPeriode
' Description: Total des heures sur une periode
'-------------------------------------------------------------------------------
Public Function GetTotalHeuresPeriode(ByVal dateDebut As Date, _
ByVal dateFin As Date, _
Optional ByVal clientID As Long = 0) As Double
Dim sql As String
sql = "SELECT SUM(t.Duree) AS Total FROM tbl_Temps t"
If clientID > 0 Then
sql = sql & " INNER JOIN tbl_Projets p ON t.ProjetID = p.ProjetID" & _
" WHERE p.ClientID = " & clientID & " AND"
Else
sql = sql & " WHERE"
End If
sql = sql & " t.Date BETWEEN #" & Format(dateDebut, "yyyy-mm-dd") & "#" & _
" AND #" & Format(dateFin, "yyyy-mm-dd") & "#"
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset(sql)
GetTotalHeuresPeriode = Nz(rs!Total, 0)
rs.Close
End Function
'-------------------------------------------------------------------------------
' Function: GetMontantProjet
' Description: Montant total pour un projet
'-------------------------------------------------------------------------------
Public Function GetMontantProjet(ByVal projetID As Long) As Currency
Dim heures As Double
Dim taux As Currency
heures = GetTotalHeuresProjet(projetID)
taux = Nz(DLookup("TauxHoraire", "tbl_Projets", "ProjetID = " & projetID), 0)
GetMontantProjet = heures * taux
End Function
'-------------------------------------------------------------------------------
' Function: GetMontantClient
' Description: Montant total pour un client
'-------------------------------------------------------------------------------
Public Function GetMontantClient(ByVal clientID As Long) As Currency
Dim sql As String
sql = "SELECT SUM(t.Duree * p.TauxHoraire) AS Total FROM tbl_Temps t " & _
"INNER JOIN tbl_Projets p ON t.ProjetID = p.ProjetID " & _
"WHERE p.ClientID = " & clientID
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset(sql)
GetMontantClient = Nz(rs!Total, 0)
rs.Close
End Function
'-------------------------------------------------------------------------------
' Function: GetHeuresMoisCourant
' Description: Total heures du mois en cours
'-------------------------------------------------------------------------------
Public Function GetHeuresMoisCourant() As Double
Dim dateDebut As Date
Dim dateFin As Date
dateDebut = DateSerial(Year(Date), Month(Date), 1)
dateFin = DateSerial(Year(Date), Month(Date) + 1, 0)
GetHeuresMoisCourant = GetTotalHeuresPeriode(dateDebut, dateFin)
End Function
'-------------------------------------------------------------------------------
' Function: GetHeuresSemaineCourante
' Description: Total heures de la semaine en cours
'-------------------------------------------------------------------------------
Public Function GetHeuresSemaineCourante() As Double
Dim dateDebut As Date
Dim dateFin As Date
dateDebut = Date - Weekday(Date, vbMonday) + 1
dateFin = dateDebut + 6
GetHeuresSemaineCourante = GetTotalHeuresPeriode(dateDebut, dateFin)
End Function
'-------------------------------------------------------------------------------
' Function: GetNbClients
' Description: Nombre total de clients
'-------------------------------------------------------------------------------
Public Function GetNbClients() As Long
GetNbClients = DCount("*", "tbl_Clients")
End Function
'-------------------------------------------------------------------------------
' Function: GetNbProjetsActifs
' Description: Nombre de projets actifs
'-------------------------------------------------------------------------------
Public Function GetNbProjetsActifs() As Long
GetNbProjetsActifs = DCount("*", "tbl_Projets", "Actif = True")
End Function
```
---
## mod_Export
Fonctions d'export PDF et Excel.
```vba
'===============================================================================
' Module: mod_Export
' Description: Fonctions d'export PDF et Excel
' Auteur: Alexis Trouve
' Date: 2025-12-30
'===============================================================================
Option Compare Database
Option Explicit
'-------------------------------------------------------------------------------
' Sub: ExportReportPDF
' Description: Exporte un rapport en PDF
'-------------------------------------------------------------------------------
Public Sub ExportReportPDF(ByVal reportName As String, _
Optional ByVal fileName As String = "")
Dim filePath As String
mod_Config.EnsureFoldersExist
If fileName = "" Then
fileName = reportName & "_" & Format(Now, "yyyymmdd_hhnnss") & ".pdf"
End If
filePath = EXPORT_PATH & fileName
DoCmd.OutputTo acOutputReport, reportName, acFormatPDF, filePath
MsgBox "Rapport exporte vers:" & vbCrLf & filePath, vbInformation
' Ouvrir le fichier
Shell "explorer """ & filePath & """", vbNormalFocus
End Sub
'-------------------------------------------------------------------------------
' Sub: ExportQueryExcel
' Description: Exporte une requete vers Excel
'-------------------------------------------------------------------------------
Public Sub ExportQueryExcel(ByVal queryName As String, _
Optional ByVal fileName As String = "")
Dim filePath As String
mod_Config.EnsureFoldersExist
If fileName = "" Then
fileName = queryName & "_" & Format(Now, "yyyymmdd_hhnnss") & ".xlsx"
End If
filePath = EXPORT_PATH & fileName
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, _
queryName, filePath, True
MsgBox "Donnees exportees vers:" & vbCrLf & filePath, vbInformation
' Ouvrir le fichier
Shell "explorer """ & filePath & """", vbNormalFocus
End Sub
'-------------------------------------------------------------------------------
' Sub: ExportTempsPeriodeExcel
' Description: Exporte les temps d'une periode vers Excel
'-------------------------------------------------------------------------------
Public Sub ExportTempsPeriodeExcel(ByVal dateDebut As Date, _
ByVal dateFin As Date, _
Optional ByVal clientID As Long = 0)
Dim sql As String
Dim qdf As DAO.QueryDef
Dim fileName As String
' Creer requete temporaire
sql = "SELECT t.Date, c.Nom AS Client, p.Nom AS Projet, " & _
"t.Duree, t.Description, t.Duree * p.TauxHoraire AS Montant " & _
"FROM (tbl_Temps t " & _
"INNER JOIN tbl_Projets p ON t.ProjetID = p.ProjetID) " & _
"INNER JOIN tbl_Clients c ON p.ClientID = c.ClientID " & _
"WHERE t.Date BETWEEN #" & Format(dateDebut, "yyyy-mm-dd") & "# " & _
"AND #" & Format(dateFin, "yyyy-mm-dd") & "#"
If clientID > 0 Then
sql = sql & " AND p.ClientID = " & clientID
End If
sql = sql & " ORDER BY t.Date"
' Supprimer si existe
On Error Resume Next
CurrentDb.QueryDefs.Delete "qry_TempExport"
On Error GoTo 0
Set qdf = CurrentDb.CreateQueryDef("qry_TempExport", sql)
' Exporter
fileName = "Temps_" & Format(dateDebut, "yyyymmdd") & "_" & _
Format(dateFin, "yyyymmdd") & ".xlsx"
ExportQueryExcel "qry_TempExport", fileName
' Nettoyer
CurrentDb.QueryDefs.Delete "qry_TempExport"
End Sub
```
---
## mod_Utils
Fonctions utilitaires diverses.
```vba
'===============================================================================
' Module: mod_Utils
' Description: Fonctions utilitaires diverses
' Auteur: Alexis Trouve
' Date: 2025-12-30
'===============================================================================
Option Compare Database
Option Explicit
'-------------------------------------------------------------------------------
' Function: FormatDuree
' Description: Formate une duree en heures
'-------------------------------------------------------------------------------
Public Function FormatDuree(ByVal heures As Double) As String
FormatDuree = Format(heures, "0.00") & " h"
End Function
'-------------------------------------------------------------------------------
' Function: FormatMontant
' Description: Formate un montant en euros
'-------------------------------------------------------------------------------
Public Function FormatMontant(ByVal montant As Currency) As String
FormatMontant = Format(montant, "#,##0.00") & " €"
End Function
'-------------------------------------------------------------------------------
' Function: FormatDateFR
' Description: Formate une date en francais
'-------------------------------------------------------------------------------
Public Function FormatDateFR(ByVal d As Date) As String
FormatDateFR = Format(d, "dd/mm/yyyy")
End Function
'-------------------------------------------------------------------------------
' Function: IsValidEmail
' Description: Valide un format email basique
'-------------------------------------------------------------------------------
Public Function IsValidEmail(ByVal email As String) As Boolean
If Len(email) = 0 Then
IsValidEmail = True ' Email optionnel
Exit Function
End If
IsValidEmail = (InStr(email, "@") > 1) And (InStr(email, ".") > InStr(email, "@") + 1)
End Function
'-------------------------------------------------------------------------------
' Function: GetFirstDayOfMonth
' Description: Premier jour du mois
'-------------------------------------------------------------------------------
Public Function GetFirstDayOfMonth(Optional ByVal d As Date = 0) As Date
If d = 0 Then d = Date
GetFirstDayOfMonth = DateSerial(Year(d), Month(d), 1)
End Function
'-------------------------------------------------------------------------------
' Function: GetLastDayOfMonth
' Description: Dernier jour du mois
'-------------------------------------------------------------------------------
Public Function GetLastDayOfMonth(Optional ByVal d As Date = 0) As Date
If d = 0 Then d = Date
GetLastDayOfMonth = DateSerial(Year(d), Month(d) + 1, 0)
End Function
'-------------------------------------------------------------------------------
' Function: GetFirstDayOfWeek
' Description: Premier jour de la semaine (lundi)
'-------------------------------------------------------------------------------
Public Function GetFirstDayOfWeek(Optional ByVal d As Date = 0) As Date
If d = 0 Then d = Date
GetFirstDayOfWeek = d - Weekday(d, vbMonday) + 1
End Function
'-------------------------------------------------------------------------------
' Sub: ShowError
' Description: Affiche un message d'erreur standardise
'-------------------------------------------------------------------------------
Public Sub ShowError(ByVal message As String, Optional ByVal details As String = "")
Dim msg As String
msg = message
If Len(details) > 0 Then
msg = msg & vbCrLf & vbCrLf & "Details: " & details
End If
MsgBox msg, vbExclamation, APP_NAME
End Sub
'-------------------------------------------------------------------------------
' Sub: ShowInfo
' Description: Affiche un message d'information
'-------------------------------------------------------------------------------
Public Sub ShowInfo(ByVal message As String)
MsgBox message, vbInformation, APP_NAME
End Sub
'-------------------------------------------------------------------------------
' Function: Confirm
' Description: Demande confirmation a l'utilisateur
'-------------------------------------------------------------------------------
Public Function Confirm(ByVal message As String) As Boolean
Confirm = (MsgBox(message, vbQuestion + vbYesNo, APP_NAME) = vbYes)
End Function
'-------------------------------------------------------------------------------
' Sub: LogAction
' Description: Log une action (pour debug)
'-------------------------------------------------------------------------------
Public Sub LogAction(ByVal action As String)
Debug.Print Format(Now, "yyyy-mm-dd hh:nn:ss") & " - " & action
End Sub
```
---
## Injection via MCP VBA
Pour injecter ces modules dans une base Access :
```python
# Avec VBA MCP Server
inject_vba("TimeTrackPro.accdb", "mod_Config", code_config)
inject_vba("TimeTrackPro.accdb", "mod_Navigation", code_navigation)
inject_vba("TimeTrackPro.accdb", "mod_DataAccess", code_dataaccess)
inject_vba("TimeTrackPro.accdb", "mod_Calculs", code_calculs)
inject_vba("TimeTrackPro.accdb", "mod_Export", code_export)
inject_vba("TimeTrackPro.accdb", "mod_Utils", code_utils)
```
---
**Version:** 1.0
**Date:** 2025-12-30

BIN
db/TimeTrackPro.accdb Normal file

Binary file not shown.

226
docs/MCP_VBA_GUIDE.md Normal file
View File

@ -0,0 +1,226 @@
# TimeTrack Pro - Guide MCP VBA
Comment utiliser VBA MCP Server pour construire ce projet.
## Prerequis
1. VBA MCP Server v0.6.0+ installe
2. Microsoft Access installe
3. "Trust access to VBA project object model" active dans Access
## Outils MCP Disponibles
### Pour Access
| Outil | Usage dans ce projet |
|-------|---------------------|
| `run_access_query` | Creer tables, executer SQL |
| `list_access_tables` | Verifier structure |
| `list_access_queries` | Lister requetes sauvegardees |
| `get_worksheet_data` | Lire donnees des tables |
| `set_worksheet_data` | Inserer donnees de test |
| `inject_vba` | Injecter les 6 modules VBA |
| `validate_vba` | Valider syntaxe avant injection |
| `create_backup` | Sauvegarder avant modifications |
---
## Etape 1: Creer la Base Access Vide
**Manuel:** Ouvrir Access > Nouvelle base > Enregistrer comme `TimeTrackPro.accdb`
**Emplacement:** `C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb`
---
## Etape 2: Creer les Tables
```
Utilise run_access_query pour executer chaque instruction SQL.
Les scripts sont dans: scripts/01_create_tables.sql
```
### Table tbl_Clients
```sql
CREATE TABLE tbl_Clients (
ClientID AUTOINCREMENT PRIMARY KEY,
Nom TEXT(100) NOT NULL,
Email TEXT(100),
Telephone TEXT(20),
Notes MEMO,
DateCreation DATETIME DEFAULT Now()
)
```
### Table tbl_Projets
```sql
CREATE TABLE tbl_Projets (
ProjetID AUTOINCREMENT PRIMARY KEY,
ClientID LONG NOT NULL,
Nom TEXT(100) NOT NULL,
Description MEMO,
TauxHoraire CURRENCY DEFAULT 0,
Actif YESNO DEFAULT True,
DateCreation DATETIME DEFAULT Now()
)
```
### Table tbl_Temps
```sql
CREATE TABLE tbl_Temps (
TempsID AUTOINCREMENT PRIMARY KEY,
ProjetID LONG NOT NULL,
Date DATETIME NOT NULL,
Duree DOUBLE NOT NULL,
Description MEMO,
DateCreation DATETIME DEFAULT Now()
)
```
### Verification
```
Utilise list_access_tables pour verifier que les 3 tables sont creees.
```
---
## Etape 3: Inserer Donnees de Test
```
Utilise run_access_query ou set_worksheet_data pour inserer les donnees.
Les scripts sont dans: scripts/03_sample_data.sql
```
### Exemple avec set_worksheet_data
```python
# Clients
data = [
["Acme Corporation", "contact@acme.com", "01 23 45 67 89", "Client principal"],
["Tech Solutions", "info@techsol.fr", "01 98 76 54 32", "Startup tech"],
]
columns = ["Nom", "Email", "Telephone", "Notes"]
set_worksheet_data("TimeTrackPro.accdb", "tbl_Clients", data, columns, mode="append")
```
---
## Etape 4: Injecter les Modules VBA
```
Utilise inject_vba pour chaque module.
Le code complet est dans: VBA_MODULES.md
```
### Ordre d'injection recommande
1. `mod_Config` - Constantes et parametres
2. `mod_Utils` - Fonctions utilitaires
3. `mod_DataAccess` - CRUD donnees
4. `mod_Calculs` - Fonctions de calcul
5. `mod_Navigation` - Navigation formulaires
6. `mod_Export` - Export PDF/Excel
### Exemple
```
inject_vba("TimeTrackPro.accdb", "mod_Config", "<code du module>")
```
### Validation avant injection
```
validate_vba("<code>", file_type="access")
```
---
## Etape 5: Verifier l'Installation
### Lister les modules
```
Utilise la session manager pour lister les VBComponents.
```
### Tester une fonction
```sql
-- Via run_access_query
SELECT * FROM tbl_Clients
```
---
## Commandes Frequentes
### Voir les tables
```
list_access_tables("db/TimeTrackPro.accdb")
```
### Lire des donnees
```
get_worksheet_data("db/TimeTrackPro.accdb", "tbl_Clients")
```
### Executer SQL
```
run_access_query("db/TimeTrackPro.accdb", sql="SELECT * FROM tbl_Temps WHERE Date > #2025-01-01#")
```
### Ajouter une entree de temps
```
run_access_query("db/TimeTrackPro.accdb", sql="INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description) VALUES (1, #2025-01-15#, 3.5, 'Travail effectue')")
```
### Sauvegarder avant modification
```
create_backup("db/TimeTrackPro.accdb")
```
---
## Limitations Connues
| Limitation | Workaround |
|------------|------------|
| Formulaires Access | Creer manuellement dans Access UI |
| Rapports Access | Creer manuellement dans Access UI |
| run_macro Access | Utiliser inject_vba + SQL direct |
| list_modules .accdb | Utiliser session manager COM |
---
## Workflow Complet
```
1. create_backup → Sauvegarde
2. run_access_query → CREATE TABLE (x3)
3. list_access_tables → Verification
4. set_worksheet_data → Donnees test
5. validate_vba → Valider code
6. inject_vba → Injecter modules (x6)
7. get_worksheet_data → Verification finale
```
---
## Fichiers de Reference
| Fichier | Contenu |
|---------|---------|
| `scripts/01_create_tables.sql` | SQL creation tables |
| `scripts/02_create_queries.sql` | Requetes sauvegardees |
| `scripts/03_sample_data.sql` | Donnees de test |
| `VBA_MODULES.md` | Code VBA complet |
| `DATABASE.md` | Schema detaille |

345
plans/implemPlan.md Normal file
View File

@ -0,0 +1,345 @@
# TimeTrack Pro - Plan d'Implementation pour Agent
## Informations Critiques
**Fichier cible:** `C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb`
**Prerequis humain:** Le fichier `.accdb` doit exister (base Access vide creee manuellement).
**Outils MCP utilises:**
- `run_access_query` - Execution SQL
- `list_access_tables` - Verification tables
- `get_worksheet_data` - Lecture donnees
- `set_worksheet_data` - Ecriture donnees
- `inject_vba` - Injection modules VBA
- `validate_vba_code` - Validation syntaxe VBA
- `backup_vba` - Sauvegarde fichier
---
## Phase 0 : Verification Prerequis
### Step 0.1 - Verifier existence fichier
```
Action: list_access_tables
Params: file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
```
- **Si erreur "fichier introuvable":** STOP - Demander a l'utilisateur de creer la base Access vide
- **Si succes (meme vide):** Continuer
### Step 0.2 - Creer backup
```
Action: backup_vba
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
action = "create"
```
- Noter le backup_id pour restauration eventuelle
---
## Phase 1 : Creation Structure BDD
### Step 1.1 - Creer table tbl_Clients
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "CREATE TABLE tbl_Clients (ClientID AUTOINCREMENT PRIMARY KEY, Nom TEXT(100) NOT NULL, Email TEXT(100), Telephone TEXT(20), Notes MEMO, DateCreation DATETIME DEFAULT Now())"
```
- **Si erreur "table existe deja":** Ignorer et continuer
- **Si autre erreur:** STOP et reporter
### Step 1.2 - Creer table tbl_Projets
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "CREATE TABLE tbl_Projets (ProjetID AUTOINCREMENT PRIMARY KEY, ClientID LONG NOT NULL, Nom TEXT(100) NOT NULL, Description MEMO, TauxHoraire CURRENCY DEFAULT 0, Actif YESNO DEFAULT True, DateCreation DATETIME DEFAULT Now())"
```
### Step 1.3 - Creer table tbl_Temps
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "CREATE TABLE tbl_Temps (TempsID AUTOINCREMENT PRIMARY KEY, ProjetID LONG NOT NULL, DateEntree DATETIME NOT NULL, Duree DOUBLE NOT NULL, Description MEMO, DateCreation DATETIME DEFAULT Now())"
```
**Note:** Utiliser `DateEntree` au lieu de `Date` (mot reserve SQL)
### Step 1.4 - Verification Checkpoint 1
```
Action: list_access_tables
Params: file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
```
- **Attendu:** 3 tables (tbl_Clients, tbl_Projets, tbl_Temps)
- **Si manquant:** Reprendre les steps 1.1-1.3 pour les tables manquantes
### Step 1.5 - Creer index (optionnel mais recommande)
```
Action: run_access_query (x4)
sql_1 = "CREATE INDEX idx_Projets_ClientID ON tbl_Projets (ClientID)"
sql_2 = "CREATE INDEX idx_Temps_ProjetID ON tbl_Temps (ProjetID)"
sql_3 = "CREATE INDEX idx_Temps_Date ON tbl_Temps (DateEntree)"
sql_4 = "CREATE INDEX idx_Projets_Actif ON tbl_Projets (Actif)"
```
- Ignorer erreurs "index existe deja"
---
## Phase 2 : Insertion Donnees de Test
### Step 2.1 - Inserer Clients
```
Action: set_worksheet_data
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sheet_name = "tbl_Clients"
columns = ["Nom", "Email", "Telephone", "Notes"]
mode = "append"
data = [
["Acme Corporation", "contact@acme.com", "01 23 45 67 89", "Client principal"],
["Tech Solutions", "info@techsol.fr", "01 98 76 54 32", "Startup tech"],
["Freelance Direct", "hello@freelance.io", "", "Plateforme freelance"],
["Marketing Pro", "contact@marketingpro.fr", "06 11 22 33 44", "Agence marketing"]
]
```
### Step 2.2 - Verifier Clients inseres
```
Action: get_worksheet_data
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sheet_name = "tbl_Clients"
```
- **Attendu:** 4 enregistrements avec ClientID 1-4
- Noter les ClientID pour la suite
### Step 2.3 - Inserer Projets
```
Action: set_worksheet_data
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sheet_name = "tbl_Projets"
columns = ["ClientID", "Nom", "Description", "TauxHoraire", "Actif"]
mode = "append"
data = [
[1, "Site Web Corporate", "Refonte du site web principal", 75, true],
[1, "Maintenance Mensuelle", "Support et maintenance", 60, true],
[2, "API Backend", "Developpement API REST", 85, true],
[2, "App Mobile", "Application iOS/Android", 90, true],
[3, "Consulting Tech", "Conseil et accompagnement", 100, true],
[4, "Campagne SEO", "Optimisation referencement", 70, true]
]
```
### Step 2.4 - Verifier Projets inseres
```
Action: get_worksheet_data
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sheet_name = "tbl_Projets"
```
- **Attendu:** 6 enregistrements avec ProjetID 1-6
### Step 2.5 - Inserer Temps
```
Action: set_worksheet_data
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sheet_name = "tbl_Temps"
columns = ["ProjetID", "DateEntree", "Duree", "Description"]
mode = "append"
data = [
[1, "2025-01-02", 3.5, "Maquettes et wireframes"],
[1, "2025-01-03", 4.0, "Integration HTML/CSS"],
[1, "2025-01-06", 5.5, "Developpement pages dynamiques"],
[2, "2025-01-07", 1.5, "Mise a jour plugins"],
[2, "2025-01-08", 2.0, "Correction bugs mineurs"],
[3, "2025-01-02", 6.0, "Architecture et endpoints"],
[3, "2025-01-03", 7.0, "Implementation CRUD"],
[3, "2025-01-06", 4.5, "Tests unitaires"],
[4, "2025-01-07", 5.0, "Setup projet React Native"],
[4, "2025-01-08", 6.5, "Ecrans principaux"],
[5, "2025-01-03", 2.0, "Reunion strategie technique"],
[5, "2025-01-09", 3.0, "Audit architecture existante"],
[6, "2025-01-06", 4.0, "Analyse mots-cles"],
[6, "2025-01-08", 3.5, "Optimisation on-page"]
]
```
### Step 2.6 - Verification Checkpoint 2
```
Action: get_worksheet_data
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sheet_name = "tbl_Temps"
```
- **Attendu:** 14 enregistrements
### Step 2.7 - Test requete agregation
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "SELECT COUNT(*) AS NbTemps, SUM(Duree) AS TotalHeures FROM tbl_Temps"
```
- **Attendu:** NbTemps = 14, TotalHeures = 58.0
---
## Phase 3 : Injection Modules VBA
**Important:** Lire le code de chaque module dans `VBA_MODULES.md` avant injection.
### Step 3.1 - Valider mod_Config
```
Action: validate_vba_code
Params:
code = "<contenu de mod_Config depuis VBA_MODULES.md>"
file_type = "excel"
```
- **Si erreurs syntaxe:** Corriger et revalider
- **Si succes:** Continuer
### Step 3.2 - Injecter mod_Config
```
Action: inject_vba
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
module_name = "mod_Config"
code = "<contenu valide>"
```
### Step 3.3 - Valider et Injecter mod_Utils
```
Action: validate_vba_code puis inject_vba
module_name = "mod_Utils"
```
### Step 3.4 - Valider et Injecter mod_DataAccess
```
Action: validate_vba_code puis inject_vba
module_name = "mod_DataAccess"
```
### Step 3.5 - Valider et Injecter mod_Calculs
```
Action: validate_vba_code puis inject_vba
module_name = "mod_Calculs"
```
### Step 3.6 - Valider et Injecter mod_Navigation
```
Action: validate_vba_code puis inject_vba
module_name = "mod_Navigation"
```
### Step 3.7 - Valider et Injecter mod_Export
```
Action: validate_vba_code puis inject_vba
module_name = "mod_Export"
```
### Step 3.8 - Verification Checkpoint 3
```
Action: list_modules (via extract_vba ou list_macros)
Params: file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
```
- **Attendu:** 6 modules (mod_Config, mod_Utils, mod_DataAccess, mod_Calculs, mod_Navigation, mod_Export)
---
## Phase 4 : Verification Finale
### Step 4.1 - Test requete TempsByClient
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "SELECT c.Nom AS Client, SUM(t.Duree) AS TotalHeures FROM (tbl_Clients c INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID) INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID GROUP BY c.Nom ORDER BY c.Nom"
```
- **Attendu:** 4 clients avec leurs totaux heures
### Step 4.2 - Test requete ProjetsActifs
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "SELECT p.Nom AS Projet, c.Nom AS Client, p.TauxHoraire FROM tbl_Clients c INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID WHERE p.Actif = True"
```
- **Attendu:** 6 projets actifs
### Step 4.3 - Test calcul montant
```
Action: run_access_query
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
sql = "SELECT SUM(t.Duree * p.TauxHoraire) AS MontantTotal FROM tbl_Temps t INNER JOIN tbl_Projets p ON t.ProjetID = p.ProjetID"
```
- **Attendu:** Montant > 0 (calcul taux * heures)
---
## Phase 5 : Post-Implementation (Manuel)
Ces etapes ne sont PAS automatisables par MCP VBA et doivent etre faites dans Access UI :
### 5.1 - Creer Formulaires
- [ ] frm_Accueil - Navigation + stats
- [ ] frm_Clients - CRUD clients
- [ ] frm_Projets - CRUD projets (filtre par client)
- [ ] frm_SaisieTemps - Saisie rapide
- [ ] frm_Historique - Liste filtrable
### 5.2 - Creer Rapports
- [ ] rpt_RecapPeriode - Recap par periode
- [ ] rpt_DetailClient - Detail par client
### 5.3 - Configurer Navigation
- [ ] Formulaire de demarrage
- [ ] Menu principal
- [ ] Boutons de navigation
---
## Resume Checkpoints
| Checkpoint | Verification | Critere Succes |
|------------|--------------|----------------|
| CP0 | Fichier existe | list_access_tables sans erreur |
| CP1 | Tables creees | 3 tables visibles |
| CP2 | Donnees inserees | 4 clients, 6 projets, 14 temps |
| CP3 | Modules VBA | 6 modules injectes |
| CP4 | Requetes OK | Agregations retournent donnees |
---
## Gestion des Erreurs
| Erreur | Action |
|--------|--------|
| "fichier introuvable" | Demander creation manuelle base Access |
| "table existe deja" | Ignorer et continuer |
| "index existe deja" | Ignorer et continuer |
| "erreur syntaxe VBA" | Revoir code, corriger, revalider |
| "Trust access to VBA" | Activer dans Access > Options > Trust Center |
| Autre erreur | STOP, backup_vba restore, reporter |
---
## Commande de Restauration (si besoin)
```
Action: backup_vba
Params:
file_path = "C:\Users\alexi\Documents\projects\timetrack-pro\db\TimeTrackPro.accdb"
action = "restore"
backup_id = "<id du backup cree en Step 0.2>"
```
---
**Auteur:** Claude
**Date:** 2025-12-30
**Version:** 1.0

View File

@ -0,0 +1,57 @@
-- TimeTrack Pro - Script de creation des tables
-- A executer via run_access_query de VBA MCP Server
-- ============================================================
-- TABLE: tbl_Clients
-- ============================================================
CREATE TABLE tbl_Clients (
ClientID AUTOINCREMENT PRIMARY KEY,
Nom TEXT(100) NOT NULL,
Email TEXT(100),
Telephone TEXT(20),
Notes MEMO,
DateCreation DATETIME DEFAULT Now()
);
-- ============================================================
-- TABLE: tbl_Projets
-- ============================================================
CREATE TABLE tbl_Projets (
ProjetID AUTOINCREMENT PRIMARY KEY,
ClientID LONG NOT NULL,
Nom TEXT(100) NOT NULL,
Description MEMO,
TauxHoraire CURRENCY DEFAULT 0,
Actif YESNO DEFAULT True,
DateCreation DATETIME DEFAULT Now()
);
-- Relation avec tbl_Clients
ALTER TABLE tbl_Projets
ADD CONSTRAINT FK_Projets_Clients
FOREIGN KEY (ClientID) REFERENCES tbl_Clients(ClientID);
-- ============================================================
-- TABLE: tbl_Temps
-- ============================================================
CREATE TABLE tbl_Temps (
TempsID AUTOINCREMENT PRIMARY KEY,
ProjetID LONG NOT NULL,
Date DATETIME NOT NULL,
Duree DOUBLE NOT NULL,
Description MEMO,
DateCreation DATETIME DEFAULT Now()
);
-- Relation avec tbl_Projets
ALTER TABLE tbl_Temps
ADD CONSTRAINT FK_Temps_Projets
FOREIGN KEY (ProjetID) REFERENCES tbl_Projets(ProjetID);
-- ============================================================
-- INDEX
-- ============================================================
CREATE INDEX idx_Projets_ClientID ON tbl_Projets (ClientID);
CREATE INDEX idx_Temps_ProjetID ON tbl_Temps (ProjetID);
CREATE INDEX idx_Temps_Date ON tbl_Temps (Date);
CREATE INDEX idx_Projets_Actif ON tbl_Projets (Actif);

View File

@ -0,0 +1,81 @@
-- TimeTrack Pro - Requetes sauvegardees
-- Note: A creer manuellement dans Access ou via VBA
-- ============================================================
-- qry_TempsByProjet
-- Total des heures par projet
-- ============================================================
SELECT
p.Nom AS Projet,
c.Nom AS Client,
SUM(t.Duree) AS TotalHeures,
SUM(t.Duree * p.TauxHoraire) AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
GROUP BY p.Nom, c.Nom
ORDER BY c.Nom, p.Nom;
-- ============================================================
-- qry_TempsByClient
-- Total des heures par client
-- ============================================================
SELECT
c.Nom AS Client,
COUNT(DISTINCT p.ProjetID) AS NbProjets,
SUM(t.Duree) AS TotalHeures,
SUM(t.Duree * p.TauxHoraire) AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
GROUP BY c.Nom
ORDER BY c.Nom;
-- ============================================================
-- qry_ProjetsActifs
-- Liste des projets actifs avec client
-- ============================================================
SELECT
p.ProjetID,
p.Nom AS Projet,
c.Nom AS Client,
p.TauxHoraire,
p.DateCreation
FROM tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID
WHERE p.Actif = True
ORDER BY c.Nom, p.Nom;
-- ============================================================
-- qry_TempsRecent
-- Entrees de temps des 30 derniers jours
-- ============================================================
SELECT
t.Date,
c.Nom AS Client,
p.Nom AS Projet,
t.Duree,
t.Description,
t.Duree * p.TauxHoraire AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
WHERE t.Date >= Date() - 30
ORDER BY t.Date DESC;
-- ============================================================
-- qry_TempsMoisCourant
-- Entrees du mois en cours
-- ============================================================
SELECT
t.Date,
c.Nom AS Client,
p.Nom AS Projet,
t.Duree,
t.Description,
t.Duree * p.TauxHoraire AS Montant
FROM (tbl_Clients c
INNER JOIN tbl_Projets p ON c.ClientID = p.ClientID)
INNER JOIN tbl_Temps t ON p.ProjetID = t.ProjetID
WHERE Year(t.Date) = Year(Date()) AND Month(t.Date) = Month(Date())
ORDER BY t.Date DESC;

View File

@ -0,0 +1,93 @@
-- TimeTrack Pro - Donnees de test
-- A executer via run_access_query de VBA MCP Server
-- ============================================================
-- CLIENTS
-- ============================================================
INSERT INTO tbl_Clients (Nom, Email, Telephone, Notes)
VALUES ('Acme Corporation', 'contact@acme.com', '01 23 45 67 89', 'Client principal');
INSERT INTO tbl_Clients (Nom, Email, Telephone, Notes)
VALUES ('Tech Solutions', 'info@techsol.fr', '01 98 76 54 32', 'Startup tech');
INSERT INTO tbl_Clients (Nom, Email, Telephone, Notes)
VALUES ('Freelance Direct', 'hello@freelance.io', '', 'Plateforme freelance');
INSERT INTO tbl_Clients (Nom, Email, Telephone, Notes)
VALUES ('Marketing Pro', 'contact@marketingpro.fr', '06 11 22 33 44', 'Agence marketing');
-- ============================================================
-- PROJETS
-- ============================================================
-- Acme Corporation (ClientID = 1)
INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif)
VALUES (1, 'Site Web Corporate', 'Refonte du site web principal', 75, True);
INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif)
VALUES (1, 'Maintenance Mensuelle', 'Support et maintenance', 60, True);
-- Tech Solutions (ClientID = 2)
INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif)
VALUES (2, 'API Backend', 'Developpement API REST', 85, True);
INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif)
VALUES (2, 'App Mobile', 'Application iOS/Android', 90, True);
-- Freelance Direct (ClientID = 3)
INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif)
VALUES (3, 'Consulting Tech', 'Conseil et accompagnement', 100, True);
-- Marketing Pro (ClientID = 4)
INSERT INTO tbl_Projets (ClientID, Nom, Description, TauxHoraire, Actif)
VALUES (4, 'Campagne SEO', 'Optimisation referencement', 70, True);
-- ============================================================
-- TEMPS
-- ============================================================
-- Site Web Corporate
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (1, #2025-01-02#, 3.5, 'Maquettes et wireframes');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (1, #2025-01-03#, 4.0, 'Integration HTML/CSS');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (1, #2025-01-06#, 5.5, 'Developpement pages dynamiques');
-- Maintenance Mensuelle
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (2, #2025-01-07#, 1.5, 'Mise a jour plugins');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (2, #2025-01-08#, 2.0, 'Correction bugs mineurs');
-- API Backend
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (3, #2025-01-02#, 6.0, 'Architecture et endpoints');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (3, #2025-01-03#, 7.0, 'Implementation CRUD');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (3, #2025-01-06#, 4.5, 'Tests unitaires');
-- App Mobile
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (4, #2025-01-07#, 5.0, 'Setup projet React Native');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (4, #2025-01-08#, 6.5, 'Ecrans principaux');
-- Consulting Tech
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (5, #2025-01-03#, 2.0, 'Reunion strategie technique');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (5, #2025-01-09#, 3.0, 'Audit architecture existante');
-- Campagne SEO
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (6, #2025-01-06#, 4.0, 'Analyse mots-cles');
INSERT INTO tbl_Temps (ProjetID, Date, Duree, Description)
VALUES (6, #2025-01-08#, 3.5, 'Optimisation on-page');