[Koha-patches] [PATCH] patron attributes - batch import

Galen Charlton galen.charlton at liblime.com
Sat May 10 01:08:23 CEST 2008


When ExtendedPatronAttributes is ON, the batch
patron import tool's behavior changes as follows:

[1] A new (required) column is added to the input CSV
    format.  This column should contain a list of
    attributes to set for the record, each value
    preceded by its type code.  For example, if
    the superlibrarian has defined two types,
    a unique identifier INSTID and a repeatable
    BASEBALL, this field could contain:

    "INSTID:12345,BASEBALL:Cubs"

    This field must be wrapped in quotes if multiple
    values are defined.  Since values can contain
    spaces, additional doubled-quotes may be required:

    "INSTID:12345,BASEBALL:Cubs,""BASEBALL:White Sox"""

    When replacing a patron record, any attributes specified
    in the input file replace all of the attribute values
    of any type that were previously assigned to the patron
    record.

[2] It is possible to specify a field other than the
    cardnumber to use for looking for matching patrons.
    Specifically, any attribute marked as a unique ID
    can be used.  The operator is asked to specify
    which ID type to use; if an input record has an
    attribute value of that type, and exactly one patron
    record in the database has that value, then the
    record will be overlaid or ignored according to the
    overlay setting.
---
 .../prog/en/modules/tools/import_borrowers.tmpl    |   23 ++++++-
 tools/import_borrowers.pl                          |   73 ++++++++++++++++++-
 2 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tmpl
index d696449..1718439 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tmpl
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tmpl
@@ -40,8 +40,21 @@
 		<input type="file" id="uploadborrowers" name="uploadborrowers" />
 	</li>
 </ol></fieldset>
+    <fieldset class="rows">
+        <legend>Field to use for record matching</legend>
+        <ol>
+            <li class="radio">
+                <select name="matchpoint" id="matchpoint">
+                    <option value="cardnumber">Cardnumber</option>
+                    <!-- TMPL_LOOP NAME="matchpoints" -->
+                        <option value="<!-- TMPL_VAR NAME="code" -->"><!-- TMPL_VAR NAME="description" --></option>
+                    <!-- /TMPL_LOOP -->
+                </select>
+            </li>
+        </ol>
+    </fieldset>
 	<fieldset class="rows">
-	<legend>If cardnumber is already in the borrowers table:</legend><ol><li class="radio">
+	<legend>If matching record is already in the borrowers table:</legend><ol><li class="radio">
 		 
 		<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></li>
 <li class="radio">
@@ -66,8 +79,14 @@
     'debarred',      'contactname',  'contactfirstname', 'contacttitle',
     'borrowernotes', 'relationship', 'ethnicity',        'ethnotes',
     'sex',           'userid',       'opacnote',         'contactnote',
-    'password',      'sort1',        'sort2'
+    'password',      'sort1',        'sort2'<!-- TMPL_IF NAME="ExtendedPatronAttributes" -->, 'patron_attributes'<!-- /TMPL_IF -->
 </li>
+<!-- TMPL_IF NAME="ExtendedPatronAttributes" -->
+<li>If loading patron attributes, the 'patron_attributes' field should contain a comma-separated list of attribute types 
+and values.  The attribute type code and a ':' should precede each value. For example: &quot;INSTID:12345,LANG:fr&quot;.  This
+means that if an input record has more than one attribute, the 'patron_attributes' field must be wrapped in double quotation marks.
+<li>
+<!-- /TMPL_IF -->
 <li>Please make sure the 'branchcode' and 'categorycode' are valid entries in your database.</li>
 <li>password should be stored in plaintext, and will be converted to a md5 hash (if your passwords are already encrypted, talk to your systems administrator about options).</li>
 </ul>
diff --git a/tools/import_borrowers.pl b/tools/import_borrowers.pl
index db448ab..a58e0da 100755
--- a/tools/import_borrowers.pl
+++ b/tools/import_borrowers.pl
@@ -39,6 +39,8 @@ use C4::Output;
 use C4::Dates qw(format_date_in_iso);
 use C4::Context;
 use C4::Members;
+use C4::Members::Attributes;
+use C4::Members::AttributeTypes;
 
 use Text::CSV;
 use CGI;
@@ -57,6 +59,9 @@ my @columnkeys = (
     'sex',           'userid',       'opacnote',         'contactnote',
     'password',      'sort1',        'sort2'
 );
+if (C4::Context->preference('ExtendedPatronAttributes')) {
+    push @columnkeys, 'patron_attributes';
+}
 
 my $input = new CGI;
 
@@ -72,40 +77,87 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
 );
 
 my $uploadborrowers      = $input->param('uploadborrowers');
