work in progress: extend reporting features - report 'meeting minutes'

This commit is contained in:
Helmut Merz 2011-12-30 12:47:23 +01:00
parent 0162adea94
commit 9f9e350933
3 changed files with 109 additions and 18 deletions

View file

@ -2,8 +2,6 @@
loops - Linked Objects for Organization and Processing Services
===============================================================
($Id$)
Let's do some basic setup
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
@ -194,6 +192,9 @@ In addition we need a predicate that connects one or more tasks with a report.
>>> hasReport = addAndConfigureObject(concepts, Concept, 'hasreport',
... title=u'has Report', conceptType=concepts.getPredicateType())
Work statement report
---------------------
Now we can create a report and register it as the report for the task
used above.
@ -235,6 +236,53 @@ in a results view.
{'effort': 900}
Meeting Minutes
===============
We can use an event with assigned tasks as the basis for planning a meeting
and recording information about the tasks.
Let's start with creating an a event and assigning it a task.
>>> from loops.organize.interfaces import ITask
>>> tEvent = addAndConfigureObject(concepts, Concept, 'event',
... title=u'Event', conceptType=concepts.getTypeConcept(),
... typeInterface=ITask)
>>> ev01 = addAndConfigureObject(concepts, Concept, 'ev01',
... title=u'loops Meeting', conceptType=tEvent)
>>> ev01.assignChild(task01)
Now we create the meeting minutes report. We assign the event type as a
child in order to provide the information for which types of objects the
report is available.
>>> from loops.organize.work.report import MeetingMinutes
>>> component.provideAdapter(MeetingMinutes, provides=IReportInstance,
... name='meeting_minutes')
>>> meetingMinutes = addAndConfigureObject(concepts, Concept, 'meeting_minutes',
... title=u'Meeting Minutes', conceptType=tReport,
... reportType='meeting_minutes')
>>> meetingMinutes.assignChild(tEvent, hasReport)
We can now access the report using a results view.
>>> from loops.util import getUidForObject
>>> input = dict(tasks=getUidForObject(ev01))
>>> resultsView = ResultsView(home, TestRequest(form=input))
>>> resultsView.virtualTargetObject = meetingMinutes
>>> results = resultsView.results()
>>> len(list(results))
1
>>> for row in results:
... for col in resultsView.displayedColumns:
... print col.getDisplayValue(row),
... print
loops Development
Fin de partie
=============

View file

@ -86,6 +86,17 @@
set_schema="loops.expert.report.IReportInstance" />
</zope:class>
<zope:adapter factory="loops.organize.work.report.MeetingMinutes"
name="meeting_minutes"
provides="loops.expert.report.IReportInstance"
trusted="True" />
<zope:class class="loops.organize.work.report.MeetingMinutes">
<require permission="zope.View"
interface="loops.expert.report.IReportInstance" />
<require permission="zope.ManageContent"
set_schema="loops.expert.report.IReportInstance" />
</zope:class>
<!-- setup -->
<zope:adapter factory="loops.organize.work.setup.SetupManager"

View file

@ -113,7 +113,7 @@ title = Field('title', u'Title',
executionSteps=['output'])
description = Field('description', u'Description',
description=u'The long description of the work.',
executionSteps=['x_output'])
executionSteps=['output'])
duration = DurationField('duration', u'Duration',
description=u'The duration of the work.',
executionSteps=['output'])
@ -125,6 +125,8 @@ state = Field('state', u'State',
executionSteps=['query', 'output'])
# basic definitions and work report instance
class WorkRow(BaseRow):
def getRawValue(self, attr):
@ -161,11 +163,13 @@ class WorkReportInstance(ReportInstance):
rowFactory = WorkRow
fields = Jeep((dayFrom, dayTo, tasks,
day, timeStart, timeEnd, task, party, title, description,
day, timeStart, timeEnd, task, party, title, #description,
duration, effort, state))
defaultOutputFields = fields
defaultSortCriteria = (day, timeStart,)
states = ('done', 'done_x', 'finished')
taskTypeNames = ('task', 'event', 'project')
@property
def queryCriteria(self):
@ -183,22 +187,20 @@ class WorkReportInstance(ReportInstance):
def selectObjects(self, parts):
result = []
tasks = [util.getObjectForUid(t) for t in parts.pop('tasks').comparisonValue]
for t in list(tasks):
tasks.extend(self.getAllSubtasks(t))
for t in tasks:
for t in self.getTasks(parts):
result.extend(self.selectWorkItems(t, parts))
# remove parts already used for selection from parts list:
parts.pop('userName', None)
return result
def selectWorkItems(self, task, parts):
states = ['done', 'done_x', 'finished']
kw = dict(task=util.getUidForObject(task), state=states)
if 'userName' in parts:
kw['userName'] = parts['userName'].comparisonValue
wi = self.workItems
return wi.query(**kw)
def getTasks(self, parts):
taskIds = parts.pop('tasks').comparisonValue
if not isinstance(taskIds, (list, tuple)):
taskIds = [taskIds]
tasks = [util.getObjectForUid(t) for t in taskIds]
for t in list(tasks):
tasks.extend(self.getAllSubtasks(t))
return tasks
def getAllSubtasks(self, concept):
result = []
@ -208,12 +210,42 @@ class WorkReportInstance(ReportInstance):
result.extend(self.getAllSubtasks(c))
return result
def selectWorkItems(self, task, parts):
# TODO: take states from parts
kw = dict(task=util.getUidForObject(task), state=self.states)
if 'userName' in parts:
kw['userName'] = parts['userName'].comparisonValue
wi = self.workItems
return wi.query(**kw)
@Lazy
def taskTypes(self):
return (self.conceptManager['task'],
self.conceptManager['event'],
self.conceptManager['project'])
return [c for c in [self.conceptManager.get(name)
for name in self.taskTypeNames]
if c is not None]
@Lazy
def workItems(self):
return IWorkItems(self.recordManager['work'])
# meeting minutes
class TaskRow(BaseRow):
pass
class MeetingMinutes(WorkReportInstance):
type = "meeting_minutes"
label = u'Meeting Minutes'
rowFactory = TaskRow
fields = Jeep((tasks, title, description))
defaultOutputFields = fields
def selectObjects(self, parts):
return self.getTasks(parts)[1:]