Bug 20912: (follow-up) Add hourly support
authorMartin Renvoize <martin.renvoize@ptfs-europe.com>
Wed, 30 Jan 2019 20:34:13 +0000 (20:34 +0000)
committerNick Clemens <nick@bywatersolutions.com>
Thu, 7 Mar 2019 17:29:56 +0000 (17:29 +0000)
It seemed strange to only add support for Daily loans in the feature
when Koha also support loan periods in hours. This patch adds parallel
functionaliy for hourly loan periods.

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Koha/Charges/Fees.pm
Koha/ItemType.pm
admin/itemtypes.pl
installer/data/mysql/atomicupdate/bug_20912.perl
installer/data/mysql/kohastructure.sql
koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt

index 0d94833..03cce2f 100644 (file)
@@ -22,6 +22,7 @@ use Modern::Perl;
 use Carp qw( confess );
 
 use Koha::Calendar;
+use Koha::IssuingRules;
 use Koha::DateUtils qw( dt_from_string );
 use Koha::Exceptions;
 
@@ -85,25 +86,44 @@ sub new {
 =cut
 
 sub accumulate_rentalcharge {
-    my ( $self, $params ) = @_;
+    my ( $self ) = @_;
 
     my $itemtype = Koha::ItemTypes->find( $self->item->effective_itemtype );
-    my $rentalcharge_daily = $itemtype->rentalcharge_daily;
-
-    return undef unless $rentalcharge_daily && $rentalcharge_daily > 0;
+    my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
+        {
+            categorycode => $self->patron->categorycode,
+            itemtype     => $itemtype->id,
+            branchcode   => $self->library->id
+        }
+    );
+    my $units = $issuing_rule->lengthunit;
+    my $rentalcharge_increment = ( $units eq 'days' ) ? $itemtype->rentalcharge_daily : $itemtype->rentalcharge_hourly;
+
+    return 0 unless $rentalcharge_increment && $rentalcharge_increment > 0;
 
     my $duration;
-    if ( C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed' ) {
-        my $calendar = Koha::Calendar->new( branchcode => $self->library->id );
-        $duration = $calendar->days_between( $self->from_date, $self->to_date );
+    my $calendar = Koha::Calendar->new( branchcode => $self->library->id );
+
+    if ( $units eq 'hours' ) {
+        if ( C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed' ) {
+            $duration =
+              $calendar->hours_between( $self->from_date, $self->to_date );
+        }
+        else {
+            $duration = $self->to_date->delta_ms($self->from_date);
+        }
     }
     else {
-        $duration = $self->to_date->delta_days($self->from_date);
+        if ( C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed' ) {
+            $duration =
+              $calendar->days_between( $self->from_date, $self->to_date );
+        }
+        else {
+            $duration = $self->to_date->delta_days( $self->from_date );
+        }
     }
-    my $days = $duration->in_units('days');
-
-    my $charge = $rentalcharge_daily * $days;
 
+    my $charge = $rentalcharge_increment * $duration->in_units($units);
     return $charge;
 }
 
index 31578f0..63c113c 100644 (file)
@@ -33,7 +33,7 @@ Koha::ItemType - Koha Item type Object class
 
 =head1 API
 
-=head2 Class Methods
+=head2 Class methods
 
 =cut
 
index 3381e21..441bd05 100755 (executable)
@@ -73,6 +73,7 @@ if ( $op eq 'add_form' ) {
     my $description  = $input->param('description');
     my $rentalcharge = $input->param('rentalcharge');
     my $rentalcharge_daily = $input->param('rentalcharge_daily');
+    my $rentalcharge_hourly = $input->param('rentalcharge_hourly');
     my $defaultreplacecost = $input->param('defaultreplacecost');
     my $processfee = $input->param('processfee');
     my $image = $input->param('image') || q||;
@@ -94,6 +95,7 @@ if ( $op eq 'add_form' ) {
         $itemtype->description($description);
         $itemtype->rentalcharge($rentalcharge);
         $itemtype->rentalcharge_daily($rentalcharge_daily);
+        $itemtype->rentalcharge_hourly($rentalcharge_hourly);
         $itemtype->defaultreplacecost($defaultreplacecost);
         $itemtype->processfee($processfee);
         $itemtype->notforloan($notforloan);
@@ -118,7 +120,8 @@ if ( $op eq 'add_form' ) {
                 itemtype            => $itemtype_code,
                 description         => $description,
                 rentalcharge        => $rentalcharge,
-                rentalcharge_daily => $rentalcharge_daily,
+                rentalcharge_daily  => $rentalcharge_daily,
+                rentalcharge_hourly => $rentalcharge_hourly,
                 defaultreplacecost  => $defaultreplacecost,
                 processfee          => $processfee,
                 notforloan          => $notforloan,
index 6e5f9ed..c75eed9 100644 (file)
@@ -5,6 +5,10 @@ if ( CheckVersion($DBversion) ) {
         $dbh->do("ALTER TABLE `itemtypes` ADD COLUMN `rentalcharge_daily` decimal(28,6) default NULL AFTER `rentalcharge`");
     }
 
+    if ( !column_exists( 'itemtypes', 'rentalcharge_hourly' ) ) {
+        $dbh->do("ALTER TABLE `itemtypes` ADD COLUMN `rentalcharge_hourly` decimal(28,6) default NULL AFTER `rentalcharge_daily`");
+    }
+
     if ( column_exists( 'itemtypes', 'rental_charge_daily' ) ) {
         $dbh->do("UPDATE `itemtypes` SET `rentalcharge_daily` = `rental_charge_daily`");
         $dbh->do("ALTER TABLE `itemtypes` DROP COLUMN `rental_charge_daily`");
index 8fad803..d20bc7e 100644 (file)
@@ -951,7 +951,8 @@ CREATE TABLE `itemtypes` ( -- defines the item types
   itemtype varchar(10) NOT NULL default '', -- unique key, a code associated with the item type
   description LONGTEXT, -- a plain text explanation of the item type
   rentalcharge decimal(28,6) default NULL, -- the amount charged when this item is checked out/issued
-  rentalcharge_daily decimal(28,6) default NULL, -- the amount charged for each increment (day/hour) between checkout date and due date
+  rentalcharge_daily decimal(28,6) default NULL, -- the amount charged for each day between checkout date and due date
+  rentalcharge_hourly decimal(28,6) default NULL, -- the amount charged for each hour between checkout date and due date
   defaultreplacecost decimal(28,6) default NULL, -- default replacement cost
   processfee decimal(28,6) default NULL, -- default text be recorded in the column note when the processing fee is applied
   notforloan smallint(6) default NULL, -- 1 if the item is not for loan, 0 if the item is available for loan
index 0f48e11..465010b 100644 (file)
@@ -236,7 +236,12 @@ Item types administration
                 <li>
                     <label for="rentalcharge_daily">Daily rental charge: </label>
                     <input type="text" id="rentalcharge_daily" name="rentalcharge_daily" size="10" value="[% itemtype.rentalcharge_daily | $Price %]" />
-                    <span class="hint">This fee is charged a checkout/renewal time for each day between the checkout/renewal date and due date.</span>
+                    <span class="hint">This fee is charged at checkout/renewal time for each day between the checkout/renewal date and due date for loans specified in days.</span>
+                </li>
+                <li>
+                    <label for="rentalcharge_hourly">Hourly rental charge: </label>
+                    <input type="text" id="rentalcharge_hourly" name="rentalcharge_hourly" size="10" value="[% itemtype.rentalcharge_hourly | $Price %]" />
+                    <span class="hint">This fee is charged at checkout/renewal time for each hour between the checkout/renewal date and due date for loans specifie in hours.</span>
                 </li>
                 <li>
                     <label for="defaultreplacecost">Default replacement cost: </label>
@@ -337,6 +342,7 @@ Item types administration
             <th>Hide in OPAC</th>
             <th>Rental charge</th>
             <th>Daily rental charge</th>
+            <th>Hourly rental charge</th>
             <th>Default replacement cost</th>
             <th>Processing fee (when lost)</th>
             <th>Checkin message</th>
@@ -383,6 +389,12 @@ Item types administration
               [% itemtype.rentalcharge_daily | $Price %]
             [% END %]
             </td>
+            <td>
+            [% UNLESS ( itemtype.notforloan ) %]
+              [% itemtype.rentalcharge_hourly | $Price %]
+            [% END %]
+            </td>
+
             <td>[% itemtype.defaultreplacecost | $Price %]</td>
             <td>[% itemtype.processfee | $Price %]</td>
             <td>[% itemtype.checkinmsg | html_line_break | $raw %]</td>
index afe6f0a..78c3498 100644 (file)
@@ -36,6 +36,7 @@
         [% END %]
         [% IF ( rentalcharge ) %]<li><span class="label">Rental charge:</span>[% rentalcharge | $Price %]&nbsp;</li>[% END %]
         [% IF ( rentalcharge_daily ) %]<li><span class="label">Daily rental charge:</span>[% rentalcharge_daily | $Price %]&nbsp;</li>[% END %]
+        [% IF ( rentalcharge_hourly ) %]<li><span class="label">Hourly rental charge:</span>[% rentalcharge_hourly | $Price %]&nbsp;</li>[% END %]
         <li><span class="label">ISBN:</span> [% isbn | html %]&nbsp;</li>
         <li><span class="label">Publisher:</span>[% place | html %] [% publishercode | html %] [% publicationyear | html %]&nbsp;</li>
         [% IF ( volumeddesc ) %]<li><span class="label">Volume:</span> [% volumeddesc | html %]</li>[% END %]