more batch improvements (save point)
This commit is contained in:
		
							parent
							
								
									523d7de3e7
								
							
						
					
					
						commit
						675c4deb63
					
				
					 12 changed files with 327 additions and 162 deletions
				
			
		|  | @ -5,8 +5,9 @@ | |||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("Back to Batches", url('batch.list'))}</p> | ||||
|   % if fieldset.edit and fieldset.model.rowcount: | ||||
|   % if fieldset.edit: | ||||
|       <p>${h.link_to("View Batch Details", url('batch.details', uuid=fieldset.model.uuid))}</p> | ||||
|       <p>${h.link_to("Execute this Batch", url('batch.execute', uuid=fieldset.model.uuid))}</p> | ||||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| <%def name="title()">Batch Dictionaries</%def> | ||||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("Back to Batches", url('batches'))}</p> | ||||
|   <p>${h.link_to("Back to Batches", url('batch.list'))}</p> | ||||
| ##  <p>${h.link_to("Create a New Dictionary", url('batch_dictionary'))}</p> | ||||
| </%def> | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,10 +2,8 @@ | |||
| <%inherit file="/crud.mako" /> | ||||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("Back to Batches", url('batches'))}</p> | ||||
|   <p>${h.link_to("Back to Batches", url('batch.list'))}</p> | ||||
|   <p>${h.link_to("Back to Dictionaries", url('batch_dictionaries'))}</p> | ||||
| </%def> | ||||
| 
 | ||||
| ${parent.body()} | ||||
| 
 | ||||
| ${columns|n} | ||||
|  |  | |||
|  | @ -3,9 +3,34 @@ | |||
| 
 | ||||
| <%def name="title()">Batches</%def> | ||||
| 
 | ||||
| <%def name="head_tags()"> | ||||
|   <style type="text/css"> | ||||
| 
 | ||||
|   div.grid table tbody td.rowcount { | ||||
|       text-align: right; | ||||
|   } | ||||
| 
 | ||||
|   </style> | ||||
|   <script language="javascript" type="text/javascript"> | ||||
| 
 | ||||
|   $(function() { | ||||
|       $('div.grid table tbody td.action.execute a').live('click', function() { | ||||
| 	  var tr = $(this).parents('tr:first'); | ||||
| 	  var desc = tr.find('td.description').text(); | ||||
| 	  if (confirm("Do you really wish to execute this batch?\n\n" + desc)) { | ||||
| 	      var url = '${url('batch.execute', uuid='{uuid}')}'; | ||||
| 	      location.href = url.replace(/%7Buuid%7D/, get_uuid(this)); | ||||
| 	  } | ||||
| 	  return false; | ||||
|       }); | ||||
|   }); | ||||
| 
 | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="menu()"> | ||||
| ##  <p>${h.link_to("Create a New Batch", url('batch.new'))}</p> | ||||
|   <p>${h.link_to("Manage Terminals", url('batch_terminal.list'))}</p> | ||||
|   <p>${h.link_to("Manage Terminals", url('batch_terminals'))}</p> | ||||
|   <p>${h.link_to("View Dictionaries", url('batch_dictionaries'))}</p> | ||||
|   <p>${h.link_to("SIL Columns", url('sil_columns'))}</p> | ||||
| </%def> | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| <%inherit file="/crud.mako" /> | ||||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("Back to Batches", url('batches'))}</p> | ||||
|   <p>${h.link_to("Back to Batches", url('batch.list'))}</p> | ||||
|   <p>${h.link_to("Back to SIL Columns", url('sil_columns'))}</p> | ||||
| </%def> | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| <%def name="title()">SIL Columns</%def> | ||||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("Back to Batches", url('batches'))}</p> | ||||
|   <p>${h.link_to("Back to Batches", url('batch.list'))}</p> | ||||
| </%def> | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("Back to Batches", url('batch.list'))}</p> | ||||
|   <p>${h.link_to("Back to Batch Terminals", url('batch_terminal.list'))}</p> | ||||
|   <p>${h.link_to("Back to Batch Terminals", url('batch_terminals'))}</p> | ||||
| </%def> | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -1,9 +1,7 @@ | |||
| <%inherit file="/products/base.mako" /> | ||||
| <%inherit file="/index.mako" /> | ||||
| 
 | ||||
| <%def name="title()">Products</%def> | ||||
| 
 | ||||
| <%def name="menu()"> | ||||
|   <p>${h.link_to("New Batch from Results", url('products.batch'))}</p> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="title()">Products</%def> | ||||
| ${parent.body()} | ||||
|  |  | |||
							
								
								
									
										96
									
								
								rattail/pyramid/util.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								rattail/pyramid/util.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,96 @@ | |||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8  -*- | ||||
