Wrap up initial vendor catalog batch support etc.
* Adds the ability to delete all batch rows matching current query. * Refactors some progress factory args. * If batch initialization fails, don't persist batch.
This commit is contained in:
parent
c28a6b2e09
commit
16be06821a
|
@ -7,6 +7,11 @@
|
||||||
${search.render()}
|
${search.render()}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="tools">
|
||||||
|
<p>${h.link_to("Delete all rows matching current search", url('{0}.rows.bulk_delete'.format(route_prefix), uuid=batch.uuid))}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
${grid}
|
${grid}
|
||||||
|
|
|
@ -473,11 +473,11 @@ class BatchCrud(BaseCrud):
|
||||||
}
|
}
|
||||||
return render_to_response('/progress.mako', kwargs, request=self.request)
|
return render_to_response('/progress.mako', kwargs, request=self.request)
|
||||||
|
|
||||||
def refresh_data(self, session, batch, progress_factory=None):
|
def refresh_data(self, session, batch, progress=None):
|
||||||
"""
|
"""
|
||||||
Instruct the batch handler to refresh all data for the batch.
|
Instruct the batch handler to refresh all data for the batch.
|
||||||
"""
|
"""
|
||||||
self.handler.refresh_data(session, batch, progress_factory=progress_factory)
|
self.handler.refresh_data(session, batch, progress=progress)
|
||||||
batch.cognized = datetime.datetime.utcnow()
|
batch.cognized = datetime.datetime.utcnow()
|
||||||
batch.cognized_by = self.request.user
|
batch.cognized_by = self.request.user
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ class BatchCrud(BaseCrud):
|
||||||
# transaction binding etc.
|
# transaction binding etc.
|
||||||
session = RatSession()
|
session = RatSession()
|
||||||
batch = session.query(self.batch_class).get(batch_uuid)
|
batch = session.query(self.batch_class).get(batch_uuid)
|
||||||
self.refresh_data(session, batch, progress_factory=progress)
|
self.refresh_data(session, batch, progress=progress)
|
||||||
session.commit()
|
session.commit()
|
||||||
session.refresh(batch)
|
session.refresh(batch)
|
||||||
session.close()
|
session.close()
|
||||||
|
@ -591,7 +591,9 @@ class FileBatchCrud(BatchCrud):
|
||||||
|
|
||||||
def save_form(self, form):
|
def save_form(self, form):
|
||||||
"""
|
"""
|
||||||
Save the uploaded data file if necessary, etc.
|
Save the uploaded data file if necessary, etc. If batch initialization
|
||||||
|
fails, don't persist the batch at all; the user will be sent back to
|
||||||
|
the "create batch" page in that case.
|
||||||
"""
|
"""
|
||||||
# Transfer form data to batch instance.
|
# Transfer form data to batch instance.
|
||||||
form.fieldset.sync()
|
form.fieldset.sync()
|
||||||
|
@ -603,7 +605,8 @@ class FileBatchCrud(BatchCrud):
|
||||||
batch.filename = form.fieldset.data_file.renderer._filename
|
batch.filename = form.fieldset.data_file.renderer._filename
|
||||||
# Expunge batch from session to prevent it from being flushed.
|
# Expunge batch from session to prevent it from being flushed.
|
||||||
Session.expunge(batch)
|
Session.expunge(batch)
|
||||||
self.init_batch(batch)
|
self.batch_inited = self.init_batch(batch)
|
||||||
|
if self.batch_inited:
|
||||||
Session.add(batch)
|
Session.add(batch)
|
||||||
batch.write_file(self.request.rattail_config, form.fieldset.data_file.value)
|
batch.write_file(self.request.rattail_config, form.fieldset.data_file.value)
|
||||||
|
|
||||||
|
@ -613,7 +616,24 @@ class FileBatchCrud(BatchCrud):
|
||||||
effectively provide default values for a batch, etc. This method is
|
effectively provide default values for a batch, etc. This method is
|
||||||
invoked after a batch has been fully prepared for insertion to the
|
invoked after a batch has been fully prepared for insertion to the
|
||||||
database, but before the push to the database occurs.
|
database, but before the push to the database occurs.
|
||||||
|
|
||||||
|
Note that the return value of this function matters; if it is boolean
|
||||||
|
false then the batch will not be persisted at all, and the user will be
|
||||||
|
redirected to the "create batch" page.
|
||||||
"""
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def post_save(self, form):
|
||||||
|
"""
|
||||||
|
This checks for failed batch initialization when creating a new batch.
|
||||||
|
If a failure is detected, the user is redirected to the page for
|
||||||
|
creating new batches. The assumption here is that the
|
||||||
|
:meth:`init_batch()` method responsible for indicating the failure will
|
||||||
|
have set a flash message for the user with more info.
|
||||||
|
"""
|
||||||
|
if self.creating and not self.batch_inited:
|
||||||
|
return HTTPFound(location=self.request.route_url(
|
||||||
|
'{0}.create'.format(self.route_prefix)))
|
||||||
|
|
||||||
def post_save_url(self, form):
|
def post_save_url(self, form):
|
||||||
"""
|
"""
|
||||||
|
@ -632,7 +652,8 @@ class FileBatchCrud(BatchCrud):
|
||||||
|
|
||||||
class BatchRowGrid(BaseGrid):
|
class BatchRowGrid(BaseGrid):
|
||||||
"""
|
"""
|
||||||
Base grid view for batch rows, which can be filtered and sorted.
|
Base grid view for batch rows, which can be filtered and sorted. Also it
|
||||||
|
can delete all rows matching the current list view query.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -734,6 +755,22 @@ class BatchRowGrid(BaseGrid):
|
||||||
def tr_class(self, row, i):
|
def tr_class(self, row, i):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def render_kwargs(self):
|
||||||
|
"""
|
||||||
|
Add the current batch and route prefix to the template context.
|
||||||
|
"""
|
||||||
|
return {'batch': self.current_batch(),
|
||||||
|
'route_prefix': self.route_prefix}
|
||||||
|
|
||||||
|
def bulk_delete(self):
|
||||||
|
"""
|
||||||
|
Delete all rows matching the current row grid view query.
|
||||||
|
"""
|
||||||
|
self.query().delete()
|
||||||
|
return HTTPFound(location=self.request.route_url(
|
||||||
|
'{0}.view'.format(self.route_prefix),
|
||||||
|
uuid=self.request.matchdict['uuid']))
|
||||||
|
|
||||||
|
|
||||||
class ProductBatchRowGrid(BatchRowGrid):
|
class ProductBatchRowGrid(BatchRowGrid):
|
||||||
"""
|
"""
|
||||||
|
@ -851,6 +888,11 @@ def defaults(config, batch_grid, batch_crud, row_grid, row_crud, url_prefix,
|
||||||
renderer='/batch/rows.mako',
|
renderer='/batch/rows.mako',
|
||||||
permission='{0}.view'.format(permission_prefix))
|
permission='{0}.view'.format(permission_prefix))
|
||||||
|
|
||||||
|
# Bulk delete batch rows
|
||||||
|
config.add_route('{0}.rows.bulk_delete'.format(route_prefix), '{0}{{uuid}}/rows/delete'.format(url_prefix))
|
||||||
|
config.add_view(row_grid, attr='bulk_delete', route_name='{0}.rows.bulk_delete'.format(route_prefix),
|
||||||
|
permission='{0}.delete'.format(permission_prefix))
|
||||||
|
|
||||||
# Delete batch row
|
# Delete batch row
|
||||||
config.add_route('{0}.rows.delete'.format(route_prefix), '{0}delete-row/{{uuid}}'.format(url_prefix))
|
config.add_route('{0}.rows.delete'.format(route_prefix), '{0}delete-row/{{uuid}}'.format(url_prefix))
|
||||||
config.add_view(row_crud, attr='delete', route_name='{0}.rows.delete'.format(route_prefix),
|
config.add_view(row_crud, attr='delete', route_name='{0}.rows.delete'.format(route_prefix),
|
||||||
|
|
|
@ -169,6 +169,8 @@ class SearchableAlchemyGridView(PagedAlchemyGridView):
|
||||||
|
|
||||||
def modify_query(self, query):
|
def modify_query(self, query):
|
||||||
join_map = self.join_map()
|
join_map = self.join_map()
|
||||||
|
if not hasattr(self, '_filter_config'):
|
||||||
|
self._filter_config = self.filter_config()
|
||||||
query = grids.search.filter_query(
|
query = grids.search.filter_query(
|
||||||
query, self._filter_config, self.filter_map(), join_map)
|
query, self._filter_config, self.filter_map(), join_map)
|
||||||
if hasattr(self, '_sort_config'):
|
if hasattr(self, '_sort_config'):
|
||||||
|
|
9
tailbone/views/vendors/catalogs.py
vendored
9
tailbone/views/vendors/catalogs.py
vendored
|
@ -26,6 +26,8 @@ Views for maintaining vendor catalogs
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from pyramid.httpexceptions import HTTPFound
|
||||||
|
|
||||||
from rattail.db import model
|
from rattail.db import model
|
||||||
from rattail.db.api import get_setting, get_vendor
|
from rattail.db.api import get_setting, get_vendor
|
||||||
from rattail.db.batch.vendorcatalog import VendorCatalog, VendorCatalogRow
|
from rattail.db.batch.vendorcatalog import VendorCatalog, VendorCatalogRow
|
||||||
|
@ -129,7 +131,12 @@ class VendorCatalogCrud(FileBatchCrud):
|
||||||
|
|
||||||
def init_batch(self, batch):
|
def init_batch(self, batch):
|
||||||
parser = require_catalog_parser(batch.parser_key)
|
parser = require_catalog_parser(batch.parser_key)
|
||||||
batch.vendor = get_vendor(Session, parser.vendor_key)
|
vendor = get_vendor(Session, parser.vendor_key)
|
||||||
|
if not vendor:
|
||||||
|
self.request.session.flash("No vendor setting found in database for key: {0}".format(parser.vendor_key))
|
||||||
|
return False
|
||||||
|
batch.vendor = vendor
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class VendorCatalogRowGrid(BatchRowGrid):
|
class VendorCatalogRowGrid(BatchRowGrid):
|
||||||
|
|
Loading…
Reference in a new issue