Lines 1-475
Link Here
|
1 |
package C4::Members::AttributeTypes; |
|
|
2 |
|
3 |
# Copyright (C) 2008 LibLime |
4 |
# |
5 |
# This file is part of Koha. |
6 |
# |
7 |
# Koha is free software; you can redistribute it and/or modify it |
8 |
# under the terms of the GNU General Public License as published by |
9 |
# the Free Software Foundation; either version 3 of the License, or |
10 |
# (at your option) any later version. |
11 |
# |
12 |
# Koha is distributed in the hope that it will be useful, but |
13 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
# GNU General Public License for more details. |
16 |
# |
17 |
# You should have received a copy of the GNU General Public License |
18 |
# along with Koha; if not, see <http://www.gnu.org/licenses>. |
19 |
|
20 |
use Modern::Perl; |
21 |
use C4::Context; |
22 |
|
23 |
|
24 |
|
25 |
=head1 NAME |
26 |
|
27 |
C4::Members::AttributeTypes - mananage extended patron attribute types |
28 |
|
29 |
=head1 SYNOPSIS |
30 |
|
31 |
my $attr_type = C4::Members::AttributeTypes->new($code, $description); |
32 |
$attr_type->code($code); |
33 |
$attr_type->description($description); |
34 |
$attr_type->repeatable($repeatable); |
35 |
$attr_type->unique_id($unique_id); |
36 |
$attr_type->opac_display($opac_display); |
37 |
$attr_type->opac_editable($opac_editable); |
38 |
$attr_type->staff_searchable($staff_searchable); |
39 |
$attr_type->authorised_value_category($authorised_value_category); |
40 |
$attr_type->store(); |
41 |
$attr_type->delete(); |
42 |
|
43 |
my $attr_type = C4::Members::AttributeTypes->fetch($code); |
44 |
$attr_type = C4::Members::AttributeTypes->delete($code); |
45 |
|
46 |
=head1 FUNCTIONS |
47 |
|
48 |
=head1 METHODS |
49 |
|
50 |
my $attr_type = C4::Members::AttributeTypes->new($code, $description); |
51 |
|
52 |
Create a new attribute type. |
53 |
|
54 |
=cut |
55 |
|
56 |
sub new { |
57 |
my $class = shift; |
58 |
my $self = {}; |
59 |
|
60 |
$self->{'code'} = shift; |
61 |
$self->{'description'} = shift; |
62 |
$self->{'repeatable'} = 0; |
63 |
$self->{'unique_id'} = 0; |
64 |
$self->{'opac_display'} = 0; |
65 |
$self->{'opac_editable'} = 0; |
66 |
$self->{'staff_searchable'} = 0; |
67 |
$self->{'display_checkout'} = 0; |
68 |
$self->{'authorised_value_category'} = ''; |
69 |
$self->{'category_code'} = ''; |
70 |
$self->{'category_description'} = ''; |
71 |
$self->{'class'} = ''; |
72 |
|
73 |
bless $self, $class; |
74 |
return $self; |
75 |
} |
76 |
|
77 |
=head2 fetch |
78 |
|
79 |
my $attr_type = C4::Members::AttributeTypes->fetch($code); |
80 |
|
81 |
Fetches an attribute type from the database. If no |
82 |
type with the given C<$code> exists, returns undef. |
83 |
|
84 |
=cut |
85 |
|
86 |
sub fetch { |
87 |
my $class = shift; |
88 |
my $code = shift; |
89 |
my $self = {}; |
90 |
my $dbh = C4::Context->dbh(); |
91 |
|
92 |
my $sth = $dbh->prepare_cached(" |
93 |
SELECT borrower_attribute_types.*, categories.description AS category_description |
94 |
FROM borrower_attribute_types |
95 |
LEFT JOIN categories ON borrower_attribute_types.category_code=categories.categorycode |
96 |
WHERE code =?"); |
97 |
$sth->execute($code); |
98 |
my $row = $sth->fetchrow_hashref; |
99 |
$sth->finish(); |
100 |
return unless defined $row; |
101 |
|
102 |
$self->{'code'} = $row->{'code'}; |
103 |
$self->{'description'} = $row->{'description'}; |
104 |
$self->{'repeatable'} = $row->{'repeatable'}; |
105 |
$self->{'unique_id'} = $row->{'unique_id'}; |
106 |
$self->{'opac_display'} = $row->{'opac_display'}; |
107 |
$self->{'opac_editable'} = $row->{'opac_editable'}; |
108 |
$self->{'staff_searchable'} = $row->{'staff_searchable'}; |
109 |
$self->{'display_checkout'} = $row->{'display_checkout'}; |
110 |
$self->{'authorised_value_category'} = $row->{'authorised_value_category'}; |
111 |
$self->{'category_code'} = $row->{'category_code'}; |
112 |
$self->{'category_description'} = $row->{'category_description'}; |
113 |
$self->{'class'} = $row->{'class'}; |
114 |
|
115 |
$sth = $dbh->prepare("SELECT branchcode, branchname FROM borrower_attribute_types_branches, branches WHERE b_branchcode = branchcode AND bat_code = ?;"); |
116 |
$sth->execute( $code ); |
117 |
while ( my $data = $sth->fetchrow_hashref ) { |
118 |
push @{ $self->{branches} }, $data; |
119 |
} |
120 |
$sth->finish(); |
121 |
|
122 |
bless $self, $class; |
123 |
return $self; |
124 |
} |
125 |
|
126 |
=head2 store |
127 |
|
128 |
$attr_type->store(); |
129 |
|
130 |
Stores attribute type in the database. If the type |
131 |
previously retrieved from the database via the fetch() |
132 |
method, the DB representation of the type is replaced. |
133 |
|
134 |
=cut |
135 |
|
136 |
sub store { |
137 |
my $self = shift; |
138 |
|
139 |
my $dbh = C4::Context->dbh; |
140 |
my $sth; |
141 |
my $existing = __PACKAGE__->fetch($self->{'code'}); |
142 |
if (defined $existing) { |
143 |
$sth = $dbh->prepare_cached("UPDATE borrower_attribute_types |
144 |
SET description = ?, |
145 |
repeatable = ?, |
146 |
unique_id = ?, |
147 |
opac_display = ?, |
148 |
opac_editable = ?, |
149 |
staff_searchable = ?, |
150 |
authorised_value_category = ?, |
151 |
display_checkout = ?, |
152 |
category_code = ?, |
153 |
class = ? |
154 |
WHERE code = ?"); |
155 |
} else { |
156 |
$sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types |
157 |
( description, |
158 |
repeatable, |
159 |
unique_id, |
160 |
opac_display, |
161 |
opac_editable, |
162 |
staff_searchable, |
163 |
authorised_value_category, |
164 |
display_checkout, |
165 |
category_code, |
166 |
class, |
167 |
code |
168 |
) |
169 |
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); |
170 |
} |
171 |
|
172 |
$sth->execute( |
173 |
$self->{'description'}, |
174 |
$self->{'repeatable'}, |
175 |
$self->{'unique_id'}, |
176 |
$self->{'opac_display'}, |
177 |
$self->{'opac_editable'}, |
178 |
$self->{'staff_searchable'} || 0, |
179 |
$self->{'authorised_value_category'}, |
180 |
$self->{'display_checkout'}, |
181 |
$self->{'category_code'} || undef, |
182 |
$self->{'class'}, |
183 |
$self->{'code'} |
184 |
); |
185 |
|
186 |
if ( defined $$self{branches} ) { |
187 |
$sth = $dbh->prepare("DELETE FROM borrower_attribute_types_branches WHERE bat_code = ?"); |
188 |
$sth->execute( $$self{code} ); |
189 |
$sth = $dbh->prepare( |
190 |
"INSERT INTO borrower_attribute_types_branches |
191 |
( bat_code, b_branchcode ) |
192 |
VALUES ( ?, ? )" |
193 |
); |
194 |
for my $branchcode ( @{$$self{branches}} ) { |
195 |
next if not $branchcode; |
196 |
$sth->bind_param( 1, $$self{code} ); |
197 |
$sth->bind_param( 2, $branchcode ); |
198 |
$sth->execute; |
199 |
} |
200 |
} |
201 |
$sth->finish; |
202 |
} |
203 |
|
204 |
=head2 code |
205 |
|
206 |
my $code = $attr_type->code(); |
207 |
$attr_type->code($code); |
208 |
|
209 |
Accessor. Note that the code is immutable once |
210 |
a type is created or fetched from the database. |
211 |
|
212 |
=cut |
213 |
|
214 |
sub code { |
215 |
my $self = shift; |
216 |
return $self->{'code'}; |
217 |
} |
218 |
|
219 |
=head2 description |
220 |
|
221 |
my $description = $attr_type->description(); |
222 |
$attr_type->description($description); |
223 |
|
224 |
Accessor. |
225 |
|
226 |
=cut |
227 |
|
228 |
sub description { |
229 |
my $self = shift; |
230 |
@_ ? $self->{'description'} = shift : $self->{'description'}; |
231 |
} |
232 |
|
233 |
=head2 branches |
234 |
|
235 |
my $branches = $attr_type->branches(); |
236 |
$attr_type->branches($branches); |
237 |
|
238 |
Accessor. |
239 |
|
240 |
=cut |
241 |
|
242 |
sub branches { |
243 |
my $self = shift; |
244 |
@_ ? $self->{branches} = shift : $self->{branches}; |
245 |
} |
246 |
|
247 |
=head2 repeatable |
248 |
|
249 |
my $repeatable = $attr_type->repeatable(); |
250 |
$attr_type->repeatable($repeatable); |
251 |
|
252 |
Accessor. The C<$repeatable> argument |
253 |
is interpreted as a Perl boolean. |
254 |
|
255 |
=cut |
256 |
|
257 |
sub repeatable { |
258 |
my $self = shift; |
259 |
@_ ? $self->{'repeatable'} = ((shift) ? 1 : 0) : $self->{'repeatable'}; |
260 |
} |
261 |
|
262 |
=head2 unique_id |
263 |
|
264 |
my $unique_id = $attr_type->unique_id(); |
265 |
$attr_type->unique_id($unique_id); |
266 |
|
267 |
Accessor. The C<$unique_id> argument |
268 |
is interpreted as a Perl boolean. |
269 |
|
270 |
=cut |
271 |
|
272 |
sub unique_id { |
273 |
my $self = shift; |
274 |
@_ ? $self->{'unique_id'} = ((shift) ? 1 : 0) : $self->{'unique_id'}; |
275 |
} |
276 |
|
277 |
=head2 opac_display |
278 |
|
279 |
my $opac_display = $attr_type->opac_display(); |
280 |
$attr_type->opac_display($opac_display); |
281 |
|
282 |
Accessor. The C<$opac_display> argument |
283 |
is interpreted as a Perl boolean. |
284 |
|
285 |
=cut |
286 |
|
287 |
sub opac_display { |
288 |
my $self = shift; |
289 |
@_ ? $self->{'opac_display'} = ((shift) ? 1 : 0) : $self->{'opac_display'}; |
290 |
} |
291 |
|
292 |
=head2 opac_editable |
293 |
|
294 |
my $opac_editable = $attr_type->opac_editable(); |
295 |
$attr_type->opac_editable($opac_editable); |
296 |
|
297 |
Accessor. The C<$opac_editable> argument |
298 |
is interpreted as a Perl boolean. |
299 |
|
300 |
=cut |
301 |
|
302 |
sub opac_editable { |
303 |
my $self = shift; |
304 |
@_ ? $self->{'opac_editable'} = ((shift) ? 1 : 0) : $self->{'opac_editable'}; |
305 |
} |
306 |
|
307 |
=head2 staff_searchable |
308 |
|
309 |
my $staff_searchable = $attr_type->staff_searchable(); |
310 |
$attr_type->staff_searchable($staff_searchable); |
311 |
|
312 |
Accessor. The C<$staff_searchable> argument |
313 |
is interpreted as a Perl boolean. |
314 |
|
315 |
=cut |
316 |
|
317 |
sub staff_searchable { |
318 |
my $self = shift; |
319 |
@_ ? $self->{'staff_searchable'} = ((shift) ? 1 : 0) : $self->{'staff_searchable'}; |
320 |
} |
321 |
|
322 |
=head2 display_checkout |
323 |
|
324 |
my $display_checkout = $attr_type->display_checkout(); |
325 |
$attr_type->display_checkout($display_checkout); |
326 |
|
327 |
Accessor. The C<$display_checkout> argument |
328 |
is interpreted as a Perl boolean. |
329 |
|
330 |
=cut |
331 |
|
332 |
sub display_checkout { |
333 |
my $self = shift; |
334 |
@_ ? $self->{'display_checkout'} = ((shift) ? 1 : 0) : $self->{'display_checkout'}; |
335 |
} |
336 |
|
337 |
=head2 authorised_value_category |
338 |
|
339 |
my $authorised_value_category = $attr_type->authorised_value_category(); |
340 |
$attr_type->authorised_value_category($authorised_value_category); |
341 |
|
342 |
Accessor. |
343 |
|
344 |
=cut |
345 |
|
346 |
sub authorised_value_category { |
347 |
my $self = shift; |
348 |
@_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'}; |
349 |
} |
350 |
|
351 |
=head2 category_code |
352 |
|
353 |
my $category_code = $attr_type->category_code(); |
354 |
$attr_type->category_code($category_code); |
355 |
|
356 |
Accessor. |
357 |
|
358 |
=cut |
359 |
|
360 |
sub category_code { |
361 |
my $self = shift; |
362 |
@_ ? $self->{'category_code'} = shift : $self->{'category_code'}; |
363 |
} |
364 |
|
365 |
=head2 category_description |
366 |
|
367 |
my $category_description = $attr_type->category_description(); |
368 |
$attr_type->category_description($category_description); |
369 |
|
370 |
Accessor. |
371 |
|
372 |
=cut |
373 |
|
374 |
sub category_description { |
375 |
my $self = shift; |
376 |
@_ ? $self->{'category_description'} = shift : $self->{'category_description'}; |
377 |
} |
378 |
|
379 |
=head2 class |
380 |
|
381 |
my $class = $attr_type->class(); |
382 |
$attr_type->class($class); |
383 |
|
384 |
Accessor. |
385 |
|
386 |
=cut |
387 |
|
388 |
sub class { |
389 |
my $self = shift; |
390 |
@_ ? $self->{'class'} = shift : $self->{'class'}; |
391 |
} |
392 |
|
393 |
|
394 |
=head2 delete |
395 |
|
396 |
$attr_type->delete(); |
397 |
C4::Members::AttributeTypes->delete($code); |
398 |
|
399 |
Delete an attribute type from the database. The attribute |
400 |
type may be specified either by an object or by a code. |
401 |
|
402 |
=cut |
403 |
|
404 |
sub delete { |
405 |
my $arg = shift; |
406 |
my $code; |
407 |
if (ref($arg) eq __PACKAGE__) { |
408 |
$code = $arg->{'code'}; |
409 |
} else { |
410 |
$code = shift; |
411 |
} |
412 |
|
413 |
my $dbh = C4::Context->dbh; |
414 |
my $sth = $dbh->prepare_cached("DELETE FROM borrower_attribute_types WHERE code = ?"); |
415 |
$sth->execute($code); |
416 |
$sth->finish; |
417 |
} |
418 |
|
419 |
=head2 num_patrons |
420 |
|
421 |
my $count = $attr_type->num_patrons(); |
422 |
|
423 |
Returns the number of patron records that use |
424 |
this attribute type. |
425 |
|
426 |
=cut |
427 |
|
428 |
sub num_patrons { |
429 |
my $self = shift; |
430 |
|
431 |
my $dbh = C4::Context->dbh; |
432 |
my $sth = $dbh->prepare_cached("SELECT COUNT(DISTINCT borrowernumber) |
433 |
FROM borrower_attributes |
434 |
WHERE code = ?"); |
435 |
$sth->execute($self->{code}); |
436 |
my ($count) = $sth->fetchrow_array; |
437 |
$sth->finish; |
438 |
return $count; |
439 |
} |
440 |
|
441 |
=head2 get_patrons |
442 |
|
443 |
my @borrowernumbers = $attr_type->get_patrons($attribute); |
444 |
|
445 |
Returns the borrowernumber of the patron records that |
446 |
have an attribute with the specifie value. |
447 |
|
448 |
=cut |
449 |
|
450 |
sub get_patrons { |
451 |
my $self = shift; |
452 |
my $value = shift; |
453 |
|
454 |
my $dbh = C4::Context->dbh; |
455 |
my $sth = $dbh->prepare_cached("SELECT DISTINCT borrowernumber |
456 |
FROM borrower_attributes |
457 |
WHERE code = ? |
458 |
AND attribute = ?"); |
459 |
$sth->execute($self->{code}, $value); |
460 |
my @results; |
461 |
while (my ($borrowernumber) = $sth->fetchrow_array) { |
462 |
push @results, $borrowernumber; |
463 |
} |
464 |
return @results; |
465 |
} |
466 |
|
467 |
=head1 AUTHOR |
468 |
|
469 |
Koha Development Team <http://koha-community.org/> |
470 |
|
471 |
Galen Charlton <galen.charlton@liblime.com> |
472 |
|
473 |
=cut |
474 |
|
475 |
1; |