Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases.pm	(revision 1294)
@@ -110,4 +110,15 @@
     my $prefix = 'Base(' . $self->type . '/' . $self->label . ')';
     LATMOS::Accounts::Log::la_log($level, "$prefix $msg", @args);
+}
+
+=head2 ReportChange($otype, $name, $ref, $changetype, $message, @args)
+
+Functions to report back
+
+=cut 
+
+sub ReportChange {
+    my ($self, $otype, $name, $ref, $changetype, $message, @args) = @_;
+
 }
 
@@ -437,5 +448,16 @@
     }
     #keys %data or return 0; # TODO: return an error ?
-    $self->create_object($otype, $id, %data);
+    my $obj = $self->create_object($otype, $id, %data) or return;
+    $obj->ReportChange('Create', 'Object created with %s', join(', ', sort keys %cdata));
+
+    foreach my $attrname (keys %data) {
+        my $attribute = $self->attribute($obj->type, $attrname) or next;
+        $obj->ReportChange('Attributes', '%s set to %s', $attrname,
+            (ref $data{$attrname}
+                ? join(', ', @{ $data{$attrname} })
+                : $data{$attrname}) || '(none)') if ($attribute->{notify});
+    }
+
+    $obj
 }
 
@@ -614,5 +636,10 @@
         return;
     };
-    $self->_delete_object($otype, $id);
+    my $ref = $obj->Iid;
+    if (my $res = $self->_delete_object($otype, $id)) {
+        $self->ReportChange($otype, $id, $ref, 'Delete', 'Object deleted');
+        return $res;
+    }
+    return;
 }
 
@@ -650,5 +677,18 @@
     };
 
-    $self->_rename_object($otype, $id, $newid);
+    my $oldref = $obj->Iid;
+
+    if (my $res = $self->_rename_object($otype, $id, $newid)) {
+        my $newobj = $self->get_object($otype, $newid) or do {
+            $self->log(LA_WARN, 'Cannot get object %s/%s: rename failed ?',
+                $otype, $id);
+            return;
+        };
+
+        $self->ReportChange($otype, $id, $oldref, 'Rename', 'Object rename to %s', $newid);
+        $newobj->ReportChange('Rename', 'Object renamed from %s', $id);
+        return $res;
+    }
+    return;
 }
 
Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Objects.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Objects.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Objects.pm	(revision 1294)
@@ -128,4 +128,16 @@
     my ($self) = @_;
     $self->{_id}
+}
+
+
+=head2 Iid
+
+Return internal id if different from Id
+
+=cut
+
+sub Iid {
+    my ($self) = @_;
+    $self->id
 }
 
@@ -368,8 +380,31 @@
             return 0;
         };
-        $res += ($attribute->set($cdata{$cfield}) || 0);
-
-    }
-    $res
+    }
+
+    my %updated = ();
+    foreach my $cfield (keys %cdata) {
+        my $attribute = $self->attribute($cfield) or do {
+            $self->base->log(LA_ERR,
+                "Cannot set unsupported attribute %s to %s (%s)",
+                $cfield, $self->id, $self->type
+            );
+            return;
+        };
+        if ($attribute->set($cdata{$cfield})) {
+            $updated{$cfield} = $attribute->{notify};
+        }
+    }
+    
+    if (keys %updated) {
+        $self->ReportChange('Update', 'Attributes %s where updated', join(', ', sort keys %updated));
+        foreach (sort keys %updated) {
+            $self->ReportChange('Attributes', '%s set to %s', $_, 
+                (ref $cdata{$_}
+                    ? join(', ', @{ $cdata{$_} })
+                    : $cdata{$_}) || '(none)')
+                if ($updated{$_});
+        }
+    }
+    return scalar(keys %updated);
 }
 
