atualização relatorios

This commit is contained in:
Thais Ferreira 2025-03-27 17:38:08 -03:00
parent 8c502c8b09
commit 3d6821682b
10 changed files with 612 additions and 15 deletions

3
app.py
View File

@ -20,6 +20,7 @@ from routes.service import service_bp
from routes.service_roles import service_role_bp
from routes.cameras import camera_bp
from routes.ambiente import ambiente_bp
from routes.reports import employee_bp
import logging
from dotenv import load_dotenv
from werkzeug.exceptions import BadRequest
@ -142,4 +143,4 @@ if __name__ == "__main__":
with app.app_context():
db.create_all() # Cria as tabelas
run_all_seeds()
app.run(debug=True, host="0.0.0.0", port=5001)
app.run(debug=True, host="0.0.0.0")

99
docs/reports/create.yml Normal file
View File

@ -0,0 +1,99 @@
tags:
- Relatórios de Horários
summary: Criar novo relatório de ponto
description: Registra um novo relatório de horário para um colaborador
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- employee_id
- entry_time
- exit_time
properties:
employee_id:
type: integer
description: ID do colaborador
example: 1
entry_time:
type: string
description: Horário de entrada
example: "08:05"
exit_time:
type: string
description: Horário de saída
example: "17:10"
date:
type: string
format: date
description: Data do relatório (opcional, padrão é data atual)
example: "2024-03-27"
status:
type: string
description: Status do relatório
enum: ['Regular', 'Atrasado', 'Saída Antecipada']
example: "Regular"
responses:
'201':
description: Relatório criado com sucesso
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Relatório criado com sucesso"
report_id:
type: integer
example: 10
'400':
description: Requisição inválida
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Dados do relatório inválidos"
'401':
description: Não autorizado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Token de autenticação inválido"
'404':
description: Colaborador não encontrado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Colaborador não encontrado"
'500':
description: Erro interno do servidor
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Erro ao processar a solicitação"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT

60
docs/reports/delete.yml Normal file
View File

@ -0,0 +1,60 @@
tags:
- Relatórios de Horários
summary: Excluir relatório de ponto
description: Remove um relatório de horário específico
security:
- bearerAuth: []
parameters:
- in: path
name: report_id
required: true
schema:
type: integer
description: ID do relatório a ser excluído
responses:
'200':
description: Relatório excluído com sucesso
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Relatório deletado com sucesso"
'401':
description: Não autorizado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Token de autenticação inválido"
'404':
description: Relatório não encontrado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Relatório não encontrado"
'500':
description: Erro interno do servidor
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Erro ao processar a solicitação"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT

107
docs/reports/list.yml Normal file
View File

@ -0,0 +1,107 @@
tags:
- Relatórios de Horários
summary: Consulta de relatórios de ponto eletrônico
description: Recupera lista de todos os relatórios de horários dos colaboradores
security:
- bearerAuth: []
parameters:
- in: query
name: start_date
schema:
type: string
format: date
description: Data inicial para filtro de relatórios
- in: query
name: end_date
schema:
type: string
format: date
description: Data final para filtro de relatórios
- in: query
name: status
schema:
type: array
items:
type: string
enum: ['Regular', 'Atrasado', 'Saída Antecipada']
description: Filtro por status do relatório
responses:
'200':
description: Lista de relatórios recuperada com sucesso
content:
application/json:
schema:
type: array
items:
type: object
properties:
id:
type: integer
description: ID do relatório
example: 1
employee_name:
type: string
description: Nome do colaborador
example: "João Silva"
group:
type: string
description: Grupo/Departamento
example: "Drogasil"
contract_type:
type: string
description: Tipo de contrato
example: "Interno"
date:
type: string
format: date
description: Data do relatório
example: "2024-03-27"
entry_time:
type: string
description: Horário de entrada
example: "08:05"
exit_time:
type: string
description: Horário de saída
example: "17:10"
status:
type: string
description: Status do relatório
enum: ['Regular', 'Atrasado', 'Saída Antecipada']
example: "Atrasado"
'400':
description: Requisição inválida
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Parâmetros de filtro inválidos"
'401':
description: Não autorizado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Token de autenticação inválido"
'500':
description: Erro interno do servidor
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Erro ao processar a solicitação"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT

90
docs/reports/update.yml Normal file
View File

