Bugzilla – Attachment 36027 Details for
Bug 10276
Extend IndependentBranches to support groups of libraries
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 10276 - Extend IndependentBranches to support groups of libraries
Bug-10276---Extend-IndependentBranches-to-support-.patch (text/plain), 66.90 KB, created by
Kyle M Hall (khall)
on 2015-02-19 12:26:53 UTC
(
hide
)
Description:
Bug 10276 - Extend IndependentBranches to support groups of libraries
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2015-02-19 12:26:53 UTC
Size:
66.90 KB
patch
obsolete
>From 5c05dd0a380774d0c11a6156d8d27ca2f93b511f Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Thu, 9 May 2013 10:55:55 -0400 >Subject: [PATCH] Bug 10276 - Extend IndependentBranches to support groups of libraries > >This patch adds the ability to have independent library groups. To >enable this feature, enable the IndependentBranches system preference. >If no libraries are in any independent library groups, >IndependentBranches will behave as it always have. If a library is >part of an independent library group with one or more libraries, that >library will be able to access and modify patrons and items from any >library in that group. > >Let's say we have 3 groups: >Group1: > LibA > LibB > LibC >Group1: > LibD > LibE > LibF >Group3: > LibG > LibH > LibA > >Note how LibA is in two groups ( Group1 and Group3 ). With this >configuration, if IndependentBranches is enabled, libraries will be able >to access and edit patrons and items in the following configuration: >LibA => LibB, LibC, LibG, LibH >LibB => LibA, LibC >LibC => LibA, LibB >LibD => LibE, LibF >LibF => LibD, LibE >LibG => LibH, LibA >LibH => LibG, LibA > >Furthermore, let us assume there is a library LibI, which does not >belong to any group. That library will only be able to view and edit >patrons and items from it's own library. > >Imagine a library consortium consisting of multiple library systems. >This feature would allow a consortium to group libraries by system such >that those systems could work independently from one another on a single >installation. > >Test Plan: >1) Apply this patch >2) Run updatedatabase.pl >3) Enable IndependentBranches >4) Test independent branches, no changes should be noted >5) Navigate to admin/branches.pl >6) Create a new Independent library group >7) Add your library and some other libraries to that group >8) Re-test IndependentBranches, everything should work as previously, > but instead of being limited to just your library, you should have > access to everything within your library group. > Example: Try to edit an item. If the item is owned by a library in > your group, you should be able to edit it. > >Signed-off-by: Joel Sasse <jsasse@plumcreeklibrary.net> >Signed-off-by: Mark Tompsett <mtompset@hotmail.com> >--- > C4/Acquisition.pm | 87 ++++++++- > C4/Branch.pm | 108 ++++++++++- > C4/Circulation.pm | 21 ++- > C4/Items.pm | 31 ++- > C4/Letters.pm | 1 + > C4/Members.pm | 112 ++++++----- > C4/Serials.pm | 109 +++++++++-- > C4/Suggestions.pm | 51 +++-- > acqui/basket.pl | 22 ++- > admin/branches.pl | 52 ++---- > catalogue/moredetail.pl | 15 +- > cataloguing/additem.pl | 13 +- > circ/circulation-home.pl | 7 +- > circ/pendingreserves.pl | 5 +- > circ/reserveratios.pl | 6 +- > installer/data/mysql/kohastructure.sql | 2 +- > installer/data/mysql/updatedatabase.pl | 18 ++- > .../prog/en/modules/admin/branches.tt | 208 +++++++++++++------- > members/deletemem.pl | 14 +- > t/db_dependent/Branch.t | 76 +++++++- > 20 files changed, 715 insertions(+), 243 deletions(-) > >diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm >index 15f69c0..cefd9b8 100644 >--- a/C4/Acquisition.pm >+++ b/C4/Acquisition.pm >@@ -33,6 +33,7 @@ use Koha::DateUtils qw( dt_from_string output_pref ); > use Koha::Acquisition::Order; > use Koha::Acquisition::Bookseller; > use Koha::Number::Price; >+use C4::Branch qw(GetIndependentGroupModificationRights); > > use Time::localtime; > use HTML::Entities; >@@ -1893,6 +1894,77 @@ sub TransferOrder { > > =head2 FUNCTIONS ABOUT PARCELS > >+=cut >+ >+#------------------------------------------------------------# >+ >+=head3 GetParcel >+ >+ @results = &GetParcel($booksellerid, $code, $date); >+ >+Looks up all of the received items from the supplier with the given >+bookseller ID at the given date, for the given code (bookseller Invoice number). Ignores cancelled and completed orders. >+ >+C<@results> is an array of references-to-hash. The keys of each element are fields from >+the aqorders, biblio, and biblioitems tables of the Koha database. >+ >+C<@results> is sorted alphabetically by book title. >+ >+=cut >+ >+sub GetParcel { >+ #gets all orders from a certain supplier, orders them alphabetically >+ my ( $supplierid, $code, $datereceived ) = @_; >+ my $dbh = C4::Context->dbh; >+ my @results = (); >+ $code .= '%' >+ if $code; # add % if we search on a given code (otherwise, let him empty) >+ my $strsth =" >+ SELECT authorisedby, >+ creationdate, >+ aqbasket.basketno, >+ closedate,surname, >+ firstname, >+ aqorders.biblionumber, >+ aqorders.ordernumber, >+ aqorders.parent_ordernumber, >+ aqorders.quantity, >+ aqorders.quantityreceived, >+ aqorders.unitprice, >+ aqorders.listprice, >+ aqorders.rrp, >+ aqorders.ecost, >+ aqorders.gstrate, >+ biblio.title >+ FROM aqorders >+ LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno >+ LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber >+ LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber >+ LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid >+ WHERE >+ aqbasket.booksellerid = ? >+ AND aqinvoices.invoicenumber LIKE ? >+ AND aqorders.datereceived = ? "; >+ >+ my @query_params = ( $supplierid, $code, $datereceived ); >+ if ( C4::Context->preference("IndependentBranches") ) { >+ unless ( C4::Context->IsSuperLibrarian() ) { >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $strsth .= " AND ( borrowers.branchcode IN ( $branches ) OR borrowers.branchcode = '')"; >+ } >+ } >+ $strsth .= " ORDER BY aqbasket.basketno"; >+ my $result_set = $dbh->selectall_arrayref( >+ $strsth, >+ { Slice => {} }, >+ @query_params); >+ >+ return @{$result_set}; >+} >+ >+#------------------------------------------------------------# >+ > =head3 GetParcels > > $results = &GetParcels($bookseller, $order, $code, $datefrom, $dateto); >@@ -2094,8 +2166,8 @@ sub GetLateOrders { > } > if (C4::Context->preference("IndependentBranches") > && !C4::Context->IsSuperLibrarian() ) { >- $from .= ' AND borrowers.branchcode LIKE ? '; >- push @query_params, C4::Context->userenv->{branch}; >+ my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $from .= qq{ AND borrowers.branchcode IN ( $branches ) }; > } > $from .= " AND orderstatus <> 'cancelled' "; > my $query = "$select $from $having\nORDER BY latesince, basketno, borrowers.branchcode, supplier"; >@@ -2319,11 +2391,12 @@ sub GetHistory { > } > > >- if ( C4::Context->preference("IndependentBranches") ) { >- unless ( C4::Context->IsSuperLibrarian() ) { >- $query .= " AND (borrowers.branchcode = ? OR borrowers.branchcode ='' ) "; >- push @query_params, C4::Context->userenv->{branch}; >- } >+ if ( C4::Context->preference("IndependentBranches") >+ && !C4::Context->IsSuperLibrarian() ) >+ { >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $query .= qq{ AND ( borrowers.branchcode = ? OR borrowers.branchcode IN ( $branches ) ) }; > } > $query .= " ORDER BY id"; > >diff --git a/C4/Branch.pm b/C4/Branch.pm >index ff571dc..764380a 100644 >--- a/C4/Branch.pm >+++ b/C4/Branch.pm >@@ -19,6 +19,7 @@ package C4::Branch; > use strict; > #use warnings; FIXME - Bug 2505 > require Exporter; >+use Carp; > use C4::Context; > > use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); >@@ -42,6 +43,7 @@ BEGIN { > &GetBranchCategories > &GetBranchesInCategory > &ModBranchCategoryInfo >+ &GetIndependentGroupModificationRights > &DelBranch > &DelBranchCategory > &CheckCategoryUnique >@@ -113,9 +115,9 @@ sub GetBranches { > my $sth; > my $query = "SELECT * FROM branches"; > my @bind_parameters; >- if ( $onlymine && C4::Context->userenv && C4::Context->userenv->{branch} ) { >- $query .= ' WHERE branchcode = ? '; >- push @bind_parameters, C4::Context->userenv->{branch}; >+ if ($onlymine && C4::Context->userenv && C4::Context->userenv->{branch}){ >+ my $branches = GetIndependentGroupModificationRights({ stringify => 1 }); >+ $query .= qq{ WHERE branchcode IN ( $branches ) }; > } > $query .= " ORDER BY branchname"; > $sth = $dbh->prepare($query); >@@ -298,7 +300,10 @@ C<$results> is an hashref > > sub GetBranchCategory { > my ($catcode) = @_; >- return unless $catcode; >+ unless ( $catcode ) { >+ carp("No category code passed in!"); >+ return; >+ } > > my $dbh = C4::Context->dbh; > my $sth; >@@ -368,7 +373,7 @@ the categories were already here, and minimally used. > > #TODO manage category types. rename possibly to 'agency domains' ? as borrowergroups are called categories. > sub GetCategoryTypes { >- return ( 'searchdomain','properties'); >+ return ( 'searchdomain','independent_groups'); > } > > =head2 GetBranch >@@ -423,6 +428,99 @@ sub GetBranchesInCategory { > return( \@branches ); > } > >+=head2 GetIndependentGroupModificationRights >+ >+ GetIndependentGroupModificationRights( >+ { >+ branch => $this_branch, >+ for => $other_branch, >+ stringify => 1, >+ } >+ ); >+ >+ Returns a list of branches this branch shares a common >+ independent group with. >+ >+ If 'branch' is not provided, it will be looked up via >+ C4::Context->userenv->{branch}. >+ >+ If 'for' is provided, the lookup is limited to that branch. >+ >+ If called in a list context, returns a list of >+ branchcodes ( including $this_branch ). >+ >+ If called in a scalar context, it returns >+ a count of matching branchcodes. Returns 1 if >+ >+ If stringify param is passed, the return value will >+ be a string of the comma delimited branchcodes. This >+ is useful for "branchcode IN $branchcodes" clauses >+ in SQL queries. >+ >+ $this_branch and $other_branch are equal for efficiency. >+ >+ So you can write: >+ my @branches = GetIndependentGroupModificationRights(); >+ or something like: >+ if ( GetIndependentGroupModificationRights( { for => $other_branch } ) ) { do_stuff(); } >+ >+=cut >+ >+sub GetIndependentGroupModificationRights { >+ my ($params) = @_; >+ >+ my $this_branch = $params->{branch}; >+ my $other_branch = $params->{for}; >+ my $stringify = $params->{stringify}; >+ >+ $this_branch ||= C4::Context->userenv->{branch}; >+ >+ carp("No branch found!") unless ($this_branch); >+ >+ return 1 if ( $this_branch eq $other_branch ); >+ >+ my $sql = q{ >+ SELECT DISTINCT(branchcode) >+ FROM branchrelations >+ JOIN branchcategories USING ( categorycode ) >+ WHERE categorycode IN ( >+ SELECT categorycode >+ FROM branchrelations >+ WHERE branchcode = ? >+ ) >+ AND branchcategories.categorytype = 'independent_group' >+ }; >+ >+ my @params; >+ push( @params, $this_branch ); >+ >+ if ($other_branch) { >+ $sql .= q{ AND branchcode = ? }; >+ push( @params, $other_branch ); >+ } >+ >+ my $dbh = C4::Context->dbh; >+ my @branchcodes = @{ $dbh->selectcol_arrayref( $sql, {}, @params ) }; >+ >+ if ( $stringify ) { >+ if ( @branchcodes ) { >+ return join( ',', map { qq{'$_'} } @branchcodes ); >+ } else { >+ return qq{'$this_branch'}; >+ } >+ } >+ >+ if ( wantarray() ) { >+ if ( @branchcodes ) { >+ return @branchcodes; >+ } else { >+ return $this_branch; >+ } >+ } else { >+ return scalar(@branchcodes); >+ } >+} >+ > =head2 GetBranchInfo > > $results = GetBranchInfo($branchcode); >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index 14dfb0e..1e23f9d 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -911,14 +911,25 @@ sub CanBookBeIssued { > $alerts{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' ); > } > if ( C4::Context->preference("IndependentBranches") ) { >- my $userenv = C4::Context->userenv; > unless ( C4::Context->IsSuperLibrarian() ) { >- if ( $item->{C4::Context->preference("HomeOrHoldingBranch")} ne $userenv->{branch} ){ >+ unless ( >+ GetIndependentGroupModificationRights( >+ { >+ for => $item->{ C4::Context->preference( >+ "HomeOrHoldingBranch") } >+ } >+ ) >+ ) >+ { > $issuingimpossible{ITEMNOTSAMEBRANCH} = 1; >- $issuingimpossible{'itemhomebranch'} = $item->{C4::Context->preference("HomeOrHoldingBranch")}; >+ $issuingimpossible{'itemhomebranch'} = >+ $item->{ C4::Context->preference("HomeOrHoldingBranch") }; > } >- $needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} ) >- if ( $borrower->{'branchcode'} ne $userenv->{branch} ); >+ >+ $needsconfirmation{BORRNOTSAMEBRANCH} = >+ GetBranchName( $borrower->{'branchcode'} ) >+ if ( >+ $borrower->{'branchcode'} ne C4::Context->userenv->{branch} ); > } > } > # >diff --git a/C4/Items.pm b/C4/Items.pm >index a225b49..c8adaf9 100644 >--- a/C4/Items.pm >+++ b/C4/Items.pm >@@ -35,6 +35,7 @@ use DateTime::Format::MySQL; > use Data::Dumper; # used as part of logging item record changes, not just for > # debugging; so please don't remove this > use Koha::DateUtils qw/dt_from_string/; >+use C4::Branch qw/GetIndependentGroupModificationRights/; > > use Koha::Database; > >@@ -1333,10 +1334,13 @@ sub GetItemsInfo { > my $serial; > > my $userenv = C4::Context->userenv; >- my $want_not_same_branch = C4::Context->preference("IndependentBranches") && !C4::Context->IsSuperLibrarian(); > while ( my $data = $sth->fetchrow_hashref ) { >- if ( $data->{borrowernumber} && $want_not_same_branch) { >- $data->{'NOTSAMEBRANCH'} = $data->{'bcode'} ne $userenv->{branch}; >+ if ( C4::Context->preference("IndependentBranches") && $userenv ) { >+ unless ( C4::Context->IsSuperLibrarian() >+ || GetIndependentGroupModificationRights( { for => $data->{'bcode'} } ) ) >+ { >+ $data->{'NOTSAMEBRANCH'} = $data->{'bcode'} ne $userenv->{branch}; >+ } > } > > $serial ||= $data->{'serial'}; >@@ -2279,12 +2283,18 @@ sub DelItemCheck { > > my $item = GetItem($itemnumber); > >- if ($onloan){ >- $error = "book_on_loan" >+ if ($onloan) { >+ $error = "book_on_loan"; > } >- elsif ( !C4::Context->IsSuperLibrarian() >- and C4::Context->preference("IndependentBranches") >- and ( C4::Context->userenv->{branch} ne $item->{'homebranch'} ) ) >+ elsif ( >+ !C4::Context->IsSuperLibrarian() >+ && C4::Context->preference("IndependentBranches") >+ && !GetIndependentGroupModificationRights( >+ { >+ for => $item->{ C4::Context->preference("HomeOrHoldingBranch") } >+ } >+ ) >+ ) > { > $error = "not_same_branch"; > } >@@ -2959,8 +2969,9 @@ sub PrepareItemrecordDisplay { > if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) { > if ( ( C4::Context->preference("IndependentBranches") ) > && !C4::Context->IsSuperLibrarian() ) { >- my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname" ); >- $sth->execute( C4::Context->userenv->{branch} ); >+ my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); >+ my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode IN ( $branches ) ORDER BY branchname" ); >+ $sth->execute(); > push @authorised_values, "" > unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); > while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) { >diff --git a/C4/Letters.pm b/C4/Letters.pm >index a11c862..91c579b 100644 >--- a/C4/Letters.pm >+++ b/C4/Letters.pm >@@ -209,6 +209,7 @@ sub getletter { > my ( $module, $code, $branchcode, $message_transport_type ) = @_; > $message_transport_type ||= 'email'; > >+ $branchcode ||= q{}; > > if ( C4::Context->preference('IndependentBranches') > and $branchcode >diff --git a/C4/Members.pm b/C4/Members.pm >index 4fb845d..d09b42c 100644 >--- a/C4/Members.pm >+++ b/C4/Members.pm >@@ -25,6 +25,7 @@ use strict; > use C4::Context; > use C4::Dates qw(format_date_in_iso format_date); > use String::Random qw( random_string ); >+use Clone qw(clone); > use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/; > use C4::Log; # logaction > use C4::Overdues; >@@ -44,6 +45,7 @@ use Text::Unaccent qw( unac_string ); > use Koha::AuthUtils qw(hash_password); > use Koha::Database; > use Module::Load; >+use C4::Branch qw( GetIndependentGroupModificationRights ); > if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { > load Koha::NorwegianPatronDB, qw( NLUpdateHashedPIN NLEncryptPIN NLSync ); > } >@@ -261,23 +263,19 @@ sub Search { > # $showallbranches was not used at the time SearchMember() was mainstreamed into Search(). > # Mentioning for the reference > >- if ( C4::Context->preference("IndependentBranches") ) { # && !$showallbranches){ >- if ( my $userenv = C4::Context->userenv ) { >- my $branch = $userenv->{'branch'}; >- if ( !C4::Context->IsSuperLibrarian() && $branch ){ >- if (my $fr = ref $filter) { >- if ( $fr eq "HASH" ) { >- $filter->{branchcode} = $branch; >- } >- else { >- foreach (@$filter) { >- $_ = { '' => $_ } unless ref $_; >- $_->{branchcode} = $branch; >- } >- } >+ if ( C4::Context->preference("IndependentBranches") ) { >+ unless ( C4::Context->IsSuperLibrarian() ) { >+ $filter = clone($filter); # Modify a copy only >+ my @branches = GetIndependentGroupModificationRights(); >+ if ( my $fr = ref $filter ) { >+ if ( $fr eq "HASH" ) { >+ $filter->{branchcode} = \@branches; > } > else { >- $filter = { '' => $filter, branchcode => $branch }; >+ foreach (@$filter) { >+ $_ = { '' => $_ } unless ref $_; >+ $_->{branchcode} = \@branches; >+ } > } > } > } >@@ -1411,6 +1409,12 @@ sub checkuniquemember { > ($dateofbirth) ? > "SELECT borrowernumber,categorycode FROM borrowers WHERE surname=? and firstname=? and dateofbirth=?" : > "SELECT borrowernumber,categorycode FROM borrowers WHERE surname=? and firstname=?"; >+ >+ if ( C4::Context->preference('IndependentBranches') ) { >+ my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $request .= " AND branchcode IN ( $branches )"; >+ } >+ > my $sth = $dbh->prepare($request); > if ($collectivity) { > $sth->execute( uc($surname) ); >@@ -2102,13 +2106,14 @@ sub GetBorrowersToExpunge { > my $filterdate = $params->{'not_borrowered_since'}; > my $filterexpiry = $params->{'expired_before'}; > my $filtercategory = $params->{'category_code'}; >- my $filterbranch = $params->{'branchcode'} || >- ((C4::Context->preference('IndependentBranches') >- && C4::Context->userenv >- && !C4::Context->IsSuperLibrarian() >- && C4::Context->userenv->{branch}) >- ? C4::Context->userenv->{branch} >- : ""); >+ my $filterbranch = $params->{'branchcode'}; >+ my @filterbranches = >+ ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && !C4::Context->IsSuperLibrarian() >+ && C4::Context->userenv->{branch} ) >+ ? GetIndependentGroupModificationRights() >+ : ($filterbranch); > > my $dbh = C4::Context->dbh; > my $query = " >@@ -2123,9 +2128,10 @@ sub GetBorrowersToExpunge { > AND borrowernumber NOT IN (SELECT guarantorid FROM borrowers WHERE guarantorid IS NOT NULL AND guarantorid <> 0) > "; > my @query_params; >- if ( $filterbranch && $filterbranch ne "" ) { >- $query.= " AND borrowers.branchcode = ? "; >- push( @query_params, $filterbranch ); >+ if ( @filterbranches ) { >+ my $placeholders = join( ',', ('?') x @filterbranches ); >+ $query.= " AND borrowers.branchcode IN ( $placeholders )"; >+ push( @query_params, @filterbranches ); > } > if ( $filterexpiry ) { > $query .= " AND dateexpiry < ? "; >@@ -2168,13 +2174,16 @@ I<$result> is a ref to an array which all elements are a hasref. > =cut > > sub GetBorrowersWhoHaveNeverBorrowed { >- my $filterbranch = shift || >- ((C4::Context->preference('IndependentBranches') >- && C4::Context->userenv >- && !C4::Context->IsSuperLibrarian() >- && C4::Context->userenv->{branch}) >- ? C4::Context->userenv->{branch} >- : ""); >+ my $filterbranch = shift; >+ >+ my @filterbranches = >+ ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && !C4::Context->IsSuperLibrarian() >+ && C4::Context->userenv->{branch} ) >+ ? GetIndependentGroupModificationRights() >+ : ($filterbranch); >+ > my $dbh = C4::Context->dbh; > my $query = " > SELECT borrowers.borrowernumber,max(timestamp) as latestissue >@@ -2182,10 +2191,12 @@ sub GetBorrowersWhoHaveNeverBorrowed { > LEFT JOIN issues ON borrowers.borrowernumber = issues.borrowernumber > WHERE issues.borrowernumber IS NULL > "; >+ > my @query_params; >- if ($filterbranch && $filterbranch ne ""){ >- $query.=" AND borrowers.branchcode= ?"; >- push @query_params,$filterbranch; >+ if (@filterbranches) { >+ my $placeholders = join( ',', ('?') x @filterbranches ); >+ $query .= " AND borrowers.branchcode IN ( $placeholders ) "; >+ push( @query_params, @filterbranches ); > } > warn $query if $debug; > >@@ -2218,25 +2229,32 @@ This hashref is containt the number of time this borrowers has borrowed before I > sub GetBorrowersWithIssuesHistoryOlderThan { > my $dbh = C4::Context->dbh; > my $date = shift ||POSIX::strftime("%Y-%m-%d",localtime()); >- my $filterbranch = shift || >- ((C4::Context->preference('IndependentBranches') >- && C4::Context->userenv >- && !C4::Context->IsSuperLibrarian() >- && C4::Context->userenv->{branch}) >- ? C4::Context->userenv->{branch} >- : ""); >+ my $filterbranch = shift; >+ >+ my @filterbranches = >+ ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && !C4::Context->IsSuperLibrarian() >+ && C4::Context->userenv->{branch} ) >+ ? GetIndependentGroupModificationRights() >+ : ($filterbranch); >+ > my $query = " > SELECT count(borrowernumber) as n,borrowernumber > FROM old_issues > WHERE returndate < ? > AND borrowernumber IS NOT NULL > "; >+ > my @query_params; >- push @query_params, $date; >- if ($filterbranch){ >- $query.=" AND branchcode = ?"; >- push @query_params, $filterbranch; >- } >+ push( @query_params, $date ); >+ >+ if (@filterbranches) { >+ my $placeholders = join( ',', ('?') x @filterbranches ); >+ $query .= " AND branchcode IN ( $placeholders ) "; >+ push( @query_params, @filterbranches ); >+ } >+ > $query.=" GROUP BY borrowernumber "; > warn $query if $debug; > my $sth = $dbh->prepare($query); >diff --git a/C4/Serials.pm b/C4/Serials.pm >index 49325cb..6a5638e 100644 >--- a/C4/Serials.pm >+++ b/C4/Serials.pm >@@ -31,6 +31,7 @@ use C4::Log; # logaction > use C4::Debug; > use C4::Serials::Frequency; > use C4::Serials::Numberpattern; >+use C4::Branch qw(GetIndependentGroupModificationRights); > > use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); > >@@ -173,7 +174,22 @@ sub GetSerialInformation { > my ($serialid) = @_; > my $dbh = C4::Context->dbh; > my $query = qq| >- SELECT serial.*, serial.notes as sernotes, serial.status as serstatus,subscription.*,subscription.subscriptionid as subsid >+ SELECT serial.*, >+ serial.notes as sernotes, >+ serial.status as serstatus, >+ subscription.*, >+ subscription.subscriptionid as subsid >+ |; >+ if ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && C4::Context->userenv->{'flags'} % 2 != 1 >+ && C4::Context->userenv->{'branch'} ) { >+ my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $query .= qq| >+ , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit >+ |; >+ } >+ $query .= qq| > FROM serial LEFT JOIN subscription ON subscription.subscriptionid=serial.subscriptionid > WHERE serialid = ? > |; >@@ -276,18 +292,35 @@ subscription, subscriptionhistory, aqbooksellers.name, biblio.title > sub GetSubscription { > my ($subscriptionid) = @_; > my $dbh = C4::Context->dbh; >- my $query = qq( >+ >+ my $query = qq| > SELECT subscription.*, > subscriptionhistory.*, > aqbooksellers.name AS aqbooksellername, > biblio.title AS bibliotitle, > subscription.biblionumber as bibnum >+ |; >+ >+ if ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && C4::Context->userenv->{'flags'} % 2 != 1 >+ && C4::Context->userenv->{'branch'} ) >+ { >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ >+ $query .= qq| >+ , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit >+ |; >+ } >+ >+ $query .= qq| > FROM subscription > LEFT JOIN subscriptionhistory ON subscription.subscriptionid=subscriptionhistory.subscriptionid > LEFT JOIN aqbooksellers ON subscription.aqbooksellerid=aqbooksellers.id > LEFT JOIN biblio ON biblio.biblionumber=subscription.biblionumber > WHERE subscription.subscriptionid = ? >- ); >+ |; > > $debug and warn "query : $query\nsubsid :$subscriptionid"; > my $sth = $dbh->prepare($query); >@@ -310,8 +343,10 @@ sub GetFullSubscription { > return unless ($subscriptionid); > > my $dbh = C4::Context->dbh; >- my $query = qq| >- SELECT serial.serialid, >+ >+ my $query = qq| >+ SELECT >+ serial.serialid, > serial.serialseq, > serial.planneddate, > serial.publisheddate, >@@ -322,6 +357,22 @@ sub GetFullSubscription { > biblio.title as bibliotitle, > subscription.branchcode AS branchcode, > subscription.subscriptionid AS subscriptionid >+ |; >+ >+ if ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && C4::Context->userenv->{'flags'} % 2 != 1 >+ && C4::Context->userenv->{'branch'} ) >+ { >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ >+ $query .= qq| >+ , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit >+ |; >+ } >+ >+ $query .= qq| > FROM serial > LEFT JOIN subscription ON > (serial.subscriptionid=subscription.subscriptionid ) >@@ -442,6 +493,16 @@ sub GetSubscriptionsFromBiblionumber { > $subs->{ "periodicity" . $subs->{periodicity} } = 1; > $subs->{ "numberpattern" . $subs->{numberpattern} } = 1; > $subs->{ "status" . $subs->{'status'} } = 1; >+ $subs->{'cannotedit'} = ( >+ C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && !C4::Context->IsSuperLibrarian() >+ && C4::Context->userenv->{branch} >+ && $subs->{branchcode} >+ && GetIndependentGroupModificationRights( >+ { for => $subs->{branchcode} } >+ ) >+ ); > > if ( $subs->{enddate} eq '0000-00-00' ) { > $subs->{enddate} = ''; >@@ -466,8 +527,10 @@ sub GetSubscriptionsFromBiblionumber { > sub GetFullSubscriptionsFromBiblionumber { > my ($biblionumber) = @_; > my $dbh = C4::Context->dbh; >- my $query = qq| >- SELECT serial.serialid, >+ >+ my $query = qq| >+ SELECT >+ serial.serialid, > serial.serialseq, > serial.planneddate, > serial.publisheddate, >@@ -477,6 +540,22 @@ sub GetFullSubscriptionsFromBiblionumber { > biblio.title as bibliotitle, > subscription.branchcode AS branchcode, > subscription.subscriptionid AS subscriptionid >+ |; >+ >+ if ( C4::Context->preference('IndependentBranches') >+ && C4::Context->userenv >+ && C4::Context->userenv->{'flags'} != 1 >+ && C4::Context->userenv->{'branch'} ) >+ { >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ >+ $query .= qq| >+ , ( ( subscription.branchcode NOT IN ( $branches ) ) AND subscription.branchcode <> '' AND subscription.branchcode IS NOT NULL ) AS cannotedit >+ |; >+ } >+ >+ $query .= qq| > FROM serial > LEFT JOIN subscription ON > (serial.subscriptionid=subscription.subscriptionid) >@@ -2762,7 +2841,9 @@ sub can_show_subscription { > sub _can_do_on_subscription { > my ( $subscription, $userid, $permission ) = @_; > return 0 unless C4::Context->userenv; >+ > my $flags = C4::Context->userenv->{flags}; >+ > $userid ||= C4::Context->userenv->{'id'}; > > if ( C4::Context->preference('IndependentBranches') ) { >@@ -2771,12 +2852,16 @@ sub _can_do_on_subscription { > or > C4::Auth::haspermission( $userid, { serials => 'superserials' } ) > or ( >- C4::Auth::haspermission( $userid, >- { serials => $permission } ) >+ C4::Auth::haspermission( >+ $userid, { serials => $permission } >+ ) > and ( not defined $subscription->{branchcode} > or $subscription->{branchcode} eq '' > or $subscription->{branchcode} eq > C4::Context->userenv->{'branch'} ) >+ ) >+ or GetIndependentGroupModificationRights( >+ { for => $subscription->{branchcode} } > ); > } > else { >@@ -2784,10 +2869,8 @@ sub _can_do_on_subscription { > if C4::Context->IsSuperLibrarian() > or > C4::Auth::haspermission( $userid, { serials => 'superserials' } ) >- or C4::Auth::haspermission( >- $userid, { serials => $permission } >- ), >- ; >+ or C4::Auth::haspermission( $userid, { serials => $permission } ) >+ ,; > } > return 0; > } >diff --git a/C4/Suggestions.pm b/C4/Suggestions.pm >index f34c942..71c35c1 100644 >--- a/C4/Suggestions.pm >+++ b/C4/Suggestions.pm >@@ -33,6 +33,7 @@ use Koha::DateUtils qw( dt_from_string ); > use List::MoreUtils qw(any); > use C4::Dates qw(format_date_in_iso); > use base qw(Exporter); >+use C4::Branch qw(GetIndependentGroupModificationRights); > > our $VERSION = 3.07.00.049; > our @EXPORT = qw( >@@ -133,18 +134,15 @@ sub SearchSuggestion { > } > > # filter on user branch >- if ( C4::Context->preference('IndependentBranches') ) { >- my $userenv = C4::Context->userenv; >- if ($userenv) { >- if ( !C4::Context->IsSuperLibrarian() && !$suggestion->{branchcode} ) >- { >- push @sql_params, $$userenv{branch}; >- push @query, q{ >- AND (suggestions.branchcode=? OR suggestions.branchcode='') >- }; >- } >- } >- } else { >+ if ( C4::Context->preference('IndependentBranches') >+ && !C4::Context->IsSuperLibrarian() >+ && !$suggestion->{branchcode} ) >+ { >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ push( @query, qq{ AND (suggestions.branchcode IN ( $branches ) OR suggestions.branchcode='') } ); >+ } >+ else { > if ( defined $suggestion->{branchcode} && $suggestion->{branchcode} ) { > unless ( $suggestion->{branchcode} eq '__ANY__' ) { > push @sql_params, $suggestion->{branchcode}; >@@ -342,13 +340,19 @@ sub GetSuggestionByStatus { > > # filter on branch > if ( C4::Context->preference("IndependentBranches") || $branchcode ) { >- my $userenv = C4::Context->userenv; >- if ($userenv) { >- unless ( C4::Context->IsSuperLibrarian() ) { >- push @sql_params, $userenv->{branch}; >- $query .= q{ AND (U1.branchcode = ? OR U1.branchcode ='') }; >- } >+ if ( C4::Context->userenv >+ && C4::Context->preference("IndependentBranches") >+ && !C4::Context->IsSuperLibrarian() ) >+ { >+ >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ >+ $query .= qq{ >+ AND (U1.branchcode IN ( $branches ) OR U1.branchcode ='') >+ }; > } >+ > if ($branchcode) { > push @sql_params, $branchcode; > $query .= q{ AND (U1.branchcode = ? OR U1.branchcode ='') }; >@@ -394,12 +398,19 @@ sub CountSuggestion { > if ( C4::Context->preference("IndependentBranches") > && !C4::Context->IsSuperLibrarian() ) > { >- my $query = q{ >+ my $branches = >+ GetIndependentGroupModificationRights( { stringify => 1 } ); >+ >+ my $query = qq{ > SELECT count(*) > FROM suggestions > LEFT JOIN borrowers ON borrowers.borrowernumber=suggestions.suggestedby > WHERE STATUS=? >- AND (borrowers.branchcode='' OR borrowers.branchcode=?) >+ AND ( >+ borrowers.branchcode IN ( $branches ) >+ OR >+ borrowers.branchcode=? >+ ) > }; > $sth = $dbh->prepare($query); > $sth->execute( $status, $userenv->{branch} ); >diff --git a/acqui/basket.pl b/acqui/basket.pl >index 921c67e..8e82b04 100755 >--- a/acqui/basket.pl >+++ b/acqui/basket.pl >@@ -36,6 +36,7 @@ use C4::Members qw/GetMember/; #needed for permissions checking for changing ba > use C4::Items; > use C4::Suggestions; > use Date::Calc qw/Add_Delta_Days/; >+use C4::Branch qw/GetIndependentGroupModificationRights/; > > =head1 NAME > >@@ -155,10 +156,17 @@ if ( $op eq 'delete_confirm' ) { > if ( C4::Context->preference("IndependentBranches") ) { > my $userenv = C4::Context->userenv; > unless ( C4::Context->IsSuperLibrarian() ) { >- my $validtest = ( $basket->{creationdate} eq '' ) >+ my $validtest = >+ ( $basket->{creationdate} eq '' ) > || ( $userenv->{branch} eq $basket->{branch} ) > || ( $userenv->{branch} eq '' ) >- || ( $basket->{branch} eq '' ); >+ || ( $basket->{branch} eq '' ) >+ || ( >+ GetIndependentGroupModificationRights( >+ { for => $basket->{branch} } >+ ) >+ ); >+ > unless ($validtest) { > print $query->redirect("../mainpage.pl"); > exit 1; >@@ -257,10 +265,16 @@ if ( $op eq 'delete_confirm' ) { > if ( C4::Context->preference("IndependentBranches") ) { > my $userenv = C4::Context->userenv; > unless ( C4::Context->IsSuperLibrarian() ) { >- my $validtest = ( $basket->{creationdate} eq '' ) >+ my $validtest = >+ ( $basket->{creationdate} eq '' ) > || ( $userenv->{branch} eq $basket->{branch} ) > || ( $userenv->{branch} eq '' ) >- || ( $basket->{branch} eq '' ); >+ || ( $basket->{branch} eq '' ) >+ || ( >+ GetIndependentGroupModificationRights( >+ { for => $basket->{branch} } >+ ) >+ ); > unless ($validtest) { > print $query->redirect("../mainpage.pl"); > exit 1; >diff --git a/admin/branches.pl b/admin/branches.pl >index a698a26..ac988c6 100755 >--- a/admin/branches.pl >+++ b/admin/branches.pl >@@ -258,7 +258,7 @@ sub editbranchform { > $oldprinter = $data->{'branchprinter'} || ''; > _branch_to_template($data, $innertemplate); > } >- $innertemplate->param( categoryloop => $catinfo ); >+ $innertemplate->param( branch_categories => $catinfo ); > > foreach my $thisprinter ( keys %$printers ) { > push @printerloop, { >@@ -277,25 +277,8 @@ sub editbranchform { > } > > sub editcatform { >- >- # prepares the edit form... >- my ($categorycode,$innertemplate) = @_; >- # warn "cat : $categorycode"; >- my @cats; >- my $data; >- if ($categorycode) { >- my $data = GetBranchCategory($categorycode); >- $innertemplate->param( >- categorycode => $data->{'categorycode'}, >- categoryname => $data->{'categoryname'}, >- codedescription => $data->{'codedescription'}, >- show_in_pulldown => $data->{'show_in_pulldown'}, >- ); >- } >- for my $ctype (GetCategoryTypes()) { >- push @cats , { type => $ctype , selected => ($data->{'categorytype'} and $data->{'categorytype'} eq $ctype) }; >- } >- $innertemplate->param(categorytype => \@cats); >+ my ( $categorycode, $innertemplate ) = @_; >+ $innertemplate->param( category => GetBranchCategory($categorycode) ); > } > > sub branchinfotable { >@@ -366,25 +349,20 @@ sub branchinfotable { > > push @loop_data, \%row; > } >- my @branchcategories = (); >- for my $ctype ( GetCategoryTypes() ) { >- my $catinfo = GetBranchCategories($ctype); >- my @categories; >- foreach my $cat (@$catinfo) { >- push @categories, { >- categoryname => $cat->{'categoryname'}, >- categorycode => $cat->{'categorycode'}, >- codedescription => $cat->{'codedescription'}, >- categorytype => $cat->{'categorytype'}, >- }; >- } >- push @branchcategories, { categorytype => $ctype , $ctype => 1 , catloop => ( @categories ? \@categories : undef) }; >- } >+ >+ my $catinfo = GetBranchCategories(); >+ my $categories; >+ foreach my $cat (@$catinfo) { >+ $categories->{ $cat->{categorytype} }->{ $cat->{'categorycode'} } = { >+ categoryname => $cat->{'categoryname'}, >+ codedescription => $cat->{'codedescription'}, >+ }; >+ } >+ > $innertemplate->param( >- branches => \@loop_data, >- branchcategories => \@branchcategories >+ branches => \@loop_data, >+ branch_categories => $categories > ); >- > } > > sub _branch_to_template { >diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl >index 39d3c9f..ca48237 100755 >--- a/catalogue/moredetail.pl >+++ b/catalogue/moredetail.pl >@@ -176,13 +176,18 @@ foreach my $item (@items){ > $item->{status_advisory} = 1; > } > >- if (C4::Context->preference("IndependentBranches")) { >- #verifying rights >- my $userenv = C4::Context->userenv(); >- unless (C4::Context->IsSuperLibrarian() or ($userenv->{'branch'} eq $item->{'homebranch'})) { >- $item->{'nomod'}=1; >+ if ( C4::Context->preference("IndependentBranches") ) { >+ unless ( >+ C4::Context->IsSuperLibrarian() >+ || GetIndependentGroupModificationRights( >+ { for => $item->{'homebranch'} } >+ ) >+ ) >+ { >+ $item->{'nomod'} = 1; > } > } >+ > $item->{'homebranchname'} = GetBranchName($item->{'homebranch'}); > $item->{'holdingbranchname'} = GetBranchName($item->{'holdingbranch'}); > if ($item->{'datedue'}) { >diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl >index 9c7fb3f..6c01bd5 100755 >--- a/cataloguing/additem.pl >+++ b/cataloguing/additem.pl >@@ -731,10 +731,19 @@ foreach my $field (@fields) { > || $subfieldvalue; > } > >- if (($field->tag eq $branchtagfield) && ($subfieldcode eq $branchtagsubfield) && C4::Context->preference("IndependentBranches")) { >+ if ( $field->tag eq $branchtagfield >+ && $subfieldcode eq $branchtagsubfield >+ && C4::Context->preference("IndependentBranches") ) >+ { > #verifying rights > my $userenv = C4::Context->userenv(); >- unless (C4::Context->IsSuperLibrarian() or (($userenv->{'branch'} eq $subfieldvalue))){ >+ unless ( >+ C4::Context->IsSuperLibrarian() >+ || GetIndependentGroupModificationRights( >+ { for => $subfieldvalue } >+ ) >+ ) >+ { > $this_row{'nomod'} = 1; > } > } >diff --git a/circ/circulation-home.pl b/circ/circulation-home.pl >index bbb715b..1a78bc5 100755 >--- a/circ/circulation-home.pl >+++ b/circ/circulation-home.pl >@@ -23,6 +23,7 @@ use C4::Auth; > use C4::Output; > use C4::Context; > use C4::Koha; >+use C4::Branch qw/GetIndependentGroupModificationRights/; > > my $query = new CGI; > my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( >@@ -40,8 +41,10 @@ my $fa = getframeworkinfo('FA'); > $template->param( fast_cataloging => 1 ) if (defined $fa); > > # Checking if the transfer page needs to be displayed >-$template->param( display_transfer => 1 ) if ( ($flags->{'superlibrarian'} == 1) || (C4::Context->preference("IndependentBranches") == 0) ); >-$template->{'VARS'}->{'AllowOfflineCirculation'} = C4::Context->preference('AllowOfflineCirculation'); >+$template->param( display_transfer => 1 ) >+ if ( $flags->{'superlibrarian'} == 1 >+ || scalar GetIndependentGroupModificationRights() ); > >+$template->{'VARS'}->{'AllowOfflineCirculation'} = C4::Context->preference('AllowOfflineCirculation'); > > output_html_with_http_headers $query, $cookie, $template->output; >diff --git a/circ/pendingreserves.pl b/circ/pendingreserves.pl >index f964074..d95efa9 100755 >--- a/circ/pendingreserves.pl >+++ b/circ/pendingreserves.pl >@@ -36,6 +36,7 @@ use C4::Auth; > use C4::Dates qw/format_date format_date_in_iso/; > use C4::Debug; > use Date::Calc qw/Today Add_Delta_YMD/; >+use C4::Branch qw/GetIndependentGroupModificationRights/; > > my $input = new CGI; > my $startdate=$input->param('from'); >@@ -153,8 +154,8 @@ if ( $run_report ) { > > > if (C4::Context->preference('IndependentBranches')){ >- $strsth .= " AND items.holdingbranch=? "; >- push @query_params, C4::Context->userenv->{'branch'}; >+ my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $strsth .= " AND items.holdingbranch IN ( $branches ) "; > } > $strsth .= " GROUP BY reserves.biblionumber ORDER BY biblio.title "; > >diff --git a/circ/reserveratios.pl b/circ/reserveratios.pl >index c0e0062..dbff959 100755 >--- a/circ/reserveratios.pl >+++ b/circ/reserveratios.pl >@@ -124,9 +124,9 @@ my $strsth = > $sqldatewhere > "; > >-if (C4::Context->preference('IndependentBranches')){ >- $strsth .= " AND items.holdingbranch=? "; >- push @query_params, C4::Context->userenv->{'branch'}; >+if ( C4::Context->preference('IndependentBranches') ) { >+ my $branches = GetIndependentGroupModificationRights( { stringify => 1 } ); >+ $strsth .= " AND items.holdingbranch IN ( $branches ) "; > } > > $strsth .= " GROUP BY reserves.biblionumber ORDER BY reservecount DESC"; >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index cd83f99..e9aefd6 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -383,7 +383,7 @@ CREATE TABLE `branchcategories` ( -- information related to library/branch group > `categorycode` varchar(10) NOT NULL default '', -- unique identifier for the library/branch group > `categoryname` varchar(32), -- name of the library/branch group > `codedescription` mediumtext, -- longer description of the library/branch group >- `categorytype` varchar(16), -- says whether this is a search group or a properties group >+ `categorytype` ENUM( 'searchdomain', 'independent_group' ) NULL DEFAULT NULL, -- says whether this is a search group or an independent group > `show_in_pulldown` tinyint(1) NOT NULL DEFAULT '0', -- says this group should be in the opac libararies pulldown if it is enabled > PRIMARY KEY (`categorycode`), > KEY `show_in_pulldown` (`show_in_pulldown`) >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index ad8ec97..ed2ca2d 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -6938,7 +6938,7 @@ $DBversion = "3.13.00.002"; > if ( CheckVersion($DBversion) ) { > $dbh->do("UPDATE systempreferences SET variable = 'IndependentBranches' WHERE variable = 'IndependantBranches'"); > print "Upgrade to $DBversion done (Bug 10080 - Change system pref IndependantBranches to IndependentBranches)\n"; >- SetVersion ($DBversion); >+ SetVersion ($DBversion); > } > > $DBversion = '3.13.00.003'; >@@ -9773,6 +9773,22 @@ if ( CheckVersion($DBversion) ) { > SetVersion ($DBversion); > } > >+$DBversion = "3.17.00.XXX"; >+if ( CheckVersion($DBversion) ) { >+ $dbh->do(q{ >+ DELETE FROM branchcategories WHERE categorytype = 'properties' >+ }); >+ >+ $dbh->do(q{ >+ ALTER TABLE branchcategories >+ CHANGE categorytype categorytype >+ ENUM( 'searchdomain', 'independent_group' ) >+ NULL DEFAULT NULL >+ }); >+ print "Upgrade to $DBversion done (Remove branch property groups, add independent groups)\n"; >+ SetVersion ($DBversion); >+} >+ > =head1 FUNCTIONS > > =head2 TableExists($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt >index 887b81f..8c17d12 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt >@@ -112,20 +112,50 @@ tinyMCE.init({ > </li> > </ol> > </fieldset> >- [% IF ( categoryloop ) %]<fieldset class="rows"><legend>Group(s):</legend> >- <ol> >- [% FOREACH categoryloo IN categoryloop %] >- <li><label for="[% categoryloo.categorycode %]">[% categoryloo.categoryname %]: </label> >- [% IF categoryloo.selected %] >- <input type="checkbox" id="[% categoryloo.categorycode %]" name="[% categoryloo.categorycode %]" checked="checked" /> >- [% ELSE %] >- <input type="checkbox" id="[% categoryloo.categorycode %]" name="[% categoryloo.categorycode %]" /> >- [% END %] >- <span class="hint">[% categoryloo.codedescription %]</span> >- </li> >- [% END %] >- </ol> >-</fieldset>[% END %] >+ >+ [% IF ( branch_categories ) %] >+ <fieldset class="rows"> >+ <legend>Group(s):</legend> >+ <ol> >+ <fieldset> >+ <legend>Search domain</legend> >+ [% FOREACH bc IN branch_categories %] >+ [% IF bc.categorytype == "searchdomain" %] >+ <li> >+ <label for="[% bc.categorycode %]">[% bc.categoryname %]: </label> >+ [% IF ( bc.selected ) %] >+ <input type="checkbox" id="[% bc.categorycode %]" name="[% bc.categorycode %]" checked="checked" /> >+ [% ELSE %] >+ <input type="checkbox" id="[% bc.categorycode %]" name="[% bc.categorycode %]" /> >+ [% END %] >+ <span class="hint">[% bc.codedescription %]</span> >+ </li> >+ [% END %] >+ [% END %] >+ </fieldset> >+ </ol> >+ <ol> >+ <fieldset> >+ <legend>Independent library groups</legend> >+ [% FOREACH bc IN branch_categories %] >+ [% IF bc.categorytype == "independent_group" %] >+ <li> >+ <label for="[% bc.categorycode %]">[% bc.categoryname %]: </label> >+ [% IF ( bc.selected ) %] >+ <input type="checkbox" id="[% bc.categorycode %]" name="[% bc.categorycode %]" checked="checked" /> >+ [% ELSE %] >+ <input type="checkbox" id="[% bc.categorycode %]" name="[% bc.categorycode %]" /> >+ [% END %] >+ <span class="hint">[% bc.codedescription %]</span> >+ </li> >+ [% END %] >+ [% END %] >+ <li><label>Note:</label><span class="hint">If independent library groups are enabled ( via the IndependentBranches system preference ), a library may access and alter records and patrons from libraries in any group that also library belongs to. A library may belong to multiple library groups.</span></li> >+ </fieldset> >+ </ol> >+ </fieldset> >+ [% END %] >+ > <fieldset class="rows"> > <ol> > <li><label for="branchaddress1">Address line 1: </label><input type="text" name="branchaddress1" id="branchaddress1" size="60" value="[% branchaddress1 |html %]" /></li> >@@ -260,89 +290,121 @@ tinyMCE.init({ > <div class="dialog message">There are no libraries defined. <a href="/cgi-bin/koha/admin/branches.pl?op=add">Start defining libraries</a>.</div> > [% END %] > >- [% IF ( branchcategories ) %] >- [% FOREACH branchcategorie IN branchcategories %] >- <h3>Group(s): [% IF ( branchcategorie.properties ) %]Properties[% ELSE %][% IF ( branchcategorie.searchdomain ) %]Search domain[% END %][% END %]</h3> >- [% IF ( branchcategorie.catloop ) %] >- <table> >- <thead> >- <tr> >- <th>Name</th> >- <th>Code</th> >- <th>Description</th> >- <th> </th> >- <th> </th> >- </tr> >- </thead> >- <tbody> >- [% FOREACH catloo IN branchcategorie.catloop %] >- <tr> >- <td>[% catloo.categoryname %]</td> >- <td>[% catloo.categorycode %]</td> >- <td>[% catloo.codedescription %]</td> >- <td> >- <a href="[% catloo.action %]?op=editcategory&categorycode=[% catloo.categorycode |url %]">Edit</a> >- </td> >- <td> >- <a href="[% catloo.action %]?op=delete_category&categorycode=[% catloo.categorycode |url %]">Delete</a> >- </td> >- </tr> >- [% END %] >- </tbody> >- </table> >+ <h3>Search domain groups</h3> >+ [% IF branch_categories.searchdomain %] >+ <table> >+ <thead> >+ <tr> >+ <th>Name</th> >+ <th>Code</th> >+ <th>Description</th> >+ <th> </th> >+ <th> </th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH bc IN branch_categories.searchdomain %] >+ <tr> >+ <td>[% bc.value.categoryname %]</td> >+ <td>[% bc.key %]</td> >+ <td>[% bc.value.codedescription %]</td> >+ <td> >+ <a href="?op=editcategory&categorycode=[% bc.key |url %]">Edit</a> >+ </td> >+ <td> >+ <a href="?op=delete_category&categorycode=[% bc.key |url %]">Delete</a> >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ No search domain groups defined. >+ [% END %] >+ <a href="/cgi-bin/koha/admin/branches.pl?op=editcategory">Add a new group</a>. >+ >+ <h3>Independent library groups:</h3> >+ [% IF branch_categories.independent_group %] >+ <table> >+ <thead> >+ <tr> >+ <th>Name</th> >+ <th>Code</th> >+ <th>Description</th> >+ <th> </th> >+ <th> </th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH bc IN branch_categories.independent_group %] >+ <tr> >+ <td>[% bc.value.categoryname %]</td> >+ <td>[% bc.key %]</td> >+ <td>[% bc.value.codedescription %]</td> >+ <td> >+ <a href="?op=editcategory&categorycode=[% bc.key |url %]">Edit</a> >+ </td> >+ <td> >+ <a href="?op=delete_category&categorycode=[% bc.key |url %]">Delete</a> >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> > [% ELSE %] >- No [% IF ( branchcategorie.properties ) %]properties[% ELSIF ( branchcategorie.searchdomain ) %]search domain[% END %] defined. <a href="/cgi-bin/koha/admin/branches.pl?op=editcategory">Add a new group</a>. >+ No independent library groups defined. > [% END %] >- [% END %] >- [% ELSE %] >- <p>No groups defined.</p> >- [% END %] <!-- NAME="branchcategories" --> >+ <a href="/cgi-bin/koha/admin/branches.pl?op=editcategory">Add a new group</a>. > [% END %] > > [% IF ( editcategory ) %] >- <h3>[% IF ( categorycode ) %]Edit group [% categorycode %][% ELSE %]Add group[% END %]</h3> >+ <h3>[% IF ( category ) %]Edit group [% category.categorycode %][% ELSE %]Add group[% END %]</h3> > <form action="[% action %]" name="Aform" method="post"> > <input type="hidden" name="op" value="addcategory_validate" /> >- [% IF ( categorycode ) %] >- <input type="hidden" name="add" value="0"> >- [% ELSE %] >- <input type="hidden" name="add" value="1"> >- [% END %] >+ [% IF ( category.categorycode ) %] >+ <input type="hidden" name="add" value="0"> >+ [% ELSE %] >+ <input type="hidden" name="add" value="1"> >+ [% END %] > <fieldset class="rows"> > > <ol><li> >- [% IF ( categorycode ) %] >+ [% IF ( category.categorycode ) %] > <span class="label">Category code: </span> >- <input type="hidden" name="categorycode" id="categorycode" value="[% categorycode |html %]" /> >- [% categorycode %] >+ <input type="hidden" name="categorycode" id="categorycode" value="[% category.categorycode | html %]" /> >+ [% category.categorycode %] > [% ELSE %] >- <label for="categorycode">Category code:</label> >- <input type="text" name="categorycode" id="categorycode" size="10" maxlength="10" value="[% categorycode |html %]" /> >+ <label for="categorycode">Category code:</label> >+ <input type="text" name="categorycode" id="categorycode" size="10" maxlength="10" value="[% categorycode | html %]" /> > [% END %] > </li> > <li> > <label for="categoryname">Name: </label> >- <input type="text" name="categoryname" id="categoryname" size="32" maxlength="32" value="[% categoryname |html %]" /> >+ <input type="text" name="categoryname" id="categoryname" size="32" maxlength="32" value="[% category.categoryname | html %]" /> > </li> > <li> > <label for="codedescription">Description: </label> >- <input type="text" name="codedescription" id="codedescription" size="70" value="[% codedescription |html %]" /> >+ <input type="text" name="codedescription" id="codedescription" size="70" value="[% category.codedescription | html %]" /> > </li> > <li> > <label for="categorytype">Category type: </label> > <select id="categorytype" name="categorytype"> >- [% FOREACH categorytyp IN categorytype %] >- [% IF ( categorytyp.selected ) %] >- <option value="[% categorytyp.type %]" selected="selected"> >+ [% IF ( category.categorytype == 'searchdomain' ) %] >+ <option value="searchdomain" selected="selected">Search domain</option> > [% ELSE %] >- <option value="[% categorytyp.type %]"> >- [% END %] [% categorytyp.type %]</option> >- [% END %] >+ <option value="searchdomain">Search domain</option> >+ [% END %] >+ >+ [% IF ( category.categorytype == 'independent_group' ) %] >+ <option value="independent_group" selected="selected">Independent group</option> >+ [% ELSE %] >+ <option value="independent_group">Independent group</option> >+ [% END %] > </select> > </li> > <li> > <label for="show_in_pulldown">Show in search pulldown: </label> >- [% IF ( show_in_pulldown ) %] >+ [% IF ( category.show_in_pulldown ) %] > <input type="checkbox" name="show_in_pulldown" id="show_in_pulldown" checked="checked"/> > [% ELSE %] > <input type="checkbox" name="show_in_pulldown" id="show_in_pulldown" /> >@@ -350,7 +412,13 @@ tinyMCE.init({ > </li> > </ol> > </fieldset> >- <fieldset class="action"><input type="submit" value="Update" /></fieldset> >+ <fieldset class="action"> >+ [% IF category %] >+ <input type="submit" value="Update group" /> >+ [% ELSE %] >+ <input type="submit" value="Add group" /> >+ [% END %] >+ </fieldset> > </form> > [% END %] > >diff --git a/members/deletemem.pl b/members/deletemem.pl >index bad636c..7d8fcc4 100755 >--- a/members/deletemem.pl >+++ b/members/deletemem.pl >@@ -85,11 +85,17 @@ if ($bor->{category_type} eq "S") { > } > } > >-if (C4::Context->preference("IndependentBranches")) { >- my $userenv = C4::Context->userenv; >+if ( C4::Context->preference("IndependentBranches") ) { > if ( !C4::Context->IsSuperLibrarian() && $bor->{'branchcode'}){ >- unless ($userenv->{branch} eq $bor->{'branchcode'}){ >- print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_OTHERLIBRARY"); >+ unless ( >+ GetIndependentGroupModificationRights( >+ { for => $bor->{'branchcode'} } >+ ) >+ ) >+ { >+ print $input->redirect( >+ "/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_OTHERLIBRARY" >+ ); > exit; > } > } >diff --git a/t/db_dependent/Branch.t b/t/db_dependent/Branch.t >index 9ca3f56..e692c78 100644 >--- a/t/db_dependent/Branch.t >+++ b/t/db_dependent/Branch.t >@@ -21,7 +21,7 @@ use Modern::Perl; > use C4::Context; > use Data::Dumper; > >-use Test::More tests => 36; >+use Test::More tests => 69; > > use C4::Branch; > >@@ -178,14 +178,14 @@ my $cat1 = { > categorycode => 'CAT1', > categoryname => 'catname1', > codedescription => 'catdesc1', >- categorytype => 'cattype1', >+ categorytype => 'searchdomain', > show_in_pulldown => 1 > }; > my $cat2 = { > add => 1, > categorycode => 'CAT2', > categoryname => 'catname2', >- categorytype => 'catype2', >+ categorytype => 'searchdomain', > codedescription => 'catdesc2', > show_in_pulldown => 1 > }; >@@ -194,7 +194,7 @@ my %new_category = ( > categorycode => 'LIBCATCODE', > categoryname => 'library category name', > codedescription => 'library category code description', >- categorytype => 'searchdomain', >+ categorytype => 'independent_group', > show_in_pulldown => 1, > ); > >@@ -343,7 +343,7 @@ is( CheckCategoryUnique('CAT_NO_EXISTS'), 1, 'CAT_NO_EXISTS doesnt exist' ); > > #Test GetCategoryTypes > my @category_types = GetCategoryTypes(); >-is_deeply(\@category_types, [ 'searchdomain', 'properties' ], 'received expected library category types'); >+is_deeply(\@category_types, [ 'searchdomain', 'independent_groups' ], 'received expected library category types'); > > $categories = GetBranchCategories(undef, undef, 'LIBCATCODE'); > is_deeply($categories, [ {%$cat1}, {%$cat2},{ %new_category, selected => 1 } ], 'retrieve expected, eselected library category (bug 10515)'); >@@ -355,6 +355,72 @@ is_deeply($categories, [ {%$cat1}, {%$cat2},{ %new_category, selected => 1 } ], > my $loop = GetBranchesLoop; > is( scalar(@$loop), GetBranchesCount(), 'There is the right number of branches' ); > >+# Test GetIndependentGroupModificationRights >+my @branches_bra = GetIndependentGroupModificationRights({ branch => 'BRA' }); >+is_deeply( \@branches_bra, [ 'BRA' ], 'Library with no group only has rights for its own branch' ); >+ >+my $string = GetIndependentGroupModificationRights({ branch => 'BRA', stringify => 1 }); >+ok( $string eq q{'BRA'}, "String returns correctly" ); >+ >+ok( GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRA' }), 'Boolean test for BRA rights to BRA returns true' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRB' }), 'Boolean test for BRA rights to BRB returns false' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRC' }), 'Boolean test for BRA rights to BRC returns false' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRB' }), 'Boolean test for BRB rights to BRB returns true' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRA' }), 'Boolean test for BRB rights to BRA returns false' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRC' }), 'Boolean test for BRB rights to BRC returns false' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRC' }), 'Boolean test for BRC rights to BRC returns true' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRA'}), 'Boolean test for BRC rights to BRA returns false' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRB'}), 'Boolean test for BRC rights to BRB returns false' ); >+ >+ModBranch({ >+ branchcode => 'BRA', >+ branchname => 'BranchA', >+ LIBCATCODE => 1, >+}); >+ModBranch({ >+ branchcode => 'BRB', >+ branchname => 'BranchB', >+ LIBCATCODE => 1, >+}); >+ >+@branches_bra = GetIndependentGroupModificationRights({ branch => 'BRA' }); >+is_deeply( \@branches_bra, [ 'BRA', 'BRB' ], 'Libraries in LIBCATCODE returned correctly' ); >+ >+$string = GetIndependentGroupModificationRights({ branch => 'BRA', stringify => 1 }); >+ok( $string eq q{'BRA','BRB'}, "String returns correctly" ); >+ >+ok( GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRA' }), 'Boolean test for BRA rights to BRA returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRB'}), 'Boolean test for BRA rights to BRB returns true' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRC'}), 'Boolean test for BRA rights to BRC returns false' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRB' }), 'Boolean test for BRB rights to BRB returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRA'}), 'Boolean test for BRB rights to BRA returns true' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRC'}), 'Boolean test for BRB rights to BRC returns false' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRC' }), 'Boolean test for BRC rights to BRC returns true' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRA'}), 'Boolean test for BRC rights to BRA returns false' ); >+ok( !GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRB'}), 'Boolean test for BRC rights to BRB returns false' ); >+ >+ModBranch({ >+ branchcode => 'BRC', >+ branchname => 'BranchC', >+ LIBCATCODE => 1, >+}); >+ >+@branches_bra = GetIndependentGroupModificationRights({ branch => 'BRA' }); >+is_deeply( \@branches_bra, [ 'BRA', 'BRB', 'BRC' ], 'Library with no group only has rights for its own branch' ); >+ >+ok( GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRA' }), 'Boolean test for BRA rights to BRA returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRB'}), 'Boolean test for BRA rights to BRB returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRA', for => 'BRC'}), 'Boolean test for BRA rights to BRC returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRB' }), 'Boolean test for BRB rights to BRB returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRA'}), 'Boolean test for BRB rights to BRA returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRB', for => 'BRC'}), 'Boolean test for BRB rights to BRC returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRC' }), 'Boolean test for BRC rights to BRC returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRA'}), 'Boolean test for BRC rights to BRA returns true' ); >+ok( GetIndependentGroupModificationRights({ branch => 'BRC', for => 'BRA'}), 'Boolean test for BRC rights to BRB returns true' ); >+ >+$string = GetIndependentGroupModificationRights({ branch => 'BRA', stringify => 1 }); >+ok( $string eq q{'BRA','BRB','BRC'}, "String returns correctly" ); >+ > # End transaction > $dbh->rollback; > >-- >1.7.2.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 10276
:
18205
|
18479
|
18519
|
18716
|
18717
|
18850
|
20773
|
21145
|
22791
|
23037
|
23484
|
23489
|
23637
|
23641
|
23953
|
23992
|
24427
|
24428
|
25722
|
25723
|
25724
|
26015
|
26026
|
26027
|
26028
|
26029
|
28354
|
28355
|
28356
|
28357
|
28358
|
28359
|
28360
|
28361
|
28365
|
28366
|
28367
|
36027
|
36028
|
36029
|
36030
|
36031
|
36032
|
41064
|
41065
|
41066
|
41067
|
41068
|
41069
|
41070