From ab4076ffae576740ed724e4ded2443bd4bcd4c54 Mon Sep 17 00:00:00 2001 From: Sai Date: Wed, 3 Dec 2025 15:33:16 +0800 Subject: [PATCH] small change --- cron/backup.py | 77 ++++++-------- importer/importer.py | 60 +++++++++-- initialiser/initialiser.py | 105 ++++++------------- merger/merger.py | 14 ++- types.csv | 199 +++++++++++++++++-------------------- 5 files changed, 218 insertions(+), 237 deletions(-) diff --git a/cron/backup.py b/cron/backup.py index 2b74acd..6f3fbc4 100644 --- a/cron/backup.py +++ b/cron/backup.py @@ -29,7 +29,7 @@ def export_patient_data(): timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") output_path = backups_dir / f"{timestamp}_patientdata.csv" - # PostgreSQL export query + # PostgreSQL export query - Updated to match new backend schema query = f"""COPY (SELECT a.id, a.vid, @@ -47,7 +47,14 @@ def export_patient_data(): a.last_menstrual_period AS a_last_menstrual_period, a.drug_allergies AS a_drug_allergies, a.sent_to_id AS a_sent_to_id, + pmh.cough AS pmh_cough, + pmh.fever AS pmh_fever, + pmh.blocked_nose AS pmh_blocked_nose, + pmh.sore_throat AS pmh_sore_throat, + pmh.night_sweats AS pmh_night_sweats, + pmh.unintentional_weight_loss AS pmh_unintentional_weight_loss, pmh.tuberculosis AS pmh_tuberculosis, + pmh.tuberculosis_has_been_treated AS pmh_tuberculosis_has_been_treated, pmh.diabetes AS pmh_diabetes, pmh.hypertension AS pmh_hypertension, pmh.hyperlipidemia AS pmh_hyperlipidemia, @@ -74,62 +81,39 @@ def export_patient_data(): vs.hr2 AS vs_hr2, vs.avg_hr AS vs_avg_hr, vs.rand_blood_glucose_mmolL AS vs_rand_blood_glucose_mmoll, + vs.icope_high_bp AS vs_icope_high_bp, haw.height AS haw_height, haw.weight AS haw_weight, haw.bmi AS haw_bmi, haw.bmi_analysis AS haw_bmi_analysis, haw.paeds_height AS haw_paeds_height, haw.paeds_weight AS haw_paeds_weight, + haw.icope_lost_weight_past_months AS haw_icope_lost_weight_past_months, + haw.icope_no_desire_to_eat AS haw_icope_no_desire_to_eat, va.l_eye_vision AS va_l_eye_vision, va.r_eye_vision AS va_r_eye_vision, + va.sent_to_opto AS va_sent_to_opto, + va.referred_for_glasses AS va_referred_for_glasses, + va.icope_eye_problem AS va_icope_eye_problem, + va.icope_treated_for_diabetes_or_bp AS va_icope_treated_for_diabetes_or_bp, va.additional_intervention AS va_additional_intervention, - d.clean_teeth_freq AS d_clean_teeth_freq, - d.sugar_consume_freq AS d_sugar_consume_freq, - d.past_year_decay AS d_past_year_decay, - d.brush_teeth_pain AS d_brush_teeth_pain, + d.fluoride_exposure AS d_fluoride_exposure, + d.diet AS d_diet, + d.bacterial_exposure AS d_bacterial_exposure, + d.oral_symptoms AS d_oral_symptoms, d.drink_other_water AS d_drink_other_water, + d.risk_for_dental_carries AS d_risk_for_dental_carries, + d.icope_difficulty_chewing AS d_icope_difficulty_chewing, + d.icope_pain_in_mouth AS d_icope_pain_in_mouth, d.dental_notes AS d_dental_notes, - d.referral_needed AS d_referral_needed, - d.referral_loc AS d_referral_loc, - d.tooth_11 AS d_tooth_11, - d.tooth_12 AS d_tooth_12, - d.tooth_13 AS d_tooth_13, - d.tooth_14 AS d_tooth_14, - d.tooth_15 AS d_tooth_15, - d.tooth_16 AS d_tooth_16, - d.tooth_17 AS d_tooth_17, - d.tooth_18 AS d_tooth_18, - d.tooth_21 AS d_tooth_21, - d.tooth_22 AS d_tooth_22, - d.tooth_23 AS d_tooth_23, - d.tooth_24 AS d_tooth_24, - d.tooth_25 AS d_tooth_25, - d.tooth_26 AS d_tooth_26, - d.tooth_27 AS d_tooth_27, - d.tooth_28 AS d_tooth_28, - d.tooth_31 AS d_tooth_31, - d.tooth_32 AS d_tooth_32, - d.tooth_33 AS d_tooth_33, - d.tooth_34 AS d_tooth_34, - d.tooth_35 AS d_tooth_35, - d.tooth_36 AS d_tooth_36, - d.tooth_37 AS d_tooth_37, - d.tooth_38 AS d_tooth_38, - d.tooth_41 AS d_tooth_41, - d.tooth_42 AS d_tooth_42, - d.tooth_43 AS d_tooth_43, - d.tooth_44 AS d_tooth_44, - d.tooth_45 AS d_tooth_45, - d.tooth_46 AS d_tooth_46, - d.tooth_47 AS d_tooth_47, - d.tooth_48 AS d_tooth_48, - fr.fall_worries AS fr_fall_worries, - fr.fall_history AS fr_fall_history, - fr.cognitive_status AS fr_cognitive_status, - fr.continence_problems AS fr_continence_problems, - fr.safety_awareness AS fr_safety_awareness, - fr.unsteadiness AS fr_unsteadiness, + fr.side_to_side_balance AS fr_side_to_side_balance, + fr.semi_tandem_balance AS fr_semi_tandem_balance, + fr.tandem_balance AS fr_tandem_balance, + fr.gait_speed_test AS fr_gait_speed_test, + fr.chair_stand_test AS fr_chair_stand_test, fr.fall_risk_score AS fr_fall_risk_score, + fr.icope_complete_chair_stands AS fr_icope_complete_chair_stands, + fr.icope_chair_stands_time AS fr_icope_chair_stands_time, dc.well AS dc_well, dc.msk AS dc_msk, dc.cvs AS dc_cvs, @@ -153,8 +137,7 @@ def export_patient_data(): p.trouble_sleep_symptoms AS p_trouble_sleep_symptoms, p.how_much_fatigue AS p_how_much_fatigue, p.anxious_low_mood AS p_anxious_low_mood, - p.medication_manage_symptoms AS p_medication_manage_symptoms, - NULL AS a_photo + p.medication_manage_symptoms AS p_medication_manage_symptoms FROM admin a LEFT JOIN pastmedicalhistory pmh ON a.id = pmh.id AND a.vid = pmh.vid LEFT JOIN socialhistory sh ON a.id = sh.id AND a.vid = sh.vid diff --git a/importer/importer.py b/importer/importer.py index e800c1d..623217d 100644 --- a/importer/importer.py +++ b/importer/importer.py @@ -6,9 +6,9 @@ import pandas as pd from sqlalchemy.orm import sessionmaker +from sqlalchemy import create_engine, text from columns import Types -from sqlalchemy import create_engine from columns import CURRENT_DATABASE """ @@ -79,20 +79,66 @@ def processTable(self, df: pd.DataFrame, schema: dict, table_name: str) -> pd.Da def writeToDatabase(self, df: pd.DataFrame, table_name: str) -> None: """ - Write DataFrame to database using SQLAlchemy session. + Write DataFrame to database using UPSERT (INSERT ... ON CONFLICT UPDATE). + Updates existing records if (id, vid) exists, otherwise inserts new records. :param df: DataFrame to write :param table_name: Name of the table - :param session: SQLAlchemy session """ + if df.empty: + print(f"No data to write for table '{table_name}'.") + return + try: - # Use pandas to_sql method with if_exists='append' - df.to_sql(table_name, self.session.bind, if_exists='append', index=False) - print(f"Data for table '{table_name}' has been written to the database.") - self.session.commit() + # Get column names (SQL names, not CSV names) + columns = df.columns.tolist() + + # Build the INSERT ... ON CONFLICT UPDATE statement + # Primary key is always (id, vid) for all tables + placeholders = ', '.join([f':{col}' for col in columns]) + column_list = ', '.join(columns) + + # Build UPDATE clause: update all columns except id and vid + update_columns = [col for col in columns if col not in ['id', 'vid']] + update_clause = ', '.join([f'{col} = EXCLUDED.{col}' for col in update_columns]) + + # Construct the UPSERT SQL statement + sql = f""" + INSERT INTO {table_name} ({column_list}) + VALUES ({placeholders}) + ON CONFLICT (id, vid) + DO UPDATE SET {update_clause} + """ + + # Execute for each row in a transaction + connection = self.engine.connect() + trans = connection.begin() + try: + for _, row in df.iterrows(): + # Convert row to dict, handling NaN values + row_dict = {} + for col in columns: + value = row[col] + # Convert pandas NaN/NaT to None (SQL NULL) + if pd.isna(value): + row_dict[col] = None + else: + row_dict[col] = value + + connection.execute(text(sql), row_dict) + + trans.commit() + print(f"Data for table '{table_name}' has been written/updated successfully ({len(df)} rows).") + except Exception as e: + trans.rollback() + raise + finally: + connection.close() + except Exception as e: self.session.rollback() print(f"Error writing to table '{table_name}': {e}") + raise def importToDatabase(self): """ diff --git a/initialiser/initialiser.py b/initialiser/initialiser.py index ac343c0..da65ea6 100644 --- a/initialiser/initialiser.py +++ b/initialiser/initialiser.py @@ -1,4 +1,3 @@ -import glob import os import sys @@ -16,8 +15,8 @@ from columns import Types """ -Initialise an Excel workbook from the patientdata csv file with data validation rules, formatting, and dropdowns. -Takes csv files from patientdata_file_path and types from types_file_path. +Initialise an empty Excel workbook with data validation rules, formatting, and dropdowns. +Generates an empty DataSheet.xlsx with column headers based on types.csv. Places generated DataSheet.xlsx in the same directory as the script. """ class Initialiser: @@ -49,47 +48,24 @@ def initialise(self): def readCSV(self): """ - - Tries to find the latest backup CSV in self.csv_folder_path based on a naming convention. - - If no matching file is found, defaults to reading any CSV file in the directory. - - Reads the CSV file into a pandas DataFrame, renames its columns from CSV name -> DataSheet name, - and initializes the Excel workbook and worksheet. + - Generates an empty DataFrame with column headers based on types.csv + - Creates an empty Excel workbook with the correct column structure + - Initializes the Excel workbook and worksheet """ try: - try: - # Try to find the latest file matching the naming convention - file_pattern = os.path.join(self.csv_folder_path, "*_patientdata.csv") - files = glob.glob(file_pattern) - - if not files: - raise FileNotFoundError("No files matching the naming convention found.") - - # Extract the timestamp from filenames and sort them - files_with_timestamps = [ - (file, filename.split("_patientdata.csv")[0]) - for file in files - for filename in [os.path.basename(file)] - ] - latest_file = max(files_with_timestamps, key=lambda x: x[1])[0] - except Exception: - # Fallback: Read any CSV file in the directory - print( - "No files matching the naming convention. Falling back to any CSV file in the folder." - ) - all_files = glob.glob(os.path.join(self.csv_folder_path, "*.csv")) - if not all_files: - raise FileNotFoundError(f"No CSV files found in {self.csv_folder_path}.") - latest_file = max(all_files, key=os.path.getmtime) # Use the most recent file - - print(f"CSV file identified: {latest_file}") - - # Read the identified CSV file into a DataFrame - self.df = pd.read_csv(latest_file) - print(f"CSV file '{latest_file}' read successfully!") - - # Rename columns of self.df from CSV Name to DataSheet Name - self.rename_columns() - - # Save DataFrame to an Excel file + # Generate a mapping from csv_name to datasheet_name + csv_to_datasheet_map = {} + for category in self.types.categories: + for field in category.fields: + csv_to_datasheet_map[field.csv_name] = field.datasheet_name + + # Create an empty DataFrame with all datasheet column names + datasheet_columns = [field.datasheet_name for category in self.types.categories for field in category.fields] + self.df = pd.DataFrame(columns=datasheet_columns) + + print("Empty DataFrame created with column headers based on types.csv") + + # Save empty DataFrame to an Excel file self.df.to_excel(self.wb_name, sheet_name=self.ws_name, index=False) # Load and store the workbook @@ -99,9 +75,10 @@ def readCSV(self): raise ValueError(f"Sheet '{self.ws_name}' does not exist in the workbook.") self.ws = self.wb[self.ws_name] + print(f"Empty Excel workbook '{self.wb_name}' created successfully!") except Exception as e: - print(f"Error reading CSV file: {e}") + print(f"Error creating empty Excel file: {e}") def applyValidationRules(self): """ @@ -208,45 +185,29 @@ def applyConditionalFormatting(self): ] for row_number in range(2, 301): # start and end rows - filled_check = ", ".join([f'ISBLANK(${col}{row_number})' for col in required_columns]) - formula = f'=OR({filled_check})' - rule = FormulaRule(formula=[formula], fill=red_fill) - - for col in category_columns: + # Mark a cell red only if it is empty + for col in required_columns: + formula = f'=ISBLANK(${col}{row_number})' + rule = FormulaRule(formula=[formula], fill=red_fill) self.ws.conditional_formatting.add(f"{col}{row_number}", rule) + self.wb.save(self.wb_name) print("Conditional formatting applied successfully!") def rename_columns(self): """ - Renames the columns of the existing DataFrame based on a csv_name to datasheet_name mapping. - - Raises: - ValueError: If self.types or self.df is not initialized. + This method is no longer needed since we generate empty sheets directly with datasheet names. + Kept for backward compatibility but does nothing. """ - # Check if self.types and self.df are initialized - if self.types is None: - raise ValueError( - "The 'types' object is not initialized. Please initialize 'self.types' before renaming columns.") - if self.df is None: - raise ValueError( - "The DataFrame 'self.df' is not initialized. Please load data into 'self.df' before renaming columns.") - - # Generate a mapping from csv_name to datasheet_name - csv_to_datasheet_map = {} - for category in self.types.categories: - for field in category.fields: - csv_to_datasheet_map[field.csv_name] = field.datasheet_name - - # Rename the columns of the existing DataFrame - self.df.rename(columns=csv_to_datasheet_map, inplace=True) + # No-op: columns are already in datasheet format when creating empty DataFrame + pass if __name__ == "__main__": - # Path to patient data csv file - patientdata_file_path = "../cron/backups" # Replace with your directory path + # types_file_path is still needed to define the schema types_file_path = "../types.csv" - datasheet_file_path = "../server/downloads" + # patientdata_file_path is no longer used but kept for backward compatibility + patientdata_file_path = "../cron/backups" # Not used anymore, kept for compatibility # delete the existing DataSheet.xlsx file try: @@ -259,4 +220,4 @@ def rename_columns(self): initialiser.readCSV() initialiser.applyValidationRules() initialiser.applyFormatting() - initialiser.applyConditionalFormatting() \ No newline at end of file + initialiser.applyConditionalFormatting() diff --git a/merger/merger.py b/merger/merger.py index 18b4cd7..56d5bde 100644 --- a/merger/merger.py +++ b/merger/merger.py @@ -124,6 +124,7 @@ def readDataSheets(self): def mergeDataSheets(self, output_file="merged_output.csv"): """ Merge read dataframes on 'id' and 'vid' columns. + For rows with the same (id, vid), combines non-null values from different sheets. Args: output_file (str): Name of the output file to save the merged dataframe. @@ -139,11 +140,18 @@ def mergeDataSheets(self, output_file="merged_output.csv"): # Concatenate dataframes self.df = pd.concat(self.dataframes, ignore_index=True) - # Rename columns based on the types + # Rename columns based on the types (second pass - redundant but kept for compatibility) self.renameColumns() - # Group by 'id' and 'vid' and aggregate to merge rows - self.df = self.df.groupby(self.merge_cols, as_index=False).first() + # Define aggregation function that takes first non-null value + def first_non_null(series): + """Return first non-null value, or null if all are null""" + non_null = series.dropna() + return non_null.iloc[0] if len(non_null) > 0 else None + + # Group by 'id' and 'vid' and aggregate using first non-null value for each column + agg_dict = {col: first_non_null for col in self.df.columns if col not in self.merge_cols} + self.df = self.df.groupby(self.merge_cols, as_index=False).agg(agg_dict) # Save the merged dataframe to a new CSV file self.df.to_csv(output_file, index=False) diff --git a/types.csv b/types.csv index 771c8e9..e2ed6ba 100644 --- a/types.csv +++ b/types.csv @@ -15,111 +15,94 @@ Admin,admin,TRUE,id,ID,id,Registration ID*,id,INTEGER,A2:A500,,Auto-incrementing ,admin,FALSE,last_menstrual_period,LastMenstrualPeriod,lastMenstrualPeriod,"If N or unsure, Last Menstrual Period",a_last_menstrual_period,DATE,N2:N500,,Date of last menstrual period.,ea9999 ,admin,FALSE,drug_allergies,DrugAllergies,drugAllerg,"Drug Allergies (if none, put ""nil"")",a_drug_allergies,TEXT,O2:O500,,Patient drug allergies,ea9999 ,admin,TRUE,sent_to_id,SentToID,sentToId,sent to Infectious Disease? (T/F)*,a_sent_to_id,BOOLEAN,P2:P500,,Boolean indicating if patient was sent to infectious diseases station.,ea9999 -,admin,FALSE,photo,Photo,photo,Photo (Leave this blank),a_photo,BYTEA,DT2:DT500,,"Postgres binary string data type, used to store photo",ea9999 -Past Medical History,pastmedicalhistory,TRUE,tuberculosis,Tuberculosis,tuberculosis,Tuberculosis (T/F)*,pmh_tuberculosis,BOOLEAN,Q2:Q500,,Boolean indicating if patient has tuberculosis,f9cb9c -,pastmedicalhistory,TRUE,diabetes,Diabetes,diabetes,Diabetes (T/F)*,pmh_diabetes,BOOLEAN,R2:R500,,Boolean indicating if patient has diabetes,f9cb9c -,pastmedicalhistory,TRUE,hypertension,Hypertension,hypertension,Hypertension (T/F)*,pmh_hypertension,BOOLEAN,S2:S500,,Boolean indicating if patient has hypertension,f9cb9c -,pastmedicalhistory,TRUE,hyperlipidemia,Hyperlipidemia,hyperlipidemia,Hyperlipidemia (T/F)*,pmh_hyperlipidemia,BOOLEAN,T2:T500,,Boolean indicating if patient has hyperlipidemia,f9cb9c -,pastmedicalhistory,TRUE,chronic_joint_pains,ChronicJointPains,chronicJointPains,Chronic Joint Pains (T/F)*,pmh_chronic_joint_pains,BOOLEAN,U2:U500,,Boolean indicating if patient has chronic joint pains,f9cb9c -,pastmedicalhistory,TRUE,chronic_muscle_aches,ChronicMuscleAches,chronicMuscleAches,Chronic Muscle Aches (T/F)*,pmh_chronic_muscle_aches,BOOLEAN,V2:V500,,Boolean indicating if patient has chronic muscle aches,f9cb9c -,pastmedicalhistory,TRUE,sexually_transmitted_disease,SexuallyTransmittedDisease,sexuallyTransmittedDisease,Sexually transmitted disease (T/F)*,pmh_sexually_transmitted_disease,BOOLEAN,W2:W500,,Boolean indicating if patient has a sexually transmitted disease,f9cb9c -,pastmedicalhistory,FALSE,specified_stds,SpecifiedSTDs,specifiedSTDs,"If Y to STD, specify: (If F, leave blank)",pmh_specified_stds,TEXT,X2:X500,,"Details of specified sexually transmitted diseases, if any",f9cb9c -,pastmedicalhistory,FALSE,others,Others,others,"PMH Others (If none, leave blank)",pmh_others,TEXT,Y2:Y500,,Any other relevant medical conditions or notes,f9cb9c -Social History,socialhistory,TRUE,past_smoking_history,PastSmokingHistory,pastSmokingHistory,Past smoking history (T/F)*,sh_past_smoking_history,BOOLEAN,Z2:Z500,,Boolean indicating if the patient has a history of smoking,ffe599 -,socialhistory,FALSE,no_of_years,NumberOfYears,numberOfYears,"If Y, no. of years",sh_no_of_years,INTEGER,AA2:AA500,,Number of years the patient has smoked,ffe599 -,socialhistory,TRUE,current_smoking_history,CurrentSmokingHistory,currentSmokingHistory,Current smoking history (T/F)*,sh_current_smoking_history,BOOLEAN,AB2:AB500,,Boolean indicating if the patient currently smokes,ffe599 -,socialhistory,FALSE,cigarettes_per_day,CigarettesPerDay,cigarettesPerDay,"If Y, how many cigarettes per day",sh_cigarettes_per_day,INTEGER,AC2:AC500,,Number of cigarettes the patient smokes per day,ffe599 -,socialhistory,TRUE,alcohol_history,AlcoholHistory,alcoholHistory,Alcohol history (T/F)*,sh_alcohol_history,BOOLEAN,AD2:AD500,,Boolean indicating if the patient has a history of alcohol consumption,ffe599 -,socialhistory,FALSE,how_regular,HowRegular,howRegular,"If Y, how regularly? (A/B/C/D)",sh_how_regular,VARCHAR_1,AE2:AE500,,"Char 'A', 'B', 'C, 'D' indicating patient's frequency of alcohol consumption",ffe599 -Vital Statistics,vitalstatistics,TRUE,temperature,Temperature,temperature,Temperature*,vs_temperature,NUMERIC_5_1,AF2:AF500,,"Patient's body temperature in degrees Celsius, 5 digits with 1 dp",b6d7a8 -,vitalstatistics,TRUE,spo2,SpO2,spO2,SpO2*,vs_spo2,NUMERIC_5_1,AG2:AG500,,Oxygen saturation level in percentage,b6d7a8 -,vitalstatistics,FALSE,systolic_bp1,SystolicBP1,systolicBP1,Systolic BP1,vs_systolic_bp1,NUMERIC_5_1,AH2:AH500,,Systolic blood pressure measurement 1,b6d7a8 -,vitalstatistics,FALSE,diastolic_bp1,DiastolicBP1,diastolicBP1,Diastolic BP1,vs_diastolic_bp1,NUMERIC_5_1,AI2:AI500,,Diastolic blood pressure measurement 1,b6d7a8 -,vitalstatistics,FALSE,systolic_bp2,SystolicBP2,systolicBP2,Systolic BP2,vs_systolic_bp2,NUMERIC_5_1,AJ2:AJ500,,Systolic blood pressure measurement 2,b6d7a8 -,vitalstatistics,FALSE,diastolic_bp2,DiastolicBP2,diastolicBP2,Diastolic BP2,vs_diastolic_bp2,NUMERIC_5_1,AK2:AK500,,Diastolic blood pressure measurement 2,b6d7a8 -,vitalstatistics,FALSE,avg_systolic_bp,AverageSystolicBP,averageSystolicBP,Avg Systolic BP,vs_avg_systolic_bp,NUMERIC_5_1,AL2:AL500,,Average systolic blood pressure,b6d7a8 -,vitalstatistics,FALSE,avg_diastolic_bp,AverageDiastolicBP,averageDiastolicBP,Avg Diastolic BP,vs_avg_diastolic_bp,NUMERIC_5_1,AM2:AM500,,Average diastolic blood pressure,b6d7a8 -,vitalstatistics,TRUE,hr1,HR1,hr1,HR1*,vs_hr1,NUMERIC_5_1,AN2:AN500,,Heart rate measurement 1,b6d7a8 -,vitalstatistics,TRUE,hr2,HR2,hr2,HR2*,vs_hr2,NUMERIC_5_1,AO2:AO500,,Heart rate measurement 2,b6d7a8 -,vitalstatistics,TRUE,avg_hr,AverageHR,averageHR,Avg HR*,vs_avg_hr,NUMERIC_5_1,AP2:AP500,,Average heart rate,b6d7a8 -,vitalstatistics,TRUE,rand_blood_glucose_mmoll,RandomBloodGlucoseMmolL,randomBloodGlucoseMmolL,Random Blood Glucose (mmol/L)*,vs_rand_blood_glucose_mmoll,NUMERIC_5_1,AQ2:AQ500,,Random blood glucose level in mmol/L,b6d7a8 -Height And Weight,heightandweight,TRUE,height,Height,height,Height (cm)*,haw_height,NUMERIC_5_1,AR2:AR500,,Patient's height in meters (with 1 decimal place),00ffff -,heightandweight,TRUE,weight,Weight,weight,Weight (kg)*,haw_weight,NUMERIC_5_1,AS2:AS500,,Patient's weight in kilograms (with 1 decimal place),00ffff -,heightandweight,TRUE,bmi,BMI,bmi,BMI*,haw_bmi,NUMERIC_5_1,AT2:AT500,,Body Mass Index (BMI) value (with 1 decimal place),00ffff -,heightandweight,TRUE,bmi_analysis,BMIAnalysis,bmiAnalysis,BMI Analysis*,haw_bmi_analysis,TEXT,AU2:AU500,,Analysis or interpretation of the BMI value,00ffff -,heightandweight,FALSE,paeds_height,PaedsHeight,paedsHeight,Paeds: Height %,haw_paeds_height,NUMERIC_5_1,AV2:AV500,,Pediatric height measurement in meters (with 1 decimal place),00ffff -,heightandweight,FALSE,paeds_weight,PaedsWeight,paedsWeight,Paeds: Weight %,haw_paeds_weight,NUMERIC_5_1,AW2:AW500,,Pediatric weight measurement in kilograms (with 1 decimal place),00ffff -Visual Acuity,visualacuity,TRUE,l_eye_vision,LEyeVision,lEyeVision,L eye vision (6/)*,va_l_eye_vision,INTEGER,AX2:AX500,,Vision measurement for the left eye,a4c2f4 -,visualacuity,TRUE,r_eye_vision,REyeVision,rEyeVision,R eye vision (6/)*,va_r_eye_vision,INTEGER,AY2:AY500,,Vision measurement for the right eye,a4c2f4 -,visualacuity,FALSE,additional_intervention,AdditionalIntervention,additionalIntervention,Additional Intervention (Optometrist OR Opthalmologist: (pathology)),va_additional_intervention,TEXT,AZ2:AZ500,,Details of any additional intervention or notes,a4c2f4 -Dental,dental,TRUE,clean_teeth_freq,CleanTeethFreq,cleanTeethFreq,How many days per week do you clean your child’s teeth or supervise/monitor them brush with fluoride toothpaste twice a day? (0/1/2/3/4/5/6)*,d_clean_teeth_freq,INTEGER,BA2:BA500,"0,1,2,3,4,5,6,7","Integer range [1,7]. Oral Hygiene Question: How many days per week do you clean your child's teeth or supervise / monitor them brush with fluoride toothpaste twice a day?",b4a7d6 -,dental,TRUE,sugar_consume_freq,SugarConsumeFreq,sugarConsumeFreq,"On average, how many times daily does your child consume starch or sugar (food or drinks) between meals? (A/B/C/D)*",d_sugar_consume_freq,INTEGER,BB2:BB500,"0,1,2,3,4,5,6","Integer range [0,6]. Diet Question: On average, how many times daily does your child consume starch or sugar (food or drinks) between meals?",b4a7d6 -,dental,TRUE,past_year_decay,PastYearDecay,pastYearDecay,Has anyone in the immediate family (including a caregiver) had tooth decay or lost a tooth from tooth decay in the past year? (T/F)*,d_past_year_decay,BOOLEAN,BC2:BC500,,Bacterial Exposure Question: Has anyone in the immediate family (including a caregiver) had tooth decay or lost a tooth from tooth decay in the past year?,b4a7d6 -,dental,TRUE,brush_teeth_pain,BrushTeethPain,brushTeethPain,Oral symptoms question: Does your child complain of tooth pain or bleeding gums when they brush their teeth (T/F)*,d_brush_teeth_pain,BOOLEAN,BD2:BD500,,Oral Symptoms Question: Does your child complain of tooth pain or bleeding gums when they brush their teeth?,b4a7d6 -,dental,TRUE,drink_other_water,DrinkOtherWater,drinkOtherWater,Does your child wake up to drink anything other than water throughout the night? (T/F)*,d_drink_other_water,BOOLEAN,BE2:BE500,,Oral Hygiene Question: Does your child wake up to drink anything other than water throughout the night?,b4a7d6 -,dental,FALSE,dental_notes,DentalNotes,dentalNotes,Dental notes?,d_dental_notes,TEXT,BF2:BF500,,Additional notes,b4a7d6 -,dental,TRUE,referral_needed,ReferralNeeded,referralNeeded,Dental Referral needed? (T/F)*,d_referral_needed,BOOLEAN,BG2:BG500,,Is additional referral needed,b4a7d6 -,dental,FALSE,referral_loc,ReferralLoc,referralLoc,Referral location?,d_referral_loc,TEXT,BH2:BH500,,Referral location if applicable,b4a7d6 -,dental,FALSE,tooth_11,Tooth11,tooth11,Tooth11,d_tooth_11,BOOLEAN,BI2:BI500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_12,Tooth12,tooth12,Tooth12,d_tooth_12,BOOLEAN,BJ2:BJ500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_13,Tooth13,tooth13,Tooth13,d_tooth_13,BOOLEAN,BK2:BK500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_14,Tooth14,tooth14,Tooth14,d_tooth_14,BOOLEAN,BL2:BL500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_15,Tooth15,tooth15,Tooth15,d_tooth_15,BOOLEAN,BM2:BM500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_16,Tooth16,tooth16,Tooth16,d_tooth_16,BOOLEAN,BN2:BN500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_17,Tooth17,tooth17,Tooth17,d_tooth_17,BOOLEAN,BO2:BO500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_18,Tooth18,tooth18,Tooth18,d_tooth_18,BOOLEAN,BP2:BP500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_21,Tooth21,tooth21,Tooth21,d_tooth_21,BOOLEAN,BQ2:BQ500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_22,Tooth22,tooth22,Tooth22,d_tooth_22,BOOLEAN,BR2:BR500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_23,Tooth23,tooth23,Tooth23,d_tooth_23,BOOLEAN,BS2:BS500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_24,Tooth24,tooth24,Tooth24,d_tooth_24,BOOLEAN,BT2:BT500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_25,Tooth25,tooth25,Tooth25,d_tooth_25,BOOLEAN,BU2:BU500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_26,Tooth26,tooth26,Tooth26,d_tooth_26,BOOLEAN,BV2:BV500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_27,Tooth27,tooth27,Tooth27,d_tooth_27,BOOLEAN,BW2:BW500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_28,Tooth28,tooth28,Tooth28,d_tooth_28,BOOLEAN,BX2:BX500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_31,Tooth31,tooth31,Tooth31,d_tooth_31,BOOLEAN,BY2:BY500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_32,Tooth32,tooth32,Tooth32,d_tooth_32,BOOLEAN,BZ2:BZ500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_33,Tooth33,tooth33,Tooth33,d_tooth_33,BOOLEAN,CA2:CA500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_34,Tooth34,tooth34,Tooth34,d_tooth_34,BOOLEAN,CB2:CB500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_35,Tooth35,tooth35,Tooth35,d_tooth_35,BOOLEAN,CC2:CC500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_36,Tooth36,tooth36,Tooth36,d_tooth_36,BOOLEAN,CD2:CD500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_37,Tooth37,tooth37,Tooth37,d_tooth_37,BOOLEAN,CE2:CE500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_38,Tooth38,tooth38,Tooth38,d_tooth_38,BOOLEAN,CF2:CF500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_41,Tooth41,tooth41,Tooth41,d_tooth_41,BOOLEAN,CG2:CG500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_42,Tooth42,tooth42,Tooth42,d_tooth_42,BOOLEAN,CH2:CH500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_43,Tooth43,tooth43,Tooth43,d_tooth_43,BOOLEAN,CI2:CI500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_44,Tooth44,tooth44,Tooth44,d_tooth_44,BOOLEAN,CJ2:CJ500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_45,Tooth45,tooth45,Tooth45,d_tooth_45,BOOLEAN,CK2:CK500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_46,Tooth46,tooth46,Tooth46,d_tooth_46,BOOLEAN,CL2:CL500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_47,Tooth47,tooth47,Tooth47,d_tooth_47,BOOLEAN,CM2:CM500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -,dental,FALSE,tooth_48,Tooth48,tooth48,Tooth48,d_tooth_48,BOOLEAN,CN2:CN500,,Indicates whether this tooth has a cavity. Defaults to null.,b4a7d6 -Fall Risk,fallrisk,TRUE,fall_worries,FallWorries,fallWorries,How often do you worry about falling? (A/B/C/D)*,fr_fall_worries,VARCHAR_1,CO2:CO500,"a,b,c,d",Multiple option question regarding fall in past 12 months,6fa8dc -,fallrisk,TRUE,fall_history,FallHistory,fallHistory,History of fall within past 12 months (A/B/C/D)*,fr_fall_history,VARCHAR_1,CP2:CP500,"a,b,c,d",Multiple option question,6fa8dc -,fallrisk,TRUE,cognitive_status,CognitiveStatus,cognitiveStatus,Cognitive status (A/B/C/D)*,fr_cognitive_status,VARCHAR_1,CQ2:CQ500,"a,b,c,d",Multiple option question,6fa8dc -,fallrisk,TRUE,continence_problems,ContinenceProblems,continenceProblems,Continence problems (A/B/C/D/E)*,fr_continence_problems,VARCHAR_1,CR2:CR500,"a,b,c,d,e",Multiple option question,6fa8dc -,fallrisk,TRUE,safety_awareness,SafetyAwareness,safetyAwareness,Safety Awareness (A/B/C/D)*,fr_safety_awareness,VARCHAR_1,CS2:CS500,"a,b,c,d",Multiple option question,6fa8dc -,fallrisk,TRUE,unsteadiness,Unsteadiness,unsteadiness,"Unsteadiness when standing, transferring and/or walking (A/B/C/D)*",fr_unsteadiness,VARCHAR_1,CT2:CT500,"a,b,c,d",,6fa8dc -,fallrisk,TRUE,fall_risk_score,FallRiskScore,fallRiskScore,Total Score (High Risk: ≥ 8)*,fr_fall_risk_score,INTEGER,CU2:CU500,,Calculated fall risk score based on previous fall risk questions,6fa8dc -Doctor's Consultation,doctorsconsultation,TRUE,well,Well,well,Well*,dc_well,BOOLEAN,CV2:CV500,,Boolean indicating if the patient is well,c27ba0 -,doctorsconsultation,TRUE,msk,Msk,msk,MSK*,dc_msk,BOOLEAN,CW2:CW500,,Boolean indicating if musculoskeletal system is healthy,c27ba0 -,doctorsconsultation,TRUE,cvs,Cvs,cvs,CVS*,dc_cvs,BOOLEAN,CX2:CX500,,Boolean indicating if cardiovascular system is healthy,c27ba0 -,doctorsconsultation,TRUE,respi,Respi,respi,Respi*,dc_respi,BOOLEAN,CY2:CY500,,Boolean indicating if respiratory system is healthy,c27ba0 -,doctorsconsultation,TRUE,gu,Gu,gu,GU*,dc_gu,BOOLEAN,CZ2:CZ500,,Boolean indicating if,c27ba0 -,doctorsconsultation,TRUE,git,Git,git,GIT*,dc_git,BOOLEAN,DA2:DA500,,Boolean indicating if,c27ba0 -,doctorsconsultation,TRUE,eye,Eye,eye,EYE*,dc_eye,BOOLEAN,DB2:DB500,,Boolean indicating if eye health is satisfactory,c27ba0 -,doctorsconsultation,TRUE,derm,Derm,derm,DERM*,dc_derm,BOOLEAN,DC2:DC500,,Boolean indicating if dermatological health is satisfactory,c27ba0 -,doctorsconsultation,TRUE,others,Others,others,DC OTHERS*,dc_others,TEXT,DD2:DD500,,Details of other relevant health assessments,c27ba0 -,doctorsconsultation,FALSE,consultation_notes,ConsultationNotes,consultationNotes,Consultation Notes,dc_consultation_notes,TEXT,DE2:DE500,,General notes from the consultation,c27ba0 -,doctorsconsultation,FALSE,diagnosis,Diagnosis,diagnosis,Diagnosis,dc_diagnosis,TEXT,DF2:DF500,,Diagnosis provided during consultation,c27ba0 -,doctorsconsultation,FALSE,treatment,Treatment,treatment,Treatment,dc_treatment,TEXT,DG2:DG500,,Treatment plan or recommendations,c27ba0 -,doctorsconsultation,TRUE,referral_needed,ReferralNeeded,referralNeeded,Referral Needed?*,dc_referral_needed,BOOLEAN,DH2:DH500,,Boolean indicating if a referral is needed,c27ba0 -,doctorsconsultation,FALSE,referral_loc,ReferralLoc,referralLoc,Referral Location,dc_referral_loc,TEXT,DI2:DI500,,"Location or details for the referral, if needed",c27ba0 -,doctorsconsultation,FALSE,remarks,Remarks,remarks,Remarks (anything that doesn't fit),dc_remarks,TEXT,DJ2:DJ500,,Additional remarks or comments,c27ba0 -Physiotherapy,physiotherapy,TRUE,pain_stiffness_day,PainStiffnessDay,painStiffnessDay,"Pain/stiffness during the day: How severe was your usual joint or muscle pain and/or stiffness overall during the day in the last 2 weeks? (0,1,2,3,4,5)*",p_pain_stiffness_day,INTEGER,DK2:DK500,"0,1,2,3,4,5 (,1,2,3,4,5)",,999999 -,physiotherapy,TRUE,pain_stiffness_night,PainStiffnessNight,painStiffnessNight,"Pain/stiffness during the night: How severe was your usual joint or muscle pain and/or stiffness overall during the night in the last 2 weeks? (0,1,2,3,4,5)*",p_pain_stiffness_night,INTEGER,DL2:DL501,"0,1,2,3,4,5",,999999 -,physiotherapy,TRUE,symptoms_interfere_tasks,SymptomsInterfereTasks,symptomsInterfereTasks,"How much has your symptoms interfered with your ability to walk or do everyday tasks like cooking, cleaning or dressing in the last 2 weeks? (Never,Rarely,Sometimes,Often,Always)*",p_symptoms_interfere_tasks,TEXT,DM2:DM501,"Never,Rarely,Sometimes,Often,Always",,999999 -,physiotherapy,TRUE,symptoms_change,SymptomsChange,symptomsChange,"Have your symptoms improved, worsened, or stayed the same over the last 2 weeks? (Improved,Worsened,Stayed the same)*",p_symptoms_change,TEXT,DN2:DN501,"Improved,Worsened,Stayed the same",,999999 -,physiotherapy,TRUE,symptoms_need_help,SymptomsNeedHelp,symptomsNeedHelp,"How often have you needed help from others (including family, friends or carers) because of your joint or muscle symptoms in the last 2 weeks? (Never,Rarely,Sometimes,Often,Always)*",p_symptoms_need_help,TEXT,DO2:DO501,"Never,Rarely,Sometimes,Often,Always",,999999 -,physiotherapy,TRUE,trouble_sleep_symptoms,TroubleSleepSymptoms,troubleSleepSymptoms,"How often have you had trouble with either falling asleep or staying asleep because of your joint or muscle symptoms in the last 2 weeks? (Never,Rarely,Sometimes,Often,Always)*",p_trouble_sleep_symptoms,TEXT,DP2:DP501,"Never,Rarely,Sometimes,Often,Always",,999999 -,physiotherapy,TRUE,how_much_fatigue,HowMuchFatigue,howMuchFatigue,"How much fatigue or low energy have you felt in the last 2 weeks? (0,1,2,3,4,5)*",p_how_much_fatigue,INTEGER,DQ2:DQ501,"0,1,2,3,4,5",,999999 -,physiotherapy,TRUE,anxious_low_mood,AnxiousLowMood,anxiousLowMood,"How much have you felt anxious or low in your mood because of your joint or muscle symptoms in the last 2 weeks? (0,1,2,3,4,5)*",p_anxious_low_mood,INTEGER,DR2:DR501,"0,1,2,3,4,5",,999999 -,physiotherapy,TRUE,medication_manage_symptoms,MedicationManageSymptoms,medicationManageSymptoms,"Have you used any medication to manage your symptoms in the last 2 weeks? If yes, how often? (Never,Rarely,Sometimes,Often,Always)*",p_medication_manage_symptoms,TEXT,DS2:DS501,"Never,Rarely,Sometimes,Often,Always",,999999 \ No newline at end of file +Past Medical History,pastmedicalhistory,FALSE,cough,Cough,cough,Cough (T/F)*,pmh_cough,BOOLEAN,Q2:Q500,,Boolean indicating if patient has cough,f9cb9c +,pastmedicalhistory,FALSE,fever,Fever,fever,Fever (T/F)*,pmh_fever,BOOLEAN,R2:R500,,Boolean indicating if patient has fever,f9cb9c +,pastmedicalhistory,FALSE,blocked_nose,BlockedNose,blockedNose,Blocked Nose (T/F)*,pmh_blocked_nose,BOOLEAN,S2:S500,,Boolean indicating if patient has blocked nose,f9cb9c +,pastmedicalhistory,FALSE,sore_throat,SoreThroat,soreThroat,Sore Throat (T/F)*,pmh_sore_throat,BOOLEAN,T2:T500,,Boolean indicating if patient has sore throat,f9cb9c +,pastmedicalhistory,FALSE,night_sweats,NightSweats,nightSweats,Night Sweats (T/F)*,pmh_night_sweats,BOOLEAN,U2:U500,,Boolean indicating if patient has night sweats,f9cb9c +,pastmedicalhistory,FALSE,unintentional_weight_loss,UnintentionalWeightLoss,unintentionalWeightLoss,Unintentional Weight Loss (T/F)*,pmh_unintentional_weight_loss,BOOLEAN,V2:V500,,Boolean indicating if patient has unintentional weight loss,f9cb9c +,pastmedicalhistory,FALSE,tuberculosis,Tuberculosis,tuberculosis,Tuberculosis (T/F)*,pmh_tuberculosis,BOOLEAN,W2:W500,,Boolean indicating if patient has tuberculosis,f9cb9c +,pastmedicalhistory,FALSE,tuberculosis_has_been_treated,TuberculosisHasBeenTreated,tuberculosisHasBeenTreated,Tuberculosis Has Been Treated (T/F)*,pmh_tuberculosis_has_been_treated,BOOLEAN,X2:X500,,Boolean indicating if tuberculosis has been treated,f9cb9c +,pastmedicalhistory,FALSE,diabetes,Diabetes,diabetes,Diabetes (T/F)*,pmh_diabetes,BOOLEAN,Y2:Y500,,Boolean indicating if patient has diabetes,f9cb9c +,pastmedicalhistory,FALSE,hypertension,Hypertension,hypertension,Hypertension (T/F)*,pmh_hypertension,BOOLEAN,Z2:Z500,,Boolean indicating if patient has hypertension,f9cb9c +,pastmedicalhistory,FALSE,hyperlipidemia,Hyperlipidemia,hyperlipidemia,Hyperlipidemia (T/F)*,pmh_hyperlipidemia,BOOLEAN,AA2:AA500,,Boolean indicating if patient has hyperlipidemia,f9cb9c +,pastmedicalhistory,FALSE,chronic_joint_pains,ChronicJointPains,chronicJointPains,Chronic Joint Pains (T/F)*,pmh_chronic_joint_pains,BOOLEAN,AB2:AB500,,Boolean indicating if patient has chronic joint pains,f9cb9c +,pastmedicalhistory,FALSE,chronic_muscle_aches,ChronicMuscleAches,chronicMuscleAches,Chronic Muscle Aches (T/F)*,pmh_chronic_muscle_aches,BOOLEAN,AC2:AC500,,Boolean indicating if patient has chronic muscle aches,f9cb9c +,pastmedicalhistory,FALSE,sexually_transmitted_disease,SexuallyTransmittedDisease,sexuallyTransmittedDisease,Sexually transmitted disease (T/F)*,pmh_sexually_transmitted_disease,BOOLEAN,AD2:AD500,,Boolean indicating if patient has a sexually transmitted disease,f9cb9c +,pastmedicalhistory,FALSE,specified_stds,SpecifiedSTDs,specifiedSTDs,"If Y to STD, specify: (If F, leave blank)",pmh_specified_stds,TEXT,AE2:AE500,,"Details of specified sexually transmitted diseases, if any",f9cb9c +,pastmedicalhistory,FALSE,others,Others,others,"PMH Others (If none, leave blank)",pmh_others,TEXT,AF2:AF500,,Any other relevant medical conditions or notes,f9cb9c +Social History,socialhistory,TRUE,past_smoking_history,PastSmokingHistory,pastSmokingHistory,Past smoking history (T/F)*,sh_past_smoking_history,BOOLEAN,AG2:AG500,,Boolean indicating if the patient has a history of smoking,ffe599 +,socialhistory,FALSE,no_of_years,NumberOfYears,numberOfYears,"If Y, no. of years",sh_no_of_years,INTEGER,AH2:AH500,,Number of years the patient has smoked,ffe599 +,socialhistory,TRUE,current_smoking_history,CurrentSmokingHistory,currentSmokingHistory,Current smoking history (T/F)*,sh_current_smoking_history,BOOLEAN,AI2:AI500,,Boolean indicating if the patient currently smokes,ffe599 +,socialhistory,FALSE,cigarettes_per_day,CigarettesPerDay,cigarettesPerDay,"If Y, how many cigarettes per day",sh_cigarettes_per_day,INTEGER,AJ2:AJ500,,Number of cigarettes the patient smokes per day,ffe599 +,socialhistory,TRUE,alcohol_history,AlcoholHistory,alcoholHistory,Alcohol history (T/F)*,sh_alcohol_history,BOOLEAN,AK2:AK500,,Boolean indicating if the patient has a history of alcohol consumption,ffe599 +,socialhistory,FALSE,how_regular,HowRegular,howRegular,"If Y, how regularly? (A/B/C/D)",sh_how_regular,VARCHAR_1,AL2:AL500,,"Char 'A', 'B', 'C, 'D' indicating patient's frequency of alcohol consumption",ffe599 +Vital Statistics,vitalstatistics,TRUE,temperature,Temperature,temperature,Temperature*,vs_temperature,NUMERIC_5_1,AM2:AM500,,"Patient's body temperature in degrees Celsius, 5 digits with 1 dp",b6d7a8 +,vitalstatistics,TRUE,spo2,SpO2,spO2,SpO2*,vs_spo2,NUMERIC_5_1,AN2:AN500,,Oxygen saturation level in percentage,b6d7a8 +,vitalstatistics,FALSE,systolic_bp1,SystolicBP1,systolicBP1,Systolic BP1,vs_systolic_bp1,NUMERIC_5_1,AO2:AO500,,Systolic blood pressure measurement 1,b6d7a8 +,vitalstatistics,FALSE,diastolic_bp1,DiastolicBP1,diastolicBP1,Diastolic BP1,vs_diastolic_bp1,NUMERIC_5_1,AP2:AP500,,Diastolic blood pressure measurement 1,b6d7a8 +,vitalstatistics,FALSE,systolic_bp2,SystolicBP2,systolicBP2,Systolic BP2,vs_systolic_bp2,NUMERIC_5_1,AQ2:AQ500,,Systolic blood pressure measurement 2,b6d7a8 +,vitalstatistics,FALSE,diastolic_bp2,DiastolicBP2,diastolicBP2,Diastolic BP2,vs_diastolic_bp2,NUMERIC_5_1,AR2:AR500,,Diastolic blood pressure measurement 2,b6d7a8 +,vitalstatistics,FALSE,avg_systolic_bp,AverageSystolicBP,averageSystolicBP,Avg Systolic BP,vs_avg_systolic_bp,NUMERIC_5_1,AS2:AS500,,Average systolic blood pressure,b6d7a8 +,vitalstatistics,FALSE,avg_diastolic_bp,AverageDiastolicBP,averageDiastolicBP,Avg Diastolic BP,vs_avg_diastolic_bp,NUMERIC_5_1,AT2:AT500,,Average diastolic blood pressure,b6d7a8 +,vitalstatistics,TRUE,hr1,HR1,hr1,HR1*,vs_hr1,NUMERIC_5_1,AU2:AU500,,Heart rate measurement 1,b6d7a8 +,vitalstatistics,TRUE,hr2,HR2,hr2,HR2*,vs_hr2,NUMERIC_5_1,AV2:AV500,,Heart rate measurement 2,b6d7a8 +,vitalstatistics,TRUE,avg_hr,AverageHR,averageHR,Avg HR*,vs_avg_hr,NUMERIC_5_1,AW2:AW500,,Average heart rate,b6d7a8 +,vitalstatistics,FALSE,rand_blood_glucose_mmoll,RandomBloodGlucoseMmolL,randomBloodGlucoseMmolL,Random Blood Glucose (mmol/L),vs_rand_blood_glucose_mmoll,NUMERIC_5_1,AX2:AX500,,Random blood glucose level in mmol/L,b6d7a8 +,vitalstatistics,FALSE,icope_high_bp,IcopeHighBp,icopeHighBp,ICOPE High BP,vs_icope_high_bp,BOOLEAN,AY2:AY500,,ICOPE high blood pressure indicator,b6d7a8 +Height And Weight,heightandweight,TRUE,height,Height,height,Height (cm)*,haw_height,NUMERIC_5_1,AZ2:AZ500,,Patient's height in meters (with 1 decimal place),00ffff +,heightandweight,TRUE,weight,Weight,weight,Weight (kg)*,haw_weight,NUMERIC_5_1,BA2:BA500,,Patient's weight in kilograms (with 1 decimal place),00ffff +,heightandweight,TRUE,bmi,BMI,bmi,BMI*,haw_bmi,NUMERIC_5_1,BB2:BB500,,Body Mass Index (BMI) value (with 1 decimal place),00ffff +,heightandweight,TRUE,bmi_analysis,BMIAnalysis,bmiAnalysis,BMI Analysis*,haw_bmi_analysis,TEXT,BC2:BC500,,Analysis or interpretation of the BMI value,00ffff +,heightandweight,FALSE,paeds_height,PaedsHeight,paedsHeight,Paeds: Height %,haw_paeds_height,NUMERIC_5_1,BD2:BD500,,Pediatric height measurement in meters (with 1 decimal place),00ffff +,heightandweight,FALSE,paeds_weight,PaedsWeight,paedsWeight,Paeds: Weight %,haw_paeds_weight,NUMERIC_5_1,BE2:BE500,,Pediatric weight measurement in kilograms (with 1 decimal place),00ffff +,heightandweight,FALSE,icope_lost_weight_past_months,IcopeLostWeightPastMonths,icopeLostWeightPastMonths,ICOPE Lost Weight Past Months,haw_icope_lost_weight_past_months,BOOLEAN,BF2:BF500,,ICOPE indicator for weight loss in past months,00ffff +,heightandweight,FALSE,icope_no_desire_to_eat,IcopeNoDesireToEat,icopeNoDesireToEat,ICOPE No Desire To Eat,haw_icope_no_desire_to_eat,BOOLEAN,BG2:BG500,,ICOPE indicator for lack of desire to eat,00ffff +Visual Acuity,visualacuity,TRUE,l_eye_vision,LEyeVision,lEyeVision,L eye vision (6/)*,va_l_eye_vision,INTEGER,BH2:BH500,,Vision measurement for the left eye,a4c2f4 +,visualacuity,TRUE,r_eye_vision,REyeVision,rEyeVision,R eye vision (6/)*,va_r_eye_vision,INTEGER,BI2:BI500,,Vision measurement for the right eye,a4c2f4 +,visualacuity,TRUE,sent_to_opto,SentToOpto,sentToOpto,Sent to Optometrist (T/F)*,va_sent_to_opto,BOOLEAN,BJ2:BJ500,,Boolean indicating if patient was sent to optometrist,a4c2f4 +,visualacuity,TRUE,referred_for_glasses,ReferredForGlasses,referredForGlasses,Referred for Glasses (T/F)*,va_referred_for_glasses,BOOLEAN,BK2:BK500,,Boolean indicating if patient was referred for glasses,a4c2f4 +,visualacuity,FALSE,icope_eye_problem,IcopeEyeProblem,icopeEyeProblem,ICOPE Eye Problem,va_icope_eye_problem,BOOLEAN,BL2:BL500,,ICOPE indicator for eye problems,a4c2f4 +,visualacuity,FALSE,icope_treated_for_diabetes_or_bp,IcopeTreatedForDiabetesOrBp,icopeTreatedForDiabetesOrBp,ICOPE Treated For Diabetes/BP,va_icope_treated_for_diabetes_or_bp,BOOLEAN,BM2:BM500,,ICOPE indicator for diabetes or blood pressure treatment,a4c2f4 +,visualacuity,FALSE,additional_intervention,AdditionalIntervention,additionalIntervention,Additional Intervention (Optometrist OR Opthalmologist: (pathology)),va_additional_intervention,TEXT,BN2:BN500,,Details of any additional intervention or notes,a4c2f4 +Dental,dental,TRUE,fluoride_exposure,FluorideExposure,fluorideExposure,Fluoride Exposure*,d_fluoride_exposure,TEXT,BO2:BO500,,Fluoride exposure information,b4a7d6 +,dental,TRUE,diet,Diet,diet,Diet*,d_diet,TEXT,BP2:BP500,,Diet information,b4a7d6 +,dental,TRUE,bacterial_exposure,BacterialExposure,bacterialExposure,Bacterial Exposure*,d_bacterial_exposure,TEXT,BQ2:BQ500,,Bacterial exposure information,b4a7d6 +,dental,TRUE,oral_symptoms,OralSymptoms,oralSymptoms,Oral Symptoms (T/F)*,d_oral_symptoms,BOOLEAN,BR2:BR500,,Boolean indicating if patient has oral symptoms,b4a7d6 +,dental,TRUE,drink_other_water,DrinkOtherWater,drinkOtherWater,Drink Other Than Water (T/F)*,d_drink_other_water,BOOLEAN,BS2:BS500,,Boolean indicating if patient drinks other than water,b4a7d6 +,dental,TRUE,risk_for_dental_carries,RiskForDentalCarries,riskForDentalCarries,Risk for Dental Carries*,d_risk_for_dental_carries,TEXT,BT2:BT500,,Risk assessment for dental carries,b4a7d6 +,dental,FALSE,icope_difficulty_chewing,IcopeDifficultyChewing,icopeDifficultyChewing,ICOPE Difficulty Chewing,d_icope_difficulty_chewing,BOOLEAN,BU2:BU500,,ICOPE indicator for difficulty chewing,b4a7d6 +,dental,FALSE,icope_pain_in_mouth,IcopePainInMouth,icopePainInMouth,ICOPE Pain In Mouth,d_icope_pain_in_mouth,BOOLEAN,BV2:BV500,,ICOPE indicator for pain in mouth,b4a7d6 +,dental,FALSE,dental_notes,DentalNotes,dentalNotes,Dental Notes,d_dental_notes,TEXT,BW2:BW500,,Additional dental notes,b4a7d6 +Fall Risk,fallrisk,TRUE,side_to_side_balance,SideToSideBalance,sideToSideBalance,Side to Side Balance*,fr_side_to_side_balance,INTEGER,BX2:BX500,,Side to side balance test score,6fa8dc +,fallrisk,TRUE,semi_tandem_balance,SemiTandemBalance,semiTandemBalance,Semi Tandem Balance*,fr_semi_tandem_balance,INTEGER,BY2:BY500,,Semi tandem balance test score,6fa8dc +,fallrisk,TRUE,tandem_balance,TandemBalance,tandemBalance,Tandem Balance*,fr_tandem_balance,INTEGER,BZ2:BZ500,,Tandem balance test score,6fa8dc +,fallrisk,TRUE,gait_speed_test,GaitSpeedTest,gaitSpeedTest,Gait Speed Test*,fr_gait_speed_test,INTEGER,CA2:CA500,,Gait speed test score,6fa8dc +,fallrisk,TRUE,chair_stand_test,ChairStandTest,chairStandTest,Chair Stand Test*,fr_chair_stand_test,INTEGER,CB2:CB500,,Chair stand test score,6fa8dc +,fallrisk,TRUE,fall_risk_score,FallRiskScore,fallRiskScore,Fall Risk Score*,fr_fall_risk_score,INTEGER,CC2:CC500,,Total fall risk score,6fa8dc +,fallrisk,FALSE,icope_complete_chair_stands,IcopeCompleteChairStands,icopeCompleteChairStands,ICOPE Complete Chair Stands,fr_icope_complete_chair_stands,BOOLEAN,CD2:CD500,,ICOPE indicator for completing chair stands,6fa8dc +,fallrisk,FALSE,icope_chair_stands_time,IcopeChairStandsTime,icopeChairStandsTime,ICOPE Chair Stands Time,fr_icope_chair_stands_time,BOOLEAN,CE2:CE500,,ICOPE indicator for chair stands time,6fa8dc +Doctor's Consultation,doctorsconsultation,FALSE,well,Well,well,Well,dc_well,BOOLEAN,CF2:CF500,,Boolean indicating if the patient is well,c27ba0 +,doctorsconsultation,FALSE,msk,Msk,msk,MSK,dc_msk,BOOLEAN,CG2:CG500,,Boolean indicating if musculoskeletal system is healthy,c27ba0 +,doctorsconsultation,FALSE,cvs,Cvs,cvs,CVS,dc_cvs,BOOLEAN,CH2:CH500,,Boolean indicating if cardiovascular system is healthy,c27ba0 +,doctorsconsultation,FALSE,respi,Respi,respi,Respi,dc_respi,BOOLEAN,CI2:CI500,,Boolean indicating if respiratory system is healthy,c27ba0 +,doctorsconsultation,FALSE,gu,Gu,gu,GU,dc_gu,BOOLEAN,CJ2:CJ500,,Boolean indicating if genitourinary system is healthy,c27ba0 +,doctorsconsultation,FALSE,git,Git,git,GIT,dc_git,BOOLEAN,CK2:CK500,,Boolean indicating if gastrointestinal system is healthy,c27ba0 +,doctorsconsultation,FALSE,eye,Eye,eye,EYE,dc_eye,BOOLEAN,CL2:CL500,,Boolean indicating if eye health is satisfactory,c27ba0 +,doctorsconsultation,FALSE,derm,Derm,derm,DERM,dc_derm,BOOLEAN,CM2:CM500,,Boolean indicating if dermatological health is satisfactory,c27ba0 +,doctorsconsultation,FALSE,others,Others,others,DC OTHERS,dc_others,TEXT,CN2:CN500,,Details of other relevant health assessments,c27ba0 +,doctorsconsultation,FALSE,consultation_notes,ConsultationNotes,consultationNotes,Consultation Notes,dc_consultation_notes,TEXT,CO2:CO500,,General notes from the consultation,c27ba0 +,doctorsconsultation,FALSE,diagnosis,Diagnosis,diagnosis,Diagnosis,dc_diagnosis,TEXT,CP2:CP500,,Diagnosis provided during consultation,c27ba0 +,doctorsconsultation,FALSE,treatment,Treatment,treatment,Treatment,dc_treatment,TEXT,CQ2:CQ500,,Treatment plan or recommendations,c27ba0 +,doctorsconsultation,TRUE,referral_needed,ReferralNeeded,referralNeeded,Referral Needed?*,dc_referral_needed,BOOLEAN,CR2:CR500,,Boolean indicating if a referral is needed,c27ba0 +,doctorsconsultation,FALSE,referral_loc,ReferralLoc,referralLoc,Referral Location,dc_referral_loc,TEXT,CS2:CS500,,"Location or details for the referral, if needed",c27ba0 +,doctorsconsultation,FALSE,remarks,Remarks,remarks,Remarks (anything that doesn't fit),dc_remarks,TEXT,CT2:CT500,,Additional remarks or comments,c27ba0 +Physiotherapy,physiotherapy,TRUE,pain_stiffness_day,PainStiffnessDay,painStiffnessDay,"Pain/stiffness during the day: How severe was your usual joint or muscle pain and/or stiffness overall during the day in the last 2 weeks? (0,1,2,3,4,5)*",p_pain_stiffness_day,INTEGER,CU2:CU500,"0,1,2,3,4,5",,999999 +,physiotherapy,TRUE,pain_stiffness_night,PainStiffnessNight,painStiffnessNight,"Pain/stiffness during the night: How severe was your usual joint or muscle pain and/or stiffness overall during the night in the last 2 weeks? (0,1,2,3,4,5)*",p_pain_stiffness_night,INTEGER,CV2:CV500,"0,1,2,3,4,5",,999999 +,physiotherapy,TRUE,symptoms_interfere_tasks,SymptomsInterfereTasks,symptomsInterfereTasks,"How much has your symptoms interfered with your ability to walk or do everyday tasks like cooking, cleaning or dressing in the last 2 weeks? (Never,Rarely,Sometimes,Often,Always)*",p_symptoms_interfere_tasks,TEXT,CW2:CW500,"Never,Rarely,Sometimes,Often,Always",,999999 +,physiotherapy,TRUE,symptoms_change,SymptomsChange,symptomsChange,"Have your symptoms improved, worsened, or stayed the same over the last 2 weeks? (Improved,Worsened,Stayed the same)*",p_symptoms_change,TEXT,CX2:CX500,"Improved,Worsened,Stayed the same",,999999 +,physiotherapy,TRUE,symptoms_need_help,SymptomsNeedHelp,symptomsNeedHelp,"How often have you needed help from others (including family, friends or carers) because of your joint or muscle symptoms in the last 2 weeks? (Never,Rarely,Sometimes,Often,Always)*",p_symptoms_need_help,TEXT,CY2:CY500,"Never,Rarely,Sometimes,Often,Always",,999999 +,physiotherapy,TRUE,trouble_sleep_symptoms,TroubleSleepSymptoms,troubleSleepSymptoms,"How often have you had trouble with either falling asleep or staying asleep because of your joint or muscle symptoms in the last 2 weeks? (Never,Rarely,Sometimes,Often,Always)*",p_trouble_sleep_symptoms,TEXT,CZ2:CZ500,"Never,Rarely,Sometimes,Often,Always",,999999 +,physiotherapy,TRUE,how_much_fatigue,HowMuchFatigue,howMuchFatigue,"How much fatigue or low energy have you felt in the last 2 weeks? (0,1,2,3,4,5)*",p_how_much_fatigue,INTEGER,DA2:DA500,"0,1,2,3,4,5",,999999 +,physiotherapy,TRUE,anxious_low_mood,AnxiousLowMood,anxiousLowMood,"How much have you felt anxious or low in your mood because of your joint or muscle symptoms in the last 2 weeks? (0,1,2,3,4,5)*",p_anxious_low_mood,INTEGER,DB2:DB500,"0,1,2,3,4,5",,999999 +,physiotherapy,TRUE,medication_manage_symptoms,MedicationManageSymptoms,medicationManageSymptoms,"Have you used any medication to manage your symptoms in the last 2 weeks? If yes, how often? (Never,Rarely,Sometimes,Often,Always)*",p_medication_manage_symptoms,TEXT,DC2:DC500,"Never,Rarely,Sometimes,Often,Always",,999999