Various tweaks to the customer and person views/forms

These things still need plenty more help...
This commit is contained in:
Lance Edgar 2017-03-17 15:52:26 -05:00
parent e61b60e412
commit 15eae8b2c7
7 changed files with 83 additions and 12 deletions

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2016 Lance Edgar # Copyright © 2010-2017 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -34,5 +34,6 @@ from .alchemy import AlchemyForm
from .fields import AssociationProxyField from .fields import AssociationProxyField
from .renderers import * from .renderers import *
from . import fields
from . import renderers from . import renderers
from . import validators from . import validators

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2015 Lance Edgar # Copyright © 2010-2017 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -26,7 +26,9 @@ FormAlchemy Fields
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from formalchemy import Field import formalchemy as fa
from rattail.db import model
def AssociationProxyField(name, **kwargs): def AssociationProxyField(name, **kwargs):
@ -35,7 +37,7 @@ def AssociationProxyField(name, **kwargs):
proxies. proxies.
""" """
class ProxyField(Field): class ProxyField(fa.Field):
def sync(self): def sync(self):
if not self.is_readonly(): if not self.is_readonly():
@ -47,3 +49,54 @@ def AssociationProxyField(name, **kwargs):
kwargs.setdefault('value', value) kwargs.setdefault('value', value)
return ProxyField(name, **kwargs) return ProxyField(name, **kwargs)
class DefaultEmailField(fa.Field):
"""
Generic field for view/edit of default email address for a contact
"""
def __init__(self, name=None, **kwargs):
kwargs.setdefault('value', self.value)
if 'renderer' not in kwargs:
from tailbone.forms.renderers import EmailFieldRenderer
kwargs['renderer'] = EmailFieldRenderer
super(DefaultEmailField, self).__init__(name, **kwargs)
def value(self, contact):
if contact.emails:
return contact.emails[0].address
def sync(self):
if not self.is_readonly():
address = self._deserialize()
contact = self.parent.model
if contact.emails:
email = contact.emails[0]
email.address = address
else:
email = contact.add_email_address(address)
class DefaultPhoneField(fa.Field):
"""
Generic field for view/edit of default phone number for a contact
"""
def __init__(self, name=None, **kwargs):
kwargs.setdefault('value', self.value)
super(DefaultPhoneField, self).__init__(name, **kwargs)
def value(self, contact):
if contact.phones:
return contact.phones[0].number
def sync(self):
if not self.is_readonly():
number = self._deserialize()
contact = self.parent.model
if contact.phones:
phone = contact.phones[0]
phone.number = number
else:
phone = contact.add_phone_number(number)

View file

@ -31,7 +31,7 @@ from .core import CustomFieldRenderer, DateFieldRenderer
from .common import (StrippedTextFieldRenderer, CodeTextAreaFieldRenderer, AutocompleteFieldRenderer, from .common import (StrippedTextFieldRenderer, CodeTextAreaFieldRenderer, AutocompleteFieldRenderer,
DecimalFieldRenderer, CurrencyFieldRenderer, QuantityFieldRenderer, DecimalFieldRenderer, CurrencyFieldRenderer, QuantityFieldRenderer,
DateTimeFieldRenderer, DateTimePrettyFieldRenderer, TimeFieldRenderer, DateTimeFieldRenderer, DateTimePrettyFieldRenderer, TimeFieldRenderer,
EnumFieldRenderer, YesNoFieldRenderer) EmailFieldRenderer, EnumFieldRenderer, YesNoFieldRenderer)
from .files import FileFieldRenderer from .files import FileFieldRenderer

View file

@ -34,7 +34,7 @@ from rattail.util import pretty_quantity
import formalchemy as fa import formalchemy as fa
from formalchemy import fields as fa_fields, helpers as fa_helpers from formalchemy import fields as fa_fields, helpers as fa_helpers
from pyramid.renderers import render from pyramid.renderers import render
from webhelpers.html import HTML from webhelpers.html import HTML, tags
from tailbone.util import pretty_datetime, raw_datetime from tailbone.util import pretty_datetime, raw_datetime
@ -178,6 +178,18 @@ class TimeFieldRenderer(fa.TimeFieldRenderer):
pass pass
class EmailFieldRenderer(fa.TextFieldRenderer):
"""
Renderer for email address fields
"""
def render_readonly(self, **kwargs):
address = self.raw_value
if not address:
return ''
return tags.link_to(address, 'mailto:{}'.format(address))
class EnumFieldRenderer(fa_fields.SelectFieldRenderer): class EnumFieldRenderer(fa_fields.SelectFieldRenderer):
""" """
Renderer for simple enumeration fields. Renderer for simple enumeration fields.

View file

@ -6,7 +6,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>${self.global_title()} &raquo; ${capture(self.title)}</title> <title>${self.global_title()} &raquo; ${capture(self.title)|n}</title>
${self.favicon()} ${self.favicon()}
${base.core_javascript()} ${base.core_javascript()}
${self.extra_javascript()} ${self.extra_javascript()}

View file

@ -37,7 +37,6 @@ from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView, AutocompleteView from tailbone.views import MasterView, AutocompleteView
from rattail import enum
from rattail.db import model from rattail.db import model
@ -112,14 +111,20 @@ class CustomersView(MasterView):
raise HTTPNotFound raise HTTPNotFound
def _preconfigure_fieldset(self, fs):
fs.append(forms.fields.DefaultPhoneField('default_phone', label="Phone Number"))
fs.append(forms.fields.DefaultEmailField('default_email', label="Email Address"))
fs.email_preference.set(renderer=forms.EnumFieldRenderer(self.enum.EMAIL_PREFERENCE))
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.email_preference.set(renderer=forms.EnumFieldRenderer(enum.EMAIL_PREFERENCE))
fs.configure( fs.configure(
include=[ include=[
fs.id.label("ID"), fs.id.label("ID"),
fs.name, fs.name,
fs.phone.label("Phone Number").readonly(), # fs.phone.label("Phone Number").readonly(),
fs.email.label("Email Address").readonly(), fs.default_phone,
# fs.email.label("Email Address").readonly(),
fs.default_email,
fs.email_preference, fs.email_preference,
]) ])

View file

@ -117,10 +117,10 @@ class PeopleView(MasterView):
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.configure( fs.configure(
include=[ include=[
fs.display_name,
fs.first_name, fs.first_name,
fs.middle_name, fs.middle_name,
fs.last_name, fs.last_name,
fs.display_name,
fs.phone, fs.phone,
fs.email, fs.email,
fs.address, fs.address,