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

(-)a/C4/Reserves.pm (+3 lines)
Lines 907-912 sub CancelExpiredReserves { Link Here
907
        if ( $hold->found eq 'W' ) {
907
        if ( $hold->found eq 'W' ) {
908
            $cancel_params->{charge_cancel_fee} = 1;
908
            $cancel_params->{charge_cancel_fee} = 1;
909
        }
909
        }
910
911
        $cancel_params->{pickupexpired} = dt_from_string($hold->expirationdate);
912
910
        $hold->cancel( $cancel_params );
913
        $hold->cancel( $cancel_params );
911
    }
914
    }
912
}
915
}
(-)a/Koha/Hold.pm (+11 lines)
Lines 35-40 use Koha::Old::Holds; Link Here
35
use Koha::Calendar;
35
use Koha::Calendar;
36
36
37
use Koha::Exceptions::Hold;
37
use Koha::Exceptions::Hold;
38
use Koha::Exceptions::BadParameter;
38
39
39
use base qw(Koha::Object);
40
use base qw(Koha::Object);
40
41
Lines 363-368 sub cancel { Link Here
363
    my ( $self, $params ) = @_;
364
    my ( $self, $params ) = @_;
364
    $self->_result->result_source->schema->txn_do(
365
    $self->_result->result_source->schema->txn_do(
365
        sub {
366
        sub {
367
368
            my $pickupexpired = $params->{pickupexpired};
369
            if ($pickupexpired) {
370
                unless ($pickupexpired && $pickupexpired->isa('DateTime')) {
371
                    Koha::Exceptions::BadParameter->throw(error => "cancel():> Parameter 'pickupexpired' is not a DateTime-object or undef!");
372
                } else {
373
                    $self->pickupexpired($pickupexpired->ymd());
374
                }
375
            }
376
366
            $self->cancellationdate( dt_from_string->strftime( '%Y-%m-%d %H:%M:%S' ) );
377
            $self->cancellationdate( dt_from_string->strftime( '%Y-%m-%d %H:%M:%S' ) );
367
            $self->priority(0);
378
            $self->priority(0);
368
            $self->_move_to_old;
379
            $self->_move_to_old;
(-)a/Koha/Old/Holds.pm (+59 lines)
Lines 20-27 package Koha::Old::Holds; Link Here
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Carp;
22
use Carp;
23
use Scalar::Util qw(blessed);
23
24
24
use Koha::Database;
25
use Koha::Database;
26
use Koha::Exceptions::BadParameter;
25
27
26
use Koha::Old::Hold;
28
use Koha::Old::Hold;
27
29
Lines 39-44 This object represents a set of holds that have been filled or canceled Link Here
39
41
40
=cut
42
=cut
41
43
44
=head3
45
46
my $expired_holds = Koha::Old::Holds->expired();
47
48
Returns all holds that have already expired and moved to old_reserves during period
49
of time given in 'PickupExpiredHoldsOverReportDuration'.
50
51
If branchcode is given returns expired holds for that branch and take into account
52
its holidays.
53
54
=cut
55
56
sub expired {
57
    my ($self, $params) = @_;
58
59
    my $pickupExpiredHoldsOverReportDuration = C4::Context->preference('PickupExpiredHoldsOverReportDuration');
60
    return undef unless $pickupExpiredHoldsOverReportDuration;
61
62
    my $branchcode = $params->{branchcode};
63
    if ($params->{from}) {
64
        unless (blessed($params->{from}) && $params->{from}->isa('DateTime')) {
65
            Koha::Exceptions::BadParameter->throw(error => "expired():> Parameter 'from' is not a DateTime-object or undef!");
66
        }
67
    }
68
    if ($params->{to}) {
69
        unless (blessed($params->{from}) && $params->{from}->isa('DateTime')) {
70
            Koha::Exceptions::BadParameter->throw(error => "expired():> Parameter 'from' is not a DateTime-object or undef!");
71
        }
72
    }
73
74
    #Calculate the days for which we get the expired reserves.
75
    my $fromDate   = $params->{from};
76
    my $toDate     = $params->{to}   || DateTime->now(time_zone => C4::Context->tz());
77
78
    unless ($fromDate) {
79
        $fromDate = DateTime->now( time_zone => C4::Context->tz() );
80
        #Look for previous open days
81
        if ($branchcode) {
82
            my $calendar = Koha::Calendar->new( branchcode => $branchcode, days_mode => 'Default'); 
83
            foreach my $i (1..$pickupExpiredHoldsOverReportDuration) {
84
                $fromDate = $calendar->prev_open_days($fromDate, 1);
85
            }
86
        }
87
        #If no branch has been specified we cannot use a calendar, so simply just go back in time.
88
        else {
89
            $fromDate = DateTime->now(time_zone => C4::Context->tz())->subtract(days => $pickupExpiredHoldsOverReportDuration);
90
        }
91
    }
92
93
    my $search_params;
94
    $search_params->{priority} = 0;
95
    $search_params->{pickupexpired} = { -between => [ $fromDate->ymd(), $toDate->ymd() ] };
96
    $search_params->{branchcode} = $branchcode if defined $branchcode;
97
98
    return $self->search( $search_params, { order_by => 'waitingdate' } );
99
}
100
42
=head3 type
101
=head3 type
43
102
44
=cut
103
=cut
(-)a/Koha/Schema/Result/OldReserve.pm (-2 / +10 lines)
Lines 112-117 __PACKAGE__->table("old_reserves"); Link Here
112
  datetime_undef_if_invalid: 1
112
  datetime_undef_if_invalid: 1
113
  is_nullable: 1
113
  is_nullable: 1
114
114
115
=head2 pickupexpired
116
117
  data_type: 'date'
118
  datetime_undef_if_invalid: 1
119
  is_nullable: 1
120
115
=head2 lowestPriority
121
=head2 lowestPriority
116
122
117
  accessor: 'lowest_priority'
123
  accessor: 'lowest_priority'
Lines 182-187 __PACKAGE__->add_columns( Link Here
182
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
188
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
183
  "expirationdate",
189
  "expirationdate",
184
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
190
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
191
  "pickupexpired",
192
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
185
  "lowestPriority",
193
  "lowestPriority",
186
  {
194
  {
187
    accessor      => "lowest_priority",
195
    accessor      => "lowest_priority",
Lines 298-305 __PACKAGE__->belongs_to( Link Here
298
);
306
);
299
307
300
308
301
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2020-03-18 12:43:15
309
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-04-28 12:23:24
302
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4vMUC/1kSr3vgQ7n0Pmuug
310
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:AAKfhZfJaya1XUWTqeVMgA
303
311
304
__PACKAGE__->add_columns(
312
__PACKAGE__->add_columns(
305
    '+item_level_hold' => { is_boolean => 1 },
313
    '+item_level_hold' => { is_boolean => 1 },
(-)a/Koha/Schema/Result/Reserve.pm (-2 / +10 lines)
Lines 116-121 __PACKAGE__->table("reserves"); Link Here
116
  datetime_undef_if_invalid: 1
116
  datetime_undef_if_invalid: 1
117
  is_nullable: 1
117
  is_nullable: 1
118
118
119
=head2 pickupexpired
120
121
  data_type: 'date'
122
  datetime_undef_if_invalid: 1
123
  is_nullable: 1
124
119
=head2 lowestPriority
125
=head2 lowestPriority
120
126
121
  accessor: 'lowest_priority'
127
  accessor: 'lowest_priority'
Lines 196-201 __PACKAGE__->add_columns( Link Here
196
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
202
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
197
  "expirationdate",
203
  "expirationdate",
198
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
204
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
205
  "pickupexpired",
206
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
199
  "lowestPriority",
207
  "lowestPriority",
200
  {
208
  {
201
    accessor      => "lowest_priority",
209
    accessor      => "lowest_priority",
Lines 337-344 __PACKAGE__->belongs_to( Link Here
337
);
345
);
338
346
339
347
340
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2020-03-18 12:43:15
348
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2020-04-28 12:23:24
341
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VH7h5kYo9WhlGobXb3N3Jg
349
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:lCAjQKeOZPYLaMstOD0oiw
342
350
343
__PACKAGE__->belongs_to(
351
__PACKAGE__->belongs_to(
344
  "item",
352
  "item",
(-)a/circ/waitingreserves.pl (-1 / +8 lines)
Lines 39-44 use Koha::BiblioFrameworks; Link Here
39
use Koha::Items;
39
use Koha::Items;
40
use Koha::ItemTypes;
40
use Koha::ItemTypes;
41
use Koha::Patrons;
41
use Koha::Patrons;
42
use Koha::Old::Holds;
42
43
43
my $input = new CGI;
44
my $input = new CGI;
44
45
Lines 84-90 $template->param( all_branches => 1 ) if $all_branches; Link Here
84
my (@reserve_loop, @over_loop);
85
my (@reserve_loop, @over_loop);
85
# FIXME - Is priority => 0 useful? If yes it must be moved to waiting, otherwise we need to remove it from here.
86
# FIXME - Is priority => 0 useful? If yes it must be moved to waiting, otherwise we need to remove it from here.
86
my $holds = Koha::Holds->waiting->search({ priority => 0, ( $all_branches ? () : ( branchcode => $default ) ) }, { order_by => ['waitingdate'] });
87
my $holds = Koha::Holds->waiting->search({ priority => 0, ( $all_branches ? () : ( branchcode => $default ) ) }, { order_by => ['waitingdate'] });
87
88
my $expired_holds = $all_branches ? Koha::Old::Holds->expired() : Koha::Old::Holds->expired({branchcode => $default});
88
# get reserves for the branch we are logged into, or for all branches
89
# get reserves for the branch we are logged into, or for all branches
89
90
90
my $today = Date_to_Days(&Today);
91
my $today = Date_to_Days(&Today);
Lines 109-114 while ( my $hold = $holds->next ) { Link Here
109
    
110
    
110
}
111
}
111
112
113
if($expired_holds){
114
    while (my $expired_hold = $expired_holds->next){
115
        push @over_loop, $expired_hold;
116
    }
117
}
118
112
$template->param(cancel_result => \@cancel_result) if @cancel_result;
119
$template->param(cancel_result => \@cancel_result) if @cancel_result;
113
120
114
$template->param(
121
$template->param(
(-)a/installer/data/mysql/atomicupdate/bug_10744-expire_reserves_conflict_hold_over_report.perl (+16 lines)
Line 0 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
    # you can use $dbh here like:
4
    # $dbh->do( "ALTER TABLE biblio ADD COLUMN badtaste int" );
5
6
    $dbh->do("ALTER TABLE reserves ADD `pickupexpired` DATE DEFAULT NULL AFTER `expirationdate`");
7
    $dbh->do("ALTER TABLE reserves ADD KEY `reserves_pickupexpired` (`pickupexpired`)");
8
    $dbh->do("ALTER TABLE old_reserves ADD `pickupexpired` DATE DEFAULT NULL AFTER `expirationdate`");
9
    $dbh->do("ALTER TABLE old_reserves ADD KEY `old_reserves_pickupexpired` (`pickupexpired`)");
10
11
    $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('PickupExpiredHoldsOverReportDuration','1',NULL,\"For how many days holds expired by the 'ExpireReservesMaxPickUpDelay'-syspref are visible in the 'Hold Over'-tab in /circ/waitingreserves.pl ?\",'Integer')");
12
13
    # Always end with this (adjust the bug info)
14
    SetVersion( $DBversion );
15
    print "Upgrade to $DBversion done (Bug 10744 - ExpireReservesMaxPickUpDelay works with hold(s) over report)\n";
16
}
(-)a/installer/data/mysql/kohastructure.sql (+4 lines)
Lines 1759-1764 CREATE TABLE `reserves` ( -- information related to holds/reserves in Koha Link Here
1759
  `itemnumber` int(11) default NULL, -- foreign key from the items table defining the specific item the patron has placed on hold or the item this hold was filled with
1759
  `itemnumber` int(11) default NULL, -- foreign key from the items table defining the specific item the patron has placed on hold or the item this hold was filled with
1760
  `waitingdate` date default NULL, -- the date the item was marked as waiting for the patron at the library
1760
  `waitingdate` date default NULL, -- the date the item was marked as waiting for the patron at the library
1761
  `expirationdate` DATE DEFAULT NULL, -- the date the hold expires (usually the date entered by the patron to say they don't need the hold after a certain date)
1761
  `expirationdate` DATE DEFAULT NULL, -- the date the hold expires (usually the date entered by the patron to say they don't need the hold after a certain date)
1762
  `pickupexpired` DATE DEFAULT NULL, -- if hold has been waiting but it expired before it was picked up, the expiration date is set here
1762
  `lowestPriority` tinyint(1) NOT NULL DEFAULT 0,
1763
  `lowestPriority` tinyint(1) NOT NULL DEFAULT 0,
1763
  `suspend` tinyint(1) NOT NULL DEFAULT 0,
1764
  `suspend` tinyint(1) NOT NULL DEFAULT 0,
1764
  `suspend_until` DATETIME NULL DEFAULT NULL,
1765
  `suspend_until` DATETIME NULL DEFAULT NULL,
Lines 1770-1775 CREATE TABLE `reserves` ( -- information related to holds/reserves in Koha Link Here
1770
  KEY `biblionumber` (`biblionumber`),
1771
  KEY `biblionumber` (`biblionumber`),
1771
  KEY `itemnumber` (`itemnumber`),
1772
  KEY `itemnumber` (`itemnumber`),
1772
  KEY `branchcode` (`branchcode`),
1773
  KEY `branchcode` (`branchcode`),
1774
  KEY `reserves_pickupexpired` (`pickupexpired`),
1773
  KEY `itemtype` (`itemtype`),
1775
  KEY `itemtype` (`itemtype`),
1774
  CONSTRAINT `reserves_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE,
1776
  CONSTRAINT `reserves_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE,
1775
  CONSTRAINT `reserves_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE,
1777
  CONSTRAINT `reserves_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE,
Lines 1799-1804 CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b Link Here
1799
  `itemnumber` int(11) default NULL, -- foreign key from the items table defining the specific item the patron has placed on hold or the item this hold was filled with
1801
  `itemnumber` int(11) default NULL, -- foreign key from the items table defining the specific item the patron has placed on hold or the item this hold was filled with
1800
  `waitingdate` date default NULL, -- the date the item was marked as waiting for the patron at the library
1802
  `waitingdate` date default NULL, -- the date the item was marked as waiting for the patron at the library
1801
  `expirationdate` DATE DEFAULT NULL, -- the date the hold expires (usually the date entered by the patron to say they don't need the hold after a certain date)
1803
  `expirationdate` DATE DEFAULT NULL, -- the date the hold expires (usually the date entered by the patron to say they don't need the hold after a certain date)
1804
  `pickupexpired` DATE DEFAULT NULL, -- if hold has been waiting but it expired before it was picked up, the expiration date is set here
1802
  `lowestPriority` tinyint(1) NOT NULL DEFAULT 0, -- has this hold been pinned to the lowest priority in the holds queue (1 for yes, 0 for no)
1805
  `lowestPriority` tinyint(1) NOT NULL DEFAULT 0, -- has this hold been pinned to the lowest priority in the holds queue (1 for yes, 0 for no)
1803
  `suspend` tinyint(1) NOT NULL DEFAULT 0, -- in this hold suspended (1 for yes, 0 for no)
1806
  `suspend` tinyint(1) NOT NULL DEFAULT 0, -- in this hold suspended (1 for yes, 0 for no)
1804
  `suspend_until` DATETIME NULL DEFAULT NULL, -- the date this hold is suspended until (NULL for infinitely)
1807
  `suspend_until` DATETIME NULL DEFAULT NULL, -- the date this hold is suspended until (NULL for infinitely)
Lines 1809-1814 CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b Link Here
1809
  KEY `old_reserves_biblionumber` (`biblionumber`),
1812
  KEY `old_reserves_biblionumber` (`biblionumber`),
1810
  KEY `old_reserves_itemnumber` (`itemnumber`),
1813
  KEY `old_reserves_itemnumber` (`itemnumber`),
1811
  KEY `old_reserves_branchcode` (`branchcode`),
1814
  KEY `old_reserves_branchcode` (`branchcode`),
1815
  KEY `old_reserves_pickupexpired` (`pickupexpired`),
1812
  KEY `old_reserves_itemtype` (`itemtype`),
1816
  KEY `old_reserves_itemtype` (`itemtype`),
1813
  CONSTRAINT `old_reserves_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`)
1817
  CONSTRAINT `old_reserves_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`)
1814
    ON DELETE SET NULL ON UPDATE SET NULL,
1818
    ON DELETE SET NULL ON UPDATE SET NULL,
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 185-190 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
185
('EnhancedMessagingPreferencesOPAC', '1', NULL, 'If ON, show patrons messaging setting on the OPAC.', 'YesNo'),
185
('EnhancedMessagingPreferencesOPAC', '1', NULL, 'If ON, show patrons messaging setting on the OPAC.', 'YesNo'),
186
('expandedSearchOption','0',NULL,'If ON, set advanced search to be expanded by default','YesNo'),
186
('expandedSearchOption','0',NULL,'If ON, set advanced search to be expanded by default','YesNo'),
187
('ExpireReservesMaxPickUpDelay','0','','Enabling this allows holds to expire automatically if they have not been picked by within the time period specified in ReservesMaxPickUpDelay','YesNo'),
187
('ExpireReservesMaxPickUpDelay','0','','Enabling this allows holds to expire automatically if they have not been picked by within the time period specified in ReservesMaxPickUpDelay','YesNo'),
188
('PickupExpiredHoldsOverReportDuration','1',NULL,"For how many days holds expired by the 'ExpireReservesMaxPickUpDelay'-syspref are visible in the 'Hold Over'-tab in /circ/waitingreserves.pl ?",'Integer'),
188
('ExpireReservesMaxPickUpDelayCharge','0',NULL,'If ExpireReservesMaxPickUpDelay is enabled, and this field has a non-zero value, than a borrower whose waiting hold has expired will be charged this amount.','free'),
189
('ExpireReservesMaxPickUpDelayCharge','0',NULL,'If ExpireReservesMaxPickUpDelay is enabled, and this field has a non-zero value, than a borrower whose waiting hold has expired will be charged this amount.','free'),
189
('ExpireReservesOnHolidays', '1', NULL, 'If false, reserves at a library will not be canceled on days the library is not open.', 'YesNo'),
190
('ExpireReservesOnHolidays', '1', NULL, 'If false, reserves at a library will not be canceled on days the library is not open.', 'YesNo'),
190
('ExcludeHolidaysFromMaxPickUpDelay', '0', NULL, 'If ON, reserves max pickup delay takes into accountthe closed days.', 'YesNo'),
191
('ExcludeHolidaysFromMaxPickUpDelay', '0', NULL, 'If ON, reserves max pickup delay takes into accountthe closed days.', 'YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+4 lines)
Lines 698-703 Circulation: Link Here
698
            - If using ExpireReservesMaxPickUpDelay, charge a borrower who allows their waiting hold to expire a fee of
698
            - If using ExpireReservesMaxPickUpDelay, charge a borrower who allows their waiting hold to expire a fee of
699
            - pref: ExpireReservesMaxPickUpDelayCharge
699
            - pref: ExpireReservesMaxPickUpDelayCharge
700
              class: currency
700
              class: currency
701
        -
702
            - pref: PickupExpiredHoldsOverReportDuration
703
              class: integer
704
            - "For how many days holds expired by the 'ExpireReservesMaxPickUpDelay'-syspref are visible in the 'Hold Over'-tab in /circ/waitingreserves.pl ?"
701
        -
705
        -
702
            - Satisfy holds using items from the libraries
706
            - Satisfy holds using items from the libraries
703
            - pref: StaticHoldsQueueWeight
707
            - pref: StaticHoldsQueueWeight
(-)a/t/db_dependent/Koha/Old.t (-2 / +102 lines)
Lines 19-36 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 2;
22
use Test::More tests => 3;
23
23
24
use DateTime;
25
use DateTime::TimeZone;
26
27
use C4::Reserves;
24
use Koha::Database;
28
use Koha::Database;
25
use Koha::Old::Patrons;
29
use Koha::Old::Patrons;
26
use Koha::Old::Biblios;
30
use Koha::Old::Biblios;
27
use Koha::Old::Items;
31
use Koha::Old::Items;
32
use Koha::Old::Holds;
33
use Koha::Calendar;
28
34
29
use t::lib::TestBuilder;
35
use t::lib::TestBuilder;
36
use t::lib::Mocks;
30
37
31
my $schema = Koha::Database->new->schema;
38
my $schema = Koha::Database->new->schema;
32
$schema->storage->txn_begin;
39
$schema->storage->txn_begin;
33
40
41
#since we use calendar here, flush caches
42
Koha::Caches->get_instance()->flush_all();
43
34
my $builder = t::lib::TestBuilder->new;
44
my $builder = t::lib::TestBuilder->new;
35
45
36
subtest 'Koha::Old::Patrons' => sub {
46
subtest 'Koha::Old::Patrons' => sub {
Lines 54-57 subtest 'Koha::Old::Biblios and Koha::Old::Items' => sub { Link Here
54
    # Cannot be tested in a meaningful way so far
64
    # Cannot be tested in a meaningful way so far
55
    ok(1);
65
    ok(1);
56
};
66
};
67
57
$schema->storage->txn_rollback;
68
$schema->storage->txn_rollback;
58
- 
69
70
subtest 'Koha::Old::Holds' => sub {
71
72
    $schema->storage->txn_begin;
73
74
    plan tests => 5;
75
76
    my $branch = $builder->build_object({ class => 'Koha::Libraries' });
77
    my $calendar = Koha::Calendar->new( branchcode => $branch->branchcode );
78
    my $holiday_date = DateTime->now(time_zone => C4::Context->tz())->subtract(days => 2);
79
    my $holiday = $builder->build({
80
        source => 'SpecialHoliday',
81
        value  => {
82
            branchcode  => $branch->branchcode,
83
            day         => $holiday_date->day,
84
            month       => $holiday_date->month,
85
            year        => $holiday_date->year,
86
        },
87
    });
88
89
    t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelay', 1);
90
91
    t::lib::Mocks::mock_preference('ReservesMaxPickUpDelay', 6);
92
    t::lib::Mocks::mock_preference('PickupExpiredHoldsOverReportDuration', 2);
93
94
    my $hold_1 = $builder->build_object({
95
        class => 'Koha::Holds',
96
        value => {
97
            branchcode => $branch->branchcode,
98
            expirationdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 3)->iso8601(),
99
        }
100
    });
101
    my $hold_2 = $builder->build_object({
102
        class => 'Koha::Holds',
103
        value => {
104
            branchcode => $branch->branchcode,
105
            expirationdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 2)->iso8601(),
106
        }
107
    });
108
    my $hold_3 = $builder->build_object({
109
        class => 'Koha::Holds',
110
        value => {
111
            branchcode => $branch->branchcode,
112
            expirationdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 1)->iso8601(),
113
        }
114
    });
115
    my $hold_4 = $builder->build_object({
116
        class => 'Koha::Holds',
117
        value => {
118
            branchcode => $branch->branchcode,
119
            expirationdate => DateTime->now(time_zone => C4::Context->tz())->subtract(days => 1)->iso8601(),
120
        }
121
    });
122
    my $hold_5 = $builder->build_object({
123
        class => 'Koha::Holds',
124
        value => {
125
            branchcode => $branch->branchcode,
126
            expirationdate => DateTime->now(time_zone => C4::Context->tz()),
127
        }
128
    });
129
    my $hold_6 = $builder->build_object({
130
        class => 'Koha::Holds',
131
        value => {
132
            branchcode => $branch->branchcode,
133
            expirationdate => DateTime->now(time_zone => C4::Context->tz())->add(days => 1)->iso8601(),
134
        }
135
    });
136
137
    C4::Reserves::CancelExpiredReserves();
138
139
    my $expired_holds = Koha::Old::Holds->expired({ branchcode => $branch->branchcode });
140
    is($expired_holds->count(), 3, 'expired() returns 3 holds');
141
142
    my $expired_hold_1 = $expired_holds->find($hold_1->id);
143
    my $expired_hold_2 = $expired_holds->find($hold_2->id);
144
    my $expired_hold_3 = $expired_holds->find($hold_3->id);
145
    my $expired_hold_4 = $expired_holds->find($hold_4->id);
146
    my $expired_hold_5 = $expired_holds->find($hold_5->id);
147
    my $expired_hold_6 = $expired_holds->find($hold_6->id);
148
149
    is($expired_hold_1, undef, "Hold 1 not found with expired().");
150
    ok($expired_hold_2->pickupexpired eq DateTime->now(time_zone => C4::Context->tz())->subtract(days => 2)->ymd()
151
    , "Pick up for hold 2 expired 2 days ago.");
152
    ok($expired_hold_3->pickupexpired && $expired_hold_4->pickupexpired eq DateTime->now(time_zone => C4::Context->tz())->subtract(days => 1)->ymd()
153
    , "Pick up for holds 3 and 4 expired yesterday.");
154
    is($expired_hold_5 && $expired_hold_6, undef, "Holds 5 and 6 not expired.");
155
156
    $schema->storage->txn_rollback;
157
158
};

Return to bug 10744