]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Utils/MFHDParser.pm
Tell MARC::File::XML to treat the XML as UTF8, otherwise non-ASCII characters get...
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / MFHDParser.pm
1 package OpenILS::Utils::MFHDParser;
2 use strict; use warnings;
3
4 use OpenSRF::EX qw/:try/;
5 use Time::HiRes qw(time);
6 use OpenILS::Utils::Fieldmapper;
7 use OpenSRF::Utils::SettingsClient;
8 use OpenSRF::Utils::Logger qw/$logger/;
9
10 use OpenILS::Utils::MFHD;
11 use MARC::File::XML (BinaryEncoding => 'utf8');
12 use Data::Dumper;
13
14 sub new { return bless( {}, shift() ); }
15
16 =head1 Subroutines
17
18 =over
19
20 =item * format_textual_holdings($field)
21
22 =back
23
24 Returns concatenated subfields $a with $z for textual holdings (866-868)
25
26 =cut
27
28 sub format_textual_holdings {
29         my ($self, $field) = @_;
30         my $holdings;
31         my $public_note;
32
33         $holdings = $field->subfield('a');
34         if (!$holdings) {
35                 return undef;
36         }
37
38         $public_note = $field->subfield('z');
39         if ($public_note) {
40                 return "$holdings - $public_note";
41         }
42         return $holdings;
43 }
44
45 =over
46
47 =item * mfhd_to_hash($mfhd_xml)
48
49 =back
50
51 Returns a Perl hash containing fields of interest from the MFHD record
52
53 =cut
54 sub mfhd_to_hash {
55         my ($self, $mfhd_xml) = @_;
56
57         my $location = '';
58         my $holdings = [];
59         my $supplements = [];
60         my $indexes = [];
61         my $current_holdings = [];
62         my $current_supplements = [];
63         my $current_indexes = [];
64         my $online = []; # Laurentian extension to MFHD standard
65         my $missing = []; # Laurentian extension to MFHD standard
66         my $incomplete = []; # Laurentian extension to MFHD standard
67
68         my $marc = MARC::Record->new_from_xml($mfhd_xml);
69         my $mfhd = MFHD->new($marc);
70
71         foreach my $field ($marc->field('852')) {
72                 foreach my $subfield_ref ($field->subfields) {
73                         my ($subfield, $data) = @$subfield_ref;
74                         $location .= $data . " -- ";
75                 }
76         }
77         $location =~ s/ -- $//;
78
79         foreach my $field ($marc->field('866')) {
80                 my $textual_holdings = $self->format_textual_holdings($field);
81                 if ($textual_holdings) {
82                         push @$holdings, $textual_holdings;
83                 }
84         }
85         foreach my $field ($marc->field('867')) {
86                 my $textual_holdings = $self->format_textual_holdings($field);
87                 if ($textual_holdings) {
88                         push @$supplements, $textual_holdings;
89                 }
90         }
91         foreach my $field ($marc->field('868')) {
92                 my $textual_holdings = $self->format_textual_holdings($field);
93                 if ($textual_holdings) {
94                         push @$indexes, $textual_holdings;
95                 }
96         }
97
98         foreach my $cap_id ($mfhd->captions('853')) {
99                 my @curr_holdings = $mfhd->holdings('863', $cap_id);
100                 next unless scalar @curr_holdings;
101                 foreach (@curr_holdings) {
102                         push @$current_holdings, $_->format();
103                 }
104         }
105
106         foreach my $cap_id ($mfhd->captions('854')) {
107                 my @curr_supplements = $mfhd->holdings('864', $cap_id);
108                 next unless scalar @curr_supplements;
109                 foreach (@curr_supplements) {
110                         push @$current_supplements, $_->format();
111                 }
112         }
113
114         foreach my $cap_id ($mfhd->captions('855')) {
115                 my @curr_indexes = $mfhd->holdings('865', $cap_id);
116                 next unless scalar @curr_indexes;
117                 foreach (@curr_indexes) {
118                         push @$current_indexes, $_->format();
119                 }
120         }
121
122         # Laurentian extensions
123         foreach my $field ($marc->field('530')) {
124                 my $online_stmt = $self->format_textual_holdings($field);
125                 if ($online_stmt) {
126                         push @$online, $online_stmt;
127                 }
128         }
129
130         foreach my $field ($marc->field('590')) {
131                 my $missing_stmt = $self->format_textual_holdings($field);
132                 if ($missing_stmt) {
133                         push @$missing, $missing_stmt;
134                 }
135         }
136
137         foreach my $field ($marc->field('591')) {
138                 my $incomplete_stmt = $self->format_textual_holdings($field);
139                 if ($incomplete_stmt) {
140                         push @$incomplete, $incomplete_stmt;
141                 }
142         }
143
144         return { location => $location, holdings => $holdings, current_holdings => $current_holdings,
145                         supplements => $supplements, current_supplements => $current_supplements,
146                         indexes => $indexes, current_indexes => $current_indexes,
147                         missing => $missing, incomplete => $incomplete, };
148 }
149
150 =over
151
152 =item * init_holdings_virtual_record()
153
154 =back
155
156 Initialize the serial virtual record (svr) instance
157
158 =cut
159 sub init_holdings_virtual_record {
160         my $record = Fieldmapper::serial::virtual_record->new;
161         $record->id();
162         $record->location();
163         $record->owning_lib();
164         $record->holdings([]);
165         $record->current_holdings([]);
166         $record->supplements([]);
167         $record->current_supplements([]);
168         $record->indexes([]);
169         $record->current_indexes([]);
170         $record->online([]);
171         $record->missing([]);
172         $record->incomplete([]);
173         return $record;
174 }
175
176 =over
177
178 =item * init_holdings_virtual_record($mfhd)
179
180 =back
181
182 Given an MFHD record, return a populated svr instance
183
184 =cut
185 sub generate_svr {
186         my ($self, $id, $mfhd, $owning_lib) = @_;
187
188         if (!$mfhd) {
189                 return undef;
190         }
191
192         my $record = init_holdings_virtual_record();
193         my $holdings = $self->mfhd_to_hash($mfhd);
194
195         $record->id($id);
196         $record->owning_lib($owning_lib);
197         $record->location($holdings->{location});
198         $record->holdings($holdings->{holdings});
199         $record->current_holdings($holdings->{current_holdings});
200         $record->supplements($holdings->{supplements});
201         $record->current_supplements($holdings->{current_supplements});
202         $record->indexes($holdings->{indexes});
203         $record->current_indexes($holdings->{current_indexes});
204         $record->online($holdings->{online});
205         $record->missing($holdings->{missing});
206         $record->incomplete($holdings->{incomplete});
207
208         return $record;
209 }
210
211 1;