Index: LATMOS-Accounts-Web/lib/LATMOS/Accounts/Web/Model/AttrForms.pm
===================================================================
--- LATMOS-Accounts-Web/lib/LATMOS/Accounts/Web/Model/AttrForms.pm	(revision 804)
+++ LATMOS-Accounts-Web/lib/LATMOS/Accounts/Web/Model/AttrForms.pm	(revision 861)
@@ -4,4 +4,5 @@
 use warnings;
 use base 'Catalyst::Model';
+use LATMOS::Accounts::Log;
 
 =head1 NAME
@@ -39,4 +40,5 @@
     sutype => [ 'Structure admin.', 'select-N:sutype' ],
     exported => [ 'PropagÃ©', 'label' ],
+    unexported => [ 'CachÃ©' ],
     locked => [ 'VÃ©rouillÃ©', 'checkbox:l' ],
     isMainAddress => [ 'Adresse principale', 'checkbox' ],
@@ -54,4 +56,32 @@
     contratType => [ 'Type de contrat', 'select-N:group/sutype=contrattype' ],
     managerContact => [ 'Contact' ],
+    owner => [ 'PropriÃ©taire' ],
+    description => [ 'Description' ],
+    name => [ 'Nom' ],
+    net => [ "RÃ©seau" ],
+    macaddr => [ "Adresse Ethernet" ],
+    noDynamic => [ "Pas d'adressage dyn." ],
+    cname => [ "Alias (CName)" ],
+    type => [ "Type" ],
+    netExclude => [ "RÃ©seau exclus" ],
+    output => [ "Sortie" ],
+    template => [ "ModÃšle" ],
+    outputD => [ "Sortie" ],
+    templateD => [ "ModÃšle" ],
+    group => [ "Groupe" ],
+    allow_dyn => [ "DHCP dynamique" ],
+    ipCount => [ "Nb d'IP" ],
+    freeIPCount => [ "Nb d'IP libres" ],
+    dnsRevision => [ "RÃ©vision DNS" ],
+    lastUpdate => [ "DerniÃšre mise Ã  jour "],
+    otherName => [ "Autres noms (A)" ],
+    'reverse' => [ "Forcer le reverse Ã " ],
+    dynFrom => [ 'Sans Ip depuis' ],
+    siteNick => [ 'Acronyme' ],
+    serialNumber => [ 'NÂ° de sÃ©rie' ],
+    snNative => [ 'Nom d\'origine' ],
+    givenNameNative => [ 'PrÃ©nom d\'origine' ],
+    wWWHomePage => [ 'Site Web' ],
+    halReference => [ 'RÃ©fÃ©rence HAL' ],
 };
 
@@ -64,5 +94,4 @@
             mail initials nickname
             locked
-            exported
             create
             date
@@ -76,6 +105,6 @@
         ) ],
     },
-    userstatus => {
-        name => 'Status',
+    userstatut => {
+        name => 'Statut',
         attrs => [ qw(
             company
@@ -87,8 +116,18 @@
         ) ],
     },
+    usermy => {
+        name => 'My',
+        attrs => [ qw(
+            snNative
+            givenNameNative
+            wWWHomePage
+            halReference
+        ) ],
+    },
     site => {
         name => 'Site',
         attrs => [ qw(
             description
+            siteNick
             streetAddress
             postOfficeBox
@@ -115,5 +154,5 @@
             site
             co
-            exported
+            unexported
             description
         ) ],
@@ -124,7 +163,48 @@
             gidNumber description
             managedBy
-            sutype exported
+            sutype
             create
             date
+        ) ],
+    },
+    nethost => {
+        name => 'Ordinateur',
+        attrs => [ qw(
+            name
+            description
+            serialNumber
+            owner
+            ip
+            macaddr
+            noDynamic
+            cname
+            otherName
+            reverse
+            create
+            date
+            unexported
+        ) ],
+    },
+    netzone => {
+        name => 'Zone rÃ©seau',
+        attrs => [ qw(
+            name
+            description
+            type
+            net
+            netExclude
+            outputD
+            templateD
+            site
+            allow_dyn
+            dynFrom
+            domain
+            ipCount
+            freeIPCount
+            create
+            date
+            dnsRevision
+            lastUpdate
+            unexported
         ) ],
     },
@@ -179,6 +259,5 @@
     my ($self, $for) = @_;
     grep { $_ }
