Lines 26-70
use C4::AuthoritiesMarc; # GetAuthority
Link Here
|
26 |
use CGI; |
26 |
use CGI; |
27 |
use C4::Koha; # GetItemTypes |
27 |
use C4::Koha; # GetItemTypes |
28 |
use C4::Branch; # GetBranches |
28 |
use C4::Branch; # GetBranches |
|
|
29 |
use C4::Record; |
30 |
use Getopt::Long; |
29 |
|
31 |
|
30 |
my $query = new CGI; |
32 |
my $query = new CGI; |
31 |
my $op=$query->param("op") || ''; |
33 |
|
32 |
my $filename=$query->param("filename"); |
34 |
my $commandline = 0; |
33 |
my $dbh=C4::Context->dbh; |
35 |
my $op; |
|
|
36 |
my $filename; |
37 |
my $dbh = C4::Context->dbh; |
34 |
my $marcflavour = C4::Context->preference("marcflavour"); |
38 |
my $marcflavour = C4::Context->preference("marcflavour"); |
|
|
39 |
my $clean; |
40 |
my $output_format; |
41 |
my $dont_export_items; |
42 |
my $deleted_barcodes; |
43 |
my $timestamp; |
44 |
my $record_type; |
45 |
my $help; |
35 |
|
46 |
|
36 |
my ($template, $loggedinuser, $cookie) |
47 |
# Checks if the script is called from commandline |
37 |
= get_template_and_user |
48 |
if ( scalar @ARGV > 0 ) { |
38 |
( |
49 |
|
39 |
{ |
50 |
# Getting parameters |
40 |
template_name => "tools/export.tmpl", |
51 |
$op = 'export'; |
41 |
query => $query, |
52 |
GetOptions( |
42 |
type => "intranet", |
53 |
'format=s' => \$output_format, |
43 |
authnotrequired => 0, |
54 |
'date=s' => \$timestamp, |
44 |
flagsrequired => {tools => 'export_catalog'}, |
55 |
'dont_export_items' => \$dont_export_items, |
45 |
debug => 1, |
56 |
'deleted_barcodes' => \$deleted_barcodes, |
46 |
} |
57 |
'clean' => \$clean, |
|
|
58 |
'filename=s' => \$filename, |
59 |
'record-type=s' => \$record_type, |
60 |
'help|?' => \$help |
47 |
); |
61 |
); |
|
|
62 |
$commandline = 1; |
63 |
|
64 |
|
65 |
if ($help) { |
66 |
print <<_USAGE_; |
67 |
export.pl [--format=format] [--date=date] [--record-type=TYPE] [--dont_export_items] [--deleted_barcodes] [--clean] --filename=outputfile |
68 |
|
69 |
|
70 |
--format=FORMAT FORMAT is either 'xml' or 'marc' (default) |
71 |
|
72 |
--date=DATE DATE should be entered as the 'dateformat' syspref is |
73 |
set (dd/mm/yyyy for metric, yyyy-mm-dd for iso, |
74 |
mm/dd/yyyy for us) records exported are the ones that |
75 |
have been modified since DATE |
76 |
|
77 |
--record-type=TYPE TYPE is 'bibs' or 'auths' |
78 |
|
79 |
--deleted_barcodes If used, a list of barcodes of items deleted since DATE |
80 |
is produced (or from all deleted items if no date is |
81 |
specified). Used only if TYPE is 'bibs' |
82 |
|
83 |
--clean removes NSE/NSB |
84 |
_USAGE_ |
85 |
exit; |
86 |
} |
87 |
|
88 |
# Default parameters values : |
89 |
$output_format ||= 'marc'; |
90 |
$timestamp ||= ''; |
91 |
$dont_export_items ||= 0; |
92 |
$deleted_barcodes ||= 0; |
93 |
$clean ||= 0; |
94 |
$record_type ||= "bibs"; |
48 |
|
95 |
|
49 |
my $limit_ind_branch=(C4::Context->preference('IndependantBranches') && |
96 |
# Redirect stdout |
50 |
C4::Context->userenv && |
97 |
open STDOUT, ">$filename" if $filename; |
51 |
!(C4::Context->userenv->{flags} & 1) && |
98 |
|
52 |
C4::Context->userenv->{branch}?1:0); |
99 |
} else { |
53 |
my $branches = GetBranches($limit_ind_branch); |
100 |
|
54 |
my $branch = $query->param("branch") || ''; |
101 |
$op = $query->param("op") || ''; |
55 |
if ( C4::Context->preference("IndependantBranches") && |
102 |
$filename = $query->param("filename") || 'koha.mrc'; |
56 |
!(C4::Context->userenv->{flags} & 1) ) { |
103 |
|
57 |
$branch = C4::Context->userenv->{'branch'}; |
104 |
} |
58 |
} |
105 |
|
|
|
106 |
my ($template, $loggedinuser, $cookie) = get_template_and_user( |
107 |
{ |
108 |
template_name => "tools/export.tmpl", |
109 |
query => $query, |
110 |
type => "intranet", |
111 |
authnotrequired => $commandline, |
112 |
flagsrequired => {tools => 'export_catalog'}, |
113 |
debug => 1, |
114 |
} |
115 |
); |
116 |
|
117 |
my $limit_ind_branch = ( |
118 |
C4::Context->preference('IndependantBranches') && |
119 |
C4::Context->userenv && |
120 |
!(C4::Context->userenv->{flags} & 1) && |
121 |
C4::Context->userenv->{branch} |
122 |
) ? 1 : 0; |
123 |
|
124 |
my $branch = $query->param("branch") || ''; |
125 |
if ( C4::Context->preference("IndependantBranches") && |
126 |
C4::Context->userenv && |
127 |
!(C4::Context->userenv->{flags} & 1) ) { |
128 |
$branch = C4::Context->userenv->{'branch'}; |
129 |
} |
59 |
|
130 |
|
60 |
if ($op eq "export") { |
131 |
if ($op eq "export") { |
61 |
binmode STDOUT, ':encoding(UTF-8)'; |
132 |
binmode STDOUT, ':encoding(UTF-8)'; |
62 |
print $query->header( -type => 'application/octet-stream', |
133 |
print $query->header( |
63 |
-charset => 'utf-8', |
134 |
-type => 'application/octet-stream', |
64 |
-attachment=>$filename); |
135 |
-charset => 'utf-8', |
|
|
136 |
-attachment => $filename |
137 |
) unless ($commandline); |
65 |
|
138 |
|
66 |
my $record_type = $query->param("record_type"); |
139 |
$record_type = $query->param("record_type") unless ($commandline); |
67 |
my $output_format = $query->param("output_format"); |
140 |
$output_format = $query->param("output_format") || 'marc' unless ($commandline); |
68 |
my $dont_export_fields = $query->param("dont_export_fields"); |
141 |
my $dont_export_fields = $query->param("dont_export_fields"); |
69 |
my @sql_params; |
142 |
my @sql_params; |
70 |
my $sql_query; |
143 |
my $sql_query; |
Lines 74-79
if ($op eq "export") {
Link Here
|
74 |
my $itemtype = $query->param("itemtype"); |
147 |
my $itemtype = $query->param("itemtype"); |
75 |
my $start_callnumber = $query->param("start_callnumber"); |
148 |
my $start_callnumber = $query->param("start_callnumber"); |
76 |
my $end_callnumber = $query->param("end_callnumber"); |
149 |
my $end_callnumber = $query->param("end_callnumber"); |
|
|
150 |
$timestamp = ($timestamp) ? C4::Dates->new($timestamp) : '' if ($commandline); |
77 |
my $start_accession = |
151 |
my $start_accession = |
78 |
( $query->param("start_accession") ) |
152 |
( $query->param("start_accession") ) |
79 |
? C4::Dates->new( $query->param("start_accession") ) |
153 |
? C4::Dates->new( $query->param("start_accession") ) |
Lines 82-143
if ($op eq "export") {
Link Here
|
82 |
( $query->param("end_accession") ) |
156 |
( $query->param("end_accession") ) |
83 |
? C4::Dates->new( $query->param("end_accession") ) |
157 |
? C4::Dates->new( $query->param("end_accession") ) |
84 |
: ''; |
158 |
: ''; |
85 |
my $dont_export_items = $query->param("dont_export_item"); |
159 |
$dont_export_items = $query->param("dont_export_item") unless ($commandline); |
86 |
my $strip_nonlocal_items = $query->param("strip_nonlocal_items"); |
160 |
my $strip_nonlocal_items = $query->param("strip_nonlocal_items"); |
87 |
|
161 |
|
|
|
162 |
my $biblioitemstable = ($commandline and $deleted_barcodes) |
163 |
? 'deletedbiblioitems' |
164 |
: 'biblioitems'; |
165 |
my $itemstable = ($commandline and $deleted_barcodes) |
166 |
? 'deleteditems' |
167 |
: 'items'; |
168 |
|
88 |
my $starting_authid = $query->param('starting_authid'); |
169 |
my $starting_authid = $query->param('starting_authid'); |
89 |
my $ending_authid = $query->param('ending_authid'); |
170 |
my $ending_authid = $query->param('ending_authid'); |
90 |
my $authtype = $query->param('authtype'); |
171 |
my $authtype = $query->param('authtype'); |
91 |
|
172 |
|
92 |
if ( $record_type eq 'bibs' ) { |
173 |
if ( $record_type eq 'bibs' ) { |
93 |
my $items_filter = |
174 |
if ($timestamp) { |
94 |
$branch || $start_callnumber || $end_callnumber || |
175 |
# Specific query when timestamp is used |
95 |
$start_accession || $end_accession || |
176 |
# Actually it's used only with CLI and so all previous filters |
96 |
($itemtype && C4::Context->preference('item-level_itypes')); |
177 |
# are not used. |
97 |
$sql_query = $items_filter ? |
178 |
# If one day timestamp is used via the web interface, this part will |
98 |
"SELECT DISTINCT biblioitems.biblionumber |
179 |
# certainly have to be rewrited |
99 |
FROM biblioitems JOIN items |
180 |
$sql_query = " ( |
100 |
USING (biblionumber) WHERE 1" |
181 |
SELECT biblionumber |
101 |
: |
182 |
FROM $biblioitemstable |
102 |
"SELECT biblioitems.biblionumber FROM biblioitems WHERE biblionumber >0 "; |
183 |
LEFT JOIN items USING(biblionumber) |
103 |
|
184 |
WHERE $biblioitemstable.timestamp >= ? |
104 |
if ( $StartingBiblionumber ) { |
185 |
OR items.timestamp >= ? |
105 |
$sql_query .= " AND biblioitems.biblionumber >= ? "; |
186 |
) UNION ( |
106 |
push @sql_params, $StartingBiblionumber; |
187 |
SELECT biblionumber |
107 |
} |
188 |
FROM $biblioitemstable |
|
|
189 |
LEFT JOIN deleteditems USING(biblionumber) |
190 |
WHERE $biblioitemstable.timestamp >= ? |
191 |
OR deleteditems.timestamp >= ? |
192 |
) "; |
193 |
my $ts = $timestamp->output('iso'); |
194 |
@sql_params = ($ts, $ts, $ts, $ts); |
195 |
} else { |
196 |
my $items_filter = |
197 |
$branch || $start_callnumber || $end_callnumber || |
198 |
$start_accession || $timestamp || $end_accession || |
199 |
($itemtype && C4::Context->preference('item-level_itypes')); |
200 |
$sql_query = $items_filter ? |
201 |
"SELECT DISTINCT $biblioitemstable.biblionumber |
202 |
FROM $biblioitemstable JOIN $itemstable |
203 |
USING (biblionumber) WHERE 1" |
204 |
: |
205 |
"SELECT $biblioitemstable.biblionumber FROM $biblioitemstable WHERE biblionumber >0 "; |
108 |
|
206 |
|
109 |
if ( $EndingBiblionumber ) { |
207 |
if ( $StartingBiblionumber ) { |
110 |
$sql_query .= " AND biblioitems.biblionumber <= ? "; |
208 |
$sql_query .= " AND $biblioitemstable.biblionumber >= ? "; |
111 |
push @sql_params, $EndingBiblionumber; |
209 |
push @sql_params, $StartingBiblionumber; |
112 |
} |
210 |
} |
113 |
|
211 |
|
114 |
if ($branch) { |
212 |
if ( $EndingBiblionumber ) { |
115 |
$sql_query .= " AND homebranch = ? "; |
213 |
$sql_query .= " AND $biblioitemstable.biblionumber <= ? "; |
116 |
push @sql_params, $branch; |
214 |
push @sql_params, $EndingBiblionumber; |
117 |
} |
215 |
} |
118 |
|
216 |
|
119 |
if ($start_callnumber) { |
217 |
if ($branch) { |
120 |
$sql_query .= " AND itemcallnumber <= ? "; |
218 |
$sql_query .= " AND homebranch = ? "; |
121 |
push @sql_params, $start_callnumber; |
219 |
push @sql_params, $branch; |
122 |
} |
220 |
} |
123 |
|
221 |
|
124 |
if ($end_callnumber) { |
222 |
if ($start_callnumber) { |
125 |
$sql_query .= " AND itemcallnumber >= ? "; |
223 |
$sql_query .= " AND itemcallnumber <= ? "; |
126 |
push @sql_params, $end_callnumber; |
224 |
push @sql_params, $start_callnumber; |
127 |
} |
225 |
} |
128 |
if ($start_accession) { |
|
|
129 |
$sql_query .= " AND dateaccessioned >= ? "; |
130 |
push @sql_params, $start_accession->output('iso'); |
131 |
} |
132 |
|
226 |
|
133 |
if ($end_accession) { |
227 |
if ($end_callnumber) { |
134 |
$sql_query .= " AND dateaccessioned <= ? "; |
228 |
$sql_query .= " AND itemcallnumber >= ? "; |
135 |
push @sql_params, $end_accession->output('iso'); |
229 |
push @sql_params, $end_callnumber; |
136 |
} |
230 |
} |
|
|
231 |
if ($start_accession) { |
232 |
$sql_query .= " AND dateaccessioned >= ? "; |
233 |
push @sql_params, $start_accession->output('iso'); |
234 |
} |
235 |
|
236 |
if ($end_accession) { |
237 |
$sql_query .= " AND dateaccessioned <= ? "; |
238 |
push @sql_params, $end_accession->output('iso'); |
239 |
} |
137 |
|
240 |
|
138 |
if ( $itemtype ) { |
241 |
if ( $itemtype ) { |
139 |
$sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?"; |
242 |
$sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?"; |
140 |
push @sql_params, $itemtype; |
243 |
push @sql_params, $itemtype; |
|
|
244 |
} |
141 |
} |
245 |
} |
142 |
} |
246 |
} |
143 |
elsif ( $record_type eq 'auths' ) { |
247 |
elsif ( $record_type eq 'auths' ) { |
Lines 164-224
if ($op eq "export") {
Link Here
|
164 |
$sth->execute(@sql_params); |
268 |
$sth->execute(@sql_params); |
165 |
|
269 |
|
166 |
while ( my ($recordid) = $sth->fetchrow ) { |
270 |
while ( my ($recordid) = $sth->fetchrow ) { |
167 |
my $record; |
271 |
if ( $deleted_barcodes ) { |
168 |
if ( $record_type eq 'bibs' ) { |
272 |
my $q = " |
169 |
$record = eval { GetMarcBiblio($recordid); }; |
273 |
SELECT DISTINCT barcode |
170 |
|
274 |
FROM deleteditems |
171 |
# FIXME: decide how to handle records GetMarcBiblio can't parse or retrieve |
275 |
WHERE deleteditems.biblionumber = ? |
172 |
if ($@) { |
276 |
"; |
173 |
next; |
277 |
my $sth = $dbh->prepare($q); |
|
|
278 |
$sth->execute($recordid); |
279 |
while (my $row = $sth->fetchrow_array) { |
280 |
print "$row\n"; |
174 |
} |
281 |
} |
175 |
next if not defined $record; |
282 |
} else { |
176 |
C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid ) |
283 |
my $record; |
177 |
unless $dont_export_items; |
284 |
if ( $record_type eq 'bibs' ) { |
178 |
if ( $strip_nonlocal_items || $limit_ind_branch ) { |
285 |
$record = eval { GetMarcBiblio($recordid); }; |
179 |
my ( $homebranchfield, $homebranchsubfield ) = |
286 |
|
180 |
GetMarcFromKohaField( 'items.homebranch', '' ); |
287 |
if ($@) { |
181 |
for my $itemfield ( $record->field($homebranchfield) ) { |
288 |
next; |
182 |
|
289 |
} |
183 |
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one |
290 |
next if not defined $record; |
184 |
$branch = C4::Context->userenv->{'branch'} unless $branch; |
291 |
C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid ) |
185 |
$record->delete_field($itemfield) |
292 |
unless $dont_export_items; |
186 |
if ( |
293 |
if ( $strip_nonlocal_items || $limit_ind_branch ) { |
187 |
$itemfield->subfield($homebranchsubfield) ne $branch ); |
294 |
my ( $homebranchfield, $homebranchsubfield ) = |
|
|
295 |
GetMarcFromKohaField( 'items.homebranch', '' ); |
296 |
for my $itemfield ( $record->field($homebranchfield) ) { |
297 |
|
298 |
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one |
299 |
$branch = C4::Context->userenv->{'branch'} unless $branch; |
300 |
$record->delete_field($itemfield) |
301 |
if ( |
302 |
$itemfield->subfield($homebranchsubfield) ne $branch ); |
303 |
} |
188 |
} |
304 |
} |
189 |
} |
305 |
} |
190 |
} |
306 |
elsif ( $record_type eq 'auths' ) { |
191 |
elsif ( $record_type eq 'auths' ) { |
307 |
$record = C4::AuthoritiesMarc::GetAuthority($recordid); |
192 |
$record = C4::AuthoritiesMarc::GetAuthority($recordid); |
308 |
next if not defined $record; |
193 |
next if not defined $record; |
309 |
} |
194 |
} |
|
|
195 |
|
310 |
|
196 |
if ( $dont_export_fields ) { |
311 |
if ( $dont_export_fields ) { |
197 |
my @fields = split " ", $dont_export_fields; |
312 |
my @fields = split " ", $dont_export_fields; |
198 |
foreach ( @fields ) { |
313 |
foreach ( @fields ) { |
199 |
/^(\d*)(\w)?$/; |
314 |
/^(\d*)(\w)?$/; |
200 |
my $field = $1; |
315 |
my $field = $1; |
201 |
my $subfield = $2; |
316 |
my $subfield = $2; |
202 |
# skip if this record doesn't have this field |
317 |
# skip if this record doesn't have this field |
203 |
next if not defined $record->field($field); |
318 |
next if not defined $record->field($field); |
204 |
if( $subfield ) { |
319 |
if( $subfield ) { |
205 |
$record->field($field)->delete_subfields($subfield); |
320 |
$record->field($field)->delete_subfields($subfield); |
|
|
321 |
} |
322 |
else { |
323 |
$record->delete_field($record->field($field)); |
324 |
} |
206 |
} |
325 |
} |
207 |
else { |
326 |
} |
208 |
$record->delete_field($record->field($field)); |
327 |
RemoveAllNsb($record) if ($clean); |
|
|
328 |
if ( $output_format eq "xml" ) { |
329 |
if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') { |
330 |
print $record->as_xml_record('UNIMARCAUTH'); |
331 |
} else { |
332 |
print $record->as_xml_record($marcflavour); |
209 |
} |
333 |
} |
210 |
} |
334 |
} |
211 |
} |
335 |
else { |
212 |
if ( $output_format eq "xml" ) { |
336 |
print $record->as_usmarc(); |
213 |
if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') { |
|
|
214 |
print $record->as_xml_record('UNIMARCAUTH'); |
215 |
} else { |
216 |
print $record->as_xml_record($marcflavour); |
217 |
} |
337 |
} |
218 |
} |
338 |
} |
219 |
else { |
|
|
220 |
print $record->as_usmarc(); |
221 |
} |
222 |
} |
339 |
} |
223 |
exit; |
340 |
exit; |
224 |
|
341 |
|
Lines 236-241
else {
Link Here
|
236 |
); |
353 |
); |
237 |
push @itemtypesloop, \%row; |
354 |
push @itemtypesloop, \%row; |
238 |
} |
355 |
} |
|
|
356 |
my $branches = GetBranches($limit_ind_branch); |
239 |
my @branchloop; |
357 |
my @branchloop; |
240 |
for my $thisbranch ( |
358 |
for my $thisbranch ( |
241 |
sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } |
359 |
sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } |
Lines 264-269
else {
Link Here
|
264 |
itemtypeloop => \@itemtypesloop, |
382 |
itemtypeloop => \@itemtypesloop, |
265 |
DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), |
383 |
DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), |
266 |
authtypeloop => \@authtypesloop, |
384 |
authtypeloop => \@authtypesloop, |
|
|
385 |
dont_export_fields => C4::Context->preference("DontExportFields"), |
267 |
); |
386 |
); |
268 |
|
387 |
|
269 |
output_html_with_http_headers $query, $cookie, $template->output; |
388 |
output_html_with_http_headers $query, $cookie, $template->output; |
270 |
- |
|
|