Refactor handheld batch views to use master3

This commit is contained in:
Lance Edgar 2018-01-27 12:23:47 -06:00
parent eac59ba5c8
commit 8eab3c5b36
3 changed files with 77 additions and 63 deletions

View file

@ -326,7 +326,9 @@ class Form(object):
widgets={}, defaults={}, validators={}, required={}, helptext={},
action_url=None, cancel_url=None):
self.fields = FieldList(fields) if fields is not None else None
self.fields = None
if fields is not None:
self.set_fields(fields)
self.schema = schema
self.request = request
self.readonly = readonly
@ -336,7 +338,7 @@ class Form(object):
if self.model_instance and not self.model_class:
self.model_class = type(self.model_instance)
if self.model_class and self.fields is None:
self.fields = self.make_fields()
self.set_fields(self.make_fields())
self.nodes = nodes or {}
self.enums = enums or {}
self.labels = labels or {}
@ -352,6 +354,9 @@ class Form(object):
self.action_url = action_url
self.cancel_url = cancel_url
def set_fields(self, fields):
self.fields = FieldList(fields)
def make_fields(self):
"""
Return a default list of fields, based on :attr:`model_class`.

View file

@ -27,9 +27,13 @@ Base views for maintaining batches
from __future__ import unicode_literals, absolute_import
import os
import tempfile
import six
import colander
import deform
from deform import widget as dfwidget
from pyramid_deform import SessionFileUploadTempStore
from webhelpers2.html import tags
from tailbone.views import MasterView3
@ -46,8 +50,7 @@ class BatchMasterView3(MasterView3, BatchMasterView2):
'created',
'created_by',
'rowcount',
'cognized',
'cognized_by',
'status_code',
'executed',
'executed_by',
'purge',
@ -113,7 +116,8 @@ class BatchMasterView3(MasterView3, BatchMasterView2):
def save_create_form(self, form):
self.before_create(form)
with self.Session.no_autoflush:
session = self.Session()
with session.no_autoflush:
# transfer form data to batch instance
batch = self.objectify(form, self.form_deserialized)
@ -121,23 +125,35 @@ class BatchMasterView3(MasterView3, BatchMasterView2):
# current user is batch creator
batch.created_by = self.request.user or self.late_login_user()
# obtain kwargs for making batch via handler, below
kwargs = self.get_batch_kwargs(batch)
# TODO: this needs work yet surely...
filedict = kwargs.pop('filename', None)
filepath = None
if filedict:
kwargs['filename'] = '' # null not allowed
tempdir = tempfile.mkdtemp()
filepath = os.path.join(tempdir, filedict['filename'])
tmpinfo = form.deform_form['filename'].widget.tmpstore.get(filedict['uid'])
tmpdata = tmpinfo['fp'].read()
with open(filepath, 'wb') as f:
f.write(tmpdata)
# TODO: is this still necessary with colander?
# destroy initial batch and re-make using handler
kwargs = self.get_batch_kwargs(batch)
# if batch in self.Session:
# self.Session.expunge(batch)
batch = self.handler.make_batch(self.Session(), **kwargs)
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
filename = getattr(batch, 'filename', None)
if filename:
path = os.path.join(self.upload_dir, filename)
if os.path.exists(path):
self.handler.set_input_file(batch, path)
os.remove(path)
if filedict:
self.handler.set_input_file(batch, filepath)
os.remove(filepath)
os.rmdir(tempdir)
return batch
@ -175,11 +191,11 @@ class FileBatchMasterView3(BatchMasterView3, FileBatchMasterView2):
if self.editing:
f.set_readonly('filename')
# if creating, let filename be our only field by default
if self.creating:
f.fields = [
'filename',
]
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)))
def render_filename(self, batch, field):
path = batch.filepath(self.rattail_config, filename=batch.filename)

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar
# Copyright © 2010-2018 Lance Edgar
#
# This file is part of Rattail.
#
@ -28,17 +28,15 @@ from __future__ import unicode_literals, absolute_import
import os
from rattail import enum
from rattail.db import model
from rattail.util import OrderedDict
import formalchemy as fa
import formencode as fe
from webhelpers2.html import tags
from tailbone import forms
from tailbone.db import Session
from tailbone.views.batch import FileBatchMasterView2 as FileBatchMasterView
from tailbone.views.batch import FileBatchMasterView3 as FileBatchMasterView
ACTION_OPTIONS = OrderedDict([
@ -53,21 +51,6 @@ class ExecutionOptions(fe.Schema):
action = fe.validators.OneOf(ACTION_OPTIONS)
class InventoryBatchFieldRenderer(fa.FieldRenderer):
"""
Renderer for handheld batch's "inventory batch" field.
"""
def render_readonly(self, **kwargs):
batch = self.raw_value
if batch:
return tags.link_to(
batch.id_str,
self.request.route_url('batch.inventory.view', uuid=batch.uuid))
return ''
class HandheldBatchView(FileBatchMasterView):
"""
Master view for handheld batches.
@ -96,6 +79,19 @@ class HandheldBatchView(FileBatchMasterView):
'executed',
]
form_fields = [
'id',
'device_type',
'device_name',
'filename',
'created',
'created_by',
'rowcount',
'status_code',
'executed',
'executed_by',
]
row_grid_columns = [
'sequence',
'upc',
@ -117,38 +113,35 @@ class HandheldBatchView(FileBatchMasterView):
if batch.status_code is not None and batch.status_code != batch.STATUS_OK:
return 'notice'
def _preconfigure_fieldset(self, fs):
super(HandheldBatchView, self)._preconfigure_fieldset(fs)
def configure_form(self, f):
super(HandheldBatchView, self).configure_form(f)
batch = f.model_instance
# device_type
device_types = OrderedDict(sorted(self.enum.HANDHELD_DEVICE_TYPE.items(),
key=lambda item: item[1]))
fs.device_type.set(renderer=forms.renderers.EnumFieldRenderer(device_types))
f.set_enum('device_type', device_types)
f.widgets['device_type'].values.insert(0, ('', "(none)"))
def configure_fieldset(self, fs):
if self.creating:
fs.configure(
include=[
fs.filename,
fs.device_type,
fs.device_name,
f.set_fields([
'filename',
'device_type',
'device_name',
])
else:
fs.configure(
include=[
fs.id,
fs.device_type,
fs.device_name,
fs.filename,
fs.created,
fs.created_by,
fs.rowcount,
fs.status_code,
fs.executed,
fs.executed_by,
])
if self.viewing:
if batch.inventory_batch:
f.append('inventory_batch')
f.set_renderer('inventory_batch', self.render_inventory_batch)
if self.viewing and fs.model.inventory_batch:
fs.append(fa.Field('inventory_batch', value=fs.model.inventory_batch, renderer=InventoryBatchFieldRenderer))
def render_inventory_batch(self, handheld_batch, field):
batch = handheld_batch.inventory_batch
if not batch:
return ""
text = batch.id_str
url = self.request.route_url('batch.inventory.view', uuid=batch.uuid)
return tags.link_to(text, url)
def get_batch_kwargs(self, batch):
kwargs = super(HandheldBatchView, self).get_batch_kwargs(batch)