View | Details | Raw Unified | Return to bug 39453
Collapse All | Expand All

(-)a/Koha/Exceptions/Patron/Attribute.pm (+10 lines)
Lines 28-33 use Exception::Class ( Link Here
28
        isa         => 'Koha::Exceptions::Patron::Attribute',
28
        isa         => 'Koha::Exceptions::Patron::Attribute',
29
        description => "the passed value is invalid for attribute type",
29
        description => "the passed value is invalid for attribute type",
30
        fields      => ["attribute"]
30
        fields      => ["attribute"]
31
    },
32
    'Koha::Exceptions::Patron::Attribute::NonEditable' => {
33
        isa         => 'Koha::Exceptions::Patron::Attribute',
34
        description => "Cannot to modify value of non editable attribute type",
35
        fields      => ["type"]
31
    }
36
    }
32
);
37
);
33
38
Lines 60-65 sub full_message { Link Here
60
                $self->attribute->code,
65
                $self->attribute->code,
61
                $self->attribute->attribute
66
                $self->attribute->attribute
62
            );
67
            );
68
        } elsif ( $self->isa('Koha::Exceptions::Patron::Attribute::NonEditable') ) {
69
            $msg = sprintf(
70
                "Cannot change value pf non editable attribute type. type=%s",
71
                $self->type
72
            );
63
        }
73
        }
64
    }
74
    }
65
75
(-)a/Koha/Exceptions/Patron/Attribute/Type.pm (+10 lines)
Lines 14-19 use Exception::Class ( Link Here
14
        description => "Cannot change property",
14
        description => "Cannot change property",
15
        fields      => ['property'],
15
        fields      => ['property'],
16
    },
16
    },
17
    'Koha::Exceptions::Patron::Attribute::Type::InvalidPropertyCombination' => {
18
        isa         => 'Koha::Exceptions::Patron::Attribute::Type',
19
        description => "An invalid property combination has been set",
20
        fields      => ['property'],
21
    },
17
);
22
);
18
23
19
sub full_message {
24
sub full_message {
Lines 27-32 sub full_message { Link Here
27
                "The property '%s' cannot be changed, some patron attributes are using it that way.",
32
                "The property '%s' cannot be changed, some patron attributes are using it that way.",
28
                $self->property
33
                $self->property
29
            );
34
            );
35
        } elsif ( $self->isa('Koha::Exceptions::Patron::Attribute::Type::InvalidPropertyCombination') ) {
36
            $msg = sprintf(
37
                "The property '%s' is incompatible with the current combination of properties",
38
                $self->property
39
            );
30
        }
40
        }
31
    }
41
    }
