From f05642589d94c25ef1b1f01b4a2606fe455400b8 Mon Sep 17 00:00:00 2001 From: Jason Etheridge Date: Fri, 8 Mar 2013 10:41:06 -0500 Subject: [PATCH] Bug 9770: fix sorting of Dewey call numbers that contain prefixes C4::ClassSortRoutine::Dewey can pad the wrong part of a call number internally. The subroutine get_class_sort_key tokenizes a call number string (splitting on periods and whitespace) and counts the number of tokens that solely contain digits. If there is only one such digit group, a comment in the code states that it will pad said digit group. However, the bug is that the code assumes said digit group is the first token, when this may not be the case. In practice, this can cause poor sorting when used a call number is in the form of PREFIX _space_ 3DIGITS. To test: [1] Create two item records whose class scheme is set to 'ddc' (Dewey) and whose call numbers contain prefixes, e.g., J DVD 700.1 ABC and J DVD 850 DEF. [2] Use the inventory tool to produce a list of item items that include the two created in step 1. Obsere that that items are sorted in the incorrect order, with "J DVD 850 DEF" coming before "J DVD 700.1 ABC". Alternatively, run the following SQL to see the incorrect sort order: SELECT cn_sort, itemcallnumber FROM items WHERE itemcallnumber LIKE 'J DVD%' ORDER BY cn_sort; [4] Apply this patch. [5] Run misc/maintenance/touch_all_items.pl to force cn_sort to be recalculated. [6] Repeat step 2 and verify that the call numbers are now sorted corrected. Signed-off-by: Jason Etheridge Signed-off-by: Galen Charlton Signed-off-by: Chris Cormack Signed-off-by: Katrin Fischer Signed-off-by: Galen Charlton (cherry picked from commit dba36a7a1216238a260ea5fbe2218627487e9f19) Signed-off-by: Tomas Cohen Arazi --- C4/ClassSortRoutine/Dewey.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/C4/ClassSortRoutine/Dewey.pm b/C4/ClassSortRoutine/Dewey.pm index 1f8b3ef44c..25480ec082 100644 --- a/C4/ClassSortRoutine/Dewey.pm +++ b/C4/ClassSortRoutine/Dewey.pm @@ -67,9 +67,13 @@ sub get_class_sort_key { $init =~ s/^([\p{IsAlpha}]+)/$1 /; my @tokens = split /\.|\s+/, $init; my $digit_group_count = 0; + my $first_digit_group_idx; for (my $i = 0; $i <= $#tokens; $i++) { if ($tokens[$i] =~ /^\d+$/) { $digit_group_count++; + if (1 == $digit_group_count) { + $first_digit_group_idx = $i; + } if (2 == $digit_group_count) { $tokens[$i] = sprintf("%-15.15s", $tokens[$i]); $tokens[$i] =~ tr/ /0/; @@ -78,7 +82,7 @@ sub get_class_sort_key { } # Pad the first digit_group if there was only one if (1 == $digit_group_count) { - $tokens[0] .= '_000000000000000' + $tokens[$first_digit_group_idx] .= '_000000000000000' } my $key = join("_", @tokens); $key =~ s/[^\p{IsAlnum}_]//g; -- 2.39.5