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

(-)a/C4/Members.pm (-14 / +29 lines)
Lines 1329-1353 sub checkuniquemember { Link Here
1329
}
1329
}
1330
1330
1331
sub checkcardnumber {
1331
sub checkcardnumber {
1332
    my ($cardnumber,$borrowernumber) = @_;
1332
    my ( $cardnumber, $borrowernumber ) = @_;
1333
1333
    # If cardnumber is null, we assume they're allowed.
1334
    # If cardnumber is null, we assume they're allowed.
1334
    return 0 if !defined($cardnumber);
1335
    return 0 unless defined $cardnumber;
1336
1335
    my $dbh = C4::Context->dbh;
1337
    my $dbh = C4::Context->dbh;
1336
    my $query = "SELECT * FROM borrowers WHERE cardnumber=?";
1338
    my $query = "SELECT * FROM borrowers WHERE cardnumber=?";
1337
    $query .= " AND borrowernumber <> ?" if ($borrowernumber);
1339
    $query .= " AND borrowernumber <> ?" if ($borrowernumber);
1338
  my $sth = $dbh->prepare($query);
1340
    my $sth = $dbh->prepare($query);
1339
  if ($borrowernumber) {
1341
    $sth->execute(
1340
   $sth->execute($cardnumber,$borrowernumber);
1342
        $cardnumber,
1341
  } else { 
1343
        ( $borrowernumber ? $borrowernumber : () )
1342
     $sth->execute($cardnumber);
1344
    );
1343
  } 
1345
1344
    if (my $data= $sth->fetchrow_hashref()){
1346
    return 1 if $sth->fetchrow_hashref;
1345
        return 1;
1347
1346
    }
1348
    if ( my $length = C4::Context->preference('CardnumberLength') ) {
1347
    else {
1349
        # Is integer and length match
1348
        return 0;
1350
        if (
1351
            $length =~ m|^\d+$|
1352
                and length $cardnumber == $length
1353
        ) {
1354
            return 0
1355
        }
1356
        # Else assuming it is a range
1357
        else {
1358
            my $qr = qr|^\d{$length}$|;
1359
            return 0
1360
                if $cardnumber =~ $qr;
1361
        }
1362
        return 1
1349
    }
1363
    }
1350
}  
1364
    return 0;
1365
}
1351
1366
1352
1367
1353
=head2 getzipnamecity (OUEST-PROVENCE)
1368
=head2 getzipnamecity (OUEST-PROVENCE)
(-)a/installer/data/mysql/updatedatabase.pl (+10 lines)
Lines 7824-7829 if ( CheckVersion($DBversion) ) { Link Here
7824
    SetVersion($DBversion);
7824
    SetVersion($DBversion);
7825
}
7825
}
7826
7826
7827
$DBversion = "3.15.00.XXX";
7828
if ( CheckVersion($DBversion) ) {
7829
   $dbh->do("
7830
       INSERT INTO systempreferences (variable,value,options,explanation,type)
7831
       VALUES('CardnumberLength', '', '', 'Set a length for card numbers.', 'Free');
7832
    ");
7833
   print "Upgrade to $DBversion done (Bug 10861: Add CardnumberLength syspref)\n";
7834
   SetVersion ($DBversion);
7835
}
7836
7827
7837
7828
=head1 FUNCTIONS
7838
=head1 FUNCTIONS
7829
7839
(-)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 178-186 Link Here
178
			[% IF ( ERROR_login_exist ) %]
178
			[% IF ( ERROR_login_exist ) %]
179
				<li id="ERROR_login_exist">Username/password already exists.</li>
179
				<li id="ERROR_login_exist">Username/password already exists.</li>
180
			[% END %]
180
			[% END %]
181
			[% IF ( ERROR_cardnumber ) %]
181
            [% IF ( ERROR_cardnumber ) %]
182
				<li id="ERROR_cardnumber">Cardnumber already in use.</li>
182
                <li id="ERROR_cardnumber">Cardnumber already in use or not in a good format.</li>
183
			[% END %]
183
            [% END %]
184
			[% IF ( ERROR_age_limitations ) %]
184
			[% IF ( ERROR_age_limitations ) %]
185
				<li id="ERROR_age_limitations">Patron's age is incorrect for their category.  
185
				<li id="ERROR_age_limitations">Patron's age is incorrect for their category.  
186
                    Ages allowed are [% age_low %]-[% age_high %].</li>
186
                    Ages allowed are [% age_low %]-[% age_high %].</li>
Lines 878-894 Link Here
878
878
879
  <fieldset class="rows" id="memberentry_library_management">
879
  <fieldset class="rows" id="memberentry_library_management">
880
    <legend id="library_management_lgd">Library management</legend><ol>
880
    <legend id="library_management_lgd">Library management</legend><ol>
881
        [% UNLESS nocardnumber %]
881
      [% UNLESS nocardnumber %]
882
   <li> [% IF ( mandatorycardnumber ) %]
882
        <li>
883
      <label for="cardnumber" class="required">
883
          [% IF ( mandatorycardnumber ) %]
884
    [% ELSE %]
884
            <label for="cardnumber" class="required">
885
      <label for="cardnumber">
885
          [% ELSE %]
886
    [% END %] 
886
            <label for="cardnumber">
887
    Card number: </label>
887
          [% END %]
888
	<input type="text" id="cardnumber" name="cardnumber" size="20" value="[% cardnumber %]" />
888
          Card number: </label>
889
	  [% IF ( mandatorycardnumber ) %]<span class="required">Required</span>[% END %]</li>
889
          [% IF minlength_cardnumber && maxlength_cardnumber %]
890
        [% END %]
890
              <input type="text" id="cardnumber" name="cardnumber" size="20" value="[% cardnumber %]" pattern=".{[% minlength_cardnumber %],[% maxlength_cardnumber %]}" title="between [% minlength_cardnumber %] and [% maxlength_cardnumber %] characters" />
891
        [% UNLESS nobranchcode %]
891
          [% ELSE %]
892
              <input type="text" id="cardnumber" name="cardnumber" size="20" value="[% cardnumber %]" />
893
          [% END %]
894
          [% IF ( mandatorycardnumber ) %]<span class="required">Required</span>[% END %]
895
        </li>
896
      [% END %]
897
      [% UNLESS nobranchcode %]
892
    <li>
898
    <li>
893
        <label for="libraries" class="required">Library:</label>
899
        <label for="libraries" class="required">Library:</label>
894
        <select name="branchcode" size="1" id="libraries">
900
        <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 751-757 if(defined($data{'contacttitle'})){ Link Here
751
  $template->param("contacttitle_" . $data{'contacttitle'} => "SELECTED");
751
  $template->param("contacttitle_" . $data{'contacttitle'} => "SELECTED");
752
}
752
}
753
753
754
  
754
if ( my $cardnumber_length = C4::Context->preference('CardnumberLength') ) {
755
    my ( $min, $max );
756
    # Is integer and length match
757
    if ( $cardnumber_length =~ m|^\d+$| ) {
758
        $min = $max = $cardnumber_length;
759
    }
760
    # Else assuming it is a range
761
    elsif ( $cardnumber_length =~ m|(\d+),(\d*)| ) {
762
        $min = $1;
763
        $max = $2 || 16; # borrowers.cardnumber is a varchar(16)
764
    }
765
    if ( defined $min ) {
766
        $template->param(
767
            minlength_cardnumber => $min,
768
            maxlength_cardnumber => $max
769
        );
770
    }
771
}
772
755
output_html_with_http_headers $input, $cookie, $template->output;
773
output_html_with_http_headers $input, $cookie, $template->output;
756
774
757
sub  parse_extended_patron_attributes {
775
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