View | Details | Raw Unified | Return to bug 8994
Collapse All | Expand All

(-)a/C4/AuthoritiesMarc.pm (-24 / +111 lines)
Lines 824-862 Comments : an improvement would be to return All the records that match. Link Here
824
824
825
=cut
825
=cut
826
826
827
sub _find_duplicate_authority_try {
828
    my ($try, $authorityfield, $authtypecode) = @_;
829
830
    my $filtervalues =
831
        qr([\001-\040\!\'\"\`\#\$\%\&\*\+,\-\./:;<=>\?\@\(\)\{\[\]\}_\|\~]);
832
833
    my $op = 'and';
834
    if (C4::Context->preference('UseQueryParser')) {
835
        my $QParser = C4::Context->queryparser;
836
        if ($QParser) {
837
            $op = '&&';
838
        }
839
    }
840
841
    # build a request for SearchAuthorities
842
    my $query = "at=$authtypecode";
843
844
    my $duplicaterecord;
845
    if ($try->{field} and $try->{subfields}) {
846
        foreach my $s (@{ $try->{subfields} }) {
847
            my $v = $authorityfield->subfield($s);
848
            if ($v) {
849
                $v =~ s/$filtervalues/ /g;
850
                $v =~ s/^\s*//;
851
                $v =~ s/\s*$//;
852
                $query .= qq/ $op $try->{index}="$v"/;
853
            }
854
        }
855
        my $maxresults = C4::Context->preference('FindDuplicateAuthorityMaxResults') || 10;
856
        my ($error, $results, $total_hits) =
857
            C4::Search::SimpleSearch($query, 0, $maxresults, ["authorityserver"]);
858
        return unless (!defined $error and @{$results});
859
860
        foreach my $result (@$results) {
861
            my $marcrecord = MARC::File::USMARC::decode($result);
862
            my @marcfields = $marcrecord->field($try->{field});
863
            next if (scalar @marcfields == 0);
864
            my $stillmatch = 1;
865
            foreach my $marcfield (@marcfields) {
866
                foreach my $subfield (@{ $try->{subfields} }) {
867
                    my $authoritysubfield = $authorityfield->subfield($subfield);
868
                    my $marcsubfield = $marcfield->subfield($subfield);
869
                    if ( (defined $authoritysubfield xor defined $marcsubfield)
870
                      or (defined $authoritysubfield
871
                        and $authoritysubfield ne $marcsubfield)
872
                    ) {
873
                        $stillmatch = 0;
874
                        last;
875
                    }
876
                }
877
                last unless $stillmatch;
878
            }
879
            if ($stillmatch) {
880
                $duplicaterecord = $marcrecord;
881
                last;
882
            }
883
        }
884
    } else {
885
        foreach my $s ($authorityfield->subfields()) {
886
            next unless ($s->[0] =~ /[A-z]/);
887
            $s->[1] =~ s/$filtervalues/ /g;
888
            $query .= qq/ $op $try->{index}="$s->[1]"/;
889
        }
890
        my ($error, $results, $total_hits) =
891
            C4::Search::SimpleSearch( $query, 0, 1, ["authorityserver"] );
892
        if (!defined $error and @{$results}) {
893
            $duplicaterecord = MARC::File::USMARC::decode($results->[0]);
894
        }
895
    }
896
897
    return $duplicaterecord;
898
}
899
827
sub FindDuplicateAuthority {
900
sub FindDuplicateAuthority {
901
    my ($record, $authtypecode) = @_;
902
903
    return unless $record;
904
905
    my $opts = C4::Context->preference('FindDuplicateAuthorityOptions');
906
    return unless $opts;
828
907
829
    my ($record,$authtypecode)=@_;
830
#    warn "IN for ".$record->as_formatted;
831
    my $dbh = C4::Context->dbh;
908
    my $dbh = C4::Context->dbh;
832
#    warn "".$record->as_formatted;
909
    my $sth = $dbh->prepare("
833
    my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?");
910
        SELECT auth_tag_to_report FROM auth_types WHERE authtypecode = ?
911
    ");
834
    $sth->execute($authtypecode);
912
    $sth->execute($authtypecode);
835
    my ($auth_tag_to_report) = $sth->fetchrow;
913
    my ($auth_tag_to_report) = $sth->fetchrow;
836
    $sth->finish;
914
    $sth->finish;
837
#     warn "record :".$record->as_formatted."  auth_tag_to_report :$auth_tag_to_report";
915
838
    # build a request for SearchAuthorities
916
    my $authorityfield = $record->field($auth_tag_to_report);
839
    my $QParser;
917
    return unless $authorityfield;
840
    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
918
841
    my $op;
919
    my @tries;
842
    if ($QParser) {
920
    $opts =~ s/ //g;
843
        $op = '&&';
921
    foreach my $try (split /\|/, $opts) {
844
    } else {
922
        my ($index, $matchcheck) = split m#/#, $try;
845
        $op = 'and';
923
        my ($field, @subfields);
924
        if ($matchcheck and length($matchcheck) > 3) {
925
            $field = substr $matchcheck, 0, 3;
926
            @subfields = split(//, substr($matchcheck, 3));
927
        }
928
        push @tries, {
929
            index => $index,
930
            field => $field,
931
            subfields => \@subfields,
932
        };
846
    }
933
    }
847
    my $query='at:'.$authtypecode.' ';
934
848
    my $filtervalues=qr([\001-\040\!\'\"\`\#\$\%\&\*\+,\-\./:;<=>\?\@\(\)\{\[\]\}_\|\~]);
935
    my $duplicaterecord;
849
    if ($record->field($auth_tag_to_report)) {
936
    foreach my $try (@tries) {
850
      foreach ($record->field($auth_tag_to_report)->subfields()) {
937
        $duplicaterecord = _find_duplicate_authority_try($try, $authorityfield,
851
        $_->[1]=~s/$filtervalues/ /g; $query.= " $op he:\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/);
938
            $authtypecode);
852
      }
939
        last if $duplicaterecord;
853
    }
940
    }
854
    my ($error, $results, $total_hits) = C4::Search::SimpleSearch( $query, 0, 1, [ "authorityserver" ] );
941
855
    # there is at least 1 result => return the 1st one
942
    if ($duplicaterecord) {
856
    if (!defined $error && @{$results} ) {
943
        my $authid = $duplicaterecord->field('001')->data;
857
      my $marcrecord = MARC::File::USMARC::decode($results->[0]);
944
        return $authid, BuildSummary($duplicaterecord, $authid, $authtypecode);
858
      return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode);
859
    }
945
    }
946
860
    # no result, returns nothing
947
    # no result, returns nothing
861
    return;
948
    return;
862
}
949
}
(-)a/installer/data/mysql/sysprefs.sql (+2 lines)
Lines 108-113 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
108
('ExtendedPatronAttributes','0',NULL,'Use extended patron IDs and attributes','YesNo'),
108
('ExtendedPatronAttributes','0',NULL,'Use extended patron IDs and attributes','YesNo'),
109
('FacetLabelTruncationLength','20',NULL,'Specify the facet max length in OPAC','Integer'),
109
('FacetLabelTruncationLength','20',NULL,'Specify the facet max length in OPAC','Integer'),
110
('FilterBeforeOverdueReport','0','','Do not run overdue report until filter selected','YesNo'),
110
('FilterBeforeOverdueReport','0','','Do not run overdue report until filter selected','YesNo'),
111
('FindDuplicateAuthorityOptions','he,wrdl',NULL,'Options to determine how to search for duplicate authorities. General form: "index1/XXXcc|index2" where indexX is the index where we want to search, and XXXcc the field(s) and subfield(s) we want to check for each search results (if omitted, the first result is returned as duplicate)','Free'),
112
('FindDuplicateAuthorityMaxResults','10',NULL'Maximum number of results fetched when searching a duplicate','Free'),
111
('FineNotifyAtCheckin','0',NULL,'If ON notify librarians of overdue fines on the items they are checking in.','YesNo'),
113
('FineNotifyAtCheckin','0',NULL,'If ON notify librarians of overdue fines on the items they are checking in.','YesNo'),
112
('finesCalendar','noFinesWhenClosed','ignoreCalendar|noFinesWhenClosed','Specify whether to use the Calendar in calculating duedates and fines','Choice'),
114
('finesCalendar','noFinesWhenClosed','ignoreCalendar|noFinesWhenClosed','Specify whether to use the Calendar in calculating duedates and fines','Choice'),
113
('FinesIncludeGracePeriod','1',NULL,'If enabled, fines calculations will include the grace period.','YesNo'),
115
('FinesIncludeGracePeriod','1',NULL,'If enabled, fines calculations will include the grace period.','YesNo'),
(-)a/installer/data/mysql/updatedatabase.pl (+15 lines)
Lines 7330-7335 if ( CheckVersion($DBversion) ) { Link Here
7330
    SetVersion($DBversion);
7330
    SetVersion($DBversion);
7331
}
7331
}
7332
7332
7333
$DBversion = "3.13.00.XXX";
7334
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
7335
    $dbh->do(q{
7336
        INSERT INTO systempreferences (variable, value, explanation, options, type)
7337
        VALUES ('FindDuplicateAuthorityOptions', 'he,wrdl', 'Options to determine how to search for duplicate authorities. General form: "index1/XXXcc#index2" where indexX is the index where we want to search, and XXXcc the field(s) and subfield(s) we want to check for each search results (if omitted, the first result is returned as duplicate)', NULL, 'Free');
7338
    });
7339
    $dbh->do(q{
7340
        INSERT INTO systempreferences (variable, value, explanation, options, type)
7341
        VALUES ('FindDuplicateAuthorityMaxResults', '10', 'Maximum number of results fetched when searching a duplicate', NULL, 'Integer');
7342
    });
7343
    print "Upgrade to $DBversion done (Bug 8994: Added system preferences FindDuplicateAuthorityOptions and FindDuplicateAuthorityMaxResults)\n";
7344
    SetVersion($DBversion);
7345
}
7346
7347
7333
=head1 FUNCTIONS
7348
=head1 FUNCTIONS
7334
7349
7335
=head2 TableExists($table)
7350
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/authorities.pref (-1 / +19 lines)
Lines 49-54 Authorities: Link Here
49
              defautl: "afrey50      ba0"
49
              defautl: "afrey50      ba0"
50
              type: textarea
50
              type: textarea
51
              class: code
51
              class: code
52
        -
53
            - pref: FindDuplicateAuthorityOptions
54
              class: long
55
            - '<br />Options to determine how to search for duplicate authorities when creating new authorities. General form: "index1/XXXcc | index2" where indexX is the index where we want to search, and XXXcc the field(s) and subfield(s) we want to check for each search results (if "XXXcc" part is omitted, the first result is returned as duplicate)'
56
            - '<br />Examples:'
57
            - '<br />- <tt>he,wrdl</tt>: Search in "he" index, do not check subfields data in search results, the first result is returned as a duplicate (default).'
58
            - '<br />- <tt>he,wrdl/2..ab</tt>: Search in "he" index, and compare 2XX$a and 2XX$b of search results with XXX$a and XXX$b of created authority (XXX is the "Authority field to copy"). The first matching authority is returned as duplicate.'
59
            - '<br />- <tt>he,wrdl | See,wrdl/4..ab</tt>: Search in "he" index and do not check subfields. If there is no results, search in "See" index and compare 4XX$a and 4XX$b of search results with XXX$a and XXX$b of created authority.'
60
            - '<br />Notes:'
61
            - '<br />- only authorities of the same type are returned by the search'
62
            - '<br />- the query to find authorities is build with subfields in syspref. For example <tt>he,wrdl/2..ab</tt> will search <tt>he,wrdl="2XX$a" and "he,wrdl="2XX$b"</tt>'
63
            - '<br />- if compared subfields are repeatable, only the first of each field is checked'
64
            - '<br />- spaces are insignificant'
65
            - '<br />- if value is empty, it disable authority duplicate searching.'
66
        -
67
            - 'Maximum number of results fetched when searching a duplicate:'
68
            - pref: FindDuplicateAuthorityMaxResults
69
              class: integer
70
            - "It's only used when FindDuplicateAuthorityOptions contains fields and subfields to check against (default: 10)"
52
    Linker:
71
    Linker:
53
        -
72
        -
54
            - Use the
73
            - Use the
55
- 

Return to bug 8994