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

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tt (-41 / +48 lines)
Lines 23-34 Link Here
23
[% IF ( uploadborrowers ) %]
23
[% IF ( uploadborrowers ) %]
24
<h5>Import results :</h5>
24
<h5>Import results :</h5>
25
<ul>
25
<ul>
26
	<li>[% imported %] imported records [% IF ( lastimported ) %](last was [% lastimported %])[% END %]</li>
26
    <li>[% imported %] imported records [% IF ( lastimported ) %](last was [% lastimported %])[% END %]</li>
27
	<li>[% overwritten %] overwritten [% IF ( lastoverwritten ) %](last was [% lastoverwritten %])[% END %]</li>
27
    <li>[% overwritten %] overwritten [% IF ( lastoverwritten ) %](last was [% lastoverwritten %])[% END %]</li>
28
	<li>[% alreadyindb %] not imported because already in borrowers table and overwrite disabled [% IF ( lastalreadyindb ) %](last was [% lastalreadyindb %])[% END %]</li>
28
    <li>[% alreadyindb %] not imported because already in borrowers table and overwrite disabled [% IF ( lastalreadyindb ) %](last was [% lastalreadyindb %])[% END %]</li>
29
	<li>[% invalid %] not imported because they are not in the expected format [% IF ( lastinvalid ) %](last was [% lastinvalid %])[% END %]</li>
29
    <li>[% invalid %] not imported because they are not in the expected format [% IF ( lastinvalid ) %](last was [% lastinvalid %])[% END %]</li>
30
	<li>[% total %] records parsed</li>
30
    <li>[% total %] records parsed</li>
31
	<li><a href="/cgi-bin/koha/tools/tools-home.pl">Back to Tools</a></li>
31
    <li><a href="/cgi-bin/koha/tools/tools-home.pl">Back to Tools</a></li>
32
</ul>
32
</ul>
33
  [% IF ( FEEDBACK ) %]
33
  [% IF ( FEEDBACK ) %]
34
  <br /><br />
34
  <br /><br />
Lines 48-76 Link Here
48
    </div>
48
    </div>
49
  [% END %]
49
  [% END %]
50
  [% IF ( ERRORS ) %]
50
  [% IF ( ERRORS ) %]
51
  <br /><br />
52
    <div>
51
    <div>
53
    <h5>Error analysis:</h5>
52
    <h5>Error analysis:</h5>
54
    <ul>
53
    [% IF download_errors %]
55
    [% FOREACH ERROR IN ERRORS %]
54
      <form method="post">
55
        <input type="hidden" name="errors_filename" value="[% errors_filename %]" />
56
        <input type="hidden" name="report" value="report" />
57
        <input type="submit" value="Download report" />
58
      </form>
59
    [% ELSE %]
60
      <ul>
61
      [% FOREACH ERROR IN ERRORS %]
56
        [% IF ( ERROR.badheader ) %]<li>Header row could not be parsed</li>[% END %]
62
        [% IF ( ERROR.badheader ) %]<li>Header row could not be parsed</li>[% END %]
57
        [% FOREACH missing_critical IN ERROR.missing_criticals %]
63
          [% FOREACH missing_critical IN ERROR.missing_criticals %]
58
        <li class="line_error">
64
          <li class="line_error">
59
            Line <span class="linenumber">[% missing_critical.line %]</span>
65
              Line <span class="linenumber">[% missing_critical.line %]</span>
60
            [% IF ( missing_critical.badparse ) %]
66
              [% IF ( missing_critical.badparse ) %]
61
                could not be parsed!
67
                  could not be parsed!
62
            [% ELSIF ( missing_critical.bad_date ) %]
68
              [% ELSIF ( missing_critical.bad_date ) %]
63
                has &quot;[% missing_critical.key %]&quot; in unrecognized format: &quot;[% missing_critical.value %]&quot;
69
                  has &quot;[% missing_critical.key %]&quot; in unrecognized format: &quot;[% missing_critical.value %]&quot;
64
            [% ELSE %]
70
              [% ELSE %]
65
                Critical field &quot;[% missing_critical.key %]&quot;
71
                  Critical field &quot;[% missing_critical.key %]&quot;
66
                [% IF ( missing_critical.branch_map ) %]has unrecognized value &quot;[% missing_critical.value %]&quot;
