Esempio n. 1
0
    def mayEvaluateCompleteness(self):
        '''Completeness can be evaluated by the finance precontroller.'''
        item = self.getSelf()
        if item.isDefinedInTool():
            return False

        # finances advice asked?
        finance_org_uid = finance_group_uid()
        finance_org_cec_uid = finance_group_cec_uid()
        if finance_org_uid not in item.adviceIndex and \
           finance_org_cec_uid not in item.adviceIndex:
            return False

        # bypass for Managers
        tool = api.portal.get_tool('portal_plonemeeting')
        if tool.isManager(realManagers=True):
            return True

        # relevant state?
        cfg = tool.getMeetingConfig(item)
        if item.query_state() not in finances_give_advice_states(cfg):
            return False

        # current user is pre-controller for asked advice?
        userGroups = tool.get_plone_groups_for_user()
        if '%s_financialprecontrollers' % finance_org_uid not in userGroups and \
           '%s_financialprecontrollers' % finance_org_cec_uid not in userGroups:
            return False

        return True
Esempio n. 2
0
 def _will_ask_completeness_eval_again(self):
     ''' '''
     res = False
     if finance_group_uid() in self.context.adviceIndex or \
        finance_group_cec_uid() in self.context.adviceIndex:
         res = super(MeetingItemPROVHainautWorkflowActions,
                     self)._will_ask_completeness_eval_again()
     return res
Esempio n. 3
0
 def test_CompletenessEvaluationAskedAgain(self):
     """When item is sent for second+ time to the finances,
        completeness is automatically set to asked again except
        for finance_group_no_cec_uid."""
     self.changeUser('dgen')
     item_df1 = self.create('MeetingItem',
                            optionalAdvisers=((finance_group_uid() +
                                               '__rowid__unique_id_002', )))
     item_df2 = self.create('MeetingItem',
                            optionalAdvisers=((finance_group_cec_uid(), )))
     item_df3 = self.create(
         'MeetingItem', optionalAdvisers=((finance_group_no_cec_uid(), )))
     for tr in [
             'proposeToValidationLevel1', 'proposeToValidationLevel2',
             'wait_advices_from_proposedToValidationLevel2'
     ]:
         self.do(item_df1, tr)
         self.do(item_df2, tr)
         self.do(item_df3, tr)
     self.assertEqual(item_df1.getCompleteness(),
                      'completeness_not_yet_evaluated')
     self.assertEqual(item_df2.getCompleteness(),
                      'completeness_not_yet_evaluated')
     self.assertEqual(item_df3.getCompleteness(),
                      'completeness_evaluation_not_required')
     # incomplete, return
     item_df1.setCompleteness('completeness_incomplete')
     item_df2.setCompleteness('completeness_incomplete')
     self.changeUser('dfin')
     self.do(item_df1,
             'backTo_proposedToValidationLevel2_from_waiting_advices')
     self.do(item_df2,
             'backTo_proposedToValidationLevel2_from_waiting_advices')
     self.do(item_df3,
             'backTo_proposedToValidationLevel2_from_waiting_advices')
     # ask again
     self.changeUser('dgen')
     self.assertEqual(item_df1.getCompleteness(), 'completeness_incomplete')
     self.assertEqual(item_df2.getCompleteness(), 'completeness_incomplete')
     # manipulate completeness, like if we changed from DF3 to DF2
     item_df2.setCompleteness('completeness_evaluation_not_required')
     self.assertEqual(item_df3.getCompleteness(),
                      'completeness_evaluation_not_required')
     self.do(item_df1, 'wait_advices_from_proposedToValidationLevel2')
     self.do(item_df2, 'wait_advices_from_proposedToValidationLevel2')
     self.do(item_df3, 'wait_advices_from_proposedToValidationLevel2')
     self.assertEqual(item_df1.getCompleteness(),
                      'completeness_evaluation_asked_again')
     self.assertEqual(item_df2.getCompleteness(),
                      'completeness_evaluation_asked_again')
     self.assertEqual(item_df3.getCompleteness(),
                      'completeness_evaluation_not_required')
