Birthday is now optional as a behaviour.
This commit is contained in:
parent
df643b9d04
commit
0339000bdf
|
@ -4,6 +4,9 @@ Changelog
|
|||
1.0 (unreleased)
|
||||
----------------
|
||||
|
||||
- Birthday is now optional as a behaviour.
|
||||
[thomasdesvenain]
|
||||
|
||||
- Use (-200, 1) years range for birthday field.
|
||||
[vincentfretin]
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ from Products.CMFPlone.utils import safe_unicode
|
|||
from collective.contact.core.interfaces import IVCard, IContactable
|
||||
from collective.contact.core.content.held_position import IHeldPosition,\
|
||||
HeldPosition
|
||||
from collective.contact.core.behaviors import IBirthday
|
||||
|
||||
|
||||
class HeldPositionVCard(grok.Adapter):
|
||||
|
@ -35,7 +36,7 @@ class HeldPositionVCard(grok.Adapter):
|
|||
vcard.add('fn')
|
||||
vcard.fn.value = ' '.join([e for e in (firstname, lastname) if e])
|
||||
|
||||
if person.birthday is not None:
|
||||
if IBirthday.providedBy(person) and person.birthday is not None:
|
||||
vcard.add('bday')
|
||||
vcard.bday.value = person.birthday.isoformat()
|
||||
|
||||
|
|
|
@ -3,14 +3,17 @@ from zope.interface import Interface
|
|||
from zope import schema
|
||||
from Acquisition import aq_base
|
||||
|
||||
from z3c.form.widget import ComputedWidgetAttribute
|
||||
from z3c.form.widget import FieldWidget
|
||||
from plone.supermodel import model
|
||||
|
||||
from plone.supermodel.directives import fieldset
|
||||
from plone.autoform.interfaces import IFormFieldProvider
|
||||
from plone.autoform import directives as form
|
||||
from plone.formwidget.masterselect import MasterSelectBoolField
|
||||
from plone.formwidget.datetime.z3cform import DateWidget
|
||||
from plone.app.textfield import RichText
|
||||
from plone.app.dexterity.browser.types import TypeSchemaContext
|
||||
from z3c.form.widget import ComputedWidgetAttribute
|
||||
|
||||
from Products.CMFDefault.utils import checkEmailAddress
|
||||
from Products.CMFDefault.exceptions import EmailAddressInvalid
|
||||
|
@ -233,6 +236,22 @@ DefaultParentAddress = ComputedWidgetAttribute(
|
|||
field=IContactDetails['parent_address'], view=Interface)
|
||||
|
||||
|
||||
|
||||
def DateFieldWidget(field, request):
|
||||
"""IFieldWidget factory for DatetimeWidget."""
|
||||
widget = FieldWidget(field, DateWidget(request))
|
||||
widget.years_range = (-200, 1)
|
||||
return widget
|
||||
|
||||
|
||||
class IBirthday(model.Schema):
|
||||
|
||||
form.widget(birthday=DateFieldWidget)
|
||||
birthday = schema.Date(
|
||||
title=_("Birthday"),
|
||||
required=False,
|
||||
)
|
||||
|
||||
class IRelatedOrganizations(model.Schema):
|
||||
"""A content on which we can attach organizations
|
||||
"""
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
provides=".behaviors.IGlobalPositioning"
|
||||
/>
|
||||
|
||||
<plone:behavior
|
||||
title="Birthday"
|
||||
description="Contact have a birthday."
|
||||
provides=".behaviors.IBirthday"
|
||||
/>
|
||||
|
||||
<plone:behavior
|
||||
title="Related organizations"
|
||||
description="We can attach organizations on content."
|
||||
|
|
|
@ -4,6 +4,7 @@ from collective.contact.core.browser.contactable import BaseView
|
|||
from collective.contact.core.browser.utils import get_ttw_fields,\
|
||||
date_to_DateTime
|
||||
from collective.contact.core.interfaces import IContactable
|
||||
from collective.contact.core.behaviors import IBirthday
|
||||
|
||||
|
||||
class Contact(BaseView):
|
||||
|
@ -35,11 +36,14 @@ class Contact(BaseView):
|
|||
self.person = person
|
||||
self.fullname = person.Title()
|
||||
self.title = held_position.Title()
|
||||
|
||||
birthday = person.birthday
|
||||
if birthday is not None:
|
||||
birthday = date_to_DateTime(birthday)
|
||||
self.birthday = self.context.toLocalizedTime(birthday)
|
||||
|
||||
if IBirthday.providedBy(person):
|
||||
birthday = person.birthday
|
||||
if birthday is not None:
|
||||
birthday = date_to_DateTime(birthday)
|
||||
self.birthday = self.context.toLocalizedTime(birthday)
|
||||
else:
|
||||
self.birthday = None
|
||||
|
||||
self.gender = person.gender or ''
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ from collective.contact.core.browser.contactable import BaseView
|
|||
from collective.contact.core.browser.utils import date_to_DateTime,\
|
||||
get_ttw_fields
|
||||
from collective.contact.core.interfaces import IContactable
|
||||
from collective.contact.core.behaviors import IBirthday
|
||||
|
||||
|
||||
class Person(BaseView):
|
||||
|
@ -21,10 +22,13 @@ class Person(BaseView):
|
|||
person = self.person
|
||||
|
||||
self.name = person.Title()
|
||||
birthday = person.birthday
|
||||
if birthday is not None:
|
||||
birthday = date_to_DateTime(birthday)
|
||||
self.birthday = self.context.toLocalizedTime(birthday)
|
||||
if IBirthday.providedBy(person):
|
||||
birthday = person.birthday
|
||||
if birthday is not None:
|
||||
birthday = date_to_DateTime(birthday)
|
||||
self.birthday = self.context.toLocalizedTime(birthday)
|
||||
else:
|
||||
self.birthday = ""
|
||||
|
||||
self.person_title = person.person_title
|
||||
self.gender = person.gender or ''
|
||||
|
|
|
@ -3,7 +3,6 @@ from zope.interface import implements
|
|||
from zope.interface import Attribute
|
||||
from z3c.form.interfaces import NO_VALUE
|
||||
from z3c.form.browser.radio import RadioFieldWidget
|
||||
from z3c.form.widget import FieldWidget
|
||||
|
||||
from five import grok
|
||||
|
||||
|
@ -12,7 +11,6 @@ from plone.dexterity.content import Container
|
|||
from plone.dexterity.schema import DexteritySchemaPolicy
|
||||
from plone.namedfile.field import NamedImage
|
||||
from plone.supermodel import model
|
||||
from plone.formwidget.datetime.z3cform import DateWidget
|
||||
|
||||
from collective.contact.core import _
|
||||
from collective.contact.core.browser.contactable import Contactable
|
||||
|
@ -20,13 +18,6 @@ from collective.contact.widget.interfaces import IContactContent
|
|||
from collective.contact.core.content.held_position import IHeldPosition
|
||||
|
||||
|
||||
def DateFieldWidget(field, request):
|
||||
"""IFieldWidget factory for DatetimeWidget."""
|
||||
widget = FieldWidget(field, DateWidget(request))
|
||||
widget.years_range = (-200, 1)
|
||||
return widget
|
||||
|
||||
|
||||
class IPerson(model.Schema, IContactContent):
|
||||
"""Interface for Person content type"""
|
||||
|
||||
|
@ -50,11 +41,6 @@ class IPerson(model.Schema, IContactContent):
|
|||
title=_("Person title"),
|
||||
required=False,
|
||||
)
|
||||
form.widget(birthday=DateFieldWidget)
|
||||
birthday = schema.Date(
|
||||
title=_("Birthday"),
|
||||
required=False,
|
||||
)
|
||||
photo = NamedImage(
|
||||
title=_("Photo"),
|
||||
required=False,
|
||||
|
@ -64,6 +50,7 @@ class IPerson(model.Schema, IContactContent):
|
|||
"""Returns held positions of this person
|
||||
"""
|
||||
|
||||
|
||||
class PersonContactableAdapter(Contactable):
|
||||
"""Contactable adapter for Person content type"""
|
||||
|
||||
|
@ -97,7 +84,10 @@ class Person(Container):
|
|||
|
||||
def get_held_positions(self):
|
||||
return [obj for obj in self.values() if IHeldPosition.providedBy(obj)]
|
||||
|
||||
|
||||
def get_held_positions_titles(self):
|
||||
return [p.Title() for p in self.get_held_positions()]
|
||||
|
||||
|
||||
class PersonSchemaPolicy(grok.GlobalUtility,
|
||||
DexteritySchemaPolicy):
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<property name="behaviors">
|
||||
<element value="plone.app.content.interfaces.INameFromTitle"/>
|
||||
<element value="collective.contact.core.behaviors.IContactDetails" />
|
||||
<element value="collective.contact.core.behaviors.IBirthday" />
|
||||
</property>
|
||||
<property name="schema" />
|
||||
<!-- DO NOT use a model_source or it removes manually added fields while reapplying the profile -->
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<property name="behaviors">
|
||||
<element value="collective.contact.core.behaviors.IContactDetails" />
|
||||
<element value="collective.contact.core.behaviors.IGlobalPositioning" />
|
||||
<element value="collective.contact.core.behaviors.IBirthday" />
|
||||
</property>
|
||||
<property name="schema" />
|
||||
<!-- DO NOT use a model_source or it removes manually added fields while reapplying the profile -->
|
||||
|
|
|
@ -12,7 +12,7 @@ from ecreall.helpers.testing.base import BaseTest
|
|||
|
||||
from collective.contact.core.testing import INTEGRATION
|
||||
from collective.contact.core.behaviors import IContactDetails,\
|
||||
IGlobalPositioning
|
||||
IGlobalPositioning, IBirthday
|
||||
|
||||
|
||||
class TestBehaviors(unittest.TestCase, BaseTest):
|
||||
|
@ -33,18 +33,22 @@ class TestBehaviors(unittest.TestCase, BaseTest):
|
|||
name='collective.contact.core.behaviors.IContactDetails')
|
||||
global_positioning_behavior = getUtility(IBehavior,
|
||||
name='collective.contact.core.behaviors.IGlobalPositioning')
|
||||
birthday_behavior = getUtility(IBehavior,
|
||||
name='collective.contact.core.behaviors.IBirthday')
|
||||
self.assertEqual(contact_details_behavior.interface, IContactDetails)
|
||||
self.assertEqual(global_positioning_behavior.interface,
|
||||
IGlobalPositioning)
|
||||
self.assertEqual(birthday_behavior.interface, IBirthday)
|
||||
IFormFieldProvider.providedBy(contact_details_behavior.interface)
|
||||
IFormFieldProvider.providedBy(global_positioning_behavior.interface)
|
||||
IFormFieldProvider.providedBy(birthday_behavior.interface)
|
||||
|
||||
def test_contact_details_fields(self):
|
||||
item = self.testitem
|
||||
self.assertIsNone(item.getAttributes())
|
||||
for attr in ('country', 'region', 'zip_code', 'city', 'street',
|
||||
'number', 'im_handle', 'cell_phone', 'phone', 'email',
|
||||
'additional_address_details'):
|
||||
'additional_address_details', 'birthday'):
|
||||
self.assertTrue(hasattr(item, attr))
|
||||
item.phone = '0655443322'
|
||||
item.email = 'toto@example.com'
|
||||
|
|
Reference in New Issue