| ################################################################################ | ||||
| # | ||||
| #  Rattail -- Retail Software Framework | ||||
| #  Copyright © 2010-2012 Lance Edgar | ||||
| # | ||||
| #  This file is part of Rattail. | ||||
| # | ||||
| #  Rattail is free software: you can redistribute it and/or modify it under the | ||||
| #  terms of the GNU Affero General Public License as published by the Free | ||||
| #  Software Foundation, either version 3 of the License, or (at your option) | ||||
| #  any later version. | ||||
| # | ||||
| #  Rattail is distributed in the hope that it will be useful, but WITHOUT ANY | ||||
| #  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||||
| #  FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for | ||||
| #  more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU Affero General Public License | ||||
| #  along with Rattail.  If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ################################################################################ | ||||
| 
 | ||||
| """ | ||||
| ``rattail.pyramid.util`` -- Utilities | ||||
| """ | ||||
| 
 | ||||
| from pyramid import threadlocal | ||||
| from webhelpers.html import tags | ||||
| 
 | ||||
| import edbob | ||||
| from edbob.pyramid import Session | ||||
| 
 | ||||
| import rattail | ||||
| 
 | ||||
| 
 | ||||
| def get_column(sil_name): | ||||
|     """ | ||||
|     Returns the :class:`rattail.SilColumn` instance with the given SIL name. | ||||
|     """ | ||||
| 
 | ||||
|     q = Session.query(rattail.SilColumn) | ||||
|     q = q.filter(rattail.SilColumn.sil_name == sil_name) | ||||
|     if q.count() == 1: | ||||
|         return q.one() | ||||
| 
 | ||||
| 
 | ||||
| def get_dictionary(name, flash=False): | ||||
|     """ | ||||
|     Returns the :class:`rattail.BatchDictionary` instance with the given name. | ||||
|     """ | ||||
| 
 | ||||
|     q = Session.query(rattail.BatchDictionary) | ||||
|     q = q.filter(rattail.BatchDictionary.name == name) | ||||
|     if q.count() == 1: | ||||
|         return q.one() | ||||
|          | ||||
|     if flash: | ||||
|         request = threadlocal.get_current_request() | ||||
|         dct = tags.link_to("Batch Dictionary", request.route_url('batch_dictionaries')) | ||||
|         request.session.flash("Hm, I couldn't find the '%s' %s." % (name, dct)) | ||||
| 
 | ||||
| 
 | ||||
| def get_terminal(key=None, default='rattail', title="Rattail"): | ||||
|     """ | ||||
|     Returns the :class:`rattail.BatchTerminal` instance with the given SIL ID. | ||||
| 
 | ||||
|     If ``key`` is specified, it will be used to obtain the SIL ID from config. | ||||
|     If no key is given, or config contains no appropriate value, then | ||||
|     ``default`` will be used as the SIL ID. | ||||
| 
 | ||||
|     ``title`` is used for a flash message, should no such terminal be found. | ||||
| 
 | ||||
|     .. highlight:: ini | ||||
| 
 | ||||
|     Given a ``key`` value of ``'products'``, a SIL ID of ``'rattail.locsms'`` | ||||
|     should be configured like this:: | ||||
| 
 | ||||
|        [rattail.pyramid] | ||||
|        batch_terminal.products = rattail.locsms | ||||
|     """ | ||||
| 
 | ||||
|     if key: | ||||
|         sil_id = edbob.config.get('rattail.pyramid', 'batch_terminal.%s' % key, | ||||
|                                   default=default) | ||||
|     assert sil_id | ||||
| 
 | ||||
|     q = Session.query(rattail.BatchTerminal) | ||||
|     q = q.filter(rattail.BatchTerminal.sil_id == sil_id) | ||||
|     if q.count() == 1: | ||||
|         return q.one() | ||||
| 
 | ||||
|     request = threadlocal.get_current_request() | ||||
|     terminal = tags.link_to("Batch Terminal", request.route_url('batch_terminals')) | ||||
|     request.session.flash("Hm, I couldn't find a %s for %s." % (terminal, title)) | ||||
|  | @ -47,6 +47,7 @@ from edbob.util import prettify | |||
| import rattail | ||||
| from rattail import sil | ||||
| from rattail.batches import next_batch_id | ||||
| from rattail.pyramid import util | ||||
| from rattail.pyramid.forms import ( | ||||
|     BatchIdFieldRenderer, | ||||
|     unique_batch_terminal_id, | ||||
|  | @ -91,9 +92,8 @@ def sil_columns(context, request): | |||
|     columns = grids.get_pager(query, config) | ||||
|     g = forms.AlchemyGrid( | ||||
|         rattail.SilColumn, columns, config, | ||||
|         request.route_url('sil_columns'), | ||||
|         url_object=request.route_url('sil_column'), | ||||
|         url_delete=request.route_url('sil_column')) | ||||
|         gridurl=request.route_url('sil_columns'), | ||||
|         objurl='sil_column', delurl='sil_column') | ||||
| 
 | ||||
