From a71c9c5058287a447c7ac4e785973586553b5bbb Mon Sep 17 00:00:00 2001
From: Aymeric Chaumont <aymeric.chaumont@student-cs.fr>
Date: Fri, 8 Jul 2022 17:04:09 +0200
Subject: [PATCH] changed some model types and made the waiting_time route
 time-dependent

---
 backend/db/crud.py               | 59 +++++++++++++++++++++++++-------
 backend/db/models.py             | 10 +++---
 backend/db/schemas.py            |  8 ++---
 backend/routers/opening_hours.py |  6 ++--
 backend/routers/stats.py         | 12 +++----
 5 files changed, 61 insertions(+), 34 deletions(-)

diff --git a/backend/db/crud.py b/backend/db/crud.py
index 5bff687..f414924 100644
--- a/backend/db/crud.py
+++ b/backend/db/crud.py
@@ -13,11 +13,38 @@ from db import models, schemas
 
 def get_waiting_time(place: str, db: Session):
     """ Get the last estimated waiting time for the given place """
-    db_record = db.query(models.Records).filter(models.Records.place == place).order_by(models.Records.date.desc()).first()
-    return db_record.waiting_time
+    date = datetime.now(tz=pytz.timezone("Europe/Paris"))
+    weekday, current_time = date.weekday(), date.time()
+    first_timeslot = get_timeslot(place, weekday, True, db)
+    if first_timeslot and current_time < first_timeslot[0]:
+        return first_timeslot[0].hour, first_timeslot[0].minute
+    elif first_timeslot and current_time <= first_timeslot[1]:
+        waiting_time = db.query(
+            models.Records.waiting_time
+        ).filter(
+            models.Records.place == place
+        ).order_by(
+            models.Records.date.desc()
+        ).first()
+        waiting_time_minutes = round(waiting_time[0].total_seconds() / 60)
+        return waiting_time_minutes, None
+    second_timeslot = get_timeslot(place, weekday, False, db)
+    if second_timeslot and current_time < second_timeslot[0]:
+        return second_timeslot[0].hour, second_timeslot[0].minute
+    elif second_timeslot and current_time <= second_timeslot[1]:
+        waiting_time = db.query(
+            models.Records.waiting_time
+        ).filter(
+            models.Records.place == place
+        ).order_by(
+            models.Records.date.desc()
+        ).first()
+        waiting_time_minutes = round(waiting_time[0].total_seconds() / 60)
+        return waiting_time_minutes, None
+    return None, None
 
 
-def get_stats(place: str, weekday: int, min_time_hour: int, min_time_mn: int, max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session):
+def get_stats(place: str, weekday: int, min_time: time, max_time: time, interval: timedelta, db: Session):
     """ Get the average waiting time for each interval between two time steps """
 
     def shift_time(t: time, delta: timedelta):
@@ -51,7 +78,6 @@ def get_stats(place: str, weekday: int, min_time_hour: int, min_time_mn: int, ma
             name = f'{start_time.hour:02}h{start_time.minute:02}'
             slots_list.append({'name': name, 'time': average_waiting_time})
 
-    min_time, max_time = time(min_time_hour, min_time_mn), time(max_time_hour, max_time_mn)
     stats = []
     start_time, end_time = min_time, shift_time(min_time, interval)
     while start_time < max_time:
@@ -132,27 +158,34 @@ def delete_news(id: int, db: Session):
 def get_opening_hours(place: str, db: Session):
     """ Get the opening hours for the given place """
     opening_hours = db.query(
-        models.OpeningHours
-        ).filter(
-            models.OpeningHours.place == place
-        ).order_by(
-            models.OpeningHours.day, models.OpeningHours.timeslot.desc()
-        ).all()
+        models.OpeningHours.day,
+        models.OpeningHours.timeslot,
+        models.OpeningHours.open_time,
+        models.OpeningHours.close_time,
+    ).filter(
+        models.OpeningHours.place == place
+    ).order_by(
+        models.OpeningHours.day, models.OpeningHours.timeslot.desc()
+    ).all()
     return opening_hours
 
 
 def get_timeslot(place: str, day: int, timeslot: bool, db: Session):
     """ Get the opening hours for the given place and timeslot"""
-    opening_hours = db.query(models.OpeningHours).filter(
+    opening_hours = db.query(
+        models.OpeningHours.open_time,
+        models.OpeningHours.close_time,
+    ).filter(
         models.OpeningHours.place == place,
         models.OpeningHours.day == day,
-        models.OpeningHours.timeslot == timeslot).first()
+        models.OpeningHours.timeslot == timeslot
+    ).first()
     return opening_hours
 
 
 def create_opening_hours(new_opening_hours: schemas.OpeningHoursBase, db: Session):
     """ Add opening hours to the database """
