@@ -, +, @@ overwritten by import firstname "Test1". Add a cardnumber so we can upload it again later. overwrite existing patrons, and preserve exiting firstnames should still be "Test" while the firstname should now be "Test2" --- Koha/Patrons/Import.pm | 10 +++++- .../prog/en/modules/tools/import_borrowers.tt | 23 +++++++++++++ misc/import_patrons.pl | 25 +++++++++------ t/db_dependent/Koha/Patrons/Import.t | 32 ++++++++++++++++++- tools/import_borrowers.pl | 7 ++-- 5 files changed, 84 insertions(+), 13 deletions(-) --- a/Koha/Patrons/Import.pm +++ a/Koha/Patrons/Import.pm @@ -70,6 +70,7 @@ sub import_patrons { my $matchpoint = $params->{matchpoint}; my $defaults = $params->{defaults}; + my $preserve_fields = $params->{preserve_fields}; my $ext_preserve = $params->{preserve_extended_attributes}; my $overwrite_cardnumber = $params->{overwrite_cardnumber}; my $overwrite_passwords = $params->{overwrite_passwords}; @@ -241,7 +242,7 @@ sub import_patrons { if exists $borrower{$field} and $borrower{$field} eq ""; } - if ($borrowernumber) { + if ($borrowernumber) { # borrower exists unless ($overwrite_cardnumber) { @@ -256,6 +257,13 @@ sub import_patrons { next LINE; } $borrower{'borrowernumber'} = $borrowernumber; + + if ( $preserve_fields ) { + for my $field ( @$preserve_fields ) { + delete $borrower{$field}; + } + } + for my $col ( keys %borrower ) { # 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 +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tt @@ -259,6 +259,23 @@ +
+ + Preserve existing values + + + + +
If matching record is already in the borrowers table: @@ -368,6 +385,12 @@ you can supply dates in ISO format (e.g., '2010-10-28'). $(".default_values").toggle(); $(".expand_defaults").toggle(); }); + + $(".expand_preserves").click(function(e){ + e.preventDefault(); + $(".preserve_values").toggle(); + $(".expand_preserves").toggle(); + }); }); $("#overwrite_cardnumberno").click(function(){ --- a/misc/import_patrons.pl +++ a/misc/import_patrons.pl @@ -35,17 +35,19 @@ my $ext_preserve = 0; my $confirm; my $verbose = 0; my $help; +my @preserve_fields; GetOptions( - 'c|confirm' => \$confirm, - 'f|file=s' => \$csv_file, - 'm|matchpoint=s' => \$matchpoint, - 'd|default=s' => \%defaults, - 'o|overwrite' => \$overwrite_cardnumber, - 'op|overwrite_passwords' => \$overwrite_passwords, + 'c|confirm' => \$confirm, + 'f|file=s' => \$csv_file, + 'm|matchpoint=s' => \$matchpoint, + 'd|default=s' => \%defaults, + 'o|overwrite' => \$overwrite_cardnumber, + 'op|overwrite_passwords' => \$overwrite_passwords, 'p|preserve-extended-attributes' => \$ext_preserve, - 'v|verbose+' => \$verbose, - 'h|help|?' => \$help, + 'pf|preserve-field=s' => \@preserve_fields, + 'v|verbose+' => \$verbose, + 'h|help|?' => \$help, ) or pod2usage(2); pod2usage(1) if $help; @@ -65,6 +67,7 @@ my $return = $Import->import_patrons( overwrite_cardnumber => $overwrite_cardnumber, overwrite_passwords => $overwrite_passwords, preserve_extended_attributes => $ext_preserve, + preserve_fields => \@preserve_fields, dry_run => !$confirm, } ); @@ -104,7 +107,7 @@ import_patrons.pl - CLI script to import patrons data into Koha =head1 SYNOPSIS -import_patrons.pl --file /path/to/patrons.csv --matchpoint cardnumber --confirm [--default branchcode=MPL] [--overwrite] [--preserve-extended-attributes] [--verbose] +import_patrons.pl --file /path/to/patrons.csv --matchpoint cardnumber --confirm [--default branchcode=MPL] [--overwrite] [--preserve_field ] [--preserve-extended-attributes] [--verbose] =head1 OPTIONS @@ -130,6 +133,10 @@ Field on which to match incoming patrons to existing patrons Set defaults to patron fields, repeatable e.g. --default branchcode=MPL --default categorycode=PT +=item B<-k|--preserve-field> + +Prevent specified patron fields for existing patrons from being overwritten + =item B<-o|--overwrite> Overwrite existing patrons with new data if a match is found --- a/t/db_dependent/Koha/Patrons/Import.t +++ a/t/db_dependent/Koha/Patrons/Import.t @@ -18,7 +18,7 @@ # along with Koha; if not, see . use Modern::Perl; -use Test::More tests => 160; +use Test::More tests => 172; use Test::Warn; use Encode qw( encode_utf8 ); use utf8; @@ -92,6 +92,7 @@ my $csv_headers = 'cardnumber,surname,firstname,title,othernames,initials,stree 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'; 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'; 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'; +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'; my $filename_1 = make_csv($temp_dir, $csv_headers, $csv_one_line); open(my $handle_1, "<", $filename_1) or die "cannot open < $filename_1: $!"; @@ -183,6 +184,35 @@ is($result_3a->{imported}, 0, 'Got the expected 0 imported result from import_pa is($result_3a->{invalid}, 0, 'Got the expected 0 invalid result from import_patrons'); is($result_3a->{overwritten}, 1, 'Got the expected 1 overwritten result from import_patrons that matched'); +# Given ... valid file handle, good matchpoint that matches should overwrite when set, surname is protected from +# overwrite but firstname is not +my $filename_3c = make_csv($temp_dir, $csv_headers, $csv_one_line_b); +open(my $handle_3c, "<", $filename_3c) or die "cannot open < $filename_3: $!"; +my $params_3c = { file => $handle_3c, matchpoint => 'cardnumber', overwrite_cardnumber => 1, preserve_fields => [ 'firstname' ] }; + +# When ... +my $result_3c; +warning_is { $result_3c = $patrons_import->import_patrons($params_3c) } + undef, + "No warning raised by import_patrons"; + +# Then ... +is($result_3c->{already_in_db}, 0, 'Got the expected 0 already_in_db from import_patrons when matched and overwrite set'); +is($result_3c->{errors}->[0]->{duplicate_userid}, undef, 'No duplicate userid error from import patrons with duplicate userid (it is our own)'); +is($result_3c->{errors}->[0]->{userid}, undef, 'No duplicate userid error from import patrons with duplicate userid (it is our own)'); + +is($result_3c->{feedback}->[0]->{feedback}, 1, 'Got 1 expected feedback from import_patrons that matched and overwritten'); +is($result_3c->{feedback}->[0]->{name}, 'headerrow', 'Got the expected header row name from import_patrons with duplicate userid'); +is($result_3c->{feedback}->[0]->{value}, $res_header, 'Got the expected header row value from import_patrons with duplicate userid'); + +is($result_3c->{imported}, 0, 'Got the expected 0 imported result from import_patrons'); +is($result_3c->{invalid}, 0, 'Got the expected 0 invalid result from import_patrons'); +is($result_3c->{overwritten}, 1, 'Got the expected 1 overwritten result from import_patrons that matched'); + +my $patron_3c = Koha::Patrons->find({ cardnumber => '1000' }); +is( $patron_3c->surname, "Nancy2", "Surname field is preserved from original" ); +is( $patron_3c->firstname, "Jenkins", "Firstname field is overwritten" ); + # Given ... valid file handle, good matchpoint that does not match and conflicting userid. my $filename_3b = make_csv($temp_dir, $csv_headers, $csv_one_line_a); open(my $handle_3b, "<", $filename_3b) or die "cannot open < $filename_3: $!"; --- a/tools/import_borrowers.pl +++ a/tools/import_borrowers.pl @@ -94,6 +94,8 @@ if ( $input->param('sample') ) { exit 0; } +my @preserve_fields = $input->param('preserve_existing'); + my $uploadborrowers = $input->param('uploadborrowers'); my $matchpoint = $input->param('matchpoint'); if ($matchpoint) { @@ -123,9 +125,10 @@ if ( $uploadborrowers && length($uploadborrowers) > 0 ) { file => $handle, defaults => \%defaults, matchpoint => $matchpoint, - overwrite_cardnumber => scalar $input->param('overwrite_cardnumber'), + overwrite_cardnumber => scalar $input->param( 'overwrite_cardnumber' ), overwrite_passwords => $overwrite_passwords, - preserve_extended_attributes => scalar $input->param('ext_preserve') || 0, + preserve_extended_attributes => scalar $input->param( 'ext_preserve' ) || 0, + preserve_fields => \@preserve_fields, } ); --