View | Details | Raw Unified | Return to bug 15261
Collapse All | Expand All

(-)a/C4/Circulation.pm (+21 lines)
Lines 1037-1042 sub CanBookBeIssued { Link Here
1037
                    $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'};
1037
                    $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'};
1038
                    $needsconfirmation{'resbranchname'} = $branchname;
1038
                    $needsconfirmation{'resbranchname'} = $branchname;
1039
                    $needsconfirmation{'reswaitingdate'} = $res->{'waitingdate'};
1039
                    $needsconfirmation{'reswaitingdate'} = $res->{'waitingdate'};
1040
                    $needsconfirmation{resreserveid} = $res->{reserve_id};
1040
                }
1041
                }
1041
                elsif ( $restype eq "Reserved" ) {
1042
                elsif ( $restype eq "Reserved" ) {
1042
                    # The item is on reserve for someone else.
1043
                    # The item is on reserve for someone else.
Lines 1047-1055 sub CanBookBeIssued { Link Here
1047
                    $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'};
1048
                    $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'};
1048
                    $needsconfirmation{'resbranchname'} = $branchname;
1049
                    $needsconfirmation{'resbranchname'} = $branchname;
1049
                    $needsconfirmation{'resreservedate'} = $res->{'reservedate'};
1050
                    $needsconfirmation{'resreservedate'} = $res->{'reservedate'};
1051
                    $needsconfirmation{resreserveid} = $res->{reserve_id};
1050
                }
1052
                }
1051
            }
1053
            }
1052
        }
1054
        }
1055
1056
        my $now = dt_from_string();
1057
        my $reserves_on_same_period =
1058
            ReservesOnSamePeriod($item->{biblionumber}, $item->{itemnumber}, $now->ymd, $duedate);
1059
        if ($reserves_on_same_period) {
1060
            my $reserve = $reserves_on_same_period->[0];
1061
            my $borrower = C4::Members::GetMember(borrowernumber => $reserve->{borrowernumber});
1062
            my $branchname = GetBranchName( $reserve->{branchcode} );
1063
1064
            $needsconfirmation{RESERVED} = 1;
1065
            $needsconfirmation{resfirstname} = $borrower->{firstname};
1066
            $needsconfirmation{ressurname} = $borrower->{surname};
1067
            $needsconfirmation{rescardnumber} = $borrower->{cardnumber};
1068
            $needsconfirmation{resborrowernumber} = $borrower->{borrowernumber};
1069
            $needsconfirmation{resbranchname} = $branchname;
1070
            $needsconfirmation{resreservedate} = $reserve->{reservedate};
1071
            $needsconfirmation{resreserveid} = $reserve->{reserve_id};
1072
        }
1073
1053
    }
1074
    }
1054
1075
1055
    ## CHECK AGE RESTRICTION
1076
    ## CHECK AGE RESTRICTION
(-)a/C4/Installer/PerlDependencies.pm (+10 lines)
Lines 787-792 our $PERL_DEPS = { Link Here
787
        'required' => '0',
787
        'required' => '0',
788
        'min_ver'  => '0.03',
788
        'min_ver'  => '0.03',
789
    },
789
    },
790
    'Date::Range' => {
791
        'usage'    => 'Compare date range',
792
        'required' => '1',
793
        'min_ver'  => '1.41',
794
    },
795
    'Date::Simple' => {
796
        'usage'    => 'Works with Date::Range',
797
        'required' => '1',
798
        'min_ver'  => '3.03',
799
    }
790
};
800
};
791
801
792
1;
802
1;
(-)a/C4/Reserves.pm (+49 lines)
Lines 139-144 BEGIN { Link Here
139
        &SuspendAll
139
        &SuspendAll
140
140
141
        &GetReservesControlBranch
141
        &GetReservesControlBranch
142
		&ReservesOnSamePeriod
142
143
143
        IsItemOnHoldAndFound
144
        IsItemOnHoldAndFound
144
    );
145
    );
