Bug 42997: Sync booking end_date with the due date at renewal
When a checkout satisfying a booking is renewed, the booking previously kept its original end_date, blocking the booked period from other patrons for the wrong window and leaving the two records out of sync. This patch updates C4::Circulation::AddRenewal to pull the linked booking's end_date along with the renewed due date, mirroring the behaviour introduced for AddIssue earlier in this patchset. As at issue time, if the new due date would clash with a subsequent booking (possible when the renewal was explicitly allowed past a clash), the booking keeps its original end_date. Together with the previous patch this makes a renewal the natural way to extend an issued booking: CanBookBeRenewed refuses renewals that would run into the next booking, and AddRenewal keeps the booking in step with the loan. Test plan: 1) Run t/db_dependent/Circulation.t and confirm the new 'AddRenewal | booking end_date sync' subtest passes 2) Check out a booked item, renew it from the checkouts screen and confirm the booking end date follows the new due date Sponsored-by: OpenFifth <https://openfifth.co.uk/\> Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/\> Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk> Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
2da3248b41
commit
50115d8322
|
|
@ -3743,6 +3743,29 @@ sub AddRenewal {
|
|||
error => 'Update of issue# ' . $issue->issue_id . ' failed with error: ' . $sth->errstr );
|
||||
}
|
||||
|
||||
# Keep any linked booking's end_date in sync with the renewed due date
|
||||
if ( $issue->booking_id ) {
|
||||
my $booking = Koha::Bookings->find( $issue->booking_id );
|
||||
if ( $booking && $booking->status eq 'issued' ) {
|
||||
my $booking_end = dt_from_string( $booking->end_date );
|
||||
if ( $datedue->compare($booking_end) != 0 ) {
|
||||
try {
|
||||
$booking->end_date($datedue)->store;
|
||||
} catch {
|
||||
my $error = $_;
|
||||
if ( blessed $error && $error->isa('Koha::Exceptions::Booking::Clash') ) {
|
||||
|
||||
# The renewal was explicitly allowed past a clash;
|
||||
# keep the booking's original end_date
|
||||
$booking->discard_changes;
|
||||
} else {
|
||||
die $error;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Update the renewal count on the item, and tell zebra to reindex
|
||||
$renews = ( $item_object->renewals || 0 ) + 1;
|
||||
$item_object->renewals($renews);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use Modern::Perl;
|
|||
use utf8;
|
||||
|
||||
use Test::NoWarnings;
|
||||
use Test::More tests => 88;
|
||||
use Test::More tests => 89;
|
||||
use Test::Exception;
|
||||
use Test::MockModule;
|
||||
use Test::Deep qw( cmp_deeply );
|
||||
|
|
@ -7840,6 +7840,107 @@ subtest 'AddRenewal | booking_id preservation' => sub {
|
|||
ok( defined $issue->booking_id, "booking_id field is not null after renewal" );
|
||||
};
|
||||
|
||||
subtest 'AddRenewal | booking end_date sync' => sub {
|
||||
plan tests => 4;
|
||||
|
||||
my $schema = Koha::Database->schema;
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
|
||||
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
|
||||
my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } );
|
||||
my $item = $builder->build_sample_item( { library => $library->branchcode, bookable => 1 } );
|
||||
|
||||
Koha::CirculationRules->set_rules(
|
||||
{
|
||||
branchcode => $library->branchcode,
|
||||
categorycode => $patron->categorycode,
|
||||
itemtype => $item->effective_itemtype,
|
||||
rules => {
|
||||
renewalsallowed => 10,
|
||||
renewalperiod => 7,
|
||||
issuelength => 7,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
my $start_date = dt_from_string()->truncate( to => 'minute' );
|
||||
my $end_date = $start_date->clone->add( days => 7 );
|
||||
|
||||
my $booking = $builder->build_object(
|
||||
{
|
||||
class => 'Koha::Bookings',
|
||||
value => {
|
||||
patron_id => $patron->borrowernumber,
|
||||
item_id => $item->itemnumber,
|
||||
biblio_id => $item->biblio->biblionumber,
|
||||
pickup_library_id => $library->branchcode,
|
||||
start_date => $start_date,
|
||||
end_date => $end_date,
|
||||
status => 'issued',
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
my $issue = AddIssue( $patron, $item->barcode, $end_date->clone );
|
||||
$issue->booking_id( $booking->booking_id )->store;
|
||||
|
||||
# Renewal to a specific due date pulls the booking end_date along
|
||||
my $new_due_date = $end_date->clone->add( days => 3 );
|
||||
AddRenewal(
|
||||
{
|
||||
borrowernumber => $patron->borrowernumber,
|
||||
itemnumber => $item->itemnumber,
|
||||
branch => $library->branchcode,
|
||||
datedue => $new_due_date->clone,
|
||||
}
|
||||
);
|
||||
$booking->discard_changes;
|
||||
is(
|
||||
dt_from_string( $booking->end_date )->compare($new_due_date), 0,
|
||||
"Booking end_date synced to the renewal due date"
|
||||
);
|
||||
is( $booking->status, 'issued', "Booking remains issued after renewal" );
|
||||
|
||||
# A renewal that would clash with the next booking keeps the original end_date
|
||||
my $next_booking = $builder->build_object(
|
||||
{
|
||||
class => 'Koha::Bookings',
|
||||
value => {
|
||||
patron_id => $patron2->borrowernumber,
|
||||
item_id => $item->itemnumber,
|
||||
biblio_id => $item->biblio->biblionumber,
|
||||
pickup_library_id => $library->branchcode,
|
||||
start_date => $new_due_date->clone->add( days => 5 ),
|
||||
end_date => $new_due_date->clone->add( days => 9 ),
|
||||
status => 'new',
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
my $clashing_due_date = $new_due_date->clone->add( days => 6 );
|
||||
AddRenewal(
|
||||
{
|
||||
borrowernumber => $patron->borrowernumber,
|
||||
itemnumber => $item->itemnumber,
|
||||
branch => $library->branchcode,
|
||||
datedue => $clashing_due_date->clone,
|
||||
}
|
||||
);
|
||||
my $renewed_issue = Koha::Checkouts->find( $issue->issue_id );
|
||||
$booking->discard_changes;
|
||||
is(
|
||||
dt_from_string( $renewed_issue->date_due )->compare($clashing_due_date), 0,
|
||||
"Checkout renewed to the requested due date"
|
||||
);
|
||||
is(
|
||||
dt_from_string( $booking->end_date )->compare($new_due_date), 0,
|
||||
"Booking end_date kept when the renewal clashes with the next booking"
|
||||
);
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest "GetSoonestRenewDate tests" => sub {
|
||||
plan tests => 6;
|
||||
Koha::CirculationRules->set_rule(
|
||||
|
|
|
|||
Loading…
Reference in New Issue