def get_indexer_value(self, searchable=False): """Return the filing value for the filing_no indexer. For Dossiers without a number and only a prefix it return the half of the number.""" value = None if IFilingNumber(self.context).filing_no: value = IFilingNumber(self.context).filing_no elif IDossier(self.context).filing_prefix: value = '%s-%s-?' % ( self._get_client_id(), self._get_term_title( IDossier(self.context).filing_prefix, 'opengever.dossier.type_prefixes'), ) if searchable: # cut the -? away value = value[:-2] if value: if searchable: return value.replace('-', ' ') return value return
def _recursive_resolve(self, dossier, end_date, recursive=False): # no end_date is given use the earliest possible if not end_date: end_date = dossier.earliest_possible_end_date() if recursive: # check the subdossiers end date # If a subdossier is already resolved, but seems to have an invalid # end date, it's because we changed the resolution logic and rules # over time, and that subdossier's end date has retroactively become # invalid. In this case, we correct the end date according to current # rules and proceed with resolving it. if dossier.is_resolved() and not dossier.has_valid_enddate(): IDossier(dossier).end = dossier.earliest_possible_end_date() # if no end date is set or the end_date is invalid, set to the parent # end date. Invalid end_date should normally be prevented by # ResolveConditions._recursive_date_validation, but this correction # would happen for example when resolving a dossier in debug mode. elif not IDossier(dossier).end or not dossier.has_valid_enddate(): IDossier(dossier).end = end_date else: # main dossier set the given end_date IDossier(dossier).end = end_date dossier.reindexObject(idxs=['end']) for subdossier in dossier.get_subdossiers(): self._recursive_resolve(subdossier.getObject(), end_date, recursive=True) if dossier.is_open(): self.wft.doActionFor(dossier, 'dossier-transition-resolve')
def test_resets_end_dates_recursively(self, browser): self.login(self.secretariat_user, browser) self.set_workflow_state('dossier-state-resolved', self.resolvable_dossier, self.resolvable_subdossier) end_date = date(2013, 2, 21) end_date_index = self.dateindex_value_from_datetime(end_date) IDossier(self.resolvable_dossier).end = end_date IDossier(self.resolvable_subdossier).end = end_date self.resolvable_dossier.reindexObject(idxs=['end']) self.resolvable_subdossier.reindexObject(idxs=['end']) subsub = create( Builder('dossier').within(self.resolvable_subdossier).having( end=end_date).in_state('dossier-state-resolved')) self.assert_index_value(end_date_index, 'end', self.resolvable_dossier, self.resolvable_subdossier, subsub) self.assert_metadata_value(end_date, 'end', self.resolvable_dossier, self.resolvable_subdossier, subsub) self.reactivate(self.resolvable_dossier, browser) self.assert_index_value('', 'end', self.resolvable_dossier, self.resolvable_subdossier, subsub) self.assert_metadata_value(None, 'end', self.resolvable_dossier, self.resolvable_subdossier, subsub) self.assertIsNone(IDossier(self.resolvable_dossier).end) self.assertIsNone(IDossier(self.resolvable_subdossier).end) self.assertIsNone(IDossier(subsub).end)
def make_dossier_keywords_unicode(self): query = {'object_provides': [IDossierTemplateMarker.__identifier__, IDossierMarker.__identifier__, ]} for obj in self.objects(query, 'Ensure dossier keywords are unicode'): dossier = IDossier(obj) dossier.keywords = tuple( safe_unicode(keyword) for keyword in dossier.keywords)
def get_render_arguments(self): args = { 'clienttitle': self.convert_plain(self.get_client_title()), 'repositoryversion': self.convert_plain(self.get_repository_version()), 'referencenr': self.convert_plain(self.get_referencenumber()), 'title': self.convert_plain(self.context.Title()), 'description': self.convert(self.get_description()), 'responsible': self.convert_plain(self.get_responsible()), 'start': self.convert_plain( self.context.toLocalizedTime(str(IDossier(self.context).start)) or '-'), 'end': self.convert_plain( self.context.toLocalizedTime(str(IDossier(self.context).end)) or '-'), } return args
def __call__(self): searchable = [] # append some other attributes to the searchableText index # reference_number refNumb = getAdapter(self.context, IReferenceNumber) searchable.append(refNumb.get_number()) # sequence_number seqNumb = getUtility(ISequenceNumber) searchable.append(str(seqNumb.get_number(self.context))) # responsible info = getUtility(IContactInformation) dossier = IDossier(self.context) searchable.append(info.describe(dossier.responsible).encode( 'utf-8')) # filling_no dossier = IDossierMarker(self.context) if getattr(dossier, 'filing_no', None): searchable.append(str(getattr(dossier, 'filing_no', None)).encode('utf-8')) # comments comments = getattr(IDossier(self.context), 'comments', None) if comments: searchable.append(comments.encode('utf-8')) return ' '.join(searchable)
def test_expired_filters_shows_only_dossiers_with_expired_retention_period(self, browser): self.login(self.records_manager, browser=browser) self.open_repo_with_filter( browser, self.leaf_repofolder, 'filter_retention_expired') data = browser.css('.listing').first.lists() self.assertEqual(self.listing_fields, data.pop(0)) expected_data = [self.get_folder_data(self.expired_dossier)] self.assertItemsEqual(expected_data, data) # update end dates to have expired retention periods IDossier(self.expired_dossier).end = date.today() self.expired_dossier.reindexObject() IDossier(self.inactive_dossier).end = date.today() - relativedelta(years=16) self.inactive_dossier.reindexObject() self.open_repo_with_filter( browser, self.leaf_repofolder, 'filter_retention_expired') data = browser.css('.listing').first.lists() self.assertEqual(self.listing_fields, data.pop(0)) expected_data = [self.get_folder_data(self.inactive_dossier)] self.assertItemsEqual(expected_data, data)
def __call__(self): searchable = [] # append some other attributes to the searchableText index # reference_number refNumb = getAdapter(self.context, IReferenceNumber) searchable.append(refNumb.get_number()) # sequence_number seqNumb = getUtility(ISequenceNumber) searchable.append(str(seqNumb.get_number(self.context))) # responsible searchable.append(self.context.responsible_label.encode('utf-8')) # filing_no if IFilingNumberMarker.providedBy(self.context): filing_no = getattr(IFilingNumber(self.context), 'filing_no', None) if filing_no: searchable.append(filing_no.encode('utf-8')) # comments comments = getattr(IDossier(self.context), 'comments', None) if comments: searchable.append(comments.encode('utf-8')) # keywords keywords = IDossier(self.context).keywords if keywords: searchable.extend( keyword.encode('utf-8') if isinstance(keyword, unicode) else keyword for keyword in keywords) return ' '.join(searchable)
def test_dossiertemplate_values_are_prefilled_properly_in_the_dossier( self, browser): values = { 'title': u'My template', 'description': u'Lorem ipsum', 'keywords': (u'secret', u'special'), 'comments': 'this is very special', 'filing_prefix': 'department' } create( Builder("dossiertemplate").within( self.templatefolder).having(**values)) browser.login().visit(self.leaf_node) factoriesmenu.add('Dossier with template') token = browser.css( 'input[name="form.widgets.template"]').first.attrib.get('value') browser.fill({'form.widgets.template': token}).submit() browser.click_on('Save') dossier = browser.context self.assertEqual(values.get('title'), dossier.title) self.assertEqual(values.get('description'), dossier.description) self.assertEqual(values.get('keywords'), IDossier(dossier).keywords) self.assertEqual(values.get('comments'), IDossier(dossier).comments) self.assertEqual(values.get('filing_prefix'), IDossier(dossier).filing_prefix)
def fix_dossier(self, dossier): intid = self.intid_utility.getId(dossier) parent = aq_parent(aq_inner(dossier)) former_reference_number = IDossier(dossier).former_reference_number if not former_reference_number: print 'SKIPPED Dosier ({}{}) created at '.format( '/'.join(dossier.getPhysicalPath()), dossier.created()) return former_prefix = former_reference_number.split('-')[-1].split('.')[-1] ref_mapping = IAnnotations(parent).get('dossier_reference_mapping') old_prefix = former_prefix new_prefix = ref_mapping.get('reference_prefix').get(intid) # check if former_reference_number is registered for current dossier if ref_mapping.get('reference_numbers').get(former_prefix) != intid: print 'Check failed' import pdb; pdb.set_trace() else: # free new prefix (remove it from the numbers list) ref_mapping['reference_numbers'].pop(new_prefix) # set old prefix as current ref_mapping['reference_prefix'][intid] = old_prefix.decode('utf-8') print '{} --> {} ({})'.format(new_prefix, old_prefix, '/'.join(dossier.getPhysicalPath())) self.reindex_dossier_and_children(dossier)
def test_end_date_is_allways_valid_in_a_empty_dossier(self): self.login(self.dossier_responsible) IDossier(self.empty_dossier).end = date(2050, 1, 1) self.assertTrue(self.empty_dossier.has_valid_enddate()) IDossier(self.empty_dossier).end = None self.assertTrue(self.empty_dossier.has_valid_enddate())
def test_none_is_not_a_valid_start_date(self): self.login(self.dossier_responsible) IDossier(self.empty_dossier).start = None IDossier(self.empty_dossier).end = None self.empty_dossier.reindexObject(idxs=['end', 'start']) self.assertIsNone(self.empty_dossier.earliest_possible_end_date()) self.assertFalse(self.empty_dossier.has_valid_startdate())
def test_update_prefix(self): self.archiver.update_prefix('FAKE PREFIX') self.assertEquals('FAKE PREFIX', IDossier(self.dossier).filing_prefix) self.assertEquals('FAKE PREFIX', IDossier(self.sub1).filing_prefix) self.assertEquals('FAKE PREFIX', IDossier(self.sub2).filing_prefix) self.assertEquals('FAKE PREFIX', IDossier(self.subsub1).filing_prefix)
def test_earliest_possible_is_end_date_of_a_dossiers(self): self.login(self.dossier_responsible) IDossier(self.empty_dossier).start = None IDossier(self.empty_dossier).end = date(2029, 9, 18) self.empty_dossier.reindexObject(idxs=['end', 'start']) self.assertEquals(date(2029, 9, 18), self.empty_dossier.earliest_possible_end_date())
def test_update_prefix(self): self.login(self.dossier_responsible) IDossierArchiver(self.dossier).update_prefix('FAKE PREFIX') self.assertEquals('FAKE PREFIX', IDossier(self.dossier).filing_prefix) self.assertEquals('FAKE PREFIX', IDossier(self.subdossier).filing_prefix) self.assertEquals('FAKE PREFIX', IDossier(self.subdossier2).filing_prefix)
def dossier_enddate_default(context): """Suggested default for the dossier's enddate. context: Dossier that's being archived. """ if IDossier(context).end and context.has_valid_enddate(): return IDossier(context).end return context.earliest_possible_end_date()
def filing_prefix_default_value(data): """If allready a filing_prefix is selected on the dossier, it return this as default.""" prefix = IDossier(data.context).filing_prefix if prefix: return prefix.decode('utf-8') return ""
def filing_prefix_default_value(data): """If allready a filing_prefix is selected on the dossier, it return this as default.""" prefix = IDossier(data.context).filing_prefix if prefix: return prefix.decode("utf-8") return ""
def test_default_values(self): """Check the default values of the dossier Default responsible of a new dossier must be the owner. The default responsible of a subdossier must be the owner of the parent-dossier """ for dossier_type in self.dossier_types: # browser = self.get_add_view(dossier_type) self.request.set('form.widgets.IDossier.responsible', []) d1_view = self.portal.repo.unrestrictedTraverse('++add++%s' % dossier_type) # We have to call the view to run the update-method d1_view() # In the request we must have the logged in user self.assertEquals([self.get_logged_in_user()], d1_view.request.get( 'form.widgets.IDossier.responsible', None)) # In tests, the default value from the request won't work correctly # So we create a new dossier and add the resposible manually d1 = self.create_dossier(dossier_type) # set the responsible IDossier(d1).responsible = self.get_logged_in_user() # We have to reset the request for the new dossier self.request.set('form.widgets.IDossier.responsible', []) logout() login(self.portal, SITE_OWNER_NAME) # The same with another user d2_view = self.portal.repo.unrestrictedTraverse('++add++%s' % dossier_type) d2_view() self.assertEquals([self.get_logged_in_user()], d2_view.request.get( 'form.widgets.IDossier.responsible', None)) d2 = self.create_dossier(dossier_type) IDossier(d2).responsible = self.get_logged_in_user() self.request.set('form.widgets.IDossier.responsible', []) # We change the user again an create a subdossier logout() login(self.portal, TEST_USER_NAME) d2_1_view = d2.unrestrictedTraverse('++add++%s' % dossier_type) d2_1_view() # This is a subdossier, so in responsible # we must still have the logged in user as responsible self.assertEquals([self.get_logged_in_user()], d2_1_view.request.get( 'form.widgets.IDossier.responsible', None))
def __call__(self): self.request.response.setHeader('Content-Type', 'application/json') self.request.response.setHeader('X-Theme-Disabled', 'True') data = json.loads(self.request.get('data', '{}')) dossier = IDossier(self.context) dossier.comments = data['comments'] self.context.reindexObject(idxs=['SearchableText']) return json.dumps({'comment': self.context.get_formatted_comments()})
def test_resets_end_dates_recursively(self, browser): self.login(self.secretariat_user, browser) IDossier(self.dossier).end = date(2013, 2, 21) IDossier(self.subdossier).end = date(2013, 2, 21) IDossier(self.subsubdossier).end = date(2013, 2, 21) self.set_workflow_state( 'dossier-state-inactive', self.dossier, self.subdossier, self.subdossier2, self.subsubdossier, ) self.assertIsNotNone(IDossier(self.dossier).end) self.assertIsNotNone(IDossier(self.subdossier).end) self.assertIsNotNone(IDossier(self.subsubdossier).end) self.activate(self.dossier, browser) self.assert_workflow_state('dossier-state-active', self.dossier) self.assert_workflow_state('dossier-state-active', self.subdossier) self.assert_workflow_state('dossier-state-active', self.subsubdossier) self.assertIsNone(IDossier(self.dossier).end) self.assertIsNone(IDossier(self.subdossier).end) self.assertIsNone(IDossier(self.subsubdossier).end)
def get_item_metadata(self, obj, guid): path = '/'.join(obj.getPhysicalPath()) title = self.get_title(obj) parent = aq_parent(obj) parent_guid = IAnnotations(parent).get(BUNDLE_GUID_KEY) if obj.portal_type == 'opengever.repository.repositoryfolder': item_info = OrderedDict([ ('guid', guid), ('parent_guid', parent_guid), ('path', path), ('title', title), ('description', obj.description), ('full_reference_number', self.get_reference_number(obj)), ]) elif obj.portal_type == 'opengever.dossier.businesscasedossier': item_info = OrderedDict([ ('guid', guid), ('parent_guid', parent_guid), ('path', path), ('title', title), ('full_reference_number', self.get_reference_number(obj)), ('reference_number', IDossier(obj).reference_number), ('responsible', IDossier(obj).responsible), ('description', IOpenGeverBase(obj).description), ('start', IDossier(obj).start), ('end', IDossier(obj).end), ('review_state', api.content.get_state(obj)), ]) elif obj.portal_type in ( 'opengever.document.document', 'ftw.mail.mail'): file_field = self.get_file_field(obj) file_size = None file_name = None if file_field is not None: file_size = file_field.getSize() file_name = file_field.filename item_info = OrderedDict([ ('guid', guid), ('parent_guid', parent_guid), ('path', path), ('title', title), ('file_size', file_size), ('file_name', file_name), ('document_date', obj.document_date), ]) else: item_info = OrderedDict([ ('guid', guid), ('path', path), ('title', title), ]) return item_info
def test_calculation_ignore_inactive_subdossiers_for_calculation(self): self.login(self.dossier_responsible) IDossier(self.subdossier).end = date(2020, 1, 1) self.subdossier.reindexObject(idxs=['end']) IDossier(self.subdossier2).end = date(2020, 2, 2) self.subdossier2.reindexObject(idxs=['end']) self.assertEquals(date(2020, 2, 2), self.dossier.earliest_possible_end_date()) self.set_workflow_state('dossier-state-inactive', self.subdossier2) self.assertEquals(date(2020, 1, 1), self.dossier.earliest_possible_end_date())
def get_folder_data(dossier): data = ['', dossier.get_reference_number(), dossier.title, api.content.get_state(dossier), dossier.responsible_label, readable_date(dossier, IDossier(dossier).start), readable_date(dossier, IDossier(dossier).end), ', '.join(IDossier(dossier).keywords), ] return data
def filing_prefix_default(context): """If the dossier already has a filing_prefix set, use that one as the default for the filing_prefix in the ArchiveForm. context: Dossier that's being archived. """ prefix = IDossier(context).filing_prefix if prefix: return prefix.decode('utf-8') # Need to return None here instead of empty string, because otherwise # validation in zope.schema's DefaultProperty fails (value not in vocab) return None
def get_retention_expiration_date(self): """Returns the date when the expiration date expires: The start of the next year (the first of january) after the retention period. """ if IDossier(self).end: year = IDossier(self).end.year + \ int(ILifeCycle(self).retention_period) return date(year + 1, 1, 1) return None
def __init__(self, dossier, disposition): self.title = dossier.title self.intid = getUtility(IIntIds).getId(dossier) self.url = dossier.absolute_url() self.reference_number = dossier.get_reference_number() self.parent = aq_parent(aq_inner(dossier)) self.start = IDossier(dossier).start self.end = IDossier(dossier).end self.public_trial = IClassification(dossier).public_trial self.archival_value = ILifeCycle(dossier).archival_value self.archival_value_annotation = ILifeCycle(dossier).archival_value_annotation self.appraisal = IAppraisal(disposition).get(dossier) self.former_state = dossier.get_former_state()
def assert_dossier_vreni_created(self, parent): dossier = self.leaf_repofolder.get('dossier-15') self.assertEqual(u'Vreni Meier ist ein Tausendsassa', IDossier(dossier).comments) self.assertEqual(tuple(), IDossier(dossier).keywords) self.assertEqual([], IDossier(dossier).relatedDossier) self.assertEqual(u'lukas.graf', IDossier(dossier).responsible) self.assertEqual('dossier-state-active', api.content.get_state(dossier)) self.assertEqual(date(2010, 11, 11), IDossier(dossier).start) self.assertEqual(u'Dossier in bestehendem Examplecontent Repository', dossier.title) self.assertEqual( IAnnotations(dossier)[BUNDLE_GUID_KEY], index_data_for(dossier)[GUID_INDEX_NAME])
def test_set_end_date_to_earliest_possible_one(self, browser): dossier = create(Builder('dossier').having(start=date(2015, 1, 1))) subdossier = create( Builder('dossier').having(start=date(2015, 1, 1)).within(dossier)) create( Builder('document').within(subdossier).having( document_date=date(2016, 6, 1))) browser.login().open(dossier, {'_authenticator': createToken()}, view='transition-resolve') self.assertEquals(date(2016, 6, 1), IDossier(dossier).end) self.assertEquals(date(2016, 6, 1), IDossier(subdossier).end, 'The end date has not been set recursively.')
def replace_interactive_user(self, principal): """Replaces interactive users in the principal. """ if principal == 'responsible': # find the dossier dossier = self.context while not IDossierMarker.providedBy(dossier): if IPloneSiteRoot.providedBy(dossier): raise ValueError('Could not find dossier') dossier = aq_parent(aq_inner(dossier)) # get the responsible of the dossier wrapped_dossier = IDossier(dossier) return wrapped_dossier.responsible elif principal == 'current_user': # get the current user mtool = getToolByName(self.context, 'portal_membership') member = mtool.getAuthenticatedMember() if not member: raise Unauthorized() return member.getId() else: return principal
def test_dossier_creation(self, browser): self.login(self.regular_user, browser) payload = { u'@type': u'opengever.dossier.businesscasedossier', u'title': u'Sanierung B\xe4rengraben 2016', u'responsible': self.regular_user.id, u'custody_period': 30, u'archival_value': u'unchecked', u'retention_period': 5, } response = browser.open(self.leaf_repofolder.absolute_url(), data=json.dumps(payload), method='POST', headers=self.api_headers) self.assertEqual(201, response.status_code) new_object_id = str(response.json['id']) dossier = self.leaf_repofolder.restrictedTraverse(new_object_id) self.assertEqual(u'Sanierung B\xe4rengraben 2016', dossier.title) self.assertEqual(self.regular_user.id, IDossier(dossier).responsible) self.assertEqual(30, ILifeCycle(dossier).custody_period) self.assertEqual(u'unchecked', ILifeCycle(dossier).archival_value) self.assertEqual(5, ILifeCycle(dossier).retention_period)
def sharing(self): # get the participants phandler = IParticipationAware(self.context) results = list(phandler.get_participations()) # also append the responsible class ResponsibleParticipant(object): pass responsible = ResponsibleParticipant() responsible.roles = _dossier(u'label_responsible', 'Responsible') responsible.role_list = responsible.roles dossier_adpt = IDossier(self.context) responsible.contact = dossier_adpt.responsible results.append(responsible) info = getUtility(IContactInformation) return [{ 'Title': info.describe(xx.contact), 'getURL': info.get_profile_url(xx.contact), 'css_class': 'function-user', } for xx in results]
def earliest_possible_end_date(self): catalog = getToolByName(self, 'portal_catalog') subdossiers = catalog({ 'path': '/'.join(self.getPhysicalPath()), 'object_provides': [ 'opengever.dossier.behaviors.dossier.IDossierMarker', ], 'review_state': [ 'dossier-state-active', 'dossier-state-resolved', ], }) end_dates = [] # main dossier if IDossier(self).start: end_dates.append(IDossier(self).start) for subdossier in subdossiers: if IDossier(subdossier.getObject()).end: temp_date = IDossier(subdossier.getObject()).end if not temp_date: temp_date = IDossier(subdossier.getObject()).start if isinstance(temp_date, datetime): end_dates.append(temp_date.date()) else: end_dates.append(temp_date) docs = subdossier.getObject().getFolderContents( {'object_provides': [ 'opengever.document.behaviors.IBaseDocument', ], }) for doc in docs: # document or mails if doc.document_date: if isinstance(doc.document_date, datetime): end_dates.append(doc.document_date.date()) else: end_dates.append(doc.document_date) if end_dates: end_dates.sort() return max(end_dates) return None
def test_related_dossiers_are_listed_on_overview(self, browser): self.login(self.regular_user, browser=browser) intids = getUtility(IIntIds) relations = IDossier(self.closed_meeting_dossier).relatedDossier relations.append(RelationValue(intids.getId(self.subdossier))) titles = ["abc", "Abd", "bcd"] for relation, title in zip(relations, titles): relation.to_object.setTitle(title) browser.open(self.closed_meeting_dossier, view='tabbedview_view-overview') self.assertEqual(titles, [node.text for node in browser.css("#referencesBox li span")]) for relation, title in zip(relations, reversed(titles)): relation.to_object.setTitle(title) browser.open(self.closed_meeting_dossier, view='tabbedview_view-overview') self.assertEqual(titles, [node.text for node in browser.css("#referencesBox li span")])
def __call__(self): searchable = [] # append some other attributes to the searchableText index # reference_number refNumb = getAdapter(self.context, IReferenceNumber) searchable.append(refNumb.get_number()) # sequence_number seqNumb = getUtility(ISequenceNumber) searchable.append(str(seqNumb.get_number(self.context))) # responsible searchable.append(self.context.responsible_label.encode('utf-8')) # filing_no if IFilingNumberMarker.providedBy(self.context): filing_no = getattr(IFilingNumber(self.context), 'filing_no', None) if filing_no: searchable.append(filing_no.encode('utf-8')) # comments comments = getattr(IDossier(self.context), 'comments', None) if comments: searchable.append(comments.encode('utf-8')) # keywords keywords = IDossier(self.context).keywords if keywords: searchable.extend( keyword.encode('utf-8') if isinstance(keyword, unicode) else keyword for keyword in keywords) searchable_external_reference = IDossier(self.context).external_reference if searchable_external_reference: searchable.append(searchable_external_reference.encode('utf-8')) return ' '.join(searchable)