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

(-)a/tools/import_borrowers.pl (-102 / +157 lines)
Lines 51-98 use Koha::Borrower::Debarments; Link Here
51
use Koha::DateUtils;
51
use Koha::DateUtils;
52
52
53
use Text::CSV;
53
use Text::CSV;
54
54
# Text::CSV::Unicode, even in binary mode, fails to parse lines with these diacriticals:
55
# Text::CSV::Unicode, even in binary mode, fails to parse lines with these diacriticals:
55
# ė
56
# ė
56
# č
57
# č
57
58
58
use CGI qw ( -utf8 );
59
use CGI qw ( -utf8 );
60
59
# use encoding 'utf8';    # don't do this
61
# use encoding 'utf8';    # don't do this
60
62
61
my (@errors, @feedback);
63
my ( @errors, @feedback );
62
my $extended = C4::Context->preference('ExtendedPatronAttributes');
64
my $extended            = C4::Context->preference('ExtendedPatronAttributes');
63
my $set_messaging_prefs = C4::Context->preference('EnhancedMessagingPreferences');
65
my $set_messaging_prefs = C4::Context->preference('EnhancedMessagingPreferences');
64
my @columnkeys = C4::Members::columns();
66
my @columnkeys          = C4::Members::columns();
65
@columnkeys = map { $_ ne 'borrowernumber' ? $_ : () } @columnkeys;
67
@columnkeys = map { $_ ne 'borrowernumber' ? $_ : () } @columnkeys;
66
if ($extended) {
68
if ($extended) {
67
    push @columnkeys, 'patron_attributes';
69
    push @columnkeys, 'patron_attributes';
68
}
70
}
69
71
70
my $input = CGI->new();
72
my $input = CGI->new();
71
our $csv  = Text::CSV->new({binary => 1});  # binary needed for non-ASCII Unicode
73
our $csv = Text::CSV->new( { binary => 1 } );    # binary needed for non-ASCII Unicode
74
72
#push @feedback, {feedback=>1, name=>'backend', value=>$csv->backend, backend=>$csv->backend}; #XXX
75
#push @feedback, {feedback=>1, name=>'backend', value=>$csv->backend, backend=>$csv->backend}; #XXX
73
76
74
my ( $template, $loggedinuser, $cookie ) = get_template_and_user({
77
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
78
    {
75
        template_name   => "tools/import_borrowers.tt",
79
        template_name   => "tools/import_borrowers.tt",
76
        query           => $input,
80
        query           => $input,
77
        type            => "intranet",
81
        type            => "intranet",
78
        authnotrequired => 0,
82
        authnotrequired => 0,
79
        flagsrequired   => { tools => 'import_patrons' },
83
        flagsrequired   => { tools => 'import_patrons' },
80
        debug           => 1,
84
        debug           => 1,
81
});
85
    }
