Index: main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py	(revision 13066)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py	(revision 13802)
@@ -232,4 +232,18 @@
     return entries
 
+def running_jobs(view):
+    """True if any job is running.
+    """
+    job_entries = view.context.get_running_export_jobs()
+    job_manager = getUtility(IJobManager)
+    entries = []
+    for entry in job_entries:
+        job = job_manager.get(entry[0])
+        status = job.finished and 'ready' or 'running'
+        status = job.failed and 'FAILED' or status
+        if status == 'running':
+            return True
+    return False
+
 class LocalRoleAssignmentUtilityView(object):
     """A view mixin with useful methods for local role assignment.
@@ -1467,4 +1481,15 @@
             return
         if CREATE:
+            utils = queryUtility(IIkobaUtils)
+            if utils.export_disabled_message():
+                self.flash(utils.export_disabled_message(), type='danger')
+                self.entries = doll_up(self, user=None)
+                return
+            if running_jobs(self):
+                self.flash(_(
+                    "Sorry, another export job is running. "
+                    "Please try again later."), type='danger')
+                self.entries = doll_up(self, user=None)
+                return
             job_id = self.context.start_export_job(
                 exporter, self.request.principal.id)
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/browser/tests/test_browser.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/browser/tests/test_browser.py	(revision 13066)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/browser/tests/test_browser.py	(revision 13802)
@@ -69,8 +69,24 @@
 
 
-class DataCenterUITests(CompanySetup):
+class DataCenterUITests(CompanySetup, FunctionalAsyncTestCase):
     # Tests for DataCenter class views and pages
 
     layer = FunctionalLayer
+
+    def wait_for_export_job_completed(self):
+        # helper function waiting until the current export job is completed
+        manager = getUtility(IJobManager)
+        job_id = self.app['datacenter'].running_exports[0][0]
+        job = manager.get(job_id)
+        wait_for_result(job)
+        return job_id
+
+    def cleanup_run_job(self):
+        # helper to remove any result file of an export
+        job_id = self.wait_for_export_job_completed()
+        manager = getUtility(IJobManager)
+        job = manager.get(job_id)
+        if os.path.exists(job.result):
+            shutil.rmtree(os.path.dirname(job.result))
 
     def test_user_data_import_permission(self):
@@ -96,2 +112,50 @@
         self.assertTrue('User Processor' in self.browser.contents)
         return
+
+    def test_export_disabled(self):
+        self.app['configuration'].export_disabled_message = u'Export forbidden'
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.datacenter_path)
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.url, self.datacenter_path)
+        self.browser.getLink("Export data").click()
+        self.browser.getControl(name="exporter").value = ['products']
+        self.browser.getControl("Create CSV file").click()
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertTrue('div class="alert alert-danger">Export forbidden</div>'
+                         in self.browser.contents)
+        return
+
+    def test_export_start(self):
+        # we can trigger export file creation
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.datacenter_path)
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.url, self.datacenter_path)
+        self.browser.getLink("Export data").click()
+        self.browser.getControl(name="exporter").value = ['products']
+        self.browser.getControl("Create CSV file").click()
+        # we can trigger export file creation only once
+        self.browser.getControl(name="exporter").value = ['pdfdocuments']
+        self.browser.getControl("Create CSV file").click()
+        self.assertTrue('Sorry, another export job is running.'
+                         in self.browser.contents)
+        self.wait_for_export_job_completed()
+        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
+        self.browser.getControl(name="exporter").value = ['pdfdocuments']
+        self.browser.getControl("Create CSV file").click()
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(len(self.app['datacenter'].running_exports), 2)
+        # The second job is running
+        self.assertTrue('<img src="/static/img/actionicon_reload.png" />'
+                         in self.browser.contents)
+        self.cleanup_run_job() # make sure to remove temp dirs
+        # Also the second job must be cleaned up
+        manager = getUtility(IJobManager)
+        job_id = self.app['datacenter'].running_exports[1][0]
+        job = manager.get(job_id)
+        wait_for_result(job)
+        if os.path.exists(job.result):
+            shutil.rmtree(os.path.dirname(job.result))
+        return
+
