Bug 34611: Add pseudonymize routine to Koha::Statistics

This patch adds a new routine to pseudonymize a statistic and adjusts
C4::Stats to use this new routine.

Additionally Koha::PseudonymizedTransaction->new_from_statistic is updated to check for
the existence of objects before using them (in the case of older stats where things may have been deleted)

Tests are added and can be run using:
1. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/PseudonymizedTransaction.t \
           t/db_dependent/Koha/Pseudonymization.t
=> SUCCESS: New tests pass, old tests keep passing

Signed-off-by: AFHDubCoLib <andrewfh@dubcolib.org>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Nick Clemens 2023-08-25 12:03:20 +00:00 committed by Katrin Fischer
parent 058ca2fe39
commit 6fb75aa6fc
No known key found for this signature in database
GPG Key ID: 0EF6E2C03357A834
2 changed files with 53 additions and 29 deletions

View File

@ -17,6 +17,7 @@ package Koha::PseudonymizedTransaction;
use Modern::Perl;
use Crypt::Eksblowfish::Bcrypt qw( bcrypt );
use List::MoreUtils qw(any);
use Koha::Database;
use Koha::Exceptions::Config;
@ -47,23 +48,30 @@ sub new_from_statistic {
my @t_fields_to_copy = split ',', C4::Context->preference('PseudonymizationTransactionFields') || '';
if ( grep { $_ eq 'transaction_branchcode' } @t_fields_to_copy ) {
my $statistic_item = $statistic->item;
# These fields are treated separately as the column names do not match
if ( any { $_ eq 'transaction_branchcode' } @t_fields_to_copy ) {
$values->{transaction_branchcode} = $statistic->branch;
}
if ( grep { $_ eq 'holdingbranch' } @t_fields_to_copy ) {
$values->{holdingbranch} = $statistic->item->holdingbranch;
}
if ( grep { $_ eq 'homebranch' } @t_fields_to_copy ) {
$values->{homebranch} = $statistic->item->homebranch;
}
if ( grep { $_ eq 'transaction_type' } @t_fields_to_copy ) {
if ( any { $_ eq 'transaction_type' } @t_fields_to_copy ) {
$values->{transaction_type} = $statistic->type;
}
if ( grep { $_ eq 'itemcallnumber' } @t_fields_to_copy ) {
$values->{itemcallnumber} = $statistic->item->itemcallnumber;
# These fields are not captured in the statistic so must be pulled from the item
if ($statistic_item) {
if ( any { $_ eq 'homebranch' } @t_fields_to_copy ) {
$values->{homebranch} = $statistic_item->homebranch;
}
if ( any { $_ eq 'holdingbranch' } @t_fields_to_copy ) {
$values->{holdingbranch} = $statistic_item->holdingbranch;
}
if ( any { $_ eq 'itemcallnumber' } @t_fields_to_copy ) {
$values->{itemcallnumber} = $statistic_item->itemcallnumber;
}
}
# Remove fields we have already handled from the list
@t_fields_to_copy = grep {
$_ ne 'transaction_branchcode'
&& $_ ne 'holdingbranch'
@ -72,28 +80,32 @@ sub new_from_statistic {
&& $_ ne 'itemcallnumber'
} @t_fields_to_copy;
# Populate the remaining columns
$values = { %$values, map { $_ => $statistic->$_ } @t_fields_to_copy };
my $patron = Koha::Patrons->find($statistic->borrowernumber);
my @p_fields_to_copy = split ',', C4::Context->preference('PseudonymizationPatronFields') || '';
$values = { %$values, map { $_ => $patron->$_ } @p_fields_to_copy };
my $patron = Koha::Patrons->find( $statistic->borrowernumber );
if ($patron) {
my @p_fields_to_copy = split ',', C4::Context->preference('PseudonymizationPatronFields') || '';
$values = { %$values, map { $_ => $patron->$_ } @p_fields_to_copy };
$values->{branchcode} = $patron->branchcode; # FIXME Must be removed from the pref options, or FK removed (?)
$values->{categorycode} = $patron->categorycode;
$values->{branchcode} = $patron->branchcode; # FIXME Must be removed from the pref options, or FK removed (?)
$values->{categorycode} = $patron->categorycode;
$values->{has_cardnumber} = $patron->cardnumber ? 1 : 0;
$values->{has_cardnumber} = $patron->cardnumber ? 1 : 0;
}
my $self = $class->SUPER::new($values);
my $extended_attributes = $patron->extended_attributes->unblessed;
for my $attribute (@$extended_attributes) {
next unless Koha::Patron::Attribute::Types->find(
$attribute->{code} )->keep_for_pseudonymization;
if ($patron) {
my $extended_attributes = $patron->extended_attributes->unblessed;
for my $attribute (@$extended_attributes) {
next unless Koha::Patron::Attribute::Types->find( $attribute->{code} )->keep_for_pseudonymization;
delete $attribute->{id};
delete $attribute->{borrowernumber};
delete $attribute->{id};
delete $attribute->{borrowernumber};
$self->_result->create_related('pseudonymized_borrower_attributes', $attribute);
$self->_result->create_related( 'pseudonymized_borrower_attributes', $attribute );
}
}
return $self;

View File

@ -121,11 +121,7 @@ sub new {
sub store {
my ($self) = @_;
$self->SUPER::store;
Koha::BackgroundJob::PseudonymizeStatistic->new->enqueue( { statistic => $self->unblessed } )
if C4::Context->preference('Pseudonymization')
&& $self->borrowernumber # Not a real transaction if the patron does not exist
# For instance can be a transfer, or hold trigger
&& grep { $_ eq $self->type } qw(renew issue return onsite_checkout);
$self->pseudonymize() if C4::Context->preference('Pseudonymization');
return $self;
}
@ -142,6 +138,22 @@ sub item {
return Koha::Items->find( $self->itemnumber );
}
=head3 pseudonymize
my $pseudonymized_stat = $statistic->pseudonymize;
Generate a pesudonymized version of the statistic.
=cut
sub pseudonymize {
my ($self) = @_;
return unless ( $self->borrowernumber && grep { $_ eq $self->type } qw(renew issue return onsite_checkout) );
Koha::BackgroundJob::PseudonymizeStatistic->new->enqueue( { statistic => $self->unblessed } );
}
=head2 Internal methods
=head3 _type