]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/biblio.pm
refactored copy targeter to use new JS copy tester; adjusted object relationships...
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher / biblio.pm
1 package OpenILS::Application::Storage::Publisher::biblio;
2 use base qw/OpenILS::Application::Storage/;
3 use vars qw/$VERSION/;
4 use OpenSRF::EX qw/:try/;
5 #use OpenILS::Application::Storage::CDBI::biblio;
6 #use OpenILS::Application::Storage::CDBI::asset;
7 use OpenILS::Utils::Fieldmapper;
8
9 $VERSION = 1;
10
11 sub record_copy_count {
12         my $self = shift;
13         my $client = shift;
14
15         my %args = @_;
16
17         my $cn_table = asset::call_number->table;
18         my $cp_table = asset::copy->table;
19         my $out_table = actor::org_unit_type->table;
20         my $descendants = "actor.org_unit_descendants(u.id)";
21         my $ancestors = "actor.org_unit_ancestors(?)";
22
23         my $sql = <<"   SQL";
24                 SELECT  t.depth,
25                         u.id AS org_unit,
26                         sum(
27                                 (SELECT count(cp.id)
28                                   FROM  $cn_table cn
29                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
30                                         JOIN $descendants a ON (cp.circ_lib = a.id)
31                                   WHERE cn.record = ?)
32                         ) AS count,
33                         sum(
34                                 (SELECT count(cp.id)
35                                   FROM  $cn_table cn
36                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
37                                         JOIN $descendants a ON (cp.circ_lib = a.id)
38                                   WHERE cn.record = ?
39                                         AND cp.status = 0)
40                         ) AS available
41                   FROM  $ancestors u
42                         JOIN $out_table t ON (u.ou_type = t.id)
43                   GROUP BY 1,2
44         SQL
45
46         my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
47         $sth->execute(''.$args{record}, ''.$args{record}, ''.$args{org_unit});
48         while ( my $row = $sth->fetchrow_hashref ) {
49                 $client->respond( $row );
50         }
51         return undef;
52 }
53 __PACKAGE__->register_method(
54         api_name        => 'open-ils.storage.biblio.record_entry.copy_count',
55         method          => 'record_copy_count',
56         api_level       => 1,
57         stream          => 1,
58         cachable        => 1,
59 );
60
61 sub record_ranged_tree {
62         my $self = shift;
63         my $client = shift;
64         my $r = shift;
65         my $ou = shift;
66         my $depth = shift || 0;
67
68         my $ou_list =
69                 actor::org_unit
70                         ->db_Main
71                         ->selectcol_arrayref(
72                                 'SELECT id FROM actor.org_unit_descendants(?,?)',
73                                 {},
74                                 $ou,
75                                 $depth
76                         );
77
78         return undef unless ($ou_list and @$ou_list);
79
80         $r = biblio::record_entry->retrieve( $r );
81         return undef unless ($r);
82
83         my $rec = $r->to_fieldmapper;
84         $rec->call_numbers([]);
85
86         $rec->fixed_fields( $r->record_descriptor->next->to_fieldmapper );
87
88         for my $cn ( $r->call_numbers  ) {
89                 my $call_number = $cn->to_fieldmapper;
90                 $call_number->copies([]);
91
92
93                 for my $cp ( $cn->copies(circ_lib => $ou_list) ) {
94                         my $copy = $cp->to_fieldmapper;
95                         $copy->status( $cp->status->to_fieldmapper );
96                         $copy->location( $cp->status->to_fieldmapper );
97
98                         push @{ $call_number->copies }, $copy;
99                 }
100
101                 push @{ $rec->call_numbers }, $call_number if (@{ $call_number->copies });
102         }
103
104         return $rec;
105 }
106 __PACKAGE__->register_method(
107         api_name        => 'open-ils.storage.biblio.record_entry.ranged_tree',
108         method          => 'record_ranged_tree',
109         argc            => 1,
110         api_level       => 1,
111 );
112
113 sub record_by_barcode {
114         my $self = shift;
115         my $client = shift;
116
117         my $cn_table = asset::call_number->table;
118         my $cp_table = asset::copy->table;
119
120         my $id = ''.shift;
121         my ($r) = biblio::record_entry->db_Main->selectrow_array( <<"   SQL", {}, $id );
122                 SELECT  cn.record
123                   FROM  $cn_table cn
124                         JOIN $cp_table cp ON (cp.call_number = cn.id)
125                   WHERE cp.barcode = ?
126         SQL
127
128         my $rec = biblio::record_entry->retrieve( $r );
129
130         return $rec->to_fieldmapper if ($rec);
131         return undef;
132 }
133 __PACKAGE__->register_method(
134         api_name        => 'open-ils.storage.biblio.record_entry.retrieve_by_barcode',
135         method          => 'record_by_barcode',
136         api_level       => 1,
137         cachable        => 1,
138 );
139
140 sub record_by_copy {
141         my $self = shift;
142         my $client = shift;
143
144         my $cn_table = asset::call_number->table;
145         my $cp_table = asset::copy->table;
146
147         my $id = ''.shift;
148         my ($r) = biblio::record_entry->db_Main->selectrow_array( <<"   SQL", {}, $id );
149                 SELECT  cn.record
150                   FROM  $cn_table cn
151                         JOIN $cp_table cp ON (cp.call_number = cn.id)
152                   WHERE cp.id = ?
153         SQL
154
155         my $rec = biblio::record_entry->retrieve( $r );
156         return undef unless ($rec);
157
158         my $r_fm = $rec->to_fieldmapper;
159         my $ff = $rec->record_descriptor->next;
160         $r_fm->fixed_fields( $ff->to_fieldmapper ) if ($ff);
161
162         return $r_fm;
163 }
164 __PACKAGE__->register_method(
165         api_name        => 'open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy',
166         method          => 'record_by_copy',
167         api_level       => 1,
168         cachable        => 1,
169 );
170
171
172 =comment Old version
173
174 my $org_unit_lookup;
175 sub record_copy_count {
176         my $self = shift;
177         my $client = shift;
178         my $oid = shift;
179         my @recs = @_;
180
181         if ($self->api_name !~ /batch/o) {
182                 @recs = ($recs[0]);
183         }
184
185         throw OpenSRF::EX::InvalidArg ( "No org_unit id passed!" )
186                 unless ($oid);
187
188         throw OpenSRF::EX::InvalidArg ( "No record id passed!" )
189                 unless (@recs);
190
191         $org_unit_lookup ||= $self->method_lookup('open-ils.storage.direct.actor.org_unit.retrieve');
192         my ($org_unit) = $org_unit_lookup->run($oid);
193
194         # XXX Use descendancy tree here!!!
195         my $short_name_hack = $org_unit->shortname;
196         $short_name_hack = '' if (!$org_unit->parent_ou);
197         $short_name_hack .= '%';
198         # XXX Use descendancy tree here!!!
199
200         my $rec_list = join(',',@recs);
201
202         my $cp_table = asset::copy->table;
203         my $cn_table = asset::call_number->table;
204
205         my $select =<<" SQL";
206                 SELECT  count(cp.*) as copies
207                   FROM  $cn_table cn
208                         JOIN $cp_table cp ON (cp.call_number = cn.id)
209                   WHERE cn.owning_lib LIKE ? AND
210                         cn.record IN ($rec_list)
211         SQL
212
213         my $sth = asset::copy->db_Main->prepare_cached($select);
214         $sth->execute($short_name_hack);
215
216         my $results = $sth->fetchall_hashref('record');
217
218         $client->respond($$results{$_}{copies} || 0) for (@recs);
219
220         return undef;
221 }
222 __PACKAGE__->register_method(
223         method          => 'record_copy_count',
224         api_name        => 'open-ils.storage.direct.biblio.record_copy_count',
225         api_level       => 1,
226         argc            => 1,
227 );
228 __PACKAGE__->register_method(
229         method          => 'record_copy_count',
230         api_name        => 'open-ils.storage.direct.biblio.record_copy_count.batch',
231         api_level       => 1,
232         argc            => 1,
233         stream          => 1,
234 );
235
236 =cut
237
238 sub global_record_copy_count {
239         my $self = shift;
240         my $client = shift;
241
242         my $rec = shift;
243
244         my $cn_table = asset::call_number->table;
245         my $cp_table = asset::copy->table;
246         my $cl_table = asset::copy_location->table;
247         my $cs_table = config::copy_status->table;
248
249         my $copies_visible = 'AND cp.opac_visible IS TRUE AND cs.holdable IS TRUE AND cl.opac_visible IS TRUE';
250         $copies_visible = '' if ($self->api_name =~ /staff/o);
251
252         my $sql = <<"   SQL";
253
254                 SELECT  owning_lib, sum(avail), sum(tot)
255                   FROM  (
256                                 SELECT  cn.owning_lib, count(cp.id) as avail, 0 as tot
257                                   FROM  $cn_table cn
258                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
259                                         JOIN $cs_table cs ON (cs.id = cp.status)
260                                         JOIN $cl_table cl ON (cl.id = cp.location)
261                                   WHERE cn.record = ?
262                                         AND cp.status = 0
263                                         $copies_visible
264                                   GROUP BY 1
265                                                 UNION
266                                 SELECT  cn.owning_lib, 0 as avail, count(cp.id) as tot
267                                   FROM  $cn_table cn
268                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
269                                         JOIN $cs_table cs ON (cs.id = cp.status)
270                                         JOIN $cl_table cl ON (cl.id = cp.location)
271                                   WHERE cn.record = ?
272                                         $copies_visible
273                                   GROUP BY 1
274                         ) x
275                   GROUP BY 1
276         SQL
277
278         my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
279         $sth->execute("$rec", "$rec");
280
281         $client->respond( $_ ) for (@{$sth->fetchall_arrayref});
282         return undef;
283 }
284 __PACKAGE__->register_method(
285         api_name        => 'open-ils.storage.biblio.record_entry.global_copy_count',
286         method          => 'global_record_copy_count',
287         api_level       => 1,
288         stream          => 1,
289         cachable        => 1,
290 );
291 __PACKAGE__->register_method(
292         api_name        => 'open-ils.storage.biblio.record_entry.global_copy_count.staff',
293         method          => 'global_record_copy_count',
294         api_level       => 1,
295         stream          => 1,
296         cachable        => 1,
297 );
298
299 sub record_copy_status_count {
300         my $self = shift;
301         my $client = shift;
302
303         my $rec = shift;
304
305         my $cn_table = asset::call_number->table;
306         my $cp_table = asset::copy->table;
307         my $cl_table = asset::copy_location->table;
308         my $cs_table = config::copy_status->table;
309
310         my $sql = <<"   SQL";
311
312                 SELECT  cp.circ_lib, cn.label, cp.status, count(cp.id)
313                   FROM  $cp_table cp,
314                         $cn_table cn,
315                         $cl_table cl,
316                         $cs_table cs
317                   WHERE cn.record = ?
318                         AND cp.call_number = cn.id
319                         AND cp.location = cl.id
320                         AND cp.status = cs.id
321                         AND cl.opac_visible IS TRUE
322                         AND cp.opac_visible IS TRUE
323                         AND cs.holdable
324                   GROUP BY 1,2,3
325                   ORDER BY 1,2,3;
326         SQL
327
328         my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
329         $sth->execute("$rec");
330
331         my ($ou,$cn) = (0,'');
332         my %data = ();
333         for my $row (@{$sth->fetchall_arrayref}) {
334                 if ($ou and $ou ne $$row[0]) {
335                         my $i = 0;
336                         $client->respond( [$ou, $cn, {%data}] );
337                         %data = ();
338                 }
339                 ($ou,$cn) = ($$row[0],$$row[1]);
340                 $data{$$row[2]} = $$row[3];
341         }
342         return [$ou, $cn, {%data}] if ($ou);
343         return undef;
344 }
345 __PACKAGE__->register_method(
346         api_name        => 'open-ils.storage.biblio.record_entry.status_copy_count',
347         method          => 'record_copy_status_count',
348         api_level       => 1,
349         stream          => 1,
350         cachable        => 1,
351 );
352
353 1;