Refactor batch views / templates per rattail framework overhaul
This commit is contained in:
parent
a5184e416a
commit
203f0242fb
|
@ -50,11 +50,12 @@
|
|||
</ul>
|
||||
|
||||
<div class="form-wrapper">
|
||||
% 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
|
||||
</div>
|
||||
|
||||
% if master.edit_with_rows:
|
||||
|
|
|
@ -43,19 +43,11 @@
|
|||
</div>
|
||||
</%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:
|
||||
<button type="button" id="refresh-data">Refresh Data</button>
|
||||
% endif
|
||||
% elif batch.refreshable:
|
||||
${h.submit('save-refresh', "Save & Refresh Data")}
|
||||
% endif
|
||||
% if master.viewing and master.batch_refreshable(batch):
|
||||
<button type="button" id="refresh-data">Refresh data</button>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
|
@ -75,6 +67,7 @@
|
|||
|
||||
${rows_grid|n}
|
||||
|
||||
% if not batch.executed:
|
||||
<div id="execution-options-dialog" style="display: none;">
|
||||
|
||||
${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
|
||||
|
@ -84,3 +77,4 @@ ${rows_grid|n}
|
|||
${h.end_form()}
|
||||
|
||||
</div>
|
||||
% endif
|
||||
|
|
|
@ -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:
|
||||
# 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()
|
||||
|
||||
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):
|
||||
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,10 +556,15 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
Instruct the batch handler to refresh all data for the batch.
|
||||
"""
|
||||
# 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):
|
||||
"""
|
||||
Thread target for refreshing batch data with progress indicator.
|
||||
|
@ -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))
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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.device_type.set(renderer=forms.renderers.EnumFieldRenderer(enum.HANDHELD_DEVICE_TYPE))
|
||||
|
||||
if self.creating:
|
||||
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.filename,
|
||||
fs.device_type.with_renderer(forms.renderers.EnumFieldRenderer(enum.HANDHELD_DEVICE_TYPE)),
|
||||
fs.device_name,
|
||||
fs.executed,
|
||||
fs.executed_by,
|
||||
])
|
||||
if self.creating:
|
||||
del fs.id
|
||||
elif self.viewing and fs.model.inventory_batch:
|
||||
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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),
|
||||
handler = get_batch_handler(self.rattail_config, batch_key,
|
||||
default=supported[batch_key])
|
||||
handler = load_object(handler_spec)(self.rattail_config)
|
||||
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
22
tailbone/views/vendors/catalogs.py
vendored
22
tailbone/views/vendors/catalogs.py
vendored
|
@ -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)
|
||||
|
|
18
tailbone/views/vendors/invoices.py
vendored
18
tailbone/views/vendors/invoices.py
vendored
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue