From 9daa2ea31730039c0bf1121b4e3a394e99443f4d Mon Sep 17 00:00:00 2001 From: flavia-vic Date: Wed, 30 Apr 2025 11:17:36 -0400 Subject: [PATCH 1/3] Enhance Shift and TimeSchedule models with additional fields and relationships; update shift creation and update routes to handle new attributes and associations. --- models/shifts.py | 31 ++++++++++++++-------- models/time_schedule.py | 10 +++----- routes/shift.py | 57 ++++++++++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/models/shifts.py b/models/shifts.py index 2ef616c..216bf2c 100644 --- a/models/shifts.py +++ b/models/shifts.py @@ -2,28 +2,39 @@ from datetime import datetime from sqlalchemy import Column, Integer, String, ForeignKey, Time from sqlalchemy.orm import relationship from extensions import db +from models.time_schedule import TimeSchedule # Certo! + +# 🔗 Tabela de associação many-to-many +shift_time_schedule = db.Table( + 'shift_time_schedule', + db.Column('shift_id', db.Integer, db.ForeignKey('shift.id'), primary_key=True), + db.Column('time_schedule_id', db.Integer, db.ForeignKey('time_schedules.id'), primary_key=True) +) class Shift(db.Model): __tablename__ = 'shift' - + id = db.Column(db.Integer, primary_key=True) - service_instance_id = db.Column(db.Integer, db.ForeignKey('service_instance.id'), nullable=False) # Relaciona com ServiceInstance - name = db.Column(db.String(50), nullable=False) # Nome do turno (Manhã, Tarde, etc.) - - day = db.Column(db.String(20), nullable=False) # Ex: Segunda, Terça + service_instance_id = db.Column(db.Integer, db.ForeignKey('service_instance.id'), nullable=False) + name = db.Column(db.String(50), nullable=False) start_time = db.Column(db.Time, nullable=False) end_time = db.Column(db.Time, nullable=False) - interval_start = db.Column(db.Time, nullable=True) interval_end = db.Column(db.Time, nullable=True) - type_interval = db.Column(db.String(50), nullable=False) + description = db.Column(db.String(255), nullable=True) # Descrição do turno + tolerance = db.Column(db.Integer, nullable=True) # Tolerância em minutos - # Relacionamento com o modelo TimeSchedule - time_schedules = db.relationship('TimeSchedule', backref='shifts', lazy=True) + # 🗓️ Relacionamento com os dias (TimeSchedule usados como dias da semana) + time_schedules = db.relationship( + 'TimeSchedule', + secondary=shift_time_schedule, + backref='shifts', + lazy='subquery' + ) - # Relacionamento com o modelo Record, utilizando a chave estrangeira corretamente + # Relacionamento com records records = db.relationship("Record", back_populates="shifts", lazy=True) def __repr__(self): diff --git a/models/time_schedule.py b/models/time_schedule.py index b11de24..401f608 100644 --- a/models/time_schedule.py +++ b/models/time_schedule.py @@ -4,13 +4,11 @@ from datetime import datetime # Modelo para TimeSchedule (Horários dentro de um turno) class TimeSchedule(db.Model): __tablename__ = 'time_schedules' - + id = db.Column(db.Integer, primary_key=True) - shift_id = db.Column(db.Integer, db.ForeignKey('shift.id'), nullable=False) # Relaciona com Shift - start_time = db.Column(db.Time, nullable=False) # Hora de início do time slot - end_time = db.Column(db.Time, nullable=False) # Hora de término do time slot - description = db.Column(db.String(255)) # Descrição do time schedule (ex: 'Almoço') + name = db.Column(db.String(20), nullable=False, unique=True) # Ex: Segunda, Terça, etc. records = db.relationship("Record", back_populates="schedule") + def __repr__(self): - return f'' \ No newline at end of file + return f'' diff --git a/routes/shift.py b/routes/shift.py index 545ef6b..07aaec8 100644 --- a/routes/shift.py +++ b/routes/shift.py @@ -2,31 +2,36 @@ from flask import Blueprint, request, jsonify from flasgger.utils import swag_from from models.shifts import Shift, db from models.service_instance import ServiceInstance +from models.time_schedule import TimeSchedule shift_bp = Blueprint('shift', __name__, url_prefix='/shift/') # Criar um turno @shift_bp.route('/', methods=['POST']) -@swag_from('../docs/shifts/create.yml') def create_shift(): - """Cria um novo turno.""" data = request.get_json() - # Verifica se a service_instance existe service_instance_id = data.get('service_instance_id') ServiceInstance.query.get_or_404(service_instance_id) # Cria o turno shift = Shift( name=data['name'], - day=data['day'], start_time=data['start_time'], end_time=data['end_time'], - interval_start=data['interval_start'], - interval_end=data['interval_end'], + interval_start=data.get('interval_start'), + interval_end=data.get('interval_end'), type_interval=data['type_interval'], - service_instance_id=data['service_instance_id'] + service_instance_id=service_instance_id, + description=data.get('description'), # Adicionando a descrição + tolerance=data.get('tolerance'), # Adicionando a tolerância ) + + # Associa os dias (TimeSchedules) + time_schedule_ids = data.get('time_schedule_ids', []) + if time_schedule_ids: + shift.time_schedules = TimeSchedule.query.filter(TimeSchedule.id.in_(time_schedule_ids)).all() + db.session.add(shift) db.session.commit() @@ -39,34 +44,45 @@ def create_shift(): def update_shift(shift_id): """Atualiza um turno existente.""" data = request.get_json() - print(data) + # Localiza o turno ou retorna 404 shift = Shift.query.get_or_404(shift_id) # Atualiza os campos fornecidos no body if 'name' in data: shift.name = data['name'] - if 'day' in data: - shift.days = data['day'] - if 'start_time' in data: + if 'start_time' in data: shift.start_time = data['start_time'] if 'end_time' in data: - shift.end_time=data['end_time'] + shift.end_time = data['end_time'] if 'interval_start' in data: - shift.interval_start=data['interval_start'] + shift.interval_start = data['interval_start'] if 'interval_end' in data: - shift.interval_end=data['interval_end'] + shift.interval_end = data['interval_end'] if 'type_interval' in data: - shift.type_interval=data['type_interval'] + shift.type_interval = data['type_interval'] + if 'description' in data: + shift.description = data['description'] + if 'tolerance' in data: + shift.tolerance = data['tolerance'] if 'service_instance_id' in data: ServiceInstance.query.get_or_404(data['service_instance_id']) # Valida a existência shift.service_instance_id = data['service_instance_id'] + # Atualiza os dias (TimeSchedules) + if 'time_schedule_ids' in data: + # Recebe a lista de IDs dos dias a serem associados ao turno + time_schedule_ids = data['time_schedule_ids'] + # Verifica se os IDs existem no banco e atualiza a associação + shift.time_schedules = TimeSchedule.query.filter(TimeSchedule.id.in_(time_schedule_ids)).all() + db.session.commit() + return jsonify({'message': 'Shift updated successfully'}), 200 + # Listar turnos @shift_bp.route('/', methods=['GET']) @swag_from('../docs/shifts/list.yml') @@ -84,17 +100,22 @@ def list_shifts(): shift_list = [{ 'id': shift.id, 'name': shift.name, - 'day': shift.day, "start_time": shift.start_time.strftime("%H:%M"), "end_time": shift.end_time.strftime("%H:%M"), "interval_start": shift.interval_start.strftime("%H:%M") if shift.interval_start else None, "interval_end": shift.interval_end.strftime("%H:%M") if shift.interval_end else None, - 'type_interval' : shift.type_interval, - 'service_instance_id': shift.service_instance_id + 'type_interval': shift.type_interval, + 'service_instance_id': shift.service_instance_id, + + # Adicionando os dias associados (TimeSchedules) + 'time_schedules': [ + {'id': ts.id, 'name': ts.name} for ts in shift.time_schedules + ] } for shift in shifts] return jsonify(shift_list), 200 + @shift_bp.route('/', methods=['GET']) @swag_from('../docs/shifts/get.yml') def get_shift_id(shift_id): From 1bf175d1101cb854ea93380e7aadb92578a316ad Mon Sep 17 00:00:00 2001 From: flavia-vic Date: Wed, 30 Apr 2025 14:40:02 -0400 Subject: [PATCH 2/3] Add description and tolerance fields to shift listing response --- routes/shift.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/routes/shift.py b/routes/shift.py index 07aaec8..2889460 100644 --- a/routes/shift.py +++ b/routes/shift.py @@ -106,6 +106,9 @@ def list_shifts(): "interval_end": shift.interval_end.strftime("%H:%M") if shift.interval_end else None, 'type_interval': shift.type_interval, 'service_instance_id': shift.service_instance_id, + 'description': shift.description, # Adicionando a descrição + 'tolerance': shift.tolerance, # Adicionando a tolerância + # Adicionando os dias associados (TimeSchedules) 'time_schedules': [ From 5ff5146889f7baca1a6f74da873a978e36019d48 Mon Sep 17 00:00:00 2001 From: flavia-vic Date: Wed, 30 Apr 2025 14:46:40 -0400 Subject: [PATCH 3/3] Add time schedule seeding functionality to populate days of the week --- seeds/run_seed.py | 36 +++++++++++++++++++----------------- seeds/time_schedule.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 17 deletions(-) create mode 100644 seeds/time_schedule.py diff --git a/seeds/run_seed.py b/seeds/run_seed.py index a1fdfd8..fe26a91 100644 --- a/seeds/run_seed.py +++ b/seeds/run_seed.py @@ -16,30 +16,32 @@ from .reports_seed import reports_seed from .shifts_times_seed import seed_shifts_and_schedules from .holiday_seed import seed_holiday from .company_seed import seed_company +from .time_schedule import seed_time_schedules from extensions import db def run_all_seeds(): try: print("Iniciando o processo de seed...") - seed_services() - seed_holiday() - seed_service_instances() - seed_company() - seed_permissions() - seed_service_roles() - seed_service_role_permissions() - seed_users() - seed_address_types() - seed_address() + # seed_services() + # seed_holiday() + # seed_service_instances() + # seed_company() + # seed_permissions() + # seed_service_roles() + # seed_service_role_permissions() + # seed_users() + # seed_address_types() + # seed_address() #seed_contacts() - seed_user_service_roles() - seed_licenses() - seed_ambiente() - reports_seed() - seed_cameras() - seed_shifts_and_schedules() - seed_holiday() + # seed_user_service_roles() + # seed_licenses() + # seed_ambiente() + # reports_seed() + # seed_cameras() + # seed_shifts_and_schedules() + # seed_holiday() + seed_time_schedules() print("Seeds executados com sucesso!") except Exception as e: diff --git a/seeds/time_schedule.py b/seeds/time_schedule.py new file mode 100644 index 0000000..4d621aa --- /dev/null +++ b/seeds/time_schedule.py @@ -0,0 +1,30 @@ +from extensions import db +from models.time_schedule import TimeSchedule + +def seed_time_schedules(): + # Lista de dias da semana + days = [ + {"id": 1, "name": "Domingo"}, + {"id": 2, "name": "Segunda-feira"}, + {"id": 3, "name": "Terça-feira"}, + {"id": 4, "name": "Quarta-feira"}, + {"id": 5, "name": "Quinta-feira"}, + {"id": 6, "name": "Sexta-feira"}, + {"id": 7, "name": "Sábado"}, + ] + + # Verifica se já existe algum dia na tabela + existing_days = TimeSchedule.query.all() + existing_names = [day.name for day in existing_days] + + for day in days: + if day["name"] in existing_names: + print(f"Dia '{day['name']}' já existe. Pulando...") + continue + + # Cria e adiciona o dia + new_day = TimeSchedule(id=day["id"], name=day["name"]) + db.session.add(new_day) + + db.session.commit() + print("Dias da semana criados com sucesso, se não existirem.")