versao 18
This commit is contained in:
parent
20046a4844
commit
6d3c0cd8d3
@ -11,6 +11,7 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$client_id = $_SESSION['client_id'];
|
||||||
$user_id = $_SESSION['user_id'];
|
$user_id = $_SESSION['user_id'];
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$error_message = '';
|
$error_message = '';
|
||||||
@ -26,13 +27,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$posted_month = $_POST['budget_month'] ?? $budget_month_date;
|
$posted_month = $_POST['budget_month'] ?? $budget_month_date;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$sql = "INSERT INTO budgets (user_id, category, amount, budget_month) VALUES (:user_id, :category, :amount, :budget_month)
|
$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 = :amount";
|
ON DUPLICATE KEY UPDATE amount = VALUES(amount)";
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
|
|
||||||
foreach ($budgets as $category => $amount) {
|
foreach ($budgets as $category => $amount) {
|
||||||
if (is_numeric($amount) && $amount >= 0) {
|
if (is_numeric($amount) && $amount >= 0) {
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
|
'client_id' => $client_id,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'category' => $category,
|
'category' => $category,
|
||||||
'amount' => $amount,
|
'amount' => $amount,
|
||||||
@ -52,8 +54,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
// Buscar orçamentos existentes para o mês selecionado
|
// Buscar orçamentos existentes para o mês selecionado
|
||||||
$existing_budgets = [];
|
$existing_budgets = [];
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("SELECT category, amount FROM budgets WHERE user_id = :user_id AND budget_month = :budget_month");
|
$stmt = $pdo->prepare("SELECT category, amount FROM budgets WHERE client_id = :client_id AND budget_month = :budget_month");
|
||||||
$stmt->execute(['user_id' => $user_id, 'budget_month' => $budget_month_date]);
|
$stmt->execute(['client_id' => $client_id, 'budget_month' => $budget_month_date]);
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
foreach ($results as $row) {
|
foreach ($results as $row) {
|
||||||
$existing_budgets[$row['category']] = $row['amount'];
|
$existing_budgets[$row['category']] = $row['amount'];
|
||||||
@ -63,8 +65,10 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Categorias fixas
|
// Obter todas as categorias (macro áreas ativas) para os dropdowns
|
||||||
$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros'];
|
$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);
|
||||||
|
|
||||||
include __DIR__ . '/includes/header.php';
|
include __DIR__ . '/includes/header.php';
|
||||||
?>
|
?>
|
||||||
@ -101,17 +105,20 @@ include __DIR__ . '/includes/header.php';
|
|||||||
<input type="hidden" name="budget_month" value="<?php echo htmlspecialchars($budget_month_date); ?>">
|
<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>
|
<h4 class="mb-3">Orçamentos para <?php echo date('F \d\e Y', strtotime($budget_month_date)); ?></h4>
|
||||||
|
|
||||||
<?php foreach ($categories as $category): ?>
|
<?php foreach ($categories as $category):
|
||||||
|
$category_slug = $category['slug'];
|
||||||
|
$category_nome = $category['nome'];
|
||||||
|
?>
|
||||||
<div class="row mb-2 align-items-center">
|
<div class="row mb-2 align-items-center">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label for="budget_<?php echo htmlspecialchars($category); ?>" class="form-label"><?php echo htmlspecialchars($category); ?></label>
|
<label for="budget_<?php echo htmlspecialchars($category_slug); ?>" class="form-label"><?php echo htmlspecialchars($category_nome); ?></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text">R$</span>
|
<span class="input-group-text">R$</span>
|
||||||
<input type="number" step="0.01" class="form-control" id="budget_<?php echo htmlspecialchars($category); ?>"
|
<input type="number" step="0.01" class="form-control" id="budget_<?php echo htmlspecialchars($category_slug); ?>"
|
||||||
name="budgets[<?php echo htmlspecialchars($category); ?>]"
|
name="budgets[<?php echo htmlspecialchars($category_slug); ?>]"
|
||||||
value="<?php echo htmlspecialchars($existing_budgets[$category] ?? '0.00'); ?>">
|
value="<?php echo htmlspecialchars($existing_budgets[$category_slug] ?? '0.00'); ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
307
Backend/categories.php
Normal file
307
Backend/categories.php
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
<?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'; ?>
|
||||||
60
Backend/db/fix_schema.php
Normal file
60
Backend/db/fix_schema.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?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());
|
||||||
|
}
|
||||||
|
|
||||||
5
Backend/db/migrations/005_create_clients_table.sql
Normal file
5
Backend/db/migrations/005_create_clients_table.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
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;
|
||||||
1
Backend/db/migrations/005a_insert_default_client.sql
Normal file
1
Backend/db/migrations/005a_insert_default_client.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `clients` (`id`, `name`) VALUES (1, 'Default Client') ON DUPLICATE KEY UPDATE `name` = `name`;
|
||||||
3
Backend/db/migrations/006_add_client_id_to_users.sql
Normal file
3
Backend/db/migrations/006_add_client_id_to_users.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
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;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
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;
|
||||||
3
Backend/db/migrations/008_add_client_id_to_budgets.sql
Normal file
3
Backend/db/migrations/008_add_client_id_to_budgets.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
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;
|
||||||
3
Backend/db/migrations/009_add_client_id_to_expenses.sql
Normal file
3
Backend/db/migrations/009_add_client_id_to_expenses.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
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;
|
||||||
10
Backend/db/migrations/010_fix_budgets_unique_key.sql
Normal file
10
Backend/db/migrations/010_fix_budgets_unique_key.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-- 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;
|
||||||
11
Backend/db/migrations/011_create_categories_table.sql
Normal file
11
Backend/db/migrations/011_create_categories_table.sql
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
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;
|
||||||
2
Backend/db/migrations/012_add_archived_to_categories.sql
Normal file
2
Backend/db/migrations/012_add_archived_to_categories.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `categories`
|
||||||
|
ADD COLUMN `is_archived` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 = active, 1 = archived' AFTER `client_id`;
|
||||||
@ -12,7 +12,7 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$expense_id = $_GET['id'] ?? null;
|
$expense_id = $_GET['id'] ?? null;
|
||||||
$user_id = $_SESSION['user_id'];
|
$client_id = $_SESSION['client_id'];
|
||||||
|
|
||||||
if (!$expense_id) {
|
if (!$expense_id) {
|
||||||
// Se não houver ID, redireciona de volta
|
// Se não houver ID, redireciona de volta
|
||||||
@ -23,11 +23,11 @@ if (!$expense_id) {
|
|||||||
try {
|
try {
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
// A cláusula WHERE garante que um usuário só pode deletar suas próprias despesas
|
// A cláusula WHERE garante que um usuário só pode deletar suas próprias despesas
|
||||||
$sql = "DELETE FROM expenses WHERE id = :id AND user_id = :user_id";
|
$sql = "DELETE FROM expenses WHERE id = :id AND client_id = :client_id";
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
'id' => $expense_id,
|
'id' => $expense_id,
|
||||||
'user_id' => $user_id
|
'client_id' => $client_id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Opcional: verificar se alguma linha foi afetada para dar um feedback mais preciso
|
// Opcional: verificar se alguma linha foi afetada para dar um feedback mais preciso
|
||||||
|
|||||||
@ -5,11 +5,12 @@ require_once 'db/config.php';
|
|||||||
// Check if ID is provided
|
// Check if ID is provided
|
||||||
if (isset($_GET['id'])) {
|
if (isset($_GET['id'])) {
|
||||||
$id = $_GET['id'];
|
$id = $_GET['id'];
|
||||||
|
$client_id = $_SESSION['client_id'];
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
// First, find the macro area to get its slug
|
// First, find the macro area to get its slug
|
||||||
$stmt = $pdo->prepare("SELECT slug FROM macro_areas WHERE id = ?");
|
$stmt = $pdo->prepare("SELECT slug FROM macro_areas WHERE id = ? AND client_id = ?");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id, $client_id]);
|
||||||
$macro_area = $stmt->fetch();
|
$macro_area = $stmt->fetch();
|
||||||
|
|
||||||
// If the macro area exists, proceed with checks and deletion
|
// If the macro area exists, proceed with checks and deletion
|
||||||
@ -17,8 +18,8 @@ if (isset($_GET['id'])) {
|
|||||||
$slug = $macro_area['slug'];
|
$slug = $macro_area['slug'];
|
||||||
|
|
||||||
// Check for dependent expenses
|
// Check for dependent expenses
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM expenses WHERE category = ?");
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM expenses WHERE category = ? AND client_id = ?");
|
||||||
$stmt->execute([$slug]);
|
$stmt->execute([$slug, $client_id]);
|
||||||
$expense_count = $stmt->fetchColumn();
|
$expense_count = $stmt->fetchColumn();
|
||||||
|
|
||||||
if ($expense_count > 0) {
|
if ($expense_count > 0) {
|
||||||
@ -26,8 +27,8 @@ if (isset($_GET['id'])) {
|
|||||||
$_SESSION['error_message'] = "Não é possível excluir a macro área. Existem {$expense_count} despesas associadas.";
|
$_SESSION['error_message'] = "Não é possível excluir a macro área. Existem {$expense_count} despesas associadas.";
|
||||||
} else {
|
} else {
|
||||||
// No dependencies, proceed with deletion
|
// No dependencies, proceed with deletion
|
||||||
$stmt = $pdo->prepare("DELETE FROM macro_areas WHERE id = ?");
|
$stmt = $pdo->prepare("DELETE FROM macro_areas WHERE id = ? AND client_id = ?");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id, $client_id]);
|
||||||
$_SESSION['success_message'] = "Macro área excluída com sucesso.";
|
$_SESSION['success_message'] = "Macro área excluída com sucesso.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$expense_id = $_GET['id'] ?? null;
|
$expense_id = $_GET['id'] ?? null;
|
||||||
$user_id = $_SESSION['user_id'];
|
$client_id = $_SESSION['client_id'];
|
||||||
$error_message = '';
|
$error_message = '';
|
||||||
$expense = null;
|
$expense = null;
|
||||||
|
|
||||||
@ -25,8 +25,8 @@ $pdo = db();
|
|||||||
|
|
||||||
// Buscar a despesa para garantir que ela pertence ao usuário
|
// Buscar a despesa para garantir que ela pertence ao usuário
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("SELECT * FROM expenses WHERE id = :id AND user_id = :user_id");
|
$stmt = $pdo->prepare("SELECT * FROM expenses WHERE id = :id AND client_id = :client_id");
|
||||||
$stmt->execute(['id' => $expense_id, 'user_id' => $user_id]);
|
$stmt->execute(['id' => $expense_id, 'client_id' => $client_id]);
|
||||||
$expense = $stmt->fetch(PDO::FETCH_ASSOC);
|
$expense = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if (!$expense) {
|
if (!$expense) {
|
||||||
@ -51,7 +51,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$error_message = 'Todos os campos são obrigatórios.';
|
$error_message = 'Todos os campos são obrigatórios.';
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$sql = "UPDATE expenses SET description = :description, amount = :amount, category = :category, expense_date = :expense_date WHERE id = :id AND user_id = :user_id";
|
$sql = "UPDATE expenses SET description = :description, amount = :amount, category = :category, expense_date = :expense_date WHERE id = :id AND client_id = :client_id";
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
'description' => $description,
|
'description' => $description,
|
||||||
@ -59,7 +59,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
'category' => $category,
|
'category' => $category,
|
||||||
'expense_date' => $expense_date,
|
'expense_date' => $expense_date,
|
||||||
'id' => $expense_id,
|
'id' => $expense_id,
|
||||||
'user_id' => $user_id
|
'client_id' => $client_id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$_SESSION['success_message'] = 'Despesa atualizada com sucesso!';
|
$_SESSION['success_message'] = 'Despesa atualizada com sucesso!';
|
||||||
@ -100,13 +100,12 @@ include __DIR__ . '/includes/header.php';
|
|||||||
<select class="form-select" id="category" name="category" required>
|
<select class="form-select" id="category" name="category" required>
|
||||||
<option value="">Selecione...</option>
|
<option value="">Selecione...</option>
|
||||||
<?php
|
<?php
|
||||||
$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros'];
|
$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);
|
||||||
foreach ($categories as $cat) {
|
foreach ($categories as $cat) {
|
||||||
$selected = ($expense['category'] === $cat) ? 'selected' : '';
|
$selected = ($expense['category'] === $cat['slug']) ? 'selected' : '';
|
||||||
echo "<option value=\"".htmlspecialchars($cat)."\" $selected>".htmlspecialchars($cat)."</option>";
|
echo "<option value=\"".htmlspecialchars($cat['slug']).
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="expense_date" class="form-label">Data da Despesa</label>
|
<label for="expense_date" class="form-label">Data da Despesa</label>
|
||||||
|
|||||||
@ -11,6 +11,7 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$client_id = $_SESSION['client_id'];
|
||||||
$user_id = $_SESSION['user_id'];
|
$user_id = $_SESSION['user_id'];
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$error_message = '';
|
$error_message = '';
|
||||||
@ -27,9 +28,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$error_message = 'Todos os campos são obrigatórios para adicionar uma despesa.';
|
$error_message = 'Todos os campos são obrigatórios para adicionar uma despesa.';
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$sql = "INSERT INTO expenses (user_id, description, amount, category, expense_date) VALUES (:user_id, :description, :amount, :category, :expense_date)";
|
$sql = "INSERT INTO expenses (client_id, user_id, description, amount, category, expense_date) VALUES (:client_id, :user_id, :description, :amount, :category, :expense_date)";
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
|
'client_id' => $client_id,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'description' => $description,
|
'description' => $description,
|
||||||
'amount' => $amount,
|
'amount' => $amount,
|
||||||
@ -50,8 +52,8 @@ $filter_start_date = $_GET['start_date'] ?? '';
|
|||||||
$filter_end_date = $_GET['end_date'] ?? '';
|
$filter_end_date = $_GET['end_date'] ?? '';
|
||||||
$filter_category = $_GET['category'] ?? '';
|
$filter_category = $_GET['category'] ?? '';
|
||||||
|
|
||||||
$sql = "SELECT * FROM expenses WHERE user_id = :user_id";
|
$sql = "SELECT * FROM expenses WHERE client_id = :client_id";
|
||||||
$params = ['user_id' => $user_id];
|
$params = ['client_id' => $client_id];
|
||||||
|
|
||||||
if ($filter_start_date) {
|
if ($filter_start_date) {
|
||||||
$sql .= " AND expense_date >= :start_date";
|
$sql .= " AND expense_date >= :start_date";
|
||||||
@ -83,8 +85,10 @@ try {
|
|||||||
$error_message = 'Erro ao buscar despesas: ' . $e->getMessage();
|
$error_message = 'Erro ao buscar despesas: ' . $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obter todas as categorias para o dropdown do filtro
|
// Obter todas as categorias (macro áreas ativas) para os dropdowns
|
||||||
$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros'];
|
$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);
|
||||||
|
|
||||||
include __DIR__ . '/includes/header.php';
|
include __DIR__ . '/includes/header.php';
|
||||||
?>
|
?>
|
||||||
@ -114,7 +118,7 @@ include __DIR__ . '/includes/header.php';
|
|||||||
<select class="form-select" id="category" name="category" required>
|
<select class="form-select" id="category" name="category" required>
|
||||||
<option value="">Selecione...</option>
|
<option value="">Selecione...</option>
|
||||||
<?php foreach ($categories as $cat): ?>
|
<?php foreach ($categories as $cat): ?>
|
||||||
<option value="<?php echo htmlspecialchars($cat); ?>"><?php echo htmlspecialchars($cat); ?></option>
|
<option value="<?php echo htmlspecialchars($cat['slug']); ?>"><?php echo htmlspecialchars($cat['nome']); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -164,7 +168,7 @@ include __DIR__ . '/includes/header.php';
|
|||||||
<select class="form-select" id="filter_category" name="category">
|
<select class="form-select" id="filter_category" name="category">
|
||||||
<option value="">Todas</option>
|
<option value="">Todas</option>
|
||||||
<?php foreach ($categories as $cat): ?>
|
<?php foreach ($categories as $cat): ?>
|
||||||
<option value="<?php echo htmlspecialchars($cat); ?>" <?php echo ($filter_category === $cat) ? 'selected' : ''; ?>><?php echo htmlspecialchars($cat); ?></option>
|
<option value="<?php echo htmlspecialchars($cat['slug']); ?>" <?php echo ($filter_category === $cat['slug']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($cat['nome']); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,12 +8,12 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_id = $_SESSION['user_id'];
|
$client_id = $_SESSION['client_id'];
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
// Build query with filters
|
// Build query with filters
|
||||||
$sql = "SELECT * FROM expenses WHERE user_id = :user_id";
|
$sql = "SELECT * FROM expenses WHERE client_id = :client_id";
|
||||||
$params = ['user_id' => $user_id];
|
$params = ['client_id' => $client_id];
|
||||||
|
|
||||||
if (!empty($_GET['start_date'])) {
|
if (!empty($_GET['start_date'])) {
|
||||||
$sql .= " AND expense_date >= :start_date";
|
$sql .= " AND expense_date >= :start_date";
|
||||||
|
|||||||
@ -71,7 +71,7 @@ $unclassifiedCount = 5; // Example value
|
|||||||
</a>
|
</a>
|
||||||
<ul class="collapse show list-unstyled sub-sub-menu" id="planoContasSubmenu">
|
<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/macro_areas.php"><span class="menu-item-text">Macro Áreas</span></a></li>
|
||||||
<li><a href="#"><span class="menu-item-text">Categorias</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">Centro de Custo</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>
|
<li><a href="#"><span class="menu-item-text">Alocação do Plano</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -20,14 +20,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$stmt = $pdo->prepare("SELECT id, password_hash FROM users WHERE email = :email");
|
$stmt = $pdo->prepare("SELECT id, client_id, email, password_hash FROM users WHERE email = :email");
|
||||||
$stmt->execute(['email' => $email]);
|
$stmt->execute(['email' => $email]);
|
||||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if ($user && password_verify($password, $user['password_hash'])) {
|
if ($user && password_verify($password, $user['password_hash'])) {
|
||||||
// Login bem-sucedido: Redireciona com flag de depuração
|
// Login bem-sucedido: Armazena dados na sessão
|
||||||
// Senha correta, inicie a sessão
|
|
||||||
$_SESSION['user_id'] = $user['id'];
|
$_SESSION['user_id'] = $user['id'];
|
||||||
|
$_SESSION['client_id'] = $user['client_id'];
|
||||||
$_SESSION['user_email'] = $user['email'];
|
$_SESSION['user_email'] = $user['email'];
|
||||||
header("Location: /index.php");
|
header("Location: /index.php");
|
||||||
exit();
|
exit();
|
||||||
|
|||||||
@ -13,6 +13,7 @@ function generateSlug($string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
$client_id = $_SESSION['client_id'];
|
||||||
$error = null;
|
$error = null;
|
||||||
$macro_area = [
|
$macro_area = [
|
||||||
'id' => '',
|
'id' => '',
|
||||||
@ -35,8 +36,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
// Repopulate form data on error
|
// Repopulate form data on error
|
||||||
$macro_area = $_POST;
|
$macro_area = $_POST;
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare('SELECT id FROM macro_areas WHERE (nome = ? OR slug = ?) AND id <> ?');
|
$stmt = $pdo->prepare('SELECT id FROM macro_areas WHERE (nome = ? OR slug = ?) AND id <> ? AND client_id = ?');
|
||||||
$stmt->execute([$nome, $slug, $id ?: 0]);
|
$stmt->execute([$nome, $slug, $id ?: 0, $client_id]);
|
||||||
if ($stmt->fetch()) {
|
if ($stmt->fetch()) {
|
||||||
$error = "Já existe uma Macro Área com este nome.";
|
$error = "Já existe uma Macro Área com este nome.";
|
||||||
// Repopulate form data on error
|
// Repopulate form data on error
|
||||||
@ -44,13 +45,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
} else {
|
} else {
|
||||||
if ($id) {
|
if ($id) {
|
||||||
// Update
|
// Update
|
||||||
$stmt = $pdo->prepare('UPDATE macro_areas SET nome = ?, slug = ?, descricao = ?, ativo = ? WHERE id = ?');
|
$stmt = $pdo->prepare('UPDATE macro_areas SET nome = ?, slug = ?, descricao = ?, ativo = ? WHERE id = ? AND client_id = ?');
|
||||||
$stmt->execute([$nome, $slug, $descricao, $ativo, $id]);
|
$stmt->execute([$nome, $slug, $descricao, $ativo, $id, $client_id]);
|
||||||
$redirect_id = $id;
|
$redirect_id = $id;
|
||||||
} else {
|
} else {
|
||||||
// Create
|
// Create
|
||||||
$stmt = $pdo->prepare('INSERT INTO macro_areas (nome, slug, descricao, ativo, user_id) VALUES (?, ?, ?, ?, ?)');
|
$stmt = $pdo->prepare('INSERT INTO macro_areas (client_id, nome, slug, descricao, ativo, user_id) VALUES (?, ?, ?, ?, ?, ?)');
|
||||||
$stmt->execute([$nome, $slug, $descricao, $ativo, $_SESSION['user_id'] ?? 1]);
|
$stmt->execute([$client_id, $nome, $slug, $descricao, $ativo, $_SESSION['user_id'] ?? 1]);
|
||||||
$redirect_id = $pdo->lastInsertId();
|
$redirect_id = $pdo->lastInsertId();
|
||||||
}
|
}
|
||||||
header("Location: /Backend/macro_area_form.php");
|
header("Location: /Backend/macro_area_form.php");
|
||||||
@ -60,8 +61,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
} elseif (isset($_GET['id'])) {
|
} elseif (isset($_GET['id'])) {
|
||||||
// Handle edit mode (fetch data)
|
// Handle edit mode (fetch data)
|
||||||
$id = $_GET['id'];
|
$id = $_GET['id'];
|
||||||
$stmt = $pdo->prepare('SELECT * FROM macro_areas WHERE id = ?');
|
$stmt = $pdo->prepare('SELECT * FROM macro_areas WHERE id = ? AND client_id = ?');
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id, $client_id]);
|
||||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if ($data) {
|
if ($data) {
|
||||||
$macro_area = $data;
|
$macro_area = $data;
|
||||||
|
|||||||
@ -5,7 +5,9 @@ include_once 'includes/header.php';
|
|||||||
|
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
$stmt = $pdo->query('SELECT * FROM macro_areas ORDER BY nome ASC');
|
$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]);
|
||||||
$macro_areas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$macro_areas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
@ -3,7 +3,9 @@ require_once 'includes/session.php';
|
|||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
|
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$stmt = $pdo->query('SELECT * FROM macro_areas ORDER BY nome ASC');
|
$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]);
|
||||||
$macro_areas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$macro_areas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$total = count($macro_areas);
|
$total = count($macro_areas);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user