[PATCH] fixed fines for hourly circulation

Elliott Davis tdavis at uttyler.edu
Thu Mar 29 21:32:46 CEST 2012


http://bugs.koha-community.org/show_bug.cgi?id=3D7852
---
 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 va=
lue.
 sub CalcFine {
     my ( $item, $bortype, $branchcode, $due_dt, $end_date  ) =3D @_;
     my $start_date =3D $due_dt->clone();
-    my $dbh =3D C4::Context->dbh;
-    my $amount =3D 0;
-    my $charge_duration;
-    # get issuingrules (fines part will be used)
-    my $data =3D C4::Circulation::GetIssuingRule($bortype, $item->{itemtyp=
e}, $branchcode);
-    if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
-        my $calendar =3D Koha::Calendar->new( branchcode =3D> $branchcode =
);
-        $charge_duration =3D $calendar->days_between( $start_date, $end_da=
te );
-    } else {
-        $charge_duration =3D $end_date - $start_date;
+    # get issuingrules (fines part will be used)
+    my $data;
+    if($item->{itemtype}){
+        $data =3D C4::Circulation::GetIssuingRule($bortype, $item->{itemty=
pe}, $branchcode);
+    }
+    else{
+        $data =3D C4::Circulation::GetIssuingRule($bortype, $item->{itype}=
, $branchcode);
     }
-    # correct for grace period.
     my $fine_unit =3D $data->{lengthunit};
     $fine_unit ||=3D 'days';
-    my $chargeable_units;
-    if ($fine_unit eq 'hours') {
-        $chargeable_units =3D $charge_duration->hours(); # TODO closed tim=
es???
-    }
-    else {
-        $chargeable_units =3D $charge_duration->days;
-    }
+
+    my $chargeable_units =3D _get_chargeable_units($fine_unit, $start_date=
, $end_date, $branchcode);
     my $days_minus_grace =3D $chargeable_units - $data->{firstremind};
+    my $amount =3D 0;
+
     if ($data->{'chargeperiod'}  && $days_minus_grace  ) {
-        $amount =3D int($chargeable_units / $data->{'chargeperiod'}) * $da=
ta->{'fine'};# TODO fine calc should be in cents
+        $amount =3D int($chargeable_units / $data->{'chargeperiod'}) * $da=
ta->{'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->pref=
erence('maxFine'))) {
         $amount =3D 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) =3D @_;
+    my $charge_units =3D 0;
+    my $charge_duration;
+    if ($unit eq 'hours') {
+        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed'=
) {
+            my $calendar =3D Koha::Calendar->new( branchcode =3D> $branchc=
ode );
+            $charge_duration =3D $calendar->hours_between( $dt1, $dt2 );
+        } else {
+            $charge_duration =3D $dt2->delta_ms( $dt1 );
+        }
+        if($charge_duration->in_units('hours') =3D=3D 0 && $charge_duratio=
n->in_units('seconds') > 0){
+            return 1;
+        }
+        return $charge_duration->in_units('hours');
+    }
+    else { # days
+        if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed'=
) {
+            my $calendar =3D Koha::Calendar->new( branchcode =3D> $branchc=
ode );
+            $charge_duration =3D $calendar->days_between( $dt1, $dt2 );
+        } else {
+            $charge_duration =3D $dt2->delta_days( $dt1 );
+        }
+        return $charge_duration->in_units('days');
+    }
+}

 =3Dhead2 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) =3D @_;
