X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FMembers.pm;h=8d4a6c57659f0306ddffd6f8c4dad74b6c8f11e7;hb=3bb33fd666d4d0eea26114b373874189edc82459;hp=9fdb3576643f9c1cf2188ebf4f48856cbd7f5775;hpb=c2cee4b445a46dda5b85c65ff742593a5125e73a;p=koha_gimpoz diff --git a/C4/Members.pm b/C4/Members.pm index 9fdb357664..8d4a6c5765 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -2,6 +2,7 @@ package C4::Members; # Copyright 2000-2003 Katipo Communications # Copyright 2010 BibLibre +# Parts Copyright 2010 Catalyst IT # # This file is part of Koha. # @@ -45,6 +46,7 @@ BEGIN { &Search &SearchMember &GetMemberDetails + &GetMemberRelatives &GetMember &GetGuarantees @@ -212,22 +214,28 @@ sub SearchMember { $query.=" borrowers.branchcode =".$dbh->quote(C4::Context->userenv->{'branch'})." AND " unless (C4::Context->userenv->{'branch'} eq "insecure"); } } - $query.="((surname LIKE ? OR surname LIKE ? - OR firstname LIKE ? OR firstname LIKE ? - OR othernames LIKE ? OR othernames LIKE ?) + $query.="((surname LIKE ? OR (surname LIKE ? AND surname REGEXP ?) + OR firstname LIKE ? OR (firstname LIKE ? AND firstname REGEXP ?) + OR othernames LIKE ? OR (othernames LIKE ? AND othernames REGEXP ?)) " . ($category_type?" AND category_type = ".$dbh->quote($category_type):""); + my $regex = '[[:punct:][:space:]]'.$data[0]; @bind = ( - "$data[0]%", "% $data[0]%", "$data[0]%", "% $data[0]%", - "$data[0]%", "% $data[0]%" + "$data[0]%", "%$data[0]%", $regex, + "$data[0]%", "%$data[0]%", $regex, + "$data[0]%", "%$data[0]%", $regex ); for ( my $i = 1 ; $i < $count ; $i++ ) { - $query = $query . " AND (" . " surname LIKE ? OR surname LIKE ? - OR firstname LIKE ? OR firstname LIKE ? - OR othernames LIKE ? OR othernames LIKE ?)"; + $query = $query . " AND (" . " surname LIKE ? OR (surname LIKE ? AND surname REGEXP ?) + OR firstname LIKE ? OR (firstname LIKE ? AND firstname REGEXP ?) + OR othernames LIKE ? OR (othernames LIKE ? AND othernames REGEXP ?))"; + $regex = '[[:punct:][:space:]]'.$data[$i]; push( @bind, - "$data[$i]%", "% $data[$i]%", "$data[$i]%", - "% $data[$i]%", "$data[$i]%", "% $data[$i]%" ); + "$data[$i]%", "%$data[$i]%", $regex, + "$data[$i]%", "%$data[$i]%", $regex, + "$data[$i]%", "%$data[$i]%", $regex + ); + # FIXME - .= <prepare("select borrowers.*,category_type,categories.description from borrowers left join categories on borrowers.categorycode=categories.categorycode where borrowernumber=?"); + $sth = $dbh->prepare("SELECT borrowers.*,category_type,categories.description,reservefee FROM borrowers LEFT JOIN categories ON borrowers.categorycode=categories.categorycode WHERE borrowernumber=?"); $sth->execute($borrowernumber); } elsif ($cardnumber) { - $sth = $dbh->prepare("select borrowers.*,category_type,categories.description from borrowers left join categories on borrowers.categorycode=categories.categorycode where cardnumber=?"); + $sth = $dbh->prepare("SELECT borrowers.*,category_type,categories.description,reservefee FROM borrowers LEFT JOIN categories ON borrowers.categorycode=categories.categorycode WHERE cardnumber=?"); $sth->execute($cardnumber); } else { @@ -379,6 +387,7 @@ sub GetMemberDetails { $sth->execute( $borrower->{'categorycode'} ); my $enrolment = $sth->fetchrow; $borrower->{'enrolmentperiod'} = $enrolment; + return ($borrower); #, $flags, $accessflagshash); } @@ -582,6 +591,46 @@ sub GetMember { return; } +=head2 GetMemberRelatives + + @borrowernumbers = GetMemberRelatives($borrowernumber); + + C returns a borrowersnumber's list of guarantor/guarantees of the member given in parameter + +=cut +sub GetMemberRelatives { + my $borrowernumber = shift; + my $dbh = C4::Context->dbh; + my @glist; + + # Getting guarantor + my $query = "SELECT guarantorid FROM borrowers WHERE borrowernumber=?"; + my $sth = $dbh->prepare($query); + $sth->execute($borrowernumber); + my $data = $sth->fetchrow_arrayref(); + push @glist, $data->[0] if $data->[0]; + my $guarantor = $data->[0] if $data->[0]; + + # Getting guarantees + $query = "SELECT borrowernumber FROM borrowers WHERE guarantorid=?"; + $sth = $dbh->prepare($query); + $sth->execute($borrowernumber); + while ($data = $sth->fetchrow_arrayref()) { + push @glist, $data->[0]; + } + + # Getting sibling guarantees + if ($guarantor) { + $query = "SELECT borrowernumber FROM borrowers WHERE guarantorid=?"; + $sth = $dbh->prepare($query); + $sth->execute($guarantor); + while ($data = $sth->fetchrow_arrayref()) { + push @glist, $data->[0] if ($data->[0] != $borrowernumber); + } + } + + return @glist; +} =head2 IsMemberBlocked @@ -725,17 +774,17 @@ sub ModMember { } } my $execute_success=UpdateInTable("borrowers",\%data); -# ok if its an adult (type) it may have borrowers that depend on it as a guarantor -# so when we update information for an adult we should check for guarantees and update the relevant part -# of their records, ie addresses and phone numbers - my $borrowercategory= GetBorrowercategory( $data{'category_type'} ); - if ( exists $borrowercategory->{'category_type'} && $borrowercategory->{'category_type'} eq ('A' || 'S') ) { - # is adult check guarantees; - UpdateGuarantees(%data); + if ($execute_success) { # only proceed if the update was a success + # ok if its an adult (type) it may have borrowers that depend on it as a guarantor + # so when we update information for an adult we should check for guarantees and update the relevant part + # of their records, ie addresses and phone numbers + my $borrowercategory= GetBorrowercategory( $data{'category_type'} ); + if ( exists $borrowercategory->{'category_type'} && $borrowercategory->{'category_type'} eq ('A' || 'S') ) { + # is adult check guarantees; + UpdateGuarantees(%data); + } + logaction("MEMBERS", "MODIFY", $data{'borrowernumber'}, "UPDATE (executed w/ arg: $data{'borrowernumber'})") if C4::Context->preference("BorrowersLog"); } - logaction("MEMBERS", "MODIFY", $data{'borrowernumber'}, "UPDATE (executed w/ arg: $data{'borrowernumber'})") - if C4::Context->preference("BorrowersLog"); - return $execute_success; } @@ -745,7 +794,9 @@ sub ModMember { $borrowernumber = &AddMember(%borrower); insert new borrower into table -Returns the borrowernumber +Returns the borrowernumber upon success + +Returns as undef upon any db error without further processing =cut @@ -753,8 +804,10 @@ Returns the borrowernumber sub AddMember { my (%data) = @_; my $dbh = C4::Context->dbh; - $data{'password'} = '!' if (not $data{'password'} and $data{'userid'}); - $data{'password'} = md5_base64( $data{'password'} ) if $data{'password'}; + # generate a proper login if none provided + $data{'userid'} = Generate_Userid($data{'borrowernumber'}, $data{'firstname'}, $data{'surname'}) if $data{'userid'} eq ''; + # create a disabled account if no password provided + $data{'password'} = ($data{'password'})? md5_base64($data{'password'}) : '!'; $data{'borrowernumber'}=InsertInTable("borrowers",\%data); # mysql_insertid is probably bad. not necessarily accurate and mysql-specific at best. logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog"); @@ -763,10 +816,15 @@ sub AddMember { my $sth = $dbh->prepare("SELECT enrolmentfee FROM categories WHERE categorycode=?"); $sth->execute($data{'categorycode'}); my ($enrolmentfee) = $sth->fetchrow; + if ($sth->err) { + warn sprintf('Database returned the following error: %s', $sth->errstr); + return; + } if ($enrolmentfee && $enrolmentfee > 0) { # insert fee in patron debts manualinvoice($data{'borrowernumber'}, '', '', 'A', $enrolmentfee); } + return $data{'borrowernumber'}; } @@ -795,7 +853,7 @@ sub Generate_Userid { do { $firstname =~ s/[[:digit:][:space:][:blank:][:punct:][:cntrl:]]//g; $surname =~ s/[[:digit:][:space:][:blank:][:punct:][:cntrl:]]//g; - $newuid = lc("$firstname.$surname"); + $newuid = lc(($firstname)? "$firstname.$surname" : $surname); $newuid .= $offset unless $offset == 0; $offset++; @@ -963,7 +1021,7 @@ sub UpdateGuarantees { } =head2 GetPendingIssues - my $issues = &GetPendingIssues($borrowernumber); + my $issues = &GetPendingIssues(@borrowernumber); Looks up what the patron with the given borrowernumber has borrowed. @@ -976,14 +1034,28 @@ The keys include C fields except marc and marcxml. #' sub GetPendingIssues { - my ($borrowernumber) = @_; + my @borrowernumbers = @_; + + unless (@borrowernumbers ) { # return a ref_to_array + return \@borrowernumbers; # to not cause surprise to caller + } + + # Borrowers part of the query + my $bquery = ''; + for (my $i = 0; $i < @borrowernumbers; $i++) { + $bquery .= ' borrowernumber = ?'; + if ($i < $#borrowernumbers ) { + $bquery .= ' OR'; + } + } + # must avoid biblioitems.* to prevent large marc and marcxml fields from killing performance # FIXME: namespace collision: each table has "timestamp" fields. Which one is "timestamp" ? # FIXME: circ/ciculation.pl tries to sort by timestamp! # FIXME: C4::Print::printslip tries to sort by timestamp! # FIXME: namespace collision: other collisions possible. # FIXME: most of this data isn't really being used by callers. - my $sth = C4::Context->dbh->prepare( + my $query = "SELECT issues.*, items.*, biblio.*, @@ -1000,21 +1072,25 @@ sub GetPendingIssues { biblioitems.url, issues.timestamp AS timestamp, issues.renewals AS renewals, + issues.borrowernumber AS borrowernumber, items.renewals AS totalrenewals FROM issues LEFT JOIN items ON items.itemnumber = issues.itemnumber LEFT JOIN biblio ON items.biblionumber = biblio.biblionumber LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber WHERE - borrowernumber=? + $bquery ORDER BY issues.issuedate" - ); - $sth->execute($borrowernumber); + ; + + my $sth = C4::Context->dbh->prepare($query); + $sth->execute(@borrowernumbers); my $data = $sth->fetchall_arrayref({}); my $today = C4::Dates->new->output('iso'); - foreach (@$data) { - $_->{date_due} or next; - ($_->{date_due} lt $today) and $_->{overdue} = 1; + foreach (@{$data}) { + if ($_->{date_due} and $_->{date_due} lt $today) { + $_->{overdue} = 1; + } } return $data; } @@ -1057,7 +1133,7 @@ sub GetAllIssues { LEFT JOIN items on items.itemnumber=old_issues.itemnumber LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber LEFT JOIN biblioitems ON items.biblioitemnumber=biblioitems.biblioitemnumber - WHERE borrowernumber=? + WHERE borrowernumber=? AND old_issues.itemnumber IS NOT NULL order by $order"; if ( $limit != 0 ) { $query .= " limit $limit"; @@ -1109,9 +1185,11 @@ sub GetMemberAccountRecords { $sth->execute( @bind ); my $total = 0; while ( my $data = $sth->fetchrow_hashref ) { - my $biblio = GetBiblioFromItemNumber($data->{itemnumber}) if $data->{itemnumber}; - $data->{biblionumber} = $biblio->{biblionumber}; - $data->{title} = $biblio->{title}; + if ( $data->{itemnumber} ) { + my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} ); + $data->{biblionumber} = $biblio->{biblionumber}; + $data->{title} = $biblio->{title}; + } $acctlines[$numlines] = $data; $numlines++; $total += int(1000 * $data->{'amountoutstanding'}); # convert float to integer to avoid round-off errors @@ -1203,6 +1281,8 @@ sub checkuniquemember { sub checkcardnumber { my ($cardnumber,$borrowernumber) = @_; + # If cardnumber is null, we assume they're allowed. + return 0 if !defined($cardnumber); my $dbh = C4::Context->dbh; my $query = "SELECT * FROM borrowers WHERE cardnumber=?"; $query .= " AND borrowernumber <> ?" if ($borrowernumber); @@ -1233,10 +1313,10 @@ sub getzipnamecity { my $dbh = C4::Context->dbh; my $sth = $dbh->prepare( - "select city_name,city_zipcode from cities where cityid=? "); + "select city_name,city_state,city_zipcode,city_country from cities where cityid=? "); $sth->execute($cityid); my @data = $sth->fetchrow; - return $data[0], $data[1]; + return $data[0], $data[1], $data[2], $data[3]; } @@ -1556,13 +1636,15 @@ sub GetCities { my $dbh = C4::Context->dbh; my $city_arr = $dbh->selectall_arrayref( - q|SELECT cityid,city_zipcode,city_name FROM cities ORDER BY city_name|, + q|SELECT cityid,city_zipcode,city_name,city_state,city_country FROM cities ORDER BY city_name|, { Slice => {} }); if ( @{$city_arr} ) { unshift @{$city_arr}, { city_zipcode => q{}, city_name => q{}, cityid => q{}, + city_state => q{}, + city_country => q{}, }; }