Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py	(revision 12102)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py	(revision 12103)
@@ -51,5 +51,6 @@
     ICustomer, ICustomersContainer, ICustomerRequestPW, ICustomersUtils,
     ICustomerDocument, ICustomerDocumentsContainer, ICustomerCreate,
-    ICustomerPDFDocument, IContractsContainer, IContract, IContractEdit
+    ICustomerPDFDocument, IContractsContainer, IContract, IContractEdit,
+    ISampleContract,
     )
 from waeup.ikoba.customers.catalog import search
@@ -1150,6 +1151,10 @@
     grok.require('waeup.viewCustomer')
     grok.template('contractpage')
-    form_fields = grok.AutoFields(IContract).omit('last_transition_date')
-    pnav = 4
+    pnav = 4
+
+    @property
+    def form_fields(self):
+        return grok.AutoFields(self.context.form_fields_interface).omit(
+            'last_transition_date')
 
     @property
@@ -1165,7 +1170,11 @@
     grok.require('waeup.manageCustomer')
     grok.template('contracteditpage')
-    form_fields = grok.AutoFields(IContract).omit('last_transition_date')
     pnav = 4
     deletion_warning = _('Are you sure?')
+
+    @property
+    def form_fields(self):
+        return grok.AutoFields(self.context.form_fields_interface).omit(
+            'last_transition_date')
 
     @property
@@ -1184,5 +1193,9 @@
     grok.name('edit')
     grok.require('waeup.handleCustomer')
-    form_fields = grok.AutoFields(IContractEdit).omit('last_transition_date')
+
+    @property
+    def form_fields(self):
+        return grok.AutoFields(self.context.edit_form_fields_interface).omit(
+            'last_transition_date')
 
     def update(self):
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py	(revision 12102)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py	(revision 12103)
@@ -30,5 +30,5 @@
     IContractsContainer, ICustomerNavigation,
     IContract, IContractEdit, ICustomersUtils,
-    )
+    ISampleContract, ISampleContractEdit)
 from waeup.ikoba.customers.utils import generate_contract_id
 from waeup.ikoba.utils.helpers import attrs_to_fields
@@ -64,4 +64,8 @@
 
     contract_category = None
+
+    form_fields_interface = None
+
+    edit_form_fields_interface = None
 
     def __init__(self):
@@ -142,5 +146,11 @@
     """
 
+    grok.implements(ISampleContract, ISampleContractEdit, ICustomerNavigation)
+
     contract_category = 'sample'
+
+    form_fields_interface = ISampleContract
+
+    edit_form_fields_interface = ISampleContractEdit
 
 SampleContract = attrs_to_fields(SampleContract)
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py	(revision 12102)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py	(revision 12103)
@@ -29,5 +29,6 @@
 
 from waeup.ikoba.customers.vocabularies import (
-    contextual_reg_num_source, GenderSource, nats_vocab, ConCatProductSource)
+    contextual_reg_num_source, GenderSource, nats_vocab,
+    ConCatProductSource, CustomerDocumentSource)
 
 
@@ -293,4 +294,5 @@
         )
 
+
 class IContractEdit(IContract):
     """Interface for editing contract data by customers.
@@ -303,2 +305,32 @@
         required = True,
         )
+
+
+class ISampleContract(IContract):
+    """A customer contract sample with document attached.
+
+    """
+
+    document = schema.Choice(
+        title = _(u'Document'),
+        source = CustomerDocumentSource(),
+        required = False,
+        )
+
+
+class ISampleContractEdit(ISampleContract):
+    """Interface for editing sample contract data by customers.
+
+    """
+
+    product = schema.Choice(
+        title = _(u'Product'),
+        source = ConCatProductSource(),
+        required = True,
+        )
+
+    document = schema.Choice(
+        title = _(u'Document'),
+        source = CustomerDocumentSource(),
+        required = True,
+        )
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py	(revision 12102)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py	(revision 12103)
@@ -40,5 +40,6 @@
 from waeup.ikoba.customers.interfaces import ICustomersUtils
 from waeup.ikoba.customers.customer import Customer
