Various tweaks to the customer and person views/forms
These things still need plenty more help...
This commit is contained in:
parent
e61b60e412
commit
15eae8b2c7
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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()} » ${capture(self.title)}</title>
|
<title>${self.global_title()} » ${capture(self.title)|n}</title>
|
||||||
${self.favicon()}
|
${self.favicon()}
|
||||||
${base.core_javascript()}
|
${base.core_javascript()}
|
||||||
${self.extra_javascript()}
|
${self.extra_javascript()}
|
||||||
|
|
|
@ -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,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue