Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/browser_templates/levelreportgeneratorpage.pt
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/browser_templates/levelreportgeneratorpage.pt	(revision 10560)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/browser_templates/levelreportgeneratorpage.pt	(revision 10560)
@@ -0,0 +1,65 @@
+<form  i18n:domain="waeup.kofa"  method="POST">
+  <p i18n:translate="">
+    Please pick the department, session and level
+    for which the report should be generated.
+    The report will be processed and then made available for you
+    to view/download.
+  </p>
+  <br />
+  <div class="clearfix">
+    <label for="session" i18n:translate="">Department:</label>
+    <div class="input">
+      <select name="faccode_depcode">
+        <span tal:repeat="items view/faccode_depcodes" tal:omit-tag="">
+          <option
+              tal:define="name python: items[1]; title python: items[0]"
+              tal:attributes="value name">
+            <span tal:replace="title">TITLE</span>
+          </option>
+        </span>
+      </select>
+      <div class="help-inline" i18n:translate="">
+        Set department filter.
+      </div>
+    </div>
+    <br />
+    <label for="session">Academic Session:</label>
+    <div class="input">
+      <select name="session" i18n:translate="">
+        <span tal:repeat="items view/sessions" tal:omit-tag="">
+          <option
+              tal:define="name python: items[1]; title python: items[0]"
+              tal:attributes="value name">
+            <span tal:replace="title">TITLE</span>
+          </option>
+        </span>
+      </select>
+      <div class="help-inline" i18n:translate="">
+        Select academic session to report.
+      </div>
+    </div>
+    <br />
+    <label for="session">Level:</label>
+    <div class="input">
+      <select name="level" i18n:translate="">
+        <span tal:repeat="items view/levels" tal:omit-tag="">
+          <option
+              tal:define="name python: items[1]; title python: items[0]"
+              tal:attributes="value name">
+            <span tal:replace="title">TITLE</span>
+          </option>
+        </span>
+      </select>
+      <div class="help-inline" i18n:translate="">
+        Select level to report.
+      </div>
+    </div>
+
+  </div>
+  <div class="input">
+    <input i18n:translate="" type="submit" class="btn primary"
+           name="CREATE" value="Create" />
+    <a class="btn secondary" href=""
+       tal:attributes="href view/parent_url">Cancel</a>
+  </div>
+</form>
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py	(revision 10559)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py	(revision 10560)
@@ -149,2 +149,104 @@
             pagesize=landscape(A4))
         return pdf
+
+@implementer(IReportGenerator)
+class LevelReportGenerator(grok.GlobalUtility):
+
+    title = _('Level Report')
+    grok.name('level_reports')
+
+    def generate(self, site, faccode=None, depcode=None,
+                 session=None, level=None, author=None):
+        result = LevelReportReport(faccode=faccode, depcode=depcode,
+                                   session=session, level=level, author=author)
+        return result
+
+###############################################################
+## Browser related stuff
+##
+## XXX: move to local browser module
+###############################################################
+from waeup.kofa.browser.layout import KofaPage
+from waeup.kofa.interfaces import academic_sessions_vocab
+from waeup.kofa.reports import get_generators
+grok.templatedir('browser_templates')
+class LevelReportGeneratorPage(KofaPage):
+
+    grok.context(LevelReportGenerator)
+    grok.name('index.html')
+    grok.require('waeup.manageReports')
+
+    label = _('Create level report')
+
+    @property
+    def generator_name(self):
+        for name, gen in get_generators():
+            if gen == self.context:
+                return name
+        return None
+
+    def update(self, CREATE=None, faccode_depcode=None,
+               session=None, level=None):
+        self.parent_url = self.url(self.context.__parent__)
+        self._set_session_values()
+        self._set_level_values()
+        self._set_faccode_depcode_values()
+        #faccode = faccode_depcode.split('_')[0]
+        #depcode = faccode_depcode.split('_')[1]
+        if CREATE and session:
+            # create a new report job for students by session
+            container = self.context.__parent__
+            user_id = self.request.principal.id
+            kw = dict(
+                session=int(session),
+                level=int(level),
+                faccode=faccode,
+                depcode=depcode)
+            self.flash(_('New report is being created in background'))
+            job_id = container.start_report_job(
+                self.generator_name, user_id, kw=kw)
+            ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
+            grok.getSite().logger.info(
+                '%s - report %s created: %s (session=%s, mode=%s)' % (
+                ob_class, job_id, self.context.title, session, mode))
+            self.redirect(self.parent_url)
+            return
+        return
+
+    def _set_session_values(self):
+        vocab_terms = academic_sessions_vocab.by_value.values()
+        self.sessions = [(x.title, x.token) for x in vocab_terms]
+        return
+
+    def _set_level_values(self):
+        vocab_terms = course_levels.by_value.values()
+        self.levels = sorted([(x.title, x.token) for x in vocab_terms])
+        return
+
+    def _set_faccode_depcode_values(self):
+        # Not yet implemented
+        self.faccode_depcodes = None
+        return
+
+
+class LevelReportPDFView(grok.View):
+
+    grok.context(ILevelReport)
+    grok.name('pdf')
+    grok.require('waeup.Public')
+
+    def render(self):
+        filename = 'LevelReport_%s_%s_%s.pdf' % (
+            self.context.session, self.context.mode,
+            self.context.creation_dt_string)
+        filename = filename.replace(
+            '/', '_').replace(' ','_').replace(':', '-')
+        self.response.setHeader(
+            'Content-Type', 'application/pdf')
+        self.response.setHeader(
+            'Content-Disposition:', 'attachment; filename="%s' % filename)
+        pdf_stream = self.context.create_pdf()
+        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
+        grok.getSite().logger.info('%s - report %s downloaded: %s' % (
+            ob_class, self.context.__name__, filename))
+        return pdf_stream
