Bug 35380: Change record sources to by systemdefined

This changes the structure of record source with an is_system column which controls whether this value can be deleted.
Also predefined values are inserted to reflect the default hard coded values from 'Record overlay rules' sources

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
This commit is contained in:
Jan Kissig 2026-03-13 10:13:48 +00:00 committed by Martin Renvoize
parent 67adbce656
commit 86443b8437
No known key found for this signature in database
GPG Key ID: 2D86E0EAEC83711B
6 changed files with 126 additions and 1 deletions

View File

@ -81,6 +81,17 @@ sub add {
openapi => $c->objects->to_api($source) openapi => $c->objects->to_api($source)
); );
} catch { } catch {
if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
return $c->render(
status => 409,
openapi => { error => 'Duplicate name.' }
);
} elsif ( blessed $_ and $_->isa('Koha::Exceptions::BadParameter') ) {
return $c->render(
status => 409,
openapi => { error => 'Name not allowed.' }
);
}
$c->unhandled_exception($_); $c->unhandled_exception($_);
}; };
} }
@ -97,11 +108,29 @@ sub update {
return $c->render_resource_not_found("Record source") return $c->render_resource_not_found("Record source")
unless $source; unless $source;
if ( $source->is_system ) {
return $c->render(
status => 409,
openapi => { error => 'Cannot edit system defined value.' }
);
}
return try { return try {
$source->set_from_api( $c->req->json )->store; $source->set_from_api( $c->req->json )->store;
$source->discard_changes; $source->discard_changes;
return $c->render( status => 200, openapi => $c->objects->to_api($source) ); return $c->render( status => 200, openapi => $c->objects->to_api($source) );
} catch { } catch {
if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
return $c->render(
status => 409,
openapi => { error => 'Duplicate name.' }
);
} elsif ( blessed $_ and $_->isa('Koha::Exceptions::BadParameter') ) {
return $c->render(
status => 409,
openapi => { error => 'Name not allowed.' }
);
}
$c->unhandled_exception($_); $c->unhandled_exception($_);
}; };
} }
@ -130,6 +159,14 @@ sub delete {
error_code => 'cannot_delete_used', error_code => 'cannot_delete_used',
} }
); );
} elsif ( blessed $_ and $_->isa('Koha::Exceptions::CannotDeleteDefault') ) {
return $c->render(
status => 409,
openapi => {
error => 'Cannot delete system defined record source',
error_code => 'cannot_delete_is_system',
}
);
} }
$c->unhandled_exception($_); $c->unhandled_exception($_);
}; };

View File

@ -46,6 +46,31 @@ sub usage_count {
return $self->_result->biblio_metadatas->count(); return $self->_result->biblio_metadatas->count();
} }
=head3 store
=cut
sub store {
my ($self) = @_;
Koha::Exceptions::BadParameter->throw('* not allowed') if $self->name eq '*';
return $self->SUPER::store;
}
=head3 delete
Overridden delete method to prevent system default deletions
=cut
sub delete {
my ($self) = @_;
Koha::Exceptions::CannotDeleteDefault->throw if $self->is_system;
return $self->SUPER::delete;
}
=head2 Internal methods =head2 Internal methods
=head3 _type =head3 _type

View File

@ -14,6 +14,9 @@ properties:
usage_count: usage_count:
description: Record source usage count (x-koha-embed) description: Record source usage count (x-koha-embed)
type: integer type: integer
is_system:
description: Is this record source system or not
type: boolean
additionalProperties: false additionalProperties: false
required: required:
- name - name

View File

@ -97,6 +97,13 @@
description: Not allowed description: Not allowed
schema: schema:
$ref: "../swagger.yaml#/definitions/error" $ref: "../swagger.yaml#/definitions/error"
"409":
description: |
Conflict creating the resource. Possible `error_code` attribute values:
* `duplicate`
schema:
$ref: "../swagger.yaml#/definitions/error"
"500": "500":
description: | description: |
Internal server error. Possible `error_code` attribute values: Internal server error. Possible `error_code` attribute values:
@ -198,6 +205,13 @@
description: Not found description: Not found
schema: schema:
$ref: "../swagger.yaml#/definitions/error" $ref: "../swagger.yaml#/definitions/error"
"409":
description: |
Conflict creating the resource. Possible `error_code` attribute values:
* `duplicate`
schema:
$ref: "../swagger.yaml#/definitions/error"
"500": "500":
description: | description: |
Internal server error. Possible `error_code` attribute values: Internal server error. Possible `error_code` attribute values:
@ -248,6 +262,7 @@
Conflict in deleting resource. Possible `error_code` attribute values: Conflict in deleting resource. Possible `error_code` attribute values:
* `cannot_delete_used`: record source linked to a record cannot be deleted. * `cannot_delete_used`: record source linked to a record cannot be deleted.
* `cannot_delete_is_system`: record source is system defined and cannot be deleted.
schema: schema:
$ref: "../swagger.yaml#/definitions/error" $ref: "../swagger.yaml#/definitions/error"
"500": "500":

View File

@ -0,0 +1,43 @@
use Modern::Perl;
return {
bug_number => "35380",
description =>
"Add new unique name to record sources, add default record sources, add is_system column to default record sources.",
up => sub {
my ($args) = @_;
my ( $dbh, $out ) = @$args{qw(dbh out)};
# change name to be unique
if ( !unique_key_exists( 'record_sources', 'name' ) ) {
$dbh->do(
q{
ALTER TABLE record_sources
ADD UNIQUE KEY name (`name`)
}
);
say $out "Added unique key 'name' ";
}
# add column is system
unless ( column_exists( 'record_sources', 'is_system' ) ) {
$dbh->do(
q{ ALTER TABLE record_sources ADD COLUMN `is_system` TINYINT(1) NOT NULL DEFAULT 0 AFTER can_be_edited }
);
say $out "Added column 'record_sources.is_system'";
}
$dbh->do(
q{
INSERT IGNORE INTO record_sources ( name, can_be_edited, is_system )
VALUES
('batchmod', 1, 1 ),
('intranet', 1, 1 ),
('batchimport', 1, 1 ),
('z3950', 1, 1 ),
('bulkmarcimport', 1, 1 ),
('import_lexile', 1, 1 )
}
);
},
};

View File

@ -5679,7 +5679,9 @@ CREATE TABLE `record_sources` (
`record_source_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the `record_sources` table', `record_source_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the `record_sources` table',
`name` text NOT NULL COMMENT 'User defined name for the record source', `name` text NOT NULL COMMENT 'User defined name for the record source',
`can_be_edited` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'If records from this source can be edited', `can_be_edited` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'If records from this source can be edited',
PRIMARY KEY (`record_source_id`) `is_system` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`record_source_id`),
UNIQUE KEY `name` (`name`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;