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; |