-from waeup.ikoba.interfaces import IUserAccount, IJobManager, APPROVED
+from waeup.ikoba.interfaces import (
+    IUserAccount, IJobManager, APPROVED, SUBMITTED)
 from waeup.ikoba.authentication import LocalRoleSetEvent
 from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
@@ -111,10 +112,10 @@
         self.customer_id = customer.customer_id
         self.customer = self.app['customers'][self.customer_id]
-        document = createObject('waeup.CustomerSampleDocument')
-        document.title = u'My first document'
-        self.customer['documents'].addDocument(document)
-        contract = createObject('waeup.SampleContract')
-        contract.title = u'My first contract'
-        self.customer['contracts'].addContract(contract)
+        self.document = createObject('waeup.CustomerSampleDocument')
+        self.document.title = u'My first document'
+        self.customer['documents'].addDocument(self.document)
+        self.contract = createObject('waeup.SampleContract')
+        self.contract.title = u'My first contract'
+        self.customer['contracts'].addContract(self.contract)
 
         # Set password
@@ -1074,5 +1075,5 @@
         self.browser.getLink("Manage").click()
         self.browser.getControl(name="form.product").value = ['SAM']
-        self.browser.getControl(name="form.title").value = 'My second app'
+        self.browser.getControl(name="form.title").value = 'My second contract'
         self.browser.getControl("Save").click()
         self.assertTrue('Form has been saved.' in self.browser.contents)
@@ -1140,5 +1141,5 @@
         IWorkflowState(self.customer).setState(APPROVED)
         self.browser.open(self.contracts_path + '/c102/edit')
-        self.browser.getControl(name="form.title").value = 'My second app'
+        self.browser.getControl(name="form.title").value = 'My second contract'
         # SAM is in the correct contract_category ...
         self.assertTrue('<option value="SAM">' in self.browser.contents)
@@ -1149,9 +1150,23 @@
         self.browser.getControl(name="form.product").value = ['SAM']
         self.browser.getControl("Save").click()
-        # After saving the form, last_product_id is set.
+        # Document is a required field on edit form page.
+        self.assertTrue('Document: <span class="error">Required input is missing.</span>'
+            in self.browser.contents)
+        # But our document can't be selected because it's not submitted
+        self.assertFalse('My first document' in self.browser.contents)
+        IWorkflowState(self.document).setState(SUBMITTED)
+        self.browser.open(self.contracts_path + '/c102/edit')
+        self.browser.getControl(name="form.product").value = ['SAM']
+        self.browser.getControl(name="form.document").value = ['d101']
+        self.browser.getControl(name="form.title").value = 'My second contract'
+        self.browser.getControl("Save").click()
+        # After saving the form, last_product_id and other attributes are set
+        self.assertTrue('Form has been saved.' in self.browser.contents)
         self.assertEqual(self.customer['contracts']['c102'].last_product_id, 'SAM')
-        self.assertTrue('Form has been saved.' in self.browser.contents)
+        self.assertEqual(contract.title, 'My second contract')
+        self.assertEqual(contract.product, self.product)
+        self.assertEqual(contract.document, self.document)
         # Saving the form again does not unset last_product_id
-        self.assertEqual(contract.title, 'My second app')
+        self.browser.getControl(name="form.title").value = 'My third contract'
         self.browser.getControl("Save").click()
         self.assertEqual(self.customer['contracts']['c102'].last_product_id, 'SAM')
@@ -1161,7 +1176,7 @@
         # Customer can submit the form. The form is also saved.
         self.browser.getLink("Edit").click()
-        self.browser.getControl(name="form.title").value = 'My third app'
+        self.browser.getControl(name="form.title").value = 'My fourth contract'
         self.browser.getControl("Apply now").click()
-        self.assertEqual(contract.title, 'My third app')
+        self.assertEqual(contract.title, 'My fourth contract')
         self.assertEqual(contract.state, 'submitted')
         self.assertTrue('Contract State: submitted for approval' in self.browser.contents)
