[35/40] Work on C4::Labels tests and various bugfixs resulting
[koha.git] / C4 / Labels / Profile.pm
1 package C4::Labels::Profile;
2
3 use strict;
4 use warnings;
5 use Sys::Syslog qw(syslog);
6
7 use C4::Context;
8 use C4::Debug;
9 use C4::Labels::Lib 1.000000 qw(get_unit_values);
10
11 BEGIN {
12     use version; our $VERSION = qv('1.0.0_1');
13 }
14
15 sub _check_params {
16     my $given_params = {};
17     my $exit_code = 0;
18     my @valid_profile_params = (
19         'printer_name',
20         'template_id',
21         'paper_bin',
22         'offset_horz',
23         'offset_vert',
24         'creep_horz',
25         'creep_vert',
26         'units',
27     );
28     if (scalar(@_) >1) {
29         $given_params = {@_};
30         foreach my $key (keys %{$given_params}) {
31             if (!(grep m/$key/, @valid_profile_params)) {
32                 syslog("LOG_ERR", "C4::Labels::Profile : Unrecognized parameter type of \"%s\".", $key);
33                 $exit_code = 1;
34             }
35         }
36     }
37     else {
38         if (!(grep m/$_/, @valid_profile_params)) {
39             syslog("LOG_ERR", "C4::Labels::Profile : Unrecognized parameter type of \"%s\".", $_);
40             $exit_code = 1;
41         }
42     }
43     return $exit_code;
44 }
45
46 sub _conv_points {
47     my $self = shift;
48     my @unit_value = grep {$_->{'type'} eq $self->{units}} @{get_unit_values()};
49     $self->{offset_horz}        = $self->{offset_horz} * $unit_value[0]->{'value'};
50     $self->{offset_vert}        = $self->{offset_vert} * $unit_value[0]->{'value'};
51     $self->{creep_horz}         = $self->{creep_horz} * $unit_value[0]->{'value'};
52     $self->{creep_vert}         = $self->{creep_vert} * $unit_value[0]->{'value'};
53     return $self;
54 }
55
56 sub new {
57     my $invocant = shift;
58     if (_check_params(@_) eq 1) {
59         return -1;
60     }
61     my $type = ref($invocant) || $invocant;
62     my $self = {
63         printer_name    => 'Default Printer',
64         template_id     => '',
65         paper_bin       => 'Tray 1',
66         offset_horz     => 0,
67         offset_vert     => 0,
68         creep_horz      => 0,
69         creep_vert      => 0,
70         units           => 'POINT',
71         @_,
72     };
73     bless ($self, $type);
74     return $self;
75 }
76
77 sub retrieve {
78     my $invocant = shift;
79     my %opts = @_;
80     my $type = ref($invocant) || $invocant;
81     my $query = "SELECT * FROM printers_profile WHERE profile_id = ?";  
82     my $sth = C4::Context->dbh->prepare($query);
83     $sth->execute($opts{profile_id});
84     if ($sth->err) {
85         syslog("LOG_ERR", "Database returned the following error: %s", $sth->errstr);
86         return -1;
87     }
88     my $self = $sth->fetchrow_hashref;
89     $self = _conv_points($self) if ($opts{convert} && $opts{convert} == 1);
90     bless ($self, $type);
91     return $self;
92 }
93
94 sub delete {
95     my $self = {};
96     my %opts = ();
97     my $call_type = '';
98     my $query_param = '';
99     if (ref($_[0])) {
100         $self = shift;  # check to see if this is a method call
101         $call_type = 'C4::Labels::Profile->delete';
102         $query_param = $self->{'profile_id'};
103     }
104     else {
105         %opts = @_;
106         $call_type = 'C4::Labels::Profile::delete';
107         $query_param = $opts{'profile_id'};
108     }
109     if ($query_param eq '') {   # If there is no profile id then we cannot delete it
110         syslog("LOG_ERR", "%s : Cannot delete layout as the profile id is invalid or non-existant.", $call_type);
111         return -1;
112     }
113     my $query = "DELETE FROM printers_profile WHERE profile_id = ?";  
114     my $sth = C4::Context->dbh->prepare($query);
115 #    $sth->{'TraceLevel'} = 3;
116     $sth->execute($query_param);
117 }
118
119 sub save {
120     my $self = shift;
121     if ($self->{'profile_id'}) {        # if we have an profile_id, the record exists and needs UPDATE
122         my @params;
123         my $query = "UPDATE printers_profile SET ";
124         foreach my $key (keys %{$self}) {
125             next if $key eq 'profile_id';
126             push (@params, $self->{$key});
127             $query .= "$key=?, ";
128         }
129         $query = substr($query, 0, (length($query)-2));
130         push (@params, $self->{'profile_id'});
131         $query .= " WHERE profile_id=?;";
132         my $sth = C4::Context->dbh->prepare($query);
133 #        $sth->{'TraceLevel'} = 3;
134         $sth->execute(@params);
135         if ($sth->err) {
136             syslog("LOG_ERR", "C4::Labels::Profile : Database returned the following error on attempted UPDATE: %s", $sth->errstr);
137             return -1;
138         }
139         return $self->{'profile_id'};
140     }
141     else {                      # otherwise create a new record
142         my @params;
143         my $query = "INSERT INTO printers_profile (";
144         foreach my $key (keys %{$self}) {
145             push (@params, $self->{$key});
146             $query .= "$key, ";
147         }
148         $query = substr($query, 0, (length($query)-2));
149         $query .= ") VALUES (";
150         for (my $i=1; $i<=(scalar keys %$self); $i++) {
151             $query .= "?,";
152         }
153         $query = substr($query, 0, (length($query)-1));
154         $query .= ");";
155         my $sth = C4::Context->dbh->prepare($query);
156         $sth->execute(@params);
157         if ($sth->err) {
158             syslog("LOG_ERR", "C4::Labels::Profile : Database returned the following error on attempted INSERT: %s", $sth->errstr);
159             return -1;
160         }
161         my $sth1 = C4::Context->dbh->prepare("SELECT MAX(profile_id) FROM printers_profile;");
162         $sth1->execute();
163         my $tmpl_id = $sth1->fetchrow_array;
164         return $tmpl_id;
165     }
166 }
167
168 sub get_attr {
169     my $self = shift;
170     if (_check_params(@_) eq 1) {
171         return -1;
172     }
173     my ($attr) = @_;
174     if (exists($self->{$attr})) {
175         return $self->{$attr};
176     }
177     else {
178         syslog("LOG_ERR", "C4::Labels::Profile : %s is currently undefined.", $attr);
179         return -1;
180     }
181 }
182
183 sub set_attr {
184     my $self = shift;
185     if (_check_params(@_) eq 1) {
186         return -1;
187     }
188     my %attrs = @_;
189     foreach my $attrib (keys(%attrs)) {
190         $self->{$attrib} = $attrs{$attrib};
191     };
192     return 0;
193 }
194
195 1;
196 __END__
197
198 =head1 NAME
199
200 C4::Labels::Profile - A class for creating and manipulating profile objects in Koha
201
202 =head1 ABSTRACT
203
204 This module provides methods for creating, retrieving, and otherwise manipulating label profile objects used by Koha to create and export labels.
205
206 =head1 METHODS
207
208 =head2 new()
209
210     Invoking the I<new> method constructs a new profile object containing the default values for a template.
211     The following parameters are optionally accepted as key => value pairs:
212
213         C<printer_name>         The name of the printer to which this profile applies.
214         C<template_id>          The template to which this profile may be applied. NOTE: There may be multiple profiles which may be applied to the same template.
215         C<paper_bin>            The paper bin of the above printer to which this profile applies. NOTE: printer name, template id, and paper bin must form a unique combination.
216         C<offset_horz>          Amount of compensation for horizontal offset (position of text on a single label). This amount is measured in the units supplied by the units parameter in this profile.
217         C<offset_vert>          Amount of compensation for vertical offset.
218         C<creep_horz>           Amount of compensation for horizontal creep (tendency of text to 'creep' off of the labels over the span of the entire page).
219         C<creep_vert>           Amount of compensation for vertical creep.
220         C<units>                The units of measure used for this template. These B<must> match the measures you supply above or
221                                 bad things will happen to your document. NOTE: The only supported units at present are:
222
223 =over 9
224
225 =item .
226 POINT   = Postscript Points (This is the base unit in the Koha label creator.)
227
228 =item .
229 AGATE   = Adobe Agates (5.1428571 points per)
230
231 =item .
232 INCH    = US Inches (72 points per)
233
234 =item .
235 MM      = SI Millimeters (2.83464567 points per)
236
237 =item .
238 CM      = SI Centimeters (28.3464567 points per)
239
240 =back
241
242     example:
243         C<my $profile = C4::Labels::Profile->new(); # Creates and returns a new profile object>
244
245         C<my $profile = C4::Labels::Profile->new(template_id => 1, paper_bin => 'Bypass Tray', offset_horz => 0.02, units => 'POINT'); # Creates and returns a new profile object using
246             the supplied values to override the defaults>
247
248     B<NOTE:> This profile is I<not> written to the database until save() is invoked. You have been warned!
249
250 =head2 retrieve(profile_id => $profile_id, convert => 1)
251
252     Invoking the I<retrieve> method constructs a new profile object containing the current values for profile_id. The method returns a new object upon success and 1 upon failure.
253     Errors are logged to the syslog. One further option maybe accessed. See the examples below for further description.
254
255     examples:
256
257         C<my $profile = C4::Labels::Profile->retrieve(profile_id => 1); # Retrieves profile record 1 and returns an object containing the record>
258
259         C<my $profile = C4::Labels::Profile->retrieve(profile_id => 1, convert => 1); # Retrieves profile record 1, converts the units to points and returns an object containing the record>
260
261 =head2 delete()
262
263     Invoking the delete method attempts to delete the profile from the database. The method returns -1 upon failure. Errors are logged to the syslog.
264     NOTE: This method may also be called as a function and passed a key/value pair simply deleteing that profile from the database. See the example below.
265
266     examples:
267         C<my $exitstat = $profile->delete(); # to delete the record behind the $profile object>
268         C<my $exitstat = C4::Labels::Profile::delete(profile_id => 1); # to delete profile record 1>
269
270 =head2 save()
271
272     Invoking the I<save> method attempts to insert the profile into the database if the profile is new and update the existing profile record if the profile exists. The method returns
273     the new record profile_id upon success and -1 upon failure (This avoids conflicting with a record profile_id of 1). Errors are logged to the syslog.
274
275     example:
276         C<my $exitstat = $profile->save(); # to save the record behind the $profile object>
277
278 =head2 get_attr($attribute)
279
280     Invoking the I<get_attr> method will return the value of the requested attribute or -1 on errors.
281
282     example:
283         C<my $value = $profile->get_attr($attribute);>
284
285 =head2 set_attr(attribute => value, attribute_2 => value)
286
287     Invoking the I<set_attr> method will set the value of the supplied attributes to the supplied values. The method accepts key/value pairs separated by commas.
288
289     example:
290         $profile->set_attr(attribute => value);
291
292 =head1 AUTHOR
293
294 Chris Nighswonger <cnighswonger AT foundations DOT edu>
295
296 =head1 COPYRIGHT
297
298 Copyright 2009 Foundations Bible College.
299
300 =head1 LICENSE
301
302 This file is part of Koha.
303        
304 Koha is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
305 Foundation; either version 2 of the License, or (at your option) any later version.
306
307 You should have received a copy of the GNU General Public License along with Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
308 Suite 330, Boston, MA  02111-1307 USA
309
310 =head1 DISCLAIMER OF WARRANTY
311
312 Koha is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
313 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
314
315 =cut
316
317 #=head1
318 #drawbox( ($left_margin), ($top_margin), ($page_width-(2*$left_margin)), ($page_height-(2*$top_margin)) ); # FIXME: Breakout code to print alignment page for printer profile setup
319 #
320 #=head2 draw_boundaries
321 #
322 # sub draw_boundaries ($llx_spine, $llx_circ1, $llx_circ2,
323 #                $lly, $spine_width, $label_height, $circ_width)  
324 #
325 #This sub draws boundary lines where the label outlines are, to aid in printer testing, and debugging.
326 #
327 #=cut
328 #
329 ##       FIXME: Template use for profile adjustment...
330 ##sub draw_boundaries {
331 ##
332 ##    my (
333 ##        $llx_spine, $llx_circ1,  $llx_circ2, $lly,
334 ##        $spine_width, $label_height, $circ_width
335 ##    ) = @_;
336 ##
337 ##    my $lly_initial = ( ( 792 - 36 ) - 90 );
338 ##    $lly            = $lly_initial; # FIXME - why are we ignoring the y_pos parameter by redefining it?
339 ##    my $i             = 1;
340 ##
341 ##    for ( $i = 1 ; $i <= 8 ; $i++ ) {
342 ##
343 ##        _draw_box( $llx_spine, $lly, ($spine_width), ($label_height) );
344 ##
345 ##   #warn "OLD BOXES  x=$llx_spine, y=$lly, w=$spine_width, h=$label_height";
346 ##        _draw_box( $llx_circ1, $lly, ($circ_width), ($label_height) );
347 ##        _draw_box( $llx_circ2, $lly, ($circ_width), ($label_height) );
348 ##
349 ##        $lly = ( $lly - $label_height );
350 ##
351 ##    }
352 ##}
353 #
354 #
355 #
356 #=cut