from datetime import date, datetime from abc import ABC from django.core.exceptions import ValidationError class DateValidator: @staticmethod def past_date(value: date, name: str = "date"): if value > date.today(): raise ValidationError(f"The {name} cannot be in the future.") @staticmethod def past_datetime(value: datetime, name: str = "timestamp"): if value > datetime.now(): raise ValidationError(f"The {name} cannot be in the future.") class PersonValidator: @staticmethod def date_of_birth(value): DateValidator.past_date(value, "date of birth") class AbstractRecordValidator(ABC): @staticmethod def recorded(value): DateValidator.past_datetime(value, "time when the value was recorded") class BloodPressureRecordValidator(AbstractRecordValidator): MIN_VALUE_SYSTOLIC_MMHG = 0 MAX_VALUE_SYSTOLIC_MMHG = 1000 MIN_VALUE_DIASTOLIC_MMHG = 0 MAX_VALUE_DIASTOLIC_MMHG = 1000 @staticmethod def value_systolic_mmhg(value: int): if value < BloodPressureRecordValidator.MIN_VALUE_SYSTOLIC_MMHG: raise ValidationError(f"Systolic Blood Pressure cannot be below {BloodPressureRecordValidator.MIN_VALUE_SYSTOLIC_MMHG}") if value > BloodPressureRecordValidator.MAX_VALUE_SYSTOLIC_MMHG: raise ValidationError(f"Systolic Blood Pressure cannot be above {BloodPressureRecordValidator.MAX_VALUE_SYSTOLIC_MMHG}") @staticmethod def value_diastolic_mmhg(value: int): if value < BloodPressureRecordValidator.MIN_VALUE_DIASTOLIC_MMHG: raise ValidationError(f"Diastolic Blood Pressure cannot be below {BloodPressureRecordValidator.MIN_VALUE_DIASTOLIC_MMHG}") if value > BloodPressureRecordValidator.MAX_VALUE_DIASTOLIC_MMHG: raise ValidationError(f"Diastolic Blood Pressure cannot be above {BloodPressureRecordValidator.MAX_VALUE_DIASTOLIC_MMHG}") class BodyTempRecordValidator(AbstractRecordValidator): MIN_VALUE_CELSIUS = 0 MAX_VALUE_CELSIUS = 100 @staticmethod def value_celsius(value: int): if value < BodyTempRecordValidator.MIN_VALUE_CELSIUS: raise ValidationError(f"Body Temperature cannot be below {BodyTempRecordValidator.MIN_VALUE_CELSIUS}") if value > BodyTempRecordValidator.MAX_VALUE_CELSIUS: raise ValidationError(f"Body Temperature cannot be above {BodyTempRecordValidator.MAX_VALUE_CELSIUS}") class HeartRateRecordValidator(AbstractRecordValidator): MIN_VALUE_BPM = 0 MAX_VALUE_BPM = 1000 @staticmethod def value_bpm(value: int): if value < HeartRateRecordValidator.MIN_VALUE_BPM: raise ValidationError(f"Heart Rate cannot be below {HeartRateRecordValidator.MIN_VALUE_BPM}") if value > HeartRateRecordValidator.MAX_VALUE_BPM: raise ValidationError(f"Heart Rate cannot be above {HeartRateRecordValidator.MAX_VALUE_BPM}") class RespirationScoreRecordValidator(AbstractRecordValidator): MIN_VALUE_SEVERITY = 0 MAX_VALUE_SEVERITY = 2 @staticmethod def value_severity(value: int): if value < RespirationScoreRecordValidator.MIN_VALUE_SEVERITY: raise ValidationError(f"Respiratory Inhibition Severity cannot be below {RespirationScoreRecordValidator.MIN_VALUE_SEVERITY}") if value > RespirationScoreRecordValidator.MAX_VALUE_SEVERITY: raise ValidationError(f"Respiratory Inhibition Severity cannot be above {RespirationScoreRecordValidator.MAX_VALUE_SEVERITY}") class Spo2LevelRecordValidator(AbstractRecordValidator): MIN_VALUE_PERCENT = 0 MAX_VALUE_PERCENT = 100 @staticmethod def value_percent(value: int): if value < Spo2LevelRecordValidator.MIN_VALUE_PERCENT: raise ValidationError(f"SPO2 cannot be below {Spo2LevelRecordValidator.MIN_VALUE_PERCENT}") if value > Spo2LevelRecordValidator.MAX_VALUE_PERCENT: raise ValidationError(f"SPO2 cannot be above {Spo2LevelRecordValidator.MAX_VALUE_PERCENT}") class MewsRecordValidator(AbstractRecordValidator): MIN_VALUE_N = 0 MAX_VALUE_N = 100 @staticmethod def value_n(value: int): if value < MewsRecordValidator.MIN_VALUE_N: raise ValidationError(f"MEWS cannot be below {MewsRecordValidator.MIN_VALUE_N}") if value > MewsRecordValidator.MAX_VALUE_N: raise ValidationError(f"MEWS cannot be above {MewsRecordValidator.MAX_VALUE_N}")