From c2996ef4cf2a61214f68bfd7b6746666373c16af Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Wed, 13 Apr 2022 08:24:22 +0100 Subject: [PATCH] Bug 30518: Correct DateTime maths for needs_advancing The needs_advancing method prior to this patch used basic DateTime arithmatic, adding a DateTime::Duration in Days to the Arrival date of the item and then comparing that to today. This, however, can cause bugs when the arrival + duration date coincides with a DST boundary and as such may result in an invalid local date. See https://metacpan.org/pod/DateTime#Making-Things-Simple for further details. This patch updates the code to use the DST safe delta_days method to count the days between arrival and now instead and then compares this integer to the defined duration of the stage. To test: 1. Re-run the unit tests, they should now pass. Signed-off-by: Nick Clemens Signed-off-by: Fridolin Somers Signed-off-by: Kyle M Hall (cherry picked from commit 3929335cdbea81c7c891a8a979d69861468502fd) Signed-off-by: Andrew Fuerste-Henry (cherry picked from commit fb1f752f47b70c56509747c5ce6e25bc56f34779) Signed-off-by: Victor Grousset/tuxayo --- Koha/StockRotationItem.pm | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Koha/StockRotationItem.pm b/Koha/StockRotationItem.pm index 43d949acaa..97f9977fae 100644 --- a/Koha/StockRotationItem.pm +++ b/Koha/StockRotationItem.pm @@ -115,23 +115,22 @@ Return 1 if this item is ready to be moved on to the next stage in its rota. =cut sub needs_advancing { - my ( $self ) = @_; + my ($self) = @_; return 0 if $self->itemnumber->get_transfer; # intransfer: don't advance. return 1 if $self->fresh; # Just on rota: advance. my $completed = $self->itemnumber->_result->branchtransfers->search( { 'reason' => "StockrotationAdvance" }, { order_by => { -desc => 'datearrived' } } ); + # Do maths on whether we need to be moved on. if ( $completed->count ) { - my $arrival = dt_from_string( - $completed->next->datearrived, 'iso' - ); - my $duration = DateTime::Duration - ->new( days => $self->stage->duration ); - if ( $arrival + $duration le dt_from_string() ) { + my $arrival = dt_from_string( $completed->next->datearrived ); + my $duration = $arrival->delta_days( dt_from_string() ); + if ( $duration->in_units('days') >= $self->stage->duration ) { return 1; - } else { + } + else { return 0; } } else { -- 2.39.5