~homeworkprod/byceps

ref: 4237b3ec9496efe95dcce82bea3207ab9de4d520 byceps/byceps/services/user/models/detail.py -rw-r--r-- 2.3 KiB
4237b3ec — Jochen Kupperschmidt Move ticketing blueprint into `site` subpackage 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
"""
byceps.services.user.models.detail
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from datetime import date
from typing import Optional

from sqlalchemy.ext.mutable import MutableDict

from ....database import db
from ....util.datetime.calc import calculate_age, calculate_days_until
from ....util.datetime.monthday import MonthDay
from ....util.instances import ReprBuilder


class UserDetail(db.Model):
    """Detailed information about a specific user."""

    __tablename__ = 'user_details'

    user_id = db.Column(db.Uuid, db.ForeignKey('users.id'), primary_key=True)
    user = db.relationship('User', backref=db.backref('detail', uselist=False))
    first_names = db.Column(db.UnicodeText)
    last_name = db.Column(db.UnicodeText)
    date_of_birth = db.Column(db.Date)
    country = db.Column(db.UnicodeText)
    zip_code = db.Column(db.UnicodeText)
    city = db.Column(db.UnicodeText)
    street = db.Column(db.UnicodeText)
    phone_number = db.Column(db.UnicodeText)
    internal_comment = db.Column(db.UnicodeText)
    extras = db.Column(MutableDict.as_mutable(db.JSONB))

    @property
    def full_name(self) -> Optional[str]:
        names = [self.first_names, self.last_name]
        return ' '.join(filter(None, names)) or None

    @property
    def age(self) -> Optional[int]:
        """Return the user's current age."""
        if self.date_of_birth is None:
            return None

        return calculate_age(self.date_of_birth, date.today())

    @property
    def days_until_next_birthday(self) -> Optional[int]:
        """Return the number of days until the user's next birthday."""
        if self.date_of_birth is None:
            return None

        return calculate_days_until(self.date_of_birth, date.today())

    @property
    def is_birthday_today(self) -> Optional[bool]:
        """Return `True` if today is the user's birthday."""
        if self.date_of_birth is None:
            return None

        return MonthDay.of(self.date_of_birth).matches(date.today())

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('user_id') \
            .add_with_lookup('first_names') \
            .add_with_lookup('last_name') \
            .build()