2026-03-09 18:46:01 +00:00
|
|
|
|
# Arquitetura de Aprovação - SGMP_PROD
|
|
|
|
|
|
|
|
|
|
|
|
## 📋 Situação Atual
|
|
|
|
|
|
|
|
|
|
|
|
### Fluxo de Aprovação Atual
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GESTOR cria solicitação
|
|
|
|
|
|
↓
|
|
|
|
|
|
Status: RASCUNHO
|
|
|
|
|
|
↓
|
|
|
|
|
|
GESTOR envia para aprovação
|
|
|
|
|
|
↓
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
Status: AGUARDANDO_HEAD (quando há etapa de Head)
|
|
|
|
|
|
↓
|
|
|
|
|
|
HEAD analisa e APROVA/REPROVA (limitado aos gestores sob sua responsabilidade)
|
2026-03-09 18:46:01 +00:00
|
|
|
|
↓
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
Status: ENVIADA
|
2026-03-09 18:46:01 +00:00
|
|
|
|
↓
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
GG registra PARECER (não aprova/reprova)
|
2026-03-09 18:46:01 +00:00
|
|
|
|
↓
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
CONTROLADORIA registra PARECER (não aprova/reprova)
|
2026-03-09 18:46:01 +00:00
|
|
|
|
↓
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
Status: AGUARDANDO_DIRETORIA
|
2026-03-09 18:46:01 +00:00
|
|
|
|
↓
|
|
|
|
|
|
DIRETORIA analisa e APROVA/REPROVA
|
|
|
|
|
|
↓
|
|
|
|
|
|
Se aprovada → Status: FINALIZADA
|
|
|
|
|
|
Se reprovada → Status: REPROVADA
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Componentes Atuais
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. Modelos (`models.py`)
|
|
|
|
|
|
|
|
|
|
|
|
- **`Solicitacao`**: Entidade central
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
- Método `etapa_atual()`: Retorna a etapa atual baseada no status.
|
|
|
|
|
|
- Método `pode_aprovar(usuario)`: Verifica se o usuário pode aprovar na etapa atual (Head ou Diretoria).
|
|
|
|
|
|
- Método `pode_dar_parecer(usuario)`: Verifica se GG/Controladoria podem registrar parecer.
|
|
|
|
|
|
|
|
|
|
|
|
- **`Parecer`**: Registro de parecer técnico
|
|
|
|
|
|
- Emitido por GG ou CONTROLADORIA.
|
|
|
|
|
|
- Não altera o status diretamente; quando existem pareceres das duas etapas, a solicitação avança para `AGUARDANDO_DIRETORIA`.
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
- **`Aprovacao`**: Registra cada decisão (aprovar/reprovar) em cada etapa
|
|
|
|
|
|
- Campos: `solicitacao`, `etapa`, `decisao`, `usuario`, `justificativa`, `decidido_em`
|
|
|
|
|
|
- Unique constraint: `(solicitacao, etapa)` - garante uma aprovação por etapa
|
|
|
|
|
|
|
|
|
|
|
|
- **`StatusSolicitacao`**: Enum com os status possíveis
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
- `RASCUNHO`, `AGUARDANDO_HEAD`, `ENVIADA`, `APROVADA_GG`, `APROVADA_CONTROLADORIA`, `APROVADA_DIRETORIA`, `AGUARDANDO_DIRETORIA`, `FINALIZADA`, `REPROVADA`
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
- **`EtapaAprovacao`**: Enum com as etapas
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
- `HEAD`, `GG`, `CONTROLADORIA`, `DIRETORIA`
|
|
|
|
|
|
|
|
|
|
|
|
- **`UsuarioSistema` e `UsuarioPerfilExtra`**:
|
|
|
|
|
|
- `UsuarioSistema.perfil` define o perfil principal.
|
|
|
|
|
|
- `UsuarioPerfilExtra` permite atribuir perfis adicionais (multi-perfis).
|
|
|
|
|
|
- Métodos como `tem_perfil` e `perfis_ativos` centralizam a checagem de perfis.
|
|
|
|
|
|
|
|
|
|
|
|
- **`HeadGestor`**:
|
|
|
|
|
|
- Vínculo Head → Gestores: define para quais gestores um Head pode aprovar solicitações.
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
#### 2. Services (`services.py`)
|
|
|
|
|
|
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
- **`aprovar_reprovar_por_head()`** – decisão da etapa HEAD:
|
|
|
|
|
|
1. Valida se a solicitação está em `AGUARDANDO_HEAD`.
|
|
|
|
|
|
2. Valida se o usuário tem perfil de Head (`tem_perfil('HEAD')`) e está vinculado como head do gestor solicitante.
|
|
|
|
|
|
3. Cria `Aprovacao` na etapa HEAD.
|
|
|
|
|
|
4. Atualiza o status para a próxima etapa (tipicamente `ENVIADA`) ou `REPROVADA`.
|
|
|
|
|
|
|
|
|
|
|
|
- **`registrar_parecer()`** – registro de parecer técnico (GG / Controladoria):
|
|
|
|
|
|
1. Valida se a solicitação está em `ENVIADA` e se o usuário pode dar parecer.
|
|
|
|
|
|
2. Cria `Parecer` para a etapa correspondente (GG ou CONTROLADORIA).
|
|
|
|
|
|
3. Quando existem pareceres das duas etapas, atualiza status para `AGUARDANDO_DIRETORIA`.
|
|
|
|
|
|
|
|
|
|
|
|
- **`aprovar_reprovar_solicitacao()`** – decisão final da Diretoria:
|
|
|
|
|
|
1. Valida se a solicitação está em `AGUARDANDO_DIRETORIA`.
|
|
|
|
|
|
2. Valida se o usuário tem perfil de Diretoria.
|
|
|
|
|
|
3. Cria `Aprovacao` na etapa DIRETORIA.
|
|
|
|
|
|
4. Atualiza o status para `FINALIZADA` ou `REPROVADA`.
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
#### 3. Views (`views.py`)
|
|
|
|
|
|
|
|
|
|
|
|
- **`decidir_solicitacao()`**: View que recebe POST com decisão e justificativa
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
- Decorator: `@requer_perfil(HEAD, DIRETORIA)`
|
|
|
|
|
|
- Para status `AGUARDANDO_HEAD`, chama `aprovar_reprovar_por_head()`
|
|
|
|
|
|
- Para status `AGUARDANDO_DIRETORIA`, chama `aprovar_reprovar_solicitacao()`
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
- **`solicitacao_detalhe()`**: Exibe detalhes e botões de aprovação
|
|
|
|
|
|
- Calcula `pode_aprovar` usando `solicitacao.pode_aprovar(usuario)`
|
|
|
|
|
|
|
|
|
|
|
|
- **`dashboard_view()`**: Lista solicitações com informações de `pode_aprovar`
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. Templates
|
|
|
|
|
|
|
|
|
|
|
|
- **`dashboard.html`**: Mostra botões "Aprovar" e "Reprovar" se `item.pode_aprovar == True`
|
|
|
|
|
|
- **`solicitacao_detalhe.html`**: Similar, mostra botões de aprovação
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
## 🔄 Arquitetura Detalhada (pareceres + Diretoria)
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
### Fluxo com Head, pareceres e Diretoria
|
2026-03-09 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
GESTOR cria solicitação
|
|
|
|
|
|
↓
|
|
|
|
|
|
Status: RASCUNHO
|
|
|
|
|
|
↓
|
|
|
|
|
|
GESTOR envia para aprovação
|
|
|
|
|
|
↓
|
feat(sgmp): API REST, app Next.js, ConfiguracaoSGMP e ajustes de permissões/serviços
- API JSON (auth, dashboard, colaboradores, solicitações) e app Next em frontend/
- Modelo ConfiguracaoSGMP, migrações e permissões (acesso, decorators, context)
- Serviços/views/templates e integrações Winthor/SQL Server
- Docs: MIGRACAO, ARQUITETURA_APROVACAO, README_PERMISSOES; Dockerfile/requirements
- Testes: fluxo de desligamento alinhado a pareceres GG/Ctrl + Diretoria; criar_solicitacao_desligamento com tipo/aviso
Made-with: Cursor
2026-04-15 01:44:49 +00:00
|
|
|
|
Status: AGUARDANDO_HEAD (quando aplicável; senão vai direto para ENVIADA)
|
|
|
|
|
|
↓
|
|
|
|
|
|
HEAD aprova/reprova (etapa HEAD)
|
|
|
|
|
|
↓
|
2026-03-09 18:46:01 +00:00
|
|
|
|
Status: ENVIADA
|
|
|
|
|
|
↓
|
|
|
|
|
|
GG registra PARECER (não aprova/reprova)
|
|
|
|
|
|
↓
|
|
|
|
|
|
CONTROLADORIA registra PARECER (não aprova/reprova)
|
|
|
|
|
|
↓
|
|
|
|
|
|
Status: AGUARDANDO_DIRETORIA (novo status)
|
|
|
|
|
|
↓
|
|
|
|
|
|
DIRETORIA analisa pareceres e APROVA/REPROVA
|
|
|
|
|
|
↓
|
|
|
|
|
|
Se aprovada → Status: FINALIZADA
|
|
|
|
|
|
Se reprovada → Status: REPROVADA
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Mudanças Necessárias
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. Novo Modelo: `Parecer`
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
class Parecer(BaseModel):
|
|
|
|
|
|
"""
|
|
|
|
|
|
Representa um parecer técnico emitido por GG ou CONTROLADORIA
|
|
|
|
|
|
sobre uma solicitação. Diferente de Aprovacao, um Parecer não
|
|
|
|
|
|
altera o status da solicitação, apenas fornece análise e dados.
|
|
|
|
|
|
"""
|
|
|
|
|
|
solicitacao = models.ForeignKey(Solicitacao, on_delete=models.CASCADE, related_name="pareceres")
|
|
|
|
|
|
etapa = models.CharField(max_length=20, choices=EtapaAprovacao.choices) # GG ou CONTROLADORIA
|
|
|
|
|
|
usuario = models.ForeignKey(UsuarioSistema, on_delete=models.PROTECT)
|
|
|
|
|
|
texto = models.TextField(help_text="Análise, dados e considerações sobre a solicitação")
|
|
|
|
|
|
criado_em = models.DateTimeField(auto_now_add=True)
|
|
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
|
unique_together = ("solicitacao", "etapa") # Um parecer por etapa
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. Modificar `StatusSolicitacao`
|
|
|
|
|
|
|
|
|
|
|
|
Adicionar novo status:
|
|
|
|
|
|
- `AGUARDANDO_DIRETORIA = "AGUARDANDO_DIRETORIA", _("Aguardando Diretoria")`
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. Modificar `Solicitacao.etapa_atual()`
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
def etapa_atual(self):
|
|
|
|
|
|
mapa = {
|
|
|
|
|
|
StatusSolicitacao.ENVIADA: None, # GG e CONTROLADORIA podem dar parecer
|
|
|
|
|
|
StatusSolicitacao.AGUARDANDO_DIRETORIA: EtapaAprovacao.DIRETORIA,
|
|
|
|
|
|
}
|
|
|
|
|
|
return mapa.get(self.status)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. Modificar `Solicitacao.pode_aprovar()`
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
def pode_aprovar(self, usuario=None):
|
|
|
|
|
|
"""
|
|
|
|
|
|
Apenas DIRETORIA pode aprovar/reprovar.
|
|
|
|
|
|
GG e CONTROLADORIA apenas podem dar parecer.
|
|
|
|
|
|
"""
|
|
|
|
|
|
etapa_atual = self.etapa_atual()
|
|
|
|
|
|
if etapa_atual is None:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# Apenas DIRETORIA pode aprovar
|
|
|
|
|
|
if etapa_atual != EtapaAprovacao.DIRETORIA:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
if usuario:
|
|
|
|
|
|
if usuario.perfil != UsuarioSistema.Perfil.DIRETORIA:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 5. Novo método: `Solicitacao.pode_dar_parecer()`
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
def pode_dar_parecer(self, usuario):
|
|
|
|
|
|
"""
|
|
|
|
|
|
Verifica se o usuário pode dar parecer na solicitação.
|
|
|
|
|
|
GG e CONTROLADORIA podem dar parecer quando status é ENVIADA.
|
|
|
|
|
|
"""
|
|
|
|
|
|
if self.status != StatusSolicitacao.ENVIADA:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# Verifica se já deu parecer
|
|
|
|
|
|
parecer_existente = self.pareceres.filter(etapa=usuario.perfil).exists()
|
|
|
|
|
|
if parecer_existente:
|
|
|
|
|
|
return False # Já deu parecer
|
|
|
|
|
|
|
|
|
|
|
|
# GG e CONTROLADORIA podem dar parecer
|
|
|
|
|
|
if usuario.perfil in [UsuarioSistema.Perfil.GG, UsuarioSistema.Perfil.CONTROLADORIA]:
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 6. Novo Service: `registrar_parecer()`
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
|
def registrar_parecer(
|
|
|
|
|
|
solicitacao: Solicitacao,
|
|
|
|
|
|
usuario: UsuarioSistema,
|
|
|
|
|
|
texto: str
|
|
|
|
|
|
) -> Parecer:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Registra um parecer de GG ou CONTROLADORIA.
|
|
|
|
|
|
Não altera o status da solicitação.
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not solicitacao.pode_dar_parecer(usuario):
|
|
|
|
|
|
raise PermissaoError("Usuário não pode dar parecer nesta solicitação.")
|
|
|
|
|
|
|
|
|
|
|
|
# Mapeia perfil para etapa
|
|
|
|
|
|
mapa_perfil_etapa = {
|
|
|
|
|
|
UsuarioSistema.Perfil.GG: EtapaAprovacao.GG,
|
|
|
|
|
|
UsuarioSistema.Perfil.CONTROLADORIA: EtapaAprovacao.CONTROLADORIA,
|
|
|
|
|
|
}
|
|
|
|
|
|
etapa = mapa_perfil_etapa.get(usuario.perfil)
|
|
|
|
|
|
|
|
|
|
|
|
parecer = Parecer.objects.create(
|
|
|
|
|
|
solicitacao=solicitacao,
|
|
|
|
|
|
etapa=etapa,
|
|
|
|
|
|
usuario=usuario,
|
|
|
|
|
|
texto=texto
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Verifica se ambos os pareceres foram dados
|
|
|
|
|
|
parecer_gg = Parecer.objects.filter(solicitacao=solicitacao, etapa=EtapaAprovacao.GG).exists()
|
|
|
|
|
|
parecer_controladoria = Parecer.objects.filter(solicitacao=solicitacao, etapa=EtapaAprovacao.CONTROLADORIA).exists()
|
|
|
|
|
|
|
|
|
|
|
|
if parecer_gg and parecer_controladoria:
|
|
|
|
|
|
# Ambos os pareceres foram dados, muda status para AGUARDANDO_DIRETORIA
|
|
|
|
|
|
solicitacao.status = StatusSolicitacao.AGUARDANDO_DIRETORIA
|
|
|
|
|
|
solicitacao.save()
|
|
|
|
|
|
|
|
|
|
|
|
return parecer
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 7. Modificar `aprovar_reprovar_solicitacao()`
|
|
|
|
|
|
|
|
|
|
|
|
Agora apenas DIRETORIA pode usar esta função:
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
|
def aprovar_reprovar_solicitacao(
|
|
|
|
|
|
solicitacao: Solicitacao,
|
|
|
|
|
|
aprovador: UsuarioSistema,
|
|
|
|
|
|
decisao: str,
|
|
|
|
|
|
justificativa: str = ""
|
|
|
|
|
|
) -> Solicitacao:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Apenas DIRETORIA pode aprovar/reprovar.
|
|
|
|
|
|
A solicitação deve estar em AGUARDANDO_DIRETORIA.
|
|
|
|
|
|
"""
|
|
|
|
|
|
if aprovador.perfil != UsuarioSistema.Perfil.DIRETORIA:
|
|
|
|
|
|
raise PermissaoError("Apenas a Diretoria pode aprovar/reprovar solicitações.")
|
|
|
|
|
|
|
|
|
|
|
|
if solicitacao.status != StatusSolicitacao.AGUARDANDO_DIRETORIA:
|
|
|
|
|
|
raise ValidacaoError("A solicitação não está aguardando aprovação da Diretoria.")
|
|
|
|
|
|
|
|
|
|
|
|
# ... resto da lógica similar
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 8. Nova View: `registrar_parecer_view()`
|
|
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
@login_required
|
|
|
|
|
|
@requer_perfil(UsuarioSistema.Perfil.GG, UsuarioSistema.Perfil.CONTROLADORIA)
|
|
|
|
|
|
def registrar_parecer_view(request, solicitacao_id):
|
|
|
|
|
|
solicitacao = get_object_or_404(Solicitacao, id=solicitacao_id)
|
|
|
|
|
|
usuario = get_usuario_sistema(request)
|
|
|
|
|
|
|
|
|
|
|
|
if request.method == "POST":
|
|
|
|
|
|
texto = request.POST.get("texto", "").strip()
|
|
|
|
|
|
if not texto:
|
|
|
|
|
|
messages.error(request, "O parecer não pode estar vazio.")
|
|
|
|
|
|
else:
|
|
|
|
|
|
try:
|
|
|
|
|
|
services.registrar_parecer(solicitacao, usuario, texto)
|
|
|
|
|
|
messages.success(request, "Parecer registrado com sucesso.")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
messages.error(request, str(e))
|
|
|
|
|
|
|
|
|
|
|
|
return redirect("solicitacoes:solicitacao_detalhe", solicitacao_id=solicitacao.id)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 9. Modificar Templates
|
|
|
|
|
|
|
|
|
|
|
|
- **Dashboard**: Mostrar botão "Dar Parecer" para GG/CONTROLADORIA quando `pode_dar_parecer == True`
|
|
|
|
|
|
- **Detalhes**: Mostrar campo de texto para parecer e botão "Registrar Parecer" para GG/CONTROLADORIA
|
|
|
|
|
|
- Mostrar pareceres já registrados na seção de auditoria
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📊 Resumo das Mudanças
|
|
|
|
|
|
|
|
|
|
|
|
| Componente | Mudança |
|
|
|
|
|
|
|------------|---------|
|
|
|
|
|
|
| **Modelo** | Adicionar `Parecer` |
|
|
|
|
|
|
| **StatusSolicitacao** | Adicionar `AGUARDANDO_DIRETORIA` |
|
|
|
|
|
|
| **Solicitacao.etapa_atual()** | Retornar `None` para `ENVIADA`, `DIRETORIA` para `AGUARDANDO_DIRETORIA` |
|
|
|
|
|
|
| **Solicitacao.pode_aprovar()** | Apenas DIRETORIA pode aprovar |
|
|
|
|
|
|
| **Solicitacao** | Adicionar método `pode_dar_parecer()` |
|
|
|
|
|
|
| **Services** | Novo: `registrar_parecer()`, modificar `aprovar_reprovar_solicitacao()` |
|
|
|
|
|
|
| **Views** | Novo: `registrar_parecer_view()`, modificar `decidir_solicitacao()` |
|
|
|
|
|
|
| **Templates** | Mostrar campos de parecer para GG/CONTROLADORIA, botões de aprovação apenas para DIRETORIA |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## ✅ Benefícios da Nova Arquitetura
|
|
|
|
|
|
|
|
|
|
|
|
1. **Separação de responsabilidades**: GG e CONTROLADORIA fornecem análise, DIRETORIA decide
|
|
|
|
|
|
2. **Flexibilidade**: Pareceres podem ser editados (se necessário) sem afetar o fluxo
|
|
|
|
|
|
3. **Rastreabilidade**: Histórico completo de pareceres e decisão final
|
|
|
|
|
|
4. **Clareza**: Status `AGUARDANDO_DIRETORIA` deixa claro que está aguardando decisão final
|
|
|
|
|
|
|