
* Replaced `forms` module with subpackage; added some initial goodies (many of which are currently just imports from `edbob`). * Added/edited various CRUD templates for consistency. * Renamed `customer_groups` module and template folder to `customergroups`. * Modified several view modules so their Pyramid configuration is more "extensible." This just means routes and views are defined as two separate steps, so that derived applications may inherit the route definitions if they so choose. * Added Employee CRUD views; added Email Address field to index view. * Updated `people` view module so it no longer derives from that of `edbob`. * Added support for, and some implementations of, extra key lookup abilities to CRUD views. This allows URLs to use a "natural" key (e.g. Customer ID instead of UUID), for cases where that is more helpful. * Product CRUD now uses autocomplete for Brand field. Also, price fields no longer appear within an editable fieldset. * Within Store index view, default sort is now ID instead of Name. * Added Contact and Phone Number fields to Vendor CRUD views; added Contact and Email Address fields to index view.
111 lines
3.7 KiB
Python
111 lines
3.7 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
################################################################################
|
|
#
|
|
# Rattail -- Retail Software Framework
|
|
# Copyright © 2010-2012 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 <http://www.gnu.org/licenses/>.
|
|
#
|
|
################################################################################
|
|
|
|
"""
|
|
``rattail.pyramid.forms.renderers`` -- FormAlchemy Field Renderers
|
|
"""
|
|
|
|
from webhelpers.html import literal
|
|
from webhelpers.html import tags
|
|
|
|
import formalchemy
|
|
|
|
from edbob.pyramid.forms import pretty_datetime
|
|
from edbob.pyramid.forms.formalchemy.renderers import (
|
|
AutocompleteFieldRenderer, EnumFieldRenderer, YesNoFieldRenderer)
|
|
|
|
import rattail
|
|
from rattail.gpc import GPC
|
|
|
|
|
|
__all__ = ['AutocompleteFieldRenderer', 'EnumFieldRenderer', 'YesNoFieldRenderer',
|
|
'GPCFieldRenderer', 'PersonFieldRenderer', 'PriceFieldRenderer',
|
|
'PriceWithExpirationFieldRenderer']
|
|
|
|
|
|
class GPCFieldRenderer(formalchemy.TextFieldRenderer):
|
|
"""
|
|
Renderer for :class:`rattail.gpc.GPC` fields.
|
|
"""
|
|
|
|
@property
|
|
def length(self):
|
|
# Hm, should maybe consider hard-coding this...?
|
|
return len(str(GPC(0)))
|
|
|
|
|
|
def PersonFieldRenderer(url):
|
|
|
|
BaseRenderer = AutocompleteFieldRenderer(url)
|
|
|
|
class PersonFieldRenderer(BaseRenderer):
|
|
|
|
def render_readonly(self, **kwargs):
|
|
person = self.raw_value
|
|
if not person:
|
|
return ''
|
|
return tags.link_to(
|
|
str(person),
|
|
self.request.route_url('person.read', uuid=person.uuid))
|
|
|
|
return PersonFieldRenderer
|
|
|
|
|
|
class PriceFieldRenderer(formalchemy.TextFieldRenderer):
|
|
"""
|
|
Renderer for fields which reference a :class:`ProductPrice` instance.
|
|
"""
|
|
|
|
def render_readonly(self, **kwargs):
|
|
price = self.field.raw_value
|
|
if price:
|
|
if price.price is not None and price.pack_price is not None:
|
|
if price.multiple > 1:
|
|
return literal('$ %0.2f / %u ($ %0.2f / %u)' % (
|
|
price.price, price.multiple,
|
|
price.pack_price, price.pack_multiple))
|
|
return literal('$ %0.2f ($ %0.2f / %u)' % (
|
|
price.price, price.pack_price, price.pack_multiple))
|
|
if price.price is not None:
|
|
if price.multiple > 1:
|
|
return '$ %0.2f / %u' % (price.price, price.multiple)
|
|
return '$ %0.2f' % price.price
|
|
if price.pack_price is not None:
|
|
return '$ %0.2f / %u' % (price.pack_price, price.pack_multiple)
|
|
return ''
|
|
|
|
|
|
class PriceWithExpirationFieldRenderer(PriceFieldRenderer):
|
|
"""
|
|
Price field renderer which also displays the expiration date, if present.
|
|
"""
|
|
|
|
def render_readonly(self, **kwargs):
|
|
res = super(PriceWithExpirationFieldRenderer, self).render_readonly(**kwargs)
|
|
if res:
|
|
price = self.field.raw_value
|
|
if price.ends:
|
|
res += ' (%s)' % pretty_datetime(price.ends, from_='utc')
|
|
return res
|