6aef206dfada40a2e4bf9fb5620650f8377ea9a4
[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_by_barcode {
62         my $self = shift;
63         my $client = shift;
64
65         my $cn_table = asset::call_number->table;
66         my $cp_table = asset::copy->table;
67
68         my $id = ''.shift;
69         my ($r) = biblio::record_entry->db_Main->selectrow_array( <<"   SQL", {}, $id );
70                 SELECT  cn.record
71                   FROM  $cn_table cn
72                         JOIN $cp_table cp ON (cp.call_number = cn.id)
73                   WHERE cp.barcode = ?
74         SQL
75
76         my $rec = biblio::record_entry->retrieve( $r );
77
78         return $rec->to_fieldmapper if ($rec);
79         return undef;
80 }
81 __PACKAGE__->register_method(
82         api_name        => 'open-ils.storage.biblio.record_entry.retrieve_by_barcode',
83         method          => 'record_by_barcode',
84         api_level       => 1,
85         cachable        => 1,
86 );
87
88 sub record_by_copy {
89         my $self = shift;
90         my $client = shift;
91
92         my $cn_table = asset::call_number->table;
93         my $cp_table = asset::copy->table;
94
95         my $id = ''.shift;
96         my ($r) = biblio::record_entry->db_Main->selectrow_array( <<"   SQL", {}, $id );
97                 SELECT  cn.record
98                   FROM  $cn_table cn
99                         JOIN $cp_table cp ON (cp.call_number = cn.id)
100                   WHERE cp.id = ?
101         SQL
102
103         my $rec = biblio::record_entry->retrieve( $r );
104         my $r_fm = $rec->to_fieldmapper;
105         $r_fm->fixed_fields( $rec->record_descriptor->next->to_fieldmapper );
106
107         return $r_fm;
108 }
109 __PACKAGE__->register_method(
110         api_name        => 'open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy',
111         method          => 'record_by_copy',
112         api_level       => 1,
113         cachable        => 1,
114 );
115
116
117 =comment Old version
118
119 my $org_unit_lookup;
120 sub record_copy_count {
121         my $self = shift;
122         my $client = shift;
123         my $oid = shift;
124         my @recs = @_;
125
126         if ($self->api_name !~ /batch/o) {
127                 @recs = ($recs[0]);
128         }
129
130         throw OpenSRF::EX::InvalidArg ( "No org_unit id passed!" )
131                 unless ($oid);
132
133         throw OpenSRF::EX::InvalidArg ( "No record id passed!" )
134                 unless (@recs);
135
136         $org_unit_lookup ||= $self->method_lookup('open-ils.storage.direct.actor.org_unit.retrieve');
137         my ($org_unit) = $org_unit_lookup->run($oid);
138
139         # XXX Use descendancy tree here!!!
140         my $short_name_hack = $org_unit->shortname;
141         $short_name_hack = '' if (!$org_unit->parent_ou);
142         $short_name_hack .= '%';
143         # XXX Use descendancy tree here!!!
144
145         my $rec_list = join(',',@recs);
146
147         my $cp_table = asset::copy->table;
148         my $cn_table = asset::call_number->table;
149
150         my $select =<<" SQL";
151                 SELECT  count(cp.*) as copies
152                   FROM  $cn_table cn
153                         JOIN $cp_table cp ON (cp.call_number = cn.id)
154                   WHERE cn.owning_lib LIKE ? AND
155                         cn.record IN ($rec_list)
156         SQL
157
158         my $sth = asset::copy->db_Main->prepare_cached($select);
159         $sth->execute($short_name_hack);
160
161         my $results = $sth->fetchall_hashref('record');
162
163         $client->respond($$results{$_}{copies} || 0) for (@recs);
164
165         return undef;
166 }
167 __PACKAGE__->register_method(
168         method          => 'record_copy_count',
169         api_name        => 'open-ils.storage.direct.biblio.record_copy_count',
170         api_level       => 1,
171         argc            => 1,
172 );
173 __PACKAGE__->register_method(
174         method          => 'record_copy_count',
175         api_name        => 'open-ils.storage.direct.biblio.record_copy_count.batch',
176         api_level       => 1,
177         argc            => 1,
178         stream          => 1,
179 );
180
181 =cut
182
183 sub global_record_copy_count {
184         my $self = shift;
185         my $client = shift;
186
187         my $rec = shift;
188
189         my $cn_table = asset::call_number->table;
190         my $cp_table = asset::copy->table;
191         my $cl_table = asset::copy_location->table;
192         my $cs_table = config::copy_status->table;
193
194         my $copies_visible = 'AND cp.opac_visible IS TRUE AND cs.holdable IS TRUE AND cl.opac_visible IS TRUE';
195         $copies_visible = '' if ($self->api_name =~ /staff/o);
196
197         my $sql = <<"   SQL";
198
199                 SELECT  owning_lib, sum(avail), sum(tot)
200                   FROM  (
201                                 SELECT  cn.owning_lib, count(cp.id) as avail, 0 as tot
202                                   FROM  $cn_table cn
203                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
204                                         JOIN $cs_table cs ON (cs.id = cp.status)
205                                         JOIN $cl_table cl ON (cl.id = cp.location)
206                                   WHERE cn.record = ?
207                                         AND cp.status = 0
208                                         $copies_visible
209                                   GROUP BY 1
210                                                 UNION
211                                 SELECT  cn.owning_lib, 0 as avail, count(cp.id) as tot
212                                   FROM  $cn_table cn
213                                         JOIN $cp_table cp ON (cn.id = cp.call_number)
214                                         JOIN $cs_table cs ON (cs.id = cp.status)
215                                         JOIN $cl_table cl ON (cl.id = cp.location)
216                                   WHERE cn.record = ?
217                                         $copies_visible
218                                   GROUP BY 1
219                         ) x
220                   GROUP BY 1
221         SQL
222
223         my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
224         $sth->execute("$rec", "$rec");
225
226         $client->respond( $_ ) for (@{$sth->fetchall_arrayref});
227         return undef;
228 }
229 __PACKAGE__->register_method(
230         api_name        => 'open-ils.storage.biblio.record_entry.global_copy_count',
231         method          => 'global_record_copy_count',
232         api_level       => 1,
233         stream          => 1,
234         cachable        => 1,
235 );
236 __PACKAGE__->register_method(
237         api_name        => 'open-ils.storage.biblio.record_entry.global_copy_count.staff',
238         method          => 'global_record_copy_count',
239         api_level       => 1,
240         stream          => 1,
241         cachable        => 1,
242 );
243
244 sub record_copy_status_count {
245         my $self = shift;
246         my $client = shift;
247
248         my $rec = shift;
249
250         my $cn_table = asset::call_number->table;
251         my $cp_table = asset::copy->table;
252         my $cl_table = asset::copy_location->table;
253         my $cs_table = config::copy_status->table;
254
255         my $sql = <<"   SQL";
256
257                 SELECT  cp.circ_lib, cn.label, cp.status, count(cp.id)
258                   FROM  $cp_table cp,
259                         $cn_table cn,
260                         $cl_table cl,
261                         $cs_table cs
262                   WHERE cn.record = ?
263                         AND cp.call_number = cn.id
264                         AND cp.location = cl.id
265                         AND cp.status = cs.id
266                         AND cl.opac_visible IS TRUE
267                         AND cp.opac_visible IS TRUE
268                         AND cs.holdable
269                   GROUP BY 1,2,3
270                   ORDER BY 1,2,3;
271         SQL
272
273         my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
274         $sth->execute("$rec");
275
276         my ($ou,$cn) = (0,'');
277         my %data = ();
278         for my $row (@{$sth->fetchall_arrayref}) {
279                 if ($ou and $ou ne $$row[0]) {
280                         my $i = 0;
281                         $client->respond( [$ou, $cn, {%data}] );
282                         %data = ();
283                 }
284                 ($ou,$cn) = ($$row[0],$$row[1]);
285                 $data{$$row[2]} = $$row[3];
286         }
287         return [$ou, $cn, {%data}] if ($ou);
288         return undef;
289 }
290 __PACKAGE__->register_method(
291         api_name        => 'open-ils.storage.biblio.record_entry.status_copy_count',
292         method          => 'record_copy_status_count',
293         api_level       => 1,
294         stream          => 1,
295         cachable        => 1,
296 );
297
298 1;