kumify/health/models.py

101 lines
3.7 KiB
Python
Raw Permalink Normal View History

from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from datetime import time, date
from dateutil.relativedelta import relativedelta
class MedicationSettings(models.Model):
user = models.ForeignKey(get_user_model(), models.CASCADE)
morning_from = models.TimeField(default=time(6))
morning_till = models.TimeField(default=time(10))
noon_from = models.TimeField(default=time(12))
noon_till = models.TimeField(default=time(14))
evening_from = models.TimeField(default=time(19))
evening_till = models.TimeField(default=time(21))
night_from = models.TimeField(default=time(22))
night_till = models.TimeField(default=time(23))
notifications = models.BooleanField(default=True)
refill_reminder = models.PositiveSmallIntegerField(default=7)
class Medication(models.Model):
user = models.ForeignKey(get_user_model(), models.CASCADE)
name = models.CharField(max_length=128)
icon = models.CharField(max_length=64, default="fas fa-tablets")
supply = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)
default_refill = models.PositiveSmallIntegerField(default=1)
prn = models.BooleanField(default=False)
remarks = models.TextField(null=True, blank=True)
class ScheduleChoices(models.IntegerChoices):
DAYS = 0
WEEKS = 1
MONTHS = 2
class MedicationSchedule(models.Model):
medication = models.ForeignKey(Medication, models.CASCADE)
cycle_type = models.IntegerField(choices=ScheduleChoices.choices)
cycle_count = models.IntegerField(default=1)
first = models.DateField(default=date.today)
last = models.DateField(null=True, blank=True)
morning = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)
noon = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)
evening = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)
night = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)
def next(self, today=True):
if timezone.now().date() > self.last:
return False
cur = self.first
while True:
if (timezone.now().date() < cur) or (today and timezone.now().date() == cur):
return cur
cur += relativedelta(
days=self.cycle_count if self.cycle_type == ScheduleChoices.DAYS else 0,
weeks=self.cycle_count if self.cycle_type == ScheduleChoices.WEEKS else 0,
months=self.cycle_count if self.cycle_type == ScheduleChoices.MONTHS else 0
)
if cur > self.last:
return False
class MedicationCalendar(models.Model):
class TimeChoices(models.IntegerChoices):
MORNING = 0
NOON = 1
EVENING = 2
NIGHT = 3
date = models.DateField(default=date.today)
time = models.IntegerField(choices=TimeChoices.choices)
medication = models.ForeignKey(Medication, models.CASCADE)
schedule = models.ForeignKey(MedicationSchedule, models.SET_NULL, null=True)
count = models.DecimalField(max_digits=5, decimal_places=2)
taken = models.BooleanField(default=False)
class HealthParameter(models.Model):
user = models.ForeignKey(get_user_model(), models.CASCADE)
name = models.CharField(max_length=128)
icon = models.CharField(max_length=64, default="fas fa-heart")
unit = models.CharField(max_length=12, null=True, blank=True)
class HealthRecord(models.Model):
parameter = models.ForeignKey(HealthParameter, models.CASCADE)
value = models.DecimalField(max_digits=12, decimal_places=6, null=True, blank=True)
comment = models.TextField(null=True, blank=True)