diff --git a/tailbone/views/inventory.py b/tailbone/views/inventory.py index 0e192b20..1a4f4322 100644 --- a/tailbone/views/inventory.py +++ b/tailbone/views/inventory.py @@ -97,6 +97,9 @@ class InventoryBatchView(BatchMasterView): # set to False to disable "zero all" batch count mode allow_zero_all = True + # set to False to disable "variance" batch count mode + allow_variance = True + # set to False to prevent exposing case fields for user input, # when the batch count mode is "adjust only" allow_adjustment_cases = True @@ -215,6 +218,9 @@ class InventoryBatchView(BatchMasterView): if not self.allow_zero_all or 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) + if not self.allow_variance or not self.request.has_perm('{}.create.variance'.format(permission_prefix)): + if hasattr(self.enum, 'INVENTORY_MODE_VARIANCE'): + modes.pop(self.enum.INVENTORY_MODE_VARIANCE, None) return modes def configure_form(self, f): @@ -284,10 +290,11 @@ class InventoryBatchView(BatchMasterView): if batch.executed: return self.redirect(self.get_action_url('view', batch)) - form = forms.Form(schema=DesktopForm(), request=self.request) + schema = DesktopForm().bind(session=self.Session()) + form = forms.Form(schema=schema, request=self.request) if form.validate(newstyle=True): - product = self.Session.merge(form.validated['product']) + product = self.Session.query(model.Product).get(form.validated['product']) row = model.InventoryBatchRow() row.product = product row.upc = form.validated['upc'] @@ -297,6 +304,7 @@ class InventoryBatchView(BatchMasterView): row.case_quantity = form.validated['case_quantity'] row.cases = form.validated['cases'] row.units = form.validated['units'] + self.handler.capture_current_units(row) self.handler.add_row(batch, row) description = make_full_description(form.validated['brand_name'], form.validated['description'], @@ -610,6 +618,9 @@ class InventoryBatchView(BatchMasterView): if cls.allow_zero_all: config.add_tailbone_permission(permission_prefix, '{}.create.zero'.format(permission_prefix), "Create new {} with 'zero' mode".format(model_title)) + if cls.allow_variance: + config.add_tailbone_permission(permission_prefix, '{}.create.variance'.format(permission_prefix), + "Create new {} with 'variance' mode".format(model_title)) # row UPC lookup, for desktop config.add_route('{}.desktop_lookup'.format(route_prefix), '{}/{{{}}}/desktop-form/lookup'.format(url_prefix, model_key)) @@ -648,9 +659,24 @@ class InventoryForm(colander.MappingSchema): units = colander.SchemaNode(colander.Decimal(), missing=colander.null) +# TODO: this is a stopgap measure to fix an obvious bug, which exists when the +# session is not provided by the view at runtime (i.e. when it was instead +# being provided by the type instance, which was created upon app startup). +@colander.deferred +def valid_product(node, kw): + session = kw['session'] + def validate(node, value): + product = session.query(model.Product).get(value) + if not product: + raise colander.Invalid(node, "Product not found") + return product.uuid + return validate + + class DesktopForm(colander.Schema): - product = colander.SchemaNode(forms.types.ProductType()) + product = colander.SchemaNode(colander.String(), + validator=valid_product) upc = colander.SchemaNode(forms.types.GPCType())