feat: Implement monthly navigation for expenses
This commit is contained in:
parent
becf639f3b
commit
75e09a3c47
8
db/migrations/066_create_inversion_general_table.sql
Normal file
8
db/migrations/066_create_inversion_general_table.sql
Normal 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
112
edit_gasto.php
Normal 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'; ?>
|
||||||
@ -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">< 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 ></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>
|
</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>
|
||||||
|
|
||||||
|
<?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'; ?>
|
||||||
Loading…
x
Reference in New Issue
Block a user