|     g.configure( | ||||
|         include=[ | ||||
|  | @ -171,9 +171,8 @@ def batch_dictionaries(context, request): | |||
|     dictionaries = grids.get_pager(query, config) | ||||
|     g = forms.AlchemyGrid( | ||||
|         rattail.BatchDictionary, dictionaries, config, | ||||
|         request.route_url('batch_dictionaries'), | ||||
|         url_object=request.route_url('batch_dictionary'), | ||||
|         url_delete=request.route_url('batch_dictionary')) | ||||
|         gridurl=request.route_url('batch_dictionaries'), | ||||
|         objurl='batch_dictionary', delurl='batch_dictionary') | ||||
| 
 | ||||
|     g.configure( | ||||
|         include=[ | ||||
|  | @ -302,7 +301,6 @@ def _terminal_columns(request, terminal): | |||
| 
 | ||||
|     def query(config): | ||||
|         q = Session.query(rattail.BatchTerminalColumn) | ||||
|         # q = q.join(rattail.BatchDictionary) | ||||
|         q = q.options(joinedload(rattail.BatchTerminalColumn.dictionary)) | ||||
|         q = q.options(joinedload(rattail.BatchTerminalColumn.sil_column)) | ||||
|         q = q.filter(rattail.BatchTerminalColumn.terminal_uuid == terminal.uuid) | ||||
|  | @ -343,78 +341,63 @@ def terminal_columns(context, request): | |||
| 
 | ||||
| def update_terminal_info(terminal): | ||||
|     """ | ||||
|     Updates the terminal's list of supported source and target columns, based | ||||
|     on feedback from the actual :class:`rattail.batch.BatchTerminal` instance. | ||||
|     Also sets the terminal's ``functional`` flag (et al.) to reflect reality. | ||||
|     This function updates a :class:`rattail.BatchTerminal` instance to reflect | ||||
|     the reality found by way of inspecting its underlying | ||||
|     :class:`rattail.batches.BatchTerminal` instance. | ||||
|     """ | ||||
| 
 | ||||
|     terminal.functional = True | ||||
|     # Assume the worst. | ||||
|     terminal.functional = False | ||||
|     del terminal.columns[:] | ||||
| 
 | ||||
|     # Fetch "real" terminal instance, if we can. | ||||
|     try: | ||||
|         true_terminal = terminal.get_terminal() | ||||
|     except LoadSpecError, err: | ||||
|         terminal.functional = False | ||||
|         return err | ||||
|     else: | ||||
|         if true_terminal: | ||||
|             # for column_type in ('source', 'target'): | ||||
|             #     declared_columns = getattr(true_terminal, '%s_columns' % column_type) | ||||
|             #     stored_columns = getattr(terminal, '%s_columns' % column_type) | ||||
|             #     cls = getattr(rattail, 'BatchTerminal%sColumn' % column_type.title()) | ||||
|             #     for dictionary, columns in declared_columns.iteritems(): | ||||
|             #         q = Session.query(rattail.BatchDictionary) | ||||
|             #         q = q.filter_by(name=dictionary) | ||||
|             #         dictionary = q.one() | ||||
|             #         for col in columns: | ||||
|             #             q = Session.query(rattail.SilColumn) | ||||
|             #             q = q.filter_by(sil_name=col) | ||||
|             #             col = q.one() | ||||
|             #             stored_columns.append(cls( | ||||
|             #                     dictionary=dictionary, | ||||
|             #                     column=col)) | ||||
|             #     setattr(terminal, column_type, bool(declared_columns)) | ||||
|             stored_columns = {} | ||||
|             for col in terminal.columns: | ||||
|                 stored_columns[col.sil_column.sil_name] = col | ||||
|             for column_type in ('source', 'target'): | ||||
|                 declared_columns = getattr(true_terminal, '%s_columns' % column_type) | ||||
|                 for dictionary, columns in declared_columns.iteritems(): | ||||
|                     q = Session.query(rattail.BatchDictionary) | ||||
|                     q = q.filter_by(name=dictionary) | ||||
|                     dictionary = q.one() | ||||
|                     for col in columns: | ||||
|                         q = Session.query(rattail.SilColumn) | ||||
|                         q = q.filter_by(sil_name=col) | ||||
|                         col = q.one() | ||||
|                         if col.sil_name in stored_columns: | ||||
|                             setattr(stored_columns[col.sil_name], column_type, True) | ||||
|                         else: | ||||
|                             col = rattail.BatchTerminalColumn( | ||||
|                                 dictionary=dictionary, | ||||
|                                 sil_column=col) | ||||
|                             setattr(col, column_type, True) | ||||
|                             terminal.columns.append(col) | ||||
|                             stored_columns[col.sil_column.sil_name] = col | ||||
|                             # Session.add(col) | ||||
|                             Session.flush() | ||||
|                         # stored_columns.append(rattail.BatchTerminalColumn( | ||||
|                         #         dictionary=dictionary, | ||||
|                         #         sil_column=col)) | ||||
|                 setattr(terminal, column_type, bool(declared_columns)) | ||||
|             for col in terminal.columns: | ||||
|                 if not col.source: | ||||
|                     col.source = False | ||||
|                 if not col.target: | ||||
|                     col.target = False | ||||
|             return true_terminal | ||||
|         else: | ||||
|             terminal.functional = False | ||||
| 
 | ||||
|     # Spec was fine but still no terminal?  (This may not be needed?) | ||||
|     if not true_terminal: | ||||
|         return | ||||
| 
 | ||||
|     # Okay, we have *something*. | ||||
|     terminal.functional = True | ||||
| 
 | ||||
|     if true_terminal.source_columns: | ||||
|         terminal.source = True | ||||
|     for dct, cols in true_terminal.source_columns.iteritems(): | ||||
|         dct = util.get_dictionary(dct) | ||||
|         for col in cols: | ||||
|             col = rattail.BatchTerminalColumn( | ||||
|                 dictionary=dct, | ||||
|                 sil_column=util.get_column(col), | ||||
|                 source=True, | ||||
|                 target=False) | ||||
|             terminal.columns.append(col) | ||||
|             Session.flush() | ||||
| 
 | ||||
|     if true_terminal.target_columns: | ||||
|         terminal.target = True | ||||
|     for dct, cols in true_terminal.target_columns.iteritems(): | ||||
|         dct = util.get_dictionary(dct) | ||||
|         for col in cols: | ||||
|             col = rattail.BatchTerminalColumn( | ||||
|                 dictionary=dct, | ||||
|                 sil_column=util.get_column(col), | ||||
|                 source=False, | ||||
|                 target=True) | ||||
|             terminal.columns.append(col) | ||||
|             Session.flush() | ||||
| 
 | ||||
|     # Really, why? | ||||
|     return true_terminal | ||||
|      | ||||
| 
 | ||||
| def terminal_fieldset(terminal, request): | ||||
|     fs = forms.make_fieldset( | ||||
|         terminal, crud_title="Batch Terminal", | ||||
|         url_action=request.current_route_url(), | ||||
|         url_cancel=request.route_url('batch_terminal.list')) | ||||
|         url_cancel=request.route_url('batch_terminals')) | ||||
| 
 | ||||
|     fs.configure( | ||||
|         include=[ | ||||
|  | @ -422,13 +405,11 @@ def terminal_fieldset(terminal, request): | |||
|             fs.description, | ||||
|             fs.class_spec.validate(forms.required), | ||||
|             fs.functional.readonly(), | ||||
|             # fs.source_kwargs, | ||||
|             # fs.target_kwargs, | ||||
|             ]) | ||||
| 
 | ||||
|     # if not fs.edit: | ||||
|     #     del fs.source_kwargs | ||||
|     #     del fs.target_kwargs | ||||
|     if not fs.edit: | ||||
|         del fs.functional | ||||
| 
 | ||||
|     return fs | ||||
| 
 | ||||
| 
 | ||||
|  | @ -508,7 +489,7 @@ def delete_terminal(context, request): | |||
|     assert terminal | ||||
|     with transaction.manager: | ||||
|         Session.delete(terminal) | ||||
|     return HTTPFound(location=request.route_url('batch_terminal.list')) | ||||
|     return HTTPFound(location=request.route_url('batch_terminals')) | ||||
| 
 | ||||
| 
 | ||||
| # @view_config(route_name='batch_terminal', renderer='/batches/terminal.mako') | ||||
|  | @ -563,7 +544,7 @@ def delete_terminal(context, request): | |||
| #         pre_render=pre_render, post_sync=post_sync) | ||||
| 
 | ||||
| 
 | ||||
| @view_config(route_name='batch_terminal.list', renderer='/batches/terminals.mako') | ||||
| @view_config(route_name='batch_terminals', renderer='/batches/terminals.mako') | ||||
| def terminals(context, request): | ||||
| 
 | ||||
|     fmap = filters.get_filter_map( | ||||
|  | @ -572,7 +553,7 @@ def terminals(context, request): | |||
|         ilike=['description']) | ||||
| 
 | ||||
|     config = filters.get_search_config( | ||||
|         'batch_terminal.list', request, fmap, | ||||
|         'batch_terminals', request, fmap, | ||||
|         include_filter_description=True, | ||||
|         filter_type_description='lk') | ||||
| 
 | ||||
|  | @ -580,7 +561,7 @@ def terminals(context, request): | |||
|         config, sil_id="SIL ID") | ||||
| 
 | ||||
|     config = grids.get_grid_config( | ||||
|         'batch_terminal.list', request, search, | ||||
|         'batch_terminals', request, search, | ||||
|         filter_map=fmap, sort='description', deletable=True) | ||||
| 
 | ||||
|     smap = grids.get_sort_map( | ||||
|  | @ -596,7 +577,7 @@ def terminals(context, request): | |||
|     terminals = grids.get_pager(query, config) | ||||
|     g = forms.AlchemyGrid( | ||||
|         rattail.BatchTerminal, terminals, config, | ||||
|         gridurl=request.route_url('batch_terminal.list'), | ||||
|         gridurl=request.route_url('batch_terminals'), | ||||
|         objurl='batch_terminal.edit', | ||||
|         delurl='batch_terminal.delete') | ||||
| 
 | ||||
|  | @ -633,12 +614,14 @@ def batches(context, request): | |||
| 
 | ||||
|     config = grids.get_grid_config( | ||||
|         'batches', request, search, | ||||
|         filter_map=fmap, deletable=True, sort='target') | ||||
|         filter_map=fmap, deletable=True, sort='target', | ||||
|         actions=['Execute']) | ||||
| 
 | ||||
|     smap = grids.get_sort_map( | ||||
|         rattail.Batch, | ||||
|         ['source_description', 'batch_id', 'action_type', | ||||
|          'description', 'rowcount', 'effective'], | ||||
|          # 'description', 'rowcount', 'effective'], | ||||
|          'description', 'rowcount'], | ||||
|         target=grids.sorter(rattail.BatchTerminal.description)) | ||||
| 
 | ||||
