Ejemplo n.º 1
0
def create_subtask(task, data):
    subtask = createContent('opengever.task.task',
                            id=data['title'],
                            **data)
    notify(ObjectCreatedEvent(subtask))
    subtask = addContentToContainer(task, subtask,
                                    checkConstraints=True)

    for schemata in iterSchemata(subtask):
        super_repr = schemata(task)
        repr = schemata(subtask)

        for name, field in schema.getFieldsInOrder(schemata):
            if name in data:
                value = data[name]

            else:
                value = getattr(super_repr, name, None)

            setattr(repr, name, value)

    activity = TaskAddedActivity(subtask, task.REQUEST, task)
    activity.record()

    notify(ObjectModifiedEvent(subtask))
    return subtask
Ejemplo n.º 2
0
    def create_subtask(self, main_task, template, values):
        data = dict(
            title=template.title,
            issuer=template.issuer,
            responsible=template.responsible,
            responsible_client=template.responsible_client,
            task_type=template.task_type,
            text=template.text,
            relatedItems=self.related_documents,
            deadline=date.today() + timedelta(template.deadline),
        )

        data.update(values)
        self.replace_interactive_actors(data)

        task = self.add_task(main_task, data)
        self.set_initial_state(task, template)
        task.reindexObject()
        task.get_sql_object().sync_with(task)

        # add activity record for subtask
        if api.content.get_state(task) != TASK_STATE_PLANNED:
            activity = TaskAddedActivity(task, getRequest(), main_task)
            activity.record()

        return task
    def create_subtask(self, main_task, template, values):
        data = dict(
            title=template.title,
            issuer=template.issuer,
            responsible=template.responsible,
            responsible_client=template.responsible_client,
            task_type=template.task_type,
            text=template.text,
            relatedItems=self.related_documents,
            deadline=date.today() + timedelta(template.deadline),
        )

        data.update(values)
        self.replace_interactive_actors(data)

        task = self.add_task(main_task, data)
        self.set_initial_state(task, template)
        task.reindexObject()
        task.get_sql_object().sync_with(task)

        # add activity record for subtask
        if api.content.get_state(task) != TASK_STATE_PLANNED:
            activity = TaskAddedActivity(task, getRequest(), main_task)
            activity.record()

        return task
Ejemplo n.º 4
0
def create_subtask(task, data):
    subtask = createContent('opengever.task.task',
                            id=data['title'],
                            **data)
    notify(ObjectCreatedEvent(subtask))
    subtask = addContentToContainer(task, subtask,
                                    checkConstraints=True)

    for schemata in iterSchemata(subtask):
        super_repr = schemata(task)
        repr = schemata(subtask)

        for name, field in schema.getFieldsInOrder(schemata):
            if name in data:
                value = data[name]

            else:
                value = getattr(super_repr, name, None)

            setattr(repr, name, value)

    activity = TaskAddedActivity(subtask, task.REQUEST, task)
    activity.record()

    notify(ObjectModifiedEvent(subtask))
    return subtask
Ejemplo n.º 5
0
    def test_notification_mails_dont_interfere_with_txn_savepoints(self):
        # Login with a different user than task_responsible to trigger mail
        self.login(self.dossier_responsible)

        # Trigger a notification that dispatches a mail
        activity = TaskAddedActivity(self.task, getRequest(), self.dossier)
        activity.record()

        # Creating a savepoint will fail with the MailDataManager if it's
        # already registered as a transaction manager at that point
        transaction.savepoint()
Ejemplo n.º 6
0
    def test_notification_mails_dont_interfere_with_txn_savepoints(self):
        # Login with a different user than task_responsible to trigger mail
        self.login(self.dossier_responsible)

        # Trigger a notification that dispatches a mail
        activity = TaskAddedActivity(self.task, getRequest(), self.dossier)
        activity.record()

        # Creating a savepoint will fail with the MailDataManager if it's
        # already registered as a transaction manager at that point
        transaction.savepoint()
