Files
controles/templates/editar_material.html
LS 7399e0000e feat: Implementar arquitetura de permissões no nível de dados
BREAKING CHANGES:
- Sistema de permissões movido do nível de template para nível de dados
- Menus sempre visíveis, controle transparente no backend
- Templates nunca quebram, sempre renderizam com dados filtrados

Features:
-  Arquitetura MVC completa implementada
-  Controllers com filtragem hierárquica de dados
-  Template helpers simplificados (user_can sempre True)
-  Controle de acesso baseado na hierarquia organizacional
-  Regra especial para tesoureiros (acesso completo)
-  Tratamento robusto de erros em todos os controllers

Controllers implementados:
- militante_controller.py - Filtragem por célula/setor/CR/CC
- cota_controller.py - Controle baseado em permissões
- material_controller.py - Acesso flexível por nível
- pagamento_controller.py - Filtragem organizacional
- auth_controller.py - Autenticação com OTP
- home_controller.py - Dashboard com estatísticas
- usuario_controller.py - Gestão de usuários

Templates corrigidos:
- listar_cotas.html - URLs corrigidas (nova_cota → cota.nova)
- listar_tipos_materiais.html - Variáveis ajustadas (tipos → tipos_materiais)
- base.html - Menus sempre visíveis
- Diversos templates com correções de URLs e referências

Services implementados:
- auth_service.py - Lógica de autenticação
- dashboard_service.py - Estatísticas do dashboard
- cache_service.py - Integração com Redis
- celula_service.py - Operações de células

Models implementados:
- militante_model.py - Operações de militantes
- pagamento_model.py - Operações de pagamentos

Documentação:
- docs/permission_fixes_summary.md - Resumo completo das correções
- docs/architecture_summary.md - Arquitetura MVC
- docs/mvc_refactoring.md - Detalhes da refatoração
- docs/permission_strategy.md - Estratégia de permissões
- docs/redis_cache_setup.md - Setup do cache Redis
- README.md atualizado com nova arquitetura

Testes:
- test_menu_navigation.py - Testes unitários de navegação
- test_integration_menu.py - Testes de integração com Selenium

Status dos testes:
 Funcionais: /, /dashboard, /pagamentos, /materiais
 Com problemas: /militantes, /cotas, /tipos-materiais, /admin/dashboard

Hierarquia de permissões implementada:
Admin → Acesso total
CC → Acesso total
CR → Dados do CR
Setor → Dados do setor
Célula → Dados da célula

Próximos passos identificados:
- Corrigir referências a Militante indefinido nos templates
- Resolver problemas de campos inexistentes
- Corrigir roteamento admin
2025-07-01 13:42:56 -03:00

94 lines
3.9 KiB
HTML

{% extends 'base.html' %}
{% block title %}Editar Material{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="mb-4">Editar Material</h1>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST" class="needs-validation" novalidate>
<div class="mb-3">
<label for="nome" class="form-label">Nome</label>
<input type="text" class="form-control" id="nome" name="nome" value="{{ material.nome }}" required>
<div class="invalid-feedback">
Por favor, insira o nome do material.
</div>
</div>
<div class="mb-3">
<label for="descricao" class="form-label">Descrição</label>
<textarea class="form-control" id="descricao" name="descricao" rows="3" required>{{ material.descricao }}</textarea>
<div class="invalid-feedback">
Por favor, insira a descrição do material.
</div>
</div>
<div class="mb-3">
<label for="preco" class="form-label">Preço</label>
<input type="number" class="form-control" id="preco" name="preco" step="0.01" value="{{ material.preco }}" required>
<div class="invalid-feedback">
Por favor, insira o preço do material.
</div>
</div>
<div class="mb-3">
<label for="quantidade" class="form-label">Quantidade</label>
<input type="number" class="form-control" id="quantidade" name="quantidade" value="{{ material.quantidade }}" required>
<div class="invalid-feedback">
Por favor, insira a quantidade do material.
</div>
</div>
<div class="mb-3">
<label for="tipo_id" class="form-label">Tipo de Material</label>
<select class="form-select" id="tipo_id" name="tipo_id" required>
<option value="">Selecione um tipo</option>
{% for tipo in tipos %}
<option value="{{ tipo.id }}" {% if tipo.id == material.tipo_id %}selected{% endif %}>{{ tipo.nome }}</option>
{% endfor %}
</select>
<div class="invalid-feedback">
Por favor, selecione o tipo do material.
</div>
</div>
<div class="d-flex justify-content-between">
<button type="submit" class="btn btn-success">Salvar</button>
<a href="{{ url_for('material.listar') }}" class="btn btn-outline-secondary">Voltar</a>
</div>
</form>
</div>
</div>
</div>
<script>
// Validação do formulário
(function () {
'use strict'
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
{% endblock %}