Esempio n. 1
0
    def _doApply(self):
        """ """
        if not self.mayChangeAttendees():
            raise Unauthorized

        items_to_update = _itemsToUpdate(
            from_item_number=self.context.getItemNumber(relativeTo='meeting'),
            until_item_number=self.apply_until_item_number,
            meeting=self.meeting)

        # apply removal of redefined attendee position
        for item_to_update in items_to_update:
            item_to_update_uid = item_to_update.UID()
            item_attendees_positions = self.meeting.item_attendees_positions.get(
                item_to_update_uid, {})
            if self.person_uid in item_attendees_positions:
                del item_attendees_positions[self.person_uid]
            if not item_attendees_positions:
                del self.meeting.item_attendees_positions[item_to_update_uid]
                notifyModifiedAndReindex(item_to_update)
        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} hp={1} from_item_number={2} until_item_number={3}'.format(
            repr(self.context), self.person_uid, first_item_number,
            last_item_number)
        fplog('remove_redefined_item_attendee_position', extras=extras)
        api.portal.show_message(_("Redefined attendee position was removed."),
                                request=self.request)
        self._finished = True
Esempio n. 2
0
    def handleSave(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # check that user is not trying to workaround security
        self._check_auth(data)

        # save proposing_group_comment and return, make sure we do not set None
        self.item.adviceIndex[data['advice_uid']]['proposing_group_comment'] = \
            data['proposing_group_comment'] or u""
        # make sure advice cache is invalidated as proposing group comment
        # is displayed on advice view and does not change the advice modified date
        advice = self.item.getAdviceObj(data['advice_uid'])
        # redirect to item or advice view on correct anchor
        self.request.RESPONSE.redirect(
            self.context.absolute_url() + "#adviceAndAnnexes")
        # invalidate advice view cache
        if advice is not None:
            # as we use etags, we will change the _p_mtime because
            # doNotCache(advice, self.request, self.request.RESPONSE)
            # seems to work with FF but not with Chrome...
            # Setting an arbitrary attribute will update _p_mtime
            # description is not used but exists on any DX content
            advice.description = advice.description
        extras = 'item={0} advice_id={1}'.format(
            repr(self.item), data['advice_uid'])
        fplog('edit_proposing_group_comment', extras=extras)
Esempio n. 3
0
    def _doApplyItemSignatures(self):
        """
          The method actually do the job, set the itemSignatures
          on self.context and following items if defined
        """
        self._check_auth()
        # only apply if different from meeting
        item_signatures_def = item_signatures_default()
        if self.item_signatures != item_signatures_def:
            items_to_update = _itemsToUpdate(
                from_item_number=self.context.getItemNumber(
                    relativeTo='meeting'),
                until_item_number=self.apply_until_item_number,
                meeting=self.context.getMeeting())
            for itemToUpdate in items_to_update:
                itemToUpdate.setItemSignatures(self.item_signatures)

            first_item_number = items_to_update[0].getItemNumber(
                for_display=True)
            last_item_number = items_to_update[-1].getItemNumber(
                for_display=True)
            extras = 'item={0} from_item_number={1} until_item_number={2}'.format(
                repr(self.context), first_item_number, last_item_number)
            fplog('manage_item_signatures', extras=extras)

        # invalidate assembly async load on item
        invalidate_cachekey_volatile_for(
            'Products.PloneMeeting.browser.async.AsyncLoadItemAssemblyAndSignaturesRawFields',
            get_again=True)

        api.portal.show_message(_("Item signatures have been updated."),
                                request=self.request)
        self._finished = True
Esempio n. 4
0
    def __call__(self, attendee_uid, position):
        """ """
        if not self.context._mayChangeAttendees():
            raise Unauthorized
        # get attendee and move it to right position
        meeting = self.context.getMeeting()
        all_uids = list(self.context.get_all_attendees(the_objects=False))
        attendee_uid_index = all_uids.index(attendee_uid)
        all_uids.insert(position - 1, all_uids.pop(attendee_uid_index))
        all_uids = tuple(all_uids)
        context_uid = self.context.UID()
        # if finally the order is back to the order of the meeting
        # remove the item UID from item_attendees_order
        if all_uids == meeting.get_all_attendees(the_objects=False):
            meeting.item_attendees_order.pop(context_uid)
        else:
            meeting._set_item_attendees_order(context_uid, all_uids)

        # log
        extras = 'item={0} hp={1} position={2}'.format(repr(self.context),
                                                       attendee_uid, position)
        fplog('change_item_attendees_order', extras=extras)
        # message
        api.portal.show_message(_("Attendee position was changed."),
                                request=self.request)
        return True
Esempio n. 5
0
    def _doApply(self):
        """ """
        if not self.mayChangeAttendees():
            raise Unauthorized

        items_to_update = _itemsToUpdate(
            from_item_number=self.context.getItemNumber(relativeTo='meeting'),
            until_item_number=self.apply_until_item_number,
            meeting=self.meeting)

        # apply redefined position
        for item_to_update in items_to_update:
            item_to_update_uid = item_to_update.UID()
            updated = set_meeting_item_attendee_position(
                self.meeting, item_to_update_uid, self.person_uid,
                self.position_type)
            if updated:
                notifyModifiedAndReindex(item_to_update)
        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} hp={1} from_item_number={2} until_item_number={3}'.format(
            repr(self.context), self.person_uid, first_item_number,
            last_item_number)
        fplog('redefine_item_attendee_position', extras=extras)
        api.portal.show_message(_("Attendee position has been redefined."),
                                request=self.request)
        self._finished = True
