Пример #1
0
 def test_rejecting_sets_responsible_to_issuer(self, browser):
     self.login(self.regular_user, browser)
     self.assertEqual(self.dossier_responsible.id, self.task.issuer)
     self.assertEqual(self.regular_user.id, self.task.responsible)
     subscription_count = len(notification_center().fetch_resource(
         self.task.oguid).subscriptions)
     subscription_assertion_text = 'Both the issuer and the responsible should be initially subscribed.'
     self.assertEqual(2, subscription_count, subscription_assertion_text)
     self.do_transition(browser, self.task, 'task-transition-open-rejected')
     browser.fill({'Response': 'No.'})
     browser.css('#form-buttons-save').first.click()
     self.assertEqual(api.content.get_state(self.task),
                      'task-state-rejected')
     task_responsible_assertion_text = 'The task responsible should have been set to the issuer.'
     self.assertEqual(self.dossier_responsible.id, self.task.issuer)
     self.assertEqual(self.dossier_responsible.id, self.task.responsible,
                      task_responsible_assertion_text)
     subscriptions = notification_center().fetch_resource(
         self.task.oguid).subscriptions
     expected_subscriptions = [
         (
             u'task_issuer',
             u'robert.ziegler',
         ),
         (
             u'task_responsible',
             u'robert.ziegler',
         ),
     ]
     self.assertItemsEqual(expected_subscriptions, [(
         s.role,
         s.watcher.actorid,
     ) for s in subscriptions])
Пример #2
0
def log_activity(task, event):

    if not is_activity_feature_enabled():
        return

    notification_center().add_activity(event.object,
                                       event.kind,
                                       event.object.title,
                                       event.label,
                                       event.summary,
                                       event.actor.getId(),
                                       description=event.description)
Пример #3
0
def log_activity(task, event):

    if not is_activity_feature_enabled():
        return

    notification_center().add_activity(
        event.object,
        event.kind,
        event.object.title,
        event.label,
        event.summary,
        event.actor.getId(),
        description=event.description)
    def test_all_team_members_are_notified_for_a_new_team_task(self, browser):
        self.login(self.regular_user, browser)
        browser.open(self.dossier)
        factoriesmenu.add('Task')

        browser.fill({'Title': u'Team Task', 'Task Type': 'To comment'})
        form = browser.find_form_by_field('Responsible')
        form.find_widget('Responsible').fill('team:2')
        browser.find('Save').click()
        create_session().flush()

        task = self.dossier.get('task-3')

        center = notification_center()
        # Assign watchers to a local variable in order to avoid having
        # a "stale association proxy" when the GC collects within the
        # list comprehension.
        watchers = center.get_watchers(task)
        self.assertEquals([u'team:2', u'kathi.barfuss'],
                          [watcher.actorid for watcher in watchers])

        activity = Activity.query.one()

        self.assertEquals([u'franzi.muller', u'herbert.jager'],
                          [note.userid for note in activity.notifications])
Пример #5
0
    def setUp(self):
        super(TestSuccesssorHandling, self).setUp()

        # we need to setup the mock mailhost to avoid problems when using
        # transaction savepoints
        Mailing(self.portal).set_up()

        create(Builder('ogds_user')
               .id('peter.meier')
               .assign_to_org_units([self.org_unit]))
        create(Builder('ogds_user')
               .id('james.meier')
               .assign_to_org_units([self.org_unit]))
        create(Builder('ogds_user')
               .id('hugo.boss')
               .assign_to_org_units([self.org_unit]))

        self.center = notification_center()
        self.dossier = create(Builder('dossier').titled(u'Dosssier A'))
        self.predecessor = create(Builder('task')
                                  .having(responsible='peter.meier',
                                          issuer='james.meier'))

        self.center.add_task_responsible(self.predecessor, 'peter.meier')
        self.center.add_task_issuer(self.predecessor, 'james.meier')
        self.center.add_watcher_to_resource(
            self.predecessor, 'hugo.boss', WATCHER_ROLE)
    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')))
Пример #7
0
    def create_successor_task(self, dossier):
        # we need all task field values from the forwarding
        fielddata = {}
        for fieldname in ITask.names():
            value = ITask.get(fieldname).get(self.context)
            fielddata[fieldname] = value

        # Reset issuer to the current inbox
        fielddata['issuer'] = get_current_org_unit().inbox().id()

        # Predefine the task_type to avoid tasks with an invalid task_type
        fielddata['task_type'] = FORWARDING_SUCCESSOR_TYPE

        # lets create a new task - the successor task
        task = createContentInContainer(
            dossier, 'opengever.task.task', **fielddata)

        # Add issuer and responsible to the watchers of the newly created task
        center = notification_center()
        center.add_task_responsible(task, task.responsible)
        center.add_task_issuer(task, task.issuer)

        # copy documents and map the intids
        intids_mapping = _copy_documents_from_forwarding(self.context, task)

        # copy the responses
        response_transporter = IResponseTransporter(task)
        response_transporter.get_responses(
            get_current_admin_unit().id(),
            '/'.join(self.context.getPhysicalPath()),
            intids_mapping=intids_mapping)

        return task
