Add support for detaching Person from Customer
This commit is contained in:
		
							parent
							
								
									b8c6e95b73
								
							
						
					
					
						commit
						96e5c42795
					
				
					 2 changed files with 121 additions and 6 deletions
				
			
		
							
								
								
									
										21
									
								
								tailbone/templates/customers/view.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tailbone/templates/customers/view.mako
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | ## -*- coding: utf-8; -*- | ||||||
|  | <%inherit file="/master/view.mako" /> | ||||||
|  | 
 | ||||||
|  | <%def name="extra_javascript()"> | ||||||
|  |   ${parent.extra_javascript()} | ||||||
|  |   % if master.people_detachable and request.has_perm('{}.detach_person'.format(permission_prefix)): | ||||||
|  |       <script type="text/javascript"> | ||||||
|  | 
 | ||||||
|  |         $(function() { | ||||||
|  |             $('.people .grid .actions a.detach').click(function() { | ||||||
|  |                 if (! confirm("Are you sure you wish to detach this Person from the Customer?")) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |       </script> | ||||||
|  |   % endif | ||||||
|  | </%def> | ||||||
|  | 
 | ||||||
|  | ${parent.body()} | ||||||
|  | @ -37,6 +37,7 @@ from deform import widget as dfwidget | ||||||
| from pyramid.httpexceptions import HTTPNotFound | from pyramid.httpexceptions import HTTPNotFound | ||||||
| from webhelpers2.html import HTML, tags | from webhelpers2.html import HTML, tags | ||||||
| 
 | 
 | ||||||
|  | from tailbone import grids | ||||||
| from tailbone.db import Session | from tailbone.db import Session | ||||||
| from tailbone.views import MasterView3 as MasterView, AutocompleteView | from tailbone.views import MasterView3 as MasterView, AutocompleteView | ||||||
| 
 | 
 | ||||||
|  | @ -50,6 +51,7 @@ class CustomersView(MasterView): | ||||||
|     model_class = model.Customer |     model_class = model.Customer | ||||||
|     has_versions = True |     has_versions = True | ||||||
|     supports_mobile = True |     supports_mobile = True | ||||||
|  |     people_detachable = True | ||||||
| 
 | 
 | ||||||
|     labels = { |     labels = { | ||||||
|         'id': "ID", |         'id': "ID", | ||||||
|  | @ -78,6 +80,7 @@ class CustomersView(MasterView): | ||||||
|         'active_in_pos', |         'active_in_pos', | ||||||
|         'active_in_pos_sticky', |         'active_in_pos_sticky', | ||||||
|         'people', |         'people', | ||||||
|  |         'groups', | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
|     def configure_grid(self, g): |     def configure_grid(self, g): | ||||||
|  | @ -151,6 +154,11 @@ class CustomersView(MasterView): | ||||||
|     def configure_form(self, f): |     def configure_form(self, f): | ||||||
|         super(CustomersView, self).configure_form(f) |         super(CustomersView, self).configure_form(f) | ||||||
|         customer = f.model_instance |         customer = f.model_instance | ||||||
|  |         permission_prefix = self.get_permission_prefix() | ||||||
|  | 
 | ||||||
|  |         # id | ||||||
|  |         if not self.creating: | ||||||
|  |             f.set_readonly('id') | ||||||
| 
 | 
 | ||||||
|         f.set_renderer('default_email', self.render_default_email) |         f.set_renderer('default_email', self.render_default_email) | ||||||
|         if not self.creating and customer.emails: |         if not self.creating and customer.emails: | ||||||
|  | @ -160,21 +168,33 @@ class CustomersView(MasterView): | ||||||
|         if not self.creating and customer.phones: |         if not self.creating and customer.phones: | ||||||
|             f.set_default('default_phone', customer.phones[0].number) |             f.set_default('default_phone', customer.phones[0].number) | ||||||
| 
 | 
 | ||||||
|         f.set_renderer('default_address', self.render_default_address) |         # default_address | ||||||
|         f.set_readonly('default_address') |         if self.creating: | ||||||
|  |             f.remove_field('default_address') | ||||||
|  |         else: | ||||||
|  |             f.set_renderer('default_address', self.render_default_address) | ||||||
|  |             f.set_readonly('default_address') | ||||||
| 
 | 
 | ||||||
|         f.set_enum('email_preference', self.enum.EMAIL_PREFERENCE) |         f.set_enum('email_preference', self.enum.EMAIL_PREFERENCE) | ||||||
|         preferences = list(self.enum.EMAIL_PREFERENCE.items()) |         preferences = list(self.enum.EMAIL_PREFERENCE.items()) | ||||||
|         preferences.insert(0, ('', "(no preference)")) |         preferences.insert(0, ('', "(no preference)")) | ||||||
|         f.set_widget('email_preference', dfwidget.SelectWidget(values=preferences)) |         f.set_widget('email_preference', dfwidget.SelectWidget(values=preferences)) | ||||||
| 
 | 
 | ||||||
|         f.set_renderer('people', self.render_people) |         # people | ||||||
|         f.set_readonly('people') |  | ||||||
| 
 |  | ||||||
|         if self.creating: |         if self.creating: | ||||||
|             f.remove_field('people') |             f.remove_field('people') | ||||||
|  |         elif self.viewing and self.request.has_perm('{}.detach_person'.format(permission_prefix)): | ||||||
|  |             f.set_renderer('people', self.render_people_removable) | ||||||
|         else: |         else: | ||||||
|             f.set_readonly('id') |             f.set_renderer('people', self.render_people) | ||||||
|  |             f.set_readonly('people') | ||||||
|  | 
 | ||||||
|  |         # groups | ||||||
|  |         if self.creating: | ||||||
|  |             f.remove_field('groups') | ||||||
|  |         else: | ||||||
|  |             f.set_renderer('groups', self.render_groups) | ||||||
|  |             f.set_readonly('groups') | ||||||
| 
 | 
 | ||||||
|     # TODO: something like this should be supported for default_email, default_phone |     # TODO: something like this should be supported for default_email, default_phone | ||||||
|     # def after_edit(self, customer): |     # def after_edit(self, customer): | ||||||
|  | @ -226,6 +246,46 @@ class CustomersView(MasterView): | ||||||
|             items.append(HTML.tag('li', link)) |             items.append(HTML.tag('li', link)) | ||||||
|         return HTML.tag('ul', HTML.literal('').join(items)) |         return HTML.tag('ul', HTML.literal('').join(items)) | ||||||
| 
 | 
 | ||||||
|  |     def render_people_removable(self, customer, field): | ||||||
|  |         people = customer.people | ||||||
|  |         if not people: | ||||||
|  |             return "" | ||||||
|  | 
 | ||||||
|  |         route_prefix = self.get_route_prefix() | ||||||
|  |         permission_prefix = self.get_permission_prefix() | ||||||
|  | 
 | ||||||
|  |         view_url = lambda p, i: self.request.route_url('people.view', uuid=p.uuid) | ||||||
|  |         actions = [ | ||||||
|  |             grids.GridAction('view', icon='zoomin', url=view_url), | ||||||
|  |         ] | ||||||
|  |         if self.people_detachable and self.request.has_perm('{}.detach_person'.format(permission_prefix)): | ||||||
|  |             url = lambda p, i: self.request.route_url('{}.detach_person'.format(route_prefix), | ||||||
|  |                                                       uuid=customer.uuid, person_uuid=p.uuid) | ||||||
|  |             actions.append( | ||||||
|  |                 grids.GridAction('detach', icon='trash', url=url)) | ||||||
|  | 
 | ||||||
|  |         columns = ['first_name', 'last_name', 'display_name'] | ||||||
|  |         g = grids.Grid( | ||||||
|  |             key='{}.people'.format(route_prefix), | ||||||
|  |             data=customer.people, | ||||||
|  |             columns=columns, | ||||||
|  |             labels={'display_name': "Full Name"}, | ||||||
|  |             url=lambda p: self.request.route_url('people.view', uuid=p.uuid), | ||||||
|  |             linked_columns=columns, | ||||||
|  |             main_actions=actions) | ||||||
|  |         return HTML.literal(g.render_grid()) | ||||||
|  | 
 | ||||||
|  |     def render_groups(self, customer, field): | ||||||
|  |         groups = customer.groups | ||||||
|  |         if not groups: | ||||||
|  |             return "" | ||||||
|  |         items = [] | ||||||
|  |         for group in groups: | ||||||
|  |             text = "({}) {}".format(group.id, group.name) | ||||||
|  |             url = self.request.route_url('customergroups.view', uuid=group.uuid) | ||||||
|  |             items.append(HTML.tag('li', tags.link_to(text, url))) | ||||||
|  |         return HTML.tag('ul', HTML.literal('').join(items)) | ||||||
|  | 
 | ||||||
|     # def configure_mobile_fieldset(self, fs): |     # def configure_mobile_fieldset(self, fs): | ||||||
|     #     fs.configure( |     #     fs.configure( | ||||||
|     #         include=[ |     #         include=[ | ||||||
|  | @ -241,6 +301,40 @@ class CustomersView(MasterView): | ||||||
|             (model.CustomerPerson, 'customer_uuid'), |             (model.CustomerPerson, 'customer_uuid'), | ||||||
|         ] |         ] | ||||||
| 
 | 
 | ||||||
|  |     def detach_person(self): | ||||||
|  |         customer = self.get_instance() | ||||||
|  |         person = self.Session.query(model.Person).get(self.request.matchdict['person_uuid']) | ||||||
|  |         if not person: | ||||||
|  |             return self.notfound() | ||||||
|  | 
 | ||||||
|  |         if person in customer.people: | ||||||
|  |             customer.people.remove(person) | ||||||
|  |         else: | ||||||
|  |             self.request.session.flash("No change; person \"{}\" not attached to customer \"{}\"".format( | ||||||
|  |                 person, customer)) | ||||||
|  | 
 | ||||||
|  |         return self.redirect(self.request.get_referrer()) | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def defaults(cls, config): | ||||||
|  |         route_prefix = cls.get_route_prefix() | ||||||
|  |         url_prefix = cls.get_url_prefix() | ||||||
|  |         permission_prefix = cls.get_permission_prefix() | ||||||
|  |         model_key = cls.get_model_key() | ||||||
|  |         model_title = cls.get_model_title() | ||||||
|  | 
 | ||||||
|  |         cls._defaults(config) | ||||||
|  | 
 | ||||||
|  |         # detach person | ||||||
|  |         if cls.people_detachable: | ||||||
|  |             config.add_tailbone_permission(permission_prefix, '{}.detach_person'.format(permission_prefix), | ||||||
|  |                                            "Detach a Person from a {}".format(model_title)) | ||||||
|  |             config.add_route('{}.detach_person'.format(route_prefix), '{}/{{{}}}/detach-person/{{person_uuid}}'.format(url_prefix, model_key), | ||||||
|  |                              # request_method='POST', | ||||||
|  |             ) | ||||||
|  |             config.add_view(cls, attr='detach_person', route_name='{}.detach_person'.format(route_prefix), | ||||||
|  |                             permission='{}.detach_person'.format(permission_prefix)) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| # # TODO: this is referenced by some custom apps, but should be moved?? | # # TODO: this is referenced by some custom apps, but should be moved?? | ||||||
| # def unique_id(value, field): | # def unique_id(value, field): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar