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

(-)a/Koha/Biblio.pm (+70 lines)
Lines 22-32 use Modern::Perl; Link Here
22
use List::MoreUtils qw( any );
22
use List::MoreUtils qw( any );
23
use URI;
23
use URI;
24
use URI::Escape qw( uri_escape_utf8 );
24
use URI::Escape qw( uri_escape_utf8 );
25
use Try::Tiny;
25
26
26
use C4::Koha qw( GetNormalizedISBN GetNormalizedUPC GetNormalizedOCLCNumber );
27
use C4::Koha qw( GetNormalizedISBN GetNormalizedUPC GetNormalizedOCLCNumber );
28
use C4::Biblio qw( DelBiblio );
29
use C4::Serials qw( CountSubscriptionFromBiblionumber );
30
use C4::Reserves qw( MergeHolds );
31
use C4::Acquisition qw( ModOrder GetOrdersByBiblionumber );
27
32
28
use Koha::Database;
33
use Koha::Database;
29
use Koha::DateUtils qw( dt_from_string );
34
use Koha::DateUtils qw( dt_from_string );
35
use Koha::Exception;
30
36
31
use base qw(Koha::Object);
37
use base qw(Koha::Object);
32
38
Lines 1919-1924 sub opac_summary_html { Link Here
1919
    return $summary_html;
1925
    return $summary_html;
1920
}
1926
}
1921
1927
1928
=head3 merge_with
1929
1930
    my $biblio = Koha::Biblios->find($biblionumber);
1931
    $biblio->merge_with(\@biblio_ids);
1932
1933
    This subroutine merges a list of bibliographic records into the bibliographic record.
1934
    This function DOES NOT CHANGE the bibliographic metadata of the record. But it links all
1935
    items, holds, subscriptions, serials issues and article_requests to the record. After doing changes
1936
    bibliographic records listed are deleted
1937
1938
=cut
1939
1940
sub merge_with {
1941
    my ( $self, $biblio_ids ) = @_;
1942
1943
    my $schema           = Koha::Database->new()->schema();
1944
    my $ref_biblionumber = $self->biblionumber;
1945
    my %results          = ( 'biblio_id' => $ref_biblionumber, 'merged_ids' => [] );
1946
1947
    # Ensure the keeper isn't in the list of records to merge
1948
    my @biblio_ids_to_merge = grep { $_ ne $ref_biblionumber } @$biblio_ids;
1949
1950
    try {
1951
        $schema->txn_do(
1952
            sub {
1953
                foreach my $bn_merge (@biblio_ids_to_merge) {
1954
                    my $from_biblio = Koha::Biblios->find($bn_merge);
1955
                    $from_biblio->items->move_to_biblio($self);
1956
                    $from_biblio->article_requests->update(
1957
                        { biblionumber => $ref_biblionumber },
1958
                        { no_triggers  => 1 }
1959
                    );
1960
1961
                    for my $resultset_name (qw(Subscription Subscriptionhistory Serial Suggestion)) {
1962
                        $schema->resultset($resultset_name)->search( { biblionumber => $bn_merge } )
1963
                            ->update( { biblionumber => $ref_biblionumber } );
1964
                    }
1965
1966
                    # TODO should this be ported to more modern DB usage (i.e. DBIx::Class)?
1967
                    my @allorders = GetOrdersByBiblionumber($bn_merge);
1968
                    foreach my $myorder (@allorders) {
1969
                        $myorder->{'biblionumber'} = $ref_biblionumber;
1970
                        ModOrder($myorder);
1971
1972
                        # TODO : add error control (in ModOrder?)
1973
                    }
1974
1975
                    # Move holds
1976
                    MergeHolds( $schema->storage->dbh, $ref_biblionumber, $bn_merge );
1977
                    my $error = DelBiblio($bn_merge);    #DelBiblio return undef unless an error occurs
1978
                    if ($error) {
1979
                        die $error;
1980
                    } else {
1981
                        push( @{ $results{merged_ids} }, $bn_merge );
1982
                    }
1983
                }
1984
            }
1985
        );
1986
    } catch {
1987
        Koha::Exception->throw($_);
1988
    };
1989
    return \%results;
1990
}
1991
1922
=head2 Internal methods
1992
=head2 Internal methods
1923
1993
1924
=head3 type
1994
=head3 type
(-)a/Koha/REST/V1/Biblios.pm (+84 lines)
Lines 35-40 use List::MoreUtils qw( any ); Link Here
35
use MARC::Record::MiJ;
35
use MARC::Record::MiJ;
36
36
37
use Try::Tiny qw( catch try );
37
use Try::Tiny qw( catch try );
38
use JSON qw( decode_json );
38
39
39
=head1 API
40
=head1 API
40
41
Lines 892-895 sub list { Link Here
892
    };
