<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">
'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: "INSTID:12345,LANG:fr". 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>
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;
'sex', 'userid', 'opacnote', 'contactnote',
'password', 'sort1', 'sort2'
);
+if (C4::Context->preference('ExtendedPatronAttributes')) {
+ push @columnkeys, 'patron_attributes';
+}
my $input = new CGI;
);
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
'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;