From c04b7ea0b541f877ab9d074ab69894a15c999e48 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Fri, 21 Sep 2012 12:50:26 -0300 Subject: [PATCH] Bug 8800 - useDaysMode=Datedue wrong behaviour (3.8.x) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useDaysMode=Datedue wasn't used as advertised in the docs. Added a next_open_day sub to Koha::Calendar and some tests for it. - AddIssue was fixed for the case $datedue was defined in circ/circulation.pl - CalcDateDue was modified to be consistent with the intended behaviour Regards To+ Sponsored-by: Universidad Nacional de Córdoba --- C4/Circulation.pm | 38 +++++++++++++++++++++++++++----------- Koha/Calendar.pm | 26 +++++++++++++++++++++++--- t/Calendar.t | 6 +++++- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index f3245c5..e4e4ee6 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -971,10 +971,9 @@ AddIssue does the following things : sub AddIssue { my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode) = @_; my $dbh = C4::Context->dbh; - my $barcodecheck=CheckValidBarcode($barcode); - if ($datedue && ref $datedue ne 'DateTime') { - $datedue = dt_from_string($datedue); - } + + my $barcodecheck=CheckValidBarcode($barcode); + # $issuedate defaults to today. if ( ! defined $issuedate ) { $issuedate = DateTime->now(time_zone => C4::Context->tz()); @@ -989,7 +988,18 @@ sub AddIssue { # find which item we issue my $item = GetItem('', $barcode) or return undef; # if we don't get an Item, abort. my $branch = _GetCircControlBranch($item,$borrower); - + + # $datedue was passed as a parameter, check validity + # and adjust if mandated by sysprefs + if ($datedue && ref $datedue ne 'DateTime') { + $datedue = dt_from_string($datedue); + my $calendar = Koha::Calendar->new( branchcode => $branch ); + if ( C4::Context->preference('useDaysMode') eq 'Datedue' ) { + # use the calendar to push the due date to the next open day + $datedue = $calendar->next_open_day($datedue); + } + } + # get actual issuing if there is one my $actualissue = GetItemIssue( $item->{itemnumber}); @@ -2819,22 +2829,29 @@ sub CalcDateDue { C4::Context->preference('dateformat') ); } else { - # otherwise, calculate the datedue as normal - if ( C4::Context->preference('useDaysMode') eq 'Days' ) - { # ignoring calendar + my $calendar = Koha::Calendar->new( branchcode => $branch ); + + if ( C4::Context->preference('useDaysMode') ne 'Calendar' ) + { # ignoring calendar to calculate date due my $dt = DateTime->now( time_zone => C4::Context->tz() ) ->truncate( to => 'minute' ); if ( $loanlength->{lengthunit} eq 'hours' ) { $dt->add( hours => $loanlength->{issuelength} ); - return $dt; } else { # days $dt->add( days => $loanlength->{issuelength} ); $dt->set_hour(23); $dt->set_minute(59); - return $dt; } + + if ( C4::Context->preference('useDaysMode') eq 'Datedue' ) { + # use the calendar to push the due date to the next open day + $dt = $calendar->next_open_day($dt); + } + + return $dt; + } else { my $dur; if ($loanlength->{lengthunit} eq 'hours') { @@ -2846,7 +2863,6 @@ sub CalcDateDue { if (ref $startdate ne 'DateTime' ) { $startdate = dt_from_string($startdate); } - my $calendar = Koha::Calendar->new( branchcode => $branch ); $datedue = $calendar->addDate( $startdate, $dur, $loanlength->{lengthunit} ); if ($loanlength->{lengthunit} eq 'days') { $datedue->set_hour(23); diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm index 2a2e062..862e4f8 100644 --- a/Koha/Calendar.pm +++ b/Koha/Calendar.pm @@ -164,6 +164,16 @@ sub is_holiday { return 0; } +sub next_open_day { + my ( $self, $dt ) = @_; + + while ($self->is_holiday($dt)) { + $dt->add(days => 1); + } + + return $dt; +} + sub days_between { my $self = shift; my $start_dt = shift; @@ -273,9 +283,9 @@ This documentation refers to Koha::Calendar version 0.0.1 =head1 SYNOPSIS - use Koha::Calendat + use Koha::Calendar - my $c = Koha::Calender->new( branchcode => 'MAIN' ); + my $c = Koha::Calendar->new( branchcode => 'MAIN' ); my $dt = DateTime->now(); # are we open @@ -315,7 +325,7 @@ parameter will be removed when issuingrules properly cope with that $yesno = $calendar->is_holiday($dt); -passed at DateTime object returns 1 if it is a closed day +passed a DateTime object returns 1 if it is a closed day 0 if not according to the calendar =head2 days_between @@ -326,6 +336,16 @@ Passed two dates returns a DateTime::Duration object measuring the length betwee ignoring closed days. Always returns a positive number irrespective of the relative order of the parameters +=head2 next_open_day + +$datetime = $calendar->next_open_day($duedate_dt) + +Passed a Datetime returns another Datetime representing the next open day. It is +intended for use to calculate the due date when useDaysMode syspref is set to either +'Datedue' or 'Calendar'. + +Note: if is_holiday($duedate_dt) = 0 then it should return the same date. + =head2 set_daysmode For testing only allows the calling script to change days mode diff --git a/t/Calendar.t b/t/Calendar.t index 7dc1f1b..bfcb306 100755 --- a/t/Calendar.t +++ b/t/Calendar.t @@ -3,7 +3,7 @@ use strict; use warnings; use DateTime; -use Test::More tests => 21; +use Test::More tests => 23; use Koha::DateUtils; BEGIN { @@ -127,3 +127,7 @@ $cal->add_holiday( dt_from_string('2012-07-07','iso') ); $daycount = $cal->days_between( dt_from_string("2012-07-01",'iso'), dt_from_string("2012-07-15",'iso') )->in_units('days'); cmp_ok( $daycount, '==', 12, 'multiple holidays correctly recognized' ); +$dt = dt_from_string('2012-07-07','iso'); +cmp_ok( $dt->add(days => 1), '==', $cal->next_open_day(dt_from_string('2012-07-07','iso')), 'Next open day correctly calculated' ); +$dt = dt_from_string('2012-07-08','iso'); +cmp_ok( $dt, '==', $cal->next_open_day(dt_from_string('2012-07-08','iso')), 'Next open day correctly calculated (idempotent version)' ); -- 1.7.9.5