Bugzilla – Attachment 46441 Details for
Bug 15261
Verify if checkout or hold request periods overlap with existing holds
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 15261: Verify if checkouts/reserves requests periods overlap...
Bug-15261-Verify-if-checkoutsreserves-requests-per.patch (text/plain), 27.19 KB, created by
Biblibre Sandboxes
on 2016-01-08 16:07:40 UTC
(
hide
)
Description:
Bug 15261: Verify if checkouts/reserves requests periods overlap...
Filename:
MIME Type:
Creator:
Biblibre Sandboxes
Created:
2016-01-08 16:07:40 UTC
Size:
27.19 KB
patch
obsolete
>From f0544e1f200afc1d72f6a82d3e3b144f02a08c62 Mon Sep 17 00:00:00 2001 >From: Alex Arnaud <alex.arnaud@biblibre.com> >Date: Thu, 26 Nov 2015 11:00:22 +0100 >Subject: [PATCH] Bug 15261: Verify if checkouts/reserves requests periods > overlap... > >... with existing reserves > >When checking out or placing hold, we should check if an existing >reserve whose period overlap exists. > >A user place an hold from opac whose requested period overlap an >existing reserve period => prevent reserve, > >A librarian place an hold from staff whose requested period overlap an >existing reserve period => Warn librarian (Ask for confirmation), > >A librarian make a checkout from staff whose requested period overlap an >existing reserve period => Warn librarian (Ask for confirmation). > >Test plan: > >Enable syspref: AllowHoldDateInFuture OPACAllowHoldDateInFuture > >1 (staff side): >Place a hold on title (which has only one items) level with start date >and expiration date. >Place another hold (also title level) with period overlaping this >reserve. >Check you are warned about an existing reserve > >2 (staff side): >Place a hold on title (which has more than one items) level with start >date and expiration date. >Place another hold (also title level) with period overlaping this >reserve. >Check you are NOT warned about an existing reserve. Because it remains >at least one item not reserved. > >3 (staff side): >Place a hold on item level with start date and expiration date. >Place another hold on item level with period overlaping this reserve. >Check you are warned about an existing reserve. > >4 (opac side): >Do the same than for staff side. Instead of a warn, reserve is >prevented. > >5: >Place a hold on title (which has only one items) level with start date >and expiration date. >Try to checkout the unique item from this title with period overlaping >the reserve period. >Check you are warned about an existing reserve > >6: >Place a hold on title (which has more than one items) level with start >date and expiration date. >Checkout an item from this title with period overlaping the reserve >period. >Check you are NOT warned about an existing reserve. > >7: >Place a hold on item level with start date and expiration date. >Checkout this item period overlaping the reserve period. >Check you are warned about an existing reserve > >Signed-off-by: delaye <stephane.delaye@biblibre.com> >--- > C4/Circulation.pm | 21 ++++ > C4/Installer/PerlDependencies.pm | 10 ++ > C4/Reserves.pm | 49 +++++++++ > Koha/DateUtils.pm | 26 ++++- > circ/circulation.pl | 4 + > .../prog/en/modules/circ/circulation.tt | 2 + > .../prog/en/modules/reserve/placerequest.tt | 66 +++++++++++ > opac/opac-reserve.pl | 8 ++ > reserve/placerequest.pl | 115 ++++++++++++-------- > t/db_dependent/Circulation/CanBookBeIssued.t | 107 ++++++++++++++++++ > t/db_dependent/Reserves/ReserveDate.t | 108 ++++++++++++++++++ > 11 files changed, 470 insertions(+), 46 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/reserve/placerequest.tt > create mode 100644 t/db_dependent/Circulation/CanBookBeIssued.t > create mode 100644 t/db_dependent/Reserves/ReserveDate.t > >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index ae53366..9f73b19 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -1037,6 +1037,7 @@ sub CanBookBeIssued { > $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'}; > $needsconfirmation{'resbranchname'} = $branchname; > $needsconfirmation{'reswaitingdate'} = $res->{'waitingdate'}; >+ $needsconfirmation{resreserveid} = $res->{reserve_id}; > } > elsif ( $restype eq "Reserved" ) { > # The item is on reserve for someone else. >@@ -1047,9 +1048,29 @@ sub CanBookBeIssued { > $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'}; > $needsconfirmation{'resbranchname'} = $branchname; > $needsconfirmation{'resreservedate'} = $res->{'reservedate'}; >+ $needsconfirmation{resreserveid} = $res->{reserve_id}; > } > } > } >+ >+ my $now = dt_from_string(); >+ my $reserves_on_same_period = >+ ReservesOnSamePeriod($item->{biblionumber}, $item->{itemnumber}, $now->ymd, $duedate); >+ if ($reserves_on_same_period) { >+ my $reserve = $reserves_on_same_period->[0]; >+ my $borrower = C4::Members::GetMember(borrowernumber => $reserve->{borrowernumber}); >+ my $branchname = GetBranchName( $reserve->{branchcode} ); >+ >+ $needsconfirmation{RESERVED} = 1; >+ $needsconfirmation{resfirstname} = $borrower->{firstname}; >+ $needsconfirmation{ressurname} = $borrower->{surname}; >+ $needsconfirmation{rescardnumber} = $borrower->{cardnumber}; >+ $needsconfirmation{resborrowernumber} = $borrower->{borrowernumber}; >+ $needsconfirmation{resbranchname} = $branchname; >+ $needsconfirmation{resreservedate} = $reserve->{reservedate}; >+ $needsconfirmation{resreserveid} = $reserve->{reserve_id}; >+ } >+ > } > > ## CHECK AGE RESTRICTION >diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm >index 778e101..c99e651 100644 >--- a/C4/Installer/PerlDependencies.pm >+++ b/C4/Installer/PerlDependencies.pm >@@ -787,6 +787,16 @@ our $PERL_DEPS = { > 'required' => '0', > 'min_ver' => '0.03', > }, >+ 'Date::Range' => { >+ 'usage' => 'Compare date range', >+ 'required' => '1', >+ 'min_ver' => '1.41', >+ }, >+ 'Date::Simple' => { >+ 'usage' => 'Works with Date::Range', >+ 'required' => '1', >+ 'min_ver' => '3.03', >+ } > }; > > 1; >diff --git a/C4/Reserves.pm b/C4/Reserves.pm >index 7bb5d69..a20c51e 100644 >--- a/C4/Reserves.pm >+++ b/C4/Reserves.pm >@@ -139,6 +139,7 @@ BEGIN { > &SuspendAll > > &GetReservesControlBranch >+ &ReservesOnSamePeriod > > IsItemOnHoldAndFound > ); >@@ -2471,6 +2472,54 @@ sub IsItemOnHoldAndFound { > return $found; > } > >+=head2 ReservesOnSamePeriod >+ >+ my $reserve = ReservesOnSamePeriod( $biblionumber, $itemnumber, $resdate, $expdate); >+ >+ Return the reserve that match the period ($resdate => $expdate), >+ undef if no reserve match. >+ >+=cut >+ >+sub ReservesOnSamePeriod { >+ my ($biblionumber, $itemnumber, $resdate, $expdate) = @_; >+ >+ unless ($resdate && $expdate) { >+ return; >+ } >+ >+ my $reserves = GetReservesFromBiblionumber({biblionumber => $biblionumber, >+ all_dates => 1}); >+ >+ $resdate = output_pref({ str => $resdate, dateonly => 1, dateformat => 'iso' }); >+ $expdate = output_pref({ str => $expdate, dateonly => 1, dateformat => 'iso' }); >+ >+ my @reserves_overlaps; >+ foreach my $reserve (@$reserves) { >+ >+ unless ($reserve->{reservedate} && $reserve->{expirationdate}) { >+ next; >+ } >+ >+ if (date_ranges_overlap($resdate, $expdate, >+ $reserve->{reservedate}, >+ $reserve->{expirationdate})) { >+ >+ # If reserve is item level and the requested periods overlap. >+ if ($itemnumber && $reserve->{itemnumber} == $itemnumber ) { >+ return [$reserve]; >+ } >+ push @reserves_overlaps, $reserve; >+ } >+ } >+ >+ if (@reserves_overlaps >= GetItemsCount($biblionumber)) { >+ return \@reserves_overlaps; >+ } >+ >+ return; >+} >+ > =head1 AUTHOR > > Koha Development Team <http://koha-community.org/> >diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm >index 65afaea..d0064ca 100644 >--- a/Koha/DateUtils.pm >+++ b/Koha/DateUtils.pm >@@ -18,6 +18,8 @@ package Koha::DateUtils; > > use Modern::Perl; > use DateTime; >+use Date::Range; >+use Date::Simple; > use C4::Context; > use Carp; > >@@ -25,7 +27,7 @@ use base 'Exporter'; > use version; our $VERSION = qv('1.0.0'); > > our @EXPORT = ( >- qw( dt_from_string output_pref format_sqldatetime ) >+ qw( dt_from_string output_pref format_sqldatetime date_ranges_overlap ) > ); > > =head1 DateUtils >@@ -296,4 +298,26 @@ sub format_sqldatetime { > return q{}; > } > >+=head2 date_ranges_overlap >+ >+ $bool = date_ranges_overlap($start1, $end1, $start2, $end2); >+ >+ Tells if first range ($start1 => $end1) overlaps >+ the second one ($start2 => $end2) >+ >+=cut >+ >+sub date_ranges_overlap { >+ my ($start1, $end1, $start2, $end2) = @_; >+ >+ my $range1 = Date::Range->new(Date::Simple->new($start1), Date::Simple->new($end1)); >+ my $range2 = Date::Range->new(Date::Simple->new($start2), Date::Simple->new($end2)); >+ >+ if ($range1->overlaps($range2)) { >+ return $range1->overlap($range2); >+ } >+ >+ return; >+} >+ > 1; >diff --git a/circ/circulation.pl b/circ/circulation.pl >index 5747fbf..44c0c7a 100755 >--- a/circ/circulation.pl >+++ b/circ/circulation.pl >@@ -410,6 +410,10 @@ if (@$barcodes) { > } > } > unless($confirm_required) { >+ if ( $cancelreserve eq 'cancel' ) { >+ CancelReserve({ reserve_id => $query->param('reserveid') }); >+ } >+ $cancelreserve = $cancelreserve eq 'revert' ? 'revert' : undef; > my $issue = AddIssue( $borrower, $barcode, $datedue, $cancelreserve, undef, undef, { onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew') } ); > $template->param( issue => $issue ); > $session->clear('auto_renew'); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >index 7c5573a..bec5aea 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -335,6 +335,7 @@ $(document).ready(function() { > [% IF ( RESERVED ) %] > <p> > <input type="checkbox" id="cancelreserve" name="cancelreserve" value="cancel" /> >+ <input type="hidden" name="reserveid" value="[% resreserveid %]" /> > <label for="cancelreserve">Cancel hold</label> > </p> > [% END %] >@@ -343,6 +344,7 @@ $(document).ready(function() { > <p> > <label for="cancelreserve">Cancel hold</label> > <input type="radio" value="cancel" name="cancelreserve" id="cancelreserve" /><br /> >+ <input type="hidden" name="reserveid" value="[% resreserveid %]" /> > <label for="revertreserve">Revert waiting status</label> > <input type="radio" value="revert" name="cancelreserve" id="revertreserve" checked="checked"/> > </p> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/placerequest.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/placerequest.tt >new file mode 100644 >index 0000000..e2b3409 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/placerequest.tt >@@ -0,0 +1,66 @@ >+[% INCLUDE 'doc-head-open.inc' %] >+ <title>Koha › Circulation › Holds › Confirm holds</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="circ_placerequest" class="catalog"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'circ-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › >+ <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a> >+ › >+ Confirm holds >+</div> >+ >+<div id="doc3" class="yui-t2"> >+ >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ >+ <h1>Confirm holds</h1> >+ >+ <div class="alert"> >+ <p> >+ Some of the reserves you are trying to do overlaps with existing reserves. >+ Please confirm you want to proceed. >+ </p> >+ </div> >+ >+ <form method="post"> >+ <input type="hidden" name="borrowernumber" value="[% borrowernumber %]"> >+ [% IF multi_hold %] >+ <input type="hidden" name="biblionumbers" value="[% biblionumbers%]"> >+ <input type="hidden" name="multi_hold" value="1"> >+ [% ELSE %] >+ <input type="hidden" name="biblionumber" value="[% biblionumber%]"> >+ [% END %] >+ <input type="hidden" name="reserve_date" value="[% reserve_date %]"> >+ <input type="hidden" name="expiration_date" value="[% expiration_date %]"> >+ <input type="hidden" name="pickup" value="[% pickup%]"> >+ <input type="hidden" name="notes" value="[% notes %]"> >+ <input type="hidden" name="confirm" value="1"> >+ >+ [% FOREACH biblionumber IN overlap_reserves.keys %] >+ [% input_id = "confirm_$biblionumber" %] >+ <div> >+ <input type="hidden" name="rank_[% biblionumber %]" value="[% overlap_reserves.$biblionumber.rank %]"> >+ [% IF (overlap_reserves.$biblionumber.checkitem) %] >+ <input type="hidden" name="checkitem" value="[% overlap_reserves.$biblionumber.checkitem%]"> >+ [% END %] >+ <input type="checkbox" name="confirm_biblionumbers" id="[% input_id %]" >+ value="[% biblionumber %]"> >+ <label for="[% input_id %]">Confirm hold for [% overlap_reserves.$biblionumber.title %]</label> >+ </div> >+ [% END %] >+ >+ <input type="submit" value="Continue"> >+ </form> >+ >+ </div> >+ </div> >+ >+ </div> >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl >index 60232cc..96f6d9c 100755 >--- a/opac/opac-reserve.pl >+++ b/opac/opac-reserve.pl >@@ -273,6 +273,14 @@ if ( $query->param('place_reserve') ) { > # Inserts a null into the 'itemnumber' field of 'reserves' table. > $itemNum = undef; > } >+ >+ if ($canreserve) { >+ if (ReservesOnSamePeriod($biblioNum, $itemNum, $startdate, $expiration_date)) { >+ $canreserve = 0; >+ $failed_holds++; >+ } >+ } >+ > my $notes = $query->param('notes_'.$biblioNum)||''; > > if ( $maxreserves >diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl >index 80dcfdc..09e81a1 100755 >--- a/reserve/placerequest.pl >+++ b/reserve/placerequest.pl >@@ -31,43 +31,57 @@ use C4::Output; > use C4::Reserves; > use C4::Circulation; > use C4::Members; >-use C4::Auth qw/checkauth/; >+use C4::Auth; > > my $input = CGI->new(); > >-checkauth($input, 0, { reserveforothers => 'place_holds' }, 'intranet'); >+my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user( >+ { >+ template_name => "reserve/placerequest.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { reserveforothers => 'place_holds' }, >+ } >+); > >-my @bibitems=$input->param('biblioitem'); >-my @reqbib=$input->param('reqbib'); > my $biblionumber=$input->param('biblionumber'); > my $borrowernumber=$input->param('borrowernumber'); > my $notes=$input->param('notes'); > my $branch=$input->param('pickup'); > my $startdate=$input->param('reserve_date') || ''; > my @rank=$input->param('rank-request'); >-my $type=$input->param('type'); > my $title=$input->param('title'); >-my $borrower=GetMember('borrowernumber'=>$borrowernumber); > my $checkitem=$input->param('checkitem'); > my $expirationdate = $input->param('expiration_date'); >+my $confirm = $input->param('confirm'); >+my @confirm_biblionumbers = $input->param('confirm_biblionumbers'); > > my $multi_hold = $input->param('multi_hold'); > my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/'); > my $bad_bibs = $input->param('bad_bibs'); > >+my $borrower=GetMember('borrowernumber'=>$borrowernumber); >+unless ($borrower) { >+ print $input->header(); >+ print "Invalid borrower number please try again"; >+ exit; >+} >+ > my %bibinfos = (); > my @biblionumbers = split '/', $biblionumbers; > foreach my $bibnum (@biblionumbers) { >- my %bibinfo = (); >+ my %bibinfo; > $bibinfo{title} = $input->param("title_$bibnum"); >+ > $bibinfo{rank} = $input->param("rank_$bibnum"); > $bibinfos{$bibnum} = \%bibinfo; > } > > my $found; > >-# if we have an item selectionned, and the pickup branch is the same as the holdingbranch >-# of the document, we force the value $rank and $found . >+# if we have an item selectionned, and the pickup branch is the same as the >+# holdingbranch of the document, we force the value $rank and $found . > if (defined $checkitem && $checkitem ne ''){ > $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns'); > my $item = $checkitem; >@@ -77,41 +91,57 @@ if (defined $checkitem && $checkitem ne ''){ > } > } > >-if ($type eq 'str8' && $borrower){ >- >- foreach my $biblionumber (keys %bibinfos) { >- my $count=@bibitems; >- @bibitems=sort @bibitems; >- my $i2=1; >- my @realbi; >- $realbi[0]=$bibitems[0]; >- for (my $i=1;$i<$count;$i++) { >- my $i3=$i2-1; >- if ($realbi[$i3] ne $bibitems[$i]) { >- $realbi[$i2]=$bibitems[$i]; >- $i2++; >- } >- } >- >- if (defined $checkitem && $checkitem ne ''){ >- my $item = GetItem($checkitem); >- if ($item->{'biblionumber'} ne $biblionumber) { >- $biblionumber = $item->{'biblionumber'}; >- } >- } >- >+my $overlap_reserves = {}; >+foreach my $biblionumber (keys %bibinfos) { >+ next if ($confirm && !grep { $_ eq $biblionumber } @confirm_biblionumbers); > >+ my ($reserve_title, $reserve_rank); >+ if ($multi_hold) { >+ my $bibinfo = $bibinfos{$biblionumber}; >+ $reserve_rank = $bibinfo->{rank}; >+ $reserve_title = $bibinfo->{title}; >+ } else { >+ $reserve_rank = $rank[0]; >+ $reserve_title = $title; >+ } > >- if ($multi_hold) { >- my $bibinfo = $bibinfos{$biblionumber}; >- AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,[$biblionumber], >- $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found); >- } else { >- # place a request on 1st available >- AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,$found); >+ if (defined $checkitem && $checkitem ne '') { >+ my $item = GetItem($checkitem); >+ if ($item->{'biblionumber'} ne $biblionumber) { >+ $biblionumber = $item->{'biblionumber'}; > } > } > >+ if (!$confirm && ReservesOnSamePeriod($biblionumber, $checkitem, $startdate, $expirationdate)) { >+ $overlap_reserves->{$biblionumber} = { >+ title => $reserve_title , >+ checkitem => $checkitem, >+ rank => $reserve_rank >+ }; >+ next; >+ } >+ >+ AddReserve($branch, $borrower->{'borrowernumber'}, $biblionumber, undef, >+ $reserve_rank, $startdate, $expirationdate, $notes, $reserve_title, >+ $checkitem, $found); >+} >+ >+if (scalar keys %$overlap_reserves) { >+ $template->param( >+ borrowernumber => $borrowernumber, >+ biblionumbers => $biblionumbers, >+ biblionumber => $biblionumber, >+ overlap_reserves => $overlap_reserves, >+ reserve_date => $startdate, >+ expiration_date => $expirationdate, >+ notes => $notes, >+ rank_request => \@rank, >+ pickup => $branch, >+ multi_hold => $multi_hold, >+ ); >+ >+ output_html_with_http_headers $input, $cookie, $template->output; >+} else { > if ($multi_hold) { > if ($bad_bibs) { > $biblionumbers .= $bad_bibs; >@@ -120,10 +150,5 @@ if ($type eq 'str8' && $borrower){ > } else { > print $input->redirect("request.pl?biblionumber=$biblionumber"); > } >-} elsif ($borrower eq ''){ >- print $input->header(); >- print "Invalid borrower number please try again"; >-# Not sure that Dump() does HTML escaping. Use firebug or something to trace >-# instead. >-# print $input->Dump; >+ exit; > } >diff --git a/t/db_dependent/Circulation/CanBookBeIssued.t b/t/db_dependent/Circulation/CanBookBeIssued.t >new file mode 100644 >index 0000000..487400d >--- /dev/null >+++ b/t/db_dependent/Circulation/CanBookBeIssued.t >@@ -0,0 +1,107 @@ >+#!/usr/bin/env perl >+ >+# 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 Test::More tests => 1; >+use C4::Members; >+use C4::Reserves; >+use C4::Circulation; >+use C4::Branch; >+use Koha::DateUtils; >+ >+use t::lib::TestBuilder; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new(); >+ >+subtest 'Tests for CanBookBeIssued with overlap reserves' => sub { >+ plan tests => 6; >+ >+ my $categorycode = $builder->build({ source => 'Category' })->{ categorycode }; >+ my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode }; >+ >+ my $borrower = $builder->build({ >+ source => 'Borrower', >+ value => { >+ branchcode => $branchcode, >+ categorycode => $categorycode, >+ } >+ }); >+ my $borrowernumber = $borrower->{borrowernumber}; >+ $borrower = GetMemberDetails($borrowernumber); >+ >+ my $biblio = $builder->build({source => 'Biblio'}); >+ my $biblioitem = $builder->build({ >+ source => 'Biblioitem', >+ value => { >+ biblionumber => $biblio->{biblionumber}, >+ }, >+ }); >+ my $item = $builder->build({ >+ source => 'Item', >+ value => { >+ biblionumber => $biblio->{biblionumber}, >+ biblioitemnumber => $biblioitem->{biblioitemnumber}, >+ withdrawn => 0, >+ itemlost => 0, >+ notforloan => 0, >+ }, >+ }); >+ >+ >+ my $startdate = dt_from_string(); >+ $startdate->add_duration(DateTime::Duration->new(days => 4)); >+ my $expdate = $startdate->clone(); >+ $expdate->add_duration(DateTime::Duration->new(days => 10)); >+ >+ my $reserveid = AddReserve($branchcode, $borrowernumber, >+ $item->{biblionumber}, undef, 1, $startdate->ymd(), $expdate->ymd, >+ undef, undef, undef, undef); >+ >+ my $non_overlap_duedate = dt_from_string(); >+ $non_overlap_duedate->add_duration(DateTime::Duration->new(days => 2)); >+ my ($error, $question, $alerts ) = >+ CanBookBeIssued($borrower, $item->{barcode}, $non_overlap_duedate, 1, 0); >+ >+ is_deeply($error, {}, ""); >+ is_deeply($question, {}, ""); >+ is_deeply($alerts, {}, ""); >+ >+ my $overlap_duedate = dt_from_string(); >+ $overlap_duedate->add_duration(DateTime::Duration->new(days => 5)); >+ ($error, $question, $alerts ) = >+ CanBookBeIssued($borrower, $item->{barcode}, $overlap_duedate, 1, 0); >+ >+ is_deeply($error, {}, ""); >+ my $expected = { >+ RESERVED => 1, >+ resfirstname => $borrower->{firstname}, >+ ressurname => $borrower->{surname}, >+ rescardnumber => $borrower->{cardnumber}, >+ resborrowernumber => $borrower->{borrowernumber}, >+ resbranchname => GetBranchName($branchcode), >+ resreservedate => $startdate->ymd, >+ resreserveid => $reserveid, >+ }; >+ is_deeply($question, $expected, ""); >+ is_deeply($alerts, {}, ""); >+}; >+ >+$schema->storage->txn_rollback; >diff --git a/t/db_dependent/Reserves/ReserveDate.t b/t/db_dependent/Reserves/ReserveDate.t >new file mode 100644 >index 0000000..4cb9025 >--- /dev/null >+++ b/t/db_dependent/Reserves/ReserveDate.t >@@ -0,0 +1,108 @@ >+#!/usr/bin/perl >+ >+# 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 Test::More tests => 6; >+use Test::Warn; >+ >+use MARC::Record; >+use DateTime::Duration; >+ >+use C4::Branch; >+use C4::Biblio; >+use C4::Items; >+use C4::Members; >+use C4::Circulation; >+use Koha::Holds; >+use t::lib::TestBuilder; >+ >+use Koha::DateUtils; >+ >+ >+use_ok('C4::Reserves'); >+ >+my $dbh = C4::Context->dbh; >+ >+# Start transaction >+$dbh->{AutoCommit} = 0; >+$dbh->{RaiseError} = 1; >+ >+my $builder = t::lib::TestBuilder->new(); >+my $categorycode = $builder->build({ source => 'Category' })->{ categorycode }; >+my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode }; >+ >+my $borrower = $builder->build({ >+ source => 'Borrower', >+ value => { >+ branchcode => $branchcode, >+ categorycode => $categorycode, >+ } >+}); >+ >+my $borrower2 = $builder->build({ >+ source => 'Borrower', >+ value => { >+ branchcode => $branchcode, >+ categorycode => $categorycode, >+ } >+}); >+ >+my $borrowernumber = $borrower->{borrowernumber}; >+my $borrowernumber2 = $borrower2->{borrowernumber}; >+ >+# Create a helper biblio >+my $biblio = MARC::Record->new(); >+my $title = 'Alone in the Dark'; >+my $author = 'Karen Rose'; >+if( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { >+ $biblio->append_fields( >+ MARC::Field->new('600', '', '1', a => $author), >+ MARC::Field->new('200', '', '', a => $title), >+ ); >+} >+else { >+ $biblio->append_fields( >+ MARC::Field->new('100', '', '', a => $author), >+ MARC::Field->new('245', '', '', a => $title), >+ ); >+} >+my ($bibnum, $bibitemnum); >+($bibnum, $title, $bibitemnum) = AddBiblio($biblio, ''); >+ >+my ($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => $branchcode, holdingbranch => $branchcode, barcode => '333' } , $bibnum); >+ >+C4::Context->set_preference('AllowHoldDateInFuture', 1); >+ >+AddReserve($branchcode, $borrowernumber, $bibnum, >+ $bibitemnum, 1, '2015-11-01', '2015-11-20', undef, >+ undef, undef, undef); >+ >+is(ReservesOnSamePeriod($bibnum, undef, '2015-11-25', '2015-11-30'), undef, "Period doesn't overlaps"); >+ >+ok(ReservesOnSamePeriod($bibnum, undef, '2015-11-02', '2015-11-10'), "Period overlaps"); >+ >+my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) = AddItem({ homebranch => $branchcode, holdingbranch => $branchcode, barcode => '444' } , $bibnum); >+is(ReservesOnSamePeriod($bibnum, undef, '2015-11-02', '2015-11-10'), undef, "Period overlaps but there is 2 items"); >+ >+AddReserve($branchcode, $borrowernumber2, $bibnum, >+ $bibitemnum, 1, '2016-02-01', '2016-02-10', undef, >+ undef, $itemnumber, undef); >+is(ReservesOnSamePeriod($bibnum, $itemnumber, '02/12/2015', '10/12/2015'), undef, "Period on item does not overlap (with metric date format)"); >+ >+ok(ReservesOnSamePeriod($bibnum, $itemnumber, '2016-01-31', '2016-02-05'), "Period on item overlaps"); >+$dbh->rollback; >-- >1.7.10.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15261
:
45216
|
45833
|
45841
|
46432
|
46433
|
46441
|
46442
|
49001
|
49002
|
49003
|
52704
|
59643
|
61534
|
61539
|
61544
|
67088
|
67094
|
67143
|
68660
|
68661
|
68662
|
68663
|
68664
|
68852
|
68853
|
72956
|
72957
|
76221
|
76222
|
88292
|
88293
|
88297
|
88298
|
92376
|
92377
|
92584
|
92585
|
92664
|
93136
|
94871
|
98383
|
98424
|
98672
|
106944
|
106949
|
120822
|
123405
|
125793
|
125794
|
125795
|
125796
|
131569
|
131570
|
131571
|
131572
|
131573