-    grep { $self->base->check_acl($self->{object} || $self->otype, $_, 'r') }
-    grep { $self->base->get_field_name($self->otype, $_, $for || 'a') }
+    grep { $self->base->attribute($self->otype, $_) }
     @{ $forms->{$self->{form}}->{attrs} };
 }
@@ -196,189 +275,217 @@
     my ($self, $attr) = @_;
     return $self->{c}->req->param($attr) ||
-        ($self->{object} ? $self->{object}->get_c_field($attr) : '')
-}
-
-sub attr_field {
-    my ($self, $attr, $type) = @_;
-    my $modallow = $self->base->check_acl($self->{object}
-        ? ($self->{object}, $attr, 'w')
-        : ($self->otype, '@CREATE', 'w'));
-    $type ||= $attrs->{$attr}[1] || '';
-    if (!($self->base->get_field_name($self->otype, $attr, 'w') && $modallow)) {
-        $type = 'label';
-    }
-    # exception: gidNumber is used also in group, but we don't want
-    # group list here, really the number !
-    $type = $modallow ? 'text-U:6' : 'label' if ($self->{otype} eq 'group' && $attr eq 'gidNumber');
-    $type ||= 'text';
-    
-    my $htmlname = $self->escape(($self->{object} 
+        ($self->{object} ? $self->{object}->get_attributes($attr) : '')
+}
+
+sub attr_field_name {
+    my ($self, $attr) = @_;
+    return ($self->{object}
             ? $self->{object}->id . '_'
             : ''
         ) . $attr
-    );
-    for ($type) {
-        /^textarea$/ and return sprintf(
-            '<textarea id="%s" name="%s" cols="40">%s</textarea>',
-            $self->escape($htmlname),
-            $self->escape($htmlname),
-            $self->escape($self->attr_raw_value($attr) || ''),
-        );
-        /^label$/ and do {
-            my $field = $self->escape(
-                $self->attr_raw_value($attr)
-            );
-            $field =~ s/\n/<br>/g;
-            return $field . sprintf('<input type="hidden" name="%s" value="%s">',
-                $self->escape($htmlname), ($self->attr_raw_value($attr) || ''));
-        };
-        /^date$/ and do {
-            my ($date, $time) = split(/ /, $self->attr_raw_value($attr) || '');
-            if ($date && $date =~ /^(\d+)-(\d+)-(\d+)$/) {
-                $date = "$3/$2/$1";
-            }
-            my $html = "\n" . q{<SCRIPT LANGUAGE="JavaScript" ID="js13">
-            var cal13 = new CalendarPopup();
-            </SCRIPT>} . "\n";
-            $html .= sprintf(
-                '<input type="text" id="%s" name="%s" value="%s" size="12">',
-                $self->escape($htmlname),
-                $self->escape($htmlname),
-                $self->escape($date)
-            );
-            $html .= q{<DIV ID="testdiv1" STYLE="position:absolute;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>};
-            $html .= qq|
-            <A HREF="#"
-                onClick="cal13.select(document.forms[0].$htmlname,'${htmlname}_anc','dd/MM/yyyy');return false;"
-                TITLE="cal13.select(document.forms[0].$htmlname,'${htmlname}_anc','dd/MM/yyyy');return false;"
-                NAME="${htmlname}_anc" ID="${htmlname}_anc">
-                <img src="| . $self->{c}->uri_for(qw(/static icons view-calendar-day.png))
-                . qq{" style="ref"></A>
-                } . "\n";
-            return $html;
-        };
-        /^checkbox(?::(\w+))?$/ and do {
-            my $options = $1 || '';
-            my $text = sprintf('<input type="checkbox" name="%s"%s>',
-                $self->escape($htmlname),
-                $self->attr_raw_value($attr) ? '  checked="yes"' : ''
-            ); 
-            $text .= sprintf('<input type="hidden" name="%s">',
-                $self->escape($htmlname));
-            if ($options =~ /l/) {
-                $text .= $self->attr_raw_value($attr)
-                    ? ' ' . $self->attr_raw_value($attr)
-                    : ''; 
-            }
-            return $text;
-        };
-        /^select(-\w+)?:([^:\/]+)(?:\/([^:]+))?(?::(.*))?/ and do {
-            my $options = $1 || '';
-            my $otype = $2;
-            my $filter = $3;
-            my $keyfield = $4;
-            my $observe_keyfield = $keyfield || 'displayName';
-            my $select = sprintf('<select id="%s" name="%s">',
-                $self->escape($htmlname),
-                $self->escape($htmlname)) . "\n";
-            $select .= '<option value="">--</option>' . "\n" if ($options =~ /N/);
-            my $value = $self->attr_raw_value($attr) || '';
-            my $initial_observed = '';
-            foreach my $id (sort $filter
-                ? $self->base->search_objects($otype, $filter)
-                : $self->base->list_objects($otype)) {
-                my $val = $id;
-                if ($keyfield) {
-                    my $obj = $self->base->get_object($otype, $id) or next;
-                    $val = $obj->get_c_field($keyfield);
-                }
-                $select .= sprintf(
-                    '    <option value="%s"%s>%s</option>',
-                    $self->escape($val || ''),
-                    $value eq $val ? ' selected="selected"' : '',
-                    $self->escape($id || ''),
+}
+
+sub attr_field {
+    my ($self, $attr, $type) = @_;
+
+    my $attribute = ($self->{object}
+        ? $self->{object}->attribute($attr)
+        : $self->base->attribute($self->otype, $attr)) or return;
+
+    my $htmlname = $self->escape($self->attr_field_name($attr));
+
+    my @html_fields;
+    foreach my $attr_raw_value (
+        $attribute->{multiple}
+            ? ((grep { $_ } $self->attr_raw_value($attr)),
+                $attribute->readonly
+                    ? ()
+                    : ('')
+            )
+            : ($self->attr_raw_value($attr))) {
+
+        my $html_id = $htmlname .
+            (scalar(@html_fields) ? scalar(@html_fields) : '');
+
+        my $html_field = '';
+        for ($attribute->form_type) {
+            /^textarea$/i and do {
+                $html_field = sprintf(
+                    '<textarea id="%s" name="%s" cols="40">%s</textarea>',
+                    $self->escape($html_id),
+                    $self->escape($htmlname),
+                    $self->escape($attr_raw_value || ''),
                 );
-                $select .= "\n";
-                if($value eq $val) {
-                    if (my $obj = $self->base->get_object($otype, $id)) {
-                        $initial_observed = $obj->get_c_field($observe_keyfield)
-                        || '';
-                    }
-                }
-            }
-            $select .= "</select>\n";
-            $select .= $self->{c}->prototype->observe_field( $htmlname, {
-                update => "${htmlname}_span",
-                url => $self->{c}->uri_for('/ajax', 'rawattr', $otype),
-                frequency => 1,
-                with   => "'attr=" . $observe_keyfield .
-                "&id='+element.options[element.selectedIndex].text",
-            }) .
-            qq|<span id="${htmlname}_span">$initial_observed</span>|;
-            return $select;
-        };
-        /^text(-\w+)?(?::(\d+))?/ and do {
-            my $flag = $1 || '';
-            if (my @allowed = $self->base->obj_attr_allowed_values(
-                    $self->{otype}, $attr)) {
-                my $cvalue = $self->attr_raw_value($attr);
-                my $textf = sprintf('<select  id="%s" name="%s">',
+                last;
+            };
+            /^label$/i and do {
+                $attr_raw_value or last;
+                $html_field = $self->escape($attr_raw_value);
+                $html_field =~ s/\n/<br>/g;
+                $html_field .= sprintf('<input type="hidden" name="%s" value="%s">',
+                    $self->escape($htmlname), ($attr_raw_value || ''));
+                last;
+            };
+            /^date$/i and do {
+                my ($date, $time) = split(/ /, $self->attr_raw_value($attr) || '');
+                if ($date && $date =~ /^(\d+)-(\d+)-(\d+)$/) {
+                    $date = "$3/$2/$1";
+                }
+                my $html = "\n" . q{<SCRIPT LANGUAGE="JavaScript" ID="js13">
+                var cal13 = new CalendarPopup();
+                </SCRIPT>} . "\n";
+                $html .= sprintf(
+                    '<input type="text" id="%s" name="%s" value="%s" size="12">',
+                    $self->escape($html_id),
                     $self->escape($htmlname),
+                    $self->escape($date)
+                );
+                $html .= q{<DIV ID="testdiv1" STYLE="position:absolute;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>};
+                $html .= qq|
+                <A HREF="#"
+                    onClick="cal13.select(document.getElementById('$html_id'),'${html_id}_anc','dd/MM/yyyy');return false;"
+                    TITLE="Date"
+                    NAME="${html_id}_anc" ID="${html_id}_anc">
+                    <img class="attr" src="| . $self->{c}->uri_for(qw(/static icons view-calendar-day.png))
+                    . qq{" style="ref"></A>
+                    } . "\n";
+                $html_field = $html;
+                last;
+            };
+            /^checkbox(?::(\w+))?$/i and do {
+                my $options = $1 || '';
+                $html_field = sprintf('<input type="checkbox" name="%s"%s>',
+                    $self->escape($htmlname),
+                    $attr_raw_value ? '  checked="yes"' : ''
+                ); 
+                $html_field .= sprintf('<input type="hidden" name="%s">',
+                    $self->escape($htmlname));
+                if ($attribute->form_option('rawvalue')) {
+                    $html_field .= $attr_raw_value
+                        ? ' ' . $attr_raw_value
+                        : ''; 
+                }
+                last;
+            };
+            /^LIST/ and do {
+                my $options = $1 || '';
+                my $select = sprintf('<select id="%s" name="%s">',
+                    $self->escape($html_id),
                     $self->escape($htmlname)) . "\n";
-                $textf .= '<option value="">--</option>' . "\n";
-                foreach (sort @allowed) {
-                    $textf .= sprintf('<option value="%s"%s>%s</option>' . "\n",
-                        $self->escape($_),
-                        (($cvalue || '') eq $_ ? ' selected="selected"' : ''),
-                        $self->escape($_),
+                $select .= '<option value="">--</option>' . "\n"
+                    unless($attribute->mandatory);
+                my $value = $attr_raw_value || '';
+                my $initial_observed = '';
+                my @valslist;
+                foreach my $val (sort $attribute->can_values) {
+                    push(@valslist, {
+                        val => $val,
+                        disp => $attribute->display($val || ''),
+                    });
+                }
+                foreach (sort { $a->{disp} cmp $b->{disp} } @valslist) {
+                    $select .= sprintf(
+                        '    <option value="%s"%s>%s</option>',
+                        $self->escape($_->{val} || ''),
+                        $value eq $_->{val} ? ' selected="selected"' : '',
+                        $self->escape($_->{disp} || ''),
                     );
-                }
-                $textf .= "</select>\n";
-                return $textf;
-            } else {
-                my $textf = sprintf(
+                    $select .= "\n";
+                }
+                $select .= "</select>\n";
+
+                $html_field = $select;
+                last;
+            };
+            /^text(-\w+)?(?::(\d+))?/i and do {
+                my $flag = $1 || '';
+                $html_field = sprintf(
                     '<input type="text" id="%s" name="%s" value="%s" size="%d">',
+                    $self->escape($html_id),
                     $self->escape($htmlname),
-                    $self->escape($htmlname),
-                    $self->escape($self->attr_raw_value($attr)),
-                    $2 || 30,
+                    $self->escape($attr_raw_value),
+                    $attribute->form_option('length') || 30,
                 );
                 if ($flag =~ /A/) {
-                $textf .= qq|<span id="${htmlname}_auto_complete"></span>|;
-                $textf .= "\n";
-                $textf .= $self->{c}->prototype->auto_complete_field(
-                    $htmlname,
-                    {
-                    update => "${htmlname}_auto_complete",
-                    url => $self->{c}->uri_for('/ajax', 'attrvalues', $self->otype, $attr),
-                    indicator => "${htmlname}_stat", min_chars => 1,
-                    with => "'val='+document.getElementById('$htmlname').value",
-                    frequency => 2,
-                    }
-                );
-                }
-                if ($flag =~ /U/) {
-                $textf .= qq|<span id="${htmlname}_observer_uniq"></span>|;
-                $textf .= "\n";
-                $textf .= $self->{c}->prototype->observe_field(
-                    $htmlname,
-                    {
-                    update => "${htmlname}_observer_uniq",
-                    url => $self->{c}->uri_for('/ajax', 'objattrexist',
-                        $self->otype, $attr),
-                    frequency => 2,
-                    indicator => "${htmlname}_stat", min_chars => 1,
-                    with => "'val='+document.getElementById('$htmlname').value" .
-                        ($self->{object} ? "+'&exclude=" . $self->{object}->id . "'" :
-                            ''),
-                    }
-                );
-                }
-                $textf .= qq|<span style="display:none" id="${htmlname}_stat">Searching...</span>|;
-
-                return $textf;
+                    $html_field .= qq|<span id="${html_id}_auto_complete"></span>|;
+                    $html_field .= "\n";
+                    $html_field .= $self->{c}->prototype->auto_complete_field(
+                        $html_id,
+                        {
+                            update => "${html_id}_auto_complete",
+                            url => $self->{c}->uri_for('/ajax', 'attrvalues', $self->otype, $attr),
+                            indicator => "${html_id}_stat", min_chars => 1,
+                            with => "'val='+document.getElementById('$html_id').value",
+                            frequency => 2,
+                        }
+                    );
+                }
+                if ($attribute->uniq) {
+                    $html_field .= qq|<span class="inputvalidate" id="${html_id}_observer_uniq"></span>|;
+                    $html_field .= "\n";
+                    $html_field .= $self->{c}->prototype->observe_field(
+                        $html_id,
+                        {
+                            update => "${html_id}_observer_uniq",
+                            url => $self->{c}->uri_for('/ajax', 'objattrexist',
+                                $self->otype, $attr),
+                            frequency => 2,
+                            indicator => "${html_id}_stat", min_chars => 1,
+                            with => "'val='+document.getElementById('$html_id').value" .
+                            ($self->{object} ? "+'&exclude=" . $self->{object}->id . "'" :
+                                ''),
+                        }
+                    );
+                    $html_field .= qq|<span style="display:none" id="${html_id}_stat">Searching...</span>|;
+                }
+                last;
+            };
+        }
+        if (my $ref = $attribute->reference) {
+            my $uri_part= {
+                user => 'users',
+                group => 'groups',
+                nethost => 'nethosts',
+                netzone => 'netzones',
+                site => 'sites'
+            }->{$ref};
+            my $text;
+            if ($self->base->attribute($ref, 'displayName')) {
+                if ($attr_raw_value &&
+                    (my $obj = $self->base->get_object($ref, $attr_raw_value)))
+                {
+                    $text = $obj->get_attributes('displayName');
+                }
+                
+                $html_field .= $self->{c}->prototype->observe_field( $html_id, {
+                        update => "${html_id}_span",
+                        url => $self->{c}->uri_for('/ajax', 'rawattr', $ref),
+                        frequency => 1,
+                        with   => "'attr=displayName" .
+                        "&id=' + element.options[element.selectedIndex].text",
+                    }) . "\n" if ($attribute->form_type =~ /list/i);
+            } elsif($attr_raw_value && $uri_part) {
+                $text = sprintf(
+                    '<img class="attr" src="%s" title="%s">',
+                    $self->{c}->uri_for('/static', 'icons', 'arrow-right.png'),
+                    $attr_raw_value,
+                )
             }
-        };
+            $html_field .= sprintf(qq{<span id="%s" style="margin-left: 1em">},
+                "${html_id}_span");
+
+            if (defined($text)) {
+                $html_field .= $uri_part
+                    ? sprintf('<a href="%s">%s</a>',
+                        $self->{c}->uri_for("/$uri_part", $attribute->display($attr_raw_value)),
+                        $text,)
+                    : $text;
+            }
+
+            $html_field .= "</span>\n";
+        }
+        push(@html_fields, $html_field);
     }
+    return join("<br>\n", @html_fields);
 }
 
@@ -391,4 +498,17 @@
 }
 
+sub write_attributes {
+    my ($self) = @_;
+    my @attrs;
+    foreach ($self->attributes) {
+        my $attr = ($self->{object}
+            ? $self->{object}->attribute($_)
+            : $self->base->attribute($self->otype, $_)) or next;
+        $attr->readonly and next;
+        push(@attrs, $_);
+    }
+    @attrs;
+}
+
 sub set_attrs {
     my ($self) = @_;
@@ -396,14 +516,22 @@
     my $prefix = $self->{object}->id . '_';
     my %fields;
-    foreach (
-        grep { $self->base->get_field_name($self->otype, $_, 'w') }
-        $self->attributes) {
+    foreach ($self->write_attributes) {
+        my $attr = ($self->{object}
+            ? $self->{object}->attribute($_)
+            : $self->base->attribute($self->otype, $_)) or next;
         if (($attrs->{$_}[1] || '') eq 'checkbox') {
             $fields{$_} = $self->{c}->req->param("$prefix$_") ? 1 : 0;
+        } elsif ($attr->{multiple}) {
+            $fields{$_} = [ grep { $_ } $self->{c}->req->param("$prefix$_") ];
         } else {
             $fields{$_} = $self->{c}->req->param("$prefix$_");
         }
     }
-    $self->{object}->set_c_fields(%fields) or return;
+    $self->{object}->set_c_fields(%fields) or do {
+        $self->{c}->stash->{page}{error} =
+            LATMOS::Accounts::Log::lastmessage(LA_ERR);
+        $self->{object}->base->rollback;
+        return;
+    };
     $self->{object}->base->commit;
 }
