feat: Implement monthly navigation for expenses

This commit is contained in:
Flatlogic Bot 2026-03-09 17:39:45 +00:00
parent becf639f3b
commit 75e09a3c47
3 changed files with 310 additions and 9 deletions

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS inversion_general (
id INT AUTO_INCREMENT PRIMARY KEY,
fecha DATE NOT NULL,
tipo_gasto VARCHAR(100) NOT NULL,
monto DECIMAL(10, 2) NOT NULL,
descripcion VARCHAR(255) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

112
edit_gasto.php Normal file
View File

@ -0,0 +1,112 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
session_start();
require_once 'db/config.php';
// Check if user is logged in and has an admin role
$allowed_roles = ['Administrador', 'admin'];
if (!isset($_SESSION['user_id']) || !isset($_SESSION['user_role']) || !in_array($_SESSION['user_role'], $allowed_roles)) {
header('Location: dashboard.php?error=access_denied');
exit;
}
$pdo = db();
$gasto = null;
$id = $_GET['id'] ?? null;
$month = $_GET['month'] ?? date('m');
$year = $_GET['year'] ?? date('Y');
if (!$id) {
header("Location: inversion_general.php?status=error");
exit;
}
// Handle form submission to update the expense
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_expense'])) {
$fecha = $_POST['fecha'];
$tipo_gasto = $_POST['tipo_gasto'];
$monto = $_POST['monto'];
$descripcion = $_POST['descripcion'];
$update_id = $_POST['id'];
$month_redirect = $_POST['month'];
$year_redirect = $_POST['year'];
if (!empty($fecha) && !empty($tipo_gasto) && !empty($monto) && !empty($update_id)) {
$stmt = $pdo->prepare("UPDATE inversion_general SET fecha = ?, tipo_gasto = ?, monto = ?, descripcion = ? WHERE id = ?");
$stmt->execute([$fecha, $tipo_gasto, $monto, $descripcion, $update_id]);
header("Location: inversion_general.php?month={$month_redirect}&year={$year_redirect}&status=updated");
exit;
} else {
header("Location: edit_gasto.php?id={$update_id}&month={$month_redirect}&year={$year_redirect}&status=error");
exit;
}
}
// Fetch the expense to edit
$stmt = $pdo->prepare("SELECT * FROM inversion_general WHERE id = ?");
$stmt->execute([$id]);
$gasto = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$gasto) {
header("Location: inversion_general.php?status=not_found");
exit;
}
$pageTitle = 'Editar Gasto';
include 'layout_header.php';
?>
<div class="container mt-4">
<h2>Editar Gasto</h2>
<div class="card">
<div class="card-header">
Modificar Información del Gasto
</div>
<div class="card-body">
<form method="POST" action="edit_gasto.php?id=<?php echo htmlspecialchars($id); ?>&month=<?php echo htmlspecialchars($month); ?>&year=<?php echo htmlspecialchars($year); ?>">
<input type="hidden" name="id" value="<?php echo htmlspecialchars($gasto['id']); ?>">
<input type="hidden" name="month" value="<?php echo htmlspecialchars($month); ?>">
<input type="hidden" name="year" value="<?php echo htmlspecialchars($year); ?>">
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label for="fecha">Fecha</label>
<input type="date" class="form-control" id="fecha" name="fecha" value="<?php echo htmlspecialchars($gasto['fecha']); ?>" required>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="tipo_gasto">Tipo de Gasto</label>
<select class="form-control" id="tipo_gasto" name="tipo_gasto" required>
<option value="">Seleccione...</option>
<option value="Publicidad" <?php echo ($gasto['tipo_gasto'] == 'Publicidad') ? 'selected' : ''; ?>>Publicidad</option>
<option value="Inversion de Mercaderia" <?php echo ($gasto['tipo_gasto'] == 'Inversion de Mercaderia') ? 'selected' : ''; ?>>Inversión de Mercadería</option>
<option value="Gastos Personales" <?php echo ($gasto['tipo_gasto'] == 'Gastos Personales') ? 'selected' : ''; ?>>Gastos Personales</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="monto">Monto</label>
<input type="number" step="0.01" class="form-control" id="monto" name="monto" value="<?php echo htmlspecialchars($gasto['monto']); ?>" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="descripcion">Descripción</label>
<input type="text" class="form-control" id="descripcion" name="descripcion" value="<?php echo htmlspecialchars($gasto['descripcion']); ?>">
</div>
</div>
</div>
<button type="submit" name="update_expense" class="btn btn-primary mt-3">Actualizar Gasto</button>
<a href="inversion_general.php?month=<?php echo htmlspecialchars($month); ?>&year=<?php echo htmlspecialchars($year); ?>" class="btn btn-secondary mt-3">Cancelar</a>
</form>
</div>
</div>
</div>
<?php include 'layout_footer.php'; ?>

