additional fields workItemType and deadline for work items

This commit is contained in:
Helmut Merz 2012-07-29 10:14:32 +02:00
parent fa56eaeedf
commit 5904b3a9e8
2 changed files with 64 additions and 22 deletions

View file

@ -527,16 +527,21 @@ class IWorkItem(ITrack):
'by its name or ID.') 'by its name or ID.')
state = Attribute('The current state the work item is in.') state = Attribute('The current state the work item is in.')
# standard attributes # standard attributes
workItemType = Attribute('The type of the work item '
'(work, event, deadline).')
title = Attribute('A short text characterizing the work item.') title = Attribute('A short text characterizing the work item.')
description = Attribute('A note about what has to be done, and why...') description = Attribute('A note about what has to be done, and why...')
deadline = Attribute('When the work has to be finished.')
start = Attribute('When the work was started.') start = Attribute('When the work was started.')
end = Attribute('When the work was finished.') end = Attribute('When the work was finished.')
duration = Attribute('How long it took to finish the work.') duration = Attribute('How long it took to finish the work.')
effort = Attribute('How much effort (time units) it took to finish the work.') effort = Attribute('How much effort (time units) it took '
'to finish the work.')
comment = Attribute('A note about what has been done, and why...') comment = Attribute('A note about what has been done, and why...')
# work item handling # work item handling
creator = Attribute('The party that has set up the work item.') creator = Attribute('The party that has set up the work item.')
created = Attribute('The timeStamp of the initial creation of the work item.') created = Attribute('The timeStamp of the initial creation '
'of the work item.')
newTask = Attribute('Optional: a new task that has been created based ' newTask = Attribute('Optional: a new task that has been created based '
'on this work item.') 'on this work item.')

View file

