From 96d2319a3dc7b5a98604b61ed90816cbcbe3914c Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Tue, 17 Apr 2012 08:07:32 -0400 Subject: [PATCH] Course Reserves Adds a course reserves system for academic libraries. The course reserves system allows libraries to create courses and put items on reserves for those courses. Each item with at least one reserve can have some of its attributes modified while it is on reserve for at least one active course. These attributes include item type, collection code, shelving location, and holding library. If there are no active courses with this item on reserve, it's attributes will revert to the original attributes it had before going on reserve. Testing Scenario: 1) Create new authorised value categories DEPARTMENT and TERM 2) Create a new course, add instructors to that course. 3) Reserve items for that course, verify item attributes have changed. 4) Disable course, verify item attributes have reverted. 5) Enable course again, verify item attributes again. 6) Delete course, verify item attributes again. 7) Create two new courses, add the same item(s) to both courses. 8) Disable one course, verify item attributes have not reverted. 9) Disable both courses, verify item attributes have reverted. 10) Enable one course, verify item attributes are again set to the new values. 11) Edit reserve item attributes, verify. 12) Disable all courses, edit reserve item attributes, verify the item itself still has its original attributes, verify the reserve item attributes have been updated. 13) Verify the ability to remove instructors from a course. 14) Verify new permissions, top level coursereserves, with subpermissions add_reserves and delete_reserves. --- C4/Auth.pm | 6 +- C4/Koha.pm | 25 +- Koha/CourseReserves.pm | 1116 ++++++++++++++++++++ Koha/Template/Plugin/AuthorisedValues.pm | 32 + Koha/Template/Plugin/Branches.pm | 37 + Koha/Template/Plugin/ItemTypes.pm | 38 + catalogue/detail.pl | 6 + course_reserves/add_items.pl | 94 ++ course_reserves/course-details.pl | 64 ++ course_reserves/course-reserves.pl | 54 + course_reserves/course.pl | 57 + course_reserves/mod_course.pl | 76 ++ installer/data/mysql/en/mandatory/userflags.sql | 1 + .../data/mysql/en/mandatory/userpermissions.sql | 5 +- installer/data/mysql/kohastructure.sql | 63 ++ installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 63 ++ .../intranet-tmpl/prog/en/css/staff-global.css | 2 +- .../intranet-tmpl/prog/en/includes/header.inc | 3 + .../intranet-tmpl/prog/en/includes/mainmenu.inc | 3 + .../en/modules/admin/preferences/circulation.pref | 7 + .../prog/en/modules/catalogue/detail.tt | 28 + .../en/modules/course_reserves/add_items-step1.tt | 63 ++ .../en/modules/course_reserves/add_items-step2.tt | 131 +++ .../en/modules/course_reserves/course-details.tt | 179 ++++ .../en/modules/course_reserves/course-reserves.tt | 102 ++ .../prog/en/modules/course_reserves/course.tt | 229 ++++ koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc | 1 + .../prog/en/modules/opac-course-details.tt | 63 ++ .../prog/en/modules/opac-course-reserves.tt | 62 ++ koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 27 + opac/opac-course-details.pl | 60 ++ opac/opac-course-reserves.pl | 51 + opac/opac-detail.pl | 6 + 34 files changed, 2746 insertions(+), 9 deletions(-) create mode 100644 Koha/CourseReserves.pm create mode 100644 Koha/Template/Plugin/AuthorisedValues.pm create mode 100644 Koha/Template/Plugin/Branches.pm create mode 100644 Koha/Template/Plugin/ItemTypes.pm create mode 100755 course_reserves/add_items.pl create mode 100755 course_reserves/course-details.pl create mode 100755 course_reserves/course-reserves.pl create mode 100755 course_reserves/course.pl create mode 100755 course_reserves/mod_course.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step1.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-details.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-reserves.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-course-details.tt create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-course-reserves.tt create mode 100755 opac/opac-course-details.pl create mode 100755 opac/opac-course-reserves.pl diff --git a/C4/Auth.pm b/C4/Auth.pm index ffee1bb..9e41ea3 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -193,7 +193,7 @@ sub get_template_and_user { $template->param( CAN_user_reserveforothers => 1 ); $template->param( CAN_user_borrow => 1 ); $template->param( CAN_user_editcatalogue => 1 ); - $template->param( CAN_user_updatecharges => 1 ); + $template->param( CAN_user_updatecharges => 1 ); $template->param( CAN_user_acquisition => 1 ); $template->param( CAN_user_management => 1 ); $template->param( CAN_user_tools => 1 ); @@ -201,6 +201,7 @@ sub get_template_and_user { $template->param( CAN_user_serials => 1 ); $template->param( CAN_user_reports => 1 ); $template->param( CAN_user_staffaccess => 1 ); + $template->param( CAN_user_coursereserves => 1 ); foreach my $module (keys %$all_perms) { foreach my $subperm (keys %{ $all_perms->{$module} }) { $template->param( "CAN_user_${module}_${subperm}" => 1 ); @@ -327,7 +328,8 @@ sub get_template_and_user { XSLTDetailsDisplay => C4::Context->preference("XSLTDetailsDisplay"), XSLTResultsDisplay => C4::Context->preference("XSLTResultsDisplay"), using_https => $in->{'query'}->https() ? 1 : 0, - noItemTypeImages => C4::Context->preference("noItemTypeImages"), + noItemTypeImages => C4::Context->preference("noItemTypeImages"), + UseCourseReserves => C4::Context->preference("UseCourseReserves"), ); if ( $in->{'type'} eq "intranet" ) { diff --git a/C4/Koha.pm b/C4/Koha.pm index 0192989..e93ebba 100644 --- a/C4/Koha.pm +++ b/C4/Koha.pm @@ -36,6 +36,7 @@ BEGIN { &subfield_is_koha_internal_p &GetPrinters &GetPrinter &GetItemTypes &getitemtypeinfo + &GetItemTypesFlat &GetCcodes &GetSupportName &GetSupportList &get_itemtypeinfos_of @@ -250,6 +251,15 @@ sub GetItemTypes { return ( \%itemtypes ); } +sub GetItemTypesFlat { + my $dbh = C4::Context->dbh; + my $query = "SELECT * FROM itemtypes ORDER BY description"; + my $sth = $dbh->prepare($query); + $sth->execute; + + return $sth->fetchall_arrayref({}); +} + sub get_itemtypeinfos_of { my @itemtypes = @_; @@ -1050,7 +1060,7 @@ sub GetAuthorisedValueCategories { =head2 GetAuthorisedValueByCode -$authhorised_value = GetAuthorisedValueByCode( $category, $authvalcode ); +$authorised_value = GetAuthorisedValueByCode( $category, $authvalcode, $opac ); Return the lib attribute from authorised_values from the row identified by the passed category and code @@ -1058,13 +1068,18 @@ by the passed category and code =cut sub GetAuthorisedValueByCode { - my ( $category, $authvalcode ) = @_; + my ( $category, $authvalcode, $opac ) = @_; my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare("SELECT lib FROM authorised_values WHERE category=? AND authorised_value =?"); + my $sth = $dbh->prepare("SELECT lib, lib_opac FROM authorised_values WHERE category=? AND authorised_value =?"); $sth->execute( $category, $authvalcode ); - while ( my $data = $sth->fetchrow_hashref ) { - return $data->{'lib'}; + + my $row = $sth->fetchrow_hashref(); + + if ( $opac ) { + return $row->{'lib_opac'} || $row->{'lib'}; + } else { + return $row->{'lib'}; } } diff --git a/Koha/CourseReserves.pm b/Koha/CourseReserves.pm new file mode 100644 index 0000000..528771f --- /dev/null +++ b/Koha/CourseReserves.pm @@ -0,0 +1,1116 @@ +package Koha::CourseReserves; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use Modern::Perl; + +require Exporter; + +use C4::Context; +use C4::Items qw(GetItem ModItem); +use C4::Biblio qw(GetBiblioFromItemNumber); +use C4::Circulation qw(GetOpenIssue); + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG @FIELDS); + +BEGIN { + @ISA = qw(Exporter); + @EXPORT = qw( + &GetCourse + &ModCourse + &GetCourses + &DelCourse + + &GetCourseInstructors + &ModCourseInstructors + + &GetCourseItem + &ModCourseItem + + &GetCourseReserve + &ModCourseReserve + &GetCourseReserves + &DelCourseReserve + + &SearchCourses + + &GetItemReservesInfo + ); + + $DEBUG = 0; + @FIELDS = ( 'itype', 'ccode', 'holdingbranch', 'location' ); +} + +=head1 NAME + +Koha::CourseReserves - Koha course reserves module + +=head1 SYNOPSIS + +use Koha::CourseReserves; + +=head1 DESCRIPTION + +This module deals with course reserves. + +=head1 FUNCTIONS + +=head2 GetCourse + + $course = GetCourse( $course_id ); + +=cut + +sub GetCourse { + my ($course_id) = @_; + warn whoami() . "( $course_id )" if $DEBUG; + + my $query = "SELECT * FROM courses WHERE course_id = ?"; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($course_id); + + my $course = $sth->fetchrow_hashref(); + + $query = " + SELECT b.* FROM course_instructors ci + LEFT JOIN borrowers b ON ( ci.borrowernumber = b.borrowernumber ) + WHERE course_id = ? + "; + $sth = $dbh->prepare($query); + $sth->execute($course_id); + $course->{'instructors'} = $sth->fetchall_arrayref( {} ); + + return $course; +} + +=head2 ModCourse + + ModCourse( [ course_id => $id ] [, course_name => $course_name ] [etc...] ); + +=cut + +sub ModCourse { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $dbh = C4::Context->dbh; + + my $course_id; + if ( defined $params{'course_id'} ) { + $course_id = $params{'course_id'}; + delete $params{'course_id'}; + } + + my @query_keys; + my @query_values; + + my $query; + + $query .= ($course_id) ? ' UPDATE ' : ' INSERT '; + $query .= ' courses SET '; + + foreach my $key ( keys %params ) { + push( @query_keys, "$key=?" ); + push( @query_values, $params{$key} ); + } + $query .= join( ',', @query_keys ); + + if ($course_id) { + $query .= " WHERE course_id = ?"; + push( @query_values, $course_id ); + } + + $dbh->do( $query, undef, @query_values ); + + $course_id = $course_id + || $dbh->last_insert_id( undef, undef, 'courses', 'course_id' ); + + EnableOrDisableCourseItems( + course_id => $course_id, + enabled => $params{'enabled'} + ); + + return $course_id; +} + +=head2 GetCourses + + @courses = GetCourses( [ fieldname => $value ] [, fieldname2 => $value2 ] [etc...] ); + +=cut + +sub GetCourses { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my @query_keys; + my @query_values; + + my $query = " + SELECT courses.* + FROM courses + LEFT JOIN course_reserves ON course_reserves.course_id = courses.course_id + LEFT JOIN course_items ON course_items.ci_id = course_reserves.ci_id + "; + + if ( keys %params ) { + + $query .= " WHERE "; + + foreach my $key ( keys %params ) { + push( @query_keys, " $key LIKE ? " ); + push( @query_values, $params{$key} ); + } + + $query .= join( ' AND ', @query_keys ); + } + + $query .= " GROUP BY courses.course_id "; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute(@query_values); + + my $courses = $sth->fetchall_arrayref( {} ); + + foreach my $c (@$courses) { + $c->{'instructors'} = GetCourseInstructors( $c->{'course_id'} ); + } + + return $courses; +} + +=head2 DelCourse + + DelCourse( $course_id ); + +=cut + +sub DelCourse { + my ($course_id) = @_; + + my $course_reserves = GetCourseReserves( course_id => $course_id ); + + foreach my $res (@$course_reserves) { + DelCourseReserve( cr_id => $res->{'cr_id'} ); + } + + my $query = " + DELETE FROM courses + WHERE course_id = ? + "; + C4::Context->dbh->do( $query, undef, $course_id ); +} + +=head2 EnableOrDisableCourseItems + + EnableOrDisableCourseItems( course_id => $course_id, enabled => $enabled ); + + For each item on reserve for this course, + if the course item has no active course reserves, + swap the fields for the item to make it 'normal' + again. + + enabled => 'yes' to enable course items + enabled => 'no' to disable course items + +=cut + +sub EnableOrDisableCourseItems { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $course_id = $params{'course_id'}; + my $enabled = $params{'enabled'}; + + my $lookfor = ( $enabled eq 'yes' ) ? 'no' : 'yes'; + + return unless ( $course_id && $enabled ); + return unless ( $enabled eq 'yes' || $enabled eq 'no' ); + + my $course_reserves = GetCourseReserves( course_id => $course_id ); + + if ( $enabled eq 'yes' ) { + foreach my $course_reserve (@$course_reserves) { + if ( + CountCourseReservesForItem( + ci_id => $course_reserve->{'ci_id'}, + enabled => 'yes' + ) + ) + { + EnableOrDisableCourseItem( + ci_id => $course_reserve->{'ci_id'}, + enabled => 'yes', + ); + } + } + } + if ( $enabled eq 'no' ) { + foreach my $course_reserve (@$course_reserves) { + unless ( + CountCourseReservesForItem( + ci_id => $course_reserve->{'ci_id'}, + enabled => 'yes' + ) + ) + { + EnableOrDisableCourseItem( + ci_id => $course_reserve->{'ci_id'}, + enabled => 'no', + ); + } + } + } +} + +=head2 EnableOrDisableCourseItem + + EnableOrDisableCourseItem( ci_id => $ci_id, enabled => $enabled ); + + enabled => 'yes' to enable course items + enabled => 'no' to disable course items + +=cut + +sub EnableOrDisableCourseItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $ci_id = $params{'ci_id'}; + my $enabled = $params{'enabled'}; + + return unless ( $ci_id && $enabled ); + return unless ( $enabled eq 'yes' || $enabled eq 'no' ); + + my $course_item = GetCourseItem( ci_id => $ci_id ); + + ## We don't want to 'enable' an already enabled item, + ## or disable and already disabled item, + ## as that would cause the fields to swap + if ( $course_item->{'enabled'} ne $enabled ) { + _SwapAllFields($ci_id); + + my $query = " + UPDATE course_items + SET enabled = ? + WHERE ci_id = ? + "; + + C4::Context->dbh->do( $query, undef, $enabled, $ci_id ); + + } + +} + +=head2 GetCourseInstructors + + @borrowernumbers = GetCourseInstructors( $course_id ); + +=cut + +sub GetCourseInstructors { + my ($course_id) = @_; + warn "Koha::CourseReserves::GetCourseInstructors( $course_id )" + if $DEBUG; + + my $query = " + SELECT * FROM borrowers + RIGHT JOIN course_instructors ON ( course_instructors.borrowernumber = borrowers.borrowernumber ) + WHERE course_instructors.course_id = ? + "; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($course_id); + + return $sth->fetchall_arrayref( {} ); +} + +=head2 ModCourseInstructors + + ModCourseInstructors( mode => $mode, course_id => $course_id, [ cardnumbers => $cardnumbers ] OR [ borrowernumbers => $borrowernumbers ); + + $mode can be 'replace', 'add', or 'delete' + + $cardnumbers and $borrowernumbers are both references to arrays + + Use either cardnumbers or borrowernumber, but not both. + +=cut + +sub ModCourseInstructors { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $course_id = $params{'course_id'}; + my $mode = $params{'mode'}; + my $cardnumbers = $params{'cardnumbers'}; + my $borrowernumbers = $params{'borrowernumbers'}; + + return unless ($course_id); + return + unless ( $mode eq 'replace' + || $mode eq 'add' + || $mode eq 'delete' ); + return unless ( $cardnumbers || $borrowernumbers ); + return if ( $cardnumbers && $borrowernumbers ); + + my @cardnumbers = @$cardnumbers if ( ref($cardnumbers) eq 'ARRAY' ); + my @borrowernumbers = @$borrowernumbers + if ( ref($borrowernumbers) eq 'ARRAY' ); + + my $field = (@cardnumbers) ? 'cardnumber' : 'borrowernumber'; + my @fields = (@cardnumbers) ? @cardnumbers : @borrowernumbers; + my $placeholders = join( ',', ('?') x scalar @fields ); + + my $dbh = C4::Context->dbh; + + $dbh->do( "DELETE FROM course_instructors WHERE course_id = ?", + undef, $course_id ) + if ( $mode eq 'replace' ); + + my $query; + + if ( $mode eq 'add' || $mode eq 'replace' ) { + $query = " + INSERT INTO course_instructors ( course_id, borrowernumber ) + SELECT ?, borrowernumber + FROM borrowers + WHERE $field IN ( $placeholders ) + "; + } + else { + $query = " + DELETE FROM course_instructors + WHERE course_id = ? + AND borrowernumber IN ( + SELECT borrowernumber FROM borrowers WHERE $field IN ( $placeholders ) + ) + "; + } + + my $sth = $dbh->prepare($query); + + $sth->execute( $course_id, @fields ) if (@fields); +} + +=head2 GetCourseItem { + + $course_item = GetCourseItem( itemnumber => $itemnumber [, ci_id => $ci_id ); + +=cut + +sub GetCourseItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $ci_id = $params{'ci_id'}; + my $itemnumber = $params{'itemnumber'}; + + return unless ( $itemnumber || $ci_id ); + + my $field = ($itemnumber) ? 'itemnumber' : 'ci_id'; + my $value = ($itemnumber) ? $itemnumber : $ci_id; + + my $query = "SELECT * FROM course_items WHERE $field = ?"; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($value); + + my $course_item = $sth->fetchrow_hashref(); + + if ($course_item) { + $query = "SELECT * FROM course_reserves WHERE ci_id = ?"; + $sth = $dbh->prepare($query); + $sth->execute( $course_item->{'ci_id'} ); + my $course_reserves = $sth->fetchall_arrayref( {} ); + + $course_item->{'course_reserves'} = $course_reserves + if ($course_reserves); + } + return $course_item; +} + +=head2 ModCourseItem { + + ModCourseItem( %params ); + + Creates or modifies an existing course item. + +=cut + +sub ModCourseItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $itemnumber = $params{'itemnumber'}; + my $itype = $params{'itype'}; + my $ccode = $params{'ccode'}; + my $holdingbranch = $params{'holdingbranch'}; + my $location = $params{'location'}; + + return unless ($itemnumber); + + my $course_item = GetCourseItem( itemnumber => $itemnumber ); + + my $ci_id; + + if ($course_item) { + $ci_id = $course_item->{'ci_id'}; + + _UpdateCourseItem( + ci_id => $ci_id, + course_item => $course_item, + %params + ); + } + else { + $ci_id = _AddCourseItem(%params); + } + + return $ci_id; + +} + +=head2 _AddCourseItem + + my $ci_id = _AddCourseItem( %params ); + +=cut + +sub _AddCourseItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my ( @fields, @values ); + + push( @fields, 'itemnumber = ?' ); + push( @values, $params{'itemnumber'} ); + + foreach (@FIELDS) { + if ( $params{$_} ) { + push( @fields, "$_ = ?" ); + push( @values, $params{$_} ); + } + } + + my $query = "INSERT INTO course_items SET " . join( ',', @fields ); + my $dbh = C4::Context->dbh; + $dbh->do( $query, undef, @values ); + + my $ci_id = $dbh->last_insert_id( undef, undef, 'course_items', 'ci_id' ); + + return $ci_id; +} + +=head2 _UpdateCourseItem + + _UpdateCourseItem( %params ); + +=cut + +sub _UpdateCourseItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $ci_id = $params{'ci_id'}; + my $course_item = $params{'course_item'}; + my $itype = $params{'itype'}; + my $ccode = $params{'ccode'}; + my $holdingbranch = $params{'holdingbranch'}; + my $location = $params{'location'}; + + return unless ( $ci_id || $course_item ); + + $course_item = GetCourseItem( ci_id => $ci_id ) + unless ($course_item); + $ci_id = $course_item->{'ci_id'} unless ($ci_id); + + ## Revert fields that had an 'original' value, but now don't + ## Update the item fields to the stored values from course_items + ## and then set those fields in course_items to NULL + my @fields_to_revert; + foreach (@FIELDS) { + if ( !$params{$_} && $course_item->{$_} ) { + push( @fields_to_revert, $_ ); + } + } + _RevertFields( + ci_id => $ci_id, + fields => \@fields_to_revert, + course_item => $course_item + ) if (@fields_to_revert); + + ## Update fields that still have an original value, but it has changed + ## This necessitates only changing the current item values, as we still + ## have the original values stored in course_items + my %mod_params; + foreach (@FIELDS) { + if ( $params{$_} + && $course_item->{$_} + && $params{$_} ne $course_item->{$_} ) + { + $mod_params{$_} = $params{$_}; + } + } + ModItem( \%mod_params, undef, $course_item->{'itemnumber'} ); + + ## Update fields that didn't have an original value, but now do + ## We must save the original value in course_items, and also + ## update the item fields to the new value + my $item = GetItem( $course_item->{'itemnumber'} ); + my %mod_params_new; + my %mod_params_old; + foreach (@FIELDS) { + if ( $params{$_} && !$course_item->{$_} ) { + $mod_params_new{$_} = $params{$_}; + $mod_params_old{$_} = $item->{$_}; + } + } + _ModStoredFields( 'ci_id' => $params{'ci_id'}, %mod_params_old ); + ModItem( \%mod_params_new, undef, $course_item->{'itemnumber'} ); + +} + +=head2 _ModStoredFields + + _ModStoredFields( %params ); + + Updates the values for the 'original' fields in course_items + for a given ci_id + +=cut + +sub _ModStoredFields { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + return unless ( $params{'ci_id'} ); + + my ( @fields_to_update, @values_to_update ); + + foreach (@FIELDS) { + if ( $params{$_} ) { + push( @fields_to_update, $_ ); + push( @values_to_update, $params{$_} ); + } + } + + my $query = + "UPDATE course_items SET " + . join( ',', map { "$_=?" } @fields_to_update ) + . " WHERE ci_id = ?"; + + C4::Context->dbh->do( $query, undef, @values_to_update, $params{'ci_id'} ) + if (@values_to_update); + +} + +=head2 _RevertFields + + _RevertFields( ci_id => $ci_id, fields => \@fields_to_revert ); + +=cut + +sub _RevertFields { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $ci_id = $params{'ci_id'}; + my $course_item = $params{'course_item'}; + my $fields = $params{'fields'}; + my @fields = @$fields; + + return unless ($ci_id); + + $course_item = GetCourseItem( ci_id => $params{'ci_id'} ) + unless ($course_item); + + my $mod_item_params; + my @fields_to_null; + foreach my $field (@fields) { + foreach (@FIELDS) { + if ( $field eq $_ && $course_item->{$_} ) { + $mod_item_params->{$_} = $course_item->{$_}; + push( @fields_to_null, $_ ); + } + } + } + ModItem( $mod_item_params, undef, $course_item->{'itemnumber'} ); + + my $query = + "UPDATE course_items SET " + . join( ',', map { "$_=NULL" } @fields_to_null ) + . " WHERE ci_id = ?"; + + C4::Context->dbh->do( $query, undef, $ci_id ) if (@fields_to_null); +} + +=head2 _SwapAllFields + + _SwapAllFields( $ci_id ); + +=cut + +sub _SwapAllFields { + my ($ci_id) = @_; + warn "Koha::CourseReserves::_SwapFields( $ci_id )" if $DEBUG; + + my $course_item = GetCourseItem( ci_id => $ci_id ); + my $item = GetItem( $course_item->{'itemnumber'} ); + + my %course_item_fields; + my %item_fields; + foreach (@FIELDS) { + if ( $course_item->{$_} ) { + $course_item_fields{$_} = $course_item->{$_}; + $item_fields{$_} = $item->{$_}; + } + } + + ModItem( \%course_item_fields, undef, $course_item->{'itemnumber'} ); + _ModStoredFields( %item_fields, ci_id => $ci_id ); +} + +=head2 GetCourseItems { + + $course_items = GetCourseItems( + [course_id => $course_id] + [, itemnumber => $itemnumber ] + ); + +=cut + +sub GetCourseItems { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $course_id = $params{'course_id'}; + my $itemnumber = $params{'itemnumber'}; + + return unless ($course_id); + + my @query_keys; + my @query_values; + + my $query = "SELECT * FROM course_items"; + + if ( keys %params ) { + + $query .= " WHERE "; + + foreach my $key ( keys %params ) { + push( @query_keys, " $key LIKE ? " ); + push( @query_values, $params{$key} ); + } + + $query .= join( ' AND ', @query_keys ); + } + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute(@query_values); + + return $sth->fetchall_arrayref( {} ); +} + +=head2 DelCourseItem { + + DelCourseItem( ci_id => $cr_id ); + +=cut + +sub DelCourseItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $ci_id = $params{'ci_id'}; + + return unless ($ci_id); + + _RevertFields( ci_id => $ci_id, fields => \@FIELDS ); + + my $query = " + DELETE FROM course_items + WHERE ci_id = ? + "; + C4::Context->dbh->do( $query, undef, $ci_id ); +} + +=head2 GetCourseReserve { + + $course_item = GetCourseReserve( %params ); + +=cut + +sub GetCourseReserve { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $cr_id = $params{'cr_id'}; + my $course_id = $params{'course_id'}; + my $ci_id = $params{'ci_id'}; + + return unless ( $cr_id || ( $course_id && $ci_id ) ); + + my $dbh = C4::Context->dbh; + my $sth; + + if ($cr_id) { + my $query = " + SELECT * FROM course_reserves + WHERE cr_id = ? + "; + $sth = $dbh->prepare($query); + $sth->execute($cr_id); + } + else { + my $query = " + SELECT * FROM course_reserves + WHERE course_id = ? AND ci_id = ? + "; + $sth = $dbh->prepare($query); + $sth->execute( $course_id, $ci_id ); + } + + my $course_reserve = $sth->fetchrow_hashref(); + return $course_reserve; +} + +=head2 ModCourseReserve + + $id = ModCourseReserve( %params ); + +=cut + +sub ModCourseReserve { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $course_id = $params{'course_id'}; + my $ci_id = $params{'ci_id'}; + my $staff_note = $params{'staff_note'}; + my $public_note = $params{'public_note'}; + + return unless ( $course_id && $ci_id ); + + my $course_reserve = + GetCourseReserve( course_id => $course_id, ci_id => $ci_id ); + my $cr_id; + + my $dbh = C4::Context->dbh; + + if ($course_reserve) { + $cr_id = $course_reserve->{'cr_id'}; + + my $query = " + UPDATE course_reserves + SET staff_note = ?, public_note = ? + WHERE cr_id = ? + "; + $dbh->do( $query, undef, $staff_note, $public_note, $cr_id ); + } + else { + my $query = " + INSERT INTO course_reserves SET + course_id = ?, + ci_id = ?, + staff_note = ?, + public_note = ? + "; + $dbh->do( $query, undef, $course_id, $ci_id, $staff_note, + $public_note ); + $cr_id = + $dbh->last_insert_id( undef, undef, 'course_reserves', 'cr_id' ); + } + + my $course = GetCourse($course_id); + EnableOrDisableCourseItem( + ci_id => $params{'ci_id'}, + enabled => $course->{'enabled'} + ); + + return $cr_id; +} + +=head2 GetCourseReserves { + + $course_reserves = GetCourseReserves( %params ); + + Required: + course_id OR ci_id + Optional: + include_items => 1, + include_count => 1, + include_courses => 1, + +=cut + +sub GetCourseReserves { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $course_id = $params{'course_id'}; + my $ci_id = $params{'ci_id'}; + my $include_items = $params{'include_items'}; + my $include_count = $params{'include_count'}; + my $include_courses = $params{'include_courses'}; + + return unless ( $course_id || $ci_id ); + + my $field = ($course_id) ? 'course_id' : 'ci_id'; + my $value = ($course_id) ? $course_id : $ci_id; + + my $query = " + SELECT cr.*, ci.itemnumber + FROM course_reserves cr, course_items ci + WHERE cr.$field = ? + AND cr.ci_id = ci.ci_id + "; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($value); + + my $course_reserves = $sth->fetchall_arrayref( {} ); + + if ($include_items) { + foreach my $cr (@$course_reserves) { + $cr->{'course_item'} = GetCourseItem( ci_id => $cr->{'ci_id'} ); + $cr->{'item'} = GetBiblioFromItemNumber( $cr->{'itemnumber'} ); + $cr->{'issue'} = GetOpenIssue( $cr->{'itemnumber'} ); + } + } + + if ($include_count) { + foreach my $cr (@$course_reserves) { + $cr->{'reserves_count'} = + CountCourseReservesForItem( ci_id => $cr->{'ci_id'} ); + } + } + + if ($include_courses) { + foreach my $cr (@$course_reserves) { + $cr->{'courses'} = + GetCourses( itemnumber => $cr->{'itemnumber'} ); + } + } + + return $course_reserves; +} + +=head2 DelCourseReserve { + + DelCourseReserve( cr_id => $cr_id ); + +=cut + +sub DelCourseReserve { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $cr_id = $params{'cr_id'}; + + return unless ($cr_id); + + my $dbh = C4::Context->dbh; + + my $course_reserve = GetCourseReserve( cr_id => $cr_id ); + + my $query = " + DELETE FROM course_reserves + WHERE cr_id = ? + "; + $dbh->do( $query, undef, $cr_id ); + + ## If there are no other course reserves for this item + ## delete the course_item as well + unless ( CountCourseReservesForItem( ci_id => $course_reserve->{'ci_id'} ) ) + { + DelCourseItem( ci_id => $course_reserve->{'ci_id'} ); + } + +} + +=head2 GetReservesInfo + + my $arrayref = GetItemReservesInfo( itemnumber => $itemnumber ); + + For a given item, returns an arrayref of reserves hashrefs, + with a course hashref under the key 'course' + +=cut + +sub GetItemReservesInfo { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $itemnumber = $params{'itemnumber'}; + + return unless ($itemnumber); + + my $course_item = GetCourseItem( itemnumber => $itemnumber ); + + return unless ( keys %$course_item ); + + my $course_reserves = GetCourseReserves( ci_id => $course_item->{'ci_id'} ); + + foreach my $cr (@$course_reserves) { + $cr->{'course'} = GetCourse( $cr->{'course_id'} ); + } + + return $course_reserves; +} + +=head2 CountCourseReservesForItem + + $bool = CountCourseReservesForItem( %params ); + + ci_id - course_item id + OR + itemnumber - course_item itemnumber + + enabled = 'yes' or 'no' + Optional, if not supplied, counts reserves + for both enabled and disabled courses + +=cut + +sub CountCourseReservesForItem { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $ci_id = $params{'ci_id'}; + my $itemnumber = $params{'itemnumber'}; + my $enabled = $params{'enabled'}; + + return unless ( $ci_id || $itemnumber ); + + my $course_item = + GetCourseItem( ci_id => $ci_id, itemnumber => $itemnumber ); + + my @params = ( $course_item->{'ci_id'} ); + push( @params, $enabled ) if ($enabled); + + my $query = " + SELECT COUNT(*) AS count + FROM course_reserves cr + LEFT JOIN courses c ON ( c.course_id = cr.course_id ) + WHERE ci_id = ? + "; + $query .= "AND c.enabled = ?" if ($enabled); + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute(@params); + + my $row = $sth->fetchrow_hashref(); + + return $row->{'count'}; +} + +=head2 SearchCourses + + my $courses = SearchCourses( term => $search_term, enabled => 'yes' ); + +=cut + +sub SearchCourses { + my (%params) = @_; + warn identify_myself(%params) if $DEBUG; + + my $term = $params{'term'}; + + my $enabled = $params{'enabled'} || '%'; + + my @params; + my $query = "SELECT c.* FROM courses c"; + + $query .= " + LEFT JOIN course_instructors ci + ON ( c.course_id = ci.course_id ) + LEFT JOIN borrowers b + ON ( ci.borrowernumber = b.borrowernumber ) + LEFT JOIN authorised_values av + ON ( c.department = av.authorised_value ) + WHERE + ( av.category = 'DEPARTMENT' OR av.category = 'TERM' ) + AND + ( + department LIKE ? OR + course_number LIKE ? OR + section LIKE ? OR + course_name LIKE ? OR + term LIKE ? OR + public_note LIKE ? OR + CONCAT(surname,' ',firstname) LIKE ? OR + CONCAT(firstname,' ',surname) LIKE ? OR + lib LIKE ? OR + lib_opac LIKE ? + ) + AND + c.enabled LIKE ? + GROUP BY c.course_id + "; + + $term = "%$term%"; + @params = ($term) x 10; + + $query .= " ORDER BY department, course_number, section, term, course_name "; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + + $sth->execute(@params, $enabled); + + my $courses = $sth->fetchall_arrayref( {} ); + + foreach my $c (@$courses) { + $c->{'instructors'} = GetCourseInstructors( $c->{'course_id'} ); + } + + return $courses; +} + +sub whoami { ( caller(1) )[3] } +sub whowasi { ( caller(2) )[3] } + +sub stringify_params { + my (%params) = @_; + + my $string = "\n"; + + foreach my $key ( keys %params ) { + $string .= " $key => " . $params{$key} . "\n"; + } + + return "( $string )"; +} + +sub identify_myself { + my (%params) = @_; + + return whowasi() . stringify_params(%params); +} + +1; + +=head1 AUTHOR + +Kyle M Hall + +=cut diff --git a/Koha/Template/Plugin/AuthorisedValues.pm b/Koha/Template/Plugin/AuthorisedValues.pm new file mode 100644 index 0000000..8ec1530 --- /dev/null +++ b/Koha/Template/Plugin/AuthorisedValues.pm @@ -0,0 +1,32 @@ +package Koha::Template::Plugin::AuthorisedValues; + +# Copyright ByWater Solutions 2012 + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Template::Plugin; +use base qw( Template::Plugin ); + +use C4::Koha; + +sub GetByCode { + my ( $self, $category, $code, $opac ) = @_; + return GetAuthorisedValueByCode( $category, $code, $opac ); +} + +1; diff --git a/Koha/Template/Plugin/Branches.pm b/Koha/Template/Plugin/Branches.pm new file mode 100644 index 0000000..ad768a5 --- /dev/null +++ b/Koha/Template/Plugin/Branches.pm @@ -0,0 +1,37 @@ +package Koha::Template::Plugin::Branches; + +# Copyright ByWater Solutions 2012 + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Template::Plugin; +use base qw( Template::Plugin ); + +use C4::Koha; + +sub GetName { + my ( $self, $branchcode ) = @_; + + my $query = "SELECT branchname FROM branches WHERE branchcode = ?"; + my $sth = C4::Context->dbh->prepare($query); + $sth->execute($branchcode); + my $b = $sth->fetchrow_hashref(); + return $b->{'branchname'}; +} + +1; diff --git a/Koha/Template/Plugin/ItemTypes.pm b/Koha/Template/Plugin/ItemTypes.pm new file mode 100644 index 0000000..60ca979 --- /dev/null +++ b/Koha/Template/Plugin/ItemTypes.pm @@ -0,0 +1,38 @@ +package Koha::Template::Plugin::ItemTypes; + +# Copyright ByWater Solutions 2012 + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Template::Plugin; +use base qw( Template::Plugin ); + +use C4::Koha; + +sub GetDescription { + my ( $self, $itemtype ) = @_; + + my $query = "SELECT description FROM itemtypes WHERE itemtype = ?"; + my $sth = C4::Context->dbh->prepare($query); + $sth->execute($itemtype); + my $d = $sth->fetchrow_hashref(); + return $d->{'description'}; + +} + +1; diff --git a/catalogue/detail.pl b/catalogue/detail.pl index de355fa..2d770e3 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -40,6 +40,7 @@ use C4::VirtualShelves; use C4::XSLT; use C4::Images; use Koha::DateUtils; +use Koha::CourseReserves; # use Smart::Comments; @@ -260,6 +261,11 @@ foreach my $item (@items) { if ($item->{'materials'} ne ''){ $materials_flag = 1; } + + if ( C4::Context->preference('UseCourseReserves') ) { + $item->{'course_reserves'} = GetItemReservesInfo( itemnumber => $item->{'itemnumber'} ); + } + push @itemloop, $item; } diff --git a/course_reserves/add_items.pl b/course_reserves/add_items.pl new file mode 100755 index 0000000..e810837 --- /dev/null +++ b/course_reserves/add_items.pl @@ -0,0 +1,94 @@ +#!/usr/bin/perl + +# +# Copyright 2012 Bywater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; +use C4::Koha; +use C4::Biblio; +use C4::Branch; + +use Koha::CourseReserves; + +my $cgi = new CGI; + +my $action = $cgi->param('action') || ''; +my $course_id = $cgi->param('course_id') || ''; +my $barcode = $cgi->param('barcode') || ''; + +die('No course_id provided') unless ($course_id); + +my $item = GetBiblioFromItemNumber( undef, $barcode ); + +my $step = ( $action eq 'lookup' && $item ) ? '2' : '1'; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "course_reserves/add_items-step$step.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { coursereserves => 'add_reserves' }, + } +); +$template->param( ERROR_BARCODE_NOT_FOUND => $barcode ) unless ( $barcode && $item && $action eq 'lookup' ); + +$template->param( course => GetCourse($course_id) ); + +if ( $action eq 'lookup' ) { + my $course_item = GetCourseItem( itemnumber => $item->{'itemnumber'} ); + my $course_reserve = GetCourseReserve( + course_id => $course_id, + ci_id => $course_item->{'ci_id'} + ) if ($course_item); + + $template->param( + item => $item, + course_item => $course_item, + course_reserve => $course_reserve, + + ccodes => GetAuthorisedValues('CCODE'), + locations => GetAuthorisedValues('LOC'), + itypes => GetItemTypesFlat(), + branches => GetBranchesLoop(), + ); + +} +elsif ( $action eq 'add' ) { + my $ci_id = ModCourseItem( + itemnumber => $cgi->param('itemnumber'), + itype => $cgi->param('itype'), + ccode => $cgi->param('ccode'), + holdingbranch => $cgi->param('holdingbranch'), + location => $cgi->param('location'), + ); + + my $cr_id = ModCourseReserve( + course_id => $course_id, + ci_id => $ci_id, + staff_note => $cgi->param('staff_note'), + public_note => $cgi->param('public_note'), + ); +} + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/course_reserves/course-details.pl b/course_reserves/course-details.pl new file mode 100755 index 0000000..1b401fc --- /dev/null +++ b/course_reserves/course-details.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl + +# +# Copyright 2012 Bywater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; +use C4::Koha; + +use Koha::CourseReserves; + +my $cgi = new CGI; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "course_reserves/course-details.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { coursereserves => 'manage_courses' }, + } +); + +my $action = $cgi->param('action') || ''; +my $course_id = $cgi->param('course_id'); + +die("No course_id given") unless ($course_id); + +if ( $action eq 'del_reserve' ) { + DelCourseReserve( cr_id => $cgi->param('cr_id') ); +} + +my $course = GetCourse($course_id); +my $course_reserves = GetCourseReserves( + course_id => $course_id, + include_items => 1, + include_courses => 1 +); + +$template->param( + course => $course, + course_reserves => $course_reserves, +); + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/course_reserves/course-reserves.pl b/course_reserves/course-reserves.pl new file mode 100755 index 0000000..91d6e3e --- /dev/null +++ b/course_reserves/course-reserves.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl + +# +# Copyright 2012 Bywater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; + +use Koha::CourseReserves; + +my $cgi = new CGI; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "course_reserves/course-reserves.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { coursereserves => 'manage_courses' }, + } +); + +my $search_on = $cgi->param('search_on'); +my %params; +if ($search_on) { + $params{'course_name'} = "%$search_on%"; +} + +my $courses = GetCourses(%params); +if ( @$courses == 1 ) { + print $cgi->redirect("/cgi-bin/koha/course_reserves/course-details.pl?course_id=" . $courses->[0]->{'course_id'}); +} else { + $template->param( courses => $courses ); + output_html_with_http_headers $cgi, $cookie, $template->output; +} diff --git a/course_reserves/course.pl b/course_reserves/course.pl new file mode 100755 index 0000000..8acf878 --- /dev/null +++ b/course_reserves/course.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl + +# +# Copyright 2012 Bywater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; +use C4::Koha; + +use Koha::CourseReserves; + +my $cgi = new CGI; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "course_reserves/course.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { course_reserves => 1 }, + } +); + +my $course_id = $cgi->param('course_id'); + +if ($course_id) { + my $course = GetCourse($course_id); + $template->param(%$course); +} + +$template->param( + departments => GetAuthorisedValues('DEPARTMENT') + , ## TODO: use syspref instead of hard coded value. + terms => GetAuthorisedValues('TERM') + , ## TODO: use syspref instead of hard coded value. +); + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/course_reserves/mod_course.pl b/course_reserves/mod_course.pl new file mode 100755 index 0000000..6d2f36d --- /dev/null +++ b/course_reserves/mod_course.pl @@ -0,0 +1,76 @@ +#!/usr/bin/perl + +#script to modify reserves/requests +#written 2/1/00 by chris@katipo.oc.nz +#last update 27/1/2000 by chris@katipo.co.nz + +# Copyright 2000-2002 Katipo Communications +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Output; +use C4::Reserves; +use C4::Auth; + +use Koha::CourseReserves; + +my $cgi = new CGI; +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "about.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { course_reserves => 1 }, + } +); + +my $action = $cgi->param('action'); + +if ( $action eq 'del' ) { + DelCourse( $cgi->param('course_id') ); + print $cgi->redirect("/cgi-bin/koha/course_reserves/course-reserves.pl"); +} +else { + my %params; + + $params{'course_id'} = $cgi->param('course_id') + if ( $cgi->param('course_id') ); + $params{'department'} = $cgi->param('department'); + $params{'course_number'} = $cgi->param('course_number'); + $params{'section'} = $cgi->param('section'); + $params{'course_name'} = $cgi->param('course_name'); + $params{'term'} = $cgi->param('term'); + $params{'staff_note'} = $cgi->param('staff_note'); + $params{'public_note'} = $cgi->param('public_note'); + $params{'students_count'} = $cgi->param('students_count'); + $params{'enabled'} = ( $cgi->param('enabled') eq 'on' ) ? 'yes' : 'no'; + + my $course_id = ModCourse(%params); + + my @instructors = $cgi->param('instructors'); + ModCourseInstructors( + mode => 'replace', + cardnumbers => \@instructors, + course_id => $course_id + ); + print $cgi->redirect( + "/cgi-bin/koha/course_reserves/course-details.pl?course_id=$course_id"); +} diff --git a/installer/data/mysql/en/mandatory/userflags.sql b/installer/data/mysql/en/mandatory/userflags.sql index e9d9b2e..cc683fd 100644 --- a/installer/data/mysql/en/mandatory/userflags.sql +++ b/installer/data/mysql/en/mandatory/userflags.sql @@ -15,3 +15,4 @@ INSERT INTO `userflags` VALUES(14,'editauthorities','Allow to edit authorities', INSERT INTO `userflags` VALUES(15,'serials','Allow to manage serials subscriptions',0); INSERT INTO `userflags` VALUES(16,'reports','Allow to access to the reports module',0); INSERT INTO `userflags` VALUES(17,'staffaccess','Modify login / permissions for staff users',0); +INSERT INTO `userflags` VALUES(18,'coursereserves','Course Reserves',0); diff --git a/installer/data/mysql/en/mandatory/userpermissions.sql b/installer/data/mysql/en/mandatory/userpermissions.sql index 873089a..0a56b69 100644 --- a/installer/data/mysql/en/mandatory/userpermissions.sql +++ b/installer/data/mysql/en/mandatory/userpermissions.sql @@ -46,5 +46,8 @@ INSERT INTO permissions (module_bit, code, description) VALUES (15, 'renew_subscription', 'Renew a subscription'), (15, 'routing', 'Routing'), (16, 'execute_reports', 'Execute SQL reports'), - (16, 'create_reports', 'Create SQL Reports') + (16, 'create_reports', 'Create SQL Reports'), + (18, 'manage_courses', 'Add, edit and delete courses'), + (18, 'add_reserves', 'Add course reserves'), + (18, 'delete_reserves', 'Remove course reserves') ; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index a210293..2ccb1be 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -464,6 +464,69 @@ CREATE TABLE collections_tracking ( ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8; -- +-- Table structure for table `courses` +-- +DROP TABLE IF EXISTS courses; +CREATE TABLE `courses` ( + `course_id` int(11) NOT NULL AUTO_INCREMENT, + `department` varchar(20) DEFAULT NULL, + `course_number` varchar(255) DEFAULT NULL, + `section` varchar(255) DEFAULT NULL, + `course_name` varchar(255) DEFAULT NULL, + `term` varchar(20) DEFAULT NULL, + `staff_note` mediumtext, + `public_note` mediumtext, + `students_count` varchar(20) DEFAULT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`course_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `course_instructors` +-- +DROP TABLE IF EXISTS course_instructors; +CREATE TABLE `course_instructors` ( + `course_id` int(11) NOT NULL, + `borrowernumber` int(11) NOT NULL, + PRIMARY KEY (`course_id`,`borrowernumber`), + KEY `borrowernumber` (`borrowernumber`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `course_items` +-- +DROP TABLE IF EXISTS course_items; +CREATE TABLE `course_items` ( + `ci_id` int(11) NOT NULL AUTO_INCREMENT, + `itemnumber` int(11) NOT NULL, + `itype` varchar(10) DEFAULT NULL, + `ccode` varchar(10) DEFAULT NULL, + `holdingbranch` varchar(10) DEFAULT NULL, + `location` varchar(80) DEFAULT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'no', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`ci_id`), + UNIQUE KEY `itemnumber` (`itemnumber`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `course_reserves` +-- +DROP TABLE IF EXISTS course_reserves; +CREATE TABLE `course_reserves` ( + `cr_id` int(11) NOT NULL AUTO_INCREMENT, + `course_id` int(11) NOT NULL, + `ci_id` int(11) NOT NULL, + `staff_note` mediumtext, + `public_note` mediumtext, + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`cr_id`), + UNIQUE KEY `psuedo_key` (`course_id`,`ci_id`), + KEY `course_id` (`course_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -- Table structure for table `borrower_branch_circ_rules` -- diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 49debd2..fa9cf5e 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -362,3 +362,4 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES(' INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('AutoResumeSuspendedHolds', '1', NULL , 'Allow suspended holds to be automatically resumed by a set date.', 'YesNo'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacStarRatings','all',NULL,'disable|all|details','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacBrowseResults','1','Disable/enable browsing and paging search results from the OPAC detail page.',NULL,'YesNo'); +INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UseCourseReserves', '0', 'Enable the course reserves feature.', NULL, 'YesNo'); \ No newline at end of file diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 84f0437..f787217 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -5212,6 +5212,69 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.07.00.XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('UseCourseReserves', '0', 'Enable the course reserves feature.', NULL, 'YesNo'"); + $dbh->do("INSERT INTO userflags (bit,flag,flagdesc,defaulton) VALUES ('18','coursereserves','Course Reserves','0')"); + $dbh->do(" +CREATE TABLE `courses` ( + `course_id` int(11) NOT NULL AUTO_INCREMENT, + `department` varchar(20) DEFAULT NULL, + `course_number` varchar(255) DEFAULT NULL, + `section` varchar(255) DEFAULT NULL, + `course_name` varchar(255) DEFAULT NULL, + `term` varchar(20) DEFAULT NULL, + `staff_note` mediumtext, + `public_note` mediumtext, + `students_count` varchar(20) DEFAULT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`course_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `course_instructors` ( + `course_id` int(11) NOT NULL, + `borrowernumber` int(11) NOT NULL, + PRIMARY KEY (`course_id`,`borrowernumber`), + KEY `borrowernumber` (`borrowernumber`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `course_items` ( + `ci_id` int(11) NOT NULL AUTO_INCREMENT, + `itemnumber` int(11) NOT NULL, + `itype` varchar(10) DEFAULT NULL, + `ccode` varchar(10) DEFAULT NULL, + `holdingbranch` varchar(10) DEFAULT NULL, + `location` varchar(80) DEFAULT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'no', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`ci_id`), + UNIQUE KEY `itemnumber` (`itemnumber`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `course_reserves` ( + `cr_id` int(11) NOT NULL AUTO_INCREMENT, + `course_id` int(11) NOT NULL, + `ci_id` int(11) NOT NULL, + `staff_note` mediumtext, + `public_note` mediumtext, + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`cr_id`), + UNIQUE KEY `psuedo_key` (`course_id`,`ci_id`), + KEY `course_id` (`course_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO permissions (module_bit, code, description) VALUES + (18, 'manage_courses', 'Add, edit and delete courses'), + (18, 'add_reserves', 'Add course reserves'), + (18, 'delete_reserves', 'Remove course reserves') +; + +"); + print "Upgrade to $DBversion done (Add Course Reserves ( system preference UseCourseReserves ))\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css index 68523d7..2a29f87 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css +++ b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css @@ -884,7 +884,7 @@ fieldset.rows .inputnote { visibility:visible; /* you propably don't need to change this one */ display:block; } -#newbiblio a, #addchild a, #newentry a, #newshelf a, #newmenuc .first-child, #newsupplier .first-child, #newlabel a, #newtemplate a, #newlabelbatch a, #newpatroncardbatch a, #newprofile a, #newsubscription a, #newdictionary a, #newbasket a, #newrootbudget-button, #budgets_menuc .first-child, #periods_menuc .first-child { +#newbiblio a, #addchild a, #newentry a, #newshelf a, #new_course a, #newmenuc .first-child, #newsupplier .first-child, #newlabel a, #newtemplate a, #newlabelbatch a, #newpatroncardbatch a, #newprofile a, #newsubscription a, #newdictionary a, #newbasket a, #newrootbudget-button, #budgets_menuc .first-child, #periods_menuc .first-child { padding-left : 34px; background-image: url("../../img/toolbar-new.gif"); background-position : center left; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc index 4783523..5083df4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc @@ -28,6 +28,9 @@ [% IF ( CAN_user_serials ) %]
  • Serials
  • [% END %] + [% IF ( CAN_user_coursereserves ) %] +
  • Course Reserves
  • + [% END %] [% IF ( CAN_user_reports ) %]
  • Reports
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/mainmenu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/mainmenu.inc index 46a412d..abbee70 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/mainmenu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/mainmenu.inc @@ -51,6 +51,9 @@ [% IF ( CAN_user_serials ) %]
  • Serials
  • [% END %] + [% IF ( CAN_user_coursereserves ) %] +
  • Course Reserves
  • + [% END %] [% IF ( CAN_user_editcatalogue ) %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 471aa0e..932056e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -412,3 +412,10 @@ Circulation: - and this password - pref: AutoSelfCheckPass - . + Course Reserves: + - + - pref: UseCourseReserves + choices: + yes: Use + no: "Don't use" + - course reserves diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index c92a891..4286034 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -1,3 +1,14 @@ +[% USE AuthorisedValues %] + +[% ShowCourseReserves = 0 %] +[% IF UseCourseReserves %] + [% FOREACH item IN itemloop %] + [% IF item.course_reserves %] + [% ShowCourseReserves = 1 %] + [% END %] + [% END %] +[% END %] + [% INCLUDE 'doc-head-open.inc' %] Koha › Catalog › [% IF ( unknownbiblionumber ) %] @@ -284,6 +295,7 @@ function verify_images() { [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th>Spine label</th>[% END %] [% IF ( hostrecords ) %]<th>Host records</th>[% END %] [% IF ( analyze ) %]<th>Used in</th><th></th>[% END %] + [% IF ( ShowCourseReserves ) %]<th>Course Reserves</th>[% END %] </tr> [% FOREACH itemloo IN itemloop %] <tr> @@ -420,6 +432,22 @@ function verify_images() { <td><a href="/cgi-bin/koha/cataloguing/addbiblio.pl?hostbiblionumber=[% itemloo.biblionumber %]&hostitemnumber=[% itemloo.itemnumber %]">Create analytics</a></td> [% END %] + [% IF ShowCourseReserves %] + <td> + [% IF itemloo.course_reserves %] + [% FOREACH r IN itemloo.course_reserves %] + <p> + <a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% r.course.course_id %]"> + [% r.course.course_name %] + <!--[% IF r.course.course_number %] [% r.course.course_number %] [% END %]--> + [% IF r.course.section %] [% r.course.section %] [% END %] + [% IF r.course.term %] [% AuthorisedValues.GetByCode( 'TERM', r.course.term ) %] [% END %] + </a> + </p> + [% END %] + [% END %] + </td> + [% END %] </tr> [% END %] </table> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step1.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step1.tt new file mode 100644 index 0000000..092bef8 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step1.tt @@ -0,0 +1,63 @@ +[% INCLUDE 'doc-head-open.inc' %] +<title>Koha › Course Reserves › Add Items +[% INCLUDE 'doc-head-close.inc' %] + + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +
    +
    +
    + [% IF ERROR_BARCODE_NOT_FOUND %] +
    No item found for barcode [% ERROR_BARCODE_NOT_FOUND %]
    + [% END %] + +
    + + + +
    + Add Items: Scan Barcode + +

    + +

  • + + +
  • + +
    + +
    + + + Cancel +
    +
    +
    +
    +
    +
    +
    +
    + + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt new file mode 100644 index 0000000..0ff5dca --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/add_items-step2.tt @@ -0,0 +1,131 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Course Reserves › Add Items +[% INCLUDE 'doc-head-close.inc' %] + + + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +
    +
    +
    + [% IF course_reserve %]
    This course already has this item on reserve.
    [% END %] + [% IF course_item %]
    Number of courses reserving this item: [% course_item.course_reserves.size %]
    [% END %] + +
    + + + +
    + Add [% item.title %] to [% course.course_name %] +
      +
    1. + + [% item.barcode %] + +
    2. + +
    3. + + +
    4. + +
    5. + + +
    6. + +
    7. + + +
    8. + +
    9. + + +
    10. + +
    11. + + +
    12. + +
    13. + + +
    14. + +
    +
    + +
    + + + Cancel +
    + +
    +
    +
    +
    +
    +
    + + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-details.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-details.tt new file mode 100644 index 0000000..e52b2f4 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-details.tt @@ -0,0 +1,179 @@ +[% USE AuthorisedValues %] +[% USE ItemTypes %] +[% USE Branches %] +[% INCLUDE 'doc-head-open.inc' %] +Koha › Course Reserves › New Course +[% INCLUDE 'doc-head-close.inc' %] + + + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +
    + + +
    + + + + + + + + + + + + +
    Course name[% course.course_name %]
    Term[% AuthorisedValues.GetByCode( 'TERM', course.term ) %]
    Department[% AuthorisedValues.GetByCode( 'DEPARTMENT', course.department ) %]
    Course number[% course.course_number %]
    Section[% course.section %]
    Instructors[% FOREACH i IN course.instructors %][% END %]
    Staff note[% course.staff_note %]
    Public note[% course.public_note %]
    Students count[% course.students_count %]
    Status[% IF course.enabled == 'yes' %]Active[% ELSE %]Inactive[% END %]
    + + + + + + + + + + + + + + [% IF CAN_user_coursereserves_add_reserves %][% END %] + [% IF CAN_user_coursereserves_delete_reserves %][% END %] + + + + + + [% FOREACH cr IN course_reserves %] + + + + + + + + + + + + [% IF CAN_user_coursereserves_add_reserves %] + + [% END %] + + [% IF CAN_user_coursereserves_delete_reserves %] + + [% END %] + + + + [% END %] + +
    TitleBarcodeCall numberItem typeCollectionLocationLibraryStaff notePublic note  Other course reserves
    [% cr.item.title %][% cr.item.barcode %][% cr.item.itemcallnumber %] + [% IF cr.course_item.itype %] + [% IF cr.course_item.enabled == 'yes' %] + [% ItemTypes.GetDescription( cr.item.itype ) %] + [% ELSE %] + [% ItemTypes.GetDescription( cr.course_item.itype ) %] + [% END %] + [% ELSE %] + Unchanged + [% END %] + + [% IF cr.course_item.ccode %] + [% IF cr.course_item.enabled == 'yes' %] + [% AuthorisedValues.GetByCode( 'CCODE', cr.item.ccode ) %] + [% ELSE %] + [% AuthorisedValues.GetByCode( 'CCODE', cr.course_item.ccode ) %] + [% END %] + [% ELSE %] + Unchanged + [% END %] + + [% IF cr.course_item.location %] + [% IF cr.course_item.enabled == 'yes' %] + [% AuthorisedValues.GetByCode( 'LOC', cr.item.location ) %] + [% ELSE %] + [% AuthorisedValues.GetByCode( 'LOC', cr.course_item.location ) %] + [% END %] + [% ELSE %] + Unchanged + [% END %] + + [% IF cr.course_item.holdingbranch %] + [% IF cr.course_item.enabled == 'yes' %] + [% Branches.GetName( cr.item.holdingbranch ) %] + [% ELSE %] + [% Branches.GetName( cr.course_item.holdingbranch ) %] + [% END %] + [% ELSE %] + Unchanged + [% END %] + [% cr.staff_note %][% cr.public_note %]Edit + [% IF cr.item.onloan %] + On Loan + [% ELSIF cr.item.itemlost %] + Item Lost + [% ELSE %] + Remove + [% END %] + + + [% FOREACH course IN cr.courses %] + [% UNLESS cr.course_id == course.course_id %] +

    + + [% course.course_name %] + [% IF course.section %] [% course.section %] [% END %] + [% IF course.term %] [% AuthorisedValues.GetByCode( 'TERM', course.term ) %] [% END %] + +

    + [% END %] + [% END %] +
    +
    +
    +
    + + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-reserves.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-reserves.tt new file mode 100644 index 0000000..897a3b3 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course-reserves.tt @@ -0,0 +1,102 @@ +[% USE AuthorisedValues %] +[% INCLUDE 'doc-head-open.inc' %] +Koha › Course Reserves +[% INCLUDE 'doc-head-close.inc' %] + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +
    +
    + +
    + + +
    + +
    + + +
    + +

    Courses

    + + + + + + + + + + + + + + + + + + [% FOREACH c IN courses %] + + + + + + + + + + + + [% END %] + +
    NameDept.Course #SectionTermInstructorsStaff NotePublic Note# of StudentsEnabled
    [% c.course_name %][% AuthorisedValues.GetByCode( 'DEPARTMENT', c.department ) %][% c.course_number %][% c.section %][% AuthorisedValues.GetByCode( 'TERM' c.term ) %] + [% FOREACH i IN c.instructors %] + + [% END %] + [% c.staff_note %][% c.public_note %][% c.students_count %] + [% IF c.enabled == 'yes' %] + + [% ELSE %] + + [% END %] +
    +
    +
    +
    +
    +
    + + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt new file mode 100644 index 0000000..bc2fd1b --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt @@ -0,0 +1,229 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Course Reserves › [% IF course_name %] Edit [% course_name %] [% ELSE %] New Course [% END %] +[% INCLUDE 'doc-head-close.inc' %] + + + + + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + + + +
    +
    +
    +
    +
    +
    +
    + [% IF course_id %][% END %] +
    + [% IF course_id %] Edit [% ELSE %] Create [% END %] course +
      +
    1. + + +
    2. + +
    3. + + +
    4. + +
    5. + + +
    6. + +
    7. + + +
    8. + +
    9. + + +
    10. + + +
    11. + + +
      +
      + [% FOREACH i IN instructors %] +
      + [% i.surname %], [% i.firstname %] ( Remove ) + +
      + [% END %] +
      + +
      + +
      + + +
      +
      +
    12. + + +
    13. + +
    14. + + +
    15. + +
    16. + + +
    17. + +
    18. + + [% IF enabled == 'no' %] + + [% ELSE %] + + [% END %] +
    19. +
    +
    + +
    + + + Cancel +
    + +
    +
    +
    +
    +
    +
    + + +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc index 822cb6e..51f2d5c 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc @@ -110,6 +110,7 @@
    Advanced search +[% IF ( UseCourseReserves ) %] | Course Reserves[% END %] [% IF ( OpacBrowser ) %] | Browse by hierarchy[% END %] [% IF ( OpacAuthorities ) %] | Browse by author or subject[% END %] [% IF ( opacuserlogin && reviewson && OpacShowRecentComments ) %] | Recent comments[% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-course-details.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-course-details.tt new file mode 100644 index 0000000..70ed2d1 --- /dev/null +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-course-details.tt @@ -0,0 +1,63 @@ +[% USE KohaDates %] +[% USE AuthorisedValues %] +[% USE ItemTypes %] +[% USE Branches %] +[% INCLUDE 'doc-head-open.inc' %] +[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog +[% INCLUDE 'doc-head-close.inc' %] + + +[% IF ( OpacNav ) %]
    [% ELSE %]
    [% END %] +
    +[% INCLUDE 'masthead.inc' %] + +
    +
    + + + + + + + + + +
    Course Name[% course.course_name %]
    Term[% AuthorisedValues.GetByCode( 'TERM', course.term ) %]
    Department[% AuthorisedValues.GetByCode( 'DEPARTMENT', course.department ) %]
    Course Number[% course.course_number %]
    Section[% course.section %]
    Instructors[% FOREACH i IN course.instructors %]
    [% i.firstname %] [% i.surname %]
    [% END %]
    Notes[% course.public_note %]
    + + + + + + + + + + + + + + + + [% FOREACH cr IN course_reserves %] + + + + + + + + + + + + [% END %] + +
    TitleItem typeLocationCollectionCall numberCopyStatus + Date due + Notes
    [% cr.item.title %][% ItemTypes.GetDescription( cr.item.itype ) %][% Branches.GetName( cr.item.holdingbranch ) %]
    [% AuthorisedValues.GetByCode( 'LOC', cr.item.location ) %]
    [% AuthorisedValues.GetByCode( 'CCODE', cr.item.ccode ) %][% cr.item.itemcallnumber %][% cr.item.copynumber %][% INCLUDE 'item-status.inc' item = cr.item %][% cr.issue.date_due | $KohaDates %][% cr.public_note %]
    + +
    +
    + + +[% INCLUDE 'opac-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-course-reserves.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-course-reserves.tt new file mode 100644 index 0000000..98965c9 --- /dev/null +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-course-reserves.tt @@ -0,0 +1,62 @@ +[% USE AuthorisedValues %] + +[% INCLUDE 'doc-head-open.inc' %] +[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog +[% INCLUDE 'doc-head-close.inc' %] + + +[% IF ( OpacNav ) %]
    [% ELSE %]
    [% END %] +
    +[% INCLUDE 'masthead.inc' %] + + +
    +
    +
    +
    + +
    + + + + +
    + +

    Courses

    + + + + + + + + + + + + + + + [% FOREACH c IN courses %] + + + + + + + + + [% END %] + +
    NameDept.Course #SectionTermInstructorsNotes
    [% c.course_name %][% AuthorisedValues.GetByCode( 'DEPARTMENT', c.department, 1 ) %][% c.course_number %][% c.section %][% AuthorisedValues.GetByCode( 'TERM' c.term ) %] + [% FOREACH i IN c.instructors %] +
    [% i.firstname %] [% i.surname %]
    + [% END %] +
    [% c.public_note %]
    +
    +
    +
    +
    + + +[% INCLUDE 'opac-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index cc59fb2..95fa565 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1,4 +1,14 @@ [% USE KohaDates %] +[% USE AuthorisedValues %] + +[% ShowCourseReservesHeader = 0 %] +[% IF UseCourseReserves %] + [% FOREACH ITEM_RESULT IN ITEM_RESULTS %] + [% IF ITEM_RESULT.course_reserves %] + [% ShowCourseReservesHeader = 1 %] + [% END %] + [% END %] +[% END %] [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Details for: [% title |html %][% FOREACH subtitl IN subtitle %], [% subtitl.subfield |html %][% END %] [% INCLUDE 'doc-head-close.inc' %] @@ -718,6 +728,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () { Status [% IF ( itemdata_itemnotes ) %]Notes[% END %] Date due + [% IF ( ShowCourseReservesHeader ) %]Course Reserves[% END %] [% FOREACH ITEM_RESULT IN ITEM_RESULTS %] [% IF ( item_level_itypes ) %][% UNLESS ( noItemTypeImages ) %][% IF ( ITEM_RESULT.imageurl ) %][% ITEM_RESULT.description %][% END %][% END %] [% ITEM_RESULT.description %][% END %] @@ -742,6 +753,22 @@ YAHOO.util.Event.onContentReady("furtherm", function () { [% INCLUDE 'item-status.inc' item = ITEM_RESULT %] [% IF ( itemdata_itemnotes ) %][% ITEM_RESULT.itemnotes %][% END %] [% ITEM_RESULT.datedue | $KohaDates %] + [% IF UseCourseReserves %] + + [% IF ITEM_RESULT.course_reserves %] + [% FOREACH r IN ITEM_RESULT.course_reserves %] +

    + + [% r.course.course_name %] + + [% IF r.course.section %] [% r.course.section %] [% END %] + [% IF r.course.term %] [% AuthorisedValues.GetByCode( 'TERM', r.course.term ) %] [% END %] + +

    + [% END %] + [% END %] + + [% END %] [% END %] diff --git a/opac/opac-course-details.pl b/opac/opac-course-details.pl new file mode 100755 index 0000000..d1f00b3 --- /dev/null +++ b/opac/opac-course-details.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl + +# +# Copyright 2012 Bywater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; +use C4::Koha; + +use Koha::CourseReserves; + +my $cgi = new CGI; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user( + { + template_name => "opac-course-details.tmpl", + query => $cgi, + type => "opac", + authnotrequired => 1, + debug => 1, + } +); + +my $action = $cgi->param('action') || ''; +my $course_id = $cgi->param('course_id'); + +die( "No course_id given" ) unless ( $course_id ); + +if ( $action eq 'del_reserve' ) { + DelCourseReserve( cr_id => $cgi->param('cr_id') ); +} + +my $course = GetCourse( $course_id ); +my $course_reserves = GetCourseReserves( course_id => $course_id, include_items => 1, include_count => 1 ); + +$template->param( + course => $course, + course_reserves => $course_reserves, +); + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/opac/opac-course-reserves.pl b/opac/opac-course-reserves.pl new file mode 100755 index 0000000..2c434dd --- /dev/null +++ b/opac/opac-course-reserves.pl @@ -0,0 +1,51 @@ +#!/usr/bin/perl + +# +# Copyright 2012 Bywater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; + +use C4::Auth; +use C4::Output; + +use Koha::CourseReserves; + +my $cgi = new CGI; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user( + { + template_name => "opac-course-reserves.tmpl", + query => $cgi, + type => "opac", + authnotrequired => 1, + debug => 1, + } +); + +my $search_on = $cgi->param('search_on'); + +my $courses = SearchCourses( term => $search_on, enabled => 'yes' ); + +if ( @$courses == 1 ) { + print $cgi->redirect("/cgi-bin/koha/opac-course-details.pl?course_id=" . $courses->[0]->{'course_id'}); +} else { + $template->param( courses => $courses ); + output_html_with_http_headers $cgi, $cookie, $template->output; +} diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index afc9498..ae4c641 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -49,6 +49,7 @@ use MARC::Field; use List::MoreUtils qw/any none/; use C4::Images; use Koha::DateUtils; +use Koha::CourseReserves; BEGIN { if (C4::Context->preference('BakerTaylorEnabled')) { @@ -970,4 +971,9 @@ if (C4::Context->preference('OPACLocalCoverImages') == 1) { $template->{VARS}->{localimages} = \@images; } +if ( C4::Context->preference('UseCourseReserves') ) { + foreach my $i ( @items ) { + $i->{'course_reserves'} = GetItemReservesInfo( itemnumber => $i->{'itemnumber'} ); + } +} output_html_with_http_headers $query, $cookie, $template->output; -- 1.7.2.5