1 package OpenILS::Application::Search::Serial;
2 use base qw/OpenILS::Application/;
3 use strict; use warnings;
6 use OpenSRF::Utils::JSON;
7 use OpenILS::Utils::Fieldmapper;
8 use OpenILS::Utils::MFHDParser;
9 use OpenSRF::Utils::SettingsClient;
10 use OpenILS::Utils::CStoreEditor q/:funcs/;
11 use OpenSRF::Utils::Cache;
14 use OpenSRF::Utils::Logger qw/:logger/;
18 use Time::HiRes qw(time);
19 use OpenSRF::EX qw(:try);
20 use Digest::MD5 qw(md5_hex);
25 use OpenILS::Const qw/:const/;
27 use OpenILS::Application::AppUtils;
28 my $U = "OpenILS::Application::AppUtils";
30 my $pfx = "open-ils.search_";
38 Takes an MFHD record ID and returns a hash of holdings statements
43 my ($self, $client, $id) = @_;
45 my $session = OpenSRF::AppSession->create("open-ils.cstore");
46 my $request = $session->request(
47 "open-ils.cstore.direct.serial.record_entry.retrieve", $id )->gather(1);
49 my $u = OpenILS::Utils::MFHDParser->new();
50 my $mfhd_hash = $u->generate_svr( $request->id, $request->marc, $request->owning_lib );
52 $session->disconnect();
56 __PACKAGE__->register_method(
57 method => "mfhd_to_hash",
58 api_name => "open-ils.search.serial.record.mfhd.retrieve",
60 note => "Given a serial record ID, return MFHD holdings"
65 =item * bib_to_mfhd_hash
69 Given a bib record ID, returns a hash of holdings statements
74 #sub bib_to_mfhd_hash {
75 # my ($self, $client, $bib) = @_;
79 # # XXX perhaps this? --miker
80 ## my $e = OpenILS::Utils::CStoreEditor->new();
81 ## my $mfhd = $e->search_serial_record_entry({ record => $bib });
82 ## return $u->generate_svr( $mfhd->[0] ) if (ref $mfhd);
85 # my @mfhd = $U->cstorereq( "open-ils.cstore.json_query.atomic", {
86 # select => { sre => 'marc' },
88 # where => { record => $bib, deleted => 'f' },
92 # if (!@mfhd or scalar(@mfhd) == 0) {
96 # my $u = OpenILS::Utils::MFHDParser->new();
97 # $mfhd_hash = $u->generate_svr( $mfhd[0][0]->{id}, $mfhd[0][0]->{marc}, $mfhd[0][0]->{owning_lib} );
102 #__PACKAGE__->register_method(
103 # method => "bib_to_mfhd_hash",
104 # api_name => "open-ils.search.serial.record.bib_to_mfhd.retrieve",
106 # note => "Given a bibliographic record ID, return MFHD holdings"
110 my ($self, $client, $bib, $ou, $ou_depth) = @_;
114 my $e = OpenILS::Utils::CStoreEditor->new();
117 # Get the root of the org_tree
118 my $aous = $e->search_actor_org_unit([{
122 $ou = $aous->[0]->id();
125 # ou_depth can be undef in get_org_descendants
126 my @orgs = $U->get_org_descendants($ou, $ou_depth);
128 # TODO: 'deleted' ssub support
129 my $sdists = $e->search_serial_distribution([
131 "+ssub" => {"record_entry" => $bib},
132 "holding_lib" => { "in" => @orgs }
137 'sdist' => [ "record_entry", "holding_lib", "basic_summary", "supplement_summary", "index_summary" ]
139 "join" => {"ssub" => {}}
142 my $sres = $e->search_serial_record_entry([
146 "owning_lib" => { "in" => @orgs },
147 "+sdist" => {"id" => undef}
150 "join" => { "sdist" => { 'type' => 'left' } }
153 if (!ref $sres and !ref $sdists) {
157 my $mfhd_parser = OpenILS::Utils::MFHDParser->new();
160 if ($_->summary_method ne 'use_sdist_only' and ref $_->record_entry and !$U->is_true($_->record_entry->deleted)) {
161 my $skip_all_computable = 0;
162 if ($_->summary_method eq 'merge_with_sre') { # 'computable' (85x/86x combos) are handled by generated_coverage when attempting to merge
163 $skip_all_computable = 1;
165 $svr = $mfhd_parser->generate_svr($_->record_entry->id, $_->record_entry->marc, $_->record_entry->owning_lib, $skip_all_computable);
167 $svr = Fieldmapper::serial::virtual_record->new;
168 if (ref $_->record_entry and !$U->is_true($_->record_entry->deleted)) {
169 $svr->sre_id($_->record_entry->id);
173 $svr->location($_->holding_lib->name);
174 $svr->owning_lib($_->holding_lib->id);
175 $svr->basic_holdings([]);
176 $svr->supplement_holdings([]);
177 $svr->index_holdings([]);
178 $svr->basic_holdings_add([]);
179 $svr->supplement_holdings_add([]);
180 $svr->index_holdings_add([]);
183 $svr->incomplete([]);
185 if ($_->summary_method ne 'use_sre_only') {
186 if (ref $_->basic_summary) { #TODO: 'show-generated' boolean on summaries
187 if ($_->basic_summary->generated_coverage) {
188 push(@{$svr->basic_holdings}, OpenSRF::Utils::JSON->JSON2perl($_->basic_summary->generated_coverage));
190 if ($_->basic_summary->textual_holdings) {
191 push(@{$svr->basic_holdings_add}, $_->basic_summary->textual_holdings);
194 if (ref $_->supplement_summary) {
195 if ($_->supplement_summary->generated_coverage) {
196 push(@{$svr->supplement_holdings}, OpenSRF::Utils::JSON->JSON2perl($_->supplement_summary->generated_coverage));
198 if ($_->supplement_summary->textual_holdings) {
199 push(@{$svr->supplement_holdings_add}, $_->supplement_summary->textual_holdings);
202 if (ref $_->index_summary) {
203 if ($_->index_summary->generated_coverage) {
204 push(@{$svr->index_holdings}, OpenSRF::Utils::JSON->JSON2perl($_->index_summary->generated_coverage));
206 if ($_->index_summary->textual_holdings) {
207 push(@{$svr->index_holdings_add}, $_->index_summary->textual_holdings);
214 push(@$svrs, $mfhd_parser->generate_svr($_->id, $_->marc, $_->owning_lib));
217 # do a basic location sort for simple predictability
218 @$svrs = sort { $a->location cmp $b->location } @$svrs;
223 __PACKAGE__->register_method(
224 method => "bib_to_svr",
225 api_name => "open-ils.search.serial.record.bib.retrieve",
228 desc => 'Given a bibliographic record ID, return holdings in svr form',
231 desc => 'ID of the bibliographic record to which serial holdings are attached',
236 desc => 'ID of the org_unit on which the search is based',
241 desc => 'Depth of the org tree at which the search should occur',