Bug 18736: (follow-up) Remove duplicate code and adjust tests
[koha.git] / C4 / ItemCirculationAlertPreference.pm
index df231a4..4eb263c 100644 (file)
@@ -1,31 +1,36 @@
 package C4::ItemCirculationAlertPreference;
 
+# Copyright Liblime 2009
+#
 # This file is part of Koha.
 #
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
 #
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along with
-# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-# Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use strict;
 use warnings;
 use C4::Context;
 use Carp qw(carp croak);
 
+use Koha::ItemTypes;
+use Koha::Patron::Categories;
+
 our $AUTOLOAD;
 
 # helper function for validating \%opts
 our $valid = sub {
     my $opts = shift;
-    for (qw(branchcode categorycode item_type)) {
+    for (qw(branchcode categorycode item_type notification)) {
         exists($opts->{$_}) || croak("'$_' is a required parameter.");
     }
 };
@@ -46,20 +51,22 @@ Basics:
     # a short-cut to reduce typing the long package name over and over again
     my $preferences = 'C4::ItemCirculationAlertPreference';
 
-Creating Rules:
+Creating a restriction on sending messages:
 
     my $pref = $preferences->create({
         branchcode   => 'CPL',
         categorycode => 'YA',
         item_type    => 'BK',
+        notification => 'CHECKOUT',
     });
 
-Deleting Rules:
+Removing a restriction on sending messages:
 
     $preferences->delete({
         branchcode   => 'CPL',
         categorycode => 'YA',
         item_type    => 'BK',
+        notification => 'CHECKOUT',
     });
 
 =head1 DESCRIPTION
@@ -96,7 +103,28 @@ sub new {
 =head3 C4::ItemCirculationAlertPreference->create(\%opts)
 
 This will find or create an item circulation alert preference.  You must pass
-it a B<branchcode>, B<categorycode>, and B<item_type>.
+it a B<branchcode>, B<categorycode>, B<item_type>, and B<notification>.  Valid
+values for these attributes are as follows:
+
+=over 4
+
+=item branchcode
+
+branches.branchcode
+
+=item categorycode
+
+category.categorycode
+
+=item item_type
+
+itemtypes.itemtype
+
+=item notification
+
+This can be "CHECKIN" or "CHECKOUT"
+
+=back
 
 =cut
 
@@ -109,22 +137,25 @@ sub create {
         FROM  item_circulation_alert_preferences
         WHERE branchcode   = ?
         AND   categorycode = ?
-        AND   item_type    = ?",
+        AND   item_type    = ?
+        AND   notification = ?",
         { Slice => {} },
         $opts->{branchcode},
         $opts->{categorycode},
         $opts->{item_type},
+        $opts->{notification},
     );
     if (@$prefs) {
         return $class->new($prefs->[0]);
     } else {
         my $success = $dbh->do(
             "INSERT INTO item_circulation_alert_preferences
-            (branchcode, categorycode, item_type) VALUES (?, ?, ?)",
+            (branchcode, categorycode, item_type, notification) VALUES (?, ?, ?, ?)",
             {},
             $opts->{branchcode},
             $opts->{categorycode},
             $opts->{item_type},
+            $opts->{notification},
         );
         if ($success) {
             my $self = {
@@ -132,11 +163,12 @@ sub create {
                 branchcode   => $opts->{branchcode},
                 categorycode => $opts->{categorycode},
                 item_type    => $opts->{item_type},
+                notification => $opts->{notification},
             };
             return $class->new($self);
         } else {
             carp $dbh->errstr;
-            return undef;
+            return;
         }
     }
 }
@@ -163,15 +195,19 @@ sub delete {
         );
     } else {
         $valid->($opts);
-        $dbh->do(
+        my $sql =
             "DELETE FROM item_circulation_alert_preferences
             WHERE branchcode   = ?
             AND   categorycode = ?
-            AND   item_type    = ?",
+            AND   item_type    = ?
+            AND   notification = ?";
+        $dbh->do(
+            $sql,
             {},
             $opts->{branchcode},
             $opts->{categorycode},
-            $opts->{item_type}
+            $opts->{item_type},
+            $opts->{notification},
         );
     }
 }
@@ -200,48 +236,52 @@ B<Example>:
 
 =cut
 
-sub is_enabled_for {
+sub is_disabled_for {
     my ($class, $opts) = @_;
     $valid->($opts);
     my $dbh = C4::Context->dbh;
 
     # Does a preference exist to block this alert?
     my $query = qq{
-        SELECT id
+        SELECT id, branchcode, categorycode, item_type, notification
           FROM item_circulation_alert_preferences
          WHERE (branchcode   = ? OR branchcode   = '*')
            AND (categorycode = ? OR categorycode = '*')
            AND (item_type    = ? OR item_type    = '*')
+           AND (notification = ? OR notification = '*')
     };
 
     my $preferences = $dbh->selectall_arrayref(
         $query,
-        { },
+        { Slice => {} },
         $opts->{branchcode},
         $opts->{categorycode},
         $opts->{item_type},
+        $opts->{notification},
     );
 
     # If any preferences showed up, we are NOT enabled.
-    if (@$preferences) {
-        return undef;
-    } else {
-        return 1;
-    }
+    return @$preferences;
+}
+
+sub is_enabled_for {
+    my ($class, $opts) = @_;
+    return not $class->is_disabled_for($opts);
 }
 
 
 
 
-=head3 C4::ItemCirculationAlertPreference->find({ branchcode => $bc })
+=head3 C4::ItemCirculationAlertPreference->find({ branchcode => $bc, notification => $type })
 
 This method returns all the item circulation alert preferences for a given
-branch.
+branch and notification.
 
 B<Example>:
 
     my @branch_prefs = C4::ItemCirculationAlertPreference->find({
-        branchcode => 'CPL',
+        branchcode   => 'CPL',
+        notification => 'CHECKIN',
     });
 
 =cut
@@ -250,35 +290,114 @@ sub find {
     my ($class, $where) = @_;
     my $dbh = C4::Context->dbh;
     my $query = qq{
-        SELECT id, branchcode, categorycode, item_type
+        SELECT id, branchcode, categorycode, item_type, notification
           FROM item_circulation_alert_preferences
-         WHERE branchcode = ?
+         WHERE branchcode = ? AND notification = ?
          ORDER BY categorycode, item_type
     };
     return    map { $class->new($_) }    @{$dbh->selectall_arrayref(
         $query,
         { Slice => {} },
-        $where->{branchcode}
+        $where->{branchcode},
+        $where->{notification},
     )};
 }
 
 
 
 
+=head3 C4::ItemCirculationAlertPreference->grid({ branchcode => $c, notification => $type })
+
+Return a 2D arrayref for the grid view in F<admin/item_circulation_alert_preferences.pl>.
+Each row represents a category (like 'Patron' or 'Young Adult') and
+each column represents an itemtype (like 'Book' or 'Music').
+
+Each cell contains...
+
+B<Example>:
+
+    use Data::Dump 'pp';
+    my $grid = C4::ItemCirculationAlertPreference->grid({
+        branchcode   => 'CPL',
+        notification => 'CHECKOUT',
+    });
+    warn pp($grid);
+
+See F<admin/item_circulation_alerts.pl> to see how this method is used.
+
+=cut
+
+sub grid {
+    my ($class, $where) = @_;
+    my @branch_prefs = $class->find($where);
+    my @default_prefs = $class->find({ branchcode => '*', notification => $where->{notification} });
+    my @cc = Koha::Patron::Categories->search_limited;
+    my @it = Koha::ItemTypes->search;
+    my $notification = $where->{notification};
+    my %disabled = map {
+        my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification;
+        $key =~ s/\*/_/g;
+        ($key => 1);
+    } @branch_prefs;
+    my %default = map {
+        my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification;
+        $key =~ s/\*/_/g;
+        ($key => 1);
+    } @default_prefs;
+    my @grid;
+    for my $c (@cc) {
+        my $row = { description => $c->description, items => [] };
+        push @grid, $row;
+        for my $i (@it) {
+            my $key = $c->categorycode . "-" . $i->itemtype . "-" . $notification;
+            $key =~ s/\*/_/g;
+            my @classes;
+            my $text = " ";
+            if ($disabled{$key}) {
+                push @classes, 'disabled';
+                $text = "Disabled for $where->{branchcode}";
+            }
+            if ($default{$key}) {
+                push @classes, 'default';
+                $text = "Disabled for all";
+            }
+            push @{$row->{items}}, {
+                class => join(' ', @classes),
+                id    => $key,
+                text  => $text,
+            };
+        }
+    }
+    return \@grid;
+}
+
+
+
+
 =head2 Object Methods
 
 These are read-only accessors for the various attributes of a preference.
 
 =head3 $pref->id
 
+=cut
+
 =head3 $pref->branchcode
 
+=cut
+
 =head3 $pref->categorycode
 
+=cut
+
 =head3 $pref->item_type
 
 =cut
 
+=head3 $pref->notification
+
+=cut
+
 sub AUTOLOAD {
     my $self = shift;
     my $attr = $AUTOLOAD;
@@ -286,16 +405,17 @@ sub AUTOLOAD {
     if (exists $self->{$attr}) {
         return $self->{$attr};
     } else {
-        return undef;
+        return;
     }
 }
 
+sub DESTROY { }
 
 
 
 =head1 SEE ALSO
 
-L<C4::Circulation>, C<admin/item_circulation_alerts.pl>
+L<C4::Circulation>, F<admin/item_circulation_alerts.pl>
 
 =head1 AUTHOR
 
@@ -304,14 +424,3 @@ John Beppu <john.beppu@liblime.com>
 =cut
 
 1;
-
-# Local Variables: ***
-# mode: cperl ***
-# indent-tabs-mode: nil ***
-# cperl-close-paren-offset: -4 ***
-# cperl-continued-statement-offset: 4 ***
-# cperl-indent-level: 4 ***
-# cperl-indent-parens-as-block: t ***
-# cperl-tab-always-indent: nil ***
-# End: ***
-# vim:tabstop=8 softtabstop=4 shiftwidth=4 shiftround expandtab