@ -0,0 +1,90 @@
tags:
- Relatórios de Horários
summary: Atualizar relatório de ponto
description: Atualiza um relatório de horário existente
security:
- bearerAuth: []
parameters:
- in: path
name: report_id
required: true
schema:
type: integer
description: ID do relatório a ser atualizado
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
entry_time:
type: string
description: Novo horário de entrada
example: "08:10"
exit_time:
type: string
description: Novo horário de saída
example: "17:15"
status:
type: string
description: Novo status do relatório
enum: ['Regular', 'Atrasado', 'Saída Antecipada']
example: "Atrasado"
responses:
'200':
description: Relatório atualizado com sucesso
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Relatório atualizado com sucesso"
'400':
description: Requisição inválida
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Dados de atualização inválidos"
'401':
description: Não autorizado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Token de autenticação inválido"
'404':
description: Relatório não encontrado
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Relatório não encontrado"
'500':
description: Erro interno do servidor
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: "Erro ao processar a solicitação"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT

22
models/reports.py Normal file
View File

@ -0,0 +1,22 @@
from extensions import db
from sqlalchemy import Column, Integer, String, DateTime, Float, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime
class Employee(db.Model):
__tablename__ = 'employee'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(80), unique=True, nullable=True)
email = db.Column(db.String(120), unique=True, nullable=False)
group = db.Column(db.String(80), unique=True, nullable=True)
contract_type = db.Column(db.String(80), unique=True, nullable=False)
date = db.Column(db.Date, nullable=True)
expected_entry_time = db.Column(db.DateTime, nullable=False)
expected_exit_time = db.Column(db.DateTime, nullable=False)
# Relacionamento hierárquico
parent_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True)
def __repr__(self):
return f"<Employee {self.name}>"

134
routes/reports.py Normal file
View File

@ -0,0 +1,134 @@
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required
from flasgger.utils import swag_from
from models.reports import Employee
from models.user import db,User
employee_bp = Blueprint('employee', __name__, url_prefix='/employee')
@employee_bp.route('/', methods=['POST'])
@jwt_required()
@swag_from('../docs/reports/create.yml')
def create_employee():
name = data.get('name')
group = data.get('group')
contract = data.get('contract')
data = request.get_json()
entry = data.get('entry')
exit = data.get('exit')
status = data.get('status')
# Cria um novo ServiceRole
employee = Employee(
id = 1,
name = name,
group = group,
contract = contract,
data = data,
entry = entry,
exit = exit,
status = status
)
# Adiciona e comita no banco de dados
db.session.add(employee)
db.session.commit()
return jsonify({'message': 'employee criado com sucesso', 'employee_id': employee.id}), 201
@employee_bp.route('/', methods=['GET'])
@jwt_required()
@swag_from('../docs/reports/list.yml')
def list_employee():
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 10, type=int)
pagination = Employee.query.paginate(page=page, per_page=per_page, error_out=False)
employee = pagination.items
return jsonify({
'employee': [
{
'id': employee.service_id,
'name': employee.name,
'group': employee.group,
'contract': employee.contract,
'data': employee.data,
'entry': employee.entry,
'exit': employee.exit,
'status': employee.status
} for employee in employee
],
'total': pagination.total,
'page': pagination.page,
'per_page': pagination.per_page
}), 200
@employee_bp.route('/<int:employee_id>', methods=['GET'])
@jwt_required()
@swag_from('../docs/reports/get.yml')
def get_employee(employee_id):
employee = Employee.query.get(employee_id)
if not employee:
return jsonify({'error': 'Relatório não encontrada'}), 404
return jsonify({
'id': employee.service_id,
'name': employee.name,
'group': employee.group,
'contract': employee.contract,
'data': employee.data,
'entry': employee.entry,
'exit': employee.exit,
'status': employee.status
}), 200
@employee_bp.route('/<int:employee_id>', methods=['PUT'])
@jwt_required()
@swag_from('../docs/reports/update.yml')
def update_employee(employee_id):
name = data.get('name')
group = data.get('group')
contract = data.get('contract')
data = request.get_json()
entry = data.get('entry')
exit = data.get('exit')
status = data.get('status')
employee = Employee.query.get(employee_id)
if not employee:
return jsonify({'error': 'Relatório não encontrado'}), 404
# Atualiza os campos fornecidos
if name:
employee.name = name
if group:
employee.group = group
if contract:
employee.contract = contract
if data:
employee.data = data
if entry:
employee.entry = entry
if exit:
employee.name = exit
if status:
employee.name = status
db.session.commit()
return jsonify({'message': 'Relatório atualizado com sucesso', 'employee_id': employee.id}), 200
@employee_bp.route('/<int:employee_id>', methods=['DELETE'])
@jwt_required()
@swag_from('../docs/reports/delete.yml')
def delete_employee(employee_id):
employee = Employee.query.get(employee_id)
if not employee:
return jsonify({'error': 'Relatório não encontrado'}), 404
db.session.delete(employee)
db.session.commit()
return jsonify({'message': 'Relatório deletado com sucesso'}), 200