86
);
82
87
83
# get the branches and pass them to the template
88
# get the branches and pass them to the template
84
my $branches = GetBranchesLoop();
89
my $branches = GetBranchesLoop();
85
$template->param( branches => $branches ) if ( $branches );
90
$template->param( branches => $branches ) if ($branches);
91
86
# get the patron categories and pass them to the template
92
# get the patron categories and pass them to the template
87
my $categories = GetBorrowercategoryList();
93
my $categories = GetBorrowercategoryList();
88
$template->param( categories => $categories ) if ( $categories );
94
$template->param( categories => $categories ) if ($categories);
89
my $columns = C4::Templates::GetColumnDefs( $input )->{borrowers};
95
my $columns = C4::Templates::GetColumnDefs($input)->{borrowers};
90
$columns = [ grep { $_->{field} ne 'borrowernumber' ? $_ : () } @$columns ];
96
$columns = [ grep { $_->{field} ne 'borrowernumber' ? $_ : () } @$columns ];
91
$template->param( borrower_fields => $columns );
97
$template->param( borrower_fields => $columns );
92
98
93
if ($input->param('sample')) {
99
if ( $input->param('sample') ) {
94
    print $input->header(
100
    print $input->header(
95
        -type       => 'application/vnd.sun.xml.calc', # 'application/vnd.ms-excel' ?
101
        -type       => 'application/vnd.sun.xml.calc',    # 'application/vnd.ms-excel' ?
96
        -attachment => 'patron_import.csv',
102
        -attachment => 'patron_import.csv',
97
    );
103
    );
98
    $csv->combine(@columnkeys);
104
    $csv->combine(@columnkeys);
Lines 109-241 my $overwrite_cardnumber = $input->param('overwrite_cardnumber'); Link Here
109
$template->param( SCRIPT_NAME => '/cgi-bin/koha/tools/import_borrowers.pl' );
115
$template->param( SCRIPT_NAME => '/cgi-bin/koha/tools/import_borrowers.pl' );
110
116
111
if ( $uploadborrowers && length($uploadborrowers) > 0 ) {
117
if ( $uploadborrowers && length($uploadborrowers) > 0 ) {
112
    push @feedback, {feedback=>1, name=>'filename', value=>$uploadborrowers, filename=>$uploadborrowers};
118
    push @feedback, { feedback => 1, name => 'filename', value => $uploadborrowers, filename => $uploadborrowers };
113
    my $handle = $input->upload('uploadborrowers');
119
    my $handle     = $input->upload('uploadborrowers');
114
    my $uploadinfo = $input->uploadInfo($uploadborrowers);
120
    my $uploadinfo = $input->uploadInfo($uploadborrowers);
115
    foreach (keys %$uploadinfo) {
121
    foreach ( keys %$uploadinfo ) {
116
        push @feedback, {feedback=>1, name=>$_, value=>$uploadinfo->{$_}, $_=>$uploadinfo->{$_}};
122
        push @feedback, { feedback => 1, name => $_, value => $uploadinfo->{$_}, $_ => $uploadinfo->{$_} };
117
    }
123
    }
118
    my $imported    = 0;
124
    my $imported    = 0;
119
    my $alreadyindb = 0;
125
    my $alreadyindb = 0;
120
    my $overwritten = 0;
126
    my $overwritten = 0;
121
    my $invalid     = 0;
127
    my $invalid     = 0;
122
    my $matchpoint_attr_type; 
128
    my $matchpoint_attr_type;
123
    my %defaults = $input->Vars;
129
    my %defaults = $input->Vars;
124
130
125
    # use header line to construct key to column map
131
    # use header line to construct key to column map
126
    my $borrowerline = <$handle>;
132
    my $borrowerline = <$handle>;
127
    my $status = $csv->parse($borrowerline);
133
    my $status       = $csv->parse($borrowerline);
128
    ($status) or push @errors, {badheader=>1,line=>$., lineraw=>$borrowerline};
134
    ($status) or push @errors, { badheader => 1, line => $., lineraw => $borrowerline };
129
    my @csvcolumns = $csv->fields();
135
    my @csvcolumns = $csv->fields();
130
    my %csvkeycol;
136
    my %csvkeycol;
131
    my $col = 0;
137
    my $col = 0;
132
    foreach my $keycol (@csvcolumns) {
138
    foreach my $keycol (@csvcolumns) {
133
    	# columnkeys don't contain whitespace, but some stupid tools add it
139
134
    	$keycol =~ s/ +//g;
140
        # columnkeys don't contain whitespace, but some stupid tools add it
141
        $keycol =~ s/ +//g;
135
        $csvkeycol{$keycol} = $col++;
142
        $csvkeycol{$keycol} = $col++;
136
    }
143
    }
144
137
    #warn($borrowerline);
145
    #warn($borrowerline);
138
    my $ext_preserve = $input->param('ext_preserve') || 0;
146
    my $ext_preserve = $input->param('ext_preserve') || 0;
139
    if ($extended) {
147
    if ($extended) {
140
        $matchpoint_attr_type = C4::Members::AttributeTypes->fetch($matchpoint);
148
        $matchpoint_attr_type = C4::Members::AttributeTypes->fetch($matchpoint);
141
    }
149
    }
142
150
143
    push @feedback, {feedback=>1, name=>'headerrow', value=>join(', ', @csvcolumns)};
151
    push @feedback, { feedback => 1, name => 'headerrow', value => join( ', ', @csvcolumns ) };
144
    my $today_iso = output_pref( { dt => dt_from_string, dateonly => 1, dateformat => 'iso' });
152
    my $today_iso = output_pref( { dt => dt_from_string, dateonly => 1, dateformat => 'iso' } );
145
    my @criticals = qw(surname branchcode categorycode);    # there probably should be others
153
    my @criticals = qw(surname branchcode categorycode);    # there probably should be others
146
    my @bad_dates;  # I've had a few.
154
    my @bad_dates;                                          # I've had a few.
147
    LINE: while ( my $borrowerline = <$handle> ) {
155
  LINE: while ( my $borrowerline = <$handle> ) {
148
        my %borrower;
156
        my %borrower;
149
        my @missing_criticals;
157
        my @missing_criticals;
150
        my $patron_attributes;
158
        my $patron_attributes;
151
        my $status  = $csv->parse($borrowerline);
159
        my $status  = $csv->parse($borrowerline);
152
        my @columns = $csv->fields();
160
        my @columns = $csv->fields();
153
        if (! $status) {
161
        if ( !$status ) {
154
            push @missing_criticals, {badparse=>1, line=>$., lineraw=>$borrowerline};
162
            push @missing_criticals, { badparse => 1, line => $., lineraw => $borrowerline };
155
        } elsif (@columns == @columnkeys) {
163
        }
164
        elsif ( @columns == @columnkeys ) {
156
            @borrower{@columnkeys} = @columns;
165
            @borrower{@columnkeys} = @columns;
166
157
            # MJR: try to fill blanks gracefully by using default values
167
            # MJR: try to fill blanks gracefully by using default values
158
            foreach my $key (@columnkeys) {
168
            foreach my $key (@columnkeys) {
159
                if ($borrower{$key} !~ /\S/) {
169
                if ( $borrower{$key} !~ /\S/ ) {
160
                    $borrower{$key} = $defaults{$key};
170
                    $borrower{$key} = $defaults{$key};
161
                }
171
                }
162
            } 
172
            }
163
        } else {
173
        }
174
        else {
164
            # MJR: try to recover gracefully by using default values
175
            # MJR: try to recover gracefully by using default values
165
            foreach my $key (@columnkeys) {
176
            foreach my $key (@columnkeys) {
166
            	if (defined($csvkeycol{$key}) and $columns[$csvkeycol{$key}] =~ /\S/) { 
177
                if ( defined( $csvkeycol{$key} ) and $columns[ $csvkeycol{$key} ] =~ /\S/ ) {
167
            	    $borrower{$key} = $columns[$csvkeycol{$key}];
178
                    $borrower{$key} = $columns[ $csvkeycol{$key} ];
168
            	} elsif ( $defaults{$key} ) {
179
                }
169
            	    $borrower{$key} = $defaults{$key};
180
                elsif ( $defaults{$key} ) {
170
            	} elsif ( scalar grep {$key eq $_} @criticals ) {
181
                    $borrower{$key} = $defaults{$key};
171
            	    # a critical field is undefined
182
                }
172
            	    push @missing_criticals, {key=>$key, line=>$., lineraw=>$borrowerline};
183
                elsif ( scalar grep { $key eq $_ } @criticals ) {
173
            	} else {
184
174
            		$borrower{$key} = '';
185
                    # a critical field is undefined
175
            	}
186
                    push @missing_criticals, { key => $key, line => $., lineraw => $borrowerline };
187
                }
188
                else {
189
                    $borrower{$key} = '';
190
                }
176
            }
191
            }
177
        }
192
        }
193
178
        #warn join(':',%borrower);
194
        #warn join(':',%borrower);
179
        if ($borrower{categorycode}) {
195
        if ( $borrower{categorycode} ) {
180
            push @missing_criticals, {key=>'categorycode', line=>$. , lineraw=>$borrowerline, value=>$borrower{categorycode}, category_map=>1}
196
            push @missing_criticals,
181
                unless GetBorrowercategory($borrower{categorycode});
197
              {
182
        } else {
198
                key          => 'categorycode',
183
            push @missing_criticals, {key=>'categorycode', line=>$. , lineraw=>$borrowerline};
199
                line         => $.,
200
                lineraw      => $borrowerline,
201
                value        => $borrower{categorycode},
202
                category_map => 1
203
              }
204
              unless GetBorrowercategory( $borrower{categorycode} );
205
        }
206
        else {
207
            push @missing_criticals, { key => 'categorycode', line => $., lineraw => $borrowerline };
184
        }
208
        }
185
        if ($borrower{branchcode}) {
209
        if ( $borrower{branchcode} ) {
186
            push @missing_criticals, {key=>'branchcode', line=>$. , lineraw=>$borrowerline, value=>$borrower{branchcode}, branch_map=>1}
210
            push @missing_criticals,
187
                unless GetBranchName($borrower{branchcode});
211
              {
188
        } else {
212
                key        => 'branchcode',
189
            push @missing_criticals, {key=>'branchcode', line=>$. , lineraw=>$borrowerline};
213
                line       => $.,
214
                lineraw    => $borrowerline,
215
                value      => $borrower{branchcode},
216
                branch_map => 1
217
              }
218
              unless GetBranchName( $borrower{branchcode} );
219
        }
220
        else {
221
            push @missing_criticals, { key => 'branchcode', line => $., lineraw => $borrowerline };
190
        }
222
        }
191
        if (@missing_criticals) {
223
        if (@missing_criticals) {
192
            foreach (@missing_criticals) {
224
            foreach (@missing_criticals) {
193
                $_->{borrowernumber} = $borrower{borrowernumber} || 'UNDEF';
225
                $_->{borrowernumber} = $borrower{borrowernumber} || 'UNDEF';
194
                $_->{surname}        = $borrower{surname} || 'UNDEF';
226
                $_->{surname}        = $borrower{surname}        || 'UNDEF';
195
            }
227
            }
196
            $invalid++;
228
            $invalid++;
197
            (25 > scalar @errors) and push @errors, {missing_criticals=>\@missing_criticals};
229
            ( 25 > scalar @errors ) and push @errors, { missing_criticals => \@missing_criticals };
230
198
            # The first 25 errors are enough.  Keeping track of 30,000+ would destroy performance.
231
            # The first 25 errors are enough.  Keeping track of 30,000+ would destroy performance.
199
            next LINE;
232
            next LINE;
200
        }
233
        }
201
        if ($extended) {
234
        if ($extended) {
202
            my $attr_str = $borrower{patron_attributes};
235
            my $attr_str = $borrower{patron_attributes};
203
            $attr_str =~ s/\xe2\x80\x9c/"/g; # fixup double quotes in case we are passed smart quotes
236
            $attr_str =~ s/\xe2\x80\x9c/"/g;    # fixup double quotes in case we are passed smart quotes
204
            $attr_str =~ s/\xe2\x80\x9d/"/g;
237
            $attr_str =~ s/\xe2\x80\x9d/"/g;
205
            push @feedback, {feedback=>1, name=>'attribute string', value=>$attr_str, filename=>$uploadborrowers};
238
            push @feedback,
206
            delete $borrower{patron_attributes};    # not really a field in borrowers, so we don't want to pass it to ModMember.
239
              { feedback => 1, name => 'attribute string', value => $attr_str, filename => $uploadborrowers };
207
            $patron_attributes = extended_attributes_code_value_arrayref($attr_str); 
240
            delete $borrower{patron_attributes}
241
              ;    # not really a field in borrowers, so we don't want to pass it to ModMember.
242
            $patron_attributes = extended_attributes_code_value_arrayref($attr_str);
208
        }
243
        }
209
	# Popular spreadsheet applications make it difficult to force date outputs to be zero-padded, but we require it.
244
245
        # Popular spreadsheet applications make it difficult to force date outputs to be zero-padded, but we require it.
210
        foreach (qw(dateofbirth dateenrolled dateexpiry)) {
246
        foreach (qw(dateofbirth dateenrolled dateexpiry)) {
211
            my $tempdate = $borrower{$_} or next;
247
            my $tempdate = $borrower{$_} or next;
212
            $tempdate = eval { output_pref( { dt => dt_from_string( $tempdate ), dateonly => 1, dateformat => 'iso' } ); };
248
            $tempdate =
249
              eval { output_pref( { dt => dt_from_string($tempdate), dateonly => 1, dateformat => 'iso' } ); };
213
            if ($tempdate) {
250
            if ($tempdate) {
214
                $borrower{$_} = $tempdate;
251
                $borrower{$_} = $tempdate;
215
            } else {
252
            }
253
            else {
216
                $borrower{$_} = '';
254
                $borrower{$_} = '';
217
                push @missing_criticals, {key=>$_, line=>$. , lineraw=>$borrowerline, bad_date=>1};
255
                push @missing_criticals, { key => $_, line => $., lineraw => $borrowerline, bad_date => 1 };
218
            }
256
            }
219
        }
257
        }
220
	$borrower{dateenrolled} = $today_iso unless $borrower{dateenrolled};
258
        $borrower{dateenrolled} = $today_iso unless $borrower{dateenrolled};
221
	$borrower{dateexpiry} = GetExpiryDate($borrower{categorycode},$borrower{dateenrolled}) unless $borrower{dateexpiry}; 
259
        $borrower{dateexpiry} = GetExpiryDate( $borrower{categorycode}, $borrower{dateenrolled} )
260
          unless $borrower{dateexpiry};
222
        my $borrowernumber;
261
        my $borrowernumber;
223
        my $member;
262
        my $member;
224
        if ( ($matchpoint eq 'cardnumber') && ($borrower{'cardnumber'}) ) {
263
        if ( ( $matchpoint eq 'cardnumber' ) && ( $borrower{'cardnumber'} ) ) {
225
            $member = GetMember( 'cardnumber' => $borrower{'cardnumber'} );
264
            $member = GetMember( 'cardnumber' => $borrower{'cardnumber'} );
226
            if ($member) {
265
            if ($member) {
227
                $borrowernumber = $member->{'borrowernumber'};
266
                $borrowernumber = $member->{'borrowernumber'};
228
            }
267
            }
229
        } elsif ( ($matchpoint eq 'userid') && ($borrower{'userid'}) ) {
268
        }
269
        elsif ( ( $matchpoint eq 'userid' ) && ( $borrower{'userid'} ) ) {
230
            $member = GetMember( 'userid' => $borrower{'userid'} );
270
            $member = GetMember( 'userid' => $borrower{'userid'} );
231
            if ($member) {
271
            if ($member) {
232
                $borrowernumber = $member->{'borrowernumber'};
272
                $borrowernumber = $member->{'borrowernumber'};
233
            }
273
            }
234
        } elsif ($extended) {
274
        }
235
            if (defined($matchpoint_attr_type)) {
275
        elsif ($extended) {
276
            if ( defined($matchpoint_attr_type) ) {
236
                foreach my $attr (@$patron_attributes) {
277
                foreach my $attr (@$patron_attributes) {
237
                    if ($attr->{code} eq $matchpoint and $attr->{value} ne '') {
278
                    if ( $attr->{code} eq $matchpoint and $attr->{value} ne '' ) {
238
                        my @borrowernumbers = $matchpoint_attr_type->get_patrons($attr->{value});
279
                        my @borrowernumbers = $matchpoint_attr_type->get_patrons( $attr->{value} );
239
                        $borrowernumber = $borrowernumbers[0] if scalar(@borrowernumbers) == 1;
280
                        $borrowernumber = $borrowernumbers[0] if scalar(@borrowernumbers) == 1;
240
                        last;
281
                        last;
241
                    }
282
                    }
Lines 244-286 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
244
        }
285
        }
245
286
246
        if ( C4::Members::checkcardnumber( $borrower{cardnumber}, $borrowernumber ) ) {
287
        if ( C4::Members::checkcardnumber( $borrower{cardnumber}, $borrowernumber ) ) {
247
            push @errors, {
288
            push @errors,
289
              {
248
                invalid_cardnumber => 1,
290
                invalid_cardnumber => 1,
249
                borrowernumber => $borrowernumber,
291
                borrowernumber     => $borrowernumber,
250
                cardnumber => $borrower{cardnumber}
292
                cardnumber         => $borrower{cardnumber}
251
            };
293
              };
252
            $invalid++;
294
            $invalid++;
253
            next;
295
            next;
254
        }
296
        }
255
297
256
257
        if ($borrowernumber) {
298
        if ($borrowernumber) {
299
258
            # borrower exists
300
            # borrower exists
259
            unless ($overwrite_cardnumber) {
301
            unless ($overwrite_cardnumber) {
260
                $alreadyindb++;
302
                $alreadyindb++;
261
                $template->param('lastalreadyindb'=>$borrower{'surname'}.' / '.$borrowernumber);
303
                $template->param( 'lastalreadyindb' => $borrower{'surname'} . ' / ' . $borrowernumber );
262
                next LINE;
304
                next LINE;
263
            }
305
            }
264
            $borrower{'borrowernumber'} = $borrowernumber;
306
            $borrower{'borrowernumber'} = $borrowernumber;
265
            for my $col (keys %borrower) {
307
            for my $col ( keys %borrower ) {
308
266
                # use values from extant patron unless our csv file includes this column or we provided a default.
309
                # use values from extant patron unless our csv file includes this column or we provided a default.
267
                # FIXME : You cannot update a field with a  perl-evaluated false value using the defaults.
310
                # FIXME : You cannot update a field with a  perl-evaluated false value using the defaults.
268
311
269
                # The password is always encrypted, skip it!
312
                # The password is always encrypted, skip it!
270
                next if $col eq 'password';
313
                next if $col eq 'password';
271
314
272
                unless(exists($csvkeycol{$col}) || $defaults{$col}) {
315
                unless ( exists( $csvkeycol{$col} ) || $defaults{$col} ) {
273
                    $borrower{$col} = $member->{$col} if($member->{$col}) ;
316
                    $borrower{$col} = $member->{$col} if ( $member->{$col} );
274
                }
317
                }
275
            }
318
            }
276
            unless (ModMember(%borrower)) {
319
            unless ( ModMember(%borrower) ) {
277
                $invalid++;
320
                $invalid++;
321
278
                # until we have better error trapping, we have no way of knowing why ModMember errored out...
322
                # until we have better error trapping, we have no way of knowing why ModMember errored out...
279
                push @errors, {unknown_error => 1};
323
                push @errors, { unknown_error => 1 };
280
                $template->param('lastinvalid'=>$borrower{'surname'}.' / '.$borrowernumber);
324
                $template->param( 'lastinvalid' => $borrower{'surname'} . ' / ' . $borrowernumber );
281
                next LINE;
325
                next LINE;
282
            }
326
            }
283
            if ( $borrower{debarred} ) {
327
            if ( $borrower{debarred} ) {
328
284
                # Check to see if this debarment already exists
329
                # Check to see if this debarment already exists
285
                my $debarrments = GetDebarments(
330
                my $debarrments = GetDebarments(
286
                    {
331
                    {
Lines 289-294 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
289
                        comment        => $borrower{debarredcomment}
334
                        comment        => $borrower{debarredcomment}
290
                    }
335
                    }
291
                );
336
                );
337
292
                # If it doesn't, then add it!
338
                # If it doesn't, then add it!
293
                unless (@$debarrments) {
339
                unless (@$debarrments) {
294
                    AddDebarment(
340
                    AddDebarment(
Lines 303-321 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
303
            if ($extended) {
349
            if ($extended) {
304
                if ($ext_preserve) {
350
                if ($ext_preserve) {
305
                    my $old_attributes = GetBorrowerAttributes($borrowernumber);
351
                    my $old_attributes = GetBorrowerAttributes($borrowernumber);
306
                    $patron_attributes = extended_attributes_merge($old_attributes, $patron_attributes);  #TODO: expose repeatable options in template
352
                    $patron_attributes = extended_attributes_merge( $old_attributes, $patron_attributes )
353
                      ;    #TODO: expose repeatable options in template
307
                }
354
                }
308
                push @errors, {unknown_error => 1} unless SetBorrowerAttributes($borrower{'borrowernumber'}, $patron_attributes);
355
                push @errors, { unknown_error => 1 }
356
                  unless SetBorrowerAttributes( $borrower{'borrowernumber'}, $patron_attributes );
309
            }
357
            }
310
            $overwritten++;
358
            $overwritten++;
311
            $template->param('lastoverwritten'=>$borrower{'surname'}.' / '.$borrowernumber);
359
            $template->param( 'lastoverwritten' => $borrower{'surname'} . ' / ' . $borrowernumber );
312
        } else {
360
        }
361
        else {
313
            # FIXME: fixup_cardnumber says to lock table, but the web interface doesn't so this doesn't either.
362
            # FIXME: fixup_cardnumber says to lock table, but the web interface doesn't so this doesn't either.
314
            # At least this is closer to AddMember than in members/memberentry.pl
363
            # At least this is closer to AddMember than in members/memberentry.pl
315
            if (!$borrower{'cardnumber'}) {
364
            if ( !$borrower{'cardnumber'} ) {
316
                $borrower{'cardnumber'} = fixup_cardnumber(undef);
365
                $borrower{'cardnumber'} = fixup_cardnumber(undef);
317
            }
366
            }
318
            if ($borrowernumber = AddMember(%borrower)) {
367
            if ( $borrowernumber = AddMember(%borrower) ) {
319
368
320
                if ( $borrower{debarred} ) {
369
                if ( $borrower{debarred} ) {
321
                    AddDebarment(
370
                    AddDebarment(
Lines 328-352 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
328
                }
377
                }
329
378
330
                if ($extended) {
379
                if ($extended) {
331
                    SetBorrowerAttributes($borrowernumber, $patron_attributes);
380
                    SetBorrowerAttributes( $borrowernumber, $patron_attributes );
332
                }
381
                }
333
382
334
                if ($set_messaging_prefs) {
383
                if ($set_messaging_prefs) {
335
                    C4::Members::Messaging::SetMessagingPreferencesFromDefaults({ borrowernumber => $borrowernumber,
384
                    C4::Members::Messaging::SetMessagingPreferencesFromDefaults(
336
                                                                                  categorycode => $borrower{categorycode} });
385
                        {
386
                            borrowernumber => $borrowernumber,
387
                            categorycode   => $borrower{categorycode}
388
                        }
389
                    );
337
                }
390
                }
338
391
339
                $imported++;
392
                $imported++;
340
                $template->param('lastimported'=>$borrower{'surname'}.' / '.$borrowernumber);
393
                $template->param( 'lastimported' => $borrower{'surname'} . ' / ' . $borrowernumber );
341
            } else {
394
            }
395
            else {
342
                $invalid++;
396
                $invalid++;
343
                push @errors, {unknown_error => 1};
397
                push @errors, { unknown_error => 1 };
344
                $template->param('lastinvalid'=>$borrower{'surname'}.' / AddMember');
398
                $template->param( 'lastinvalid' => $borrower{'surname'} . ' / AddMember' );
345
            }
399
            }
346
        }
400
        }
347
    }
401
    }
348
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
402
    (@errors)   and $template->param( ERRORS   => \@errors );
349
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
403
    (@feedback) and $template->param( FEEDBACK => \@feedback );
350
    $template->param(
404
    $template->param(
351
        'uploadborrowers' => 1,
405
        'uploadborrowers' => 1,
352
        'imported'        => $imported,
406
        'imported'        => $imported,
Lines 356-372 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
356
        'total'           => $imported + $alreadyindb + $invalid + $overwritten,
410
        'total'           => $imported + $alreadyindb + $invalid + $overwritten,
357
    );
411
    );
358
412
359
} else {
413
}
414
else {
360
    if ($extended) {
415
    if ($extended) {
361
        my @matchpoints = ();
416
        my @matchpoints = ();
362
        my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes(undef, 1);
417
        my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes( undef, 1 );
363
        foreach my $type (@attr_types) {
418
        foreach my $type (@attr_types) {
364
            my $attr_type = C4::Members::AttributeTypes->fetch($type->{code});
419
            my $attr_type = C4::Members::AttributeTypes->fetch( $type->{code} );
365
            if ($attr_type->unique_id()) {
420
            if ( $attr_type->unique_id() ) {
366
            push @matchpoints, { code =>  "patron_attribute_" . $attr_type->code(), description => $attr_type->description() };
421
                push @matchpoints,
422
                  { code => "patron_attribute_" . $attr_type->code(), description => $attr_type->description() };
367
            }
423
            }
368
        }
424
        }
369
        $template->param(matchpoints => \@matchpoints);
425
        $template->param( matchpoints => \@matchpoints );
370
    }
426
    }
371
}
427
}
372
428
373
- 

Return to bug 12598