File: | C4/Creators/Batch.pm |
Coverage: | 13.8% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package C4::Creators::Batch; | |||||
2 | ||||||
3 | 3 3 3 | 502 4 83 | use strict; | |||
4 | 3 3 3 | 13 4 112 | use warnings; | |||
5 | ||||||
6 | 3 3 3 | 710 2492 35 | use autouse 'Data::Dumper' => qw(Dumper); | |||
7 | ||||||
8 | 3 3 3 | 626 53 78 | use C4::Context; | |||
9 | 3 3 3 | 22 7 324 | use C4::Debug; | |||
10 | ||||||
11 | BEGIN { | |||||
12 | 3 3 3 3 | 35 2227 35 232 | use version; our $VERSION = qv('1.0.0_1'); | |||
13 | } | |||||
14 | ||||||
15 | sub _check_params { | |||||
16 | 0 | my $given_params = {}; | ||||
17 | 0 | my $exit_code = 0; | ||||
18 | 0 | my @valid_template_params = ( | ||||
19 | 'label_id', | |||||
20 | 'batch_id', | |||||
21 | 'item_number', | |||||
22 | 'card_number', | |||||
23 | 'branch_code', | |||||
24 | 'creator', | |||||
25 | ); | |||||
26 | 0 | if (scalar(@_) >1) { | ||||
27 | 0 | $given_params = {@_}; | ||||
28 | 0 0 | foreach my $key (keys %{$given_params}) { | ||||
29 | 0 | if (!(grep m/$key/, @valid_template_params)) { | ||||
30 | 0 | warn sprintf('Unrecognized parameter type of "%s".', $key); | ||||
31 | 0 | $exit_code = 1; | ||||
32 | } | |||||
33 | } | |||||
34 | } | |||||
35 | else { | |||||
36 | 0 | if (!(grep m/$_/, @valid_template_params)) { | ||||
37 | 0 | warn sprintf('Unrecognized parameter type of %s', $_); | ||||
38 | 0 | $exit_code = 1; | ||||
39 | } | |||||
40 | } | |||||
41 | 0 | return $exit_code; | ||||
42 | } | |||||
43 | ||||||
44 | sub new { | |||||
45 | 0 | my ($invocant) = shift; | ||||
46 | 0 | my $type = ref($invocant) || $invocant; | ||||
47 | 0 | my $self = { | ||||
48 | batch_id => 0, | |||||
49 | items => [], | |||||
50 | branch_code => 'NB', | |||||
51 | batch_stat => 0, # False if any data has changed and the db has not been updated | |||||
52 | @_, | |||||
53 | }; | |||||
54 | 0 | my $sth = C4::Context->dbh->prepare("SELECT MAX(batch_id) FROM creator_batches;"); | ||||
55 | 0 | $sth->execute(); | ||||
56 | 0 | my $batch_id = $sth->fetchrow_array; | ||||
57 | 0 | $self->{'batch_id'} = ++$batch_id unless $self->{'batch_id'} != 0; # this allows batch_id to be passed in for individual label printing | ||||
58 | 0 | bless ($self, $type); | ||||
59 | 0 | return $self; | ||||
60 | } | |||||
61 | ||||||
62 | sub add_item { | |||||
63 | 0 | my $self = shift; | ||||
64 | 0 | my $number = shift; | ||||
65 | 0 | ref($self) =~ m/C4::(.+)::.+$/; | ||||
66 | 0 | my $number_type = ($1 eq 'Patroncards' ? 'borrower_number' : 'item_number'); | ||||
67 | 0 | my $query = "INSERT INTO creator_batches (batch_id, $number_type, branch_code, creator) VALUES (?,?,?,?);"; | ||||
68 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
69 | # $sth->{'TraceLevel'} = 3; | |||||
70 | 0 | $sth->execute($self->{'batch_id'}, $number, $self->{'branch_code'}, $1); | ||||
71 | 0 | if ($sth->err) { | ||||
72 | 0 | warn sprintf('Database returned the following error on attempted INSERT: %s', $sth->errstr); | ||||
73 | 0 | return -1; | ||||
74 | } | |||||
75 | 0 | $query = "SELECT max(label_id) FROM creator_batches WHERE batch_id=? AND $number_type=? AND branch_code=?;"; | ||||
76 | 0 | my $sth1 = C4::Context->dbh->prepare($query); | ||||
77 | 0 | $sth1->execute($self->{'batch_id'}, $number, $self->{'branch_code'}); | ||||
78 | 0 | my $label_id = $sth1->fetchrow_array; | ||||
79 | 0 0 | push (@{$self->{'items'}}, {$number_type => $number, label_id => $label_id}); | ||||
80 | 0 | $self->{'batch_stat'} = 1; | ||||
81 | 0 | return 0; | ||||
82 | } | |||||
83 | ||||||
84 | sub get_attr { | |||||
85 | 0 | my $self = shift; | ||||
86 | 0 | return $self->{$_[0]}; | ||||
87 | } | |||||
88 | ||||||
89 | sub remove_item { | |||||
90 | 0 | my $self = shift; | ||||
91 | 0 | my $label_id = shift; | ||||
92 | 0 | my $query = "DELETE FROM creator_batches WHERE label_id=? AND batch_id=?;"; | ||||
93 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
94 | # $sth->{'TraceLevel'} = 3; | |||||
95 | 0 | $sth->execute($label_id, $self->{'batch_id'}); | ||||
96 | 0 | if ($sth->err) { | ||||
97 | 0 | warn sprintf('Database returned the following error on attempted DELETE: %s', $sth->errstr); | ||||
98 | 0 | return -1; | ||||
99 | } | |||||
100 | 0 0 0 0 | @{$self->{'items'}} = grep{$_->{'label_id'} != $label_id} @{$self->{'items'}}; | ||||
101 | 0 | $self->{'batch_stat'} = 1; | ||||
102 | 0 | return 0; | ||||
103 | } | |||||
104 | ||||||
105 | # FIXME: This method is effectively useless the way the current add_item method is written. Ideally, the items should be added to the object | |||||
106 | # and then the save method called. This does not work well in practice due to the inability to pass objects accross cgi script calls. | |||||
107 | # I'm leaving it here because it should be here and for consistency's sake and once memcached support is fully implimented this should be as well. -cnighswonger | |||||
108 | # | |||||
109 | #=head2 $batch->save() | |||||
110 | # | |||||
111 | # Invoking the I<save> method attempts to insert the batch into the database. The method returns | |||||
112 | # the new record batch_id upon success and -1 upon failure (This avoids conflicting with a record | |||||
113 | # batch_id of 1). Errors are logged to the Apache log. | |||||
114 | # | |||||
115 | # example: | |||||
116 | # my $exitstat = $batch->save(); # to save the record behind the $batch object | |||||
117 | # | |||||
118 | #=cut | |||||
119 | # | |||||
120 | #sub save { | |||||
121 | # my $self = shift; | |||||
122 | # foreach my $item_number (@{$self->{'items'}}) { | |||||
123 | # my $query = "INSERT INTO creator_batches (batch_id, item_number, branch_code) VALUES (?,?,?);"; | |||||
124 | # my $sth1 = C4::Context->dbh->prepare($query); | |||||
125 | # $sth1->execute($self->{'batch_id'}, $item_number->{'item_number'}, $self->{'branch_code'}); | |||||
126 | # if ($sth1->err) { | |||||
127 | # warn sprintf('Database returned the following error on attempted INSERT: %s', $sth1->errstr); | |||||
128 | # return -1; | |||||
129 | # } | |||||
130 | # $self->{'batch_stat'} = 1; | |||||
131 | # return $self->{'batch_id'}; | |||||
132 | # } | |||||
133 | #} | |||||
134 | ||||||
135 | sub retrieve { | |||||
136 | 0 | my $invocant = shift; | ||||
137 | 0 | my %opts = @_; | ||||
138 | 0 | my $type = ref($invocant) || $invocant; | ||||
139 | 0 | $type =~ m/C4::(.+)::.+$/; | ||||
140 | 0 | my $number_type = ($1 eq 'Patroncards' ? 'borrower_number' : 'item_number'); | ||||
141 | 0 | my $record_flag = 0; | ||||
142 | 0 | my $query = "SELECT * FROM creator_batches WHERE batch_id = ? ORDER BY label_id"; | ||||
143 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
144 | # $sth->{'TraceLevel'} = 3; | |||||
145 | 0 | $sth->execute($opts{'batch_id'}); | ||||
146 | 0 | my $self = { | ||||
147 | batch_id => $opts{'batch_id'}, | |||||
148 | items => [], | |||||
149 | }; | |||||
150 | 0 | while (my $record = $sth->fetchrow_hashref) { | ||||
151 | 0 | $self->{'branch_code'} = $record->{'branch_code'}; | ||||
152 | 0 | $self->{'creator'} = $record->{'creator'}; | ||||
153 | 0 0 | push (@{$self->{'items'}}, {$number_type => $record->{$number_type}, label_id => $record->{'label_id'}}); | ||||
154 | 0 | $record_flag = 1; # true if one or more rows were retrieved | ||||
155 | } | |||||
156 | 0 | return -2 if $record_flag == 0; # a hackish sort of way of indicating no such record exists | ||||
157 | 0 | if ($sth->err) { | ||||
158 | 0 | warn sprintf('Database returned the following error on attempted SELECT: %s', $sth->errstr); | ||||
159 | 0 | return -1; | ||||
160 | } | |||||
161 | 0 | $self->{'batch_stat'} = 1; | ||||
162 | 0 | bless ($self, $type); | ||||
163 | 0 | return $self; | ||||
164 | } | |||||
165 | ||||||
166 | sub delete { | |||||
167 | 0 | my $self = {}; | ||||
168 | 0 | my %opts = (); | ||||
169 | 0 | my $call_type = ''; | ||||
170 | 0 | my @query_params = (); | ||||
171 | 0 | if (ref($_[0])) { | ||||
172 | 0 | $self = shift; # check to see if this is a method call | ||||
173 | 0 | $call_type = 'C4::Labels::Batch->delete'; # seems hackish | ||||
174 | 0 | @query_params = ($self->{'batch_id'}, $self->{'branch_code'}); | ||||
175 | } | |||||
176 | else { | |||||
177 | 0 | shift @_; | ||||
178 | 0 | %opts = @_; | ||||
179 | 0 | $call_type = 'C4::Labels::Batch::delete'; | ||||
180 | 0 | @query_params = ($opts{'batch_id'}, $opts{'branch_code'}); | ||||
181 | } | |||||
182 | 0 | if ($query_params[0] eq '') { # If there is no template id then we cannot delete it | ||||
183 | 0 | warn sprintf('%s : Cannot delete batch as the batch id is invalid or non-existent.', $call_type); | ||||
184 | 0 | return -1; | ||||
185 | } | |||||
186 | 0 | my $query = "DELETE FROM creator_batches WHERE batch_id = ? AND branch_code =?"; | ||||
187 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
188 | # $sth->{'TraceLevel'} = 3; | |||||
189 | 0 | $sth->execute(@query_params); | ||||
190 | 0 | if ($sth->err) { | ||||
191 | 0 | warn sprintf('%s : Database returned the following error on attempted INSERT: %s', $call_type, $sth->errstr); | ||||
192 | 0 | return -1; | ||||
193 | } | |||||
194 | 0 | return 0; | ||||
195 | } | |||||
196 | ||||||
197 | sub remove_duplicates { | |||||
198 | 0 | my $self = shift; | ||||
199 | 0 | my %seen=(); | ||||
200 | 0 | my $query = "DELETE FROM creator_batches WHERE label_id = ?;"; # ORDER BY timestamp ASC LIMIT ?;"; | ||||
201 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
202 | 0 0 0 | my @duplicate_items = grep{$seen{$_->{'item_number'}}++} @{$self->{'items'}}; | ||||
203 | 0 | foreach my $item (@duplicate_items) { | ||||
204 | 0 | $sth->execute($item->{'label_id'}); | ||||
205 | 0 | if ($sth->err) { | ||||
206 | 0 | warn sprintf('Database returned the following error on attempted DELETE for label_id %s: %s', $item->{'label_id'}, $sth->errstr); | ||||
207 | 0 | return -1; | ||||
208 | } | |||||
209 | 0 | $sth->finish(); # Per DBI.pm docs: "If execute() is called on a statement handle that's still active ($sth->{Active} is true) then it should effectively call finish() to tidy up the previous execution results before starting this new execution." | ||||
210 | 0 0 0 0 | @{$self->{'items'}} = grep{$_->{'label_id'} != $item->{'label_id'}} @{$self->{'items'}}; # the correct label/item must be removed from the current batch object as well; this should be done *after* each sql DELETE in case the DELETE fails | ||||
211 | } | |||||
212 | 0 | return scalar(@duplicate_items); | ||||
213 | } | |||||
214 | ||||||
215 | 1; |