diff --git a/CHANGES.rst b/CHANGES.rst
index 87c74e0..8234597 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -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]
diff --git a/src/collective/contact/core/adapters.py b/src/collective/contact/core/adapters.py
index 6588e9c..791a74d 100644
--- a/src/collective/contact/core/adapters.py
+++ b/src/collective/contact/core/adapters.py
@@ -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()
diff --git a/src/collective/contact/core/behaviors.py b/src/collective/contact/core/behaviors.py
index 859b549..36d8b47 100644
--- a/src/collective/contact/core/behaviors.py
+++ b/src/collective/contact/core/behaviors.py
@@ -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
"""
diff --git a/src/collective/contact/core/behaviors.zcml b/src/collective/contact/core/behaviors.zcml
index 41324ae..a7da041 100644
--- a/src/collective/contact/core/behaviors.zcml
+++ b/src/collective/contact/core/behaviors.zcml
@@ -21,6 +21,12 @@
provides=".behaviors.IGlobalPositioning"
/>
+
+
+
diff --git a/src/collective/contact/core/profiles/testing/types/testtype.xml b/src/collective/contact/core/profiles/testing/types/testtype.xml
index cef2be5..78269d3 100644
--- a/src/collective/contact/core/profiles/testing/types/testtype.xml
+++ b/src/collective/contact/core/profiles/testing/types/testtype.xml
@@ -21,6 +21,7 @@
+
diff --git a/src/collective/contact/core/tests/test_behaviors.py b/src/collective/contact/core/tests/test_behaviors.py
index 37ce58d..a0494fa 100644
--- a/src/collective/contact/core/tests/test_behaviors.py
+++ b/src/collective/contact/core/tests/test_behaviors.py
@@ -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'