Ejemplo n.º 7
0
    def test_list_all_notifications_for_the_given_userid(self, browser):
        self.login(self.administrator, browser=browser)

        center = notification_center()

        self.assertEqual(0,  Notification.query.count())

        with freeze(datetime(2017, 10, 16, 0, 0, tzinfo=pytz.utc)):
            TaskAddedActivity(self.task, self.request, self.task.__parent__).record()

        for notification in Notification.query.all():
            notification.is_read = True

        with freeze(datetime(2018, 10, 16, 0, 0, tzinfo=pytz.utc)):
            TaskAddedActivity(self.task, self.request, self.task.__parent__).record()

        self.assertEqual(2, len(center.get_watchers(self.task)))

        # two notifications for each watcher, the responsible and the issuer
        self.assertEqual(4,  Notification.query.count())

        self.login(self.regular_user, browser=browser)

        url = '{}/@notifications/{}'.format(self.portal.absolute_url(),
                                            self.regular_user.getId())
        browser.open(url, method='GET', headers={'Accept': 'application/json'})

        self.assertEqual(200, browser.status_code)

        self.assertEquals(
            [{u'@id': u'http://nohost/plone/@notifications/kathi.barfuss/3',
              u'actor_id': u'nicole.kohler',
              u'actor_label': u'Kohler Nicole',
              u'created': u'2018-10-16T00:00:00+00:00',
              u'label': u'Task opened',
              u'link': u'http://nohost/plone/@@resolve_notification?notification_id=3',
              u'notification_id': 3,
              u'read': False,
              u'summary': u'New task opened by Ziegler Robert',
              u'title': u'Vertragsentwurf \xdcberpr\xfcfen'},
             {u'@id': u'http://nohost/plone/@notifications/kathi.barfuss/1',
              u'actor_id': u'nicole.kohler',
              u'actor_label': u'Kohler Nicole',
              u'created': u'2017-10-16T00:00:00+00:00',
              u'label': u'Task opened',
              u'link': u'http://nohost/plone/@@resolve_notification?notification_id=1',
              u'notification_id': 1,
              u'read': True,
              u'summary': u'New task opened by Ziegler Robert',
              u'title': u'Vertragsentwurf \xdcberpr\xfcfen'}],
            browser.json.get('items'))
Ejemplo n.º 8
0
    def _create_task(self, task_payload):

        view = self.context.restrictedTraverse('++add++opengever.task.task')
        task_form = view.form_instance
        task_form.instance_schema = ITask

        task_form.updateFieldsFromSchemata()
        task_form.updateWidgets()

        task = task_form.create(task_payload)
        notify(ObjectCreatedEvent(task))
        task_form.add(task)

        activity = TaskAddedActivity(task, self.request, self.context)
        activity.record()
        return task
Ejemplo n.º 9
0
    def test_batch_notifications(self, browser):
        self.login(self.administrator, browser=browser)

        center = notification_center()

        self.assertEqual(0,  Notification.query.count())

        with freeze(datetime(2017, 10, 16, 0, 0, tzinfo=pytz.utc)):
            for i in range(5):
                TaskAddedActivity(self.task, self.request, self.task.__parent__).record()

        self.login(self.regular_user, browser=browser)

        batch_size = 2
        url = '{}/@notifications/{}?b_size={}'.format(
            self.portal.absolute_url(),
            self.regular_user.getId(),
            batch_size)

        browser.open(url, method='GET', headers={'Accept': 'application/json'})

        self.assertEqual(200, browser.status_code)

        self.assertEquals(5, browser.json.get('items_total'))
        self.assertEquals(2, len(browser.json.get('items')))

        url = browser.json.get('batching').get('last')
        browser.open(url, method='GET', headers={'Accept': 'application/json'})

        # 5 notifications with a batchsize of 2 will display only 1 notification
        # on the last batch
        self.assertEquals(1, len(browser.json.get('items')))
Ejemplo n.º 10
0
    def open_next_task(self):
        next_task = self.get_sql_object().get_next_task()
        if not next_task:
            return

        next_task = next_task.oguid.resolve_object()
        if api.content.get_state(obj=next_task) == TASK_STATE_PLANNED:
            with as_internal_workflow_transition():
                api.content.transition(
                    obj=next_task, transition='task-transition-planned-open')

            next_task.sync()

            activity = TaskAddedActivity(
                next_task, getRequest(), aq_parent(next_task))
            activity.record()
