Bug 37893: SIP accounts sort bin mappings

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Pedro Amorim 2025-02-06 16:09:33 -01:00 committed by Lucas Gass
parent 507b90b13f
commit 103038c167
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
12 changed files with 360 additions and 3 deletions

View File

@ -87,6 +87,7 @@ sub add {
my $item_fields = delete $body->{item_fields} // [];
my $custom_patron_fields = delete $body->{custom_patron_fields} // [];
my $patron_attributes = delete $body->{patron_attributes} // [];
my $sort_bin_mappings = delete $body->{sort_bin_mappings} // [];
my $system_preference_overrides = delete $body->{system_preference_overrides} // [];
my $account = Koha::SIP2::Account->new_from_api($body)->store;
@ -94,6 +95,7 @@ sub add {
$account->item_fields($item_fields);
$account->custom_patron_fields($custom_patron_fields);
$account->patron_attributes($patron_attributes);
$account->sort_bin_mappings($sort_bin_mappings);
$account->system_preference_overrides($system_preference_overrides);
$c->res->headers->location( $c->req->url->to_string . '/' . $account->sip_account_id );
@ -149,6 +151,7 @@ sub update {
my $item_fields = delete $body->{item_fields} // [];
my $custom_patron_fields = delete $body->{custom_patron_fields} // [];
my $patron_attributes = delete $body->{patron_attributes} // [];
my $sort_bin_mappings = delete $body->{sort_bin_mappings} // [];
my $system_preference_overrides = delete $body->{system_preference_overrides} // [];
$account->set_from_api($body)->store;
@ -156,6 +159,7 @@ sub update {
$account->item_fields($item_fields);
$account->custom_patron_fields($custom_patron_fields);
$account->patron_attributes($patron_attributes);
$account->sort_bin_mappings($sort_bin_mappings);
$account->system_preference_overrides($system_preference_overrides);
$c->res->headers->location( $c->req->url->to_string . '/' . $account->sip_account_id );

View File

@ -23,6 +23,7 @@ use Koha::SIP2::Account::CustomItemFields;
use Koha::SIP2::Account::ItemFields;
use Koha::SIP2::Account::CustomPatronFields;
use Koha::SIP2::Account::PatronAttributes;
use Koha::SIP2::Account::SortBinMappings;
use Koha::SIP2::Account::SystemPreferenceOverrides;
use Koha::SIP2::Institution;
@ -104,6 +105,12 @@ sub get_for_config {
$unblessed->{syspref_overrides} = \%system_preference_overrides;
}
my @sort_bin_mappings = map { $_->get_for_config } @{ $self->sort_bin_mappings->as_list };
if (@sort_bin_mappings) {
$unblessed->{sort_bin_mapping} =
scalar(@sort_bin_mappings) == 1 ? $sort_bin_mappings[0] : \@sort_bin_mappings;
}
return $unblessed;
}
@ -224,6 +231,32 @@ sub patron_attributes {
return Koha::SIP2::Account::PatronAttributes->_new_from_dbic($patron_attributes_rs);
}
=head3 sort_bin_mappings
Returns the sort bin mappings for this SIP account
=cut
sub sort_bin_mappings {
my ( $self, $sort_bin_mappings ) = @_;
if ($sort_bin_mappings) {
my $schema = $self->_result->result_source->schema;
$schema->txn_do(
sub {
$self->sort_bin_mappings->delete;
for my $sort_bin_mapping (@$sort_bin_mappings) {
$self->_result->add_to_sip_account_sort_bin_mappings($sort_bin_mapping);
}
}
);
}
my $sort_bin_mappings_rs = $self->_result->sip_account_sort_bin_mappings;
return Koha::SIP2::Account::SortBinMappings->_new_from_dbic($sort_bin_mappings_rs);
}
=head3 system_preference_overrides
Returns the system preference overrides for this SIP account

View File

@ -0,0 +1,58 @@
package Koha::SIP2::Account::SortBinMapping;
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use Koha::Database;
use base qw(Koha::Object);
=head1 NAME
Koha::SIP2::Account::SortBinMapping - Koha SIP2 Account Sort Bin Mapping Object class
=head1 API
=head2 Class Methods
=cut
=head3 get_for_config
Returns the sort bin mapping hashref as expected by C4/SIP/Sip/Configuration->new;
=cut
sub get_for_config {
my ($self) = @_;
return {
'mapping' => $self->mapping,
};
}
=head2 Internal methods
=head3 _type
=cut
sub _type {
return 'SipAccountSortBinMapping';
}
1;

View File

@ -0,0 +1,52 @@
package Koha::SIP2::Account::SortBinMappings;
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use Koha::Database;
use Koha::SIP2::Account::SortBinMapping;
use base qw(Koha::Objects);
=head1 NAME
Koha::SIP2::Account::SortBinMappings - Koha SIP2 Account Sort Bin Mappings Object set class
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'SipAccountSortBinMapping';
}
=head3 object_class
=cut
sub object_class {
return 'Koha::SIP2::Account::SortBinMapping';
}
1;

View File

@ -406,6 +406,21 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 sip_account_sort_bin_mappings
Type: has_many
Related object: L<Koha::Schema::Result::SipAccountSortBinMapping>
=cut
__PACKAGE__->has_many(
"sip_account_sort_bin_mappings",
"Koha::Schema::Result::SipAccountSortBinMapping",
{ "foreign.sip_account_id" => "self.sip_account_id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 sip_account_system_preference_overrides
Type: has_many
@ -437,8 +452,8 @@ __PACKAGE__->belongs_to(
);
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-02-05 13:46:36
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:WMlJotQoh47vVKXLPZ93cg
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-02-06 16:48:50
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HkXHNDQw+5MKHCjxhbCdmA
__PACKAGE__->add_columns(

View File

@ -0,0 +1,113 @@
use utf8;
package Koha::Schema::Result::SipAccountSortBinMapping;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::SipAccountSortBinMapping
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<sip_account_sort_bin_mappings>
=cut
__PACKAGE__->table("sip_account_sort_bin_mappings");
=head1 ACCESSORS
=head2 sip_account_sort_bin_mapping_id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 sip_account_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
Foreign key to sip_accounts.sip_account_id
=head2 mapping
data_type: 'varchar'
is_nullable: 0
size: 255
The mapping definition
=cut
__PACKAGE__->add_columns(
"sip_account_sort_bin_mapping_id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"sip_account_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"mapping",
{ data_type => "varchar", is_nullable => 0, size => 255 },
);
=head1 PRIMARY KEY
=over 4
=item * L</sip_account_sort_bin_mapping_id>
=back
=cut
__PACKAGE__->set_primary_key("sip_account_sort_bin_mapping_id");
=head1 UNIQUE CONSTRAINTS
=head2 C<sip_account>
=over 4
=item * L</sip_account_sort_bin_mapping_id>
=item * L</sip_account_id>
=back
=cut
__PACKAGE__->add_unique_constraint(
"sip_account",
["sip_account_sort_bin_mapping_id", "sip_account_id"],
);
=head1 RELATIONS
=head2 sip_account
Type: belongs_to
Related object: L<Koha::Schema::Result::SipAccount>
=cut
__PACKAGE__->belongs_to(
"sip_account",
"Koha::Schema::Result::SipAccount",
{ sip_account_id => "sip_account_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-02-06 16:48:50
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0qnrb3rQha57wadFOFZo+w
# You can replace this text with custom code or comments, and it will be preserved on regeneration
1;

View File

@ -209,6 +209,11 @@ properties:
type:
- array
- 'null'
sort_bin_mappings:
description: Related sort_bin_mappings embed
type:
- array
- 'null'
system_preference_overrides:
description: Related system_preference_overrides embed
type:

View File

@ -27,6 +27,7 @@
- item_fields
- custom_patron_fields
- patron_attributes
- sort_bin_mappings
- system_preference_overrides
collectionFormat: csv
- $ref: "../swagger.yaml#/parameters/match"
@ -149,6 +150,7 @@
- item_fields
- custom_patron_fields
- patron_attributes
- sort_bin_mappings
- system_preference_overrides
collectionFormat: csv
responses:

View File

@ -229,6 +229,22 @@ return {
) if $item_field;
}
# Accounts sort bin mappings
my @sort_bin_mappings =
ref $SIPconfig->{accounts}->{$account_key}->{sort_bin_mapping} eq "ARRAY"
? @{ $SIPconfig->{accounts}->{$account_key}->{sort_bin_mapping} }
: ( $SIPconfig->{accounts}->{$account_key}->{sort_bin_mapping} );
my $insert_sort_bin_mappings = $dbh->prepare(
q{INSERT IGNORE INTO sip_account_sort_bin_mappings (sip_account_id, mapping) VALUES (?, ?)});
foreach my $sort_bin_mapping (@sort_bin_mappings) {
$insert_sort_bin_mappings->execute(
$new_account_id,
$sort_bin_mapping->{mapping}
) if $sort_bin_mapping;
}
# Accounts system preference overrides
my @account_system_preference_overrides =
ref $SIPconfig->{accounts}->{$account_key}->{syspref_overrides} eq "ARRAY"

View File

@ -6210,6 +6210,24 @@ CREATE TABLE `sip_account_item_fields` (
-- Table structure for table `sip_account_system_preference_overrides`
--
DROP TABLE IF EXISTS `sip_account_sort_bin_mappings`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sip_account_sort_bin_mappings` (
`sip_account_sort_bin_mapping_id` int(11) NOT NULL AUTO_INCREMENT,
`sip_account_id` int(11) NOT NULL COMMENT 'Foreign key to sip_accounts.sip_account_id',
`mapping` varchar(255) NOT NULL COMMENT 'The mapping definition',
PRIMARY KEY (`sip_account_sort_bin_mapping_id`),
UNIQUE KEY `sip_account` (`sip_account_sort_bin_mapping_id`,`sip_account_id`),
KEY `sip_account_sort_bin_mappings_ibfk_1` (`sip_account_id`),
CONSTRAINT `sip_account_sort_bin_mappings_ibfk_1` FOREIGN KEY (`sip_account_id`) REFERENCES `sip_accounts` (`sip_account_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `sip_account_system_preference_overrides`
--
DROP TABLE IF EXISTS `sip_account_system_preference_overrides`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;

View File

@ -49,7 +49,7 @@ export class SIP2APIClient {
endpoint: "accounts/" + id,
headers: {
"x-koha-embed":
"custom_item_fields,item_fields,custom_patron_fields,patron_attributes,system_preference_overrides",
"custom_item_fields,item_fields,custom_patron_fields,patron_attributes,sort_bin_mappings,system_preference_overrides",
},
}),
getAll: params =>

View File

@ -605,6 +605,47 @@ export default {
},
],
},
{
name: "sort_bin_mappings",
type: "relationshipWidget",
showElement: {
type: "table",
columnData: "sort_bin_mappings",
hidden: account => !!account.sort_bin_mappings?.length,
columns: [
{
name: __("Mapping"),
value: "mapping",
},
],
},
group: __("SIP response mappings"),
componentProps: {
resourceRelationships: {
resourceProperty: "sort_bin_mappings",
},
relationshipStrings: {
nameLowerCase: __("sort bin mapping"),
nameUpperCase: __("Sort bin mapping"),
namePlural: __("sort bin mappings"),
},
newRelationshipDefaultAttrs: {
type: "object",
value: {
mapping: null,
},
},
},
relationshipFields: [
{
name: "mapping",
required: true,
type: "text",
placeholder: "CPL:location:eq:OFFICE:2",
label: __("Mapping"),
},
],
},
{
name: "system_preference_overrides",
type: "relationshipWidget",