Browse Source

Add item handling

theenglishway (time) 6 năm trước cách đây
mục cha
commit
4c9728c667
4 tập tin đã thay đổi với 107 bổ sung19 xóa
  1. 45 15
      planner/cli.py
  2. 3 1
      planner/models/__init__.py
  3. 53 0
      planner/models/items.py
  4. 6 3
      planner/models/mixins.py

+ 45 - 15
planner/cli.py

@@ -22,6 +22,22 @@ def sprint(ctx):
     """Handle sprints"""
     ctx.obj['model'] = Sprint
 
+@main.group()
+@click.pass_context
+def item(ctx):
+    """Handle items"""
+    ctx.obj['model'] = Item
+
+def save_or_display_errors(model, data):
+    ok, m_doc = model.validate(data)
+    if ok :
+        m = model.get(m_doc)
+        click.secho(f"{m} was successfully added", fg='green')
+        m.save()
+    else:
+        click.secho(f"Errors : {m_doc}", fg='red')
+
+
 @milestone.command('new')
 @click.option('--name', prompt='Milestone name')
 @click.option('--description', prompt='Milestone description')
@@ -33,13 +49,7 @@ def new_milestone(ctx, name, description):
         'name': name,
         'description': description
     }
-    ok, m_doc = model.validate(data)
-    if ok :
-        m = model.get(m_doc)
-        click.secho(f"{m} was successfully added", fg='green')
-        m.save()
-    else:
-        click.secho(f"Errors : {m_doc}", fg='red')
+    save_or_display_errors(model, data)
 
 @sprint.command('new')
 @click.option('--name', prompt='Sprint name')
@@ -54,13 +64,32 @@ def new_sprint(ctx, name, description, milestone_id):
         'description': description,
         'milestone_id': milestone_id
     }
-    ok, m_doc = model.validate(data)
-    if ok :
-        m = model.get(m_doc)
-        click.secho(f"{m} was successfully added", fg='green')
-        m.save()
-    else:
-        click.secho(f"Errors : {m_doc}", fg='red')
+    save_or_display_errors(model, data)
+
+@item.command('new')
+@click.option('--name', prompt='Item name')
+@click.option('--description', prompt='Item description')
+@click.option('--milestone_id', type=int)
+@click.option('--sprint_id', type=int)
+@click.pass_context
+def new_item(ctx, name, description, milestone_id=None, sprint_id=None):
+    """Add a new sprint"""
+    model = ctx.obj['model']
+    data = {}
+    if not milestone_id and not sprint_id:
+        parent_type = click.prompt('Related to [M]ilestone or [S]print ?', type=click.Choice(['m', 's']))
+        if parent_type == 'm':
+            milestone_id = click.prompt('Related milestone ID', type=int)
+        elif parent_type == 's':
+            sprint_id = click.prompt('Related sprint ID', type=int)
+    if milestone_id:
+        data = {'milestone_id': milestone_id}
+    if sprint_id:
+        data = {'sprint_id': sprint_id}
+
+    data.update({'name': name, 'description': description})
+
+    save_or_display_errors(model, data)
 
 @click.command()
 @click.pass_context
@@ -72,8 +101,9 @@ def list(ctx):
 
 
 milestone.add_command(list)
-
 sprint.add_command(list)
+item.add_command(list)
+
 
 if __name__ == '__main__':
     main()

+ 3 - 1
planner/models/__init__.py

@@ -1,7 +1,9 @@
 from .milestones import Milestone
 from .sprints import Sprint
+from .items import Item
 
 __all__ = [
     'Milestone',
-    'Sprint'
+    'Sprint',
+    'Item'
 ]

+ 53 - 0
planner/models/items.py

@@ -0,0 +1,53 @@
+from dataclasses import dataclass
+from datetime import datetime
+from copy import deepcopy
+
+from .mixins import SchemaMixin, DbMixin
+from .milestones import Milestone
+from .sprints import Sprint
+
+
+@dataclass(repr=False)
+class Item(SchemaMixin, DbMixin):
+    document: dict
+    name: str
+    description: str
+    milestone: Milestone
+    sprint: Sprint
+    date_added: datetime = None
+    date_expected: datetime = None
+    date_started: datetime = None
+
+    schema_yaml = """
+        name:
+            required: true
+            type: string
+            is_unique_with: 
+                table: sprint
+                fields:
+                  - milestone_id
+                  - sprint_id
+        description:
+            required: true
+            type: string
+        milestone_id:
+            is_fk: milestone
+        sprint_id:
+            is_fk: sprint
+        date_added:
+            type: datetime
+            default_setter: utcnow
+    """
+
+    @classmethod
+    def get(cls, document):
+        kwargs = deepcopy(document)
+        milestone = Milestone.fetch(kwargs.pop('milestone_id', None))
+        sprint = Sprint.fetch(kwargs.pop('sprint_id', None))
+        return cls(document=document, milestone=milestone, sprint=sprint, **kwargs)
+
+    def __repr__(self):
+        return "{}(name='{}', milestone='{}')".format(self.__class__.__qualname__, self.name, repr(self.milestone))
+
+    def __terminal__(self):
+        return f"Item : {self.name} ({self.sprint or self.milestone})"

+ 6 - 3
planner/models/mixins.py

@@ -35,9 +35,12 @@ class DbMixin:
         return cls(document=document, **document)
 
     @classmethod
-    def fetch(cls, doc_id):
-        document = db.table(cls.class_name()).get(doc_id=doc_id)
-        return cls(document=document, **document)
+    def fetch(cls, doc_id=None):
+        if doc_id:
+            document = db.table(cls.class_name()).get(doc_id=doc_id)
+            return cls.get(document)
+        else:
+            return None
 
     def save(self):
         db.table(self.class_name()).insert(self.document)