From 6fb75aa6fcbb61d952868333da08b459eecc0043 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Fri, 25 Aug 2023 12:03:20 +0000 Subject: [PATCH] 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 Signed-off-by: Tomas Cohen Arazi Signed-off-by: Katrin Fischer --- Koha/PseudonymizedTransaction.pm | 60 +++++++++++++++++++------------- Koha/Statistic.pm | 22 +++++++++--- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/Koha/PseudonymizedTransaction.pm b/Koha/PseudonymizedTransaction.pm index 70049a48c9..6d013fae2e 100644 --- a/Koha/PseudonymizedTransaction.pm +++ b/Koha/PseudonymizedTransaction.pm @@ -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; diff --git a/Koha/Statistic.pm b/Koha/Statistic.pm index 19d56cbc32..0eb7414c46 100644 --- a/Koha/Statistic.pm +++ b/Koha/Statistic.pm @@ -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 -- 2.39.5