Koha/C4/ItemCirculationAlertPreference.pm
Jonathan Druart e53667105d Bug 29844: Fix ->search occurrences
and some more...

There are lot of inconsistencies in our ->search calls. We could
simplify some of them, but not in this patch. Here we want to prevent
regressions as much as possible and so don't add unecessary changes.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
2022-02-09 15:36:23 -10:00

426 lines
10 KiB
Perl

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 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.
#
# 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 notification)) {
exists($opts->{$_}) || croak("'$_' is a required parameter.");
}
};
=head1 NAME
C4::ItemCirculationAlertPreference - manage preferences for sending alerts
=head1 SYNOPSIS
Basics:
use C4::ItemCirculationAlertPreference;
# a short-cut to reduce typing the long package name over and over again
my $preferences = 'C4::ItemCirculationAlertPreference';
Creating a restriction on sending messages:
my $pref = $preferences->create({
branchcode => 'CPL',
categorycode => 'YA',
item_type => 'BK',
notification => 'CHECKOUT',
});
Removing a restriction on sending messages:
$preferences->delete({
branchcode => 'CPL',
categorycode => 'YA',
item_type => 'BK',
notification => 'CHECKOUT',
});
=head1 DESCRIPTION
This class is used to manage the preferences for when an alert may be sent. By
default, item circulation alerts are enabled for every B<branch>, B<patron
category> and B<item type>.
However, if you would like to prevent item circulation alerts from being sent
for any combination of these 3 variables, a preference can be inserted into the
C<item_circulation_alert_preferences> table to make that a policy.
=head1 API
=head2 Class Methods
=cut
=head3 C4::ItemCirculationAlertPreference->new(\%opts)
This is a constructor for an in-memory C4::ItemCirculationAlertPreference
object. The database is not affected by this method.
=cut
sub new {
my ($class, $opts) = @_;
bless $opts => $class;
}
=head3 C4::ItemCirculationAlertPreference->create(\%opts)
This will find or create an item circulation alert preference. You must pass
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
sub create {
my ($class, $opts) = @_;
$valid->($opts);
my $dbh = C4::Context->dbh;
my $prefs = $dbh->selectall_arrayref(
"SELECT id, branchcode, categorycode, item_type
FROM item_circulation_alert_preferences
WHERE branchcode = ?
AND categorycode = ?
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, notification) VALUES (?, ?, ?, ?)",
{},
$opts->{branchcode},
$opts->{categorycode},
$opts->{item_type},
$opts->{notification},
);
if ($success) {
my $self = {
id => $dbh->last_insert_id(undef, undef, undef, undef),
branchcode => $opts->{branchcode},
categorycode => $opts->{categorycode},
item_type => $opts->{item_type},
notification => $opts->{notification},
};
return $class->new($self);
} else {
carp $dbh->errstr;
return;
}
}
}
=head3 C4::ItemCirculationAlertPreference->delete(\%opts)
Delete an item circulation alert preference. You can delete by either passing
in an B<id> or passing in a B<branchcode>, B<categorycode>, B<item_type>
triplet.
=cut
sub delete {
my ($class, $opts) = @_;
my $dbh = C4::Context->dbh;
if ($opts->{id}) {
$dbh->do(
"DELETE FROM item_circulation_alert_preferences WHERE id = ?",
{},
$opts->{id}
);
} else {
$valid->($opts);
my $sql =
"DELETE FROM item_circulation_alert_preferences
WHERE branchcode = ?
AND categorycode = ?
AND item_type = ?
AND notification = ?";
$dbh->do(
$sql,
{},
$opts->{branchcode},
$opts->{categorycode},
$opts->{item_type},
$opts->{notification},
);
}
}
=head3 C4::ItemCirculationAlertPreference->is_enabled_for(\%opts)
Based on the existing preferences in the C<item_circulation_alert_preferences>
table, can an alert be sent for the given B<branchcode>, B<categorycode>, and
B<itemtype>?
B<Example>:
my $alert = 'C4::ItemCirculationAlertPreference';
my $conditions = {
branchcode => 'CPL',
categorycode => 'IL',
item_type => 'MU',
};
if ($alert->is_enabled_for($conditions)) {
# ...
}
=cut
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, 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.
return @$preferences;
}
sub is_enabled_for {
my ($class, $opts) = @_;
return not $class->is_disabled_for($opts);
}
=head3 C4::ItemCirculationAlertPreference->find({ branchcode => $bc, notification => $type })
This method returns all the item circulation alert preferences for a given
branch and notification.
B<Example>:
my @branch_prefs = C4::ItemCirculationAlertPreference->find({
branchcode => 'CPL',
notification => 'CHECKIN',
});
=cut
sub find {
my ($class, $where) = @_;
my $dbh = C4::Context->dbh;
my $query = qq{
SELECT id, branchcode, categorycode, item_type, notification
FROM item_circulation_alert_preferences
WHERE branchcode = ? AND notification = ?
ORDER BY categorycode, item_type
};
return map { $class->new($_) } @{$dbh->selectall_arrayref(
$query,
{ Slice => {} },
$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_with_library_limits->as_list;
my @it = Koha::ItemTypes->search->as_list;
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;
$attr =~ s/.*://;
if (exists $self->{$attr}) {
return $self->{$attr};
} else {
return;
}
}
sub DESTROY { }
=head1 SEE ALSO
L<C4::Circulation>, F<admin/item_circulation_alerts.pl>
=head1 AUTHOR
John Beppu <john.beppu@liblime.com>
=cut
1;