Ejemplo n.º 11
0
    def test_returns_serialized_notifications_for_the_given_userid_and_notification_id(self, browser):
        self.login(self.dossier_responsible, browser=browser)

        self.assertEqual(0,  Notification.query.count())

        with freeze(datetime(2017, 10, 16, 0, 0, tzinfo=pytz.utc)):
            TaskAddedActivity(self.task, self.request, self.task.__parent__).record()

        url = '{}/@notifications/{}/1'.format(self.portal.absolute_url(),
                                              self.regular_user.getId())

        self.login(self.regular_user, browser=browser)
        browser.open(url, method='GET', headers={'Accept': 'application/json'})

        self.assertEqual(200, browser.status_code)

        self.assertEquals(
            {u'@id': u'http://nohost/plone/@notifications/kathi.barfuss/1',
             u'actor_id': u'robert.ziegler',
             u'actor_label': u'Ziegler Robert',
             u'created': u'2017-10-16T00:00:00+00:00',
             u'label': u'Task opened',
             u'link': u'http://nohost/plone/@@resolve_notification?notification_id=1',
             u'notification_id': 1,
             u'read': False,
             u'summary': u'New task opened by Ziegler Robert',
             u'title': u'Vertragsentwurf \xdcberpr\xfcfen'},
            browser.json)
Ejemplo n.º 12
0
    def open_next_task(self):
        next_task = self.get_sql_object().get_next_task()
        if not next_task:
            return

        next_task = next_task.oguid.resolve_object()
        if api.content.get_state(obj=next_task) == TASK_STATE_PLANNED:
            with as_internal_workflow_transition():
                api.content.transition(
                    obj=next_task, transition='task-transition-planned-open')

            next_task.sync()

            activity = TaskAddedActivity(next_task, getRequest(),
                                         aq_parent(next_task))
            activity.record()
Ejemplo n.º 13
0
    def _create_task(self, task_payload):

        view = self.context.restrictedTraverse('++add++opengever.task.task')
        task_form = view.form_instance
        task_form.instance_schema = ITask

        task_form.updateFieldsFromSchemata()
        task_form.updateWidgets()

        task = task_form.create(task_payload)
        notify(ObjectCreatedEvent(task))
        task_form.add(task)

        activity = TaskAddedActivity(task, self.request, self.context)
        activity.record()
        return task
Ejemplo n.º 14
0
    def after_transition_hook(self, transition, disable_sync, transition_params):
        response = add_simple_response(self.context, transition=transition,
                                       text=transition_params.get('text'),
            supress_activity=True)

        TaskAddedActivity(
            self.context, getRequest(), aq_parent(self.context)).record()

        self.save_related_items(response, transition_params.get('relatedItems'))
        self.sync_change(transition, transition_params.get('text'), disable_sync)
Ejemplo n.º 15
0
    def create_subtask(self, main_task, template, related_documents):
        data = dict(
            title=template.title,
            issuer=self.replace_interactive_user(template.issuer),
            responsible=self.replace_interactive_user(template.responsible),
            task_type=template.task_type,
            text=template.text,
            relatedItems=related_documents,
            deadline=date.today() + timedelta(template.deadline),
        )

        data['responsible_client'] = self.get_responsible_client(
            template, data['responsible'])

        task = createContent('opengever.task.task', **data)
        notify(ObjectCreatedEvent(task))
        task = addContentToContainer(main_task, task, checkConstraints=True)
        self.mark_as_generated_from_tasktemplate(task)

        task.reindexObject()

        # add activity record for subtask
        activity = TaskAddedActivity(task, self.request, self.context)
        activity.record()
Ejemplo n.º 16
0
    def create_subtask(self, main_task, template, related_documents):
        data = dict(
            title=template.title,
            issuer=self.replace_interactive_user(template.issuer),
            responsible=self.replace_interactive_user(template.responsible),
            task_type=template.task_type,
            text=template.text,
            relatedItems=related_documents,
            deadline=date.today() + timedelta(template.deadline),
        )

        data['responsible_client'] = self.get_responsible_client(
            template, data['responsible'])

        task = createContent('opengever.task.task', **data)
        notify(ObjectCreatedEvent(task))
        task = addContentToContainer(main_task, task, checkConstraints=True)
        self.mark_as_generated_from_tasktemplate(task)

        task.reindexObject()

        # add activity record for subtask
        activity = TaskAddedActivity(task, self.request, self.context)
        activity.record()
