diff --git a/product/ERP5/skins/erp5_core/Base_editRelation.py b/product/ERP5/skins/erp5_core/Base_editRelation.py
new file mode 100755
index 0000000000000000000000000000000000000000..5f90f3065a80f28de806aa2b484c3ab2914e906f
--- /dev/null
+++ b/product/ERP5/skins/erp5_core/Base_editRelation.py
@@ -0,0 +1,74 @@
+## Script (Python) "Base_editRelation"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=form_id, field_id, selection_index, selection_name, uids, object_uid, listbox_uid
+##title=
+##
+# Updates attributes of an Zope document
+# which is in a class inheriting from ERP5 Base
+
+
+from Products.Formulator.Errors import ValidationError, FormValidationError
+
+request=context.REQUEST
+
+o = context.portal_catalog.getObject(object_uid)
+
+if o is None:
+  return "Sorrry, Error, the calling object was not catalogued. Do not know how to do ?"
+
+if listbox_uid is not None:
+  selected_uids = context.portal_selections.updateSelectionCheckedUidList(selection_name,listbox_uid,uids)
+  uids = context.portal_selections.getSelectionCheckedUidsFor(selection_name)
+
+if request.has_key('previous_form_id'):
+  previous_form_id = request.get('previous_form_id')
+  if previous_form_id != '':
+    form_id = previous_form_id
+
+form = getattr(context, form_id)
+field = form.get_field(field_id)
+base_category = field.get_value('base_category')
+relation_setter_id = field.get_value('relation_setter_id')
+if relation_setter_id: relation_setter = getattr(o, relation_setter_id)
+portal_type = map(lambda x:x[0],field.get_value('portal_type'))
+
+if uids != []:
+  if relation_setter_id:
+    # Clear the relation
+    relation_setter((), portal_type=portal_type)
+    # Warning, portal type is at strange value because of form
+    # And update it
+    relation_setter(uids, portal_type=portal_type)
+  else:
+    # Clear the relation
+    o.setValueUids(base_category, (), portal_type=portal_type)
+    # Warning, portal type is at strange value because of form
+    # And update it
+    o.setValueUids(base_category, uids, portal_type=portal_type)
+else:
+  if relation_setter_id:
+    # Clear the relation
+    relation_setter((), portal_type=portal_type)
+  else:    
+    # Clear the relation
+    o.setValueUids(base_category,  (), portal_type=portal_type)
+
+if not selection_index:
+  redirect_url = '%s/%s?%s' % ( o.absolute_url()
+                            , form_id
+                            , 'portal_status_message=Data+Updated.'
+                            )
+else:
+  redirect_url = '%s/%s?selection_index=%s&selection_name=%s&%s' % ( o.absolute_url()
+                            , form_id
+                            , selection_index
+                            , selection_name
+                            , 'portal_status_message=Data+Updated.'
+                            )
+
+
+request[ 'RESPONSE' ].redirect( redirect_url )
diff --git a/product/ERP5/skins/erp5_core/Base_validateRelation.py b/product/ERP5/skins/erp5_core/Base_validateRelation.py
new file mode 100755
index 0000000000000000000000000000000000000000..891edc3e557dc22605487bae89683ac494d13740
--- /dev/null
+++ b/product/ERP5/skins/erp5_core/Base_validateRelation.py
@@ -0,0 +1,212 @@
+## Script (Python) "Base_validateRelation"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=form_id, selection_index, selection_name, object_uid, object_path
+##title=
+##
+from Products.Formulator.Errors import ValidationError, FormValidationError
+from ZTUtils import make_query
+
+
+
+request=context.REQUEST
+
+# We stop doing this
+#base_category = context.getBaseCategoryId()
+base_category = None
+
+o = context.portal_catalog.getObject(object_uid)
+redirect_url = None
+
+if o is None:
+  # we first try to reindex the object, thanks to the object_path
+  o = context.restrictedTraverse(object_path)
+  if o is not None:
+    o.immediateReindexObject()
+  else:
+    return "Sorrry, Error, the calling object was not catalogued. Do not know how to do ?"
+
+def checkSameKeys(a , b):
+  """
+    Checks if the two lists contain
+    the same values
+  """
+  same = 1
+  for ka in a:
+    if not ka in b:
+      same = 0
+  for kb in b:
+    if not kb in a:
+      same = 0
+  return same
+
+def getOrderedUids(uids, values, catalog_index):
+  value_to_uid = {}
+  for uid in uids:
+    key = context.portal_catalog(uid=uid)[0].getObject().getProperty(catalog_index)
+    value_to_uid[key] = uid
+  uids = []
+  for value in values:
+    uids.append(value_to_uid[value])
+  return uids
+
+  field.get_value('base_category')
+
+try:
+  # Validate the form
+  form = getattr(context,form_id)
+  form.validate_all_to_request(request)
+  my_field = None
+  # XXXXXXXXXXXXXXXXX
+  # we should update data here if we want to be clever
+  # Find out which field defines the relation
+  for f in form.get_fields():
+    if f.has_value( 'base_category'):
+        #if f.get_value('base_category') == base_category:
+        k = f.id
+        v = getattr(request,k,None)
+        if v in (None, '', 'None', [], ()) and context.getProperty(k[3:]) in (None, '', 'None', [], ()):
+          # The old value is None and the new value is not significant
+          # This bug fix is probably temporary since '' means None
+          pass
+        elif v != context.getProperty(k[3:]):
+          old_value = context.getProperty(k[3:])
+          my_field = f
+          new_value = v
+          base_category = f.get_value( 'base_category')
+  if my_field and base_category is not None:
+    empty_list = 0
+    if new_value == '':
+      new_value = []
+    if same_type(new_value,'a'):
+      new_value = [new_value]
+    same_keys = 0
+    if my_field.meta_type == 'MultiRelationStringField':
+      # The checkProperty sometimes does not provide an
+      # acceptable value - XXXX - see vetement_id in Modele View
+      if old_value is '' or old_value is None:
+        old_value = []
+      try:
+        old_value = list(old_value)
+      except:
+        old_value = [old_value]
+      #return str((context.getProperty('vetement_id_list'),my_field.id, new_value, old_value))
+      if checkSameKeys(new_value, old_value):
+        # Reorder keys
+        same_keys = 1
+    portal_type = map(lambda x:x[0],my_field.get_value('portal_type'))
+    # We work with strings - ie. single values
+    kw ={}
+    kw[my_field.get_value('catalog_index')] = new_value
+    context.portal_selections.setSelectionParamsFor('search_relation', kw.copy())
+    kw['base_category'] = base_category
+    kw['portal_type'] = portal_type
+    request.set('base_category', base_category)
+    request.set('portal_type', portal_type)
+    request.set(my_field.get_value('catalog_index'), new_value)
+    request.set('field_id', my_field.id)
+    previous_uids = o.getValueUids(base_category, portal_type=portal_type)
+    relation_list = context.portal_catalog(**kw)
+    relation_uid_list = map(lambda x: x.uid, relation_list)
+    uids = []
+    for uid in previous_uids:
+      if uid in relation_uid_list:
+        uids.append(uid)
+    context.portal_selections.setSelectionCheckedUidsFor('search_relation', uids)
+    if len(new_value) == 0:
+      # Clear the relation
+      o.setValueUids(base_category,  (), portal_type=portal_type)
+    elif same_keys:
+      uids = getOrderedUids(uids, new_value, my_field.get_value('catalog_index'))
+      return o.Base_editRelation( form_id,
+                                my_field.id,
+                                selection_index,
+                                selection_name,
+                                uids,
+                                object_uid,
+                                listbox_uid=None)
+    elif len(relation_list) > 0:
+      # If we have only one in the list, we don't want to lose our time by
+      # selecting it. So we directly do the update
+      if len(relation_list) == 1:
+          selection_index=None
+          uids = [relation_list[0].uid]
+          return o.Base_editRelation( form_id = form_id,
+                                    field_id = my_field.id,
+                                    selection_index = selection_index,
+                                    selection_name = selection_name,
+                                    uids = uids,
+                                    object_uid = object_uid,
+                                    listbox_uid=None)
+      # This is just added when we want to just remove
+      # one item inside a multiRelationField
+      else:
+        if len(relation_uid_list) == len(new_value):
+          complete_value_list = []
+          # We have to find the full value, for example instead of
+          # /foo/ba% we should have /foo/bar
+          for value in new_value:
+            catalog_index = my_field.get_value('catalog_index')
+            kw[catalog_index] = value
+            complete_value = context.portal_catalog(**kw)[0].getObject().getProperty(catalog_index)
+            complete_value_list.append(complete_value)
+          new_value = complete_value_list
+          uids = getOrderedUids(relation_uid_list, new_value, my_field.get_value('catalog_index'))
+          selection_index=None
+          return o.Base_editRelation( form_id = form_id,
+                                    field_id = my_field.id,
+                                    selection_index = selection_index,
+                                    selection_name = selection_name,
+                                    uids = uids,
+                                    object_uid = object_uid,
+                                    listbox_uid=None)
+
+      kw = {}
+      kw['form_id'] = 'search_relation'
+      kw['selection_index'] = selection_index
+      kw['object_uid'] = object_uid
+      kw['field_id'] = my_field.id
+      kw['portal_type'] = portal_type
+      kw['base_category'] = base_category
+      kw['selection_name'] = 'search_relation'
+      kw['cancel_url'] = request.get('HTTP_REFERER')
+      kw['previous_form_id'] = form_id
+      redirect_url = '%s/%s?%s' % ( o.absolute_url()
+                                , 'search_relation'
+                                , make_query(kw)
+                                )
+    else:
+      request.set('catalog_index', my_field.get_value('catalog_index'))
+      if my_field.meta_type == 'MultiRelationStringField':
+        request.set('relation_values', request.get( my_field.id, None))
+      else:
+        request.set('relation_values', [request.get( my_field.id, None)])
+      request.set('default_module', my_field.get_value('default_module'))
+      request.set('portal_type', portal_type[0])
+      return o.Base_viewCreateRelationDialog( REQUEST=request )
+except FormValidationError, validation_errors:
+  # Pack errors into the request
+  field_errors = form.ErrorFields(validation_errors)
+  request.set('field_errors', field_errors)
+  return form(request)
+else:
+  message = 'Relation+Unchanged.'
+
+if redirect_url is None:
+  if not selection_index:
+    redirect_url = '%s/%s?%s' % ( o.absolute_url()
+                              , form_id
+                              , 'portal_status_message=%s' % message
+                              )
+  else:
+    redirect_url = '%s/%s?selection_index=%s&selection_name=%s&%s' % ( o.absolute_url()
+                              , form_id
+                              , selection_index
+                              , selection_name
+                              , 'portal_status_message=%s' % message
+                              )
+
+request[ 'RESPONSE' ].redirect( redirect_url )