Esempio n. 4
0
 def _adviceDelayMayBeStarted(self, org_uid):
     """Delay is started when advice no more at controllers states."""
     res = True
     if org_uid == finance_group_uid():
         item = self.getSelf()
         adviceObj = item.getAdviceObj(org_uid)
         if not adviceObj or adviceObj.query_state() in [
                 'advicecreated', 'proposed_to_financial_controller'
         ]:
             res = False
     if res:
         res = super(CustomMeetingItem,
                     self)._adviceDelayMayBeStarted(org_uid)
     return res
Esempio n. 5
0
 def _setupFinancesGroup(self):
     '''Configure finances group.'''
     self._addPrincipalToGroup('pmAdviser2', '{0}_advisers'.format(finance_group_uid()))
     # respective _financesXXX groups
     self._addPrincipalToGroup('pmAdviser2', '{0}_financialprecontrollers'.format(finance_group_uid()))
     self._addPrincipalToGroup('pmAdviser2', '{0}_financialcontrollers'.format(finance_group_uid()))
     self._addPrincipalToGroup('pmAdviser2', '{0}_financialeditors'.format(finance_group_uid()))
     self._addPrincipalToGroup('pmAdviser2', '{0}_financialreviewers'.format(finance_group_uid()))
     self._addPrincipalToGroup('pmAdviser2', '{0}_financialmanagers'.format(finance_group_uid()))
Esempio n. 6
0
 def getCustomAdviceMessageFor(self, advice):
     '''If we are on a finance advice that is still not giveable because
        the item is not 'complete', we display a clear message.'''
     item = self.getSelf()
     finance_org_uids = (finance_group_uid(), finance_group_cec_uid())
     if advice['id'] in finance_org_uids and \
        not advice['advice_addable']:
         finance_org = get_organization(advice['id'])
         tool = api.portal.get_tool('portal_plonemeeting')
         cfg = tool.getMeetingConfig(item)
         # item in state giveable but item not complete
         if item.query_state() in finance_org.get_item_advice_states(cfg):
             if not self._is_complete():
                 return {
                     'displayDefaultComplementaryMessage':
                     False,
                     'displayAdviceReviewState':
                     True,
                     'customAdviceMessage':
                     translate(
                         'finance_advice_not_giveable_because_item_not_complete',
                         domain="PloneMeeting",
                         context=item.REQUEST,
                         default=
                         "Advice is still not giveable because item is not considered complete."
                     )
                 }
             # delay still not started when advice created/proposed_to_controller
             if not item.adapted()._adviceDelayMayBeStarted(advice['id']):
                 return {
                     'displayDefaultComplementaryMessage':
                     False,
                     'displayAdviceReviewState':
                     True,
                     'customAdviceMessage':
                     translate('finance_advice_delay_still_not_started',
                               domain="PloneMeeting",
                               context=item.REQUEST,
                               default="Advice delay is still not started.")
                 }
     return {
         'displayDefaultComplementaryMessage': True,
         'displayAdviceReviewState': True,
         'customAdviceMessage': None
     }
Esempio n. 7
0
 def get_extra_adviser_infos(self):
     ''' '''
     infos = {}
     infos[finance_group_uid()] = {
         'portal_type': 'meetingadvicefinances',
         'base_wf': 'meetingadvicefinances_workflow',
         'wf_adaptations': ['add_advicecreated_state']
     }
     infos[finance_group_cec_uid()] = {
         'portal_type': 'meetingadvicefinancescec',
         'base_wf': 'meetingadvicefinancesmanager_workflow',
         'wf_adaptations': ['add_advicecreated_state']
     }
     infos[finance_group_no_cec_uid()] = {
         'portal_type': 'meetingadvicefinancesnocec',
         'base_wf': 'meetingadvicefinanceseditor_workflow',
         'wf_adaptations': []
     }
     return infos
