Add private function to calculate chargeable units and reconfigure 
Koha/Calendar.pm to use this function.

To test:

Check out an hourly item, manipulate the database to backdate the checkin or 
let the item go overdue whilst enjoying a sandwich.  After the Item is overdue 
Check the item back in and wait for the fines cron job to run (or run it 
yourself).  You should see a fine assessed for this item.


>From 4a7c4f3395fd910b026d05f4ed2c8a736e045cdb Mon Sep 17 00:00:00 2001
From: Elliott Davis <tda...@uttyler.edu<mailto:tda...@uttyler.edu>>
Date: Thu, 29 Mar 2012 19:32:46 +0000
Subject: [PATCH] fixed fines for hourly circulation

http://bugs.koha-community.org/show_bug.cgi?id=7852
---
 C4/Overdues.pm   |   61 +++++++++++++++++++++++++++++++++++------------------
 Koha/Calendar.pm |   18 +++++++++++++++-
 2 files changed, 57 insertions(+), 22 deletions(-)

diff --git a/C4/Overdues.pm b/C4/Overdues.pm
index 7676a87..ebe6cff 100644
--- a/C4/Overdues.pm
+++ b/C4/Overdues.pm
@@ -254,40 +254,59 @@ or "Final Notice".  But CalcFine never defined any value.
 sub CalcFine {
     my ( $item, $bortype, $branchcode, $due_dt, $end_date  ) = @_;
     my $start_date = $due_dt->clone();
-    my $dbh = C4::Context->dbh;
-    my $amount = 0;
-    my $charge_duration;
-    # get issuingrules (fines part will be used)
-    my $data = C4::Circulation::GetIssuingRule($bortype, $item->{itemtype}, 
$branchcode);
-    if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
-        my $calendar = Koha::Calendar->new( branchcode => $branchcode );
-        $charge_duration = $calendar->days_between( $start_date, $end_date );
-    } else {
-        $charge_duration = $end_date - $start_date;
+    # get issuingrules (fines part will be used)
+    my $data;
+    if($item->{itemtype}){
+        $data = C4::Circulation::GetIssuingRule($bortype, $item->{itemtype}, 
$branchcode);
+    }
+    else{
+        $data = C4::Circulation::GetIssuingRule($bortype, $item->{itype}, 
$branchcode);
     }
-    # correct for grace period.
     my $fine_unit = $data->{lengthunit};
     $fine_unit ||= 'days';
-    my $chargeable_units;
-    if ($fine_unit eq 'hours') {
-        $chargeable_units = $charge_duration->hours(); # TODO closed times???
-    }
-    else {
-        $chargeable_units = $charge_duration->days;
-    }
+
+    my $chargeable_units = _get_chargeable_units($fine_unit, $start_date, 
$end_date, $branchcode);
     my $days_minus_grace = $chargeable_units - $data->{firstremind};
+    my $amount = 0;
+
     if ($data->{'chargeperiod'}  && $days_minus_grace  ) {
-        $amount = int($chargeable_units / $data->{'chargeperiod'}) * 
$data->{'fine'};# TODO fine calc should be in cents
+        $amount = int($chargeable_units / $data->{'chargeperiod'}) * 
$data->{'fine'};# TODO fine calc should be in cents
     } else {
-        # a zero (or null)  chargeperiod means no charge.
+        # a zero (or null)  chargeperiod means no charge.
     }
     if(C4::Context->preference('maxFine') && ( $amount > 
C4::Context->preference('maxFine'))) {
         $amount = C4::Context->preference('maxFine');
     }
     return ($amount, $data->{chargename}, $days_minus_grace);
-    # FIXME: chargename is NEVER populated anywhere.
+    # FIXME: chargename is NEVER populated anywhere.
 }

+sub _get_chargeable_units {
+    my ($unit, $dt1, $dt2, $branchcode) = @_;
+    my $charge_units = 0;
+    my $charge_duration;
+    if ($unit eq 'hours') {
+        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
+            my $calendar = Koha::Calendar->new( branchcode => $branchcode );
+            $charge_duration = $calendar->hours_between( $dt1, $dt2 );
+        } else {
+            $charge_duration = $dt2->delta_ms( $dt1 );
+        }
+        if($charge_duration->in_units('hours') == 0 && 
$charge_duration->in_units('seconds') > 0){
+            return 1;
+        }
+        return $charge_duration->in_units('hours');
+    }
+    else { # days
+        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
+            my $calendar = Koha::Calendar->new( branchcode => $branchcode );
+            $charge_duration = $calendar->days_between( $dt1, $dt2 );
+        } else {
+            $charge_duration = $dt2->delta_days( $dt1 );
+        }
+        return $charge_duration->in_units('days');
+    }
+}

 =head2 GetSpecialHolidays

diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm
index 1e7299c..c94432f 100644
--- a/Koha/Calendar.pm
+++ b/Koha/Calendar.pm
@@ -137,7 +137,23 @@ sub addDate {
         return $base_date + $add_duration;
     }
 }
-
+sub hours_between {
+    my ($self, $start_dt, $end_dt) = @_;
+    my $duration = $end_dt->delta_ms($start_dt);
+    $start_dt->truncate( to => 'days' );
+    $end_dt->truncate( to => 'days' );
+    # NB this is a kludge in that it assumes all days are 24 hours
+    # However for hourly loans the logic should be expanded to
+    # take into account open/close times then it would be a duration
+    # of library open hours
+    while ( DateTime->compare( $start_dt, $end_dt ) == -1 ) {
+       $start_dt->add( days => 1 );
+       if ( $self->is_holiday($start_dt) ) {
+           $duration->subtract( hours => 24 );
+       }
+    }
+    return $duration;
+}
 sub is_holiday {
     my ( $self, $dt ) = @_;
     my $dow = $dt->day_of_week;
--
1.7.2.5


_______________________________________________
Koha-patches mailing list
Koha-patches@lists.koha-community.org
http://lists.koha-community.org/cgi-bin/mailman/listinfo/koha-patches
website : http://www.koha-community.org/
git : http://git.koha-community.org/
bugs : http://bugs.koha-community.org/

Reply via email to