Esempio n. 6
0
    def _doApply(self):
        """ """
        if not self.mayChangeAttendees():
            raise Unauthorized

        # check where is person_uid, item_absents or item_excused
        meeting_absent_attr = self._get_meeting_absent_attr()
        items_to_update = _itemsToUpdate(
            from_item_number=self.context.getItemNumber(relativeTo='meeting'),
            until_item_number=self.apply_until_item_number,
            meeting=self.meeting)
        for item_to_update in items_to_update:
            item_to_update_uid = item_to_update.UID()
            item_absents = meeting_absent_attr.get(item_to_update_uid, [])
            if self.person_uid in item_absents:
                item_absents.remove(self.person_uid)
                meeting_absent_attr[item_to_update_uid] = item_absents
                notifyModifiedAndReindex(item_to_update)
        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} hp={1} from_item_number={2} until_item_number={3}'.format(
            repr(self.context), self.person_uid, first_item_number,
            last_item_number)
        fplog('welcome_item_attendee', extras=extras)
        api.portal.show_message(self.attendee_welcome_msg,
                                request=self.request)
        self._finished = True
Esempio n. 7
0
    def handleSaveRemoveAdviceInheritance(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        advice_infos = self._advice_infos(data)
        if not advice_infos.mayRemoveInheritedAdvice():
            raise Unauthorized

        # if 'ask_localy', check if advice_id may be asked locally, if it is not the case
        # return a portal message but do not remove the inherited advice
        advice_asked_locally = False
        if data['inherited_advice_action'] == 'ask_locally':
            if self.context.showOptionalAdvisers():
                advisers_vocab = get_vocab(
                    self.context,
                    self.context.getField(
                        'optionalAdvisers').vocabulary_factory, **{
                            'include_selected': False,
                            'include_not_selectable_values': False
                        })
                if data['advice_uid'] in advisers_vocab:
                    optionalAdvisers = list(
                        self.context.getOptionalAdvisers(computed=True))
                    if data['advice_uid'] not in optionalAdvisers:
                        optionalAdvisers.append(data['advice_uid'])
                        self.context.setOptionalAdvisers(optionalAdvisers)
                    advice_asked_locally = True
            if not advice_asked_locally:
                api.portal.show_message(message=_(
                    'remove_advice_inheritance_ask_locally_not_configured'),
                                        request=self.request,
                                        type='warning')
                self.request.RESPONSE.redirect(self.context.absolute_url())
                return
        del self.context.adviceIndex[data['advice_uid']]
        self.context.update_local_roles()
        if advice_asked_locally:
            api.portal.show_message(message=_(
                'remove_advice_inheritance_removed_and_asked_locally'),
                                    request=self.request)
        else:
            api.portal.show_message(
                message=_('remove_advice_inheritance_removed'),
                request=self.request)
        # in case an adviser removed inherited advice and may not
        # see the item anymore, we redirect him to a viewable place
        cleanMemoize(
            self.context,
            prefixes=['borg.localrole.workspace.checkLocalRolesAllowed'])
        url = findViewableURL(self.context, self.request)
        self.request.RESPONSE.redirect(url)

        # add logging message to fingerpointing log
        extras = 'object={0} advice_uid={1} inherited_advice_action={2}'.format(
            repr(self.context), data['advice_uid'],
            data['inherited_advice_action'])
        fplog('remove_advice_inheritance', extras=extras)
        return
Esempio n. 8
0
 def _after_reply_hook(self, serialized_obj):
     """ """
     obj = self.context.get(serialized_obj["id"])
     # add a record to the item workflow_history to specify that item was created thru SOAP WS
     action_name = "create_element_using_ws_rest"
     action_label = action_name + "_comments"
     # there may be several actions in the workflow_history, especially when
     # wf_transitions are used so we insert our event just after event 0
     add_wf_history_action(obj,
                           action_name=action_name,
                           action_label=action_label,
                           insert_index=0)
     # fingerpointing
     extras = "object={0}".format(
         repr(self.context.get(serialized_obj["id"])))
     fplog("create_by_ws_rest", extras=extras)
Esempio n. 9
0
    def __call__(self):
        """ """
        if not self.context._mayChangeAttendees():
            raise Unauthorized

        meeting = self.context.getMeeting()
        meeting.item_attendees_order.pop(self.context.UID())

        # log
        extras = 'item={0}'.format(repr(self.context))
        fplog('reinit_item_attendees_order', extras=extras)
        # message
        api.portal.show_message(_(
            "Attendees order was reinitialized to meeting order for this item."
        ),
                                request=self.request)
        return redirect(self.request, self.context.absolute_url())
Esempio n. 10
0
    def _doApply(self):
        """ """
        if not self.mayChangeAttendees():
            raise Unauthorized

        items_to_update = _itemsToUpdate(
            from_item_number=self.context.getItemNumber(relativeTo='meeting'),
            until_item_number=self.apply_until_item_number,
            meeting=self.meeting)

        # return a portal_message if trying to byebye an attendee that is
        # a signatory redefined on the item
        # user will first have to select another signatory on meeting or item
        # return a portal_message if trying to set absent and item that is
        # already excused (and the other way round)
        error = self._mayByeByeAttendeePrecondition(items_to_update)
        if error:
            self._finished = True
            return

        # apply item_absents/item_excused
        meeting_not_present_attr = getattr(
            self.meeting, self.NOT_PRESENT_MAPPING[self.not_present_type])
        for item_to_update in items_to_update:
            item_to_update_uid = item_to_update.UID()
            item_not_present = meeting_not_present_attr.get(
                item_to_update_uid, [])
            if self.person_uid not in item_not_present:
                item_not_present.append(self.person_uid)
                meeting_not_present_attr[item_to_update_uid] = item_not_present
                notifyModifiedAndReindex(item_to_update)
        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} hp={1} not_present_type={2} from_item_number={3} until_item_number={4}'.format(
            repr(self.context), self.person_uid, self.not_present_type,
            first_item_number, last_item_number)
        fplog('byebye_item_attendee', extras=extras)
        api.portal.show_message(_("Attendee has been set ${not_present_type}.",
                                  mapping={
                                      'not_present_type':
                                      _('item_not_present_type_{0}'.format(
                                          self.not_present_type))
                                  }),
                                request=self.request)
        self._finished = True
