| File: | C4/ItemCirculationAlertPreference.pm |
| Coverage: | 20.2% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package C4::ItemCirculationAlertPreference; | |||||
| 2 | ||||||
| 3 | # This file is part of Koha. | |||||
| 4 | # | |||||
| 5 | # Koha is free software; you can redistribute it and/or modify it under the | |||||
| 6 | # terms of the GNU General Public License as published by the Free Software | |||||
| 7 | # Foundation; either version 2 of the License, or (at your option) any later | |||||
| 8 | # version. | |||||
| 9 | # | |||||
| 10 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| 11 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| 12 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| 13 | # | |||||
| 14 | # You should have received a copy of the GNU General Public License along with | |||||
| 15 | # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, | |||||
| 16 | # Suite 330, Boston, MA 02111-1307 USA | |||||
| 17 | ||||||
| 18 | 15 15 15 | 458 43 689 | use strict; | |||
| 19 | 15 15 15 | 107 43 754 | use warnings; | |||
| 20 | 15 15 15 | 293 42 220 | use C4::Context; | |||
| 21 | 15 15 15 | 2952 97 512 | use C4::Category; | |||
| 22 | 15 15 15 | 2234 56 590 | use C4::ItemType; | |||
| 23 | 15 15 15 | 182 70 23009 | use Carp qw(carp croak); | |||
| 24 | ||||||
| 25 | our $AUTOLOAD; | |||||
| 26 | ||||||
| 27 | # helper function for validating \%opts | |||||
| 28 | our $valid = sub { | |||||
| 29 | my $opts = shift; | |||||
| 30 | for (qw(branchcode categorycode item_type notification)) { | |||||
| 31 | exists($opts->{$_}) || croak("'$_' is a required parameter."); | |||||
| 32 | } | |||||
| 33 | }; | |||||
| 34 | ||||||
| 35 | ||||||
| 36 | ||||||
| 37 | ||||||
| 38 - 83 | =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 | |||||
| 84 | ||||||
| 85 - 90 | =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 | |||||
| 91 | ||||||
| 92 | sub new { | |||||
| 93 | 0 | my ($class, $opts) = @_; | ||||
| 94 | 0 | bless $opts => $class; | ||||
| 95 | } | |||||
| 96 | ||||||
| 97 | ||||||
| 98 | ||||||
| 99 | ||||||
| 100 - 126 | =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 | |||||
| 127 | ||||||
| 128 | sub create { | |||||
| 129 | 0 | my ($class, $opts) = @_; | ||||
| 130 | 0 | $valid->($opts); | ||||
| 131 | 0 | my $dbh = C4::Context->dbh; | ||||
| 132 | 0 | my $prefs = $dbh->selectall_arrayref( | ||||
| 133 | "SELECT id, branchcode, categorycode, item_type | |||||
| 134 | FROM item_circulation_alert_preferences | |||||
| 135 | WHERE branchcode = ? | |||||
| 136 | AND categorycode = ? | |||||
| 137 | AND item_type = ? | |||||
| 138 | AND notification = ?", | |||||
| 139 | { Slice => {} }, | |||||
| 140 | $opts->{branchcode}, | |||||
| 141 | $opts->{categorycode}, | |||||
| 142 | $opts->{item_type}, | |||||
| 143 | $opts->{notification}, | |||||
| 144 | ); | |||||
| 145 | 0 | if (@$prefs) { | ||||
| 146 | 0 | return $class->new($prefs->[0]); | ||||
| 147 | } else { | |||||
| 148 | 0 | my $success = $dbh->do( | ||||
| 149 | "INSERT INTO item_circulation_alert_preferences | |||||
| 150 | (branchcode, categorycode, item_type, notification) VALUES (?, ?, ?, ?)", | |||||
| 151 | {}, | |||||
| 152 | $opts->{branchcode}, | |||||
| 153 | $opts->{categorycode}, | |||||
| 154 | $opts->{item_type}, | |||||
| 155 | $opts->{notification}, | |||||
| 156 | ); | |||||
| 157 | 0 | if ($success) { | ||||
| 158 | 0 | my $self = { | ||||
| 159 | id => $dbh->last_insert_id(undef, undef, undef, undef), | |||||
| 160 | branchcode => $opts->{branchcode}, | |||||
| 161 | categorycode => $opts->{categorycode}, | |||||
| 162 | item_type => $opts->{item_type}, | |||||
| 163 | notification => $opts->{notification}, | |||||
| 164 | }; | |||||
| 165 | 0 | return $class->new($self); | ||||
| 166 | } else { | |||||
| 167 | 0 | carp $dbh->errstr; | ||||
| 168 | 0 | return undef; | ||||
| 169 | } | |||||
| 170 | } | |||||
| 171 | } | |||||
| 172 | ||||||
| 173 | ||||||
| 174 | ||||||
| 175 | ||||||
| 176 - 182 | =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 | |||||
| 183 | ||||||
| 184 | sub delete { | |||||
| 185 | 0 | my ($class, $opts) = @_; | ||||
| 186 | 0 | my $dbh = C4::Context->dbh; | ||||
| 187 | 0 | if ($opts->{id}) { | ||||
| 188 | 0 | $dbh->do( | ||||
| 189 | "DELETE FROM item_circulation_alert_preferences WHERE id = ?", | |||||
| 190 | {}, | |||||
| 191 | $opts->{id} | |||||
| 192 | ); | |||||
| 193 | } else { | |||||
| 194 | 0 | $valid->($opts); | ||||
| 195 | 0 | my $sql = | ||||
| 196 | "DELETE FROM item_circulation_alert_preferences | |||||
| 197 | WHERE branchcode = ? | |||||
| 198 | AND categorycode = ? | |||||
| 199 | AND item_type = ? | |||||
| 200 | AND notification = ?"; | |||||
| 201 | 0 | $dbh->do( | ||||
| 202 | $sql, | |||||
| 203 | {}, | |||||
| 204 | $opts->{branchcode}, | |||||
| 205 | $opts->{categorycode}, | |||||
| 206 | $opts->{item_type}, | |||||
| 207 | $opts->{notification}, | |||||
| 208 | ); | |||||
| 209 | } | |||||
| 210 | } | |||||
| 211 | ||||||
| 212 | ||||||
| 213 | ||||||
| 214 | ||||||
| 215 - 234 | =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 | |||||
| 235 | ||||||
| 236 | sub is_disabled_for { | |||||
| 237 | 0 | my ($class, $opts) = @_; | ||||
| 238 | 0 | $valid->($opts); | ||||
| 239 | 0 | my $dbh = C4::Context->dbh; | ||||
| 240 | ||||||
| 241 | # Does a preference exist to block this alert? | |||||
| 242 | 0 | my $query = qq{ | ||||
| 243 | SELECT id, branchcode, categorycode, item_type, notification | |||||
| 244 | FROM item_circulation_alert_preferences | |||||
| 245 | WHERE (branchcode = ? OR branchcode = '*') | |||||
| 246 | AND (categorycode = ? OR categorycode = '*') | |||||
| 247 | AND (item_type = ? OR item_type = '*') | |||||
| 248 | AND (notification = ? OR notification = '*') | |||||
| 249 | }; | |||||
| 250 | ||||||
| 251 | 0 | my $preferences = $dbh->selectall_arrayref( | ||||
| 252 | $query, | |||||
| 253 | { Slice => {} }, | |||||
| 254 | $opts->{branchcode}, | |||||
| 255 | $opts->{categorycode}, | |||||
| 256 | $opts->{item_type}, | |||||
| 257 | $opts->{notification}, | |||||
| 258 | ); | |||||
| 259 | ||||||
| 260 | # If any preferences showed up, we are NOT enabled. | |||||
| 261 | 0 | return @$preferences; | ||||
| 262 | } | |||||
| 263 | ||||||
| 264 | sub is_enabled_for { | |||||
| 265 | 0 | my ($class, $opts) = @_; | ||||
| 266 | 0 | return not $class->is_disabled_for($opts); | ||||
| 267 | } | |||||
| 268 | ||||||
| 269 | ||||||
| 270 | ||||||
| 271 | ||||||
| 272 - 284 | =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 | |||||
| 285 | ||||||
| 286 | sub find { | |||||
| 287 | 0 | my ($class, $where) = @_; | ||||
| 288 | 0 | my $dbh = C4::Context->dbh; | ||||
| 289 | 0 | my $query = qq{ | ||||
| 290 | SELECT id, branchcode, categorycode, item_type, notification | |||||
| 291 | FROM item_circulation_alert_preferences | |||||
| 292 | WHERE branchcode = ? AND notification = ? | |||||
| 293 | ORDER BY categorycode, item_type | |||||
| 294 | }; | |||||
| 295 | 0 0 0 | return map { $class->new($_) } @{$dbh->selectall_arrayref( | ||||
| 296 | $query, | |||||
| 297 | { Slice => {} }, | |||||
| 298 | $where->{branchcode}, | |||||
| 299 | $where->{notification}, | |||||
| 300 | )}; | |||||
| 301 | } | |||||
| 302 | ||||||
| 303 | ||||||
| 304 | ||||||
| 305 | ||||||
| 306 - 325 | =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 | |||||
| 326 | ||||||
| 327 | sub grid { | |||||
| 328 | 0 | my ($class, $where) = @_; | ||||
| 329 | 0 | my @branch_prefs = $class->find($where); | ||||
| 330 | 0 | my @default_prefs = $class->find({ branchcode => '*', notification => $where->{notification} }); | ||||
| 331 | 0 | my @cc = C4::Category->all; | ||||
| 332 | 0 | my @it = C4::ItemType->all; | ||||
| 333 | 0 | my $notification = $where->{notification}; | ||||
| 334 | 0 | my %disabled = map { | ||||
| 335 | 0 | my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification; | ||||
| 336 | 0 | $key =~ s/\*/_/g; | ||||
| 337 | 0 | ($key => 1); | ||||
| 338 | } @branch_prefs; | |||||
| 339 | 0 | my %default = map { | ||||
| 340 | 0 | my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification; | ||||
| 341 | 0 | $key =~ s/\*/_/g; | ||||
| 342 | 0 | ($key => 1); | ||||
| 343 | } @default_prefs; | |||||
| 344 | 0 | my @grid; | ||||
| 345 | 0 | for my $c (@cc) { | ||||
| 346 | 0 | my $row = { description => $c->description, items => [] }; | ||||
| 347 | 0 | push @grid, $row; | ||||
| 348 | 0 | for my $i (@it) { | ||||
| 349 | 0 | my $key = $c->categorycode . "-" . $i->itemtype . "-" . $notification; | ||||
| 350 | 0 | $key =~ s/\*/_/g; | ||||
| 351 | 0 | my @classes; | ||||
| 352 | 0 | my $text = " "; | ||||
| 353 | 0 | if ($disabled{$key}) { | ||||
| 354 | 0 | push @classes, 'disabled'; | ||||
| 355 | 0 | $text = "Disabled for $where->{branchcode}"; | ||||
| 356 | } | |||||
| 357 | 0 | if ($default{$key}) { | ||||
| 358 | 0 | push @classes, 'default'; | ||||
| 359 | 0 | $text = "Disabled for all"; | ||||
| 360 | } | |||||
| 361 | 0 0 | push @{$row->{items}}, { | ||||
| 362 | class => join(' ', @classes), | |||||
| 363 | id => $key, | |||||
| 364 | text => $text, | |||||
| 365 | }; | |||||
| 366 | } | |||||
| 367 | } | |||||
| 368 | 0 | return \@grid; | ||||
| 369 | } | |||||
| 370 | ||||||
| 371 | ||||||
| 372 | ||||||
| 373 | ||||||
| 374 - 380 | =head2 Object Methods These are read-only accessors for the various attributes of a preference. =head3 $pref->id =cut | |||||
| 381 | ||||||
| 382 - 384 | =head3 $pref->branchcode =cut | |||||
| 385 | ||||||
| 386 - 388 | =head3 $pref->categorycode =cut | |||||
| 389 | ||||||
| 390 - 392 | =head3 $pref->item_type =cut | |||||
| 393 | ||||||
| 394 - 396 | =head3 $pref->notification =cut | |||||
| 397 | ||||||
| 398 | sub AUTOLOAD { | |||||
| 399 | 0 | my $self = shift; | ||||
| 400 | 0 | my $attr = $AUTOLOAD; | ||||
| 401 | 0 | $attr =~ s/.*://; | ||||
| 402 | 0 | if (exists $self->{$attr}) { | ||||
| 403 | 0 | return $self->{$attr}; | ||||
| 404 | } else { | |||||
| 405 | 0 | return undef; | ||||
| 406 | } | |||||
| 407 | } | |||||
| 408 | ||||||
| 409 | 0 | sub DESTROY { } | ||||
| 410 | ||||||
| 411 | ||||||
| 412 | ||||||
| 413 - 421 | =head1 SEE ALSO L<C4::Circulation>, F<admin/item_circulation_alerts.pl> =head1 AUTHOR John Beppu <john.beppu@liblime.com> =cut | |||||
| 422 | ||||||
| 423 | 1; | |||||