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

(-)a/Koha/Patrons/Import.pm (+8 lines)
Lines 70-75 sub import_patrons { Link Here
70
70
71
    my $matchpoint           = $params->{matchpoint};
71
    my $matchpoint           = $params->{matchpoint};
72
    my $defaults             = $params->{defaults};
72
    my $defaults             = $params->{defaults};
73
    my $preserve_fields      = $params->{preserve_fields};
73
    my $ext_preserve         = $params->{preserve_extended_attributes};
74
    my $ext_preserve         = $params->{preserve_extended_attributes};
74
    my $overwrite_cardnumber = $params->{overwrite_cardnumber};
75
    my $overwrite_cardnumber = $params->{overwrite_cardnumber};
75
    my $overwrite_passwords  = $params->{overwrite_passwords};
76
    my $overwrite_passwords  = $params->{overwrite_passwords};
Lines 257-262 sub import_patrons { Link Here
257
                next LINE;
258
                next LINE;
258
            }
259
            }
259
            $borrower{'borrowernumber'} = $borrowernumber;
260
            $borrower{'borrowernumber'} = $borrowernumber;
261
262
            if ( $preserve_fields ) {
263
                for my $field ( @$preserve_fields ) {
264
                    $borrower{$field} = $patron->$field;
265
                }
266
            }
267
260
            for my $col ( keys %borrower ) {
268
            for my $col ( keys %borrower ) {
261
269
262
                # use values from extant patron unless our csv file includes this column or we provided a default.
270
                # use values from extant patron unless our csv file includes this column or we provided a default.
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tt (+23 lines)
Lines 290-295 Link Here
290
290
291
            </ol>
291
            </ol>
292
        </fieldset>
292
        </fieldset>
293
        <fieldset class="rows">
294
            <legend>
295
                <a href="#" class="expand_preserves"><i class="fa fa-plus-square"></i> Preserve existing values</a>
296
                <a href="#" class="expand_preserves" style="display:none;"><i class="fa fa-minus-square"></i> Hide preserve value fields</a>
297
            </legend>
298
299
            <ol class="preserve_values" style="display:none;">
300
                <div class="hint">Selected fields will be preserved from original patron record when overwriting existing patron.</div>
301
                [% FOREACH borrower_field IN borrower_fields %]
302
                        <li>
303
                            <label class="description" for="[% borrower_field.field | html %]">[% borrower_field.description | html %]: </label>
304
                            <input name="preserve_existing" id="preserve_existing_[%  borrower_field.field | html %]" value="[%  borrower_field.field | html %]" type="checkbox">
305
                            <span class="field_hint">[% borrower_field.field | html %]</span>
306
                        </li>
307
                [% END %]
308
            </ol>
309
        </fieldset>
293
310
294
        <fieldset class="rows">
311
        <fieldset class="rows">
295
            <legend>If matching record is already in the borrowers table:</legend>
312
            <legend>If matching record is already in the borrowers table:</legend>
Lines 399-404 you can supply dates in ISO format (e.g., '2010-10-28'). Link Here
399
                $(".default_values").toggle();
416
                $(".default_values").toggle();
400
                $(".expand_defaults").toggle();
417
                $(".expand_defaults").toggle();
401
            });
418
            });
419
420
            $(".expand_preserves").click(function(e){
421
                e.preventDefault();
422
                $(".preserve_values").toggle();
423
                $(".expand_preserves").toggle();
424
            });
402
        });
425
        });