+    my $duration =3D $end_dt->delta_ms($start_dt);
+    $start_dt->truncate( to =3D> 'days' );
+    $end_dt->truncate( to =3D> '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 ) =3D=3D -1 ) {
+       $start_dt->add( days =3D> 1 );
+       if ( $self->is_holiday($start_dt) ) {
+           $duration->subtract( hours =3D> 24 );
+       }
+    }
+    return $duration;
+}
 sub is_holiday {
     my ( $self, $dt ) =3D @_;
     my $dow =3D $dt->day_of_week;
--
1.7.2.5



--_000_CB9A750C404Ctdavisuttyleredu_
Content-Type: text/html; charset="us-ascii"
Content-ID: <7B048A4FB1D68544A965B59E71E0E9E8 at uttyler.edu>
Content-Transfer-Encoding: quoted-printable

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
</head>
<body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-lin=
e-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-fami=
ly: Calibri, sans-serif; ">
<div>
<pre class=3D"bz_comment_text" id=3D"comment_text_1" style=3D"font-size: me=
dium; font-family: monospace; white-space: pre-wrap; width: 50em; color: rg=
b(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; =
letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webki=
t-auto; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0p=
x; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span =
class=3D"Apple-style-span" style=3D"background-color: transparent; ">Add pr=
ivate 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 o=
r let the item go overdue whilst enjoying a sandwich.  After the Item is ov=
erdue 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.</span></pre>
<pre class=3D"bz_comment_text" id=3D"comment_text_1" style=3D"font-size: me=
dium; font-family: monospace; white-space: pre-wrap; width: 50em; color: rg=
b(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; =
letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webki=
t-auto; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0p=
x; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span =
class=3D"Apple-style-span" style=3D"background-color: transparent; "><br></=
span></pre>
<pre class=3D"bz_comment_text" id=3D"comment_text_1" style=3D"font-size: me=
dium; font-family: monospace; white-space: pre-wrap; width: 50em; color: rg=
b(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; =
letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webki=
t-auto; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0p=
x; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span =
class=3D"Apple-style-span" style=3D"background-color: transparent; ">From 4=
a7c4f3395fd910b026d05f4ed2c8a736e045cdb Mon Sep 17 00:00:00 2001
From: Elliott Davis &lt;<a href=3D"mailto:tdavis at uttyler.edu">tdavis at uttyle=
r.edu</a>&gt;
Date: Thu, 29 Mar 2012 19:32:46 &#43;0000
Subject: [PATCH] fixed fines for hourly circulation

<a href=3D"http://bugs.koha-community.org/show_bug.cgi?id=3D7852">http://bu=
gs.koha-community.org/show_bug.cgi?id=3D7852</a>
---
 C4/Overdues.pm   |   61 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;=
&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;=
&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;------------------
 Koha/Calendar.pm |   18 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;=
&#43;&#43;&#43;&#43;&#43;-
 2 files changed, 57 insertions(&#43;), 22 deletions(-)

diff --git a/C4/Overdues.pm b/C4/Overdues.pm
index 7676a87..ebe6cff 100644
--- a/C4/Overdues.pm
&#43;&#43;&#43; b/C4/Overdues.pm
@@ -254,40 &#43;254,59 @@ or &quot;Final Notice&quot;.  But CalcFine never =
defined any value.
 sub CalcFine {
     my ( $item, $bortype, $branchcode, $due_dt, $end_date  ) =3D @_;
     my $start_date =3D $due_dt-&gt;clone();
-    my $dbh =3D C4::Context-&gt;dbh;
-    my $amount =3D 0;
-    my $charge_duration;
-    # get issuingrules (fines part will be used)
-    my $data =3D C4::Circulation::GetIssuingRule($bortype, $item-&gt;{item=
type}, $branchcode);
-    if(C4::Context-&gt;preference('finesCalendar') eq 'noFinesWhenClosed')=
 {
-        my $calendar =3D Koha::Calendar-&gt;new( branchcode =3D&gt; $branc=
hcode );
-        $charge_duration =3D $calendar-&gt;days_between( $start_date, $end=
_date );
-    } else {
-        $charge_duration =3D $end_date - $start_date;
&#43;    # get issuingrules (fines part will be used)                      =
                                                                           =
                                                                           =
                 =20
&#43;    my $data;
&#43;    if($item-&gt;{itemtype}){
&#43;        $data =3D C4::Circulation::GetIssuingRule($bortype, $item-&gt;=
{itemtype}, $branchcode);
&#43;    }
&#43;    else{
&#43;        $data =3D C4::Circulation::GetIssuingRule($bortype, $item-&gt;=
{itype}, $branchcode);
     }
-    # correct for grace period.
     my $fine_unit =3D $data-&gt;{lengthunit};
     $fine_unit ||=3D 'days';
-    my $chargeable_units;
-    if ($fine_unit eq 'hours') {
-        $chargeable_units =3D $charge_duration-&gt;hours(); # TODO closed =
times???
-    }
-    else {
-        $chargeable_units =3D $charge_duration-&gt;days;
-    }
&#43;
&#43;    my $chargeable_units =3D _get_chargeable_units($fine_unit, $start_=
date, $end_date, $branchcode);
     my $days_minus_grace =3D $chargeable_units - $data-&gt;{firstremind};
&#43;    my $amount =3D 0;
&#43;
     if ($data-&gt;{'chargeperiod'}  &amp;&amp; $days_minus_grace  ) {
-        $amount =3D int($chargeable_units / $data-&gt;{'chargeperiod'}) * =
$data-&gt;{'fine'};# TODO fine calc should be in cents
&#43;        $amount =3D int($chargeable_units / $data-&gt;{'chargeperiod'}=
) * $data-&gt;{'fine'};# TODO fine calc should be in cents                 =
                                                                           =
                         =20
     } else {
-        # a zero (or null)  chargeperiod means no charge.
&#43;        # a zero (or null)  chargeperiod means no charge.             =
                                                                           =
                                                                           =
                 =20
     }
     if(C4::Context-&gt;preference('maxFine') &amp;&amp; ( $amount &gt; C4:=
:Context-&gt;preference('maxFine'))) {
         $amount =3D C4::Context-&gt;preference('maxFine');
     }
     return ($amount, $data-&gt;{chargename}, $days_minus_grace);
-    # FIXME: chargename is NEVER populated anywhere.
&#43;    # FIXME: chargename is NEVER populated anywhere.                  =
                                                                           =
                                                                           =
                =20
 }
=20
&#43;sub _get_chargeable_units {
&#43;    my ($unit, $dt1, $dt2, $branchcode) =3D @_;
&#43;    my $charge_units =3D 0;
&#43;    my $charge_duration;
&#43;    if ($unit eq 'hours') {
&#43;        if(C4::Context-&gt;preference('finesCalendar') eq 'noFinesWhen=
Closed') {
&#43;            my $calendar =3D Koha::Calendar-&gt;new( branchcode =3D&gt=
; $branchcode );
&#43;            $charge_duration =3D $calendar-&gt;hours_between( $dt1, $d=
t2 );
&#43;        } else {
&#43;            $charge_duration =3D $dt2-&gt;delta_ms( $dt1 );
&#43;        }
&#43;        if($charge_duration-&gt;in_units('hours') =3D=3D 0 &amp;&amp; =
$charge_duration-&gt;in_units('seconds') &gt; 0){
&#43;            return 1;
&#43;        }
&#43;        return $charge_duration-&gt;in_units('hours');
&#43;    }
&#43;    else { # days                                                     =
                                                                           =
                                                                           =
                 =20
&#43;        if(C4::Context-&gt;preference('finesCalendar') eq 'noFinesWhen=
Closed') {
&#43;            my $calendar =3D Koha::Calendar-&gt;new( branchcode =3D&gt=
; $branchcode );
&#43;            $charge_duration =3D $calendar-&gt;days_between( $dt1, $dt=
2 );
&#43;        } else {
&#43;            $charge_duration =3D $dt2-&gt;delta_days( $dt1 );
&#43;        }
&#43;        return $charge_duration-&gt;in_units('days');
&#43;    }
&#43;}
=20
 =3Dhead2 GetSpecialHolidays
=20
diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm
index 1e7299c..c94432f 100644
--- a/Koha/Calendar.pm
&#43;&#43;&#43; b/Koha/Calendar.pm
@@ -137,7 &#43;137,23 @@ sub addDate {
         return $base_date &#43; $add_duration;
     }
 }
-
&#43;sub hours_between {
&#43;    my ($self, $start_dt, $end_dt) =3D @_;
&#43;    my $duration =3D $end_dt-&gt;delta_ms($start_dt);
&#43;    $start_dt-&gt;truncate( to =3D&gt; 'days' );
&#43;    $end_dt-&gt;truncate( to =3D&gt; 'days' );
&#43;    # NB this is a kludge in that it assumes all days are 24 hours
&#43;    # However for hourly loans the logic should be expanded to
&#43;    # take into account open/close times then it would be a duration
&#43;    # of library open hours
&#43;    while ( DateTime-&gt;compare( $start_dt, $end_dt ) =3D=3D -1 ) {
&#43;	$start_dt-&gt;add( days =3D&gt; 1 );
&#43;	if ( $self-&gt;is_holiday($start_dt) ) {
&#43;	    $duration-&gt;subtract( hours =3D&gt; 24 );
&#43;	}
&#43;    }
&#43;    return $duration;
&#43;}
 sub is_holiday {
     my ( $self, $dt ) =3D @_;
     my $dow =3D $dt-&gt;day_of_week;
--=20
1.7.2.5
</span></pre>
</div>
<div><span class=3D"Apple-style-span" style=3D"background-color: transparen=
t; "><br>
</span></div>
</body>
</html>

--_000_CB9A750C404Ctdavisuttyleredu_--


More information about the Koha-patches mailing list