Ejemplo n.º 17
0
    def test_raises_unauthorized_when_accessing_notification_of_other_user(self, browser):
        self.login(self.dossier_responsible, browser=browser)

        with freeze(datetime(2017, 10, 16, 0, 0, tzinfo=pytz.utc)):
            TaskAddedActivity(self.task, self.request, self.task.__parent__).record()

        # Different username in path
        with browser.expect_http_error(401):
            url = '{}/@notifications/{}/1'.format(
                self.portal.absolute_url(), self.regular_user.getId())
            browser.open(url, data=json.dumps({}), method='PATCH',
                         headers={'Accept': 'application/json'})

        # Own username but foreign notification-id
        with browser.expect_http_error(401):
            url = '{}/@notifications/{}/1'.format(
                self.portal.absolute_url(), self.dossier_responsible.getId())
            browser.open(url, data=json.dumps({}), method='PATCH',
                         headers={'Accept': 'application/json'})
Ejemplo n.º 18
0
    def test_mark_notification_as_read(self, browser):
        self.login(self.dossier_responsible, browser=browser)

        TaskAddedActivity(self.task, self.request, self.task.__parent__).record()

        url = '{}/@notifications/{}/{}'.format(self.portal.absolute_url(),
                                               self.regular_user.getId(), 1)

        self.login(self.regular_user, browser=browser)

        browser.open(url, method='GET', headers={'Accept': 'application/json'})

        self.assertFalse(Notification.query.first().is_read)

        data = json.dumps({'read': True})
        browser.open(url, data=data, method='PATCH',
                     headers={'Accept': 'application/json'})

        self.assertEqual(204, browser.status_code)
        self.assertTrue(Notification.query.first().is_read)
Ejemplo n.º 19
0
def record_added_activity(task, event):
    """Record task added activity, which also sets wathcers and
    create notifications.
    """
    # Skip tasks created during successor creation, those are handled manually
    if getRequest().get('X-CREATING-SUCCESSOR', None):
        return

    # Skip tasks created during tasktemplatefolder triggering, those are
    # handled manually
    if IDuringTaskTemplateFolderTriggering.providedBy(getRequest()):
        return

    parent = aq_parent(aq_inner(task))
    if IForwarding.providedBy(task):
        activity = ForwardingAddedActivity(task, getRequest(), parent)
    else:
        activity = TaskAddedActivity(task, getRequest(), parent)

    activity.record()
Ejemplo n.º 20
0
    def create(self, paths=[]):
        """generate the task templates"""

        if 'abort' in self.request.keys():
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        templates = []

        for path in paths:
            templates.append(self.context.restrictedTraverse(path))

        if len(templates) == 0:
            IStatusMessage(self.request).addStatusMessage(_(
                u'message_no_templates_selected',
                default=u'You have not selected any templates'),
                                                          type="info")

            return self.request.RESPONSE.redirect(self.context.absolute_url())

        # Create main task
        templatefolder = aq_parent(aq_inner(templates[0]))

        highest_deadline = max([temp.deadline for temp in templates])

        deadline_timedelta = api.portal.get_registry_record(
            'deadline_timedelta', interface=ITaskSettings)

        data = dict(
            title=templatefolder.title,
            issuer=self.replace_interactive_user('current_user'),
            responsible=self.replace_interactive_user('current_user'),
            responsible_client=get_current_org_unit().id(),
            task_type='direct-execution',
            deadline=date.today() +
            timedelta(highest_deadline + deadline_timedelta),
        )

        main_task = createContent('opengever.task.task', **data)
        notify(ObjectCreatedEvent(main_task))
        main_task = addContentToContainer(self.context,
                                          main_task,
                                          checkConstraints=True)
        ogdsservice = ogds_service()

        # set marker Interfaces
        alsoProvides(main_task, IFromTasktemplateGenerated)

        # set the main_task in to the in progress state
        wft = getToolByName(self.context, 'portal_workflow')
        wft.doActionFor(main_task, 'task-transition-open-in-progress')

        # create subtasks
        for template in templates:
            deadline = date.today() + timedelta(template.deadline)

            data = dict(
                title=template.title,
                issuer=self.replace_interactive_user(template.issuer),
                responsible=self.replace_interactive_user(
                    template.responsible),
                task_type=template.task_type,
                text=template.text,
                deadline=deadline,
            )

            if template.responsible_client == 'interactive_users':
                responsible_assigned_org_units = ogdsservice.assigned_org_units(
                    data['responsible'])
                current_org_unit = get_current_org_unit()
                if not responsible_assigned_org_units or \
                        current_org_unit in responsible_assigned_org_units:
                    data['responsible_client'] = current_org_unit.id()
                else:
                    data['responsible_client'] = \
                        responsible_assigned_org_units[0].id()
            else:
                data['responsible_client'] = template.responsible_client

            task = createContent('opengever.task.task', **data)
            notify(ObjectCreatedEvent(task))
            task = addContentToContainer(main_task,
                                         task,
                                         checkConstraints=True)
            alsoProvides(task, IFromTasktemplateGenerated)
            task.reindexObject()

            # add activity record for subtask
            activity = TaskAddedActivity(task, self.request, self.context)
            activity.record()

        # add activity record for the main task
        activity = TaskAddedActivity(main_task, self.request, self.context)
        activity.record()

        IStatusMessage(self.request).addStatusMessage(_(
            u'message_tasks_created', default=u'tasks created'),
                                                      type="info")

        return self.request.RESPONSE.redirect('%s#tasks' %
                                              self.context.absolute_url())