Esempio n. 11
0
    def _doApplyItemAssembly(self):
        """
          The method actually do the job, set the itemAssembly on self.context
          and following items if defined
        """
        self._check_auth()
        # only update if default proposed value was changed
        item_assembly_def = item_assembly_default()
        item_excused_def = item_excused_default()
        item_absents_def = item_absents_default()
        item_guests_def = item_guests_default()
        from_item_number = self.context.getItemNumber(relativeTo='meeting')
        until_item_number = self.apply_until_item_number
        items_to_update = _itemsToUpdate(
            from_item_number=from_item_number,
            until_item_number=until_item_number,
            meeting=self.meeting)
        for itemToUpdate in items_to_update:
            # only update if we changed default value
            if self.item_assembly != item_assembly_def:
                itemToUpdate.setItemAssembly(self.item_assembly)
            if self.item_excused != item_excused_def:
                itemToUpdate.setItemAssemblyExcused(self.item_excused)
            if self.item_absents != item_absents_def:
                itemToUpdate.setItemAssemblyAbsents(self.item_absents)
            if self.item_guests != item_guests_def:
                itemToUpdate.setItemAssemblyGuests(self.item_guests)
            notifyModifiedAndReindex(itemToUpdate)

        # invalidate assembly async load on item
        invalidate_cachekey_volatile_for(
            'Products.PloneMeeting.browser.async.AsyncLoadItemAssemblyAndSignaturesRawFields',
            get_again=True)

        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} from_item_number={1} until_item_number={2}'.format(
            repr(self.context), first_item_number, last_item_number)
        fplog('manage_item_assembly', extras=extras)
        api.portal.show_message(_("Item assemblies have been updated."), request=self.request)
        self._finished = True
