Fix FSF address in directory admin/
[koha.git] / C4 / ItemCirculationAlertPreference.pm
blob73f7573b014a5f7027f66891161cd6ed0d4ce57c
1 package C4::ItemCirculationAlertPreference;
3 # This file is part of Koha.
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.
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.
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
18 use strict;
19 use warnings;
20 use C4::Context;
21 use C4::Category;
22 use C4::ItemType;
23 use Carp qw(carp croak);
25 our $AUTOLOAD;
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.");
38 =head1 NAME
40 C4::ItemCirculationAlertPreference - manage preferences for sending alerts
42 =head1 SYNOPSIS
44 Basics:
46 use C4::ItemCirculationAlertPreference;
48 # a short-cut to reduce typing the long package name over and over again
49 my $preferences = 'C4::ItemCirculationAlertPreference';
51 Creating a restriction on sending messages:
53 my $pref = $preferences->create({
54 branchcode => 'CPL',
55 categorycode => 'YA',
56 item_type => 'BK',
57 notification => 'CHECKOUT',
58 });
60 Removing a restriction on sending messages:
62 $preferences->delete({
63 branchcode => 'CPL',
64 categorycode => 'YA',
65 item_type => 'BK',
66 notification => 'CHECKOUT',
67 });
69 =head1 DESCRIPTION
71 This class is used to manage the preferences for when an alert may be sent. By
72 default, item circulation alerts are enabled for every B<branch>, B<patron
73 category> and B<item type>.
75 However, if you would like to prevent item circulation alerts from being sent
76 for any combination of these 3 variables, a preference can be inserted into the
77 C<item_circulation_alert_preferences> table to make that a policy.
79 =head1 API
81 =head2 Class Methods
83 =cut
85 =head3 C4::ItemCirculationAlertPreference->new(\%opts)
87 This is a constructor for an in-memory C4::ItemCirculationAlertPreference
88 object. The database is not affected by this method.
90 =cut
92 sub new {
93 my ($class, $opts) = @_;
94 bless $opts => $class;
100 =head3 C4::ItemCirculationAlertPreference->create(\%opts)
102 This will find or create an item circulation alert preference. You must pass
103 it a B<branchcode>, B<categorycode>, B<item_type>, and B<notification>. Valid
104 values for these attributes are as follows:
106 =over 4
108 =item branchcode
110 branches.branchcode
112 =item categorycode
114 category.categorycode
116 =item item_type
118 itemtypes.itemtype
120 =item notification
122 This can be "CHECKIN" or "CHECKOUT"
124 =back
126 =cut
128 sub create {
129 my ($class, $opts) = @_;
130 $valid->($opts);
131 my $dbh = C4::Context->dbh;
132 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},
145 if (@$prefs) {
146 return $class->new($prefs->[0]);
147 } else {
148 my $success = $dbh->do(
149 "INSERT INTO item_circulation_alert_preferences
150 (branchcode, categorycode, item_type, notification) VALUES (?, ?, ?, ?)",
152 $opts->{branchcode},
153 $opts->{categorycode},
154 $opts->{item_type},
155 $opts->{notification},
157 if ($success) {
158 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},
165 return $class->new($self);
166 } else {
167 carp $dbh->errstr;
168 return undef;
176 =head3 C4::ItemCirculationAlertPreference->delete(\%opts)
178 Delete an item circulation alert preference. You can delete by either passing
179 in an B<id> or passing in a B<branchcode>, B<categorycode>, B<item_type>
180 triplet.
182 =cut
184 sub delete {
185 my ($class, $opts) = @_;
186 my $dbh = C4::Context->dbh;
187 if ($opts->{id}) {
188 $dbh->do(
189 "DELETE FROM item_circulation_alert_preferences WHERE id = ?",
191 $opts->{id}
193 } else {
194 $valid->($opts);
195 my $sql =
196 "DELETE FROM item_circulation_alert_preferences
197 WHERE branchcode = ?
198 AND categorycode = ?
199 AND item_type = ?
200 AND notification = ?";
201 $dbh->do(
202 $sql,
204 $opts->{branchcode},
205 $opts->{categorycode},
206 $opts->{item_type},
207 $opts->{notification},
215 =head3 C4::ItemCirculationAlertPreference->is_enabled_for(\%opts)
217 Based on the existing preferences in the C<item_circulation_alert_preferences>
218 table, can an alert be sent for the given B<branchcode>, B<categorycode>, and
219 B<itemtype>?
221 B<Example>:
223 my $alert = 'C4::ItemCirculationAlertPreference';
224 my $conditions = {
225 branchcode => 'CPL',
226 categorycode => 'IL',
227 item_type => 'MU',
230 if ($alert->is_enabled_for($conditions)) {
231 # ...
234 =cut
236 sub is_disabled_for {
237 my ($class, $opts) = @_;
238 $valid->($opts);
239 my $dbh = C4::Context->dbh;
241 # Does a preference exist to block this alert?
242 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 = '*')
251 my $preferences = $dbh->selectall_arrayref(
252 $query,
253 { Slice => {} },
254 $opts->{branchcode},
255 $opts->{categorycode},
256 $opts->{item_type},
257 $opts->{notification},
260 # If any preferences showed up, we are NOT enabled.
261 return @$preferences;
264 sub is_enabled_for {
265 my ($class, $opts) = @_;
266 return not $class->is_disabled_for($opts);
272 =head3 C4::ItemCirculationAlertPreference->find({ branchcode => $bc, notification => $type })
274 This method returns all the item circulation alert preferences for a given
275 branch and notification.
277 B<Example>:
279 my @branch_prefs = C4::ItemCirculationAlertPreference->find({
280 branchcode => 'CPL',
281 notification => 'CHECKIN',
284 =cut
286 sub find {
287 my ($class, $where) = @_;
288 my $dbh = C4::Context->dbh;
289 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
295 return map { $class->new($_) } @{$dbh->selectall_arrayref(
296 $query,
297 { Slice => {} },
298 $where->{branchcode},
299 $where->{notification},
306 =head3 C4::ItemCirculationAlertPreference->grid({ branchcode => $c, notification => $type })
308 Return a 2D arrayref for the grid view in F<admin/item_circulation_alert_preferences.pl>.
309 Each row represents a category (like 'Patron' or 'Young Adult') and
310 each column represents an itemtype (like 'Book' or 'Music').
312 Each cell contains...
314 B<Example>:
316 use Data::Dump 'pp';
317 my $grid = C4::ItemCirculationAlertPreference->grid({
318 branchcode => 'CPL',
319 notification => 'CHECKOUT',
321 warn pp($grid);
323 See F<admin/item_circulation_alerts.pl> to see how this method is used.
325 =cut
327 sub grid {
328 my ($class, $where) = @_;
329 my @branch_prefs = $class->find($where);
330 my @default_prefs = $class->find({ branchcode => '*', notification => $where->{notification} });
331 my @cc = C4::Category->all;
332 my @it = C4::ItemType->all;
333 my $notification = $where->{notification};
334 my %disabled = map {
335 my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification;
336 $key =~ s/\*/_/g;
337 ($key => 1);
338 } @branch_prefs;
339 my %default = map {
340 my $key = $_->categorycode . "-" . $_->item_type . "-" . $notification;
341 $key =~ s/\*/_/g;
342 ($key => 1);
343 } @default_prefs;
344 my @grid;
345 for my $c (@cc) {
346 my $row = { description => $c->description, items => [] };
347 push @grid, $row;
348 for my $i (@it) {
349 my $key = $c->categorycode . "-" . $i->itemtype . "-" . $notification;
350 $key =~ s/\*/_/g;
351 my @classes;
352 my $text = " ";
353 if ($disabled{$key}) {
354 push @classes, 'disabled';
355 $text = "Disabled for $where->{branchcode}";
357 if ($default{$key}) {
358 push @classes, 'default';
359 $text = "Disabled for all";
361 push @{$row->{items}}, {
362 class => join(' ', @classes),
363 id => $key,
364 text => $text,
368 return \@grid;
374 =head2 Object Methods
376 These are read-only accessors for the various attributes of a preference.
378 =head3 $pref->id
380 =head3 $pref->branchcode
382 =head3 $pref->categorycode
384 =head3 $pref->item_type
386 =head3 $pref->notification
388 =cut
390 sub AUTOLOAD {
391 my $self = shift;
392 my $attr = $AUTOLOAD;
393 $attr =~ s/.*://;
394 if (exists $self->{$attr}) {
395 return $self->{$attr};
396 } else {
397 return undef;
401 sub DESTROY { }
405 =head1 SEE ALSO
407 L<C4::Circulation>, F<admin/item_circulation_alerts.pl>
409 =head1 AUTHOR
411 John Beppu <john.beppu@liblime.com>
413 =cut