Lines 2471-2476 sub IsItemOnHoldAndFound { Link Here
2471
    return $found;
2472
    return $found;
2472
}
2473
}
2473
2474
2475
=head2 ReservesOnSamePeriod
2476
2477
    my $reserve = ReservesOnSamePeriod( $biblionumber, $itemnumber, $resdate, $expdate);
2478
2479
    Return the reserve that match the period ($resdate => $expdate),
2480
    undef if no reserve match.
2481
2482
=cut
2483
2484
sub ReservesOnSamePeriod {
2485
    my ($biblionumber, $itemnumber, $resdate, $expdate) = @_;
2486
2487
    unless ($resdate && $expdate) {
2488
        return;
2489
    }
2490
2491
    my $reserves = GetReservesFromBiblionumber({biblionumber => $biblionumber,
2492
                                                all_dates => 1});
2493
2494
    $resdate = output_pref({ str => $resdate, dateonly => 1, dateformat => 'iso' });
2495
    $expdate = output_pref({ str => $expdate, dateonly => 1, dateformat => 'iso' });
2496
2497
    my @reserves_overlaps;
2498
    foreach my $reserve (@$reserves) {
2499
2500
        unless ($reserve->{reservedate} && $reserve->{expirationdate}) {
2501
            next;
2502
        }
2503
2504
        if (date_ranges_overlap($resdate, $expdate,
2505
                                $reserve->{reservedate},
2506
                                $reserve->{expirationdate})) {
2507
2508
            # If reserve is item level and the requested periods overlap.
2509
            if ($itemnumber && $reserve->{itemnumber} == $itemnumber ) {
2510
                return [$reserve];
2511
            }
2512
            push @reserves_overlaps, $reserve;
2513
        }
2514
    }
2515
2516
    if (@reserves_overlaps >= GetItemsCount($biblionumber)) {
2517
        return \@reserves_overlaps;
2518
    }
2519
2520
    return;
2521
}
2522
2474
=head1 AUTHOR
2523
=head1 AUTHOR
2475
2524
2476
Koha Development Team <http://koha-community.org/>
2525
Koha Development Team <http://koha-community.org/>
(-)a/Koha/DateUtils.pm (-1 / +25 lines)
Lines 18-23 package Koha::DateUtils; Link Here
18
18
19
use Modern::Perl;
19
use Modern::Perl;
20
use DateTime;
20
use DateTime;
21
use Date::Range;
22
use Date::Simple;
21
use C4::Context;
23
use C4::Context;
22
use Carp;
24
use Carp;
23
25
Lines 25-31 use base 'Exporter'; Link Here
25
use version; our $VERSION = qv('1.0.0');
27
use version; our $VERSION = qv('1.0.0');
26
28
27
our @EXPORT = (
29
our @EXPORT = (
28
    qw( dt_from_string output_pref format_sqldatetime )
30
    qw( dt_from_string output_pref format_sqldatetime date_ranges_overlap )
29
);
31
);
30
32
31
=head1 DateUtils
33
=head1 DateUtils
Lines 296-299 sub format_sqldatetime { Link Here
296
    return q{};
298
    return q{};
297
}
299
}
298
300
301
=head2 date_ranges_overlap
302
303
    $bool = date_ranges_overlap($start1, $end1, $start2, $end2);
304
305
    Tells if first range ($start1 => $end1) overlaps
306
    the second one ($start2 => $end2)
307
308
=cut
309
310
sub date_ranges_overlap {
311
    my ($start1, $end1, $start2, $end2) = @_;
312
313
    my $range1 = Date::Range->new(Date::Simple->new($start1), Date::Simple->new($end1));
314
    my $range2 = Date::Range->new(Date::Simple->new($start2), Date::Simple->new($end2));
315
316
    if ($range1->overlaps($range2)) {
317
        return $range1->overlap($range2);
318
    }
319
320
    return;
321
}
322
299
1;
323
1;
(-)a/circ/circulation.pl (+4 lines)
Lines 410-415 if (@$barcodes) { Link Here
410
            }
410
            }
411
        }
411
        }
