Fix some basic product editing features
mostly for sake of online demo
This commit is contained in:
parent
815cdbdd0a
commit
86617e410f
54
tailbone/exceptions.py
Normal file
54
tailbone/exceptions.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# -*- coding: utf-8; -*-
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# Rattail -- Retail Software Framework
|
||||||
|
# Copyright © 2010-2020 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 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 General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
"""
|
||||||
|
Tailbone Exceptions
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from rattail.exceptions import RattailError
|
||||||
|
|
||||||
|
|
||||||
|
class TailboneError(RattailError):
|
||||||
|
"""
|
||||||
|
Base class for all Tailbone exceptions.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@six.python_2_unicode_compatible
|
||||||
|
class TailboneJSONFieldError(TailboneError):
|
||||||
|
"""
|
||||||
|
Error raised when JSON serialization of a form field results in an error.
|
||||||
|
This is just a simple wrapper, to make the error message more helpful for
|
||||||
|
the developer.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, field, error):
|
||||||
|
self.field = field
|
||||||
|
self.error = error
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ("Failed to serialize field '{}' as JSON! "
|
||||||
|
"Original error was: {}".format(self.field, self.error))
|
|
@ -51,6 +51,7 @@ from webhelpers2.html import tags, HTML
|
||||||
from tailbone.util import raw_datetime
|
from tailbone.util import raw_datetime
|
||||||
from . import types
|
from . import types
|
||||||
from .widgets import ReadonlyWidget, PlainDateWidget, JQueryDateWidget, JQueryTimeWidget
|
from .widgets import ReadonlyWidget, PlainDateWidget, JQueryDateWidget, JQueryTimeWidget
|
||||||
|
from tailbone.exceptions import TailboneJSONFieldError
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -786,7 +787,10 @@ class Form(object):
|
||||||
if field.cstruct is colander.null:
|
if field.cstruct is colander.null:
|
||||||
return 'null'
|
return 'null'
|
||||||
|
|
||||||
return json.dumps(field.cstruct)
|
try:
|
||||||
|
return json.dumps(field.cstruct)
|
||||||
|
except Exception as error:
|
||||||
|
raise TailboneJSONFieldError(field.name, error)
|
||||||
|
|
||||||
def messages_json(self, messages):
|
def messages_json(self, messages):
|
||||||
dump = json.dumps(messages)
|
dump = json.dumps(messages)
|
||||||
|
|
|
@ -786,11 +786,17 @@ class ProductsView(MasterView):
|
||||||
if not require_report_code:
|
if not require_report_code:
|
||||||
report_code_values.insert(0, ('', "(none)"))
|
report_code_values.insert(0, ('', "(none)"))
|
||||||
f.set_widget('report_code_uuid', dfwidget.SelectWidget(values=report_code_values))
|
f.set_widget('report_code_uuid', dfwidget.SelectWidget(values=report_code_values))
|
||||||
f.set_label('report_code_uuid', "Report_Code")
|
f.set_label('report_code_uuid', "Report Code")
|
||||||
else:
|
else:
|
||||||
f.set_readonly('report_code')
|
f.set_readonly('report_code')
|
||||||
# f.set_renderer('report_code', self.render_report_code)
|
# f.set_renderer('report_code', self.render_report_code)
|
||||||
|
|
||||||
|
# regular_price_amount
|
||||||
|
if self.editing:
|
||||||
|
f.set_node('regular_price_amount', colander.Decimal())
|
||||||
|
f.set_default('regular_price_amount', product.regular_price.price if product.regular_price else None)
|
||||||
|
f.set_label('regular_price_amount', "Regular Price")
|
||||||
|
|
||||||
# deposit_link
|
# deposit_link
|
||||||
if self.creating or self.editing:
|
if self.creating or self.editing:
|
||||||
if 'deposit_link' in f.fields:
|
if 'deposit_link' in f.fields:
|
||||||
|
@ -803,7 +809,7 @@ class ProductsView(MasterView):
|
||||||
if not require_deposit_link:
|
if not require_deposit_link:
|
||||||
deposit_link_values.insert(0, ('', "(none)"))
|
deposit_link_values.insert(0, ('', "(none)"))
|
||||||
f.set_widget('deposit_link_uuid', dfwidget.SelectWidget(values=deposit_link_values))
|
f.set_widget('deposit_link_uuid', dfwidget.SelectWidget(values=deposit_link_values))
|
||||||
f.set_label('deposit_link_uuid', "Deposit_Link")
|
f.set_label('deposit_link_uuid', "Deposit Link")
|
||||||
else:
|
else:
|
||||||
f.set_readonly('deposit_link')
|
f.set_readonly('deposit_link')
|
||||||
# f.set_renderer('deposit_link', self.render_deposit_link)
|
# f.set_renderer('deposit_link', self.render_deposit_link)
|
||||||
|
@ -831,18 +837,24 @@ class ProductsView(MasterView):
|
||||||
f.set_readonly('tax3')
|
f.set_readonly('tax3')
|
||||||
|
|
||||||
# brand
|
# brand
|
||||||
if self.creating:
|
if self.creating or self.editing:
|
||||||
f.replace('brand', 'brand_uuid')
|
if 'brand' in f.fields:
|
||||||
brand_display = ""
|
f.replace('brand', 'brand_uuid')
|
||||||
if self.request.method == 'POST':
|
f.set_node('brand_uuid', colander.String(), missing=colander.null)
|
||||||
if self.request.POST.get('brand_uuid'):
|
brand_display = ""
|
||||||
brand = self.Session.query(model.Brand).get(self.request.POST['brand_uuid'])
|
if self.request.method == 'POST':
|
||||||
if brand:
|
if self.request.POST.get('brand_uuid'):
|
||||||
brand_display = six.text_type(brand)
|
brand = self.Session.query(model.Brand).get(self.request.POST['brand_uuid'])
|
||||||
brands_url = self.request.route_url('brands.autocomplete')
|
if brand:
|
||||||
f.set_widget('brand_uuid', forms.widgets.JQueryAutocompleteWidget(
|
brand_display = six.text_type(brand)
|
||||||
field_display=brand_display, service_url=brands_url))
|
elif self.editing:
|
||||||
f.set_label('brand_uuid', "Brand")
|
brand_display = six.text_type(product.brand or '')
|
||||||
|
brands_url = self.request.route_url('brands.autocomplete')
|
||||||
|
f.set_widget('brand_uuid', forms.widgets.JQueryAutocompleteWidget(
|
||||||
|
field_display=brand_display, service_url=brands_url))
|
||||||
|
f.set_label('brand_uuid', "Brand")
|
||||||
|
else:
|
||||||
|
f.set_readonly('brand')
|
||||||
|
|
||||||
# status_code
|
# status_code
|
||||||
f.set_label('status_code', "Status")
|
f.set_label('status_code', "Status")
|
||||||
|
@ -856,6 +868,17 @@ class ProductsView(MasterView):
|
||||||
if not self.request.has_perm('products.view_deleted'):
|
if not self.request.has_perm('products.view_deleted'):
|
||||||
f.remove('deleted')
|
f.remove('deleted')
|
||||||
|
|
||||||
|
def objectify(self, form, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = form.validated
|
||||||
|
product = super(ProductsView, self).objectify(form, data=data)
|
||||||
|
|
||||||
|
# regular_price_amount
|
||||||
|
if (self.creating or self.editing) and 'regular_price_amount' in form.fields:
|
||||||
|
api.set_regular_price(product, data['regular_price_amount'])
|
||||||
|
|
||||||
|
return product
|
||||||
|
|
||||||
def render_department(self, product, field):
|
def render_department(self, product, field):
|
||||||
department = product.department
|
department = product.department
|
||||||
if not department:
|
if not department:
|
||||||
|
|
Loading…
Reference in a new issue