From de0614fa6ccc08918bfdffcbdb6edcd3185ca320 Mon Sep 17 00:00:00 2001 From: Matthias Le Gac Date: Mon, 22 Jan 2024 10:45:21 -0500 Subject: [PATCH] Bug 35836: Search for loops in dependencies. We have guarantors who guarantee individuals who are, in turn, their guarantors. It is not clear if this should be allowed (bz35421), but it works, and has been working for a while. However, it breaks with bz12532, which produces a recursion that disrupts everything. Creation of a code in search_for_data_inconsistencies.pl that identifies loops in borrower_relationships. This must work in both directions for validation. This is the first bz I've made. Here's the test plan, let me know if there's anything to improve. Test Plan: 1 - Apply the patch. 2 - Create 4 different adult users. 3 - In the terminal, navigate to the database. 4 - Insert relationships into the "borrower_relationships" table: - Example: INSERT INTO borrower_relationships (id, guarantor_id, guarantee_id, relationship) VALUES (1, 52, 53, 'father'); INSERT INTO borrower_relationships (id, guarantor_id, guarantee_id, relationship) VALUES (2, 53, 54, 'father'); INSERT INTO borrower_relationships (id, guarantor_id, guarantee_id, relationship) VALUES (3, 54, 52, 'father'); - Ensure that the relationships created form a loop of guarantors. 5 - In the terminal, navigate to your Koha environment's git repository. 6 - Change directory to "cd misc/maintenance." 7 - Run the script to detect guarantor loops: ./search_for_data_inconsistencies.pl 8 - Verify that the output provides the borrower IDs involved in the guarantor loop. *Have fun creating intricate relationships to test the script's limit Signed-off-by: Matt Blenkinsop --- .../search_for_data_inconsistencies.pl | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/misc/maintenance/search_for_data_inconsistencies.pl b/misc/maintenance/search_for_data_inconsistencies.pl index ddc6b457dd..f73be04483 100755 --- a/misc/maintenance/search_for_data_inconsistencies.pl +++ b/misc/maintenance/search_for_data_inconsistencies.pl @@ -26,6 +26,8 @@ use Koha::Biblioitems; use Koha::Items; use Koha::ItemTypes; use Koha::Patrons; +use Koha::Patron::Relationship; +use Koha::Patron::Relationships; use C4::Biblio qw( GetMarcFromKohaField ); { @@ -326,6 +328,95 @@ use C4::Biblio qw( GetMarcFromKohaField ); } } +{ + my @loop_borrowers_relationships; + my $relationships = Koha::Patron::Relationships->search(); + my @patrons_guarantors = Koha::Patron::Relationships::guarantors($relationships)->as_list; + my @patrons_guarantees = Koha::Patron::Relationships::guarantees($relationships)->as_list; + + foreach my $patron_guarantor (@patrons_guarantors) { + foreach my $patron_guarantee (@patrons_guarantees) { + if ($patron_guarantor->borrowernumber == $patron_guarantee->borrowernumber) { + + my $guarantor_id; + my $guarantee_id; + my $size_list; + my $tmp_garantor_id = $patron_guarantor->borrowernumber; + my @guarantor_ids; + + do { + my @relationship_for_go = Koha::Patron::Relationships->search( + { + -or => [ + 'guarantor_id' => { '=', $tmp_garantor_id }, + ] + }, + )->as_list; + $size_list = scalar @relationship_for_go; + + foreach my $relation (@relationship_for_go) { + $guarantor_id = $relation->guarantor_id; + unless (grep { $_ == $guarantor_id } @guarantor_ids) { + push @guarantor_ids, $guarantor_id; + } + $guarantee_id = $relation->guarantee_id; + + my @relationship_for_go = Koha::Patron::Relationships->search( + { + -or => [ + 'guarantor_id' => { '=', $guarantee_id }, + ] + }, + )->as_list; + $size_list = scalar @relationship_for_go; + + if ($patron_guarantor->borrowernumber == $guarantee_id) { + last; + } + + foreach my $relation (@relationship_for_go) { + $guarantor_id = $relation->guarantor_id; + unless (grep { $_ == $guarantor_id } @guarantor_ids) { + push @guarantor_ids, $guarantor_id; + } + $guarantee_id = $relation->guarantee_id; + + if ($patron_guarantor->borrowernumber == $guarantee_id) { + last; + } + } + if ($patron_guarantor->borrowernumber == $guarantee_id) { + last; + } + } + + $tmp_garantor_id = $guarantee_id; + } while ($patron_guarantor->borrowernumber != $guarantee_id && $size_list > 0); + + if ($patron_guarantor->borrowernumber == $guarantee_id) { + unless (grep { join("", sort @$_) eq join("", sort @guarantor_ids) } @loop_borrowers_relationships) { + push @loop_borrowers_relationships, \@guarantor_ids; + } + } + } + } + } + + if (scalar @loop_borrowers_relationships > 0) { + new_section("The list of guarantors who are also guarantee."); + my $count = 0; + foreach my $table (@loop_borrowers_relationships) { + $count++; + print "Loop $count, borrowers id : "; + foreach my $borrower_id (@$table) { + print "$borrower_id | "; + } + print "\n"; + } + new_hint("Relationships that form guarantor loops must be deleted"); + } +} + sub new_section { my ( $name ) = @_; say "\n== $name =="; -- 2.34.1