412
        unless($confirm_required) {
412
        unless($confirm_required) {
413
            if ( $cancelreserve eq 'cancel' ) {
414
                CancelReserve({ reserve_id => $query->param('reserveid') });
415
            }
416
            $cancelreserve = $cancelreserve eq 'revert' ? 'revert' : undef;
413
            my $issue = AddIssue( $borrower, $barcode, $datedue, $cancelreserve, undef, undef, { onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew') } );
417
            my $issue = AddIssue( $borrower, $barcode, $datedue, $cancelreserve, undef, undef, { onsite_checkout => $onsite_checkout, auto_renew => $session->param('auto_renew') } );
414
            $template->param( issue => $issue );
418
            $template->param( issue => $issue );
415
            $session->clear('auto_renew');
419
            $session->clear('auto_renew');
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+2 lines)
Lines 335-340 $(document).ready(function() { Link Here
335
[% IF ( RESERVED ) %]
335
[% IF ( RESERVED ) %]
336
    <p>
336
    <p>
337
    <input type="checkbox" id="cancelreserve" name="cancelreserve" value="cancel" />
337
    <input type="checkbox" id="cancelreserve" name="cancelreserve" value="cancel" />
338
    <input type="hidden" name="reserveid" value="[% resreserveid %]" />
338
    <label for="cancelreserve">Cancel hold</label>
339
    <label for="cancelreserve">Cancel hold</label>
339
    </p>
340
    </p>
340
[% END %]
341
[% END %]
Lines 343-348 $(document).ready(function() { Link Here
343
<p>
344
<p>
344
    <label for="cancelreserve">Cancel hold</label>
345
    <label for="cancelreserve">Cancel hold</label>
345
    <input type="radio" value="cancel" name="cancelreserve" id="cancelreserve" /><br />
346
    <input type="radio" value="cancel" name="cancelreserve" id="cancelreserve" /><br />
347
    <input type="hidden" name="reserveid" value="[% resreserveid %]" />
346
    <label for="revertreserve">Revert waiting status</label>
348
    <label for="revertreserve">Revert waiting status</label>
347
    <input type="radio" value="revert" name="cancelreserve" id="revertreserve" checked="checked"/>
349
    <input type="radio" value="revert" name="cancelreserve" id="revertreserve" checked="checked"/>
348
</p>
350
</p>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/placerequest.tt (+66 lines)
Line 0 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
    <title>Koha &rsaquo; Circulation &rsaquo; Holds &rsaquo; Confirm holds</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
</head>
5
<body id="circ_placerequest" class="catalog">
6
[% INCLUDE 'header.inc' %]
7
[% INCLUDE 'circ-search.inc' %]
8
9
<div id="breadcrumbs">
10
  <a href="/cgi-bin/koha/mainpage.pl">Home</a>
11
  &rsaquo;
12
  <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
13
  &rsaquo;
14
  Confirm holds
15
</div>
16
17
<div id="doc3" class="yui-t2">
18
19
  <div id="bd">
20
    <div id="yui-main">
21
      <div class="yui-b">
22
23
        <h1>Confirm holds</h1>
24
25
        <div class="alert">
26
          <p>
27
            Some of the reserves you are trying to do overlaps with existing reserves.
28
            Please confirm you want to proceed.
29
          </p>
30
        </div>
31
32
        <form method="post">
33
          <input type="hidden" name="borrowernumber" value="[% borrowernumber %]">
34
          [% IF multi_hold %]
35
            <input type="hidden" name="biblionumbers" value="[% biblionumbers%]">
36
            <input type="hidden" name="multi_hold" value="1">
37
          [% ELSE %]
38
            <input type="hidden" name="biblionumber" value="[% biblionumber%]">
39
          [% END %]
40
          <input type="hidden" name="reserve_date" value="[% reserve_date %]">
41
          <input type="hidden" name="expiration_date" value="[% expiration_date %]">
42
          <input type="hidden" name="pickup" value="[% pickup%]">
43
          <input type="hidden" name="notes" value="[% notes %]">
44
          <input type="hidden" name="confirm" value="1">
45
46
          [% FOREACH biblionumber IN overlap_reserves.keys %]
47
            [% input_id = "confirm_$biblionumber" %]
48
            <div>
49
              <input type="hidden" name="rank_[% biblionumber %]" value="[% overlap_reserves.$biblionumber.rank %]">
50
              [% IF (overlap_reserves.$biblionumber.checkitem) %]
51
                <input type="hidden" name="checkitem" value="[% overlap_reserves.$biblionumber.checkitem%]">
52
              [% END %]
53
              <input type="checkbox" name="confirm_biblionumbers" id="[% input_id %]"
54
                     value="[% biblionumber %]">
55
              <label for="[% input_id %]">Confirm hold for [% overlap_reserves.$biblionumber.title %]</label>
56
            </div>
57
          [% END %]
58
59
          <input type="submit" value="Continue">
60
        </form>
61
62
      </div>
63
    </div>
64
65
  </div>
66
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/opac/opac-reserve.pl (+8 lines)
Lines 273-278 if ( $query->param('place_reserve') ) { Link Here
273
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
273
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
274
            $itemNum = undef;
274
            $itemNum = undef;
275
        }
275
        }
276
277
        if ($canreserve) {
278
            if (ReservesOnSamePeriod($biblioNum, $itemNum, $startdate, $expiration_date)) {
279
                $canreserve = 0;
280
                $failed_holds++;
281
            }
282
        }
283
276
        my $notes = $query->param('notes_'.$biblioNum)||'';
284
        my $notes = $query->param('notes_'.$biblioNum)||'';
277
285
278
        if (   $maxreserves
286
        if (   $maxreserves
(-)a/reserve/placerequest.pl (-45 / +70 lines)
Lines 31-73 use C4::Output; Link Here
31
use C4::Reserves;
31
use C4::Reserves;
32
use C4::Circulation;
32
use C4::Circulation;
33
use C4::Members;
33
use C4::Members;
34
use C4::Auth qw/checkauth/;
34
use C4::Auth;
35
35
36
my $input = CGI->new();
36
my $input = CGI->new();
37
37
38
checkauth($input, 0, { reserveforothers => 'place_holds' }, 'intranet');
38
my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user(
39
    {
40
        template_name   => "reserve/placerequest.tt",
41
        query           => $input,
42
        type            => "intranet",
43
        authnotrequired => 0,
44
        flagsrequired   => { reserveforothers => 'place_holds' },
45
    }
46
);
39
47
40
my @bibitems=$input->param('biblioitem');
41
my @reqbib=$input->param('reqbib'); 
42
my $biblionumber=$input->param('biblionumber');
48
my $biblionumber=$input->param('biblionumber');
43
my $borrowernumber=$input->param('borrowernumber');
49
my $borrowernumber=$input->param('borrowernumber');
44
my $notes=$input->param('notes');
50
my $notes=$input->param('notes');
45
my $branch=$input->param('pickup');
51
my $branch=$input->param('pickup');
46
my $startdate=$input->param('reserve_date') || '';
52
my $startdate=$input->param('reserve_date') || '';
47
my @rank=$input->param('rank-request');
53
my @rank=$input->param('rank-request');
48
my $type=$input->param('type');
49
my $title=$input->param('title');
54
my $title=$input->param('title');
50
my $borrower=GetMember('borrowernumber'=>$borrowernumber);
51
my $checkitem=$input->param('checkitem');
55
my $checkitem=$input->param('checkitem');
52
my $expirationdate = $input->param('expiration_date');
56
my $expirationdate = $input->param('expiration_date');
57
my $confirm = $input->param('confirm');
58
my @confirm_biblionumbers = $input->param('confirm_biblionumbers');
53
59
54
my $multi_hold = $input->param('multi_hold');
60
my $multi_hold = $input->param('multi_hold');
55
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
61
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
56
my $bad_bibs = $input->param('bad_bibs');
62
my $bad_bibs = $input->param('bad_bibs');
57
63
64
my $borrower=GetMember('borrowernumber'=>$borrowernumber);
65
unless ($borrower) {
66
    print $input->header();
67
    print "Invalid borrower number please try again";
68
    exit;
69
}
70
58
my %bibinfos = ();
71
my %bibinfos = ();
59
my @biblionumbers = split '/', $biblionumbers;
72
my @biblionumbers = split '/', $biblionumbers;
60
foreach my $bibnum (@biblionumbers) {
73
foreach my $bibnum (@biblionumbers) {
61
    my %bibinfo = ();
74
    my %bibinfo;
62
    $bibinfo{title} = $input->param("title_$bibnum");
75
    $bibinfo{title} = $input->param("title_$bibnum");
76
63
    $bibinfo{rank} = $input->param("rank_$bibnum");
77
    $bibinfo{rank} = $input->param("rank_$bibnum");
64
    $bibinfos{$bibnum} = \%bibinfo;
78
    $bibinfos{$bibnum} = \%bibinfo;
65
}
79
}
66
80
67
my $found;
81
my $found;
68
82
69
# if we have an item selectionned, and the pickup branch is the same as the holdingbranch
83
# if we have an item selectionned, and the pickup branch is the same as the
70
# of the document, we force the value $rank and $found .
84
# holdingbranch of the document, we force the value $rank and $found .
71
if (defined $checkitem && $checkitem ne ''){
85
if (defined $checkitem && $checkitem ne ''){
72
    $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns');
86
    $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns');
73
    my $item = $checkitem;
87
    my $item = $checkitem;
Lines 77-117 if (defined $checkitem && $checkitem ne ''){ Link Here
77
    }
91
    }
78
}
92
}
79
93
80
if ($type eq 'str8' && $borrower){
94
my $overlap_reserves = {};
81
95
foreach my $biblionumber (keys %bibinfos) {
82
    foreach my $biblionumber (keys %bibinfos) {
96
    next if ($confirm && !grep { $_ eq $biblionumber } @confirm_biblionumbers);
83
        my $count=@bibitems;
84
        @bibitems=sort @bibitems;
85
        my $i2=1;
86
        my @realbi;
87
        $realbi[0]=$bibitems[0];
88
        for (my $i=1;$i<$count;$i++) {
89
            my $i3=$i2-1;
90
            if ($realbi[$i3] ne $bibitems[$i]) {
91
                $realbi[$i2]=$bibitems[$i];
92
                $i2++;
93
            }
94
        }
95
96
    if (defined $checkitem && $checkitem ne ''){
97
		my $item = GetItem($checkitem);
98
        	if ($item->{'biblionumber'} ne $biblionumber) {
99
                	$biblionumber = $item->{'biblionumber'};
100
        	}
101
	}
102
103
97
98
    my ($reserve_title, $reserve_rank);
99
    if ($multi_hold) {
100
        my $bibinfo = $bibinfos{$biblionumber};
101
        $reserve_rank = $bibinfo->{rank};
102
        $reserve_title = $bibinfo->{title};
103
    } else {
104
        $reserve_rank = $rank[0];
105
        $reserve_title = $title;
106
    }
104
107
105
        if ($multi_hold) {
108
    if (defined $checkitem && $checkitem ne '') {
106
            my $bibinfo = $bibinfos{$biblionumber};
109
        my $item = GetItem($checkitem);
107
            AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,[$biblionumber],
110
        if ($item->{'biblionumber'} ne $biblionumber) {
108
                       $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found);
111
            $biblionumber = $item->{'biblionumber'};
109
        } else {
110
            # place a request on 1st available
111
            AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,$found);
112
        }
112
        }
113
    }
113
    }
114
114
115
    if (!$confirm && ReservesOnSamePeriod($biblionumber, $checkitem, $startdate, $expirationdate)) {
116
        $overlap_reserves->{$biblionumber} = {
117
            title => $reserve_title ,
118
            checkitem => $checkitem,
119
            rank => $reserve_rank
120
        };
121
        next;
122
    }
123
124
    AddReserve($branch, $borrower->{'borrowernumber'}, $biblionumber, undef,
125
        $reserve_rank, $startdate, $expirationdate, $notes, $reserve_title,
126
        $checkitem, $found);
127
}
128
129
if (scalar keys %$overlap_reserves) {
130
    $template->param(
131
        borrowernumber => $borrowernumber,
132
        biblionumbers => $biblionumbers,
133
        biblionumber => $biblionumber,
134
        overlap_reserves => $overlap_reserves,
135
        reserve_date => $startdate,
136
        expiration_date => $expirationdate,
137
        notes => $notes,
138
        rank_request => \@rank,
139
        pickup => $branch,
140
        multi_hold => $multi_hold,
141
    );
142
143
    output_html_with_http_headers $input, $cookie, $template->output;
144
} else {
115
    if ($multi_hold) {
145
    if ($multi_hold) {
116
        if ($bad_bibs) {
146
        if ($bad_bibs) {
117
            $biblionumbers .= $bad_bibs;
147
            $biblionumbers .= $bad_bibs;
Lines 120-129 if ($type eq 'str8' && $borrower){ Link Here
120
    } else {
150
    } else {
121
        print $input->redirect("request.pl?biblionumber=$biblionumber");
151
        print $input->redirect("request.pl?biblionumber=$biblionumber");
122
    }
152
    }
123
} elsif ($borrower eq ''){
153
    exit;
124
	print $input->header();
125
	print "Invalid borrower number please try again";
126
# Not sure that Dump() does HTML escaping. Use firebug or something to trace
127
# instead.
128
#	print $input->Dump;
129
}
154
}
(-)a/t/db_dependent/Circulation/CanBookBeIssued.t (+107 lines)
Line 0 Link Here
1
#!/usr/bin/env perl
2
3
# This file is part of Koha.
4
#
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.
9
#
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.
14
#
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>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 1;
21
use C4::Members;
22
use C4::Reserves;
23
use C4::Circulation;
24
use C4::Branch;
25
use Koha::DateUtils;
26
27
use t::lib::TestBuilder;
28
29
my $schema  = Koha::Database->new->schema;
30
$schema->storage->txn_begin;
31
32
my $builder = t::lib::TestBuilder->new();
33
34
subtest 'Tests for CanBookBeIssued with overlap reserves' => sub {
35
    plan tests => 6;
36
37
    my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
38
    my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
39
40
    my $borrower = $builder->build({
41
        source => 'Borrower',
42
        value => {
43
            branchcode   => $branchcode,
44
            categorycode => $categorycode,
45
        }
46
    });
47
    my $borrowernumber = $borrower->{borrowernumber};
48
    $borrower = GetMemberDetails($borrowernumber);
49
50
    my $biblio = $builder->build({source => 'Biblio'});
51
    my $biblioitem = $builder->build({
52
        source => 'Biblioitem',
53
        value => {
54
            biblionumber => $biblio->{biblionumber},
55
        },
56
    });
57
    my $item = $builder->build({
58
        source => 'Item',
59
        value => {
60
            biblionumber => $biblio->{biblionumber},
61
            biblioitemnumber => $biblioitem->{biblioitemnumber},
62
            withdrawn => 0,
63
            itemlost => 0,
64
            notforloan => 0,
65
        },
66
    });
67
68
69
    my $startdate = dt_from_string();
70
    $startdate->add_duration(DateTime::Duration->new(days => 4));
71
    my $expdate = $startdate->clone();
72
    $expdate->add_duration(DateTime::Duration->new(days => 10));
73
74
    my $reserveid = AddReserve($branchcode, $borrowernumber,
75
        $item->{biblionumber}, undef,  1, $startdate->ymd(), $expdate->ymd,
76
        undef, undef, undef, undef);
77
78
    my $non_overlap_duedate = dt_from_string();
79
    $non_overlap_duedate->add_duration(DateTime::Duration->new(days => 2));
80
    my ($error, $question, $alerts ) =
81
        CanBookBeIssued($borrower, $item->{barcode}, $non_overlap_duedate, 1, 0);
82
83
    is_deeply($error, {}, "");
84
    is_deeply($question, {}, "");
85
    is_deeply($alerts, {}, "");
86
87
    my $overlap_duedate = dt_from_string();
88
    $overlap_duedate->add_duration(DateTime::Duration->new(days => 5));
89
    ($error, $question, $alerts ) =
90
        CanBookBeIssued($borrower, $item->{barcode}, $overlap_duedate, 1, 0);
91
92
    is_deeply($error, {}, "");
93
    my $expected = {
94
        RESERVED => 1,
95
        resfirstname => $borrower->{firstname},
96
        ressurname => $borrower->{surname},
97
        rescardnumber => $borrower->{cardnumber},
98
        resborrowernumber => $borrower->{borrowernumber},
99
        resbranchname => GetBranchName($branchcode),
100
        resreservedate => $startdate->ymd,
101
        resreserveid => $reserveid,
102
    };
103
    is_deeply($question, $expected, "");
104
    is_deeply($alerts, {}, "");
105
};
106
107
$schema->storage->txn_rollback;
(-)a/t/db_dependent/Reserves/ReserveDate.t (-1 / +108 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
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.
9
#
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.
14
#
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>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 6;
21
use Test::Warn;
22
23
use MARC::Record;
24
use DateTime::Duration;
25
26
use C4::Branch;
27
use C4::Biblio;
28
use C4::Items;
29
use C4::Members;
30
use C4::Circulation;
31
use Koha::Holds;
32
use t::lib::TestBuilder;
33
34
use Koha::DateUtils;
35
36
37
use_ok('C4::Reserves');
38
39
my $dbh = C4::Context->dbh;
40
41
# Start transaction
42
$dbh->{AutoCommit} = 0;
43
$dbh->{RaiseError} = 1;
44
45
my $builder = t::lib::TestBuilder->new();
46
my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
47
my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
48
49
my $borrower = $builder->build({
50
    source => 'Borrower',
51
    value => {
52
        branchcode   => $branchcode,
53
        categorycode => $categorycode,
54
    }
55
});
56
57
my $borrower2 = $builder->build({
58
    source => 'Borrower',
59
    value => {
60
        branchcode   => $branchcode,
61
        categorycode => $categorycode,
62
    }
63
});
64
65
my $borrowernumber = $borrower->{borrowernumber};
66
my $borrowernumber2 = $borrower2->{borrowernumber};
67
68
# Create a helper biblio
69
my $biblio = MARC::Record->new();
70
my $title = 'Alone in the Dark';
71
my $author = 'Karen Rose';
72
if( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
73
    $biblio->append_fields(
74
        MARC::Field->new('600', '', '1', a => $author),
75
        MARC::Field->new('200', '', '', a => $title),
76
    );
77
}
78
else {
79
    $biblio->append_fields(
80
        MARC::Field->new('100', '', '', a => $author),
81
        MARC::Field->new('245', '', '', a => $title),
82
    );
83
}
84
my ($bibnum, $bibitemnum);
85
($bibnum, $title, $bibitemnum) = AddBiblio($biblio, '');
86
87
my ($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => $branchcode, holdingbranch => $branchcode, barcode => '333' } , $bibnum);
88
89
C4::Context->set_preference('AllowHoldDateInFuture', 1);
90
91
AddReserve($branchcode, $borrowernumber, $bibnum,
92
           $bibitemnum,  1, '2015-11-01', '2015-11-20', undef,
93
           undef, undef, undef);
94
95
is(ReservesOnSamePeriod($bibnum, undef, '2015-11-25', '2015-11-30'), undef, "Period doesn't overlaps");
96
97
ok(ReservesOnSamePeriod($bibnum, undef, '2015-11-02', '2015-11-10'), "Period overlaps");
98
99
my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) = AddItem({ homebranch => $branchcode, holdingbranch => $branchcode, barcode => '444' } , $bibnum);
100
is(ReservesOnSamePeriod($bibnum, undef, '2015-11-02', '2015-11-10'), undef, "Period overlaps but there is 2 items");
101
102
AddReserve($branchcode, $borrowernumber2, $bibnum,
103
           $bibitemnum,  1, '2016-02-01', '2016-02-10', undef,
104
           undef, $itemnumber, undef);
105
is(ReservesOnSamePeriod($bibnum, $itemnumber, '02/12/2015', '10/12/2015'), undef, "Period on item does not overlap (with metric date format)");
106
107
ok(ReservesOnSamePeriod($bibnum, $itemnumber, '2016-01-31', '2016-02-05'), "Period on item overlaps");
108
$dbh->rollback;

Return to bug 15261