96
seeds/reports_seed.py Normal file
View File

@ -0,0 +1,96 @@
from extensions import db
from models.reports import Employee
def reports_seed():
employee = [
# Usuário 1
{
"parent_id": 1,
"name":'João Silva',
"group":'Drogasil',
"contract_type":'Interno',
"expected_entry_time":'08:00',
"expected_exit_time":'17:00',
"status":'Ausente'
},
# Usuário 2
{
"parent_id": 2,
"name":'João Silva',
"group":'Drogasil',
"contract_type":'Interno',
"expected_entry_time":'08:00',
"expected_exit_time":'17:00',
"status":'Ausente'
},
# Usuário 3
{
"parent_id": 3,
"name":'João Silva',
"group":'Drogasil',
"contract_type":'Interno',
"expected_entry_time":'08:00',
"expected_exit_time":'17:00',
"status":'Ausente'
},
# Usuário 4
{
"parent_id": 4,
"name":'João Silva',
"group":'Drogasil',
"contract_type":'Interno',
"expected_entry_time":'08:00',
"expected_exit_time":'17:00',
"status":'Ausente'
},
# Usuário 5
{
"parent_id": 5,
"name":'João Silva',
"group":'Drogasil',
"contract_type":'Interno',
"expected_entry_time":'08:00',
"expected_exit_time":'17:00',
"status":'Ausente'
},
# Usuário 6
{
"parent_id": 6,
"name":'João Silva',
"group":'Drogasil',
"contract_type":'Interno',
"expected_entry_time":'08:00',
"expected_exit_time":'17:00',
"status":'Ausente'
},
]
for employee_data in employee:
# Verifica se já existe um papel para o service_id e name fornecidos
existing_employee = db.session.query(Employee).filter_by(
name=employee_data["name"],
group=employee_data["group"],
contract=employee_data["contract"],
data=employee_data["data"],
entry=employee_data["entry"],
exit=employee_data["exit"],
status=employee_data["status"]
).first()
# Se não existe, cria o novo papel
if not existing_employee:
employee = Employee(
name=employee_data["name"],
group=employee_data["group"],
contract=employee_data["contract"],
data=employee_data["data"],
entry=employee_data["entry"],
exit=employee_data["exit"],
status=employee_data["status"]
)
db.session.add(employee)
# Commit a transação para salvar os dados no banco
db.session.commit()

View File

@ -12,6 +12,7 @@ from .user_service_roles import seed_user_service_roles
from .services_seed import seed_services
from .camera_seed import seed_cameras
from .ambiente_seed import seed_ambiente
from .reports_seed import reports_seed
from extensions import db
@ -31,6 +32,7 @@ def run_all_seeds():
seed_licenses()
seed_cameras()
seed_ambiente()
reports_seed()
print("Seeds executados com sucesso!")
except Exception as e:
db.session.rollback()

View File

@ -58,20 +58,6 @@ def seed_service_roles():
"name": "Admin",
"description": "Coordenador de plataforma."
},
# Disciplinas Role: Coordenador de Disciplinas
#{
# "service_id": 1,
# "name": "Disciplinas",
# "description": "Coordenador de disciplinas com acesso para atribuir professores às disciplinas e controlar o conteúdo programático de cada matéria."
#},
# Professores Role: Professor
#{
# "service_id": 1,
# "name": "Professores",
# "description": "Professor com acesso para lecionar disciplinas, criar e corrigir provas e acompanhar o desempenho dos alunos nas suas matérias."
#},
]
# Verificar se o role já existe antes de criar