72
                  [% IF ( missing_critical.branch_map ) %]has unrecognized value &quot;[% missing_critical.value %]&quot;
67
                [% ELSIF ( missing_critical.category_map ) %]has unrecognized value &quot;[% missing_critical.value %]&quot;
73
                  [% ELSIF ( missing_critical.category_map ) %]has unrecognized value &quot;[% missing_critical.value %]&quot;
68
                [% ELSE %]missing
74
                  [% ELSE %]missing
69
                [% END %]
75
                  [% END %]
70
                (borrowernumber: [% missing_critical.borrowernumber %]; surname: [% missing_critical.surname %]).
76
                  (borrowernumber: [% missing_critical.borrowernumber %]; surname: [% missing_critical.surname %]).
71
            [% END %]
77
              [% END %]
72
            <br /><code>[% missing_critical.lineraw %]</code>
78
              <br /><code>[% missing_critical.lineraw %]</code>
73
        </li>
79
          </li>
74
        [% END %]
80
        [% END %]
75
        [% IF ERROR.invalid_cardnumber %]
81
        [% IF ERROR.invalid_cardnumber %]
76
            <li class="line_error">
82
            <li class="line_error">
Lines 80-100 Link Here
80
        [% END %]
86
        [% END %]
81
    [% END %]
87
    [% END %]
82
    </ul>
88
    </ul>
89
    [% END %]
83
    </div>
90
    </div>
84
  [% END %]
91
  [% END %]
85
[% ELSE %]
92
[% ELSE %]
86
<ul>
93
<ul>
87
	<li>Select a file to import into the borrowers table</li>
94
    <li>Select a file to import into the borrowers table</li>
88
	<li>If a cardnumber exists in the table, you can choose whether to ignore the new one or overwrite the old one.</li>
95
    <li>If a cardnumber exists in the table, you can choose whether to ignore the new one or overwrite the old one.</li>
89
</ul>
96
</ul>
90
<form method="post" action="[% SCRIPT_NAME %]" enctype="multipart/form-data">
97
<form method="post" action="[% SCRIPT_NAME %]" enctype="multipart/form-data">
91
<fieldset class="rows">
98
<fieldset class="rows">
92
<legend>Import into the borrowers table</legend>
99
<legend>Import into the borrowers table</legend>
93
<ol>
100
<ol>
94
	<li>
101
    <li>
95
		<label for="uploadborrowers">Select the file to import: </label>
102
        <label for="uploadborrowers">Select the file to import: </label>
96
		<input type="file" id="uploadborrowers" name="uploadborrowers" />
103
        <input type="file" id="uploadborrowers" name="uploadborrowers" />
97
	</li>
104
    </li>
98
</ol></fieldset>
105
</ol></fieldset>
99
    <fieldset class="rows">
106
    <fieldset class="rows">
100
        <legend>Field to use for record matching</legend>
107
        <legend>Field to use for record matching</legend>
Lines 113-137 Link Here
113
<legend>Default values</legend>
120
<legend>Default values</legend>
114
<ol>
121
<ol>
115
    [% FOREACH columnkey IN columnkeys %]
122
    [% FOREACH columnkey IN columnkeys %]
116
	<li>
123
    <li>
117
        <label class="widelabel" for="[% columnkey.key %]">[% columnkey.key %]: </label>
124
        <label class="widelabel" for="[% columnkey.key %]">[% columnkey.key %]: </label>
118
		<input id="[% columnkey.key %]" name="[% columnkey.key %]" />
125
        <input id="[% columnkey.key %]" name="[% columnkey.key %]" />
119
	</li>
126
    </li>
120
    [% END %]
127
    [% END %]
121
</ol></fieldset>
128
</ol></fieldset>
122
	<fieldset class="rows">
129
    <fieldset class="rows">
123
	<legend>If matching record is already in the borrowers table:</legend>
130
    <legend>If matching record is already in the borrowers table:</legend>
124
    <ol><li class="radio">
131
    <ol><li class="radio">
125
        <input type="radio" id="overwrite_cardnumberno" name="overwrite_cardnumber" value="0" checked="checked" /><label for="overwrite_cardnumberno">Ignore this one, keep the existing one</label>
132
        <input type="radio" id="overwrite_cardnumberno" name="overwrite_cardnumber" value="0" checked="checked" /><label for="overwrite_cardnumberno">Ignore this one, keep the existing one</label>