Esempio n. 12
0
    def _doApply(self):
        """ """
        if not self.mayChangeAttendees():
            raise Unauthorized

        items_to_update = _itemsToUpdate(
            from_item_number=self.context.getItemNumber(relativeTo='meeting'),
            until_item_number=self.apply_until_item_number,
            meeting=self.meeting)

        # apply signatory
        for item_to_update in items_to_update:
            item_to_update_uid = item_to_update.UID()
            item_signatories = self.meeting.item_signatories.get(
                item_to_update_uid, {})
            signature_number = [
                k for k, v in item_signatories.items()
                if v['hp_uid'] == self.person_uid
            ]
            if signature_number:
                del item_signatories[signature_number[0]]
                # if no more redefined item signatories,
                # remove item UID from meeting.item_signatories
                if item_signatories:
                    self.meeting.item_signatories[
                        item_to_update_uid] = item_signatories
                else:
                    del self.meeting.item_signatories[item_to_update_uid]
                notifyModifiedAndReindex(item_to_update)
        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} hp={1} from_item_number={2} until_item_number={3}'.format(
            repr(self.context), self.person_uid, first_item_number,
            last_item_number)
        fplog('remove_redefined_item_signatory', extras=extras)
        api.portal.show_message(
            _("Attendee is no more defined as item signatory."),
            request=self.request)
        self._finished = True
Esempio n. 13
0
    def handleApply(self, action):
        """ """
        if not self.available():
            raise Unauthorized

        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
        else:
            # log in fingerpointing before executing job
            extras = 'action={0} number_of_elements={1}'.format(
                repr(self.label), len(self.brains))
            fplog('apply_batch_action', extras=extras)
            # call the method that does the job
            applied = self._apply(**data)
            # redirect if not using an overlay
            if not self.request.form.get('ajax_load', ''):
                self.request.response.redirect(
                    self.request.form['form.widgets.referer'])
            else:
                # make sure we return nothing, taken into account by ajax query
                if not applied:
                    self.request.RESPONSE.setStatus(204)
                return applied or ""
