From c5f4346788a4fef5654769af5765d88c8d191b3f 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 --- 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 70049a48c92..6d013fae2e8 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 c3deb71b2a1..d5483e590c5 100644 --- a/Koha/Statistic.pm +++ b/Koha/Statistic.pm @@ -121,11 +121,7 @@ sub new { sub store { my ($self) = @_; $self->SUPER::store; - Koha::PseudonymizedTransaction->new_from_statistic($self)->store - 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) ); + + return Koha::PseudonymizedTransaction->new_from_statistic($self)->store; +} + =head2 Internal methods =head3 _type -- 2.43.0