Skip to content

Commit

Permalink
Merge pull request #8091 from 4teamwork/es/TI-1546-exporter
Browse files Browse the repository at this point in the history
Role assignment excel exporter
  • Loading branch information
elioschmutz authored Nov 28, 2024
2 parents b30c334 + f72a6fd commit cd0a98f
Show file tree
Hide file tree
Showing 17 changed files with 687 additions and 154 deletions.
1 change: 1 addition & 0 deletions changes/TI-1546.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement ad-hoc role assignment excel export. [elioschmutz]
2 changes: 1 addition & 1 deletion docs/public/dev-manual/api/role_assignment_reports.rst
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Mittels eines GET-Requests können die Daten für einen spezifischen Berechtigun
Content-Type: application/json

{
"@id": "http://localhost:8081/fd/@role-assignment-report?b_size=25&b_start=0&principal_id:list=hugo.boss&root=abca20b04af54d2cbb2816545333e555&include_memberships=true",
"@id": "http://localhost:8081/fd/@role-assignment-report?b_size=25&b_start=0&filters.principal_id:record:list=hugo.boss&filters.root:record=abca20b04af54d2cbb2816545333e555&filters.include_memberships:record:boolean=true",
"items": [
{
"@id": "http://nohost/plone/ordnungssystem/fuhrung/vertrage-und-vereinbarungen/dossier-1",
Expand Down
8 changes: 4 additions & 4 deletions opengever/api/role_assignment_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ def reply(self):
class RoleAssignmentReportGet(Service):

def reply(self):
principal_ids = self.resolve_principals(
self.request.form.get("principal_ids", []))
filters = self.request.get('filters', {})

include_memberships = self.request.form.get("include_memberships", False)
root = self.request.form.get("root")
principal_ids = self.resolve_principals(filters.get("principal_ids", []))
include_memberships = filters.get("include_memberships", False)
root = filters.get("root")
b_start = safe_int(self.request.form.get("b_start", 0))
b_size = safe_int(self.request.form.get("b_size", 25))

Expand Down
7 changes: 3 additions & 4 deletions opengever/api/tests/test_role_assignment_reports.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from datetime import datetime
from ftw.testbrowser import browsing
from ftw.testing import freeze
from opengever.sharing.local_roles_lookup.reporter import RoleAssignmentReporter
from opengever.testing import IntegrationTestCase
from opengever.testing import SolrIntegrationTestCase
import json
Expand Down Expand Up @@ -290,13 +289,13 @@ class TestRoleAssignmentReportGet(SolrIntegrationTestCase):
def test_role_assignment_report(self, browser):
self.login(self.administrator, browser=browser)

url = "{absolute_url}/@role-assignment-report?principal_ids:list={regular_user}".format(
url = "{absolute_url}/@role-assignment-report?filters.principal_ids:record:list={regular_user}".format(
absolute_url=self.portal.absolute_url(),
regular_user=self.regular_user.getId()
)
browser.open(url, method='GET', headers=self.api_headers)
expected_data = {
u'@id': u'http://nohost/plone/@role-assignment-report?principal_ids%3Alist=regular_user',
u'@id': u'http://nohost/plone/@role-assignment-report?filters.principal_ids%3Arecord%3Alist=regular_user',
u'items': [
{
u'@id': u'http://nohost/plone/ordnungssystem/fuhrung/vertrage-und-vereinbarungen/dossier-1',
Expand Down Expand Up @@ -384,4 +383,4 @@ def test_role_assignment_report(self, browser):
]
}
self.assertEqual(200, browser.status_code)
self.assertSequenceEqual(expected_data, browser.json)
self.assertEqual(expected_data, browser.json)
7 changes: 0 additions & 7 deletions opengever/base/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,6 @@
permission="cmf.ManagePortal"
/>

<browser:page
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
name="download-role-assignment-report"
class=".role_assignment_excel_report.RoleAssignmentReportExcelDownload"
permission="opengever.api.ManageRoleAssignmentReports"
/>

<browser:page
name="logout"
for="*"
Expand Down
73 changes: 0 additions & 73 deletions opengever/base/browser/role_assignment_excel_report.py

This file was deleted.

61 changes: 0 additions & 61 deletions opengever/base/tests/test_role_assignment_excel_report.py

This file was deleted.

1 change: 1 addition & 0 deletions opengever/sharing/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

<include package="plone.app.workflow" />
<include package=".browser" />
<include package=".local_roles_lookup" />

<i18n:registerTranslations directory="locales" />

Expand Down
12 changes: 12 additions & 0 deletions opengever/sharing/local_roles_lookup/configure.zcml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">

<browser:page
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
name="download-role-assignment-report"
class=".exporter.RoleAssignmentReportExcelDownload"
permission="opengever.api.ManageRoleAssignmentReports"
/>

</configure>
98 changes: 98 additions & 0 deletions opengever/sharing/local_roles_lookup/exporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from datetime import datetime
from opengever.base.browser.reporting_view import BaseReporterView
from opengever.base.reporter import XLSReporter
from opengever.sharing import _
from opengever.sharing.local_roles_lookup.reporter import RoleAssignmentReporter
from plone.app.uuid.utils import uuidToObject


class RoleAssignmentReportExcelDownload(BaseReporterView):

def __call__(self):
principal_ids, include_memberships, root = self.extract_query_params()

report = RoleAssignmentReporter().excel_report_for(
principal_ids=principal_ids,
include_memberships=include_memberships,
root=root)

items = list(self.prepare_report_for_export(report))
reporter = XLSReporter(self.request, self.columns(), items)
return self.return_excel(reporter)

def extract_query_params(self):
filters = self.request.get('filters', {})

principal_ids = filters.get("principal_ids", [])
include_memberships = filters.get("include_memberships", False)
root = filters.get("root")

return principal_ids, include_memberships, root

@property
def filename(self):
principal_ids, include_membership, root = self.extract_query_params()

parts = [datetime.now().strftime('%Y-%m-%d_%H-%M')]

if root:
root = uuidToObject(root)
parts.append('branch_{}'.format(root.id))

if include_membership:
parts.append('including_memberships')

if principal_ids:
parts.append('-'.join(principal_ids))

return u'role_assignment_report_{}.xlsx'.format('_'.join(parts))

def prepare_report_for_export(self, report):
for report_item in report:
item = report_item.get('item')
principal = report_item.get('principal')
yield {
u'title': item.get('title'),
u'url': item.get('@id'),
u'portal_type': item.get('@type'),
u'principal_id': principal.get('principal_id'),
u'username': principal.get('username'),
u'groupname': principal.get('groupname'),
u'role': report_item.get('role'),
}

@property
def _columns(self):
columns = [
{
'id': 'title',
'title': _('label_title', default=u'Title'),
},
{
'id': 'url',
'title': _('label_url', default=u'URL'),
'hyperlink': lambda value, obj: obj.get('url'),
},
{
'id': 'portal_type',
'title': _('label_portal_type', default=u'Portal type'),
},
{
'id': 'principal_id',
'title': _('label_principal_id', default=u'Principal id'),
},
{
'id': 'username',
'title': _('label_user_name', default=u'User name'),
},
{
'id': 'groupname',
'title': _('label_group_name', default=u'Group name'),
},
{
'id': 'role',
'title': _('label_role', default=u'Role'),
}
]

return columns
Loading

0 comments on commit cd0a98f

Please sign in to comment.