Avoid outright error if user scans barcode for inventory count

This commit is contained in:
Lance Edgar 2023-11-15 09:46:23 -06:00
parent 853cc871f7
commit 97e7026cc9

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2022 Lance Edgar # Copyright © 2010-2023 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -24,15 +24,12 @@
Tailbone Web API - Inventory Batches Tailbone Web API - Inventory Batches
""" """
from __future__ import unicode_literals, absolute_import
import decimal import decimal
import six import sqlalchemy as sa
from rattail import pod from rattail import pod
from rattail.db import model from rattail.db.model import InventoryBatch, InventoryBatchRow
from rattail.util import pretty_quantity
from cornice import Service from cornice import Service
@ -41,7 +38,7 @@ from tailbone.api.batch import APIBatchView, APIBatchRowView
class InventoryBatchViews(APIBatchView): class InventoryBatchViews(APIBatchView):
model_class = model.InventoryBatch model_class = InventoryBatch
default_handler_spec = 'rattail.batch.inventory:InventoryBatchHandler' default_handler_spec = 'rattail.batch.inventory:InventoryBatchHandler'
route_prefix = 'inventory' route_prefix = 'inventory'
permission_prefix = 'batch.inventory' permission_prefix = 'batch.inventory'
@ -50,12 +47,12 @@ class InventoryBatchViews(APIBatchView):
supports_toggle_complete = True supports_toggle_complete = True
def normalize(self, batch): def normalize(self, batch):
data = super(InventoryBatchViews, self).normalize(batch) data = super().normalize(batch)
data['mode'] = batch.mode data['mode'] = batch.mode
data['mode_display'] = self.enum.INVENTORY_MODE.get(batch.mode) data['mode_display'] = self.enum.INVENTORY_MODE.get(batch.mode)
if data['mode_display'] is None and batch.mode is not None: if data['mode_display'] is None and batch.mode is not None:
data['mode_display'] = six.text_type(batch.mode) data['mode_display'] = str(batch.mode)
data['reason_code'] = batch.reason_code data['reason_code'] = batch.reason_code
@ -119,7 +116,7 @@ class InventoryBatchViews(APIBatchView):
class InventoryBatchRowViews(APIBatchRowView): class InventoryBatchRowViews(APIBatchRowView):
model_class = model.InventoryBatchRow model_class = InventoryBatchRow
default_handler_spec = 'rattail.batch.inventory:InventoryBatchHandler' default_handler_spec = 'rattail.batch.inventory:InventoryBatchHandler'
route_prefix = 'inventory.rows' route_prefix = 'inventory.rows'
permission_prefix = 'batch.inventory' permission_prefix = 'batch.inventory'
@ -130,23 +127,24 @@ class InventoryBatchRowViews(APIBatchRowView):
def normalize(self, row): def normalize(self, row):
batch = row.batch batch = row.batch
data = super(InventoryBatchRowViews, self).normalize(row) data = super().normalize(row)
app = self.get_rattail_app()
data['item_id'] = row.item_id data['item_id'] = row.item_id
data['upc'] = six.text_type(row.upc) data['upc'] = str(row.upc)
data['upc_pretty'] = row.upc.pretty() if row.upc else None data['upc_pretty'] = row.upc.pretty() if row.upc else None
data['brand_name'] = row.brand_name data['brand_name'] = row.brand_name
data['description'] = row.description data['description'] = row.description
data['size'] = row.size data['size'] = row.size
data['full_description'] = row.product.full_description if row.product else row.description data['full_description'] = row.product.full_description if row.product else row.description
data['image_url'] = pod.get_image_url(self.rattail_config, row.upc) if row.upc else None data['image_url'] = pod.get_image_url(self.rattail_config, row.upc) if row.upc else None
data['case_quantity'] = pretty_quantity(row.case_quantity or 1) data['case_quantity'] = app.render_quantity(row.case_quantity or 1)
data['cases'] = row.cases data['cases'] = row.cases
data['units'] = row.units data['units'] = row.units
data['unit_uom'] = 'LB' if row.product and row.product.weighed else 'EA' data['unit_uom'] = 'LB' if row.product and row.product.weighed else 'EA'
data['quantity_display'] = "{} {}".format( data['quantity_display'] = "{} {}".format(
pretty_quantity(row.cases or row.units), app.render_quantity(row.cases or row.units),
'CS' if row.cases else data['unit_uom']) 'CS' if row.cases else data['unit_uom'])
data['allow_cases'] = self.batch_handler.allow_cases(batch) data['allow_cases'] = self.batch_handler.allow_cases(batch)
@ -174,7 +172,17 @@ class InventoryBatchRowViews(APIBatchRowView):
data['units'] = decimal.Decimal(data['units']) data['units'] = decimal.Decimal(data['units'])
# update row per usual # update row per usual
row = super(InventoryBatchRowViews, self).update_object(row, data) try:
row = super().update_object(row, data)
except sa.exc.DataError as error:
# detect when user scans barcode for cases/units field
if hasattr(error, 'orig'):
orig = type(error.orig)
if hasattr(orig, '__name__'):
# nb. this particular error is from psycopg2
if orig.__name__ == 'NumericValueOutOfRange':
return {'error': "Numeric value out of range"}
raise
return row return row