|
|
@@ -2,13 +2,26 @@ from pyplanner.database import SQLABase
|
|
|
from pyplanner.models import Base
|
|
|
from sqlalchemy import Column, Integer, String, Text, ForeignKey
|
|
|
from sqlalchemy.orm import relationship, backref
|
|
|
+from sqlalchemy.ext.hybrid import hybrid_property
|
|
|
from pydantic import BaseModel
|
|
|
from enum import Enum
|
|
|
from functools import total_ordering
|
|
|
|
|
|
|
|
|
+class BaseEnum:
|
|
|
+ @classmethod
|
|
|
+ def to_yaml(cls, representer, node):
|
|
|
+ return representer.represent_scalar(
|
|
|
+ node.value
|
|
|
+ )
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def from_yaml(cls, constructor, node):
|
|
|
+ return cls(node)
|
|
|
+
|
|
|
+
|
|
|
@total_ordering
|
|
|
-class Length(Enum):
|
|
|
+class Length(BaseEnum, Enum):
|
|
|
MINUTES = 'mi'
|
|
|
SEVERAL_MINUTES = 'mi+'
|
|
|
HOURS = 'h'
|
|
|
@@ -21,7 +34,7 @@ class Length(Enum):
|
|
|
SEVERAL_MONTHS = 'mo+'
|
|
|
|
|
|
def __add__(self, other):
|
|
|
- all_values = list(Length.__members__.values())
|
|
|
+ all_values = list(Length)
|
|
|
if self == other and '+' not in self.value:
|
|
|
return Length(f'{self.value}+')
|
|
|
elif self.value in other.value:
|
|
|
@@ -37,20 +50,35 @@ class Length(Enum):
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
def __lt__(self, other):
|
|
|
- all_values = list(Length.__members__.values())
|
|
|
+ all_values = list(Length)
|
|
|
return all_values.index(self) < all_values.index(other)
|
|
|
|
|
|
|
|
|
+class ItemType(BaseEnum, Enum):
|
|
|
+ ITEM = 'none'
|
|
|
+ LIMITATION = 'lim'
|
|
|
+ FEATURE = 'feat'
|
|
|
+ CONSTRAINT = 'cons'
|
|
|
+ UNKNOWN = 'unk'
|
|
|
+
|
|
|
+
|
|
|
+class ItemPriority(BaseEnum, Enum):
|
|
|
+ VERY_NOT_IMPORTANT = '--'
|
|
|
+ NOT_IMPORTANT = '-'
|
|
|
+ SO_SO = '='
|
|
|
+ IMPORTANT = '+'
|
|
|
+ VERY_IMPORTANT = '++'
|
|
|
+
|
|
|
+
|
|
|
class SchemaItem(BaseModel):
|
|
|
name: str
|
|
|
description: str
|
|
|
- type: str
|
|
|
+ type: ItemType
|
|
|
uuid: str
|
|
|
|
|
|
- milestone_id: int
|
|
|
- sprint_id: int
|
|
|
+ collection_id: int
|
|
|
|
|
|
- priority: str
|
|
|
+ priority: ItemPriority = ItemPriority.SO_SO
|
|
|
length: Length = Length.DAYS
|
|
|
|
|
|
|
|
|
@@ -63,42 +91,76 @@ class Item(SQLABase, Base):
|
|
|
name = Column(String)
|
|
|
description = Column(Text)
|
|
|
uuid = Column(String)
|
|
|
- type = Column(String)
|
|
|
+ _type = Column(String)
|
|
|
+
|
|
|
+ collection_id = Column(Integer, ForeignKey('collections.id'))
|
|
|
+ collection = relationship('Collection', backref=backref('items'))
|
|
|
+
|
|
|
+ _priority = Column(String)
|
|
|
+ _length = Column(String)
|
|
|
+
|
|
|
+ @hybrid_property
|
|
|
+ def type(self):
|
|
|
+ return ItemType(self._type)
|
|
|
+
|
|
|
+ @type.setter
|
|
|
+ def type(self, value):
|
|
|
+ self._type = value.value
|
|
|
+
|
|
|
+ @type.expression
|
|
|
+ def type(cls):
|
|
|
+ return cls._type
|
|
|
+
|
|
|
+ @hybrid_property
|
|
|
+ def length(self):
|
|
|
+ return Length(self._length)
|
|
|
+
|
|
|
+ @length.setter
|
|
|
+ def length(self, value):
|
|
|
+ self._length = value.value
|
|
|
+
|
|
|
+ @length.expression
|
|
|
+ def length(cls):
|
|
|
+ return cls._length
|
|
|
|
|
|
- milestone_id = Column(Integer, ForeignKey('milestones.id'))
|
|
|
- milestone = relationship('Milestone', backref=backref('items'))
|
|
|
+ @hybrid_property
|
|
|
+ def priority(self):
|
|
|
+ return ItemPriority(self._priority)
|
|
|
|
|
|
- sprint_id = Column(Integer, ForeignKey('sprints.id'))
|
|
|
- sprint = relationship('Sprint', backref=backref('items'))
|
|
|
+ @priority.setter
|
|
|
+ def priority(self, value):
|
|
|
+ self._priority = value.value
|
|
|
|
|
|
- priority = Column(String)
|
|
|
- length = Column(String)
|
|
|
+ @priority.expression
|
|
|
+ def priority(cls):
|
|
|
+ return cls._priority
|
|
|
|
|
|
__mapper_args__ = {
|
|
|
- 'polymorphic_on': type,
|
|
|
- 'polymorphic_identity': 'item'
|
|
|
+ 'polymorphic_on': _type,
|
|
|
+ 'polymorphic_identity': ItemType.ITEM.value,
|
|
|
+ 'with_polymorphic': '*'
|
|
|
}
|
|
|
|
|
|
|
|
|
class Limitation(Item):
|
|
|
__mapper_args__ = {
|
|
|
- 'polymorphic_identity': 'limitation'
|
|
|
+ 'polymorphic_identity': ItemType.LIMITATION.value
|
|
|
}
|
|
|
|
|
|
|
|
|
class Feature(Item):
|
|
|
__mapper_args__ = {
|
|
|
- 'polymorphic_identity': 'feature'
|
|
|
+ 'polymorphic_identity': ItemType.FEATURE.value
|
|
|
}
|
|
|
|
|
|
|
|
|
class Constraint(Item):
|
|
|
__mapper_args__ = {
|
|
|
- 'polymorphic_identity': 'constraint'
|
|
|
+ 'polymorphic_identity': ItemType.CONSTRAINT.value
|
|
|
}
|
|
|
|
|
|
|
|
|
class Unknown(Item):
|
|
|
__mapper_args__ = {
|
|
|
- 'polymorphic_identity': 'unknown'
|
|
|
+ 'polymorphic_identity': ItemType.UNKNOWN.value
|
|
|
}
|