diff --git a/tailbone/templates/newbatch/edit.mako b/tailbone/templates/newbatch/edit.mako
index 120ec8fa..ce1cbf42 100644
--- a/tailbone/templates/newbatch/edit.mako
+++ b/tailbone/templates/newbatch/edit.mako
@@ -50,11 +50,12 @@
- % if master.edit_with_rows:
- ${form.render(buttons=capture(buttons))|n}
- % else:
+## TODO: clean this up or fix etc..?
+## % if master.edit_with_rows:
+## ${form.render(buttons=capture(buttons))|n}
+## % else:
${form.render()|n}
- % endif
+## % endif
% if master.edit_with_rows:
diff --git a/tailbone/templates/newbatch/view.mako b/tailbone/templates/newbatch/view.mako
index 23e57b6b..f2b6ff2b 100644
--- a/tailbone/templates/newbatch/view.mako
+++ b/tailbone/templates/newbatch/view.mako
@@ -43,19 +43,11 @@
%def>
-<%def name="leading_buttons()">
-%def>
+<%def name="leading_buttons()">%def>
<%def name="refresh_button()">
-## TODO: the refreshable thing still seems confusing...
- % if master.refreshable:
- % if form.readonly:
- % if not batch.executed:
-
- % endif
- % elif batch.refreshable:
- ${h.submit('save-refresh', "Save & Refresh Data")}
- % endif
+ % if master.viewing and master.batch_refreshable(batch):
+
% endif
%def>
@@ -75,12 +67,14 @@
${rows_grid|n}
-
+% if not batch.executed:
+
- ${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
- % if master.has_execution_options:
- ${rendered_execution_options|n}
- % endif
- ${h.end_form()}
+ ${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
+ % if master.has_execution_options:
+ ${rendered_execution_options|n}
+ % endif
+ ${h.end_form()}
-
+
+% endif
diff --git a/tailbone/views/batch.py b/tailbone/views/batch.py
index d3912c93..8e3253ee 100644
--- a/tailbone/views/batch.py
+++ b/tailbone/views/batch.py
@@ -63,12 +63,13 @@ class BatchMasterView(MasterView):
"""
Base class for all "batch master" views.
"""
+ default_handler_spec = None
has_rows = True
rows_deletable = True
rows_downloadable = True
refreshable = True
refresh_after_create = False
- edit_with_rows = True
+ edit_with_rows = False
def __init__(self, request):
super(BatchMasterView, self).__init__(request)
@@ -92,7 +93,8 @@ class BatchMasterView(MasterView):
``batch_key`` attribute of the main batch model class.
"""
key = self.model_class.batch_key
- spec = self.rattail_config.get('rattail.batch', '{}.handler'.format(key))
+ spec = self.rattail_config.get('rattail.batch', '{}.handler'.format(key),
+ default=self.default_handler_spec)
if spec:
return load_object(spec)(self.rattail_config)
return self.batch_handler_class(self.rattail_config)
@@ -233,41 +235,34 @@ class BatchMasterView(MasterView):
delattr(fs, field)
def save_create_form(self, form):
- """
- 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.
- """
self.before_create(form)
- # Transfer form data to batch instance.
+ # transfer form data to batch instance
form.fieldset.sync()
batch = form.fieldset.model
- # Assign current user as creator.
- with Session.no_autoflush:
- batch.created_by = self.request.user or self.late_login_user()
+ # current user is batch creator
+ batch.created_by = self.request.user or self.late_login_user()
- # TODO: Wouldn't this be handled sufficiently by `no_autoflush` ?
- # Expunge batch from session to prevent it from being flushed
- # during init. This is done as a convenience to views which
- # provide an init method. Some batches may have required fields
- # which aren't filled in yet, but the view may need to query the
- # database to obtain the values. This will cause a session flush,
- # and the missing fields will trigger data integrity errors.
+ # destroy initial batch and re-make using handler
+ kwargs = self.get_batch_kwargs(batch)
Session.expunge(batch)
+ # TODO: is no_autoflush necessary?
+ with Session.no_autoflush:
+ batch = self.handler.make_batch(Session(), **kwargs)
- self.batch_inited = self.init_batch(batch)
- if self.batch_inited:
- Session.add(batch)
- Session.flush()
+ Session.flush()
- else: # batch init failed
+ # TODO: this needs work yet surely...
+ # if batch has input data file, let handler properly establish that
+ filename = getattr(batch, 'filename', None)
+ if filename:
+ path = os.path.join(self.upload_dir, filename)
+ self.handler.set_input_file(batch, path)
+ os.remove(path)
- # Here we assume that the :meth:`init_batch()` method responsible
- # for indicating the failure will have set a flash message for the
- # user with more info.
- raise self.redirect(self.request.current_route_url())
+ # return this object to replace the original
+ return batch
def init_batch(self, batch):
"""
@@ -283,9 +278,12 @@ class BatchMasterView(MasterView):
return True
def redirect_after_create(self, batch):
- if self.refresh_after_create:
+ if self.handler.requires_prefill(batch):
+ return self.redirect(self.get_action_url('prefill', batch))
+ elif self.refresh_after_create:
return self.redirect(self.get_action_url('refresh', batch))
- return super(BatchMasterView, self).redirect_after_create(batch)
+ else:
+ return self.redirect(self.get_action_url('view', batch))
# TODO: some of this at least can go to master now right?
def edit(self):
@@ -398,6 +396,22 @@ class BatchMasterView(MasterView):
def executable(self, batch):
return self.handler.executable(batch)
+ def batch_refreshable(self, batch):
+ """
+ Return a boolean indicating whether the given batch should allow a
+ refresh operation.
+ """
+ # TODO: deprecate/remove this?
+ if not self.refreshable:
+ return False
+
+ # (this is how it should be done i think..)
+ if callable(self.handler.refreshable):
+ return self.handler.refreshable(batch)
+
+ # TODO: deprecate/remove this
+ return self.handler.refreshable and not batch.executed
+
@property
def has_execution_options(self):
return bool(self.execution_options_schema)
@@ -419,7 +433,68 @@ class BatchMasterView(MasterView):
defaults=defaults or None)
def get_execute_title(self, batch):
- return self.handler.get_execute_title(batch)
+ if hasattr(self.handler, 'get_execute_title'):
+ return self.handler.get_execute_title(batch)
+ return "Execute this batch"
+
+ def prefill(self):
+ """
+ View which will attempt to prefill all data for the batch. What
+ exactly this means will depend on the type of batch etc.
+ """
+ batch = self.get_instance()
+ route_prefix = self.get_route_prefix()
+ permission_prefix = self.get_permission_prefix()
+
+ # showing progress requires a separate thread; start that first
+ progress_key = '{}.prefill'.format(route_prefix)
+ progress = SessionProgress(self.request, progress_key)
+ thread = Thread(target=self.prefill_thread, args=(batch.uuid, progress))
+ thread.start()
+
+ # Send user to progress page.
+ kwargs = {
+ 'key': progress_key,
+ 'cancel_url': self.get_action_url('view', batch),
+ 'cancel_msg': "Batch prefill was canceled.",
+ }
+
+ # TODO: This seems hacky...it exists for (only) one specific scenario.
+ if not self.request.has_perm('{}.view'.format(permission_prefix)):
+ kwargs['cancel_url'] = self.request.route_url('{}.create'.format(route_prefix))
+
+ return self.render_progress(kwargs)
+
+ def prefill_thread(self, batch_uuid, progress):
+ """
+ Thread target for prefilling batch data with progress indicator.
+ """
+ # mustn't use tailbone web session here
+ session = RattailSession()
+ batch = session.query(self.model_class).get(batch_uuid)
+ try:
+ self.handler.make_initial_rows(batch, progress=progress)
+ except Exception as error:
+ session.rollback()
+ log.warning("batch pre-fill failed: {}".format(batch), exc_info=True)
+ session.close()
+ if progress:
+ progress.session.load()
+ progress.session['error'] = True
+ progress.session['error_msg'] = "Batch pre-fill failed: {} {}".format(error.__class__.__name__, error)
+ progress.session.save()
+ return
+
+ session.commit()
+ session.refresh(batch)
+ session.close()
+
+ # finalize progress
+ if progress:
+ progress.session.load()
+ progress.session['complete'] = True
+ progress.session['success_url'] = self.get_action_url('view', batch)
+ progress.session.save()
def refresh(self):
"""
@@ -430,14 +505,16 @@ class BatchMasterView(MasterView):
route_prefix = self.get_route_prefix()
permission_prefix = self.get_permission_prefix()
+ # TODO: deprecate / remove this
cognizer = self.request.user
if not cognizer:
uuid = self.request.session.pop('late_login_user', None)
cognizer = Session.query(model.User).get(uuid) if uuid else None
+ # TODO: refresh should probably always imply/use progress
# If handler doesn't declare the need for progress indicator, things
# are nice and simple.
- if not self.handler.show_progress:
+ if not getattr(self.handler, 'show_progress', True):
self.refresh_data(Session, batch, cognizer=cognizer)
self.request.session.flash("Batch data has been refreshed.")
@@ -479,9 +556,14 @@ class BatchMasterView(MasterView):
"""
Instruct the batch handler to refresh all data for the batch.
"""
- self.handler.refresh_data(session, batch, progress=progress)
- batch.cognized = datetime.datetime.utcnow()
- batch.cognized_by = cognizer or session.merge(self.request.user)
+ # TODO: deprecate/remove this
+ if hasattr(self.handler, 'refresh_data'):
+ self.handler.refresh_data(session, batch, progress=progress)
+ batch.cognized = datetime.datetime.utcnow()
+ batch.cognized_by = cognizer or session.merge(self.request.user)
+
+ else: # the future
+ self.handler.refresh(batch, progress=progress)
def refresh_thread(self, batch_uuid, progress=None, cognizer_uuid=None, success_url=None):
"""
@@ -744,6 +826,11 @@ class BatchMasterView(MasterView):
# else the perm group label will not display correctly...
config.add_tailbone_permission_group(permission_prefix, model_title_plural, overwrite=False)
+ # prefill row data
+ config.add_route('{}.prefill'.format(route_prefix), '{}/{{uuid}}/prefill'.format(url_prefix))
+ config.add_view(cls, attr='prefill', route_name='{}.prefill'.format(route_prefix),
+ permission='{}.create'.format(permission_prefix))
+
# refresh rows data
config.add_route('{}.refresh'.format(route_prefix), '{}/{{uuid}}/refresh'.format(url_prefix))
config.add_view(cls, attr='refresh', route_name='{}.refresh'.format(route_prefix),
@@ -835,46 +922,15 @@ class FileBatchMasterView(BatchMasterView):
fs.filename,
])
- def save_create_form(self, form):
- self.before_create(form)
-
- # Transfer form data to batch instance.
- form.fieldset.sync()
- batch = form.fieldset.model
-
- # Assign current user as creator.
- with Session.no_autoflush:
- batch.created_by = self.request.user or self.late_login_user()
-
- # TODO: Wouldn't this be handled sufficiently by `no_autoflush` ?
- # Expunge batch from session to prevent it from being flushed
- # during init. This is done as a convenience to views which
- # provide an init method. Some batches may have required fields
- # which aren't filled in yet, but the view may need to query the
- # database to obtain the values. This will cause a session flush,
- # and the missing fields will trigger data integrity errors.
- Session.expunge(batch)
-
- self.batch_inited = self.init_batch(batch)
-
- if self.batch_inited:
- Session.add(batch)
- Session.flush()
-
- # Handler saves a copy of the file and updates the batch filename.
- path = os.path.join(self.upload_dir, batch.filename)
- self.handler.set_data_file(batch, path)
- os.remove(path)
-
- else: # batch init failed
-
- # Here we assume that the :meth:`init_batch()` method responsible
- # for indicating the failure will have set a flash message for the
- # user with more info.
- raise self.redirect(self.request.current_route_url())
-
- def redirect_after_create(self, batch):
- return self.redirect(self.get_action_url('refresh', batch))
+ def get_batch_kwargs(self, batch):
+ """
+ Return a kwargs dict for use with ``self.handler.make_batch()``, using
+ the given batch as a template.
+ """
+ kwargs = {'created_by': batch.created_by}
+ if hasattr(batch, 'filename'):
+ kwargs['filename'] = batch.filename
+ return kwargs
def download(self):
"""
@@ -902,6 +958,10 @@ class FileBatchMasterView(BatchMasterView):
url_prefix = cls.get_url_prefix()
permission_prefix = cls.get_permission_prefix()
model_title = cls.get_model_title()
+ model_title_plural = cls.get_model_title_plural()
+
+ # fix permission group title
+ config.add_tailbone_permission_group(permission_prefix, model_title_plural)
# download batch data file
config.add_route('{}.download'.format(route_prefix), '{}/{{uuid}}/download'.format(url_prefix))
diff --git a/tailbone/views/core.py b/tailbone/views/core.py
index b0a17c63..f39cdc92 100644
--- a/tailbone/views/core.py
+++ b/tailbone/views/core.py
@@ -41,6 +41,7 @@ class View(object):
def __init__(self, request):
self.request = request
+ self.enum = self.rattail_config.get_enum()
@property
def rattail_config(self):
diff --git a/tailbone/views/handheld.py b/tailbone/views/handheld.py
index de3a3656..2b02284f 100644
--- a/tailbone/views/handheld.py
+++ b/tailbone/views/handheld.py
@@ -26,9 +26,10 @@ Views for handheld batches
from __future__ import unicode_literals, absolute_import
+import os
+
from rattail import enum
from rattail.db import model
-from rattail.db.batch.handheld.handler import HandheldBatchHandler
from rattail.util import OrderedDict
import formalchemy as fa
@@ -36,6 +37,7 @@ import formencode as fe
from webhelpers.html import tags
from tailbone import forms
+from tailbone.db import Session
from tailbone.views.batch import FileBatchMasterView
@@ -71,47 +73,63 @@ class HandheldBatchView(FileBatchMasterView):
Master view for handheld batches.
"""
model_class = model.HandheldBatch
+ default_handler_spec = 'rattail.batch.handheld:HandheldBatchHandler'
model_title_plural = "Handheld Batches"
- batch_handler_class = HandheldBatchHandler
route_prefix = 'batch.handheld'
url_prefix = '/batch/handheld'
execution_options_schema = ExecutionOptions
editable = False
- refreshable = False
model_row_class = model.HandheldBatchRow
rows_creatable = False
rows_editable = True
def configure_grid(self, g):
+ enum = self.rattail_config.get_enum()
g.configure(
include=[
g.id,
+ g.device_type.with_renderer(forms.renderers.EnumFieldRenderer(enum.HANDHELD_DEVICE_TYPE)),
+ g.device_name,
g.created,
g.created_by,
- g.device_name,
g.executed,
- g.executed_by,
],
readonly=True)
def configure_fieldset(self, fs):
- fs.configure(
- include=[
- fs.id,
- fs.created,
- fs.created_by,
- fs.filename,
- fs.device_type.with_renderer(forms.renderers.EnumFieldRenderer(enum.HANDHELD_DEVICE_TYPE)),
- fs.device_name,
- fs.executed,
- fs.executed_by,
- ])
+ fs.device_type.set(renderer=forms.renderers.EnumFieldRenderer(enum.HANDHELD_DEVICE_TYPE))
+
if self.creating:
- del fs.id
- elif self.viewing and fs.model.inventory_batch:
+ fs.configure(
+ include=[
+ fs.filename,
+ fs.device_type,
+ fs.device_name,
+ ])
+
+ else:
+ fs.configure(
+ include=[
+ fs.id,
+ fs.device_type,
+ fs.device_name,
+ fs.filename,
+ fs.created,
+ fs.created_by,
+ fs.executed,
+ fs.executed_by,
+ ])
+
+ if self.viewing and fs.model.inventory_batch:
fs.append(fa.Field('inventory_batch', value=fs.model.inventory_batch, renderer=InventoryBatchFieldRenderer))
+ def get_batch_kwargs(self, batch):
+ kwargs = super(HandheldBatchView, self).get_batch_kwargs(batch)
+ kwargs['device_type'] = batch.device_type
+ kwargs['device_name'] = batch.device_name
+ return kwargs
+
def configure_row_grid(self, g):
g.configure(
include=[
@@ -167,16 +185,6 @@ class HandheldBatchView(FileBatchMasterView):
return self.request.route_url('labels.batch.view', uuid=result.uuid)
return super(HandheldBatchView, self).get_execute_success_url(batch)
- @classmethod
- def defaults(cls, config):
-
- # fix permission group title
- config.add_tailbone_permission_group('batch.handheld', "Handheld Batches")
-
- cls._filebatch_defaults(config)
- cls._batch_defaults(config)
- cls._defaults(config)
-
def includeme(config):
HandheldBatchView.defaults(config)
diff --git a/tailbone/views/inventory.py b/tailbone/views/inventory.py
index fa58d5ff..e3aa9abe 100644
--- a/tailbone/views/inventory.py
+++ b/tailbone/views/inventory.py
@@ -26,9 +26,7 @@ Views for inventory batches
from __future__ import unicode_literals, absolute_import
-from rattail import enum
from rattail.db import model
-from rattail.db.batch.inventory.handler import InventoryBatchHandler
from tailbone import forms
from tailbone.views.batch import BatchMasterView
@@ -40,19 +38,18 @@ class InventoryBatchView(BatchMasterView):
"""
model_class = model.InventoryBatch
model_title_plural = "Inventory Batches"
- batch_handler_class = InventoryBatchHandler
+ default_handler_spec = 'rattail.batch.inventory:InventoryBatchHandler'
route_prefix = 'batch.inventory'
url_prefix = '/batch/inventory'
creatable = False
editable = False
- refreshable = False
model_row_class = model.InventoryBatchRow
rows_editable = True
def _preconfigure_grid(self, g):
super(InventoryBatchView, self)._preconfigure_grid(g)
- g.mode.set(renderer=forms.renderers.EnumFieldRenderer(enum.INVENTORY_MODE),
+ g.mode.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.INVENTORY_MODE),
label="Count Mode")
def configure_grid(self, g):
@@ -62,7 +59,7 @@ class InventoryBatchView(BatchMasterView):
def _preconfigure_fieldset(self, fs):
super(InventoryBatchView, self)._preconfigure_fieldset(fs)
fs.handheld_batch.set(renderer=forms.renderers.HandheldBatchFieldRenderer, readonly=True)
- fs.mode.set(renderer=forms.renderers.EnumFieldRenderer(enum.INVENTORY_MODE),
+ fs.mode.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.INVENTORY_MODE),
label="Count Mode")
def configure_fieldset(self, fs):
@@ -124,15 +121,6 @@ class InventoryBatchView(BatchMasterView):
fs.units,
])
- @classmethod
- def defaults(cls, config):
-
- # fix permission group title
- config.add_tailbone_permission_group('batch.inventory', "Inventory Batches")
-
- cls._batch_defaults(config)
- cls._defaults(config)
-
def includeme(config):
InventoryBatchView.defaults(config)
diff --git a/tailbone/views/labels/batch.py b/tailbone/views/labels/batch.py
index f3092853..8c3f06d2 100644
--- a/tailbone/views/labels/batch.py
+++ b/tailbone/views/labels/batch.py
@@ -27,7 +27,6 @@ Views for label batches
from __future__ import unicode_literals, absolute_import
from rattail.db import model
-from rattail.db.batch.labels.handler import LabelBatchHandler
from tailbone import forms
from tailbone.views.batch import BatchMasterView
@@ -39,7 +38,7 @@ class LabelBatchView(BatchMasterView):
"""
model_class = model.LabelBatch
model_row_class = model.LabelBatchRow
- batch_handler_class = LabelBatchHandler
+ default_handler_spec = 'rattail.batch.labels:LabelBatchHandler'
model_title_plural = "Label Batches"
route_prefix = 'labels.batch'
url_prefix = '/labels/batches'
@@ -61,6 +60,9 @@ class LabelBatchView(BatchMasterView):
fs.executed,
fs.executed_by,
])
+ batch = fs.model
+ if self.viewing and not batch.handheld_batch:
+ del fs.handheld_batch
def _preconfigure_row_grid(self, g):
super(LabelBatchView, self)._preconfigure_row_grid(g)
diff --git a/tailbone/views/master.py b/tailbone/views/master.py
index cb47a25e..4e8c286d 100644
--- a/tailbone/views/master.py
+++ b/tailbone/views/master.py
@@ -128,12 +128,12 @@ class MasterView(View):
form = self.make_form(self.get_model_class())
if self.request.method == 'POST':
if form.validate():
- self.save_create_form(form)
- instance = form.fieldset.model
- self.after_create(instance)
+ # let save_create_form() return alternate object if necessary
+ obj = self.save_create_form(form) or form.fieldset.model
+ self.after_create(obj)
self.request.session.flash("{} has been created: {}".format(
- self.get_model_title(), self.get_instance_title(instance)))
- return self.redirect_after_create(instance)
+ self.get_model_title(), self.get_instance_title(obj)))
+ return self.redirect_after_create(obj)
return self.render_to_response('create', {'form': form})
def save_create_form(self, form):
diff --git a/tailbone/views/products.py b/tailbone/views/products.py
index ccd167ec..f9a1206a 100644
--- a/tailbone/views/products.py
+++ b/tailbone/views/products.py
@@ -38,6 +38,7 @@ from rattail.gpc import GPC
from rattail.threads import Thread
from rattail.exceptions import LabelPrintingError
from rattail.util import load_object
+from rattail.batch import get_batch_handler
import formalchemy as fa
from pyramid import httpexceptions
@@ -349,15 +350,14 @@ class ProductsView(MasterView):
# okay then, new-style it is
# TODO: make this more configurable surely..?
supported = {
- 'labels': 'rattail.db.batch.labels.handler:LabelBatchHandler',
+ 'labels': 'rattail.batch.labels:LabelBatchHandler',
}
if self.request.method == 'POST':
batch_key = self.request.POST.get('batch_type')
if batch_key and batch_key in supported:
- handler_spec = self.rattail_config.get('rattail.batch', '{}.handler'.format(batch_key),
- default=supported[batch_key])
- handler = load_object(handler_spec)(self.rattail_config)
+ handler = get_batch_handler(self.rattail_config, batch_key,
+ default=supported[batch_key])
progress = SessionProgress(self.request, 'products.batch')
thread = Thread(target=self.make_batch_thread,
@@ -372,7 +372,7 @@ class ProductsView(MasterView):
batch_types = []
for key, spec in supported.iteritems():
handler = load_object(spec)(self.rattail_config)
- batch_types.append((key, handler.model_title))
+ batch_types.append((key, handler.get_model_title()))
return {'supported_batches': batch_types}
@@ -384,11 +384,9 @@ class ProductsView(MasterView):
user = session.query(model.User).get(user_uuid)
assert user
products = self.get_effective_query(session)
- batch = handler.make_batch(session, created_by=user, products=products, progress=progress)
- if not batch:
- session.rollback()
- session.close()
- return
+ batch = handler.make_batch(session, created_by=user)
+ batch.products = products.all()
+ handler.make_initial_rows(batch, progress=progress)
session.commit()
session.refresh(batch)
diff --git a/tailbone/views/purchases/batch.py b/tailbone/views/purchases/batch.py
index 2d0f7d79..b7ba9be7 100644
--- a/tailbone/views/purchases/batch.py
+++ b/tailbone/views/purchases/batch.py
@@ -31,7 +31,6 @@ from sqlalchemy import orm
from rattail import enum
from rattail.db import model, api
from rattail.gpc import GPC
-from rattail.db.batch.purchase.handler import PurchaseBatchHandler
from rattail.time import localtime
from rattail.core import Object
from rattail.util import OrderedDict
@@ -50,7 +49,7 @@ class PurchaseBatchView(BatchMasterView):
model_class = model.PurchaseBatch
model_title_plural = "Purchase Batches"
model_row_class = model.PurchaseBatchRow
- batch_handler_class = PurchaseBatchHandler
+ default_handler_spec = 'rattail.batch.purchase:PurchaseBatchHandler'
route_prefix = 'purchases.batch'
url_prefix = '/purchases/batches'
rows_creatable = True
diff --git a/tailbone/views/vendors/catalogs.py b/tailbone/views/vendors/catalogs.py
index caa41c35..a08ad614 100644
--- a/tailbone/views/vendors/catalogs.py
+++ b/tailbone/views/vendors/catalogs.py
@@ -29,7 +29,6 @@ from __future__ import unicode_literals, absolute_import
import logging
from rattail.db import model, api
-from rattail.db.batch.vendorcatalog.handler import VendorCatalogHandler
from rattail.vendors.catalogs import iter_catalog_parsers
import formalchemy
@@ -48,7 +47,7 @@ class VendorCatalogsView(FileBatchMasterView):
"""
model_class = model.VendorCatalog
model_row_class = model.VendorCatalogRow
- batch_handler_class = VendorCatalogHandler
+ default_handler_spec = 'rattail.batch.vendorcatalog:VendorCatalogHandler'
url_prefix = '/vendors/catalogs'
editable = False
@@ -105,6 +104,15 @@ class VendorCatalogsView(FileBatchMasterView):
fs.executed_by,
])
+ def get_batch_kwargs(self, batch):
+ kwargs = super(VendorCatalogsView, self).get_batch_kwargs(batch)
+ kwargs['parser_key'] = batch.parser_key
+ if batch.vendor:
+ kwargs['vendor'] = batch.vendor
+ elif batch.vendor_uuid:
+ kwargs['vendor_uuid'] = batch.vendor_uuid
+ return kwargs
+
def configure_row_grid(self, g):
g.configure(
include=[
@@ -146,16 +154,6 @@ class VendorCatalogsView(FileBatchMasterView):
kwargs['parsers'] = parsers
return kwargs
- @classmethod
- def defaults(cls, config):
-
- # fix permission group title
- config.add_tailbone_permission_group('vendorcatalogs', "Vendor Catalogs")
-
- cls._filebatch_defaults(config)
- cls._batch_defaults(config)
- cls._defaults(config)
-
def includeme(config):
VendorCatalogsView.defaults(config)
diff --git a/tailbone/views/vendors/invoices.py b/tailbone/views/vendors/invoices.py
index e1a89906..4ab379e1 100644
--- a/tailbone/views/vendors/invoices.py
+++ b/tailbone/views/vendors/invoices.py
@@ -27,7 +27,6 @@ Views for maintaining vendor invoices
from __future__ import unicode_literals, absolute_import
from rattail.db import model, api
-from rattail.db.batch.vendorinvoice.handler import VendorInvoiceHandler
from rattail.vendors.invoices import iter_invoice_parsers, require_invoice_parser
import formalchemy
@@ -42,7 +41,7 @@ class VendorInvoicesView(FileBatchMasterView):
"""
model_class = model.VendorInvoice
model_row_class = model.VendorInvoiceRow
- batch_handler_class = VendorInvoiceHandler
+ default_handler_spec = 'rattail.batch.vendorinvoice:VendorInvoiceHandler'
url_prefix = '/vendors/invoices'
def get_instance_title(self, batch):
@@ -109,6 +108,11 @@ class VendorInvoicesView(FileBatchMasterView):
except ValueError as error:
raise formalchemy.ValidationError(unicode(error))
+ def get_batch_kwargs(self, batch):
+ kwargs = super(VendorInvoicesView, self).get_batch_kwargs(batch)
+ kwargs['parser_key'] = batch.parser_key
+ return kwargs
+
def init_batch(self, batch):
parser = require_invoice_parser(batch.parser_key)
vendor = api.get_vendor(Session(), parser.vendor_key)
@@ -148,16 +152,6 @@ class VendorInvoicesView(FileBatchMasterView):
attrs['class_'] = 'warning'
return attrs
- @classmethod
- def defaults(cls, config):
-
- # fix permission group title
- config.add_tailbone_permission_group('vendorinvoices', "Vendor Invoices")
-
- cls._filebatch_defaults(config)
- cls._batch_defaults(config)
- cls._defaults(config)
-
def includeme(config):
VendorInvoicesView.defaults(config)