126
        </li>
133
        </li>
127
        <li class="radio">
134
        <li class="radio">
128
		<input type="radio" id="overwrite_cardnumberyes" name="overwrite_cardnumber" value="1" /><label for="overwrite_cardnumberyes">Overwrite the existing one with this</label>
135
        <input type="radio" id="overwrite_cardnumberyes" name="overwrite_cardnumber" value="1" /><label for="overwrite_cardnumberyes">Overwrite the existing one with this</label>
129
        </li>
136
        </li>
130
    </ol>
137
    </ol>
131
    </fieldset>
138
    </fieldset>
132
    [% IF ( ExtendedPatronAttributes ) %]
139
    [% IF ( ExtendedPatronAttributes ) %]
133
	<fieldset class="rows">
140
    <fieldset class="rows">
134
	<legend>Patron Attributes</legend>
141
    <legend>Patron Attributes</legend>
135
    <ol><li class="radio">
142
    <ol><li class="radio">
136
        <input type="radio" id="ext_preserve_0" name="ext_preserve" value="0" checked="checked" /><label for="ext_preserve_0">Replace all Patron Attributes</label>
143
        <input type="radio" id="ext_preserve_0" name="ext_preserve" value="0" checked="checked" /><label for="ext_preserve_0">Replace all Patron Attributes</label>
137
        </li>
144
        </li>
Lines 141-147 Link Here
141
    </ol>
148
    </ol>
142
    </fieldset>
149
    </fieldset>
143
    [% END %]
150
    [% END %]
144
	<fieldset class="action"><input type="submit" value="Import" /></fieldset>
151
    <fieldset class="action"><input type="submit" value="Import" /></fieldset>
145
</form>
152
</form>
146
[% END %]
153
[% END %]
147
</div>
154
</div>
(-)a/tools/import_borrowers.pl (-33 / +104 lines)
Lines 1-7 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
2
3
# Copyright 2007 Liblime
3
# Copyright 2007 Liblime
4
# Parts copyright 2010 BibLibre
4
# Parts copyright 2013 BibLibre
5
#
5
#
6
# This file is part of Koha.
6
# This file is part of Koha.
7
#
7
#
Lines 34-41 Link Here
34
# dates should be in the format you have set up Koha to expect
34
# dates should be in the format you have set up Koha to expect
35
# branchcode and categorycode need to be valid
35
# branchcode and categorycode need to be valid
36
36
37
use strict;
37
use Modern::Perl;
38
use warnings;
39
38
40
use C4::Auth;
39
use C4::Auth;
41
use C4::Output;
40
use C4::Output;
Lines 46-53 use C4::Members; Link Here
46
use C4::Members::Attributes qw(:all);
45
use C4::Members::Attributes qw(:all);
47
use C4::Members::AttributeTypes;
46
use C4::Members::AttributeTypes;
48
use C4::Members::Messaging;
47
use C4::Members::Messaging;
49
48
use Koha::DateUtils;
49
use Date::Calc qw(Today_and_Now);
50
use Getopt::Long;
51
use File::Temp;
50
use Text::CSV;
52
use Text::CSV;
53
51
# Text::CSV::Unicode, even in binary mode, fails to parse lines with these diacriticals:
54
# Text::CSV::Unicode, even in binary mode, fails to parse lines with these diacriticals:
52
# ė
55
# ė
53
# č
56
# č
Lines 75-84 my ( $template, $loggedinuser, $cookie ) = get_template_and_user({ Link Here
75
        authnotrequired => 0,
78
        authnotrequired => 0,
76
        flagsrequired   => { tools => 'import_patrons' },
79
        flagsrequired   => { tools => 'import_patrons' },
77
        debug           => 1,
80
        debug           => 1,
78
});
81
    });