-    db_opening_hours = models.News(**new_opening_hours.dict())
+    db_opening_hours = models.OpeningHours(**new_opening_hours.dict())
     db.add(db_opening_hours)
     db.commit()
     db.refresh(db_opening_hours)
diff --git a/backend/db/models.py b/backend/db/models.py
index 58c3afa..ebc4048 100644
--- a/backend/db/models.py
+++ b/backend/db/models.py
@@ -1,7 +1,7 @@
 """
 Models of the database for magasin app
 """
-from sqlalchemy import Column, Integer, DateTime, Float, Interval, String, Text, Boolean
+from sqlalchemy import Column, Integer, DateTime, Float, Interval, String, Text, Boolean, Time
 
 from db.database import Base
 
@@ -45,9 +45,7 @@ class OpeningHours(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     place = Column(String(10))
-    day= Column(Integer)
+    day = Column(Integer)
     timeslot = Column(Boolean)
-    open_hour = Column(Integer)
-    open_minute = Column(Integer)
-    close_hour = Column(Integer)
-    close_minute = Column(Integer)
+    open_time = Column(Time)
+    close_time = Column(Time)
diff --git a/backend/db/schemas.py b/backend/db/schemas.py
index 474dd94..5af670e 100644
--- a/backend/db/schemas.py
+++ b/backend/db/schemas.py
@@ -2,7 +2,7 @@
 Pydantic schemas for the magasin app
 """
 from typing import Optional
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, time
 from pydantic import BaseModel, Field
 
 
@@ -59,10 +59,8 @@ class OpeningHoursBase(BaseModel):
     place: str = Field(..., title="Name of the RU corresponding the given record")
     day: int = Field(..., title="Day of the week")
     timeslot: bool = Field(..., title="Service slot (True for midday, False for evening)")
-    open_hour: int = Field(..., title="Hour of the opening time")
-    open_minute: int = Field(..., title="Minute of the opening time")
-    close_hour: int = Field(..., title="Hour of the closing time")
-    close_minute: int = Field(..., title="Minute of the closing time")
+    open_time: time = Field(..., title="Opening time")
+    close_time: time = Field(..., title="Closing time")
 
 
 class OpeningHours(OpeningHoursBase):
diff --git a/backend/routers/opening_hours.py b/backend/routers/opening_hours.py
index 6362d1c..230d0df 100644
--- a/backend/routers/opening_hours.py
+++ b/backend/routers/opening_hours.py
@@ -19,9 +19,9 @@ async def get_timeslot(place: str, day: int, timeslot: bool, db: Session = Depen
     return crud.get_timeslot(place, day, timeslot, db)
 
 
-@router.post('/{place}/opening_hours', response_model=schemas.OpeningHours)
-async def create_opening_hours(place: str, opening_hours: schemas.OpeningHoursBase, db: Session = Depends(get_db)):
-    return crud.create_opening_hours(place, opening_hours, db)
+@router.post('/opening_hours', response_model=schemas.OpeningHours)
+async def create_opening_hours(opening_hours: schemas.OpeningHoursBase, db: Session = Depends(get_db)):
+    return crud.create_opening_hours(opening_hours, db)
 
 
 @router.delete('/opening_hours/{id}', response_model=None)
diff --git a/backend/routers/stats.py b/backend/routers/stats.py
index 092a062..b388793 100644
--- a/backend/routers/stats.py
+++ b/backend/routers/stats.py
@@ -1,7 +1,6 @@
 from fastapi import APIRouter, Depends
 from sqlalchemy.orm import Session
-from datetime import timedelta
-from typing import List
+from datetime import timedelta, time
 
 from db import crud
 from db.database import get_db
@@ -10,12 +9,11 @@ from db.database import get_db
 router = APIRouter(prefix="/api", tags=["stats"])
 
 
-@router.get('/{place}/waiting_time', response_model=timedelta)
+@router.get('/{place}/waiting_time', response_model=tuple)
 async def waiting_time(place: str, db: Session = Depends(get_db)):
     return crud.get_waiting_time(place, db)
 
 
-@router.get('/{place}/stats/{day}/{min_time_hour}/{min_time_mn}/{max_time_hour}/{max_time_mn}/{interval}', response_model=list)
-async def stats(place: str, day: int, min_time_hour: int, min_time_mn: int,
-                max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session = Depends(get_db)):
-    return crud.get_stats(place, day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval, db)
+@router.get('/{place}/stats/{day}/{min_time}/{max_time}/{interval}', response_model=list)
+async def stats(place: str, day: int, min_time: time, max_time: time, interval: timedelta, db: Session = Depends(get_db)):
+    return crud.get_stats(place, day, min_time, max_time, interval, db)
-- 
GitLab