Changeset 11985 for main/waeup.ikoba/trunk/src
- Timestamp:
- 18 Nov 2014, 11:37:28 (10 years ago)
- Location:
- main/waeup.ikoba/trunk/src/waeup/ikoba/customers
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/__init__.py
r11956 r11985 2 2 """ 3 3 # Make this a package. 4 -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/authentication.py
r11958 r11985 1 1 ## $Id: authentication.py 10055 2013-04-04 15:12:43Z uli $ 2 ## 2 ## 3 3 ## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann 4 4 ## This program is free software; you can redistribute it and/or modify … … 6 6 ## the Free Software Foundation; either version 2 of the License, or 7 7 ## (at your option) any later version. 8 ## 8 ## 9 9 ## This program is distributed in the hope that it will be useful, 10 10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 11 11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 12 ## GNU General Public License for more details. 13 ## 13 ## 14 14 ## You should have received a copy of the GNU General Public License 15 15 ## along with this program; if not, write to the Free Software … … 35 35 from waeup.ikoba.customers.interfaces import ICustomer 36 36 37 37 38 class CustomerAccount(grok.Adapter): 38 39 """An adapter to turn customer objects into accounts on-the-fly. … … 126 127 return passwordmanager.checkPassword(self.context.password, password) 127 128 129 128 130 class CustomersAuthenticatorPlugin(grok.GlobalUtility): 129 131 grok.implements(IAuthenticatorPlugin) … … 188 190 return IUserAccount(customer) 189 191 192 190 193 class PasswordChangeCredentialsPlugin(grok.GlobalUtility, 191 194 SessionCredentialsPlugin): … … 279 282 # Return old credentials for this one request only 280 283 return old_credentials 284 281 285 282 286 class CustomersAuthenticatorSetup(grok.GlobalUtility): -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/batching.py
r11964 r11985 25 25 """ 26 26 import grok 27 import unicodecsv as csv # XXX: csv ops should move to dedicated module.27 import unicodecsv as csv # XXX: csv ops should move to dedicated module. 28 28 from time import time 29 29 from datetime import datetime … … 46 46 from waeup.ikoba.utils.batching import BatchProcessor 47 47 48 48 49 class CustomerProcessor(BatchProcessor): 49 50 """A batch processor for ICustomer objects. … … 66 67 fields = getFields(self.iface) 67 68 return sorted(list(set( 68 ['customer_id', 'reg_number',69 ['customer_id', 'reg_number', 69 70 'password', 'state', 'transition'] + fields.keys()))) 70 71 … … 96 97 97 98 def getLocator(self, row): 98 if row.get('customer_id', None) not in (None, IGNORE_MARKER):99 if row.get('customer_id', None) not in (None, IGNORE_MARKER): 99 100 return 'customer_id' 100 elif row.get('reg_number', None) not in (None, IGNORE_MARKER):101 elif row.get('reg_number', None) not in (None, IGNORE_MARKER): 101 102 return 'reg_number' 102 103 else: … … 192 193 value = row['state'] 193 194 IWorkflowState(obj).setState(value) 194 msg = _("State '${a}' set", mapping = {'a':value})195 msg = _("State '${a}' set", mapping={'a': value}) 195 196 history = IObjectHistory(obj) 196 197 history.addMessage(msg) … … 212 213 # Log actions... 213 214 parent = self.getParent(row, site) 214 if hasattr(obj, 'customer_id'):215 if hasattr(obj, 'customer_id'): 215 216 # Update mode: the customer exists and we can get the customer_id. 216 217 # Create mode: the record contains the customer_id … … 223 224 # is always set. 224 225 parent.logger.info( 225 '%s - %s - %s - imported: %s' 226 '%s - %s - %s - imported: %s' 226 227 % (self.name, filename, obj.customer_id, items_changed)) 227 228 return items_changed … … 250 251 iface = self.iface_byregnumber 251 252 converter = IObjectConverter(iface) 252 errs, inv_errs, conv_dict = 253 errs, inv_errs, conv_dict = converter.fromStringDict( 253 254 row, self.factory_name, mode=mode) 254 255 if 'transition' in row: 255 256 if row['transition'] not in IMPORTABLE_TRANSITIONS: 256 257 if row['transition'] not in (IGNORE_MARKER, ''): 257 errs.append(('transition', 'not allowed'))258 errs.append(('transition', 'not allowed')) 258 259 if 'state' in row: 259 260 if row['state'] not in IMPORTABLE_STATES: 260 261 if row['state'] not in (IGNORE_MARKER, ''): 261 errs.append(('state', 'not allowed'))262 errs.append(('state', 'not allowed')) 262 263 else: 263 264 # State is an attribute of Customer and must not … … 292 293 @property 293 294 def available_fields(self): 294 fields = ['customer_id', 'reg_number'] + self.additional_fields295 fields = ['customer_id', 'reg_number'] + self.additional_fields 295 296 return sorted(list(set(fields + getFields( 296 297 self.iface).keys()))) … … 342 343 """ 343 344 converter = IObjectConverter(self.iface) 344 errs, inv_errs, conv_dict = 345 errs, inv_errs, conv_dict = converter.fromStringDict( 345 346 row, self.factory_name, mode=mode) 346 347 return errs, inv_errs, conv_dict … … 361 362 result[raw_header[num]] = field 362 363 return result 363 364 -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py
r11979 r11985 51 51 grok.context(IIkobaObject) 52 52 53 53 54 class CustomersBreadcrumb(Breadcrumb): 54 55 """A breadcrumb for the customers container. … … 72 73 def title(self): 73 74 return self.context.display_fullname 75 74 76 75 77 class CustomersContainerPage(IkobaPage): … … 112 114 self.flash(_('No customer found.'), type="warning") 113 115 return 116 114 117 115 118 class CustomersContainerManagePage(IkobaPage): … … 168 171 if len(deleted): 169 172 self.flash(_('Successfully removed: ${a}', 170 mapping = {'a':', '.join(deleted)})) 171 return 173 mapping={'a': ','.join(deleted)})) 174 return 175 172 176 173 177 class CustomerAddFormPage(IkobaAddFormPage): … … 191 195 return 192 196 197 193 198 class LoginAsCustomerStep1(IkobaEditFormPage): 194 199 """ View to temporarily set a customer password. … … 202 207 def label(self): 203 208 return _(u'Set temporary password for ${a}', 204 mapping = {'a':self.context.display_fullname})209 mapping={'a': self.context.display_fullname}) 205 210 206 211 @action('Set password now', style='primary') … … 211 216 self.context.writeLogMessage( 212 217 self, 'temp_password generated: %s' % password) 213 args = {'password': password}218 args = {'password': password} 214 219 self.redirect(self.url(self.context) + 215 220 '/loginasstep2?%s' % urlencode(args)) 216 221 return 222 217 223 218 224 class LoginAsCustomerStep2(IkobaPage): … … 228 234 def label(self): 229 235 return _(u'Login as ${a}', 230 mapping = {'a':self.context.customer_id})236 mapping={'a': self.context.customer_id}) 231 237 232 238 def update(self, SUBMIT=None, password=None): … … 237 243 return 238 244 245 239 246 class CustomerBaseDisplayFormPage(IkobaDisplayFormPage): 240 247 """ Page to display customer base data … … 252 259 if self.context.suspended: 253 260 return _('${a}: Base Data (account deactivated)', 254 mapping = {'a':self.context.display_fullname})261 mapping={'a': self.context.display_fullname}) 255 262 return _('${a}: Base Data', 256 mapping = {'a':self.context.display_fullname})263 mapping={'a': self.context.display_fullname}) 257 264 258 265 @property … … 262 269 return _('unset') 263 270 271 264 272 class ContactCustomerForm(ContactAdminForm): 265 273 grok.context(ICustomer) … … 277 285 def label(self): 278 286 return _(u'Send message to ${a}', 279 mapping = {'a':self.context.display_fullname})287 mapping={'a': self.context.display_fullname}) 280 288 281 289 @action('Send message now', style='primary') … … 289 297 ikoba_utils = getUtility(IIkobaUtils) 290 298 success = ikoba_utils.sendContactForm( 291 self.request.principal.title, email,292 self.context.display_fullname, self.context.email,299 self.request.principal.title, email, 300 self.context.display_fullname, self.context.email, 293 301 self.request.principal.id,usertype, 294 302 self.config.name, 295 data['body'], data['subject'])303 data['body'], data['subject']) 296 304 if success: 297 305 self.flash(_('Your message has been sent.')) … … 299 307 self.flash(_('An smtp server error occurred.'), type="danger") 300 308 return 309 301 310 302 311 class CustomerBaseManageFormPage(IkobaEditFormPage): … … 326 335 errors = validator.validate_password(password, password_ctl) 327 336 if errors: 328 self.flash( 337 self.flash(' '.join(errors), type="danger") 329 338 return 330 339 changed_fields = self.applyData(self.context, **data) … … 344 353 return 345 354 355 346 356 class CustomerTriggerTransitionFormPage(IkobaEditFormPage): 347 357 """ View to manage customer base data … … 375 385 return 376 386 387 377 388 class CustomerActivatePage(UtilityView, grok.View): 378 389 """ Activate customer account … … 394 405 return 395 406 407 396 408 class CustomerDeactivatePage(UtilityView, grok.View): 397 409 """ Deactivate customer account … … 413 425 return 414 426 427 415 428 class CustomerHistoryPage(IkobaPage): 416 429 """ Page to display customer history … … 424 437 @property 425 438 def label(self): 426 return _('${a}: History', mapping = {'a':self.context.display_fullname}) 439 return _('${a}: History', mapping={'a':self.context.display_fullname}) 440 427 441 428 442 class CustomerRequestPasswordPage(IkobaAddFormPage): … … 446 460 # Forward only email to landing page in base package. 447 461 self.redirect(self.url(self.context, 'requestpw_complete', 448 data =dict(email=email)))462 data=dict(email=email))) 449 463 return 450 464 … … 513 527 return 514 528 529 515 530 class CustomerRequestPasswordEmailSent(IkobaPage): 516 531 """Landing page after successful password request. … … 527 542 self.customer_id = customer_id 528 543 return 544 529 545 530 546 class CustomerFilesUploadPage(IkobaPage): … … 548 564 # Pages for customers only 549 565 566 550 567 class CustomerBaseEditFormPage(IkobaEditFormPage): 551 568 """ View to edit customer base data … … 563 580 msave(self, **data) 564 581 return 582 565 583 566 584 class CustomerChangePasswordPage(IkobaEditFormPage): … … 587 605 self.flash(_('Password changed.')) 588 606 else: 589 self.flash( ' '.join(errors), type="warning") 590 return 591 607 self.flash(' '.join(errors), type="warning") 608 return -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/catalog.py
r11958 r11985 29 29 from waeup.ikoba.customers.interfaces import ICustomer 30 30 31 31 32 class CustomersCatalog(grok.Indexes): 32 33 """A catalog for customers. … … 41 42 reg_number = index.Field(attribute='reg_number') 42 43 state = index.Field(attribute='state') 44 43 45 44 46 class CustomerQueryResultItem(object): … … 56 58 self.state = context.state 57 59 self.translated_state = context.translated_state 60 58 61 59 62 def search(query=None, searchtype=None, view=None): … … 82 85 return hitlist 83 86 87 84 88 class SimpleFieldSearch(object): 85 89 """A programmatic (no UI required) search. … … 93 97 """ 94 98 catalog_name = 'customers_catalog' 99 95 100 def __call__(self, **kw): 96 101 """Search customers catalog programmatically. … … 106 111 simple_search = SimpleFieldSearch() 107 112 113 108 114 class CustomersQuery(FilteredCatalogQueryBase): 109 115 """Query customers in a site. See waeup.ikoba.catalog for more info. 110 116 """ 111 117 cat_name = 'customers_catalog' 112 defaults = dict(customer_id=None) # make sure we get all studs by default118 defaults = dict(customer_id=None) # make sure we get all studs by default -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/container.py
r11956 r11985 28 28 from waeup.ikoba.utils.logger import Logger 29 29 30 lock = allocate_lock() # a lock object to lock threads. 30 lock = allocate_lock() # a lock object to lock threads. 31 31 32 32 33 class CustomersContainer(grok.Container, Logger): -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/customer.py
r11964 r11985 46 46 RE_CUSTID_NON_NUM = re.compile('[^\d]+') 47 47 48 48 49 class Customer(grok.Container): 49 50 """This is a customer container for the various objects … … 76 77 'password'] = passwordmanager.encodePassword(password) 77 78 self.temp_password['user'] = user 78 self.temp_password['timestamp'] = datetime.utcnow() # offset-naive datetime79 self.temp_password['timestamp'] = datetime.utcnow() # offset-naive datetime 79 80 80 81 def getTempPassword(self): 81 82 """Check if a temporary password has been set and if it 82 is not expired. 83 is not expired. 83 84 84 85 Return the temporary password if valid, … … 147 148 Customer = attrs_to_fields(Customer) 148 149 150 149 151 class CustomerFactory(grok.GlobalUtility): 150 152 """A factory for customers. … … 160 162 def getInterfaces(self): 161 163 return implementedBy(Customer) 164 162 165 163 166 @grok.subscribe(ICustomer, grok.IObjectAddedEvent) … … 177 180 IWorkflowInfo(customer).fireTransition('create') 178 181 return 182 179 183 180 184 def path_from_custid(customer_id): … … 215 219 return folder_name 216 220 221 217 222 def move_customer_files(customer, del_dir): 218 223 """Move files belonging to `customer` to `del_dir`. … … 242 247 return 243 248 249 244 250 def update_customer_deletion_csvs(customer, del_dir): 245 251 """Update deletion CSV files with data from customer. … … 262 268 263 269 # append a deletion timestamp on each data row 264 timestamp = str(now().replace(microsecond=0)) # store UTC timestamp270 timestamp = str(now().replace(microsecond=0)) # store UTC timestamp 265 271 for num, row in enumerate(csv_data[1:-1]): 266 272 csv_data[num+1] = csv_data[num+1] + ',' + timestamp … … 276 282 open(csv_path, 'a').write('\r\n'.join(csv_data[1:])) 277 283 return 284 278 285 279 286 @grok.subscribe(ICustomer, grok.IObjectRemovedEvent) … … 320 327 CUSTOMER_FILE_STORE_NAME = 'file-customer' 321 328 329 322 330 class CustomerFileNameChooser(grok.Adapter): 323 331 """A file id chooser for :class:`Customer` objects. … … 410 418 # call super method to ensure that any old files with 411 419 # different filename extension are deleted. 412 file, path, file_obj = 420 file, path, file_obj = super( 413 421 CustomerFileStoreHandler, self).createFile( 414 422 store, root, filename, file_id, file) -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/export.py
r11958 r11985 35 35 EXPORTER_NAMES = ('customers', ) 36 36 37 37 38 def get_customers(site, cust_filter=CustomersQuery()): 38 39 """Get all customers registered in catalog in `site`. 39 40 """ 40 41 return cust_filter.query() 42 41 43 42 44 class CustomerExporterBase(ExporterBase): -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/files.py
r11972 r11985 36 36 CustomerFilesUploadPage) 37 37 38 grok.context(IIkobaObject) # Make IIkobaObject the default context38 grok.context(IIkobaObject) # Make IIkobaObject the default context 39 39 grok.templatedir('browser_templates') 40 40 41 41 42 def handle_file_delete(context, view, download_name): … … 46 47 store.deleteFileByContext(context, attr=download_name) 47 48 context.writeLogMessage(view, 'deleted: %s' % download_name) 48 view.flash(_('${a} deleted.', mapping = {'a':download_name}))49 view.flash(_('${a} deleted.', mapping={'a': download_name})) 49 50 return 51 50 52 51 53 def handle_file_upload(upload, context, view, max_size, download_name=None): … … 62 64 view.flash(_('Uploaded file is too big.'), type="danger") 63 65 return False 64 upload.seek(0) # file pointer moved when determining size66 upload.seek(0) # file pointer moved when determining size 65 67 dummy,ext = os.path.splitext(upload.filename) 66 68 # fpm files are expected to be fingerprint minutiae, file … … 70 72 else: 71 73 file_format = get_fileformat(None, upload.read(512)) 72 upload.seek(0) # same here74 upload.seek(0) # same here 73 75 if file_format is None: 74 76 view.flash(_('Could not determine file type.'), type="danger") … … 78 80 if '.' + file_format != expected_ext: 79 81 view.flash(_('${a} file extension expected.', 80 mapping = {'a':expected_ext[1:]}), type="danger")82 mapping={'a': expected_ext[1:]}), type="danger") 81 83 return False 82 84 else: … … 84 86 view.flash( 85 87 _('Only the following extensions are allowed: ${a}', 86 mapping = {'a':', '.join(ALLOWED_FILE_EXTENSIONS)}),88 mapping={'a': ', '.join(ALLOWED_FILE_EXTENSIONS)}), 87 89 type="danger") 88 90 return False … … 93 95 context.writeLogMessage(view, 'uploaded: %s (%s)' % ( 94 96 download_name,upload.filename)) 95 view.flash(_('File ${a} uploaded.', mapping = {'a':download_name}))97 view.flash(_('File ${a} uploaded.', mapping={'a': download_name})) 96 98 return True 99 97 100 98 101 class FileManager(grok.ViewletManager): … … 100 103 """ 101 104 grok.name('files') 105 102 106 103 107 class FileDisplay(grok.Viewlet): … … 123 127 else: 124 128 return False 129 125 130 126 131 class FileUpload(FileDisplay): … … 179 184 return 180 185 186 181 187 class PassportDisplay(FileDisplay): 182 188 """Passport display viewlet. … … 188 194 label = _(u'Passport Picture') 189 195 download_name = u'passport.jpg' 196 190 197 191 198 class PassportUploadManage(FileUpload): … … 201 208 tab_redirect = '#tab2' 202 209 210 203 211 class PassportUploadEdit(PassportUploadManage): 204 212 """Passport upload viewlet for customers. … … 206 214 grok.view(CustomerFilesUploadPage) 207 215 grok.require('waeup.uploadCustomerFile') 216 208 217 209 218 class Image(grok.View): … … 238 247 return image 239 248 249 240 250 class Passport(Image): 241 251 """Renders jpeg passport picture. … … 244 254 download_name = u'passport.jpg' 245 255 grok.context(ICustomer) 246 -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py
r11967 r11985 30 30 contextual_reg_num_source, GenderSource, nats_vocab) 31 31 32 32 33 class ICustomersUtils(Interface): 33 34 """A collection of methods which are subject to customization. 34 35 35 36 """ 37 36 38 37 39 class ICustomersContainer(IIkobaObject): … … 87 89 88 90 """ 91 89 92 90 93 class ICustomer(IIkobaObject): … … 173 176 """ 174 177 178 175 179 class ICustomerUpdateByRegNo(ICustomer): 176 180 """Representation of a customer. Skip regular reg_number validation. … … 181 185 required = False, 182 186 ) 187 183 188 184 189 class ICSVCustomerExporter(ICSVExporter): … … 198 203 """ 199 204 205 200 206 class ICustomerRequestPW(ICustomer): 201 207 """Representation of an customer for first-time password request. … … 219 225 constraint=validate_email, 220 226 ) 221 -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/permissions.py
r11967 r11985 23 23 # Customer section permissions 24 24 25 25 26 class HandleCustomer(grok.Permission): 26 27 grok.name('waeup.handleCustomer') 28 27 29 28 30 class ViewCustomer(grok.Permission): 29 31 grok.name('waeup.viewCustomer') 30 32 33 31 34 class ViewCustomersTab(grok.Permission): 32 35 grok.name('waeup.viewCustomersTab') 36 33 37 34 38 class ViewMyCustomerDataTab(grok.Permission): 35 39 grok.name('waeup.viewMyCustomerDataTab') 36 40 41 37 42 class ViewCustomersContainer(grok.Permission): 38 43 grok.name('waeup.viewCustomersContainer') 44 39 45 40 46 class PayCustomer(grok.Permission): 41 47 grok.name('waeup.payCustomer') 42 48 49 43 50 class UploadCustomerFile(grok.Permission): 44 51 grok.name('waeup.uploadCustomerFile') 52 45 53 46 54 class ManageCustomer(grok.Permission): 47 55 grok.name('waeup.manageCustomer') 48 56 57 49 58 class LoginAsCustomer(grok.Permission): 50 59 grok.name('waeup.loginAsCustomer') 51 60 61 52 62 class TriggerTransition(grok.Permission): 53 63 grok.name('waeup.triggerTransition') 64 54 65 55 66 # Local role … … 60 71 'waeup.viewCustomer', 'waeup.payCustomer') 61 72 73 62 74 # Site Roles 63 75 class CustomerRole(grok.Role): … … 67 79 'waeup.Authenticated') 68 80 81 69 82 class CustomersOfficer(grok.Role): 70 83 grok.name('waeup.CustomersOfficer') … … 72 85 grok.permissions('waeup.viewCustomer','waeup.viewCustomers', 73 86 'waeup.viewCustomersTab', 'waeup.viewCustomersContainer') 87 74 88 75 89 class CustomersManager(grok.Role): … … 81 95 'waeup.viewCustomersTab', 'waeup.triggerTransition') 82 96 97 83 98 class CustomerImpersonator(grok.Role): 84 99 grok.name('waeup.CustomerImpersonator') -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/utils.py
r11971 r11985 22 22 from waeup.ikoba.customers.interfaces import ICustomersUtils 23 23 24 24 25 def generate_customer_id(): 25 26 customers = grok.getSite()['customers'] 26 27 new_id = customers.unique_customer_id 27 28 return new_id 29 28 30 29 31 class CustomersUtils(grok.GlobalUtility): -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/viewlets.py
r11979 r11985 1 3## $Id: viewlets.py 11772 2014-07-31 04:38:23Z henrik $1 ## $Id: viewlets.py 11772 2014-07-31 04:38:23Z henrik $ 2 2 ## 3 3 ## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann … … 33 33 CustomerBaseDisplayFormPage) 34 34 35 grok.context(IIkobaObject) # Make IIkobaObject the default context35 grok.context(IIkobaObject) # Make IIkobaObject the default context 36 36 grok.templatedir('browser_templates') 37 37 38 38 39 class CustomersTab(PrimaryNavTab): … … 52 53 return self.view.application_url('customers') 53 54 55 54 56 class PrimaryCustomerNavManager(grok.ViewletManager): 55 57 """Viewlet manager for the primary navigation tab. 56 58 """ 57 59 grok.name('primary_nav_customer') 60 58 61 59 62 class PrimaryCustomerNavTab(grok.Viewlet): … … 78 81 return 'active' 79 82 return '' 83 80 84 81 85 class MyCustomerDataTab(PrimaryCustomerNavTab): … … 107 111 return targets 108 112 113 109 114 class CustomerManageSidebar(grok.ViewletManager): 110 115 grok.name('left_customermanage') 116 111 117 112 118 class CustomerManageLink(grok.Viewlet): … … 135 141 url, text) 136 142 143 137 144 class CustomerManageBaseLink(CustomerManageLink): 138 145 grok.order(2) … … 140 147 text = _(u'Base Data') 141 148 149 142 150 class CustomerManageHistoryLink(CustomerManageLink): 143 151 grok.order(8) … … 145 153 text = _(u'History') 146 154 155 147 156 class CustomersContainerManageActionButton(ManageActionButton): 148 157 grok.order(1) … … 152 161 text = _('Manage customer section') 153 162 163 154 164 class CustomersContainerAddActionButton(AddActionButton): 155 165 grok.order(1) … … 159 169 text = _('Add customer') 160 170 target = 'addcustomer' 171 161 172 162 173 class ContactActionButton(ManageActionButton): … … 169 180 target = 'contactcustomer' 170 181 182 171 183 class CustomerBaseManageActionButton(ManageActionButton): 172 184 grok.order(1) … … 176 188 text = _('Manage') 177 189 target = 'manage_base' 190 178 191 179 192 class CustomerTrigTransActionButton(ManageActionButton): … … 186 199 target = 'trigtrans' 187 200 201 188 202 class CustomerLoginAsActionButton(ManageActionButton): 189 203 grok.order(3) … … 195 209 target = 'loginasstep1' 196 210 211 197 212 class CustomerDeactivateActionButton(ManageActionButton): 198 213 grok.order(7) … … 215 230 "'A history message will be added. Are you sure?'") 216 231 232 217 233 class CustomerActivateActionButton(ManageActionButton): 218 234 grok.order(7) … … 235 251 "'A history message will be added. Are you sure?'") 236 252 253 237 254 class CustomerPasswordActionButton(ManageActionButton): 238 255 grok.order(2) -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/vocabularies.py
r11958 r11985 56 56 return _('female') 57 57 58 58 59 class RegNumNotInSource(ValidationError): 59 60 """Registration number exists already … … 62 63 # by zope.formlib. 63 64 pass 65 64 66 65 67 class RegNumberSource(object): … … 79 81 validation_error = RegNumNotInSource 80 82 comp_field = 'customer_id' 83 81 84 def __init__(self, context): 82 85 self.context = context … … 107 110 return True 108 111 112 109 113 def contextual_reg_num_source(context): 110 114 source = RegNumberSource(context) 111 115 return source 116 112 117 directlyProvides(contextual_reg_num_source, IContextSourceBinder) -
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/workflow.py
r11982 r11985 100 100 registration_workflow = IkobaWorkflow(REGISTRATION_TRANSITIONS) 101 101 102 102 103 class RegistrationWorkflowState(WorkflowState, grok.Adapter): 103 104 """An adapter to adapt Customer objects to workflow states. … … 108 109 state_key = 'wf.registration.state' 109 110 state_id = 'wf.registration.id' 111 110 112 111 113 class RegistrationWorkflowInfo(IkobaWorkflowInfo, grok.Adapter): … … 118 120 self.context = context 119 121 self.wf = registration_workflow 122 120 123 121 124 @grok.subscribe(ICustomer, IWorkflowTransitionEvent)
Note: See TracChangeset for help on using the changeset viewer.