Changeset 12094


Ignore:
Timestamp:
30 Nov 2014, 08:12:27 (10 years ago)
Author:
Henrik Bettermann
Message:

Add applications_catalog. We need this catalog for imports.

Add catalog tests.

Add attribute last_product_id. This ensures that the last product can be identified even if the product assigned to the application has been removed.

Location:
main/waeup.ikoba/trunk/src/waeup/ikoba/customers
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/applications.py

    r12092 r12094  
    7272        except AttributeError:
    7373            self.application_id = u'a123'
     74        self.last_product_id = None
    7475        return
    7576
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/batching.py

    r12089 r12094  
    4343from waeup.ikoba.customers.interfaces import (
    4444    ICustomer, ICustomerUpdateByRegNo,
    45     ICustomerDocument)
     45    ICustomerDocument, IApplication)
    4646from waeup.ikoba.customers.workflow import  (
    4747    IMPORTABLE_REGISTRATION_STATES, IMPORTABLE_REGISTRATION_TRANSITIONS,
     
    461461                errs.append(('document_id','invalid format'))
    462462        return errs, inv_errs, conv_dict
     463
     464
     465class ApplicationProcessor(CustomerProcessorBase):
     466    """A batch processor for IApplication objects.
     467    """
     468    grok.implements(IBatchProcessor)
     469    grok.provides(IBatchProcessor)
     470    grok.context(Interface)
     471    util_name = 'applicationprocessor'
     472    grok.name(util_name)
     473
     474    name = _('Application Processor')
     475    iface = IApplication
     476    factory_name = 'waeup.SampleApplication'
     477
     478    location_fields = []
     479    additional_fields = ['application_id', 'class_name']
     480    additional_headers = ['class_name']
     481
     482    def checkHeaders(self, headerfields, mode='ignore'):
     483        super(ApplicationProcessor, self).checkHeaders(headerfields)
     484        if mode in ('update', 'remove') and not 'application_id' in headerfields:
     485            raise FatalCSVError(
     486                "Need application_id for import in update and remove modes!")
     487        return True
     488
     489    def getParent(self, row, site):
     490        customer = self._getCustomer(row, site)
     491        if customer is None:
     492            return None
     493        return customer['applications']
     494
     495    def getEntry(self, row, site):
     496        applications = self.getParent(row, site)
     497        if applications is None:
     498            return None
     499        application_id = row.get('application_id', None)
     500        if application_id is None:
     501            return None
     502        entry = applications.get(application_id)
     503        return entry
     504
     505    def updateEntry(self, obj, row, site, filename):
     506        """Update obj to the values given in row.
     507        """
     508        items_changed = super(ApplicationProcessor, self).updateEntry(
     509            obj, row, site, filename)
     510        customer = self.getParent(row, site).__parent__
     511        customer.__parent__.logger.info(
     512            '%s - %s - %s - updated: %s'
     513            % (self.name, filename, customer.customer_id, items_changed))
     514        return
     515
     516    def addEntry(self, obj, row, site):
     517        parent = self.getParent(row, site)
     518        application_id = row['application_id'].strip('#')
     519        parent[application_id] = obj
     520        return
     521
     522    def delEntry(self, row, site):
     523        application = self.getEntry(row, site)
     524        parent = self.getParent(row, site)
     525        if application is not None:
     526            customer = self._getCustomer(row, site)
     527            customer.__parent__.logger.info('%s - Application removed: %s'
     528                % (customer.customer_id, application.application_id))
     529            del parent[application.application_id]
     530        return
     531
     532    def checkConversion(self, row, mode='ignore'):
     533        """Validates all values in row.
     534        """
     535        errs, inv_errs, conv_dict = super(
     536            ApplicationProcessor, self).checkConversion(row, mode=mode)
     537        # We need to check if the class_name corresponds with the
     538        # processor chosen. This is to avoid accidentally wrong imports.
     539        if mode != 'remove':
     540            class_name = row.get('class_name', None)
     541            if class_name != self.factory_name.strip('waeup.'):
     542                errs.append(('class_name','wrong processor'))
     543        # We have to check application_id.
     544        application_id = row.get('application_id', None)
     545        if mode == 'create':
     546            if not application_id:
     547                application_id = generate_application_id()
     548                conv_dict['application_id'] = application_id
     549                return errs, inv_errs, conv_dict
     550            cat = queryUtility(ICatalog, name='applications_catalog')
     551            results = list(
     552                cat.searchResults(application_id=(application_id, application_id)))
     553            if results:
     554                # application_id must not exist.
     555                errs.append(('application_id','id exists'))
     556        else:
     557            if not application_id.startswith('a'):
     558                errs.append(('application_id','invalid format'))
     559        return errs, inv_errs, conv_dict
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py

    r12091 r12094  
    6767    if changed_fields:
    6868        changed_fields = reduce(lambda x,y: x+y, changed_fields.values())
     69    if 'product' in changed_fields:
     70        view.context.last_product_id = data['product'].product_id
    6971    fields_string = ' + '.join(changed_fields)
    7072    view.flash(_('Form has been saved.'))
     
    11501152    pnav = 4
    11511153
    1152     #@property
    1153     #def label(self):
    1154     #    return _('${a}: Application ${b}', mapping = {
    1155     #        'a':self.context.customer.display_fullname,
    1156     #        'b':self.context.application_id})
    1157 
    11581154    @property
    11591155    def label(self):
     
    11721168    deletion_warning = _('Are you sure?')
    11731169
    1174     #@property
    1175     #def label(self):
    1176     #    return _('${a}: Application ${b}', mapping = {
    1177     #        'a':self.context.customer.display_fullname,
    1178     #        'b':self.context.application_id})
    1179 
    11801170    @property
    11811171    def label(self):
     
    12051195        return
    12061196
    1207     @action(_('Final Submit'), warning=WARNING)
     1197    @action(_('Apply now (final submit)'), warning=WARNING)
    12081198    def finalsubmit(self, **data):
    12091199        msave(self, **data)
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/catalog.py

    r12006 r12094  
    2727from waeup.ikoba.interfaces import (
    2828    ICompany, IQueryResultItem)
    29 from waeup.ikoba.customers.interfaces import ICustomer
     29from waeup.ikoba.customers.interfaces import ICustomer, IApplication
    3030
    3131
     
    117117    cat_name = 'customers_catalog'
    118118    defaults = dict(customer_id=None)  # make sure we get all studs by default
     119
     120
     121# Catalog for customer applications
     122
     123class ApplicationIndexes(grok.Indexes):
     124    """A catalog for all applications.
     125    """
     126    grok.site(ICompany)
     127    grok.name('applications_catalog')
     128    grok.context(IApplication)
     129
     130    application_id = grok.index.Field(attribute='application_id')
     131    last_product_id = grok.index.Field(attribute='last_product_id')
     132    application_category = grok.index.Field(attribute='application_category')
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py

    r12092 r12094  
    273273        'Last transition formatted date string')
    274274    application_category = Attribute('Category for the grouping of products')
     275    last_product_id = Attribute(
     276        'Id of product recently stored with the application')
    275277
    276278    title = schema.TextLine(
     
    288290        title = _(u'Product'),
    289291        source = AppCatProductSource(),
    290         required = False,
    291         )
     292        required = True,
     293        )
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py

    r12093 r12094  
    10731073        self.browser.getLink("a102").click()
    10741074        self.browser.getLink("Manage").click()
     1075        self.browser.getControl(name="form.product").value = ['SAM']
    10751076        self.browser.getControl(name="form.title").value = 'My second app'
    10761077        self.browser.getControl("Save").click()
     
    11441145        # ... but NOTSAM not.
    11451146        self.assertFalse('<option value="LIC">' in self.browser.contents)
     1147        # So far last_product_id is None.
     1148        self.assertTrue(self.customer['applications']['a102'].last_product_id is None)
    11461149        self.browser.getControl(name="form.product").value = ['SAM']
    11471150        self.browser.getControl("Save").click()
     1151        # After saving the form, last_product_id is set.
     1152        self.assertEqual(self.customer['applications']['a102'].last_product_id, 'SAM')
     1153        self.assertTrue('Form has been saved.' in self.browser.contents)
     1154        # Saving the form again does not unset last_product_id
    11481155        self.assertEqual(application.title, 'My second app')
     1156        self.browser.getControl("Save").click()
     1157        self.assertEqual(self.customer['applications']['a102'].last_product_id, 'SAM')
    11491158        self.assertTrue('Form has been saved.' in self.browser.contents)
    11501159        self.browser.getLink("View").click()
     
    11531162        self.browser.getLink("Edit").click()
    11541163        self.browser.getControl(name="form.title").value = 'My third app'
    1155         self.browser.getControl("Final Submit").click()
     1164        self.browser.getControl("Apply now").click()
    11561165        self.assertEqual(application.title, 'My third app')
    11571166        self.assertEqual(application.state, 'submitted')
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_catalog.py

    r11997 r12094  
    1 ## $Id: test_catalog.py 10552 2013-08-28 14:33:33Z henrik $
     1## $Id$
    22##
    33## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
     
    2626from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
    2727from waeup.ikoba.customers.customer import Customer
     28from waeup.ikoba.customers.applications import SampleApplication
     29
    2830
    2931class CatalogTestSetup(FunctionalTestCase):
     
    5456        self.customer_id = customer.customer_id
    5557        self.customer = self.app['customers'][self.customer_id]
    56         # Update the customers_catalog
    57         notify(grok.ObjectModifiedEvent(self.customer))
     58
     59        product = createObject('waeup.Product')
     60        product.product_id = u'SAM'
     61        product.title = u'Our Samle Product'
     62        product.application_category = u'sample'
     63        self.app['products'].addProduct(product)
     64        self.product_id = product.product_id
     65        self.product = self.app['products'][self.product_id]
     66
     67        application = createObject('waeup.SampleApplication')
     68        application.title = u'My Samle Application'
     69        application.product = product
     70        application.last_product_id = product.product_id
     71        self.customer['applications'].addApplication(application)
     72        self.application_id = application.application_id
     73        self.application = self.customer['applications'][self.application_id]
     74
     75        document = createObject('waeup.CustomerSampleDocument')
     76        document.title = u'My Samle Document'
     77        self.customer['documents'].addDocument(document)
     78        self.document_id = document.document_id
     79        self.document = self.customer['documents'][self.document_id]
     80
    5881        return
    5982
     
    6386        return
    6487
    65 class CustomerCatalogTests(CatalogTestSetup):
     88
     89class CustomersCatalogTests(CatalogTestSetup):
    6690
    6791    layer = FunctionalLayer
     
    88112        assert len(results) == 1
    89113        assert results[0] is self.app['customers'][self.customer_id]
     114
     115
     116class DocumentsCatalogTests(CatalogTestSetup):
     117
     118    layer = FunctionalLayer
     119
     120    def test_get_catalog(self):
     121        # We can get an customers catalog if we wish
     122        cat = queryUtility(ICatalog, name='documents_catalog')
     123        assert cat is not None
     124
     125    def test_search_by_id(self):
     126        # We can find a certain application id
     127        cat = queryUtility(ICatalog, name='documents_catalog')
     128        results = cat.searchResults(document_id=(self.document_id,
     129                                                self.document_id))
     130        results = [x for x in results] # Turn results generator into list
     131        assert len(results) == 1
     132        assert results[0] is self.customer['documents'][self.document_id]
     133
     134
     135class ApplicationsCatalogTests(CatalogTestSetup):
     136
     137    layer = FunctionalLayer
     138
     139    def test_get_catalog(self):
     140        # We can get an customers catalog if we wish
     141        cat = queryUtility(ICatalog, name='applications_catalog')
     142        assert cat is not None
     143
     144    def test_search_by_id(self):
     145        # We can find a certain application id
     146        cat = queryUtility(ICatalog, name='applications_catalog')
     147        results = cat.searchResults(application_id=(self.application_id,
     148                                                self.application_id))
     149        results = [x for x in results] # Turn results generator into list
     150        assert len(results) == 1
     151        assert results[0] is self.customer['applications'][self.application_id]
     152
     153    def test_search_by_category(self):
     154        # We can find a certain name
     155        cat = queryUtility(ICatalog, name='applications_catalog')
     156        results = cat.searchResults(application_category=('sample', 'sample'))
     157        results = [x for x in results] # Turn results generator into list
     158        assert len(results) == 1
     159        assert results[0] is self.customer['applications'][self.application_id]
     160
     161    def test_search_by_last_product_id(self):
     162        # We can find a certain name
     163        cat = queryUtility(ICatalog, name='applications_catalog')
     164        results = cat.searchResults(last_product_id=('SAM', 'SAM'))
     165        results = [x for x in results] # Turn results generator into list
     166        assert len(results) == 1
     167        assert results[0] is self.customer['applications'][self.application_id]
     168        assert results[0].product is self.product
Note: See TracChangeset for help on using the changeset viewer.