@ -32,6 +32,7 @@ from cybertools.stateful.definition import State, Transition
from cybertools.stateful.interfaces import IStatesDefinition from cybertools.stateful.interfaces import IStatesDefinition
from cybertools.tracking.btree import Track, getTimeStamp from cybertools.tracking.btree import Track, getTimeStamp
from cybertools.tracking.interfaces import ITrackingStorage from cybertools.tracking.interfaces import ITrackingStorage
from cybertools.util.jeep import Jeep
_not_found = object() _not_found = object()
@ -63,11 +64,11 @@ def workItemStates():
State('cancelled', 'cancelled', State('cancelled', 'cancelled',
('plan', 'accept', 'start', 'work', 'move', 'modify', 'close'), ('plan', 'accept', 'start', 'work', 'move', 'modify', 'close'),
color='grey'), color='grey'),
State('closed', 'closed', (), color='lightblue'), State('closed', 'closed', ('reopen',), color='lightblue'),
# not directly reachable states: # not directly reachable states:
State('delegated', 'delegated', State('delegated', 'delegated',
('plan', 'accept', 'start', 'work', 'finish', 'close', ('plan', 'accept', #'start', 'work', 'finish',
'delegate', 'move', 'cancel', 'modify'), 'close', 'delegate', 'move', 'cancel', 'modify'),
color='purple'), color='purple'),
State('delegated_x', 'delegated', (), color='purple'), State('delegated_x', 'delegated', (), color='purple'),
State('moved', 'moved', State('moved', 'moved',
@ -82,7 +83,7 @@ def workItemStates():
# transitions: # transitions:
Transition('plan', 'plan', 'planned'), Transition('plan', 'plan', 'planned'),
Transition('accept', 'accept', 'accepted'), Transition('accept', 'accept', 'accepted'),
Transition('start', 'start working', 'running'), Transition('start', 'start working', 'running'), # obsolete?
Transition('work', 'work', 'done'), Transition('work', 'work', 'done'),
Transition('finish', 'finish', 'finished'), Transition('finish', 'finish', 'finished'),
Transition('cancel', 'cancel', 'cancelled'), Transition('cancel', 'cancel', 'cancelled'),
@ -90,10 +91,12 @@ def workItemStates():
Transition('delegate', 'delegate', 'planned'), Transition('delegate', 'delegate', 'planned'),
Transition('move', 'move', 'planned'), Transition('move', 'move', 'planned'),
Transition('close', 'close', 'closed'), Transition('close', 'close', 'closed'),
Transition('reopen', 're-open', 'planned'),
initialState='new') initialState='new')
fieldNames = ['title', 'description', 'start', 'end', 'duration', 'effort', fieldNames = ['title', 'description', 'deadline', 'start', 'end',
'duration', 'effort',
'comment', 'party'] # for use in editingRules 'comment', 'party'] # for use in editingRules
# meaning: - not editable, value=default # meaning: - not editable, value=default
@ -102,22 +105,55 @@ fieldNames = ['title', 'description', 'start', 'end', 'duration', 'effort',
# . default (may be empty) # . default (may be empty)
editingRules = dict( editingRules = dict(
plan = {'*': '++.....+'}, plan = {'*': '+++.....+'},
accept = {'*': '++.....-', accept = {'*': '+++.....-',
'planned': '++++++.-', 'planned': '+++++++.-',
'accepted': '++++++.-'}, 'accepted': '+++++++.-'},
start = {'*': '++./...-'}, start = {'*': '+++./...-'},
work = {'*': '++.....-', work = {'*': '+++.....-',
'running': '+++....-'}, 'running': '++++....-'},
finish = {'*': '++.....-', finish = {'*': '+++.....-',
'running': '+++....-'}, 'running': '++++....-'},
cancel = {'*': '++////./'}, cancel = {'*': '+++////./'},
modify = {'*': '++++++++'}, modify = {'*': '+++++++++'},
delegate= {'*': '++......'}, delegate= {'*': '+++++++.+'},
close = {'*': '++////./'}, move = {'*': '+++++++.-'},
close = {'*': '+++////./'},
reopen = {'*': '+++////./'},
) )
class WorkItemType(object):
""" Specify the type of a work item.
The work item type controls which actions (transitions)
and fields are available for a certain work item.
"""
def __init__(self, name, title, description=u'',
actions=None, fields=None, color=None):
self.name = name
self.title = title
self.description = description
self.actions = actions or list(editingRules)
self.fields = fields or ('deadline', 'start-end', 'duration-effort')
self.color = color
workItemTypes = Jeep((
WorkItemType('work', u'Unit of Work'),
WorkItemType('scheduled', u'Scheduled Event',
actions=('plan', 'accept', 'finish', 'cancel',
'modify', 'delegate', 'close', 'reopen'),
fields =('start-end', 'duration-effort',),
color ='#aaaaff'),
WorkItemType('deadline', u'Deadline',
actions=('plan', 'accept', 'finish', 'cancel',
'modify', 'delegate', 'close', 'reopen'),
fields =('deadline',),
color ='#ffffaa')
))
class WorkItem(Stateful, Track): class WorkItem(Stateful, Track):
""" A work item that may be stored as a track in a tracking storage. """ A work item that may be stored as a track in a tracking storage.
""" """
@ -130,7 +166,8 @@ class WorkItem(Stateful, Track):
typeInterface = IWorkItem typeInterface = IWorkItem
statesDefinition = 'organize.workItemStates' statesDefinition = 'organize.workItemStates'
initAttributes = set(['party', 'title', 'description', 'start', 'end', initAttributes = set(['workItemType', 'party', 'title', 'description',
'deadline', 'start', 'end',
'duration', 'effort']) 'duration', 'effort'])
def __init__(self, taskId, runId, userName, data): def __init__(self, taskId, runId, userName, data):
@ -274,7 +311,7 @@ class WorkItem(Stateful, Track):
if party is not None: if party is not None:
self.userName = party self.userName = party
self.reindex('userName') self.reindex('userName')
start = kw.get('start') start = kw.get('start') or kw.get('deadline') # TODO: check OK?
if start is not None: if start is not None:
self.timeStamp = start self.timeStamp = start
self.reindex('timeStamp') self.reindex('timeStamp')