loops/organize/work
helmutm ec7dd9391d quicksearch improvements; make search process in relation widget more flexible
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3250 fd906abe-77d9-0310-91a1-e0d9ade77398
2009-02-25 17:42:23 +00:00
..
__init__.py work in progress: task management with work items 2008-12-27 10:42:48 +00:00
base.py work in progress: task management with work items 2008-12-27 10:42:48 +00:00
browser.py quicksearch improvements; make search process in relation widget more flexible 2009-02-25 17:42:23 +00:00
configure.zcml improve queries: make configurable via query options 2009-01-27 12:04:57 +00:00
README.txt improve queries: make configurable via query options 2009-01-27 12:04:57 +00:00
setup.py update copyright info 2009-01-11 15:05:05 +00:00
tests.py work in progress: task management with work items 2008-12-28 14:26:02 +00:00
work_macros.pt provide description appropriately formatted for title attribute and info field 2009-02-16 07:02:41 +00:00

===============================================================
loops - Linked Objects for Organization and Processing Services
===============================================================

  ($Id$)

Let's do some basic setup

  >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
  >>> site = placefulSetUp(True)
  >>> from zope import component, interface
  >>> from zope.publisher.browser import TestRequest

and set up a simple loops site with a concept manager and some concepts
(with all the type machinery, what in real life is done via standard
ZCML setup):

  >>> from loops.organize.setup import SetupManager
  >>> component.provideAdapter(SetupManager, name='organize')
  >>> from loops.organize.work.setup import SetupManager
  >>> component.provideAdapter(SetupManager, name='organize.work')

  >>> from loops.tests.setup import TestSite
  >>> t = TestSite(site)
  >>> concepts, resources, views = t.setup()


Work Items - Plannning and Recording Activities for Tasks
=========================================================

  >>> loopsRoot = concepts.getLoopsRoot()
  >>> records = loopsRoot.getRecordManager()

  >>> from cybertools.organize.work import WorkItems
  >>> component.provideAdapter(WorkItems)

  >>> from cybertools.organize.interfaces import IWorkItems
  >>> workItems = IWorkItems(records['work'])

  >>> from cybertools.organize.work import workItemStates
  >>> component.provideUtility(workItemStates(), name='organize.workItemStates')

More setup
----------

In order to be able to login and store favorites and other personal data
we have to prepare our environment. We need some basic adapter registrations,
and a pluggable authentication utility with a principal folder.

  >>> from loops.organize.tests import setupObjectsForTesting
  >>> setupData = setupObjectsForTesting(site, concepts)
  >>> johnC = setupData.johnC

  >>> from zope.app.authentication.principalfolder import Principal
  >>> pJohn = Principal('users.john', 'xxx', u'John')
  >>> from loops.tests.auth import login
  >>> login(pJohn)

We also assign a task as a target to the home node so that we are able
to assign work items to this task.

  >>> tTask = concepts['task']
  >>> home = views['home']
  >>> from loops.concept import Concept
  >>> from loops.setup import addAndConfigureObject
  >>> task01 = addAndConfigureObject(concepts, Concept, 'loops_dev',
  ...                   title=u'loops Development', conceptType=tTask)
  >>> home.target = task01

Forms for adding and editing work items
---------------------------------------

New work items are created using a CreateWorkItemForm.

  >>> from loops.organize.work.browser import CreateWorkItemForm, CreateWorkItem
  >>> form = CreateWorkItemForm(home, TestRequest())

When this form is submitted, a form controller is automatically created
for the view on the currently shown node. The data from the form is processed
by calling the form controller's update method

  >>> input = {u'form.action': u'create_workitem', u'workitem.action': u'finish',
  ...          u'description': u'Description', u'comment': u'Comment',
  ...          u'start_date': u'2008-12-28', u'start_time': u'T19:00:00',
  ...          u'end_time': u'T20:15:00', u'duration': u'1:15', u'effort': u'0:15'}
  >>> request = TestRequest(form=input)
  >>> request.setPrincipal(pJohn)

  >>> from loops.browser.node import NodeView
  >>> nodeView = NodeView(home, request)
  >>> cwiController = CreateWorkItem(nodeView, request)

  >>> cwiController.update()
  False

  >>> list(workItems)
  [<WorkItem ['36', 1, '33', '2008-12-28 18:00', 'finished']:
   {'comment': u'Comment', 'end': 1230491700, 'description': u'Description',
    'created': ..., 'creator': '33', 'start': 1230487200,
    'duration': 4500, 'effort': 900}>]

Work items views
----------------

  >>> from loops.organize.work.browser import WorkItemView, TaskWorkItems
  >>> wi01 = workItems['0000001']
  >>> view = WorkItemView(wi01, TestRequest())
  >>> view.taskUrl
  'http://127.0.0.1/loops/concepts/loops_dev/@@SelectedManagementView.html'

  >>> work = TaskWorkItems(task01, request)
  >>> from loops.organize.work.browser import WorkItemDetails
  >>> view = WorkItemDetails(work, wi01)
  >>> view.day, view.start, view.end
  (u'08/12/28', u'19:00', u'20:15')

Work items life cycle
---------------------

Let's create another work item, now in state planned.

  >>> input = {u'form.action': u'create_workitem', u'workitem.action': u'plan',
  ...          u'title': u'Install Zope',
  ...          u'start_date': u'2009-01-19', u'start_time': u'T09:00:00'}
  >>> request = TestRequest(form=input)
  >>> request.setPrincipal(pJohn)
  >>> nodeView = NodeView(home, request)
  >>> cwiController = CreateWorkItem(nodeView, request)
  >>> cwiController.update()
  False

If we now open another form, providing the identifier of the newly created
work item, the form will be pre-filled with some of the item's data.

  >>> form = CreateWorkItemForm(home, TestRequest(form=dict(id='0000002')))
  >>> form.title
  u'Install Zope'

  >>> form.actions
  [{'name': 'plan', 'title': 'plan'}, {'name': 'accept', 'title': 'accept'},
   {'name': 'start', 'title': 'start working'}, {'name': 'work', 'title': 'work'},
   {'name': 'finish', 'title': 'finish'}, {'name': 'cancel', 'title': 'cancel'},
   {'name': 'modify', 'title': 'modify'}]


Work Item Queries
=================

  >>> from loops.common import adapted
  >>> from loops.expert.concept import IQueryConcept
  >>> from loops.organize.work.browser import UserWorkItems, PersonWorkItems

  >>> tQuery = addAndConfigureObject(concepts, Concept, 'query',
  ...                   title=u'Query', conceptType=concepts.getTypeConcept(),
  ...                   typeInterface=IQueryConcept)

  >>> query = addAndConfigureObject(concepts, Concept, 'userworkitems',
  ...                               conceptType=tQuery)

The UserWorkItems view does not give any results because there is no current
user (principal) available in our test setting.

  >>> work = UserWorkItems(query, TestRequest())
  >>> work.listWorkItems()

So we use the PersonWorkItems view, assigning john to the query.

  >>> query.assignParent(johnC)
  >>> adapted(query).options = ['wi_from:2009-01-01', 'wi_to:today']

  >>> input = dict()
  >>> work = PersonWorkItems(query, TestRequest(form=input))
  >>> work.listWorkItems()
  [<WorkItem ['36', 2, '33', '2009-01-19 08:00', 'planned']:
   {'start': 1232352000, 'created': ..., 'title': u'Install Zope',
    'creator': '33'}>]


Fin de partie
=============

  >>> placefulTearDown()