Bug 11317: (follow-up) Add two-level entry to koha-conf and remove unwanted characters
[koha.git] / C4 / CourseReserves.pm
blob3a3f422a9682fbcc1146c05602d6e55d39d3486c
1 package C4::CourseReserves;
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
18 use Modern::Perl;
20 use List::MoreUtils qw(any);
22 use C4::Context;
23 use C4::Items qw(GetItem ModItem);
24 use C4::Circulation qw(GetOpenIssue);
26 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG @FIELDS);
28 BEGIN {
29 require Exporter;
30 @ISA = qw(Exporter);
31 @EXPORT_OK = qw(
32 &GetCourse
33 &ModCourse
34 &GetCourses
35 &DelCourse
37 &GetCourseInstructors
38 &ModCourseInstructors
40 &GetCourseItem
41 &ModCourseItem
43 &GetCourseReserve
44 &ModCourseReserve
45 &GetCourseReserves
46 &DelCourseReserve
48 &SearchCourses
50 &GetItemCourseReservesInfo
52 %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
54 $DEBUG = 0;
55 @FIELDS = ( 'itype', 'ccode', 'holdingbranch', 'location' );
58 =head1 NAME
60 C4::CourseReserves - Koha course reserves module
62 =head1 SYNOPSIS
64 use C4::CourseReserves;
66 =head1 DESCRIPTION
68 This module deals with course reserves.
70 =head1 FUNCTIONS
72 =head2 GetCourse
74 $course = GetCourse( $course_id );
76 =cut
78 sub GetCourse {
79 my ($course_id) = @_;
80 warn whoami() . "( $course_id )" if $DEBUG;
82 my $query = "SELECT * FROM courses WHERE course_id = ?";
83 my $dbh = C4::Context->dbh;
84 my $sth = $dbh->prepare($query);
85 $sth->execute($course_id);
87 my $course = $sth->fetchrow_hashref();
89 $query = "
90 SELECT b.* FROM course_instructors ci
91 LEFT JOIN borrowers b ON ( ci.borrowernumber = b.borrowernumber )
92 WHERE course_id = ?
94 $sth = $dbh->prepare($query);
95 $sth->execute($course_id);
96 $course->{'instructors'} = $sth->fetchall_arrayref( {} );
98 return $course;
101 =head2 ModCourse
103 ModCourse( [ course_id => $id ] [, course_name => $course_name ] [etc...] );
105 =cut
107 sub ModCourse {
108 my (%params) = @_;
109 warn identify_myself(%params) if $DEBUG;
111 my $dbh = C4::Context->dbh;
113 my $course_id;
114 if ( defined $params{'course_id'} ) {
115 $course_id = $params{'course_id'};
116 delete $params{'course_id'};
119 my @query_keys;
120 my @query_values;
122 my $query;
124 $query .= ($course_id) ? ' UPDATE ' : ' INSERT ';
125 $query .= ' courses SET ';
127 foreach my $key ( keys %params ) {
128 push( @query_keys, "$key=?" );
129 push( @query_values, $params{$key} );
131 $query .= join( ',', @query_keys );
133 if ($course_id) {
134 $query .= " WHERE course_id = ?";
135 push( @query_values, $course_id );
138 $dbh->do( $query, undef, @query_values );
140 $course_id = $course_id
141 || $dbh->last_insert_id( undef, undef, 'courses', 'course_id' );
143 EnableOrDisableCourseItems(
144 course_id => $course_id,
145 enabled => $params{'enabled'}
148 return $course_id;
151 =head2 GetCourses
153 @courses = GetCourses( [ fieldname => $value ] [, fieldname2 => $value2 ] [etc...] );
155 =cut
157 sub GetCourses {
158 my (%params) = @_;
159 warn identify_myself(%params) if $DEBUG;
161 my @query_keys;
162 my @query_values;
164 my $query = "
165 SELECT courses.*
166 FROM courses
167 LEFT JOIN course_reserves ON course_reserves.course_id = courses.course_id
168 LEFT JOIN course_items ON course_items.ci_id = course_reserves.ci_id
171 if ( keys %params ) {
173 $query .= " WHERE ";
175 foreach my $key ( keys %params ) {
176 push( @query_keys, " $key LIKE ? " );
177 push( @query_values, $params{$key} );
180 $query .= join( ' AND ', @query_keys );
183 $query .= " GROUP BY courses.course_id ";
185 my $dbh = C4::Context->dbh;
186 my $sth = $dbh->prepare($query);
187 $sth->execute(@query_values);
189 my $courses = $sth->fetchall_arrayref( {} );
191 foreach my $c (@$courses) {
192 $c->{'instructors'} = GetCourseInstructors( $c->{'course_id'} );
195 return $courses;
198 =head2 DelCourse
200 DelCourse( $course_id );
202 =cut
204 sub DelCourse {
205 my ($course_id) = @_;
207 my $course_reserves = GetCourseReserves( course_id => $course_id );
209 foreach my $res (@$course_reserves) {
210 DelCourseReserve( cr_id => $res->{'cr_id'} );
213 my $query = "
214 DELETE FROM course_instructors
215 WHERE course_id = ?
217 C4::Context->dbh->do( $query, undef, $course_id );
219 $query = "
220 DELETE FROM courses
221 WHERE course_id = ?
223 C4::Context->dbh->do( $query, undef, $course_id );
226 =head2 EnableOrDisableCourseItems
228 EnableOrDisableCourseItems( course_id => $course_id, enabled => $enabled );
230 For each item on reserve for this course,
231 if the course item has no active course reserves,
232 swap the fields for the item to make it 'normal'
233 again.
235 enabled => 'yes' to enable course items
236 enabled => 'no' to disable course items
238 =cut
240 sub EnableOrDisableCourseItems {
241 my (%params) = @_;
242 warn identify_myself(%params) if $DEBUG;
244 my $course_id = $params{'course_id'};
245 my $enabled = $params{'enabled'} || 0;
247 my $lookfor = ( $enabled eq 'yes' ) ? 'no' : 'yes';
249 return unless ( $course_id && $enabled );
250 return unless ( $enabled eq 'yes' || $enabled eq 'no' );
252 my $course_reserves = GetCourseReserves( course_id => $course_id );
254 if ( $enabled eq 'yes' ) {
255 foreach my $course_reserve (@$course_reserves) {
256 if (CountCourseReservesForItem(
257 ci_id => $course_reserve->{'ci_id'},
258 enabled => 'yes'
261 EnableOrDisableCourseItem(
262 ci_id => $course_reserve->{'ci_id'},
267 if ( $enabled eq 'no' ) {
268 foreach my $course_reserve (@$course_reserves) {
269 unless (
270 CountCourseReservesForItem(
271 ci_id => $course_reserve->{'ci_id'},
272 enabled => 'yes'
275 EnableOrDisableCourseItem(
276 ci_id => $course_reserve->{'ci_id'},
283 =head2 EnableOrDisableCourseItem
285 EnableOrDisableCourseItem( ci_id => $ci_id );
287 =cut
289 sub EnableOrDisableCourseItem {
290 my (%params) = @_;
291 warn identify_myself(%params) if $DEBUG;
293 my $ci_id = $params{'ci_id'};
295 return unless ( $ci_id );
297 my $course_item = GetCourseItem( ci_id => $ci_id );
299 my $info = GetItemCourseReservesInfo( itemnumber => $course_item->{itemnumber} );
301 my $enabled = any { $_->{course}->{enabled} eq 'yes' } @$info;
302 $enabled = $enabled ? 'yes' : 'no';
304 ## We don't want to 'enable' an already enabled item,
305 ## or disable and already disabled item,
306 ## as that would cause the fields to swap
307 if ( $course_item->{'enabled'} ne $enabled ) {
308 _SwapAllFields($ci_id);
310 my $query = "
311 UPDATE course_items
312 SET enabled = ?
313 WHERE ci_id = ?
316 C4::Context->dbh->do( $query, undef, $enabled, $ci_id );
322 =head2 GetCourseInstructors
324 @$borrowers = GetCourseInstructors( $course_id );
326 =cut
328 sub GetCourseInstructors {
329 my ($course_id) = @_;
330 warn "C4::CourseReserves::GetCourseInstructors( $course_id )"
331 if $DEBUG;
333 my $query = "
334 SELECT * FROM borrowers
335 RIGHT JOIN course_instructors ON ( course_instructors.borrowernumber = borrowers.borrowernumber )
336 WHERE course_instructors.course_id = ?
339 my $dbh = C4::Context->dbh;
340 my $sth = $dbh->prepare($query);
341 $sth->execute($course_id);
343 return $sth->fetchall_arrayref( {} );
346 =head2 ModCourseInstructors
348 ModCourseInstructors( mode => $mode, course_id => $course_id, [ cardnumbers => $cardnumbers ] OR [ borrowernumbers => $borrowernumbers );
350 $mode can be 'replace', 'add', or 'delete'
352 $cardnumbers and $borrowernumbers are both references to arrays
354 Use either cardnumbers or borrowernumber, but not both.
356 =cut
358 sub ModCourseInstructors {
359 my (%params) = @_;
360 warn identify_myself(%params) if $DEBUG;
362 my $course_id = $params{'course_id'};
363 my $mode = $params{'mode'};
364 my $cardnumbers = $params{'cardnumbers'};
365 my $borrowernumbers = $params{'borrowernumbers'};
367 return unless ($course_id);
368 return
369 unless ( $mode eq 'replace'
370 || $mode eq 'add'
371 || $mode eq 'delete' );
372 return unless ( $cardnumbers || $borrowernumbers );
373 return if ( $cardnumbers && $borrowernumbers );
375 my ( @cardnumbers, @borrowernumbers );
376 @cardnumbers = @$cardnumbers if ( ref($cardnumbers) eq 'ARRAY' );
377 @borrowernumbers = @$borrowernumbers
378 if ( ref($borrowernumbers) eq 'ARRAY' );
380 my $field = (@cardnumbers) ? 'cardnumber' : 'borrowernumber';
381 my @fields = (@cardnumbers) ? @cardnumbers : @borrowernumbers;
382 my $placeholders = join( ',', ('?') x scalar @fields );
384 my $dbh = C4::Context->dbh;
386 $dbh->do( "DELETE FROM course_instructors WHERE course_id = ?", undef, $course_id )
387 if ( $mode eq 'replace' );
389 my $query;
391 if ( $mode eq 'add' || $mode eq 'replace' ) {
392 $query = "
393 INSERT INTO course_instructors ( course_id, borrowernumber )
394 SELECT ?, borrowernumber
395 FROM borrowers
396 WHERE $field IN ( $placeholders )
398 } else {
399 $query = "
400 DELETE FROM course_instructors
401 WHERE course_id = ?
402 AND borrowernumber IN (
403 SELECT borrowernumber FROM borrowers WHERE $field IN ( $placeholders )
408 my $sth = $dbh->prepare($query);
410 $sth->execute( $course_id, @fields ) if (@fields);
413 =head2 GetCourseItem {
415 $course_item = GetCourseItem( itemnumber => $itemnumber [, ci_id => $ci_id );
417 =cut
419 sub GetCourseItem {
420 my (%params) = @_;
421 warn identify_myself(%params) if $DEBUG;
423 my $ci_id = $params{'ci_id'};
424 my $itemnumber = $params{'itemnumber'};
426 return unless ( $itemnumber || $ci_id );
428 my $field = ($itemnumber) ? 'itemnumber' : 'ci_id';
429 my $value = ($itemnumber) ? $itemnumber : $ci_id;
431 my $query = "SELECT * FROM course_items WHERE $field = ?";
432 my $dbh = C4::Context->dbh;
433 my $sth = $dbh->prepare($query);
434 $sth->execute($value);
436 my $course_item = $sth->fetchrow_hashref();
438 if ($course_item) {
439 $query = "SELECT * FROM course_reserves WHERE ci_id = ?";
440 $sth = $dbh->prepare($query);
441 $sth->execute( $course_item->{'ci_id'} );
442 my $course_reserves = $sth->fetchall_arrayref( {} );
444 $course_item->{'course_reserves'} = $course_reserves
445 if ($course_reserves);
447 return $course_item;
450 =head2 ModCourseItem {
452 ModCourseItem( %params );
454 Creates or modifies an existing course item.
456 =cut
458 sub ModCourseItem {
459 my (%params) = @_;
460 warn identify_myself(%params) if $DEBUG;
462 my $itemnumber = $params{'itemnumber'};
463 my $itype = $params{'itype'};
464 my $ccode = $params{'ccode'};
465 my $holdingbranch = $params{'holdingbranch'};
466 my $location = $params{'location'};
468 return unless ($itemnumber);
470 my $course_item = GetCourseItem( itemnumber => $itemnumber );
472 my $ci_id;
474 if ($course_item) {
475 $ci_id = $course_item->{'ci_id'};
477 _UpdateCourseItem(
478 ci_id => $ci_id,
479 course_item => $course_item,
480 %params
482 } else {
483 $ci_id = _AddCourseItem(%params);
486 return $ci_id;
490 =head2 _AddCourseItem
492 my $ci_id = _AddCourseItem( %params );
494 =cut
496 sub _AddCourseItem {
497 my (%params) = @_;
498 warn identify_myself(%params) if $DEBUG;
500 my ( @fields, @values );
502 push( @fields, 'itemnumber = ?' );
503 push( @values, $params{'itemnumber'} );
505 foreach (@FIELDS) {
506 if ( $params{$_} ) {
507 push( @fields, "$_ = ?" );
508 push( @values, $params{$_} );
512 my $query = "INSERT INTO course_items SET " . join( ',', @fields );
513 my $dbh = C4::Context->dbh;
514 $dbh->do( $query, undef, @values );
516 my $ci_id = $dbh->last_insert_id( undef, undef, 'course_items', 'ci_id' );
518 return $ci_id;
521 =head2 _UpdateCourseItem
523 _UpdateCourseItem( %params );
525 =cut
527 sub _UpdateCourseItem {
528 my (%params) = @_;
529 warn identify_myself(%params) if $DEBUG;
531 my $ci_id = $params{'ci_id'};
532 my $course_item = $params{'course_item'};
533 my $itype = $params{'itype'};
534 my $ccode = $params{'ccode'};
535 my $holdingbranch = $params{'holdingbranch'};
536 my $location = $params{'location'};
538 return unless ( $ci_id || $course_item );
540 $course_item = GetCourseItem( ci_id => $ci_id )
541 unless ($course_item);
542 $ci_id = $course_item->{'ci_id'} unless ($ci_id);
544 ## Revert fields that had an 'original' value, but now don't
545 ## Update the item fields to the stored values from course_items
546 ## and then set those fields in course_items to NULL
547 my @fields_to_revert;
548 foreach (@FIELDS) {
549 if ( !$params{$_} && $course_item->{$_} ) {
550 push( @fields_to_revert, $_ );
553 _RevertFields(
554 ci_id => $ci_id,
555 fields => \@fields_to_revert,
556 course_item => $course_item
557 ) if (@fields_to_revert);
559 ## Update fields that still have an original value, but it has changed
560 ## This necessitates only changing the current item values, as we still
561 ## have the original values stored in course_items
562 my %mod_params;
563 foreach (@FIELDS) {
564 if ( $params{$_}
565 && $course_item->{$_}
566 && $params{$_} ne $course_item->{$_} ) {
567 $mod_params{$_} = $params{$_};
570 ModItem( \%mod_params, undef, $course_item->{'itemnumber'} ) if %mod_params;
572 ## Update fields that didn't have an original value, but now do
573 ## We must save the original value in course_items, and also
574 ## update the item fields to the new value
575 my $item = GetItem( $course_item->{'itemnumber'} );
576 my %mod_params_new;
577 my %mod_params_old;
578 foreach (@FIELDS) {
579 if ( $params{$_} && !$course_item->{$_} ) {
580 $mod_params_new{$_} = $params{$_};
581 $mod_params_old{$_} = $item->{$_};
584 _ModStoredFields( 'ci_id' => $params{'ci_id'}, %mod_params_old );
585 ModItem( \%mod_params_new, undef, $course_item->{'itemnumber'} ) if %mod_params_new;
589 =head2 _ModStoredFields
591 _ModStoredFields( %params );
593 Updates the values for the 'original' fields in course_items
594 for a given ci_id
596 =cut
598 sub _ModStoredFields {
599 my (%params) = @_;
600 warn identify_myself(%params) if $DEBUG;
602 return unless ( $params{'ci_id'} );
604 my ( @fields_to_update, @values_to_update );
606 foreach (@FIELDS) {
607 if ( $params{$_} ) {
608 push( @fields_to_update, $_ );
609 push( @values_to_update, $params{$_} );
613 my $query = "UPDATE course_items SET " . join( ',', map { "$_=?" } @fields_to_update ) . " WHERE ci_id = ?";
615 C4::Context->dbh->do( $query, undef, @values_to_update, $params{'ci_id'} )
616 if (@values_to_update);
620 =head2 _RevertFields
622 _RevertFields( ci_id => $ci_id, fields => \@fields_to_revert );
624 =cut
626 sub _RevertFields {
627 my (%params) = @_;
628 warn identify_myself(%params) if $DEBUG;
630 my $ci_id = $params{'ci_id'};
631 my $course_item = $params{'course_item'};
632 my $fields = $params{'fields'};
633 my @fields = @$fields;
635 return unless ($ci_id);
637 $course_item = GetCourseItem( ci_id => $params{'ci_id'} )
638 unless ($course_item);
640 my $mod_item_params;
641 my @fields_to_null;
642 foreach my $field (@fields) {
643 foreach (@FIELDS) {
644 if ( $field eq $_ && $course_item->{$_} ) {
645 $mod_item_params->{$_} = $course_item->{$_};
646 push( @fields_to_null, $_ );
650 ModItem( $mod_item_params, undef, $course_item->{'itemnumber'} ) if $mod_item_params && %$mod_item_params;
652 my $query = "UPDATE course_items SET " . join( ',', map { "$_=NULL" } @fields_to_null ) . " WHERE ci_id = ?";
654 C4::Context->dbh->do( $query, undef, $ci_id ) if (@fields_to_null);
657 =head2 _SwapAllFields
659 _SwapAllFields( $ci_id );
661 =cut
663 sub _SwapAllFields {
664 my ($ci_id) = @_;
665 warn "C4::CourseReserves::_SwapFields( $ci_id )" if $DEBUG;
667 my $course_item = GetCourseItem( ci_id => $ci_id );
668 my $item = GetItem( $course_item->{'itemnumber'} );
670 my %course_item_fields;
671 my %item_fields;
672 foreach (@FIELDS) {
673 if ( $course_item->{$_} ) {
674 $course_item_fields{$_} = $course_item->{$_};
675 $item_fields{$_} = $item->{$_};
679 ModItem( \%course_item_fields, undef, $course_item->{'itemnumber'} ) if %course_item_fields;
680 _ModStoredFields( %item_fields, ci_id => $ci_id );
683 =head2 GetCourseItems {
685 $course_items = GetCourseItems(
686 [course_id => $course_id]
687 [, itemnumber => $itemnumber ]
690 =cut
692 sub GetCourseItems {
693 my (%params) = @_;
694 warn identify_myself(%params) if $DEBUG;
696 my $course_id = $params{'course_id'};
697 my $itemnumber = $params{'itemnumber'};
699 return unless ($course_id);
701 my @query_keys;
702 my @query_values;
704 my $query = "SELECT * FROM course_items";
706 if ( keys %params ) {
708 $query .= " WHERE ";
710 foreach my $key ( keys %params ) {
711 push( @query_keys, " $key LIKE ? " );
712 push( @query_values, $params{$key} );
715 $query .= join( ' AND ', @query_keys );
718 my $dbh = C4::Context->dbh;
719 my $sth = $dbh->prepare($query);
720 $sth->execute(@query_values);
722 return $sth->fetchall_arrayref( {} );
725 =head2 DelCourseItem {
727 DelCourseItem( ci_id => $cr_id );
729 =cut
731 sub DelCourseItem {
732 my (%params) = @_;
733 warn identify_myself(%params) if $DEBUG;
735 my $ci_id = $params{'ci_id'};
737 return unless ($ci_id);
739 _RevertFields( ci_id => $ci_id, fields => \@FIELDS );
741 my $query = "
742 DELETE FROM course_items
743 WHERE ci_id = ?
745 C4::Context->dbh->do( $query, undef, $ci_id );
748 =head2 GetCourseReserve {
750 $course_item = GetCourseReserve( %params );
752 =cut
754 sub GetCourseReserve {
755 my (%params) = @_;
756 warn identify_myself(%params) if $DEBUG;
758 my $cr_id = $params{'cr_id'};
759 my $course_id = $params{'course_id'};
760 my $ci_id = $params{'ci_id'};
762 return unless ( $cr_id || ( $course_id && $ci_id ) );
764 my $dbh = C4::Context->dbh;
765 my $sth;
767 if ($cr_id) {
768 my $query = "
769 SELECT * FROM course_reserves
770 WHERE cr_id = ?
772 $sth = $dbh->prepare($query);
773 $sth->execute($cr_id);
774 } else {
775 my $query = "
776 SELECT * FROM course_reserves
777 WHERE course_id = ? AND ci_id = ?
779 $sth = $dbh->prepare($query);
780 $sth->execute( $course_id, $ci_id );
783 my $course_reserve = $sth->fetchrow_hashref();
784 return $course_reserve;
787 =head2 ModCourseReserve
789 $id = ModCourseReserve( %params );
791 =cut
793 sub ModCourseReserve {
794 my (%params) = @_;
795 warn identify_myself(%params) if $DEBUG;
797 my $course_id = $params{'course_id'};
798 my $ci_id = $params{'ci_id'};
799 my $staff_note = $params{'staff_note'};
800 my $public_note = $params{'public_note'};
802 return unless ( $course_id && $ci_id );
804 my $course_reserve = GetCourseReserve( course_id => $course_id, ci_id => $ci_id );
805 my $cr_id;
807 my $dbh = C4::Context->dbh;
809 if ($course_reserve) {
810 $cr_id = $course_reserve->{'cr_id'};
812 my $query = "
813 UPDATE course_reserves
814 SET staff_note = ?, public_note = ?
815 WHERE cr_id = ?
817 $dbh->do( $query, undef, $staff_note, $public_note, $cr_id );
818 } else {
819 my $query = "
820 INSERT INTO course_reserves SET
821 course_id = ?,
822 ci_id = ?,
823 staff_note = ?,
824 public_note = ?
826 $dbh->do( $query, undef, $course_id, $ci_id, $staff_note, $public_note );
827 $cr_id = $dbh->last_insert_id( undef, undef, 'course_reserves', 'cr_id' );
830 EnableOrDisableCourseItem(
831 ci_id => $params{'ci_id'},
834 return $cr_id;
837 =head2 GetCourseReserves {
839 $course_reserves = GetCourseReserves( %params );
841 Required:
842 course_id OR ci_id
843 Optional:
844 include_items => 1,
845 include_count => 1,
846 include_courses => 1,
848 =cut
850 sub GetCourseReserves {
851 my (%params) = @_;
852 warn identify_myself(%params) if $DEBUG;
854 my $course_id = $params{'course_id'};
855 my $ci_id = $params{'ci_id'};
856 my $include_items = $params{'include_items'};
857 my $include_count = $params{'include_count'};
858 my $include_courses = $params{'include_courses'};
860 return unless ( $course_id || $ci_id );
862 my $field = ($course_id) ? 'course_id' : 'ci_id';
863 my $value = ($course_id) ? $course_id : $ci_id;
865 my $query = "
866 SELECT cr.*, ci.itemnumber
867 FROM course_reserves cr, course_items ci
868 WHERE cr.$field = ?
869 AND cr.ci_id = ci.ci_id
871 my $dbh = C4::Context->dbh;
872 my $sth = $dbh->prepare($query);
873 $sth->execute($value);
875 my $course_reserves = $sth->fetchall_arrayref( {} );
877 if ($include_items) {
878 foreach my $cr (@$course_reserves) {
879 my $item = Koha::Items->find( $cr->{itemnumber} );
880 my $biblio = $item->biblio;
881 my $biblioitem = $biblio->biblioitem;
882 $cr->{'course_item'} = GetCourseItem( ci_id => $cr->{'ci_id'} );
883 $cr->{'item'} = $item;
884 $cr->{'biblio'} = $biblio;
885 $cr->{'biblioitem'} = $biblioitem;
886 $cr->{'issue'} = GetOpenIssue( $cr->{'itemnumber'} );
890 if ($include_count) {
891 foreach my $cr (@$course_reserves) {
892 $cr->{'reserves_count'} = CountCourseReservesForItem( ci_id => $cr->{'ci_id'} );
896 if ($include_courses) {
897 foreach my $cr (@$course_reserves) {
898 $cr->{'courses'} = GetCourses( itemnumber => $cr->{'itemnumber'} );
902 return $course_reserves;
905 =head2 DelCourseReserve {
907 DelCourseReserve( cr_id => $cr_id );
909 =cut
911 sub DelCourseReserve {
912 my (%params) = @_;
913 warn identify_myself(%params) if $DEBUG;
915 my $cr_id = $params{'cr_id'};
917 return unless ($cr_id);
919 my $dbh = C4::Context->dbh;
921 my $course_reserve = GetCourseReserve( cr_id => $cr_id );
923 my $query = "
924 DELETE FROM course_reserves
925 WHERE cr_id = ?
927 $dbh->do( $query, undef, $cr_id );
929 ## If there are no other course reserves for this item
930 ## delete the course_item as well
931 unless ( CountCourseReservesForItem( ci_id => $course_reserve->{'ci_id'} ) ) {
932 DelCourseItem( ci_id => $course_reserve->{'ci_id'} );
937 =head2 GetItemCourseReservesInfo
939 my $arrayref = GetItemCourseReservesInfo( itemnumber => $itemnumber );
941 For a given item, returns an arrayref of reserves hashrefs,
942 with a course hashref under the key 'course'
944 =cut
946 sub GetItemCourseReservesInfo {
947 my (%params) = @_;
948 warn identify_myself(%params) if $DEBUG;
950 my $itemnumber = $params{'itemnumber'};
952 return unless ($itemnumber);
954 my $course_item = GetCourseItem( itemnumber => $itemnumber );
956 return unless ( keys %$course_item );
958 my $course_reserves = GetCourseReserves( ci_id => $course_item->{'ci_id'} );
960 foreach my $cr (@$course_reserves) {
961 $cr->{'course'} = GetCourse( $cr->{'course_id'} );
964 return $course_reserves;
967 =head2 CountCourseReservesForItem
969 $bool = CountCourseReservesForItem( %params );
971 ci_id - course_item id
973 itemnumber - course_item itemnumber
975 enabled = 'yes' or 'no'
976 Optional, if not supplied, counts reserves
977 for both enabled and disabled courses
979 =cut
981 sub CountCourseReservesForItem {
982 my (%params) = @_;
983 warn identify_myself(%params) if $DEBUG;
985 my $ci_id = $params{'ci_id'};
986 my $itemnumber = $params{'itemnumber'};
987 my $enabled = $params{'enabled'};
989 return unless ( $ci_id || $itemnumber );
991 my $course_item = GetCourseItem( ci_id => $ci_id, itemnumber => $itemnumber );
993 my @params = ( $course_item->{'ci_id'} );
994 push( @params, $enabled ) if ($enabled);
996 my $query = "
997 SELECT COUNT(*) AS count
998 FROM course_reserves cr
999 LEFT JOIN courses c ON ( c.course_id = cr.course_id )
1000 WHERE ci_id = ?
1002 $query .= "AND c.enabled = ?" if ($enabled);
1004 my $dbh = C4::Context->dbh;
1005 my $sth = $dbh->prepare($query);
1006 $sth->execute(@params);
1008 my $row = $sth->fetchrow_hashref();
1010 return $row->{'count'};
1013 =head2 SearchCourses
1015 my $courses = SearchCourses( term => $search_term, enabled => 'yes' );
1017 =cut
1019 sub SearchCourses {
1020 my (%params) = @_;
1021 warn identify_myself(%params) if $DEBUG;
1023 my $term = $params{'term'};
1025 my $enabled = $params{'enabled'} || '%';
1027 my @params;
1028 my $query = "SELECT c.* FROM courses c";
1030 $query .= "
1031 LEFT JOIN course_instructors ci
1032 ON ( c.course_id = ci.course_id )
1033 LEFT JOIN borrowers b
1034 ON ( ci.borrowernumber = b.borrowernumber )
1035 LEFT JOIN authorised_values av
1036 ON ( c.department = av.authorised_value )
1037 WHERE
1038 ( av.category = 'DEPARTMENT' OR av.category = 'TERM' )
1041 department LIKE ? OR
1042 course_number LIKE ? OR
1043 section LIKE ? OR
1044 course_name LIKE ? OR
1045 term LIKE ? OR
1046 public_note LIKE ? OR
1047 CONCAT(surname,' ',firstname) LIKE ? OR
1048 CONCAT(firstname,' ',surname) LIKE ? OR
1049 lib LIKE ? OR
1050 lib_opac LIKE ?
1053 c.enabled LIKE ?
1054 GROUP BY c.course_id
1057 $term //= '';
1058 $term = "%$term%";
1059 @params = ($term) x 10;
1061 $query .= " ORDER BY department, course_number, section, term, course_name ";
1063 my $dbh = C4::Context->dbh;
1064 my $sth = $dbh->prepare($query);
1066 $sth->execute( @params, $enabled );
1068 my $courses = $sth->fetchall_arrayref( {} );
1070 foreach my $c (@$courses) {
1071 $c->{'instructors'} = GetCourseInstructors( $c->{'course_id'} );
1074 return $courses;
1077 sub whoami { ( caller(1) )[3] }
1078 sub whowasi { ( caller(2) )[3] }
1080 sub stringify_params {
1081 my (%params) = @_;
1083 my $string = "\n";
1085 foreach my $key ( keys %params ) {
1086 $string .= " $key => " . $params{$key} . "\n";
1089 return "( $string )";
1092 sub identify_myself {
1093 my (%params) = @_;
1095 return whowasi() . stringify_params(%params);
1100 =head1 AUTHOR
1102 Kyle M Hall <kyle@bywatersolutions.com>
1104 =cut