Revert to version 20046a4

This commit is contained in:
Flatlogic Bot 2025-10-29 19:24:01 +00:00
parent 6d3c0cd8d3
commit dbdbcd28a8
22 changed files with 59 additions and 483 deletions

View File

@ -11,7 +11,6 @@ if (!isset($_SESSION['user_id'])) {
exit;
}
$client_id = $_SESSION['client_id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
$error_message = '';
@ -27,14 +26,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$posted_month = $_POST['budget_month'] ?? $budget_month_date;
try {
$sql = "INSERT INTO budgets (client_id, user_id, category, amount, budget_month) VALUES (:client_id, :user_id, :category, :amount, :budget_month)
ON DUPLICATE KEY UPDATE amount = VALUES(amount)";
$sql = "INSERT INTO budgets (user_id, category, amount, budget_month) VALUES (:user_id, :category, :amount, :budget_month)
ON DUPLICATE KEY UPDATE amount = :amount";
$stmt = $pdo->prepare($sql);
foreach ($budgets as $category => $amount) {
if (is_numeric($amount) && $amount >= 0) {
$stmt->execute([
'client_id' => $client_id,
'user_id' => $user_id,
'category' => $category,
'amount' => $amount,
@ -54,8 +52,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Buscar orçamentos existentes para o mês selecionado
$existing_budgets = [];
try {
$stmt = $pdo->prepare("SELECT category, amount FROM budgets WHERE client_id = :client_id AND budget_month = :budget_month");
$stmt->execute(['client_id' => $client_id, 'budget_month' => $budget_month_date]);
$stmt = $pdo->prepare("SELECT category, amount FROM budgets WHERE user_id = :user_id AND budget_month = :budget_month");
$stmt->execute(['user_id' => $user_id, 'budget_month' => $budget_month_date]);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $row) {
$existing_budgets[$row['category']] = $row['amount'];
@ -65,10 +63,8 @@ try {
}
// Obter todas as categorias (macro áreas ativas) para os dropdowns
$stmt_categories = $pdo->prepare("SELECT nome, slug FROM macro_areas WHERE client_id = :client_id AND ativo = 1 ORDER BY nome ASC");
$stmt_categories->execute(['client_id' => $client_id]);
$categories = $stmt_categories->fetchAll(PDO::FETCH_ASSOC);
// Categorias fixas
$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros'];
include __DIR__ . '/includes/header.php';
?>
@ -105,20 +101,17 @@ include __DIR__ . '/includes/header.php';
<input type="hidden" name="budget_month" value="<?php echo htmlspecialchars($budget_month_date); ?>">
<h4 class="mb-3">Orçamentos para <?php echo date('F \d\e Y', strtotime($budget_month_date)); ?></h4>
<?php foreach ($categories as $category):
$category_slug = $category['slug'];
$category_nome = $category['nome'];
?>
<?php foreach ($categories as $category): ?>
<div class="row mb-2 align-items-center">
<div class="col-md-3">
<label for="budget_<?php echo htmlspecialchars($category_slug); ?>" class="form-label"><?php echo htmlspecialchars($category_nome); ?></label>
<label for="budget_<?php echo htmlspecialchars($category); ?>" class="form-label"><?php echo htmlspecialchars($category); ?></label>
</div>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-text">R$</span>
<input type="number" step="0.01" class="form-control" id="budget_<?php echo htmlspecialchars($category_slug); ?>"
name="budgets[<?php echo htmlspecialchars($category_slug); ?>]"
value="<?php echo htmlspecialchars($existing_budgets[$category_slug] ?? '0.00'); ?>">
<input type="number" step="0.01" class="form-control" id="budget_<?php echo htmlspecialchars($category); ?>"
name="budgets[<?php echo htmlspecialchars($category); ?>]"
value="<?php echo htmlspecialchars($existing_budgets[$category] ?? '0.00'); ?>">
</div>
</div>
</div>

View File

@ -1,307 +0,0 @@
<?php
require_once __DIR__ . '/includes/session.php';
require_once __DIR__ . '/db/config.php';
// Ensure the user is logged in and has a client_id
if (!isset($_SESSION['user_id']) || !isset($_SESSION['client_id'])) {
header("Location: login.php");
exit;
}
$client_id = $_SESSION['client_id'];
$pdo = db();
$errors = [];
$success = '';
// Handle POST requests for CUD operations
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
try {
if ($action === 'save_category') {
$id = $_POST['id'] ?? null;
$nome = trim($_POST['nome'] ?? '');
$macro_area_id = $_POST['macro_area_id'] ?? null;
if (empty($nome) || empty($macro_area_id)) {
$errors[] = "Nome da categoria e macro área são obrigatórios.";
} else {
if ($id) {
// Update
$stmt = $pdo->prepare("UPDATE categories SET nome = :nome, macro_area_id = :macro_area_id WHERE id = :id AND client_id = :client_id");
$stmt->execute(['nome' => $nome, 'macro_area_id' => $macro_area_id, 'id' => $id, 'client_id' => $client_id]);
$success = "Categoria atualizada com sucesso!";
} else {
// Create
$stmt = $pdo->prepare("INSERT INTO categories (nome, macro_area_id, client_id) VALUES (:nome, :macro_area_id, :client_id)");
$stmt->execute(['nome' => $nome, 'macro_area_id' => $macro_area_id, 'client_id' => $client_id]);
$success = "Categoria criada com sucesso!";
}
}
} elseif ($action === 'toggle_archive') {
$id = $_POST['id'] ?? null;
if ($id) {
$stmt = $pdo->prepare("UPDATE categories SET is_archived = 1 - is_archived WHERE id = :id AND client_id = :client_id");
$stmt->execute(['id' => $id, 'client_id' => $client_id]);
$success = "Status da categoria alterado com sucesso!";
}
} elseif ($action === 'delete') {
$id = $_POST['id'] ?? null;
if ($id) {
// Check for related expenses
$stmt = $pdo->prepare("SELECT COUNT(*) FROM expenses WHERE category_id = :category_id AND client_id = :client_id");
$stmt->execute(['category_id' => $id, 'client_id' => $client_id]);
if ($stmt->fetchColumn() > 0) {
$errors[] = "Não é possível excluir a categoria, pois existem despesas associadas a ela.";
} else {
$stmt = $pdo->prepare("DELETE FROM categories WHERE id = :id AND client_id = :client_id");
$stmt->execute(['id' => $id, 'client_id' => $client_id]);
$success = "Categoria excluída com sucesso!";
}
}
}
} catch (PDOException $e) {
if ($e->getCode() == '23000') { // Integrity constraint violation
$errors[] = "Erro: Já existe uma categoria com este nome para a macro área selecionada.";
} else {
$errors[] = "Ocorreu um erro no banco de dados: " . $e->getMessage();
}
}
}
// Fetch data for display
$macro_areas = $pdo->prepare("SELECT id, nome FROM macro_areas WHERE client_id = :client_id ORDER BY nome");
$macro_areas->execute(['client_id' => $client_id]);
$macro_areas_list = $macro_areas->fetchAll();
$stmt = $pdo->prepare("
SELECT c.id, c.nome, c.is_archived, c.macro_area_id, m.nome as macro_area_nome
FROM categories c
JOIN macro_areas m ON c.macro_area_id = m.id
WHERE c.client_id = :client_id
ORDER BY m.nome, c.nome
");
$stmt->execute(['client_id' => $client_id]);
$categories = $stmt->fetchAll();
$page_title = "Categorias";
include 'includes/header.php';
?>
<style>
:root {
--bg-page: #eeeeee;
--text-main: #10403B;
--text-secondary: #4C5958;
--action-bg: #005C53;
--action-text: #FFFFFF;
--delete-bg-modal: #8AA6A3;
--card-border: #005C53;
--table-header-bg: #8AA6A3;
--table-header-text: #FFFFFF;
--badge-bg: #8AA6A3;
--badge-text: #FFFFFF;
--icon-action: #4C5958;
--icon-section: #005C53;
--hover-row: #f8fafc; /* hover:bg-slate-50 */
}
body {
background-color: var(--bg-page);
color: var(--text-main);
}
.btn-primary {
background-color: var(--action-bg);
color: var(--action-text);
border: none;
}
.btn-primary:hover {
background-color: #004c45;
}
.table thead th {
background-color: var(--table-header-bg);
color: var(--table-header-text);
}
.table tbody tr:hover {
background-color: var(--hover-row);
}
.badge-active {
background-color: var(--badge-bg);
color: var(--badge-text);
}
.badge-archived {
background-color: #f1f5f9; /* bg-gray-100 */
color: #1f2937; /* text-gray-800 */
}
.action-icon {
color: var(--icon-action);
cursor: pointer;
}
.section-icon {
color: var(--icon-section);
}
.card {
border: 1px solid var(--card-border);
}
.modal-content {
background-color: var(--bg-page);
border: 1px solid var(--text-main);
}
.modal-header, .modal-body, .modal-footer {
border-color: #d1d5db;
}
.form-label {
color: var(--text-main);
}
.form-control::placeholder {
color: var(--text-secondary);
}
</style>
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 font-weight-bold d-flex align-items-center">
<i class="fas fa-layer-group me-2 section-icon"></i>
Categorias
</h1>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#categoryModal" onclick="openModal()">
<i class="fas fa-plus me-1"></i> Nova Categoria
</button>
</div>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p class="mb-0"><?php echo htmlspecialchars($error); ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success">
<?php echo htmlspecialchars($success); ?>
</div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Nome da Categoria</th>
<th>Macro Área</th>
<th class="text-center">Status</th>
<th class="text-end">Ações</th>
</tr>
</thead>
<tbody>
<?php if (empty($categories)): ?>
<tr>
<td colspan="4" class="text-center text-secondary py-4">Nenhuma categoria encontrada.</td>
</tr>
<?php else: ?>
<?php foreach ($categories as $category): ?>
<tr>
<td class="font-weight-medium"><?php echo htmlspecialchars($category['nome']); ?></td>
<td><?php echo htmlspecialchars($category['macro_area_nome']); ?></td>
<td class="text-center">
<span class="badge <?php echo $category['is_archived'] ? 'badge-archived' : 'badge-active'; ?>">
<?php echo $category['is_archived'] ? 'Arquivado' : 'Ativo'; ?>
</span>
</td>
<td class="text-end">
<i class="fas fa-edit action-icon me-3" title="Editar" onclick='openModal(<?php echo json_encode($category, JSON_HEX_TAG); ?>)'></i>
<form action="categories.php" method="POST" class="d-inline" onsubmit="return confirm('Tem certeza que deseja alterar o status desta categoria?');">
<input type="hidden" name="action" value="toggle_archive">
<input type="hidden" name="id" value="<?php echo $category['id']; ?>">
<button type="submit" class="btn btn-link p-0 m-0 align-baseline">
<i class="fas <?php echo $category['is_archived'] ? 'fa-box-open' : 'fa-archive'; ?> action-icon me-3" title="<?php echo $category['is_archived'] ? 'Reativar' : 'Arquivar'; ?>"></i>
</button>
</form>
<form action="categories.php" method="POST" class="d-inline" onsubmit="return confirm('Atenção! A exclusão é permanente. Deseja continuar?');">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?php echo $category['id']; ?>">
<button type="submit" class="btn btn-link p-0 m-0 align-baseline">
<i class="fas fa-trash-alt action-icon text-danger" title="Excluir"></i>
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="categoryModal" tabindex="-1" aria-labelledby="categoryModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<form action="categories.php" method="POST" id="categoryForm">
<input type="hidden" name="action" value="save_category">
<input type="hidden" name="id" id="categoryId">
<div class="modal-header">
<h5 class="modal-title" id="categoryModalLabel">Nova Categoria</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="categoryName" class="form-label">Nome da Categoria</label>
<input type="text" class="form-control" id="categoryName" name="nome" required placeholder="Ex: Aluguel, Combustível">
</div>
<div class="mb-3">
<label for="macroArea" class="form-label">Macro Área</label>
<select class="form-select" id="macroArea" name="macro_area_id" required>
<option value="" disabled selected>Selecione uma macro área</option>
<?php foreach ($macro_areas_list as $ma): ?>
<option value="<?php echo $ma['id']; ?>"><?php echo htmlspecialchars($ma['nome']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="submit" class="btn btn-primary">Salvar</button>
</div>
</form>
</div>
</div>
</div>
<script>
function openModal(category = null) {
const form = document.getElementById('categoryForm');
const modalTitle = document.getElementById('categoryModalLabel');
const categoryIdInput = document.getElementById('categoryId');
const categoryNameInput = document.getElementById('categoryName');
const macroAreaSelect = document.getElementById('macroArea');
form.reset(); // Reset form for both create and edit
if (category) {
// Edit mode
modalTitle.textContent = 'Editar Categoria';
categoryIdInput.value = category.id;
categoryNameInput.value = category.nome;
macroAreaSelect.value = category.macro_area_id; // Directly use the ID
} else {
// Create mode
modalTitle.textContent = 'Nova Categoria';
categoryIdInput.value = '';
}
}
// Reset form on modal close
const categoryModal = document.getElementById('categoryModal');
categoryModal.addEventListener('hidden.bs.modal', function (event) {
document.getElementById('categoryForm').reset();
document.getElementById('categoryId').value = '';
document.getElementById('categoryModalLabel').textContent = 'Nova Categoria';
});
</script>
<?php include 'includes/footer.php'; ?>

View File

@ -1,60 +0,0 @@
<?php
require_once __DIR__ . '/config.php';
function fix_table($pdo, $table_name, $fk_name) {
echo "--- Processing table: {$table_name} ---\\n";
// Check and add column
$res = $pdo->query("SHOW COLUMNS FROM `{$table_name}` LIKE 'client_id'");
if ($res->rowCount() == 0) {
echo "Adding client_id to {$table_name}...\\n";
$pdo->exec("ALTER TABLE `{$table_name}` ADD COLUMN `client_id` INT NOT NULL DEFAULT 1");
} else {
echo "client_id already exists in {$table_name}. Setting to default...\\n";
// This handles cases where the column was added but not populated correctly
$pdo->exec("UPDATE `{$table_name}` SET `client_id` = 1 WHERE `client_id` = 0 OR `client_id` IS NULL");
}
// Check and add foreign key
$res = $pdo->query("SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '{$table_name}' AND COLUMN_NAME = 'client_id' AND REFERENCED_TABLE_NAME = 'clients'");
if ($res->rowCount() == 0) {
echo "Adding foreign key to {$table_name}...\\n";
try {
$pdo->exec("ALTER TABLE `{$table_name}` ADD CONSTRAINT `{$fk_name}` FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON DELETE CASCADE");
} catch (PDOException $e) {
// If the constraint somehow exists with a different name, this might fail.
echo "Could not add foreign key to {$table_name}. It might already exist with a different name. Error: " . $e->getMessage() . "\\n";
}
} else {
echo "Foreign key on {$table_name}.client_id already exists.\\n";
}
}
try {
$pdo = db();
fix_table($pdo, 'users', 'fk_users_client_id');
fix_table($pdo, 'macro_areas', 'fk_macro_areas_client_id');
fix_table($pdo, 'budgets', 'fk_budgets_client_id');
fix_table($pdo, 'expenses', 'fk_expenses_client_id');
// Mark migrations as executed to prevent them from running again
$migrations_to_mark = [
'006_add_client_id_to_users.sql',
'007_add_client_id_to_macro_areas.sql',
'008_add_client_id_to_budgets.sql',
'009_add_client_id_to_expenses.sql'
];
$stmt = $pdo->prepare("INSERT IGNORE INTO migrations (migration_name) VALUES (:migration_name)");
foreach ($migrations_to_mark as $migration_name) {
echo "Marking migration {$migration_name} as executed...\\n";
$stmt->execute(['migration_name' => $migration_name]);
}
echo "\\nSchema fix script finished.\\n";
} catch (PDOException $e) {
die("Error fixing schema: " . $e->getMessage());
}

View File

@ -1,5 +0,0 @@
CREATE TABLE IF NOT EXISTS `clients` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1 +0,0 @@
INSERT INTO `clients` (`id`, `name`) VALUES (1, 'Default Client') ON DUPLICATE KEY UPDATE `name` = `name`;

View File

@ -1,3 +0,0 @@
ALTER TABLE `users`
ADD COLUMN `client_id` INT NOT NULL DEFAULT 1 AFTER `id`,
ADD CONSTRAINT `fk_users_client_id` FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON DELETE CASCADE;

View File

@ -1,3 +0,0 @@
ALTER TABLE `macro_areas`
ADD COLUMN `client_id` INT NOT NULL DEFAULT 1 AFTER `id`,
ADD CONSTRAINT `fk_macro_areas_client_id` FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON DELETE CASCADE;

View File

@ -1,3 +0,0 @@
ALTER TABLE `budgets`
ADD COLUMN `client_id` INT NOT NULL DEFAULT 1 AFTER `id`,
ADD CONSTRAINT `fk_budgets_client_id` FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON DELETE CASCADE;

View File

@ -1,3 +0,0 @@
ALTER TABLE `expenses`
ADD COLUMN `client_id` INT NOT NULL DEFAULT 1 AFTER `id`,
ADD CONSTRAINT `fk_expenses_client_id` FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON DELETE CASCADE;

View File

@ -1,10 +0,0 @@
-- Drop the foreign key constraint first
ALTER TABLE `budgets` DROP FOREIGN KEY `budgets_ibfk_1`;
-- Now, drop the old unique key and add the new one
ALTER TABLE `budgets`
DROP KEY `user_category_month`,
ADD UNIQUE KEY `client_month_category` (`client_id`, `budget_month`, `category`);
-- Add the foreign key back
ALTER TABLE `budgets` ADD CONSTRAINT `fk_budgets_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;

View File

@ -1,11 +0,0 @@
CREATE TABLE IF NOT EXISTS `categories` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`nome` VARCHAR(255) NOT NULL,
`macro_area_id` INT NOT NULL,
`client_id` INT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (`macro_area_id`) REFERENCES `macro_areas`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`client_id`) REFERENCES `clients`(`id`) ON DELETE CASCADE,
UNIQUE KEY `client_macro_area_nome` (`client_id`, `macro_area_id`, `nome`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,2 +0,0 @@
ALTER TABLE `categories`
ADD COLUMN `is_archived` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 = active, 1 = archived' AFTER `client_id`;

View File

@ -12,7 +12,7 @@ if (!isset($_SESSION['user_id'])) {
}
$expense_id = $_GET['id'] ?? null;
$client_id = $_SESSION['client_id'];
$user_id = $_SESSION['user_id'];
if (!$expense_id) {
// Se não houver ID, redireciona de volta
@ -23,11 +23,11 @@ if (!$expense_id) {
try {
$pdo = db();
// A cláusula WHERE garante que um usuário só pode deletar suas próprias despesas
$sql = "DELETE FROM expenses WHERE id = :id AND client_id = :client_id";
$sql = "DELETE FROM expenses WHERE id = :id AND user_id = :user_id";
$stmt = $pdo->prepare($sql);
$stmt->execute([
'id' => $expense_id,
'client_id' => $client_id
'user_id' => $user_id
]);
// Opcional: verificar se alguma linha foi afetada para dar um feedback mais preciso

View File

@ -5,12 +5,11 @@ require_once 'db/config.php';
// Check if ID is provided
if (isset($_GET['id'])) {
$id = $_GET['id'];
$client_id = $_SESSION['client_id'];
$pdo = db();
// First, find the macro area to get its slug
$stmt = $pdo->prepare("SELECT slug FROM macro_areas WHERE id = ? AND client_id = ?");
$stmt->execute([$id, $client_id]);
$stmt = $pdo->prepare("SELECT slug FROM macro_areas WHERE id = ?");
$stmt->execute([$id]);
$macro_area = $stmt->fetch();
// If the macro area exists, proceed with checks and deletion
@ -18,8 +17,8 @@ if (isset($_GET['id'])) {
$slug = $macro_area['slug'];
// Check for dependent expenses
$stmt = $pdo->prepare("SELECT COUNT(*) FROM expenses WHERE category = ? AND client_id = ?");
$stmt->execute([$slug, $client_id]);
$stmt = $pdo->prepare("SELECT COUNT(*) FROM expenses WHERE category = ?");
$stmt->execute([$slug]);
$expense_count = $stmt->fetchColumn();
if ($expense_count > 0) {
@ -27,8 +26,8 @@ if (isset($_GET['id'])) {
$_SESSION['error_message'] = "Não é possível excluir a macro área. Existem {$expense_count} despesas associadas.";
} else {
// No dependencies, proceed with deletion
$stmt = $pdo->prepare("DELETE FROM macro_areas WHERE id = ? AND client_id = ?");
$stmt->execute([$id, $client_id]);
$stmt = $pdo->prepare("DELETE FROM macro_areas WHERE id = ?");
$stmt->execute([$id]);
$_SESSION['success_message'] = "Macro área excluída com sucesso.";
}
}

View File

@ -12,7 +12,7 @@ if (!isset($_SESSION['user_id'])) {
}
$expense_id = $_GET['id'] ?? null;
$client_id = $_SESSION['client_id'];
$user_id = $_SESSION['user_id'];
$error_message = '';
$expense = null;
@ -25,8 +25,8 @@ $pdo = db();
// Buscar a despesa para garantir que ela pertence ao usuário
try {
$stmt = $pdo->prepare("SELECT * FROM expenses WHERE id = :id AND client_id = :client_id");
$stmt->execute(['id' => $expense_id, 'client_id' => $client_id]);
$stmt = $pdo->prepare("SELECT * FROM expenses WHERE id = :id AND user_id = :user_id");
$stmt->execute(['id' => $expense_id, 'user_id' => $user_id]);
$expense = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$expense) {
@ -51,7 +51,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$error_message = 'Todos os campos são obrigatórios.';
} else {
try {
$sql = "UPDATE expenses SET description = :description, amount = :amount, category = :category, expense_date = :expense_date WHERE id = :id AND client_id = :client_id";
$sql = "UPDATE expenses SET description = :description, amount = :amount, category = :category, expense_date = :expense_date WHERE id = :id AND user_id = :user_id";
$stmt = $pdo->prepare($sql);
$stmt->execute([
'description' => $description,
@ -59,7 +59,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'category' => $category,
'expense_date' => $expense_date,
'id' => $expense_id,
'client_id' => $client_id
'user_id' => $user_id
]);
$_SESSION['success_message'] = 'Despesa atualizada com sucesso!';
@ -100,12 +100,13 @@ include __DIR__ . '/includes/header.php';
<select class="form-select" id="category" name="category" required>
<option value="">Selecione...</option>
<?php
$stmt_categories = $pdo->prepare("SELECT nome, slug FROM macro_areas WHERE client_id = :client_id AND ativo = 1 ORDER BY nome ASC");
$stmt_categories->execute(['client_id' => $client_id]);
$categories = $stmt_categories->fetchAll(PDO::FETCH_ASSOC);
$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros'];
foreach ($categories as $cat) {
$selected = ($expense['category'] === $cat['slug']) ? 'selected' : '';
echo "<option value=\"".htmlspecialchars($cat['slug']).
$selected = ($expense['category'] === $cat) ? 'selected' : '';
echo "<option value=\"".htmlspecialchars($cat)."\" $selected>".htmlspecialchars($cat)."</option>";
}
?>
</select>
</div>
<div class="mb-3">
<label for="expense_date" class="form-label">Data da Despesa</label>

View File

@ -11,7 +11,6 @@ if (!isset($_SESSION['user_id'])) {
exit;
}
$client_id = $_SESSION['client_id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
$error_message = '';
@ -28,10 +27,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$error_message = 'Todos os campos são obrigatórios para adicionar uma despesa.';
} else {
try {
$sql = "INSERT INTO expenses (client_id, user_id, description, amount, category, expense_date) VALUES (:client_id, :user_id, :description, :amount, :category, :expense_date)";
$sql = "INSERT INTO expenses (user_id, description, amount, category, expense_date) VALUES (:user_id, :description, :amount, :category, :expense_date)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
'client_id' => $client_id,
'user_id' => $user_id,
'description' => $description,
'amount' => $amount,
@ -52,8 +50,8 @@ $filter_start_date = $_GET['start_date'] ?? '';
$filter_end_date = $_GET['end_date'] ?? '';
$filter_category = $_GET['category'] ?? '';
$sql = "SELECT * FROM expenses WHERE client_id = :client_id";
$params = ['client_id' => $client_id];
$sql = "SELECT * FROM expenses WHERE user_id = :user_id";
$params = ['user_id' => $user_id];
if ($filter_start_date) {
$sql .= " AND expense_date >= :start_date";
@ -85,10 +83,8 @@ try {
$error_message = 'Erro ao buscar despesas: ' . $e->getMessage();
}
// Obter todas as categorias (macro áreas ativas) para os dropdowns
$stmt_categories = $pdo->prepare("SELECT nome, slug FROM macro_areas WHERE client_id = :client_id AND ativo = 1 ORDER BY nome ASC");
$stmt_categories->execute(['client_id' => $client_id]);
$categories = $stmt_categories->fetchAll(PDO::FETCH_ASSOC);
// Obter todas as categorias para o dropdown do filtro
$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros'];
include __DIR__ . '/includes/header.php';
?>
@ -118,7 +114,7 @@ include __DIR__ . '/includes/header.php';
<select class="form-select" id="category" name="category" required>
<option value="">Selecione...</option>
<?php foreach ($categories as $cat): ?>
<option value="<?php echo htmlspecialchars($cat['slug']); ?>"><?php echo htmlspecialchars($cat['nome']); ?></option>
<option value="<?php echo htmlspecialchars($cat); ?>"><?php echo htmlspecialchars($cat); ?></option>
<?php endforeach; ?>
</select>
</div>
@ -168,7 +164,7 @@ include __DIR__ . '/includes/header.php';
<select class="form-select" id="filter_category" name="category">
<option value="">Todas</option>
<?php foreach ($categories as $cat): ?>
<option value="<?php echo htmlspecialchars($cat['slug']); ?>" <?php echo ($filter_category === $cat['slug']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($cat['nome']); ?></option>
<option value="<?php echo htmlspecialchars($cat); ?>" <?php echo ($filter_category === $cat) ? 'selected' : ''; ?>><?php echo htmlspecialchars($cat); ?></option>
<?php endforeach; ?>
</select>
</div>

View File

@ -8,12 +8,12 @@ if (!isset($_SESSION['user_id'])) {
exit();
}
$client_id = $_SESSION['client_id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Build query with filters
$sql = "SELECT * FROM expenses WHERE client_id = :client_id";
$params = ['client_id' => $client_id];
$sql = "SELECT * FROM expenses WHERE user_id = :user_id";
$params = ['user_id' => $user_id];
if (!empty($_GET['start_date'])) {
$sql .= " AND expense_date >= :start_date";

View File

@ -71,7 +71,7 @@ $unclassifiedCount = 5; // Example value
</a>
<ul class="collapse show list-unstyled sub-sub-menu" id="planoContasSubmenu">
<li><a href="/Backend/macro_areas.php"><span class="menu-item-text">Macro Áreas</span></a></li>
<li><a href="/Backend/categories.php"><span class="menu-item-text">Categorias</span></a></li>
<li><a href="#"><span class="menu-item-text">Categorias</span></a></li>
<li><a href="#"><span class="menu-item-text">Centro de Custo</span></a></li>
<li><a href="#"><span class="menu-item-text">Alocação do Plano</span></a></li>
</ul>

View File

@ -20,17 +20,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT id, client_id, email, password_hash FROM users WHERE email = :email");
$stmt = $pdo->prepare("SELECT id, password_hash FROM users WHERE email = :email");
$stmt->execute(['email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password_hash'])) {
// Login bem-sucedido: Armazena dados na sessão
$_SESSION['user_id'] = $user['id'];
$_SESSION['client_id'] = $user['client_id'];
$_SESSION['user_email'] = $user['email'];
header("Location: /index.php");
exit();
// Login bem-sucedido: Redireciona com flag de depuração
// Senha correta, inicie a sessão
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_email'] = $user['email'];
header("Location: /index.php");
exit();
} else {
// Credenciais inválidas
$error_message = 'E-mail ou senha inválidos.';

View File

@ -13,7 +13,6 @@ function generateSlug($string) {
}
$pdo = db();
$client_id = $_SESSION['client_id'];
$error = null;
$macro_area = [
'id' => '',
@ -36,8 +35,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Repopulate form data on error
$macro_area = $_POST;
} else {
$stmt = $pdo->prepare('SELECT id FROM macro_areas WHERE (nome = ? OR slug = ?) AND id <> ? AND client_id = ?');
$stmt->execute([$nome, $slug, $id ?: 0, $client_id]);
$stmt = $pdo->prepare('SELECT id FROM macro_areas WHERE (nome = ? OR slug = ?) AND id <> ?');
$stmt->execute([$nome, $slug, $id ?: 0]);
if ($stmt->fetch()) {
$error = "Já existe uma Macro Área com este nome.";
// Repopulate form data on error
@ -45,13 +44,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
if ($id) {
// Update
$stmt = $pdo->prepare('UPDATE macro_areas SET nome = ?, slug = ?, descricao = ?, ativo = ? WHERE id = ? AND client_id = ?');
$stmt->execute([$nome, $slug, $descricao, $ativo, $id, $client_id]);
$stmt = $pdo->prepare('UPDATE macro_areas SET nome = ?, slug = ?, descricao = ?, ativo = ? WHERE id = ?');
$stmt->execute([$nome, $slug, $descricao, $ativo, $id]);
$redirect_id = $id;
} else {
// Create
$stmt = $pdo->prepare('INSERT INTO macro_areas (client_id, nome, slug, descricao, ativo, user_id) VALUES (?, ?, ?, ?, ?, ?)');
$stmt->execute([$client_id, $nome, $slug, $descricao, $ativo, $_SESSION['user_id'] ?? 1]);
$stmt = $pdo->prepare('INSERT INTO macro_areas (nome, slug, descricao, ativo, user_id) VALUES (?, ?, ?, ?, ?)');
$stmt->execute([$nome, $slug, $descricao, $ativo, $_SESSION['user_id'] ?? 1]);
$redirect_id = $pdo->lastInsertId();
}
header("Location: /Backend/macro_area_form.php");
@ -61,8 +60,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} elseif (isset($_GET['id'])) {
// Handle edit mode (fetch data)
$id = $_GET['id'];
$stmt = $pdo->prepare('SELECT * FROM macro_areas WHERE id = ? AND client_id = ?');
$stmt->execute([$id, $client_id]);
$stmt = $pdo->prepare('SELECT * FROM macro_areas WHERE id = ?');
$stmt->execute([$id]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
if ($data) {
$macro_area = $data;

View File

@ -5,9 +5,7 @@ include_once 'includes/header.php';
$pdo = db();
$client_id = $_SESSION['client_id'];
$stmt = $pdo->prepare('SELECT * FROM macro_areas WHERE client_id = :client_id ORDER BY nome ASC');
$stmt->execute(['client_id' => $client_id]);
$stmt = $pdo->query('SELECT * FROM macro_areas ORDER BY nome ASC');
$macro_areas = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

View File

@ -3,9 +3,7 @@ require_once 'includes/session.php';
require_once 'db/config.php';
$pdo = db();
$client_id = $_SESSION['client_id'];
$stmt = $pdo->prepare('SELECT * FROM macro_areas WHERE client_id = :client_id ORDER BY nome ASC');
$stmt->execute(['client_id' => $client_id]);
$stmt = $pdo->query('SELECT * FROM macro_areas ORDER BY nome ASC');
$macro_areas = $stmt->fetchAll(PDO::FETCH_ASSOC);
$total = count($macro_areas);