|     def query(config): | ||||
|  | @ -672,7 +655,7 @@ def batches(context, request): | |||
|             g.action_type.with_renderer(forms.EnumFieldRenderer(rattail.BATCH_ACTION_TYPE)).label("Action"), | ||||
|             g.description, | ||||
|             g.rowcount.label("Rows"), | ||||
|             g.effective.with_renderer(forms.PrettyDateTimeFieldRenderer), | ||||
|             # g.effective.with_renderer(forms.PrettyDateTimeFieldRenderer), | ||||
|             ]) | ||||
| 
 | ||||
|     g.readonly = True | ||||
|  | @ -692,7 +675,7 @@ def _batch_columns(request, batch): | |||
|     smap = grids.get_sort_map( | ||||
|         rattail.BatchColumn, | ||||
|         ['ordinal', 'targeted']) | ||||
|     smap['column'] = grids.sorter(rattail.SilColumn.sil_name) | ||||
|     smap['sil_column'] = grids.sorter(rattail.SilColumn.sil_name) | ||||
|     smap['display'] = grids.sorter(rattail.SilColumn.display) | ||||
|     smap['source'] = grids.sorter(rattail.BatchTerminal.description) | ||||
| 
 | ||||
|  | @ -741,10 +724,7 @@ def batch_fieldset(batch, request): | |||
| 
 | ||||
