]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Serial.pm
Fix currently harmless but still confusing sigil error
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / Search / Serial.pm
1 package OpenILS::Application::Search::Serial;
2 use base qw/OpenILS::Application/;
3 use strict; use warnings;
4
5
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;
12 use Encode;
13
14 use OpenSRF::Utils::Logger qw/:logger/;
15
16 use Data::Dumper;
17
18 use Time::HiRes qw(time);
19 use OpenSRF::EX qw(:try);
20 use Digest::MD5 qw(md5_hex);
21
22 use XML::LibXML;
23 use XML::LibXSLT;
24
25 use OpenILS::Const qw/:const/;
26
27 use OpenILS::Application::AppUtils;
28 my $U = "OpenILS::Application::AppUtils";
29
30 my $pfx = "open-ils.search_";
31
32 =over
33
34 =item * mfhd_to_hash
35
36 =back
37
38 Takes an MFHD record ID and returns a hash of holdings statements
39
40 =cut
41
42 sub mfhd_to_hash {
43     my ($self, $client, $id) = @_;
44     
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);
48
49     my $u = OpenILS::Utils::MFHDParser->new();
50     my $mfhd_hash = $u->generate_svr( $request->id, $request->marc, $request->owning_lib );
51
52     $session->disconnect();
53     return $mfhd_hash;
54 }
55
56 __PACKAGE__->register_method(
57     method  => "mfhd_to_hash",
58     api_name    => "open-ils.search.serial.record.mfhd.retrieve",
59     argc        => 1, 
60     note        => "Given a serial record ID, return MFHD holdings"
61 );
62
63 =over
64
65 =item * bib_to_mfhd_hash 
66
67 =back
68
69 Given a bib record ID, returns a hash of holdings statements
70
71 =cut
72
73 # DEFUNCT ?
74 #sub bib_to_mfhd_hash {
75 #   my ($self, $client, $bib) = @_;
76 #   
77 #   my $mfhd_hash;
78 #
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);
83 ##  return undef;
84 #
85 #   my @mfhd = $U->cstorereq( "open-ils.cstore.json_query.atomic", {
86 #       select  => { sre => 'marc' },
87 #       from    => 'sre',
88 #       where   => { record => $bib, deleted => 'f' },
89 #       distinct => 1
90 #   });
91 #   
92 #   if (!@mfhd or scalar(@mfhd) == 0) {
93 #       return undef;
94 #   }
95 #
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} );
98 #
99 #   return $mfhd_hash;
100 #}
101 #
102 #__PACKAGE__->register_method(
103 #   method  => "bib_to_mfhd_hash",
104 #   api_name    => "open-ils.search.serial.record.bib_to_mfhd.retrieve",
105 #   argc        => 1, 
106 #   note        => "Given a bibliographic record ID, return MFHD holdings"
107 #);
108
109 sub bib_to_svr {
110     my ($self, $client, $bib, $ou, $ou_depth) = @_;
111     
112     my $svrs = [];
113
114     my $e = OpenILS::Utils::CStoreEditor->new();
115
116     if (!$ou) {
117         # Get the root of the org_tree
118         my $aous = $e->search_actor_org_unit([{
119             "parent_ou" => undef
120         }]); 
121
122         $ou = $aous->[0]->id();
123     }
124
125     # ou_depth can be undef in get_org_descendants
126     my $orgs = $U->get_org_descendants($ou, $ou_depth);
127
128     # TODO: 'deleted' ssub support
129     my $sdists = $e->search_serial_distribution([
130         {
131             "+ssub" => {"record_entry" => $bib},
132             "holding_lib" => { "in" => $orgs }
133         },
134         {
135             "flesh" => 1,
136             "flesh_fields" => {
137                 'sdist' => [ "record_entry", "holding_lib", "basic_summary", "supplement_summary", "index_summary" ]
138             },
139             "join" => {"ssub" => {}}
140         }
141     ]);
142     my $sres = $e->search_serial_record_entry([
143         {
144             record => $bib,
145             deleted => 'f',
146             "owning_lib" => { "in" => $orgs },
147             "+sdist" => {"id" => undef}
148         },
149         {
150             "join" => { "sdist" => { 'type' => 'left' } } 
151         }
152     ]);
153     if (!ref $sres and !ref $sdists) {
154         return undef;
155     }
156
157     my $mfhd_parser = OpenILS::Utils::MFHDParser->new();
158     foreach (@$sdists) {
159         my $svr;
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;
164             }
165             $svr = $mfhd_parser->generate_svr($_->record_entry->id, $_->record_entry->marc, $_->record_entry->owning_lib, $skip_all_computable);
166         } else {
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);
170             } else {
171                 $svr->sre_id(-1);
172             }
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([]);
181             $svr->online([]);
182             $svr->missing([]);
183             $svr->incomplete([]);
184         }
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));
189                 }
190                 if ($_->basic_summary->textual_holdings) {
191                     push(@{$svr->basic_holdings_add}, $_->basic_summary->textual_holdings);
192                 }
193             }
194             if (ref $_->supplement_summary) {
195                 if ($_->supplement_summary->generated_coverage) {
196                     push(@{$svr->supplement_holdings}, OpenSRF::Utils::JSON->JSON2perl($_->supplement_summary->generated_coverage));
197                 }
198                 if ($_->supplement_summary->textual_holdings) {
199                     push(@{$svr->supplement_holdings_add}, $_->supplement_summary->textual_holdings);
200                 }
201             }
202             if (ref $_->index_summary) {
203                 if ($_->index_summary->generated_coverage) {
204                     push(@{$svr->index_holdings}, OpenSRF::Utils::JSON->JSON2perl($_->index_summary->generated_coverage));
205                 }
206                 if ($_->index_summary->textual_holdings) {
207                     push(@{$svr->index_holdings_add}, $_->index_summary->textual_holdings);
208                 }
209             }
210         }
211         push(@$svrs, $svr);
212     }
213     foreach (@$sres) {
214         push(@$svrs, $mfhd_parser->generate_svr($_->id, $_->marc, $_->owning_lib));
215     }
216
217     # do a basic location sort for simple predictability
218     @$svrs = sort { $a->location cmp $b->location } @$svrs;
219
220     return $svrs;
221 }
222
223 __PACKAGE__->register_method(
224     method  => "bib_to_svr",
225     api_name    => "open-ils.search.serial.record.bib.retrieve",
226     argc        => 1, 
227     signature => {
228         desc   => 'Given a bibliographic record ID, return holdings in svr form',
229         params => [
230             {   name => 'bibid',
231                 desc => 'ID of the bibliographic record to which serial holdings are attached',
232                 type => 'number'
233             },
234             {
235                 name => 'ou',
236                 desc => 'ID of the org_unit on which the search is based',
237                 type => 'number'
238             },
239             {
240                 name => 'ou_depth',
241                 desc => 'Depth of the org tree at which the search should occur', 
242                 type => 'number'
243             }
244         ]
245     }
246 );
247
248 1;