Koha/C4/CourseReserves.pm
Jonathan Druart 88c29de465 Bug 20177: [sql_modes] Fix GROUP BY clause in GetCourses
Fix for:
'koha_kohadev.courses.department' isn't in GROUP BY

t/db_dependent/CourseReserves.t

A better fix would be to remove the joins and only return values from
the courses table. But more work is needed to acchieve that goal.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Test passes and the behavior of Course reserves appears to be unchanged
Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
2018-10-09 11:05:48 +00:00

1104 lines
27 KiB
Perl

package C4::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 3 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, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use List::MoreUtils qw(any);
use C4::Context;
use C4::Items qw(GetItem ModItem);
use C4::Circulation qw(GetOpenIssue);
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG @FIELDS);
BEGIN {
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(
&GetCourse
&ModCourse
&GetCourses
&DelCourse
&GetCourseInstructors
&ModCourseInstructors
&GetCourseItem
&ModCourseItem
&GetCourseReserve
&ModCourseReserve
&GetCourseReserves
&DelCourseReserve
&SearchCourses
&GetItemCourseReservesInfo
);
%EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
$DEBUG = 0;
@FIELDS = ( 'itype', 'ccode', 'holdingbranch', 'location' );
}
=head1 NAME
C4::CourseReserves - Koha course reserves module
=head1 SYNOPSIS
use C4::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 c.course_id, c.department, c.course_number, c.section, c.course_name, c.term, c.staff_note, c.public_note, c.students_count, c.enabled, c.timestamp
FROM courses c
LEFT JOIN course_reserves ON course_reserves.course_id = c.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 c.course_id, c.department, c.course_number, c.section, c.course_name, c.term, c.staff_note, c.public_note, c.students_count, c.enabled, c.timestamp ";
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 course_instructors
WHERE course_id = ?
";
C4::Context->dbh->do( $query, undef, $course_id );
$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'} || 0;
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'},
);
}
}
}
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'},
);
}
}
}
}
=head2 EnableOrDisableCourseItem
EnableOrDisableCourseItem( ci_id => $ci_id );
=cut
sub EnableOrDisableCourseItem {
my (%params) = @_;
warn identify_myself(%params) if $DEBUG;
my $ci_id = $params{'ci_id'};
return unless ( $ci_id );
my $course_item = GetCourseItem( ci_id => $ci_id );
my $info = GetItemCourseReservesInfo( itemnumber => $course_item->{itemnumber} );
my $enabled = any { $_->{course}->{enabled} eq 'yes' } @$info;
$enabled = $enabled ? 'yes' : 'no';
## 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
@$borrowers = GetCourseInstructors( $course_id );
=cut
sub GetCourseInstructors {
my ($course_id) = @_;
warn "C4::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, @borrowernumbers );
@cardnumbers = @$cardnumbers if ( ref($cardnumbers) eq 'ARRAY' );
@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'} ) if %mod_params;
## 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'} ) if %mod_params_new;
}
=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'} ) if $mod_item_params && %$mod_item_params;
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 "C4::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'} ) if %course_item_fields;
_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' );
}
EnableOrDisableCourseItem(
ci_id => $params{'ci_id'},
);
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) {
my $item = Koha::Items->find( $cr->{itemnumber} );
my $biblio = $item->biblio;
my $biblioitem = $biblio->biblioitem;
$cr->{'course_item'} = GetCourseItem( ci_id => $cr->{'ci_id'} );
$cr->{'item'} = $item;
$cr->{'biblio'} = $biblio;
$cr->{'biblioitem'} = $biblioitem;
$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 GetItemCourseReservesInfo
my $arrayref = GetItemCourseReservesInfo( itemnumber => $itemnumber );
For a given item, returns an arrayref of reserves hashrefs,
with a course hashref under the key 'course'
=cut
sub GetItemCourseReservesInfo {
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 = "%$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