[Koha-patches] [PATCH] Alter Overdues::CalcFine to use Dates objects.

Ryan Higgins rch at balrog.liblime.com
Mon May 12 12:29:35 CEST 2008


---
 C4/Calendar.pm            |    7 ++++-
 C4/Overdues.pm            |   53 ++++++++++++++++++++++++++++----------------
 misc/cronjobs/fines-ll.pl |   29 +++++++++++++++++-------
 3 files changed, 59 insertions(+), 30 deletions(-)

diff --git a/C4/Calendar.pm b/C4/Calendar.pm
index b2d2f78..239e603 100644
--- a/C4/Calendar.pm
+++ b/C4/Calendar.pm
@@ -19,8 +19,7 @@ use strict;
 require Exporter;
 use vars qw($VERSION @EXPORT);
 
-#use Date::Manip;
-# use Date::Calc;
+use Date::Calc qw( Date_to_Days );
 
 # set the version for version checking
 $VERSION = 3.00;
@@ -439,6 +438,10 @@ C<$year> Is the year to check whether if is a holiday or not.
 
 sub isHoliday {
     my ($self, $day, $month, $year) = @_;
+	# FIXME - date strings are stored in non-padded metric format. should change to iso.
+	$month=$month+0;
+	$year=$year+0;
+	$day=$day+0;
     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();
diff --git a/C4/Overdues.pm b/C4/Overdues.pm
index 7a9572c..ffeaabc 100644
--- a/C4/Overdues.pm
+++ b/C4/Overdues.pm
@@ -179,7 +179,7 @@ sub checkoverdues {
 =item CalcFine
 
   ($amount, $chargename, $message, $daycounttotal, $daycount) =
-    &CalcFine($itemnumber, $categorycode, $branch, $days_overdue, $description);
+    &CalcFine($itemnumber, $categorycode, $branch, $days_overdue, $description, $start_date, $end_date );
 
 Calculates the fine for a book.
 
@@ -197,9 +197,15 @@ the book.
 
 C<$branchcode> is the library whose issuingrules govern this transaction.
 
-C<$days_overdue> is the number of days elapsed since the book's due
-date.
+C<$days_overdue> is the number of days elapsed since the book's due date.
+  NOTE: supplying days_overdue is deprecated.
 
+C<$start_date> & C<$end_date> are C4::Dates objects 
+defining the date range over which to determine the fine.
+Note that if these are defined, we ignore C<$difference> and C<$dues> , 
+but retain these for backwards-comptibility with extant fines scripts.
+
+Fines scripts should just supply the date range over which to calculate the fine.
 
 C<&CalcFine> returns a list of three values:
 
@@ -215,30 +221,39 @@ or "Final Notice".
 
 #'
 sub CalcFine {
-    my ( $item, $bortype, $branchcode, $difference , $dues  ) = @_;
+    my ( $item, $bortype, $branchcode, $difference ,$dues , $start_date, $end_date  ) = @_;
     my $dbh = C4::Context->dbh;
     my $amount = 0;
     my $printout;
-    # calculate how many days the patron is late
-    my $countspecialday=&GetSpecialHolidays($dues,$item->{itemnumber});
-    my $countrepeatableday=&GetRepeatableHolidays($dues,$item->{itemnumber},$difference);    
-    my $countalldayclosed = $countspecialday + $countrepeatableday;
-    my $daycount = $difference - $countalldayclosed;
-    # get issuingrules (fines part will be used)
+	my $daystocharge;
+	# get issuingrules (fines part will be used)
     my $data = C4::Circulation::GetIssuingRule($bortype, $item->{'itemtype'},$branchcode);
-    my $daycounttotal = $daycount - $data->{'firstremind'};
-    if ($data->{'chargeperiod'} >0) { # if there is a rule for this bortype
-        if ($data->{'firstremind'} < $daycount)
-            {
-            $amount   = int($daycounttotal/$data->{'chargeperiod'})*$data->{'fine'};
-        }
+	if($difference) {
+		# if $difference is supplied, the difference has already been calculated, but we still need to adjust for the calendar.
+    	# use copy-pasted functions from calendar module.  (deprecated -- these functions will be removed from C4::Overdues ).
+	    my $countspecialday=&GetSpecialHolidays($dues,$item->{itemnumber});
+	    my $countrepeatableday=&GetRepeatableHolidays($dues,$item->{itemnumber},$difference);    
+	    my $countalldayclosed = $countspecialday + $countrepeatableday;
+	    $daystocharge = $difference - $countalldayclosed;
+	} else {
+		# if $difference is not supplied, we have C4::Dates objects giving us the date range, and we use the calendar module.
+		if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
+			my $calendar = C4::Calendar->new(  branchcode => $branchcode );
+			$daystocharge = $calendar->daysBetween( $start_date, $end_date );
+		} else {
+			$daystocharge = Date_to_Days(split('-',$end_date->output('iso'))) - Date_to_Days(split('-',$start_date->output('iso')));
+		}
+	}
+	# correct for grace period.
+	$daystocharge -= $data->{'firstremind'};
+    if ($data->{'chargeperiod'} > 0 && $daystocharge > 0 ) { 
+        $amount   = int($daystocharge / $data->{'chargeperiod'}) * $data->{'fine'};
     } else {
         # a zero (or null)  chargeperiod means no charge.
-		#  
     }
     
-  #  warn "Calc Fine: " . join(", ", ($item->{'itemnumber'}, $bortype, $difference , $data->{'fine'} . " * " . $daycount . " days = \$ " . $amount , "desc: $dues")) ;
- return ( $amount, $data->{'chargename'}, $printout ,$daycounttotal ,$daycount );
+    #  warn "Calc Fine: " . join(", ", ($item->{'itemnumber'}, $bortype, $difference , $data->{'fine'} . " * " . $daycount . " days = \$ " . $amount , "desc: $dues")) ;
+    return ( $amount, $data->{'chargename'}, $printout ,$daystocharge , $daystocharge + $data->{'firstremind'} );
 }
 
 
diff --git a/misc/cronjobs/fines-ll.pl b/misc/cronjobs/fines-ll.pl
index a8d1fc4..88ebe0a 100755
--- a/misc/cronjobs/fines-ll.pl
+++ b/misc/cronjobs/fines-ll.pl
@@ -36,6 +36,7 @@ BEGIN {
 use C4::Context;
 use C4::Circulation;
 use C4::Overdues;
+use C4::Calendar;
 use Date::Manip qw/Date_DaysSince1BC/;
 use C4::Biblio;
 #use Data::Dumper;
@@ -45,6 +46,8 @@ my $fldir = "/tmp";
 my $libname=C4::Context->preference('LibraryName');
 my $dbname= C4::Context->config('database');
 
+my $SET_LOST = 0;  #  automatically charge item price at delay=3 if set.
+
 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time);
 $mon++;
 $year=$year+1900;
@@ -54,7 +57,7 @@ my $filename= $dbname;
 $filename =~ s/\W//;
 $filename = $fldir . '/'. $filename . $datestr . ".log";
 open (FILE,">$filename") || die "Can't open LOG";
-print FILE "cardnumber\tcategory\tsurname\tfirstname\temail\tphone\taddress\tcitystate\tbarcode\tdate_due\ttype\tdays_overdue\tfine\n";
+print FILE "cardnumber\tcategory\tsurname\tfirstname\temail\tphone\taddress\tcitystate\tbarcode\tdate_due\ttype\titemnumber\tdays_overdue\tfine\n";
 
 # FIXME
 # it looks like $count is just a counter, would it be
@@ -83,19 +86,27 @@ for (my $i=0;$i<scalar(@$data);$i++){
   	# CircControl must be PickupLibrary. (branchcode comes from issues table here).
 	$branchcode =  $data->[$i]->{'branchcode'};
   }
-  
+  my $calendar = C4::Calendar->new( branchcode => $branchcode );
+
+  my @dmy =  split( '-', C4::Dates->new()->output('metric') ) ;
+  my $isHoliday = $calendar->isHoliday( split( '/', C4::Dates->new()->output('metric') ) );
   my $starter;
       
  if ($date2 <= $date){
     $overdueItemsCounted++ if $DEBUG;
     my $difference=$date-$date2;
+	my $start_date = C4::Dates->new($data->[$i]->{'date_due'},'iso');
+	my $end_date = C4::Dates->new($datestr,'iso');
     my ($amount,$type,$printout,$daycounttotal,$daycount)=
-  		CalcFine($data->[$i], $borrower->{'categorycode'}, $branchcode,
-        		$difference, $datedue);
+  		CalcFine($data->[$i], $borrower->{'categorycode'}, $branchcode,undef,undef, $start_date,$end_date);
     my ($delays1,$delays2,$delays3)=GetOverdueDelays($borrower->{'categorycode'});
-    my $issuingrules=GetIssuingRule($borrower->{'categorycode'}, $data->[$i]->{'itemnumber'},$branchcode);
-	UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due) if( $amount > 0 ) ;
- 	if($delays1  and $delays2  and $delays3)  {
+
+	# Don't update the fine if today is a holiday.  
+  	# This ensures that dropbox mode will remove the correct amount of fine.
+	if( ! $isHoliday ) {
+		UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due) if( $amount > 0 ) ;
+ 	}
+	if($delays1  and $delays2  and $delays3)  {
     
     	my $debarredstatus=CheckBorrowerDebarred($borrower->{'borrowernumber'});
 
@@ -146,7 +157,7 @@ for (my $i=0;$i<scalar(@$data);$i++){
             my $notifyid=GetNotifyId($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'});
             my $timestamp=$todaydate." ".$hour."\:".$min."\:".$sec;
             my $create=CheckAccountLineItemInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},$typeaccount,$notifyid);
-            if ($create eq '0'){
+            if ($SET_LOST && ($create eq '0') ){
           		CreateItemAccountLine($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},$todaydate,$items->{'price'},$description,$typeaccount,
             		$items->{'price'},$timestamp,$notifyid,$level);
             }
@@ -166,7 +177,7 @@ for (my $i=0;$i<scalar(@$data);$i++){
         $sth->finish;
         $borrower->{'phone'}=$tdata->{'phone'};
     }
- 	print FILE "$printout\t$borrower->{'cardnumber'}\t$borrower->{'categorycode'}\t$borrower->{'surname'}\t$borrower->{'firstname'}\t$borrower->{'email'}\t$borrower->{'phone'}\t$borrower->{'address'}\t$borrower->{'city'}\t$data->[$i]->{'barcode'}\t$data->[$i]->{'date_due'}\t$type\t$difference\t$amount\n";
+ 	print FILE "$printout\t$borrower->{'cardnumber'}\t$borrower->{'categorycode'}\t$borrower->{'surname'}\t$borrower->{'firstname'}\t$borrower->{'email'}\t$borrower->{'phone'}\t$borrower->{'address'}\t$borrower->{'city'}\t$data->[$i]->{'barcode'}\t$data->[$i]->{'date_due'}\t$type\t$data->[$i]->{'itemnumber'}\t$daycounttotal\t$amount\n";
  }
 }
 
-- 
1.5.4.2




More information about the Koha-patches mailing list