Пример #8
0
    def __call__(self):
        self.center = notification_center()

        query = {'object_provides': 'opengever.task.task.ITask',
                 'review_state': Task.PENDING_STATES}
        for task in self.objects(query, "Reregister watchers for all tasks."):
            self.register_watchers(task)
Пример #9
0
    def test_all_team_members_are_notified_for_a_new_team_task(self, browser):
        self.login(self.regular_user, browser)

        with self.observe_children(self.dossier) as children:
            browser.open(self.dossier)
            factoriesmenu.add('Task')
            browser.fill({'Title': u'Team Task', 'Task Type': 'To comment'})
            form = browser.find_form_by_field('Responsible')
            form.find_widget('Responsible').fill('team:2')
            browser.find('Save').click()
            create_session().flush()

        task = children.get('added').pop()
        center = notification_center()
        # Assign watchers to a local variable in order to avoid having
        # a "stale association proxy" when the GC collects within the
        # list comprehension.
        watchers = center.get_watchers(task)
        self.assertEquals(
            [u'team:2', u'kathi.barfuss'],
            [watcher.actorid for watcher in watchers]
        )

        activity = Activity.query.one()

        self.assertEquals(
            [u'franzi.muller', u'herbert.jager'],
            [note.userid for note in activity.notifications])
Пример #10
0
    def test_watchers_are_correclty_registered(self, browser):
        self.activate_feature('activity')

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

        data = {
            "@type": "opengever.task.task",
            "title": "Task",
            "task_type": "correction",
            "text": "Anweisungen etc.",
            "responsible": self.regular_user.id,
            "issuer": self.secretariat_user.id,
            "responsible_client": "fa"
        }

        with self.observe_children(self.dossier) as children:
            browser.open(self.dossier.absolute_url(),
                         method='POST',
                         data=json.dumps(data),
                         headers=self.api_headers)

        task = children['added'].pop()
        watchers = notification_center().get_watchers(task)

        self.assertEqual([u'kathi.barfuss', u'jurgen.konig'],
                         [watcher.actorid for watcher in watchers])
Пример #11
0
    def read(self):
        """Mark badge notifications from all activities read up to a timestamp.

        Takes in an unixtime timestamp.

        Fetches the IDs for all all unread badge notifications for the current
        user, which come from activities created at up to the passed in
        timestamp.

        Marks those notifications as read.
        """
        timestamp = self.request.get('timestamp')
        if not timestamp:
            raise Exception('Missing parameter `timestamp`')
        timestamp = int(timestamp)
        timestamp = datetime.fromtimestamp(int(timestamp), pytz.UTC)
        userid = api.user.get_current().getId()
        notifications = (
            Notification.query
            .join(Activity)
            .filter(
                Notification.userid == userid,
                Notification.is_badge == true(),
                Notification.is_read == false(),
                Activity.created < timestamp,
            )
            .all()
        )
        notification_ids = [n.notification_id for n in notifications]
        return notification_center().mark_notifications_as_read(
            notification_ids)
Пример #12
0
    def render(self):
        resource = notification_center().fetch_resource(self.context)
        watchers = {}
        for subscription in resource.subscriptions:
            watchers[subscription.watcher.user_id] = subscription.roles

        return json.dumps(watchers)
Пример #13
0
    def setUp(self):
        super(TestSuccesssorHandling, self).setUp()

        # we need to setup the mock mailhost to avoid problems when using
        # transaction savepoints
        Mailing(self.portal).set_up()

        create(
            Builder('ogds_user').id('peter.meier').assign_to_org_units(
                [self.org_unit]))
        create(
            Builder('ogds_user').id('james.meier').assign_to_org_units(
                [self.org_unit]))
        create(
            Builder('ogds_user').id('hugo.boss').assign_to_org_units(
                [self.org_unit]))

        self.center = notification_center()
        self.dossier = create(Builder('dossier').titled(u'Dosssier A'))
        self.predecessor = create(
            Builder('task').having(responsible='peter.meier',
                                   issuer='james.meier'))

        self.center.add_task_responsible(self.predecessor, 'peter.meier')
        self.center.add_task_issuer(self.predecessor, 'james.meier')
        self.center.add_watcher_to_resource(self.predecessor, 'hugo.boss',
                                            WATCHER_ROLE)