403
426
404
        $("#overwrite_cardnumberno").click(function(){
427
        $("#overwrite_cardnumberno").click(function(){
(-)a/misc/import_patrons.pl (-9 / +16 lines)
Lines 35-51 my $ext_preserve = 0; Link Here
35
my $confirm;
35
my $confirm;
36
my $verbose      = 0;
36
my $verbose      = 0;
37
my $help;
37
my $help;
38
my @preserve_fields;
38
39
39
GetOptions(
40
GetOptions(
40
    'c|confirm'                     => \$confirm,
41
    'c|confirm'                      => \$confirm,
41
    'f|file=s'                      => \$csv_file,
42
    'f|file=s'                       => \$csv_file,
42
    'm|matchpoint=s'                => \$matchpoint,
43
    'm|matchpoint=s'                 => \$matchpoint,
43
    'd|default=s'                   => \%defaults,
44
    'd|default=s'                    => \%defaults,
44
    'o|overwrite'                   => \$overwrite_cardnumber,
45
    'o|overwrite'                    => \$overwrite_cardnumber,
45
    'op|overwrite_passwords'        => \$overwrite_passwords,
46
    'op|overwrite_passwords'         => \$overwrite_passwords,
46
    'p|preserve-extended-attributes' => \$ext_preserve,
47
    'p|preserve-extended-attributes' => \$ext_preserve,
47
    'v|verbose+'                    => \$verbose,
48
    'pf|preserve-field=s'            => \@preserve_fields,
48
    'h|help|?'                      => \$help,
49
    'v|verbose+'                     => \$verbose,
50
    'h|help|?'                       => \$help,
49
) or pod2usage(2);
51
) or pod2usage(2);
50
52
51
pod2usage(1) if $help;
53
pod2usage(1) if $help;
Lines 65-70 my $return = $Import->import_patrons( Link Here
65
        overwrite_cardnumber         => $overwrite_cardnumber,
67
        overwrite_cardnumber         => $overwrite_cardnumber,
66
        overwrite_passwords          => $overwrite_passwords,
68
        overwrite_passwords          => $overwrite_passwords,
67
        preserve_extended_attributes => $ext_preserve,
69
        preserve_extended_attributes => $ext_preserve,
70
        preserve_fields              => \@preserve_fields,
68
        dry_run                      => !$confirm,
71
        dry_run                      => !$confirm,
69
    }
72
    }
70
);
73
);
Lines 104-110 import_patrons.pl - CLI script to import patrons data into Koha Link Here
104
107
105
=head1 SYNOPSIS
108
=head1 SYNOPSIS
106
109
107
import_patrons.pl --file /path/to/patrons.csv --matchpoint cardnumber --confirm [--default branchcode=MPL] [--overwrite] [--preserve-extended-attributes] [--verbose]
110
import_patrons.pl --file /path/to/patrons.csv --matchpoint cardnumber --confirm [--default branchcode=MPL] [--overwrite] [--preserve_field <column>] [--preserve-extended-attributes] [--verbose]
108
111
109
=head1 OPTIONS
112
=head1 OPTIONS
110
113
Lines 130-135 Field on which to match incoming patrons to existing patrons Link Here
130
133
131
Set defaults to patron fields, repeatable e.g. --default branchcode=MPL --default categorycode=PT
134
Set defaults to patron fields, repeatable e.g. --default branchcode=MPL --default categorycode=PT
132
135
136
=item B<-k|--preserve-field>
137
138
Prevent specified patron fields for existing patrons from being overwritten
139
133
=item B<-o|--overwrite>
140
=item B<-o|--overwrite>
134
141
135
Overwrite existing patrons with new data if a match is found
142
Overwrite existing patrons with new data if a match is found
(-)a/t/db_dependent/Koha/Patrons/Import.t (-1 / +31 lines)
Lines 18-24 Link Here
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
use Test::More tests => 161;
21
use Test::More tests => 173;
22
use Test::Warn;
22
use Test::Warn;
23
use Test::Exception;
23
use Test::Exception;
24
use Encode qw( encode_utf8 );
24
use Encode qw( encode_utf8 );
Lines 93-98 my $csv_headers = 'cardnumber,surname,firstname,title,othernames,initials,stree Link Here
93
my $res_header   = 'cardnumber, surname, firstname, title, othernames, initials, streetnumber, streettype, address, address2, city, state, zipcode, country, email, phone, mobile, fax, dateofbirth, branchcode, categorycode, dateenrolled, dateexpiry, userid, password';
93
my $res_header   = 'cardnumber, surname, firstname, title, othernames, initials, streetnumber, streettype, address, address2, city, state, zipcode, country, email, phone, mobile, fax, dateofbirth, branchcode, categorycode, dateenrolled, dateexpiry, userid, password';
94
my $csv_one_line = '1000,Nancy,Jenkins,Dr,,NJ,78,Circle,Bunting,El Paso,Henderson,Texas,79984,United States,ajenkins0@sourceforge.net,7-(388)559-6763,3-(373)151-4471,8-(509)286-4001,10/16/1965,CPL,PT,12/28/2014,07/01/2015,jjenkins0,DPQILy';
94
my $csv_one_line = '1000,Nancy,Jenkins,Dr,,NJ,78,Circle,Bunting,El Paso,Henderson,Texas,79984,United States,ajenkins0@sourceforge.net,7-(388)559-6763,3-(373)151-4471,8-(509)286-4001,10/16/1965,CPL,PT,12/28/2014,07/01/2015,jjenkins0,DPQILy';
95
my $csv_one_line_a = '1001,Nancy,Jenkins,Dr,,NJ,78,Circle,Bunting,El Paso,Henderson,Texas,79984,United States,ajenkins0@sourceforge.net,7-(388)559-6763,3-(373)151-4471,8-(509)286-4001,10/16/1965,CPL,PT,12/28/2014,07/01/2015,jjenkins0,DPQILy';
95
my $csv_one_line_a = '1001,Nancy,Jenkins,Dr,,NJ,78,Circle,Bunting,El Paso,Henderson,Texas,79984,United States,ajenkins0@sourceforge.net,7-(388)559-6763,3-(373)151-4471,8-(509)286-4001,10/16/1965,CPL,PT,12/28/2014,07/01/2015,jjenkins0,DPQILy';
96
my $csv_one_line_b = '1000,Nancy2,Jenkins2,Dr,,NJ,78,Circle,Bunting,El Paso,Henderson,Texas,79984,United States,ajenkins0@sourceforge.net,7-(388)559-6763,3-(373)151-4471,8-(509)286-4001,10/16/1965,CPL,PT,12/28/2014,07/01/2015,jjenkins0,DPQILy';
96
97
97
my $filename_1 = make_csv($temp_dir, $csv_headers, $csv_one_line);
98
my $filename_1 = make_csv($temp_dir, $csv_headers, $csv_one_line);
98
open(my $handle_1, "<", $filename_1) or die "cannot open < $filename_1: $!";
99
open(my $handle_1, "<", $filename_1) or die "cannot open < $filename_1: $!";
Lines 184-189 is($result_3a->{imported}, 0, 'Got the expected 0 imported result from import_pa Link Here
184
is($result_3a->{invalid}, 0, 'Got the expected 0 invalid result from import_patrons');
185
is($result_3a->{invalid}, 0, 'Got the expected 0 invalid result from import_patrons');
185
is($result_3a->{overwritten}, 1, 'Got the expected 1 overwritten result from import_patrons that matched');
186
is($result_3a->{overwritten}, 1, 'Got the expected 1 overwritten result from import_patrons that matched');
186
187
188
# Given ... valid file handle, good matchpoint that matches should overwrite when set, surname is protected from
189
# overwrite but firstname is not
190
my $filename_3c = make_csv($temp_dir, $csv_headers, $csv_one_line_b);
191
open(my $handle_3c, "<", $filename_3c) or die "cannot open < $filename_3: $!";
192
my $params_3c = { file => $handle_3c, matchpoint => 'cardnumber', overwrite_cardnumber => 1, preserve_fields => [ 'firstname' ] };
193
194
# When ...
195
my $result_3c;
196
warning_is { $result_3c = $patrons_import->import_patrons($params_3c) }
197
    undef,
198
    "No warning raised by import_patrons";
199
200
# Then ...
201
is($result_3c->{already_in_db}, 0, 'Got the expected 0 already_in_db from import_patrons when matched and overwrite set');
202
is($result_3c->{errors}->[0]->{duplicate_userid}, undef, 'No duplicate userid error from import patrons with duplicate userid (it is our own)');
203
is($result_3c->{errors}->[0]->{userid}, undef, 'No duplicate userid error from import patrons with duplicate userid (it is our own)');
204
205
is($result_3c->{feedback}->[0]->{feedback}, 1, 'Got 1 expected feedback from import_patrons that matched and overwritten');
206
is($result_3c->{feedback}->[0]->{name}, 'headerrow', 'Got the expected header row name from import_patrons with duplicate userid');
207
is($result_3c->{feedback}->[0]->{value}, $res_header, 'Got the expected header row value from import_patrons with duplicate userid');
208
209
is($result_3c->{imported}, 0, 'Got the expected 0 imported result from import_patrons');
210
is($result_3c->{invalid}, 0, 'Got the expected 0 invalid result from import_patrons');
211
is($result_3c->{overwritten}, 1, 'Got the expected 1 overwritten result from import_patrons that matched');
212
213
my $patron_3c = Koha::Patrons->find({ cardnumber => '1000' });
214
is( $patron_3c->surname, "Nancy2", "Surname field is preserved from original" );
215
is( $patron_3c->firstname, "Jenkins", "Firstname field is overwritten" );
216
187
# Given ... valid file handle, good matchpoint that does not match and conflicting userid.
217
# Given ... valid file handle, good matchpoint that does not match and conflicting userid.
188
my $filename_3b = make_csv($temp_dir, $csv_headers, $csv_one_line_a);
218
my $filename_3b = make_csv($temp_dir, $csv_headers, $csv_one_line_a);
189
open(my $handle_3b, "<", $filename_3b) or die "cannot open < $filename_3: $!";
219
open(my $handle_3b, "<", $filename_3b) or die "cannot open < $filename_3: $!";
(-)a/tools/import_borrowers.pl (-3 / +5 lines)
Lines 94-99 if ( $input->param('sample') ) { Link Here
94
    exit 0;
94
    exit 0;
95
}
95
}
96
96
97
my @preserve_fields = $input->param('preserve_existing');
98
97
my $uploadborrowers = $input->param('uploadborrowers');
99
my $uploadborrowers = $input->param('uploadborrowers');
98
my $matchpoint      = $input->param('matchpoint');
100
my $matchpoint      = $input->param('matchpoint');
99
if ($matchpoint) {
101
if ($matchpoint) {
Lines 123-131 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
123
            file                         => $handle,
125
            file                         => $handle,
124
            defaults                     => \%defaults,
126
            defaults                     => \%defaults,
125
            matchpoint                   => $matchpoint,
127
            matchpoint                   => $matchpoint,
126
            overwrite_cardnumber         => scalar $input->param('overwrite_cardnumber'),
128
            overwrite_cardnumber         => scalar $input->param( 'overwrite_cardnumber' ),
127
            overwrite_passwords          => $overwrite_passwords,
129
            overwrite_passwords          => $overwrite_passwords,
128
            preserve_extended_attributes => scalar $input->param('ext_preserve') || 0,
130
            preserve_extended_attributes => scalar $input->param( 'ext_preserve' ) || 0,
131
            preserve_fields              => \@preserve_fields,
129
        }
132
        }
130
    );
133
    );
131
134
132
- 

Return to bug 27883