diff --git a/expert/README.txt b/expert/README.txt index 545c865..7ac8ed8 100644 --- a/expert/README.txt +++ b/expert/README.txt @@ -27,7 +27,7 @@ configuration): >>> concepts, resources, views = t.setup() >>> len(concepts) + len(resources) - 38 + 41 >>> loopsRoot = site['loops'] @@ -47,11 +47,11 @@ Type- and text-based queries >>> from loops.expert import query >>> qu = query.Title('ty*') >>> list(qu.apply()) - [0, 2, 69] + [0, 2, 79] >>> qu = query.Type('loops:*') >>> len(list(qu.apply())) - 38 + 41 >>> qu = query.Type('loops:concept:predicate') >>> len(list(qu.apply())) diff --git a/expert/search.txt b/expert/search.txt index d66ed00..8905fc6 100755 --- a/expert/search.txt +++ b/expert/search.txt @@ -66,13 +66,13 @@ zcml in real life: >>> t = searchView.typesForSearch() >>> len(t) - 16 + 19 >>> t.getTermByToken('loops:resource:*').title 'Any Resource' >>> t = searchView.conceptTypesForSearch() >>> len(t) - 13 + 16 >>> t.getTermByToken('loops:concept:*').title 'Any Concept' @@ -91,7 +91,7 @@ a controller attribute for the search view. >>> searchView.submitReplacing('1.results', '1.search.form', pageView) 'submitReplacing("1.results", "1.search.form", - "http://127.0.0.1/loops/views/page/.target100/@@searchresults.html");...' + "http://127.0.0.1/loops/views/page/.target110/@@searchresults.html");...' Basic (text/title) search ------------------------- @@ -177,7 +177,7 @@ of the concepts' titles: >>> request = TestRequest(form=form) >>> view = Search(page, request) >>> view.listConcepts() - u"{identifier: 'id', items: [{label: 'Zope (Thema)', name: 'Zope', id: '105'}, {label: 'Zope 2 (Thema)', name: 'Zope 2', id: '107'}, {label: 'Zope 3 (Thema)', name: 'Zope 3', id: '109'}]}" + u"{identifier: 'id', items: [{label: 'Zope (Thema)', name: 'Zope', id: '115'}, {label: 'Zope 2 (Thema)', name: 'Zope 2', id: '117'}, {label: 'Zope 3 (Thema)', name: 'Zope 3', id: '119'}]}" Preset Concept Types on Search Forms ------------------------------------ @@ -219,13 +219,13 @@ and thus include the customer type in the preset search types. >>> searchView.conceptsForType('loops:concept:customer') [{'token': 'none', 'title': u'not selected'}, - {'token': '78', 'title': u'Customer 1'}, - {'token': '80', 'title': u'Customer 2'}, - {'token': '82', 'title': u'Customer 3'}] + {'token': '88', 'title': u'Customer 1'}, + {'token': '90', 'title': u'Customer 2'}, + {'token': '92', 'title': u'Customer 3'}] Let's use this new search option for querying: - >>> form = {'search.4.text_selected': u'74'} + >>> form = {'search.4.text_selected': u'84'} >>> resultsView = SearchResults(page, TestRequest(form=form)) >>> results = list(resultsView.results) >>> results[0].title diff --git a/external/README.txt b/external/README.txt index 5fddc0e..c98ad79 100644 --- a/external/README.txt +++ b/external/README.txt @@ -17,7 +17,7 @@ Let's set up a loops site with basic and example concepts and resources. >>> concepts, resources, views = t.setup() >>> loopsRoot = site['loops'] >>> len(concepts), len(resources), len(views) - (35, 3, 1) + (38, 3, 1) Importing loops Objects @@ -44,7 +44,7 @@ Creating the corresponding objects >>> loader = Loader(loopsRoot) >>> loader.load(elements) >>> len(concepts), len(resources), len(views) - (36, 3, 1) + (39, 3, 1) >>> from loops.common import adapted >>> adMyquery = adapted(concepts['myquery']) @@ -118,7 +118,7 @@ Extracting elements >>> extractor = Extractor(loopsRoot, os.path.join(dataDirectory, 'export')) >>> elements = list(extractor.extract()) >>> len(elements) - 67 + 74 Writing object information to the external storage -------------------------------------------------- diff --git a/knowledge/data/knowledge_de.dmp b/knowledge/data/knowledge_de.dmp index 83367d9..751cf9f 100644 --- a/knowledge/data/knowledge_de.dmp +++ b/knowledge/data/knowledge_de.dmp @@ -1,6 +1,12 @@ -type(u'competence', u'Kompetenz', viewName=u'', +type(u'competence', u'Qualifikation', viewName=u'', typeInterface=u'loops.knowledge.qualification.interfaces.ICompetence', options=u'action.portlet:create_subtype,edit_concept') +type(u'ipskill', u'Kompetenz', viewName=u'', + options=u'action.portlet:edit_concept') +type(u'ipskillsrequired', u'Soll-Profil', viewName=u'', + options=u'action.portlet:edit_concept') +type(u'jobposition', u'Stelle', viewName=u'', + options=u'action.portlet:edit_concept') type(u'person', u'Person', viewName=u'', typeInterface=u'loops.knowledge.interfaces.IPerson', options=u'action.portlet:createQualification,editPerson') @@ -35,6 +41,9 @@ concept(u'qualification_overview', u'Qualification Overview', u'report', # structure child(u'general', u'competence', u'standard') child(u'general', u'depends', u'standard') +child(u'general', u'ipskill', u'standard') +child(u'general', u'ipskillsrequired', u'standard') +child(u'general', u'jobposition', u'standard') child(u'general', u'knows', u'standard') child(u'general', u'person', u'standard') child(u'general', u'provides', u'standard') @@ -44,6 +53,7 @@ child(u'general', u'topic', u'standard') #child(u'general', u'training', u'standard') child(u'system', u'issubtype', u'standard') +child(u'system', u'report', u'standard') child(u'competence', u'competence', u'issubtype') #child(u'competence', u'training', u'issubtype', usePredicate=u'provides') diff --git a/knowledge/data/knowledge_update_de.dmp b/knowledge/data/knowledge_update_de.dmp index 2a359c2..06d7f29 100644 --- a/knowledge/data/knowledge_update_de.dmp +++ b/knowledge/data/knowledge_update_de.dmp @@ -1,6 +1,14 @@ -type(u'competence', u'Kompetenz', viewName=u'', +type(u'competence', u'Qualifikation', viewName=u'', typeInterface=u'loops.knowledge.qualification.interfaces.ICompetence', options=u'action.portlet:create_subtype,edit_concept') +type(u'ipskill', u'Kompetenz', viewName=u'', + options=u'action.portlet:edit_concept') +type(u'ipskillsrequired', u'Soll-Profil', viewName=u'', + options=u'action.portlet:edit_concept') +type(u'jobposition', u'Stelle', viewName=u'', + options=u'action.portlet:edit_concept') +type(u'report', u'Report', viewName=u'', + typeInterface='loops.expert.report.IReport') # type(u'person', u'Person', viewName=u'', # typeInterface=u'loops.knowledge.interfaces.IPerson', # options=u'action.portlet:editPerson') @@ -33,6 +41,9 @@ concept(u'qualification_overview', u'Qualification Overview', u'report', # structure child(u'general', u'competence', u'standard') child(u'general', u'depends', u'standard') +child(u'general', u'ipskill', u'standard') +child(u'general', u'ipskillsrequired', u'standard') +child(u'general', u'jobposition', u'standard') child(u'general', u'knows', u'standard') #child(u'general', u'person', u'standard') child(u'general', u'provides', u'standard') @@ -42,6 +53,7 @@ child(u'general', u'requires', u'standard') #child(u'general', u'training', u'standard') child(u'system', u'issubtype', u'standard') +child(u'system', u'report', u'standard') child(u'competence', u'competence', u'issubtype') #child(u'competence', u'training', u'issubtype', usePredicate=u'provides') diff --git a/knowledge/qualification/browser.py b/knowledge/qualification/browser.py index e9e6641..054e143 100644 --- a/knowledge/qualification/browser.py +++ b/knowledge/qualification/browser.py @@ -25,11 +25,71 @@ from zope import interface, component from zope.app.pagetemplate import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy +from cybertools.browser.action import actions +from loops.browser.action import DialogAction +from loops.browser.concept import ConceptView from loops.expert.browser.report import ResultsConceptView -from loops.knowledge.browser import template, knowledge_macros +from loops.organize.party import getPersonForUser +from loops.util import _ + +template = ViewPageTemplateFile('qualification_macros.pt') + + +actions.register('createJobPosition', 'portlet', DialogAction, + title=_(u'Create Job...'), + description=_(u'Create a new job / position.'), + viewName='create_concept.html', + dialogName='createPosition', + typeToken='.loops/concepts/jobposition', + fixedType=True, + innerForm='inner_concept_form.html', + permission='loops.AssignAsParent', +) class Qualifications(ResultsConceptView): reportName = 'qualification_overview' + +class QualificationBaseView(object): + + template = template + templateName = 'knowledge.qualification' + + @Lazy + def institutionType(self): + return self.conceptManager['institution'] + + @Lazy + def jobPositionType(self): + return self.conceptManager['jobposition'] + + @Lazy + def isMemberPredicate(self): + return self.conceptManager['ismember'] + + +class JobPositionsOverview(QualificationBaseView, ConceptView): + + macroName = 'jobpositions' + + @Lazy + def positions(self): + result = [] + p = getPersonForUser(self.context, self.request) + if p is not None: + for parent in p.getParents([self.isMemberPredicate]): + if parent.conceptType == self.institutionType: + for child in parent.getChildren([self.defaultPredicate]): + if child.conceptType == self.jobPositionType: + result.append(child) + return result + + +class IPSkillsForm(QualificationBaseView, ConceptView): + """ Form for entering interpersonal skills required for a certain position. + """ + + macroName = 'ipskillsform' + diff --git a/knowledge/qualification/configure.zcml b/knowledge/qualification/configure.zcml index e4f02c9..06a3a27 100644 --- a/knowledge/qualification/configure.zcml +++ b/knowledge/qualification/configure.zcml @@ -23,6 +23,22 @@ factory="loops.knowledge.qualification.browser.Qualifications" permission="zope.View" /> + + + + + + + + +

Jobs / Positions

+ + + + + + +
+
+ + + \ No newline at end of file diff --git a/locales/de/LC_MESSAGES/loops.mo b/locales/de/LC_MESSAGES/loops.mo index a98c638..bcc801f 100644 Binary files a/locales/de/LC_MESSAGES/loops.mo and b/locales/de/LC_MESSAGES/loops.mo differ diff --git a/locales/de/LC_MESSAGES/loops.po b/locales/de/LC_MESSAGES/loops.po index 0b403e5..09a8588 100644 --- a/locales/de/LC_MESSAGES/loops.po +++ b/locales/de/LC_MESSAGES/loops.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: 0.13.0\n" "POT-Creation-Date: 2007-05-22 12:00 CET\n" -"PO-Revision-Date: 2014-07-11 12:00 CET\n" +"PO-Revision-Date: 2014-07-30 12:00 CET\n" "Last-Translator: Helmut Merz \n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -298,7 +298,16 @@ msgstr "Rang Team" msgid "Team Size" msgstr "Anzahl der vom Team ausgefüllten Fragebögen" -# competence (qualification) +# compentence and qualification management + +msgid "Jobs / Positions" +msgstr "Stellen" + +msgid "Create Job..." +msgstr "Stelle anlegen..." + +msgid "Create a new job / position" +msgstr "Eine neue Stelle anlegen..." msgid "Validity Period (Months)" msgstr "Gültigkeitszeitraum (Monate)" diff --git a/organize/README.txt b/organize/README.txt index c37d7f3..adfe499 100644 --- a/organize/README.txt +++ b/organize/README.txt @@ -427,7 +427,7 @@ Send Email to Members >>> form.subject u"loops Notification from '$site'" >>> form.mailBody - u'\n\nEvent #1\nhttp://127.0.0.1/loops/views/menu/.117\n\n' + u'\n\nEvent #1\nhttp://127.0.0.1/loops/views/menu/.127\n\n' Show Presence of Other Users diff --git a/system/sync/README.txt b/system/sync/README.txt index 143c6a9..0cfb89d 100644 --- a/system/sync/README.txt +++ b/system/sync/README.txt @@ -18,7 +18,7 @@ Let's set up a loops site with basic and example concepts and resources. >>> concepts, resources, views = t.setup() >>> loopsRoot = site['loops'] >>> len(concepts), len(resources), len(views) - (35, 3, 1) + (38, 3, 1) >>> from cybertools.tracking.btree import TrackingStorage >>> from loops.system.job import JobRecord diff --git a/xmlrpc/README.txt b/xmlrpc/README.txt index de55ea2..b12dd76 100755 --- a/xmlrpc/README.txt +++ b/xmlrpc/README.txt @@ -35,7 +35,7 @@ ZCML setup): Let's look what setup has provided us with: >>> len(concepts) - 24 + 27 Now let's add a few more concepts: @@ -72,7 +72,8 @@ note that the 'hasType' predicate is not shown as it should not be applied in an explicit assignment. >>> sorted(t['name'] for t in xrf.getConceptTypes()) - [u'competence', u'customer', u'domain', u'file', u'note', u'person', + [u'competence', u'customer', u'domain', u'file', u'ipskill', + u'ipskillsrequired', u'jobposition', u'note', u'person', u'predicate', u'report', u'task', u'textdocument', u'topic', u'type'] >>> sorted(t['name'] for t in xrf.getPredicates()) [u'depends', u'issubtype', u'knows', u'ownedby', u'provides', u'requires', @@ -95,7 +96,8 @@ All methods that retrieve one object also returns its children and parents: >>> ch[0]['name'] u'hasType' >>> sorted(c['name'] for c in ch[0]['objects']) - [u'competence', u'customer', u'domain', u'file', u'note', u'person', + [u'competence', u'customer', u'domain', u'file', u'ipskill', + u'ipskillsrequired', u'jobposition', u'note', u'person', u'predicate', u'report', u'task', u'textdocument', u'topic', u'type'] >>> pa = defaultPred['parents'] @@ -114,7 +116,8 @@ We can also retrieve children and parents explicitely: >>> ch[0]['name'] u'hasType' >>> sorted(c['name'] for c in ch[0]['objects']) - [u'competence', u'customer', u'domain', u'file', u'note', u'person', + [u'competence', u'customer', u'domain', u'file', u'ipskill', + u'ipskillsrequired', u'jobposition', u'note', u'person', u'predicate', u'report', u'task', u'textdocument', u'topic', u'type'] >>> pa = xrf.getParents('5') @@ -174,14 +177,14 @@ Updating the concept map >>> topicId = xrf.getObjectByName('topic')['id'] >>> xrf.createConcept(topicId, u'zope2', u'Zope 2') - {'description': u'', 'title': u'Zope 2', 'type': '38', 'id': '76', + {'description': u'', 'title': u'Zope 2', 'type': '44', 'id': '86', 'name': u'zope2'} The name of the concept is checked by a name chooser; if the corresponding parameter is empty, the name will be generated from the title. >>> xrf.createConcept(topicId, u'', u'Python') - {'description': u'', 'title': u'Python', 'type': '38', 'id': '78', + {'description': u'', 'title': u'Python', 'type': '44', 'id': '88', 'name': u'python'} If we try to deassign a ``hasType`` relation nothing will happen; a