Index: /main/waeup.ikoba/trunk/CHANGES.txt
===================================================================
--- /main/waeup.ikoba/trunk/CHANGES.txt	(revision 13803)
+++ /main/waeup.ikoba/trunk/CHANGES.txt	(revision 13804)
@@ -4,4 +4,7 @@
 0.2.dev0 (unreleased)
 =====================
+
+* Rearrange datacenter upload page. Provide modal windows to view all
+  processors and sources and vocabularies.
 
 * Enable temporary suspension of officer accounts. Plugins must be
Index: /main/waeup.ikoba/trunk/layout/theme.html
===================================================================
--- /main/waeup.ikoba/trunk/layout/theme.html	(revision 13803)
+++ /main/waeup.ikoba/trunk/layout/theme.html	(revision 13804)
@@ -328,4 +328,30 @@
             </div>
             <div>...content that spans the whole page.</div>
+            <br><br>
+
+            <h3>Accordions</h3>
+            <div class="panel-group" id="accordion" role="tablist"
+                 aria-multiselectable="true">
+              <div class="panel panel-default">
+                <div class="panel-heading" role="tab" id="headingTwo">
+                  <h4 class="panel-title">
+                    <a class="collapsed" data-toggle="collapse"
+                       data-parent="#accordion" href="#collapseTwo"
+                       aria-expanded="false" aria-controls="collapseTwo">
+                      Collapsible Group
+                    </a>
+                  </h4>
+                </div>
+                <div id="collapseTwo" class="panel-collapse collapse"
+                     role="tabpanel" aria-labelledby="headingTwo">
+                  <div class="panel-body">
+                    Anim pariatur cliche reprehenderit, enim eiusmod high life
+                    terry richardson ad squid. 3 wolf moon officia aute, non
+                    skateboard dolor brunch. Food truck quinoa laborum eiusmod.
+                  </div>
+                </div>
+              </div>
+            </div>
+
             <br><br>
             <h3>A Sample Data Table</h3>
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py	(revision 13803)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py	(revision 13804)
@@ -55,13 +55,16 @@
     ILocalRolesAssignable, DuplicationError, IConfigurationContainer,
     IJobManager,
-    IPasswordValidator, IContactForm, IIkobaUtils, ICSVExporter)
+    IPasswordValidator, IContactForm, IIkobaUtils, ICSVExporter,
+    CurrencySource)
 from waeup.ikoba.permissions import (
     get_users_with_local_roles, get_all_roles, get_all_users,
     get_users_with_role)
-
+from waeup.ikoba.customers.vocabularies import GenderSource
 from waeup.ikoba.authentication import LocalRoleSetEvent
 from waeup.ikoba.utils.helpers import get_user_account, check_csv_charset
 from waeup.ikoba.mandates.mandate import PasswordMandate
 from waeup.ikoba.datacenter import DataCenterFile
+from waeup.ikoba.customers.utils import ICustomersUtils
+from waeup.ikoba.documents.utils import IDocumentsUtils
 
 FORBIDDEN_CHARACTERS = (160,)
@@ -245,4 +248,30 @@
             return True
     return False
+
+def getImporters(context):
+    importers = getAllUtilitiesRegisteredFor(IBatchProcessor)
+    importer_props = []
+    for x in importers:
+        # Skip User Processor if user isn't allowed to manage users.
+        if x.util_name == 'userprocessor' and not checkPermission(
+            'waeup.manageUsers', context):
+            continue
+        iface_fields = schema.getFields(x.iface)
+        available_fields = []
+        for key in iface_fields.keys():
+            iface_fields[key] = (iface_fields[key].__class__.__name__,
+                iface_fields[key].required)
+        for value in x.available_fields:
+            available_fields.append(
+                dict(f_name=value,
+                     f_type=iface_fields.get(value, (None, False))[0],
+                     f_required=iface_fields.get(value, (None, False))[1]
+                     )
+                )
+        available_fields = sorted(available_fields, key=lambda k: k[
+            'f_name'])
+        importer_props.append(
+            dict(title=x.name, name=x.util_name, fields=available_fields))
+    return sorted(importer_props, key=lambda k: k['title'])
 
 class LocalRoleAssignmentUtilityView(object):
@@ -496,4 +525,128 @@
             return html
 
