View | Details | Raw Unified | Return to bug 5600
Collapse All | Expand All

(-)a/C4/Biblio.pm (+45 lines)
Lines 104-109 BEGIN { Link Here
104
      &ModBiblio
104
      &ModBiblio
105
      &ModBiblioframework
105
      &ModBiblioframework
106
      &ModZebra
106
      &ModZebra
107
      &RemoveAllNsb
107
    );
108
    );
108
109
109
    # To delete something
110
    # To delete something
Lines 3825-3830 sub prepare_host_field { Link Here
3825
    return;
3826
    return;
3826
}
3827
}
3827
3828
3829
=head2 RemoveAllNsb
3830
3831
    &RemoveAllNsb($record);
3832
3833
Removes all nsb/nse chars from a record
3834
3835
=cut
3836
3837
sub RemoveAllNsb {
3838
    my $record = shift;
3839
3840
    SetUTF8Flag($record);
3841
3842
    foreach my $field ($record->fields()) {
3843
        if ($field->is_control_field()) {
3844
            $field->update(nsb_clean($field->data()));
3845
        } else {
3846
            my @subfields = $field->subfields();
3847
            my @new_subfields;
3848
            foreach my $subfield (@subfields) {
3849
                push @new_subfields, $subfield->[0] => nsb_clean($subfield->[1]);
3850
            }
3851
            if (scalar(@new_subfields) > 0) {
3852
                my $new_field;
3853
                eval {
3854
                    $new_field = MARC::Field->new(
3855
                        $field->tag(),
3856
                        $field->indicator(1),
3857
                        $field->indicator(2),
3858
                        @new_subfields
3859
                    );
3860
                };
3861
                if ($@) {
3862
                    warn "error in RemoveAllNsb : $@";
3863
                } else {
3864
                    $field->replace_with($new_field);
3865
                }
3866
            }
3867
        }
3868
    }
3869
3870
    return $record;
3871
}
3872
3828
1;
3873
1;
3829
3874
3830
3875
(-)a/tools/export.pl (-66 / +169 lines)
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
    }
47
71
48
	my $limit_ind_branch=(C4::Context->preference('IndependantBranches') &&
72
    # Default parameters values :
49
              C4::Context->userenv &&
73
    $output_format     ||= 'marc';
50
              !(C4::Context->userenv->{flags} & 1) &&
74
    $timestamp         ||= '';
51
              C4::Context->userenv->{branch}?1:0);
75
    $dont_export_items ||= 0;
52
	my $branches = GetBranches($limit_ind_branch);    
76
    $deleted_barcodes  ||= 0;
53
    my $branch                = $query->param("branch") || '';
77
    $clean             ||= 0;
54
	if ( C4::Context->preference("IndependantBranches") &&
78
    $filename          ||= "koha.mrc";
55
         !(C4::Context->userenv->{flags} & 1) ) {
79
56
    	$branch = C4::Context->userenv->{'branch'};
80
    # Redirect stdout
57
	}
81
    open STDOUT, ">$filename";