|     # Remove unsupported action types...for now. | ||||
|     enum = rattail.BATCH_ACTION_TYPE.copy() | ||||
|     del enum[rattail.BATCH_ADD_REPLACE] | ||||
|     del enum[rattail.BATCH_CHANGE] | ||||
|     del enum[rattail.BATCH_LOAD] | ||||
|     del enum[rattail.BATCH_REMOVE] | ||||
| 
 | ||||
|     fs.configure( | ||||
|         include=[ | ||||
|  | @ -754,20 +734,21 @@ def batch_fieldset(batch, request): | |||
|             fs.dictionary.validate(forms.required), | ||||
|             fs.action_type.with_renderer(forms.EnumFieldRenderer(enum)).validate(forms.required).label("Action"), | ||||
|             fs.description, | ||||
|             fs.effective.with_renderer(forms.PrettyDateTimeFieldRenderer), | ||||
|             # fs.effective.with_renderer(forms.PrettyDateTimeFieldRenderer), | ||||
|             fs.rowcount.label("Rows").readonly(), | ||||
|             ]) | ||||
| 
 | ||||
|     if fs.edit: | ||||
|         fs.source.set(readonly=True) | ||||
|         fs.dictionary.set(readonly=True) | ||||
|         if fs.model.target: | ||||
|             fs.target.set(readonly=True) | ||||
|         fs.action_type.set(readonly=True) | ||||
|         fs.effective.set(readonly=True) | ||||
|         # if fs.model.target: | ||||
|         #     fs.target.set(readonly=True) | ||||
|         # fs.action_type.set(readonly=True) | ||||
|         # fs.effective.set(readonly=True) | ||||
|         fs.append(forms.ChildGridField('columns', _batch_columns(request, fs.model))) | ||||
|     else: | ||||
|         del fs.batch_id | ||||
|         del fs.effective | ||||
|         # del fs.effective | ||||
|         del fs.rowcount | ||||
|     return fs | ||||
| 
 | ||||
|  | @ -995,38 +976,13 @@ def execute(context, request): | |||
|     Executes a batch. | ||||
|     """ | ||||
| 
 | ||||
|     home = HTTPFound(location=request.route_url('batch.list')) | ||||
| 
 | ||||
|     # batch = self.request.params.get('uuid') | ||||
|     # batch = self.Session.query(rattail.Batch).get(batch) if batch else None | ||||
|     # if not batch: | ||||
|     #     return home | ||||
|     # print 'got a batch' | ||||
| 
 | ||||
|     uuid = request.matchdict['uuid'] | ||||
|     home = HTTPFound(location=request.route_url('batch.list')) | ||||
| 
 | ||||
|     with transaction.manager: | ||||
|         batch = Session.query(rattail.Batch).get(uuid) if uuid else None | ||||
|         if not batch: | ||||
|             return home | ||||
|     # print 'got a batch' | ||||
| 
 | ||||
|     # jct = batch.target_junction | ||||
|     # if not jct: | ||||
|     #     self.request.session.flash("Batch does not have a valid target") | ||||
|     #     return home | ||||
|     # print 'got a target' | ||||
| 
 | ||||
|     # if not batch.target: | ||||
|     #     request.session.flash("Batch does not have a valid target") | ||||
|     #     return home | ||||
| 
 | ||||
|     # jct = jct() | ||||
|     # if batch.dictionary == rattail.BATCH_MAIN_ITEM: | ||||
|     #     print 'exporting main item' | ||||
|     #     jct.export_main_item(batch, self.Session) | ||||
|     #     print 'exported main item' | ||||
| 
 | ||||
|         batch.execute() | ||||
| 
 | ||||
|     # table = batch.table | ||||
|  | @ -1053,10 +1009,10 @@ def includeme(config): | |||
|     config.add_route('batch_dictionary', '/batches/dictionary') | ||||
|     config.add_route('batch_dictionary.columns', '/batches/dictionary-columns') | ||||
| 
 | ||||
|     config.add_route('batch_terminal.list', '/batches/terminals') | ||||
|     config.add_route('batch_terminal.new', '/batches/terminal') | ||||
|     config.add_route('batch_terminal.delete', '/batches/terminal/{uuid}/delete') | ||||
|     config.add_route('batch_terminals', '/batches/terminals') | ||||
|     config.add_route('batch_terminal.new', '/batches/terminal/new') | ||||
|     config.add_route('batch_terminal.edit', '/batches/terminal/{uuid}/edit') | ||||
|     config.add_route('batch_terminal.delete', '/batches/terminal/{uuid}/delete') | ||||
|     config.add_route('batch_terminal.columns', '/batches/terminal/{uuid}/columns') | ||||
|     # config.add_route('batch_terminal', '/batches/terminal/{uuid}') | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,6 +26,8 @@ | |||
| ``rattail.pyramid.views.departments`` -- Department Views | ||||
| """ | ||||
| 
 | ||||
| import transaction | ||||
| from pyramid.httpexceptions import HTTPFound | ||||
| from pyramid.view import view_config | ||||
| 
 | ||||
| from edbob.pyramid import filters | ||||
|  | @ -36,7 +38,7 @@ from edbob.pyramid import Session | |||
| import rattail | ||||
| 
 | ||||
| 
 | ||||
| @view_config(route_name='department.list', renderer='/departments/index.mako') | ||||
| @view_config(route_name='departments.list', renderer='/departments/index.mako') | ||||
| def list_departments(context, request): | ||||
| 
 | ||||
|     fmap = filters.get_filter_map( | ||||
|  | @ -45,15 +47,15 @@ def list_departments(context, request): | |||
|         ilike=['name']) | ||||
| 
 | ||||
|     config = filters.get_search_config( | ||||
|         'department.list', request, fmap, | ||||
|         'departments.list', request, fmap, | ||||
|         include_filter_name=True, | ||||
|         filter_type_name='lk') | ||||
| 
 | ||||
|     search = filters.get_search_form(config) | ||||
| 
 | ||||