Пример #14
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')))
Пример #15
0
def accept_task_with_successor(dossier, predecessor_oguid, response_text):
    predecessor = Task.query.by_oguid(predecessor_oguid)

    # Transport the original task (predecessor) to this dossier. The new
    # response and task change is not yet done and will be done later. This
    # is necessary for beeing as transaction aware as possible.
    transporter = Transporter()
    successor = transporter.transport_from(dossier, predecessor.admin_unit_id,
                                           predecessor.physical_path)
    successor_tc = ISuccessorTaskController(successor)

    # Set the "X-CREATING-SUCCESSOR" flag for preventing the event handler
    # from creating additional responses per added document.
    successor.REQUEST.set('X-CREATING-SUCCESSOR', True)

    # copy documents and map the intids
    doc_transporter = getUtility(ITaskDocumentsTransporter)

    comment = _(u'version_message_accept_task',
                default=u'Document copied from task (task accepted)')
    intids_mapping = doc_transporter.copy_documents_from_remote_task(
        predecessor, successor, comment=comment)

    # copy the responses
    response_transporter = IResponseTransporter(successor)
    response_transporter.get_responses(predecessor.admin_unit_id,
                                       predecessor.physical_path,
                                       intids_mapping=intids_mapping)

    # Move current responsible from predecessor task to successor
    center = notification_center()
    center.add_task_responsible(successor, successor.responsible)

    # First "accept" the successor task..
    accept_task_with_response(successor, response_text)

    transaction.savepoint()
    response_text = response_text or ''
    request_data = {
        'text': response_text.encode('utf-8'),
        'successor_oguid': successor_tc.get_oguid()
    }

    response = dispatch_request(predecessor.admin_unit_id,
                                '@@accept_task_workflow_transition',
                                path=predecessor.physical_path,
                                data=request_data)

    response_body = response.read()
    if response_body.strip() != 'OK':
        raise TaskRemoteRequestError(
            'Adding the response and changing the workflow state on the '
            'predecessor task failed.')

    # Connect the predecessor and the successor task. This needs to be done
    # that late for preventing a deadlock because of the locked tasks table.
    successor_tc.set_predecessor(predecessor_oguid)

    return successor
Пример #16
0
    def register_watchers(self):
        center = notification_center()
        center.add_watcher_to_resource(self, self.Creator(),
                                       DISPOSITION_RECORDS_MANAGER_ROLE)

        for archivist in self.get_all_archivists():
            center.add_watcher_to_resource(self, archivist,
                                           DISPOSITION_ARCHIVIST_ROLE)
Пример #17
0
    def render(self):
        resource = notification_center().fetch_resource(self.context)
        watchers = {}
        for subscription in resource.subscriptions:
            watchers.setdefault(subscription.watcher.actorid,
                                []).append(subscription.role)

        return json.dumps(watchers)
Пример #18
0
    def test_removes_old_responsible_from_watchers_list(self, browser):
        forwarding = self.add_forwarding(browser)
        self.reassign(browser, forwarding, responsible='peter.mueller')

        resource = notification_center().fetch_resource(forwarding)
        self.assertItemsEqual(
            ['peter.mueller', u'hugo.boss'],
            [watcher.actorid for watcher in resource.watchers])
Пример #19
0
    def test_removes_old_responsible_from_watchers_list(self, browser):
        forwarding = self.add_forwarding(browser)
        self.reassign(browser, forwarding, responsible='peter.mueller')

        resource = notification_center().fetch_resource(forwarding)
        self.assertItemsEqual(
            ['peter.mueller', u'hugo.boss'],
            [watcher.actorid for watcher in resource.watchers])
Пример #20
0
    def register_watchers(self):
        center = notification_center()
        center.add_watcher_to_resource(
            self, self.Creator(), DISPOSITION_RECORDS_MANAGER_ROLE)

        for archivist in self.get_all_archivists():
            center.add_watcher_to_resource(
                self, archivist, DISPOSITION_ARCHIVIST_ROLE)
Пример #21
0
    def render(self):
        resource = notification_center().fetch_resource(self.context)
        watchers = {}
        for subscription in resource.subscriptions:
            watchers.setdefault(subscription.watcher.actorid, []).append(
                subscription.role)

        return json.dumps(watchers)
