X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FMembers.pm;h=91f4331186265f2a65dd3c4268d235d6a009750c;hb=4958a8a0f67d04c41eb300d9247c915f2346acf0;hp=fc0f0b42c788415786d93a2ef55930baab2f46cf;hpb=80b7a8153dca1bc8f97976e3686c6527766deef3;p=koha.git diff --git a/C4/Members.pm b/C4/Members.pm index fc0f0b42c7..91f4331186 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -33,14 +33,20 @@ use C4::Accounts; use C4::Biblio; use C4::Letters; use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable); -use C4::Members::Attributes qw(SearchIdMatchingAttribute); +use C4::Members::Attributes qw(SearchIdMatchingAttribute UpdateBorrowerAttribute); use C4::NewsChannels; #get slip news use DateTime; use DateTime::Format::DateParse; +use Koha::Database; use Koha::DateUtils; use Koha::Borrower::Debarments qw(IsDebarred); use Text::Unaccent qw( unac_string ); use Koha::AuthUtils qw(hash_password); +use Koha::Database; +use Module::Load; +if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { + load Koha::NorwegianPatronDB, qw( NLUpdateHashedPIN NLEncryptPIN NLSync ); +} our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug); @@ -273,7 +279,7 @@ sub Search { else { $filter = { '' => $filter, branchcode => $branch }; } - } + } } } @@ -354,6 +360,7 @@ sub GetMemberDetails { return; } my $borrower = $sth->fetchrow_hashref; + return unless $borrower; my ($amount) = GetMemberAccountRecords( $borrowernumber); $borrower->{'amountoutstanding'} = $amount; # FIXME - patronflags calls GetMemberAccountRecords... just have patronflags return $amount @@ -380,6 +387,18 @@ sub GetMemberDetails { $borrower->{'showname'} = $borrower->{'firstname'}; } + # Handle setting the true behavior for BlockExpiredPatronOpacActions + $borrower->{'BlockExpiredPatronOpacActions'} = + C4::Context->preference('BlockExpiredPatronOpacActions') + if ( $borrower->{'BlockExpiredPatronOpacActions'} == -1 ); + + $borrower->{'is_expired'} = 0; + $borrower->{'is_expired'} = 1 if + defined($borrower->{dateexpiry}) && + $borrower->{'dateexpiry'} ne '0000-00-00' && + Date_to_Days( Today() ) > + Date_to_Days( split /-/, $borrower->{'dateexpiry'} ); + return ($borrower); #, $flags, $accessflagshash); } @@ -591,7 +610,8 @@ sub GetMember { C returns a borrowersnumber's list of guarantor/guarantees of the member given in parameter -=cut +=cut + sub GetMemberRelatives { my $borrowernumber = shift; my $dbh = C4::Context->dbh; @@ -636,7 +656,8 @@ that would block circulation privileges. C<$block_status> can have the following values: -1 if the patron has outstanding fine days, in which case C<$count> is the number of them +1 if the patron has outstanding fine days or a manual debarment, in which case +C<$count> is the expiration date (9999-12-31 for indefinite) -1 if the patron has overdue items, in which case C<$count> is the number of them @@ -769,6 +790,10 @@ sub ModMember { if ($data{password} eq '****' or $data{password} eq '') { delete $data{password}; } else { + if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { + # Update the hashed PIN in borrower_sync.hashed_pin, before Koha hashes it + NLUpdateHashedPIN( $data{'borrowernumber'}, $data{password} ); + } $data{password} = hash_password($data{password}); } } @@ -789,6 +814,25 @@ sub ModMember { AddEnrolmentFeeIfNeeded( $data{categorycode}, $data{borrowernumber} ); } + # If NorwegianPatronDBEnable is enabled, we set syncstatus to something that a + # cronjob will use for syncing with NL + if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { + my $borrowersync = Koha::Database->new->schema->resultset('BorrowerSync')->find({ + 'synctype' => 'norwegianpatrondb', + 'borrowernumber' => $data{'borrowernumber'} + }); + # Do not set to "edited" if syncstatus is "new". We need to sync as new before + # we can sync as changed. And the "new sync" will pick up all changes since + # the patron was created anyway. + if ( $borrowersync->syncstatus ne 'new' && $borrowersync->syncstatus ne 'delete' ) { + $borrowersync->update( { 'syncstatus' => 'edited' } ); + } + # Set the value of 'sync' + $borrowersync->update( { 'sync' => $data{'sync'} } ); + # Try to do the live sync + NLSync({ 'borrowernumber' => $data{'borrowernumber'} }); + } + logaction("MEMBERS", "MODIFY", $data{'borrowernumber'}, "UPDATE (executed w/ arg: $data{'borrowernumber'})") if C4::Context->preference("BorrowersLog"); } return $execute_success; @@ -811,7 +855,8 @@ sub AddMember { my $dbh = C4::Context->dbh; # generate a proper login if none provided - $data{'userid'} = Generate_Userid($data{'borrowernumber'}, $data{'firstname'}, $data{'surname'}) if $data{'userid'} eq ''; + $data{'userid'} = Generate_Userid( $data{'borrowernumber'}, $data{'firstname'}, $data{'surname'} ) + if ( $data{'userid'} eq '' || !Check_Userid( $data{'userid'} ) ); # add expiration date if it isn't already there unless ( $data{'dateexpiry'} ) { @@ -823,10 +868,33 @@ sub AddMember { $data{'dateenrolled'} = C4::Dates->new()->output("iso"); } + my $patron_category = + Koha::Database->new()->schema()->resultset('Category') + ->find( $data{'categorycode'} ); + $data{'privacy'} = + $patron_category->default_privacy() eq 'default' ? 1 + : $patron_category->default_privacy() eq 'never' ? 2 + : $patron_category->default_privacy() eq 'forever' ? 0 + : undef; + # Make a copy of the plain text password for later use + my $plain_text_password = $data{'password'}; + # create a disabled account if no password provided $data{'password'} = ($data{'password'})? hash_password($data{'password'}) : '!'; $data{'borrowernumber'}=InsertInTable("borrowers",\%data); + # If NorwegianPatronDBEnable is enabled, we set syncstatus to something that a + # cronjob will use for syncing with NL + if ( exists $data{'borrowernumber'} && C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { + Koha::Database->new->schema->resultset('BorrowerSync')->create({ + 'borrowernumber' => $data{'borrowernumber'}, + 'synctype' => 'norwegianpatrondb', + 'sync' => 1, + 'syncstatus' => 'new', + 'hashed_pin' => NLEncryptPIN( $plain_text_password ), + }); + } + # mysql_insertid is probably bad. not necessarily accurate and mysql-specific at best. logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog"); @@ -850,18 +918,21 @@ sub AddMember { =cut sub Check_Userid { - my ($uid,$member) = @_; - my $dbh = C4::Context->dbh; - my $sth = - $dbh->prepare( - "SELECT * FROM borrowers WHERE userid=? AND borrowernumber != ?"); - $sth->execute( $uid, $member ); - if ( ( $uid ne '' ) && ( my $row = $sth->fetchrow_hashref ) ) { - return 0; - } - else { - return 1; - } + my ( $uid, $borrowernumber ) = @_; + + return 0 unless ($uid); # userid is a unique column, we should assume NULL is not unique + + return 0 if ( $uid eq C4::Context->config('user') ); + + my $rs = Koha::Database->new()->schema()->resultset('Borrower'); + + my $params; + $params->{userid} = $uid; + $params->{borrowernumber} = { '!=' => $borrowernumber } if ($borrowernumber); + + my $count = $rs->count( $params ); + + return $count ? 0 : 1; } =head2 Generate_Userid @@ -1157,6 +1228,9 @@ C tables of the Koha database. sub GetAllIssues { my ( $borrowernumber, $order, $limit ) = @_; + return unless $borrowernumber; + $order = 'date_due desc' unless $order; + my $dbh = C4::Context->dbh; my $query = 'SELECT *, issues.timestamp as issuestimestamp, issues.renewals AS renewals,items.renewals AS totalrenewals,items.timestamp AS itemstimestamp @@ -1243,7 +1317,8 @@ sub GetMemberAccountBalance { my $ACCOUNT_TYPE_LENGTH = 5; # this is plain ridiculous... - my @not_fines = ('Res'); + my @not_fines; + push @not_fines, 'Res' unless C4::Context->preference('HoldsInNoissuesCharge'); push @not_fines, 'Rent' unless C4::Context->preference('RentalsInNoissuesCharge'); unless ( C4::Context->preference('ManInvInNoissuesCharge') ) { my $dbh = C4::Context->dbh; @@ -1605,6 +1680,7 @@ sub GetBorrowercategory { $categorycode = &GetBorrowerCategoryCode( $borrowernumber ); Given the borrowernumber, the function returns the corresponding categorycode + =cut sub GetBorrowerCategorycode { @@ -1720,6 +1796,49 @@ sub GetAge{ return $age; } # sub get_age +=head2 SetAge + + $borrower = C4::Members::SetAge($borrower, $datetimeduration); + $borrower = C4::Members::SetAge($borrower, '0015-12-10'); + $borrower = C4::Members::SetAge($borrower, $datetimeduration, $datetime_reference); + + eval { $borrower = C4::Members::SetAge($borrower, '015-1-10'); }; + if ($@) {print $@;} #Catch a bad ISO Date or kill your script! + +This function sets the borrower's dateofbirth to match the given age. +Optionally relative to the given $datetime_reference. + +@PARAM1 koha.borrowers-object +@PARAM2 DateTime::Duration-object as the desired age + OR a ISO 8601 Date. (To make the API more pleasant) +@PARAM3 DateTime-object as the relative date, defaults to now(). +RETURNS The given borrower reference @PARAM1. +DIES If there was an error with the ISO Date handling. + +=cut + +#' +sub SetAge{ + my ( $borrower, $datetimeduration, $datetime_ref ) = @_; + $datetime_ref = DateTime->now() unless $datetime_ref; + + if ($datetimeduration && ref $datetimeduration ne 'DateTime::Duration') { + if ($datetimeduration =~ /^(\d{4})-(\d{2})-(\d{2})/) { + $datetimeduration = DateTime::Duration->new(years => $1, months => $2, days => $3); + } + else { + die "C4::Members::SetAge($borrower, $datetimeduration), datetimeduration not a valid ISO 8601 Date!\n"; + } + } + + my $new_datetime_ref = $datetime_ref->clone(); + $new_datetime_ref->subtract_duration( $datetimeduration ); + + $borrower->{dateofbirth} = $new_datetime_ref->ymd(); + + return $borrower; +} # sub SetAge + =head2 GetCities $cityarrayref = GetCities(); @@ -1779,27 +1898,22 @@ sub GetSortDetails { $result = &MoveMemberToDeleted($borrowernumber); Copy the record from borrowers to deletedborrowers table. +The routine returns 1 for success, undef for failure. =cut -# FIXME: should do it in one SQL statement w/ subquery -# Otherwise, we should return the @data on success - sub MoveMemberToDeleted { my ($member) = shift or return; - my $dbh = C4::Context->dbh; - my $query = qq|SELECT * - FROM borrowers - WHERE borrowernumber=?|; - my $sth = $dbh->prepare($query); - $sth->execute($member); - my @data = $sth->fetchrow_array; - (@data) or return; # if we got a bad borrowernumber, there's nothing to insert - $sth = - $dbh->prepare( "INSERT INTO deletedborrowers VALUES (" - . ( "?," x ( scalar(@data) - 1 ) ) - . "?)" ); - $sth->execute(@data); + + my $schema = Koha::Database->new()->schema(); + my $borrowers_rs = $schema->resultset('Borrower'); + $borrowers_rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); + my $borrower = $borrowers_rs->find($member); + return unless $borrower; + + my $deleted = $schema->resultset('Deletedborrower')->create($borrower); + + return $deleted ? 1 : undef; } =head2 DelMember @@ -2158,17 +2272,13 @@ sub GetBorrowersNamesAndLatestIssue { =head2 ModPrivacy -=over 4 - -my $success = ModPrivacy( $borrowernumber, $privacy ); + my $success = ModPrivacy( $borrowernumber, $privacy ); Update the privacy of a patron. return : true on success, false on failure -=back - =cut sub ModPrivacy {