diff --git a/tailbone/templates/batch/handheld/exec_options.mako b/tailbone/templates/batch/handheld/exec_options.mako new file mode 100644 index 00000000..af5eaf14 --- /dev/null +++ b/tailbone/templates/batch/handheld/exec_options.mako @@ -0,0 +1,3 @@ +## -*- coding: utf-8 -*- + +${form.field_div('action', form.select('action', options=ACTION_OPTIONS), label="Action to Perform")} diff --git a/tailbone/views/handheld.py b/tailbone/views/handheld.py new file mode 100644 index 00000000..9d0134c6 --- /dev/null +++ b/tailbone/views/handheld.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2016 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Rattail. If not, see . +# +################################################################################ +""" +Views for handheld batches +""" + +from __future__ import unicode_literals, absolute_import + +from rattail.db.batch.handheld.handler import HandheldBatchHandler +from rattail.util import OrderedDict + +import formalchemy as fa +import formencode as fe +from webhelpers.html import tags + +from tailbone import forms +from tailbone.views.batch import FileBatchMasterView + +from dtail import enum +from dtail.db import model + + +ACTION_OPTIONS = OrderedDict([ + ('make_label_batch', "Make a new Label Batch"), + ('make_inventory_batch', "Make a new Inventory Batch"), +]) + + +class ExecutionOptions(fe.Schema): + allow_extra_fields = True + filter_extra_fields = True + action = fe.validators.OneOf(ACTION_OPTIONS) + + +class InventoryBatchFieldRenderer(fa.FieldRenderer): + """ + Renderer for handheld batch's "inventory batch" field. + """ + + def render_readonly(self, **kwargs): + batch = self.raw_value + if batch: + return tags.link_to( + batch.id_str, + self.request.route_url('batch.inventory.view', uuid=batch.uuid)) + return '' + + + +class HandheldBatchView(FileBatchMasterView): + """ + Master view for handheld batches. + """ + model_class = model.HandheldBatch + model_title_plural = "Handheld Batches" + batch_row_class = model.HandheldBatchRow + batch_handler_class = HandheldBatchHandler + route_prefix = 'batch.handheld' + url_prefix = '/batch/handheld' + execution_options_schema = ExecutionOptions + + def configure_grid(self, g): + g.configure( + include=[ + g.id, + g.created, + g.created_by, + g.device_name, + g.executed, + g.executed_by, + ], + readonly=True) + + def configure_fieldset(self, fs): + fs.configure( + include=[ + fs.id, + fs.created, + fs.created_by, + fs.filename, + fs.device_type.with_renderer(forms.renderers.EnumFieldRenderer(enum.HANDHELD_DEVICE)), + fs.device_name, + fs.executed, + fs.executed_by, + ]) + if self.creating: + del fs.id + elif self.viewing: + fs.append(fa.Field('inventory_batch', value=fs.model.inventory_batch, renderer=InventoryBatchFieldRenderer)) + + def configure_row_grid(self, g): + g.configure( + include=[ + g.sequence, + g.upc.label("UPC"), + g.brand_name.label("Brand"), + g.description, + g.size, + g.cases, + g.units, + g.status_code.label("Status"), + ], + readonly=True) + + def row_grid_row_attrs(self, row, i): + attrs = {} + if row.status_code == row.STATUS_PRODUCT_NOT_FOUND: + attrs['class_'] = 'warning' + return attrs + + def get_exec_options_kwargs(self, **kwargs): + kwargs['ACTION_OPTIONS'] = list(ACTION_OPTIONS.iteritems()) + return kwargs + + def get_execute_success_url(self, batch, result, **kwargs): + if kwargs['action'] == 'make_inventory_batch': + return self.request.route_url('batch.inventory.view', uuid=result.uuid) + elif kwargs['action'] == 'make_label_batch': + return self.request.route_url('batch.rows', uuid=result.uuid) + return super(HandheldBatchView, self).get_execute_success_url(batch) + + @classmethod + def defaults(cls, config): + + # fix permission group title + config.add_tailbone_permission_group('batch.handheld', "Handheld Batches") + + cls._batch_defaults(config) + cls._defaults(config) + + +def includeme(config): + HandheldBatchView.defaults(config) diff --git a/tailbone/views/inventory.py b/tailbone/views/inventory.py new file mode 100644 index 00000000..49519a82 --- /dev/null +++ b/tailbone/views/inventory.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2016 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Rattail. If not, see . +# +################################################################################ +""" +Views for inventory batches +""" + +from __future__ import unicode_literals, absolute_import + +from rattail.db.batch.inventory.handler import InventoryBatchHandler + +import formalchemy as fa +from webhelpers.html import tags + +from tailbone import forms +from tailbone.views.batch import BatchMasterView + +from dtail.db import model + + +class HandheldBatchFieldRenderer(fa.FieldRenderer): + """ + Renderer for inventory batch's "handheld batch" field. + """ + + def render_readonly(self, **kwargs): + batch = self.raw_value + if batch: + return tags.link_to( + batch.id_str, + self.request.route_url('batch.handheld.view', uuid=batch.uuid)) + return '' + + +class InventoryBatchView(BatchMasterView): + """ + Master view for inventory batches. + """ + model_class = model.InventoryBatch + model_title_plural = "Inventory Batches" + batch_row_class = model.InventoryBatchRow + batch_handler_class = InventoryBatchHandler + route_prefix = 'batch.inventory' + url_prefix = '/batch/inventory' + creatable = False + + def configure_fieldset(self, fs): + fs.configure( + include=[ + fs.id, + fs.created, + fs.created_by, + fs.handheld_batch.with_renderer(HandheldBatchFieldRenderer), + fs.executed, + fs.executed_by, + ]) + if not self.viewing: + del fs.handheld_batch + + def configure_row_grid(self, g): + g.configure( + include=[ + g.sequence, + g.upc.label("UPC"), + g.brand_name.label("Brand"), + g.description, + g.size, + g.cases, + g.units, + g.status_code.label("Status"), + ], + readonly=True) + + def row_grid_row_attrs(self, row, i): + attrs = {} + if row.status_code == row.STATUS_PRODUCT_NOT_FOUND: + attrs['class_'] = 'warning' + return attrs + + @classmethod + def defaults(cls, config): + + # fix permission group title + config.add_tailbone_permission_group('batch.inventory', "Inventory Batches") + + cls._batch_defaults(config) + cls._defaults(config) + + +def includeme(config): + InventoryBatchView.defaults(config)