From 9b4098c9da106b31d3e3b44bf2ac13468de1ad12 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Thu, 9 Aug 2012 14:05:04 +0200 Subject: [PATCH] meeting minutes improvements create follow-up event: automatic creation of work items on new agenda item if selected; finished work items are not selected append new child to end of existing children if option 'children_append' is set and children is already ordered manually --- browser/form.py | 8 +++++ locales/de/LC_MESSAGES/loops.mo | Bin 18541 -> 18719 bytes locales/de/LC_MESSAGES/loops.po | 8 ++++- organize/browser/event.py | 19 ++++++++++-- organize/work/meeting.pt | 52 +++++++++++++++++++------------- organize/work/report.py | 5 ++- 6 files changed, 66 insertions(+), 26 deletions(-) diff --git a/browser/form.py b/browser/form.py index c20723f..8fcda99 100644 --- a/browser/form.py +++ b/browser/form.py @@ -45,6 +45,7 @@ from cybertools.composer.schema.grid.field import grid_macros from cybertools.composer.schema.interfaces import ISchemaFactory from cybertools.composer.schema.browser.common import schema_macros, schema_edit_macros from cybertools.composer.schema.schema import FormState +from cybertools.meta.interfaces import IOptions from cybertools.stateful.interfaces import IStateful from cybertools.typology.interfaces import IType, ITypeManager from cybertools.util.format import toUnicode @@ -727,6 +728,13 @@ class EditConcept(EditObject): return obj.getParentRelations(predicates=predicates, parent=concept) def assignConcept(self, obj, concept, predicate): + if IOptions(adapted(concept.conceptType)).children_append: + sibRelations = concept.getChildRelations() + if sibRelations: + maxOrder = max([r.order for r in sibRelations]) + if maxOrder > 0: + return obj.assignParent(concept, predicate, + order=maxOrder+1) obj.assignParent(concept, predicate) def deassignConcept(self, obj, concept, predicates): diff --git a/locales/de/LC_MESSAGES/loops.mo b/locales/de/LC_MESSAGES/loops.mo index 4e48081b67f87851c8ec7d1574773185113692fc..25e408f49f0556a845b72ad254e0b6e8330e026a 100644 GIT binary patch delta 7197 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\n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -275,6 +275,12 @@ msgstr "Eine neues Projekt anlegen." msgid "Create Work Item..." msgstr "Aktivität anlegen..." +msgid "Create a work item for this object." +msgstr "Eine Aktivität zu diesem Objekt anlegen." + +msgid "Add Work Item" +msgstr "Aktivität anlegen/bearbeiten" + msgid "Edit Video..." msgstr "Video bearbeiten..." diff --git a/organize/browser/event.py b/organize/browser/event.py index 7245e41..514c0ed 100644 --- a/organize/browser/event.py +++ b/organize/browser/event.py @@ -39,6 +39,7 @@ from loops.browser.node import NodeView from loops.common import adapted, baseObject from loops.concept import Concept from loops.organize.work.meeting import MeetingMinutes +from loops.organize.tracking.report import TrackDetails from loops.setup import addAndConfigureObject from loops.util import _ from loops import util @@ -317,9 +318,21 @@ class CreateFollowUpEvent(CreateConcept, BaseFollowUpController): result = super(CreateFollowUpEvent, self).update() form = self.request.form toBeAssigned = form.get('cb_select_tasks') or [] - for uid in toBeAssigned: - task = util.getObjectForUid(uid) - self.createFollowUpTask(adapted(task)) + taskId = newTask = None + workItems = self.view.loopsRoot.getRecordManager()['work'] + for id in sorted(toBeAssigned): + if not '.' in id: + taskId = id + task = util.getObjectForUid(id) + newTask = self.createFollowUpTask(adapted(task)) + else: + tId, trackId = id.split('.') + if tId == taskId: + track = workItems.get(trackId) + if track is not None: + td = TrackDetails(self.view, track) + newTId = self.view.getUidForObject(newTask) + track.doAction('move', td.personId, task=newTId) return result def createFollowUpTask(self, source): diff --git a/organize/work/meeting.pt b/organize/work/meeting.pt index 4e80606..3d5a5c7 100644 --- a/organize/work/meeting.pt +++ b/organize/work/meeting.pt @@ -86,19 +86,21 @@ style="border: 1px solid grey">Copy Agenda Items +           - + + + style="border: 1px solid grey" class="center"> + value taskUid" /> - - - header_workitems - header_responsible - header_deadline - - - + + + + header_workitems + header_responsible + header_deadline + + - + + + tal:define="fields results/displayedColumns"> + style="border: 1px solid grey" class="center"> + +