Ignore:
Timestamp:
26 Sep 2013, 09:37:25 (11 years ago)
Author:
Henrik Bettermann
Message:

Implement an VirtualApplicantsExportJobContainer? which allows to export applicants locally. On each container page there is now an'Export applicants' button which directs to the exports overview page. Unlike student exporters, the applicants exporter can't be configured. It just exports all applicants in the container.

Location:
main/waeup.kofa/trunk/src/waeup/kofa
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py

    r10645 r10655  
    3434    IApplicantRegisterUpdate
    3535    )
    36 from waeup.kofa.applicants.container import ApplicantsContainer
     36from waeup.kofa.applicants.container import (
     37    ApplicantsContainer, VirtualApplicantsExportJobContainer)
    3738from waeup.kofa.applicants.applicant import search
    3839from waeup.kofa.applicants.workflow import (
     
    4849from waeup.kofa.browser.layout import (
    4950    NullValidator, jsaction, action, UtilityView, JSAction)
    50 from waeup.kofa.browser.pages import add_local_role, del_local_roles
     51from waeup.kofa.browser.pages import (
     52    add_local_role, del_local_roles, doll_up, ExportCSVView)
    5153from waeup.kofa.browser.resources import datepicker, tabs, datatable, warning
    5254from waeup.kofa.interfaces import (
     
    273275    """
    274276    grok.context(IApplicantsContainer)
     277
     278
     279class ApplicantsExportsBreadcrumb(Breadcrumb):
     280    """A breadcrumb for exports.
     281    """
     282    grok.context(VirtualApplicantsExportJobContainer)
     283    title = _(u'Applicant Data Exports')
     284    target = None
    275285
    276286class ApplicantBreadcrumb(Breadcrumb):
     
    11621172        self.applicant_id = applicant_id
    11631173        return
     1174
     1175class ExportJobContainerOverview(KofaPage):
     1176    """Page that lists active applicant data export jobs and provides links
     1177    to discard or download CSV files.
     1178
     1179    """
     1180    grok.context(VirtualApplicantsExportJobContainer)
     1181    grok.require('waeup.manageApplication')
     1182    grok.name('index.html')
     1183    grok.template('exportjobsindex')
     1184    label = _('Applicant Data Exports')
     1185    pnav = 3
     1186
     1187    def update(self, CREATE=None, DISCARD=None, job_id=None):
     1188        if CREATE:
     1189            self.redirect(self.url('@@start_export'))
     1190            return
     1191        if DISCARD and job_id:
     1192            entry = self.context.entry_from_job_id(job_id)
     1193            self.context.delete_export_entry(entry)
     1194            ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
     1195            self.context.logger.info(
     1196                '%s - discarded: job_id=%s' % (ob_class, job_id))
     1197            self.flash(_('Discarded export') + ' %s' % job_id)
     1198        self.entries = doll_up(self, user=self.request.principal.id)
     1199        return
     1200
     1201class ExportJobContainerJobStart(KofaPage):
     1202    """Page that starts an applicants export job.
     1203
     1204    """
     1205    grok.context(VirtualApplicantsExportJobContainer)
     1206    grok.require('waeup.manageApplication')
     1207    grok.name('start_export')
     1208
     1209    def update(self):
     1210        exporter = 'applicants'
     1211        container_code = self.context.__parent__.code
     1212        job_id = self.context.start_export_job(exporter,
     1213                                      self.request.principal.id,
     1214                                      container=container_code)
     1215
     1216        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
     1217        self.context.logger.info(
     1218            '%s - exported: %s (%s), job_id=%s'
     1219            % (ob_class, exporter, container_code, job_id))
     1220        self.flash(_('Export started.'))
     1221        self.redirect(self.url(self.context))
     1222        return
     1223
     1224    def render(self):
     1225        return
     1226
     1227class ExportJobContainerDownload(ExportCSVView):
     1228    """Page that downloads a students export csv file.
     1229
     1230    """
     1231    grok.context(VirtualApplicantsExportJobContainer)
     1232    grok.require('waeup.manageApplication')
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/container.py

    r9531 r10655  
    2323import pytz
    2424from datetime import datetime
     25import zope.location.location
    2526from zope.component import getUtility
    2627from zope.component.factory import Factory
     
    3132    IApplicantsUtils)
    3233from waeup.kofa.utils.helpers import attrs_to_fields
    33 
     34from waeup.kofa.utils.batching import VirtualExportJobContainer
    3435
    3536def generate_applicant_id(container=None):
     
    4243        # In some tests we don't use containers
    4344        return u"xxx_1234"
     45
     46class VirtualApplicantsExportJobContainer(VirtualExportJobContainer):
     47    """A virtual export job container for certificates.
     48    """
    4449
    4550class ApplicantsContainer(grok.Container):
     
    119124        return
    120125
     126    def traverse(self, name):
     127        """Deliver appropriate containers.
     128        """
     129        if name == 'exports':
     130            # create a virtual exports container and return it
     131            container = VirtualApplicantsExportJobContainer()
     132            zope.location.location.located(container, self, 'exports')
     133            return container
     134        return None
     135
    121136ApplicantsContainer = attrs_to_fields(ApplicantsContainer)
    122137
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py

    r10645 r10655  
    2828from datetime import datetime, date, timedelta
    2929from mechanize import LinkNotFoundError
     30from zc.async.testing import wait_for_result
    3031from zope.event import notify
    3132from zope.catalog.interfaces import ICatalog
     
    4243from waeup.kofa.applicants.applicant import Applicant
    4344from waeup.kofa.interfaces import (
    44     IExtFileStore, IFileStoreNameChooser, IUserAccount)
     45    IExtFileStore, IFileStoreNameChooser, IUserAccount, IJobManager)
    4546from waeup.kofa.university.faculty import Faculty
    4647from waeup.kofa.university.department import Department
     48from waeup.kofa.tests.test_async import FunctionalAsyncTestCase
    4749
    4850PH_LEN = 15911  # Length of placeholder file
     
    11201122            'An email with your user name and password has been sent'
    11211123            in self.browser.contents)
     1124
     1125class ApplicantsExportTests(ApplicantsFullSetup, FunctionalAsyncTestCase):
     1126    # Tests for StudentsContainer class views and pages
     1127
     1128    layer = FunctionalLayer
     1129
     1130    def wait_for_export_job_completed(self):
     1131        # helper function waiting until the current export job is completed
     1132        manager = getUtility(IJobManager)
     1133        job_id = self.app['datacenter'].running_exports[0][0]
     1134        job = manager.get(job_id)
     1135        wait_for_result(job)
     1136        return job_id
     1137
     1138    def test_applicants_in_container_export(self):
     1139        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     1140        container_path = 'http://localhost/app/applicants/app2011'
     1141        self.browser.open(container_path)
     1142        self.browser.getLink("Export applicants").click()
     1143        self.browser.getControl("Start new export").click()
     1144
     1145        # When the job is finished and we reload the page...
     1146        job_id = self.wait_for_export_job_completed()
     1147        self.browser.open(container_path + '/exports')
     1148        # ... the csv file can be downloaded ...
     1149        self.browser.getLink("Download").click()
     1150        self.assertEqual(self.browser.headers['content-type'],
     1151            'text/csv; charset=UTF-8')
     1152        self.assertTrue(
     1153            'filename="WAeUP.Kofa_applicants_%s.csv' % job_id in
     1154            self.browser.headers['content-disposition'])
     1155        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
     1156        job_id = self.app['datacenter'].running_exports[0][0]
     1157        # ... and discarded
     1158        self.browser.open(container_path + '/exports')
     1159        self.browser.getControl("Discard").click()
     1160        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
     1161        # Creation, downloading and discarding is logged
     1162        logfile = os.path.join(
     1163            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     1164        logcontent = open(logfile).read()
     1165        self.assertTrue(
     1166            'zope.mgr - applicants.browser.ExportJobContainerJobStart - '
     1167            'exported: applicants (app2011), job_id=%s'
     1168            % job_id in logcontent
     1169            )
     1170        self.assertTrue(
     1171            'zope.mgr - applicants.browser.ExportJobContainerDownload '
     1172            '- downloaded: WAeUP.Kofa_applicants_%s.csv, job_id=%s'
     1173            % (job_id, job_id) in logcontent
     1174            )
     1175        self.assertTrue(
     1176            'zope.mgr - applicants.browser.ExportJobContainerOverview '
     1177            '- discarded: job_id=%s' % job_id in logcontent
     1178            )
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/viewlets.py

    r10644 r10655  
    138138    target = 'manage'
    139139
     140class ExportApplicantsActionButton(ManageActionButton):
     141    """ 'Export applicants' button for faculties.
     142    """
     143    grok.context(IApplicantsContainer)
     144    grok.view(ApplicantsContainerPage)
     145    grok.require('waeup.manageApplication')
     146    icon = 'actionicon_down.png'
     147    text = _('Export applicants')
     148    target = 'exports'
     149    grok.order(4)
     150
    140151class ApplicantsRootCreateStudentsActionButton(ManageActionButton):
    141152    grok.order(3)
  • main/waeup.kofa/trunk/src/waeup/kofa/browser/breadcrumbs.py

    r10650 r10655  
    169169
    170170class ExportsBreadcrumb(Breadcrumb):
    171     """A breadcrumb for reports.
     171    """A breadcrumb for exports.
    172172    """
    173173    grok.context(IExportJobContainer)
Note: See TracChangeset for help on using the changeset viewer.