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

(-)a/C4/Members.pm (-14 / +29 lines)
Lines 1327-1351 sub checkuniquemember { Link Here
1327
}
1327
}
1328
1328
1329
sub checkcardnumber {
1329
sub checkcardnumber {
1330
    my ($cardnumber,$borrowernumber) = @_;
1330
    my ( $cardnumber, $borrowernumber ) = @_;
1331
1331
    # If cardnumber is null, we assume they're allowed.
1332
    # If cardnumber is null, we assume they're allowed.
1332
    return 0 if !defined($cardnumber);
1333
    return 0 unless defined $cardnumber;
1334
1333
    my $dbh = C4::Context->dbh;
1335
    my $dbh = C4::Context->dbh;
1334
    my $query = "SELECT * FROM borrowers WHERE cardnumber=?";
1336
    my $query = "SELECT * FROM borrowers WHERE cardnumber=?";
1335
    $query .= " AND borrowernumber <> ?" if ($borrowernumber);
1337
    $query .= " AND borrowernumber <> ?" if ($borrowernumber);
1336
  my $sth = $dbh->prepare($query);
1338
    my $sth = $dbh->prepare($query);
1337
  if ($borrowernumber) {
1339
    $sth->execute(
1338
   $sth->execute($cardnumber,$borrowernumber);
1340
        $cardnumber,
1339
  } else { 
1341
        ( $borrowernumber ? $borrowernumber : () )
1340
     $sth->execute($cardnumber);
1342
    );
1341
  } 
1343
1342
    if (my $data= $sth->fetchrow_hashref()){
1344
    return 1 if $sth->fetchrow_hashref;
1343
        return 1;
1345
1344
    }
1346
    if ( my $length = C4::Context->preference('CardnumberLength') ) {
1345
    else {
1347
        # Is integer and length match
1346
        return 0;
1348
        if (
1349
            $length =~ m|^\d+$|
1350
                and length $cardnumber == $length
1351
        ) {
1352
            return 0
1353
        }
1354
        # Else assuming it is a range
1355
        else {
1356
            my $qr = qr|^\d{$length}$|;
1357
            return 0
1358
                if $cardnumber =~ $qr;
1359
        }
1360
        return 1
1347
    }
1361
    }
1348
}  
1362
    return 0;
1363
}
1349
1364
1350
1365
1351
=head2 getzipnamecity (OUEST-PROVENCE)
1366
=head2 getzipnamecity (OUEST-PROVENCE)
(-)a/installer/data/mysql/updatedatabase.pl (+10 lines)
Lines 7155-7160 if ( CheckVersion($DBversion) ) { Link Here
7155
    SetVersion($DBversion);
7155
    SetVersion($DBversion);
7156
}
7156
}
7157
7157
7158
$DBversion = "3.13.00.XXX";
7159
if ( CheckVersion($DBversion) ) {
7160
   $dbh->do("
7161
       INSERT INTO systempreferences (variable,value,options,explanation,type)
7162
       VALUES('CardnumberLength', '', '', 'Set a length for card numbers.', 'Free');
7163
    ");
7164
   print "Upgrade to $DBversion done (Bug 10861: Add CardnumberLength syspref)\n";
7165
   SetVersion ($DBversion);
7166
}
7167
7158
=head1 FUNCTIONS
7168
=head1 FUNCTIONS
7159
7169
7160
=head2 TableExists($table)
7170
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (+4 lines)
Lines 139-141 Patrons: Link Here
139
               yes: Do
139
               yes: Do
140
               no: "Don't"
140
               no: "Don't"
141
         - enable the ability to upload and attach arbitrary files to a borrower record.
141
         - enable the ability to upload and attach arbitrary files to a borrower record.
142
     -
143
         - Card numbers for patrons must be strictly equal to
144
         - pref: CardnumberLength
145
         - characters. The length can be a simple number or a range separated by a coma (xx,yy).
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt (-14 / +20 lines)
Lines 152-160 Link Here
152
			[% IF ( ERROR_login_exist ) %]
152
			[% IF ( ERROR_login_exist ) %]
153
				<li id="ERROR_login_exist">Username/password already exists.</li>
153
				<li id="ERROR_login_exist">Username/password already exists.</li>
154
			[% END %]
154
			[% END %]
155
			[% IF ( ERROR_cardnumber ) %]
155
            [% IF ( ERROR_cardnumber ) %]
156
				<li id="ERROR_cardnumber">Cardnumber already in use.</li>
156
                <li id="ERROR_cardnumber">Cardnumber already in use or not in a good format.</li>
157
			[% END %]
157
            [% END %]
158
			[% IF ( ERROR_age_limitations ) %]
158
			[% IF ( ERROR_age_limitations ) %]
159
				<li id="ERROR_age_limitations">Patron's age is incorrect for their category.  
159
				<li id="ERROR_age_limitations">Patron's age is incorrect for their category.  
160
                    Ages allowed are [% age_low %]-[% age_high %].</li>
160
                    Ages allowed are [% age_low %]-[% age_high %].</li>
Lines 852-868 Link Here
852
852
853
  <fieldset class="rows" id="memberentry_library_management">
853
  <fieldset class="rows" id="memberentry_library_management">
854
    <legend id="library_management_lgd">Library management</legend><ol>
854
    <legend id="library_management_lgd">Library management</legend><ol>
855
        [% UNLESS nocardnumber %]
855
      [% UNLESS nocardnumber %]
856
   <li> [% IF ( mandatorycardnumber ) %]
856
        <li>
857
      <label for="cardnumber" class="required">
857
          [% IF ( mandatorycardnumber ) %]
858
    [% ELSE %]
858
            <label for="cardnumber" class="required">
859
      <label for="cardnumber">
859
          [% ELSE %]
860
    [% END %] 
860
            <label for="cardnumber">
861
    Card number: </label>
861
          [% END %]
862
	<input type="text" id="cardnumber" name="cardnumber" size="20" value="[% cardnumber %]" />
862
          Card number: </label>
863
	  [% IF ( mandatorycardnumber ) %]<span class="required">Required</span>[% END %]</li>
863
          [% IF minlength_cardnumber && maxlength_cardnumber %]
864
        [% END %]
864
              <input type="text" id="cardnumber" name="cardnumber" size="20" value="[% cardnumber %]" pattern=".{[% minlength_cardnumber %],[% maxlength_cardnumber %]}" title="between [% minlength_cardnumber %] and [% maxlength_cardnumber %] characters" />
865
        [% UNLESS nobranchcode %]
865
          [% ELSE %]
866
              <input type="text" id="cardnumber" name="cardnumber" size="20" value="[% cardnumber %]" />
867
          [% END %]
868
          [% IF ( mandatorycardnumber ) %]<span class="required">Required</span>[% END %]
869
        </li>
870
      [% END %]
871
      [% UNLESS nobranchcode %]
866
    <li>
872
    <li>
867
        <label for="libraries" class="required">Library:</label>
873
        <label for="libraries" class="required">Library:</label>
868
        <select name="branchcode" size="1" id="libraries">
874
        <select name="branchcode" size="1" id="libraries">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tt (+6 lines)
Lines 72-77 Link Here
72
            <br /><code>[% missing_critical.lineraw %]</code>
72
            <br /><code>[% missing_critical.lineraw %]</code>
73
        </li>
73
        </li>
74
        [% END %]
74
        [% END %]
75
        [% IF ERROR.invalid_cardnumber %]
76
            <li class="line_error">
77
                Cardnumber [% ERROR.cardnumber %] is not a valid cardnumber
78
                [% IF ERROR.borrowernumber %] (for patron with borrowernumber [% ERROR.borrowernumber %])[% END %]
79
            </li>
80
        [% END %]
75
    [% END %]
81
    [% END %]
76
    </ul>
82
    </ul>
77
    </div>
83
    </div>
(-)a/members/memberentry.pl (-1 / +19 lines)
Lines 727-733 if(defined($data{'contacttitle'})){ Link Here
727
  $template->param("contacttitle_" . $data{'contacttitle'} => "SELECTED");
727
  $template->param("contacttitle_" . $data{'contacttitle'} => "SELECTED");
728
}
728
}
729
729
730
  
