Add support for making new product on-the-fly during mobile ordering
let's face it, that will be necessary sometimes. this feature still needs some work before can be called complete though...
This commit is contained in:
		
							parent
							
								
									6ec0ddb94e
								
							
						
					
					
						commit
						652f51d484
					
				
					 7 changed files with 83 additions and 10 deletions
				
			
		|  | @ -52,7 +52,7 @@ div.fieldset { | |||
|     margin: 15px; | ||||
| } | ||||
| 
 | ||||
| .field-wrapper.error { | ||||
| .field-wrapper.with-error { | ||||
|     background-color: #ddcccc; | ||||
|     border: 2px solid #dd6666; | ||||
|     padding-bottom: 1em; | ||||
|  | @ -71,7 +71,7 @@ div.fieldset { | |||
|     white-space: nowrap; | ||||
| } | ||||
| 
 | ||||
| .field-wrapper.error label { | ||||
| .field-wrapper.with-error label { | ||||
|     padding-left: 1em; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,7 +21,8 @@ | |||
| } | ||||
| 
 | ||||
| /* error flash messages */ | ||||
| .error { | ||||
| .error, | ||||
| .error-messages { | ||||
|     color: red; | ||||
|     margin-bottom: 1em; | ||||
| } | ||||
|  | @ -35,11 +36,21 @@ | |||
|     display: none; | ||||
| } | ||||
| 
 | ||||
| .field-wrapper.with-error { | ||||
|     background-color: #ddcccc; | ||||
|     border: 2px solid #dd6666; | ||||
|     margin-bottom: 1em; | ||||
| } | ||||
| 
 | ||||
| .field-wrapper label { | ||||
|     font-weight: bold; | ||||
|     margin-top: 1em; | ||||
| } | ||||
| 
 | ||||
| .field-error .error-msg { | ||||
|     color: Red; | ||||
| } | ||||
| 
 | ||||
| /* make sure space comes between simple filter and "grid" list */ | ||||
| .simple-filter { | ||||
|     margin-bottom: 1.5em; | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ ${h.csrf_token(request)} | |||
|         <% field = dform[field] %> | ||||
| 
 | ||||
|         % if form.field_visible(field.name): | ||||
|             <div class="field-wrapper ${field.name} ${'error' if field.error else ''}"> | ||||
|             <div class="field-wrapper ${field.name} ${'with-error' if field.error else ''}"> | ||||
|               % if field.error: | ||||
|                   <div class="field-error"> | ||||
|                     % for msg in field.error.messages(): | ||||
|  |  | |||
|  | @ -5,12 +5,14 @@ | |||
| 
 | ||||
| <%def name="page_title()">${h.link_to(index_title, index_url)} » ${h.link_to(parent_title, parent_url)} » ${h.link_to(instance_title, instance_url)} » Edit</%def> | ||||
| 
 | ||||
| <%def name="buttons()"> | ||||
|   <br /> | ||||
|   ${h.submit('create', form.update_label)} | ||||
|   <a href="${form.cancel_url}" class="ui-btn">Cancel</a> | ||||
| </%def> | ||||
| ## TODO: this should not be necessary, correct? | ||||
| ## <%def name="buttons()"> | ||||
| ##   <br /> | ||||
| ##   ${h.submit('create', form.update_label)} | ||||
| ##   ${h.link_to("Cancel", form.cancel_url, class_='ui-btn ui-corner-all')} | ||||
| ## </%def> | ||||
| 
 | ||||
| <div class="form-wrapper"> | ||||
|   ${form.render(buttons=capture(self.buttons))|n} | ||||
| ##  ${form.render(buttons=capture(self.buttons))|n} | ||||
|   ${form.render()|n} | ||||
| </div><!-- form-wrapper --> | ||||
|  |  | |||
							
								
								
									
										6
									
								
								tailbone/templates/mobile/ordering/new_product.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tailbone/templates/mobile/ordering/new_product.mako
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| ## -*- coding: utf-8; -*- | ||||
| <%inherit file="/mobile/master/create_row.mako" /> | ||||
| 
 | ||||
| <%def name="page_title()">${h.link_to(index_title, index_url)} » ${h.link_to(instance_title, instance_url)} » Add Item</%def> | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  | @ -1045,6 +1045,7 @@ class MasterView(View): | |||
|         """ | ||||
|         defaults = { | ||||
|             'request': self.request, | ||||
|             'mobile': True, | ||||
|             'readonly': self.viewing, | ||||
|             'model_class': getattr(self, 'model_row_class', None), | ||||
|             'action_url': self.request.current_route_url(_query=None), | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ class PurchasingBatchView(BatchMasterView): | |||
|     model_class = model.PurchaseBatch | ||||
|     model_row_class = model.PurchaseBatchRow | ||||
|     default_handler_spec = 'rattail.batch.purchase:PurchaseBatchHandler' | ||||
|     supports_new_product = False | ||||
| 
 | ||||
|     grid_columns = [ | ||||
|         'id', | ||||
|  | @ -701,6 +702,42 @@ class PurchasingBatchView(BatchMasterView): | |||
|         #     else: | ||||
|         #         f.remove_field('product') | ||||
| 
 | ||||
|     def mobile_new_product(self): | ||||
|         """ | ||||
|         View which allows user to create a new Product and add a row for it to | ||||
|         the Purchasing Batch. | ||||
|         """ | ||||
|         batch = self.get_instance() | ||||
|         batch_url = self.get_action_url('view', batch, mobile=True) | ||||
|         form = forms.Form(schema=self.make_new_product_schema(), | ||||
|                           request=self.request, | ||||
|                           mobile=True, | ||||
|                           cancel_url=batch_url) | ||||
| 
 | ||||
|         if form.validate(newstyle=True): | ||||
|             product = model.Product() | ||||
|             product.item_id = form.validated['item_id'] | ||||
|             product.description = form.validated['description'] | ||||
|             row = self.model_row_class() | ||||
|             row.product = product | ||||
|             self.handler.add_row(batch, row) | ||||
|             self.Session.flush() | ||||
|             return self.redirect(self.get_row_action_url('edit', row, mobile=True)) | ||||
| 
 | ||||
|         return self.render_to_response('new_product', { | ||||
|             'form': form, | ||||
|             'dform': form.make_deform_form(), | ||||
|             'instance_title': self.get_instance_title(batch), | ||||
|             'instance_url': batch_url, | ||||
|         }, mobile=True) | ||||
| 
 | ||||
|     def make_new_product_schema(self): | ||||
|         """ | ||||
|         Must return a ``colander.Schema`` instance for use with the form in the | ||||
|         :meth:`mobile_new_product()` view. | ||||
|         """ | ||||
|         return NewProduct() | ||||
| 
 | ||||
| #     def item_lookup(self, value, field=None): | ||||
| #         """ | ||||
| #         Try to locate a single product using ``value`` as a lookup code. | ||||
|  | @ -785,8 +822,24 @@ class PurchasingBatchView(BatchMasterView): | |||
|         config.add_view(cls, attr='eligible_purchases', route_name='{}.eligible_purchases'.format(route_prefix), | ||||
|                         renderer='json', permission='{}.view'.format(permission_prefix)) | ||||
| 
 | ||||
|         # add new product | ||||
|         if cls.supports_new_product: | ||||
|             config.add_tailbone_permission(permission_prefix, '{}.new_product'.format(permission_prefix), | ||||
|                                            "Create new Product when adding row to {}".format(model_title)) | ||||
|             config.add_route('mobile.{}.new_product'.format(route_prefix), '{}/{{{}}}/new-product'.format(url_prefix, model_key)) | ||||
|             config.add_view(cls, attr='mobile_new_product', route_name='mobile.{}.new_product'.format(route_prefix), | ||||
|                             permission='{}.new_product'.format(permission_prefix)) | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def defaults(cls, config): | ||||
|         cls._purchasing_defaults(config) | ||||
|         cls._batch_defaults(config) | ||||
|         cls._defaults(config) | ||||
| 
 | ||||
| 
 | ||||
| class NewProduct(colander.Schema): | ||||
| 
 | ||||
|     item_id = colander.SchemaNode(colander.String()) | ||||
| 
 | ||||
|     description = colander.SchemaNode(colander.String()) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar