1
1
"""Object model."""
2
2
3
- import email
4
- from typing import Optional , List , Dict , Type
5
- from pydantic import constr , BaseModel , condecimal
6
- from enum import Enum
3
+ from typing import Dict , List , Optional , Type
4
+
5
+ import re
7
6
import datetime
7
+ import decimal
8
+ import email
8
9
import hashlib
9
- import uuid
10
+ import string
10
11
import textwrap
12
+ import uuid
13
+ from decimal import Decimal
14
+ from enum import Enum
11
15
16
+ import pandas
12
17
import sqlalchemy
13
- from sqlmodel import (
14
- SQLModel ,
15
- Field ,
16
- Relationship ,
17
- )
18
18
19
19
# from pydantic import str
20
- import decimal
21
- from decimal import Decimal
22
- import pandas
23
-
24
-
25
- from .time import Cycle , TimeUnit
20
+ from pydantic import BaseModel , condecimal , constr , validator
21
+ from sqlmodel import Field , Relationship , SQLModel , Constraint
26
22
27
23
from .dev import deprecated
24
+ from .time import Cycle , TimeUnit
28
25
29
26
30
27
def help (model_class ):
@@ -369,8 +366,10 @@ class Project(SQLModel, table=True):
369
366
description : str = Field (
370
367
description = "A longer description of the project" , default = ""
371
368
)
372
- # TODO: tag: constr(regex=r"#\S+")
373
- tag : str = Field (description = "A unique tag" , sa_column_kwargs = {"unique" : True })
369
+ tag : str = Field (
370
+ description = "A unique tag, starting with a # symbol" ,
371
+ sa_column_kwargs = {"unique" : True },
372
+ )
374
373
start_date : datetime .date
375
374
end_date : datetime .date
376
375
is_completed : bool = Field (
@@ -393,13 +392,24 @@ class Project(SQLModel, table=True):
393
392
sa_relationship_kwargs = {"lazy" : "subquery" },
394
393
)
395
394
395
+ # PROPERTIES
396
396
@property
397
397
def client (self ) -> Optional [Client ]:
398
398
if self .contract :
399
399
return self .contract .client
400
400
else :
401
401
return None
402
402
403
+ # VALIDATORS
404
+ @validator ("tag" )
405
+ def validate_tag (cls , v ):
406
+ if not re .match (r"^#\S+$" , v ):
407
+ raise ValueError (
408
+ "Tag must start with a # symbol and not contain any punctuation or whitespace."
409
+ )
410
+ return v
411
+
412
+ @deprecated
403
413
def get_brief_description (self ):
404
414
if len (self .description ) <= 108 :
405
415
return self .description
@@ -420,6 +430,7 @@ def is_upcoming(self) -> bool:
420
430
today = datetime .date .today ()
421
431
return self .start_date > today
422
432
433
+ # FIXME: replace string literals with enum
423
434
def get_status (self , default : str = "" ) -> str :
424
435
if self .is_active ():
425
436
return "Active"
0 commit comments