From 4a7c4f3395fd910b026d05f4ed2c8a736e045cdb Mon Sep 17 00:00:00 2001 From: Elliott Davis 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