From 7baf7a9bf4d37eaeed3d3a3bf657ecc4e874e720 Mon Sep 17 00:00:00 2001 From: Maxime Pelletier Date: Tue, 27 Sep 2011 12:27:08 -0400 Subject: [PATCH] =?UTF-8?q?Version=203.6=20de=20la=20r=C3=A9serve=20des=20professeurs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New feature reserves for courses --- C4/Circulation.pm | 5 + C4/Courses.pm | 65 ++++++++ C4/Items.pm | 167 ++++++++++---------- C4/XSLT.pm | 3 + cataloguing/additem.pl | 40 +++-- circ/returns.pl | 10 ++ .../prog/en/modules/cataloguing/additem.tt | 37 +++++ .../intranet-tmpl/prog/en/modules/circ/returns.tt | 7 + .../prog/en/modules/tools/batchMod-edit.tt | 38 +++++ koha-tmpl/opac-tmpl/prog/en/css/datatables.css | 42 +++--- koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc | 1 + .../lib/jquery/plugins/jquery.tablesorter.min.js | 4 +- .../prog/en/modules/opac-coursereserves.tt | 48 ++++++ .../prog/en/xslt/MARC21slim2OPACResults.xsl | 6 + lbo_sql/lbo_RM1738_reserve_profs.sql | 23 +++ opac/opac-coursereserves.pl | 33 ++++ t/db_dependent/Courses.t | 41 +++++ tools/batchMod.pl | 24 ++-- 21 files changed, 524 insertions(+), 132 deletions(-) create mode 100644 C4/Courses.pm create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-coursereserves.tt create mode 100644 lbo_sql/lbo_RM1738_reserve_profs.sql create mode 100644 opac/opac-coursereserves.pl create mode 100644 t/db_dependent/Courses.t diff --git a/C4/Circulation.pm b/C4/Circulation.pm index d41da1f..8328e18 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1597,6 +1597,11 @@ sub AddReturn { $messages->{'wthdrawn'} = 1; $doreturn = 0; } + + # book is reserved to a teacher + if ( $doreturn && ($item->{'notforloan'} == 101 || $item->{'notforloan'} == -101 )) { + $messages->{'coursereserve'} = 1; + } # case of a return of document (deal with issues and holdingbranch) if ($doreturn) { diff --git a/C4/Courses.pm b/C4/Courses.pm new file mode 100644 index 0000000..8795316 --- /dev/null +++ b/C4/Courses.pm @@ -0,0 +1,65 @@ +package C4::Courses; + +use strict; +use warnings; +use vars qw($VERSION); +use Data::Dumper; +use C4::Context; + +BEGIN { + $VERSION = 1.00; # set the version for version checking +} + +sub GetReserveFromItemNumber { + my ($itemnumber) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT * FROM reserve_courses WHERE itemnumber = ?"); + + $sth->execute($itemnumber); + my $data = $sth->fetchrow_hashref; + $sth->finish; + return ($data); +} + +sub GetAllReserves { + my @results; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare('SELECT *, + ExtractValue(biblioitems.marcxml,"//record/datafield[@tag=\"245\"]/subfield[@code=\"h\"]") AS typedocument, + ExtractValue(biblioitems.marcxml,"//record/datafield[@tag=\"245\"]/subfield[@code=\"b\"]") AS subtitle + FROM items + JOIN reserve_courses USING (itemnumber) + JOIN biblio USING (biblionumber) + JOIN biblioitems USING (biblionumber) + JOIN branches b ON (b.branchcode = holdingbranch) + LEFT OUTER JOIN authorised_values av ON (av.authorised_value = items.location) + WHERE notforloan = 101 OR notforloan = -101'); + $sth->execute(); + while ( my $data = $sth->fetchrow_hashref ) { + push @results, $data; + } + + $sth->finish; + return @results; +} + +sub DeleteReserveFromItemNumber { + my ($itemnumber) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("DELETE FROM reserve_courses WHERE itemnumber = ?"); + $sth->execute($itemnumber); + return; +} + +sub SaveReserve { + my ($itemnumber, $teacher_name, $course_name) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("DELETE FROM reserve_courses WHERE itemnumber = ?"); + $sth->execute($itemnumber); + $sth = $dbh->prepare("INSERT INTO reserve_courses(teacher_name, course_name, itemnumber) + VALUES (?, ?, ?)"); + $sth->execute($teacher_name, $course_name, $itemnumber); + return; +} + +1; diff --git a/C4/Items.pm b/C4/Items.pm index 30de1b3..b1be35e 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -32,6 +32,7 @@ use C4::Log; use List::MoreUtils qw/any/; use Data::Dumper; # used as part of logging item record changes, not just for # debugging; so please don't remove this +use C4::Courses; #DeleteReserveFromItemNumber use vars qw($VERSION @ISA @EXPORT); @@ -2246,6 +2247,9 @@ Internal function to delete an item record from the koha tables sub _koha_delete_item { my ( $dbh, $itemnum ) = @_; + + # delete the course reservations + C4::Courses::DeleteReserveFromItemNumber($itemnum); # save the deleted item to deleteditems table my $sth = $dbh->prepare("SELECT * FROM items WHERE itemnumber=?"); diff --git a/C4/XSLT.pm b/C4/XSLT.pm index f9eb65c..e793571 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -249,6 +249,9 @@ sub buildKohaItemsNamespace { if ( $item->{itemnotforloan} > 0 || $item->{notforloan} > 0 || $itemtypes->{ $item->{itype} }->{notforloan} == 1 ) { $status = "reference"; } + if ( $item->{itemnotforloan} == 101 || $item->{notforloan} == -101 ) { + $status = "reserveprofs"; + } if ($item->{onloan}) { $status = "Checked out"; } diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl index 9c8120e..41a0e7f 100755 --- a/cataloguing/additem.pl +++ b/cataloguing/additem.pl @@ -33,6 +33,7 @@ use C4::ClassSource; use C4::Dates; use List::MoreUtils qw/any/; use C4::Search; +use C4::Courses; use MARC::File::XML; use URI::Escape; @@ -348,6 +349,7 @@ if ($op eq "additem") { # if barcode exists, don't create, but report The problem. unless ($exist_itemnumber) { my ($oldbiblionumber,$oldbibnum,$oldbibitemnum) = AddItemFromMarc($record,$biblionumber); + C4::Courses::SaveReserve($oldbibitemnum, $input->param('teacher_name'), $input->param('course_name')); set_item_default_location($oldbibitemnum); } $nextop = "additem"; @@ -517,6 +519,7 @@ if ($op eq "additem") { push @errors,"barcode_not_unique"; } else { ModItemFromMarc($itemtosave,$biblionumber,$itemnumber); + C4::Courses::SaveReserve($itemnumber, $input->param('teacher_name'), $input->param('course_name')); $itemnumber=""; } $nextop="additem"; @@ -710,6 +712,8 @@ foreach my $tag ( keys %{$tagslib}){ } @loop_data = sort {$a->{subfield} cmp $b->{subfield} } @loop_data; +my $reserve = C4::Courses::GetReserveFromItemNumber($itemnumber); + # what's the next op ? it's what we are not in : an add if we're editing, otherwise, and edit. $template->param( title => $record->title() ) if ($record ne "-1"); $template->param( @@ -725,6 +729,8 @@ $template->param( op => $nextop, opisadd => ($nextop eq "saveitem") ? 0 : 1, C4::Search::enabled_staff_search_views, + teacher_name => $reserve->{teacher_name}, + course_name => $reserve->{course_name}, ); if ($frameworkcode eq 'FA'){ diff --git a/circ/returns.pl b/circ/returns.pl index bd60d42..109fc96 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -334,6 +334,13 @@ if ( $messages->{'Wrongbranch'} ){ ); } +if ( $messages->{'coursereserve'} ){ + $template->param( + found => 1, + coursereserve => 1 + ); +} + # case of wrong transfert, if the document wasn't transfered to the right library (according to branchtransfer (tobranch) BDD) if ( $messages->{'WrongTransfer'} and not $messages->{'WasTransfered'}) { @@ -470,6 +477,9 @@ foreach my $code ( keys %$messages ) { $err{debarborrowernumber} = $borrower->{borrowernumber}; $err{debarname} = "$borrower->{firstname} $borrower->{surname}"; } + elsif ( $code eq 'coursereserve' ) { + } + else { die "Unknown error code $code"; # note we need all the (empty) elsif's above, or we die. # This forces the issue of staying in sync w/ Circulation.pm diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt index eabf5a8..c819c8b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt @@ -16,6 +16,31 @@ $(document).ready(function(){ $(this).append("Edit Item Delete Item"); } }); + + lstNotLoad = $('[id^="tag_952_subfield_7"]'); + divNotLoan = lstNotLoad.parent().parent(); + //Move the course and teacher fields below the not_for_load field + $("#course_name").insertAfter(divNotLoan); + $("#teacher_name").insertAfter(divNotLoan); + //Hide the course and teacher fields if not_for_loan isn't "Réservé par professeur" + if (lstNotLoad.val() != 101 && lstNotLoad.val() != -101) + { + $("#course_name").hide(); + $("#teacher_name").hide(); + } + lstNotLoad.bind('change', function() { + //If not_for_loan changes to "Réservé par professeur" show the course and teacher fields + if ($(this).val() == 101 || $(this).val() == -101) + { + $("#course_name").show(); + $("#teacher_name").show(); + } + else //Else, hide them + { + $("#course_name").hide(); + $("#teacher_name").hide(); + } + }); }); function active(numlayer) { @@ -244,6 +269,18 @@ $(document).ready(function() { [% IF ( ite.mandatory ) %] Required[% END %] [% END %] +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt index 835724f..efff50c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt @@ -208,6 +208,13 @@ $(document).ready(function () { [% END %] [% END %] + + [% IF ( coursereserve ) %] + +
    +

    Please return [% title or "item" |html %] to the reserved items

    +
    + [% END %] [% IF ( needstransfer ) %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-edit.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-edit.tt index bc6b7c6..56b35e1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-edit.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-edit.tt @@ -37,6 +37,32 @@ $("input[name='disable_input']").click(function() { } }); +$(document).ready(function() { + lstNotLoad = $('[id^="tag_952_subfield_7"]'); + divNotLoan = lstNotLoad.parent().parent(); + //Move the course and teacher fields below the not_for_load field + $("#course_name").insertAfter(divNotLoan); + $("#teacher_name").insertAfter(divNotLoan); + //Hide the course and teacher fields if not_for_loan isn't "Réservé par professeur" + if (lstNotLoad.val() != 101 && lstNotLoad.val() != -101) + { + $("#course_name").hide(); + $("#teacher_name").hide(); + } + lstNotLoad.bind('change', function() { + //If not_for_loan changes to "Réservé par professeur" show the course and teacher fields + if ($(this).val() == 101 || $(this).val() == -101) + { + $("#course_name").show(); + $("#teacher_name").show(); + } + else //Else, hide them + { + $("#course_name").hide(); + $("#teacher_name").hide(); + } + }); +}); //]]> @@ -160,6 +186,18 @@ $("input[name='disable_input']").click(function() { [% END %] +
  • +
    + + +
    +
  • +
  • +
    + + +
    +
  • diff --git a/koha-tmpl/opac-tmpl/prog/en/css/datatables.css b/koha-tmpl/opac-tmpl/prog/en/css/datatables.css index e7b11bd..2a80b5a 100644 --- a/koha-tmpl/opac-tmpl/prog/en/css/datatables.css +++ b/koha-tmpl/opac-tmpl/prog/en/css/datatables.css @@ -3,23 +3,23 @@ input.search_init { } .sorting_asc { padding-right: 19px; - background: url("../../img/asc.gif") no-repeat scroll right center #EEEEEE; + background: url("../../images/asc.gif") no-repeat scroll right center #EEEEEE; } .sorting_desc { padding-right: 19px; - background: url("../../img/desc.gif") no-repeat scroll right center #EEEEEE; + background: url("../../images/desc.gif") no-repeat scroll right center #EEEEEE; } .sorting { padding-right: 19px; - background: url("../../img/ascdesc.gif") no-repeat scroll right center #EEEEEE; + background: url("../../images/ascdesc.gif") no-repeat scroll right center #EEEEEE; } .sorting_asc_disabled { padding-right: 19px; - background: url("../../img/datatables/sort_asc_disabled.png") no-repeat scroll right center #EEEEEE; + background: url("../../images/datatables/sort_asc_disabled.png") no-repeat scroll right center #EEEEEE; } .sorting_desc_disabled { padding-right: 19px; - background: url("../../img/datatables/sort_desc_disabled.png") no-repeat scroll right center #EEEEEE; + background: url("../../images/datatables/sort_desc_disabled.png") no-repeat scroll right center #EEEEEE; } .sorting_disabled { padding-right: 19px; @@ -83,25 +83,25 @@ div.dataTables_paginate { color : #0000CC; } .paging_full_numbers span.paginate_button.first { - background-image : url('../../img/first.png'); + background-image : url('../../images/first.png'); background-repeat: no-repeat; background-position : 2px center; padding-left : 2em; } .paging_full_numbers span.paginate_button.previous { - background-image : url('../../img/prev.png'); + background-image : url('../../images/prev.png'); background-repeat: no-repeat; background-position : 2px center; padding-left : 2em; } .paging_full_numbers span.paginate_button.next { - background-image : url('../../img/next.png'); + background-image : url('../../images/next.png'); background-repeat: no-repeat; background-position : right center; padding-right : 2em; } .paging_full_numbers span.paginate_button.last { - background-image : url('../../img/last.png'); + background-image : url('../../images/last.png'); background-repeat: no-repeat; background-position : right center; border-right : 1px solid #686868; @@ -147,31 +147,31 @@ div.dataTables_paginate.paging_four_button { width: 16px; } .paginate_disabled_first { - background-image: url("../../img/first-disabled.png"); + background-image: url("../../images/first-disabled.png"); } .paginate_enabled_first { - background-image: url("../../img/first.png"); + background-image: url("../../images/first.png"); cursor: pointer; } .paginate_disabled_previous { - background-image: url("../../img/prev-disabled.png"); + background-image: url("../../images/prev-disabled.png"); } .paginate_enabled_previous { - background-image: url("../../img/prev.png"); + background-image: url("../../images/prev.png"); cursor: pointer; } .paginate_disabled_next { - background-image: url("../../img/next-disabled.png"); + background-image: url("../../images/next-disabled.png"); } .paginate_enabled_next { - background-image: url("../../img/next.png"); + background-image: url("../../images/next.png"); cursor: pointer; } .paginate_disabled_last { - background-image: url("../../img/last-disabled.png"); + background-image: url("../../images/last-disabled.png"); } .paginate_enabled_last { - background-image: url("../../img/last.png"); + background-image: url("../../images/last.png"); cursor: pointer; } @@ -248,16 +248,16 @@ table.display thead th { width: 19px; } .paginate_disabled_previous { - background-image: url("../../img/datatables/back_disabled.jpg"); + background-image: url("../../images/datatables/back_disabled.jpg"); } .paginate_enabled_previous { - background-image: url("../../img/datatables/back_enabled.jpg"); + background-image: url("../../images/datatables/back_enabled.jpg"); } .paginate_disabled_next { - background-image: url("../../img/datatables/forward_disabled.jpg"); + background-image: url("../../images/datatables/forward_disabled.jpg"); } .paginate_enabled_next { - background-image: url("../../img/datatables/forward_enabled.jpg"); + background-image: url("../../images/datatables/forward_enabled.jpg"); } .spacer { clear: both; diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc index 822cb6e..96793ea 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc @@ -121,6 +121,7 @@ [% ELSIF ( OPACViewOthersSuggestions ) %] | Purchase suggestions [% END %] [% END %] + | Course reserves diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-coursereserves.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-coursereserves.tt new file mode 100644 index 0000000..878e30f --- /dev/null +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-coursereserves.tt @@ -0,0 +1,48 @@ +[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog › Course Reserves Search +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'datatables-strings.inc' %] + + + + +[% INCLUDE 'masthead.inc' %] +

    Course reserves

    +
    + + + + + + + + + + +[% FOREACH course_reserves_loo IN course_reserves_loop %] + + + + + + + + +[% END %] + +
    TitleAuthorCall NumberLocationTeacherCourse
    + + [% course_reserves_loo.title %] [% course_reserves_loo.typedocument %] [% course_reserves_loo.subtitle %] + + [% course_reserves_loo.author %][% course_reserves_loo.itemcallnumber %][% course_reserves_loo.lib_opac %][% course_reserves_loo.teacher_name %][% course_reserves_loo.course_name %]
    +
    +[% INCLUDE 'opac-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl index 2b5aacc..0993fa4 100644 --- a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl +++ b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl @@ -1074,6 +1074,12 @@ ). + + + Reserved by teacher ( + + ). + Lost ( diff --git a/lbo_sql/lbo_RM1738_reserve_profs.sql b/lbo_sql/lbo_RM1738_reserve_profs.sql new file mode 100644 index 0000000..c9d04a4 --- /dev/null +++ b/lbo_sql/lbo_RM1738_reserve_profs.sql @@ -0,0 +1,23 @@ +/* Maxime Pelletier, 27-09-2011 */ + +CREATE TABLE `reserve_courses` ( + `id` INT NOT NULL AUTO_INCREMENT , + `teacher_name` VARCHAR(80) NULL , + `course_name` VARCHAR(80) NULL , + `itemnumber` INT NULL , + PRIMARY KEY (`id`) , + INDEX `itemnumber` (`itemnumber` ASC) , + CONSTRAINT `itemnumber` + FOREIGN KEY (`itemnumber` ) + REFERENCES `items` (`itemnumber` ) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; + +INSERT INTO `authorised_values` (`category`, `authorised_value`, `lib`, `lib_opac`) + VALUES ('NOT_LOAN', '101', 'Réserve des profs', 'Réserve des profs'); +UPDATE `authorised_values` SET lib = 'Réserve des profs avec alerte', lib_opac = 'Réserve des profs avec alerte' + WHERE authorised_value = 101; + +INSERT INTO `authorised_values` (`category`, `authorised_value`, `lib`, `lib_opac`) + VALUES ('NOT_LOAN', '-101', 'Réserve des profs', 'Réserve des profs'); diff --git a/opac/opac-coursereserves.pl b/opac/opac-coursereserves.pl new file mode 100644 index 0000000..4e6c13a --- /dev/null +++ b/opac/opac-coursereserves.pl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +use strict; + +use CGI; +use C4::Context; +use C4::Auth; +use C4::Output; +use C4::Members; +use C4::Dates qw(format_date_in_iso); +use C4::Courses qw(GetCourse GetCourses GetCourseReserves); +use Date::Calc qw(Today Date_to_Days); +use C4::Branch qw(GetBranchName GetBranchesLoop); +use C4::Koha; +use C4::Items; +use Data::Dumper; + +my $query = new CGI; + +my ($template, $loggedinuser, $cookie) += get_template_and_user({ + template_name => "opac-coursereserves.tt", + query => $query, + type => "opac", + authnotrequired => 1 + }); + +my @course_reserves = C4::Courses::GetAllReserves(); + +$template->param('course_reserves_loop' => \@course_reserves); + +output_html_with_http_headers $query, $cookie, $template->output; + diff --git a/t/db_dependent/Courses.t b/t/db_dependent/Courses.t new file mode 100644 index 0000000..9a452e3 --- /dev/null +++ b/t/db_dependent/Courses.t @@ -0,0 +1,41 @@ +#!/usr/bin/perl +# +# This is to test C4/Courses +# It requires a working Koha database with the sample data + +use strict; +use warnings; + +use Test::More tests => 8; + +BEGIN { + use_ok('C4::Courses'); + use_ok('C4::Items'); +} + +#No reserves for item 1 +my $reserve = C4::Courses::GetReserveFromItemNumber(1); +is ($reserve, undef); + +#No reserves in the db +my $reserves = C4::Courses::GetAllReserves(); +is ($reserves, 0); + +#Create reserve for item 1 and check if properly added +C4::Courses::SaveReserve(1, 'teacher', 'course'); +$reserve = C4::Courses::GetReserveFromItemNumber(1); +is ($reserve->{teacher_name}, 'teacher'); +is ($reserve->{course_name}, 'course'); + +#Set the item to the proper notloan value for teacher reserve +C4::Items::ModItem({ notforloan => 101 }, undef, 1); + +#Newly created reserve should be returned +$reserves = C4::Courses::GetAllReserves(); +is ($reserves, 1); + +C4::Courses::DeleteReserveFromItemNumber(1); + +#No reserves for item 1 +$reserve = C4::Courses::GetReserveFromItemNumber(1); +is ($reserve, undef); diff --git a/tools/batchMod.pl b/tools/batchMod.pl index 5469496..e3e2287 100755 --- a/tools/batchMod.pl +++ b/tools/batchMod.pl @@ -34,6 +34,7 @@ use C4::ClassSource; use C4::Dates; use C4::Debug; use MARC::File::XML; +use C4::Courses; my $input = new CGI; my $dbh = C4::Context->dbh; @@ -189,6 +190,9 @@ if ($op eq "action") { LostItem($itemnumber, 'MARK RETURNED', 'CHARGE FEE') if $item->{itemlost}; } }; + # LIBEO - st_6478_reserve_profs + C4::Courses::SaveReserve($itemnumber, $input->param('teacher_name'), $input->param('course_name')); + # /LIBEO } } $i++; -- 1.7.2.5