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

(-)a/C4/Auth.pm (-3 / +3 lines)
Lines 33-39 use C4::Branch; # GetBranches Link Here
33
use C4::Search::History;
33
use C4::Search::History;
34
use Koha;
34
use Koha;
35
use Koha::AuthUtils qw(hash_password);
35
use Koha::AuthUtils qw(hash_password);
36
use Koha::LibraryCategories;
36
use Koha::Library::Groups;
37
use Koha::Libraries;
37
use Koha::Libraries;
38
use POSIX qw/strftime/;
38
use POSIX qw/strftime/;
39
use List::MoreUtils qw/ any /;
39
use List::MoreUtils qw/ any /;
Lines 508-519 sub get_template_and_user { Link Here
508
            $opac_name = C4::Context->userenv->{'branch'};
508
            $opac_name = C4::Context->userenv->{'branch'};
509
        }
509
        }
510
510
511
        my $library_categories = Koha::LibraryCategories->search({categorytype => 'searchdomain', show_in_pulldown => 1}, { order_by => ['categorytype', 'categorycode']});
511
        my $search_groups = Koha::Library::Groups->get_search_groups();
512
        $template->param(
512
        $template->param(
513
            OpacAdditionalStylesheet                   => C4::Context->preference("OpacAdditionalStylesheet"),
513
            OpacAdditionalStylesheet                   => C4::Context->preference("OpacAdditionalStylesheet"),
514
            AnonSuggestions                       => "" . C4::Context->preference("AnonSuggestions"),
514
            AnonSuggestions                       => "" . C4::Context->preference("AnonSuggestions"),
515
            BranchesLoop                          => GetBranchesLoop($opac_name),
515
            BranchesLoop                          => GetBranchesLoop($opac_name),
516
            BranchCategoriesLoop                  => $library_categories,
516
            LibrarySearchGroups                   => $search_groups,
517
            opac_name                             => $opac_name,
517
            opac_name                             => $opac_name,
518
            LibraryName                           => "" . C4::Context->preference("LibraryName"),
518
            LibraryName                           => "" . C4::Context->preference("LibraryName"),
519
            LibraryNameTitle                      => "" . $LibraryNameTitle,
519
            LibraryNameTitle                      => "" . $LibraryNameTitle,
(-)a/C4/Branch.pm (-1 lines)
Lines 20-26 use strict; Link Here
20
#use warnings; FIXME - Bug 2505
20
#use warnings; FIXME - Bug 2505
21
require Exporter;
21
require Exporter;
22
use C4::Context;
22
use C4::Context;
23
use Koha::LibraryCategories;
24
23
25
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
24
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
26
25
(-)a/Koha/Library.pm (-19 lines)
Lines 35-59 Koha::Library - Koha Library Object class Link Here
35
35
36
=cut
36
=cut
37
37
38
sub get_categories {
39
    my ( $self, $params ) = @_;
40
    # TODO This should return Koha::LibraryCategories
41
    return $self->{_result}->categorycodes( $params );
42
}
43
44
sub update_categories {
45
    my ( $self, $categories ) = @_;
46
    $self->_result->delete_related( 'branchrelations' );
47
    $self->add_to_categories( $categories );
48
}
49
50
sub add_to_categories {
51
    my ( $self, $categories ) = @_;
52
    for my $category ( @$categories ) {
53
        $self->_result->add_to_categorycodes( $category->_result );
54
    }
55
}
56
57
=head3 type
38
=head3 type
58
39
59
=cut
40
=cut
(-)a/Koha/Library/Group.pm (-7 / +27 lines)
Lines 59-65 sub children { Link Here
59
    my $children =
59
    my $children =
60
      Koha::Library::Groups->search( { parent_id => $self->id }, { order_by => [ 'title', 'branchcode' ] } );
60
      Koha::Library::Groups->search( { parent_id => $self->id }, { order_by => [ 'title', 'branchcode' ] } );
61
61
62
    return $children;
62
    return wantarray ? $children->as_list : $children;
63
}
63
}
64
64
65
=head3 library
65
=head3 library
Lines 80-95 sub library { Link Here
80
    return $self->{_library};
80
    return $self->{_library};
81
}
81
}
82
82
83
=head3 libraries_not_direct_children
83
=head3 libraries
84
84
85
my @libraries = $group->libraries_not_direct_children();
85
my @libraries = $group->libraries( { [invert => 1] } );
86
86
87
Returns the libraries *not* set as direct children of this group
87
Returns the libraries set as direct children of this group.
88
89
If invert param is true, the returned list will be libraries
90
that are *not* direct children of this group.
88
91
89
=cut
92
=cut
90
93
91
sub libraries_not_direct_children {
94
sub libraries {
92
    my ($self) = @_;
95
    my ($self, $params) = @_;
96
    my $invert = $params->{invert};
97
98
    my $in_or_not = $invert ? '-not_in' : '-in';
93
99
94
    my @children = Koha::Library::Groups->search(
100
    my @children = Koha::Library::Groups->search(
95
        {
101
        {
Lines 103-109 sub libraries_not_direct_children { Link Here
103
109
104
    return Koha::Libraries->search(
110
    return Koha::Libraries->search(
105
        {
111
        {
106
            branchcode => { -not_in => \@branchcodes }
112
            branchcode => { $in_or_not => \@branchcodes }
107
        },
113
        },
108
        {
114
        {
109
            order_by => 'branchname'
115
            order_by => 'branchname'
Lines 111-116 sub libraries_not_direct_children { Link Here
111
    );
117
    );
112
}
118
}
113
119
120
=head3 libraries_not_direct_children
121
122
my @libraries = $group->libraries_not_direct_children();
123
124
Returns the libraries *not* set as direct children of this group
125
126
=cut
127
128
sub libraries_not_direct_children {
129
    my ($self) = @_;
130
131
    return $self->libraries( { invert => 1 } );
132
}
133
114
=head3 store
134
=head3 store
115
135
116
=cut
136
=cut
(-)a/Koha/Library/Groups.pm (+23 lines)
Lines 45-50 sub get_root_groups { Link Here
45
    return $self->search( { parent_id => undef }, { order_by => 'title' } );
45
    return $self->search( { parent_id => undef }, { order_by => 'title' } );
46
}
46
}
47
47
48
=head3 my @search_groups = $self->get_search_groups({[interface => 'staff' || 'opac']}))
49
50
Returns search groups for the specified interface.
51
Defaults to OPAC if no interface is specified.
52
53
=cut
54
55
sub get_search_groups {
56
    my ( $self, $params ) = @_;
57
    my $interface = $params->{interface} || q{};
58
59
    my $title = $interface eq 'staff' ? '__SEARCH_GROUPS__' : '__SEARCH_GROUPS_OPAC__';
60
61
    my ($search_groups_root) =
62
      $self->search( { parent_id => undef, title => $title } );
63
64
    return unless $search_groups_root;
65
66
    my $children = $search_groups_root->children();
67
68
    return wantarray ? $children->as_list : $children;
69
}
70
48
=head3 type
71
=head3 type
49
72
50
=cut
73
=cut
(-)a/admin/branches.pl (-84 / +1 lines)
Lines 27-33 use C4::Koha; Link Here
27
use Koha::Patrons;
27
use Koha::Patrons;
28
use Koha::Items;
28
use Koha::Items;
29
use Koha::Libraries;
29
use Koha::Libraries;
30
use Koha::LibraryCategories;
31
30
32
my $input        = new CGI;
31
my $input        = new CGI;
33
my $branchcode   = $input->param('branchcode');
32
my $branchcode   = $input->param('branchcode');
Lines 53-60 if ( $op eq 'add_form' ) { Link Here
53
52
54
    $template->param(
53
    $template->param(
55
        library    => $library,
54
        library    => $library,
56
        categories => [ Koha::LibraryCategories->search( {}, { order_by => [ 'categorytype', 'categoryname' ] } ) ],
57
        $library ? ( selected_categorycodes => [ map { $_->categorycode } $library->get_categories ] ) : (),
58
    );
55
    );
59
} elsif ( $op eq 'add_validate' ) {
56
} elsif ( $op eq 'add_validate' ) {
60
    my @fields = qw(
57
    my @fields = qw(
Lines 79-96 if ( $op eq 'add_form' ) { Link Here
79
    );
76
    );
80
    my $is_a_modif = $input->param('is_a_modif');
77
    my $is_a_modif = $input->param('is_a_modif');
81
78
82
    my @categories;
83
    for my $category ( Koha::LibraryCategories->search ) {
84
        push @categories, $category
85
          if $input->param( "selected_categorycode_" . $category->categorycode );
86
    }
87
    if ($is_a_modif) {
79
    if ($is_a_modif) {
88
        my $library = Koha::Libraries->find($branchcode);
80
        my $library = Koha::Libraries->find($branchcode);
89
        for my $field (@fields) {
81
        for my $field (@fields) {
90
            $library->$field( scalar $input->param($field) );
82
            $library->$field( scalar $input->param($field) );
91
        }
83
        }
92
        $library->update_categories( \@categories );
93
94
        eval { $library->store; };
84
        eval { $library->store; };
95
        if ($@) {
85
        if ($@) {
96
            push @messages, { type => 'alert', code => 'error_on_update' };
86
            push @messages, { type => 'alert', code => 'error_on_update' };
Lines 105-111 if ( $op eq 'add_form' ) { Link Here
105
            }
95
            }
106
        );
96
        );
107
        eval { $library->store; };
97
        eval { $library->store; };
108
        $library->add_to_categories( \@categories );
109
        if ($@) {
98
        if ($@) {
110
            push @messages, { type => 'alert', code => 'error_on_insert' };
99
            push @messages, { type => 'alert', code => 'error_on_insert' };
111
        } else {
100
        } else {
Lines 152-236 if ( $op eq 'add_form' ) { Link Here
152
        push @messages, { type => 'message', code => 'success_on_delete' };
141
        push @messages, { type => 'message', code => 'success_on_delete' };
153
    }
142
    }
154
    $op = 'list';
143
    $op = 'list';
155
} elsif ( $op eq 'add_form_category' ) {
156
    my $category;
157
    if ($categorycode) {
158
        $category = Koha::LibraryCategories->find($categorycode);
159
    }
160
    $template->param( category => $category, );
161
} elsif ( $op eq 'add_validate_category' ) {
162
    my $is_a_modif = $input->param('is_a_modif');
163
    my @fields     = qw(
164
      categoryname
165
      codedescription
166
      categorytype
167
    );
168
    if ($is_a_modif) {
169
        my $category = Koha::LibraryCategories->find($categorycode);
170
        for my $field (@fields) {
171
            $category->$field( scalar $input->param($field) );
172
        }
173
        $category->show_in_pulldown( scalar $input->param('show_in_pulldown') eq 'on' );
174
        eval { $category->store; };
175
        if ($@) {
176
            push @messages, { type => 'alert', code => 'error_on_update_category' };
177
        } else {
178
            push @messages, { type => 'message', code => 'success_on_update_category' };
179
        }
180
    } else {
181
        my $category = Koha::LibraryCategory->new(
182
            {   categorycode => $categorycode,
183
                ( map { $_ => scalar $input->param($_) || undef } @fields )
184
            }
185
        );
186
        $category->show_in_pulldown( scalar $input->param('show_in_pulldown') eq 'on' );
187
        eval { $category->store; };
188
        if ($@) {
189
            push @messages, { type => 'alert', code => 'error_on_insert_category' };
190
        } else {
191
            push @messages, { type => 'message', code => 'success_on_insert_category' };
192
        }
193
    }
194
    $op = 'list';
195
} elsif ( $op eq 'delete_confirm_category' ) {
196
    my $category = Koha::LibraryCategories->find($categorycode);
197
    if ( my $libraries_count = $category->libraries->count ) {
198
        push @messages,
199
          { type => 'alert',
200
            code => 'cannot_delete_category',
201
            data => { libraries_count => $libraries_count, },
202
          };
203
        $op = 'list';
204
    } else {
205
        $template->param( category => $category );
206
    }
207
} elsif ( $op eq 'delete_confirmed_category' ) {
208
    my $category = Koha::LibraryCategories->find($categorycode);
209
    my $deleted = eval { $category->delete; };
210
211
    if ( $@ or not $deleted ) {
212
        push @messages, { type => 'alert', code => 'error_on_delete_category' };
213
    } else {
214
        push @messages, { type => 'message', code => 'success_on_delete_category' };
215
    }
216
    $op = 'list';
217
} else {
144
} else {
218
    $op = 'list';
145
    $op = 'list';
219
}
146
}
220
147
221
if ( $op eq 'list' ) {
148
if ( $op eq 'list' ) {
222
    my $libraries = Koha::Libraries->search( {}, { order_by => ['branchcode'] }, );
149
    my $libraries = Koha::Libraries->search( {}, { order_by => ['branchcode'] }, );
223
    $template->param(
150
    $template->param( libraries => $libraries, );
224
        libraries   => $libraries,
225
        group_types => [
226
            {   categorytype => 'searchdomain',
227
                categories   => [ Koha::LibraryCategories->search( { categorytype => 'searchdomain' } ) ],
228
            },
229
            {   categorytype => 'properties',
230
                categories   => [ Koha::LibraryCategories->search( { categorytype => 'properties' } ) ],
231
            },
232
        ]
233
    );
234
}
151
}
235
152
236
$template->param(
153
$template->param(
(-)a/catalogue/search.pl (-5 / +13 lines)
Lines 152-158 use POSIX qw(ceil floor); Link Here
152
use C4::Branch; # GetBranches
152
use C4::Branch; # GetBranches
153
use C4::Search::History;
153
use C4::Search::History;
154
154
155
use Koha::LibraryCategories;
155
use Koha::Library::Groups;
156
use Koha::Virtualshelves;
156
use Koha::Virtualshelves;
157
use Koha::SearchEngine::Search;
157
use Koha::SearchEngine::Search;
158
use Koha::SearchEngine::QueryBuilder;
158
use Koha::SearchEngine::QueryBuilder;
Lines 222-230 my @branch_loop = map { Link Here
222
    $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
222
    $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname}
223
} keys %$branches;
223
} keys %$branches;
224
224
225
my $categories = Koha::LibraryCategories->search( { categorytype => 'searchdomain' }, { order_by => [ 'categorytype', 'categorycode' ] } );
225
my @search_groups_opac =
226
  Koha::Library::Groups->get_search_groups( { interface => 'opac' } );
227
my @search_groups_staff =
228
  Koha::Library::Groups->get_search_groups( { interface => 'staff' } );
229
my @search_groups = ( @search_groups_opac, @search_groups_staff );
230
@search_groups = sort { $a->title cmp $b->title } @search_groups;
226
231
227
$template->param(branchloop => \@branch_loop, searchdomainloop => $categories);
232
$template->param(
233
    branchloop       => \@branch_loop,
234
    search_groups    => \@search_groups,
235
);
228
236
229
# load the Type stuff
237
# load the Type stuff
230
my $itemtypes = GetItemTypes;
238
my $itemtypes = GetItemTypes;
Lines 404-411 my %is_nolimit = map { $_ => 1 } @nolimits; Link Here
404
@limits = grep { not $is_nolimit{$_} } @limits;
412
@limits = grep { not $is_nolimit{$_} } @limits;
405
413
406
if($params->{'multibranchlimit'}) {
414
if($params->{'multibranchlimit'}) {
407
    my $library_category = Koha::LibraryCategories->find( $params->{multibranchlimit} );
415
    my $search_group = Koha::Library::Groups->find( $params->{multibranchlimit} );
408
    my @libraries = $library_category->libraries;
416
    my @libraries = $search_group->libraries;
409
    my $multibranch = '('.join( " or ", map { 'branch: ' . $_->id } @libraries ) .')';
417
    my $multibranch = '('.join( " or ", map { 'branch: ' . $_->id } @libraries ) .')';
410
    push @limits, $multibranch if ($multibranch ne  '()');
418
    push @limits, $multibranch if ($multibranch ne  '()');
411
}
419
}
(-)a/installer/data/mysql/updatedatabase.pl (+38 lines)
Lines 12637-12642 if ( CheckVersion($DBversion) ) { Link Here
12637
    SetVersion($DBversion);
12637
    SetVersion($DBversion);
12638
}
12638
}
12639
12639
12640
$DBversion = "16.06.00.XXX";
12641
if ( CheckVersion($DBversion) ) {
12642
    require Koha::Library::Group;
12643
12644
    my $search_groups_staff_root = Koha::Library::Group->new( { title => '__SEARCH_GROUPS__', description => "Library search groups - Staff only" } )->store();
12645
    my $search_groups_opac_root = Koha::Library::Group->new( { title => '__SEARCH_GROUPS_OPAC__', description => "Library search groups - OPAC & Staff" } )->store();
12646
12647
    my $sth = $dbh->prepare("SELECT * FROM branchcategories");
12648
    $sth->execute();
12649
12650
    while ( my $lc = $sth->fetchrow_hashref ) {
12651
        my $description = $lc->{categorycode};
12652
        $description .= " - " . $lc->{codedescription} if $lc->{codedescription};
12653
12654
        my $subgroup = Koha::Library::Group->new(
12655
            {
12656
                parent_id   => $lc->{show_in_pulldown} ? $search_groups_opac_root->id : $search_groups_staff_root->id,
12657
                title       => $lc->{categoryname},
12658
                description => $description,
12659
            }
12660
        )->store();
12661
12662
        my $sth2 = $dbh->prepare("SELECT * FROM branchrelations WHERE categorycode = ?");
12663
        $sth2->execute( $lc->{categorycode} );
12664
12665
        while ( my $l = $sth2->fetchrow_hashref ) {
12666
            Koha::Library::Group->new( { parent_id => $subgroup->id, branchcode => $l->{branchcode} } )->store();
12667
        }
12668
    }
12669
12670
# RM Should uncomment these
12671
#    $dbh->do("DROP TABLE branchrelations");
12672
#    $dbh->do("DROP TABLE branchcategories");
12673
12674
    print "Upgrade to $DBversion done (Bug 16735 - Replace existing library search groups functionality with the new hierarchical groups system)\n";
12675
    SetVersion($DBversion);
12676
}
12677
12640
12678
12641
# DEVELOPER PROCESS, search for anything to execute in the db_update directory
12679
# DEVELOPER PROCESS, search for anything to execute in the db_update directory
12642
# SEE bug 13068
12680
# SEE bug 13068
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc (-1 / +1 lines)
Lines 20-26 Link Here
20
20
21
<h5>Basic parameters</h5>
21
<h5>Basic parameters</h5>
22
<ul>
22
<ul>
23
    <li><a href="/cgi-bin/koha/admin/branches.pl">Libraries and groups</a></li>
23
    <li><a href="/cgi-bin/koha/admin/branches.pl">Libraries</a></li>
24
    <li><a href="/cgi-bin/koha/admin/library_groups.pl">Library groups</a></li>
24
    <li><a href="/cgi-bin/koha/admin/library_groups.pl">Library groups</a></li>
25
    <li><a href="/cgi-bin/koha/admin/itemtypes.pl">Item types</a></li>
25
    <li><a href="/cgi-bin/koha/admin/itemtypes.pl">Item types</a></li>
26
    <li><a href="/cgi-bin/koha/admin/authorised_values.pl">Authorized values</a></li>
26
    <li><a href="/cgi-bin/koha/admin/authorised_values.pl">Authorized values</a></li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt (-3 / +3 lines)
Lines 29-38 Link Here
29
                <div class="hint"><h4>Hint:</h4><p>Configure these parameters in the order they appear.</p></div>
29
                <div class="hint"><h4>Hint:</h4><p>Configure these parameters in the order they appear.</p></div>
30
                <h3>Basic parameters</h3>
30
                <h3>Basic parameters</h3>
31
                <dl>
31
                <dl>
32
                    <dt><a href="/cgi-bin/koha/admin/branches.pl">Libraries and groups</a></dt>
32
                    <dt><a href="/cgi-bin/koha/admin/branches.pl">Libraries</a></dt>
33
                    <dd>Define libraries and groups.</dd>
33
                    <dd>Define libraries.</dd>
34
                    <dt><a href="/cgi-bin/koha/admin/library_groups.pl">Library groups</a></dt>
34
                    <dt><a href="/cgi-bin/koha/admin/library_groups.pl">Library groups</a></dt>
35
                    <dd>Define library hierarchies.</dd>
35
                    <dd>Define hierarchical library groups.</dd>
36
                    <dt><a href="/cgi-bin/koha/admin/itemtypes.pl">Item types</a></dt>
36
                    <dt><a href="/cgi-bin/koha/admin/itemtypes.pl">Item types</a></dt>
37
                    <dd>Define item types used for circulation rules.</dd>
37
                    <dd>Define item types used for circulation rules.</dd>
38
                    <dt><a href="/cgi-bin/koha/admin/authorised_values.pl">Authorized values</a></dt>
38
                    <dt><a href="/cgi-bin/koha/admin/authorised_values.pl">Authorized values</a></dt>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt (-132 / +4 lines)
Lines 1-10 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Administration &rsaquo; Libraries and groups
2
<title>Koha &rsaquo; Administration &rsaquo; Libraries
3
[% IF op == 'editcategory' %]
3
[% IF op == 'add_form' %]
4
    &rsaquo;[% IF category.categorycode %]Edit group [% category.categorycode%][% ELSE %]New group[% END %]
5
[% ELSIF op == 'delete_confirm_category' %]
6
    &rsaquo; Confirm deletion of group [% category.categorycode %]
7
[% ELSIF op == 'add_form' %]
8
    &rsaquo;[% IF library %]Modify library[% ELSE %]New library [% library.branchcode %][% END %]
4
    &rsaquo;[% IF library %]Modify library[% ELSE %]New library [% library.branchcode %][% END %]
9
[% ELSIF op == 'delete_confirm' %]
5
[% ELSIF op == 'delete_confirm' %]
10
    &rsaquo; Confirm deletion of library '[% library.branchcode %]'
6
    &rsaquo; Confirm deletion of library '[% library.branchcode %]'
Lines 61-72 tinyMCE.init({ Link Here
61
<div id="breadcrumbs">
57
<div id="breadcrumbs">
62
    <a href="/cgi-bin/koha/mainpage.pl">Home</a>
58
    <a href="/cgi-bin/koha/mainpage.pl">Home</a>
63
&rsaquo; <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
59
&rsaquo; <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
64
&rsaquo; <a href="/cgi-bin/koha/admin/branches.pl">Libraries and groups</a>
60
&rsaquo; <a href="/cgi-bin/koha/admin/branches.pl">Libraries</a>
65
[% IF op == 'add_form_category' %]
61
[% IF op == 'add_form'  %]
66
&rsaquo; [% IF category.categorycode %]Edit group [% category.categorycode %][% ELSE %]New group[% END %]
67
[% ELSIF op == 'delete_confirm_category' %]
68
&rsaquo; Confirm deletion of group [% category.categorycode %]
69
[% ELSIF op == 'add_form'  %]
70
&rsaquo; [% IF library %]Modify library[% ELSE %]New library [% library.branchcode %][% END %]
62
&rsaquo; [% IF library %]Modify library[% ELSE %]New library [% library.branchcode %][% END %]
71
[% ELSIF op == 'delete_confirm' %]
63
[% ELSIF op == 'delete_confirm' %]
72
&rsaquo; Confirm deletion of library '[% library.branchcode %]'
64
&rsaquo; Confirm deletion of library '[% library.branchcode %]'
Lines 126-132 tinyMCE.init({ Link Here
126
[% IF op == 'list' %]
118
[% IF op == 'list' %]
127
    <div id="toolbar" class="btn-toolbar">
119
    <div id="toolbar" class="btn-toolbar">
128
        <a class="btn btn-small" id="newbranch" href="/cgi-bin/koha/admin/branches.pl?op=add_form"><i class="fa fa-plus"></i> New library</a>
120
        <a class="btn btn-small" id="newbranch" href="/cgi-bin/koha/admin/branches.pl?op=add_form"><i class="fa fa-plus"></i> New library</a>
129
        <a class="btn btn-small" id="newcategory" href="/cgi-bin/koha/admin/branches.pl?op=add_form_category"><i class="fa fa-plus"></i> New group</a>
130
    </div>
121
    </div>
131
[% END %]
122
[% END %]
132
123
Lines 225-231 tinyMCE.init({ Link Here
225
                    <th>Name</th>
216
                    <th>Name</th>
226
                    <th>Code</th>
217
                    <th>Code</th>
227
                    <th>Address</th>
218
                    <th>Address</th>
228
                    <th>Properties</th>
229
                    <th>IP</th>
219
                    <th>IP</th>
230
                    <th>Actions</th>
220
                    <th>Actions</th>
231
                </tr>
221
                </tr>
Lines 262-272 tinyMCE.init({ Link Here
262
                            [% IF library.branchnotes %]
252
                            [% IF library.branchnotes %]
263
                                <br />Notes: [% library.branchnotes |html %][% END %]
253
                                <br />Notes: [% library.branchnotes |html %][% END %]
264
                        </td>
254
                        </td>
265
                        <td>
266
                            [% FOREACH category IN library.get_categories %]
267
                                [% category.categoryname %]<br />
268
                            [% END %]
269
                        </td>
270
                        <td>[% library.branchip %]</td>
255
                        <td>[% library.branchip %]</td>
271
                        <td class="actions">
256
                        <td class="actions">
272
                            <a class="btn btn-mini" href="/cgi-bin/koha/admin/branches.pl?op=add_form&amp;branchcode=[% library.branchcode %]"><i class="fa fa-pencil"></i> Edit</a>
257
                            <a class="btn btn-mini" href="/cgi-bin/koha/admin/branches.pl?op=add_form&amp;branchcode=[% library.branchcode %]"><i class="fa fa-pencil"></i> Edit</a>
Lines 279-397 tinyMCE.init({ Link Here
279
    [% ELSE %]
264
    [% ELSE %]
280
        <div class="dialog message">There are no libraries defined. <a href="/cgi-bin/koha/admin/branches.pl?op=add_form">Start defining libraries</a>.</div>
265
        <div class="dialog message">There are no libraries defined. <a href="/cgi-bin/koha/admin/branches.pl?op=add_form">Start defining libraries</a>.</div>
281
    [% END %]
266
    [% END %]
282
283
    [% IF group_types %]
284
        [% FOREACH group_type IN group_types %]
285
            <h3>[% IF group_type.categorytype == 'properties' %]Properties[% ELSIF group_type.categorytype == 'searchdomain' %]Search domain[% END %]</h3>
286
            [% IF group_type.categories.size %]
287
                <table>
288
                    <thead>
289
                        <tr>
290
                            <th>Name</th>
291
                            <th>Code</th>
292
                            <th>Description</th>
293
                            <th>Actions</th>
294
                        </tr>
295
                    </thead>
296
                    <tbody>
297
                        [% FOREACH category IN group_type.categories %]
298
                            <tr>
299
                                <td>[% category.categoryname %]</td>
300
                                <td>[% category.categorycode %]</td>
301
                                <td>[% category.codedescription %]</td>
302
                                <td class="actions">
303
                                  <a class="btn btn-mini" href="/cgi-bin/koha/admin/branches.pl?categorycode=[% category.categorycode %]&amp;op=add_form_category"><i class="fa fa-pencil"></i> Edit</a>
304
                                  <a class="btn btn-mini" href="/cgi-bin/koha/admin/branches.pl?categorycode=[% category.categorycode %]&amp;op=delete_confirm_category"><i class="fa fa-trash"></i> Delete</a>
305
                                </td>
306
                            </tr>
307
                        [% END %]
308
                    </tbody>
309
                </table>
310
            [% ELSE %]
311
                [% IF group_type.categorytype == 'properties' %]
312
                    No properties defined.
313
                [% ELSIF group_type.categorytype == 'searchdomain' %]
314
                    No search domain defined.
315
                [% END %]
316
                <a href="/cgi-bin/koha/admin/branches.pl?op=add_form_category">Add a new group</a>.
317
            [% END %]
318
        [% END %]
319
    [% ELSE %]
320
        <p>No groups defined.</p>
321
    [% END %]
322
[% END %]
323
324
[% IF op == 'add_form_category' %]
325
    <h3>[% IF category.categorycode %]Edit group [% category.categorycode %][% ELSE %]Add group[% END %]</h3>
326
    <form action="/cgi-bin/koha/admin/branches.pl" name="Aform" method="post" class="validated">
327
        <input type="hidden" name="op" value="add_validate_category" />
328
        [% IF category.categorycode %]
329
            <input type="hidden" name="is_a_modif" value="1" />
330
        [% END %]
331
        <fieldset class="rows">
332
            <ol>
333
                <li>
334
                    [% IF category.categorycode %]
335
                        <span class="label">Category code: </span>
336
                        <input type="hidden" name="categorycode" id="categorycode" value="[% category.categorycode |html %]" />
337
                        [% category.categorycode %]
338
                    [% ELSE %]
339
                        <label for="categorycode" class="required">Category code:</label>
340
                        <input type="text" name="categorycode" id="categorycode" size="10" maxlength="10" class="required" required="required" />
341
                        <span class="required">Required</span>
342
                    [% END %]
343
                </li>
344
                <li>
345
                    <label for="categoryname" class="required">Name: </label>
346
                    <input type="text" name="categoryname" id="categoryname" size="32" maxlength="32" value="[% category.categoryname |html %]" class="required" required="required" />
347
                    <span class="required">Required</span>
348
                </li>
349
                <li>
350
                    <label for="codedescription">Description: </label>
351
                    <input type="text" name="codedescription" id="codedescription" size="70" value="[% category.codedescription |html %]" />
352
                </li>
353
                <li>
354
                    <label for="categorytype">Category type: </label>
355
                    <select id="categorytype" name="categorytype">
356
                        [% IF category.categorytype == 'properties' %]
357
                            <option value="searchdomain">Search domain</option>
358
                            <option value="properties" selected="selected">Properties</option>
359
                        [% ELSE %]
360
                            <option value="searchdomain">Search domain</option>
361
                            <option value="properties">Properties</option>
362
363
                        [% END %]
364
                    </select>
365
                </li>
366
                <li>
367
                    <label for="show_in_pulldown">Show in search pulldown: </label>
368
                    [% IF category.show_in_pulldown %]
369
                        <input type="checkbox" name="show_in_pulldown" id="show_in_pulldown" checked="checked"/>
370
                    [% ELSE %]
371
                        <input type="checkbox" name="show_in_pulldown" id="show_in_pulldown" />
372
                    [% END %]
373
                </li>
374
            </ol>
375
        </fieldset>
376
        <fieldset class="action">
377
            <input type="submit" value="Submit" />
378
            <a href="/cgi-bin/koha/admin/branches.pl" class="cancel">Cancel</a>
379
        </fieldset>
380
    </form>
381
[% END %]
382
383
[% IF op == 'delete_confirm_category' %]
384
    <div class="dialog alert">
385
    <h3>Are you sure you want to delete the group '[% category.codedescription %]' ([% category.categorycode %])?</h3>
386
    <form action="/cgi-bin/koha/admin/branches.pl" method="post">
387
        <input type="hidden" name="op" value="delete_confirmed_category" />
388
        <input type="hidden" name="categorycode" value="[% category.categorycode |html %]" />
389
        <button type="submit" class="approve"><i class="fa fa-fw fa-check"></i> Yes, delete</button>
390
    </form>
391
    <form action="/cgi-bin/koha/admin/branches.pl" method="get">
392
        <button type="submit" class="deny"><i class="fa fa-fw fa-remove"></i> No, do not delete</button>
393
    </form>
394
    </div>
395
[% END %]
267
[% END %]
396
268
397
</div>
269
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt (-8 / +12 lines)
Lines 261-274 Link Here
261
        [% END %]
261
        [% END %]
262
        </select></p>
262
        </select></p>
263
    <!-- <input type="hidden" name="limit" value="branch: MAIN" /> -->
263
    <!-- <input type="hidden" name="limit" value="branch: MAIN" /> -->
264
        [% IF ( searchdomainloop ) %]
264
        [% IF search_groups %]
265
    <p>OR</p> <!-- should addjs to grey out group pulldown if a library is selected. -->
265
            <p>OR</p> <!-- should addjs to grey out group pulldown if a library is selected. -->
266
        <p><label for="categoryloop">Groups of libraries: </label><select name="multibranchlimit" id="categoryloop">
266
267
        <option value=""> -- none -- </option>
267
            <p>
268
        [% FOREACH searchdomainloo IN searchdomainloop %]
268
                <label for="categoryloop">Groups of libraries: </label>
269
        <option value="[% searchdomainloo.categorycode %]">[% searchdomainloo.categoryname %]</option>
269
                <select name="multibranchlimit" id="categoryloop">
270
        [% END %]
270
                    <option value=""> -- none -- </option>
271
        </select></p>
271
                    [% FOREACH sg IN search_groups %]
272
                        <option value="[% sg.id %]">[% sg.title %]</option>
273
                    [% END %]
274
                </select>
275
            </p>
272
    [% END %]
276
    [% END %]
273
</fieldset>
277
</fieldset>
274
    </fieldset>
278
    </fieldset>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc (-6 / +6 lines)
Lines 227-245 Link Here
227
                                    <div class="input-append">
227
                                    <div class="input-append">
228
                                        <select name="branch_group_limit" id="select_library">
228
                                        <select name="branch_group_limit" id="select_library">
229
                                            <option value="">All libraries</option>
229
                                            <option value="">All libraries</option>
230
                                            [% IF BranchCategoriesLoop %]<optgroup label="Libraries">[% END %]
230
                                            [% IF LibrarySearchGroups %]<optgroup label="Libraries">[% END %]
231
                                                [% FOREACH BranchesLoo IN BranchesLoop %]
231
                                                [% FOREACH BranchesLoo IN BranchesLoop %]
232
                                                    [% IF ( BranchesLoo.selected ) %]<option selected="selected" value="branch:[% BranchesLoo.value %]">[% BranchesLoo.branchname %]</option>
232
                                                    [% IF ( BranchesLoo.selected ) %]<option selected="selected" value="branch:[% BranchesLoo.value %]">[% BranchesLoo.branchname %]</option>
233
                                                    [% ELSE %]<option value="branch:[% BranchesLoo.value %]">[% BranchesLoo.branchname %]</option>[% END %]
233
                                                    [% ELSE %]<option value="branch:[% BranchesLoo.value %]">[% BranchesLoo.branchname %]</option>[% END %]
234
                                                [% END %]
234
                                                [% END %]
235
                                            [% IF BranchCategoriesLoop %]
235
                                            [% IF LibrarySearchGroups %]
236
                                                </optgroup>
236
                                                </optgroup>
237
                                                <optgroup label="Groups">
237
                                                <optgroup label="Groups">
238
                                                    [% FOREACH bc IN BranchCategoriesLoop %]
238
                                                    [% FOREACH lsg IN LibrarySearchGroups %]
239
                                                        [% IF bc.categorycode == opac_name %]
239
                                                        [% IF lsg.id == opac_name %]
240
                                                            <option selected="selected" value="multibranchlimit-[% bc.categorycode %]">[% bc.categoryname %]</option>
240
                                                            <option selected="selected" value="multibranchlimit-[% lsg.id %]">[% lsg.title %]</option>
241
                                                        [% ELSE %]
241
                                                        [% ELSE %]
242
                                                            <option value="multibranchlimit-[% bc.categorycode %]">[% bc.categoryname %]</option>
242
                                                            <option value="multibranchlimit-[% lsg.id %]">[% lsg.title %]</option>
243
                                                        [% END # / bc.selected %]
243
                                                        [% END # / bc.selected %]
244
                                                    [% END %]
244
                                                    [% END %]
245
                                                </optgroup>
245
                                                </optgroup>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt (-3 / +3 lines)
Lines 222-234 Link Here
222
                                        [% END %]
222
                                        [% END %]
223
                                    [% END %]
223
                                    [% END %]
224
                                    </select>
224
                                    </select>
225
                                    [% IF ( searchdomainloop ) %]
225
                                    [% IF search_groups %]
226
                                        <p>OR</p>
226
                                        <p>OR</p>
227
                                        <label for="categoryloop">Groups of libraries</label>
227
                                        <label for="categoryloop">Groups of libraries</label>
228
                                        <select name="multibranchlimit" id="categoryloop">
228
                                        <select name="multibranchlimit" id="categoryloop">
229
                                            <option value=""> -- none -- </option>
229
                                            <option value=""> -- none -- </option>
230
                                            [% FOREACH searchdomainloo IN searchdomainloop %]
230
                                            [% FOREACH sg IN search_groups %]
231
                                                <option value="[% searchdomainloo.categorycode %]">[% searchdomainloo.categoryname %]</option>
231
                                                <option value="[% sg.id %]">[% sg.title %]</option>
232
                                            [% END %]
232
                                            [% END %]
233
                                        </select>
233
                                        </select>
234
                                    [% END %]
234
                                    [% END %]
(-)a/opac/opac-search.pl (-5 / +6 lines)
Lines 54-60 use C4::SocialData; Link Here
54
use C4::Ratings;
54
use C4::Ratings;
55
use C4::External::OverDrive;
55
use C4::External::OverDrive;
56
56
57
use Koha::LibraryCategories;
57
use Koha::Library::Groups;
58
58
59
use POSIX qw(ceil floor strftime);
59
use POSIX qw(ceil floor strftime);
60
use URI::Escape;
60
use URI::Escape;
Lines 214-221 if ($cgi->cookie("search_path_code")) { Link Here
214
}
214
}
215
215
216
my $branches = GetBranches();   # used later in *getRecords, probably should be internalized by those functions after caching in C4::Branch is established
216
my $branches = GetBranches();   # used later in *getRecords, probably should be internalized by those functions after caching in C4::Branch is established
217
my $library_categories = Koha::LibraryCategories->search( { categorytype => 'searchdomain' }, { order_by => [ 'categorytype', 'categorycode' ] } );
217
218
$template->param( searchdomainloop => $library_categories );
218
my $search_groups = Koha::Library::Groups->get_search_groups();
219
$template->param( search_groups => $search_groups );
219
220
220
# load the language limits (for search)
221
# load the language limits (for search)
221
my $languages_limit_loop = getLanguages($lang, 1);
222
my $languages_limit_loop = getLanguages($lang, 1);
Lines 491-498 if (@searchCategories > 0) { Link Here
491
@limits = map { uri_unescape($_) } @limits;
492
@limits = map { uri_unescape($_) } @limits;
492
493
493
if($params->{'multibranchlimit'}) {
494
if($params->{'multibranchlimit'}) {
494
    my $library_category = Koha::LibraryCategories->find( $params->{multibranchlimit} );
495
    my $search_group = Koha::Library::Groups->find( $params->{multibranchlimit} );
495
    my @libraries = $library_category->libraries;
496
    my @libraries = $search_group->libraries;
496
    my $multibranch = '('.join( " or ", map { 'branch: ' . $_->id } @libraries ) .')';
497
    my $multibranch = '('.join( " or ", map { 'branch: ' . $_->id } @libraries ) .')';
497
    push @limits, $multibranch if ($multibranch ne  '()');
498
    push @limits, $multibranch if ($multibranch ne  '()');
498
}
499
}
(-)a/t/db_dependent/Branch.t (-60 / +1 lines)
Lines 21-33 use Modern::Perl; Link Here
21
use C4::Context;
21
use C4::Context;
22
use Data::Dumper;
22
use Data::Dumper;
23
23
24
use Test::More tests => 17;
24
use Test::More tests => 10;
25
25
26
use C4::Branch;
26
use C4::Branch;
27
use Koha::Database;
27
use Koha::Database;
28
use Koha::Library;
28
use Koha::Library;
29
use Koha::Libraries;
29
use Koha::Libraries;
30
use Koha::LibraryCategories;
31
30
32
BEGIN {
31
BEGIN {
33
    use FindBin;
32
    use FindBin;
Lines 49-57 $schema->storage->txn_begin; Link Here
49
48
50
my $dbh = C4::Context->dbh;
49
my $dbh = C4::Context->dbh;
51
50
52
# clear the slate
53
$dbh->do('DELETE FROM branchcategories');
54
55
# Start test
51
# Start test
56
52
57
my $count = Koha::Libraries->search->count;
53
my $count = Koha::Libraries->search->count;
Lines 148-208 Koha::Libraries->find($b1->{branchcode})->set($b1)->store; Link Here
148
is( Koha::Libraries->search->count, $count + 1,
144
is( Koha::Libraries->search->count, $count + 1,
149
    "A branch has been modified, no new branch added" );
145
    "A branch has been modified, no new branch added" );
150
146
151
#Test categories
152
my $count_cat  = Koha::LibraryCategories->search->count;
153
154
my $cat1 = {
155
    categorycode     => 'CAT1',
156
    categoryname     => 'catname1',
157
    codedescription  => 'catdesc1',
158
    categorytype     => 'cattype1',
159
    show_in_pulldown => 1
160
};
161
my $cat2 = {
162
    categorycode     => 'CAT2',
163
    categoryname     => 'catname2',
164
    categorytype     => 'catype2',
165
    codedescription  => 'catdesc2',
166
    show_in_pulldown => 1
167
};
168
169
my %new_category = (
170
    categorycode     => 'LIBCATCODE',
171
    categoryname     => 'library category name',
172
    codedescription  => 'library category code description',
173
    categorytype     => 'searchdomain',
174
    show_in_pulldown => 1,
175
);
176
177
Koha::LibraryCategory->new(\%new_category)->store;
178
Koha::LibraryCategory->new($cat1)->store;
179
Koha::LibraryCategory->new($cat2)->store;
180
181
my $categories = Koha::LibraryCategories->search;
182
is( $categories->count, $count_cat + 3, "Two categories added" );
183
184
my $del = Koha::LibraryCategories->find( $cat2->{categorycode} )->delete;
185
is( $del, 1, 'One row affected' );
186
187
is( Koha::LibraryCategories->search->count, $count_cat + 2, "Category CAT 2 deleted" );
188
189
my $b2_stored = Koha::Library->new($b2)->store;
190
my $CAT1 = Koha::LibraryCategories->find('CAT1');
191
$b2_stored->add_to_categories([$CAT1]);
192
is( Koha::Libraries->search->count, $count + 2, 'BRB added' );
193
194
my $b1info = Koha::Libraries->find( $b1->{branchcode} );
195
is_deeply( $b1info->get_categories->count, 0, 'BRA has no categories' );
196
197
my $b2info = Koha::Libraries->find( $b2->{branchcode} );
198
is_deeply( $b2info->get_categories->count, 1, 'BRB has the category CAT1' );
199
200
Koha::LibraryCategory->new($cat2)->store;
201
is( Koha::LibraryCategories->search->count, $count_cat + 3, "Two categories added" );
202
203
#TODO later: test mybranchine and onlymine
204
# Actually we cannot mock C4::Context->userenv in unit tests
205
206
#Test GetBranchesLoop
147
#Test GetBranchesLoop
207
my $loop = GetBranchesLoop;
148
my $loop = GetBranchesLoop;
208
is( scalar(@$loop), Koha::Libraries->search->count, 'There is the right number of branches' );
149
is( scalar(@$loop), Koha::Libraries->search->count, 'There is the right number of branches' );
(-)a/t/db_dependent/Koha/Libraries.t (-36 / +1 lines)
Lines 19-30 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 9;
22
use Test::More tests => 3;
23
23
24
use Koha::Library;
24
use Koha::Library;
25
use Koha::Libraries;
25
use Koha::Libraries;
26
use Koha::LibraryCategory;
27
use Koha::LibraryCategories;
28
use Koha::Database;
26
use Koha::Database;
29
27
30
use t::lib::TestBuilder;
28
use t::lib::TestBuilder;
Lines 34-40 $schema->storage->txn_begin; Link Here
34
32
35
my $builder = t::lib::TestBuilder->new;
33
my $builder = t::lib::TestBuilder->new;
36
my $nb_of_libraries = Koha::Libraries->search->count;
34
my $nb_of_libraries = Koha::Libraries->search->count;
37
my $nb_of_categories = Koha::LibraryCategories->search->count;
38
my $new_library_1 = Koha::Library->new({
35
my $new_library_1 = Koha::Library->new({
39
    branchcode => 'my_bc_1',
36
    branchcode => 'my_bc_1',
40
    branchname => 'my_branchname_1',
37
    branchname => 'my_branchname_1',
Lines 45-90 my $new_library_2 = Koha::Library->new({ Link Here
45
    branchname => 'my_branchname_2',
42
    branchname => 'my_branchname_2',
46
    branchnotes => 'my_branchnotes_2',
43
    branchnotes => 'my_branchnotes_2',
47
})->store;
44
})->store;
48
my $new_category_1 = Koha::LibraryCategory->new({
49
    categorycode => 'my_cc_1',
50
    categoryname => 'my_categoryname_1',
51
    codedescription => 'my_codedescription_1',
52
    categorytype => 'properties',
53
} )->store;
54
my $new_category_2 = Koha::LibraryCategory->new( {
55
          categorycode    => 'my_cc_2',
56
          categoryname    => 'my_categoryname_2',
57
          codedescription => 'my_codedescription_2',
58
          categorytype    => 'searchdomain',
59
} )->store;
60
my $new_category_3 = Koha::LibraryCategory->new( {
61
          categorycode    => 'my_cc_3',
62
          categoryname    => 'my_categoryname_3',
63
          codedescription => 'my_codedescription_3',
64
          categorytype    => 'searchdomain',
65
} )->store;
66
45
67
is( Koha::Libraries->search->count,         $nb_of_libraries + 2,  'The 2 libraries should have been added' );
46
is( Koha::Libraries->search->count,         $nb_of_libraries + 2,  'The 2 libraries should have been added' );
68
is( Koha::LibraryCategories->search->count, $nb_of_categories + 3, 'The 3 library categories should have been added' );
69
47
70
$new_library_1->add_to_categories( [$new_category_1] );
71
$new_library_2->add_to_categories( [$new_category_2] );
72
my $retrieved_library_1 = Koha::Libraries->find( $new_library_1->branchcode );
48
my $retrieved_library_1 = Koha::Libraries->find( $new_library_1->branchcode );
73
is( $retrieved_library_1->branchname, $new_library_1->branchname, 'Find a library by branchcode should return the correct library' );
49
is( $retrieved_library_1->branchname, $new_library_1->branchname, 'Find a library by branchcode should return the correct library' );
74
is( Koha::Libraries->find( $new_library_1->branchcode )->get_categories->count, 1, '1 library should have been linked to the category 1' );
75
76
$retrieved_library_1->update_categories( [ $new_category_2, $new_category_3 ] );
77
is( Koha::Libraries->find( $new_library_1->branchcode )->get_categories->count, 2, '2 libraries should have been linked to the category 2' );
78
79
my $retrieved_category_2 = Koha::LibraryCategories->find( $new_category_2->categorycode );
80
is( $retrieved_category_2->libraries->count, 2, '2 libraries should have been linked to the category_2' );
81
is( $retrieved_category_2->categorycode, uc('my_cc_2'), 'The Koha::LibraryCategory constructor should have upercased the categorycode' );
82
50
83
$retrieved_library_1->delete;
51
$retrieved_library_1->delete;
84
is( Koha::Libraries->search->count, $nb_of_libraries + 1, 'Delete should have deleted the library' );
52
is( Koha::Libraries->search->count, $nb_of_libraries + 1, 'Delete should have deleted the library' );
85
53
86
$retrieved_category_2->delete;
87
is( Koha::LibraryCategories->search->count, $nb_of_categories + 2, 'Delete should have deleted the library category' );
88
89
$schema->storage->txn_rollback;
54
$schema->storage->txn_rollback;
90
1;
55
1;
(-)a/t/db_dependent/RotatingCollections.t (-2 lines)
Lines 57-63 $dbh->do(q|DELETE FROM collections_tracking |); Link Here
57
$dbh->do(q|DELETE FROM collections |);
57
$dbh->do(q|DELETE FROM collections |);
58
$dbh->do(q|DELETE FROM branches |);
58
$dbh->do(q|DELETE FROM branches |);
59
$dbh->do(q|DELETE FROM categories|);
59
$dbh->do(q|DELETE FROM categories|);
60
$dbh->do(q|DELETE FROM branchcategories|);
61
60
62
#Test CreateCollection
61
#Test CreateCollection
63
my $collections     = GetCollections();
62
my $collections     = GetCollections();
64
- 

Return to bug 16735