Refactor inventory batch views per master4
This commit is contained in:
parent
533b491124
commit
e78d1ac3c1
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue