@@ -, +, @@ - Go on the page: tools > Patrons modification (modborrowers.pl) - Enter a list of cardnumbers (or use a file) - Modify one or more patron's fields (you can modify surname, firstname, - Save - Check on the result page (or in database for non-displayed fields) if - re test with different attributes. For each attributes filled with an - Save - Verify on the result page --- C4/Members.pm | 159 +++++---- C4/Members/AttributeTypes.pm | 2 +- C4/Members/Attributes.pm | 56 +++- .../data/mysql/de-DE/mandatory/userpermissions.sql | 1 + .../data/mysql/en/mandatory/userpermissions.sql | 1 + .../data/mysql/es-ES/mandatory/userpermissions.sql | 1 + .../mysql/fr-FR/1-Obligatoire/userpermissions.sql | 1 + .../data/mysql/it-IT/necessari/userpermissions.sql | 1 + .../mysql/nb-NO/1-Obligatorisk/userpermissions.sql | 1 + .../data/mysql/pl-PL/mandatory/userpermissions.sql | 1 + installer/data/mysql/updatedatabase.pl | 11 + .../prog/en/modules/tools/modborrowers.tt | 312 ++++++++++++++++++ .../prog/en/modules/tools/tools-home.tt | 5 + tools/modborrowers.pl | 342 ++++++++++++++++++++ 14 files changed, 817 insertions(+), 77 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt create mode 100755 tools/modborrowers.pl --- a/C4/Members.pm +++ a/C4/Members.pm @@ -42,86 +42,87 @@ use Koha::DateUtils; our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug); BEGIN { - $VERSION = 3.02; - $debug = $ENV{DEBUG} || 0; - require Exporter; - @ISA = qw(Exporter); - #Get data - push @EXPORT, qw( - &Search - &GetMemberDetails + $VERSION = 3.02; + $debug = $ENV{DEBUG} || 0; + require Exporter; + @ISA = qw(Exporter); + #Get data + push @EXPORT, qw( + &Search + &GetMemberDetails &GetMemberRelatives - &GetMember + &GetMember - &GetGuarantees + &GetGuarantees - &GetMemberIssuesAndFines - &GetPendingIssues - &GetAllIssues + &GetMemberIssuesAndFines + &GetPendingIssues + &GetAllIssues - &get_institutions - &getzipnamecity - &getidcity + &get_institutions + &getzipnamecity + &getidcity - &GetFirstValidEmailAddress + &GetFirstValidEmailAddress - &GetAge - &GetCities - &GetRoadTypes - &GetRoadTypeDetails - &GetSortDetails - &GetTitles + &GetAge + &GetCities + &GetRoadTypes + &GetRoadTypeDetails + &GetSortDetails + &GetTitles - &GetPatronImage - &PutPatronImage - &RmPatronImage + &GetPatronImage + &PutPatronImage + &RmPatronImage - &GetHideLostItemsPreference + &GetHideLostItemsPreference - &IsMemberBlocked - &GetMemberAccountRecords - &GetBorNotifyAcctRecord + &IsMemberBlocked + &GetMemberAccountRecords + &GetBorNotifyAcctRecord - &GetborCatFromCatType - &GetBorrowercategory - &GetBorrowercategoryList + &GetborCatFromCatType + &GetBorrowercategory + GetBorrowerCategorycode + &GetBorrowercategoryList - &GetBorrowersWhoHaveNotBorrowedSince - &GetBorrowersWhoHaveNeverBorrowed - &GetBorrowersWithIssuesHistoryOlderThan + &GetBorrowersWhoHaveNotBorrowedSince + &GetBorrowersWhoHaveNeverBorrowed + &GetBorrowersWithIssuesHistoryOlderThan - &GetExpiryDate + &GetExpiryDate - &AddMessage - &DeleteMessage - &GetMessages - &GetMessagesCount + &AddMessage + &DeleteMessage + &GetMessages + &GetMessagesCount &IssueSlip - GetBorrowersWithEmail - ); + GetBorrowersWithEmail + ); - #Modify data - push @EXPORT, qw( - &ModMember - &changepassword + #Modify data + push @EXPORT, qw( + &ModMember + &changepassword &ModPrivacy - ); - - #Delete data - push @EXPORT, qw( - &DelMember - ); - - #Insert data - push @EXPORT, qw( - &AddMember - &add_member_orgs - &MoveMemberToDeleted - &ExtendMemberSubscriptionTo - ); - - #Check data + ); + + #Delete data + push @EXPORT, qw( + &DelMember + ); + + #Insert data + push @EXPORT, qw( + &AddMember + &add_member_orgs + &MoveMemberToDeleted + &ExtendMemberSubscriptionTo + ); + + #Check data push @EXPORT, qw( &checkuniquemember &checkuserpassword @@ -329,7 +330,7 @@ sub GetMemberDetails { $sth->execute($cardnumber); } else { - return undef; + return; } my $borrower = $sth->fetchrow_hashref; my ($amount) = GetMemberAccountRecords( $borrowernumber); @@ -581,7 +582,7 @@ sub GetMemberRelatives { $sth->execute($borrowernumber); my $data = $sth->fetchrow_arrayref(); push @glist, $data->[0] if $data->[0]; - my $guarantor = $data->[0] if $data->[0]; + my $guarantor = $data->[0] ? $data->[0] : undef; # Getting guarantees $query = "SELECT borrowernumber FROM borrowers WHERE guarantorid=?"; @@ -692,7 +693,7 @@ sub GetMemberIssuesAndFines { return ($overdue_count, $issue_count, $total_fines); } -sub columns(;$) { +sub columns { return @{C4::Context->dbh->selectcol_arrayref("SHOW columns from borrowers")}; } @@ -846,7 +847,7 @@ mode, to avoid database corruption. use vars qw( @weightings ); my @weightings = ( 8, 4, 6, 3, 5, 2, 1 ); -sub fixup_cardnumber ($) { +sub fixup_cardnumber { my ($cardnumber) = @_; my $autonumber_members = C4::Context->boolean_preference('autoMemberNum') || 0; @@ -1409,10 +1410,6 @@ sub GetborCatFromCatType { Given the borrower's category code, the function returns the corresponding data hashref for a comprehensive information display. - $arrayref_hashref = &GetBorrowercategory; - -If no category code provided, the function returns all the categories. - =cut sub GetBorrowercategory { @@ -1433,6 +1430,26 @@ sub GetBorrowercategory { return; } # sub getborrowercategory + +=head2 GetBorrowerCategorycode + + $categorycode = &GetBorrowerCategoryCode( $borrowernumber ); + +Given the borrowernumber, the function returns the corresponding categorycode +=cut + +sub GetBorrowerCategorycode { + my ( $borrowernumber ) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( qq{ + SELECT categorycode + FROM borrowers + WHERE borrowernumber = ? + } ); + $sth->execute( $borrowernumber ); + return $sth->fetchrow; +} + =head2 GetBorrowercategoryList $arrayref_hashref = &GetBorrowercategoryList; --- a/C4/Members/AttributeTypes.pm +++ a/C4/Members/AttributeTypes.pm @@ -151,7 +151,7 @@ sub fetch { $sth->execute($code); my $row = $sth->fetchrow_hashref; $sth->finish(); - return undef unless defined $row; + return unless defined $row; $self->{'code'} = $row->{'code'}; $self->{'description'} = $row->{'description'}; --- a/C4/Members/Attributes.pm +++ a/C4/Members/Attributes.pm @@ -32,8 +32,9 @@ BEGIN { $VERSION = 3.01; @ISA = qw(Exporter); @EXPORT_OK = qw(GetBorrowerAttributes GetBorrowerAttributeValue CheckUniqueness SetBorrowerAttributes + DeleteBorrowerAttribute UpdateBorrowerAttribute extended_attributes_code_value_arrayref extended_attributes_merge - SearchIdMatchingAttribute); + SearchIdMatchingAttribute); %EXPORT_TAGS = ( all => \@EXPORT_OK ); } @@ -76,18 +77,19 @@ sub GetBorrowerAttributes { FROM borrower_attributes JOIN borrower_attribute_types USING (code) LEFT JOIN authorised_values ON (category = authorised_value_category AND attribute = authorised_value) - WHERE borrowernumber = ?"; + WHERE 1"; + $query .= "\nAND borrowernumber = ?" if $borrowernumber; $query .= "\nAND opac_display = 1" if $opac_only; $query .= "\nORDER BY code, attribute"; my $sth = $dbh->prepare_cached($query); - $sth->execute($borrowernumber); + $sth->execute($borrowernumber ? $borrowernumber : ()); my @results = (); while (my $row = $sth->fetchrow_hashref()) { push @results, { code => $row->{'code'}, description => $row->{'description'}, - value => $row->{'attribute'}, - value_description => $row->{'lib'}, + value => $row->{'attribute'}, + value_description => $row->{'lib'}, password => $row->{'password'}, display_checkout => $row->{'display_checkout'}, category_code => $row->{'category_code'}, @@ -233,6 +235,50 @@ sub SetBorrowerAttributes { return 1; # borower attributes successfully set } +=head2 DeleteBorrowerAttribute + + DeleteBorrowerAttribute($borrowernumber, $attribute); + +Delete a borrower attribute for the patron identified by C<$borrowernumber> and the attribute code of C<$attribute> + +=cut +sub DeleteBorrowerAttribute { + my ( $borrowernumber, $attribute ) = @_; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare(qq{ + DELETE FROM borrower_attributes + WHERE borrowernumber = ? + AND code = ? + } ); + $sth->execute( $borrowernumber, $attribute->{code} ); +} + +=head2 UpdateBorrowerAttribute + + UpdateBorrowerAttribute($borrowernumber, $attribute ); + +Update a borrower attribute C<$attribute> for the patron identified by C<$borrowernumber>, + +=cut +sub UpdateBorrowerAttribute { + my ( $borrowernumber, $attribute ) = @_; + + DeleteBorrowerAttribute $borrowernumber, $attribute; + + my $dbh = C4::Context->dbh; + my $query = "INSERT INTO borrower_attributes SET attribute = ?, code = ?, borrowernumber = ?"; + my @params = ( $attribute->{attribute}, $attribute->{code}, $borrowernumber ); + if ( defined $attribute->{password} ) { + $query .= ", password = ?"; + push @params, $attribute->{password}; + } + my $sth = $dbh->prepare( $query ); + + $sth->execute( @params ); +} + + =head2 extended_attributes_code_value_arrayref my $patron_attributes = "homeroom:1150605,grade:01,extradata:foobar"; --- a/installer/data/mysql/de-DE/mandatory/userpermissions.sql +++ a/installer/data/mysql/de-DE/mandatory/userpermissions.sql @@ -28,6 +28,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'MARC-Importe verwalten, auch Übernahme in Katalog und Import rückgängig machen'), (13, 'export_catalog', 'Titel- und Exemplardaten exportieren'), (13, 'import_patrons', 'Benutzerdaten importieren'), + (13, 'edit_patrons', 'Perform batch modification of patrons'), (13, 'delete_anonymize_patrons', 'Inaktive Benutzer löschen und Ausleihhistorie anonymisieren (Benutzerausleihhistorie löschen)'), (13, 'batch_upload_patron_images', 'Benutzerfotos einzeln oder im Stapel hochladen'), (13, 'schedule_tasks', 'Aufgabenplaner verwenden'), --- a/installer/data/mysql/en/mandatory/userpermissions.sql +++ a/installer/data/mysql/en/mandatory/userpermissions.sql @@ -28,6 +28,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'Managed staged MARC records, including completing and reversing imports'), (13, 'export_catalog', 'Export bibliographic and holdings data'), (13, 'import_patrons', 'Import patron data'), + (13, 'edit_patrons', 'Perform batch modification of patrons'), (13, 'delete_anonymize_patrons', 'Delete old borrowers and anonymize circulation history (deletes borrower reading history)'), (13, 'batch_upload_patron_images', 'Upload patron images in batch or one at a time'), (13, 'schedule_tasks', 'Schedule tasks to run'), --- a/installer/data/mysql/es-ES/mandatory/userpermissions.sql +++ a/installer/data/mysql/es-ES/mandatory/userpermissions.sql @@ -28,6 +28,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'Managed staged MARC records, including completing and reversing imports'), (13, 'export_catalog', 'Export bibliographic and holdings data'), (13, 'import_patrons', 'Import patron data'), + (13, 'edit_patrons', 'Perform batch modification of patrons'), (13, 'delete_anonymize_patrons', 'Delete old borrowers and anonymize circulation history (deletes borrower reading history)'), (13, 'batch_upload_patron_images', 'Upload patron images in batch or one at a time'), (13, 'schedule_tasks', 'Schedule tasks to run'), --- a/installer/data/mysql/fr-FR/1-Obligatoire/userpermissions.sql +++ a/installer/data/mysql/fr-FR/1-Obligatoire/userpermissions.sql @@ -18,6 +18,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'Gérer les notices du réservoir, les charger ou annuler leur chargement'), (13, 'export_catalog', 'Exporter des notices bibliographiques et leurs exemplaires'), (13, 'import_patrons', 'Importer des données d''adhérents'), + (13, 'edit_patrons', 'Modification par lot des lecteurs'), (13, 'delete_anonymize_patrons', 'Supprimer les anciens adhérents et anonymiser l''historique des prêts (supprime l''historique des prêts des lecteurs'), (13, 'batch_upload_patron_images', 'Charger sur le serveur les images des adhérents par lot ou un par un'), (13, 'schedule_tasks', 'Planifier les tâches à exécuter'), --- a/installer/data/mysql/it-IT/necessari/userpermissions.sql +++ a/installer/data/mysql/it-IT/necessari/userpermissions.sql @@ -30,6 +30,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'Gestisci i record MARC in lavorazione, inclusi il completare e il cancellare gli import'), (13, 'export_catalog', 'Esporta i dati bibliografici e di copia'), (13, 'import_patrons', 'Importa i dati utente'), + (13, 'edit_patrons', 'Perform batch modification of patrons'), (13, 'delete_anonymize_patrons', 'Cancella i vecchi prestiti e rendi anonimo lo storico della circolazione (canella in lettura lo storico utenti prestito)'), (13, 'batch_upload_patron_images', 'Aggiorna le foto utente in modalità batch o al momento'), (13, 'schedule_tasks', 'Schedula i task da far andare'), --- a/installer/data/mysql/nb-NO/1-Obligatorisk/userpermissions.sql +++ a/installer/data/mysql/nb-NO/1-Obligatorisk/userpermissions.sql @@ -49,6 +49,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'Behandle lagrede MARC-poster, inkludert ferdigstilling og reversering av importer'), (13, 'export_catalog', 'Eksportere bibliografiske data og beholdningsdata'), (13, 'import_patrons', 'Importere låneropplysninger'), + (13, 'edit_patrons', 'Perform batch modification of patrons'), (13, 'delete_anonymize_patrons', 'Slette utgåtte lånere og anonymisere lånehistorikk'), (13, 'batch_upload_patron_images', 'Laste opp bilder av lånere enkeltvis eller en masse'), (13, 'schedule_tasks', 'Planlegge oppgaver som skal kjøres'), --- a/installer/data/mysql/pl-PL/mandatory/userpermissions.sql +++ a/installer/data/mysql/pl-PL/mandatory/userpermissions.sql @@ -28,6 +28,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (13, 'manage_staged_marc', 'Managed staged MARC records, including completing and reversing imports'), (13, 'export_catalog', 'Export bibliographic and holdings data'), (13, 'import_patrons', 'Import patron data'), + (13, 'edit_patrons', 'Perform batch modification of patrons'), (13, 'delete_anonymize_patrons', 'Delete old borrowers and anonymize circulation history (deletes borrower reading history)'), (13, 'batch_upload_patron_images', 'Upload patron images in batch or one at a time'), (13, 'schedule_tasks', 'Schedule tasks to run'), --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -5139,6 +5139,17 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } + + + + +$DBversion = "3.07.00.XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do("INSERT IGNORE INTO permissions (module_bit, code, description) VALUES('13', 'edit_patrons', 'Perform batch modifivation of patrons')"); + print "Upgrade to $DBversion done (Adds permissions flag for access to the patron modifications tool)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/modborrowers.tt @@ -0,0 +1,312 @@ +[% USE KohaDates %] +[% INCLUDE 'doc-head-open.inc'%] +
Warning, the following cardnumbers were not found:
Cardnumbers not found |
---|
[% notfoundcardnumber.cardnumber %] |