Bug 5549 followup: fix suspension in days further
authorIan Walls <koha.sekjal@gmail.com>
Thu, 22 Mar 2012 21:06:21 +0000 (17:06 -0400)
committerPaul Poulain <paul.poulain@biblibre.com>
Mon, 14 May 2012 16:15:54 +0000 (18:15 +0200)
Grace periods are now measured in the same unit as the loan.

Suspension in days works explicitly in days, independent of unit.  Since
the 'deltadays' duration is actually the duration, possibly in hours, between
when the material was due and when it's returned, we need to take the finedays
factor (how many days per unit overdue) and multiple it by 24 if the unit is
hourly.

Example: a 1 hour loan material with 1 hour grace period and finedays = 2,
returned 2 hours late would give 4 days suspension

To test:
1.  create some circ rules:
  A) an hourly loan rule with suspension in days
  B) an hourly loan rule with suspension in days and a grace period
  C) a daily loan rule with suspension in days
  D) a daily loan rule with suspension in days and a grace period
2.  Check out 2 materials under each rule.  We'll call these A1-D1
and A2-D2 (to associate with the rule)
3.  Return A1-D1 late, but within the grace period for B1 and D1 as appropriate
4.  Return A2-D2 late, after the grace periods

You should get:

A1: suspended for (#hours late) * (#suspensionindays) days
B1: not suspended
C1: suspended for (#days late) * (#suspensionindays) days
D1: not suspended

A2: suspended for (#hours late) * (#suspensionindays) days
B2: suspended for (#hours late) * (#suspensionindays) days
C2: suspended for (#days late) * (#suspensionindays) days
D2: suspended for (#days late) * (#suspensionindays) days

Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz>
Signed-off-by: Paul Poulain <paul.poulain@biblibre.com>
C4/Circulation.pm

index 3742ec7..4902c13 100644 (file)
@@ -1826,10 +1826,16 @@ sub _FixFineDaysOnReturn {
     my $circcontrol = C4::Context::preference('CircControl');
     my $issuingrule = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode );
     my $finedays    = $issuingrule->{finedays};
+    my $unit        = $issuingrule->{lengthunit};
 
     # exit if no finedays defined
     return unless $finedays;
-    my $grace = DateTime::Duration->new( days => $issuingrule->{firstremind} );
+    # finedays is in days, so hourly loans must multiply by 24
+    # thus 1 hour late equals 1 day suspension * finedays rate
+    $finedays       = $finedays * 24 if ($unit eq 'hours');
+
+    # grace period is measured in the same units as the loan
+    my $grace = DateTime::Duration->new( $unit => $issuingrule->{firstremind} );
 
     if ( ( $deltadays - $grace )->is_positive ) { # you can't compare DateTime::Durations with logical operators
         my $new_debar_dt = $dt_today->clone()->add_duration( $deltadays * $finedays );