79
82
80
$template->param(columnkeys => $columnkeystpl);
83
$template->param(columnkeys => $columnkeystpl);
81
82
if ($input->param('sample')) {
84
if ($input->param('sample')) {
83
    print $input->header(
85
    print $input->header(
84
        -type       => 'application/vnd.sun.xml.calc', # 'application/vnd.ms-excel' ?
86
        -type       => 'application/vnd.sun.xml.calc', # 'application/vnd.ms-excel' ?
Lines 88-93 if ($input->param('sample')) { Link Here
88
    print $csv->string, "\n";
90
    print $csv->string, "\n";
89
    exit 1;
91
    exit 1;
90
}
92
}
93
94
if ($input->param('report')) {
95
    print $input->header(
96
        -type => 'text/plain',
97
        -attachment => 'import_borrowers_report.txt'
98
    );
99
    my $filename = $input->param('errors_filename');
100
    if ( -f $filename ) {
101
        open my $fh, '<', $filename;
102
        print <$fh>;
103
        close $fh;
104
105
        unlink $filename;
106
        exit 1;
107
    }
108
}
109
91
my $uploadborrowers = $input->param('uploadborrowers');
110
my $uploadborrowers = $input->param('uploadborrowers');
92
my $matchpoint      = $input->param('matchpoint');
111
my $matchpoint      = $input->param('matchpoint');
93
if ($matchpoint) {
112
if ($matchpoint) {
Lines 110-116 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
110
    my $alreadyindb = 0;
129
    my $alreadyindb = 0;
111
    my $overwritten = 0;
130
    my $overwritten = 0;
112
    my $invalid     = 0;
131
    my $invalid     = 0;
113
    my $matchpoint_attr_type; 
132
    my $matchpoint_attr_type;
114
    my %defaults = $input->Vars;
133
    my %defaults = $input->Vars;
115
134
116
    # use header line to construct key to column map
135
    # use header line to construct key to column map
Lines 121-131 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
121
    my %csvkeycol;
140
    my %csvkeycol;
122
    my $col = 0;
141
    my $col = 0;
123
    foreach my $keycol (@csvcolumns) {
142
    foreach my $keycol (@csvcolumns) {
124
    	# columnkeys don't contain whitespace, but some stupid tools add it
143
        # columnkeys don't contain whitespace, but some stupid tools add it
125
    	$keycol =~ s/ +//g;
144
        $keycol =~ s/ +//g;
126
        $csvkeycol{$keycol} = $col++;
145
        $csvkeycol{$keycol} = $col++;
127
    }
146
    }
128
    #warn($borrowerline);
147
129
    my $ext_preserve = $input->param('ext_preserve') || 0;
148
    my $ext_preserve = $input->param('ext_preserve') || 0;
130
    if ($extended) {
149
    if ($extended) {
131
        $matchpoint_attr_type = C4::Members::AttributeTypes->fetch($matchpoint);
150
        $matchpoint_attr_type = C4::Members::AttributeTypes->fetch($matchpoint);
Lines 137-142 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
137
    my @bad_dates;  # I've had a few.
156
    my @bad_dates;  # I've had a few.
138
    my $date_re = C4::Dates->new->regexp('syspref');
157
    my $date_re = C4::Dates->new->regexp('syspref');
139
    my  $iso_re = C4::Dates->new->regexp('iso');
158
    my  $iso_re = C4::Dates->new->regexp('iso');
159
    my $lastalreadyindb;
160
    my $lastinvalid;
140
    LINE: while ( my $borrowerline = <$handle> ) {
161
    LINE: while ( my $borrowerline = <$handle> ) {
141
        my %borrower;
162
        my %borrower;
142
        my @missing_criticals;
163
        my @missing_criticals;
Lines 152-174 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
152
                if ($borrower{$key} !~ /\S/) {
173
                if ($borrower{$key} !~ /\S/) {
153
                    $borrower{$key} = $defaults{$key};
174
                    $borrower{$key} = $defaults{$key};
154
                }
175
                }
155
            } 
176
            }
156
        } else {
177
        } else {
157
            # MJR: try to recover gracefully by using default values
178
            # MJR: try to recover gracefully by using default values
158
            foreach my $key (@columnkeys) {
179
            foreach my $key (@columnkeys) {
159
            	if (defined($csvkeycol{$key}) and $columns[$csvkeycol{$key}] =~ /\S/) { 
180
                if (defined($csvkeycol{$key}) and $columns[$csvkeycol{$key}] =~ /\S/) {
160
            	    $borrower{$key} = $columns[$csvkeycol{$key}];
181
                    $borrower{$key} = $columns[$csvkeycol{$key}];
161
            	} elsif ( $defaults{$key} ) {
182
                } elsif ( $defaults{$key} ) {
162
            	    $borrower{$key} = $defaults{$key};
183
                    $borrower{$key} = $defaults{$key};
163
            	} elsif ( scalar grep {$key eq $_} @criticals ) {
184
                } elsif ( scalar grep {$key eq $_} @criticals ) {
164
            	    # a critical field is undefined
185
                    # a critical field is undefined
165
            	    push @missing_criticals, {key=>$key, line=>$., lineraw=>$borrowerline};
186
                    push @missing_criticals, {key=>$key, line=>$., lineraw=>$borrowerline};
166
            	} else {
187
                } else {
167
            		$borrower{$key} = '';
188
                    $borrower{$key} = '';
168
            	}
189
                }
169
            }
190
            }
170
        }
191
        }
171
        #warn join(':',%borrower);
192
172
        if ($borrower{categorycode}) {
193
        if ($borrower{categorycode}) {
173
            push @missing_criticals, {key=>'categorycode', line=>$. , lineraw=>$borrowerline, value=>$borrower{categorycode}, category_map=>1}
194
            push @missing_criticals, {key=>'categorycode', line=>$. , lineraw=>$borrowerline, value=>$borrower{categorycode}, category_map=>1}
174
                unless GetBorrowercategory($borrower{categorycode});
195
                unless GetBorrowercategory($borrower{categorycode});
Lines 187-194 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
187
                $_->{surname}        = $borrower{surname} || 'UNDEF';
208
                $_->{surname}        = $borrower{surname} || 'UNDEF';
188
            }
209
            }
189
            $invalid++;
210
            $invalid++;
190
            (25 > scalar @errors) and push @errors, {missing_criticals=>\@missing_criticals};
211
            push @errors, {missing_criticals=>\@missing_criticals};
191
            # The first 25 errors are enough.  Keeping track of 30,000+ would destroy performance.
192
            next LINE;
212
            next LINE;
193
        }
213
        }
194
        if ($extended) {
214
        if ($extended) {
Lines 197-205 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
197
            $attr_str =~ s/\xe2\x80\x9d/"/g;
217
            $attr_str =~ s/\xe2\x80\x9d/"/g;
198
            push @feedback, {feedback=>1, name=>'attribute string', value=>$attr_str, filename=>$uploadborrowers};
218
            push @feedback, {feedback=>1, name=>'attribute string', value=>$attr_str, filename=>$uploadborrowers};
199
            delete $borrower{patron_attributes};    # not really a field in borrowers, so we don't want to pass it to ModMember.
219
            delete $borrower{patron_attributes};    # not really a field in borrowers, so we don't want to pass it to ModMember.
200
            $patron_attributes = extended_attributes_code_value_arrayref($attr_str); 
220
            $patron_attributes = extended_attributes_code_value_arrayref($attr_str);
201
        }
221
        }
202
	# Popular spreadsheet applications make it difficult to force date outputs to be zero-padded, but we require it.
222
        # Popular spreadsheet applications make it difficult to force date outputs to be zero-padded, but we require it.
203
        foreach (qw(dateofbirth dateenrolled dateexpiry)) {
223
        foreach (qw(dateofbirth dateenrolled dateexpiry)) {
204
            my $tempdate = $borrower{$_} or next;
224
            my $tempdate = $borrower{$_} or next;
205
            if ($tempdate =~ /$date_re/) {
225
            if ($tempdate =~ /$date_re/) {
Lines 211-218 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
211
                push @missing_criticals, {key=>$_, line=>$. , lineraw=>$borrowerline, bad_date=>1};
231
                push @missing_criticals, {key=>$_, line=>$. , lineraw=>$borrowerline, bad_date=>1};
212
            }
232
            }
213
        }
233
        }
214
	$borrower{dateenrolled} = $today_iso unless $borrower{dateenrolled};
234
        $borrower{dateenrolled} = $today_iso unless $borrower{dateenrolled};
215
	$borrower{dateexpiry} = GetExpiryDate($borrower{categorycode},$borrower{dateenrolled}) unless $borrower{dateexpiry}; 
235
        $borrower{dateexpiry} = GetExpiryDate($borrower{categorycode},$borrower{dateenrolled}) unless $borrower{dateexpiry};
216
        my $borrowernumber;
236
        my $borrowernumber;
217
        my $member;
237
        my $member;
218
        if ( ($matchpoint eq 'cardnumber') && ($borrower{'cardnumber'}) ) {
238
        if ( ($matchpoint eq 'cardnumber') && ($borrower{'cardnumber'}) ) {
Lines 242-253 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
242
            next;
262
            next;
243
        }
263
        }
244
264
245
246
        if ($borrowernumber) {
265
        if ($borrowernumber) {
247
            # borrower exists
266
            # borrower exists
248
            unless ($overwrite_cardnumber) {
267
            unless ($overwrite_cardnumber) {
249
                $alreadyindb++;
268
                $alreadyindb++;
250
                $template->param('lastalreadyindb'=>$borrower{'surname'}.' / '.$borrowernumber);
269
                $lastalreadyindb = $borrower{'surname'}.' / '.$borrowernumber;
270
                $template->param('lastalreadyindb'=>$lastalreadyindb);
251
                next LINE;
271
                next LINE;
252
            }
272
            }
253
            $borrower{'borrowernumber'} = $borrowernumber;
273
            $borrower{'borrowernumber'} = $borrowernumber;
Lines 266-272 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
266
                $invalid++;
286
                $invalid++;
267
                # untill we have better error trapping, we have no way of knowing why ModMember errored out...
287
                # untill we have better error trapping, we have no way of knowing why ModMember errored out...
268
                push @errors, {unknown_error => 1};
288
                push @errors, {unknown_error => 1};
269
                $template->param('lastinvalid'=>$borrower{'surname'}.' / '.$borrowernumber);
289
                $lastinvalid = $borrower{'surname'}.' / '.$borrowernumber;
290
                $template->param('lastinvalid'=>$lastinvalid);
270
                next LINE;
291
                next LINE;
271
            }
292
            }
272
            if ($extended) {
293
            if ($extended) {
Lines 312-317 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
312
        'total'           => $imported + $alreadyindb + $invalid + $overwritten,
333
        'total'           => $imported + $alreadyindb + $invalid + $overwritten,
313
    );
334
    );
314
335
336
    my $max_errors = 25;
337
    if (scalar(@errors) > $max_errors ) {
338
339
        my $total = $imported + $alreadyindb + $invalid + $overwritten;
340
        my $output;
341
342
        my $timestamp = output_pref( dt_from_string );
343
        $output .= "Timestamp : $timestamp\n";
344
        $output .= "Import results\n";
345
        $output .= "$imported imported records\n";
346
        $output .= "$overwritten overwritten records\n";
347
        $output .= "$alreadyindb not imported because already in borrowers table and overwrite disabled\n";
348
        $output .= "(last was $lastalreadyindb)\n" if ($lastalreadyindb);
349
        $output .= "$invalid not imported because they are not in the expected format\n";
350
        $output .= "(last was $lastinvalid)\n" if ($lastinvalid);
351
        $output .= "$total records parsed\n";
352
353
354
        $output .= "\nError analysis\n";
355
        foreach my $error (@errors) {
356
            $output .= "Header row could not be parsed" if ($error->{'badheader'});
357
            foreach my $array ($error->{'missing_criticals'}) {
358
                foreach (@$array) {
359
                    $output .= "Line $_->{'line'}: ";
360
                    if ($error->{'badparse'}) {
361
                        $output .= "could not be parsed!";
362
                    } elsif ($error->{'bad_date'}) {
363
                        $output .= "has $_->{'key'} in unrecognized format: $_->{'value'} ";
364
                    } else {
365
                        $output .= "Critical field $_->{'key'}: ";
366
                        if ($_->{'branch_map'} || $_->{'category_map'}) {
367
                            $output .= "has unrecognized value: $_->{'value'}";
368
                        } else {
369
                            $output .= " missing";
370
                        }
371
                        $output .= " (borrowernumber: $_->{'borrowernumber'}; surname: $_->{'surname'})";
372
                    }
373
                    $output .= "\n";
374
                }
375
            }
376
        }
377
378
        my $tmpf = File::Temp->new(UNLINK => 0);
379
        print $tmpf $output;
380
        $template->param(
381
            download_errors => 1,
382
            errors_filename => $tmpf->filename
383
        );
384
        close $tmpf;
385
386
    }
387
315
} else {
388
} else {
316
    if ($extended) {
389
    if ($extended) {
317
        my @matchpoints = ();
390
        my @matchpoints = ();
Lines 327-330 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
327
}
400
}
328
401
329
output_html_with_http_headers $input, $cookie, $template->output;
402
output_html_with_http_headers $input, $cookie, $template->output;
330
331
- 

Return to bug 5771