@@ -390,5 +425,10 @@
     my ($self, $clear_pass) = @_;
     if ($self->base->check_acl($self, 'userPassword', 'w')) {
-        return $self->_set_password($clear_pass);
+        if ($self->_set_password($clear_pass)) {
+             $self->ReportChange('Password', 'user password has changed');
+             return 1;
+        } else {
+            return;
+        }
     } else {
         $self->base->log(LA_ERROR, "Permission denied for %s to change its password",
@@ -619,4 +659,21 @@
 }
 
+=head2 ReportChange($changetype, $message, @args)
+
+Possible per database way to log changes
+
+=cut
+
+sub ReportChange {
+    my ($self, $changetype, $message, @args) = @_;
+
+    $self->base->ReportChange(
+        $self->type,
+        $self->id,
+        $self->Iid,
+        $changetype, $message, @args
+    )
+}
+
 1;
 
Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql.pm	(revision 1294)
@@ -637,4 +637,22 @@
 }
 
+sub ReportChange {
+    my ($self, $otype, $name, $ref, $changetype, $message, @args) = @_;
+
+    my $sth = $self->db->prepare(q{
+        INSERT into objectslogs (ikey, otype, name, changetype, username, message)
+        VALUES (?,?,?,?,?,?)
+        });
+
+    $sth->execute(
+        $ref,
+        $otype,
+        $name,
+        $changetype,
+        $self->user || '@Console',
+        sprintf($message, @args),
+    );
+}
+
 =head2 getobjectlogs($otype, $name)
 
Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Address.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Address.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Address.pm	(revision 1294)
@@ -143,4 +143,5 @@
     my ($self, %data) = @_;
     my %fdata;
+    my $res = 0;
     foreach my $attr (keys %data) {
         $attr =~ /^site$/ and do {
@@ -161,6 +162,8 @@
     }
     if  (keys %fdata) {
-        $self->SUPER::set_fields(%fdata);
+        $res += $self->SUPER::set_fields(%fdata);
     }
+
+    $res;
 }
 
Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Group.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Group.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Group.pm	(revision 1294)
@@ -36,4 +36,5 @@
             date       => { inline => 1, ro => 1 },
             memberUID  => {
+                notify => 1,
                 hide => 1,
                 reference => 'user',
@@ -48,4 +49,5 @@
             },
             member     => {
+                notify => 1,
                 reference => 'user',
                 multiple => 1, 
@@ -169,5 +171,5 @@
                 next;
             }
-            $self->_set_group_members($data{$attr});
+            $res += $self->_set_group_members($data{$attr});
             next;
         };
@@ -180,9 +182,9 @@
             $res += $self->populate_dyn_group;
         }
