Bugzilla – Attachment 11131 Details for
Bug 8215
Add Course Reserves
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Course Reserves
Course-Reserves.patch (text/plain), 114.69 KB, created by
Kyle M Hall (khall)
on 2012-07-25 13:59:33 UTC
(
hide
)
Description:
Course Reserves
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2012-07-25 13:59:33 UTC
Size:
114.69 KB
patch
obsolete
>From aacf1e0e1316bd3c8dba1f5127600ec52b75b315 Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >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. > >http://bugs.koha-community.org/show_bug.cgi?id=8215 >--- > C4/Auth.pm | 4 +- > 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 | 55 + > 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 | 71 ++ > .../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 + > 33 files changed, 2750 insertions(+), 7 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 b6dc2f5..31764e8 100644 >--- a/C4/Auth.pm >+++ b/C4/Auth.pm >@@ -194,7 +194,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 ); >@@ -202,6 +202,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 ); >@@ -330,6 +331,7 @@ sub get_template_and_user { > using_https => $in->{'query'}->https() ? 1 : 0, > noItemTypeImages => C4::Context->preference("noItemTypeImages"), > marcflavour => C4::Context->preference("marcflavour"), >+ UseCourseReserves => C4::Context->preference("UseCourseReserves"), > ); > > if ( $in->{'type'} eq "intranet" ) { >diff --git a/C4/Koha.pm b/C4/Koha.pm >index 4f386e4..46f865e 100644 >--- a/C4/Koha.pm >+++ b/C4/Koha.pm >@@ -41,6 +41,7 @@ BEGIN { > &subfield_is_koha_internal_p > &GetPrinters &GetPrinter > &GetItemTypes &getitemtypeinfo >+ &GetItemTypesFlat > &GetCcodes > &GetSupportName &GetSupportList > &get_itemtypeinfos_of >@@ -256,6 +257,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 = @_; > >@@ -1065,7 +1075,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 >@@ -1073,13 +1083,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..0046b61 >--- /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 <kyle@bywatersolutions.com> >+ >+=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 d110740..676d9e2 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; > >@@ -264,6 +265,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..02ab771 >--- /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 ( keys %params && @$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..1418421 >--- /dev/null >+++ b/course_reserves/course.pl >@@ -0,0 +1,55 @@ >+#!/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'), >+ terms => GetAuthorisedValues('TERM'), >+); >+ >+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 070e8f5..a0cc833 100644 >--- a/installer/data/mysql/en/mandatory/userpermissions.sql >+++ b/installer/data/mysql/en/mandatory/userpermissions.sql >@@ -51,5 +51,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 fc9c5f0..125ec5c 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -465,6 +465,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 7009155..8322905 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -375,3 +375,4 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ( > INSERT INTO systempreferences (variable,value,explanation,type) VALUES('EnableBorrowerFiles','0','If enabled, allows librarians to upload and attach arbitrary files to a borrower record.','YesNo'); > INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UpdateTotalIssuesOnCirc','0','Whether to update the totalissues field in the biblio on each circ.',NULL,'YesNo'); > INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('IntranetSlipPrinterJS','','Use this JavaScript for printing slips. Define at least function printThenClose(). For use e.g. with Firefox PlugIn jsPrintSetup, see http://jsprintsetup.mozdev.org/','','Free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UseCourseReserves', '0', 'Enable the course reserves feature.', NULL, 'YesNo'); >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 9eaee8b..581672d 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -5315,6 +5315,7 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { > SetVersion($DBversion); > } > >+<<<<<<< HEAD > $DBversion = "3.09.00.011"; > if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { > $dbh->do("ALTER TABLE `biblioitems` ADD `ean` VARCHAR( 13 ) NULL AFTER issn"); >@@ -5553,6 +5554,76 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { > SetVersion($DBversion); > } > >+$DBversion = "3.08.01.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; >+"); >+ >+ $dbh->do(" >+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; >+"); >+ >+ $dbh->do(" >+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; >+"); >+ >+ $dbh->do(" >+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; >+"); >+ >+ $dbh->do(" >+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/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc >index 3d71d45..f8679a0 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 ) %] > <li><a href="/cgi-bin/koha/serials/serials-home.pl">Serials</a></li> > [% END %] >+ [% IF ( CAN_user_coursereserves ) %] >+ <li><a href="/cgi-bin/koha/course_reserves/course-reserves.pl">Course Reserves</a></li> >+ [% END %] > [% IF ( CAN_user_reports ) %] > <li><a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a></li> > [% 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 ) %] > <li><a href="/cgi-bin/koha/serials/serials-home.pl">Serials</a></li> > [% END %] >+ [% IF ( CAN_user_coursereserves ) %] >+ <li><a href="/cgi-bin/koha/course_reserves/course_reserves.pl">Course Reserves</a></li> >+ [% END %] > [% IF ( CAN_user_editcatalogue ) %] > </ul></li> > >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 e07fc0d..f2bc0e0 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 >@@ -438,3 +438,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 4f00524..76f520f 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' %] > <title>Koha › Catalog › > [% IF ( unknownbiblionumber ) %] >@@ -285,6 +296,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> >@@ -421,6 +433,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</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+ >+<script type="text/javascript"> >+//<![CDATA[ >+ >+$(document).ready(function() { >+ $('#barcode').focus(); >+}); >+ >+//]]> >+</script> >+ >+<body> >+ >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/course_reserves/course-reserves.pl">Course Reserves</a> › Add Reserves for <i><a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% course.course_id %]">[% course.course_name %]</a></i></div> >+ >+<div id="doc2" class="yui-t7"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ <div class="yui-g"> >+ <div class="yui-u first"> >+ [% IF ERROR_BARCODE_NOT_FOUND %] >+ <div class="error">No item found for barcode [% ERROR_BARCODE_NOT_FOUND %]</div> >+ [% END %] >+ >+ <form method="post" action="/cgi-bin/koha/course_reserves/add_items.pl"> >+ <input type="hidden" name="course_id" value="[% course.course_id %]" /> >+ <input type="hidden" name="action" value="lookup" /> >+ >+ <fieldset class="rows"> >+ <legend>Add Items: Scan Barcode</legend> >+ >+ <p> >+ >+ <li> >+ <label class="required" for="barcode">Item Barcode:</label> >+ <input id="barcode" name="barcode" type="text" /> >+ </li> >+ </ol> >+ </fieldset> >+ >+ <fieldset class="action"> >+ <input type="submit" value="Submit" class="submit" /> >+ >+ <a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% course.course_id %]" class="cancel">Cancel</a> >+ </fieldset> >+ </form> >+ </div> >+ </div> >+ </div> >+ </div> >+ </div> >+</div> >+ >+ >+[% 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' %] >+<title>Koha › Course Reserves › Add Items</title> >+[% INCLUDE 'doc-head-close.inc' %] >+ >+<script type="text/javascript"> >+//<![CDATA[ >+$(document).ready(function() { >+ $('#submit').focus(); >+}); >+//]]> >+</script> >+ >+</head> >+ >+<body> >+ >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/course_reserves/course-reserves.pl">Course Reserves</a> › Reserve <i><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% item.biblionumber %]">[% item.title %]</a></i> for <i><a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% course.course_id %]">[% course.course_name %]</a></i></div> >+ >+<div id="doc2" class="yui-t7"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ <div class="yui-g"> >+ <div class="yui-u first"> >+ [% IF course_reserve %]<div class="warn" id="already_on_reserve_this">This course already has this item on reserve.<div>[% END %] >+ [% IF course_item %]<div class="warn" id="already_on_reserve">Number of courses reserving this item: [% course_item.course_reserves.size %]<div>[% END %] >+ >+ <form method="post" action="/cgi-bin/koha/course_reserves/add_items.pl"> >+ <input type="hidden" name="course_id" value="[% course.course_id %]" /> >+ <input type="hidden" name="action" value="add" /> >+ >+ <fieldset class="rows"> >+ <legend>Add <i>[% item.title %]</i> to <i>[% course.course_name %]</i></legend> >+ <ol> >+ <li> >+ <label for="barcode">Barcode:</label> >+ <span id="barcode">[% item.barcode %]</span> >+ <input type="hidden" name="itemnumber" value="[% item.itemnumber %]" /> >+ </li> >+ >+ <li> >+ <label class="required" for="itype">Item Type:</label> >+ <select id="itype" name="itype"> >+ <option value="">LEAVE UNCHANGED</option> >+ >+ [% FOREACH it IN itypes %] >+ [% IF course_item.itype && ( ( course.enabled == 'yes' && it.itemtype == item.itype ) || ( course.enabled == 'no' && it.itemtype == course_item.itype ) ) %] >+ <option value="[% it.itemtype %]" selected="selected">[% it.description %]</option> >+ [% ELSE %] >+ <option value="[% it.itemtype %]">[% it.description %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ >+ <li> >+ <label class="required" for="ccode">Collection Code:</label> >+ <select id="ccode" name="ccode"> >+ <option value="">LEAVE UNCHANGED</option> >+ >+ [% FOREACH c IN ccodes %] >+ [% IF course_item.ccode && ( ( course.enabled == 'yes' && c.authorised_value == item.ccode ) || ( course.enabled == 'no' && c.authorised_value == course_item.ccode ) ) %] >+ <option value="[% c.authorised_value %]" selected="selected">[% c.lib %]</option> >+ [% ELSE %] >+ <option value="[% c.authorised_value %]">[% c.lib %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ >+ <li> >+ <label class="required" for="location">Shelving Location:</label> >+ <select id="location" name="location"> >+ <option value="">LEAVE UNCHANGED</option> >+ >+ [% FOREACH s IN locations %] >+ [% IF course_item.location && ( ( course.enabled == 'yes' && s.authorised_value == item.location ) || ( course.enabled == 'no' && s.authorised_value == course_item.location ) ) %] >+ <option value="[% s.authorised_value %]" selected="selected">[% s.lib %]</option> >+ [% ELSE %] >+ <option value="[% s.authorised_value %]">[% s.lib %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ >+ <li> >+ <label class="required" for="holdingbranch">Holding Library:</label> >+ <select id="holdingbranch" name="holdingbranch"> >+ <option value="">LEAVE UNCHANGED</option> >+ >+ [% FOREACH b IN branches %] >+ [% IF course_item.holdingbranch && ( ( course.enabled == 'yes' && b.value == item.holdingbranch ) || ( course.enabled == 'no' && b.value == course_item.holdingbranch ) ) %] >+ <option value="[% b.value %]" selected="selected">[% b.branchname %]</option> >+ [% ELSE %] >+ <option value="[% b.value %]">[% b.branchname %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ >+ <li> >+ <label for="staff_note">Staff note:</label> >+ <textarea name="staff_note" id="staff_note">[% course_reserve.staff_note %]</textarea> >+ </li> >+ >+ <li> >+ <label for="public_note">Public note:</label> >+ <textarea name="public_note" id="public_note">[% course_reserve.public_note %]</textarea> >+ </li> >+ >+ </ol> >+ </fieldset> >+ >+ <fieldset class="action"> >+ <input type="submit" id="submit" value="Save" class="submit" /> >+ >+ <a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% course.course_id %]" class="cancel">Cancel</a> >+ </fieldset> >+ >+ </div> >+ </div> >+ </div> >+ </div> >+ </div> >+</div> >+ >+ >+[% 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..c599d65 >--- /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' %] >+<title>Koha › Course Reserves › New Course</title> >+[% INCLUDE 'doc-head-close.inc' %] >+ >+<script type="text/javascript"> >+//<![CDATA[ >+ >+ function confirmItemDelete(){ >+ return confirm( _('Are you sure you want to delete this item?'); >+ } >+ >+//]]> >+</script> >+ >+</head> >+ >+<body> >+ >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/course_reserves/course-reserves.pl">Course Reserves</a> › Course Details for <i>[% course.course_name %]</i></div> >+ >+<div id="doc2" class="yui-t7"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div id="toolbar"> >+ <script type="text/javascript"> >+ //<![CDATA[ >+ $(document).ready(function(){ >+ addItemsButton = new YAHOO.widget.Button("add_items"); >+ editCourseButton = new YAHOO.widget.Button("edit_course"); >+ deleteCourseButton = new YAHOO.widget.Button("delete_course"); >+ >+ deleteCourseButton.on("click", confirmDelete ); >+ }); >+ >+ function confirmDelete(p_oEvent){ >+ if ( ! confirm( _('Are you sure you want to delete this course?') ) ) { >+ YAHOO.util.Event.stopEvent( p_oEvent ); >+ } >+ } >+ >+ //]]> >+ </script> >+ <ul class="toolbar"> >+ [% IF CAN_user_coursereserves_add_reserves %]<li><a id="add_items" href="/cgi-bin/koha/course_reserves/add_items.pl?course_id=[% course.course_id %]">Add Reserves</a></li>[% END %] >+ <li><a id="edit_course" href="/cgi-bin/koha/course_reserves/course.pl?course_id=[% course.course_id %]">Edit Course</a></li> >+ <li><a id="delete_course" href="/cgi-bin/koha/course_reserves/mod_course.pl?course_id=[% course.course_id %]&action=del">Delete Course</a></li> >+ </ul> >+ </div><!-- /toolbar --> >+ >+ <table> >+ <tr><th>Course name</th><td>[% course.course_name %]</td></tr> >+ <tr><th>Term</th><td>[% AuthorisedValues.GetByCode( 'TERM', course.term ) %]</td></tr> >+ <tr><th>Department</th><td>[% AuthorisedValues.GetByCode( 'DEPARTMENT', course.department ) %]</td></tr> >+ <tr><th>Course number</th><td>[% course.course_number %]</td></tr> >+ <tr><th>Section</th><td>[% course.section %]</td></tr> >+ <tr><th>Instructors</th><td>[% FOREACH i IN course.instructors %]<div class="instructor"><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% i.borrowernumber %]">[% i.firstname %] [% i.surname %]</a></div>[% END %]</td></tr> >+ <tr><th>Staff note</th><td>[% course.staff_note %]</td></tr> >+ <tr><th>Public note</th><td>[% course.public_note %]</td></tr> >+ <tr><th>Students count</th><td>[% course.students_count %]</td></tr> >+ <tr><th>Status</th><td>[% IF course.enabled == 'yes' %]Active[% ELSE %]Inactive[% END %]</td></tr> >+ </table> >+ >+ <table> >+ <thead> >+ <tr> >+ <th>Title</th> >+ <th>Barcode</th> >+ <th>Call number</th> >+ <th>Item type</th> >+ <th>Collection</th> >+ <th>Location</th> >+ <th>Library</th> >+ <th>Staff note</th> >+ <th>Public note</th> >+ [% IF CAN_user_coursereserves_add_reserves %]<th> <!-- Edit --></th>[% END %] >+ [% IF CAN_user_coursereserves_delete_reserves %]<th> <!-- Remove --></th>[% END %] >+ <th>Other course reserves</th> >+ </tr> >+ </thead> >+ >+ <tbody> >+ [% FOREACH cr IN course_reserves %] >+ <tr> >+ <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% cr.item.biblionumber %]">[% cr.item.title %]</a></td> >+ <td><a href="/cgi-bin/koha/catalogue/moredetail.pl?itemnumber=[% cr.item.itemnumber %]&biblionumber=[% cr.item.biblionumber %]&bi=[% cr.item.biblioitemnumber %]">[% cr.item.barcode %]</a></td> >+ <td>[% cr.item.itemcallnumber %]</td> >+ <td> >+ [% 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 %] >+ <i>Unchanged</i> >+ [% END %] >+ </td> >+ <td> >+ [% 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 %] >+ <i>Unchanged</i> >+ [% END %] >+ </td> >+ <td> >+ [% 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 %] >+ <i>Unchanged</i> >+ [% END %] >+ </td> >+ <td> >+ [% 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 %] >+ <i>Unchanged</i> >+ [% END %] >+ </td> >+ <td>[% cr.staff_note %]</td> >+ <td>[% cr.public_note %]</td> >+ >+ [% IF CAN_user_coursereserves_add_reserves %] >+ <td><a href="add_items.pl?course_id=[% course.course_id %]&barcode=[% cr.item.barcode %]&action=lookup">Edit</a></td> >+ [% END %] >+ >+ [% IF CAN_user_coursereserves_delete_reserves %] >+ <td> >+ [% IF cr.item.onloan %] >+ On Loan >+ [% ELSIF cr.item.itemlost %] >+ Item Lost >+ [% ELSE %] >+ <a href="course-details.pl?course_id=[% course.course_id %]&action=del_reserve&cr_id=[% cr.cr_id %]" onclick="return confirmItemDelete()" >Remove</a> >+ [% END %] >+ >+ </td> >+ [% END %] >+ >+ <td> >+ [% FOREACH course IN cr.courses %] >+ [% UNLESS cr.course_id == course.course_id %] >+ <p> >+ <a href="course-details.pl?course_id=[% course.course_id %]"> >+ [% course.course_name %] >+ [% IF course.section %] [% course.section %] [% END %] >+ [% IF course.term %] [% AuthorisedValues.GetByCode( 'TERM', course.term ) %] [% END %] >+ </a> >+ </p> >+ [% END %] >+ [% END %] >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ </div> >+ </div> >+</div> >+ >+ >+[% 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' %] >+<title>Koha › Course Reserves</title> >+[% INCLUDE 'doc-head-close.inc' %] >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script> >+</head> >+<body id="lists_shelves" class="lists"> >+ >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/course_reserves/course-reserves.pl">Course Reserves</a></div> >+ >+<div id="doc2" class="yui-t7"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ <div class="yui-g"> >+ >+ <div id="toolbar"> >+ <script type="text/javascript"> >+ //<![CDATA[ >+ $(document).ready(function(){ >+ newCourseButton = new YAHOO.widget.Button("new_course"); >+ }); >+ //]]> >+ </script> >+ <ul class="toolbar"> >+ <li><a id="new_course" href="/cgi-bin/koha/course_reserves/course.pl">New Course</a></li> >+ </ul> >+ </div><!-- /toolbar --> >+ >+ <div id="search-toolbar"> >+ <script type="text/javascript"> >+ //<![CDATA[ >+ function submitSearchForm(p_oEvent){ >+ $('#search_courses_form').submit(); >+ } >+ >+ $(document).ready(function(){ >+ newCourseButton = new YAHOO.widget.Button("search_courses"); >+ newCourseButton.on("click", submitSearchForm ); >+ }); >+ //]]> >+ </script> >+ <ul class="toolbar"> >+ <li><form id="search_courses_form"><input type="text" name="search_on" id="search_on"></form></li> >+ <li><a id="search_courses">Search Courses</a></li> >+ </ul> >+ </div><!-- /toolbar --> >+ >+ <h1>Courses</h1> >+ <table id="course_reserves_table"> >+ <thead> >+ <tr> >+ <th>Name</th> >+ <th>Dept.</th> >+ <th>Course #</th> >+ <th>Section</th> >+ <th>Term</th> >+ <th>Instructors</th> >+ <th>Staff Note</th> >+ <th>Public Note</th> >+ <th># of Students</th> >+ <th>Enabled</th> >+ </tr> >+ </thead> >+ >+ <tbody> >+ [% FOREACH c IN courses %] >+ <tr> >+ <td><a href="course-details.pl?course_id=[% c.course_id %]">[% c.course_name %]</a></td> >+ <td>[% AuthorisedValues.GetByCode( 'DEPARTMENT', c.department ) %]</td> >+ <td>[% c.course_number %]</td> >+ <td>[% c.section %]</td> >+ <td>[% AuthorisedValues.GetByCode( 'TERM' c.term ) %]</td> >+ <td> >+ [% FOREACH i IN c.instructors %] >+ <div class="instructor"><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% i.borrowernumber %]">[% i.firstname %] [% i.surname %]</a></div> >+ [% END %] >+ </td> >+ <td>[% c.staff_note %]</td> >+ <td>[% c.public_note %]</td> >+ <td>[% c.students_count %]</td> >+ <td> >+ [% IF c.enabled == 'yes' %] >+ <img src="/intranet-tmpl/prog/img/approve.gif" /> >+ [% ELSE %] >+ <img src="http://kohadev:8080/intranet-tmpl/prog/img/deny.gif" /> >+ [% END %] >+ </td> >+ [% END %] >+ </tbody> >+ </table> >+ </div> >+ </div> >+ </div> >+ </div> >+</div> >+ >+ >+[% 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' %] >+<title>Koha › Course Reserves › [% IF course_name %] Edit [% course_name %] [% ELSE %] New Course [% END %]</title> >+[% INCLUDE 'doc-head-close.inc' %] >+ >+<script type="text/javascript"> >+//<![CDATA[ >+ >+ function Check(f) { >+ var _alertString = ""; >+ >+ if( ! $("#department").val() ) { >+ _alertString += _("- You must choose a department") + "\n"; >+ } >+ >+ if( ! $("#course_number").val() ) { >+ _alertString += _("- You must choose a course number") + "\n"; >+ } >+ >+ if( ! $("#course_name").val() ) { >+ _alertString += _("- You must add a course name") + "\n"; >+ } >+ >+ if ( _alertString.length ) { >+ var alertHeader; >+ alertHeader = _("Form not submitted because of the following problem(s)"); >+ alertHeader += "\n------------------------------------------------------------------------------------\n\n"; >+ >+ alert( alertHeader + _alertString ); >+ } else { >+ f.submit(); >+ } >+ } >+ >+//]]> >+</script> >+ >+<script type="text/javascript"> >+//<![CDATA[ >+YAHOO.util.Event.onContentReady("find_instructor", function() { >+ new function() { >+ // Define a custom formatter function >+ this.fnCustomFormatter = function(oResultItem, sQuery) { >+ var name = oResultItem[0]; >+ var cardnumber = oResultItem[1]; >+ var address = oResultItem[2]; >+ var city = oResultItem[3]; >+ var zip = oResultItem[4]; >+ >+ var aMarkup = [ >+ "<div class=\"sample-result\">", >+ name, >+ " (", >+ cardnumber, >+ ")<small> -- ", >+ address, >+ ", ", >+ city, >+ "<\/small>", >+ "<\/div>"]; >+ return (aMarkup.join("")); >+ }; >+ >+ // Instantiate one XHR DataSource and define schema as an array: >+ // ["Record Delimiter", >+ // "Field Delimiter"] >+ this.oACDS = new YAHOO.widget.DS_XHR("/cgi-bin/koha/circ/ysearch.pl", ["\n", "\t"]); >+ this.oACDS.responseType = YAHOO.widget.DS_XHR.TYPE_FLAT; >+ this.oACDS.maxCacheEntries = 60; >+ this.oACDS.queryMatchSubset = true; >+ >+ // Instantiate first AutoComplete >+ var myInput = document.getElementById('find_instructor'); >+ var myContainer = document.getElementById('find_instructor_container'); >+ this.oAutoComp = new YAHOO.widget.AutoComplete(myInput,myContainer,this.oACDS); >+ this.oAutoComp.formatResult = this.fnCustomFormatter; >+ >+ var myHandler = function(sType, aArgs) { >+ var myAC = aArgs[0]; // reference back to the AC instance >+ var elLI = aArgs[1]; // reference to the selected LI element >+ var oData = aArgs[2]; // object literal of selected item's result data >+ >+ AddInstructor( oData[0], oData[1] ); >+ }; >+ >+ this.oAutoComp.itemSelectEvent.subscribe( myHandler ); >+} >+}); >+ >+function AddInstructor( name, cardnumber ) { >+ div = "<div id='borrower_" + cardnumber + "'>" + name + " ( <a href='#' onclick='RemoveInstructor(" + cardnumber + ");'> Remove </a> ) <input type='hidden' name='instructors' value='" + cardnumber + "' /></div>"; >+ $('#instructors').append( div ); >+ >+ $('#find_instructor').val('').focus(); >+} >+ >+function RemoveInstructor( cardnumber ) { >+ $( '#borrower_' + cardnumber ).remove(); >+} >+ >+//]]> >+</script> >+ >+</head> >+ >+<body> >+ >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/course_reserves/course-reserves.pl">Course Reserves</a> › [% IF course_name %] Edit <i>[% course_name %]</i> [% ELSE %] New Course [% END %]</div> >+ >+<div id="doc2" class="yui-t7"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ <div class="yui-g"> >+ <div class="yui-u first"> >+ <form method="post" action="/cgi-bin/koha/course_reserves/mod_course.pl"> >+ [% IF course_id %]<input type="hidden" name="course_id" value="[% course_id %]" />[% END %] >+ <fieldset class="rows"> >+ <legend>[% IF course_id %] Edit [% ELSE %] Create [% END %] course</legend> >+ <ol> >+ <li> >+ <label class="required" for="department">Department:</label> >+ <select id="department" name="department"> >+ <option value="">Select A Department</option> >+ >+ [% FOREACH d IN departments %] >+ [% IF d.authorised_value == department %] >+ <option value="[% d.authorised_value %]" selected="selected">[% d.lib %]</option> >+ [% ELSE %] >+ <option value="[% d.authorised_value %]">[% d.lib %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ >+ <li> >+ <label class="required" for="course_number">Course number:</label> >+ <input id="course_number" name="course_number" type="text" value="[% course_number %]" /> >+ </li> >+ >+ <li> >+ <label for="section">Section:</label> >+ <input id="section" name="section" type="text" value="[% section %]"/> >+ </li> >+ >+ <li> >+ <label class="required" for="course_name">Course name:</label> >+ <input id="course_name" name="course_name" type="text" value="[% course_name %]" /> >+ </li> >+ >+ <li> >+ <label for="term">Term:</label> >+ <select id="term" name="term"> >+ <option value=""></option> >+ >+ [% FOREACH t IN terms %] >+ [% IF t.authorised_value == term %] >+ <option value="[% t.authorised_value %]" selected="selected">[% t.lib %]</option> >+ [% ELSE %] >+ <option value="[% t.authorised_value %]">[% t.lib %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ >+ <!-- TODO: Add Instructors --> >+ <li> >+ <label for="instructors">Instructors:</label> >+ >+ <fieldset> >+ <div id="instructors"> >+ [% FOREACH i IN instructors %] >+ <div id="borrower_[% i.cardnumber %]"> >+ [% i.surname %], [% i.firstname %] ( <a href='#' onclick='RemoveInstructor( [% i.cardnumber %] );'> Remove </a> ) >+ <input type='hidden' name='instructors' value='[% i.cardnumber %]' /> >+ </div> >+ [% END %] >+ </div> >+ >+ </fieldset> >+ >+ <fieldset> >+ <label for="find_instructor">Instructor Search:</label> >+ <input autocomplete="off" id="find_instructor" type="text" style="width:150px" /> >+ <div id="find_instructor_container"></div> >+ </fieldset> >+ <li> >+ <label for="staff_note">Staff note:</label> >+ <textarea name="staff_note" id="staff_note">[% staff_note %]</textarea> >+ </li> >+ >+ <li> >+ <label for="public_note">Public note:</label> >+ <textarea name="public_note" id="public_note">[% public_note %]</textarea> >+ </li> >+ >+ <li> >+ <label for="students_count">Number of students:</label> >+ <input id="students_count" name="students_count" type="text" value="[% students_count %]" /> >+ </li> >+ >+ <li> >+ <label for="enabled">Enabled?</label> >+ [% IF enabled == 'no' %] >+ <input type="checkbox" name="enabled" id="enabled" /> >+ [% ELSE %] >+ <input type="checkbox" name="enabled" id="enabled" checked="checked" /> >+ [% END %] >+ </li> >+ </ol> >+ </fieldset> >+ >+ <fieldset class="action"> >+ <input type="submit" onclick="Check(this.form); return false;" value="Save" class="submit" /> >+ >+ <a href="/cgi-bin/koha/course_reserves/course-reserves.pl" class="cancel">Cancel</a> >+ </fieldset> >+ >+ </div> >+ </div> >+ </div> >+ </div> >+ </div> >+</div> >+ >+ >+[% 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 @@ > > <div id="moresearches"> > <a href="/cgi-bin/koha/opac-search.pl">Advanced search</a> >+[% IF ( UseCourseReserves ) %]<span class="pipe"> | </span><a href="/cgi-bin/koha/opac-course-reserves.pl">Course Reserves</a>[% END %] > [% IF ( OpacBrowser ) %]<span class="pipe"> | </span><a href="/cgi-bin/koha/opac-browser.pl">Browse by hierarchy</a>[% END %] > [% IF ( OpacAuthorities ) %]<span class="pipe"> | </span><a href="/cgi-bin/koha/opac-authorities-home.pl">Browse by author or subject</a>[% END %] > [% IF ( opacuserlogin && reviewson && OpacShowRecentComments ) %]<span class="pipe"> | </span><a href="/cgi-bin/koha/opac-showreviews.pl">Recent comments</a>[% 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' %] >+</head> >+<body id="opac-main"> >+[% IF ( OpacNav ) %]<div id="doc3" class="yui-t1">[% ELSE %]<div id="doc3" class="yui-t7">[% END %] >+ <div id="bd"> >+[% INCLUDE 'masthead.inc' %] >+ >+<div id="doc2" class="yui-t7"> >+ <div id="yui-main"> >+ >+ <table> >+ <tr><th>Course Name</th><td>[% course.course_name %]</td></tr> >+ <tr><th>Term</th><td>[% AuthorisedValues.GetByCode( 'TERM', course.term ) %]</td></tr> >+ <tr><th>Department</th><td>[% AuthorisedValues.GetByCode( 'DEPARTMENT', course.department ) %]</td></tr> >+ <tr><th>Course Number</th><td>[% course.course_number %]</td></tr> >+ <tr><th>Section</th><td>[% course.section %]</td></tr> >+ <tr><th>Instructors</th><td>[% FOREACH i IN course.instructors %]<div class="instructor">[% i.firstname %] [% i.surname %]</div>[% END %]</td></tr> >+ <tr><th>Notes</th><td>[% course.public_note %]</td></tr> >+ </table> >+ >+ <table> >+ <thead> >+ <tr> >+ <th>Title</th> >+ <th>Item type</th> >+ <th>Location</th> >+ <th>Collection</th> >+ <th>Call number</th> >+ <th>Copy</th> >+ <th>Status</td> >+ <th>Date due</td> >+ <th>Notes</th> >+ </tr> >+ </thead> >+ >+ <tbody> >+ [% FOREACH cr IN course_reserves %] >+ <tr> >+ <td><a href="opac-detail.pl?biblionumber=[% cr.item.biblionumber %]">[% cr.item.title %]</a></td> >+ <td>[% ItemTypes.GetDescription( cr.item.itype ) %]</td> >+ <td>[% Branches.GetName( cr.item.holdingbranch ) %] <br/> <i>[% AuthorisedValues.GetByCode( 'LOC', cr.item.location ) %]</i></td> >+ <td>[% AuthorisedValues.GetByCode( 'CCODE', cr.item.ccode ) %]</td> >+ <td>[% cr.item.itemcallnumber %]</td> >+ <td>[% cr.item.copynumber %]</td> >+ <td>[% INCLUDE 'item-status.inc' item = cr.item %]</td> >+ <td>[% cr.issue.date_due | $KohaDates %]</td> >+ <td>[% cr.public_note %]</td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ >+ </div> >+</div> >+ >+ >+[% 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' %] >+</head> >+<body id="opac-main"> >+[% IF ( OpacNav ) %]<div id="doc3" class="yui-t1">[% ELSE %]<div id="doc3" class="yui-t7">[% END %] >+ <div id="bd"> >+[% INCLUDE 'masthead.inc' %] >+ >+ >+<div id="doc2" class="yui-t7"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ <div class="yui-g"> >+ >+ <div id="search-toolbar"> >+ <form id="search_courses_form"> >+ <input type="text" name="search_on" id="search_on" /> >+ <input type="submit" value="Search" /> >+ </form> >+ </div><!-- /toolbar --> >+ >+ <h1>Courses</h1> >+ <table id="course_reserves_table"> >+ <thead> >+ <tr> >+ <th>Name</th> >+ <th>Dept.</th> >+ <th>Course #</th> >+ <th>Section</th> >+ <th>Term</th> >+ <th>Instructors</th> >+ <th>Notes</th> >+ </tr> >+ </thead> >+ >+ <tbody> >+ [% FOREACH c IN courses %] >+ <tr> >+ <td><a href="opac-course-details.pl?course_id=[% c.course_id %]">[% c.course_name %]</a></td> >+ <td>[% AuthorisedValues.GetByCode( 'DEPARTMENT', c.department, 1 ) %]</td> >+ <td>[% c.course_number %]</td> >+ <td>[% c.section %]</td> >+ <td>[% AuthorisedValues.GetByCode( 'TERM' c.term ) %]</td> >+ <td> >+ [% FOREACH i IN c.instructors %] >+ <div class="instructor">[% i.firstname %] [% i.surname %]</div> >+ [% END %] >+ </td> >+ <td>[% c.public_note %]</td> >+ [% END %] >+ </tbody> >+ </table> >+ </div> >+ </div> >+ </div> >+</div> >+ >+ >+[% 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 5e2b55e..a9dc039 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' %] >@@ -724,6 +734,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () { > [% ELSIF show_priority %] > <th>Item hold queue priority</th> > [% END %] >+ [% IF ( ShowCourseReservesHeader ) %]<th id="item_coursereserves">Course Reserves</th>[% END %] > </tr></thead> > <tbody>[% FOREACH ITEM_RESULT IN ITEM_RESULTS %] > <tr>[% IF ( item_level_itypes ) %]<td>[% UNLESS ( noItemTypeImages ) %][% IF ( ITEM_RESULT.imageurl ) %]<img src="[% ITEM_RESULT.imageurl %]" title="[% ITEM_RESULT.description %]" alt="[% ITEM_RESULT.description %]" />[% END %][% END %] [% ITEM_RESULT.description %]</td>[% END %] >@@ -761,6 +772,22 @@ YAHOO.util.Event.onContentReady("furtherm", function () { > [% END %] > </td> > [% END %] >+ [% IF UseCourseReserves %] >+ <td> >+ [% IF ITEM_RESULT.course_reserves %] >+ [% FOREACH r IN ITEM_RESULT.course_reserves %] >+ <p> >+ <a href="opac-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 %]</tbody> > </table> >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 0bafabd..902249e 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')) { >@@ -1000,4 +1001,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
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 8215
:
9990
|
10181
|
10224
|
11131
|
11612
|
11657
|
11677
|
11678
|
11679
|
11680
|
11681
|
11682
|
11683
|
11860
|
11861
|
11862
|
11865
|
11875
|
11881
|
11882
|
11980
|
12039
|
12120
|
12128
|
12188
|
12189
|
12192
|
12246
|
12361
|
12400
|
12413
|
12414
|
12593
|
12627
|
13496
|
13497
|
13498
|
13499
|
15195
|
15196
|
15197
|
15198
|
15199
|
16228
|
16229
|
16251
|
16252
|
16532
|
16533
|
16534
|
16536
|
16537
|
16545
|
16567
|
16568
|
16587
|
16588
|
16599
|
16621
|
16623
|
16634
|
17333
|
17334
|
17335
|
17336
|
17337
|
17377
|
17378
|
17379
|
17894
|
17895
|
17896
|
17897
|
17898
|
17899
|
18274
|
18275
|
18276
|
18277
|
18278
|
18279
|
18282
|
18283
|
18284
|
18285
|
18286
|
18287
|
18288
|
18289
|
18290
|
18291
|
18292
|
18293
|
21885
|
23264