feat(export): UI unificada de Excel + PDF en los 4 módulos

- Nuevos assets compartidos /assets/donna-export.{css,js}: botón
  "Exportar ▾" + menú dropdown Excel/PDF y helpers DonnaExport.toExcel
  / .toPDF / .attach / .buttonHtml
- escrituras: refactor de exportExcel/exportPDF para usar el módulo
  compartido (sin cambio de comportamiento)
- tramites: nuevo botón en la toolbar de cada tab (adm/corp/mig/lit),
  exporta los rows filtrados de ese tab; PDF excluye Involucrados
- calendario: nuevo botón al final de la toolbar, exporta visibleEvents()
  (respeta chips de origen y búsqueda)
- horas: reemplaza CSV server-side por XLSX client-side + agrega PDF;
  removida la acción ?action=export del api.php
This commit is contained in:
Soporte ZH Consultores
2026-06-04 22:30:37 -05:00
parent 012c4e1c66
commit eff590af47
7 changed files with 377 additions and 236 deletions
+1 -31
View File
@@ -19,7 +19,7 @@ $method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';
$pdo = Db::pdo();
if ($method !== 'GET' || !in_array($action, ['list','export'], true)) err('Acción no reconocida', 404);
if ($method !== 'GET' || $action !== 'list') err('Acción no reconocida', 404);
try {
$from = clean_date($_GET['from'] ?? null);
@@ -175,36 +175,6 @@ try {
unset($u);
}
if ($action === 'export') {
// CSV con BOM UTF-8 para que Excel lea acentos correctamente
$filename = 'horas_' . date('Y-m-d_His') . '.csv';
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
$deptLabels = ['adm'=>'Administrativo', 'corp'=>'Corp · Com · Civil', 'mig'=>'Migración', 'lit'=>'Litigios'];
$out = fopen('php://output', 'w');
fwrite($out, "\xEF\xBB\xBF");
fputcsv($out, ['Fecha', 'Abogado', 'Departamento', 'Código', 'Trámite', 'Cliente', 'Estatus', 'Horas', 'Descripción']);
foreach ($entries as $e) {
$hrs = (float)$e['hrs'];
$full = floor($hrs);
$mins = (int)round(($hrs - $full) * 60);
$hrsFmt = $mins === 0 ? (string)$full : sprintf('%d:%02d', $full, $mins);
fputcsv($out, [
date('Y-m-d H:i', strtotime($e['fecha'])),
$e['abogado'],
$deptLabels[$e['tramite_departamento']] ?? $e['tramite_departamento'],
$e['tramite_codigo'],
$e['tramite_title'],
$e['tramite_cliente'],
$e['tramite_estatus'],
$hrsFmt,
$e['descripcion'],
]);
}
fclose($out);
exit;
}
ok([
'entries' => $entries,
'by_user' => $byUser,