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