893
    };
893
}
894
}
894
895
896
=head3 merge
897
898
Controller function that handles merging two biblios. If an optional
899
MARCXML is provided as the request body, this MARCXML replaces the
900
bibliodata of the merge target biblio. Syntax format inside the request body
901
must match with the Marc format used into Koha installation (MARC21 or UNIMARC)
902
903
=cut
904
905
sub merge {
906
    my $c                = shift->openapi->valid_input or return;
907
    my $ref_biblionumber = $c->param('biblio_id');
908
    my $json             = decode_json( $c->req->body );
909
    my $bn_merge         = $json->{'biblio_id_to_merge'};
910
    my $framework        = $json->{'framework_to_use'};
911
    my $rules            = $json->{'rules'};
912
    my $override_rec     = $json->{'datarecord'};
913
914
    if ( ( !defined $rules ) || ( $rules eq '' ) ) { $rules        = 'override'; }
915
    if ( ( !defined $override_rec ) )              { $override_rec = ''; }
916
    if ( ( !defined $framework ) )                 { $framework    = ''; }
917
918
    my $biblio = Koha::Biblios->find($ref_biblionumber);
919
    if ( not defined $biblio ) {
920
        return $c->render(
921
            status => 404,
922
            json   => { error => sprintf( "[%s] biblio to merge into not found", $ref_biblionumber ) }
923
        );
924
    }
925
    my $frombib = Koha::Biblios->find($bn_merge);
926
    if ( not defined $frombib ) {
927
        return $c->render(
928
            status => 404,
929
            json   => { error => sprintf( "[%s] from which to merge not found", $bn_merge ) }
930
        );
931
    }
932
933
    if ( ( $rules eq 'override_ext' ) && ( $override_rec eq '' ) ) {
934
        return $c->render(
935
            status => 404,
936
            json   => {
937
                error =>
938
                    "With the rule 'override_ext' you need to insert a bib record in marc-in-json format into 'record' field."
939
            }
940
        );
941
    }
942
943
    if ( ( $rules eq 'override' ) && ( $framework ne '' ) ) {
944
        return $c->render(
945
            status => 404,
946
            json   => { error => "With the rule 'override' you can not use the field 'framework_to_use'." }
947
        );
948
    }
949
950
    my $results;
951
    eval {
952
        if ( $rules eq 'override_ext' ) {
953
            my $record = MARC::Record::MiJ->new_from_mij_structure($override_rec);
954
            $record->encoding('UTF-8');
955
            if ( $framework eq '' ) { $framework = $biblio->frameworkcode; }
956
            my $chk = ModBiblio( $record, $ref_biblionumber, $framework );
957
            if ( $chk != 1 ) { die "Error on ModBiblio"; }    # ModBiblio returns 1 if everything as gone well
958
            my @biblio_ids_to_merge = ($bn_merge);
959
            $results = $biblio->merge_with( \@biblio_ids_to_merge );
960
        }
961
        if ( $rules eq 'override' ) {
962
            my @biblio_ids_to_merge = ($bn_merge);
963
            $results = $biblio->merge_with( \@biblio_ids_to_merge );
964
        }
965
    };
966
    if ($@) {
967
        return $c->render( status => 400, json => { error => $@ } );
968
    } else {
969
        $c->respond_to(
970
            mij => {
971
                status => 200,
972
                format => 'mij',
973
                data   => $biblio->metadata->record->to_mij
974
            }
975
        );
976
    }
977
}
978
895
1;
979
1;
(-)a/api/v1/swagger/definitions/merge_biblios.yaml (+28 lines)
Line 0 Link Here
1
---
2
type: object
3
properties:
4
  biblio_id_to_merge:
5
    type: integer
6
    description: Biblionumber from which to merge
7
  rules:
8
    type:
9
      - string
10
      - "null"
11
    description: Internally identifier of a merge algoritm. Now two identifier are supported, 'override' and 'override_ext'.
12
      'override' is to use when you the bibliographic data of biblio_id as resulting bibliographic data. The null value is equivalent
13
       of 'override'.
14
      'override_ext' is to use only with a value in datarecord field. In fact is mandatory to use if you insert a record inside datarecord field.
15
  framework_to_use:
16
    type:
17
      - string
18
      - "null"
19
    description: Framework code, you can use it only with a value in datarecord field. With null value it uses the framework
20
      code of record to be merged into.
21
  datarecord:
22
    description: Bibliographic record used as result of the merge. It uses the format MARC-in-JSON
23
    type:
24
      - object
25
      - "null"
26
additionalProperties: false
27
required:
28
  - biblio_id_to_merge
(-)a/api/v1/swagger/paths/biblios_merge.yaml (+49 lines)
Line 0 Link Here
1
"/biblios/{biblio_id}/merge":
2
  post:
3
    x-mojo-to: Biblios#merge
4
    operationId: mergeBiblios
5
    tags:
6
        - merge_biblios
7
    summary: Merge Biblios
8
    parameters:
9
      - name: biblio_id
10
        in: path
11
        description: Bilblionumber
12
        required: true
13
        type: string
14
      - name: body
15
        in: body
16
        required: true
17
        description: JSON Object with params and an optional marc record in MARC-in-JSON format
18
        schema:
19
          $ref: "../swagger.yaml#/definitions/merge_biblios"
20
    consumes:
21
      - application/json
22
    produces:
23
      - application/marc-in-json
24
    responses:
25
      '200':
26
        description: The merge result as a biblio record
27
      '404':
28
        description: Biblio not found
29
        schema:
30
          "$ref": "../swagger.yaml#/definitions/error"
31
      '401':
32
        description: Authentication required
33
        schema:
34
          "$ref": "../swagger.yaml#/definitions/error"
35
      '403':
36
        description: Access forbidden
37
        schema:
38
          "$ref": "../swagger.yaml#/definitions/error"
39
      '500':
40
        description: Internal server error
41
        schema:
42
          "$ref": "../swagger.yaml#/definitions/error"
43
      '503':
44
        description: Under maintenance
45
        schema:
46
          "$ref": "../swagger.yaml#/definitions/error"
47
    x-koha-authorization:
48
      permissions:
49
        catalogue: "editcatalogue"
(-)a/api/v1/swagger/swagger.yaml (+4 lines)
Lines 118-123 definitions: Link Here
118
    $ref: ./definitions/job.yaml
118
    $ref: ./definitions/job.yaml
119
  library:
119
  library:
120
    $ref: ./definitions/library.yaml
120
    $ref: ./definitions/library.yaml
121
  merge_biblios:
122
    $ref: ./definitions/merge_biblios.yaml
121
  order:
123
  order:
122
    $ref: ./definitions/order.yaml
124
    $ref: ./definitions/order.yaml
123
  patron:
125
  patron:
Lines 243-248 paths: Link Here
243
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items"
245
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items"
244
  "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}":
246
  "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}":
245
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items~1{item_id}"
247
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items~1{item_id}"
248
  "/biblios/{biblio_id}/merge":
249
    $ref: "./paths/biblios_merge.yaml#/~1biblios~1{biblio_id}~1merge"
246
  "/cash_registers/{cash_register_id}/cashups":
250
  "/cash_registers/{cash_register_id}/cashups":
247
    $ref: "./paths/cash_registers.yaml#/~1cash_registers~1{cash_register_id}~1cashups"
251
    $ref: "./paths/cash_registers.yaml#/~1cash_registers~1{cash_register_id}~1cashups"
248
  "/cashups/{cashup_id}":
252
  "/cashups/{cashup_id}":
(-)a/cataloguing/merge.pl (-54 / +11 lines)
Lines 86-118 if ($merge) { Link Here
86
    # Rewriting the leader
86
    # Rewriting the leader
87
    my $biblio = Koha::Biblios->find($ref_biblionumber);
87
    my $biblio = Koha::Biblios->find($ref_biblionumber);
88
    $record->leader($biblio->metadata->record->leader());
88
    $record->leader($biblio->metadata->record->leader());
89
89
    #Take new framework code
90
    my $frameworkcode = $input->param('frameworkcode');
90
    my $frameworkcode = $input->param('frameworkcode');
91
91
92
    # Modifying the reference record
92
    # Modifying the reference record
93
    ModBiblio($record, $ref_biblionumber, $frameworkcode);
93
    ModBiblio($record, $ref_biblionumber, $frameworkcode);
94
94
95
    # Moving items and article requests from the other record to the reference record
96
    $biblio = $biblio->get_from_storage;
97
    foreach my $biblionumber (@biblionumbers) {
98
        my $from_biblio = Koha::Biblios->find($biblionumber);
99
        $from_biblio->items->move_to_biblio($biblio);
100
        $from_biblio->article_requests->update({ biblionumber => $ref_biblionumber }, { no_triggers => 1 });
101
    }
102
103
    my $sth_subscription = $dbh->prepare("
104
        UPDATE subscription SET biblionumber = ? WHERE biblionumber = ?
105
    ");
106
    my $sth_subscriptionhistory = $dbh->prepare("
107
        UPDATE subscriptionhistory SET biblionumber = ? WHERE biblionumber = ?
108
    ");
109
    my $sth_serial = $dbh->prepare("
110
        UPDATE serial SET biblionumber = ? WHERE biblionumber = ?
111
    ");
112
    my $sth_suggestions = $dbh->prepare("
113
        UPDATE suggestions SET biblionumber = ? WHERE biblionumber = ?
114
    ");
115
116
    my $report_header = {};
95
    my $report_header = {};
117
    foreach my $biblionumber ($ref_biblionumber, @biblionumbers) {
96
    foreach my $biblionumber ($ref_biblionumber, @biblionumbers) {
118
        # build report
97
        # build report
Lines 148-189 if ($merge) { Link Here
148
        push @report_records, \%report_record;
127
        push @report_records, \%report_record;
149
    }
128
    }
150
129
151
    foreach my $biblionumber (@biblionumbers) {
130
    my $rmerge;
152
        # Moving subscriptions from the other record to the reference record
131
    eval {
153
        my $subcount = CountSubscriptionFromBiblionumber($biblionumber);
132
        my $newbiblio = Koha::Biblios->find($ref_biblionumber);
154
        if ($subcount > 0) {
133
        $rmerge = $newbiblio->merge_with( \@biblionumbers );
155
            $sth_subscription->execute($ref_biblionumber, $biblionumber);
134
    };
156
            $sth_subscriptionhistory->execute($ref_biblionumber, $biblionumber);
135
    if ($@) {
157
        }
136
        push @errors, $@;
158
159
    # Moving serials
160
    $sth_serial->execute($ref_biblionumber, $biblionumber);
161
162
    # Moving suggestions
163
    $sth_suggestions->execute($ref_biblionumber, $biblionumber);
164
165
    # Moving orders (orders linked to items of frombiblio have already been moved by move_to_biblio)
166
    my @allorders = GetOrdersByBiblionumber($biblionumber);
167
    foreach my $myorder (@allorders) {
168
        $myorder->{'biblionumber'} = $ref_biblionumber;
169
        ModOrder ($myorder);
170
    # TODO : add error control (in ModOrder?)
171
    }
137
    }
172
138
173
    # Deleting the other records
174
    if (scalar(@errors) == 0) {
175
        # Move holds
176
        MergeHolds($dbh, $ref_biblionumber, $biblionumber);
177
        my $error = DelBiblio($biblionumber);
178
        push @errors, $error if ($error);
179
    }
180
}
181
182
    # Parameters
139
    # Parameters
183
    $template->param(
140
    $template->param(
184
        result => 1,
141
        result           => 1,
185
        report_records => \@report_records,
142
        report_records   => \@report_records,
186
        report_header => $report_header,
143
        report_header    => $report_header,
187
        ref_biblionumber => scalar $input->param('ref_biblionumber')
144
        ref_biblionumber => scalar $input->param('ref_biblionumber')
188
    );
145
    );
189
146
(-)a/t/db_dependent/Koha/Biblio.t (-1 / +37 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 30;
20
use Test::More tests => 31;
21
use Test::Exception;
21
use Test::Exception;
22
use Test::Warn;
22
use Test::Warn;
23
23
Lines 486-491 subtest 'to_api() tests' => sub { Link Here
486
    $schema->storage->txn_rollback;
486
    $schema->storage->txn_rollback;
487
};
487
};
488
488
489
subtest 'merge of records' => sub {
490
    plan tests => 3;
491
    $schema->storage->txn_begin;
492
493
    #Three biblio
494
    my $biblio1 = $builder->build_sample_biblio( { title => 'Title number 1' } );
495
    my $biblio2 = $builder->build_sample_biblio( { title => 'Title number 2' } );
496
    my $biblio3 = $builder->build_sample_biblio( { title => 'Title number 3' } );
497
498
    # One items each
499
    my $item1_1 = $builder->build_sample_item( { biblionumber => $biblio1->biblionumber, barcode => 'bar11' } );
500
    my $item2_1 = $builder->build_sample_item( { biblionumber => $biblio2->biblionumber, barcode => 'bar22' } );
501
    my $item3_1 = $builder->build_sample_item( { biblionumber => $biblio3->biblionumber, barcode => 'bar33' } );
502
    my $results = '';
503
    my @to_merge = ( $biblio2->biblionumber, $biblio3->biblionumber );
504
505
    my $pre_merged_rs = Koha::Biblios->search(
506
        { biblionumber => [ $biblio1->biblionumber, $biblio2->biblionumber, $biblio3->biblionumber ] } );
507
    is( $pre_merged_rs->count, 3, '3 biblios exist' );
508
509
    eval { $results = $biblio1->merge_with( \@to_merge ); };
510
    if ($@) {
511
        is( 0, 1, "Not working. Error: " . $@ );
512
    } else {
513
        my $items = $biblio1->items;
514
        is( $items->count, 3, "After merge we have 3 items on first record" );
515
516
        my $merged_rs = Koha::Biblios->search(
517
            { biblionumber => [ $biblio1->biblionumber, $biblio2->biblionumber, $biblio3->biblionumber ] } );
518
        is( $merged_rs->count, 1, 'only 1 biblio left, the merged ones are gone' );
519
    }
520
521
    #End work
522
    $schema->storage->txn_rollback;
523
};
524
489
subtest 'suggestions() tests' => sub {
525
subtest 'suggestions() tests' => sub {
490
526
491
    plan tests => 3;
527
    plan tests => 3;
(-)a/t/db_dependent/api/v1/biblios.t (-2 / +250 lines)
Lines 20-26 use Modern::Perl; Link Here
20
use utf8;
20
use utf8;
21
use Encode;
21
use Encode;
22
22
23
use Test::More tests => 14;
23
use Test::More tests => 15;
24
use Test::MockModule;
24
use Test::MockModule;
25
use Test::Mojo;
25
use Test::Mojo;
26
use Test::Warn;
26
use Test::Warn;
Lines 1879-1881 subtest 'update_item() tests' => sub { Link Here
1879
1879
1880
  $schema->storage->txn_rollback;
1880
  $schema->storage->txn_rollback;
1881
};
1881
};
1882
- 
1882
1883
subtest 'merge() tests' => sub {
1884
    plan tests => 12;
1885
    $schema->storage->txn_begin;
1886
1887
    my $mij_rec = q|{
1888
      "fields": [
1889
        {
1890
          "001": "2504398"
1891
        },
1892
        {
1893
          "005": "20200421093816.0"
1894
        },
1895
        {
1896
          "008": "920610s1993    caub         s001 0 eng  "
1897
        },
1898
        {
1899
          "010": {
1900
            "ind1": " ",
1901
            "subfields": [
1902
              {
1903
                "a": "   92021731 "
1904
              }
1905
            ],
1906
            "ind2": " "
1907
          }
1908
        },
1909
        {
1910
          "020": {
1911
            "subfields": [
1912
              {
1913
                "a": "05200784462 (Test mij)"
1914
              }
1915
            ],
1916
            "ind1": " ",
1917
            "ind2": " "
1918
          }
1919
        },
1920
        {
1921
          "040": {
1922
            "subfields": [
1923
              {
1924
                "a": "DLC"
1925
              },
1926
              {
1927
                "c": "DLC"
1928
              },
1929
              {
1930
                "d": "DLC"
1931
              }
1932
            ],
1933
            "ind2": " ",
1934
            "ind1": " "
1935
          }
1936
        },
1937
        {
1938
          "041": {
1939
            "ind2": " ",
1940
            "subfields": [
1941
              {
1942
                "a": "enggrc"
1943
              }
1944
            ],
1945
            "ind1": "0"
1946
          }
1947
        },
1948
        {
1949
          "082": {
1950
            "subfields": [
1951
              {
1952
                "a": "480"
1953
              },
1954
              {
1955
                "2": "20"
1956
              }
1957
            ],
1958
            "ind2": "0",
1959
            "ind1": "0"
1960
          }
1961
        },
1962
        {
1963
          "100": {
1964
            "ind2": " ",
1965
            "subfields": [
1966
              {
1967
                "a": "Mastronarde, Donald J."
1968
              },
1969
              {
1970
                "9": "389"
1971
              }
1972
            ],
1973
            "ind1": "1"
1974
          }
1975
        },
1976
        {
1977
          "245": {
1978
            "ind1": "1",
1979
            "subfields": [
1980
              {
1981
                "a": "Introduction to Attic Greek  (Using mij) /"
1982
              },
1983
              {
1984
                "c": "Donald J. Mastronarde."
1985
              }
1986
            ],
1987
            "ind2": "0"
1988
          }
1989
        },
1990
        {
1991
          "260": {
1992
            "subfields": [
1993
              {
1994
                "a": "Berkeley :"
1995
              },
1996
              {
1997
                "b": "University of California Press,"
1998
              },
1999
              {
2000
                "c": "c1993."
2001
              }
2002
            ],
2003
            "ind2": " ",
2004
            "ind1": " "
2005
          }
2006
        },
2007
        {
2008
          "300": {
2009
            "ind1": " ",
2010
            "subfields": [
2011
              {
2012
                "a": "ix, 425 p. :"
2013
              },
2014
              {
2015
                "b": "maps ;"
2016
              },
2017
              {
2018
                "c": "26 cm."
2019
              }
2020
            ],
2021
            "ind2": " "
2022
          }
2023
        },
2024
        {
2025
          "650": {
2026
            "subfields": [
2027
              {
2028
                "a": "Attic Greek dialect"
2029
              },
2030
              {
2031
                "9": "7"
2032
              }
2033
            ],
2034
            "ind2": "0",
2035
            "ind1": " "
2036
          }
2037
        },
2038
        {
2039
          "942": {
2040
            "subfields": [
2041
              {
2042
                "2": "ddc"
2043
              },
2044
              {
2045
                "c": "BK"
2046
              }
2047
            ],
2048
            "ind2": " ",
2049
            "ind1": " "
2050
          }
2051
        },
2052
        {
2053
          "955": {
2054
            "subfields": [
2055
              {
2056
                "a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
2057
              }
2058
            ],
2059
            "ind2": " ",
2060
            "ind1": " "
2061
          }
2062
        },
2063
        {
2064
          "999": {
2065
            "subfields": [
2066
              {
2067
                "c": "3"
2068
              },
2069
              {
2070
                "d": "3"
2071
              }
2072
            ],
2073
            "ind1": " ",
2074
            "ind2": " "
2075
          }
2076
        }
2077
      ],
2078
      "leader": "01102pam a2200289 a 8500"
2079
    }|;
2080
2081
    my $patron = $builder->build_object(
2082
        {
2083
            class => 'Koha::Patrons',
2084
            value => { flags => 0 }
2085
        }
2086
    );
2087
    my $password = 'thePassword123';
2088
    $patron->set_password( { password => $password, skip_validation => 1 } );
2089
    my $userid = $patron->userid;
2090
2091
    my $title_1     = 'Title number 1';
2092
    my $title_2     = 'Title number 2';
2093
    my $biblio1     = $builder->build_sample_biblio( { title => $title_1 } );
2094
    my $biblio2     = $builder->build_sample_biblio( { title => $title_2 } );
2095
    my $biblio_id1  = $biblio1->biblionumber;
2096
    my $biblio_id2  = $biblio2->biblionumber;
2097
    my $json_input1 = '{ "biblio_id_to_merge": "' . $biblio_id2 . '" }';
2098
2099
    $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" =>
2100
            { 'Content-Type' => 'application/json', 'Accept' => 'application/marc-in-json' } => $json_input1 )
2101
        ->status_is( 403, 'Not enough permissions to merge two bib records' );
2102
2103
    # Add permissions
2104
    $patron->flags(516)->store;
2105
2106
    $t->post_ok(
2107
        "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" => { 'Content-Type' => 'application/weird+format' } =>
2108
            $json_input1 )->status_is( 400, 'Not correct headers' );
2109
2110
    my $result =
2111
        $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" =>
2112
            { 'Content-Type' => 'application/json', 'Accept' => 'application/marc-in-json' } => $json_input1 )
2113
        ->status_is(200)->tx->res->body;
2114
    like( $result, qr/$title_1/, "Merged record has the correct title" );
2115
    unlike( $result, qr/$title_2/, "Merged record doesn't have the wrong title" );
2116
2117
    my $biblio3     = $builder->build_sample_biblio( { title => 'Title number 3' } );
2118
    my $biblio_id3  = $biblio3->biblionumber;
2119
    my $json_input2 = '{ "biblio_id_to_merge": "' . $biblio_id3 . '",
2120
                         "rules": "override_ext",
2121
                         "datarecord": ' . $mij_rec . ' }';
2122
    $result =
2123
        $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" =>
2124
            { 'Content-Type' => 'application/json', 'Accept' => 'application/marc-in-json' } => $json_input2 )
2125
        ->status_is(200)->tx->res->body;
2126
    like( $result, qr/Using mij/, "Update with Marc-in-json record" );
2127
    unlike( $result, qr/$title_1/, "Change all record with dat in the 'datarecord' field" );
2128
2129
    $schema->storage->txn_rollback;
2130
    }

Return to bug 33036