+class SourcesOverview(grok.View):
+    grok.context(ICompany)
+    grok.name('sourcesoverview')
+    grok.require('waeup.Public')
+
+    def _set_con_cats(self):
+        con_cats = getUtility(IIkobaUtils).CON_CATS_DICT
+        self.con_cats = con_cats.items()
+        return
+
+    def _set_payment_categories(self):
+        payment_categories = getUtility(IIkobaUtils).PAYMENT_CATEGORIES
+        self.payment_categories = payment_categories.items()
+        return
+
+    def _set_customer_doctypes(self):
+        customer_doctypes = getUtility(ICustomersUtils).DOCTYPES_DICT
+        self.customer_doctypes = customer_doctypes.items()
+        return
+
+    def _set_contypes(self):
+        contypes = getUtility(ICustomersUtils).CONTYPES_DICT
+        self.contypes = contypes.items()
+        return
+
+    def _set_doctypes(self):
+        doctypes = getUtility(IDocumentsUtils).DOCTYPES_DICT
+        self.doctypes = doctypes.items()
+        return
+
+    def _set_customer_states(self):
+        customer_states = getUtility(ICustomersUtils).TRANSLATED_CUSTOMER_STATES
+        self.customer_states = customer_states.items()
+        return
+
+    def _set_contract_states(self):
+        contract_states = getUtility(ICustomersUtils).TRANSLATED_CONTRACT_STATES
+        self.contract_states = contract_states.items()
+        return
+
+    def _set_customer_document_states(self):
+        customer_document_states = getUtility(
+            ICustomersUtils).TRANSLATED_DOCUMENT_STATES
+        self.customer_document_states = customer_document_states.items()
+        return
+
+    def _set_document_states(self):
+        document_states = getUtility(
+            IDocumentsUtils).TRANSLATED_DOCUMENT_STATES
+        self.document_states = document_states.items()
+        return
+
+    def _set_currencies(self):
+        currenciessource = CurrencySource().factory
+        self.currencies = []
+        for code in currenciessource.getValues():
+            title = currenciessource.getTitle(code)
+            self.currencies.append((code, title))
+        return
+
+    def _set_sex(self):
+        gendersource = GenderSource().factory
+        self.sex = []
+        for sex in gendersource.getValues():
+            title = gendersource.getTitle(sex)
+            self.sex.append((sex, title))
+        return
+
+    def update(self):
+        self._set_con_cats()
+        self._set_payment_categories()
+        self._set_customer_doctypes()
+        self._set_contypes()
+        self._set_doctypes()
+        self._set_currencies()
+        self._set_sex()
+        self._set_customer_states()
+        self._set_contract_states()
+        self._set_customer_document_states()
+        self._set_document_states()
+
+class SourcesOverviewPage(IkobaPage, SourcesOverview):
+    grok.name('sources')
+    grok.require('waeup.Public')
+    label = _(u'Sources & Vocabularies')
+    pnav = 0
+
+class ProcessorsOverview(grok.View):
+    grok.context(ICompany)
+    grok.name('processorsoverview')
+    grok.require('waeup.Public')
+
+    def getImporters(self):
+        return getImporters(self.context)
+
+class ProcessorsOverviewPage(IkobaPage, ProcessorsOverview):
+    grok.name('processors')
+    grok.require('waeup.Public')
+    label = _(u'Available Processors (Importers)')
+    pnav = 0
+
+class SkeletonDownloadView(UtilityView, grok.View):
+    grok.context(ICompany)
+    grok.name('skeleton')
+    grok.require('waeup.Public')
+
+    def update(self, processorname=None):
+        self.processorname = self.request.form['name']
+        self.filename = ('%s_000.csv' %
+            self.processorname.replace('processor','import'))
+        return
+
+    def render(self):
+        #ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
+        #self.context.logger.info(
+        #    '%s - skeleton downloaded: %s' % (ob_class, self.filename))
+        self.response.setHeader(
+            'Content-Type', 'text/csv; charset=UTF-8')
+        self.response.setHeader(
+            'Content-Disposition:', 'attachment; filename="%s' % self.filename)
+        processor = getUtility(IBatchProcessor, name=self.processorname)
+        csv_data = processor.get_csv_skeleton()
+        return csv_data
+
 class AdministrationPage(IkobaPage):
     """ The administration overview page.
@@ -997,30 +1150,5 @@
 
     def getImporters(self):
-        importers = getAllUtilitiesRegisteredFor(IBatchProcessor)
-        ikoba_utils = getUtility(IIkobaUtils)
-        importer_props = []
-        for x in importers:
-            if not x.util_name in ikoba_utils.BATCH_PROCESSOR_NAMES:
-                continue
-            # Skip User Processor if user isn't allowed to manage users.
-            if x.util_name == 'userprocessor' and not checkPermission(
-                'waeup.manageUsers', self.context):
-                continue
-            iface_fields = schema.getFields(x.iface)
-            available_fields = []
-            for key in iface_fields.keys():
-                iface_fields[key] = (iface_fields[key].__class__.__name__,
-                    iface_fields[key].required)
-            for value in x.available_fields:
-                available_fields.append(
-                    dict(f_name=value,
-                         f_type=iface_fields.get(value, (None, False))[0],
-                         f_required=iface_fields.get(value, (None, False))[1]
-                         )
-                    )
-            available_fields = sorted(available_fields, key=lambda k: k['f_name'])
-            importer_props.append(
-                dict(title=x.name, name=x.util_name, fields=available_fields))
-        return sorted(importer_props, key=lambda k: k['title'])
+        return getImporters(self.context)
 
 class FileDownloadView(UtilityView, grok.View):
@@ -1044,27 +1172,4 @@
         fullpath = os.path.join(self.context.storage, self.filename)
         return open(fullpath, 'rb').read()
-
-class SkeletonDownloadView(UtilityView, grok.View):
-    grok.context(IDataCenter)
-    grok.name('skeleton')
-    grok.require('waeup.manageDataCenter')
-
-    def update(self, processorname=None):
-        self.processorname = self.request.form['name']
-        self.filename = ('%s_000.csv' %
-            self.processorname.replace('processor','import'))
-        return
-
-    def render(self):
-        #ob_class = self.__implemented__.__name__.replace('waeup.ikoba.','')
-        #self.context.logger.info(
-        #    '%s - skeleton downloaded: %s' % (ob_class, self.filename))
-        self.response.setHeader(
-            'Content-Type', 'text/csv; charset=UTF-8')
-        self.response.setHeader(
-            'Content-Disposition:', 'attachment; filename="%s' % self.filename)
-        processor = getUtility(IBatchProcessor, name=self.processorname)
-        csv_data = processor.get_csv_skeleton()
-        return csv_data
 
 class DatacenterImportStep1(IkobaPage):
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/datacenteruploadpage.pt
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/datacenteruploadpage.pt	(revision 13803)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/datacenteruploadpage.pt	(revision 13804)
@@ -1,11 +1,38 @@
-<p i18n:translate="">
-    Before uploading a file check that your file header corresponds
-    with header format of the selected processor. All available headers
-    are listed below.
-    After file upload click the 'Process data' button and proceed up to
-    import step 3. Verify that the data format
-    meets all the import criteria and requirements of the processor.
-</p>
-
+<span i18n:translate="">
+    Before uploading a file, check that your file header corresponds
+    with the header format of the selected processor:
+</span>
+<!-- Processors Modal -->
+<button i18n:translate="" class="btn btn-info btn-xs"
+   data-toggle="modal" data-target="#ProcessorsModal"
+   href="../processorsoverview">
+   View available processors (importers)
+</button>
+<div class="modal fade" id="ProcessorsModal" tabindex="-1"
+     role="dialog" aria-labelledby="ProcessorsModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+    </div>
+  </div>
+</div>
+<br /><br />
+<span i18n:translate="">
+    Many importer fields are of type 'Choice' which means only definied keywords
+    are allowed:
+</span>
+<!-- Sources Modal -->
+<button i18n:translate="" class="btn btn-info btn-xs"
+   data-toggle="modal" data-target="#SourcesModal"
+   href="../sourcesoverview">
+   View choices
+</button>
+<div class="modal fade" id="SourcesModal" tabindex="-1"
+     role="dialog" aria-labelledby="SourcesModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+    </div>
+  </div>
+</div>
+<br />
 <form method="post" enctype="multipart/form-data">
 <br />
@@ -16,12 +43,12 @@
       </td>
       <td>
-    		<div class="input-group half">
-    			<div class="input-group-btn">
-    				<div class="btn btn-default btn-file">
+        <div class="input-group half">
+          <div class="input-group-btn">
+            <div class="btn btn-default btn-file">
               Select&hellip;
               <input type="file" name="uploadfile:file" />
             </div>
-    			</div>
-    			<input type="text" class="form-control" readonly>
+          </div>
+          <input type="text" class="form-control" readonly>
         </div>
       </td>
@@ -59,63 +86,15 @@
       tal:attributes="value view/cancel_button"/>
 </form>
-<br />
-<p i18n:translate="">
-    Import managers will be automatically informed by email after file upload.
-    There is no need for assigning tickets or sending emails anymore.
-    The data will be imported according to the information given.
-</p>
+
 
 <br /><br />
 
-<h2 i18n:translate="">Available Processors (Importers)</h2>
-
-<table i18n:domain="waeup.ikoba" class="table table-condensed">
-  <thead>
-    <tr>
-      <th i18n:translate="">Processor</th>
-      <th i18n:translate="">Required Schema Fields</th>
-      <th i18n:translate="">Optional Schema Fields</th>
-      <th i18n:translate="">Non-Schema Fields</th>
-    </tr>
-  </thead>
-  <tr tal:repeat="importer view/getImporters">
-    <td>
-      <span tal:content="importer/title">TITLE</span><br /><br />
-      <a i18n:translate="" class="btn btn-primary btn-xs"
-         tal:attributes="href python: 'skeleton?name=' + importer['name']">
-         Download CSV Skeleton File
-      </a>
-    </td>
-    <td nowrap>
-      <span tal:repeat="field importer/fields">
-          <tal:schemafield condition="field/f_type">
-            <tal:required condition="field/f_required">
-              <span tal:replace="field/f_name"></span>
-              (<span tal:replace="field/f_type"></span>)
-              <br />
-            </tal:required>
-          </tal:schemafield>
-      </span>
-    </td>
-    <td nowrap>
-      <span tal:repeat="field importer/fields">
-          <tal:schemafield condition="field/f_type">
-            <tal:notrequired condition="not:field/f_required">
-              <span tal:replace="field/f_name"></span>
-              (<span tal:replace="field/f_type"></span>)
-              <br />
-            </tal:notrequired>
-          </tal:schemafield>
-      </span>
-    </td>
-    <td>
-      <span tal:repeat="field importer/fields">
-          <tal:extrafield condition="not:field/f_type">
-            <span tal:replace="field/f_name"></span>
-            <br />
-          </tal:extrafield>
-      </span>
-    </td>
-
-  </tr>
-</table>
+<div i18n:translate="">
+    After file upload click the 'Process data' button and proceed up to
+    import step 3. Verify that the data format
+    meets all the import criteria and requirements of the processor.
+</div>
+<br />
+<div i18n:translate="">
+    Import managers will be automatically informed by email after file upload.
+</div>
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/processorsoverview.pt
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/processorsoverview.pt	(revision 13804)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/processorsoverview.pt	(revision 13804)
@@ -0,0 +1,89 @@
+<div class="modal-body">
+  <div class="panel-group"
+       id="accordion"
+       role="tablist"
+       aria-multiselectable="true"
+       i18n:domain="waeup.kofa"
+       >
+    <div class="panel panel-default"  tal:repeat="importer view/getImporters">
+      <div class="panel-heading" role="tab"
+           tal:attributes="id python: 'heading' + importer['name']">
+        <h4 class="panel-title">
+          <a class="collapsed" data-toggle="collapse"
+             data-parent="#accordion"
+             tal:attributes="href python: '#collapse' + importer['name'];
+                             aria-controls python: 'collapse' + importer['name']"
+             aria-expanded="false">
+            <span tal:replace="importer/title">TITLE</span>
+          </a>
+        </h4>
+      </div>
+      <div tal:attributes="id python: 'collapse' + importer['name'];
+                           aria-labelledby python: 'heading' + importer['name']"
+           class="panel-collapse collapse"
+           role="tabpanel">
+        <div class="panel-body">
+          <table class="table table-condensed">
+            <thead>
+              <tr>
+                <th i18n:translate="">Processor</th>
+                <th i18n:translate="">Required Schema Fields</th>
+                <th i18n:translate="">Optional Schema Fields</th>
+                <th i18n:translate="">Non-Schema Fields</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr>
+                <td>
+                  <span tal:content="importer/title">TITLE</span><br /><br />
+                  <a i18n:translate="" class="btn btn-primary btn-xs"
+                     tal:attributes="href python: view.url(context)
+                                          + '/skeleton?name='
+                                          + importer['name']">
+                     Download CSV File Template
+                  </a>
+                </td>
+                <td nowrap>
+                  <span tal:repeat="field importer/fields">
+                      <tal:schemafield condition="field/f_type">
+                        <tal:required condition="field/f_required">
+                          <span tal:replace="field/f_name"></span>
+                          (<span tal:replace="field/f_type"></span>)
+                          <br />
+                        </tal:required>
+                      </tal:schemafield>
+                  </span>
+                </td>
+                <td nowrap>
+                  <span tal:repeat="field importer/fields">
+                      <tal:schemafield condition="field/f_type">
+                        <tal:notrequired condition="not:field/f_required">
+                          <span tal:replace="field/f_name"></span>
+                          (<span tal:replace="field/f_type"></span>)
+                          <br />
+                        </tal:notrequired>
+                      </tal:schemafield>
+                  </span>
+                </td>
+                <td>
+                  <span tal:repeat="field importer/fields">
+                      <tal:extrafield condition="not:field/f_type">
+                        <span tal:replace="field/f_name"></span>
+                        <br />
+                      </tal:extrafield>
+                  </span>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+      </div>
+    </div>
+  </div>
+  <br />
+  <button type="button" class="btn btn-default" style="float: right"
+          i18n:translate="" data-dismiss="modal"
+          tal:condition="python: view.__name__ == 'processorsoverview'">
+      Close
+  </button>
+</div>
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/source.pt
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/source.pt	(revision 13804)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/source.pt	(revision 13804)
@@ -0,0 +1,35 @@
+<div class="panel panel-default">
+  <div class="panel-heading" role="tab"
+       tal:attributes="id viewlet/heading">
+    <h4 class="panel-title">
+      <a class="collapsed" data-toggle="collapse"
+         tal:attributes="data-parent viewlet/accordion;
+                         href viewlet/hash_collapse;
+                         aria-controls viewlet/collapse"
+         aria-expanded="false">
+        <span tal:replace="viewlet/title">TITLE</span>
+      </a>
+    </h4>
+  </div>
+  <div tal:attributes="id viewlet/collapse;
+                       aria-labelledby viewlet/heading"
+       class="panel-collapse collapse"
+       role="tabpanel">
+    <div class="panel-body">
+      <table class="table">
+        <thead>
+          <tr>
+            <th i18n:translate="">Value</th>
+            <th i18n:translate="">Title</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr tal:repeat="item viewlet/source">
+            <td tal:content="python: item[0]">NAME</td>
+            <td tal:content="python: item[1]">TITLE</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </div>
+</div>
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/sourcesoverview.pt
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/sourcesoverview.pt	(revision 13804)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/sourcesoverview.pt	(revision 13804)
@@ -0,0 +1,24 @@
+<div class="modal-body" i18n:domain="waeup.ikoba">
+  <table width="100%">
+    <tr>
+      <td valign="top">
+        <div class="panel-group" id="accordion-left" role="tablist"
+             aria-multiselectable="true">
+          <tal:sourcesleft tal:content="structure provider:sources_left" />
+        </div>
+      </td>
+      <td valign="top">
+        <div class="panel-group" id="accordion-right" role="tablist"
+             aria-multiselectable="true">
+          <tal:sourcesright tal:content="structure provider:sources_right" />
+        </div>
+      </td>
+    </tr>
+  </table>
+
+  <button type="button" class="btn btn-default" style="float: right"
+          i18n:translate="" data-dismiss="modal"
+          tal:condition="python: view.__name__ == 'sourcesoverview'">
+      Close
+  </button>
+</div>
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 13803)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/tests/test_browser.py	(revision 13804)
@@ -214,2 +214,20 @@
             'This account has been suspended.' in self.browser.contents)
         return
+
+    def test_sources_overview(self):
+        self.browser.open('http://localhost/app/sources')
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertTrue('id="headingCustomerStates"' in self.browser.contents)
+
+    def test_processors_overview(self):
+        self.browser.open('http://localhost/app/processors')
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.browser.getLink(url='skeleton?name=productprocessor').click()
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.headers['Content-Type'],
+                         'text/csv; charset=UTF-8')
+        self.assertEqual(self.browser.contents,
+            'contract_category,contract_title,description,'
+            'options,product_id,terms_and_conditions,title,'
+            'valid_from,valid_to\r\n')
+        return
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/viewlets.py
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/viewlets.py	(revision 13803)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/browser/viewlets.py	(revision 13804)
@@ -57,4 +57,10 @@
     grok.name('widgets')
 
+class SourcesLeft(grok.ViewletManager):
+    grok.name('sources_left')
+
+class SourcesRight(grok.ViewletManager):
+    grok.name('sources_right')
+
 
 #
@@ -601,2 +607,125 @@
         super(SubobjectLister, self).update()
         return
+
+class ConCatsSource(grok.Viewlet):
+    """Avalable contract categories for the sources overview page.
+    """
+    grok.order(1)
+    grok.viewletmanager(SourcesLeft)
+    grok.require('waeup.Public')
+    grok.template('source')
+    column = 'left'
+    name = 'ConCats'
+    source_name = 'con_cats'
+    title = _('Contract Categories')
+
+    def heading(self):
+        return 'heading%s' % self.name
+
+    def accordion(self):
+        return '#accordion-%s' % self.column
+
+    def collapse(self):
+        return 'collapse%s' % self.name
+
+    def hash_collapse(self):
+        return '#collapse%s' % self.name
+
+    def source(self):
+        return getattr(self.view, self.source_name)
+
+class PaymentCatsSource(ConCatsSource):
+    """Avalable payment categories for the sources overview page.
+    """
+    grok.order(2)
+    name = 'PaymentCats'
+    source_name = 'payment_categories'
+    title = _('Payment Categories')
+
+class PaymentCatsSource(ConCatsSource):
+    """Avalable payment categories for the sources overview page.
+    """
+    grok.order(2)
+    name = 'PaymentCats'
+    source_name = 'payment_categories'
+    title = _('Payment Categories')
+
+class CustomerDocTypesSource(ConCatsSource):
+    """Avalable customer document types for the sources overview page.
+    """
+    grok.order(3)
+    name = 'CustomerDocTypes'
+    source_name = 'customer_doctypes'
+    title = _('Customer Document Types')
+
+class ConTypesSource(ConCatsSource):
+    """Avalable contract types for the sources overview page.
+    """
+    grok.order(4)
+    name = 'ConTypes'
+    source_name = 'contypes'
+    title = _('Contract Types')
+
+class DocTypesSource(ConCatsSource):
+    """Avalable document types for the sources overview page.
+    """
+    grok.order(5)
+    name = 'DocTypes'
+    source_name = 'doctypes'
+    title = _('Document Types')
+
+class SexSource(ConCatsSource):
+    """Avalable sex values for the sources overview page.
+    """
+    grok.order(6)
+    name = 'Sex'
+    source_name = 'sex'
+    title = _('Sex')
+
+class CurrencySource(ConCatsSource):
+    """Avalable currencies for the sources overview page.
+    """
+    grok.order(7)
+    name = 'Currencies'
+    source_name = 'currencies'
+    title = _('Currencies')
+
+class CustomerStatesSource(ConCatsSource):
+    """Avalable customer sates for the sources overview page.
+    """
+    grok.order(1)
+    grok.viewletmanager(SourcesRight)
+    column = 'right'
+    name = 'CustomerStates'
+    source_name = 'customer_states'
+    title = _('Customer Registration States')
+
+class ContractStatesSource(ConCatsSource):
+    """Avalable contract sates for the sources overview page.
+    """
+    grok.order(2)
+    grok.viewletmanager(SourcesRight)
+    column = 'right'
+    name = 'ContractStates'
+    source_name = 'contract_states'
+    title = _('Contract Workflow States')
+
+class CustomerDocumentStatesSource(ConCatsSource):
+    """Avalable customer document sates for the sources overview page.
+    """
+    grok.order(3)
+    grok.viewletmanager(SourcesRight)
+    column = 'right'
+    name = 'CustomerDocumentStates'
+    source_name = 'customer_document_states'
+    title = _('Customer Document Workflow States')
+
+class DocumentsDocumentStatesSource(ConCatsSource):
+    """Avalable document sates for the sources overview page.
+    """
+    grok.order(4)
+    grok.viewletmanager(SourcesRight)
+    column = 'right'
+    name = 'DocumentStates'
+    source_name = 'document_states'
+    title = _('Document Workflow States')