Esempio n. 8
0
 def _configureFinancesAdvice(self, cfg):
     """ """
     # add finances group
     self._createFinancesGroup()
     # put users in finances group
     self._setupFinancesGroup()
     # configure customAdvisers for 'meeting-config-college'
     # turn FINANCE_GROUP_ID into relevant org UID
     customAdvisers = deepcopy(provhainaut_import_data.collegeMeeting.customAdvisers)
     for customAdviser in customAdvisers:
         customAdviser['org'] = finance_group_uid()
     cfg.setCustomAdvisers(customAdvisers)
     # configure usedAdviceTypes
     cfg.setUsedAdviceTypes(('positive',
                             'positive_with_remarks',
                             'negative',
                             'nil',
                             'positive_finance',
                             'positive_with_remarks_finance',
                             'negative_finance',
                             'not_given_finance'))
Esempio n. 9
0
    def test_FinancesAdvicesWorkflow(self):
        """
           Test finances advices workflow.
        """
        def _check_date(item, modified_date, volatile_date):
            '''Check that item modified date was updated.'''
            new_modified_date = item.modified()
            self.assertNotEqual(modified_date, new_modified_date)
            new_volatile_date = get_cachekey_volatile(
                'Products.PloneMeeting.MeetingItem.modified')
            self.assertNotEqual(volatile_date, new_volatile_date)
            return new_modified_date, new_volatile_date

        cfg = self.meetingConfig
        self.changeUser('dgen')
        gic1_uid = cfg.getOrderedGroupsInCharge()[0]
        item = self.create('MeetingItem', groupsInCharge=(gic1_uid, ))
        item_uid = item.UID()
        self.assertEqual(self.transitions(item), ['proposeToValidationLevel1'])
        # ask finances advice
        fin_group_uid = finance_group_uid()
        item.setOptionalAdvisers((fin_group_uid + '__rowid__unique_id_002', ))
        item._update_after_edit()
        # advice still not askable, askable as level2 or level3
        self.assertEqual(self.transitions(item), ['proposeToValidationLevel1'])
        self.do(item, 'proposeToValidationLevel1')
        self.assertEqual(self.transitions(item),
                         ['backToItemCreated', 'proposeToValidationLevel2'])
        self.do(item, 'proposeToValidationLevel2')
        self.assertEqual(self.transitions(item), [
            'backToProposedToValidationLevel1', 'proposeToValidationLevel3',
            'wait_advices_from_proposedToValidationLevel2'
        ])
        self.do(item, 'wait_advices_from_proposedToValidationLevel2')
        # a MeetingManager is able to send back but not a normal user
        self.assertEqual(self.transitions(item), [
            'backTo_proposedToValidationLevel2_from_waiting_advices',
            'backTo_proposedToValidationLevel3_from_waiting_advices',
            'backTo_validated_from_waiting_advices'
        ])
        # but a
        self._addPrincipalToGroup('bourgmestre', self.dirgen_creators)
        self._addPrincipalToGroup('bourgmestre', self.dirgen_level1reviewers)
        self._addPrincipalToGroup('bourgmestre', self.dirgen_level2reviewers)
        self._addPrincipalToGroup('bourgmestre', self.dirgen_level3reviewers)
        self.changeUser('bourgmestre')
        self.assertTrue(self.hasPermission("View", item))
        self.assertEqual(self.transitions(item), [])

        # give advice
        self.changeUser('dfin')
        self.assertEqual(self.transitions(item), [
            'backTo_proposedToValidationLevel2_from_waiting_advices',
            'backTo_proposedToValidationLevel3_from_waiting_advices'
        ])
        # advice may be taken over
        self.assertTrue(item.adapted().mayTakeOver())
        # advice giveable when item complete
        self.assertFalse(item.adviceIndex[fin_group_uid]['advice_addable'])
        self.assertTrue(item.adapted().mayEvaluateCompleteness())
        # we will check that item modified date is invalidated when advice changed
        # this is responsible for updating collections counter in faceted portlet
        volatile_date = get_cachekey_volatile(
            'Products.PloneMeeting.MeetingItem.modified')
        item_modified = item.modified()
        item.setCompleteness('completeness_complete')
        item._update_after_edit()
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        advice_portal_type = item._advicePortalTypeForAdviser(fin_group_uid)
        advice = self.addAdvice(item,
                                advice_group=fin_group_uid,
                                advice_type='positive_finance',
                                advice_portal_type=advice_portal_type)
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        self.assertTrue(advice.advice_hide_during_redaction)
        self.assertEqual(self.transitions(advice),
                         ['proposeToFinancialController'])
        # once advice given but hidden during redaction, item may no more be sent back
        self.assertEqual(self.transitions(item), [])
        # financial controller
        self.do(advice, 'proposeToFinancialController')
        self.assertEqual(self.transitions(item), [])
        self.assertEqual(self.transitions(advice),
                         ['backToAdviceCreated', 'proposeToFinancialEditor'])
        # indexAdvisers is correctly reindexed
        advice_index_value = "delay__{0}_proposed_to_financial_controller".format(
            fin_group_uid)
        self.assertTrue(
            self.catalog(UID=item_uid, indexAdvisers=[advice_index_value]))
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        # financial editor
        self.do(advice, 'proposeToFinancialEditor')
        self.assertEqual(self.transitions(advice), [
            'backToProposedToFinancialController', 'proposeToFinancialReviewer'
        ])
        # indexAdvisers is correctly reindexed
        advice_index_value = "delay__{0}_proposed_to_financial_editor".format(
            fin_group_uid)
        self.assertTrue(
            self.catalog(UID=item_uid, indexAdvisers=[advice_index_value]))
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        # financial reviewer
        self.do(advice, 'proposeToFinancialReviewer')
        self.assertEqual(self.transitions(item), [])
        self.assertEqual(self.transitions(advice), [
            'backToProposedToFinancialController',
            'backToProposedToFinancialEditor', 'proposeToFinancialManager'
        ])
        # indexAdvisers is correctly reindexed
        advice_index_value = "delay__{0}_proposed_to_financial_reviewer".format(
            fin_group_uid)
        self.assertTrue(
            self.catalog(UID=item_uid, indexAdvisers=[advice_index_value]))
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        # financial manager
        self.do(advice, 'proposeToFinancialManager')
        self.assertEqual(self.transitions(item), [])
        self.assertEqual(self.transitions(advice), [
            'backToProposedToFinancialController',
            'backToProposedToFinancialReviewer', 'signFinancialAdvice'
        ])
        # indexAdvisers is correctly reindexed
        advice_index_value = "delay__{0}_proposed_to_financial_manager".format(
            fin_group_uid)
        self.assertTrue(
            self.catalog(UID=item_uid, indexAdvisers=[advice_index_value]))
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        # sign advice
        self.do(advice, 'signFinancialAdvice')
        self.assertEqual(self.transitions(item), [
            'backTo_proposedToValidationLevel2_from_waiting_advices',
            'backTo_proposedToValidationLevel3_from_waiting_advices',
            'backTo_validated_from_waiting_advices'
        ])
        self.assertEqual(self.transitions(advice),
                         ['backToProposedToFinancialManager'])
        self.assertFalse(advice.advice_hide_during_redaction)
        # indexAdvisers is correctly reindexed
        advice_index_value = "delay__{0}_financial_advice_signed".format(
            fin_group_uid)
        self.assertTrue(
            self.catalog(UID=item_uid, indexAdvisers=[advice_index_value]))
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)
        # validate item
        self.do(item, 'backTo_validated_from_waiting_advices')
        self.assertEqual(item.query_state(), 'validated')
        # indexAdvisers is correctly reindexed
        advice_index_value = "delay__{0}_advice_given".format(fin_group_uid)
        self.assertTrue(
            self.catalog(UID=item_uid, indexAdvisers=[advice_index_value]))
        # item modified date was updated
        item_modified, volatile_date = _check_date(item, item_modified,
                                                   volatile_date)