Ejemplo n.º 21
0
    def create(self, paths=[]):
        """generate the task templates"""

        if "abort" in self.request.keys():
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        templates = []

        for path in paths:
            templates.append(self.context.restrictedTraverse(path))

        if len(templates) == 0:
            IStatusMessage(self.request).addStatusMessage(
                _(u"message_no_templates_selected", default=u"You have not selected any templates"), type="info"
            )

            return self.request.RESPONSE.redirect(self.context.absolute_url())

        # Create main task
        templatefolder = aq_parent(aq_inner(templates[0]))

        highest_deadline = max([temp.deadline for temp in templates])

        data = dict(
            title=templatefolder.title,
            issuer=self.replace_interactive_user("current_user"),
            responsible=self.replace_interactive_user("current_user"),
            responsible_client=get_current_org_unit().id(),
            task_type="direct-execution",
            deadline=date.today() + timedelta(highest_deadline + MAIN_TASK_DEADLINE_DELTA),
        )

        main_task = createContent("opengever.task.task", **data)
        notify(ObjectCreatedEvent(main_task))
        main_task = addContentToContainer(self.context, main_task, checkConstraints=True)
        ogdsservice = ogds_service()

        # set marker Interfaces
        alsoProvides(main_task, IFromTasktemplateGenerated)

        # set the main_task in to the in progress state
        wft = getToolByName(self.context, "portal_workflow")
        wft.doActionFor(main_task, "task-transition-open-in-progress")

        # create subtasks
        for template in templates:
            deadline = date.today() + timedelta(template.deadline)

            data = dict(
                title=template.title,
                issuer=self.replace_interactive_user(template.issuer),
                responsible=self.replace_interactive_user(template.responsible),
                task_type=template.task_type,
                text=template.text,
                deadline=deadline,
            )

            if template.responsible_client == "interactive_users":
                responsible_assigned_org_units = ogdsservice.assigned_org_units(data["responsible"])
                current_org_unit = get_current_org_unit()
                if not responsible_assigned_org_units or current_org_unit in responsible_assigned_org_units:
                    data["responsible_client"] = current_org_unit.id()
                else:
                    data["responsible_client"] = responsible_assigned_org_units[0].id()
            else:
                data["responsible_client"] = template.responsible_client

            task = createContent("opengever.task.task", **data)
            notify(ObjectCreatedEvent(task))
            task = addContentToContainer(main_task, task, checkConstraints=True)
            alsoProvides(task, IFromTasktemplateGenerated)
            task.reindexObject()

            # add activity record for subtask
            activity = TaskAddedActivity(task, self.request, self.context)
            activity.record()

        # add activity record for the main task
        activity = TaskAddedActivity(main_task, self.request, self.context)
        activity.record()

        IStatusMessage(self.request).addStatusMessage(
            _(u"message_tasks_created", default=u"tasks created"), type="info"
        )

        return self.request.RESPONSE.redirect("%s#tasks" % self.context.absolute_url())