730
if ( my $cardnumber_length = C4::Context->preference('CardnumberLength') ) {
731
    my ( $min, $max );
732
    # Is integer and length match
733
    if ( $cardnumber_length =~ m|^\d+$| ) {
734
        $min = $max = $cardnumber_length;
735
    }
736
    # Else assuming it is a range
737
    elsif ( $cardnumber_length =~ m|(\d+),(\d*)| ) {
738
        $min = $1;
739
        $max = $2 || 16; # borrowers.cardnumber is a varchar(16)
740
    }
741
    if ( defined $min ) {
742
        $template->param(
743
            minlength_cardnumber => $min,
744
            maxlength_cardnumber => $max
745
        );
746
    }
747
}
748
731
output_html_with_http_headers $input, $cookie, $template->output;
749
output_html_with_http_headers $input, $cookie, $template->output;
732
750
733
sub  parse_extended_patron_attributes {
751
sub  parse_extended_patron_attributes {
(-)a/t/Members/checkcardnumber.t (+66 lines)
Line 0 Link Here
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
use Test::More tests =>14;
5
6
use Test::MockModule;
7
use DBD::Mock;
8
9
use_ok('C4::Members');
10
11
my $module_context = new Test::MockModule('C4::Context');
12
$module_context->mock(
13
    '_new_dbh',
14
    sub {
15
        my $dbh = DBI->connect( 'DBI:Mock:', '', '' )
16
          || die "Cannot create handle: $DBI::errstr\n";
17
        return $dbh;
18
    }
19
);
20
21
my $dbh = C4::Context->dbh;
22
my $rs = [];
23
24
my $pref = "10";
25
set_pref( $module_context, $pref );
26
27
$dbh->{mock_add_resultset} = $rs;
28
is( C4::Members::checkcardnumber( q{123456789} ), 1, "123456789 is shorter than $pref");
29
$dbh->{mock_add_resultset} = $rs;
30
is( C4::Members::checkcardnumber( q{12345678901234567890} ), 1, "12345678901234567890 is longer than $pref");
31
$dbh->{mock_add_resultset} = $rs;
32
is( C4::Members::checkcardnumber( q{1234567890} ), 0, "1234567890 is equal to $pref");
33
34
$pref = q|10,10|; # Same as before !
35
set_pref( $module_context, $pref );
36
$dbh->{mock_add_resultset} = $rs;
37
is( C4::Members::checkcardnumber( q{123456789} ), 1, "123456789 is shorter than $pref");
38
$dbh->{mock_add_resultset} = $rs;
39
is( C4::Members::checkcardnumber( q{12345678901234567890} ), 1, "12345678901234567890 is longer than $pref");
40
$dbh->{mock_add_resultset} = $rs;
41
is( C4::Members::checkcardnumber( q{1234567890} ), 0, "1234567890 is equal to $pref");
42
43
$pref = q|8,10|; # between 8 and 10 chars
44
set_pref( $module_context, $pref );
45
$dbh->{mock_add_resultset} = $rs;
46
is( C4::Members::checkcardnumber( q{12345678} ), 0, "12345678 matches $pref");
47
$dbh->{mock_add_resultset} = $rs;
48
is( C4::Members::checkcardnumber( q{12345678901234567890} ), 1, "12345678901234567890 is longer than $pref");
49
$dbh->{mock_add_resultset} = $rs;
50
is( C4::Members::checkcardnumber( q{1234567} ), 1, "1234567 is shorter than $pref");
51
$dbh->{mock_add_resultset} = $rs;
52
is( C4::Members::checkcardnumber( q{1234567890} ), 0, "1234567890 matches $pref");
53
54
$pref = q|8,|; # At least 8 chars
55
set_pref( $module_context, $pref );
56
$dbh->{mock_add_resultset} = $rs;
57
is( C4::Members::checkcardnumber( q{1234567} ), 1, "1234567 is shorter than $pref");
58
$dbh->{mock_add_resultset} = $rs;
59
is( C4::Members::checkcardnumber( q{12345678901234567890} ), 0, "12345678901234567890 matches $pref");
60
$dbh->{mock_add_resultset} = $rs;
61
is( C4::Members::checkcardnumber( q{1234567890} ), 0, "12345678 matches $pref");
62
63
sub set_pref {
64
    my ( $module, $value ) = @_;
65
    $module->mock('preference', sub { return $value } );
66
}
(-)a/tools/import_borrowers.pl (-2 / +12 lines)
Lines 231-237 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
231
                }
231
                }
232
            }
232
            }
233
        }
233
        }
234
            
234
235
        if ( C4::Members::checkcardnumber( $borrower{cardnumber}, $borrowernumber ) ) {
236
            push @errors, {
237
                invalid_cardnumber => 1,
238
                borrowernumber => $borrowernumber,
239
                cardnumber => $borrower{cardnumber}
240
            };
241
            $invalid++;
242
            next;
243
        }
244
245
235
        if ($borrowernumber) {
246
        if ($borrowernumber) {
236
            # borrower exists
247
            # borrower exists
237
            unless ($overwrite_cardnumber) {
248
            unless ($overwrite_cardnumber) {
238
- 

Return to bug 10861