Add "most of" support for truck dump receiving
still not complete, but conceptually it sort of is...
This commit is contained in:
parent
805a1afa3f
commit
cd7922f204
8 changed files with 368 additions and 76 deletions
|
@ -42,11 +42,9 @@ from rattail.util import load_object, prettify
|
|||
|
||||
import colander
|
||||
import deform
|
||||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from pyramid.renderers import render_to_response
|
||||
from pyramid.response import FileResponse
|
||||
from pyramid_deform import SessionFileUploadTempStore
|
||||
from webhelpers2.html import HTML, tags
|
||||
|
||||
from tailbone import forms, grids
|
||||
|
@ -131,6 +129,9 @@ class BatchMasterView(MasterView):
|
|||
return load_object(spec)(self.rattail_config)
|
||||
return self.batch_handler_class(self.rattail_config)
|
||||
|
||||
def download_path(self, batch, filename):
|
||||
return self.rattail_config.batch_filepath(batch.batch_key, batch.uuid, filename)
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
batch = kwargs['instance']
|
||||
kwargs['batch'] = batch
|
||||
|
@ -140,6 +141,8 @@ class BatchMasterView(MasterView):
|
|||
if kwargs['execute_enabled']:
|
||||
url = self.get_action_url('execute', batch)
|
||||
kwargs['execute_form'] = self.make_execute_form(batch, action_url=url)
|
||||
else:
|
||||
kwargs['why_not_execute'] = self.handler.why_not_execute(batch)
|
||||
return kwargs
|
||||
|
||||
def allow_worksheet(self, batch):
|
||||
|
@ -278,9 +281,6 @@ class BatchMasterView(MasterView):
|
|||
return status_code_text
|
||||
return render_status
|
||||
|
||||
def download_path(self, batch, filename):
|
||||
return self.rattail_config.batch_filepath(batch.batch_key, batch.uuid, filename)
|
||||
|
||||
def render_user(self, batch, field):
|
||||
user = getattr(batch, field)
|
||||
if not user:
|
||||
|
@ -312,6 +312,7 @@ class BatchMasterView(MasterView):
|
|||
f.remove_field('complete')
|
||||
|
||||
def save_create_form(self, form):
|
||||
uploads = self.normalize_uploads(form, skip=['filename'])
|
||||
self.before_create(form)
|
||||
|
||||
session = self.Session()
|
||||
|
@ -346,17 +347,15 @@ class BatchMasterView(MasterView):
|
|||
batch = self.handler.make_batch(session, **kwargs)
|
||||
|
||||
self.Session.flush()
|
||||
|
||||
# TODO: this needs work yet surely...
|
||||
# if batch has input data file, let handler properly establish that
|
||||
if 'filename' in form.schema:
|
||||
if filedict:
|
||||
self.handler.set_input_file(batch, filepath)
|
||||
os.remove(filepath)
|
||||
os.rmdir(tempdir)
|
||||
|
||||
self.process_uploads(batch, form, uploads)
|
||||
return batch
|
||||
|
||||
def process_uploads(self, batch, form, uploads):
|
||||
for key, upload in six.iteritems(uploads):
|
||||
self.handler.set_input_file(batch, upload['temp_path'], attr=key)
|
||||
os.remove(upload['temp_path'])
|
||||
os.rmdir(upload['tempdir'])
|
||||
|
||||
def save_mobile_create_form(self, form):
|
||||
self.before_create(form)
|
||||
session = self.Session()
|
||||
|
@ -536,6 +535,39 @@ class BatchMasterView(MasterView):
|
|||
url = self.request.route_url('{}.delete_rows'.format(self.get_route_prefix()), uuid=batch.uuid)
|
||||
return HTML.tag('p', c=[tags.link_to("Delete all rows matching current search", url)])
|
||||
|
||||
def make_row_grid_kwargs(self, **kwargs):
|
||||
"""
|
||||
Whether or not rows may be edited or deleted will depend partially on
|
||||
whether the parent batch has been executed.
|
||||
"""
|
||||
batch = self.get_instance()
|
||||
|
||||
# TODO: most of this logic is copied from MasterView, should refactor/merge somehow...
|
||||
if 'main_actions' not in kwargs:
|
||||
actions = []
|
||||
|
||||
# view action
|
||||
if self.rows_viewable:
|
||||
view = lambda r, i: self.get_row_action_url('view', r)
|
||||
actions.append(grids.GridAction('view', icon='zoomin', url=view))
|
||||
|
||||
# edit and delete are NOT allowed after execution, or if batch is "complete"
|
||||
if not batch.executed and not batch.complete:
|
||||
|
||||
# edit action
|
||||
if self.rows_editable:
|
||||
actions.append(grids.GridAction('edit', icon='pencil', url=self.row_edit_action_url))
|
||||
|
||||
# delete action
|
||||
permission_prefix = self.get_permission_prefix()
|
||||
if self.rows_deletable and self.request.has_perm('{}.delete_row'.format(permission_prefix)):
|
||||
actions.append(grids.GridAction('delete', icon='trash', url=self.row_delete_action_url))
|
||||
kwargs.setdefault('delete_speedbump', self.rows_deletable_speedbump)
|
||||
|
||||
kwargs['main_actions'] = actions
|
||||
|
||||
return super(BatchMasterView, self).make_row_grid_kwargs(**kwargs)
|
||||
|
||||
def make_row_grid_tools(self, batch):
|
||||
return (self.make_default_row_grid_tools(batch) or '') + (self.make_batch_row_grid_tools(batch) or '')
|
||||
|
||||
|
@ -555,10 +587,7 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
Delete all data (files etc.) for the batch.
|
||||
"""
|
||||
if hasattr(batch, 'delete_data'):
|
||||
batch.delete_data(self.rattail_config)
|
||||
if hasattr(batch, 'data_rows'):
|
||||
del batch.data_rows[:]
|
||||
self.handler.delete(batch)
|
||||
super(BatchMasterView, self).delete_instance(batch)
|
||||
|
||||
def get_fallback_templates(self, template, mobile=False):
|
||||
|
@ -1153,6 +1182,7 @@ class FileBatchMasterView(BatchMasterView):
|
|||
"""
|
||||
Base class for all file-based "batch master" views.
|
||||
"""
|
||||
downloadable = True
|
||||
|
||||
@property
|
||||
def upload_dir(self):
|
||||
|
@ -1171,62 +1201,26 @@ class FileBatchMasterView(BatchMasterView):
|
|||
|
||||
def configure_form(self, f):
|
||||
super(FileBatchMasterView, self).configure_form(f)
|
||||
batch = f.model_instance
|
||||
|
||||
# filename
|
||||
f.set_renderer('filename', self.render_filename)
|
||||
f.set_label('filename', "Data File")
|
||||
if self.editing:
|
||||
f.set_readonly('filename')
|
||||
|
||||
if self.creating:
|
||||
if 'filename' not in f.fields:
|
||||
f.fields.insert(0, 'filename')
|
||||
tmpstore = SessionFileUploadTempStore(self.request)
|
||||
f.set_node('filename', colander.SchemaNode(deform.FileData(), widget=dfwidget.FileUploadWidget(tmpstore)))
|
||||
# TODO: what's up with this re-insertion again..?
|
||||
# if 'filename' not in f.fields:
|
||||
# f.fields.insert(0, 'filename')
|
||||
f.set_type('filename', 'file')
|
||||
else:
|
||||
f.set_readonly('filename')
|
||||
f.set_renderer('filename', self.render_filename)
|
||||
|
||||
def render_filename(self, batch, field):
|
||||
path = batch.filepath(self.rattail_config, filename=batch.filename)
|
||||
filename = getattr(batch, field)
|
||||
if not filename:
|
||||
return ""
|
||||
path = batch.filepath(self.rattail_config, filename=filename)
|
||||
url = self.get_action_url('download', batch)
|
||||
return self.render_file_field(path, url)
|
||||
|
||||
def download(self):
|
||||
"""
|
||||
View for downloading the data file associated with a batch.
|
||||
"""
|
||||
batch = self.get_instance()
|
||||
if not batch:
|
||||
raise httpexceptions.HTTPNotFound()
|
||||
path = batch.filepath(self.rattail_config)
|
||||
response = FileResponse(path, request=self.request)
|
||||
response.headers[b'Content-Length'] = six.binary_type(os.path.getsize(path))
|
||||
filename = os.path.basename(batch.filename).encode('ascii', 'replace')
|
||||
response.headers[b'Content-Disposition'] = b'attachment; filename="{}"'.format(filename)
|
||||
return response
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
cls._filebatch_defaults(config)
|
||||
cls._batch_defaults(config)
|
||||
cls._defaults(config)
|
||||
|
||||
@classmethod
|
||||
def _filebatch_defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
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))
|
||||
config.add_view(cls, attr='download', route_name='{}.download'.format(route_prefix),
|
||||
permission='{}.download'.format(permission_prefix))
|
||||
config.add_tailbone_permission(permission_prefix, '{}.download'.format(permission_prefix),
|
||||
"Download existing {} data file".format(model_title))
|
||||
|
||||
|
||||
class MobileBatchStatusFilter(grids.filters.MobileFilter):
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue