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

(-)a/Koha/Biblio.pm (+57 lines)
Lines 891-896 sub to_api_mapping { Link Here
891
    };
891
    };
892
}
892
}
893
893
894
=head3 host_record
895
896
    $host = $biblio->host_record;
897
    # OR:
898
    ( $host, $relatedparts ) = $biblio->host_record;
899
900
    Returns host biblio record from MARC21 773 (undef if no 773 present).
901
    It looks at the first 773 field with MARCorgCode or only a control
902
    number. Complete $w or numeric part is used to search host record.
903
    The optional parameter no_items triggers a check if $biblio has items.
904
    If there are, the sub returns undef.
905
    Called in list context, it also returns 773$g (related parts).
906
907
=cut
908
909
sub host_record {
910
    my ($self, $params) = @_;
911
    my $no_items = $params->{no_items};
912
    return if C4::Context->preference('marcflavour') eq 'UNIMARC'; # TODO
913
    return if $params->{no_items} && $self->items->count > 0;
914
915
    my $record;
916
    eval { $record = $self->metadata->record };
917
    return if !$record;
918
919
    # We pick the first $w with your MARCOrgCode or the first $w that has no
920
    # code (between parentheses) at all.
921
    my $orgcode = C4::Context->preference('MARCOrgCode') // q{};
922
    my $hostfld;
923
    foreach my $f ( $record->field('773') ) {
924
        my $w = $f->subfield('w') or next;
925
        if( $w =~ /^\($orgcode\)\s*(\d+)/i or $w =~ /^\d+/ ) {
926
            $hostfld = $f;
927
            last;
928
        }
929
    }
930
    return if !$hostfld;
931
    my $rcn = $hostfld->subfield('w');
932
933
    # Look for control number with/without orgcode
934
    my $engine = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
935
    my $bibno;
936
    for my $try (1..2) {
937
        my ( $error, $results, $total_hits ) = $engine->simple_search_compat( 'Control-number='.$rcn, 0,1 );
938
        if( !$error and $total_hits == 1 ) {
939
            $bibno = $engine->extract_biblionumber( $results->[0] );
940
            last;
941
        }
942
        # Extract number from $w (remove orgcode) for second try
943
        $rcn= $1 if $try == 1 && $rcn =~ /\)\s*(\d+)/;
944
    }
945
    if( $bibno ) {
946
        my $host = Koha::Biblios->find($bibno) or return;
947
        return wantarray ? ( $host, $hostfld->subfield('g') ) : $host;
948
    }
949
}
950
894
=head2 Internal methods
951
=head2 Internal methods
895
952
896
=head3 type
953
=head3 type
(-)a/t/db_dependent/Koha/Biblio/host_record.t (-1 / +102 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 1;
21
use Data::Dumper qw/Dumper/;
22
use MARC::Field;
23
use MARC::Record;
24
use Test::MockModule;
25
use Test::MockObject;
26
27
use t::lib::TestBuilder;
28
use t::lib::Mocks;
29
use Koha::Database;
30
use Koha::Biblios;
31
use C4::Biblio;
32
33
34
my $schema = Koha::Database->new->schema;
35
$schema->storage->txn_begin;
36
our $builder = t::lib::TestBuilder->new;
37
38
subtest 'host_record' => sub {
39
    plan tests => 11;
40
41
    t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
42
    t::lib::Mocks::mock_preference( 'MARCOrgCode', 'xyz' );
43
44
    my $bib1 = $builder->build_object({ class => 'Koha::Biblios' });
45
    my $bib2 = $builder->build_object({ class => 'Koha::Biblios' });
46
    my $marc = MARC::Record->new;
47
    my $results = [];
48
49
    # Lets mock! Simulate search engine response and biblio metadata call.
50
    my $metadata = Test::MockObject->new;
51
    $metadata->mock( 'record', sub { return $marc; } );
52
    my $meta_mod = Test::MockModule->new( 'Koha::Biblio' );
53
    $meta_mod->mock( 'metadata', sub { return $metadata; } );
54
    my $engine = Test::MockObject->new;
55
    $engine->mock( 'simple_search_compat', sub { return ( undef, $results, scalar @$results ); } );
56
    $engine->mock( 'extract_biblionumber', sub { return $results->[0]; } );
57
    my $search_mod = Test::MockModule->new( 'Koha::SearchEngine::Search' );
58
    $search_mod->mock( 'new', sub { return $engine; } );
59
60
    # Case 1: Search engine does not return any results on controlnumber
61
    is( $bib1->host_record, undef, 'Empty MARC record' );
62
    $marc->append_fields(
63
        MARC::Field->new( '773', '', '', g => 'relpart', w => '(xyz)123' ),
64
    );
65
    is( $bib1->host_record, undef, '773 looks fine, but no search results' );
66
67
    # Case 2: Search engine returns (at maximum) one result
68
    $results = [ $bib1->biblionumber ]; # will be found because 773w is in shape
69
    my $host = $bib1->host_record;
70
    is( ref( $host ), 'Koha::Biblio', 'Correct object returned' );
71
    is( $host->biblionumber, $bib1->biblionumber, 'Check biblionumber' );
72
    $marc->field('773')->update( w => '(xyz) bad data' ); # causes no results
73
    $host = $bib1->host_record;
74
    is( $bib1->host_record, undef, 'No results for bad 773' );
75
    # Add second 773
76
    $marc->append_fields( MARC::Field->new( '773', '', '', g => 'relpart2', w => '234' ) );
77
    $host = $bib1->host_record;
78
    is( $host->biblionumber, $bib1->biblionumber, 'Result triggered by second 773' );
79
    # Replace orgcode
80
    ($marc->field('773'))[1]->update( w => '(abc)345' );
81
    is( $bib1->host_record, undef, 'No results for two 773s' );
82
    # Test no_items flag
83
    ($marc->field('773'))[1]->update( w => '234' ); # restore
84
    $host = $bib1->host_record({ no_items => 1 });
85
    is( $host->biblionumber, $bib1->biblionumber, 'Record found with no_items' );
86
    $builder->build({ source => 'Item', value => { biblionumber => $bib1->biblionumber } });
87
    is( $bib1->host_record({ no_items => 1 }), undef, 'Record not found with no_items flag after adding one item' );
88
    # Test list context
89
    my @temp = $bib1->host_record;
90
    is( $temp[1], 'relpart2', 'Return $g in list context' );
91
92
    # Case 3: Search engine returns more results
93
    $results = [ 1, 2 ];
94
    is( $bib1->host_record, undef, 'host_record returns undef for non-unique control number' );
95
};
96
97
sub mocked_search {
98
    my $results = shift;
99
    return ( undef, $results, scalar @$results );
100
}
101
102
$schema->storage->txn_rollback();

Return to bug 20310