+my $matchpoint           = $input->param('matchpoint');
+if ($matchpoint) {
+    $matchpoint =~ s/^patron_attribute_//;
+}
 my $overwrite_cardnumber = $input->param('overwrite_cardnumber');
 
 $template->param( SCRIPT_NAME => $ENV{'SCRIPT_NAME'} );
 
+if (C4::Context->preference('ExtendedPatronAttributes')) {
+    $template->param(ExtendedPatronAttributes => 1);
+}
+
 if ( $uploadborrowers && length($uploadborrowers) > 0 ) {
     my $csv         = Text::CSV->new();
     my $imported    = 0;
     my $alreadyindb = 0;
     my $overwritten = 0;
     my $invalid     = 0;
+    my $matchpoint_attr_type; 
+
+    if (C4::Context->preference('ExtendedPatronAttributes')) {
+        $matchpoint_attr_type = C4::Members::AttributeTypes->fetch($matchpoint);
+    }
+
     while ( my $borrowerline = <$uploadborrowers> ) {
         my $status  = $csv->parse($borrowerline);
         my @columns = $csv->fields();
         my %borrower;
+        my $patron_attributes;
         if ( @columns == @columnkeys ) {
             @borrower{@columnkeys} = @columns;
+            my @attrs;
+            if (C4::Context->preference('ExtendedPatronAttributes')) {
+                my $attr_str = $borrower{patron_attributes};
+                delete $borrower{patron_attributes};
+                my $ok = $csv->parse($attr_str);
+                my @list = $csv->fields();
+                # FIXME error handling
+                $patron_attributes = [ map { map { my @arr = split /:/, $_, 2; { code => $arr[0], value => $arr[1] } } $_ } @list ];
+            }
 			foreach (qw(dateofbirth dateenrolled dateexpiry)) {
 				my $tempdate = $borrower{$_} or next;
 				$borrower{$_} = format_date_in_iso($tempdate) || '';
 			}
-            if ( my $member =
-                GetMember( $borrower{'cardnumber'}, 'cardnumber' ) )
+            my $borrowernumber;
+            if ($matchpoint eq 'cardnumber') {
+                my $member = GetMember( $borrower{'cardnumber'}, 'cardnumber' );
+                if ($member) {
+                    $borrowernumber = $member->{'borrowernumber'};
+                }
+            } elsif (C4::Context->preference('ExtendedPatronAttributes')) {
+                if (defined($matchpoint_attr_type)) {
+                    foreach my $attr (@$patron_attributes) {
+                        if ($attr->{code} eq $matchpoint and $attr->{value} ne '') {
+                            my @borrowernumbers = $matchpoint_attr_type->get_patrons($attr->{value});
+                            $borrowernumber = $borrowernumbers[0] if scalar(@borrowernumbers) == 1;
+                            last;
+                        }
+                    }
+                }
+            }
+            
+            if ( $borrowernumber) 
             {
                 # borrower exists
                 if ($overwrite_cardnumber) {
-                    $borrower{'borrowernumber'} = $member->{'borrowernumber'};
+                    $borrower{'borrowernumber'} = $borrowernumber;
                     ModMember(%borrower);
+                    if (C4::Context->preference('ExtendedPatronAttributes')) {
+                        C4::Members::Attributes::SetBorrowerAttributes($borrower{'borrowernumber'}, $patron_attributes);
+                    }
                     $overwritten++;
                 } else {
                     $alreadyindb++;
                 }
             }
             else {
-                if (AddMember(%borrower)) {
+                if ($borrowernumber = AddMember(%borrower)) {
+                    if (C4::Context->preference('ExtendedPatronAttributes')) {
+                        C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $patron_attributes);
+                    }
                     $imported++;
                 } else {
                     $invalid++;		# was just "$invalid", I assume incrementing was the point --atz
@@ -125,6 +177,19 @@ if ( $uploadborrowers && length($uploadborrowers) > 0 ) {
         'total'           => $imported + $alreadyindb + $invalid + $overwritten,
     );
 
+} else {
+    if (C4::Context->preference('ExtendedPatronAttributes')) {
+        my @matchpoints = ();
+        my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes();
+        foreach my $type (@attr_types) {
+            my $attr_type = C4::Members::AttributeTypes->fetch($type->{code});
+            if ($attr_type->unique_id()) {
+            push @matchpoints, { code =>  "patron_attribute_" . $attr_type->code(), description => $attr_type->description() };
+            }
+        }
+        $template->param(matchpoints => \@matchpoints);
+    }
 }
+
 output_html_with_http_headers $input, $cookie, $template->output;
 
-- 
1.5.5.rc0.16.g02b00




More information about the Koha-patches mailing list