Пример #22
0
def accept_task_with_successor(dossier, predecessor_oguid, response_text):
    predecessor = Task.query.by_oguid(predecessor_oguid)

    # Set the "X-CREATING-SUCCESSOR" flag for preventing the event handler
    # from creating additional responses per added document.
    getRequest().set('X-CREATING-SUCCESSOR', True)

    # Transport the original task (predecessor) to this dossier. The new
    # response and task change is not yet done and will be done later. This
    # is necessary for beeing as transaction aware as possible.
    transporter = Transporter()
    successor = transporter.transport_from(
        dossier, predecessor.admin_unit_id, predecessor.physical_path)
    successor_tc = ISuccessorTaskController(successor)

    # copy documents and map the intids
    doc_transporter = getUtility(ITaskDocumentsTransporter)

    comment = _(u'version_message_accept_task',
               default=u'Document copied from task (task accepted)')
    intids_mapping = doc_transporter.copy_documents_from_remote_task(
        predecessor, successor, comment=comment)

    # copy the responses
    response_transporter = IResponseTransporter(successor)
    response_transporter.get_responses(predecessor.admin_unit_id,
                                       predecessor.physical_path,
                                       intids_mapping=intids_mapping)

    # Move current responsible from predecessor task to successor
    center = notification_center()
    center.add_task_responsible(successor, successor.responsible)

    # First "accept" the successor task..
    accept_task_with_response(successor, response_text)

    transaction.savepoint()
    response_text = response_text or ''
    request_data = {'text': response_text.encode('utf-8'),
                    'successor_oguid': successor_tc.get_oguid()}

    response = dispatch_request(predecessor.admin_unit_id,
                                '@@accept_task_workflow_transition',
                                path=predecessor.physical_path,
                                data=request_data)

    response_body = response.read()
    if response_body.strip() != 'OK':
        raise TaskRemoteRequestError(
            'Adding the response and changing the workflow state on the '
            'predecessor task failed.')

    # Connect the predecessor and the successor task. This needs to be done
    # that late for preventing a deadlock because of the locked tasks table.
    successor_tc.set_predecessor(predecessor_oguid)

    return successor
Пример #23
0
    def __call__(self):
        self.center = notification_center()

        query = {
            'object_provides': 'opengever.task.task.ITask',
            'review_state': Task.PENDING_STATES
        }
        for task in self.objects(query, "Reregister watchers for all tasks."):
            self.register_watchers(task)
Пример #24
0
    def test_removes_old_responsible_from_watchers_list(self, browser):
        self.task = self.add_task(browser)
        self.reassign(browser, 'hugo.boss', u'Bitte Abkl\xe4rungen erledigen.')

        resource = notification_center().fetch_resource(self.task)
        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(u'hugo.boss', TASK_RESPONSIBLE_ROLE),
             (u'peter.meier', TASK_ISSUER_ROLE)],
            [(sub.watcher.actorid, sub.role) for sub in subscriptions])
 def test_rejecting_sets_responsible_to_issuer(self, browser):
     self.login(self.regular_user, browser)
     self.assertEqual(self.dossier_responsible.id, self.task.issuer)
     self.assertEqual(self.regular_user.id, self.task.responsible)
     subscription_count = len(notification_center().fetch_resource(self.task.oguid).subscriptions)
     subscription_assertion_text = 'Both the issuer and the responsible should be initially subscribed.'
     self.assertEqual(2, subscription_count, subscription_assertion_text)
     self.do_transition(browser, self.task, 'task-transition-open-rejected')
     browser.fill({'Response': 'No.'})
     browser.css('#form-buttons-save').first.click()
     self.assertEqual(api.content.get_state(self.task), 'task-state-rejected')
     task_responsible_assertion_text = 'The task responsible should have been set to the issuer.'
     self.assertEqual(self.dossier_responsible.id, self.task.issuer)
     self.assertEqual(self.dossier_responsible.id, self.task.responsible, task_responsible_assertion_text)
     subscriptions = notification_center().fetch_resource(self.task.oguid).subscriptions
     expected_subscriptions = [
         (u'task_issuer', u'robert.ziegler', ),
         (u'task_responsible', u'robert.ziegler', ),
         ]
     self.assertItemsEqual(expected_subscriptions, [(s.role, s.watcher.actorid, ) for s in subscriptions])
Пример #26
0
def assign_forwarding_to_dossier(
        context, forwarding_oguid, dossier, response_text):

    forwarding = Task.query.by_oguid(forwarding_oguid)

    forwarding_obj = context.unrestrictedTraverse(
        forwarding.physical_path.encode('utf-8'))

    # we need all task field values from the forwarding
    fielddata = {}
    for fieldname in ITask.names():
        value = ITask.get(fieldname).get(forwarding_obj)
        fielddata[fieldname] = value

    # Reset issuer to the current inbox
    fielddata['issuer'] = get_current_org_unit().inbox().id()

    # Predefine the task_type to avoid tasks with an invalid task_type
    fielddata['task_type'] = FORWARDING_SUCCESSOR_TYPE

    # lets create a new task - the successor task
    task = createContentInContainer(
        dossier, 'opengever.task.task', **fielddata)

    successor_tc_task = ISuccessorTaskController(task)

    # Add issuer and responsible to the watchers of the newly created task
    center = notification_center()
    center.add_task_responsible(task, task.responsible)
    center.add_task_issuer(task, task.issuer)

    # copy documents and map the intids
    intids_mapping = _copy_documents_from_forwarding(forwarding_obj, task)

    # copy the responses
    response_transporter = IResponseTransporter(task)
    response_transporter.get_responses(
        get_current_admin_unit().id(),
        '/'.join(forwarding_obj.getPhysicalPath()),
        intids_mapping=intids_mapping)

    # close and store the forwarding in yearfolder
    change_task_workflow_state(
        forwarding_obj,
        'forwarding-transition-assign-to-dossier',
        text=response_text,
        successor_oguid=successor_tc_task.get_oguid())

    IYearfolderStorer(forwarding_obj).store_in_yearfolder()

    # successor
    successor_tc_task.set_predecessor(forwarding_oguid)

    return task