82
83
} else {
84
85
    $op          = $query->param("op") || '';
86
    $filename    = $query->param("filename") || 'koha.mrc';
87
88
}
89
90
91
my $limit_ind_branch = (
92
    C4::Context->preference('IndependantBranches') &&
93
    C4::Context->userenv &&
94
    !(C4::Context->userenv->{flags} & 1) &&
95
    C4::Context->userenv->{branch}
96
) ? 1 : 0;
97
98
my $branch = $query->param("branch") || '';
99
if ( C4::Context->preference("IndependantBranches") &&
100
     !(C4::Context->userenv->{flags} & 1) ) {
101
    $branch = C4::Context->userenv->{'branch'};
102
}
58
103
59
if ($op eq "export") {
104
if ($op eq "export") {
60
    binmode STDOUT, ':encoding(UTF-8)';
105
    binmode STDOUT, ':encoding(UTF-8)';
61
	print $query->header(   -type => 'application/octet-stream', 
106
    print $query->header(
62
                            -charset => 'utf-8',
107
        -type => 'application/octet-stream',
63
                            -attachment=>$filename);
108
        -charset => 'utf-8',
64
     
109
        -attachment => $filename
110
    ) unless ($commandline);
111
65
    my $StartingBiblionumber  = $query->param("StartingBiblionumber");
112
    my $StartingBiblionumber  = $query->param("StartingBiblionumber");
66
    my $EndingBiblionumber    = $query->param("EndingBiblionumber");
113
    my $EndingBiblionumber    = $query->param("EndingBiblionumber");
67
    my $output_format         = $query->param("output_format");
114
    $output_format            = $query->param("output_format") || 'marc' unless ($commandline);
68
    my $itemtype              = $query->param("itemtype");
115
    my $itemtype              = $query->param("itemtype");
69
    my $start_callnumber      = $query->param("start_callnumber");
116
    my $start_callnumber      = $query->param("start_callnumber");
70
    my $end_callnumber        = $query->param("end_callnumber");
117
    my $end_callnumber        = $query->param("end_callnumber");
118
    if ($commandline) {
119
        $timestamp = ($timestamp) ? C4::Dates->new($timestamp) : '';
120
    }
71
    my $start_accession      = ($query->param("start_accession")) ? C4::Dates->new($query->param("start_accession")) : '' ;
121
    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")) : '' ;
122
    my $end_accession        = ($query->param("end_accession")) ? C4::Dates->new($query->param("end_accession")) : '' ;
73
    my $dont_export_items     = $query->param("dont_export_item");
123
    $dont_export_items       = $query->param("dont_export_item") unless ($commandline);
74
    my $strip_nonlocal_items   = $query->param("strip_nonlocal_items");
124
    my $strip_nonlocal_items = $query->param("strip_nonlocal_items");
75
    my $dont_export_fields    = $query->param("dont_export_fields");
125
    my $dont_export_fields   = $query->param("dont_export_fields");
126
    my $export_only_borrowed = $query->param("export_only_borrowed");
127
    my $borrowernumber       = $query->param("borrowernumber");
128
    my $biblioitemstable     = ($commandline and $deleted_barcodes) ? 'deletedbiblioitems' : 'biblioitems';
129
    my $itemstable           = ($commandline and $deleted_barcodes) ? 'deleteditems' : 'items';
130
76
    my @sql_params;
131
    my @sql_params;
77
    
132
78
    my $items_filter =
133
    my $items_filter =
79
        $branch || $start_callnumber || $end_callnumber ||  
134
        $branch || $start_callnumber || $end_callnumber ||
80
        $start_accession || $end_accession || 
135
        $start_accession || $timestamp || $end_accession ||
81
        ($itemtype && C4::Context->preference('item-level_itypes'));
136
        ($itemtype && C4::Context->preference('item-level_itypes'));
82
    my $query = $items_filter ?
137
    my $q = $items_filter ?
83
        "SELECT DISTINCT biblioitems.biblionumber
138
        "SELECT DISTINCT $biblioitemstable.biblionumber
84
         FROM biblioitems JOIN items
139
        FROM $biblioitemstable JOIN $itemstable
85
         USING (biblionumber) WHERE 1"
140
        USING (biblionumber) WHERE 1"
86
        :
141
    :
87
        "SELECT biblioitems.biblionumber FROM biblioitems WHERE biblionumber >0 ";
142
        "SELECT $biblioitemstable.biblionumber FROM $biblioitemstable WHERE biblionumber >0 ";
88
                  
143
89
    if ( $StartingBiblionumber ) {
144
    if ( $StartingBiblionumber ) {
90
        $query .= " AND biblioitems.biblionumber >= ? ";
145
        $q .= " AND $biblioitemstable.biblionumber >= ? ";
91
        push @sql_params, $StartingBiblionumber;
146
        push @sql_params, $StartingBiblionumber;
92
    }
147
    }
93
    
148
94
    if ( $EndingBiblionumber ) {
149
    if ( $EndingBiblionumber ) {
95
        $query .= " AND biblioitems.biblionumber <= ? ";
150
        $q .= " AND $biblioitemstable.biblionumber <= ? ";
96
        push @sql_params, $EndingBiblionumber;    
151
        push @sql_params, $EndingBiblionumber;
97
    }
152
    }
98
153
99
    if ($branch) {
154
    if ($branch) {
100
        $query .= " AND homebranch = ? ";
155
        $q .= " AND homebranch = ? ";
101
        push @sql_params, $branch;
156
        push @sql_params, $branch;
102
    }
157
    }
103
158
104
    if ($start_callnumber) {
159
    if ($start_callnumber) {
105
        $query .= " AND itemcallnumber <= ? ";
160
        $q .= " AND itemcallnumber <= ? ";
106
        push @sql_params, $start_callnumber;
161
        push @sql_params, $start_callnumber;
107
    }
162
    }
108
163
109
    if ($end_callnumber) {
164
    if ($end_callnumber) {
110
        $query .= " AND itemcallnumber >= ? ";
165
        $q .= " AND itemcallnumber >= ? ";
111
        push @sql_params, $end_callnumber;
166
        push @sql_params, $end_callnumber;
112
    }
167
    }
113
    if ($start_accession) {
168
    if ($start_accession) {
114
        $query .= " AND dateaccessioned >= ? ";
169
        $q .= " AND dateaccessioned >= ? ";
115
        push @sql_params, $start_accession->output('iso');
170
        push @sql_params, $start_accession->output('iso');
116
    }
171
    }
117
172
118
    if ($end_accession) {
173
    if ($end_accession) {
119
        $query .= " AND dateaccessioned <= ? ";
174
        $q .= " AND dateaccessioned <= ? ";
120
        push @sql_params, $end_accession->output('iso');
175
        push @sql_params, $end_accession->output('iso');
121
    }
176
    }
122
    
177
123
    if ( $itemtype ) {
178
    if ( $itemtype ) {
124
        $query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?";
179
        $q .= (C4::Context->preference('item-level_itypes')) ? " AND $itemstable.itype = ? " : " AND $biblioitemstable.itemtype = ?";
125
        push @sql_params, $itemtype;
180
        push @sql_params, $itemtype;
126
    }
181
    }
127
    my $sth = $dbh->prepare($query);
182
183
    # Specific query when timestamp is used
184
    # Actually it's used only with CLI and so all previous filters
185
    # are not used.
186
    # If one day timestamp is used via the web interface, this part will
187
    # certainly have to be rewrited
188
    if ($timestamp) {
189
        $q = " (
190
            SELECT biblionumber
191
            FROM $biblioitemstable
192
              JOIN items USING(biblionumber)
193
            WHERE $biblioitemstable.timestamp >= ?
194
              OR items.timestamp >= ?
195
        ) UNION (
196
            SELECT biblionumber
197
            FROM $biblioitemstable
198
              JOIN deleteditems USING(biblionumber)
199
            WHERE $biblioitemstable.timestamp >= ?
200
              OR deleteditems.timestamp >= ?
201
        ) ";
202
        my $ts = $timestamp->output('iso');
203
        @sql_params = ($ts, $ts, $ts, $ts);
204
    }
205
206
    my $sth = $dbh->prepare($q);
128
    $sth->execute(@sql_params);
207
    $sth->execute(@sql_params);
129
    
208
130
    while (my ($biblionumber) = $sth->fetchrow) {
209
    while (my ($biblionumber) = $sth->fetchrow) {
210
211
        if ( $deleted_barcodes ) {
212
            my $q = "SELECT DISTINCT barcode from deleteditems where deleteditems.biblionumber = ?";
213
            my $sth = $dbh->prepare($q);
214
            $sth->execute($biblionumber);
215
            while (my $row = $sth->fetchrow_array) {
216
                print $row . "\n";
217
            }
218
            next;
219
        }
220
131
        my $record = eval{ GetMarcBiblio($biblionumber); };
221
        my $record = eval{ GetMarcBiblio($biblionumber); };
132
        # FIXME: decide how to handle records GetMarcBiblio can't parse or retrieve
222
        # FIXME: decide how to handle records GetMarcBiblio can't parse or retrieve
133
        if ($@) {
223
        if ($@) {
Lines 135-150 if ($op eq "export") { Link Here
135
        }
225
        }
136
        next if not defined $record;
226
        next if not defined $record;
137
        C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) unless $dont_export_items;
227
        C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) unless $dont_export_items;
138
        if ($strip_nonlocal_items || $limit_ind_branch) {
228
        if ( $dont_export_items || $strip_nonlocal_items || $limit_ind_branch) {
139
            my ( $homebranchfield, $homebranchsubfield ) =
229
            my ( $homebranchfield, $homebranchsubfield ) =
140
                GetMarcFromKohaField( 'items.homebranch', '' );
230
                GetMarcFromKohaField( 'items.homebranch', '' );
141
			for my $itemfield ($record->field($homebranchfield)){
231
            for my $itemfield ($record->field($homebranchfield)){
142
				# if stripping nonlocal items, use loggedinuser's branch if they didn't select one
232
                # if stripping nonlocal items, use loggedinuser's branch if they didn't select one
143
				$branch = C4::Context->userenv->{'branch'} unless $branch;
233
                if ($strip_nonlocal_items) {
144
                $record->delete_field($itemfield) if($itemfield->subfield($homebranchsubfield) ne $branch) ;
234
                    $branch = C4::Context->userenv->{'branch'} unless $branch;
235
                }
236
                $record->delete_field($itemfield) if($dont_export_items || ($branch ne '' && $itemfield->subfield($homebranchsubfield) ne $branch) );
145
            }
237
            }
146
        }
238
        }
147
        
239
148
        if ( $dont_export_fields ) {
240
        if ( $dont_export_fields ) {
149
            my @fields = split " ", $dont_export_fields;
241
            my @fields = split " ", $dont_export_fields;
150
            foreach ( @fields ) {
242
            foreach ( @fields ) {
Lines 161-178 if ($op eq "export") { Link Here
161
                }
253
                }
162
            }
254
            }
163
        }
255
        }
256
        RemoveAllNsb($record) if ($clean);
164
        if ( $output_format eq "xml" ) {
257
        if ( $output_format eq "xml" ) {
165
            print $record->as_xml_record($marcflavour);
258
            print $record->as_xml_record($marcflavour);
166
        }
259
        }
167
        else {
260
        else {
168
            print $record->as_usmarc(); 
261
            print $record->as_usmarc();
169
        }
262
        }
170
    }
