1 package OpenILS::Application::Storage::Publisher::biblio;
2 use base qw/OpenILS::Application::Storage/;
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;
11 sub record_copy_count {
17 my $cn_table = asset::call_number->table;
18 my $cp_table = asset::copy->table;
19 my $st_table = config::copy_status->table;
20 my $src_table = config::bib_source->table;
21 my $br_table = biblio::record_entry->table;
22 my $loc_table = asset::copy_location->table;
23 my $out_table = actor::org_unit_type->table;
25 my $descendants = "actor.org_unit_descendants(u.id)";
26 my $ancestors = "actor.org_unit_ancestors(?) u JOIN $out_table t ON (u.ou_type = t.id)";
28 if ($args{org_unit} < 0) {
29 $args{org_unit} *= -1;
30 $ancestors = "(select org_unit as id from actor.org_lasso_map where lasso = ?) u CROSS JOIN (SELECT -1 AS depth) t";
33 my $visible = 'AND a.opac_visible = TRUE AND st.holdable = TRUE AND loc.opac_visible = TRUE AND cp.opac_visible = TRUE';
34 if ($self->api_name =~ /staff/o) {
44 JOIN $cp_table cp ON (cn.id = cp.call_number)
45 JOIN $descendants a ON (cp.circ_lib = a.id)
46 JOIN $st_table st ON (cp.status = st.id)
47 JOIN $loc_table loc ON (cp.location = loc.id)
50 AND cn.deleted IS FALSE
51 AND cp.deleted IS FALSE)
56 JOIN $cp_table cp ON (cn.id = cp.call_number)
57 JOIN $descendants a ON (cp.circ_lib = a.id)
58 JOIN $st_table st ON (cp.status = st.id)
59 JOIN $loc_table loc ON (cp.location = loc.id)
62 AND cn.deleted IS FALSE
63 AND cp.deleted IS FALSE
64 AND cp.status IN (0,7,12))
69 JOIN $cp_table cp ON (cn.id = cp.call_number)
70 JOIN $st_table st ON (cp.status = st.id)
71 JOIN $loc_table loc ON (cp.location = loc.id)
73 AND st.holdable = TRUE
74 AND loc.opac_visible = TRUE
75 AND cp.opac_visible = TRUE
76 AND cn.deleted IS FALSE
77 AND cp.deleted IS FALSE)
82 JOIN $src_table src ON (src.id = br.source)
84 AND src.transcendant IS TRUE
91 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
92 $sth->execute(''.$args{record}, ''.$args{record}, ''.$args{record}, ''.$args{record}, ''.$args{org_unit});
93 while ( my $row = $sth->fetchrow_hashref ) {
94 $client->respond( $row );
98 __PACKAGE__->register_method(
99 api_name => 'open-ils.storage.biblio.record_entry.copy_count',
100 method => 'record_copy_count',
105 __PACKAGE__->register_method(
106 api_name => 'open-ils.storage.biblio.record_entry.copy_count.staff',
107 method => 'record_copy_count',
113 sub record_ranged_tree {
119 my $limit = shift || 0;
120 my $offset = shift || 0;
122 my $ou_sql = defined($depth) ?
123 "SELECT id FROM actor.org_unit_descendants(?,?)":
124 "SELECT id FROM actor.org_unit_descendants(?)";
129 ->selectcol_arrayref(
133 (defined($depth) ? ($depth) : ()),
136 return undef unless ($ou_list and @$ou_list);
138 $r = biblio::record_entry->retrieve( $r );
139 return undef unless ($r);
141 my $rec = $r->to_fieldmapper;
142 $rec->call_numbers([]);
144 $rec->fixed_fields( $r->record_descriptor->next->to_fieldmapper );
146 my $offset_count = 0;
148 for my $cn ( $r->call_numbers ) {
149 next if ($cn->deleted);
150 my $call_number = $cn->to_fieldmapper;
151 $call_number->copies([]);
154 for my $cp ( $cn->copies(circ_lib => $ou_list) ) {
155 next if ($cp->deleted);
156 if ($offset > 0 && $offset_count < $offset) {
161 last if ($limit > 0 && $limit_count >= $limit);
163 my $copy = $cp->to_fieldmapper;
164 $copy->status( $cp->status->to_fieldmapper );
165 $copy->location( $cp->location->to_fieldmapper );
166 push @{ $call_number->copies }, $copy;
171 last if ($limit > 0 && $limit_count >= $limit);
173 push @{ $rec->call_numbers }, $call_number if (@{ $call_number->copies });
178 __PACKAGE__->register_method(
179 api_name => 'open-ils.storage.biblio.record_entry.ranged_tree',
180 method => 'record_ranged_tree',
185 sub record_by_barcode {
189 my $cn_table = asset::call_number->table;
190 my $cp_table = asset::copy->table;
193 my ($r) = biblio::record_entry->db_Main->selectrow_array( <<" SQL", {}, $id );
196 JOIN $cp_table cp ON (cp.call_number = cn.id)
200 my $rec = biblio::record_entry->retrieve( $r );
202 return $rec->to_fieldmapper if ($rec);
205 __PACKAGE__->register_method(
206 api_name => 'open-ils.storage.biblio.record_entry.retrieve_by_barcode',
207 method => 'record_by_barcode',
216 my $cn_table = asset::call_number->table;
217 my $cp_table = asset::copy->table;
220 my ($r) = biblio::record_entry->db_Main->selectrow_array( <<" SQL", {}, $id );
223 JOIN $cp_table cp ON (cp.call_number = cn.id)
227 my $rec = biblio::record_entry->retrieve( $r );
228 return undef unless ($rec);
230 my $r_fm = $rec->to_fieldmapper;
231 my $ff = $rec->record_descriptor->next;
232 $r_fm->fixed_fields( $ff->to_fieldmapper ) if ($ff);
236 __PACKAGE__->register_method(
237 api_name => 'open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy',
238 method => 'record_by_copy',
247 sub record_copy_count {
253 if ($self->api_name !~ /batch/o) {
257 throw OpenSRF::EX::InvalidArg ( "No org_unit id passed!" )
260 throw OpenSRF::EX::InvalidArg ( "No record id passed!" )
263 $org_unit_lookup ||= $self->method_lookup('open-ils.storage.direct.actor.org_unit.retrieve');
264 my ($org_unit) = $org_unit_lookup->run($oid);
266 # XXX Use descendancy tree here!!!
267 my $short_name_hack = $org_unit->shortname;
268 $short_name_hack = '' if (!$org_unit->parent_ou);
269 $short_name_hack .= '%';
270 # XXX Use descendancy tree here!!!
272 my $rec_list = join(',',@recs);
274 my $cp_table = asset::copy->table;
275 my $cn_table = asset::call_number->table;
277 my $select =<<" SQL";
278 SELECT count(cp.*) as copies
280 JOIN $cp_table cp ON (cp.call_number = cn.id)
281 WHERE cn.owning_lib LIKE ? AND
282 cn.record IN ($rec_list)
285 my $sth = asset::copy->db_Main->prepare_cached($select);
286 $sth->execute($short_name_hack);
288 my $results = $sth->fetchall_hashref('record');
290 $client->respond($$results{$_}{copies} || 0) for (@recs);
294 __PACKAGE__->register_method(
295 method => 'record_copy_count',
296 api_name => 'open-ils.storage.direct.biblio.record_copy_count',
300 __PACKAGE__->register_method(
301 method => 'record_copy_count',
302 api_name => 'open-ils.storage.direct.biblio.record_copy_count.batch',
310 sub global_record_copy_count {
316 my $cn_table = asset::call_number->table;
317 my $cp_table = asset::copy->table;
318 my $cl_table = asset::copy_location->table;
319 my $cs_table = config::copy_status->table;
321 my $copies_visible = 'AND cp.opac_visible IS TRUE AND cs.holdable IS TRUE AND cl.opac_visible IS TRUE';
322 $copies_visible = '' if ($self->api_name =~ /staff/o);
326 SELECT owning_lib, sum(avail), sum(tot)
328 SELECT cn.owning_lib, count(cp.id) as avail, 0 as tot
330 JOIN $cp_table cp ON (cn.id = cp.call_number)
331 JOIN $cs_table cs ON (cs.id = cp.status)
332 JOIN $cl_table cl ON (cl.id = cp.location)
334 AND cp.status IN (0,7,12)
338 SELECT cn.owning_lib, 0 as avail, count(cp.id) as tot
340 JOIN $cp_table cp ON (cn.id = cp.call_number)
341 JOIN $cs_table cs ON (cs.id = cp.status)
342 JOIN $cl_table cl ON (cl.id = cp.location)
350 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
351 $sth->execute("$rec", "$rec");
353 $client->respond( $_ ) for (@{$sth->fetchall_arrayref});
356 __PACKAGE__->register_method(
357 api_name => 'open-ils.storage.biblio.record_entry.global_copy_count',
358 method => 'global_record_copy_count',
363 __PACKAGE__->register_method(
364 api_name => 'open-ils.storage.biblio.record_entry.global_copy_count.staff',
365 method => 'global_record_copy_count',
371 sub record_copy_status_count {
377 my $depth = shift || 0;
380 my $descendants = "actor.org_unit_descendants(?,?)";
382 my $cn_table = asset::call_number->table;
383 my $cp_table = asset::copy->table;
384 my $cl_table = asset::copy_location->table;
385 my $cs_table = config::copy_status->table;
389 SELECT cp.circ_lib, cn.label, cp.status, count(cp.id)
396 AND cp.call_number = cn.id
397 AND cp.location = cl.id
398 AND cp.circ_lib = d.id
399 AND cp.status = cs.id
400 AND cl.opac_visible IS TRUE
401 AND cp.opac_visible IS TRUE
402 AND cp.deleted IS FALSE
407 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
408 $sth->execute($ou, $depth, "$rec" );
411 for my $row (@{$sth->fetchall_arrayref}) {
412 $data{$$row[0]}{$$row[1]}{$$row[2]} += $$row[3];
415 for my $ou (keys %data) {
416 for my $cn (keys %{$data{$ou}}) {
417 $client->respond( [$ou, $cn, $data{$ou}{$cn}] );
422 __PACKAGE__->register_method(
423 api_name => 'open-ils.storage.biblio.record_entry.status_copy_count',
424 method => 'record_copy_status_count',