Пример #27
0
    def setUp(self):
        super(TestToDoWatchers, self).setUp()
        # Because the activity is not setup during creation of the fixture
        # there is no responsible set as watcher on the assigned_todo, which
        # we correct here
        self.center = notification_center()

        with self.login(self.workspace_member):
            self.center.add_watcher_to_resource(self.assigned_todo,
                                                self.assigned_todo.responsible,
                                                TODO_RESPONSIBLE_ROLE)
Пример #28
0
    def test_removes_old_responsible_from_watchers_list(self, browser):
        self.task = self.add_task(browser)
        self.reassign(browser, 'hugo.boss', u'Bitte Abkl\xe4rungen erledigen.')

        resource = notification_center().fetch_resource(self.task)
        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(u'hugo.boss', TASK_RESPONSIBLE_ROLE),
             (u'peter.meier', TASK_ISSUER_ROLE)],
            [(sub.watcher.actorid, sub.role) for sub in subscriptions])
Пример #29
0
    def test_removes_old_responsible_from_watchers_list(self, browser):
        self.reassign(browser, self.meeting_user, u'Bitte Abkl\xe4rungen erledigen.')

        self.login(self.regular_user, browser)
        resource = notification_center().fetch_resource(self.task)
        create_session().refresh(resource)
        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(u'herbert.jager', TASK_RESPONSIBLE_ROLE)],
            [(sub.watcher.actorid, sub.role) for sub in subscriptions])
Пример #30
0
    def read(self):
        """Mark the notification passed as request parameter `notification_id`
        or multiple notification ids as json list via the `notification_ids`
        parameter as read.
        """

        notification_ids = self.request.get('notification_ids')
        if not notification_ids:
            raise Exception('Missing parameter `notification_ids`')

        return notification_center().mark_notifications_as_read(
            json.loads(notification_ids))
Пример #31
0
    def render(self):
        if self.is_already_accepted():
            return ok_response()

        text = self.request.get("text")
        successor_oguid = self.request.get("successor_oguid")

        center = notification_center()
        center.remove_task_responsible(self.context, self.context.responsible)

        accept_task_with_response(self.context, text, successor_oguid=successor_oguid)
        return ok_response()
Пример #32
0
    def read(self):
        """Mark the notification passed as request parameter `notification_id`
        or multiple notification ids as json list via the `notification_ids`
        parameter as read.
        """

        notification_ids = self.request.get('notification_ids')
        if not notification_ids:
            raise Exception('Missing parameter `notification_ids`')

        return notification_center().mark_notifications_as_read(
            json.loads(notification_ids))
Пример #33
0
    def test_removes_old_responsible_from_watchers_list(self, browser):
        self.reassign(browser, self.meeting_user,
                      u'Bitte Abkl\xe4rungen erledigen.')

        self.login(self.regular_user, browser)
        resource = notification_center().fetch_resource(self.task)
        create_session().refresh(resource)
        subscriptions = resource.subscriptions

        self.assertItemsEqual([(u'herbert.jager', TASK_RESPONSIBLE_ROLE)],
                              [(sub.watcher.actorid, sub.role)
                               for sub in subscriptions])
Пример #34
0
def assign_forwarding_to_dossier(context, forwarding_oguid, dossier,
                                 response_text):

    forwarding = Task.query.by_oguid(forwarding_oguid)

    forwarding_obj = context.unrestrictedTraverse(
        forwarding.physical_path.encode('utf-8'))

    # we need all task field values from the forwarding
    fielddata = {}
    for fieldname in ITask.names():
        value = ITask.get(fieldname).get(forwarding_obj)
        fielddata[fieldname] = value

    # Reset issuer to the current inbox
    fielddata['issuer'] = get_current_org_unit().inbox().id()

    # Predefine the task_type to avoid tasks with an invalid task_type
    fielddata['task_type'] = FORWARDING_SUCCESSOR_TYPE

    # lets create a new task - the successor task
    task = createContentInContainer(dossier, 'opengever.task.task',
                                    **fielddata)

    successor_tc_task = ISuccessorTaskController(task)

    # Add issuer and responsible to the watchers of the newly created task
    center = notification_center()
    center.add_task_responsible(task, task.responsible)
    center.add_task_issuer(task, task.issuer)

    # copy documents and map the intids
    intids_mapping = _copy_documents_from_forwarding(forwarding_obj, task)

    # copy the responses
    response_transporter = IResponseTransporter(task)
    response_transporter.get_responses(get_current_admin_unit().id(),
                                       '/'.join(
                                           forwarding_obj.getPhysicalPath()),
                                       intids_mapping=intids_mapping)

    # close and store the forwarding in yearfolder
    change_task_workflow_state(forwarding_obj,
                               'forwarding-transition-assign-to-dossier',
                               text=response_text,
                               successor_oguid=successor_tc_task.get_oguid())

    IYearfolderStorer(forwarding_obj).store_in_yearfolder()

    # successor
    successor_tc_task.set_predecessor(forwarding_oguid)

    return task