263
    }
171
    exit;
264
    exit;
172
    
173
} # if export
265
} # if export
174
266
175
else {
267
else {
268
    my ($template, $loggedinuser, $cookie) = get_template_and_user(
269
        {
270
            template_name => "tools/export.tmpl",
271
            query => $query,
272
            type => "intranet",
273
            authnotrequired => $commandline,
274
            flagsrequired => {tools => 'export_catalog'},
275
            debug => 1,
276
        }
277
    );
176
278
177
    my $itemtypes = GetItemTypes;
279
    my $itemtypes = GetItemTypes;
178
    my @itemtypesloop;
280
    my @itemtypesloop;
Lines 184-189 else { Link Here
184
            );
286
            );
185
       push @itemtypesloop, \%row;
287
       push @itemtypesloop, \%row;
186
    }
288
    }
289
    my $branches = GetBranches($limit_ind_branch);
187
    my @branchloop;
290
    my @branchloop;
188
    for my $thisbranch (
291
    for my $thisbranch (
189
        sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} }
292
        sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} }
Lines 199-206 else { Link Here
199
    $template->param(
302
    $template->param(
200
        branchloop   => \@branchloop,
303
        branchloop   => \@branchloop,
201
        itemtypeloop => \@itemtypesloop,
304
        itemtypeloop => \@itemtypesloop,
202
		DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
305
        DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
306
        dont_export_fields        => C4::Context->preference("DontExportFields"),
203
    );
307
    );
204
    
308
205
    output_html_with_http_headers $query, $cookie, $template->output;
309
    output_html_with_http_headers $query, $cookie, $template->output;
206
}
310
}
207
- 

Return to bug 5600