reporting, work in progress: sub-report field
This commit is contained in:
		
							parent
							
								
									9896c546c3
								
							
						
					
					
						commit
						7ca0892551
					
				
					 4 changed files with 89 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -18,18 +18,18 @@
 | 
			
		|||
  <table class="report"
 | 
			
		||||
         tal:define="results view/results">
 | 
			
		||||
    <tr>
 | 
			
		||||
        <th tal:repeat="col view/displayedColumns"
 | 
			
		||||
        <th tal:repeat="col results/displayedColumns"
 | 
			
		||||
            tal:content="col/title"
 | 
			
		||||
            i18n:translate="" />
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr tal:repeat="row results">
 | 
			
		||||
        <tal:column repeat="col view/displayedColumns">
 | 
			
		||||
        <tal:column repeat="col results/displayedColumns">
 | 
			
		||||
            <metal:column use-macro="python:view.getColumnRenderer(col.renderer)" />
 | 
			
		||||
        </tal:column>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr tal:define="row nocall:results/totals"
 | 
			
		||||
        tal:condition="nocall:row">
 | 
			
		||||
        <tal:column repeat="col view/displayedColumns">
 | 
			
		||||
        <tal:column repeat="col results/displayedColumns">
 | 
			
		||||
            <metal:column use-macro="python:view.getColumnRenderer(col.renderer)" />
 | 
			
		||||
        </tal:column>
 | 
			
		||||
    </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -56,4 +56,29 @@
 | 
			
		|||
</metal:target>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div metal:define-macro="subreport">
 | 
			
		||||
  <td>
 | 
			
		||||
    <table class="subreport"
 | 
			
		||||
           tal:define="results python:col.getValue(row)">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th tal:repeat="col results/displayedColumns"
 | 
			
		||||
            tal:content="col/title"
 | 
			
		||||
            i18n:translate="" />
 | 
			
		||||
      </tr>
 | 
			
		||||
      <tr tal:repeat="row results">
 | 
			
		||||
        <tal:column repeat="col results/displayedColumns">
 | 
			
		||||
            <metal:column use-macro="python:view.getColumnRenderer(col.renderer)" />
 | 
			
		||||
        </tal:column>
 | 
			
		||||
      </tr>
 | 
			
		||||
      <tr tal:define="row nocall:results/totals"
 | 
			
		||||
        tal:condition="nocall:row">
 | 
			
		||||
        <tal:column repeat="col results/displayedColumns">
 | 
			
		||||
            <metal:column use-macro="python:view.getColumnRenderer(col.renderer)" />
 | 
			
		||||
        </tal:column>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
  </td>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#
 | 
			
		||||
#  Copyright (c) 2011 Helmut Merz helmutm@cy55.de
 | 
			
		||||
#  Copyright (c) 2012 Helmut Merz helmutm@cy55.de
 | 
			
		||||
#
 | 
			
		||||
#  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
#  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,9 @@ Field definitions for reports.
 | 
			
		|||
