1 package OpenILS::WWW::EGCatLoader;
2 use strict; use warnings;
3 use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
4 use OpenSRF::Utils::Logger qw/$logger/;
5 use OpenILS::Utils::CStoreEditor qw/:funcs/;
6 use OpenILS::Utils::Fieldmapper;
7 use OpenILS::Application::AppUtils;
8 my $U = 'OpenILS::Application::AppUtils';
15 $ctx->{page} = 'record';
17 my $org = $self->_get_search_lib();
18 my $org_name = $ctx->{get_aou}->($org)->shortname;
19 my $pref_ou = $self->_get_pref_lib();
20 my $depth = $self->cgi->param('depth');
21 $depth = $ctx->{get_aou}->($org)->ou_type->depth
22 unless defined $depth; # can be 0
24 my $copy_depth = $self->cgi->param('copy_depth');
25 $copy_depth = $depth unless defined $copy_depth; # can be 0
26 $self->ctx->{copy_depth} = $copy_depth;
28 my $copy_limit = int($self->cgi->param('copy_limit') || 10);
29 my $copy_offset = int($self->cgi->param('copy_offset') || 0);
31 my $rec_id = $ctx->{page_args}->[0]
32 or return Apache2::Const::HTTP_BAD_REQUEST;
34 $self->get_staff_search_settings;
35 if ($ctx->{staff_saved_search_size}) {
36 $ctx->{saved_searches} = ($self->staff_load_searches)[1];
39 $self->fetch_related_search_info($rec_id);
41 # run copy retrieval in parallel to bib retrieval
43 my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
44 my $copy_rec = $cstore->request(
45 'open-ils.cstore.json_query.atomic',
46 $self->mk_copy_query($rec_id, $org, $copy_depth, $copy_limit, $copy_offset, $pref_ou)
49 my (undef, @rec_data) = $self->get_records_and_facets([$rec_id], undef, {
50 flesh => '{holdings_xml,bmp,mra,acp,acnp,acns}',
55 $ctx->{bre_id} = $rec_data[0]->{id};
56 $ctx->{marc_xml} = $rec_data[0]->{marc_xml};
58 $ctx->{copies} = $copy_rec->gather(1);
59 $ctx->{copy_limit} = $copy_limit;
60 $ctx->{copy_offset} = $copy_offset;
62 $ctx->{have_holdings_to_show} = 0;
63 $ctx->{have_mfhd_to_show} = 0;
65 $self->get_hold_copy_summary($rec_id, $org);
70 $ctx->{get_org_setting}->
71 ($org, "opac.fully_compressed_serial_holdings")
73 $ctx->{holding_summaries} =
74 $self->get_holding_summaries($rec_id, $org, $copy_depth);
76 $ctx->{have_holdings_to_show} =
77 scalar(@{$ctx->{holding_summaries}->{basic}}) ||
78 scalar(@{$ctx->{holding_summaries}->{index}}) ||
79 scalar(@{$ctx->{holding_summaries}->{supplement}});
81 $ctx->{mfhd_summaries} =
82 $self->get_mfhd_summaries($rec_id, $org, $copy_depth);
84 if ($ctx->{mfhd_summaries} && scalar(@{$ctx->{mfhd_summaries}})
86 $ctx->{have_mfhd_to_show} = 1;
92 $ctx->{marchtml} = $self->mk_marc_html($rec_id);
95 $ctx->{expanded_holdings} =
96 $self->get_expanded_holdings($rec_id, $org, $copy_depth)
97 if $ctx->{have_holdings_to_show};
100 $self->prepare_browse_call_numbers();
104 my @expand = $self->cgi->param('expand');
105 if (grep {$_ eq 'all'} @expand) {
106 $ctx->{expand_all} = 1;
107 $expandies{$_}->() for keys %expandies;
110 for my $exp (@expand) {
111 $ctx->{"expand_$exp"} = 1;
112 $expandies{$exp}->() if exists $expandies{$exp};
116 return Apache2::Const::OK;
119 # collect IDs and info on the search that lead to this details page
120 # If no search query, etc is present, we leave ctx.search_result_index == -1
121 sub fetch_related_search_info {
124 my $ctx = $self->ctx;
125 $ctx->{search_result_index} = -1;
127 $self->load_rresults(internal => 1);
129 my @search_ids = @{$ctx->{ids}};
130 return unless @search_ids;
132 for my $idx (0..$#search_ids) {
133 if ($search_ids[$idx] == $rec_id) {
134 $ctx->{prev_search_record} = $search_ids[$idx - 1] if $idx > 0;
135 $ctx->{next_search_record} = $search_ids[$idx + 1];
136 $ctx->{search_result_index} = $idx;
141 $ctx->{first_search_record} = $search_ids[0];
142 $ctx->{last_search_record} = $search_ids[-1];
151 my $copy_limit = shift;
152 my $copy_offset = shift;
157 acp => ['id', 'barcode', 'circ_lib', 'create_date', 'age_protect', 'holdable'],
159 {column => 'name', alias => 'copy_location'},
160 {column => 'holdable', alias => 'location_holdable'}
163 {column => 'name', alias => 'copy_status'},
164 {column => 'holdable', alias => 'status_holdable'}
167 {column => 'label', alias => 'call_number_label'},
168 {column => 'id', alias => 'call_number'}
170 circ => ['due_date'],
172 {column => 'label', alias => 'call_number_prefix_label'},
173 {column => 'id', alias => 'call_number_prefix'}
176 {column => 'label', alias => 'call_number_suffix_label'},
177 {column => 'id', alias => 'call_number_suffix'}
180 {column => 'label', alias => 'part_label'},
188 acnp => { fkey => 'prefix' },
189 acns => { fkey => 'suffix' }
191 filter => [{deleted => 'f'}, {record => $rec_id}],
193 circ => { # If the copy is circulating, retrieve the open circ
195 filter => {checkin_time => undef}
203 bmp => { type => 'left' }
210 '+acp' => {deleted => 'f' }
214 { class => "aou", field => 'id',
215 transform => 'evergreen.rank_ou', params => [$org]
217 {class => 'aou', field => 'name'},
218 {class => 'acn', field => 'label'},
219 { class => "acp", field => 'status',
220 transform => 'evergreen.rank_cp_status'
224 limit => $copy_limit,
225 offset => $copy_offset
228 if($org != $self->ctx->{aou_tree}->()->id) {
229 # no need to add the org join filter if we're not actually filtering
230 $query->{from}->{acp}->{aou} = {
238 transform => 'actor.org_unit_descendants',
239 result_field => 'id',
243 where => {id => $org}
250 # Filter hidden items if this is the public catalog
251 unless($self->ctx->{is_staff}) {
252 $query->{where}->{'+acp'}->{opac_visible} = 't';
253 $query->{from}->{'acp'}->{'acpl'}->{filter} = {opac_visible => 't'};
254 $query->{from}->{'acp'}->{'ccs'}->{filter} = {opac_visible => 't'};
255 $query->{where}->{'+aou'}->{opac_visible} = 't';
262 my($self, $rec_id) = @_;
264 # could be optimized considerably by performing the xslt on the already fetched record
265 return $U->simplereq(
267 'open-ils.search.biblio.record.html', $rec_id, 1);
270 sub get_holding_summaries {
271 my ($self, $rec_id, $org, $depth) = @_;
273 my $serial = create OpenSRF::AppSession("open-ils.serial");
274 my $result = $serial->request(
275 "open-ils.serial.bib.summary_statements",
276 $rec_id, {"org_id" => $org, "depth" => $depth}
283 sub get_mfhd_summaries {
284 my ($self, $rec_id, $org, $depth) = @_;
286 my $serial = create OpenSRF::AppSession("open-ils.search");
287 my $result = $serial->request(
288 "open-ils.search.serial.record.bib.retrieve",
289 $rec_id, $org, $depth
296 sub get_expanded_holdings {
297 my ($self, $rec_id, $org, $depth) = @_;
299 my $holding_limit = int($self->cgi->param("holding_limit") || 10);
300 my $holding_offset = int($self->cgi->param("holding_offset") || 0);
301 my $type = $self->cgi->param("expand_holding_type");
303 my $serial = create OpenSRF::AppSession("open-ils.serial");
304 my $result = $serial->request(
305 "open-ils.serial.received_siss.retrieve.by_bib.atomic",
307 "ou" => $org, "depth" => $depth,
308 "limit" => $holding_limit, "offset" => $holding_offset,
317 sub any_call_number_label {
320 if ($self->ctx->{copies} and @{$self->ctx->{copies}}) {
321 return $self->ctx->{copies}->[0]->{call_number_label};
327 sub prepare_browse_call_numbers {
330 my $cn = ($self->cgi->param("cn") || $self->any_call_number_label) or
333 my $org_unit = $self->ctx->{get_aou}->($self->cgi->param('loc')) ||
334 $self->ctx->{aou_tree}->();
336 my $supercat = create OpenSRF::AppSession("open-ils.supercat");
337 my $results = $supercat->request(
338 "open-ils.supercat.call_number.browse",
339 $cn, $org_unit->shortname, 9, $self->cgi->param("cnoffset")
344 $self->ctx->{browsed_call_numbers} = [
347 (new XML::LibXML)->parse_string($_->record->marc)
352 $self->ctx->{browsing_ou} = $org_unit;
355 sub get_hold_copy_summary {
356 my ($self, $rec_id, $org) = @_;
358 my $search = OpenSRF::AppSession->create('open-ils.search');
359 my $req1 = $search->request(
360 'open-ils.search.biblio.record.copy_count', $org, $rec_id);
362 $self->ctx->{record_hold_count} = $U->simplereq(
363 'open-ils.circ', 'open-ils.circ.bre.holds.count', $rec_id);
365 $self->ctx->{copy_summary} = $req1->recv->content;
370 sub load_print_record {
373 my $rec_id = $self->ctx->{page_args}->[0]
374 or return Apache2::Const::HTTP_BAD_REQUEST;
376 $self->{ctx}->{bre_id} = $rec_id;
377 $self->{ctx}->{printable_record} = $U->simplereq(
379 'open-ils.search.biblio.record.print', $rec_id);
381 return Apache2::Const::OK;
384 sub load_email_record {
387 my $rec_id = $self->ctx->{page_args}->[0]
388 or return Apache2::Const::HTTP_BAD_REQUEST;
390 $self->{ctx}->{bre_id} = $rec_id;
393 'open-ils.search.biblio.record.email',
394 $self->ctx->{authtoken}, $rec_id);
396 return Apache2::Const::OK;