-	    if (defined($setres)) { return $res + $setres; }
-	    else { return; } 
-    } else {
-        $res
-    }
+        return unless(defined($setres));
+	    $res += ($setres || 0);
+    }
+    
+    $res
 }
 
Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/User.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/User.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/User.pm	(revision 1294)
@@ -521,27 +521,27 @@
         };
         $attr =~ /^memberOf$/ and do {
-            my %member;
+            my %members;
             my $memberof = $self->get_field('memberOf');
             foreach (ref $memberof
                 ? @{ $memberof }
                 : $memberof || ()) {
-                $member{$_}{c} = 1;
+                $members{$_}{c} = 1;
             }
             foreach (grep { $_ } ref $data{$attr} ? @{ $data{$attr} || []} : $data{$attr}) {
-                $member{$_}{n} = 1;
-            }
-
-            foreach (keys %member) {
-                $member{$_}{c} && $member{$_}{n} and next; # no change !
-                my $group = $self->base->get_object('group', $_) or next;
+                $members{$_}{n} = 1;
+            }
+
+            foreach my $member (keys %members) {
+                $members{$member}{c} && $members{$member}{n} and next; # no change !
+                my $group = $self->base->get_object('group', $member) or do {
+                    la_log(LA_WARN, "Cannot get group %s to set members", $member); 
+                    next;
+                };
                 ($group->_get_c_field('sutype') || '') =~ /^(jobtype|contrattype)$/ and next;
-                if ($member{$_}{n}) {
-                    my $sth = $self->db->prepare_cached(
-                        q{insert into group_attributes_users (value, attr, okey) values (?,?,?)}
-                    );
-                    $sth->execute($self->id, 'memberUID', $group->_get_ikey);
-                    $res++;
-                } elsif ($member{$_}{c}) {
-                    if (($self->get_c_field('department') || '') eq $group->id) {
+                if ($members{$member}{n}) {
+                    my @newmembers = $group->get_attributes('memberUID');
+                    $res += $group->_set_c_fields('memberUID', [ $self->id, @newmembers ]);
+                } elsif ($members{$member}{c}) {
+                    if (($self->_get_c_field('department') || '') eq $group->id) {
                         $self->base->log(LA_WARN,
                             "Don't removing user %s from group %s: is it's department",
@@ -549,9 +549,6 @@
                         next;
                     }
-                    my $sth = $self->db->prepare_cached(
-                        q{delete from group_attributes_users where value = ? and attr = ? and okey = ?}
-                    );
-                    $sth->execute($self->id, 'memberUID', $group->_get_ikey);
-                    $res++;
+                    my @newmembers = grep { $_ ne $self->id } $group->get_attributes('memberUID');
+                    $res += $group->_set_c_fields('memberUID', [ @newmembers ]);
                 } # else {} # can't happend
             }
Index: /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/objects.pm
===================================================================
--- /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/objects.pm	(revision 1293)
+++ /branches/4.0/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/objects.pm	(revision 1294)
@@ -129,4 +129,6 @@
 }
 
+sub Iid { $_[0]->_get_ikey }
+
 sub _get_ikey {
     my ($class, $base, $id) = @_;
@@ -179,15 +181,4 @@
 
     my $obj = $class->new($base, $id);
-    $obj->objectlog('Create', 'Object created');
-    foreach (keys %first) {
-        my $attr = $obj->attribute($_);
-        $obj->objectlog('Attribute', '%s set to %s', $_, (
-                defined($data{$_}) 
-                ? (ref $data{$_}
-                    ? join(', ', @{ $data{$_} })
-                    : $data{$_})
-                : '(none)'))
-            if ($attr->{notify});
-    }
     $obj->set_fields(%second);
 
@@ -200,5 +191,4 @@
     my $obj = $base->get_object($class->type, $id)
         or return;
-    $obj->objectlog('Delete', 'Object deleted');
 
     my $sthd = $base->db->prepare_cached(
@@ -215,10 +205,4 @@
     my ($class, $base, $id, $newid) = @_;
 
-    {
-        my $obj = $base->get_object($class->type, $id)
-            or return;
-        $obj->objectlog('Rename', 'Object rename to %s', $newid);
-    }
-
     my $sthr = $base->db->prepare_cached(
         sprintf(
@@ -238,9 +222,4 @@
     }
 
-    {
-        my $obj = $base->get_object($class->type, $newid)
-            or return;
-        $obj->objectlog('Rename', 'Object renamed from %s', $id);
-    }
     1;
 }
@@ -471,16 +450,4 @@
 
     delete($self->base->{__cache}{"_" . $self->type}{$self->id});
-    $self->objectlog('Update', 'Attributes %s where updated', join(', ', @updated_attributes))
-        if(@updated_attributes);
-    foreach (@updated_attributes) {
-        my $attr = $self->attribute($_);
-        $self->objectlog('Attribute', '%s set to %s', $_, (
-                defined($data{$_}) 
-                ? (ref $data{$_}
-                    ? join(', ', @{ $data{$_} })
-                    : $data{$_})
-                : '(none)'))
-            if ($attr->{notify});
-    }
     scalar(@updated_attributes);
 }
@@ -546,5 +513,5 @@
                 $self->id
             );
-            $self->objectlog('Password', 'user password has changed%s', ($asymencrypted ? ' and stored using internal key' : ''));
+            $self->ReportChange('Password', 'Password stored using internal key');
             return 1;
         }
@@ -749,26 +716,4 @@
 }
 
-=head2 objectlog
-
-=cut
-
-sub objectlog {
-    my ($self, $changetype, $message, @args) = @_;
-
-    my $sth = $self->base->db->prepare(q{
-        INSERT into objectslogs (ikey, otype, name, changetype, username, message)
-        VALUES (?,?,?,?,?,?)
-    });
-
-    $sth->execute(
-        $self->_get_ikey,
-        $self->type,
-        $self->id,
-        $changetype,
-        $self->base->user || '@Console',
-        sprintf($message, @args),
-    );
-}
-
 1;
 
