|
Lines 36-47
our %options = (
Link Here
|
| 36 |
'check-framework' => 0, |
36 |
'check-framework' => 0, |
| 37 |
'check-title' => 0, |
37 |
'check-title' => 0, |
| 38 |
'check-age' => 0, |
38 |
'check-age' => 0, |
| 39 |
'skip-branch' => 1, |
39 |
'check-loop' => 0, |
| 40 |
'skip-auth' => 1, |
40 |
'skip-branch' => 0, |
| 41 |
'skip-status' => 1, |
41 |
'skip-auth' => 0, |
| 42 |
'skip-framework' => 1, |
42 |
'skip-status' => 0, |
| 43 |
'skip-title' => 1, |
43 |
'skip-framework' => 0, |
| 44 |
'skip-age' => 1, |
44 |
'skip-title' => 0, |
|
|
45 |
'skip-age' => 0, |
| 46 |
'skip-loop' => 0, |
| 45 |
'help' => 0, |
47 |
'help' => 0, |
| 46 |
); |
48 |
); |
| 47 |
|
49 |
|
|
Lines 53-64
GetOptions(
Link Here
|
| 53 |
'check-framework' => sub { $options{'check-framework'} = 1 }, |
55 |
'check-framework' => sub { $options{'check-framework'} = 1 }, |
| 54 |
'check-title' => sub { $options{'check-title'} = 1 }, |
56 |
'check-title' => sub { $options{'check-title'} = 1 }, |
| 55 |
'check-age' => sub { $options{'check-age'} = 1 }, |
57 |
'check-age' => sub { $options{'check-age'} = 1 }, |
| 56 |
'skip-branch' => sub { $options{'skip-branch'} = 0 }, |
58 |
'check-loop' => sub { $options{'check-loop'} = 1 }, |
| 57 |
'skip-auth' => sub { $options{'skip-auth'} = 0 }, |
59 |
'skip-branch' => sub { $options{'skip-branch'} = 1 }, |
| 58 |
'skip-status' => sub { $options{'skip-status'} = 0 }, |
60 |
'skip-auth' => sub { $options{'skip-auth'} = 1 }, |
| 59 |
'skip-framework' => sub { $options{'skip-framework'} = 0 }, |
61 |
'skip-status' => sub { $options{'skip-status'} = 1 }, |
| 60 |
'skip-title' => sub { $options{'skip-title'} = 0 }, |
62 |
'skip-framework' => sub { $options{'skip-framework'} = 1 }, |
| 61 |
'skip-age' => sub { $options{'skip-age'} = 0 }, |
63 |
'skip-title' => sub { $options{'skip-title'} = 1 }, |
|
|
64 |
'skip-age' => sub { $options{'skip-age'} = 1 }, |
| 65 |
'skip-loop' => sub { $options{'skip-loop'} = 1 }, |
| 62 |
'help' => sub { $options{'help'} = 1; }, |
66 |
'help' => sub { $options{'help'} = 1; }, |
| 63 |
) or pod2usage(2); # Print usage if invalid options are provided |
67 |
) or pod2usage(2); # Print usage if invalid options are provided |
| 64 |
|
68 |
|
|
Lines 74-87
GetOptions(
Link Here
|
| 74 |
# Print usage and exit if --help flag is provided |
78 |
# Print usage and exit if --help flag is provided |
| 75 |
pod2usage(1) if $options{'help'}; |
79 |
pod2usage(1) if $options{'help'}; |
| 76 |
|
80 |
|
| 77 |
# Run tests based on options |
81 |
# Set skip options based on check options |
| 78 |
set_skip_options(); |
82 |
set_skip_options(); |
| 79 |
CheckItemsBranch() if $options{'check-branch'} || $options{'skip-branch'}; |
83 |
|
| 80 |
CheckItemsAuthHeader() if $options{'check-auth'} || $options{'skip-auth'}; |
84 |
# Set all check options to 1 if none are provided, unless specified skip options |
| 81 |
CheckItemsStatus() if $options{'check-status'} || $options{'skip-status'}; |
85 |
set_all_check_options_if_none_provided(); |
| 82 |
CheckItemsFramework() if $options{'check-framework'} || $options{'skip-framework'}; |
86 |
|
| 83 |
CheckItemsTitle() if $options{'check-title'} || $options{'skip-title'}; |
87 |
# Run checks based on options |
| 84 |
CheckAgeForCategory() if $options{'check-age'} || $options{'skip-age'}; |
88 |
CheckItemsBranch() if $options{'check-branch'} && !$options{'skip-branch'}; |
|
|
89 |
CheckItemsAuthHeader() if $options{'check-auth'} && !$options{'skip-auth'}; |
| 90 |
CheckItemsStatus() if $options{'check-status'} && !$options{'skip-status'}; |
| 91 |
CheckItemsFramework() if $options{'check-framework'} && !$options{'skip-framework'}; |
| 92 |
CheckItemsTitle() if $options{'check-title'} && !$options{'skip-title'}; |
| 93 |
CheckAgeForCategory() if $options{'check-age'} && !$options{'skip-age'}; |
| 94 |
CheckRelationshipsLoop() if $options{'check-loop'} && !$options{'skip-loop'}; |
| 85 |
|
95 |
|
| 86 |
# Handle invalid options |
96 |
# Handle invalid options |
| 87 |
sub handle_invalid_options { |
97 |
sub handle_invalid_options { |
|
Lines 92-106
sub handle_invalid_options {
Link Here
|
| 92 |
|
102 |
|
| 93 |
# Set skip options based on check options |
103 |
# Set skip options based on check options |
| 94 |
sub set_skip_options { |
104 |
sub set_skip_options { |
| 95 |
my $has_check_option = grep { $options{$_} == 1 } grep { /^check-/ } keys %options; |
105 |
|
|
|
106 |
# If at least one check option is provided, set all skip options to 0 |
| 107 |
my $has_check_option = grep { $options{$_} } grep { /^check-/ } keys %options; |
| 96 |
if ($has_check_option) { |
108 |
if ($has_check_option) { |
|
|
109 |
|
| 110 |
# if a least one skip option is provided, print a warning |
| 111 |
my $has_skip_option = grep { $options{$_} == 1 } grep { /^skip-/ } keys %options; |
| 112 |
if ($has_skip_option) { |
| 113 |
print("Warning : skip options are ignored when check options are provided\n"); |
| 114 |
} |
| 115 |
|
| 116 |
# Set all skip options to 0 |
| 97 |
foreach my $key ( keys %options ) { |
117 |
foreach my $key ( keys %options ) { |
| 98 |
$options{$key} = 0 if $key =~ /^skip-/; |
118 |
if ( $key =~ /^skip-/ ) { |
|
|
119 |
$options{$key} = 0; |
| 120 |
} |
| 99 |
} |
121 |
} |
| 100 |
} |
122 |
} |
| 101 |
return %options; |
123 |
return %options; |
| 102 |
} |
124 |
} |
| 103 |
|
125 |
|
|
|
126 |
# Set all check options to 1 if none are provided, considering skip options |
| 127 |
sub set_all_check_options_if_none_provided { |
| 128 |
my $any_check_option_provided = grep { $options{$_} } grep { /^check-/ } keys %options; |
| 129 |
if ( !$any_check_option_provided ) { |
| 130 |
foreach my $key ( keys %options ) { |
| 131 |
if ( $key =~ /^check-/ ) { |
| 132 |
my $skip_key = $key; |
| 133 |
$skip_key =~ s/^check-/skip-/; |
| 134 |
|
| 135 |
# Set check option to 1 unless the corresponding skip option indicated |
| 136 |
$options{$key} = 1 unless $options{$skip_key}; |
| 137 |
} |
| 138 |
} |
| 139 |
} |
| 140 |
} |
| 141 |
|
| 104 |
sub CheckItemsBranch { |
142 |
sub CheckItemsBranch { |
| 105 |
my $items = Koha::Items->search( { -or => { homebranch => undef, holdingbranch => undef } } ); |
143 |
my $items = Koha::Items->search( { -or => { homebranch => undef, holdingbranch => undef } } ); |
| 106 |
if ( $items->count ) { new_section("Not defined items.homebranch and/or items.holdingbranch") } |
144 |
if ( $items->count ) { new_section("Not defined items.homebranch and/or items.holdingbranch") } |
|
Lines 453-458
sub CheckAgeForCategory {
Link Here
|
| 453 |
} |
491 |
} |
| 454 |
|
492 |
|
| 455 |
{ |
493 |
{ |
|
|
494 |
use Koha::Database; |
| 495 |
my $schema = Koha::Database->new->schema; |
| 496 |
|
| 497 |
# Loop over all the DBIx::Class classes |
| 498 |
for my $class ( sort values %{ $schema->{class_mappings} } ) { |
| 499 |
|
| 500 |
# Retrieve the resultset so we can access the columns info |
| 501 |
my $rs = $schema->resultset($class); |
| 502 |
my $columns = $rs->result_source->columns_info; |
| 503 |
|
| 504 |
# Loop over the columns |
| 505 |
while ( my ( $column, $info ) = each %$columns ) { |
| 506 |
|
| 507 |
# Next if data type is not date/datetime/timestamp |
| 508 |
my $data_type = $info->{data_type}; |
| 509 |
next unless grep { $data_type =~ m{^$_$} } qw( timestamp datetime date ); |
| 510 |
|
| 511 |
# Count the invalid dates |
| 512 |
my $invalid_dates = $rs->search( { $column => '0000-00-00' } )->count; |
| 513 |
|
| 514 |
next unless $invalid_dates; |
| 515 |
|
| 516 |
new_section( |
| 517 |
"Column " . $rs->result_source->name . "." . $column . " contains $invalid_dates invalid dates" ); |
| 518 |
|
| 519 |
if ( $invalid_dates > 0 ) { |
| 520 |
new_hint("You may change the dates with script: misc/cronjobs/fix_invalid_dates.pl (-c -v)"); |
| 521 |
} |
| 522 |
|
| 523 |
} |
| 524 |
} |
| 525 |
} |
| 526 |
|
| 527 |
{ |
| 528 |
my @loop_borrowers_relationships; |
| 529 |
my @guarantor_ids = Koha::Patron::Relationships->_resultset->get_column('guarantor_id')->all(); |
| 530 |
my @guarantee_ids = Koha::Patron::Relationships->_resultset->get_column('guarantee_id')->all(); |
| 531 |
|
| 532 |
foreach my $guarantor_id (@guarantor_ids) { |
| 533 |
foreach my $guarantee_id (@guarantee_ids) { |
| 534 |
if ( $guarantor_id == $guarantee_id ) { |
| 535 |
|
| 536 |
my $relation_guarantor_id; |
| 537 |
my $relation_guarantee_id; |
| 538 |
my $size_list; |
| 539 |
my $tmp_garantor_id = $guarantor_id; |
| 540 |
my @guarantor_ids; |
| 541 |
|
| 542 |
do { |
| 543 |
my @relationship_for_go = Koha::Patron::Relationships->search( |
| 544 |
{ |
| 545 |
-or => [ |
| 546 |
'guarantor_id' => { '=', $tmp_garantor_id }, |
| 547 |
] |
| 548 |
}, |
| 549 |
)->as_list; |
| 550 |
$size_list = scalar @relationship_for_go; |
| 551 |
|
| 552 |
foreach my $relation (@relationship_for_go) { |
| 553 |
$relation_guarantor_id = $relation->guarantor_id; |
| 554 |
unless ( grep { $_ == $relation_guarantor_id } @guarantor_ids ) { |
| 555 |
push @guarantor_ids, $relation_guarantor_id; |
| 556 |
} |
| 557 |
$relation_guarantee_id = $relation->guarantee_id; |
| 558 |
|
| 559 |
my @relationship_for_go = Koha::Patron::Relationships->search( |
| 560 |
{ |
| 561 |
-or => [ |
| 562 |
'guarantor_id' => { '=', $relation_guarantee_id }, |
| 563 |
] |
| 564 |
}, |
| 565 |
)->as_list; |
| 566 |
$size_list = scalar @relationship_for_go; |
| 567 |
|
| 568 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 569 |
last; |
| 570 |
} |
| 571 |
|
| 572 |
foreach my $relation (@relationship_for_go) { |
| 573 |
$relation_guarantor_id = $relation->guarantor_id; |
| 574 |
unless ( grep { $_ == $relation_guarantor_id } @guarantor_ids ) { |
| 575 |
push @guarantor_ids, $relation_guarantor_id; |
| 576 |
} |
| 577 |
$relation_guarantee_id = $relation->guarantee_id; |
| 578 |
|
| 579 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 580 |
last; |
| 581 |
} |
| 582 |
} |
| 583 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 584 |
last; |
| 585 |
} |
| 586 |
} |
| 587 |
|
| 588 |
$tmp_garantor_id = $relation_guarantee_id; |
| 589 |
} while ( $guarantor_id != $relation_guarantee_id && $size_list > 0 ); |
| 590 |
|
| 591 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 592 |
unless ( grep { join( "", sort @$_ ) eq join( "", sort @guarantor_ids ) } |
| 593 |
@loop_borrowers_relationships ) |
| 594 |
{ |
| 595 |
push @loop_borrowers_relationships, \@guarantor_ids; |
| 596 |
} |
| 597 |
} |
| 598 |
} |
| 599 |
} |
| 600 |
} |
| 601 |
|
| 602 |
if ( scalar @loop_borrowers_relationships > 0 ) { |
| 603 |
new_section("The list of guarantors who are also guarantee."); |
| 604 |
my $count = 0; |
| 605 |
foreach my $table (@loop_borrowers_relationships) { |
| 606 |
$count++; |
| 607 |
print "Loop $count, borrowers id : "; |
| 608 |
foreach my $borrower_id (@$table) { |
| 609 |
print "$borrower_id , "; |
| 610 |
} |
| 611 |
print "\n"; |
| 612 |
} |
| 613 |
new_hint("Relationships that form guarantor loops must be deleted"); |
| 614 |
} |
| 615 |
} |
| 616 |
|
| 617 |
sub CheckRelationshipsLoop { |
| 618 |
my @loop_borrowers_relationships; |
| 619 |
my @guarantor_ids = Koha::Patron::Relationships->_resultset->get_column('guarantor_id')->all(); |
| 620 |
my @guarantee_ids = Koha::Patron::Relationships->_resultset->get_column('guarantee_id')->all(); |
| 621 |
|
| 622 |
foreach my $guarantor_id (@guarantor_ids) { |
| 623 |
foreach my $guarantee_id (@guarantee_ids) { |
| 624 |
if ( $guarantor_id == $guarantee_id ) { |
| 625 |
|
| 626 |
my $relation_guarantor_id; |
| 627 |
my $relation_guarantee_id; |
| 628 |
my $size_list; |
| 629 |
my $tmp_garantor_id = $guarantor_id; |
| 630 |
my @guarantor_ids; |
| 631 |
|
| 632 |
do { |
| 633 |
my @relationship_for_go = Koha::Patron::Relationships->search( |
| 634 |
{ |
| 635 |
-or => [ |
| 636 |
'guarantor_id' => { '=', $tmp_garantor_id }, |
| 637 |
] |
| 638 |
}, |
| 639 |
)->as_list; |
| 640 |
$size_list = scalar @relationship_for_go; |
| 641 |
|
| 642 |
foreach my $relation (@relationship_for_go) { |
| 643 |
$relation_guarantor_id = $relation->guarantor_id; |
| 644 |
unless ( grep { $_ == $relation_guarantor_id } @guarantor_ids ) { |
| 645 |
push @guarantor_ids, $relation_guarantor_id; |
| 646 |
} |
| 647 |
$relation_guarantee_id = $relation->guarantee_id; |
| 648 |
|
| 649 |
my @relationship_for_go = Koha::Patron::Relationships->search( |
| 650 |
{ |
| 651 |
-or => [ |
| 652 |
'guarantor_id' => { '=', $relation_guarantee_id }, |
| 653 |
] |
| 654 |
}, |
| 655 |
)->as_list; |
| 656 |
$size_list = scalar @relationship_for_go; |
| 657 |
|
| 658 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 659 |
last; |
| 660 |
} |
| 661 |
|
| 662 |
foreach my $relation (@relationship_for_go) { |
| 663 |
$relation_guarantor_id = $relation->guarantor_id; |
| 664 |
unless ( grep { $_ == $relation_guarantor_id } @guarantor_ids ) { |
| 665 |
push @guarantor_ids, $relation_guarantor_id; |
| 666 |
} |
| 667 |
$relation_guarantee_id = $relation->guarantee_id; |
| 668 |
|
| 669 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 670 |
last; |
| 671 |
} |
| 672 |
} |
| 673 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 674 |
last; |
| 675 |
} |
| 676 |
} |
| 677 |
|
| 678 |
$tmp_garantor_id = $relation_guarantee_id; |
| 679 |
} while ( $guarantor_id != $relation_guarantee_id && $size_list > 0 ); |
| 680 |
|
| 681 |
if ( $guarantor_id == $relation_guarantee_id ) { |
| 682 |
unless ( grep { join( "", sort @$_ ) eq join( "", sort @guarantor_ids ) } |
| 683 |
@loop_borrowers_relationships ) |
| 684 |
{ |
| 685 |
push @loop_borrowers_relationships, \@guarantor_ids; |
| 686 |
} |
| 687 |
} |
| 688 |
} |
| 689 |
} |
| 690 |
} |
| 691 |
|
| 692 |
if ( scalar @loop_borrowers_relationships > 0 ) { |
| 693 |
new_section("The list of guarantors who are also guarantee."); |
| 694 |
my $count = 0; |
| 695 |
foreach my $table (@loop_borrowers_relationships) { |
| 696 |
$count++; |
| 697 |
print "Loop $count, borrowers id : "; |
| 698 |
foreach my $borrower_id (@$table) { |
| 699 |
print "$borrower_id , "; |
| 700 |
} |
| 701 |
print "\n"; |
| 702 |
} |
| 703 |
new_hint("Relationships that form guarantor loops must be deleted"); |
| 704 |
} |
| 705 |
} |
| 706 |
|
| 707 |
sub CheckRelationshipsLoop { |
| 456 |
my @loop_borrowers_relationships; |
708 |
my @loop_borrowers_relationships; |
| 457 |
my @guarantor_ids = Koha::Patron::Relationships->_resultset->get_column('guarantor_id')->all(); |
709 |
my @guarantor_ids = Koha::Patron::Relationships->_resultset->get_column('guarantor_id')->all(); |
| 458 |
my @guarantee_ids = Koha::Patron::Relationships->_resultset->get_column('guarantee_id')->all(); |
710 |
my @guarantee_ids = Koha::Patron::Relationships->_resultset->get_column('guarantee_id')->all(); |
|
Lines 574-596
Catch data inconsistencies in Koha database:
Link Here
|
| 574 |
* Bibliographic records without a title |
826 |
* Bibliographic records without a title |
| 575 |
* Invalid MARCXML in bibliographic records |
827 |
* Invalid MARCXML in bibliographic records |
| 576 |
* Patrons with invalid category types due to lower and upper age limits |
828 |
* Patrons with invalid category types due to lower and upper age limits |
|
|
829 |
* Relationships that form guarantor loops |
| 577 |
* Any date fields in the database (timestamp, datetime, date) set to 0000-00-00 |
830 |
* Any date fields in the database (timestamp, datetime, date) set to 0000-00-00 |
| 578 |
|
831 |
|
| 579 |
=head2 OPTIONS |
832 |
=head2 OPTIONS |
| 580 |
|
833 |
|
| 581 |
--check-branch Check for items without home or holding library |
834 |
--check-branch Check for items without home or holding library |
| 582 |
--check-auth Check for authority records with invalid authority type |
835 |
--check-auth Check for authority records with invalid authority type |
| 583 |
--check-status Check for bibliographic records and items without an item type or with an invalid item type |
836 |
--check-status Check for bibliographic records and items without an item type or with an invalid item type |
| 584 |
--check-framework Check for invalid values in fields where the framework limits to an authorized value category |
837 |
--check-framework Check for invalid values in fields where the framework limits to an authorized value category |
| 585 |
--check-title Check for bibliographic records without a title |
838 |
--check-title Check for bibliographic records without a title |
| 586 |
--check-age Check for patrons with invalid age for category |
839 |
--check-age Check for patrons with invalid age for category |
| 587 |
--skip-branch Skip checking for items without home or holding library |
840 |
--check-loop Check for relationships that form guarantor loops |
| 588 |
--skip-auth Skip checking for authority records with invalid authority type |
841 |
--skip-branch Skip checking for items without home or holding library |
| 589 |
--skip-status Skip checking for bibliographic records and items without an item type or with an invalid item type |
842 |
--skip-auth Skip checking for authority records with invalid authority type |
| 590 |
--skip-framework Skip checking for invalid values in fields where the framework limits to an authorized value category |
843 |
--skip-status Skip checking for bibliographic records and items without an item type or with an invalid item type |
| 591 |
--skip-title Skip checking for bibliographic records without a title |
844 |
--skip-framework Skip checking for invalid values in fields where the framework limits to an authorized value category |
| 592 |
--skip-age Skip checking for patrons with invalid age for category |
845 |
--skip-title Skip checking for bibliographic records without a title |
| 593 |
--help Print usage information |
846 |
--skip-age Skip checking for patrons with invalid age for category |
|
|
847 |
--skip-loop Skip checking for relationships that form guarantor loops |
| 848 |
--help Print usage information |
| 594 |
|
849 |
|
| 595 |
Note: If no options are provided, all tests will be run. |
850 |
Note: If no options are provided, all tests will be run. |
| 596 |
|
851 |
|
| 597 |
- |
|
|