|     config = grids.get_grid_config( | ||||
|         'department.list', request, search, | ||||
|         filter_map=fmap, sort='name') | ||||
|         'departments.list', request, search, | ||||
|         filter_map=fmap, sort='name', deletable=True) | ||||
| 
 | ||||
|     smap = grids.get_sort_map( | ||||
|         rattail.Department, | ||||
|  | @ -68,7 +70,9 @@ def list_departments(context, request): | |||
|     departments = grids.get_pager(query, config) | ||||
|     g = forms.AlchemyGrid( | ||||
|         rattail.Department, departments, config, | ||||
|         gridurl=request.route_url('department.list')) | ||||
|         gridurl=request.route_url('departments.list'), | ||||
|         delurl='department.delete', | ||||
|         ) | ||||
| 
 | ||||
|     g.configure( | ||||
|         include=[ | ||||
|  | @ -77,10 +81,25 @@ def list_departments(context, request): | |||
|             ], | ||||
|         readonly=True) | ||||
| 
 | ||||
|     grid = g.render(class_='clickable departments') | ||||
|     grid = g.render(class_='hoverable departments') | ||||
|     return grids.render_grid(request, grid, search) | ||||
| 
 | ||||
| 
 | ||||
| @view_config(route_name='department.delete') | ||||
| def delete_department(context, request): | ||||
|     uuid = request.matchdict['uuid'] | ||||
|     dept = Session.query(rattail.Department).get(uuid) if uuid else None | ||||
|     assert dept | ||||
|     with transaction.manager: | ||||
|         q = Session.query(rattail.Product) | ||||
|         q = q.filter(rattail.Product.department_uuid == dept.uuid) | ||||
|         if q.count(): | ||||
|             q.update({'department_uuid': None}, synchronize_session=False) | ||||
|         Session.delete(dept) | ||||
|     return HTTPFound(location=request.route_url('departments.list')) | ||||
| 
 | ||||
| 
 | ||||
| def includeme(config): | ||||
|     config.add_route('department.list', '/departments') | ||||
|     config.add_route('departments.list', '/departments') | ||||
|     config.add_route('department.delete', '/department/{uuid}/delete') | ||||
|     config.scan(__name__) | ||||
|  |  | |||
|  | @ -28,6 +28,8 @@ | |||
| 
 | ||||
| from sqlalchemy.orm import joinedload | ||||
| 
 | ||||
| import transaction | ||||
| from pyramid.httpexceptions import HTTPFound | ||||
| from pyramid.view import view_config | ||||
| 
 | ||||
| from edbob.pyramid import filters | ||||
|  | @ -36,59 +38,79 @@ from edbob.pyramid import grids | |||
| from edbob.pyramid import Session | ||||
| 
 | ||||
| import rattail | ||||
| from rattail.batches import next_batch_id | ||||
| from rattail.pyramid import util | ||||
| from rattail.pyramid.forms import UpcFieldRenderer | ||||
| 
 | ||||
| 
 | ||||
| @view_config(route_name='products', renderer='/products/index.mako') | ||||
| def products(context, request): | ||||
| 
 | ||||
