Refactor inventory batch views per master4

This commit is contained in:
Lance Edgar 2018-02-04 12:30:51 -06:00
parent 533b491124
commit e78d1ac3c1

View file

@ -39,11 +39,12 @@ from rattail.util import pretty_quantity
import colander import colander
import formencode as fe import formencode as fe
from deform import widget as dfwidget
from webhelpers2.html import HTML, tags from webhelpers2.html import HTML, tags
from tailbone import forms, grids from tailbone import forms, forms2, grids
from tailbone.views import MasterView4 as MasterView from tailbone.views import MasterView4 as MasterView
from tailbone.views.batch import BatchMasterView3 as BatchMasterView from tailbone.views.batch import BatchMasterView4 as BatchMasterView
class InventoryAdjustmentReasonsView(MasterView): class InventoryAdjustmentReasonsView(MasterView):
@ -90,6 +91,10 @@ class InventoryBatchView(BatchMasterView):
mobile_creatable = True mobile_creatable = True
mobile_rows_creatable = True mobile_rows_creatable = True
labels = {
'mode': "Count Mode",
}
grid_columns = [ grid_columns = [
'id', 'id',
'created', 'created',
@ -108,6 +113,16 @@ class InventoryBatchView(BatchMasterView):
'created', 'created',
'created_by', 'created_by',
'handheld_batches', 'handheld_batches',
'mode',
'reason_code',
'total_cost',
'rowcount',
'complete',
'executed',
'executed_by',
]
mobile_form_fields = [
'mode', 'mode',
'reason_code', 'reason_code',
'rowcount', 'rowcount',
@ -119,6 +134,11 @@ class InventoryBatchView(BatchMasterView):
model_row_class = model.InventoryBatchRow model_row_class = model.InventoryBatchRow
rows_editable = True rows_editable = True
row_labels = {
'upc': "UPC",
'previous_units_on_hand': "Prev. On Hand",
}
row_grid_columns = [ row_grid_columns = [
'sequence', 'sequence',
'upc', 'upc',
@ -134,6 +154,21 @@ class InventoryBatchView(BatchMasterView):
'status_code', 'status_code',
] ]
row_form_fields = [
'sequence',
'upc',
'brand_name',
'description',
'size',
'status_code',
'previous_units_on_hand',
'case_quantity',
'cases',
'units',
'unit_cost',
'total_cost',
]
def configure_grid(self, g): def configure_grid(self, g):
super(InventoryBatchView, self).configure_grid(g) super(InventoryBatchView, self).configure_grid(g)
@ -141,7 +176,6 @@ class InventoryBatchView(BatchMasterView):
g.set_enum('mode', self.enum.INVENTORY_MODE) g.set_enum('mode', self.enum.INVENTORY_MODE)
g.filters['mode'].set_value_renderer( g.filters['mode'].set_value_renderer(
grids.filters.EnumValueRenderer(self.enum.INVENTORY_MODE)) grids.filters.EnumValueRenderer(self.enum.INVENTORY_MODE))
g.set_label('mode', "Count Mode")
# total_cost # total_cost
g.set_type('total_cost', 'currency') g.set_type('total_cost', 'currency')
@ -162,10 +196,8 @@ class InventoryBatchView(BatchMasterView):
def allow_worksheet(self, batch): def allow_worksheet(self, batch):
return self.mutable_batch(batch) return self.mutable_batch(batch)
def configure_form(self, f): def get_available_modes(self):
super(InventoryBatchView, self).configure_form(f)
permission_prefix = self.get_permission_prefix() permission_prefix = self.get_permission_prefix()
modes = dict(self.enum.INVENTORY_MODE) modes = dict(self.enum.INVENTORY_MODE)
if not self.request.has_perm('{}.create.replace'.format(permission_prefix)): if not self.request.has_perm('{}.create.replace'.format(permission_prefix)):
if hasattr(self.enum, 'INVENTORY_MODE_REPLACE'): if hasattr(self.enum, 'INVENTORY_MODE_REPLACE'):
@ -175,16 +207,24 @@ class InventoryBatchView(BatchMasterView):
if not self.request.has_perm('{}.create.zero'.format(permission_prefix)): if not self.request.has_perm('{}.create.zero'.format(permission_prefix)):
if hasattr(self.enum, 'INVENTORY_MODE_ZERO_ALL'): if hasattr(self.enum, 'INVENTORY_MODE_ZERO_ALL'):
modes.pop(self.enum.INVENTORY_MODE_ZERO_ALL, None) modes.pop(self.enum.INVENTORY_MODE_ZERO_ALL, None)
return modes
def configure_form(self, f):
super(InventoryBatchView, self).configure_form(f)
# mode # mode
modes = self.get_available_modes()
f.set_enum('mode', modes) f.set_enum('mode', modes)
f.set_label('mode', "Count Mode") f.set_label('mode', "Count Mode")
if len(modes) == 1: if len(modes) == 1:
f.set_readonly('mode') f.set_readonly('mode')
# total_cost # total_cost
f.set_readonly('total_cost') if self.creating:
f.set_type('total_cost', 'currency') f.remove_field('total_cost')
else:
f.set_readonly('total_cost')
f.set_type('total_cost', 'currency')
# handheld_batches # handheld_batches
f.set_readonly('handheld_batches') f.set_readonly('handheld_batches')
@ -205,7 +245,7 @@ class InventoryBatchView(BatchMasterView):
return self.mutable_batch(row.batch) return self.mutable_batch(row.batch)
def save_edit_row_form(self, form): def save_edit_row_form(self, form):
row = form.fieldset.model row = form.model_instance
batch = row.batch batch = row.batch
if batch.total_cost is not None and row.total_cost is not None: if batch.total_cost is not None and row.total_cost is not None:
batch.total_cost -= row.total_cost batch.total_cost -= row.total_cost
@ -220,40 +260,19 @@ class InventoryBatchView(BatchMasterView):
batch.total_cost -= row.total_cost batch.total_cost -= row.total_cost
return super(InventoryBatchView, self).delete_row() return super(InventoryBatchView, self).delete_row()
def configure_mobile_fieldset(self, fs): def configure_mobile_form(self, f):
permission_prefix = self.get_permission_prefix() super(InventoryBatchView, self).configure_mobile_form(f)
batch = f.model_instance
# TODO: this was copied from configure_form() # mode
modes = dict(self.enum.INVENTORY_MODE) modes = self.get_available_modes()
if not self.request.has_perm('{}.create.replace'.format(permission_prefix)): f.set_enum('mode', modes)
if hasattr(self.enum, 'INVENTORY_MODE_REPLACE'): mode_values = [(k, v) for k, v in sorted(modes.items())]
modes.pop(self.enum.INVENTORY_MODE_REPLACE, None) f.set_widget('mode', forms2.widgets.PlainSelectWidget(values=mode_values))
if hasattr(self.enum, 'INVENTORY_MODE_REPLACE_ADJUST'):
modes.pop(self.enum.INVENTORY_MODE_REPLACE_ADJUST, None)
if not self.request.has_perm('{}.create.zero'.format(permission_prefix)):
if hasattr(self.enum, 'INVENTORY_MODE_ZERO_ALL'):
modes.pop(self.enum.INVENTORY_MODE_ZERO_ALL, None)
fs.mode.set(renderer=forms.renderers.EnumFieldRenderer(modes), # complete
label="Count Mode", required=True, attrs={'auto-enhance': 'true'}) if self.creating or batch.executed or not batch.complete:
f.remove_field('complete')
fs.configure(include=[
fs.mode,
fs.reason_code,
fs.rowcount,
fs.complete,
fs.executed,
fs.executed_by,
])
batch = fs.model
if self.creating:
del fs.rowcount
if not batch.executed:
del [fs.executed, fs.executed_by]
if not batch.complete:
del fs.complete
else:
del fs.complete
# TODO: document this, maybe move it etc. # TODO: document this, maybe move it etc.
unknown_product_creates_row = True unknown_product_creates_row = True
@ -371,17 +390,20 @@ class InventoryBatchView(BatchMasterView):
def configure_row_grid(self, g): def configure_row_grid(self, g):
super(InventoryBatchView, self).configure_row_grid(g) super(InventoryBatchView, self).configure_row_grid(g)
# quantity fields
g.set_type('previous_units_on_hand', 'quantity') g.set_type('previous_units_on_hand', 'quantity')
g.set_type('cases', 'quantity') g.set_type('cases', 'quantity')
g.set_type('units', 'quantity') g.set_type('units', 'quantity')
# currency fields
g.set_type('unit_cost', 'currency') g.set_type('unit_cost', 'currency')
g.set_type('total_cost', 'currency') g.set_type('total_cost', 'currency')
g.set_label('upc', "UPC") # short labels
g.set_label('brand_name', "Brand") g.set_label('brand_name', "Brand")
g.set_label('status_code', "Status") g.set_label('status_code', "Status")
g.set_label('previous_units_on_hand', "Prev. On Hand")
# links
g.set_link('upc') g.set_link('upc')
g.set_link('item_id') g.set_link('item_id')
g.set_link('description') g.set_link('description')
@ -396,37 +418,41 @@ class InventoryBatchView(BatchMasterView):
qty = "{} {}".format(pretty_quantity(row.cases or row.units), 'CS' if row.cases else unit_uom) qty = "{} {}".format(pretty_quantity(row.cases or row.units), 'CS' if row.cases else unit_uom)
return "({}) {} - {}".format(row.upc.pretty(), description, qty) return "({}) {} - {}".format(row.upc.pretty(), description, qty)
def _preconfigure_row_fieldset(self, fs): def configure_row_form(self, f):
super(InventoryBatchView, self)._preconfigure_row_fieldset(fs) super(InventoryBatchView, self).configure_row_form(f)
fs.upc.set(readonly=True, label="UPC", renderer=forms.renderers.GPCFieldRenderer,
attrs={'link': lambda r: self.request.route_url('products.view', uuid=r.product_uuid)})
fs.item_id.set(readonly=True)
fs.brand_name.set(readonly=True)
fs.description.set(readonly=True)
fs.size.set(readonly=True)
fs.previous_units_on_hand.set(label="Prev. On Hand")
fs.case_quantity.set(renderer=forms.renderers.QuantityFieldRenderer)
fs.cases.set(renderer=forms.renderers.QuantityFieldRenderer)
fs.units.set(renderer=forms.renderers.QuantityFieldRenderer)
fs.unit_cost.set(readonly=True, renderer=forms.renderers.CurrencyFieldRenderer)
fs.total_cost.set(readonly=True, renderer=forms.renderers.CurrencyFieldRenderer)
def configure_row_fieldset(self, fs): # readonly fields
fs.configure( f.set_readonly('upc')
include=[ f.set_readonly('item_id')
fs.sequence, f.set_readonly('brand_name')
fs.upc, f.set_readonly('description')
fs.brand_name, f.set_readonly('size')
fs.description, f.set_readonly('previous_units_on_hand')
fs.size, f.set_readonly('case_quantity')
fs.status_code, f.set_readonly('unit_cost')
fs.previous_units_on_hand, f.set_readonly('total_cost')
fs.case_quantity,
fs.cases, # quantity fields
fs.units, f.set_type('case_quantity', 'quantity')
fs.unit_cost, f.set_type('cases', 'quantity')
fs.total_cost, f.set_type('units', 'quantity')
])
# currency fields
f.set_type('unit_cost', 'currency')
f.set_type('total_cost', 'currency')
# upc
f.set_renderer('upc', self.render_upc)
def render_upc(self, row, field):
upc = row.upc
if not upc:
return ""
text = upc.pretty()
if row.product_uuid:
url = self.request.route_url('products.view', uuid=row.product_uuid)
return tags.link_to(text, url)
return text
@classmethod @classmethod
def defaults(cls, config): def defaults(cls, config):