@@ -, +, @@ --- C4/Overdues.pm | 44 +++++++++++++++++++++++++++----------------- Koha/Calendar.pm | 23 ++++++++++++++++++++--- 2 files changed, 47 insertions(+), 20 deletions(-) --- a/C4/Overdues.pm +++ a/C4/Overdues.pm @@ -226,28 +226,14 @@ 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; - } - # 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 } else { @@ -260,6 +246,30 @@ sub CalcFine { # 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 ); + } + 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 --- a/Koha/Calendar.pm +++ a/Koha/Calendar.pm @@ -167,11 +167,9 @@ sub days_between { my $self = shift; my $start_dt = shift; my $end_dt = shift; - $start_dt->truncate( to => 'hours' ); - $end_dt->truncate( to => 'hours' ); # start and end should not be closed days - my $duration = $end_dt - $start_dt; + my $duration = $end_dt->delta_days($start_dt); $start_dt->truncate( to => 'days' ); $end_dt->truncate( to => 'days' ); while ( DateTime->compare( $start_dt, $end_dt ) == -1 ) { @@ -184,6 +182,25 @@ sub days_between { } +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 _mockinit { my $self = shift; $self->{weekly_closed_days} = [ 1, 0, 0, 0, 0, 0, 0 ]; # Sunday only --