View File

@ -3,10 +3,6 @@ ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);
// Log errors to a file
ini_set('log_errors', 1);
ini_set('error_log', 'php-error.log');
session_start(); session_start();
require_once 'db/config.php'; require_once 'db/config.php';
@ -17,18 +13,203 @@ if (!isset($_SESSION['user_id']) || !isset($_SESSION['user_role']) || !in_array(
exit; exit;
} }
$pdo = db();
// Handle form submission to add a new expense
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_expense'])) {
$fecha = $_POST['fecha'];
$tipo_gasto = $_POST['tipo_gasto'];
$monto = $_POST['monto'];
$descripcion = $_POST['descripcion'];
if (!empty($fecha) && !empty($tipo_gasto) && !empty($monto)) {
$stmt = $pdo->prepare("INSERT INTO inversion_general (fecha, tipo_gasto, monto, descripcion) VALUES (?, ?, ?, ?)");
$stmt->execute([$fecha, $tipo_gasto, $monto, $descripcion]);
// Redirect to the same month view after adding an expense
$month = date('m', strtotime($fecha));
$year = date('Y', strtotime($fecha));
header("Location: inversion_general.php?month=$month&year=$year&status=success");
exit;
} else {
header("Location: inversion_general.php?status=error");
exit;
}
}
// Handle deletion of an expense
if (isset($_GET['delete_id'])) {
$delete_id = $_GET['delete_id'];
// Get the month and year from the query string for redirection
$month = $_GET['month'] ?? date('m');
$year = $_GET['year'] ?? date('Y');
$stmt = $pdo->prepare("DELETE FROM inversion_general WHERE id = ?");
$stmt->execute([$delete_id]);
header("Location: inversion_general.php?month=$month&year=$year&status=deleted");
exit;
}
// --- Monthly Navigation Logic ---
$month = isset($_GET['month']) ? (int)$_GET['month'] : date('m');
$year = isset($_GET['year']) ? (int)$_GET['year'] : date('Y');
$dateObj = DateTime::createFromFormat('!m', $month);
$monthName = $dateObj->format('F'); // Full month name
// Create a mapping for Spanish month names
$meses_espanol = [
'January' => 'Enero', 'February' => 'Febrero', 'March' => 'Marzo', 'April' => 'Abril',
'May' => 'Mayo', 'June' => 'Junio', 'July' => 'Julio', 'August' => 'Agosto',
'September' => 'Septiembre', 'October' => 'Octubre', 'November' => 'Noviembre', 'December' => 'Diciembre'
];
$monthNameSpanish = $meses_espanol[$monthName];
$prev_month = $month - 1;
$prev_year = $year;
if ($prev_month == 0) {
$prev_month = 12;
$prev_year--;
}
$next_month = $month + 1;
$next_year = $year;
if ($next_month == 13) {
$next_month = 1;
$next_year++;
}
// --- End of Navigation Logic ---
// Fetch expenses for the selected month and year
$stmt = $pdo->prepare("SELECT * FROM inversion_general WHERE YEAR(fecha) = ? AND MONTH(fecha) = ? ORDER BY fecha DESC");
$stmt->execute([$year, $month]);
$gastos = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Group expenses by type
$gastos_por_tipo = [
'Publicidad' => [],
'Inversion de Mercaderia' => [],
'Gastos Personales' => []
];
$totales_por_tipo = [
'Publicidad' => 0,
'Inversion de Mercaderia' => 0,
'Gastos Personales' => 0
];
foreach ($gastos as $gasto) {
$tipo = $gasto['tipo_gasto'];
if (array_key_exists($tipo, $gastos_por_tipo)) {
$gastos_por_tipo[$tipo][] = $gasto;
$totales_por_tipo[$tipo] += $gasto['monto'];
}
}
$pageTitle = 'Inversión General'; $pageTitle = 'Inversión General';
include 'layout_header.php'; include 'layout_header.php';
?> ?>
<div class="container mt-4"> <div class="container mt-4">
<h2>Registro de Inversión General</h2>
<!-- Content for Inversion General will go here --> <!-- Monthly Navigation -->
<div class="card"> <div class="d-flex justify-content-between align-items-center my-4">
<a href="inversion_general.php?month=<?php echo $prev_month; ?>&year=<?php echo $prev_year; ?>" class="btn btn-outline-primary">&lt; Mes Anterior</a>
<h4 class="mb-0"><?php echo $monthNameSpanish . ' ' . $year; ?></h4>
<a href="inversion_general.php?month=<?php echo $next_month; ?>&year=<?php echo $next_year; ?>" class="btn btn-outline-primary">Mes Siguiente &gt;</a>
</div>
<!-- Form to add new expense -->
<div class="card mb-4">
<div class="card-header">
Agregar Nuevo Gasto
</div>
<div class="card-body"> <div class="card-body">
<p>Esta sección está en construcción.</p> <form method="POST" action="inversion_general.php">
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label for="fecha">Fecha</label>
<input type="date" class="form-control" id="fecha" name="fecha" value="<?php echo date('Y-m-d'); ?>" required>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="tipo_gasto">Tipo de Gasto</label>
<select class="form-control" id="tipo_gasto" name="tipo_gasto" required>
<option value="">Seleccione...</option>
<option value="Publicidad">Publicidad</option>
<option value="Inversion de Mercaderia">Inversión de Mercadería</option>
<option value="Gastos Personales">Gastos Personales</option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="monto">Monto</label>
<input type="number" step="0.01" class="form-control" id="monto" name="monto" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="descripcion">Descripción</label>
<input type="text" class="form-control" id="descripcion" name="descripcion">
</div>
</div>
</div>
<button type="submit" name="add_expense" class="btn btn-primary mt-3">Guardar Gasto</button>
</form>
</div> </div>
</div> </div>
<?php
$tipos_de_gasto = [
'Publicidad' => 'Gastos de Publicidad',
'Inversion de Mercaderia' => 'Inversión de Mercadería',
'Gastos Personales' => 'Gastos Personales'
];
?>
<?php foreach ($tipos_de_gasto as $tipo_key => $titulo): ?>
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<span><?php echo $titulo; ?></span>
<span class="font-weight-bold">Total: S/ <?php echo number_format($totales_por_tipo[$tipo_key], 2); ?></span>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 15%;">Fecha</th>
<th style="width: 15%;">Monto</th>
<th>Descripción</th>
<th style="width: 15%;">Acciones</th>
</tr>
</thead>
<tbody>
<?php if (empty($gastos_por_tipo[$tipo_key])): ?>
<tr>
<td colspan="4" class="text-center">No hay gastos registrados en esta categoría para <?php echo $monthNameSpanish . ' ' . $year; ?>.</td>
</tr>
<?php else: ?>
<?php foreach ($gastos_por_tipo[$tipo_key] as $gasto): ?>
<tr>
<td><?php echo htmlspecialchars($gasto['fecha']); ?></td>
<td>S/ <?php echo number_format($gasto['monto'], 2); ?></td>
<td><?php echo htmlspecialchars($gasto['descripcion']); ?></td>
<td>
<a href="edit_gasto.php?id=<?php echo $gasto['id']; ?>&month=<?php echo $month; ?>&year=<?php echo $year; ?>" class="btn btn-warning btn-sm">Editar</a>
<a href="inversion_general.php?delete_id=<?php echo $gasto['id']; ?>&month=<?php echo $month; ?>&year=<?php echo $year; ?>" class="btn btn-danger btn-sm" onclick="return confirm('¿Estás seguro de que quieres eliminar este gasto?');">Eliminar</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php endforeach; ?>
</div> </div>
<?php include 'layout_footer.php'; ?> <?php include 'layout_footer.php'; ?>