@@ -, +, @@
---
C4/HoldsQueue.pm | 4 +-
C4/Reserves.pm | 31 +++++++-
Koha/Item.pm | 2 +-
.../prog/en/includes/holds_table.inc | 10 ++-
.../prog/en/includes/waiting_holds.inc | 6 +-
.../prog/en/modules/circ/pendingreserves.tt | 6 +-
.../prog/en/modules/circ/view_holdsqueue.tt | 8 +-
.../prog/en/modules/members/holdshistory.tt | 11 ++-
.../prog/en/modules/reserve/request.tt | 25 ++++++-
svc/holds | 21 ++++--
t/db_dependent/Holds.t | 75 ++++++++++++++++++-
11 files changed, 171 insertions(+), 28 deletions(-)
--- a/C4/HoldsQueue.pm
+++ a/C4/HoldsQueue.pm
@@ -224,7 +224,7 @@ sub GetBibsWithPendingHoldRequests {
FROM reserves
WHERE found IS NULL
AND priority > 0
- AND reservedate <= CURRENT_DATE()
+ AND reservedate <= CURRENT_TIMESTAMP()
AND suspend = 0
";
my $sth = $dbh->prepare($bib_query);
@@ -268,7 +268,7 @@ sub GetPendingHoldRequestsForBib {
WHERE biblionumber = ?
AND found IS NULL
AND priority > 0
- AND reservedate <= CURRENT_DATE()
+ AND reservedate <= CURRENT_TIMESTAMP()
AND suspend = 0
ORDER BY priority";
my $sth = $dbh->prepare($request_query);
--- a/C4/Reserves.pm
+++ a/C4/Reserves.pm
@@ -200,7 +200,26 @@ sub AddReserve {
my $non_priority = $params->{non_priority};
my $item_group_id = $params->{item_group_id};
- $resdate ||= dt_from_string;
+ if ( C4::Context->preference('HourBasedHolds') ){
+ if ( $resdate ){
+ $resdate = dt_from_string( $resdate );
+ } else {
+ $resdate = dt_from_string();
+ }
+ if ( $expdate ){
+ $expdate = dt_from_string( $expdate );
+ }
+ } else {
+ # add hour and minute components
+ if ( $resdate ){
+ $resdate = dt_from_string( $resdate )->set({ hour => 00, minute => 00, second => 00 });
+ } else {
+ $resdate = dt_from_string();
+ }
+ if ( $expdate ){
+ $expdate = dt_from_string( $expdate )->set({ hour => 23, minute => 59, second => 59 });
+ }
+ }
# if we have an item selectionned, and the pickup branch is the same as the holdingbranch
# of the document, we force the value $priority and $found .
@@ -570,11 +589,15 @@ sub CanItemBeReserved {
}
}
+ my $dtf = Koha::Database->new->schema->storage->datetime_parser;
+ my $fromdate = dt_from_string->set({ hour => 00, minute => 00, second => 00 });
+ my $todate = dt_from_string->set({ hour => 23, minute => 59, second => 59 });
+
if (!$params->{ignore_hold_counts} && defined $holds_per_day && $holds_per_day ne '')
{
my $today_holds = Koha::Holds->search({
borrowernumber => $patron->borrowernumber,
- reservedate => dt_from_string->date
+ reservedate => [ -and => { '>=' => $dtf->format_datetime($fromdate) }, { '<=' => $dtf->format_datetime($todate) } ],
});
return _cache { status => 'tooManyReservesToday', limit => $holds_per_day } if $today_holds->count() >= $holds_per_day;
}
@@ -1019,7 +1042,7 @@ sub CancelExpiredReserves {
my $dtf = Koha::Database->new->schema->storage->datetime_parser;
my $params = {
-or => [
- { expirationdate => { '<', $dtf->format_date($today) } },
+ { expirationdate => { '<', $dtf->format_datetime($today) } },
{ patron_expiration_date => { '<' => $dtf->format_date($today) } }
]
};
@@ -2271,7 +2294,7 @@ sub CalculatePriority {
$sql.= ' AND ( reservedate <= ? )';
}
else {
- $sql.= ' AND ( reservedate < NOW() )';
+ $sql.= ' AND ( reservedate <= NOW() )';
}
my $dbh = C4::Context->dbh();
my @row = $dbh->selectrow_array(
--- a/Koha/Item.pm
+++ a/Koha/Item.pm
@@ -1055,7 +1055,7 @@ sub current_holds {
itemnumber => $self->itemnumber,
suspend => 0,
-or => [
- reservedate => { '<=' => $dtf->format_date(dt_from_string) },
+ reservedate => { '<=' => $dtf->format_datetime(dt_from_string) },
waitingdate => { '!=' => undef },
],
};
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc
@@ -121,14 +121,18 @@
[% hold.notes | html | html_line_break %] |
[% IF Koha.Preference('AllowHoldDateInFuture') %]
-
+
[% ELSE %]
- [% hold.date | $KohaDates %]
+ [% IF Koha.Preference('HourBasedHolds') %]
+ [% hold.date | $KohaDates with_hours = 1 %]
+ [% ELSE %]
+ [% hold.date | $KohaDates %]
+ [% END %]
[% END %]
|
[% UNLESS hold.expired %]
-
+
[% ELSE %]
[% hold.expirationdate | $KohaDates %]
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/waiting_holds.inc
@@ -27,7 +27,11 @@
|
|
[% reserveloo.waitingdate | $KohaDates %] |
- [% reserveloo.reservedate | $KohaDates %] |
+ [% IF Koha.Preference('HourBasedHolds') %]
+ [% reserveloo.reservedate | $KohaDates with_hours = 1 %] |
+ [% ELSE %]
+ [% reserveloo.reservedate | $KohaDates %] |
+ [% END %]
[% IF table_name == 'holdscr' %]
[% IF reserveloo.cancellation_requests.count %]
[% FOREACH cancellation_request IN reserveloo.cancellation_requests %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingreserves.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingreserves.tt
@@ -198,7 +198,11 @@
- [% hold.reservedate | $KohaDates %] in [% Branches.GetName ( hold.branchcode ) | html %]
+ [% IF Koha.Preference('HourBasedHolds') %]
+ [% hold.reservedate | $KohaDates with_hours = 1 %] in [% Branches.GetName ( hold.branchcode ) | html %]
+ [% ELSE %]
+ [% hold.reservedate | $KohaDates %] in [% Branches.GetName ( hold.branchcode ) | html %]
+ [% END %]
|
[% hold.reservenotes | html %] |
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt
@@ -208,7 +208,13 @@
|
[% itemsloo.patron.category.description | html %] ([% itemsloo.patron.categorycode | html %]) |
[% Branches.GetName( itemsloo.pickbranch ) | html %] |
- [% itemsloo.reservedate | $KohaDates %] |
+
+ [% IF Koha.Preference('HourBasedHolds') %]
+ [% itemsloo.reservedate | $KohaDates with_hours = 1 %]
+ [% ELSE %]
+ [% itemsloo.reservedate | $KohaDates %]
+ [% END %]
+ |
[% itemsloo.notes | html %] |
[% END %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt
@@ -80,10 +80,13 @@
[% hold.biblio.author | html %] |
[% hold.item.barcode | html %] |
[% Branches.GetName( hold.branchcode ) | html %] |
- [% hold.reservedate | $KohaDates %] |
-
- [% hold.expirationdate | $KohaDates %]
- |
+ [% IF Koha.Preference('HourBasedHolds') %]
+ [% hold.reservedate | $KohaDates with_hours = 1 %] |
+ [% hold.expirationdate | $KohaDates with_hours = 1 %] |
+ [% ELSE %]
+ [% hold.reservedate | $KohaDates %] |
+ [% hold.expirationdate | $KohaDates %] |
+ [% END %]
[% hold.waitingdate | $KohaDates %]
|
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
@@ -579,13 +579,13 @@
[% IF ( Koha.Preference('AllowHoldDateInFuture') ) %]
-
+
[% END %]
-
+
[% UNLESS ( multi_hold ) %]
@@ -1384,6 +1384,27 @@
});
[% END %]
+ var startPicker = $("#reserve_date").flatpickr({
+ [% IF Koha.Preference('HourBasedHolds') %]
+ enableTime: true,
+ dateFormat: flatpickr_dateformat_string + " " + flatpickr_timeformat_string,
+ [% END %]
+ });
+
+ var endPicker = $("#expiration_date").flatpickr({
+ [% IF Koha.Preference('HourBasedHolds') %]
+ enableTime: true,
+ dateFormat: flatpickr_dateformat_string + " " + flatpickr_timeformat_string,
+ [% END %]
+ });
+
+ [% IF Koha.Preference('HourBasedHolds') %]
+ $(".holdst_reservedate, .futuredate").flatpickr({
+ enableTime: true,
+ dateFormat: flatpickr_dateformat_string + " " + flatpickr_timeformat_string,
+ });
+ [% END %]
+
var my_table = $("#requestspecific").dataTable($.extend(true, {}, dataTablesDefaults, {
"paginate": false,
"dom": '<"top pager"ilf>t',
--- a/svc/holds
+++ a/svc/holds
@@ -115,16 +115,27 @@ while ( my $h = $holds_rs->next() ) {
priority => $h->priority(),
reservenotes => $h->reservenotes(),
itemtype_limit => $itemtype_limit,
- reservedate_formatted => $h->reservedate()
- ? output_pref( { dt => dt_from_string( $h->reservedate() ), dateonly => 1 } )
- : q{},
suspend_until_formatted => $h->suspend_until()
? output_pref( { dt => dt_from_string( $h->suspend_until() ), dateonly => 1 } )
: q{},
- expirationdate_formatted => $h->expirationdate()
+ };
+
+ if ( C4::Context->preference('HourBasedHolds') ){
+ $hold->{reservedate_formatted} => $h->reservedate()
+ ? output_pref( { dt => dt_from_string( $h->reservedate() ) } )
+ : q{},
+ $hold->{expirationdate_formatted} => $h->expirationdate()
+ ? output_pref( { dt => dt_from_string( $h->expirationdate() ) } )
+ : q{},
+ } else {
+ $hold->{reservedate_formatted} => $h->reservedate()
+ ? output_pref( { dt => dt_from_string( $h->reservedate() ), dateonly => 1 } )
+ : q{},
+ $hold->{expirationdate_formatted} => $h->expirationdate()
? output_pref( { dt => dt_from_string( $h->expirationdate() ), dateonly => 1 } )
: q{},
- };
+ }
+
$hold->{transfered} = 0;
$hold->{not_transfered} = 0;
--- a/t/db_dependent/Holds.t
+++ a/t/db_dependent/Holds.t
@@ -7,7 +7,7 @@ use t::lib::TestBuilder;
use C4::Context;
-use Test::More tests => 74;
+use Test::More tests => 75;
use Test::Exception;
use MARC::Record;
@@ -108,7 +108,7 @@ my $reservedate = $first_hold->reservedate;
my $borrowernumber = $first_hold->borrowernumber;
my $branch_1code = $first_hold->branchcode;
my $reserve_id = $first_hold->reserve_id;
-is( $reservedate, output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 }), "holds_placed_today should return a valid reserve date");
+is( dt_from_string($reservedate), dt_from_string, "holds_placed_today should return a valid reserve date");
is( $borrowernumber, $borrowernumbers[0], "holds_placed_today should return a valid borrowernumber");
is( $branch_1code, $branch_1, "holds_placed_today should return a valid branchcode");
ok($reserve_id, "Test holds_placed_today()");
@@ -939,7 +939,7 @@ subtest 'CanItemBeReserved / holds_per_day tests' => sub {
is_deeply(
CanItemBeReserved( $patron, $item_2 ),
{ status => 'tooManyReservesToday', limit => 2 },
- 'Patron cannot a third item with 2 reserves daily cap'
+ 'Patron cannot reserve a third item with 2 reserves daily cap'
);
# Update last hold so reservedate is in the past, so 2 holds, but different day
@@ -1702,7 +1702,7 @@ subtest 'ModReserve can only update expirationdate for found holds' => sub {
$hold = Koha::Holds->find($reserve_id);
- is( $hold->expirationdate, '1981-06-10',
+ is( dt_from_string( $hold->expirationdate )->ymd, '1981-06-10',
'Found hold expiration date updated correctly' );
is( $hold->priority, '0', 'Found hold priority was not updated' );
@@ -1887,3 +1887,70 @@ subtest 'EmailPatronWhenHoldIsPlaced tests' => sub {
$schema->storage->txn_rollback;
};
+
+subtest 'HourBasedHolds' => sub {
+ plan tests => 4;
+ $schema->storage->txn_begin;
+
+ my $category = $builder->build({ source => 'Category' });
+ my $branch = $builder->build({ source => 'Branch' })->{ branchcode };
+ my $biblio = $builder->build_sample_biblio( { itemtype => 'DUMMY' } );
+ my $itemnumber = $builder->build_sample_item(
+ { library => $branch, biblionumber => $biblio->biblionumber } )
+ ->itemnumber;
+
+ my $borrowernumber = Koha::Patron->new(
+ {
+ firstname => 'firstname',
+ surname => 'surname',
+ categorycode => $category->{categorycode},
+ branchcode => $branch,
+ }
+ )->store->borrowernumber;
+
+ t::lib::Mocks::mock_preference('HourBasedHolds', 1);
+
+ my $reservation_date = DateTime->now->set( hour => 7, minute => 30 );
+ my $expiration_date = DateTime->now->set( hour => 19, minute => 30 );
+
+ my $reserve_id = AddReserve(
+ {
+ branchcode => $branch,
+ borrowernumber => $borrowernumber,
+ biblionumber => $biblio->biblionumber,
+ priority =>
+ C4::Reserves::CalculatePriority( $biblio->biblionumber ),
+ itemnumber => $itemnumber,
+ reservation_date => $reservation_date,
+ expiration_date => $expiration_date,
+ }
+ );
+
+ my $hold = Koha::Holds->find($reserve_id);
+ is( dt_from_string( $hold->reservedate )->hour, 07, "Hold reserve date is set correctly with hours when HourBasedHolds enabled" );
+ is( dt_from_string( $hold->expirationdate )->hour, 19, "Hold expiration date is set correctly with hours when HourBasedHolds enabled" );
+
+ t::lib::Mocks::mock_preference('HourBasedHolds', 0);
+
+ $reservation_date = DateTime->now->ymd;
+ $expiration_date = DateTime->now->ymd;
+
+ $reserve_id = AddReserve(
+ {
+ branchcode => $branch,
+ borrowernumber => $borrowernumber,
+ biblionumber => $biblio->biblionumber,
+ priority =>
+ C4::Reserves::CalculatePriority( $biblio->biblionumber ),
+ itemnumber => $itemnumber,
+ reservation_date => $reservation_date,
+ expiration_date => $expiration_date,
+ }
+ );
+
+ $hold = Koha::Holds->find($reserve_id);
+ is( dt_from_string( $hold->reservedate )->hour, 00, "Hold reserve date is set correctly when HourBasedHolds disabled" );
+ is( dt_from_string( $hold->expirationdate )->hour, 23, "Hold expiration date is set correctly when HourBasedHolds disabled" );
+
+ $schema->storage->txn_rollback;
+};
--