Commits

Andy Mikhailenko  committed 5d01f94

ext.needs: Added commands list_plans and move_plans; updated templates.

  • Participants
  • Parent commits cfce2dd

Comments (0)

Files changed (6)

File orgtool/ext/needs/__init__.py

 """
 from tool.plugins import BasePlugin
 #from tool.ext.templating import register_templates
-from commands import (
-    list_needs, view_need, add_need, rename_need, mark_need, move_need,
-    delete_need
-)
+from .commands import available_commands
 import admin
 
 
     "A stripped-down lightweight needs management plugin (CLI only)"
     features = 'needs'
     requires = ['{document_storage}']
-    commands = [
-        list_needs, view_need, add_need, rename_need, mark_need, move_need,
-        delete_need
-    ]
+    commands = available_commands
 
 
 class NeedsPlugin(NeedsCLI):

File orgtool/ext/needs/commands.py

 from tool import app
 from tool.cli import (
     # commands
-    arg, alias, CommandError, confirm,
+    arg, alias, CommandError, confirm, wrap_errors,
     # colors
     Fore, Back, Style
 )
     need = Need(summary=args.summary, is_satisfied=False)
     project = None
     if args.project:
-        qs = SystemUnderDevelopment.objects(db)
+        qs = db.find(SystemUnderDevelopment)
         qs = qs.where(summary__matches_caseless=args.project)
         if not qs:
             yield('No projects matching "{0}"'.format(args.project))
             yield('Changes have been applied.')
     else:
         yield('Operation cancelled.')
+
+@alias('lsplans')
+@arg('-q', '--query')
+@arg('-n', '--need')
+def list_plans(args):
+    plans = ensure_results(find_plans, query=args.query, need=args.need)
+    for plan in plans:
+        yield u'[{x}] {plan} {dim}→ {plan.outcome}{normal}'.format(
+            plan=plan, dim=Style.DIM, normal=Style.NORMAL,
+            x=('x' if plan.is_accomplished else ' '))
+
+@alias('mvplans')
+@arg('-q', '--query')
+@arg('-n', '--need')
+@arg('-t', '--target', help='target need')
+@arg('--dry-run', default=False)
+@wrap_errors(AssertionError, NotFound, MultipleMatches)
+def move_plans(args):
+    assert args.query or args.need, 'query or need must be specified'
+    assert args.target, 'target must be specified'
+    plans = ensure_results(find_plans, query=args.query, need=args.need)
+    yield 'Matching plans:'
+    for plan in plans:
+        yield u'* {summary} → {outcome}'.format(**plan)
+    target = get_single(find_needs, args.target)
+    action = u'move {cnt} plans to {target}'.format(
+        cnt = len(plans),
+        target = target
+    )
+    if confirm(action):
+        if args.dry_run:
+            yield('Simulation: nothing was actually changed in the database.')
+        else:
+            for plan in plans:
+                plan.outcome = target
+                plan.save()
+            yield('Changes have been applied.')
+    else:
+        yield('Operation cancelled.')
+
+
+available_commands = (
+    # Need
+    list_needs, view_need, add_need, rename_need, mark_need, move_need,
+    delete_need,
+    # ReasonedPlan
+    list_plans, move_plans,
+)

File orgtool/ext/needs/helpers.py

 # -*- coding: utf-8 -*-
 import re
 
-from tool.ext.documents import default_storage
+from tool import app
 
-from .schema import SystemUnderDevelopment, Need
+from .schema import SystemUnderDevelopment, Need, ReasonedPlan
 
 
 class NotFound(Exception):
 
 
 def find_projects(query=None, exclude=None):
-    db = default_storage()
-    suds = SystemUnderDevelopment.objects(db)
+    db = app.get_feature('document_storage').default_db
+    suds = db.find(SystemUnderDevelopment)
     if query:
         suds = suds.where(summary__matches_caseless=query)
     if exclude:
     return suds
 
 def find_needs(query=None, exclude=None, project=None, extra=None):
-    db = default_storage()
+    db = app.get_feature('document_storage').default_db
     extra = extra or {}
     if project:
         needs = project.needs
         for need in needs:
             yield need
     else:
-        needs = Need.objects(db)
+        needs = db.find(Need)
         if query:
             needs = needs.where(summary__matches_caseless=query)
         if exclude:
         for need in needs:
             yield need
 
+def find_plans(query=None, need=None, exclude=None):
+    db = app.get_feature('document_storage').default_db
+
+    plans = db.find(ReasonedPlan)
+
+    if query:
+        plans = plans.where(summary__matches_caseless=query)
+    if exclude:
+        plans = plans.where_not(summary__matches_caseless=exclude)
+    if need:
+        needs = find_needs(query=need)
+        for plan in plans.where(outcome__contains_any=[n.pk for n in needs]):
+            yield plan
+    else:
+        for plan in plans:
+            yield plan
+
 def ensure_results(finder, *args, **kwargs):
     items = list(finder(*args, **kwargs))
     if not items:

File orgtool/ext/needs/templates/need_detail.html

 {% if object.stakeholders %}
     <p>Stakeholders: 
         {% for actor in object.stakeholders %}
-            <a href="{{ url_for('orgtool.ext.contacts.person',
+            <a href="{{ url_for('orgtool.ext.contacts.views.person',
                                 pk=actor.pk) }}">{{ actor }}</a>
             {%- if not loop.last %},{% endif %}
         {% endfor %}

File orgtool/ext/needs/templates/plan_detail.html

 
     {#<p>{{ object.describe_recurrence() }}</p>#}
     {% if object.is_active() and object.next_date_time %}
-        <p>Plan: <em>{{ object.dates_rrule_text }}</em>.</p>
+        <p>Recurrence rule: <em>{{ object.ical_rrule }}</em>.</p>
         <p>Next: 
            {{ object.next_date_time.strftime("%A, %d %B %Y") }},
            <strong>{{ render_rel_delta(object.next_date_time) }}</strong>.</p>
         {% endif %}
     {% endif %}
 
+
+
+{#
+First five occurrence dates:
+{% for occ in object.rrule[:5] %}
+    {{ occ }}
+{% endfor %}
+#}
+
+
     {# RELATED EVENTS #}
 
     {% set prev_dt = None %}
         {% if event.get_duration() %}
             <p style="font-size: 0.8em;">duration: {{ event.get_duration() }}</p>
         {% endif %}
-        (<a href="{{ url_for('tool.ext.admin.object_detail',
-        namespace='events', model_name='Event', pk=event.pk) }}">admin</a>)
+        (<a href="{{ url_for('tool.ext.admin.views.object_detail',
+                             namespace='events', model_name='Event', pk=event.pk) }}">admin</a>)
         </div>
     {% endfor %}
 </div>

File orgtool/ext/needs/templates/project_detail.html

 
 <h2>Stakeholders</h2>
 
-<ul>
-{% for actor in object.stakeholders %}
-    <li><a href="{{ url_for('orgtool.ext.contacts.person', 
-                            pk=actor.pk) }}">{{ actor }}</a></li>
-{% endfor %}
-</ul>
+{% if object.stakeholders %}<!-- can be None -->
+    <ul>
+    {% for actor in object.stakeholders %}
+        <li><a href="{{ url_for('orgtool.ext.contacts.views.person', 
+                                pk=actor.pk) }}">{{ actor }}</a></li>
+    {% endfor %}
+    </ul>
+{% endif %}
 
 {% if object.needs %}