Пример #35
0
    def __call__(self):
        if self.is_already_accepted():
            return ok_response()

        text = safe_unicode(self.request.get('text'))
        successor_oguid = self.request.get('successor_oguid')

        center = notification_center()
        center.remove_task_responsible(self.context, self.context.responsible)

        accept_task_with_response(self.context, text,
                                  successor_oguid=successor_oguid)
        return ok_response()
Пример #36
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'))
Пример #37
0
    def __call__(self):
        notification_id = self.request.get('notification_id', '')
        center = notification_center()
        self.notification = center.get_notification(notification_id)

        if not self.notification:
            raise NotFound('Invalid notification_id ({}) is given'.format(
                self.request.get('notification')))

        if not self.check_permission():
            raise Unauthorized()

        self.mark_as_read()
        self.redirect()
Пример #38
0
    def test_handles_reassign_to_the_same_user_correctly(self, browser):
        # add additional org_unit
        org_unit = self.add_additional_org_unit()
        org_unit.users_group.users.append(User.get(self.regular_user.id))

        self.login(self.regular_user, browser)

        # manually register watchers
        center = notification_center()
        center.add_task_responsible(self.task, self.task.responsible)
        center.add_task_issuer(self.task, self.task.issuer)

        self.reassign(browser, self.regular_user,
                      u'Bitte Abkl\xe4rungen erledigen.')

        resource = notification_center().fetch_resource(self.task)
        create_session().refresh(resource)
        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(self.regular_user.id, TASK_RESPONSIBLE_ROLE),
             (self.dossier_responsible.id, TASK_ISSUER_ROLE)],
            [(sub.watcher.actorid, sub.role) for sub in subscriptions])
Пример #39
0
    def setUp(self):
        super(TestForwardingActivites, self).setUp()
        self.center = notification_center()
        self.inbox = create(Builder('inbox').titled(u'Inbox'))
        self.document = create(Builder('document').titled(u'Document'))

        self.hugo = create(
            Builder('ogds_user').id('hugo.boss').assign_to_org_units(
                [self.org_unit]).having(firstname=u'Hugo', lastname=u'Boss'))

        create(
            Builder('ogds_user').id('peter.mueller').assign_to_org_units(
                [self.org_unit]).in_group(self.org_unit.inbox_group).having(
                    firstname=u'Peter', lastname=u'M\xfcller'))
Пример #40
0
    def render(self):
        notification_id = self.request.get('notification_id', '')
        center = notification_center()
        self.notification = center.get_notification(notification_id)

        if not self.notification:
            raise NotFound('Invalid notification_id ({}) is given'.format(
                self.request.get('notification')))

        if not self.check_permission():
            raise Unauthorized()

        self.mark_as_read()
        self.redirect()
Пример #41
0
    def __call__(self):
        if self.is_already_accepted():
            return ok_response()

        text = self.request.get('text')
        successor_oguid = self.request.get('successor_oguid')

        center = notification_center()
        center.remove_task_responsible(self.context, self.context.responsible)

        accept_task_with_response(self.context,
                                  text,
                                  successor_oguid=successor_oguid)
        return ok_response()
Пример #42
0
    def setUp(self):
        super(TestDispositionNotifications, self).setUp()

        self.hugo = create(Builder('user')
                           .named('Hugo', 'Boss')
                           .with_roles('Contributor', 'Archivist'))
        self.peter = create(Builder('user')
                            .named('Peter', 'Boss')
                            .with_roles('Contributor'))
        self.hans = create(Builder('user')
                           .named('Hans', 'Boss')
                           .with_roles('Contributor', 'Archivist'))

        self.center = notification_center()
        self.actor_link = Actor.lookup(TEST_USER_ID).get_link()
Пример #43
0
    def test_mark_notification_as_read(self, browser):
        task = create(Builder('task'))
        oguid = Oguid.for_object(task)

        resource = create(Builder('resource').oguid(oguid.id))
        activity = create(Builder('activity').having(resource=resource))
        notification = create(Builder('notification')
                              .having(activity=activity, userid=TEST_USER_ID))

        browser.login().open(self.portal, view='resolve_notification',
                             data={'notification_id': notification.notification_id})

        notification = notification_center().get_notification(
            notification.notification_id)

        self.assertTrue(notification.is_read)