|     fmap = filters.get_filter_map( | ||||
| def filter_map(): | ||||
|     return filters.get_filter_map( | ||||
|         rattail.Product, | ||||
|         exact=['upc'], | ||||
|         ilike=['description'], | ||||
|         ilike=['description', 'size'], | ||||
|         department=filters.filter_ilike(rattail.Department.name), | ||||
|         brand=filters.filter_ilike(rattail.Brand.name)) | ||||
| 
 | ||||
|     config = filters.get_search_config( | ||||
|         'products', request, fmap, | ||||
| def search_config(request, fmap): | ||||
|     return filters.get_search_config( | ||||
|         'products.list', request, fmap, | ||||
|         include_filter_brand=True, | ||||
|         filter_type_brand='lk', | ||||
|         include_filter_description=True, | ||||
|         filter_type_description='lk') | ||||
|         filter_type_description='lk', | ||||
|         include_filter_department=True, | ||||
|         filter_type_department='lk') | ||||
| 
 | ||||
|     search = filters.get_search_form( | ||||
| def search_form(config): | ||||
|     return filters.get_search_form( | ||||
|         config, upc="UPC") | ||||
| 
 | ||||
|     config = grids.get_grid_config( | ||||
|         'products', request, search, | ||||
| def grid_config(request, search, fmap): | ||||
|     return grids.get_grid_config( | ||||
|         'products.list', request, search, | ||||
|         filter_map=fmap, sort='description') | ||||
| 
 | ||||
|     smap = grids.get_sort_map( | ||||
| def sort_map(): | ||||
|     return grids.get_sort_map( | ||||
|         rattail.Product, | ||||
|         ['upc', 'description'], | ||||
|         ['upc', 'description', 'size'], | ||||
|         department=grids.sorter(rattail.Department.name), | ||||
|         brand=grids.sorter(rattail.Brand.name)) | ||||
| 
 | ||||
| def query(config): | ||||
|     jmap = { | ||||
|         'brand': | ||||
|             lambda q: q.join(rattail.Brand), | ||||
|         'department':   lambda q: q.outerjoin(rattail.Department), | ||||
|         'brand':        lambda q: q.outerjoin(rattail.Brand), | ||||
|         } | ||||
|     smap = sort_map() | ||||
|     q = Session.query(rattail.Product) | ||||
|     q = q.options(joinedload(rattail.Product.department)) | ||||
|     q = q.options(joinedload(rattail.Product.brand)) | ||||
|     q = filters.filter_query(q, config, jmap) | ||||
|     q = grids.sort_query(q, config, smap, jmap) | ||||
|     return q | ||||
| 
 | ||||
|     def query(config): | ||||
|         q = Session.query(rattail.Product) | ||||
|         q = q.options(joinedload(rattail.Product.brand)) | ||||
|         q = filters.filter_query(q, config, jmap) | ||||
|         q = grids.sort_query(q, config, smap, jmap) | ||||
|         return q | ||||
| 
 | ||||
| @view_config(route_name='products.list', renderer='/products/index.mako') | ||||
| def products(context, request): | ||||
| 
 | ||||
|     fmap = filter_map() | ||||
|     config = search_config(request, fmap) | ||||
|     search = search_form(config) | ||||
|     config = grid_config(request, search, fmap) | ||||
|     products = grids.get_pager(query, config) | ||||
| 
 | ||||
|     g = forms.AlchemyGrid( | ||||
|         rattail.Product, products, config, | ||||
|         request.route_url('products')) | ||||
|         gridurl=request.route_url('products.list')) | ||||
| 
 | ||||
|     g.configure( | ||||
|         include=[ | ||||
|             g.upc.with_renderer(UpcFieldRenderer).label("UPC"), | ||||
|             g.brand, | ||||
|             g.description, | ||||
|             g.size, | ||||
|             g.department, | ||||
|             ], | ||||
|         readonly=True) | ||||
| 
 | ||||
|  | @ -96,6 +118,56 @@ def products(context, request): | |||
|     return grids.render_grid(request, grid, search) | ||||
| 
 | ||||
| 
 | ||||
| @view_config(route_name='products.batch') | ||||
| def batch(context, request): | ||||
| 
 | ||||
|     fmap = filter_map() | ||||
|     config = search_config(request, fmap) | ||||
|     search = search_form(config) | ||||
|     config = grid_config(request, search, fmap) | ||||
|     products = query(config) | ||||
| 
 | ||||
|     home = HTTPFound(location=request.route_url('products.list')) | ||||
| 
 | ||||
|     source = util.get_terminal('rattail') | ||||
|     if not source: | ||||
|         return home | ||||
| 
 | ||||
|     dct = util.get_dictionary('ITEM_DCT') | ||||
|     if not dct: | ||||
|         return home | ||||
| 
 | ||||
|     with transaction.manager: | ||||
|         batch = rattail.Batch() | ||||
|         Session.add(batch) | ||||
| 
 | ||||
|         batch.source = source | ||||
|         batch.source_description = source.description | ||||
|         batch.batch_id = next_batch_id(source.sil_id, consume=True, | ||||
|                                        session=Session()) | ||||
|         batch.name = '%s.%08u' % (source.sil_id, batch.batch_id) | ||||
|         batch.dictionary = dct | ||||
|         batch.action_type = rattail.BATCH_ADD | ||||
|         batch.description = "products from Rattail" | ||||
| 
 | ||||
|         for i, col in enumerate(source.source_columns(dct), 1): | ||||
|             batch.columns.append(rattail.BatchColumn( | ||||
|                     ordinal=i, | ||||
|                     sil_column=col.sil_column, | ||||
|                     source=source, | ||||
|                     targeted=True, | ||||
|                     )) | ||||
| 
 | ||||
|         batch.create_table() | ||||
|         batch.add_rows(source, dct, query=products) | ||||
|         batch.rowcount = products.count() | ||||
| 
 | ||||
|         url = request.route_url('batch.edit', uuid=batch.uuid) | ||||
| 
 | ||||
|     return HTTPFound(location=url) | ||||
| 
 | ||||
| 
 | ||||
| def includeme(config): | ||||
|     config.add_route('products', '/products') | ||||
|     config.add_route('products.list', '/products') | ||||
|     config.add_route('products.batch', '/products/batch') | ||||
|     config.scan(__name__) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar