Bug 15451: Koha::CsvProfiles - Remove GetCsvProfileId
[koha.git] / misc / export_records.pl
1 #!/usr/bin/perl
2
3 #
4 # This file is part of Koha.
5 #
6 # Koha is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # Koha is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Koha; if not, see <http://www.gnu.org/licenses>.
18
19 use Modern::Perl;
20 use MARC::File::XML;
21 use List::MoreUtils qw(uniq);
22 use Getopt::Long;
23 use Pod::Usage;
24
25 use C4::Auth;
26 use C4::Context;
27 use C4::Csv;
28 use C4::Record;
29
30 use Koha::Biblioitems;
31 use Koha::Database;
32 use Koha::CsvProfiles;
33 use Koha::Exporter::Record;
34 use Koha::DateUtils qw( dt_from_string output_pref );
35
36 my ( $output_format, $timestamp, $dont_export_items, $csv_profile_id, $deleted_barcodes, $clean, $filename, $record_type, $id_list_file, $starting_authid, $ending_authid, $authtype, $starting_biblionumber, $ending_biblionumber, $itemtype, $starting_callnumber, $ending_callnumber, $start_accession, $end_accession, $help );
37 GetOptions(
38     'format=s'                => \$output_format,
39     'date=s'                  => \$timestamp,
40     'dont_export_items'       => \$dont_export_items,
41     'csv_profile_id=s'        => \$csv_profile_id,
42     'deleted_barcodes'        => \$deleted_barcodes,
43     'clean'                   => \$clean,
44     'filename=s'              => \$filename,
45     'record-type=s'           => \$record_type,
46     'id_list_file=s'          => \$id_list_file,
47     'starting_authid=s'       => \$starting_authid,
48     'ending_authid=s'         => \$ending_authid,
49     'authtype=s'              => \$authtype,
50     'starting_biblionumber=s' => \$starting_biblionumber,
51     'ending_biblionumber=s'   => \$ending_biblionumber,
52     'itemtype=s'              => \$itemtype,
53     'starting_callnumber=s'   => \$starting_callnumber,
54     'ending_callnumber=s'     => \$ending_callnumber,
55     'start_accession=s'       => \$start_accession,
56     'end_accession=s'         => \$end_accession,
57     'h|help|?'                => \$help
58 ) || pod2usage(1);
59
60 if ($help) {
61     pod2usage(1);
62 }
63
64 $filename ||= 'koha.mrc';
65 $output_format ||= 'iso2709';
66 $record_type ||= 'bibs';
67
68 # Retrocompatibility for the format parameter
69 $output_format = 'iso2709' if $output_format eq 'marc';
70
71 if ( $output_format eq 'csv' and $record_type eq 'auths' ) {
72     pod2usage(q|CSV output is only available for biblio records|);
73 }
74
75
76 if ( $timestamp and $record_type ne 'bibs' ) {
77     pod2usage(q|--timestamp can only be used with biblios|);
78 }
79
80 if ( $record_type ne 'bibs' and $record_type ne 'auths' ) {
81     pod2usage(q|--record_type is not valid|);
82 }
83
84 if ( $deleted_barcodes and $record_type ne 'bibs' ) {
85     pod2usage(q|--deleted_barcodes can only be used with biblios|);
86 }
87
88 $start_accession = dt_from_string( $start_accession ) if $start_accession;
89 $end_accession   = dt_from_string( $end_accession )   if $end_accession;
90
91 my $dbh = C4::Context->dbh;
92
93 # Redirect stdout
94 open STDOUT, '>', $filename if $filename;
95
96
97 my @record_ids;
98
99 $timestamp = ($timestamp) ? output_pref({ dt => dt_from_string($timestamp), dateformat => 'iso', dateonly => 1, }): '';
100
101 if ( $record_type eq 'bibs' ) {
102     if ( $timestamp ) {
103         push @record_ids, $_->{biblionumber} for @{
104             $dbh->selectall_arrayref(q| (
105                 SELECT biblionumber
106                 FROM biblioitems
107                   LEFT JOIN items USING(biblionumber)
108                 WHERE biblioitems.timestamp >= ?
109                   OR items.timestamp >= ?
110             ) UNION (
111                 SELECT biblionumber
112                 FROM biblioitems
113                   LEFT JOIN deleteditems USING(biblionumber)
114                 WHERE biblioitems.timestamp >= ?
115                   OR deleteditems.timestamp >= ?
116             ) |, { Slice => {} }, ( $timestamp ) x 4 );
117         };
118     } else {
119         my $conditions = {
120             ( $starting_biblionumber or $ending_biblionumber )
121                 ? (
122                     "me.biblionumber" => {
123                         ( $starting_biblionumber ? ( '>=' => $starting_biblionumber ) : () ),
124                         ( $ending_biblionumber   ? ( '<=' => $ending_biblionumber   ) : () ),
125                     }
126                 )
127                 : (),
128             ( $starting_callnumber or $ending_callnumber )
129                 ? (
130                     callnumber => {
131                         ( $starting_callnumber ? ( '>=' => $starting_callnumber ) : () ),
132                         ( $ending_callnumber   ? ( '<=' => $ending_callnumber   ) : () ),
133                     }
134                 )
135                 : (),
136             ( $start_accession or $end_accession )
137                 ? (
138                     dateaccessioned => {
139                         ( $start_accession ? ( '>=' => $start_accession ) : () ),
140                         ( $end_accession   ? ( '<=' => $end_accession   ) : () ),
141                     }
142                 )
143                 : (),
144             ( $itemtype
145                 ?
146                   C4::Context->preference('item-level_itypes')
147                     ? ( 'items.itype' => $itemtype )
148                     : ( 'biblioitems.itemtype' => $itemtype )
149                 : ()
150             ),
151
152         };
153         my $biblioitems = Koha::Biblioitems->search( $conditions, { join => 'items' } );
154         while ( my $biblioitem = $biblioitems->next ) {
155             push @record_ids, $biblioitem->biblionumber;
156         }
157     }
158 }
159 elsif ( $record_type eq 'auths' ) {
160     my $conditions = {
161         ( $starting_authid or $ending_authid )
162             ? (
163                 authid => {
164                     ( $starting_authid ? ( '>=' => $starting_authid ) : () ),
165                     ( $ending_authid   ? ( '<=' => $ending_authid   ) : () ),
166                 }
167             )
168             : (),
169         ( $authtype ? ( authtypecode => $authtype ) : () ),
170     };
171     # Koha::MetadataRecord::Authority is not a Koha::Object...
172     my $authorities = Koha::Database->new->schema->resultset('AuthHeader')->search( $conditions );
173     @record_ids = map { $_->authid } $authorities->all;
174 }
175
176 @record_ids = uniq @record_ids;
177 if ( @record_ids and $id_list_file ) {
178     open my $fh, '<', $id_list_file or die "Cannot open file $id_list_file ($!)";
179     my @filter_record_ids = <$fh>;
180     @filter_record_ids = map { my $id = $_; $id =~ s/[\r\n]*$//; $id } @filter_record_ids;
181     # intersection
182     my %record_ids = map { $_ => 1 } @record_ids;
183     @record_ids = grep $record_ids{$_}, @filter_record_ids;
184 }
185
186 if ($deleted_barcodes) {
187     for my $record_id ( @record_ids ) {
188         my $q = q|
189         |;
190         my $barcode = $dbh->selectall_arrayref(q| (
191             SELECT DISTINCT barcode
192             FROM deleteditems
193             WHERE deleteditems.biblionumber = ?
194         |, { Slice => {} }, $record_id );
195         say $_->{barcode} for @$barcode
196     }
197 }
198 else {
199     unless ( $csv_profile_id ) {
200         my $default_csv_profile = Koha::CsvProfiles->search({ profile => C4::Context->preference('ExportWithCsvProfile') });
201         $csv_profile_id = $default_csv_profile ? $default_csv_profile->export_format_id : undef;
202     }
203     Koha::Exporter::Record::export(
204         {   record_type        => $record_type,
205             record_ids         => \@record_ids,
206             format             => $output_format,
207             csv_profile_id     => $csv_profile_id,
208             export_items       => (not $dont_export_items),
209             clean              => $clean || 0,
210         }
211     );
212 }
213 exit;
214
215
216 =head1 NAME
217
218 export records - This script exports record (biblios or authorities)
219
220 =head1 SYNOPSIS
221
222 export_records.pl [-h|--help] [--format=format] [--date=date] [--record-type=TYPE] [--dont_export_items] [--deleted_barcodes] [--clean] [--id_list_file=PATH] --filename=outputfile
223
224 =head1 OPTIONS
225
226 =over
227
228 =item B<-h|--help>
229
230 Print a brief help message.
231
232 =item B<--format>
233
234  --format=FORMAT        FORMAT is either 'xml', 'csv' (biblio records only) or 'marc' (default).
235
236 =item B<--date>
237
238  --date=DATE            DATE should be entered as the 'dateformat' syspref is
239                         set (dd/mm/yyyy for metric, yyyy-mm-dd for iso,
240                         mm/dd/yyyy for us) records exported are the ones that
241                         have been modified since DATE.
242
243 =item B<--record-type>
244
245  --record-type=TYPE     TYPE is 'bibs' or 'auths'.
246
247 =item B<--dont_export_items>
248
249  --dont_export_items    If enabled, the item infos won't be exported.
250
251 =item B<--csv_profile_id>
252
253  --csv_profile_id=ID    Generate a CSV file with the given CSV profile id (see tools/csv-profiles.pl)
254                         Unless provided, the one defined in the system preference 'ExportWithCsvProfile' will be used.
255                         This can only be used to export biblio records.
256
257 =item B<--deleted_barcodes>
258
259  --deleted_barcodes     If used, a list of barcodes of items deleted since DATE
260                         is produced (or from all deleted items if no date is
261                         specified). Used only if TYPE is 'bibs'.
262
263 =item B<--clean>
264
265  --clean                removes NSE/NSB.
266
267 =item B<--id_list_file>
268
269  --id_list_file=PATH    PATH is a path to a file containing a list of
270                         IDs (biblionumber or authid) with one ID per line.
271                         This list works as a filter; it is compatible with
272                         other parameters for selecting records.
273
274 =item B<--filename>
275
276  --filename=FILENAME   FILENAME used to export the data.
277
278 =item B<--starting_authid>
279
280  --starting_authid=ID  Export authorities with authid >= ID
281
282 =item B<--ending_authid>
283
284  --ending_authid=ID    Export authorities with authid <= ID
285
286 =item B<--authtype>
287
288  --authtype=AUTHTYPE   Export authorities from the given AUTHTYPE
289
290 =item B<--starting_biblionumber>
291
292  --starting_biblionumber=ID  Export biblio with biblionumber >= ID
293
294 =item B<--ending_biblionumber>
295
296  --ending_biblionumber=ID    Export biblio with biblionumber <= ID
297
298 =item B<--itemtype>
299
300  --itemtype=ITEMTYPE         Export biblio from the given ITEMTYPE
301
302 =item B<--starting_callnumber>
303
304  --starting_callnumber=CALLNUMBER Export biblio with callnumber >=CALLNUMBER
305
306 =item B<--ending_callnumber>
307
308  --ending_callnumber=CALLNUMBER Export biblio with callnumber <=CALLNUMBER
309
310 =item B<--start_accession>
311
312  --starting_accession=DATE      Export biblio with an item accessionned after DATE
313
314 =item B<--end_accession>
315
316  --end_accession=DATE           Export biblio with an item accessionned after DATE
317
318 =back
319
320 =head1 AUTHOR
321
322 Koha Development Team
323
324 =head1 COPYRIGHT
325
326 Copyright Koha Team
327
328 =head1 LICENSE
329
330 This file is part of Koha.
331
332 Koha is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
333 Foundation; either version 3 of the License, or (at your option) any later version.
334
335 You should have received a copy of the GNU General Public License along
336 with Koha; if not, write to the Free Software Foundation, Inc.,
337 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
338
339 =cut