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.opac_visible = 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
52 AND loc.deleted IS FALSE)
57 JOIN $cp_table cp ON (cn.id = cp.call_number)
58 JOIN $descendants a ON (cp.circ_lib = a.id)
59 JOIN $st_table st ON (cp.status = st.id)
60 JOIN $loc_table loc ON (cp.location = loc.id)
63 AND cn.deleted IS FALSE
64 AND cp.deleted IS FALSE
65 AND loc.deleted IS FALSE
66 AND cp.status IN (0,7,12))
71 JOIN $cp_table cp ON (cn.id = cp.call_number)
72 JOIN $st_table st ON (cp.status = st.id)
73 JOIN $loc_table loc ON (cp.location = loc.id)
75 AND st.opac_visible = TRUE
76 AND loc.opac_visible = TRUE
77 AND cp.opac_visible = TRUE
78 AND cn.deleted IS FALSE
79 AND cp.deleted IS FALSE
80 AND loc.deleted IS FALSE)
85 JOIN $src_table src ON (src.id = br.source)
87 AND src.transcendant IS TRUE
94 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
95 $sth->execute(''.$args{record}, ''.$args{record}, ''.$args{record}, ''.$args{record}, ''.$args{org_unit});
96 while ( my $row = $sth->fetchrow_hashref ) {
97 $client->respond( $row );
101 __PACKAGE__->register_method(
102 api_name => 'open-ils.storage.biblio.record_entry.copy_count',
103 method => 'record_copy_count',
108 __PACKAGE__->register_method(
109 api_name => 'open-ils.storage.biblio.record_entry.copy_count.staff',
110 method => 'record_copy_count',
116 sub record_ranged_tree {
122 my $limit = shift || 0;
123 my $offset = shift || 0;
125 my $ou_sql = defined($depth) ?
126 "SELECT id FROM actor.org_unit_descendants(?,?)":
127 "SELECT id FROM actor.org_unit_descendants(?)";
132 ->selectcol_arrayref(
136 (defined($depth) ? ($depth) : ()),
139 return undef unless ($ou_list and @$ou_list);
141 $r = biblio::record_entry->retrieve( $r );
142 return undef unless ($r);
144 my $rec = $r->to_fieldmapper;
145 $rec->call_numbers([]);
147 $rec->fixed_fields( $r->record_descriptor->next->to_fieldmapper );
149 my $offset_count = 0;
151 for my $cn ( $r->call_numbers ) {
152 next if ($cn->deleted);
153 my $call_number = $cn->to_fieldmapper;
154 $call_number->copies([]);
157 for my $cp ( $cn->copies(circ_lib => $ou_list) ) {
158 next if ($cp->deleted);
159 if ($offset > 0 && $offset_count < $offset) {
164 last if ($limit > 0 && $limit_count >= $limit);
166 my $copy = $cp->to_fieldmapper;
167 $copy->status( $cp->status->to_fieldmapper );
168 $copy->location( $cp->location->to_fieldmapper );
169 push @{ $call_number->copies }, $copy;
174 last if ($limit > 0 && $limit_count >= $limit);
176 push @{ $rec->call_numbers }, $call_number if (@{ $call_number->copies });
181 __PACKAGE__->register_method(
182 api_name => 'open-ils.storage.biblio.record_entry.ranged_tree',
183 method => 'record_ranged_tree',
188 sub record_by_barcode {
192 my $cn_table = asset::call_number->table;
193 my $cp_table = asset::copy->table;
196 my ($r) = biblio::record_entry->db_Main->selectrow_array( <<" SQL", {}, $id );
199 JOIN $cp_table cp ON (cp.call_number = cn.id)
203 my $rec = biblio::record_entry->retrieve( $r );
205 return $rec->to_fieldmapper if ($rec);
208 __PACKAGE__->register_method(
209 api_name => 'open-ils.storage.biblio.record_entry.retrieve_by_barcode',
210 method => 'record_by_barcode',
219 my $cn_table = asset::call_number->table;
220 my $cp_table = asset::copy->table;
223 my ($r) = biblio::record_entry->db_Main->selectrow_array( <<" SQL", {}, $id );
226 JOIN $cp_table cp ON (cp.call_number = cn.id)
230 my $rec = biblio::record_entry->retrieve( $r );
231 return undef unless ($rec);
233 my $r_fm = $rec->to_fieldmapper;
234 my $ff = $rec->record_descriptor->next;
235 $r_fm->fixed_fields( $ff->to_fieldmapper ) if ($ff);
239 __PACKAGE__->register_method(
240 api_name => 'open-ils.storage.fleshed.biblio.record_entry.retrieve_by_copy',
241 method => 'record_by_copy',
247 =head1 comment Old version
250 sub record_copy_count {
256 if ($self->api_name !~ /batch/o) {
260 throw OpenSRF::EX::InvalidArg ( "No org_unit id passed!" )
263 throw OpenSRF::EX::InvalidArg ( "No record id passed!" )
266 $org_unit_lookup ||= $self->method_lookup('open-ils.storage.direct.actor.org_unit.retrieve');
267 my ($org_unit) = $org_unit_lookup->run($oid);
269 # XXX Use descendancy tree here!!!
270 my $short_name_hack = $org_unit->shortname;
271 $short_name_hack = '' if (!$org_unit->parent_ou);
272 $short_name_hack .= '%';
273 # XXX Use descendancy tree here!!!
275 my $rec_list = join(',',@recs);
277 my $cp_table = asset::copy->table;
278 my $cn_table = asset::call_number->table;
280 my $select =<<" SQL";
281 SELECT count(cp.*) as copies
283 JOIN $cp_table cp ON (cp.call_number = cn.id)
284 WHERE cn.owning_lib LIKE ? AND
285 cn.record IN ($rec_list)
288 my $sth = asset::copy->db_Main->prepare_cached($select);
289 $sth->execute($short_name_hack);
291 my $results = $sth->fetchall_hashref('record');
293 $client->respond($$results{$_}{copies} || 0) for (@recs);
297 __PACKAGE__->register_method(
298 method => 'record_copy_count',
299 api_name => 'open-ils.storage.direct.biblio.record_copy_count',
303 __PACKAGE__->register_method(
304 method => 'record_copy_count',
305 api_name => 'open-ils.storage.direct.biblio.record_copy_count.batch',
313 sub global_record_copy_count {
319 my $cn_table = asset::call_number->table;
320 my $cp_table = asset::copy->table;
321 my $cl_table = asset::copy_location->table;
322 my $cs_table = config::copy_status->table;
324 my $copies_visible = 'AND cp.opac_visible IS TRUE AND cs.opac_visible IS TRUE AND cl.opac_visible IS TRUE';
325 $copies_visible = '' if ($self->api_name =~ /staff/o);
329 SELECT owning_lib, sum(avail), sum(tot)
331 SELECT cn.owning_lib, count(cp.id) as avail, 0 as tot
333 JOIN $cp_table cp ON (cn.id = cp.call_number)
334 JOIN $cs_table cs ON (cs.id = cp.status)
335 JOIN $cl_table cl ON (cl.id = cp.location)
337 AND cp.status IN (0,7,12)
341 SELECT cn.owning_lib, 0 as avail, count(cp.id) as tot
343 JOIN $cp_table cp ON (cn.id = cp.call_number)
344 JOIN $cs_table cs ON (cs.id = cp.status)
345 JOIN $cl_table cl ON (cl.id = cp.location)
353 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
354 $sth->execute("$rec", "$rec");
356 $client->respond( $_ ) for (@{$sth->fetchall_arrayref});
359 __PACKAGE__->register_method(
360 api_name => 'open-ils.storage.biblio.record_entry.global_copy_count',
361 method => 'global_record_copy_count',
366 __PACKAGE__->register_method(
367 api_name => 'open-ils.storage.biblio.record_entry.global_copy_count.staff',
368 method => 'global_record_copy_count',
374 sub record_copy_status_count {
380 my $depth = shift || 0;
383 my $descendants = "actor.org_unit_descendants(?,?)";
385 my $cn_table = asset::call_number->table;
386 my $cnp_table = asset::call_number_prefix->table;
387 my $cns_table = asset::call_number_suffix->table;
388 my $cp_table = asset::copy->table;
389 my $cl_table = asset::copy_location->table;
390 my $cs_table = config::copy_status->table;
395 CASE WHEN cnp.id > -1 THEN cnp.label ELSE '' END,
397 CASE WHEN cns.id > -1 THEN cns.label ELSE '' END,
408 AND cnp.id = cn.prefix
409 AND cns.id = cn.suffix
410 AND cp.call_number = cn.id
411 AND cp.location = cl.id
412 AND cp.circ_lib = d.id
413 AND cp.status = cs.id
414 AND cl.opac_visible IS TRUE
415 AND cp.opac_visible IS TRUE
416 AND cp.deleted IS FALSE
417 AND cl.deleted IS FALSE
418 AND cs.opac_visible IS TRUE
422 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
423 $sth->execute($ou, $depth, "$rec" );
426 for my $row (@{$sth->fetchall_arrayref}) {
427 $data{$$row[0]}{$$row[1]}{$$row[2]}{$$row[3]}{$$row[4]} += $$row[5];
430 for my $ou (keys %data) {
431 for my $cn_prefix (keys %{$data{$ou}}) {
432 for my $cn (keys %{$data{$ou}{$cn_prefix}}) {
433 for my $cn_suffix (keys %{$data{$ou}{$cn_prefix}{$cn}}) {
434 $client->respond( [$ou, $cn_prefix, $cn, $cn_suffix, $data{$ou}{$cn}{$cn_prefix}{$cn}{$cn_suffix}] );
441 __PACKAGE__->register_method(
442 api_name => 'open-ils.storage.biblio.record_entry.status_copy_count',
443 method => 'record_copy_status_count',
450 sub record_copy_status_location_count {
456 my $depth = shift || 0;
459 my $descendants = "actor.org_unit_descendants(?,?)";
461 my $cn_table = asset::call_number->table;
462 my $cnp_table = asset::call_number_prefix->table;
463 my $cns_table = asset::call_number_suffix->table;
464 my $cp_table = asset::copy->table;
465 my $cl_table = asset::copy_location->table;
466 my $cs_table = config::copy_status->table;
468 # FIXME using oils_i18n_xlate here is exposing a hitherto unexposed
469 # implementation detail of json_query; doing it this way because
470 # json_query currently doesn't grok joining a function to tables
474 CASE WHEN cnp.id > -1 THEN cnp.label ELSE '' END,
476 CASE WHEN cns.id > -1 THEN cns.label ELSE '' END,
477 oils_i18n_xlate('asset.copy_location', 'acpl', 'name', 'id', cl.id::TEXT, ?),
488 AND cnp.id = cn.prefix
489 AND cns.id = cn.suffix
490 AND cp.call_number = cn.id
491 AND cp.location = cl.id
492 AND cp.circ_lib = d.id
493 AND cp.status = cs.id
494 AND cl.opac_visible IS TRUE
495 AND cp.opac_visible IS TRUE
496 AND cp.deleted IS FALSE
497 AND cl.deleted IS FALSE
498 AND cs.opac_visible IS TRUE
499 GROUP BY 1,2,3,4,5,6;
502 my $sth = biblio::record_entry->db_Main->prepare_cached($sql);
503 my $ses_locale = $client->session ? $client->session->session_locale : 'en-US';
504 $sth->execute($ses_locale, $ou, $depth, "$rec" );
507 for my $row (@{$sth->fetchall_arrayref}) {
508 $data{$$row[0]}{$$row[1]}{$$row[2]}{$$row[3]}{$$row[4]}{$$row[5]} += $$row[6];
511 for my $ou (keys %data) {
512 for my $cn_prefix (keys %{$data{$ou}}) {
513 for my $cn (keys %{$data{$ou}{$cn_prefix}}) {
514 for my $cn_suffix (keys %{$data{$ou}{$cn_prefix}{$cn}}) {
515 for my $cl (keys %{$data{$ou}{$cn_prefix}{$cn}{$cn_suffix}}) {
516 $client->respond( [$ou, $cn_prefix, $cn, $cn_suffix, $cl, $data{$ou}{$cn_prefix}{$cn}{$cn_suffix}{$cl}] );
524 __PACKAGE__->register_method(
525 api_name => 'open-ils.storage.biblio.record_entry.status_copy_location_count',
526 method => 'record_copy_status_location_count',