========================================================== Organizations: Persons, Institutions, Addresses, Work, ... ========================================================== ($Id$) >>> from zope import component Basic Work Item Lifecycle ========================= Work items are stored in a tracking storage; in order to conveniently access the work items we have to provide an adapter to the tracking storage. >>> from cybertools.tracking.btree import TrackingStorage >>> from cybertools.organize.interfaces import IWorkItems >>> from cybertools.organize.work import WorkItem, WorkItems >>> component.provideAdapter(WorkItems) The individual work item (a track) is carrying a state attribute that is governed by a special states definition. We have to register this states definition as a utility. >>> from cybertools.organize.work import workItemStates >>> component.provideUtility(workItemStates(), name='organize.workItemStates') We are now ready to set up the tracking storage. >>> tracks = TrackingStorage(trackFactory=WorkItem) >>> workItems = IWorkItems(tracks) The work management only deals with the IDs or names of tasks and persons, so we do not have to set up real objects. >>> wi01 = workItems.add('001', 'john') >>> wi01 Properties that have not been set explicitly have a default of None; properties not specified in the IWorkItem interface will lead to an AttributeError. >>> wi01.description is None True >>> wi01.something Traceback (most recent call last): ... AttributeError: something Properties may be set as long as the work item is in status "new". >>> wi01.setData(start=1229955772, party='annie') >>> wi01 The duration value is calculated automatically when start and end are set; the effort is taken from the duration if not set explicitly. >>> (wi01.end, wi01.duration, wi01.effort) (None, None, None) >>> wi01.setData(end=1229956372) >>> (wi01.end, wi01.duration, wi01.effort) (1229956372, 600, 600) >>> wi01.setData(duration=700) >>> wi01.effort 700 >>> w = wi01.doAction('plan', 'john', party='jim') >>> wi01.userName 'jim' Change work item state ---------------------- Now Jim accepts the work item, i.e. he wants to work on it. >>> wi02 = wi01.doAction('accept', 'jim') >>> wi01.state 'planned' >>> wi02 It is not possible to change a value of a work item that is not in state "new". >>> wi01.setData(party='annie') Traceback (most recent call last): ... ValueError: Attributes may only be changed in state 'new'. Jim now really starts to work. The start time is usually set automatically but may also be specified explicitly. >>> wi03 = wi02.doAction('start', 'jim', start=1229958000) >>> wi03 Stopping and finishing work --------------------------- After five minutes of work Jim decides to stop working; but he will continue work later, so he executes a ``stop`` action. The work item marked as "running" will be replaced by a new one. >>> wi04 = wi03.doAction('stop', 'jim', end=1229958300) >>> wi03 >>> wi04 After another hour Jim works again on the task; he now finishes it within ten minutes and records this in one step. >>> wi05 = wi04.doAction('finish', 'jim', start=1229961600, end=1229962200) >>> wi05 >>> wi05.duration, wi05.effort (600, 600) Closing work ------------ As the work is now finished, the work item may be closed; the corresponding "run" (a sequence of work items belonging together) will be finished. >>> wi06 = wi05.doAction('close', 'john') >>> wi06 Let's now check how many work items have been generated. >>> len(list(workItems)) 6 Delegation of Work Items ======================== A user may delegate a newly created work item to another party. This will create a new work item even if the initial one is still in state "new". Both work items are now in "planned" state. >>> wi07 = workItems.add('001', 'john', start=1229970800) >>> wi08 = wi07.doAction('delegate', 'john', party='annie') >>> wi07 >>> wi08 >>> len(list(workItems)) 8 Modification of Work Items ========================== Existing work items may never be modified except when still in "new" state. To allow for correcting errors that may be detected later there is a "modify" action that will in fact create a new work item. This makes sure that all changes will be tracked correctly. Note that nevertheless only the last work item of a run may be modified. >>> wi09 = wi08.doAction('modify', 'annie', duration=3600) >>> wi08 >>> wi09 Queries ======= Runs ---- >>> list(tracks.runs) [2] >>> list(tracks.finishedRuns) [1]