diff --git a/Koha/REST/V1/Authorities.pm b/Koha/REST/V1/Authorities.pm index 98b54cee5e..8374497552 100644 --- a/Koha/REST/V1/Authorities.pm +++ b/Koha/REST/V1/Authorities.pm @@ -21,6 +21,7 @@ use Mojo::Base 'Mojolicious::Controller'; use Koha::Authorities; use C4::AuthoritiesMarc qw( DelAuthority AddAuthority FindDuplicateAuthority ModAuthority); +use C4::Matcher; use List::MoreUtils qw( any ); use MARC::Record::MiJ; @@ -156,17 +157,63 @@ sub add { ); } - unless ( $overrides->{any} || $overrides->{duplicate} ) { - my ( $duplicateauthid, $duplicateauthvalue ) = - C4::AuthoritiesMarc::FindDuplicateAuthority( $record, $authtypecode ); + my $matcher_id = $headers->header('x-koha-matchrule'); + my $matcher; + if ( defined $matcher_id && $matcher_id ne '' ) { + $matcher = C4::Matcher->fetch($matcher_id); + unless ($matcher) { + return $c->render( + status => 400, + openapi => { + error => "Matching rule $matcher_id not found", + error_code => 'matching_rule_not_found', + } + ); + } + unless ( $matcher->record_type eq 'authority' ) { + return $c->render( + status => 400, + openapi => { + error => "Matching rule $matcher_id is not an authority matcher", + error_code => 'invalid_matching_rule_type', + } + ); + } + } - return $c->render( - status => 409, - openapi => { - error => "Duplicate record ($duplicateauthid)", - error_code => 'duplicate', + unless ( $overrides->{any} || $overrides->{duplicate} ) { + if ($matcher) { + my @matches = $matcher->get_matches( $record, 10 ); + if (@matches) { + my $first = $matches[0]->{record_id}; + return $c->render( + status => 409, + openapi => { + error => "Duplicate record ($first)", + error_code => 'duplicate', + matches => [ + map { + { + authid => $_->{record_id} + 0, + score => $_->{score} + 0, + } + } @matches + ], + } + ); } - ) unless !$duplicateauthid; + } else { + my ( $duplicateauthid, $duplicateauthvalue ) = + C4::AuthoritiesMarc::FindDuplicateAuthority( $record, $authtypecode ); + + return $c->render( + status => 409, + openapi => { + error => "Duplicate record ($duplicateauthid)", + error_code => 'duplicate', + } + ) unless !$duplicateauthid; + } } my $authid = AddAuthority( $record, undef, $authtypecode ); diff --git a/api/v1/swagger/paths/authorities.yaml b/api/v1/swagger/paths/authorities.yaml index 05d1e39330..b67c0990cf 100644 --- a/api/v1/swagger/paths/authorities.yaml +++ b/api/v1/swagger/paths/authorities.yaml @@ -94,11 +94,24 @@ - any - duplicate collectionFormat: csv + - name: x-koha-matchrule + in: header + required: false + description: | + Numeric id of a Koha record matching rule (record_type=authority) to + use for duplicate detection instead of the default heading-based + check. If the id does not reference an authority matcher a 400 + response is returned. + type: integer responses: "201": description: An authority "400": - description: Bad request + description: | + Bad request. Possible `error_code` attribute values: + + * `matching_rule_not_found` + * `invalid_matching_rule_type` schema: $ref: "../swagger.yaml#/definitions/error" "401": @@ -121,6 +134,10 @@ Conflict creating the resource. Possible `error_code` attribute values: * `duplicate` + + When a matching rule is requested via `x-koha-matchrule`, the response + body additionally contains a `matches` array of objects with + `authid` and `score` for every authority returned by the matcher. schema: $ref: "../swagger.yaml#/definitions/error" "500":