Esempio n. 14
0
    def __call__(self, moveType, wishedNumber=None):
        """
          Change the items order on a meeting.
          This is an unrestricted method so a MeetingManager can change items
          order even if some items are no more movable because decided
          (and so no more 'Modify portal content' on it).
          We double check that current user can actually may_change_items_order.
          Anyway, this method move an item, one level up/down or at a given position.
        """
        # we do this unrestrictively but anyway respect the Meeting.may_change_items_order
        meeting = self.context.getMeeting()

        if not meeting.wfConditions().may_change_items_order():
            raise Unauthorized

        oldIndex = self.context.getItemNumber()
        plone_utils = api.portal.get_tool('plone_utils')

        # Move the item up (-1), down (+1) or at a given position ?
        if moveType == 'number':
            try:
                float(wishedNumber)
                # In this case, wishedNumber specifies the new position where
                # the item must be moved.
            except (ValueError, TypeError):
                plone_utils.addPortalMessage(translate(
                    msgid='item_number_invalid',
                    domain='PloneMeeting',
                    context=self.request),
                                             type='warning')
                return False

        nbOfItems = meeting.number_of_items(as_int=True)
        items = meeting.get_items(ordered=True, unrestricted=True)

        # Calibrate and validate moveValue
        if moveType == 'number':
            # we receive 2.1, 2.5 or 2.10 but we store 201, 205 and 210 so it is orderable integers
            moveNumber = _itemNumber_to_storedItemNumber(wishedNumber)
            moveNumberIsInteger = _is_integer(moveNumber)
            # Is this move allowed ?
            if moveNumber == oldIndex:
                plone_utils.addPortalMessage(translate(
                    msgid='item_did_not_move',
                    domain='PloneMeeting',
                    context=self.request),
                                             type='warning')
                return False
            # check that moveNumber is not < 1 or not > next possible item
            # check that the moveNumber is valid, aka integer (4) or max 2 decimal number (4.1 or 4.13)
            # check also that if we use a subnumber, the previous exists (22.2 exists if we specified 22.3)
            # check finally that if we are moving an item to a subnumber,
            # the master exists (moving to 12.1, 12 has to exist)
            last_item = items[-1]
            last_item_number = last_item.getItemNumber()
            if (moveNumber < 100) or \
               (moveNumber > _to_integer(last_item_number + 100)) or \
               (not moveNumberIsInteger and len(wishedNumber.split('.')[1]) > 2) or \
               (not moveNumberIsInteger and
                (not meeting.get_item_by_number(moveNumber - 1) or
                 moveNumber - 1 == oldIndex)):
                plone_utils.addPortalMessage(translate(
                    msgid='item_illegal_move',
                    domain='PloneMeeting',
                    context=self.request),
                                             type='warning')
                return False
        else:
            # down, must not be last
            # up, must not be first
            if (moveType == 'down' and self.context == items[-1]) or \
               (moveType == 'up' and self.context == items[0]):
                plone_utils.addPortalMessage(translate(
                    msgid='item_illegal_switch',
                    domain='PloneMeeting',
                    context=self.request),
                                             type='warning')
                return False
            # 'down' or 'up' may not switch an integer and a subnumber
            currentIsInteger = _is_integer(self.context.getItemNumber())
            illegal_switch = False
            if moveType == 'down':
                nextIsInteger = _is_integer(
                    self.context.getSiblingItem('next'))
                if (currentIsInteger
                        and not nextIsInteger) or (not currentIsInteger
                                                   and nextIsInteger):
                    illegal_switch = True
            elif moveType == 'up':
                previousIsInteger = _is_integer(
                    self.context.getSiblingItem('previous'))
                if (currentIsInteger
                        and not previousIsInteger) or (not currentIsInteger
                                                       and previousIsInteger):
                    illegal_switch = True
            if illegal_switch:
                plone_utils.addPortalMessage(translate(
                    msgid='item_illegal_switch',
                    domain='PloneMeeting',
                    context=self.request),
                                             type='warning')
                return False

        # Move the item
        if nbOfItems >= 2:
            if not moveType == 'number':
                # switch the items
                if moveType == 'up':
                    if oldIndex == 100:
                        # moving first item 'up', does not change anything
                        # actually it is not possible in the UI because the 'up'
                        # icon is not displayed on the first item
                        return False
                    otherNumber = self.context.getSiblingItem('previous')
                else:
                    # moveType == 'down'
                    otherNumber = self.context.getSiblingItem('next')
                otherItem = meeting.get_item_by_number(otherNumber)
                self.context.setItemNumber(otherItem.getItemNumber())
                otherItem.setItemNumber(oldIndex)
            else:
                # Move the item to an absolute position
                self.context.setItemNumber(moveNumber)
                # get items again now that context number was updated
                items = meeting.get_items(ordered=True, unrestricted=True)
                oldIndexIsInteger = _is_integer(oldIndex)
                oldIndexHasSubnumbers = meeting.get_item_by_number(oldIndex +
                                                                   1)
                if moveNumber < oldIndex:
                    # We moved the item up
                    for item in items:
                        itemNumber = item.getItemNumber()
                        # moved item
                        if item == self.context:
                            # moving 4 to 2
                            if (oldIndexIsInteger and moveNumberIsInteger):
                                pass
                            # moving 4.1 to 2
                            elif (not oldIndexIsInteger
                                  and moveNumberIsInteger):
                                pass
                            # moving 4 to 2.1
                            elif (oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                pass
                            elif (not oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # moving 3.1 to 2.2
                                pass
                        # item that was at the moveNumber position
                        elif itemNumber == moveNumber:
                            # moving 4 to 2
                            if (oldIndexIsInteger and moveNumberIsInteger):
                                item.setItemNumber(itemNumber + 100)
                            # moving 4.1 to 2
                            elif (not oldIndexIsInteger
                                  and moveNumberIsInteger):
                                item.setItemNumber(
                                    itemNumber +
                                    _compute_value_to_add(itemNumber))
                            # moving 4 to 2.1
                            elif (oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                item.setItemNumber(
                                    itemNumber +
                                    _compute_value_to_add(itemNumber))
                            elif (not oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # moving 3.1 to 2.2
                                item.setItemNumber(itemNumber + 1)
                        # other items
                        else:
                            # moving 4 to 2
                            if (oldIndexIsInteger and moveNumberIsInteger) and \
                               (itemNumber < oldIndex and itemNumber > moveNumber):
                                item.setItemNumber(itemNumber + 100)
                            # moving 4.1 to 2
                            elif (not oldIndexIsInteger and moveNumberIsInteger
                                  ) and itemNumber > moveNumber:
                                # subnumbers of oldIndex (4.2, 4.3, ...) must be decreased of 0.1
                                if _use_same_integer(
                                        itemNumber,
                                        oldIndex) and itemNumber > oldIndex:
                                    item.setItemNumber(
                                        itemNumber + 100 -
                                        _compute_value_to_add(itemNumber))
                                else:
                                    item.setItemNumber(itemNumber + 100)
                            # moving 4 to 2.1
                            elif (oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # moving master, decrease old subnumbers if > oldIndex
                                if _use_same_integer(itemNumber, oldIndex):
                                    item.setItemNumber(
                                        itemNumber -
                                        _compute_value_to_add(itemNumber))
                                # increase subnumbers > moveNumber
                                if _use_same_integer(
                                        itemNumber, moveNumber
                                ) and itemNumber > moveNumber:
                                    item.setItemNumber(
                                        itemNumber +
                                        _compute_value_to_add(itemNumber))
                                # decrease every number > oldIndex if oldIndex was not a master number
                                elif not oldIndexHasSubnumbers and itemNumber > oldIndex:
                                    item.setItemNumber(itemNumber - 100)
                            elif (not oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # manage when moving 3.1 to 2.2 or 3.4 to 3.2
                                # moving to another integer (3.1 to 2.2)
                                if not _use_same_integer(moveNumber, oldIndex):
                                    # decrease 3.2 to 3.1
                                    if _use_same_integer(itemNumber, oldIndex):
                                        if itemNumber > oldIndex:
                                            item.setItemNumber(itemNumber - 1)
                                    # increase 2.3 to 2.4
                                    elif _use_same_integer(itemNumber, moveNumber) and \
                                            itemNumber > moveNumber:
                                        item.setItemNumber(itemNumber + 1)
                                else:
                                    # moving to same integer (3.4 to 3.2)
                                    # increase itemNumber in between but itemNumber after
                                    # oldIndex does not change
                                    if _use_same_integer(itemNumber, moveNumber) and \
                                       itemNumber > moveNumber and \
                                       itemNumber < oldIndex:
                                        item.setItemNumber(itemNumber + 1)
                else:
                    # We moved the item down
                    for item in items:
                        itemNumber = item.getItemNumber()
                        if item == self.context:
                            # moving 2 to 4
                            if (oldIndexIsInteger and moveNumberIsInteger):
                                # if moving to last position, we need to remove 100 if > last_item_number
                                if moveNumber > last_item_number:
                                    item.setItemNumber(moveNumber - 100)
                            # moving 2.1 to 4
                            elif (not oldIndexIsInteger
                                  and moveNumberIsInteger):
                                pass
                            # moving 2 to 4.2
                            elif (oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                if not oldIndexHasSubnumbers:
                                    item.setItemNumber(moveNumber - 100)
                            elif (not oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # moving 2.1 to 3.2
                                # (not oldIndexIsInteger and not moveNumberIsInteger)
                                pass
                        elif itemNumber == moveNumber:
                            # moving 2 to 4
                            if (oldIndexIsInteger and moveNumberIsInteger):
                                item.setItemNumber(
                                    itemNumber -
                                    _compute_value_to_add(itemNumber))
                            # moving 2.1 to 4
                            elif (not oldIndexIsInteger
                                  and moveNumberIsInteger):
                                item.setItemNumber(
                                    itemNumber +
                                    _compute_value_to_add(itemNumber))
                            # moving 2 to 4.2
                            elif (oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                item.setItemNumber(
                                    itemNumber - 100 +
                                    _compute_value_to_add(itemNumber))
                            elif (not oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # moving 2.1 to 3.2
                                # increase 3.2 to 3.3
                                if not _use_same_integer(moveNumber, oldIndex):
                                    item.setItemNumber(itemNumber + 1)
                                else:
                                    # moving 2.1 to 2.4, decrease 2.4 to 2.3
                                    item.setItemNumber(itemNumber - 1)
                        else:
                            # moving 2 to 4
                            if (oldIndexIsInteger and moveNumberIsInteger) and \
                               (itemNumber > oldIndex and itemNumber < moveNumber):
                                item.setItemNumber(itemNumber - 100)
                            # moving 2.1 to 4
                            elif (not oldIndexIsInteger and moveNumberIsInteger
                                  ) and itemNumber > oldIndex:
                                # decrease elements having same subnumber as oldIndex
                                if (_use_same_integer(itemNumber, oldIndex)):
                                    item.setItemNumber(
                                        itemNumber -
                                        _compute_value_to_add(itemNumber))
                                elif itemNumber > moveNumber:
                                    item.setItemNumber(itemNumber + 100)
                            # moving 2 to 4.2
                            elif (oldIndexIsInteger and not moveNumberIsInteger
                                  ) and itemNumber > oldIndex:
                                # decrease from 1 but add + 0.1 to subnumbers > moveNumber
                                if (_use_same_integer(itemNumber, moveNumber)
                                    ) and itemNumber > moveNumber:
                                    item.setItemNumber(
                                        itemNumber - 100 +
                                        _compute_value_to_add(itemNumber))
                                # decrease subnumbers of master we moved
                                elif (_use_same_integer(itemNumber, oldIndex)):
                                    item.setItemNumber(
                                        itemNumber -
                                        _compute_value_to_add(itemNumber))
                                elif not oldIndexHasSubnumbers:
                                    item.setItemNumber(itemNumber - 100)
                            elif (not oldIndexIsInteger
                                  and not moveNumberIsInteger):
                                # manage when moving 2.1 to 3.2 or 3.2 to 3.4
                                # moving to another integer (2.1 to 3.2)
                                if not _use_same_integer(moveNumber, oldIndex):
                                    # decrease 2.2 to 2.1
                                    if _use_same_integer(
                                            itemNumber, oldIndex
                                    ) and itemNumber > oldIndex:
                                        item.setItemNumber(itemNumber - 1)
                                    # increase 3.2 to 3.3
                                    elif _use_same_integer(itemNumber, moveNumber) and \
                                            itemNumber > moveNumber:
                                        item.setItemNumber(itemNumber + 1)
                                else:
                                    # moving to same integer (3.2 to 3.4)
                                    # increase itemNumber in between but itemNumber after
                                    # oldIndex does not change
                                    if _use_same_integer(itemNumber, moveNumber) and \
                                       itemNumber < moveNumber and \
                                       itemNumber > oldIndex:
                                        item.setItemNumber(itemNumber - 1)

        # when items order on meeting changed, it is considered modified,
        # do this before update_item_references
        meeting.notifyModified()

        # add logging message to fingerpointing log
        extras = 'object={0} meeting={1} original_position={2} new_position={3}'.format(
            repr(self.context), repr(meeting),
            _storedItemNumber_to_itemNumber(oldIndex, forceShowDecimal=False),
            self.context.getItemNumber(for_display=True))
        fplog('change_item_order', extras=extras)

        # update item references starting from minus between oldIndex and new itemNumber
        meeting.update_item_references(
            start_number=min(oldIndex, self.context.getItemNumber()))
        return True
Esempio n. 15
0
    def __call__(self, object_uid, redirect=True):
        """ """
        if not self.context._mayChangeAttendees():
            raise Unauthorized

        # redirect can by passed by jQuery, in this case, we receive '0' or '1'
        redirect = boolean_value(redirect)
        vote_number = int(object_uid)
        item_uid = self.context.UID()
        meeting = self.context.getMeeting()
        if item_uid in meeting.item_votes:
            item_votes = meeting.item_votes[item_uid]
            assert self.context._voteIsDeletable(vote_number)

            vote_to_delete = item_votes[vote_number]
            if self.context.get_votes_are_secret():
                originnal_vote_keys = [
                    str(vote_count) for vote_value, vote_count in
                    vote_to_delete['votes'].items()
                ]
                originnal_vote_keys = "__".join(originnal_vote_keys)
                originnal_vote_values = [
                    vote_value for vote_value, vote_count in
                    vote_to_delete['votes'].items()
                ]
                originnal_vote_values = "__".join(originnal_vote_values)
                fp_extras_pattern = 'item={0} vote_number={1} vote_label={2} vote_count={3} vote_values={4}'
            else:
                originnal_vote_keys = [
                    voter_uid for voter_uid in vote_to_delete['voters']
                ]
                originnal_vote_keys = "__".join(originnal_vote_keys)
                originnal_vote_values = [
                    vote_value
                    for vote_value in vote_to_delete['voters'].values()
                ]
                originnal_vote_values = "__".join(originnal_vote_values)
                fp_extras_pattern = 'item={0} vote_number={1} vote_label={2} voter_uids={3} vote_values={4}'
                # call clean_voters_linked_to with every values NOT_ENCODED_VOTE_VALUE
                # to liberate every values
                new_voters = vote_to_delete['voters'].copy()
                new_voters = {
                    voter_uid: NOT_ENCODED_VOTE_VALUE
                    for voter_uid, vote_value in new_voters.items()
                    if vote_value != NOT_VOTABLE_LINKED_TO_VALUE
                }
                clean_voters_linked_to(self.context, meeting, vote_number,
                                       new_voters)

            # delete from meeting itemVote
            deleted_vote = meeting.item_votes[item_uid].pop(vote_number)
            # if deleted last existing vote (vote_number 0) remove context UID from meeting itemVotes
            if not meeting.item_votes[item_uid]:
                del meeting.item_votes[item_uid]
            # finish deletion
            label = deleted_vote['label'] or ""
            extras = fp_extras_pattern.format(repr(self.context), vote_number,
                                              label.encode('utf-8'),
                                              originnal_vote_keys,
                                              originnal_vote_values)
            fplog('delete_item_votes', extras=extras)
        # message
        api.portal.show_message(_(
            "Votes number ${vote_number} have been deleted for current item.",
            mapping={'vote_number': vote_number + 1}),
                                request=self.request)
        self._finished = True
Esempio n. 16
0
    def _doApply(self):
        """ """
        if not self.mayChangeAttendees():
            raise Unauthorized

        # prepare Meeting.itemVotes compatible data
        # while datagrid used in an overlay, some <NO_VALUE>
        # wipeout self.votes from these values
        self.votes = [vote for vote in self.votes if isinstance(vote, dict)]
        data = {}
        data['label'] = self.label
        data['linked_to_previous'] = self.linked_to_previous
        data['votes'] = {}
        for vote in self.votes:
            data['votes'][vote['vote_value_id']] = vote['vote_count']

        items_to_update = _itemsToUpdate(
            from_item_number=self.context.getItemNumber(relativeTo='meeting'),
            until_item_number=self.apply_until_item_number,
            meeting=self.meeting)
        updated = []
        not_updated = []
        for item_to_update in items_to_update:
            # set item secret vote
            if is_vote_updatable_for(self.context, item_to_update):
                self.meeting.set_item_secret_vote(item_to_update, data,
                                                  self.vote_number)
                updated.append(item_to_update.getItemNumber(for_display=True))
            else:
                not_updated.append(
                    item_to_update.getItemNumber(for_display=True))

        # finish
        vote_values = [vote['vote_value_id'] for vote in self.votes]
        vote_values = "__".join(vote_values)
        vote_count = [str(vote['vote_count']) for vote in self.votes]
        vote_count = "__".join(vote_count)
        first_item_number = items_to_update[0].getItemNumber(for_display=True)
        last_item_number = items_to_update[-1].getItemNumber(for_display=True)
        extras = 'item={0} vote_number={1} vote_values={2} vote_count={3} ' \
            'from_item_number={4} until_item_number={5}'.format(
                repr(self.context),
                self.vote_number,
                vote_values,
                vote_count,
                first_item_number,
                last_item_number)
        fplog('encode_item_secret_votes', extras=extras)
        if len(updated) == 1:
            api.portal.show_message(
                _("Votes have been encoded for current item."),
                request=self.request)
        else:
            api.portal.show_message(_(
                "Votes have been encoded for items \"${item_numbers}\".",
                mapping={'item_numbers': display_item_numbers(updated)}),
                                    request=self.request)

        # display items that could not be updated
        if not_updated:
            api.portal.show_message(_(
                "error_updating_votes_for_items",
                mapping={'item_numbers': display_item_numbers(not_updated)}),
                                    request=self.request,
                                    type="warning")
        self._finished = True