32
42
(-)a/Koha/Patron.pm (-2 / +25 lines)
Lines 2576-2589 sub add_extended_attribute { Link Here
2576
2576
2577
=head3 extended_attributes
2577
=head3 extended_attributes
2578
2578
2579
Return object of Koha::Patron::Attributes type with all attributes set for this patron
2579
Getter/setter for Koha::Patron::Attributes. Always return the extended attributes of the patron.
2580
2580
2581
Or setter FIXME
2581
Or setter FIXME
2582
2582
2583
=over 4
2584
2585
=item C<$extended_attributes>
2586
2587
The extended attributes to set on the format [{ code => $code, attribute => $value }, ...].
2588
All extended attributes of the patron must be provided.
2589
2590
=item C<$params>
2591
2592
A hashfre for Optional parameters.
2593
2594
if called from within the staff interface C<check_editable> must be set so that
2595
attribute type settings making the attribute non editable are enforced.
2596
2597
=back
2598
2583
=cut
2599
=cut
2584
2600
2585
sub extended_attributes {
2601
sub extended_attributes {
2586
    my ( $self, $attributes ) = @_;
2602
    my ( $self, $attributes, $params ) = @_;
2603
    $params //= {};
2587
2604
2588
    if ($attributes) {    # setter
2605
    if ($attributes) {    # setter
2589
        my %attribute_changes;
2606
        my %attribute_changes;
Lines 2638-2643 sub extended_attributes { Link Here
2638
                        $change->{after}  //= [];
2655
                        $change->{after}  //= [];
2639
2656
2640
                        if ( $is_different->( $change->{before}, $change->{after} ) ) {
2657
                        if ( $is_different->( $change->{before}, $change->{after} ) ) {
2658
                            if ( $params->{check_editable} ) {
2659
                                my $type = Koha::Patron::Attribute::Types->find($code);
2660
                                unless ( $type->is_editable ) {
2661
                                    Koha::Exceptions::Patron::Attribute::NonEditable->throw( type => $code );
2662
                                }
2663
                            }
2641
                            $changed_attributes_codes{$code} = 1;
2664
                            $changed_attributes_codes{$code} = 1;
2642
2665
2643
                            unless ($repeatable) {
2666
                            unless ($repeatable) {
(-)a/Koha/Patron/Attribute.pm (+2 lines)
Lines 20-27 use Modern::Perl; Link Here
20
use Koha::Database;
20
use Koha::Database;
21
use Koha::Exceptions::Patron::Attribute;
21
use Koha::Exceptions::Patron::Attribute;
22
use Koha::Patron::Attribute::Types;
22
use Koha::Patron::Attribute::Types;
23
use Koha::Patron::Attributes;
23
use Koha::AuthorisedValues;
24
use Koha::AuthorisedValues;
24
use Koha::DateUtils qw( dt_from_string );
25
use Koha::DateUtils qw( dt_from_string );
26
use C4::Context;
25
27
26
use base qw(Koha::Object);
28
use base qw(Koha::Object);
27
29
(-)a/Koha/Patron/Attribute/Type.pm (+71 lines)
Lines 46-51 sub store { Link Here
46
46
47
    $self->check_repeatables;
47
    $self->check_repeatables;
48
    $self->check_unique_ids;
48
    $self->check_unique_ids;
49
    $self->check_hidden;
50
    $self->check_readonly;
51
    $self->check_secret;
49
52
50
    return $self->SUPER::store();
53
    return $self->SUPER::store();
51
}
54
}
Lines 112-117 sub check_unique_ids { Link Here
112
    return $self;
115
    return $self;
113
}
116
}
114
117
118
=head3 check_hidden
119
120
=cut
121
122
sub check_hidden {
123
    my ($self) = @_;
124
    if (
125
        $self->hidden
126
        && (   $self->readonly
127
            || $self->secret
128
            || $self->opac_display
129
            || $self->opac_editable
130
            || $self->display_checkout )
131
        )
132
    {
133
        Koha::Exceptions::Patron::Attribute::Type::InvalidPropertyCombination->throw( property => 'hidden' );
134
    }
135
}
136
137
=head3 check_readonly
138
139
=cut
140
141
sub check_readonly {
142
    my ($self) = @_;
143
    if (
144
        $self->readonly
145
        && (   $self->hidden
146
            || $self->secret
147
            || $self->opac_editable )
148
        )
149
    {
150
        Koha::Exceptions::Patron::Attribute::Type::InvalidPropertyCombination->throw( property => 'readonly' );
151
    }
152
}
153
154
=head3 check_secret
155
156
=cut
157
158
sub check_secret {
159
    my ($self) = @_;
160
    if (
161
        $self->secret
162
        && (   $self->readonly
163
            || $self->hidden
164
            || $self->opac_display
165
            || $self->opac_editable
166
            || $self->display_checkout )
167
        )
168
    {
169
        Koha::Exceptions::Patron::Attribute::Type::InvalidPropertyCombination->throw( property => 'hidden' );
170
    }
171
}
172
173
=head3 is_editable
174
175
=cut
176
177
sub is_editable {
178
    my ($self) = @_;
179
    my $logged_in_borrowernumber = C4::Context->userenv->{'number'};
180
    if ($logged_in_borrowernumber) {
181
        my $patron = Koha::Patrons->find($logged_in_borrowernumber);
182
        return $patron->_is_superlibrarian && !( $self->hidden || $self->readonly || $self->secret ) if $patron;
183
    }
184
}
185
115
=head3 _type
186
=head3 _type
116
187
117
=cut
188
=cut
(-)a/Koha/Patron/Attribute/Types.pm (-16 / +30 lines)
Lines 19-24 use Modern::Perl; Link Here
19
19
20
use Koha::Patron::Attribute::Type;
20
use Koha::Patron::Attribute::Type;
21
use C4::Koha qw( GetAuthorisedValues );
21
use C4::Koha qw( GetAuthorisedValues );
22
use List::Util qw ( all );
22
23
23
use base qw(Koha::Objects Koha::Objects::Limit::Library);
24
use base qw(Koha::Objects Koha::Objects::Limit::Library);
24
25
Lines 47-60 Params: Link Here
47
=cut
48
=cut
48
49
49
sub patron_attributes_form {
50
sub patron_attributes_form {
50
    my $template   = shift;
51
    my $template       = shift;
51
    my $attributes = shift;
52
    my $logged_in_user = shift;
52
    my $op         = shift;
53
    my $attributes     = shift;
53
    my $query      = shift // {};
54
    my $op             = shift;
55
    my $query          = shift // {};
54
56
55
    my $library_id      = C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
57
    my $library_id      = C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
56
    my $attribute_types = Koha::Patron::Attribute::Types->search_with_library_limits( $query, {}, $library_id );
58
    my $attribute_types = Koha::Patron::Attribute::Types->search_with_library_limits( $query, {}, $library_id );
57
    if ( $attribute_types->count == 0 ) {
59
    if ( $attribute_types->count == 0
60
        || ( !$logged_in_user->is_superlibrarian && all { $_->hidden } $attribute_types->as_list ) )
61
    {
58
        $template->param( no_patron_attribute_types => 1 );
62
        $template->param( no_patron_attribute_types => 1 );
59
        return;
63
        return;
60
    }
64
    }
Lines 68-79 sub patron_attributes_form { Link Here
68
    my @attribute_loop = ();
72
    my @attribute_loop = ();
69
    my $i              = 0;
73
    my $i              = 0;
70
    my %items_by_class;
74
    my %items_by_class;
75
    my @hidden_attributes;
76
    my $is_superlibrarian = $logged_in_user->is_superlibrarian;
77
71
    while ( my ($attr_type) = $attribute_types->next ) {
78
    while ( my ($attr_type) = $attribute_types->next ) {
72
        my $entry = {
79
        my $entry = {
73
            class         => $attr_type->class(),
80
            class         => $attr_type->class(),
74
            code          => $attr_type->code(),
81
            code          => $attr_type->code(),
75
            description   => $attr_type->description(),
82
            description   => $attr_type->description(),
76
            repeatable    => $attr_type->repeatable(),
83
            repeatable    => $attr_type->repeatable(),
84
            hidden        => !$is_superlibrarian && $attr_type->hidden(),
85
            readonly      => !$is_superlibrarian && $attr_type->readonly(),
86
            secret        => !$is_superlibrarian && $attr_type->secret(),
77
            category      => $attr_type->authorised_value_category(),
87
            category      => $attr_type->authorised_value_category(),
78
            category_code => $attr_type->category_code(),
88
            category_code => $attr_type->category_code(),
79
            mandatory     => $attr_type->mandatory(),
89
            mandatory     => $attr_type->mandatory(),
Lines 84-106 sub patron_attributes_form { Link Here
84
                my $newentry = {%$entry};
94
                my $newentry = {%$entry};
85
                $newentry->{value}        = $attr->{attribute};
95
                $newentry->{value}        = $attr->{attribute};
86
                $newentry->{use_dropdown} = 0;
96
                $newentry->{use_dropdown} = 0;
87
                if ( $attr_type->authorised_value_category() ) {
97
88
                    $newentry->{use_dropdown} = 1;
98
                if ( !$is_superlibrarian && ( $attr_type->hidden() || $attr_type->secret() ) ) {
89
                    $newentry->{auth_val_loop} =
99
                    push @hidden_attributes, $newentry;
90
                        C4::Koha::GetAuthorisedValues( $attr_type->authorised_value_category(), $attr->{attribute} );
100
                } else {
101
                    if ( $attr_type->authorised_value_category() ) {
102
                        $newentry->{use_dropdown} = 1;
103
                        $newentry->{auth_val_loop} =
104
                            GetAuthorisedValues( $attr_type->authorised_value_category(), $attr->{attribute} );
105
                    }
106
                    undef $newentry->{value} if ( $attr_type->unique_id() && $op eq 'duplicate' );
107
                    $i++;
108
                    $newentry->{form_id} = "patron_attr_$i";
109
                    push @{ $items_by_class{ $attr_type->class() } }, $newentry;
91
                }
110
                }
92
                $i++;
93
                undef $newentry->{value} if ( $attr_type->unique_id() && $op eq 'duplicate' );
94
                $newentry->{form_id} = "patron_attr_$i";
95
                push @{ $items_by_class{ $attr_type->class() } }, $newentry;
96
            }
111
            }
97
        } else {
112
        } else {
98
            $i++;
99
            my $newentry = {%$entry};
113
            my $newentry = {%$entry};
100
            if ( $attr_type->authorised_value_category() ) {
114
            if ( $attr_type->authorised_value_category() ) {
101
                $newentry->{use_dropdown}  = 1;
115
                $newentry->{use_dropdown}  = 1;
102
                $newentry->{auth_val_loop} = C4::Koha::GetAuthorisedValues( $attr_type->authorised_value_category() );
116
                $newentry->{auth_val_loop} = C4::Koha::GetAuthorisedValues( $attr_type->authorised_value_category() );
103
            }
117
            }
118
            $i++;
104
            $newentry->{form_id} = "patron_attr_$i";
119
            $newentry->{form_id} = "patron_attr_$i";
105
            push @{ $items_by_class{ $attr_type->class() } }, $newentry;
120
            push @{ $items_by_class{ $attr_type->class() } }, $newentry;
106
        }
121
        }
Lines 115-122 sub patron_attributes_form { Link Here
115
        };
130
        };
116
    }
131
    }
117
132
118
    $template->param( patron_attributes => \@attribute_loop );
133
    $template->param( patron_attributes => \@attribute_loop, hidden_patron_attributes => \@hidden_attributes );
119
120
}
134
}
121
135
122
=head2 Internal methods
136
=head2 Internal methods
(-)a/admin/patron-attr-types.pl (+6 lines)
Lines 109-114 sub add_update_attribute_type { Link Here
109
    my $description               = $input->param('description');
109
    my $description               = $input->param('description');
110
    my $repeatable                = $input->param('repeatable')                ? 1 : 0;
110
    my $repeatable                = $input->param('repeatable')                ? 1 : 0;
111
    my $unique_id                 = $input->param('unique_id')                 ? 1 : 0;
111
    my $unique_id                 = $input->param('unique_id')                 ? 1 : 0;
112
    my $hidden                    = $input->param('hidden')                    ? 1 : 0;
113
    my $readonly                  = $input->param('readonly')                  ? 1 : 0;
114
    my $secret                    = $input->param('secret')                    ? 1 : 0;
112
    my $is_date                   = $input->param('is_date')                   ? 1 : 0;
115
    my $is_date                   = $input->param('is_date')                   ? 1 : 0;
113
    my $opac_display              = $input->param('opac_display')              ? 1 : 0;
116
    my $opac_display              = $input->param('opac_display')              ? 1 : 0;
114
    my $opac_editable             = $input->param('opac_editable')             ? 1 : 0;
117
    my $opac_editable             = $input->param('opac_editable')             ? 1 : 0;
Lines 146-151 sub add_update_attribute_type { Link Here
146
        {
149
        {
147
            repeatable                => $repeatable,
150
            repeatable                => $repeatable,
148
            unique_id                 => $unique_id,
151
            unique_id                 => $unique_id,
152
            hidden                    => $hidden,
153
            readonly                  => $readonly,
154
            secret                    => $secret,
149
            is_date                   => $is_date,
155
            is_date                   => $is_date,
150
            opac_display              => $opac_display,
156
            opac_display              => $opac_display,
151
            opac_editable             => $opac_editable,
157
            opac_editable             => $opac_editable,
(-)a/installer/data/mysql/atomicupdate/bug_39453-add-new-columns-to-borrower-attribute-types.pl (+19 lines)
Line 0 Link Here
1
use Modern::Perl;
2
use Koha::Installer::Output qw(say_warning say_success say_info);
3
4
return {
5
    bug_number  => "39453",
6
    description => "Add attribute type settings for restricting access to extended attributes",
7
    up          => sub {
8
        my ($args) = @_;
9
        my ( $dbh, $out ) = @$args{qw(dbh out)};
10
11
        $dbh->do(
12
            q{ALTER TABLE `borrower_attribute_types` ADD COLUMN `hidden` tinyint(1) NOT NULL DEFAULT 0, ADD COLUMN `readonly` tinyint(1) NOT NULL DEFAULT 0, ADD COLUMN `secret` tinyint(1) NOT NULL DEFAULT 0}
13
        );
14
15
        say $out
16
            "Added columns 'borrower_attribute_types.hidden', 'borrower_attribute_types.readonly' and 'borrower_attribute_types.secret'";
17
18
    },
19
};
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/member-attribute-types.inc (-32 / +40 lines)
Lines 7-12 Link Here
7
            </legend>
7
            </legend>
8
            <div class="attributes_tables">
8
            <div class="attributes_tables">
9
                <input type="hidden" name="setting_extended_patron_attributes" value="1" />
9
                <input type="hidden" name="setting_extended_patron_attributes" value="1" />
10
                [% FOREACH patron_attribute IN hidden_patron_attributes %]
11
                    <input type="hidden" id="[% patron_attribute.form_id | html %]" name="[% patron_attribute.form_id | html %]" value="[% patron_attribute.value | html %]" />
12
                    <input type="hidden" id="[% patron_attribute.form_id | html %]_code" name="[% patron_attribute.form_id | html %]_code" value="[% patron_attribute.code | html %]" />
13
                [% END %]
10
                [% FOREACH pa_loo IN patron_attributes %]
14
                [% FOREACH pa_loo IN patron_attributes %]
11
                    <ol class="attributes_table">
15
                    <ol class="attributes_table">
12
                        <div id="aai_[% pa_loo.class | html %]">
16
                        <div id="aai_[% pa_loo.class | html %]">
Lines 14-27 Link Here
14
                                <h3 id="[% pa_loo.class | html %]_lgd">[% pa_loo.lib | html %]</h3>
18
                                <h3 id="[% pa_loo.class | html %]_lgd">[% pa_loo.lib | html %]</h3>
15
                            [% END %]
19
                            [% END %]
16
                            [% FOREACH patron_attribute IN pa_loo.items %]
20
                            [% FOREACH patron_attribute IN pa_loo.items %]
17
                                <li data-category_code="[% patron_attribute.category_code | html %]" data-pa_code="[% patron_attribute.code | replace('[^a-zA-Z0-9_-]', '') %]">
21
                                <li
22
                                    data-category_code="[% patron_attribute.category_code | html %]"
23
                                    data-pa_code="[% patron_attribute.code | replace('[^a-zA-Z0-9_-]', '') %]"
24
                                    [% IF patron_attribute.readonly %]aria-readonly="true"[% END %]
25
                                >
18
                                    [% IF patron_attribute.mandatory %]
26
                                    [% IF patron_attribute.mandatory %]
19
                                        <label for="[% patron_attribute.form_id | html %]" class="required" required="required">[% patron_attribute.description | html %]: </label>
27
                                        <label for="[% patron_attribute.form_id | html %]" class="required" required="required">[% patron_attribute.description | html %]: </label>
20
                                    [% ELSE %]
28
                                    [% ELSE %]
21
                                        <label for="[% patron_attribute.form_id | html %]">[% patron_attribute.description | html %]: </label>
29
                                        <label for="[% patron_attribute.form_id | html %]">[% patron_attribute.description | html %]: </label>
22
                                    [% END %]
30
                                    [% END %]
23
                                    [% IF ( patron_attribute.use_dropdown ) %]
31
                                    [% IF ( patron_attribute.use_dropdown ) %]
24
                                        <select id="[% patron_attribute.form_id | html %]" name="[% patron_attribute.form_id | html %]" [% IF patron_attribute.mandatory %]required="required"[% END %]>
32
                                        <select
33
                                            id="[% patron_attribute.form_id | html %]"
34
                                            name="[% patron_attribute.form_id | html %]"
35
                                            [% IF patron_attribute.mandatory %]required="required"[% END %][% IF patron_attribute.readonly %]disabled[% END %]
36
                                        >
25
                                            <option value=""></option>
37
                                            <option value=""></option>
26
                                            [% FOREACH auth_val_loo IN patron_attribute.auth_val_loop %]
38
                                            [% FOREACH auth_val_loo IN patron_attribute.auth_val_loop %]
27
                                                [% IF auth_val_loo.authorised_value == patron_attribute.value %]
39
                                                [% IF auth_val_loo.authorised_value == patron_attribute.value %]
Lines 31-73 Link Here
31
                                                [% END %]
43
                                                [% END %]
32
                                            [% END %]
44
                                            [% END %]
33
                                        </select>
45
                                        </select>
46
                                        [% IF ( patron_attribute.readonly ) %]
47
                                            <input type="hidden" id="[% patron_attribute.form_id | html %]" name="[% patron_attribute.form_id | html %]" value="[% patron_attribute.value | html %]" />
48
                                        [% END %]
34
                                    [% ELSE %]
49
                                    [% ELSE %]
35
                                        [% IF patron_attribute.mandatory %]
50
                                        [% IF patron_attribute.is_date %]
36
                                            [% IF patron_attribute.is_date %]
51
                                            <input
37
                                                <input
52
                                                type="text"
38
                                                    type="text"
53
                                                id="[% patron_attribute.form_id | html %]"
39
                                                    id="[% patron_attribute.form_id | html %]"
54
                                                name="[% patron_attribute.form_id | html %]"
40
                                                    name="[% patron_attribute.form_id | html %]"
55
                                                maxlength="10"
41
                                                    maxlength="10"
56
                                                size="10"
42
                                                    size="10"
57
                                                value="[% patron_attribute.value | html %]"
43
                                                    value="[% patron_attribute.value | html %]"
58
                                                class="flatpickr"
44
                                                    required="required"
59
                                                [% IF patron_attribute.mandatory %]required="required"[% END %]
45
                                                    class="flatpickr"
60
                                                [% IF ( patron_attribute.readonly ) %]readonly[% ELSE %]class="flatpickr"[% END %]
46
                                                />
61
                                            />
47
                                            [% ELSE %]
48
                                                <textarea rows="2" cols="30" id="[% patron_attribute.form_id | html %]" name="[% patron_attribute.form_id | html %]" required="required">[% patron_attribute.value | html %]</textarea>
49
                                            [% END %]
50
                                        [% ELSE %]
62
                                        [% ELSE %]
51
                                            [% IF patron_attribute.is_date %]
63
                                            <textarea
52
                                                <input
64
                                                rows="2"
53
                                                    type="text"
65
                                                cols="30"
54
                                                    id="[% patron_attribute.form_id | html %]"
66
                                                id="[% patron_attribute.form_id | html %]"
55
                                                    name="[% patron_attribute.form_id | html %]"
67
                                                name="[% patron_attribute.form_id | html %]"
56
                                                    maxlength="10"
68
                                                [% IF patron_attribute.mandatory %]required="required"[% END %][% IF ( patron_attribute.readonly ) %]readonly[% END %]
57
                                                    size="10"
69
                                            >
58
                                                    value="[% patron_attribute.value | html %]"
70
                                                [% patron_attribute.value | html %]
59
                                                    class="flatpickr"
71
                                            </textarea>
60
                                                />
61
                                            [% ELSE %]
62
                                                <textarea rows="2" cols="30" id="[% patron_attribute.form_id | html %]" name="[% patron_attribute.form_id | html %]">[% patron_attribute.value | html %]</textarea>
63
                                            [% END %]
64
                                        [% END %]
72
                                        [% END %]
65
                                    [% END # /IF ( patron_attribute.use_dropdown ) %]
73
                                    [% END # /IF ( patron_attribute.use_dropdown ) %]
66
                                    <input type="hidden" id="[% patron_attribute.form_id | html %]_code" name="[% patron_attribute.form_id | html %]_code" value="[% patron_attribute.code | html %]" />
74
                                    <input type="hidden" id="[% patron_attribute.form_id | html %]_code" name="[% patron_attribute.form_id | html %]_code" value="[% patron_attribute.code | html %]" />
67
                                    [% IF ( !patron_attribute.is_date ) %]
75
                                    [% IF ( !patron_attribute.is_date && !patron_attribute.readonly ) %]
68
                                        <a href="#" class="clear_attribute"><i class="fa fa-fw fa-trash-can"></i> Clear</a>
76
                                        <a href="#" class="clear_attribute"><i class="fa fa-fw fa-trash-can"></i> Clear</a>
69
                                    [% END %]
77
                                    [% END %]
70
                                    [% IF ( patron_attribute.repeatable ) %]
78
                                    [% IF ( patron_attribute.repeatable && !patron_attribute.readonly ) %]
71
                                        <a href="#" class="clone_attribute"><i class="fa fa-fw fa-plus"></i> New</a>
79
                                        <a href="#" class="clone_attribute"><i class="fa fa-fw fa-plus"></i> New</a>
72
                                    [% END %]
80
                                    [% END %]
73
                                    [% IF patron_attribute.mandatory %]<span class="required">Required</span>[% END %]
81
                                    [% IF patron_attribute.mandatory %]<span class="required">Required</span>[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt (+76 lines)
Lines 139-144 Link Here
139
                        [% END %]
139
                        [% END %]
140
                        <span class="hint">If checked, attribute will be a unique identifier. If a value is given to a patron record, the same value cannot be given to a different record.</span>
140
                        <span class="hint">If checked, attribute will be a unique identifier. If a value is given to a patron record, the same value cannot be given to a different record.</span>
141
                    </li>
141
                    </li>
142
                    <li>
143
                        <label for="hidden">Hidden: </label>
144
                        [% IF attribute_type AND attribute_type.hidden %]
145
                            <input type="checkbox" id="hidden" name="hidden" checked="checked" />
146
                        [% ELSE %]
147
                            <input type="checkbox" id="hidden" name="hidden" />
148
                        [% END %]
149
                        <span class="hint">Check to hide this attribute on a patron's details page in the OPAC and staff interface, and when creating or editing a patron from the staff interface. Does not apply for superlibrarians.</span>
150
                    </li>
151
                    <li>
152
                        <label for="readonly">Readonly: </label>
153
                        [% IF attribute_type AND attribute_type.readonly %]
154
                            <input type="checkbox" id="readonly" name="readonly" checked="checked" />
155
                        [% ELSE %]
156
                            <input type="checkbox" id="readonly" name="readonly" />
157
                        [% END %]
158
                        <span class="hint">Check to make this attribute readonly when creating or editing a patron from the staff interface. Does not apply for superlibrarians.</span>
159
                    </li>
160
                    <li>
161
                        <label for="secret">Secret: </label>
162
                        [% IF attribute_type AND attribute_type.secret %]
163
                            <input type="checkbox" id="secret" name="secret" checked="checked" />
164
                        [% ELSE %]
165
                            <input type="checkbox" id="secret" name="secret" />
166
                        [% END %]
167
                        <span class="hint">Check to mask attribute value on a patron's details page, and hide when creating or editing a patron. Does not apply for superlibrarians.</span>
168
                    </li>
142
                    <li
169
                    <li
143
                        ><label for="is_date">Is a date: </label>
170
                        ><label for="is_date">Is a date: </label>
144
                        [% IF attribute_type AND attribute_type.is_date %]
171
                        [% IF attribute_type AND attribute_type.is_date %]
Lines 459-464 Link Here
459
            if ($("#branches option:selected").length < 1) {
486
            if ($("#branches option:selected").length < 1) {
460
                $("#branches option:first").attr("selected", "selected");
487
                $("#branches option:first").attr("selected", "selected");
461
            }
488
            }
489
            $("#hidden")
490
                .change(function () {
491
                    if (this.checked) {
492
                        $("#opac_editable").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
493
                        $("#opac_display").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
494
                        $("#readonly").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
495
                        $("#secret").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
496
                        $("#display_checkout").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
497
                    } else {
498
                        $("#opac_editable").removeAttr("disabled").parent().removeAttr("aria-disabled");
499
                        $("#opac_display").removeAttr("disabled").parent().removeAttr("aria-disabled");
500
                        $("#readonly").removeAttr("disabled").parent().removeAttr("aria-disabled");
501
                        $("#secret").removeAttr("disabled").parent().removeAttr("aria-disabled");
502
                        $("#display_checkout").removeAttr("disabled").parent().removeAttr("aria-disabled");
503
                    }
504
                })
505
                .change();
506
507
            $("#readonly")
508
                .change(function () {
509
                    if (this.checked) {
510
                        $("#opac_editable").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
511
                        $("#hidden").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
512
                        $("#secret").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
513
                    } else {
514
                        $("#opac_editable").removeAttr("disabled").parent().removeAttr("aria-disabled");
515
                        $("#hidden").removeAttr("disabled").parent().removeAttr("aria-disabled");
516
                        $("#secret").removeAttr("disabled").parent().removeAttr("aria-disabled");
517
                    }
518
                })
519
                .change();
520
521
            $("#secret")
522
                .change(function () {
523
                    if (this.checked) {
524
                        $("#opac_editable").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
525
                        $("#opac_display").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
526
                        $("#hidden").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
527
                        $("#readony").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
528
                        $("#display_checkout").attr("disabled", true).prop("checked", false).parent().attr("aria-disabled", "true");
529
                    } else {
530
                        $("#opac_editable").removeAttr("disabled").parent().removeAttr("aria-disabled");
531
                        $("#opac_display").removeAttr("disabled").parent().removeAttr("aria-disabled");
532
                        $("#hidden").removeAttr("disabled").parent().removeAttr("aria-disabled");
533
                        $("#readonly").removeAttr("disabled").parent().removeAttr("aria-disabled");
534
                        $("#display_checkout").removeAttr("disabled").parent().removeAttr("aria-disabled");
535
                    }
536
                })
537
                .change();
462
538
463
            $("#is_date")
539
            $("#is_date")
464
                .change(function () {
540
                .change(function () {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (-3 / +7 lines)
Lines 359-368 Link Here
359
                                        [% FOREACH item IN attribute.items %]
359
                                        [% FOREACH item IN attribute.items %]
360
                                            <li data-pa_code="[% item.type.code | replace('[^a-zA-Z0-9_-]', '') %]">
360
                                            <li data-pa_code="[% item.type.code | replace('[^a-zA-Z0-9_-]', '') %]">
361
                                                <span class="label">[% item.type.description | html %]: </span>
361
                                                <span class="label">[% item.type.description | html %]: </span>
362
                                                [% IF item.type.is_date %]
362
                                                [% IF item.type.secret %]
363
                                                    [% item.description | $KohaDates %]
363
                                                    *****
364
                                                [% ELSE %]
364
                                                [% ELSE %]
365
                                                    [% item.description | html_line_break %]
365
                                                    [% IF item.type.is_date %]
366
                                                        [% item.description | $KohaDates %]
367
                                                    [% ELSE %]
368
                                                        [% item.description | html_line_break %]
369
                                                    [% END %]
366
                                                [% END %]
370
                                                [% END %]
367
                                            </li>
371
                                            </li>
368
                                        [% END %]
372
                                        [% END %]
(-)a/members/memberentry.pl (-3 / +4 lines)
Lines 165-172 foreach (@field_check) { Link Here
165
$template->param( "quickadd"  => 1 ) if ($quickadd);
165
$template->param( "quickadd"  => 1 ) if ($quickadd);
166
$template->param( "duplicate" => 1 ) if ( $op eq 'duplicate' );
166
$template->param( "duplicate" => 1 ) if ( $op eq 'duplicate' );
167
$template->param( "checked"   => 1 ) if ( defined($nodouble) && $nodouble eq 1 );
167
$template->param( "checked"   => 1 ) if ( defined($nodouble) && $nodouble eq 1 );
168
my $logged_in_user = Koha::Patrons->find($loggedinuser);
169
168
if ( $op eq 'edit_form' or $op eq 'cud-save' or $op eq 'duplicate' ) {
170
if ( $op eq 'edit_form' or $op eq 'cud-save' or $op eq 'duplicate' ) {
169
    my $logged_in_user = Koha::Patrons->find($loggedinuser);
170
    output_and_exit_if_error(
171
    output_and_exit_if_error(
171
        $input, $cookie, $template,
172
        $input, $cookie, $template,
172
        { module => 'members', logged_in_user => $logged_in_user, current_patron => $patron }
173
        { module => 'members', logged_in_user => $logged_in_user, current_patron => $patron }
Lines 661-667 if ( ( !$nok ) and $nodouble and ( $op eq 'cud-insert' or $op eq 'cud-save' ) ) Link Here
661
        if ( C4::Context->preference('ExtendedPatronAttributes')
662
        if ( C4::Context->preference('ExtendedPatronAttributes')
662
            and $input->param('setting_extended_patron_attributes') )
663
            and $input->param('setting_extended_patron_attributes') )
663
        {
664
        {
664
            $patron->extended_attributes($extended_patron_attributes);
665
            $patron->extended_attributes( $extended_patron_attributes, { check_editable => 1 } );
665
        }
666
        }
666
667
667
        if (
668
        if (
Lines 868-874 if ( C4::Context->preference('uppercasesurnames') ) { Link Here
868
}
869
}
869
870
870
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
871
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
871
    Koha::Patron::Attribute::Types::patron_attributes_form( $template, $extended_patron_attributes, $op );
872
    Koha::Patron::Attribute::Types::patron_attributes_form( $template, $logged_in_user, $extended_patron_attributes, $op );
872
}
873
}
873
874
874
if ( C4::Context->preference('EnhancedMessagingPreferences') ) {
875
if ( C4::Context->preference('EnhancedMessagingPreferences') ) {
(-)a/members/moremember.pl (-8 / +9 lines)
Lines 27-33 Link Here
27
=cut
27
=cut
28
28
29
use Modern::Perl;
29
use Modern::Perl;
30
use CGI qw ( -utf8 );
30
use CGI        qw ( -utf8 );
31
use List::Util qw ( all );
31
use C4::Context;
32
use C4::Context;
32
use C4::Auth   qw( get_template_and_user );
33
use C4::Auth   qw( get_template_and_user );
33
use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_http_headers );
34
use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_http_headers );
Lines 143-157 unless ( Koha::Patron::Categories->search_with_library_limits( { 'me.categorycod Link Here
143
}
144
}
144
145
145
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
146
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
146
    my @attributes = $patron->extended_attributes->as_list;         # FIXME Must be improved!
147
    my $is_superlibrarian = $logged_in_user->is_superlibrarian;
147
    my @classes    = uniq( map { $_->type->class } @attributes );
148
    my @attributes        = $patron->extended_attributes->as_list;         # FIXME Must be improved!
149
    my @classes           = uniq( map { $_->type->class } @attributes );
148
    @classes = sort @classes;
150
    @classes = sort @classes;
149
151
150
    my @attributes_loop;
152
    my @attributes_loop;
151
    for my $class (@classes) {
153
    for my $class (@classes) {
152
        my @items;
154
        my @items;
153
        for my $attr (@attributes) {
155
        for my $attr (@attributes) {
154
            push @items, $attr if $attr->type->class eq $class;
156
            push @items, $attr if $attr->type->class eq $class && ( $is_superlibrarian || !$attr->hidden );
155
        }
157
        }
156
        my $av  = Koha::AuthorisedValues->search( { category => 'PA_CLASS', authorised_value => $class } );
158
        my $av  = Koha::AuthorisedValues->search( { category => 'PA_CLASS', authorised_value => $class } );
157
        my $lib = $av->count ? $av->next->lib : $class;
159
        my $lib = $av->count ? $av->next->lib : $class;
Lines 166-174 if ( C4::Context->preference('ExtendedPatronAttributes') ) { Link Here
166
    $template->param( attributes_loop => \@attributes_loop );
168
    $template->param( attributes_loop => \@attributes_loop );
167
169
168
    my $library_id = C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
170
    my $library_id = C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
169
    my $nb_of_attribute_types =
171
    my $attribute_types =
170
        Koha::Patron::Attribute::Types->search_with_library_limits( {}, {}, $library_id )->count;
172
        Koha::Patron::Attribute::Types->search_with_library_limits( {}, {}, $library_id );
171
    if ( $nb_of_attribute_types == 0 ) {
173
    if ( $attribute_types->count == 0 || ( !$is_superlibrarian && all { $_->hidden } $attribute_types->as_list ) ) {
172
        $template->param( no_patron_attribute_types => 1 );
174
        $template->param( no_patron_attribute_types => 1 );
173
    }
175
    }
174
}
176
}
175
- 

Return to bug 39453