atualização relatorios
This commit is contained in:
parent
8c502c8b09
commit
3d6821682b
3
app.py
3
app.py
@ -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
99
docs/reports/create.yml
Normal 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
60
docs/reports/delete.yml
Normal 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
107
docs/reports/list.yml
Normal 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
90
docs/reports/update.yml
Normal 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
22
models/reports.py
Normal 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
134
routes/reports.py
Normal 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
96
seeds/reports_seed.py
Normal 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()
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user