From 542da50713515acc32e08052968028b2136b891d Mon Sep 17 00:00:00 2001 From: Ryan Higgins Date: Thu, 28 Feb 2008 18:41:29 -0600 Subject: [PATCH] Reinstating use of C4::Calendar object on issuing. Also implementing useDaysMode syspref 3 modes: Calendar: every 'closed' day increments loan length by one. Days: ignore the calendar when calculating loan length. Datedue: increase loan length only to prevent due date from falling on 'closed' date. Signed-off-by: Joshua Ferraro --- C4/Calendar.pm | 54 ++++++++++++++--------------- C4/Circulation.pm | 88 ++++++++++++++++++++++++++++++----------------- 2 files changed, 81 insertions(+), 61 deletions(-) diff --git a/C4/Calendar.pm b/C4/Calendar.pm index cd9be63c0a..c355850d6a 100644 --- a/C4/Calendar.pm +++ b/C4/Calendar.pm @@ -429,31 +429,28 @@ sub delete_holiday { $isHoliday = isHoliday($day, $month $year); -C<$day> Is the day to check wether if is a holiday or not. +C<$day> Is the day to check whether if is a holiday or not. -C<$month> Is the month to check wether if is a holiday or not. +C<$month> Is the month to check whether if is a holiday or not. -C<$year> Is the year to check wether if is a holiday or not. +C<$year> Is the year to check whether if is a holiday or not. =cut sub isHoliday { my ($self, $day, $month, $year) = @_; - - my $weekday = Date_DayOfWeek($month, $day, $year) % 7; - + my $weekday = &Date::Calc::Day_of_Week($year, $month, $day) % 7; my $weekDays = $self->get_week_days_holidays(); my $dayMonths = $self->get_day_month_holidays(); my $exceptions = $self->get_exception_holidays(); my $singles = $self->get_single_holidays(); - if (defined($exceptions->{"$year/$month/$day"})) { return 0; } else { if ((exists($weekDays->{$weekday})) || (exists($dayMonths->{"$month/$day"})) || (exists($singles->{"$year/$month/$day"}))) { - return 1; + return 1; } else { return 0; } @@ -463,40 +460,38 @@ sub isHoliday { =item addDate - my ($day, $month, $year) = $calendar->addDate($day, $month, $year, $offset) - -C<$day> Is the starting day of the interval. + my ($day, $month, $year) = $calendar->addDate($date, $offset) -C<$month> Is the starting month of the interval. - -C<$year> Is the starting year of the interval. +C<$date> is a C4::Dates object representing the starting date of the interval. C<$offset> Is the number of days that this function has to count from $date. =cut sub addDate { - my ($self, $day, $month, $year, $offset) = @_; - - if ($offset < 0) { # In case $offset is negative + my ($self, $startdate, $offset) = @_; + my ($year,$month,$day) = split("-",$startdate->output('iso')); + if ($offset < 0) { # In case $offset is negative $offset = $offset*(-1); } - - my $daysMode = C4::Context->preference('useDaysMode'); - if ($daysMode eq 'normal') { - ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, ($offset - 1)); - } else { + my $daysMode = C4::Context->preference('useDaysMode'); + if ($daysMode eq 'Datedue') { + ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, $offset ); + while ($self->isHoliday($day, $month, $year)) { + ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, 1); + } + } elsif($daysMode eq 'Calendar') { while ($offset > 0) { + ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, 1); if (!($self->isHoliday($day, $month, $year))) { $offset = $offset - 1; - } - if ($offset > 0) { - ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, 1); - } + } } + } else { ## ($daysMode eq 'Days') + ($year, $month, $day) = &Date::Calc::Add_Delta_Days($year, $month, $day, $offset ); } - - return($day, $month, $year); +warn sprintf("%04d-%02d-%02d",$year,$month,$day); + return(C4::Dates->new( sprintf("%04d-%02d-%02d",$year,$month,$day),'iso')); } =item daysBetween @@ -522,9 +517,10 @@ sub daysBetween { my ($self, $dayFrom, $monthFrom, $yearFrom, $dayTo, $monthTo, $yearTo) = @_; my $daysMode = C4::Context->preference('useDaysMode'); +#FIXME : useDaysMode == 'Datedue' is not implemented here, but neither is this fcn used anywhere. my $count = 1; my $continue = 1; - if ($daysMode eq 'normal') { + if ($daysMode eq 'Days') { while ($continue) { if (($yearFrom != $yearTo) || ($monthFrom != $monthTo) || ($dayFrom != $dayTo)) { ($yearFrom, $monthFrom, $dayFrom) = &Date::Calc::Add_Delta_Days($yearFrom, $monthFrom, $dayFrom, 1); diff --git a/C4/Circulation.pm b/C4/Circulation.pm index a403a9edbf..0ed7b58e94 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -28,6 +28,7 @@ use C4::Biblio; use C4::Items; use C4::Members; use C4::Dates; +use C4::Calendar; use Date::Calc qw( Today Today_and_Now @@ -955,7 +956,7 @@ sub AddIssue { "UPDATE branchtransfers SET datearrived = now(), tobranch = ?, - comments = 'Forced branchtransfert' + comments = 'Forced branchtransfer' WHERE itemnumber= ? AND datearrived IS NULL" ); $sth->execute(C4::Context->userenv->{'branch'},$item->{'itemnumber'}); @@ -979,11 +980,7 @@ sub AddIssue { $itype, $branch ); - $datedue = time + ($loanlength) * 86400; - my @datearr = localtime($datedue); - $dateduef = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso'); - $dateduef=CheckValidDatedue($dateduef,$item->{'itemnumber'},C4::Context->userenv->{'branch'}); - + $dateduef = CalcDateDue(C4::Dates->new(),$loanlength,$branch); # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate if ( C4::Context->preference('ReturnBeforeExpiry') && $dateduef->output('iso') gt $borrower->{dateexpiry} ) { $dateduef = C4::Dates->new($borrower->{dateexpiry},'iso'); @@ -1654,15 +1651,16 @@ sub AddRenewal { (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} , $borrower->{'branchcode'} ); - #FIXME -- choose issuer or borrower branch. - #FIXME -- where's the calendar ? + #FIXME -- choose issuer or borrower branch -- use circControl. + #FIXME -- $debug-ify the (0) - my @darray = Add_Delta_DHMS( Today_and_Now(), $loanlength, 0, 0, 0 ); - $datedue = C4::Dates->new( sprintf("%04d-%02d-%02d",@darray[0..2]), 'iso'); - (0) and print STDERR "C4::Dates->new->output = " . C4::Dates->new()->output() - . "\ndatedue->output = " . $datedue->output() - . "\n(Y,M,D) = " . join ',', @darray; - $datedue=CheckValidDatedue($datedue,$itemnumber,$branch); + #my @darray = Add_Delta_DHMS( Today_and_Now(), $loanlength, 0, 0, 0 ); + #$datedue = C4::Dates->new( sprintf("%04d-%02d-%02d",@darray[0..2]), 'iso'); + #(0) and print STDERR "C4::Dates->new->output = " . C4::Dates->new()->output() + # . "\ndatedue->output = " . $datedue->output() + # . "\n(Y,M,D) = " . join ',', @darray; + #$datedue=CheckValidDatedue($datedue,$itemnumber,$branch,$loanlength); + $datedue = CalcDateDue(C4::Dates->new(),$loanlength,$branch); } # Find the issues record for this book @@ -1961,19 +1959,44 @@ sub UpdateHoldingbranch { ModItem({ holdingbranch => $branch }, undef, $itemnumber); } +=head2 CalcDateDue + +$newdatedue = CalcDateDue($startdate,$loanlength,$branchcode); +this function calculates the due date given the loan length , +checking against the holidays calendar as per the 'useDaysMode' syspref. +C<$startdate> = C4::Dates object representing start date of loan period (assumed to be today) +C<$branch> = location whose calendar to use +C<$loanlength> = loan length prior to adjustment +=cut + +sub CalcDateDue { + my ($startdate,$loanlength,$branch) = @_; + if(C4::Context->preference('useDaysMode') eq 'Days') { # ignoring calendar + my $datedue = time + ($loanlength) * 86400; + #FIXME - assumes now even though we take a startdate + my @datearr = localtime($datedue); + return C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso'); + } else { + warn $branch; + my $calendar = C4::Calendar->new( branchcode => $branch ); + my $datedue = $calendar->addDate($startdate, $loanlength); + return $datedue; + } +} + =head2 CheckValidDatedue + This function does not account for holiday exceptions nor does it handle the 'useDaysMode' syspref . + To be replaced by CalcDateDue() once C4::Calendar use is tested. $newdatedue = CheckValidDatedue($date_due,$itemnumber,$branchcode); -this function return a new date due after checked if it's a repeatable or special holiday +this function validates the loan length against the holidays calendar, and adjusts the due date as per the 'useDaysMode' syspref. C<$date_due> = returndate calculate with no day check C<$itemnumber> = itemnumber -C<$branchcode> = localisation of issue - +C<$branchcode> = location of issue (affected by 'CircControl' syspref) +C<$loanlength> = loan length prior to adjustment =cut -# Why not create calendar object? - -# TODO add 'duedate' option to useDaysMode . -sub CheckValidDatedue { +sub CheckValidDatedue { my ($date_due,$itemnumber,$branchcode)=@_; my @datedue=split('-',$date_due->output('iso')); my $years=$datedue[0]; @@ -1982,24 +2005,25 @@ my $day=$datedue[2]; # die "Item# $itemnumber ($branchcode) due: " . ${date_due}->output() . "\n(Y,M,D) = ($years,$month,$day)": my $dow; for (my $i=0;$i<2;$i++){ - $dow=Day_of_Week($years,$month,$day); - ($dow=0) if ($dow>6); - my $result=CheckRepeatableHolidays($itemnumber,$dow,$branchcode); - my $countspecial=CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode); - my $countspecialrepeatable=CheckRepeatableSpecialHolidays($month,$day,$itemnumber,$branchcode); - if (($result ne '0') or ($countspecial ne '0') or ($countspecialrepeatable ne '0') ){ - $i=0; - (($years,$month,$day) = Add_Delta_Days($years,$month,$day, 1))if ($i ne '1'); - } - } - my $newdatedue=C4::Dates->new(sprintf("%04d-%02d-%02d",$years,$month,$day),'iso'); + $dow=Day_of_Week($years,$month,$day); + ($dow=0) if ($dow>6); + my $result=CheckRepeatableHolidays($itemnumber,$dow,$branchcode); + my $countspecial=CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode); + my $countspecialrepeatable=CheckRepeatableSpecialHolidays($month,$day,$itemnumber,$branchcode); + if (($result ne '0') or ($countspecial ne '0') or ($countspecialrepeatable ne '0') ){ + $i=0; + (($years,$month,$day) = Add_Delta_Days($years,$month,$day, 1))if ($i ne '1'); + } + } + my $newdatedue=C4::Dates->new(sprintf("%04d-%02d-%02d",$years,$month,$day),'iso'); return $newdatedue; } + =head2 CheckRepeatableHolidays $countrepeatable = CheckRepeatableHoliday($itemnumber,$week_day,$branchcode); -this function check if the date due is a repeatable holiday +this function checks if the date due is a repeatable holiday C<$date_due> = returndate calculate with no day check C<$itemnumber> = itemnumber C<$branchcode> = localisation of issue -- 2.39.5