Start refactoring person overview (list) page, currently is accessible through tags and workout exercise select. Doesnt have any stats or graphs
This commit is contained in:
164
features/person_overview.py
Normal file
164
features/person_overview.py
Normal file
@@ -0,0 +1,164 @@
|
||||
|
||||
class PersonOverview:
|
||||
def __init__(self, db_connection_method):
|
||||
self.execute = db_connection_method
|
||||
|
||||
def get_earliest_and_latest_workout_dates(self, person_id):
|
||||
sql_query = """
|
||||
SELECT
|
||||
MIN(w.start_date) AS earliest_date,
|
||||
MAX(w.start_date) AS latest_date
|
||||
FROM workout w
|
||||
INNER JOIN topset t ON w.workout_id = t.workout_id
|
||||
WHERE w.person_id = %s;
|
||||
"""
|
||||
result = self.execute(sql_query, [person_id])
|
||||
|
||||
if not result or not result[0]:
|
||||
return None, None
|
||||
|
||||
return result[0]['earliest_date'], result[0]['latest_date']
|
||||
|
||||
def list_of_performed_exercise_ids(self, person_id, min_date, max_date):
|
||||
sql_query = """
|
||||
SELECT
|
||||
ARRAY_AGG(DISTINCT e.exercise_id) AS exercise_ids
|
||||
FROM workout w
|
||||
LEFT JOIN topset t ON w.workout_id = t.workout_id
|
||||
LEFT JOIN exercise e ON t.exercise_id = e.exercise_id
|
||||
WHERE w.start_date BETWEEN %s AND %s
|
||||
AND w.person_id = %s
|
||||
"""
|
||||
result = self.execute(sql_query, [min_date, max_date, person_id])
|
||||
|
||||
if not result or not result[0]:
|
||||
return []
|
||||
|
||||
return result[0]['exercise_ids']
|
||||
|
||||
def get_exercises_with_selection(self, person_id, start_date, end_date, selected_exercise_ids):
|
||||
# SQL query to fetch all exercises performed by the person in the given time range
|
||||
sql_query = """
|
||||
SELECT DISTINCT
|
||||
e.exercise_id,
|
||||
e.name AS exercise_name
|
||||
FROM
|
||||
workout w
|
||||
JOIN
|
||||
topset t ON w.workout_id = t.workout_id
|
||||
JOIN
|
||||
exercise e ON t.exercise_id = e.exercise_id
|
||||
WHERE
|
||||
w.person_id = %s
|
||||
AND w.start_date BETWEEN %s AND %s
|
||||
ORDER BY
|
||||
e.name ASC;
|
||||
"""
|
||||
|
||||
# Execute the query with parameters
|
||||
result = self.execute(sql_query, [person_id, start_date, end_date])
|
||||
|
||||
if not result:
|
||||
return [] # No exercises found in the given time range
|
||||
|
||||
# Add the "selected" property to each exercise
|
||||
exercises = []
|
||||
for row in result:
|
||||
exercises.append({
|
||||
"id": row["exercise_id"],
|
||||
"name": row["exercise_name"],
|
||||
"selected": row["exercise_id"] in selected_exercise_ids
|
||||
})
|
||||
|
||||
return exercises
|
||||
|
||||
|
||||
def get(self, person_id, start_date, end_date, selected_exercise_ids):
|
||||
# Build placeholders for exercise IDs
|
||||
placeholders = ", ".join(["%s"] * len(selected_exercise_ids))
|
||||
|
||||
# Dynamically inject placeholders into the query
|
||||
sql_query = f"""
|
||||
SELECT
|
||||
p.person_id,
|
||||
p.name AS person_name,
|
||||
w.workout_id,
|
||||
w.start_date,
|
||||
w.note AS workout_note,
|
||||
e.exercise_id,
|
||||
e.name AS exercise_name,
|
||||
t.topset_id,
|
||||
t.repetitions,
|
||||
t.weight
|
||||
FROM
|
||||
person p
|
||||
JOIN
|
||||
workout w ON p.person_id = w.person_id
|
||||
JOIN
|
||||
topset t ON w.workout_id = t.workout_id
|
||||
JOIN
|
||||
exercise e ON t.exercise_id = e.exercise_id
|
||||
WHERE
|
||||
p.person_id = %s
|
||||
AND w.start_date BETWEEN %s AND %s
|
||||
AND e.exercise_id IN ({placeholders})
|
||||
ORDER BY
|
||||
w.start_date DESC, e.exercise_id ASC, t.topset_id ASC;
|
||||
"""
|
||||
|
||||
# Add parameters for the query
|
||||
params = [person_id, start_date, end_date] + selected_exercise_ids
|
||||
result = self.execute(sql_query, params)
|
||||
|
||||
if not result:
|
||||
return {"person_id": person_id, "person_name": None, "workouts": [], "selected_exercises": []}
|
||||
|
||||
# Extract person info from the first row
|
||||
person_info = {"person_id": result[0]["person_id"], "person_name": result[0]["person_name"]}
|
||||
|
||||
# Extract and sort all unique exercises by name
|
||||
exercises = []
|
||||
unique_exercise_ids = set()
|
||||
for row in result:
|
||||
if row["exercise_id"] not in unique_exercise_ids:
|
||||
unique_exercise_ids.add(row["exercise_id"])
|
||||
exercises.append({"id": row["exercise_id"], "name": row["exercise_name"]})
|
||||
|
||||
# Sort the exercises by name
|
||||
exercises = sorted(exercises, key=lambda ex: ex["name"])
|
||||
|
||||
# Initialize the table structure
|
||||
workouts = []
|
||||
workout_map = {} # Map to track workouts
|
||||
|
||||
for row in result:
|
||||
workout_id = row["workout_id"]
|
||||
|
||||
# Initialize the workout if not already present
|
||||
if workout_id not in workout_map:
|
||||
workout_map[workout_id] = {
|
||||
"id": workout_id,
|
||||
"start_date": row["start_date"],
|
||||
"note": row["workout_note"],
|
||||
"exercises": {exercise["id"]: [] for exercise in exercises} # Keyed by exercise_id
|
||||
}
|
||||
|
||||
# Add topset to the corresponding exercise
|
||||
if row["exercise_id"] and row["topset_id"]:
|
||||
workout_map[workout_id]["exercises"][row["exercise_id"]].append({
|
||||
"repetitions": row["repetitions"],
|
||||
"weight": row["weight"]
|
||||
})
|
||||
|
||||
# Transform into a list of rows
|
||||
for workout_id, workout in workout_map.items():
|
||||
workouts.append(workout)
|
||||
|
||||
return {**person_info, "workouts": workouts, "selected_exercises": exercises}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user