Bug 26846: Fix regressions - Preselect expected and late serials
[koha.git] / C4 / CourseReserves.pm
blob1c08ad4d5e313f3903208a47f06462e001f187d3
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::Circulation qw(GetOpenIssue);
25 use Koha::Courses;
26 use Koha::Course::Instructors;
27 use Koha::Course::Items;
28 use Koha::Course::Reserves;
30 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG @FIELDS);
32 BEGIN {
33 require Exporter;
34 @ISA = qw(Exporter);
35 @EXPORT_OK = qw(
36 &GetCourse
37 &ModCourse
38 &GetCourses
39 &DelCourse
41 &GetCourseInstructors
42 &ModCourseInstructors
44 &GetCourseItem
45 &ModCourseItem
47 &GetCourseReserve
48 &ModCourseReserve
49 &GetCourseReserves
50 &DelCourseReserve
52 &SearchCourses
54 &GetItemCourseReservesInfo
56 %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
58 $DEBUG = 0;
59 @FIELDS = ( 'itype', 'ccode', 'homebranch', 'holdingbranch', 'location' );
62 =head1 NAME
64 C4::CourseReserves - Koha course reserves module
66 =head1 SYNOPSIS
68 use C4::CourseReserves;
70 =head1 DESCRIPTION
72 This module deals with course reserves.
74 =head1 FUNCTIONS
76 =head2 GetCourse
78 $course = GetCourse( $course_id );
80 =cut
82 sub GetCourse {
83 my ($course_id) = @_;
84 warn whoami() . "( $course_id )" if $DEBUG;
86 my $course = Koha::Courses->find( $course_id );
87 return unless $course;
88 $course = $course->unblessed;
90 my $dbh = C4::Context->dbh;
91 my $query = "
92 SELECT b.* FROM course_instructors ci
93 LEFT JOIN borrowers b ON ( ci.borrowernumber = b.borrowernumber )
94 WHERE course_id = ?
96 my $sth = $dbh->prepare($query);
97 $sth->execute($course_id);
98 $course->{'instructors'} = $sth->fetchall_arrayref( {} );
100 return $course;
103 =head2 ModCourse
105 ModCourse( [ course_id => $id ] [, course_name => $course_name ] [etc...] );
107 =cut
109 sub ModCourse {
110 my (%params) = @_;
111 warn identify_myself(%params) if $DEBUG;
113 my $dbh = C4::Context->dbh;
115 my $course_id;
116 if ( defined $params{'course_id'} ) {
117 $course_id = $params{'course_id'};
118 delete $params{'course_id'};
121 my @query_keys;
122 my @query_values;
124 my $query;
126 $query .= ($course_id) ? ' UPDATE ' : ' INSERT ';
127 $query .= ' courses SET ';
129 foreach my $key ( keys %params ) {
130 push( @query_keys, "$key=?" );
131 push( @query_values, $params{$key} );
133 $query .= join( ',', @query_keys );
135 if ($course_id) {
136 $query .= " WHERE course_id = ?";
137 push( @query_values, $course_id );
140 $dbh->do( $query, undef, @query_values );
142 $course_id = $course_id
143 || $dbh->last_insert_id( undef, undef, 'courses', 'course_id' );
145 EnableOrDisableCourseItems(
146 course_id => $course_id,
147 enabled => $params{'enabled'}
150 return $course_id;
153 =head2 GetCourses
155 @courses = GetCourses( [ fieldname => $value ] [, fieldname2 => $value2 ] [etc...] );
157 =cut
159 sub GetCourses {
160 my (%params) = @_;
161 warn identify_myself(%params) if $DEBUG;
163 my @query_keys;
164 my @query_values;
166 my $query = "
167 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
168 FROM courses c
169 LEFT JOIN course_reserves ON course_reserves.course_id = c.course_id
170 LEFT JOIN course_items ON course_items.ci_id = course_reserves.ci_id
173 if ( keys %params ) {
175 $query .= " WHERE ";
177 foreach my $key ( keys %params ) {
178 push( @query_keys, " $key LIKE ? " );
179 push( @query_values, $params{$key} );
182 $query .= join( ' AND ', @query_keys );
185 $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 ";
187 my $dbh = C4::Context->dbh;
188 my $sth = $dbh->prepare($query);
189 $sth->execute(@query_values);
191 my $courses = $sth->fetchall_arrayref( {} );
193 foreach my $c (@$courses) {
194 $c->{'instructors'} = GetCourseInstructors( $c->{'course_id'} );
197 return $courses;
200 =head2 DelCourse
202 DelCourse( $course_id );
204 =cut
206 sub DelCourse {
207 my ($course_id) = @_;
209 my $course_reserves = GetCourseReserves( course_id => $course_id );
211 foreach my $res (@$course_reserves) {
212 DelCourseReserve( cr_id => $res->{'cr_id'} );
215 my $query = "
216 DELETE FROM course_instructors
217 WHERE course_id = ?
219 C4::Context->dbh->do( $query, undef, $course_id );
221 $query = "
222 DELETE FROM courses
223 WHERE course_id = ?
225 C4::Context->dbh->do( $query, undef, $course_id );
228 =head2 EnableOrDisableCourseItems
230 EnableOrDisableCourseItems( course_id => $course_id, enabled => $enabled );
232 For each item on reserve for this course,
233 if the course item has no active course reserves,
234 swap the fields for the item to make it 'normal'
235 again.
237 enabled => 'yes' to enable course items
238 enabled => 'no' to disable course items
240 =cut
242 sub EnableOrDisableCourseItems {
243 my (%params) = @_;
244 warn identify_myself(%params) if $DEBUG;
246 my $course_id = $params{'course_id'};
247 my $enabled = $params{'enabled'} || 0;
249 my $lookfor = ( $enabled eq 'yes' ) ? 'no' : 'yes';
251 return unless ( $course_id && $enabled );
252 return unless ( $enabled eq 'yes' || $enabled eq 'no' );
254 my $course_reserves = GetCourseReserves( course_id => $course_id );
256 if ( $enabled eq 'yes' ) {
257 foreach my $course_reserve (@$course_reserves) {
258 if (CountCourseReservesForItem(
259 ci_id => $course_reserve->{'ci_id'},
260 enabled => 'yes'
263 EnableOrDisableCourseItem(
264 ci_id => $course_reserve->{'ci_id'},
269 if ( $enabled eq 'no' ) {
270 foreach my $course_reserve (@$course_reserves) {
271 unless (
272 CountCourseReservesForItem(
273 ci_id => $course_reserve->{'ci_id'},
274 enabled => 'yes'
277 EnableOrDisableCourseItem(
278 ci_id => $course_reserve->{'ci_id'},
285 =head2 EnableOrDisableCourseItem
287 EnableOrDisableCourseItem( ci_id => $ci_id );
289 =cut
291 sub EnableOrDisableCourseItem {
292 my (%params) = @_;
293 warn identify_myself(%params) if $DEBUG;
295 my $ci_id = $params{'ci_id'};
297 return unless ( $ci_id );
299 my $course_item = GetCourseItem( ci_id => $ci_id );
301 my $info = GetItemCourseReservesInfo( itemnumber => $course_item->{itemnumber} );
303 my $enabled = any { $_->{course}->{enabled} eq 'yes' } @$info;
304 $enabled = $enabled ? 'yes' : 'no';
306 ## We don't want to 'enable' an already enabled item,
307 ## or disable and already disabled item,
308 ## as that would cause the fields to swap
309 if ( $course_item->{'enabled'} ne $enabled ) {
310 _SwapAllFields($ci_id, $enabled );
312 my $query = "
313 UPDATE course_items
314 SET enabled = ?
315 WHERE ci_id = ?
318 C4::Context->dbh->do( $query, undef, $enabled, $ci_id );
324 =head2 GetCourseInstructors
326 @$borrowers = GetCourseInstructors( $course_id );
328 =cut
330 sub GetCourseInstructors {
331 my ($course_id) = @_;
332 warn "C4::CourseReserves::GetCourseInstructors( $course_id )"
333 if $DEBUG;
335 my $query = "
336 SELECT * FROM borrowers
337 RIGHT JOIN course_instructors ON ( course_instructors.borrowernumber = borrowers.borrowernumber )
338 WHERE course_instructors.course_id = ?
341 my $dbh = C4::Context->dbh;
342 my $sth = $dbh->prepare($query);
343 $sth->execute($course_id);
345 return $sth->fetchall_arrayref( {} );
348 =head2 ModCourseInstructors
350 ModCourseInstructors( mode => $mode, course_id => $course_id, [ cardnumbers => $cardnumbers ] OR [ borrowernumbers => $borrowernumbers );
352 $mode can be 'replace', 'add', or 'delete'
354 $cardnumbers and $borrowernumbers are both references to arrays
356 Use either cardnumbers or borrowernumber, but not both.
358 =cut
360 sub ModCourseInstructors {
361 my (%params) = @_;
362 warn identify_myself(%params) if $DEBUG;
364 my $course_id = $params{'course_id'};
365 my $mode = $params{'mode'};
366 my $cardnumbers = $params{'cardnumbers'};
367 my $borrowernumbers = $params{'borrowernumbers'};
369 return unless ($course_id);
370 return
371 unless ( $mode eq 'replace'
372 || $mode eq 'add'
373 || $mode eq 'delete' );
374 return unless ( $cardnumbers || $borrowernumbers );
375 return if ( $cardnumbers && $borrowernumbers );
377 my ( @cardnumbers, @borrowernumbers );
378 @cardnumbers = @$cardnumbers if ( ref($cardnumbers) eq 'ARRAY' );
379 @borrowernumbers = @$borrowernumbers
380 if ( ref($borrowernumbers) eq 'ARRAY' );
382 my $field = (@cardnumbers) ? 'cardnumber' : 'borrowernumber';
383 my @fields = (@cardnumbers) ? @cardnumbers : @borrowernumbers;
384 my $placeholders = join( ',', ('?') x scalar @fields );
386 my $dbh = C4::Context->dbh;
388 $dbh->do( "DELETE FROM course_instructors WHERE course_id = ?", undef, $course_id )
389 if ( $mode eq 'replace' );
391 my $query;
393 if ( $mode eq 'add' || $mode eq 'replace' ) {
394 $query = "
395 INSERT INTO course_instructors ( course_id, borrowernumber )
396 SELECT ?, borrowernumber
397 FROM borrowers
398 WHERE $field IN ( $placeholders )
400 } else {
401 $query = "
402 DELETE FROM course_instructors
403 WHERE course_id = ?
404 AND borrowernumber IN (
405 SELECT borrowernumber FROM borrowers WHERE $field IN ( $placeholders )
410 my $sth = $dbh->prepare($query);
412 $sth->execute( $course_id, @fields ) if (@fields);
415 =head2 GetCourseItem {
417 $course_item = GetCourseItem( itemnumber => $itemnumber [, ci_id => $ci_id );
419 =cut
421 sub GetCourseItem {
422 my (%params) = @_;
423 warn identify_myself(%params) if $DEBUG;
425 my $ci_id = $params{'ci_id'};
426 my $itemnumber = $params{'itemnumber'};
428 return unless ( $itemnumber || $ci_id );
430 my $field = ($itemnumber) ? 'itemnumber' : 'ci_id';
431 my $value = ($itemnumber) ? $itemnumber : $ci_id;
433 my $query = "SELECT * FROM course_items WHERE $field = ?";
434 my $dbh = C4::Context->dbh;
435 my $sth = $dbh->prepare($query);
436 $sth->execute($value);
438 my $course_item = $sth->fetchrow_hashref();
440 if ($course_item) {
441 $query = "SELECT * FROM course_reserves WHERE ci_id = ?";
442 $sth = $dbh->prepare($query);
443 $sth->execute( $course_item->{'ci_id'} );
444 my $course_reserves = $sth->fetchall_arrayref( {} );
446 $course_item->{'course_reserves'} = $course_reserves
447 if ($course_reserves);
449 return $course_item;
452 =head2 ModCourseItem {
454 ModCourseItem( %params );
456 Creates or modifies an existing course item.
458 =cut
460 sub ModCourseItem {
461 my (%params) = @_;
462 warn identify_myself(%params) if $DEBUG;
464 my $itemnumber = $params{'itemnumber'};
466 return unless ($itemnumber);
468 my $course_item = GetCourseItem( itemnumber => $itemnumber );
470 my $ci_id;
472 if ($course_item) {
473 $ci_id = $course_item->{'ci_id'};
475 _UpdateCourseItem(
476 ci_id => $ci_id,
477 course_item => $course_item,
478 %params
480 } else {
481 $ci_id = _AddCourseItem(%params);
484 return $ci_id;
488 =head2 _AddCourseItem
490 my $ci_id = _AddCourseItem( %params );
492 =cut
494 sub _AddCourseItem {
495 my (%params) = @_;
496 warn identify_myself(%params) if $DEBUG;
498 $params{homebranch} ||= undef; # Can't be empty string, FK constraint
499 $params{holdingbranch} ||= undef; # Can't be empty string, FK constraint
501 my %data = map { $_ => $params{$_} } @FIELDS;
502 my %enabled = map { $_ . "_enabled" => $params{ $_ . "_enabled" } } @FIELDS;
504 my $ci = Koha::Course::Item->new(
506 itemnumber => $params{itemnumber},
507 %data,
508 %enabled,
510 )->store();
512 return $ci->id;
515 =head2 _UpdateCourseItem
517 _UpdateCourseItem( %params );
519 =cut
521 sub _UpdateCourseItem {
522 my (%params) = @_;
523 warn identify_myself(%params) if $DEBUG;
525 my $ci_id = $params{'ci_id'};
526 my $course_item = $params{'course_item'};
528 $params{homebranch} ||= undef; # Can't be empty string, FK constraint
529 $params{holdingbranch} ||= undef; # Can't be empty string, FK constraint
531 return unless ( $ci_id || $course_item );
533 $course_item = Koha::Course::Items->find( $ci_id || $course_item->{ci_id} );
535 my %data = map { $_ => $params{$_} } @FIELDS;
536 my %enabled = map { $_ . "_enabled" => $params{ $_ . "_enabled" } } @FIELDS;
538 my $item = Koha::Items->find( $course_item->itemnumber );
540 # Handle updates to changed fields for a course item, both adding and removing
541 if ( $course_item->is_enabled ) {
542 my $item_fields = {};
544 for my $field ( @FIELDS ) {
546 my $field_enabled = $field . '_enabled';
547 my $field_storage = $field . '_storage';
549 # Find newly enabled field and add item value to storage
550 if ( $params{$field_enabled} && !$course_item->$field_enabled ) {
551 $enabled{$field_storage} = $item->$field;
552 $item_fields->{$field} = $params{$field};
554 # Find newly disabled field and copy the storage value to the item, unset storage value
555 elsif ( !$params{$field_enabled} && $course_item->$field_enabled ) {
556 $item_fields->{$field} = $course_item->$field_storage;
557 $enabled{$field_storage} = undef;
559 # The field was already enabled, copy the incoming value to the item.
560 # The "original" ( when not on course reserve ) value is already in the storage field
561 elsif ( $course_item->$field_enabled) {
562 $item_fields->{$field} = $params{$field};
566 $item->set( $item_fields )->store
567 if keys %$item_fields;
570 $course_item->update( { %data, %enabled } );
574 =head2 _RevertFields
576 _RevertFields( ci_id => $ci_id, fields => \@fields_to_revert );
578 Copies fields from course item storage back to the actual item
580 =cut
582 sub _RevertFields {
583 my (%params) = @_;
584 warn identify_myself(%params) if $DEBUG;
586 my $ci_id = $params{'ci_id'};
588 return unless $ci_id;
590 my $course_item = Koha::Course::Items->find( $ci_id );
592 my $item_fields = {};
593 $item_fields->{itype} = $course_item->itype_storage if $course_item->itype_enabled;
594 $item_fields->{ccode} = $course_item->ccode_storage if $course_item->ccode_enabled;
595 $item_fields->{location} = $course_item->location_storage if $course_item->location_enabled;
596 $item_fields->{homebranch} = $course_item->homebranch_storage if $course_item->homebranch_enabled;
597 $item_fields->{holdingbranch} = $course_item->holdingbranch_storage if $course_item->holdingbranch_enabled;
599 Koha::Items->find( $course_item->itemnumber )
600 ->set( $item_fields )
601 ->store
602 if keys %$item_fields;
604 $course_item->itype_storage(undef);
605 $course_item->ccode_storage(undef);
606 $course_item->location_storage(undef);
607 $course_item->homebranch_storage(undef);
608 $course_item->holdingbranch_storage(undef);
609 $course_item->store();
612 =head2 _SwapAllFields
614 _SwapAllFields( $ci_id );
616 =cut
618 sub _SwapAllFields {
619 my ( $ci_id, $enabled ) = @_;
620 warn "C4::CourseReserves::_SwapFields( $ci_id )" if $DEBUG;
622 my $course_item = Koha::Course::Items->find( $ci_id );
623 my $item = Koha::Items->find( $course_item->itemnumber );
625 if ( $enabled eq 'yes' ) { # Copy item fields to course item storage, course item fields to item
626 $course_item->itype_storage( $item->effective_itemtype ) if $course_item->itype_enabled;
627 $course_item->ccode_storage( $item->ccode ) if $course_item->ccode_enabled;
628 $course_item->location_storage( $item->location ) if $course_item->location_enabled;
629 $course_item->homebranch_storage( $item->homebranch ) if $course_item->homebranch_enabled;
630 $course_item->holdingbranch_storage( $item->holdingbranch ) if $course_item->holdingbranch_enabled;
631 $course_item->store();
633 my $item_fields = {};
634 $item_fields->{itype} = $course_item->itype if $course_item->itype_enabled;
635 $item_fields->{ccode} = $course_item->ccode if $course_item->ccode_enabled;
636 $item_fields->{location} = $course_item->location if $course_item->location_enabled;
637 $item_fields->{homebranch} = $course_item->homebranch if $course_item->homebranch_enabled;
638 $item_fields->{holdingbranch} = $course_item->holdingbranch if $course_item->holdingbranch_enabled;
640 Koha::Items->find( $course_item->itemnumber )
641 ->set( $item_fields )
642 ->store
643 if keys %$item_fields;
645 } else { # Copy course item storage to item
646 my $item_fields = {};
647 $item_fields->{itype} = $course_item->itype_storage if $course_item->itype_enabled;
648 $item_fields->{ccode} = $course_item->ccode_storage if $course_item->ccode_enabled;
649 $item_fields->{location} = $course_item->location_storage if $course_item->location_enabled;
650 $item_fields->{homebranch} = $course_item->homebranch_storage if $course_item->homebranch_enabled;
651 $item_fields->{holdingbranch} = $course_item->holdingbranch_storage if $course_item->holdingbranch_enabled;
653 Koha::Items->find( $course_item->itemnumber )
654 ->set( $item_fields )
655 ->store
656 if keys %$item_fields;
658 $course_item->itype_storage(undef);
659 $course_item->ccode_storage(undef);
660 $course_item->location_storage(undef);
661 $course_item->homebranch_storage(undef);
662 $course_item->holdingbranch_storage(undef);
663 $course_item->store();
667 =head2 GetCourseItems {
669 $course_items = GetCourseItems(
670 [course_id => $course_id]
671 [, itemnumber => $itemnumber ]
674 =cut
676 sub GetCourseItems {
677 my (%params) = @_;
678 warn identify_myself(%params) if $DEBUG;
680 my $course_id = $params{'course_id'};
681 my $itemnumber = $params{'itemnumber'};
683 return unless ($course_id);
685 my @query_keys;
686 my @query_values;
688 my $query = "SELECT * FROM course_items";
690 if ( keys %params ) {
692 $query .= " WHERE ";
694 foreach my $key ( keys %params ) {
695 push( @query_keys, " $key LIKE ? " );
696 push( @query_values, $params{$key} );
699 $query .= join( ' AND ', @query_keys );
702 my $dbh = C4::Context->dbh;
703 my $sth = $dbh->prepare($query);
704 $sth->execute(@query_values);
706 return $sth->fetchall_arrayref( {} );
709 =head2 DelCourseItem {
711 DelCourseItem( ci_id => $cr_id );
713 =cut
715 sub DelCourseItem {
716 my (%params) = @_;
717 warn identify_myself(%params) if $DEBUG;
719 my $ci_id = $params{'ci_id'};
721 return unless ($ci_id);
723 my $course_item = Koha::Course::Items->find( $ci_id );
724 return unless $course_item;
726 _RevertFields( ci_id => $ci_id ) if $course_item->enabled eq 'yes';
728 my $query = "
729 DELETE FROM course_items
730 WHERE ci_id = ?
732 C4::Context->dbh->do( $query, undef, $ci_id );
735 =head2 GetCourseReserve {
737 $course_item = GetCourseReserve( %params );
739 =cut
741 sub GetCourseReserve {
742 my (%params) = @_;
743 warn identify_myself(%params) if $DEBUG;
745 my $cr_id = $params{'cr_id'};
746 my $course_id = $params{'course_id'};
747 my $ci_id = $params{'ci_id'};
749 return unless ( $cr_id || ( $course_id && $ci_id ) );
751 my $dbh = C4::Context->dbh;
752 my $sth;
754 if ($cr_id) {
755 my $query = "
756 SELECT * FROM course_reserves
757 WHERE cr_id = ?
759 $sth = $dbh->prepare($query);
760 $sth->execute($cr_id);
761 } else {
762 my $query = "
763 SELECT * FROM course_reserves
764 WHERE course_id = ? AND ci_id = ?
766 $sth = $dbh->prepare($query);
767 $sth->execute( $course_id, $ci_id );
770 my $course_reserve = $sth->fetchrow_hashref();
771 return $course_reserve;
774 =head2 ModCourseReserve
776 $id = ModCourseReserve( %params );
778 =cut
780 sub ModCourseReserve {
781 my (%params) = @_;
782 warn identify_myself(%params) if $DEBUG;
784 my $course_id = $params{'course_id'};
785 my $ci_id = $params{'ci_id'};
786 my $staff_note = $params{'staff_note'};
787 my $public_note = $params{'public_note'};
789 return unless ( $course_id && $ci_id );
791 my $course_reserve = GetCourseReserve( course_id => $course_id, ci_id => $ci_id );
792 my $cr_id;
794 my $dbh = C4::Context->dbh;
796 if ($course_reserve) {
797 $cr_id = $course_reserve->{'cr_id'};
799 my $query = "
800 UPDATE course_reserves
801 SET staff_note = ?, public_note = ?
802 WHERE cr_id = ?
804 $dbh->do( $query, undef, $staff_note, $public_note, $cr_id );
805 } else {
806 my $query = "
807 INSERT INTO course_reserves SET
808 course_id = ?,
809 ci_id = ?,
810 staff_note = ?,
811 public_note = ?
813 $dbh->do( $query, undef, $course_id, $ci_id, $staff_note, $public_note );
814 $cr_id = $dbh->last_insert_id( undef, undef, 'course_reserves', 'cr_id' );
817 EnableOrDisableCourseItem(
818 ci_id => $params{'ci_id'},
821 return $cr_id;
824 =head2 GetCourseReserves {
826 $course_reserves = GetCourseReserves( %params );
828 Required:
829 course_id OR ci_id
830 Optional:
831 include_items => 1,
832 include_count => 1,
833 include_courses => 1,
835 =cut
837 sub GetCourseReserves {
838 my (%params) = @_;
839 warn identify_myself(%params) if $DEBUG;
841 my $course_id = $params{'course_id'};
842 my $ci_id = $params{'ci_id'};
843 my $include_items = $params{'include_items'};
844 my $include_count = $params{'include_count'};
845 my $include_courses = $params{'include_courses'};
847 return unless ( $course_id || $ci_id );
849 my $field = ($course_id) ? 'course_id' : 'ci_id';
850 my $value = ($course_id) ? $course_id : $ci_id;
852 my $query = "
853 SELECT cr.*, ci.itemnumber
854 FROM course_reserves cr, course_items ci
855 WHERE cr.$field = ?
856 AND cr.ci_id = ci.ci_id
858 my $dbh = C4::Context->dbh;
859 my $sth = $dbh->prepare($query);
860 $sth->execute($value);
862 my $course_reserves = $sth->fetchall_arrayref( {} );
864 if ($include_items) {
865 foreach my $cr (@$course_reserves) {
866 my $item = Koha::Items->find( $cr->{itemnumber} );
867 my $biblio = $item->biblio;
868 my $biblioitem = $biblio->biblioitem;
869 $cr->{'course_item'} = GetCourseItem( ci_id => $cr->{'ci_id'} );
870 $cr->{'item'} = $item;
871 $cr->{'biblio'} = $biblio;
872 $cr->{'biblioitem'} = $biblioitem;
873 $cr->{'issue'} = GetOpenIssue( $cr->{'itemnumber'} );
877 if ($include_count) {
878 foreach my $cr (@$course_reserves) {
879 $cr->{'reserves_count'} = CountCourseReservesForItem( ci_id => $cr->{'ci_id'} );
883 if ($include_courses) {
884 foreach my $cr (@$course_reserves) {
885 $cr->{'courses'} = GetCourses( itemnumber => $cr->{'itemnumber'} );
889 return $course_reserves;
892 =head2 DelCourseReserve {
894 DelCourseReserve( cr_id => $cr_id );
896 =cut
898 sub DelCourseReserve {
899 my (%params) = @_;
900 warn identify_myself(%params) if $DEBUG;
902 my $cr_id = $params{'cr_id'};
904 return unless ($cr_id);
906 my $dbh = C4::Context->dbh;
908 my $course_reserve = GetCourseReserve( cr_id => $cr_id );
910 my $query = "
911 DELETE FROM course_reserves
912 WHERE cr_id = ?
914 $dbh->do( $query, undef, $cr_id );
916 ## If there are no other course reserves for this item
917 ## delete the course_item as well
918 unless ( CountCourseReservesForItem( ci_id => $course_reserve->{'ci_id'} ) ) {
919 DelCourseItem( ci_id => $course_reserve->{'ci_id'} );
924 =head2 GetItemCourseReservesInfo
926 my $arrayref = GetItemCourseReservesInfo( itemnumber => $itemnumber );
928 For a given item, returns an arrayref of reserves hashrefs,
929 with a course hashref under the key 'course'
931 =cut
933 sub GetItemCourseReservesInfo {
934 my (%params) = @_;
935 warn identify_myself(%params) if $DEBUG;
937 my $itemnumber = $params{'itemnumber'};
939 return unless ($itemnumber);
941 my $course_item = GetCourseItem( itemnumber => $itemnumber );
943 return unless ( keys %$course_item );
945 my $course_reserves = GetCourseReserves( ci_id => $course_item->{'ci_id'} );
947 foreach my $cr (@$course_reserves) {
948 $cr->{'course'} = GetCourse( $cr->{'course_id'} );
951 return $course_reserves;
954 =head2 CountCourseReservesForItem
956 $bool = CountCourseReservesForItem( %params );
958 ci_id - course_item id
960 itemnumber - course_item itemnumber
962 enabled = 'yes' or 'no'
963 Optional, if not supplied, counts reserves
964 for both enabled and disabled courses
966 =cut
968 sub CountCourseReservesForItem {
969 my (%params) = @_;
970 warn identify_myself(%params) if $DEBUG;
972 my $ci_id = $params{'ci_id'};
973 my $itemnumber = $params{'itemnumber'};
974 my $enabled = $params{'enabled'};
976 return unless ( $ci_id || $itemnumber );
978 my $course_item = GetCourseItem( ci_id => $ci_id, itemnumber => $itemnumber );
980 my @params = ( $course_item->{'ci_id'} );
981 push( @params, $enabled ) if ($enabled);
983 my $query = "
984 SELECT COUNT(*) AS count
985 FROM course_reserves cr
986 LEFT JOIN courses c ON ( c.course_id = cr.course_id )
987 WHERE ci_id = ?
989 $query .= "AND c.enabled = ?" if ($enabled);
991 my $dbh = C4::Context->dbh;
992 my $sth = $dbh->prepare($query);
993 $sth->execute(@params);
995 my $row = $sth->fetchrow_hashref();
997 return $row->{'count'};
1000 =head2 SearchCourses
1002 my $courses = SearchCourses( term => $search_term, enabled => 'yes' );
1004 =cut
1006 sub SearchCourses {
1007 my (%params) = @_;
1008 warn identify_myself(%params) if $DEBUG;
1010 my $term = $params{'term'};
1012 my $enabled = $params{'enabled'} || '%';
1014 my @params;
1015 my $query = "
1016 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
1017 FROM courses c
1018 LEFT JOIN course_instructors ci
1019 ON ( c.course_id = ci.course_id )
1020 LEFT JOIN borrowers b
1021 ON ( ci.borrowernumber = b.borrowernumber )
1022 LEFT JOIN authorised_values av
1023 ON ( c.department = av.authorised_value )
1024 WHERE
1025 ( av.category = 'DEPARTMENT' OR av.category = 'TERM' )
1028 department LIKE ? OR
1029 course_number LIKE ? OR
1030 section LIKE ? OR
1031 course_name LIKE ? OR
1032 term LIKE ? OR
1033 public_note LIKE ? OR
1034 CONCAT(surname,' ',firstname) LIKE ? OR
1035 CONCAT(firstname,' ',surname) LIKE ? OR
1036 lib LIKE ? OR
1037 lib_opac LIKE ?
1040 c.enabled LIKE ?
1041 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
1044 $term //= '';
1045 $term = "%$term%";
1046 @params = ($term) x 10;
1048 $query .= " ORDER BY department, course_number, section, term, course_name ";
1050 my $dbh = C4::Context->dbh;
1051 my $sth = $dbh->prepare($query);
1053 $sth->execute( @params, $enabled );
1055 my $courses = $sth->fetchall_arrayref( {} );
1057 foreach my $c (@$courses) {
1058 $c->{'instructors'} = GetCourseInstructors( $c->{'course_id'} );
1061 return $courses;
1064 sub whoami { ( caller(1) )[3] }
1065 sub whowasi { ( caller(2) )[3] }
1067 sub stringify_params {
1068 my (%params) = @_;
1070 my $string = "\n";
1072 foreach my $key ( keys %params ) {
1073 $string .= " $key => " . $params{$key} . "\n";
1076 return "( $string )";
1079 sub identify_myself {
1080 my (%params) = @_;
1082 return whowasi() . stringify_params(%params);
1087 =head1 AUTHOR
1089 Kyle M Hall <kyle@bywatersolutions.com>
1091 =cut