Пример #44
0
    def setUp(self):
        super(TestForwardingActivites, self).setUp()
        self.center = notification_center()
        self.inbox = create(Builder('inbox').titled(u'Inbox'))
        self.document = create(Builder('document').titled(u'Document'))

        self.hugo = create(Builder('ogds_user')
                           .id('hugo.boss')
                           .assign_to_org_units([self.org_unit])
                           .having(firstname=u'Hugo', lastname=u'Boss'))

        create(Builder('ogds_user')
               .id('peter.mueller')
               .assign_to_org_units([self.org_unit])
               .in_group(self.org_unit.inbox_group)
               .having(firstname=u'Peter', lastname=u'M\xfcller'))
Пример #45
0
    def test_add_watcher_adds_subscription_for_each_actor(self, member):
        browser.login().open(self.dossier, view='++add++opengever.task.task')
        browser.fill({'Title': 'Test Task',
                      'Responsible': 'inbox:client1',
                      'Task Type': 'comment'})
        browser.css('#form-buttons-save').first.click()

        task = self.dossier.get('task-1')
        resource = notification_center().fetch_resource(task)

        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(u'inbox:client1', u'task_responsible'),
             (u'test_user_1_', u'task_issuer')],
            [(sub.watcher.actorid, sub.role) for sub in subscriptions])
Пример #46
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'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'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'))
Пример #47
0
    def test_adding_task_adds_responsible_and_issuer_to_watchers(self, browser):
        browser.login().open(self.dossier, view='++add++opengever.task.task')
        browser.fill({'Title': u'Abkl\xe4rung Fall Meier',
                      'Responsible': u'hugo.boss',
                      'Task Type': 'comment',
                      'Text': 'Lorem ipsum'})
        browser.css('#form-buttons-save').first.click()

        center = notification_center()
        resource = center.fetch_resource(self.dossier.listFolderContents()[0])
        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(u'hugo.boss', TASK_RESPONSIBLE_ROLE),
             (u'test_user_1_', TASK_ISSUER_ROLE)],
            [(subscription.watcher.actorid, subscription.role)
             for subscription in subscriptions])
Пример #48
0
    def test_assign_forwarding_to_dossier_add_responsible_and_issuer_to_successors_watcherlist(
            self, browser):
        dossier = create(Builder('dossier').titled(u'Dossier A'))
        inbox = create(Builder('inbox').titled(u'Inbox'))
        forwarding = create(
            Builder('forwarding').within(inbox).having(
                issuer='inbox:client2',
                responsible='hugo.boss').titled(u'Anfrage XY'))

        task = assign_forwarding_to_dossier(self.portal, forwarding.oguid.id,
                                            dossier, "Ok!")

        resource = notification_center().fetch_resource(task)
        self.assertItemsEqual(
            [(u'hugo.boss', u'task_responsible'),
             (u'inbox:client1', u'task_issuer')],
            [(subscription.watcher.actorid, subscription.role)
             for subscription in resource.subscriptions])
Пример #49
0
    def test_add_watcher_adds_subscription_for_each_actor(self, member):
        browser.login().open(self.dossier, view='++add++opengever.task.task')
        browser.fill({'Title': 'Test Task', 'Task Type': 'comment'})

        form = browser.find_form_by_field('Responsible')
        form.find_widget('Responsible').fill('inbox:org-unit-1')

        browser.css('#form-buttons-save').first.click()

        task = self.dossier.get('task-1')
        resource = notification_center().fetch_resource(task)

        subscriptions = resource.subscriptions

        self.assertItemsEqual([(u'inbox:org-unit-1', u'task_responsible'),
                               (u'test_user_1_', u'task_issuer')],
                              [(sub.watcher.actorid, sub.role)
                               for sub in subscriptions])
Пример #50
0
    def test_assign_forwarding_to_dossier_add_responsible_and_issuer_to_successors_watcherlist(self, browser):
        dossier = create(Builder('dossier').titled(u'Dossier A'))
        inbox = create(Builder('inbox').titled(u'Inbox'))
        forwarding = create(Builder('forwarding')
                            .within(inbox)
                            .having(issuer='inbox:client2',
                                    responsible='hugo.boss')
                            .titled(u'Anfrage XY'))

        task = assign_forwarding_to_dossier(self.portal, forwarding.oguid.id,
                                            dossier, "Ok!")

        resource = notification_center().fetch_resource(task)
        self.assertItemsEqual(
            [(u'hugo.boss', u'task_responsible'),
             (u'inbox:client1', u'task_issuer')],
            [(subscription.watcher.actorid, subscription.role)
             for subscription in resource.subscriptions])
Пример #51
0
    def test_assign_to_dossier_open_successor_task(self, browser):
        self.login(self.secretariat_user, browser=browser)

        url = '{}/@workflow/forwarding-transition-assign-to-dossier'.format(
            self.inbox_forwarding.absolute_url())

        dossier_uid = obj2brain(self.empty_dossier).UID
        data = {'dossier': dossier_uid}
        browser.open(url, method='POST',
                     data=json.dumps(data), headers=self.api_headers)

        task = self.empty_dossier.objectValues()[-1]

        resource = notification_center().fetch_resource(task)
        self.assertItemsEqual(
            [(self.regular_user.id, u'task_responsible'),
             (u'inbox:fa', u'task_issuer')],
            [(subscription.watcher.actorid, subscription.role)
             for subscription in resource.subscriptions])
Пример #52
0
    def test_mark_notification_as_read(self, browser):
        task = create(Builder('task'))
        oguid = Oguid.for_object(task)

        resource = create(Builder('resource').oguid(oguid.id))
        activity = create(Builder('activity').having(resource=resource))
        notification = create(
            Builder('notification').having(activity=activity,
                                           userid=TEST_USER_ID))

        browser.login().open(
            self.portal,
            view='resolve_notification',
            data={'notification_id': notification.notification_id})

        notification = notification_center().get_notification(
            notification.notification_id)

        self.assertTrue(notification.is_read)
Пример #53
0
    def __call__(self):
        if self.is_already_accepted():
            return ok_response()

        text = safe_unicode(self.request.get('text'))
        successor_oguid = self.request.get('successor_oguid')

        center = notification_center()
        center.remove_task_responsible(self.context, self.context.responsible)

        # Remove task reminders of potential responsibles
        reminders = self.context.get_reminders_of_potential_responsibles()
        for userid in reminders.keys():
            self.context.clear_reminder(user_id=userid)

        accept_task_with_response(self.context,
                                  text,
                                  successor_oguid=successor_oguid)
        return ok_response()
Пример #54
0
    def test_adding_task_adds_responsible_and_issuer_to_watchers(self, browser):
        browser.login().open(self.dossier, view='++add++opengever.task.task')
        browser.fill({'Title': u'Abkl\xe4rung Fall Meier',
                      'Task Type': 'comment',
                      'Text': 'Lorem ipsum'})

        form = browser.find_form_by_field('Responsible')
        form.find_widget('Responsible').fill(self.org_unit.id() + ':hugo.boss')
        browser.css('#form-buttons-save').first.click()

        center = notification_center()
        resource = center.fetch_resource(self.dossier.listFolderContents()[0])
        subscriptions = resource.subscriptions

        self.assertItemsEqual(
            [(u'hugo.boss', TASK_RESPONSIBLE_ROLE),
             (u'test_user_1_', TASK_ISSUER_ROLE)],
            [(subscription.watcher.actorid, subscription.role)
             for subscription in subscriptions])
Пример #55
0
    def list(self):
        """Returns a json representation of the current users notifications.
        """
        center = notification_center()
        current_user_id = api.user.get_current().getId()

        # batching
        batch_size = int(self.request.get('batch_size', 10))
        page = int(self.request.get('page', 1))
        offset = (page - 1) * batch_size

        total = center.count_notifications(current_user_id)
        notifications = center.list_notifications(
            current_user_id,
            limit=batch_size,
            sort_reverse=True,
            offset=offset)

        next_url = self.get_next_batch_url(page, batch_size, total, offset)
        return self.json_response({
            'next_page': next_url,
            'notifications': self.dump_notifications(notifications)})
Пример #56
0
    def test_edit_responsible_records_activity(self, browser):
        self.activate_feature('activity')
        self.login(self.administrator, browser=browser)

        # register_watchers
        center = notification_center()
        center.add_task_responsible(self.task, self.task.responsible)
        center.add_task_issuer(self.task, self.task.issuer)

        self.set_workflow_state('task-state-open', self.task)

        browser.open(self.task, view='edit')
        form = browser.find_form_by_field('Responsible')
        form.find_widget('Responsible').fill('fa:{}'.format(self.secretariat_user.id))
        browser.find('Save').click()

        activity = Activity.query.order_by(Activity.created.desc()).first()

        self.assertEquals(u'task-transition-reassign', activity.kind)
        self.assertEquals(
            [(u'robert.ziegler', u'task_issuer'),
             (u'jurgen.konig', u'task_responsible')],
            [(sub.watcher.actorid, sub.role) for sub in Subscription.query.all()])
Пример #57
0
    def test_watchers_are_correclty_registered(self, browser):
        self.activate_feature('activity')

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

        data = {
            "@type": "opengever.task.task",
            "title": "Task",
            "task_type": "correction",
            "text": "Anweisungen etc.",
            "responsible": self.regular_user.id,
            "issuer": self.secretariat_user.id,
            "responsible_client": "fa"}

        with self.observe_children(self.dossier) as children:
            browser.open(self.dossier.absolute_url(),
                         method='POST', data=json.dumps(data),
                         headers=self.api_headers)

        task = children['added'].pop()
        watchers = notification_center().get_watchers(task)

        self.assertEqual([u'kathi.barfuss', u'jurgen.konig'],
                         [watcher.actorid for watcher in watchers])