Index: main/waeup.ikoba/trunk/src/waeup/ikoba/app.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/app.py	(revision 12257)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/app.py	(revision 12258)
@@ -42,6 +42,4 @@
     grok.implements(ICompany)
 
-    _curr_con_id = 101
-
     # Setup authentication for this app. Note: this is only
     # initialized, when a new instance of this app is created.
@@ -54,23 +52,4 @@
         self.setup()
         return
-
-    @property
-    def unique_contract_id(self):
-        """A unique contract id for all contract objects in customers.
-
-        The contract id returned is guaranteed to be unique.
-
-        Once a contract id was issued, it won't be issued again.
-
-        Obtaining an contract id is currently not thread-safe but can be
-        made easily by enabling commented lines.
-        """
-        # lock.acquire() # lock data
-        new_id = u'c%s' % (self._curr_con_id)
-        self._curr_con_id += 1
-        # self._p_changed = True
-        # commit()
-        # lock.release() # end of lock
-        return new_id
 
     def setup(self):
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/batching.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/batching.py	(revision 12257)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/batching.py	(revision 12258)
@@ -406,13 +406,4 @@
         return None
 
-        #documents = self.getParent(row, site)
-        #if documents is None:
-        #    return None
-        #document_id = row.get('document_id', None)
-        #if document_id is None:
-        #    return None
-        #entry = documents.get(document_id)
-        #return entry
-
     def updateEntry(self, obj, row, site, filename):
         """Update obj to the values given in row.
@@ -496,26 +487,28 @@
         if contract_id is None:
             return None
-        entry = contracts.get(contract_id)
-        return entry
+        cat = queryUtility(ICatalog, name='contracts_catalog')
+        results = list(cat.searchResults(contract_id=(contract_id, contract_id)))
+        if results:
+            return results[0]
+        return None
 
     def updateEntry(self, obj, row, site, filename):
         """Update obj to the values given in row.
         """
+        # Remove contract_id from row if empty
+        if 'contract_id' in row and row['contract_id'] in (None, IGNORE_MARKER):
+            row.pop('contract_id')
         items_changed = super(ContractProcessor, self).updateEntry(
             obj, row, site, filename)
         customer = self.getParent(row, site).__parent__
         customer.__parent__.logger.info(
-            '%s - %s - %s - updated: %s'
-            % (self.name, filename, customer.customer_id, items_changed))
+            '%s - %s - %s - %s - updated: %s'
+            % (self.name, filename, customer.customer_id, obj.contract_id,
+               items_changed))
         return
 
     def addEntry(self, obj, row, site):
         parent = self.getParent(row, site)
-        contract_id = row['contract_id'].strip('#')
-        parent[contract_id] = obj
-        # Reset _curr_con_id if contract_id has been imported
-        site = grok.getSite()
-        if row.get('contract_id', None) not in (None, IGNORE_MARKER):
-            site._curr_con_id -= 1
+        parent.addContract(obj)
         return
 
@@ -541,27 +534,3 @@
             if class_name != self.factory_name.strip('waeup.'):
                 errs.append(('class_name','wrong processor'))
-        try:
-            # Correct con_id counter. As the IConverter for contracts
-            # creates contract objects that are not used afterwards, we
-            # have to fix the site-wide con_id counter.
-            site = grok.getSite()
-            site._curr_con_id -= 1
-        except (KeyError, TypeError, AttributeError):
-                pass
-        # We have to check contract_id.
-        contract_id = row.get('contract_id', None)
-        if mode == 'create':
-            if not contract_id:
-                contract_id = generate_contract_id()
-                conv_dict['contract_id'] = contract_id
-                return errs, inv_errs, conv_dict
-            cat = queryUtility(ICatalog, name='contracts_catalog')
-            results = list(
-                cat.searchResults(contract_id=(contract_id, contract_id)))
-            if results:
-                # contract_id must not exist.
-                errs.append(('contract_id','id exists'))
-        else:
-            if not contract_id.startswith('c'):
-                errs.append(('contract_id','invalid format'))
         return errs, inv_errs, conv_dict
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py	(revision 12257)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py	(revision 12258)
@@ -1165,5 +1165,6 @@
     pnav = 4
 
-    form_fields = grok.AutoFields(IContract).omit('product_object')
+    form_fields = grok.AutoFields(IContract).omit(
+        'product_object', 'contract_id')
 
     @property
@@ -1180,4 +1181,5 @@
         # classes depending on the contype parameter given in form.
         contract = createObject('waeup.%s' % contype)
+        self.applyData(contract, **data)
         self.context.addContract(contract)
         contype = getUtility(ICustomersUtils).SELECTABLE_CONTYPES_DICT[contype]
@@ -1227,5 +1229,6 @@
     @property
     def form_fields(self):
-        return grok.AutoFields(self.context.form_fields_interface)
+        return grok.AutoFields(self.context.form_fields_interface).omit(
+            'contract_id')
 
     @property
@@ -1247,5 +1250,6 @@
     @property
     def form_fields(self):
-        return grok.AutoFields(self.context.edit_form_fields_interface)
+        return grok.AutoFields(self.context.edit_form_fields_interface).omit(
+            'contract_id')
 
     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 12257)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py	(revision 12258)
@@ -27,5 +27,6 @@
 from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
 from waeup.ikoba.interfaces import MessageFactory as _
-from waeup.ikoba.interfaces import IIkobaUtils, IObjectHistory, VERIFIED
+from waeup.ikoba.interfaces import (
+    IIkobaUtils, IObjectHistory, VERIFIED, IIDSource)
 from waeup.ikoba.customers.interfaces import (
     IContractsContainer, ICustomerNavigation,
@@ -75,8 +76,6 @@
         super(ContractBase, self).__init__()
         # The site doesn't exist in unit tests
-        try:
-            self.contract_id = generate_contract_id()
-        except AttributeError:
-            self.contract_id = u'c999'
+        source = getUtility(IIDSource)
+        self.contract_id = unicode(source.get_hex_uuid())
         self.last_product_id = None
         return
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py	(revision 12257)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py	(revision 12258)
@@ -265,5 +265,4 @@
 
     """
-    contract_id = Attribute('Contract Identifier')
     history = Attribute('Object history, a list of messages')
     state = Attribute('Returns the contract state')
@@ -280,4 +279,9 @@
     translated_class_name = Attribute('Translatable class name')
 
+    contract_id = schema.TextLine(
+        title = _(u'Contract Id'),
+        required = False,
+        )
+
     title = schema.TextLine(
         title = _(u'Contract Title'),
Index: main/waeup.ikoba/trunk/src/waeup/ikoba/utils/batching.py
===================================================================
--- main/waeup.ikoba/trunk/src/waeup/ikoba/utils/batching.py	(revision 12257)
+++ main/waeup.ikoba/trunk/src/waeup/ikoba/utils/batching.py	(revision 12258)
@@ -227,5 +227,6 @@
                 # Computed attributes can't be set.
                 continue
-            log_value = getattr(value, 'any_id', value)
+            log_value = getattr(value, 'product_id', value)
+            log_value = getattr(value, 'document_id', log_value)
             changed.append('%s=%s' % (key, log_value))
 
