Bug 15395: Allow correct handling of plural translation
[koha.git] / C4 / Members / AttributeTypes.pm
blobbfd1494ee841b78c324ba3ed7ed4aa260dd6172a
1 package C4::Members::AttributeTypes;
3 # Copyright (C) 2008 LibLime
5 # This file is part of Koha.
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.
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.
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>.
20 use strict;
21 #use warnings; FIXME - Bug 2505
22 use C4::Context;
26 =head1 NAME
28 C4::Members::AttributeTypes - mananage extended patron attribute types
30 =head1 SYNOPSIS
32 my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes();
34 my $attr_type = C4::Members::AttributeTypes->new($code, $description);
35 $attr_type->code($code);
36 $attr_type->description($description);
37 $attr_type->repeatable($repeatable);
38 $attr_type->unique_id($unique_id);
39 $attr_type->opac_display($opac_display);
40 $attr_type->opac_editable($opac_editable);
41 $attr_type->staff_searchable($staff_searchable);
42 $attr_type->authorised_value_category($authorised_value_category);
43 $attr_type->store();
44 $attr_type->delete();
46 my $attr_type = C4::Members::AttributeTypes->fetch($code);
47 $attr_type = C4::Members::AttributeTypes->delete($code);
49 =head1 FUNCTIONS
51 =head2 GetAttributeTypes
53 my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes($all_fields);
55 Returns an array of hashrefs of each attribute type defined
56 in the database. The array is sorted by code. Each hashref contains
57 at least the following fields:
59 - code
60 - description
62 If $all_fields is true, then each hashref also contains the other fields from borrower_attribute_types.
64 =cut
66 sub GetAttributeTypes {
67 my $all = @_ ? shift : 0;
68 my $no_branch_limit = @_ ? shift : 0;
69 my $branch_limit = $no_branch_limit
70 ? 0
71 : C4::Context->userenv ? C4::Context->userenv->{"branch"} : 0;
72 my $select = $all ? '*' : 'DISTINCT(code), description, class';
74 my $dbh = C4::Context->dbh;
75 my $query = "SELECT $select FROM borrower_attribute_types";
76 $query .= qq{
77 LEFT JOIN borrower_attribute_types_branches ON bat_code = code
78 WHERE b_branchcode = ? OR b_branchcode IS NULL
79 } if $branch_limit;
80 $query .= " ORDER BY code";
81 my $sth = $dbh->prepare($query);
82 $sth->execute( $branch_limit ? $branch_limit : () );
83 my $results = $sth->fetchall_arrayref({});
84 $sth->finish;
85 return @$results;
88 sub GetAttributeTypes_hashref {
89 my %hash = map {$_->{code} => $_} GetAttributeTypes(@_);
90 return \%hash;
93 =head1 METHODS
95 my $attr_type = C4::Members::AttributeTypes->new($code, $description);
97 Create a new attribute type.
99 =cut
101 sub new {
102 my $class = shift;
103 my $self = {};
105 $self->{'code'} = shift;
106 $self->{'description'} = shift;
107 $self->{'repeatable'} = 0;
108 $self->{'unique_id'} = 0;
109 $self->{'opac_display'} = 0;
110 $self->{'opac_editable'} = 0;
111 $self->{'staff_searchable'} = 0;
112 $self->{'display_checkout'} = 0;
113 $self->{'authorised_value_category'} = '';
114 $self->{'category_code'} = '';
115 $self->{'category_description'} = '';
116 $self->{'class'} = '';
118 bless $self, $class;
119 return $self;
122 =head2 fetch
124 my $attr_type = C4::Members::AttributeTypes->fetch($code);
126 Fetches an attribute type from the database. If no
127 type with the given C<$code> exists, returns undef.
129 =cut
131 sub fetch {
132 my $class = shift;
133 my $code = shift;
134 my $self = {};
135 my $dbh = C4::Context->dbh();
137 my $sth = $dbh->prepare_cached("
138 SELECT borrower_attribute_types.*, categories.description AS category_description
139 FROM borrower_attribute_types
140 LEFT JOIN categories ON borrower_attribute_types.category_code=categories.categorycode
141 WHERE code =?");
142 $sth->execute($code);
143 my $row = $sth->fetchrow_hashref;
144 $sth->finish();
145 return unless defined $row;
147 $self->{'code'} = $row->{'code'};
148 $self->{'description'} = $row->{'description'};
149 $self->{'repeatable'} = $row->{'repeatable'};
150 $self->{'unique_id'} = $row->{'unique_id'};
151 $self->{'opac_display'} = $row->{'opac_display'};
152 $self->{'opac_editable'} = $row->{'opac_editable'};
153 $self->{'staff_searchable'} = $row->{'staff_searchable'};
154 $self->{'display_checkout'} = $row->{'display_checkout'};
155 $self->{'authorised_value_category'} = $row->{'authorised_value_category'};
156 $self->{'category_code'} = $row->{'category_code'};
157 $self->{'category_description'} = $row->{'category_description'};
158 $self->{'class'} = $row->{'class'};
160 $sth = $dbh->prepare("SELECT branchcode, branchname FROM borrower_attribute_types_branches, branches WHERE b_branchcode = branchcode AND bat_code = ?;");
161 $sth->execute( $code );
162 while ( my $data = $sth->fetchrow_hashref ) {
163 push @{ $self->{branches} }, $data;
165 $sth->finish();
167 bless $self, $class;
168 return $self;
171 =head2 store
173 $attr_type->store();
175 Stores attribute type in the database. If the type
176 previously retrieved from the database via the fetch()
177 method, the DB representation of the type is replaced.
179 =cut
181 sub store {
182 my $self = shift;
184 my $dbh = C4::Context->dbh;
185 my $sth;
186 my $existing = __PACKAGE__->fetch($self->{'code'});
187 if (defined $existing) {
188 $sth = $dbh->prepare_cached("UPDATE borrower_attribute_types
189 SET description = ?,
190 repeatable = ?,
191 unique_id = ?,
192 opac_display = ?,
193 opac_editable = ?,
194 staff_searchable = ?,
195 authorised_value_category = ?,
196 display_checkout = ?,
197 category_code = ?,
198 class = ?
199 WHERE code = ?");
200 } else {
201 $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types
202 ( description,
203 repeatable,
204 unique_id,
205 opac_display,
206 opac_editable,
207 staff_searchable,
208 authorised_value_category,
209 display_checkout,
210 category_code,
211 class,
212 code
214 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
217 $sth->execute(
218 $self->{'description'},
219 $self->{'repeatable'},
220 $self->{'unique_id'},
221 $self->{'opac_display'},
222 $self->{'opac_editable'},
223 $self->{'staff_searchable'} || 0,
224 $self->{'authorised_value_category'},
225 $self->{'display_checkout'},
226 $self->{'category_code'} || undef,
227 $self->{'class'},
228 $self->{'code'}
231 if ( defined $$self{branches} ) {
232 $sth = $dbh->prepare("DELETE FROM borrower_attribute_types_branches WHERE bat_code = ?");
233 $sth->execute( $$self{code} );
234 $sth = $dbh->prepare(
235 "INSERT INTO borrower_attribute_types_branches
236 ( bat_code, b_branchcode )
237 VALUES ( ?, ? )"
239 for my $branchcode ( @{$$self{branches}} ) {
240 next if not $branchcode;
241 $sth->bind_param( 1, $$self{code} );
242 $sth->bind_param( 2, $branchcode );
243 $sth->execute;
246 $sth->finish;
249 =head2 code
251 my $code = $attr_type->code();
252 $attr_type->code($code);
254 Accessor. Note that the code is immutable once
255 a type is created or fetched from the database.
257 =cut
259 sub code {
260 my $self = shift;
261 return $self->{'code'};
264 =head2 description
266 my $description = $attr_type->description();
267 $attr_type->description($description);
269 Accessor.
271 =cut
273 sub description {
274 my $self = shift;
275 @_ ? $self->{'description'} = shift : $self->{'description'};
278 =head2 branches
280 my $branches = $attr_type->branches();
281 $attr_type->branches($branches);
283 Accessor.
285 =cut
287 sub branches {
288 my $self = shift;
289 @_ ? $self->{branches} = shift : $self->{branches};
292 =head2 repeatable
294 my $repeatable = $attr_type->repeatable();
295 $attr_type->repeatable($repeatable);
297 Accessor. The C<$repeatable> argument
298 is interpreted as a Perl boolean.
300 =cut
302 sub repeatable {
303 my $self = shift;
304 @_ ? $self->{'repeatable'} = ((shift) ? 1 : 0) : $self->{'repeatable'};
307 =head2 unique_id
309 my $unique_id = $attr_type->unique_id();
310 $attr_type->unique_id($unique_id);
312 Accessor. The C<$unique_id> argument
313 is interpreted as a Perl boolean.
315 =cut
317 sub unique_id {
318 my $self = shift;
319 @_ ? $self->{'unique_id'} = ((shift) ? 1 : 0) : $self->{'unique_id'};
322 =head2 opac_display
324 my $opac_display = $attr_type->opac_display();
325 $attr_type->opac_display($opac_display);
327 Accessor. The C<$opac_display> argument
328 is interpreted as a Perl boolean.
330 =cut
332 sub opac_display {
333 my $self = shift;
334 @_ ? $self->{'opac_display'} = ((shift) ? 1 : 0) : $self->{'opac_display'};
337 =head2 opac_editable
339 my $opac_editable = $attr_type->opac_editable();
340 $attr_type->opac_editable($opac_editable);
342 Accessor. The C<$opac_editable> argument
343 is interpreted as a Perl boolean.
345 =cut
347 sub opac_editable {
348 my $self = shift;
349 @_ ? $self->{'opac_editable'} = ((shift) ? 1 : 0) : $self->{'opac_editable'};
352 =head2 staff_searchable
354 my $staff_searchable = $attr_type->staff_searchable();
355 $attr_type->staff_searchable($staff_searchable);
357 Accessor. The C<$staff_searchable> argument
358 is interpreted as a Perl boolean.
360 =cut
362 sub staff_searchable {
363 my $self = shift;
364 @_ ? $self->{'staff_searchable'} = ((shift) ? 1 : 0) : $self->{'staff_searchable'};
367 =head2 display_checkout
369 my $display_checkout = $attr_type->display_checkout();
370 $attr_type->display_checkout($display_checkout);
372 Accessor. The C<$display_checkout> argument
373 is interpreted as a Perl boolean.
375 =cut
377 sub display_checkout {
378 my $self = shift;
379 @_ ? $self->{'display_checkout'} = ((shift) ? 1 : 0) : $self->{'display_checkout'};
382 =head2 authorised_value_category
384 my $authorised_value_category = $attr_type->authorised_value_category();
385 $attr_type->authorised_value_category($authorised_value_category);
387 Accessor.
389 =cut
391 sub authorised_value_category {
392 my $self = shift;
393 @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'};
396 =head2 category_code
398 my $category_code = $attr_type->category_code();
399 $attr_type->category_code($category_code);
401 Accessor.
403 =cut
405 sub category_code {
406 my $self = shift;
407 @_ ? $self->{'category_code'} = shift : $self->{'category_code'};
410 =head2 category_description
412 my $category_description = $attr_type->category_description();
413 $attr_type->category_description($category_description);
415 Accessor.
417 =cut
419 sub category_description {
420 my $self = shift;
421 @_ ? $self->{'category_description'} = shift : $self->{'category_description'};
424 =head2 class
426 my $class = $attr_type->class();
427 $attr_type->class($class);
429 Accessor.
431 =cut
433 sub class {
434 my $self = shift;
435 @_ ? $self->{'class'} = shift : $self->{'class'};
439 =head2 delete
441 $attr_type->delete();
442 C4::Members::AttributeTypes->delete($code);
444 Delete an attribute type from the database. The attribute
445 type may be specified either by an object or by a code.
447 =cut
449 sub delete {
450 my $arg = shift;
451 my $code;
452 if (ref($arg) eq __PACKAGE__) {
453 $code = $arg->{'code'};
454 } else {
455 $code = shift;
458 my $dbh = C4::Context->dbh;
459 my $sth = $dbh->prepare_cached("DELETE FROM borrower_attribute_types WHERE code = ?");
460 $sth->execute($code);
461 $sth->finish;
464 =head2 num_patrons
466 my $count = $attr_type->num_patrons();
468 Returns the number of patron records that use
469 this attribute type.
471 =cut
473 sub num_patrons {
474 my $self = shift;
476 my $dbh = C4::Context->dbh;
477 my $sth = $dbh->prepare_cached("SELECT COUNT(DISTINCT borrowernumber)
478 FROM borrower_attributes
479 WHERE code = ?");
480 $sth->execute($self->{code});
481 my ($count) = $sth->fetchrow_array;
482 $sth->finish;
483 return $count;
486 =head2 get_patrons
488 my @borrowernumbers = $attr_type->get_patrons($attribute);
490 Returns the borrowernumber of the patron records that
491 have an attribute with the specifie value.
493 =cut
495 sub get_patrons {
496 my $self = shift;
497 my $value = shift;
499 my $dbh = C4::Context->dbh;
500 my $sth = $dbh->prepare_cached("SELECT DISTINCT borrowernumber
501 FROM borrower_attributes
502 WHERE code = ?
503 AND attribute = ?");
504 $sth->execute($self->{code}, $value);
505 my @results;
506 while (my ($borrowernumber) = $sth->fetchrow_array) {
507 push @results, $borrowernumber;
509 return @results;
512 =head1 AUTHOR
514 Koha Development Team <http://koha-community.org/>
516 Galen Charlton <galen.charlton@liblime.com>
518 =cut