"""
 | 
			
		||||
 | 
			
		||||
from cybertools.composer.report.field import Field
 | 
			
		||||
from cybertools.composer.report.result import ResultSet
 | 
			
		||||
from loops.common import baseObject
 | 
			
		||||
from loops.expert.report import ReportInstance
 | 
			
		||||
from loops import util
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +42,8 @@ class UrlField(Field):
 | 
			
		|||
 | 
			
		||||
    def getDisplayValue(self, row):
 | 
			
		||||
        nv = row.parent.context.view.nodeView
 | 
			
		||||
        if row.context is None:     # probably a totals row
 | 
			
		||||
            return dict(title=u'', url=u'')
 | 
			
		||||
        return dict(title=self.getValue(row),
 | 
			
		||||
                    url=nv.getUrlForTarget(baseObject(row.context)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,3 +65,25 @@ class TargetField(Field):
 | 
			
		|||
        view = row.parent.context.view
 | 
			
		||||
        return dict(title=value.title, url=view.getUrlForTarget(value))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# sub-report stuff
 | 
			
		||||
 | 
			
		||||
class SubReport(ReportInstance):
 | 
			
		||||
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SubReportField(Field):
 | 
			
		||||
 | 
			
		||||
    renderer = 'subreport'
 | 
			
		||||
    reportFactory = SubReport
 | 
			
		||||
 | 
			
		||||
    def getReportInstance(self, row):
 | 
			
		||||
        baseReport = row.parent.context
 | 
			
		||||
        instance = self.reportFactory(baseReport.context)
 | 
			
		||||
        instance.view = baseReport.view
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
    def getValue(self, row):
 | 
			
		||||
        ri = self.getReportInstance(row)
 | 
			
		||||
        return ResultSet(ri, ri.getResults())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,7 +280,8 @@ We can now access the report using a results view.
 | 
			
		|||
  ...     for col in resultsView.displayedColumns:
 | 
			
		||||
  ...         print col.getDisplayValue(row),
 | 
			
		||||
  ...     print
 | 
			
		||||
  loops Development
 | 
			
		||||
  {'url': 'http://127.0.0.1/loops/views/home/.36', 'title': u'loops Development'}
 | 
			
		||||
  <cybertools.composer.report.result.ResultSet object ...>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Fin de partie
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#
 | 
			
		||||
#  Copyright (c) 2011 Helmut Merz helmutm@cy55.de
 | 
			
		||||
#  Copyright (c) 2012 Helmut Merz helmutm@cy55.de
 | 
			
		||||
#
 | 
			
		||||
#  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
#  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ from cybertools.util.date import timeStamp2Date
 | 
			
		|||
from cybertools.util.format import formatDate
 | 
			
		||||
from cybertools.util.jeep import Jeep
 | 
			
		||||
from loops.common import adapted, baseObject
 | 
			
		||||
from loops.expert.field import TargetField
 | 
			
		||||
from loops.expert.field import TargetField, TextField, UrlField, SubReportField
 | 
			
		||||
from loops.expert.report import ReportInstance
 | 
			
		||||
from loops import util
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,9 +84,15 @@ class DurationField(Field):
 | 
			
		|||
        return u'%02i:%02i' % divmod(value * 60, 60)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# common fields
 | 
			
		||||
 | 
			
		||||
tasks = Field('tasks', u'Tasks',
 | 
			
		||||
                description=u'The tasks from which work items should be selected.',
 | 
			
		||||
                description=u'The tasks from which sub-tasks and '
 | 
			
		||||
                        u'work items should be selected.',
 | 
			
		||||
                executionSteps=['query'])
 | 
			
		||||
 | 
			
		||||
# work report fields
 | 
			
		||||
 | 
			
		||||
dayFrom = Field('dayFrom', u'Start Day',
 | 
			
		||||
                description=u'The first day from which to select work.',
 | 
			
		||||
                executionSteps=['query'])
 | 
			
		||||
| 
						 | 
				
			
			@ -108,10 +114,10 @@ task = TargetField('taskId', u'Task',
 | 
			
		|||
party = TargetField('userName', u'Party',
 | 
			
		||||
                description=u'The party (usually a person) who did the work.',
 | 
			
		||||
                executionSteps=['query', 'sort', 'output'])
 | 
			
		||||
title = Field('title', u'Title',
 | 
			
		||||
workTitle = Field('title', u'Title',
 | 
			
		||||
                description=u'The short description of the work.',
 | 
			
		||||
                executionSteps=['output'])
 | 
			
		||||
description = Field('description', u'Description',
 | 
			
		||||
workDescription = Field('description', u'Description',
 | 
			
		||||
                description=u'The long description of the work.',
 | 
			
		||||
                executionSteps=['output'])
 | 
			
		||||
duration = DurationField('duration', u'Duration',
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +130,18 @@ state = Field('state', u'State',
 | 
			
		|||
                description=u'The state of the work.',
 | 
			
		||||
                executionSteps=['query', 'output'])
 | 
			
		||||
 | 
			
		||||
# task/event report fields
 | 
			
		||||
 | 
			
		||||
taskTitle = UrlField('title', u'Title',
 | 
			
		||||
                description=u'The short description of the task.',
 | 
			
		||||
                executionSteps=['output'])
 | 
			
		||||
taskDescription = TextField('description', u'Description',
 | 
			
		||||
                description=u'The long description of the task.',
 | 
			
		||||
                executionSteps=['output'])
 | 
			
		||||
workItems = SubReportField('workItems', u'Work Items',
 | 
			
		||||
                description=u'A list of work items belonging to the task.',
 | 
			
		||||
                executionSteps=['output'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# basic definitions and work report instance
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +181,7 @@ class WorkReportInstance(ReportInstance):
 | 
			
		|||
    rowFactory = WorkRow
 | 
			
		||||
 | 
			
		||||
    fields = Jeep((dayFrom, dayTo, tasks,
 | 
			
		||||
                   day, timeStart, timeEnd, task, party, title, #description,
 | 
			
		||||
                   day, timeStart, timeEnd, task, party, workTitle, #description,
 | 
			
		||||
                   duration, effort, state))
 | 
			
		||||
 | 
			
		||||
    defaultOutputFields = fields
 | 
			
		||||
| 
						 | 
				
			
			@ -238,13 +256,20 @@ class TaskRow(BaseRow):
 | 
			
		|||
 | 
			
		||||
class MeetingMinutes(WorkReportInstance):
 | 
			
		||||
 | 
			
		||||
    # TODO:
 | 
			
		||||
    # header (event) fields: title, description, from/to,
 | 
			
		||||
    #               location, participants (or put in description?)
 | 
			
		||||
    # result set field for work items
 | 
			
		||||
    # work item fields: title, description, party, deadline, state
 | 
			
		||||
 | 
			
		||||
    type = "meeting_minutes"
 | 
			
		||||
    label = u'Meeting Minutes'
 | 
			
		||||
 | 
			
		||||
    rowFactory = TaskRow
 | 
			
		||||
 | 
			
		||||
    fields = Jeep((tasks, title, description))
 | 
			
		||||
    fields = Jeep((tasks, taskTitle, taskDescription, workItems))
 | 
			
		||||
    defaultOutputFields = fields
 | 
			
		||||
    states = ('planned', 'accepted', 'done', 'done_x', 'finished')
 | 
			
		||||
 | 
			
		||||
    def selectObjects(self, parts):
 | 
			
		||||
        return self.getTasks(parts)[1:]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue