work in progress: Competence and Certification Management (CCM): fix structure, start with form for qualification record creation

This commit is contained in:
Helmut Merz 2012-06-11 17:32:34 +02:00
parent 707a1dd8c4
commit 719bd165aa
8 changed files with 134 additions and 22 deletions

View file

@ -32,6 +32,7 @@ from loops.browser.common import BaseView
from loops.browser.concept import ConceptView from loops.browser.concept import ConceptView
from loops.expert.browser.report import ResultsConceptView from loops.expert.browser.report import ResultsConceptView
from loops.knowledge.interfaces import IPerson, ITask from loops.knowledge.interfaces import IPerson, ITask
from loops.knowledge.qualification import QualificationRecord
from loops.organize.work.browser import CreateWorkItemForm, CreateWorkItem from loops.organize.work.browser import CreateWorkItemForm, CreateWorkItem
from loops.organize.party import getPersonForUser from loops.organize.party import getPersonForUser
from loops.util import _ from loops.util import _
@ -120,6 +121,8 @@ class PersonQualificationView(ResultsConceptView):
class CreateQualificationRecordForm(CreateWorkItemForm): class CreateQualificationRecordForm(CreateWorkItemForm):
macros = knowledge_macros macros = knowledge_macros
recordManagerName = 'qualification'
trackFactory = QualificationRecord
@Lazy @Lazy
def macro(self): def macro(self):

View file

@ -100,6 +100,19 @@
factory="loops.knowledge.browser.Candidates" factory="loops.knowledge.browser.Candidates"
permission="zope.View" /> permission="zope.View" />
<browser:page
name="create_qualification.html"
for="loops.interfaces.INode"
class="loops.knowledge.browser.CreateQualificationRecordForm"
permission="zope.View" />
<zope:adapter
name="create_qualification"
for="loops.browser.node.NodeView
zope.publisher.interfaces.browser.IBrowserRequest"
factory="loops.knowledge.browser.CreateQualificationRecord"
permission="zope.View" />
<!-- other adapters --> <!-- other adapters -->
<zope:adapter factory="loops.knowledge.schema.PersonSchemaFactory" /> <zope:adapter factory="loops.knowledge.schema.PersonSchemaFactory" />

View file

@ -1,17 +1,17 @@
type(u'competence', u'Competence', viewName=u'', type(u'competence', u'Kompetenz', viewName=u'',
typeInterface=u'', options=u'action.portlet:edit_concept') typeInterface=u'', options=u'action.portlet:create_subtype,edit_concept')
type(u'person', u'Person', viewName=u'', type(u'person', u'Person', viewName=u'',
typeInterface=u'loops.knowledge.interfaces.IPerson', typeInterface=u'loops.knowledge.interfaces.IPerson',
options=u'action.portlet:editPerson') options=u'action.portlet:createQualification,editPerson')
type(u'task', u'Aufgabe', viewName=u'', type(u'task', u'Aufgabe', viewName=u'',
typeInterface=u'loops.knowledge.interfaces.ITask', typeInterface=u'loops.knowledge.interfaces.ITask',
options=u'action.portlet:createTopic,editTopic') options=u'action.portlet:createTask,editTask')
type(u'topic', u'Thema', viewName=u'', type(u'topic', u'Thema', viewName=u'',
typeInterface=u'loops.knowledge.interfaces.ITopic', typeInterface=u'loops.knowledge.interfaces.ITopic',
options=u'action.portlet:createTopic,editTopic') options=u'action.portlet:createTask,createTopic,editTopic')
type(u'training', u'Schulung', viewName=u'', type(u'training', u'Schulung', viewName=u'',
typeInterface=u'loops.organize.interfaces.ITask', typeInterface=u'loops.organize.interfaces.ITask',
options=u'action.portlet:create_subtype,edit_concept') options=u'action.portlet:edit_concept')
concept(u'general', u'Allgemein', u'domain') concept(u'general', u'Allgemein', u'domain')
concept(u'system', u'System', u'domain') concept(u'system', u'System', u'domain')
@ -26,19 +26,19 @@ concept(u'issubtype', u'is Subtype', u'predicate', options=u'hide_children',
predicateInterface='loops.interfaces.IIsSubtype') predicateInterface='loops.interfaces.IIsSubtype')
# structure # structure
child(u'competence', u'general', u'standard') child(u'general', u'competence', u'standard')
child(u'depends', u'general', u'standard') child(u'general', u'depends', u'standard')
child(u'knows', u'general', u'standard') child(u'general', u'knows', u'standard')
child(u'person', u'general', u'standard') child(u'general', u'person', u'standard')
child(u'provides', u'general', u'standard') child(u'general', u'provides', u'standard')
child(u'requires', u'general', u'standard') child(u'general', u'requires', u'standard')
child(u'task', u'general', u'standard') child(u'general', u'task', u'standard')
child(u'topic', u'general', u'standard') child(u'general', u'topic', u'standard')
child(u'training', u'general', u'standard') child(u'general', u'training', u'standard')
child(u'issubtype', u'system', u'standard') child(u'system', u'issubtype', u'standard')
child(u'training', u'competence', u'issubtype', usePredicate=u'provides') child(u'competence', u'training', u'issubtype', usePredicate=u'provides')
# records # records
records(u'qualification', u'loops.knowledge.qualification.QualificationRecord') records(u'qualification', u'loops.knowledge.qualification.QualificationRecord')

View file

@ -0,0 +1,44 @@
type(u'competence', u'Kompetenz', viewName=u'',
typeInterface=u'', options=u'action.portlet:create_subtype,edit_concept')
# type(u'person', u'Person', viewName=u'',
# typeInterface=u'loops.knowledge.interfaces.IPerson',
# options=u'action.portlet:editPerson')
# type(u'task', u'Aufgabe', viewName=u'',
# typeInterface=u'loops.knowledge.interfaces.ITask',
# options=u'action.portlet:createTask,editTask')
# type(u'topic', u'Thema', viewName=u'',
# typeInterface=u'loops.knowledge.interfaces.ITopic',
# options=u'action.portlet:createTask,createTopic,editTopic')
type(u'training', u'Schulung', viewName=u'',
typeInterface=u'loops.organize.interfaces.ITask',
options=u'action.portlet:edit_concept')
concept(u'general', u'Allgemein', u'domain')
concept(u'system', u'System', u'domain')
# predicates
concept(u'depends', u'depends', u'predicate')
concept(u'knows', u'knows', u'predicate')
concept(u'provides', u'provides', u'predicate')
concept(u'requires', u'requires', u'predicate')
concept(u'issubtype', u'is Subtype', u'predicate', options=u'hide_children',
predicateInterface='loops.interfaces.IIsSubtype')
# structure
child(u'general', u'competence', u'standard')
child(u'general', u'depends', u'standard')
child(u'general', u'knows', u'standard')
#child(u'general', u'person', u'standard')
child(u'general', u'provides', u'standard')
child(u'general', u'requires', u'standard')
#child(u'general', u'task', u'standard')
#child(u'general', u'topic', u'standard')
child(u'general', u'training', u'standard')
child(u'system', u'issubtype', u'standard')
child(u'competence', u'training', u'issubtype', usePredicate=u'provides')
# records
records(u'qualification', u'loops.knowledge.qualification.QualificationRecord')

View file

@ -62,6 +62,48 @@
<metal:block define-macro="create_qualification"> <metal:block define-macro="create_qualification">
<form method="post" id="addQualification_form" class="dialog" <form method="post" id="addQualification_form" class="dialog"
dojoType="dijit.form.Form"> dojoType="dijit.form.Form">
<input type="hidden" name="form.action" value="create_qualification" />
<input type="hidden" name="id"
tal:attributes="value request/form/id|nothing" />
<div class="heading" i18n:translate="">Add Qualification Record</div>
<div>
<label i18n:translate="" for="title">Title</label>
<div>
<input name="title" id="title" style="width: 60em"
dojoType="dijit.form.ValidationTextBox" required
tal:attributes="value view/title" /></div>
</div>
<div>
<label i18n:translate="" for="action">Action</label>
<select name="workitem.action" id="action" style="display:none">
<option tal:repeat="action view/actions"
tal:attributes="value action/name"
tal:content="action/title"
i18n:translate="" />
</select>
<span id="target_competence">&nbsp;
<label i18n:translate="assign_to_competence" for="input_competence"
style="display: inline">Assign to Competence</label>
<span dojoType="dojox.data.QueryReadStore"
jsId="competence_search_store"
tal:define="types python:
view.getTypesParamsForFilteringSelect(['competence'])"
tal:attributes="url string:listConceptsForComboBox.js$types;" >
</span>
<input dojoType="dijit.form.FilteringSelect"
autoComplete="False" labelAttr="label" searchDelay="400"
name="competence" id="input_competence"
store="competence_search_store" />
</span>
</div>
<div>
<label i18n:translate="" for="comment">Comment</label>
<div>
<textarea name="comment" cols="80" rows="4" id="comment"
dojoType="dijit.form.SimpleTextarea"
style="width: 60em"
tal:content="view/comment"></textarea></div>
</div>
<div class="buttons"> <div class="buttons">
<input value="Save" type="submit" <input value="Save" type="submit"
i18n:attributes="value"> i18n:attributes="value">

View file

@ -38,8 +38,12 @@ from loops.organize.work.base import WorkItem, WorkItems
@implementer(IStatesDefinition) @implementer(IStatesDefinition)
def qualificationStates(): def qualificationStates():
return StatesDefinition('qualification', return StatesDefinition('qualification',
State('new', 'new', ('assign',),
color='grey'),
State('open', 'open', State('open', 'open',
('register', 'pass', 'fail', 'cancel', 'modify'), ('register',
#'pass', 'fail',
'cancel', 'modify'),
color='red'), color='red'),
State('registered', 'registered', State('registered', 'registered',
('register', 'pass', 'fail', 'unregister', 'cancel', 'modify'), ('register', 'pass', 'fail', 'unregister', 'cancel', 'modify'),
@ -61,14 +65,17 @@ def qualificationStates():
State('open_x', 'open', ('modify',), color='red'), State('open_x', 'open', ('modify',), color='red'),
State('registered_x', 'registered', ('modify',), color='yellow'), State('registered_x', 'registered', ('modify',), color='yellow'),
# transitions: # transitions:
Transition('assign', 'assign', 'open'),
Transition('register', 'register', 'registered'), Transition('register', 'register', 'registered'),
Transition('pass', 'pass', 'passed'), Transition('pass', 'pass', 'passed'),
Transition('fail', 'fail', 'failed'), Transition('fail', 'fail', 'failed'),
Transition('unregister', 'unregister', 'open'), Transition('unregister', 'unregister', 'open'),
Transition('cancel', 'cancel', 'cancelled'), Transition('cancel', 'cancel', 'cancelled'),
Transition('modify', 'modify', 'open'),
Transition('close', 'close', 'closed'), Transition('close', 'close', 'closed'),
Transition('open', 'open', 'open'), Transition('open', 'open', 'open'),
initialState='open') #initialState='open')
initialState='new') # TODO: handle assignment to competence
class QualificationRecord(WorkItem): class QualificationRecord(WorkItem):

View file

@ -260,7 +260,7 @@ Automatic security settings on persons
>>> from zope.traversing.api import getName >>> from zope.traversing.api import getName
>>> list(sorted(getName(c) for c in concepts['person'].getChildren())) >>> list(sorted(getName(c) for c in concepts['person'].getChildren()))
[u'general', u'jim', u'john', u'martha', u'person.newuser'] [u'jim', u'john', u'martha', u'person.newuser']
Person objects that have a user assigned to them receive this user Person objects that have a user assigned to them receive this user
(principal) as their owner. (principal) as their owner.

View file

@ -307,6 +307,8 @@ class UserWorkItems(PersonWorkItems):
class CreateWorkItemForm(ObjectForm, BaseTrackView): class CreateWorkItemForm(ObjectForm, BaseTrackView):
template = work_macros template = work_macros
recordManagerName = 'work'
trackFactory = WorkItem
def checkPermissions(self): def checkPermissions(self):
return canAccessObject(self.task or self.target) return canAccessObject(self.task or self.target)
@ -325,9 +327,10 @@ class CreateWorkItemForm(ObjectForm, BaseTrackView):
def track(self): def track(self):
id = self.request.form.get('id') id = self.request.form.get('id')
if id is not None: if id is not None:
workItems = self.loopsRoot.getRecordManager()['work'] workItems = self.loopsRoot.getRecordManager()[
self.recordManagerName]
return workItems.get(id) return workItems.get(id)
return WorkItem(None, 0, None, {}) return self.trackFactory(None, 0, None, {})
@Lazy @Lazy
def title(self): def title(self):