|
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 |
- |
|
|