81 lines
3.0 KiB
PHP
81 lines
3.0 KiB
PHP
<?php
|
|
// pagos/api/movimientos.php
|
|
require_once 'auth.php'; // Protección de acceso
|
|
header('Content-Type: application/json');
|
|
require_once 'db.php';
|
|
|
|
$pdo = getDB();
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
if ($method === 'GET') {
|
|
// Retornar balance, datos para gráfico y últimos movimientos
|
|
try {
|
|
// 1. Balance total
|
|
$stmtBalance = $pdo->query("SELECT
|
|
SUM(CASE WHEN tipo = 'ingreso' THEN monto ELSE -monto END) as balance
|
|
FROM movimientos");
|
|
$balance = $stmtBalance->fetch(PDO::FETCH_ASSOC)['balance'] ?? 0;
|
|
|
|
// 2. Últimos movimientos
|
|
$stmtMovi = $pdo->query("SELECT m.*, c.nombre as categoria_nombre, c.icono as categoria_icono
|
|
FROM movimientos m
|
|
LEFT JOIN categorias c ON m.id_categoria = c.id
|
|
ORDER BY m.fecha DESC, m.id DESC LIMIT 5");
|
|
$movimientos = $stmtMovi->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// 3. Agrupación por categoría para gráfico donut (sólo gastos de este mes/año)
|
|
// Por simplicidad traemos todos los gastos
|
|
$stmtGraph = $pdo->query("SELECT c.nombre, c.color_hex, SUM(m.monto) as total
|
|
FROM movimientos m
|
|
JOIN categorias c ON m.id_categoria = c.id
|
|
WHERE m.tipo = 'gasto'
|
|
GROUP BY c.id
|
|
ORDER BY total DESC");
|
|
$grafico = $stmtGraph->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// 4. Categorías para el modal de nuevo registro
|
|
$stmtCat = $pdo->query("SELECT * FROM categorias");
|
|
$categorias = $stmtCat->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
echo json_encode([
|
|
'status' => 'success',
|
|
'balance' => (float)$balance,
|
|
'movimientos' => $movimientos,
|
|
'grafico' => $grafico,
|
|
'categorias' => $categorias
|
|
]);
|
|
} catch (Exception $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
|
|
}
|
|
|
|
} elseif ($method === 'POST') {
|
|
// Insertar nuevo movimiento
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
|
|
// Validación mínima
|
|
if (!isset($data['tipo'], $data['monto'], $data['id_categoria'], $data['fecha'])) {
|
|
http_response_code(400);
|
|
die(json_encode(['status' => 'error', 'message' => 'Faltan campos obligatorios']));
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("INSERT INTO movimientos (tipo, monto, fecha, notas, id_categoria) VALUES (?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$data['tipo'],
|
|
(float) $data['monto'],
|
|
$data['fecha'],
|
|
$data['notas'] ?? '',
|
|
(int) $data['id_categoria']
|
|
]);
|
|
echo json_encode(['status' => 'success', 'id' => $pdo->lastInsertId()]);
|
|
} catch (Exception $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
|
|
}
|
|
} else {
|
|
http_response_code(405);
|
|
echo json_encode(['status' => 'error', 'message' => 'Método no permitido']);
|
|
}
|
|
?>
|