Initial commit — Mek-Tech AI Consultancy Framework v2.0
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { getDb } = require('../db');
|
||||
|
||||
function initReportsTable() {
|
||||
const db = getDb();
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS reports (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
report_type TEXT DEFAULT 'client_summary',
|
||||
client_id INTEGER REFERENCES clients(id) ON DELETE SET NULL,
|
||||
project_id INTEGER,
|
||||
config TEXT DEFAULT '{}',
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
initReportsTable();
|
||||
const db = getDb();
|
||||
const tab = req.query.tab || 'builder';
|
||||
const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
|
||||
let projects = [];
|
||||
try { projects = db.prepare('SELECT id, name FROM projects ORDER BY name').all(); } catch (e) {}
|
||||
const savedReports = db.prepare(`
|
||||
SELECT r.*, c.name as client_name FROM reports r
|
||||
LEFT JOIN clients c ON c.id = r.client_id ORDER BY r.created_at DESC LIMIT 20
|
||||
`).all();
|
||||
res.render('reports', { tab, clients, projects, savedReports });
|
||||
});
|
||||
|
||||
router.get('/generate', async (req, res) => {
|
||||
const { report_type, client_id, project_id, date_from, date_to, format } = req.query;
|
||||
const db = getDb();
|
||||
let data = [];
|
||||
|
||||
if (report_type === 'client_summary') {
|
||||
data = db.prepare(`
|
||||
SELECT c.*,
|
||||
(SELECT COUNT(*) FROM engagements e WHERE e.client_id = c.id) as engagement_count,
|
||||
(SELECT COALESCE(SUM(i.total),0) FROM invoices i WHERE i.client_id = c.id) as total_revenue
|
||||
FROM clients c WHERE (? = '' OR ? IS NULL OR c.id = ?)
|
||||
`).all(client_id || '', client_id || '', client_id || '');
|
||||
} else if (report_type === 'financial') {
|
||||
data = db.prepare(`
|
||||
SELECT i.*, c.name as client_name FROM invoices i
|
||||
LEFT JOIN clients c ON c.id = i.client_id
|
||||
WHERE (? = '' OR i.created_at >= ?) AND (? = '' OR i.created_at <= ?)
|
||||
`).all(date_from || '', date_from || '', date_to || '', date_to || '');
|
||||
} else if (report_type === 'time') {
|
||||
data = db.prepare(`
|
||||
SELECT t.*, c.name as client_name, e.title as engagement_title
|
||||
FROM time_entries t
|
||||
LEFT JOIN clients c ON c.id = t.client_id
|
||||
LEFT JOIN engagements e ON e.id = t.engagement_id
|
||||
ORDER BY t.date DESC LIMIT 500
|
||||
`).all();
|
||||
} else if (report_type === 'project_summary') {
|
||||
data = db.prepare(`
|
||||
SELECT p.*, c.name as client_name,
|
||||
(SELECT COUNT(*) FROM project_tasks pt WHERE pt.project_id = p.id) as task_count
|
||||
FROM projects p LEFT JOIN clients c ON c.id = p.client_id
|
||||
WHERE (? = '' OR ? IS NULL OR p.id = ?)
|
||||
`).all(project_id || '', project_id || '', project_id || '');
|
||||
}
|
||||
|
||||
if (format === 'pdf' || format === 'excel') {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
return res.json({ report_type, format, data, generated_at: new Date().toISOString(), note: 'JSON export — open in browser of gebruik Opslaan in rapporten' });
|
||||
}
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.json({ report_type, data, count: data.length });
|
||||
});
|
||||
|
||||
router.post('/generate', async (req, res) => {
|
||||
const { report_type, client_id, project_id, date_from, date_to, format } = req.body;
|
||||
const db = getDb();
|
||||
let data = [];
|
||||
|
||||
if (report_type === 'client_summary') {
|
||||
data = db.prepare(`
|
||||
SELECT c.*,
|
||||
(SELECT COUNT(*) FROM engagements e WHERE e.client_id = c.id) as engagement_count,
|
||||
(SELECT COALESCE(SUM(i.total),0) FROM invoices i WHERE i.client_id = c.id) as total_revenue
|
||||
FROM clients c WHERE (? = '' OR c.id = ?)
|
||||
`).all(client_id || '', client_id || '');
|
||||
} else if (report_type === 'financial') {
|
||||
data = db.prepare(`
|
||||
SELECT i.*, c.name as client_name FROM invoices i
|
||||
LEFT JOIN clients c ON c.id = i.client_id
|
||||
WHERE (? = '' OR i.created_at >= ?) AND (? = '' OR i.created_at <= ?)
|
||||
`).all(date_from || '', date_from || '', date_to || '', date_to || '');
|
||||
}
|
||||
|
||||
if (format === 'pdf' || format === 'excel') {
|
||||
return res.json({ data, note: 'Export naar PDF/Excel — installeer pdfkit/exceljs of gebruik JSON' });
|
||||
}
|
||||
res.json({ data });
|
||||
});
|
||||
|
||||
router.post('/save', (req, res) => {
|
||||
initReportsTable();
|
||||
const db = getDb();
|
||||
const body = req.body;
|
||||
const name = body.name || 'Rapport ' + new Date().toLocaleDateString('nl-NL');
|
||||
const report_type = body.report_type || (body.config && body.config.report_type) || 'client_summary';
|
||||
const client_id = body.client_id || (body.config && body.config.client_id) || null;
|
||||
const project_id = body.project_id || (body.config && body.config.project_id) || null;
|
||||
const config = typeof body.config === 'string' ? body.config : JSON.stringify(body.config || body);
|
||||
db.prepare(`INSERT INTO reports (name, report_type, client_id, project_id, config) VALUES (?, ?, ?, ?, ?)`)
|
||||
.run(name, report_type, client_id, project_id, config);
|
||||
if (req.headers.accept && req.headers.accept.includes('application/json')) {
|
||||
return res.json({ success: true });
|
||||
}
|
||||
res.redirect('/reports?saved=1');
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user