Skip to content

Models

Dependencies

SingletonModel

Model representing a singleton model.

Attributes:

Source code in backend/api/models.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class SingletonModel(models.Model):
    """
    Model representing a singleton model.

    Attributes:
    """

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        """
        Override save method to validate only one instance exists.
        """
        if not self.pk and self.__class__.objects.exists():
            raise ValidationError("There is already one instance of this model")
        return super(SingletonModel, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        """
        Override delete method to block deletes.
        """
        raise ValidationError("You cannot delete this object")

save(*args, **kwargs)

Override save method to validate only one instance exists.

Source code in backend/api/models.py
23
24
25
26
27
28
29
def save(self, *args, **kwargs):
    """
    Override save method to validate only one instance exists.
    """
    if not self.pk and self.__class__.objects.exists():
        raise ValidationError("There is already one instance of this model")
    return super(SingletonModel, self).save(*args, **kwargs)

delete(*args, **kwargs)

Override delete method to block deletes.

Source code in backend/api/models.py
31
32
33
34
35
def delete(self, *args, **kwargs):
    """
    Override delete method to block deletes.
    """
    raise ValidationError("You cannot delete this object")

CustomUser

Custom user object using AbstractUser.

Attributes:

Name Type Description
username

The username of the user.

email EmailField

The email of the user. Unique.

profile_picture ImageField

An image to use as the user profile picture.

male BooleanField

True if the user is male.

user_color ColorField

A color used to represent the user.

Source code in backend/api/models.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class CustomUser(AbstractUser):
    """
    Custom user object using AbstractUser.

    Attributes:
        username (): The username of the user.
        email (EmailField): The email of the user. Unique.
        profile_picture (ImageField): An image to use as the user profile
            picture.
        male (BooleanField): True if the user is male.
        user_color (ColorField): A color used to represent the user.
    """

    COLOR_PALETTE = [
        ("#E91E63", "Color1"),
        ("#3F51B5", "Color2"),
        ("#009688", "Color3"),
        ("#CDDC39", "Color4"),
    ]
    username = None
    email = models.EmailField("email address", unique=True)
    profile_picture = models.ImageField(
        upload_to=user_profile_picture_upload, blank=True, null=True
    )
    male = models.BooleanField(default=True)
    user_color = ColorField(default="#E91E63", samples=COLOR_PALETTE)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def __str__(self):
        """
        Returns:
            (String): The user's email address.
        """
        return self.email

    @property
    def fullname(self):
        fullname = self.first_name + " " + self.last_name
        return fullname

__str__()

Returns:

Type Description
String

The user's email address.

Source code in backend/api/models.py
79
80
81
82
83
84
def __str__(self):
    """
    Returns:
        (String): The user's email address.
    """
    return self.email

Area Group

AreaGroup

Model representing an area group.

Attributes:

Name Type Description
group_name CharField

The name of the group. Max=254.

group_order IntegerField

The order index of the group. Default=1.

group_color CharField

A hex value of a color to represent the group. Max=12.

Source code in backend/api/models.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
class AreaGroup(models.Model):
    """
    Model representing an area group.

    Attributes:
        group_name (CharField): The name of the group. Max=254.
        group_order (IntegerField): The order index of the group. Default=1.
        group_color (CharField): A hex value of a color to represent the group. Max=12.
    """

    group_name = models.CharField(max_length=254)
    group_order = models.IntegerField(default=1)
    group_color = models.CharField(max_length=12)

    def __str__(self):
        """
        Returns:
            (String): The area group name.
        """
        return self.group_name

__str__()

Returns:

Type Description
String

The area group name.

Source code in backend/api/models.py
106
107
108
109
110
111
def __str__(self):
    """
    Returns:
        (String): The area group name.
    """
    return self.group_name

Area

Area

Model representing an area.

Attributes:

Name Type Description
area_name CharField

The name of a store. Max=254

area_icon CharField

The name of an icon to use. Max=254

group AreaGroup

An area group object.

area_order IntegerField

The order index of the area.

Source code in backend/api/models.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
class Area(models.Model):
    """
    Model representing an area.

    Attributes:
        area_name (CharField): The name of a store. Max=254
        area_icon (CharField): The name of an icon to use. Max=254
        group (AreaGroup): An area group object.
        area_order (IntegerField): The order index of the area.
    """

    area_name = models.CharField(max_length=254)
    area_icon = models.CharField(max_length=254)
    group = models.ForeignKey(
        AreaGroup, null=True, on_delete=models.SET_DEFAULT, default=1
    )
    area_order = models.IntegerField(default=1)

    def __str__(self):
        """
        Returns:
            (String): The Area Object name.
        """
        return self.area_name

    @property
    def dirtiness(self):
        """
        Calculates the dirtiness percentage of an area.

        Returns:
            percentage (integer): The dirtiness of an area as a percentage.
        """
        total_dirtiness = self.total_dirtiness()
        total_chores = self.chore_set.filter(status=0).count()

        if total_chores > 0:
            # Calculate the percentage if there are chores
            percentage = total_dirtiness / total_chores
            perecentage = round(percentage)
        else:
            # Handle the case when there are no chores
            percentage = 0

        return percentage

    @property
    def dueCount(self):
        """
        Determines the number of chores due for this area.

        Returns:
            count (integer): The count of chores due for this area.
        """
        today = date.today().isoformat()
        count = self.chore_set.filter(status=0, nextDue__lte=today).count()
        return count

    @property
    def totalCount(self):
        """
        Calculates the total chores in this area.

        Returns:
            count (integer): The total count of chores for this area.
        """
        count = self.chore_set.filter(status=0).count()
        return count

    def total_dirtiness(self):
        """
        Returns:
            total (integer): The total dirtiness of an area.
        """
        total = sum(
            chore.dirtiness for chore in self.chore_set.filter(status=0)
        )
        return total

dirtiness property

Calculates the dirtiness percentage of an area.

Returns:

Name Type Description
percentage integer

The dirtiness of an area as a percentage.

dueCount property

Determines the number of chores due for this area.

Returns:

Name Type Description
count integer

The count of chores due for this area.

totalCount property

Calculates the total chores in this area.

Returns:

Name Type Description
count integer

The total count of chores for this area.

total_dirtiness()

Returns:

Name Type Description
total integer

The total dirtiness of an area.

Source code in backend/api/models.py
183
184
185
186
187
188
189
190
191
def total_dirtiness(self):
    """
    Returns:
        total (integer): The total dirtiness of an area.
    """
    total = sum(
        chore.dirtiness for chore in self.chore_set.filter(status=0)
    )
    return total

Month

Month

Model representing a month.

Attributes:

Name Type Description
name CharField

The name of the month. Max=20

Source code in backend/api/models.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
class Month(models.Model):
    """
    Model representing a month.

    Attributes:
        name (CharField): The name of the month. Max=20
    """

    name = models.CharField(max_length=20)

    def __str__(self):
        """
        Returns:
            (String): The Month Object name.
        """
        return self.name

__str__()

Returns:

Type Description
String

The Month Object name.

Source code in backend/api/models.py
204
205
206
207
208
209
def __str__(self):
    """
    Returns:
        (String): The Month Object name.
    """
    return self.name

Chore

Chore

Model representing a month.

Attributes:

Name Type Description
chore_name CharField

The name of the chore. Max=254

area Area

An area object.

nextDue DateField

The date chore is next due. Default=Today

lastCompleted DateField

The date chore was last completed. Default=Today.

intervalNumber integer

The repeat interval. Default=1.

unit CharField

The unit of the repeat intervals. Default="day(s)".

active_months Month

An array of Months chore is active.

assignee CustomUser

A CustomUser object assigned to chore. Default=None.

effort IntegerField

How difficult the task is. Default=0.

vacationPause IntegerField

Default=0.

expand BooleanField

Default=False.

status IntegerField

The status of the chore. Default=0.

Source code in backend/api/models.py
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
class Chore(models.Model):
    """
    Model representing a month.

    Attributes:
        chore_name (CharField): The name of the chore. Max=254
        area (Area): An area object.
        nextDue (DateField): The date chore is next due. Default=Today
        lastCompleted (DateField): The date chore was last completed. Default=Today.
        intervalNumber (integer): The repeat interval. Default=1.
        unit (CharField): The unit of the repeat intervals. Default="day(s)".
        active_months (Month): An array of Months chore is active.
        assignee (CustomUser): A CustomUser object assigned to chore. Default=None.
        effort (IntegerField): How difficult the task is. Default=0.
        vacationPause (IntegerField): Default=0.
        expand (BooleanField): Default=False.
        status (IntegerField): The status of the chore. Default=0.
    """

    chore_name = models.CharField(max_length=254)
    area = models.ForeignKey(Area, null=True, on_delete=models.CASCADE)
    nextDue = models.DateField(default=date.today)
    lastCompleted = models.DateField(default=date.today)
    intervalNumber = models.IntegerField(default=1)
    unit = models.CharField(max_length=10, default="day(s)")
    active_months = models.ManyToManyField(Month)
    assignee = models.ForeignKey(
        CustomUser,
        null=True,
        on_delete=models.SET_NULL,
        blank=True,
        default=None,
    )
    effort = models.IntegerField(default=0)
    vacationPause = models.IntegerField(default=0)
    expand = models.BooleanField(default=False)
    status = models.IntegerField(default=0)

    def __str__(self):
        """
        Returns:
            (String): The Chore Object name.
        """
        return self.chore_name

    @property
    def dirtiness(self):
        """
        Calculates how dirty the chore is.

        Returns:
            dirtiness (integer): The dirtiness of the chore.
        """
        timesincedone = self.lastCompleted - date.today()
        timeperiod = self.lastCompleted - self.nextDue
        if timeperiod.days == 0:
            dirtiness = 0
        else:
            dirtiness = round((timesincedone.days / timeperiod.days) * 100)
            if dirtiness > 100:
                dirtiness = 100
        return dirtiness

    @property
    def duedays(self):
        """
        Calculates the days until chore is due.

        Returns:
            (integer): The days until chore is due.
        """
        delta = self.nextDue - date.today()
        return delta.days

dirtiness property

Calculates how dirty the chore is.

Returns:

Name Type Description
dirtiness integer

The dirtiness of the chore.

duedays property

Calculates the days until chore is due.

Returns:

Type Description
integer

The days until chore is due.

HistoryItem

HistoryItem

Model representing a history item for a chore.

Attributes:

Name Type Description
completed_date DateField

The date a chore was completed. Default=Today.

completed_by CustomUser

The user object who completed the chore.

chore Chore

The chore object.

Source code in backend/api/models.py
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
class HistoryItem(models.Model):
    """
    Model representing a history item for a chore.

    Attributes:
        completed_date (DateField): The date a chore was completed. Default=Today.
        completed_by (CustomUser): The user object who completed the chore.
        chore (Chore): The chore object.
    """

    completed_date = models.DateField(default=date.today)
    completed_by = models.ForeignKey(
        CustomUser, null=True, on_delete=models.SET_NULL
    )
    chore = models.ForeignKey(Chore, on_delete=models.CASCADE)

Option

Option

Model representing an option.

Attributes:

Name Type Description
vacation_mode BooleanField

Is vacation mode active or not. Default=False.

med_thresh IntegerField

The medium threshold for dirtiness. Default=50.

high_thresh IntegerField

The high threshold for dirtiness. Default=50.

Source code in backend/api/models.py
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
class Option(SingletonModel):
    """
    Model representing an option.

    Attributes:
        vacation_mode (BooleanField): Is vacation mode active or not. Default=False.
        med_thresh (IntegerField): The medium threshold for dirtiness. Default=50.
        high_thresh (IntegerField): The high threshold for dirtiness. Default=50.
    """

    vacation_mode = models.BooleanField(default=False)
    med_thresh = models.IntegerField(default=50)
    high_thresh = models.IntegerField(default=50)

    def __str__(self):
        """
        Returns:
            (String): The option object.
        """
        return "Options"

    @classmethod
    def load(cls):
        return cls.objects.first()

__str__()

Returns:

Type Description
String

The option object.

Source code in backend/api/models.py
318
319
320
321
322
323
def __str__(self):
    """
    Returns:
        (String): The option object.
    """
    return "Options"

Version

Version

Model representing app version.

Fields: - version_number (CharField): The current version of the app.

Source code in backend/api/models.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
class Version(SingletonModel):
    """
    Model representing app version.

    Fields:
    - version_number (CharField): The current version of the app.
    """

    version_number = models.CharField(max_length=10)

    def __str__(self):
        """
        Returns:
            (String): The app version number.
        """
        return self.version_number

__str__()

Returns:

Type Description
String

The app version number.

Source code in backend/api/models.py
340
341
342
343
344
345
def __str__(self):
    """
    Returns:
        (String): The app version number.
    """
    return self.version_number