Let inventory batch handler declare which count modes are allowed

preparing for API/mobile usage
This commit is contained in:
Lance Edgar 2020-03-29 12:46:41 -05:00
parent 242e14e8a9
commit 0704717ec5
2 changed files with 37 additions and 23 deletions

View file

@ -71,6 +71,7 @@ class BatchMasterView(MasterView):
Base class for all "batch master" views. Base class for all "batch master" views.
""" """
default_handler_spec = None default_handler_spec = None
batch_handler_class = None
has_rows = True has_rows = True
rows_deletable = True rows_deletable = True
rows_downloadable_csv = True rows_downloadable_csv = True
@ -120,29 +121,43 @@ class BatchMasterView(MasterView):
super(BatchMasterView, self).__init__(request) super(BatchMasterView, self).__init__(request)
self.handler = self.get_handler() self.handler = self.get_handler()
def get_handler(self): @classmethod
def get_handler_factory(cls, rattail_config):
""" """
Returns a `BatchHandler` instance for the view. All (?) custom batch Returns the "factory" (class) which will be used to create the batch
views should define a default handler class; however this may in all handler. All (?) custom batch views should define a default handler
(?) cases be overridden by config also. The specific setting required class; however this may in all (?) cases be overridden by config also.
to do so will depend on the 'key' for the type of batch involved, e.g. The specific setting required to do so will depend on the 'key' for the
assuming the 'vendor_catalog' batch: type of batch involved, e.g. assuming the 'inventory' batch:
.. code-block:: ini .. code-block:: ini
[rattail.batch] [rattail.batch]
vendor_catalog.handler = myapp.batch.vendorcatalog:CustomCatalogHandler inventory.handler = poser.batch.inventory:InventoryBatchHandler
Note that the 'key' for a batch is generally the same as its primary Note that the 'key' for a batch is generally the same as its primary
table name, although technically it is whatever value returns from the table name, although technically it is whatever value returns from the
``batch_key`` attribute of the main batch model class. ``batch_key`` attribute of the main batch model class.
""" """
key = self.model_class.batch_key # first try to figure out if config defines a factory class
spec = self.rattail_config.get('rattail.batch', '{}.handler'.format(key), model_class = cls.get_model_class()
default=self.default_handler_spec) batch_key = model_class.batch_key
if spec: spec = rattail_config.get('rattail.batch', '{}.handler'.format(batch_key),
return load_object(spec)(self.rattail_config) default=cls.default_handler_spec)
return self.batch_handler_class(self.rattail_config) if spec: # yep, so use that
return load_object(spec)
# fall back to whatever class was defined statically
return cls.batch_handler_class
def get_handler(self):
"""
Returns a batch handler instance to be used by the view. Note that
this will use the factory provided by :meth:`get_handler_factory()` to
create the handler instance.
"""
factory = self.get_handler_factory(self.rattail_config)
return factory(self.rattail_config)
def download_path(self, batch, filename): def download_path(self, batch, filename):
return self.rattail_config.batch_filepath(batch.batch_key, batch.uuid, filename) return self.rattail_config.batch_filepath(batch.batch_key, batch.uuid, filename)

View file

@ -67,12 +67,6 @@ class InventoryBatchView(BatchMasterView):
mobile_creatable = True mobile_creatable = True
mobile_rows_creatable = True mobile_rows_creatable = True
# 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, # set to False to prevent exposing case fields for user input,
# when the batch count mode is "adjust only" # when the batch count mode is "adjust only"
allow_adjustment_cases = True allow_adjustment_cases = True
@ -192,10 +186,10 @@ class InventoryBatchView(BatchMasterView):
modes.pop(self.enum.INVENTORY_MODE_REPLACE, None) modes.pop(self.enum.INVENTORY_MODE_REPLACE, None)
if hasattr(self.enum, 'INVENTORY_MODE_REPLACE_ADJUST'): if hasattr(self.enum, 'INVENTORY_MODE_REPLACE_ADJUST'):
modes.pop(self.enum.INVENTORY_MODE_REPLACE_ADJUST, None) modes.pop(self.enum.INVENTORY_MODE_REPLACE_ADJUST, None)
if not self.allow_zero_all or not self.request.has_perm('{}.create.zero'.format(permission_prefix)): if not self.handler.allow_zero_all or 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)
if not self.allow_variance or not self.request.has_perm('{}.create.variance'.format(permission_prefix)): if not self.handler.allow_variance or not self.request.has_perm('{}.create.variance'.format(permission_prefix)):
if hasattr(self.enum, 'INVENTORY_MODE_VARIANCE'): if hasattr(self.enum, 'INVENTORY_MODE_VARIANCE'):
modes.pop(self.enum.INVENTORY_MODE_VARIANCE, None) modes.pop(self.enum.INVENTORY_MODE_VARIANCE, None)
return modes return modes
@ -694,19 +688,24 @@ class InventoryBatchView(BatchMasterView):
@classmethod @classmethod
def _inventory_defaults(cls, config): def _inventory_defaults(cls, config):
rattail_config = config.registry.settings['rattail_config']
model_key = cls.get_model_key() model_key = cls.get_model_key()
model_title = cls.get_model_title() model_title = cls.get_model_title()
route_prefix = cls.get_route_prefix() route_prefix = cls.get_route_prefix()
url_prefix = cls.get_url_prefix() url_prefix = cls.get_url_prefix()
permission_prefix = cls.get_permission_prefix() permission_prefix = cls.get_permission_prefix()
# we need batch handler to determine available permissions
factory = cls.get_handler_factory(rattail_config)
handler = factory(rattail_config)
# extra perms for creating batches per "mode" # extra perms for creating batches per "mode"
config.add_tailbone_permission(permission_prefix, '{}.create.replace'.format(permission_prefix), config.add_tailbone_permission(permission_prefix, '{}.create.replace'.format(permission_prefix),
"Create new {} with 'replace' mode".format(model_title)) "Create new {} with 'replace' mode".format(model_title))
if cls.allow_zero_all: if handler.allow_zero_all:
config.add_tailbone_permission(permission_prefix, '{}.create.zero'.format(permission_prefix), config.add_tailbone_permission(permission_prefix, '{}.create.zero'.format(permission_prefix),
"Create new {} with 'zero' mode".format(model_title)) "Create new {} with 'zero' mode".format(model_title))
if cls.allow_variance: if handler.allow_variance:
config.add_tailbone_permission(permission_prefix, '{}.create.variance'.format(permission_prefix), config.add_tailbone_permission(permission_prefix, '{}.create.variance'.format(permission_prefix),
"Create new {} with 'variance' mode".format(model_title)) "Create new {} with 'variance' mode".format(model_title))