Koha/C4/CourseReserves.pm
Nick Clemens 02326ebf24
Bug 30016: Remove GetOpenIssue subroutine
This patch adjusts the code that uses GetOpenIssue to use/find a Koha::Checkout object
instead

To test:
1 - Add a course to course reserves
2 - Create an item with barcode TESTKOC
3 - Add the item to a course
4 - Checkout the item
5 - View course details on stff and opac and confirm item shows as checked out and due date displays
6 - prove t/db_dependent/Circulation/issue.t t/db_dependent/Circulation.t t/db_dependent/CourseReserves.t
7 - Browse to Circulation->Upload offline circulation
8 - Upload a file to return the item: https://wiki.koha-community.org/wiki/Koha_offline_circulation_file_format
9 - Confirm item is returned

Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
2022-08-31 08:50:37 -03:00

1089 lines
29 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 Koha::Courses;
use Koha::Course::Instructors;
use Koha::Course::Items;
use Koha::Course::Reserves;
use Koha::Checkouts;
use vars qw(@FIELDS);
our (@ISA, @EXPORT_OK);
BEGIN {
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(
GetCourse
ModCourse
GetCourses
DelCourse
GetCourseInstructors
ModCourseInstructors
GetCourseItem
ModCourseItem
GetCourseReserve
ModCourseReserve
GetCourseReserves
DelCourseReserve
SearchCourses
GetItemCourseReservesInfo
);
@FIELDS = ( 'itype', 'ccode', 'homebranch', '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) = @_;
my $course = Koha::Courses->find( $course_id );
return unless $course;
$course = $course->unblessed;
my $dbh = C4::Context->dbh;
my $query = "
SELECT b.* FROM course_instructors ci
LEFT JOIN borrowers b ON ( ci.borrowernumber = b.borrowernumber )
WHERE course_id = ?
";
my $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) = @_;
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) = @_;
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) = @_;
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) = @_;
my $ci_id = $params{'ci_id'};
return unless ( $ci_id );
my $course_item = GetCourseItem( ci_id => $ci_id );
my $info = $course_item->{itemnumber} ? GetItemCourseReservesInfo( itemnumber => $course_item->{itemnumber} ) : GetItemCourseReservesInfo( biblionumber => $course_item->{biblionumber} );
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, $enabled );
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) = @_;
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) = @_;
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 {
Given one of biblionumber, itenumber, or ci_id, returns hashref of the course_items values
$course_item = GetCourseItem( itemnumber => $itemnumber [, ci_id => $ci_id ] );
$course_item = GetCourseItem( biblionumber => $biblionumber [, ci_id => $ci_id ]);
$course_item = GetCourseItem( ci_id => $ci_id );
=cut
sub GetCourseItem {
my (%params) = @_;
my $ci_id = $params{'ci_id'};
my $itemnumber = $params{'itemnumber'};
my $biblionumber = $params{'biblionumber'};
return unless ( $itemnumber xor $biblionumber xor $ci_id );
my ( $field, $value );
if ( $itemnumber ) {
$field = 'itemnumber';
$value = $itemnumber;
} elsif ( $biblionumber ) {
$field = 'biblionumber';
$value = $biblionumber;
} else {
$field = 'ci_id';
$value = $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. Must be passed either an itemnumber or biblionumber parameter
=cut
sub ModCourseItem {
my (%params) = @_;
my $itemnumber = $params{'itemnumber'};
my $biblionumber = $params{'biblionumber'};
return unless ($itemnumber xor $biblionumber);
my $course_item = $itemnumber ? GetCourseItem( itemnumber => $itemnumber ) : GetCourseItem( biblionumber => $biblionumber );
if ( $itemnumber and !$biblionumber ) {
$biblionumber = Koha::Items->find( $itemnumber )->biblionumber;
$params{biblionumber} = $biblionumber;
}
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) = @_;
$params{homebranch} ||= undef; # Can't be empty string, FK constraint
$params{holdingbranch} ||= undef; # Can't be empty string, FK constraint
my %data = map { $_ => $params{$_} } @FIELDS;
my %enabled = map { $_ . "_enabled" => $params{ $_ . "_enabled" } } @FIELDS;
my $ci = Koha::Course::Item->new(
{
itemnumber => $params{itemnumber},
biblionumber => $params{biblionumber},
%data,
%enabled,
}
)->store();
return $ci->id;
}
=head2 _UpdateCourseItem
_UpdateCourseItem( %params );
=cut
sub _UpdateCourseItem {
my (%params) = @_;
my $ci_id = $params{'ci_id'};
my $course_item = $params{'course_item'};
$params{homebranch} ||= undef; # Can't be empty string, FK constraint
$params{holdingbranch} ||= undef; # Can't be empty string, FK constraint
return unless ( $ci_id || $course_item );
$course_item = Koha::Course::Items->find( $ci_id || $course_item->{ci_id} );
my %data = map { $_ => $params{$_} } @FIELDS;
my %enabled = map { $_ . "_enabled" => $params{ $_ . "_enabled" } } @FIELDS;
if ( $course_item->itemnumber ) {
# biblio-level course items don't store any of these fields
my $item = Koha::Items->find( $course_item->itemnumber );
# Handle updates to changed fields for a course item, both adding and removing
if ( $course_item->is_enabled ) {
my $item_fields = {};
for my $field ( @FIELDS ) {
my $field_enabled = $field . '_enabled';
my $field_storage = $field . '_storage';
# Find newly enabled field and add item value to storage
if ( $params{$field_enabled} && !$course_item->$field_enabled ) {
$enabled{$field_storage} = $item->$field;
$item_fields->{$field} = $params{$field};
}
# Find newly disabled field and copy the storage value to the item, unset storage value
elsif ( !$params{$field_enabled} && $course_item->$field_enabled ) {
$item_fields->{$field} = $course_item->$field_storage;
$enabled{$field_storage} = undef;
}
# The field was already enabled, copy the incoming value to the item.
# The "original" ( when not on course reserve ) value is already in the storage field
elsif ( $course_item->$field_enabled) {
$item_fields->{$field} = $params{$field};
}
}
$item->set( $item_fields )->store
if keys %$item_fields;
}
}
$course_item->update( { %data, %enabled } );
}
=head2 _RevertFields
_RevertFields( ci_id => $ci_id, fields => \@fields_to_revert );
Copies fields from course item storage back to the actual item
=cut
sub _RevertFields {
my (%params) = @_;
my $ci_id = $params{'ci_id'};
return unless $ci_id;
my $course_item = Koha::Course::Items->find( $ci_id );
my $item_fields = {};
$item_fields->{itype} = $course_item->itype_storage if $course_item->itype_enabled;
$item_fields->{ccode} = $course_item->ccode_storage if $course_item->ccode_enabled;
$item_fields->{location} = $course_item->location_storage if $course_item->location_enabled;
$item_fields->{homebranch} = $course_item->homebranch_storage if $course_item->homebranch_enabled;
$item_fields->{holdingbranch} = $course_item->holdingbranch_storage if $course_item->holdingbranch_enabled;
Koha::Items->find( $course_item->itemnumber )
->set( $item_fields )
->store
if keys %$item_fields;
$course_item->itype_storage(undef);
$course_item->ccode_storage(undef);
$course_item->location_storage(undef);
$course_item->homebranch_storage(undef);
$course_item->holdingbranch_storage(undef);
$course_item->store();
}
=head2 _SwapAllFields
_SwapAllFields( $ci_id );
=cut
sub _SwapAllFields {
my ( $ci_id, $enabled ) = @_;
my $course_item = Koha::Course::Items->find( $ci_id );
my $item = Koha::Items->find( $course_item->itemnumber );
if ( $enabled eq 'yes' ) { # Copy item fields to course item storage, course item fields to item
$course_item->itype_storage( $item->effective_itemtype ) if $course_item->itype_enabled;
$course_item->ccode_storage( $item->ccode ) if $course_item->ccode_enabled;
$course_item->location_storage( $item->location ) if $course_item->location_enabled;
$course_item->homebranch_storage( $item->homebranch ) if $course_item->homebranch_enabled;
$course_item->holdingbranch_storage( $item->holdingbranch ) if $course_item->holdingbranch_enabled;
$course_item->store();
my $item_fields = {};
$item_fields->{itype} = $course_item->itype if $course_item->itype_enabled;
$item_fields->{ccode} = $course_item->ccode if $course_item->ccode_enabled;
$item_fields->{location} = $course_item->location if $course_item->location_enabled;
$item_fields->{homebranch} = $course_item->homebranch if $course_item->homebranch_enabled;
$item_fields->{holdingbranch} = $course_item->holdingbranch if $course_item->holdingbranch_enabled;
Koha::Items->find( $course_item->itemnumber )
->set( $item_fields )
->store
if keys %$item_fields;
} else { # Copy course item storage to item
my $item_fields = {};
$item_fields->{itype} = $course_item->itype_storage if $course_item->itype_enabled;
$item_fields->{ccode} = $course_item->ccode_storage if $course_item->ccode_enabled;
$item_fields->{location} = $course_item->location_storage if $course_item->location_enabled;
$item_fields->{homebranch} = $course_item->homebranch_storage if $course_item->homebranch_enabled;
$item_fields->{holdingbranch} = $course_item->holdingbranch_storage if $course_item->holdingbranch_enabled;
Koha::Items->find( $course_item->itemnumber )
->set( $item_fields )
->store
if keys %$item_fields;
$course_item->itype_storage(undef);
$course_item->ccode_storage(undef);
$course_item->location_storage(undef);
$course_item->homebranch_storage(undef);
$course_item->holdingbranch_storage(undef);
$course_item->store();
}
}
=head2 GetCourseItems {
$course_items = GetCourseItems(
[course_id => $course_id]
[, itemnumber => $itemnumber ]
);
=cut
sub GetCourseItems {
my (%params) = @_;
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) = @_;
my $ci_id = $params{'ci_id'};
return unless ($ci_id);
my $course_item = Koha::Course::Items->find( $ci_id );
return unless $course_item;
_RevertFields( ci_id => $ci_id ) if $course_item->enabled eq 'yes';
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) = @_;
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) = @_;
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) = @_;
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, ci.biblionumber
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}, { prefetch => ['biblio','biblioitem'] });
my $biblio = $cr->{itemnumber} ? $item->biblio : Koha::Biblios->find( $cr->{biblionumber}, { prefetch => ['biblioitem'] });
my $biblioitem = $biblio->biblioitem;
$cr->{'course_item'} = GetCourseItem( ci_id => $cr->{'ci_id'} );
$cr->{'item'} = $item;
$cr->{'biblio'} = $biblio;
$cr->{'biblioitem'} = $biblioitem;
$cr->{'issue'} = Koha::Checkouts->find({ itemnumber => $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'} = $cr->{itemnumber} ? GetCourses( itemnumber => $cr->{'itemnumber'} ) : GetCourses( biblionumber => $cr->{biblionumber} );
}
}
return $course_reserves;
}
=head2 DelCourseReserve {
DelCourseReserve( cr_id => $cr_id );
=cut
sub DelCourseReserve {
my (%params) = @_;
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 );
my $arrayref = GetItemCourseReservesInfo( biblionumber => $biblionumber );
For a given itemnumber or biblionumber, returns an arrayref of reserves hashrefs,
with a course hashref under the key 'course'
=cut
sub GetItemCourseReservesInfo {
my (%params) = @_;
my $itemnumber = $params{'itemnumber'};
my $biblionumber = $params{'biblionumber'};
return unless ($itemnumber xor $biblionumber);
my $course_item = $itemnumber ? GetCourseItem( itemnumber => $itemnumber ) : GetCourseItem( biblionumber => $biblionumber );
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
OR
biblionumber - course_item biblionumber
enabled = 'yes' or 'no'
Optional, if not supplied, counts reserves
for both enabled and disabled courses
=cut
sub CountCourseReservesForItem {
my (%params) = @_;
my $ci_id = $params{'ci_id'};
my $itemnumber = $params{'itemnumber'};
my $enabled = $params{'enabled'};
my $biblionumber = $params{'biblionumber'};
return unless ( $ci_id xor $itemnumber xor $biblionumber );
my $course_item = GetCourseItem( ci_id => $ci_id ) || GetCourseItem( itemnumber => $itemnumber ) || GetCourseItem( biblionumber => $biblionumber );
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) = @_;
my $term = $params{'term'};
my $enabled = $params{'enabled'} || '%';
my @params;
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_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, 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
";
$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 )";
}
1;
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut