Bugs 6634: manager_id not recorded for payments and rental charges
[koha.git] / C4 / Members / AttributeTypes.pm
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 under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20 use strict;
21 #use warnings; FIXME - Bug 2505
22 use C4::Context;
23
24 use vars qw($VERSION);
25
26 BEGIN {
27     # set the version for version checking
28     $VERSION = 3.00;
29 }
30
31 =head1 NAME
32
33 C4::Members::AttributeTypes - mananage extended patron attribute types
34
35 =head1 SYNOPSIS
36
37   my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes();
38
39   my $attr_type = C4::Members::AttributeTypes->new($code, $description);
40   $attr_type->code($code);
41   $attr_type->description($description);
42   $attr_type->repeatable($repeatable);
43   $attr_type->unique_id($unique_id);
44   $attr_type->opac_display($opac_display);
45   $attr_type->password_allowed($password_allowed);
46   $attr_type->staff_searchable($staff_searchable);
47   $attr_type->authorised_value_category($authorised_value_category);
48   $attr_type->store();
49   $attr_type->delete();
50
51   my $attr_type = C4::Members::AttributeTypes->fetch($code);
52   $attr_type = C4::Members::AttributeTypes->delete($code);
53
54 =head1 FUNCTIONS
55
56 =head2 GetAttributeTypes
57
58   my @attribute_types = C4::Members::AttributeTypes::GetAttributeTypes($all_fields);
59
60 Returns an array of hashrefs of each attribute type defined
61 in the database.  The array is sorted by code.  Each hashref contains
62 at least the following fields:
63
64  - code
65  - description
66
67 If $all_fields is true, then each hashref also contains the other fields from borrower_attribute_types.
68
69 =cut
70
71 sub GetAttributeTypes {
72     my ($all) = @_;
73     my $select = $all ? '*' : 'code, description';
74     my $dbh = C4::Context->dbh;
75     my $sth = $dbh->prepare("SELECT $select FROM borrower_attribute_types ORDER by code");
76     $sth->execute();
77     my $results = $sth->fetchall_arrayref({});
78     return @$results;
79 }
80
81 sub GetAttributeTypes_hashref {
82     my %hash = map {$_->{code} => $_} GetAttributeTypes(@_);
83     return \%hash;
84 }
85
86 =head2 AttributeTypeExists
87
88   my $have_attr_xyz = C4::Members::AttributeTypes::AttributeTypeExists($code)
89
90 Returns true if we have attribute type C<$code>
91 in the database.
92
93 =cut
94
95 sub AttributeTypeExists {
96     my ($code) = @_;
97     my $dbh = C4::Context->dbh;
98     my $exists = $dbh->selectrow_array("SELECT code FROM borrower_attribute_types WHERE code = ?", undef, $code);
99     return $exists;
100 }
101
102 =head1 METHODS 
103
104   my $attr_type = C4::Members::AttributeTypes->new($code, $description);
105
106 Create a new attribute type.
107
108 =cut 
109
110 sub new {
111     my $class = shift;
112     my $self = {};
113
114     $self->{'code'} = shift;
115     $self->{'description'} = shift;
116     $self->{'repeatable'} = 0;
117     $self->{'unique_id'} = 0;
118     $self->{'opac_display'} = 0;
119     $self->{'password_allowed'} = 0;
120     $self->{'staff_searchable'} = 0;
121     $self->{'authorised_value_category'} = '';
122
123     bless $self, $class;
124     return $self;
125 }
126
127 =head2 fetch
128
129   my $attr_type = C4::Members::AttributeTypes->fetch($code);
130
131 Fetches an attribute type from the database.  If no
132 type with the given C<$code> exists, returns undef.
133
134 =cut
135
136 sub fetch {
137     my $class = shift;
138     my $code = shift;
139     my $self = {};
140     my $dbh = C4::Context->dbh();
141
142     my $sth = $dbh->prepare_cached("SELECT * FROM borrower_attribute_types WHERE code = ?");
143     $sth->execute($code);
144     my $row = $sth->fetchrow_hashref;
145     $sth->finish();
146     return undef unless defined $row;    
147
148     $self->{'code'}                      = $row->{'code'};
149     $self->{'description'}               = $row->{'description'};
150     $self->{'repeatable'}                = $row->{'repeatable'};
151     $self->{'unique_id'}                 = $row->{'unique_id'};
152     $self->{'opac_display'}              = $row->{'opac_display'};
153     $self->{'password_allowed'}          = $row->{'password_allowed'};
154     $self->{'staff_searchable'}          = $row->{'staff_searchable'};
155     $self->{'authorised_value_category'} = $row->{'authorised_value_category'};
156
157     bless $self, $class;
158     return $self;
159 }
160
161 =head2 store
162
163   $attr_type->store();
164
165 Stores attribute type in the database.  If the type
166 previously retrieved from the database via the fetch()
167 method, the DB representation of the type is replaced.
168
169 =cut
170
171 sub store {
172     my $self = shift;
173
174     my $dbh = C4::Context->dbh;
175     my $sth;
176     my $existing = __PACKAGE__->fetch($self->{'code'});
177     if (defined $existing) {
178         $sth = $dbh->prepare_cached("UPDATE borrower_attribute_types
179                                      SET description = ?,
180                                          repeatable = ?,
181                                          unique_id = ?,
182                                          opac_display = ?,
183                                          password_allowed = ?,
184                                          staff_searchable = ?,
185                                          authorised_value_category = ?
186                                      WHERE code = ?");
187     } else {
188         $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types 
189                                         (description, repeatable, unique_id, opac_display, password_allowed,
190                                          staff_searchable, authorised_value_category, code)
191                                         VALUES (?, ?, ?, ?, ?,
192                                                 ?, ?, ?)");
193     }
194     $sth->bind_param(1, $self->{'description'});
195     $sth->bind_param(2, $self->{'repeatable'});
196     $sth->bind_param(3, $self->{'unique_id'});
197     $sth->bind_param(4, $self->{'opac_display'});
198     $sth->bind_param(5, $self->{'password_allowed'});
199     $sth->bind_param(6, $self->{'staff_searchable'});
200     $sth->bind_param(7, $self->{'authorised_value_category'});
201     $sth->bind_param(8, $self->{'code'});
202     $sth->execute;
203
204 }
205
206 =head2 code
207
208   my $code = $attr_type->code();
209   $attr_type->code($code);
210
211 Accessor.  Note that the code is immutable once
212 a type is created or fetched from the database.
213
214 =cut
215
216 sub code {
217     my $self = shift;
218     return $self->{'code'};
219 }
220
221 =head2 description
222
223   my $description = $attr_type->description();
224   $attr_type->description($description);
225
226 Accessor.
227
228 =cut
229
230 sub description {
231     my $self = shift;
232     @_ ? $self->{'description'} = shift : $self->{'description'};
233 }
234
235 =head2 repeatable
236
237   my $repeatable = $attr_type->repeatable();
238   $attr_type->repeatable($repeatable);
239
240 Accessor.  The C<$repeatable> argument
241 is interpreted as a Perl boolean.
242
243 =cut
244
245 sub repeatable {
246     my $self = shift;
247     @_ ? $self->{'repeatable'} = ((shift) ? 1 : 0) : $self->{'repeatable'};
248 }
249
250 =head2 unique_id
251
252   my $unique_id = $attr_type->unique_id();
253   $attr_type->unique_id($unique_id);
254
255 Accessor.  The C<$unique_id> argument
256 is interpreted as a Perl boolean.
257
258 =cut
259
260 sub unique_id {
261     my $self = shift;
262     @_ ? $self->{'unique_id'} = ((shift) ? 1 : 0) : $self->{'unique_id'};
263 }
264 =head2 opac_display
265
266   my $opac_display = $attr_type->opac_display();
267   $attr_type->opac_display($opac_display);
268
269 Accessor.  The C<$opac_display> argument
270 is interpreted as a Perl boolean.
271
272 =cut
273
274 sub opac_display {
275     my $self = shift;
276     @_ ? $self->{'opac_display'} = ((shift) ? 1 : 0) : $self->{'opac_display'};
277 }
278 =head2 password_allowed
279
280   my $password_allowed = $attr_type->password_allowed();
281   $attr_type->password_allowed($password_allowed);
282
283 Accessor.  The C<$password_allowed> argument
284 is interpreted as a Perl boolean.
285
286 =cut
287
288 sub password_allowed {
289     my $self = shift;
290     @_ ? $self->{'password_allowed'} = ((shift) ? 1 : 0) : $self->{'password_allowed'};
291 }
292 =head2 staff_searchable
293
294   my $staff_searchable = $attr_type->staff_searchable();
295   $attr_type->staff_searchable($staff_searchable);
296
297 Accessor.  The C<$staff_searchable> argument
298 is interpreted as a Perl boolean.
299
300 =cut
301
302 sub staff_searchable {
303     my $self = shift;
304     @_ ? $self->{'staff_searchable'} = ((shift) ? 1 : 0) : $self->{'staff_searchable'};
305 }
306
307 =head2 authorised_value_category
308
309   my $authorised_value_category = $attr_type->authorised_value_category();
310   $attr_type->authorised_value_category($authorised_value_category);
311
312 Accessor.
313
314 =cut
315
316 sub authorised_value_category {
317     my $self = shift;
318     @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'};
319 }
320
321 =head2 delete
322
323   $attr_type->delete();
324   C4::Members::AttributeTypes->delete($code);
325
326 Delete an attribute type from the database.  The attribute
327 type may be specified either by an object or by a code.
328
329 =cut
330
331 sub delete {
332     my $arg = shift;
333     my $code;
334     if (ref($arg) eq __PACKAGE__) {
335         $code = $arg->{'code'};
336     } else {
337         $code = shift;
338     }
339
340     my $dbh = C4::Context->dbh;
341     my $sth = $dbh->prepare_cached("DELETE FROM borrower_attribute_types WHERE code = ?");
342     $sth->execute($code);
343 }
344
345 =head2 num_patrons
346
347   my $count = $attr_type->num_patrons();
348
349 Returns the number of patron records that use
350 this attribute type.
351
352 =cut
353
354 sub num_patrons {
355     my $self = shift;
356
357     my $dbh = C4::Context->dbh;
358     my $sth = $dbh->prepare_cached("SELECT COUNT(DISTINCT borrowernumber)
359                                     FROM borrower_attributes
360                                     WHERE code = ?");
361     $sth->execute($self->{code});
362     my ($count) = $sth->fetchrow_array;
363     $sth->finish;
364     return $count;
365 }
366
367 =head2 get_patrons
368
369   my @borrowernumbers = $attr_type->get_patrons($attribute);
370
371 Returns the borrowernumber of the patron records that
372 have an attribute with the specifie value.
373
374 =cut
375
376 sub get_patrons {
377     my $self = shift;
378     my $value = shift;
379
380     my $dbh = C4::Context->dbh;
381     my $sth = $dbh->prepare_cached("SELECT DISTINCT borrowernumber
382                                     FROM borrower_attributes
383                                     WHERE code = ?
384                                     AND   attribute = ?");
385     $sth->execute($self->{code}, $value);
386     my @results;
387     while (my ($borrowernumber) = $sth->fetchrow_array) {
388         push @results, $borrowernumber;
389     } 
390     return @results;
391 }
392
393 =head1 AUTHOR
394
395 Koha Development Team <http://koha-community.org/>
396
397 Galen Charlton <galen.charlton@liblime.com>
398
399 =cut
400
401 1;