From 769a1b34779f0bc92b979475325b78b754c18ae7 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Mon, 20 Jun 2022 14:57:01 +0200 Subject: [PATCH] Bug 32030: Proxy with HoldingsIQ Signed-off-by: Jonathan Field Signed-off-by: Martin Renvoize Signed-off-by: Kyle M Hall Signed-off-by: Tomas Cohen Arazi --- Koha/ERM/EHoldings/Resource.pm | 19 +- Koha/ERM/Providers/EBSCO.pm | 162 ++++++++++++ Koha/REST/Plugin/Pagination.pm | 2 +- Koha/REST/V1/ERM/EHoldings/Packages.pm | 192 ++------------ Koha/REST/V1/ERM/EHoldings/Packages/EBSCO.pm | 147 +++++++++++ Koha/REST/V1/ERM/EHoldings/Packages/Manual.pm | 210 +++++++++++++++ Koha/REST/V1/ERM/EHoldings/Resources.pm | 197 +------------- Koha/REST/V1/ERM/EHoldings/Resources/EBSCO.pm | 249 ++++++++++++++++++ .../REST/V1/ERM/EHoldings/Resources/Manual.pm | 83 ++++++ Koha/REST/V1/ERM/EHoldings/Titles.pm | 203 +++----------- Koha/REST/V1/ERM/EHoldings/Titles/EBSCO.pm | 160 +++++++++++ Koha/REST/V1/ERM/EHoldings/Titles/Manual.pm | 241 +++++++++++++++++ .../definitions/erm_eholdings_package.yaml | 10 +- .../definitions/erm_eholdings_resource.yaml | 26 +- .../definitions/erm_eholdings_title.yaml | 5 - api/v1/swagger/paths/erm_agreements.yaml | 4 + .../swagger/paths/erm_eholdings_packages.yaml | 9 +- .../erm_eholdings_packages_resources.yaml | 69 +++++ .../paths/erm_eholdings_resources.yaml | 163 +----------- .../swagger/paths/erm_eholdings_titles.yaml | 9 +- .../paths/erm_eholdings_titles_resources.yaml | 69 +++++ api/v1/swagger/paths/erm_licenses.yaml | 4 + api/v1/swagger/paths/erm_users.yaml | 12 +- api/v1/swagger/swagger.yaml | 8 +- installer/data/mysql/atomicupdate/erm.pl | 42 ++- installer/data/mysql/kohastructure.sql | 6 +- .../data/mysql/mandatory/auth_val_cat.sql | 37 ++- .../intranet-tmpl/prog/en/modules/erm/erm.tt | 4 + .../js/vue/components/ERM/AgreementsShow.vue | 6 - .../ERM/EHoldingsPackageTitlesList.vue | 205 ++++++++++++++ .../ERM/EHoldingsPackagesFormAdd.vue | 1 + .../components/ERM/EHoldingsPackagesList.vue | 227 ++++++++++------ .../components/ERM/EHoldingsPackagesShow.vue | 64 +++-- .../components/ERM/EHoldingsResourcesShow.vue | 17 +- .../ERM/EHoldingsTitlePackagesList.vue | 157 +++++++++++ .../components/ERM/EHoldingsTitlesFormAdd.vue | 52 ++-- .../ERM/EHoldingsTitlesFormAddResources.vue | 25 ++ .../components/ERM/EHoldingsTitlesList.vue | 190 ++++++++++--- .../components/ERM/EHoldingsTitlesShow.vue | 122 ++++----- .../prog/js/vue/components/ERM/ERMMain.vue | 6 +- koha-tmpl/intranet-tmpl/prog/js/vue/fetch.js | 34 ++- .../prog/js/vue/stores/authorised_values.js | 3 +- .../intranet-tmpl/prog/js/vue/stores/main.js | 4 +- 43 files changed, 2450 insertions(+), 1005 deletions(-) create mode 100644 Koha/ERM/Providers/EBSCO.pm create mode 100644 Koha/REST/V1/ERM/EHoldings/Packages/EBSCO.pm create mode 100644 Koha/REST/V1/ERM/EHoldings/Packages/Manual.pm create mode 100644 Koha/REST/V1/ERM/EHoldings/Resources/EBSCO.pm create mode 100644 Koha/REST/V1/ERM/EHoldings/Resources/Manual.pm create mode 100644 Koha/REST/V1/ERM/EHoldings/Titles/EBSCO.pm create mode 100644 Koha/REST/V1/ERM/EHoldings/Titles/Manual.pm create mode 100644 api/v1/swagger/paths/erm_eholdings_packages_resources.yaml create mode 100644 api/v1/swagger/paths/erm_eholdings_titles_resources.yaml create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackageTitlesList.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlePackagesList.vue diff --git a/Koha/ERM/EHoldings/Resource.pm b/Koha/ERM/EHoldings/Resource.pm index a7badbbb35..fa776cf081 100644 --- a/Koha/ERM/EHoldings/Resource.pm +++ b/Koha/ERM/EHoldings/Resource.pm @@ -21,9 +21,10 @@ use MARC::Record; use Koha::Database; +use Koha::Acquisition::Booksellers; use Koha::Biblios; -use Koha::ERM::EHoldings::Title; -use Koha::ERM::EHoldings::Package; +use Koha::ERM::EHoldings::Titles; +use Koha::ERM::EHoldings::Packages; use base qw(Koha::Object); @@ -92,6 +93,20 @@ sub title { return Koha::ERM::EHoldings::Title->_new_from_dbic($title_rs); } +=head3 vendor + +Return the vendor for this resource + +=cut + +sub vendor { + my ( $self ) = @_; + my $vendor_rs = $self->_result->vendor; + return unless $vendor_rs; + return Koha::Acquisition::Bookseller->_new_from_dbic($vendor_rs); +} + + =head2 Internal methods =head3 _type diff --git a/Koha/ERM/Providers/EBSCO.pm b/Koha/ERM/Providers/EBSCO.pm new file mode 100644 index 0000000000..7326184814 --- /dev/null +++ b/Koha/ERM/Providers/EBSCO.pm @@ -0,0 +1,162 @@ +package Koha::ERM::Providers::EBSCO; + +use Modern::Perl; + +use HTTP::Request; +use LWP::UserAgent; +use JSON qw( decode_json ); +use List::Util qw( first ); + +use Koha::Exceptions; + +sub new { + my $class = shift; + my $self = {}; + return bless $self, $class; +} + +sub config { + return { + custid => C4::Context->preference('ERMProviderEbscoCustomerID'), + api_key => C4::Context->preference('ERMProviderEbscoApiKey'), + }; +} + +sub build_title { + my ( $self, $result ) = @_; + my $title = { + title_id => $result->{titleId}, + publication_title => $result->{titleName}, + # date_first_issue_online => ?, + # num_first_vol_online => ?, + # num_first_issue_online => ?, + # date_last_issue_online => ?, + # num_last_vol_online => ?, + # num_last_issue_online => ?, + # title_url => ?, + # embargo_info => ?, + # coverage_depth => ?, + # notes => ?, + publisher_name => $result->{publisherName}, + publication_type => $result->{pubType}, + # date_monograph_published_print => ?, + # date_monograph_published_online => ?, + # monograph_volume => ?, + # monograph_edition => ?, + # first_editor => ?, + # parent_publication_title_id => ?, + # preceeding_publication_title_id => ?, + # access_type => ?, + }; + if ( $result->{contributorsList} ) { + my @contributors = @{ $result->{contributorsList} }; + my $first_author = first { $_->{type} eq 'author' || $_->{type} eq 'Author' } @contributors; + if ( $first_author ) { + $title->{first_author} = $first_author->{contributor} + } + } + for my $identifier ( @{ $result->{identifiersList} } ) { + + # FIXME $identifier->{type} : 0 for ISSN and 1 for ISBN + if ( $identifier->{subtype} == 1 ) { + $title->{print_identifier} = $identifier->{id}; + } + elsif ( $identifier->{subtype} == 2 ) { + $title->{online_identifier} = $identifier->{id}; + } + } + return $title; +} + +sub build_vendor { + my ( $self, $result ) = @_; + my $vendor = { + vendor_id => $result->{vendorId}, + name => $result->{vendorName}, + }; + return $vendor; +} + +sub build_package { + my ( $self, $result ) = @_; + my $package = { + package_id => $result->{packageId}, + name => $result->{packageName}, + }; + return $package; +} + +sub build_resource { + my ( $self, $result ) = @_; + my $resource = { + resource_id => $result->{vendorId} . '-' . $result->{packageId} . '-'. $result->{titleId}, + is_selected => $result->{isSelected}, + } +} + + +sub build_query { + my ( $self, $url, $params ) = @_; + + return $url unless $params && %$params; + while ( my ( $attr, $value ) = each %$params ) { + my $their_attr; + if ( $attr eq 'name' ) { + $url .= '&search=' . $value; + } + elsif ( $attr eq 'content_type' ) { + $url .= '&contenttype=' . $value; + } + elsif ( $attr eq 'selection_type' ) { + $url .= '&selection=' . $value; + } + elsif ( $attr eq 'publication_title' ) { + $url .= '&search=' . $value; + } + elsif ( $attr eq 'publication_type' ) { + $url .= '&resourcetype=' . $value; + } + } + return $url; +} + +sub request { + my ( $self, $method, $url, $params ) = @_; + + $url = $self->build_query($url, $params) if $params; + + warn $url; + my $config = $self->config; + my $base_url = 'https://api.ebsco.io/rm/rmaccounts/' . $config->{custid}; + my $request = HTTP::Request->new( $method => $base_url . $url); + $request->header( 'x-api-key' => $config->{api_key} ); + my $ua = LWP::UserAgent->new; + my $response = $ua->simple_request($request); + if ( $response->code >= 400 ) { + my $result = decode_json( $response->decoded_content ); + my $message; + if ( ref($result) eq 'ARRAY' ) { + for my $r (@$result) { + $message .= $r->{message}; + } + } + else { + $message = $result->{message} || $result->{Message} || q{}; + if ( $result->{errors} ) { + for my $e ( @{ $result->{errors} } ) { + $message .= $e->{message}; + } + } + } + warn sprintf "ERROR - EBSCO API %s returned %s - %s\n", $url, $response->code, $message; + if ( $response->code == 404 ) { + Koha::Exceptions::ObjectNotFound->throw($message); + } else { + die sprintf "ERROR requesting EBSCO API\n%s\ncode %s: %s\n", $url, $response->code, + $message; + } + } + return decode_json( $response->decoded_content ); +} + +1; diff --git a/Koha/REST/Plugin/Pagination.pm b/Koha/REST/Plugin/Pagination.pm index 1176c834b6..9873a7af57 100644 --- a/Koha/REST/Plugin/Pagination.pm +++ b/Koha/REST/Plugin/Pagination.pm @@ -117,7 +117,7 @@ If page size is omitted, it defaults to the value of the RESTdefaultPageSize sys # Add X-Total-Count header $c->res->headers->add( 'X-Total-Count' => $total ); - $c->res->headers->add( 'X-Base-Total-Count' => $base_total ); + $c->res->headers->add( 'X-Base-Total-Count' => $base_total ) if defined $base_total; return $c; } ); diff --git a/Koha/REST/V1/ERM/EHoldings/Packages.pm b/Koha/REST/V1/ERM/EHoldings/Packages.pm index e354a19d80..fa974fc4a8 100644 --- a/Koha/REST/V1/ERM/EHoldings/Packages.pm +++ b/Koha/REST/V1/ERM/EHoldings/Packages.pm @@ -19,11 +19,12 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; -use Koha::ERM::EHoldings::Packages; - use Scalar::Util qw( blessed ); use Try::Tiny qw( catch try ); +use Koha::REST::V1::ERM::EHoldings::Packages::Manual; +use Koha::REST::V1::ERM::EHoldings::Packages::EBSCO; + =head1 API =head2 Methods @@ -33,17 +34,12 @@ use Try::Tiny qw( catch try ); =cut sub list { - my $c = shift->openapi->valid_input or return; - - return try { - my $packages_set = Koha::ERM::EHoldings::Packages->new; - my $packages = $c->objects->search( $packages_set ); - return $c->render( status => 200, openapi => $packages ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + return Koha::REST::V1::ERM::EHoldings::Packages::EBSCO::list(@_); + } else { + return Koha::REST::V1::ERM::EHoldings::Packages::Manual::list(@_); } - catch { - $c->unhandled_exception($_); - }; - } =head3 get @@ -53,27 +49,12 @@ Controller function that handles retrieving a single Koha::ERM::EHoldings::Packa =cut sub get { - my $c = shift->openapi->valid_input or return; - - return try { - my $package_id = $c->validation->param('package_id'); - my $package = $c->objects->find( Koha::ERM::EHoldings::Packages->search, $package_id ); - - unless ($package) { - return $c->render( - status => 404, - openapi => { error => "Package not found" } - ); - } - - return $c->render( - status => 200, - openapi => $package - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + return Koha::REST::V1::ERM::EHoldings::Packages::EBSCO::get(@_); + } else { + return Koha::REST::V1::ERM::EHoldings::Packages::Manual::get(@_); } - catch { - $c->unhandled_exception($_); - }; } =head3 add @@ -83,62 +64,12 @@ Controller function that handles adding a new Koha::ERM::EHoldings::Package obje =cut sub add { - my $c = shift->openapi->valid_input or return; - - return try { - Koha::Database->new->schema->txn_do( - sub { - - my $body = $c->validation->param('body'); - - my $package_agreements = delete $body->{package_agreements} // []; - - my $package = Koha::ERM::EHoldings::Package->new_from_api($body)->store; - $package->package_agreements($package_agreements); - - $c->res->headers->location($c->req->url->to_string . '/' . $package->package_id); - return $c->render( - status => 201, - openapi => $package->to_api - ); - } - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + die "invalid action"; + } else { + return Koha::REST::V1::ERM::EHoldings::Packages::Manual::add(@_); } - catch { - - my $to_api_mapping = Koha::ERM::EHoldings::Package->new->to_api_mapping; - - if ( blessed $_ ) { - if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { - return $c->render( - status => 409, - openapi => { error => $_->error, conflict => $_->duplicate_id } - ); - } - elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->broken_fk } - . " does not exist" - } - ); - } - elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->parameter } - . " does not exist" - } - ); - } - } - - $c->unhandled_exception($_); - }; } =head3 update @@ -148,65 +79,12 @@ Controller function that handles updating a Koha::ERM::EHoldings::Package object =cut sub update { - my $c = shift->openapi->valid_input or return; - - my $package_id = $c->validation->param('package_id'); - my $package = Koha::ERM::EHoldings::Packages->find( $package_id ); - - unless ($package) { - return $c->render( - status => 404, - openapi => { error => "Package not found" } - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + die "invalid action"; + } else { + return Koha::REST::V1::ERM::EHoldings::Packages::Manual::update(@_); } - - return try { - Koha::Database->new->schema->txn_do( - sub { - - my $body = $c->validation->param('body'); - - my $package_agreements = delete $body->{package_agreements} // []; - - $package->set_from_api($body)->store; - $package->package_agreements($package_agreements); - - $c->res->headers->location($c->req->url->to_string . '/' . $package->package_id); - return $c->render( - status => 200, - openapi => $package->to_api - ); - } - ); - } - catch { - my $to_api_mapping = Koha::ERM::EHoldings::Package->new->to_api_mapping; - - if ( blessed $_ ) { - if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->broken_fk } - . " does not exist" - } - ); - } - elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->parameter } - . " does not exist" - } - ); - } - } - - $c->unhandled_exception($_); - }; }; =head3 delete @@ -214,26 +92,12 @@ sub update { =cut sub delete { - my $c = shift->openapi->valid_input or return; - - my $package = Koha::ERM::EHoldings::Packages->find( $c->validation->param('package_id') ); - unless ($package) { - return $c->render( - status => 404, - openapi => { error => "Package not found" } - ); - } - - return try { - $package->delete; - return $c->render( - status => 204, - openapi => q{} - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + die "invalid action"; + } else { + return Koha::REST::V1::ERM::EHoldings::Packages::Manual::update(@_); } - catch { - $c->unhandled_exception($_); - }; } 1; diff --git a/Koha/REST/V1/ERM/EHoldings/Packages/EBSCO.pm b/Koha/REST/V1/ERM/EHoldings/Packages/EBSCO.pm new file mode 100644 index 0000000000..ddb93b4c27 --- /dev/null +++ b/Koha/REST/V1/ERM/EHoldings/Packages/EBSCO.pm @@ -0,0 +1,147 @@ +package Koha::REST::V1::ERM::EHoldings::Packages::EBSCO; + +# 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 . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use JSON qw( decode_json ); +use Koha::ERM::Providers::EBSCO; + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + + my $args = $c->validation->output; + my $params = '?orderby=packagename&offset=1&count=1'; + my $result = + Koha::ERM::Providers::EBSCO->request( GET => '/packages' . $params ); + my $base_total = $result->{totalResults}; + + my $per_page = $args->{_per_page} + // C4::Context->preference('RESTdefaultPageSize') // 20; + if ( $per_page == -1 || $per_page > 100 ) { $per_page = 100; } + my $page = $args->{_page} || 1; + + my ( $search, $content_type, $selection_type ); + my $query_params = $c->req->params->to_hash; + my $additional_params; + if ( $query_params->{q} ) { + my $q = decode_json $query_params->{q}; + while ( my ( $attr, $value ) = each %$q ) { + $additional_params->{$attr} = $value; + } + } + + my $orderby = $additional_params->{name} ? 'relevance' : 'packagename'; + $params = sprintf '?orderby=%s&offset=%s&count=%s', $orderby, $page, + $per_page; + $result = Koha::ERM::Providers::EBSCO->request( + GET => '/packages' . $params, + $additional_params + ); + + my @packages; + for my $p ( @{ $result->{packagesList} } ) { + my $package = { + content_type => $p->{contentType}, + created_on => undef, + is_selected => $p->{isSelected}, + name => $p->{packageName}, + package_id => $p->{vendorId} . '-' . $p->{packageId}, + package_type => $p->{packageType}, + vendor_id => $p->{vendorId}, + }; + my $embed_header = $c->req->headers->header('x-koha-embed') || q{}; + foreach my $embed_req ( split /\s*,\s*/, $embed_header ) { + if ( $embed_req eq 'vendor.name' ) { + $package->{vendor} = { name => $p->{vendorName}, }; + } + elsif ( $embed_req eq 'resources+count' ) { + $package->{resources_count} = $p->{titleCount}; + } + } + push @packages, $package; + } + my $total = $result->{totalResults}; + $total = 10000 if $total > 10000; + + $c->add_pagination_headers( + { + base_total => $base_total, + total => $total, + params => $args, + } + ); + return $c->render( status => 200, openapi => \@packages ); + } + catch { + $c->unhandled_exception($_); + }; +} + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my ( $vendor_id, $package_id ) = split '-', + $c->validation->param('package_id'); + my $p = Koha::ERM::Providers::EBSCO->request( + GET => '/vendors/' . $vendor_id . '/packages/' . $package_id ); + unless ($p) { + return $c->render( + status => 404, + openapi => { error => "Package not found" } + ); + } + + my $package = { + content_type => $p->{contentType}, + name => $p->{packageName}, + package_id => $p->{vendorId} . '-' . $p->{packageId}, + package_type => $p->{packageType}, + vendor_id => $p->{vendorId}, + }; + + my $embed_header = $c->req->headers->header('x-koha-embed') || q{}; + foreach my $embed_req ( split /\s*,\s*/, $embed_header ) { + if ( $embed_req eq 'vendor' ) { + $package->{vendor} = { + id => $p->{vendorId}, + name => $p->{vendorName}, + }; + } + elsif ( $embed_req eq 'resources+count' ) { + $package->{resources_count} = $p->{titleCount}; + } + } + + return $c->render( + status => 200, + openapi => $package + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/Koha/REST/V1/ERM/EHoldings/Packages/Manual.pm b/Koha/REST/V1/ERM/EHoldings/Packages/Manual.pm new file mode 100644 index 0000000000..27731ae81f --- /dev/null +++ b/Koha/REST/V1/ERM/EHoldings/Packages/Manual.pm @@ -0,0 +1,210 @@ +package Koha::REST::V1::ERM::EHoldings::Packages::Manual; + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::ERM::EHoldings::Packages; + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +sub list { + my $c = shift->openapi->valid_input or return; + return try { + my $packages_set = Koha::ERM::EHoldings::Packages->new; + my $packages = $c->objects->search($packages_set); + return $c->render( status => 200, openapi => $packages ); + } + catch { + $c->unhandled_exception($_); + }; +} + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my $package_id = $c->validation->param('package_id'); + my $package = $c->objects->find( Koha::ERM::EHoldings::Packages->search, + $package_id ); + + unless ($package) { + return $c->render( + status => 404, + openapi => { error => "Package not found" } + ); + } + + return $c->render( + status => 200, + openapi => $package + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 add + +Controller function that handles adding a new Koha::ERM::EHoldings::Package object + +=cut + +sub add { + my $c = shift->openapi->valid_input or return; + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $package_agreements = delete $body->{package_agreements} // []; + + my $package = Koha::ERM::EHoldings::Package->new_from_api($body)->store; + $package->package_agreements($package_agreements); + + $c->res->headers->location($c->req->url->to_string . '/' . $package->package_id); + return $c->render( + status => 201, + openapi => $package->to_api + ); + } + ); + } + catch { + + my $to_api_mapping = Koha::ERM::EHoldings::Package->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { + return $c->render( + status => 409, + openapi => { error => $_->error, conflict => $_->duplicate_id } + ); + } + elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + } + + $c->unhandled_exception($_); + }; +} + +=head3 update + +Controller function that handles updating a Koha::ERM::EHoldings::Package object + +=cut + +sub update { + my $c = shift->openapi->valid_input or return; + + my $package_id = $c->validation->param('package_id'); + my $package = Koha::ERM::EHoldings::Packages->find( $package_id ); + + unless ($package) { + return $c->render( + status => 404, + openapi => { error => "Package not found" } + ); + } + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $package_agreements = delete $body->{package_agreements} // []; + + $package->set_from_api($body)->store; + $package->package_agreements($package_agreements); + + $c->res->headers->location($c->req->url->to_string . '/' . $package->package_id); + return $c->render( + status => 200, + openapi => $package->to_api + ); + } + ); + } + catch { + my $to_api_mapping = Koha::ERM::EHoldings::Package->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + } + + $c->unhandled_exception($_); + }; +}; + +=head3 delete + +=cut + +sub delete { + my $c = shift->openapi->valid_input or return; + + my $package = Koha::ERM::EHoldings::Packages->find( $c->validation->param('package_id') ); + unless ($package) { + return $c->render( + status => 404, + openapi => { error => "Package not found" } + ); + } + + return try { + $package->delete; + return $c->render( + status => 204, + openapi => q{} + ); + } + catch { + $c->unhandled_exception($_); + }; +} + + +1; diff --git a/Koha/REST/V1/ERM/EHoldings/Resources.pm b/Koha/REST/V1/ERM/EHoldings/Resources.pm index 9c45005dc2..e752a21681 100644 --- a/Koha/REST/V1/ERM/EHoldings/Resources.pm +++ b/Koha/REST/V1/ERM/EHoldings/Resources.pm @@ -19,7 +19,8 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; -use Koha::ERM::EHoldings::Resources; +use Koha::REST::V1::ERM::EHoldings::Resources::Manual; +use Koha::REST::V1::ERM::EHoldings::Resources::EBSCO; use Scalar::Util qw( blessed ); use Try::Tiny qw( catch try ); @@ -33,17 +34,12 @@ use Try::Tiny qw( catch try ); =cut sub list { - my $c = shift->openapi->valid_input or return; - - return try { - my $resources_set = Koha::ERM::EHoldings::Resources->new; - my $resources = $c->objects->search( $resources_set ); - return $c->render( status => 200, openapi => $resources ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + return Koha::REST::V1::ERM::EHoldings::Resources::EBSCO::list(@_); + } else { + return Koha::REST::V1::ERM::EHoldings::Resources::Manual::list(@_); } - catch { - $c->unhandled_exception($_); - }; - } =head3 get @@ -53,181 +49,12 @@ Controller function that handles retrieving a single Koha::ERM::EHoldings::Resou =cut sub get { - my $c = shift->openapi->valid_input or return; - - return try { - my $resource_id = $c->validation->param('resource_id'); - my $resource = $c->objects->find( Koha::ERM::EHoldings::Resources->search, $resource_id ); - - unless ($resource ) { - return $c->render( - status => 404, - openapi => { error => "eHolding title not found" } - ); - } - - return $c->render( - status => 200, - openapi => $resource, - ); - } - catch { - $c->unhandled_exception($_); - }; -} - -=head3 add - -Controller function that handles adding a new Koha::ERM::EHoldings::Resource object - -=cut - -sub add { - my $c = shift->openapi->valid_input or return; - - return try { - Koha::Database->new->schema->txn_do( - sub { - - my $body = $c->validation->param('body'); - - my $resource = Koha::ERM::EHoldings::Resource->new_from_api($body)->store; - - $c->res->headers->location($c->req->url->to_string . '/' . $resource->resource_id); - return $c->render( - status => 201, - openapi => $resource->to_api - ); - } - ); - } - catch { - - my $to_api_mapping = Koha::ERM::EHoldings::Resource->new->to_api_mapping; - - if ( blessed $_ ) { - if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { - return $c->render( - status => 409, - openapi => { error => $_->error, conflict => $_->duplicate_id } - ); - } - elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->broken_fk } - . " does not exist" - } - ); - } - elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->parameter } - . " does not exist" - } - ); - } - } - - $c->unhandled_exception($_); - }; -} - -=head3 update - -Controller function that handles updating a Koha::ERM::EHoldings::Resource object - -=cut - -sub update { - my $c = shift->openapi->valid_input or return; - - my $resource_id = $c->validation->param('resource_id'); - my $resource = Koha::ERM::EHoldings::Resources->find( $resource_id ); - - unless ($resource) { - return $c->render( - status => 404, - openapi => { error => "eHolding title not found" } - ); - } - - return try { - Koha::Database->new->schema->txn_do( - sub { - - my $body = $c->validation->param('body'); - - $resource->set_from_api($body)->store; - - $c->res->headers->location($c->req->url->to_string . '/' . $resource->resource_id); - return $c->render( - status => 200, - openapi => $resource->to_api - ); - } - ); - } - catch { - my $to_api_mapping = Koha::ERM::EHoldings::Resource->new->to_api_mapping; - - if ( blessed $_ ) { - if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->broken_fk } - . " does not exist" - } - ); - } - elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->parameter } - . " does not exist" - } - ); - } - } - - $c->unhandled_exception($_); - }; -}; - -=head3 delete - -=cut - -sub delete { - my $c = shift->openapi->valid_input or return; - - my $resource = Koha::ERM::EHoldings::Resources->find( $c->validation->param('resource_id') ); - unless ($resource) { - return $c->render( - status => 404, - openapi => { error => "eHolding title not found" } - ); - } - - return try { - $resource->delete; - return $c->render( - status => 204, - openapi => q{} - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + return Koha::REST::V1::ERM::EHoldings::Resources::EBSCO::get(@_); + } else { + return Koha::REST::V1::ERM::EHoldings::Resources::Manual::get(@_); } - catch { - $c->unhandled_exception($_); - }; } 1; diff --git a/Koha/REST/V1/ERM/EHoldings/Resources/EBSCO.pm b/Koha/REST/V1/ERM/EHoldings/Resources/EBSCO.pm new file mode 100644 index 0000000000..555a6e3099 --- /dev/null +++ b/Koha/REST/V1/ERM/EHoldings/Resources/EBSCO.pm @@ -0,0 +1,249 @@ +package Koha::REST::V1::ERM::EHoldings::Resources::EBSCO; + +# 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 . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use JSON qw( decode_json ); +use Koha::ERM::Providers::EBSCO; + +use Scalar::Util qw( blessed ); +use Try::Tiny; + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + + my $args = $c->validation->output; + + # FIXME Do we need more validation here? Don't think so we have the API specs. + my ( $vendor_id, $package_id ) = split '-', + $c->validation->param('package_id') || q{}; + my $title_id = $c->validation->param('title_id') || q{}; + + my $url = + $title_id + ? sprintf '/titles/%s', $title_id + : sprintf '/vendors/%s/packages/%s/titles', $vendor_id, $package_id; + + my $params = + '?orderby=titlename&offset=1&count=1&searchfield=titlename'; + my $result; + try { + $result = + Koha::ERM::Providers::EBSCO->request( GET => $url . $params ); + } + catch { + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::ObjectNotFound') ) { + return $c->render( + status => 404, + openapi => { error => $_->error } + ); + + } + } + + $c->unhandled_exception($_); + }; + + my $base_total = $result->{totalResults}; + + my $per_page = $args->{_per_page} + // C4::Context->preference('RESTdefaultPageSize') // 20; + if ( $per_page == -1 || $per_page > 100 ) { $per_page = 100; } + my $page = $args->{_page} || 1; + + my ( $search, $content_type, $selection_type ); + my $query_params = $c->req->params->to_hash; + my $additional_params; + if ( $query_params->{q} ) { + my $q = decode_json $query_params->{q}; + while ( my ( $attr, $value ) = each %$q ) { + $additional_params->{$attr} = $value; + } + } + my $searchfield = 'titlename'; + + $params = + sprintf '?orderby=titlename&offset=%s&count=%s&searchfield=%s', + $page, $per_page, $searchfield; + $result = Koha::ERM::Providers::EBSCO->request( + GET => $url . $params, + $additional_params + ); + + my @resources; + for my $t ( @{ $result->{titles} } ) { + my $r = + $t->{customerResourcesList}->[0]; # FIXME What about the others? + my $resource = { + resource_id => $r->{vendorId} . '-' + . $r->{packageId} . '-' + . $r->{titleId}, + package_id => $r->{vendorId} . '-' . $r->{packageId}, + title_id => $r->{titleId}, + is_selected => $r->{isSelected}, + started_on => $r->{managedCoverageList}->[0]->{beginCoverage}, + ended_on => $r->{managedCoverageList}->[0]->{endCoverage}, + }; + my $embed_header = $c->req->headers->header('x-koha-embed') || q{}; + foreach my $embed_req ( split /\s*,\s*/, $embed_header ) { + if ( $embed_req eq 'title.publication_title' ) { + $resource->{title} = { + publication_title => $t->{titleName}, + publisher_name => $t->{publisherName}, + publication_type => $t->{pubType}, + }; + } + elsif ( $embed_req eq 'package.name' ) { + $resource->{package} = { name => $t->{packageName}, }; + } + + } + push @resources, $resource; + } + my $total = $result->{totalResults}; + $total = 10000 if $total > 10000; + $c->add_pagination_headers( + { + base_total => $base_total, + total => $total, + params => $args, + } + ); + return $c->render( status => 200, openapi => \@resources ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 get + +=cut + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my ( $vendor_id, $package_id, $resource_id ) = split '-', + $c->validation->param('resource_id'); + my $t; + try { + $t = + Koha::ERM::Providers::EBSCO->request( GET => '/vendors/' + . $vendor_id + . '/packages/' + . $package_id + . '/titles/' + . $resource_id ); + + } + catch { + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::ObjectNotFound') ) { + return $c->render( + status => 404, + openapi => { error => $_->error } + ); + + } + } + + $c->unhandled_exception($_); + }; + + unless ($t) { + return $c->render( + status => 404, + openapi => { error => "Resource not found" } + ); + } + + my $r = $t->{customerResourcesList}->[0]; # FIXME What about the others? + my $resource = { + resource_id => $r->{vendorId} . '-' + . $r->{packageId} . '-' + . $r->{titleId}, + package_id => $r->{vendorId} . '-' . $r->{packageId}, + title_id => $r->{titleId}, + started_on => $r->{managedCoverageList}->[0]->{beginCoverage}, + ended_on => $r->{managedCoverageList}->[0]->{endCoverage}, + }; + + my $embed_header = $c->req->headers->header('x-koha-embed') || q{}; + foreach my $embed_req ( split /\s*,\s*/, $embed_header ) { + if ( $embed_req eq 'title' ) { + $resource->{title} = { + publication_title => $t->{titleName}, + publisher_name => $t->{publisherName}, + publication_type => $t->{pubType}, + }; + for my $identifier ( @{ $t->{identifiersList} } ) { + + # FIXME $identifier->{type} : 0 for ISSN and 1 for ISBN + if ( $identifier->{subtype} == 1 ) { + $resource->{title}->{print_identifier} = + $identifier->{id}; + } + elsif ( $identifier->{subtype} == 1 ) { + $resource->{title}->{online_identifier} = + $identifier->{id}; + } + } + } + elsif ( $embed_req eq 'package' ) { + $resource->{package} = { + + #content_type => $e->{contentType}, FIXME We don't have that + name => $r->{packageName}, + package_id => $r->{vendorId} . '-' . $r->{packageId}, + package_type => $r->{packageType}, + vendor_id => $r->{vendorId}, + }; + } + elsif ( $embed_req eq 'vendor' ) { + $resource->{vendor} = { + name => $r->{vendorName}, + id => $r->{vendorId}, + package_type => $r->{packageType}, + }; + } + } + + return $c->render( + status => 200, + openapi => $resource, + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/Koha/REST/V1/ERM/EHoldings/Resources/Manual.pm b/Koha/REST/V1/ERM/EHoldings/Resources/Manual.pm new file mode 100644 index 0000000000..537e34518b --- /dev/null +++ b/Koha/REST/V1/ERM/EHoldings/Resources/Manual.pm @@ -0,0 +1,83 @@ +package Koha::REST::V1::ERM::EHoldings::Resources::Manual; + +# 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 . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::ERM::EHoldings::Resources; + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + my $package_id = $c->validation->param('package_id'); + my $resources_set = + $package_id + ? Koha::ERM::EHoldings::Resources->search( { package_id => $package_id } ) + : Koha::ERM::EHoldings::Resources->new; + my $resources = $c->objects->search( $resources_set ); + return $c->render( status => 200, openapi => $resources ); + } + catch { + $c->unhandled_exception($_); + }; + +} + +=head3 get + +Controller function that handles retrieving a single Koha::ERM::EHoldings::Resource object + +=cut + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my $resource_id = $c->validation->param('resource_id'); + my $resource = $c->objects->find( Koha::ERM::EHoldings::Resources->search, $resource_id ); + + unless ($resource ) { + return $c->render( + status => 404, + openapi => { error => "eHolding resource not found" } + ); + } + + return $c->render( + status => 200, + openapi => $resource, + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/Koha/REST/V1/ERM/EHoldings/Titles.pm b/Koha/REST/V1/ERM/EHoldings/Titles.pm index 82cbe9bb06..6b2975fdad 100644 --- a/Koha/REST/V1/ERM/EHoldings/Titles.pm +++ b/Koha/REST/V1/ERM/EHoldings/Titles.pm @@ -19,11 +19,12 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; -use Koha::ERM::EHoldings::Titles; - use Scalar::Util qw( blessed ); use Try::Tiny qw( catch try ); +use Koha::REST::V1::ERM::EHoldings::Titles::Manual; +use Koha::REST::V1::ERM::EHoldings::Titles::EBSCO; + =head1 API =head2 Methods @@ -33,47 +34,27 @@ use Try::Tiny qw( catch try ); =cut sub list { - my $c = shift->openapi->valid_input or return; - - return try { - my $titles_set = Koha::ERM::EHoldings::Titles->new; - my $titles = $c->objects->search( $titles_set ); - return $c->render( status => 200, openapi => $titles ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + return Koha::REST::V1::ERM::EHoldings::Titles::EBSCO::list(@_); + } else { + return Koha::REST::V1::ERM::EHoldings::Titles::Manual::list(@_); } - catch { - $c->unhandled_exception($_); - }; - } =head3 get -Controller function that handles retrieving a single Koha::ERM::EHoldings::Title object +Controller function that handles retrieving a single Koha::ERM::EHoldings::Package object =cut sub get { - my $c = shift->openapi->valid_input or return; - - return try { - my $title_id = $c->validation->param('title_id'); - my $title = $c->objects->find( Koha::ERM::EHoldings::Titles->search, $title_id ); - - unless ($title ) { - return $c->render( - status => 404, - openapi => { error => "eHolding title not found" } - ); - } - - return $c->render( - status => 200, - openapi => $title, - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + return Koha::REST::V1::ERM::EHoldings::Titles::EBSCO::get(@_); + } else { + return Koha::REST::V1::ERM::EHoldings::Titles::Manual::get(@_); } - catch { - $c->unhandled_exception($_); - }; } =head3 add @@ -82,66 +63,16 @@ Controller function that handles adding a new Koha::ERM::EHoldings::Title object =cut -sub add { - my $c = shift->openapi->valid_input or return; - - return try { - Koha::Database->new->schema->txn_do( - sub { - - my $body = $c->validation->param('body'); - - my $resources = delete $body->{resources} // []; - - my $title = Koha::ERM::EHoldings::Title->new_from_api($body)->store; - - $title->resources($resources); - - $c->res->headers->location($c->req->url->to_string . '/' . $title->title_id); - return $c->render( - status => 201, - openapi => $title->to_api - ); - } - ); +sub add{ + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + die "invalid action"; + } else { + return Koha::REST::V1::ERM::EHoldings::Titles::Manual::add(@_); } - catch { - - my $to_api_mapping = Koha::ERM::EHoldings::Title->new->to_api_mapping; - - if ( blessed $_ ) { - if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { - return $c->render( - status => 409, - openapi => { error => $_->error, conflict => $_->duplicate_id } - ); - } - elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->broken_fk } - . " does not exist" - } - ); - } - elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->parameter } - . " does not exist" - } - ); - } - } - - $c->unhandled_exception($_); - }; } + =head3 update Controller function that handles updating a Koha::ERM::EHoldings::Title object @@ -149,93 +80,25 @@ Controller function that handles updating a Koha::ERM::EHoldings::Title object =cut sub update { - my $c = shift->openapi->valid_input or return; - - my $title_id = $c->validation->param('title_id'); - my $title = Koha::ERM::EHoldings::Titles->find( $title_id ); - - unless ($title) { - return $c->render( - status => 404, - openapi => { error => "eHolding title not found" } - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + die "invalid action"; + } else { + return Koha::REST::V1::ERM::EHoldings::Titles::Manual::update(@_); } - - return try { - Koha::Database->new->schema->txn_do( - sub { - - my $body = $c->validation->param('body'); - - my $resources = delete $body->{resources} // []; - - $title->set_from_api($body)->store; - - $title->resources($resources); - - $c->res->headers->location($c->req->url->to_string . '/' . $title->title_id); - return $c->render( - status => 200, - openapi => $title->to_api - ); - } - ); - } - catch { - my $to_api_mapping = Koha::ERM::EHoldings::Title->new->to_api_mapping; - - if ( blessed $_ ) { - if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->broken_fk } - . " does not exist" - } - ); - } - elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { - return $c->render( - status => 400, - openapi => { - error => "Given " - . $to_api_mapping->{ $_->parameter } - . " does not exist" - } - ); - } - } - - $c->unhandled_exception($_); - }; -}; +} =head3 delete =cut sub delete { - my $c = shift->openapi->valid_input or return; - - my $title = Koha::ERM::EHoldings::Titles->find( $c->validation->param('title_id') ); - unless ($title) { - return $c->render( - status => 404, - openapi => { error => "eHolding title not found" } - ); - } - - return try { - $title->delete; - return $c->render( - status => 204, - openapi => q{} - ); + my $provider = C4::Context->preference('ERMProvider'); + if ( $provider eq 'ebsco' ) { + die "invalid action"; + } else { + return Koha::REST::V1::ERM::EHoldings::Titles::Manual::delete(@_); } - catch { - $c->unhandled_exception($_); - }; -} +}; 1; diff --git a/Koha/REST/V1/ERM/EHoldings/Titles/EBSCO.pm b/Koha/REST/V1/ERM/EHoldings/Titles/EBSCO.pm new file mode 100644 index 0000000000..3537a8b195 --- /dev/null +++ b/Koha/REST/V1/ERM/EHoldings/Titles/EBSCO.pm @@ -0,0 +1,160 @@ +package Koha::REST::V1::ERM::EHoldings::Titles::EBSCO; + +# 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 . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use JSON qw( decode_json ); +use Koha::ERM::Providers::EBSCO; + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + + my $args = $c->validation->output; + + my $ebsco = Koha::ERM::Providers::EBSCO->new; + + # We cannot get base_total as a search kw is required by the API + #my $params = '?orderby=relevance&offset=1&count=1&searchfield=titlename&search=a'; + #my $result = $ebsco->request( GET => '/titles' . $params ); + #my $base_total = $result->{totalResults}; + + my $per_page = $args->{_per_page} + // C4::Context->preference('RESTdefaultPageSize') // 20; + if ( $per_page == -1 || $per_page > 100 ) { $per_page = 100; } + my $page = $args->{_page} || 1; + + my ( $search, $content_type, $selection_type ); + my $query_params = $c->req->params->to_hash; + my $additional_params; + if ( $query_params->{q} ) { + my $q = decode_json $query_params->{q}; + while ( my ( $attr, $value ) = each %$q ) { + $additional_params->{$attr} = $value; + } + } + + unless ( defined $additional_params->{publication_title} ) { + + # TODO We can add search on publisher, isxn, [subject or zdbid] + return $c->render( + status => 400, + openapi => { + errors => [ + { + message => +"A search keyword on publication_title is required" + } + ] + } + ); + } + + my $searchfield = 'titlename'; + my $params = + sprintf '?orderby=relevance&offset=%s&count=%s&searchfield=%s', + $page, $per_page, $searchfield; + my $result = + $ebsco->request( GET => '/titles' . $params, $additional_params ); + + my @titles; + for my $t ( @{ $result->{titles} } ) { + my $title = $ebsco->build_title($t); + + my $embed_header = $c->req->headers->header('x-koha-embed') || q{}; + foreach my $embed_req ( split /\s*,\s*/, $embed_header ) { + if ( $embed_req eq 'vendor.name' ) { + $title->{vendor} = $ebsco->build_vendor($t); + } + } + push @titles, $title; + } + my $total = $result->{totalResults}; + $total = 10000 if $total > 10000; + + $c->add_pagination_headers( + { + #base_total => $base_total, + total => $total, + params => $args, + } + ); + return $c->render( status => 200, openapi => \@titles ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 get + +=cut + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my $title_id = $c->validation->param('title_id'); + my $ebsco = Koha::ERM::Providers::EBSCO->new; + my $t = $ebsco->request( GET => '/titles/' . $title_id ); + unless ($t) { + return $c->render( + status => 404, + openapi => { error => "Title not found" } + ); + } + + my $title = $ebsco->build_title($t); + my $embed_header = $c->req->headers->header('x-koha-embed') || q{}; + for my $r ( @{ $t->{customerResourcesList} } ) { + my $resource = {}; + foreach my $embed_req ( split /\s*,\s*/, $embed_header ) { + if ( $embed_req eq 'resources' ) { + $resource = $ebsco->build_resource($r); + } + elsif ( $embed_req eq 'resources.package' ) { + $resource->{package} = $ebsco->build_package($r); + } + } + push @{ $title->{resources} }, $resource; + } + + return $c->render( + status => 200, + openapi => $title, + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/Koha/REST/V1/ERM/EHoldings/Titles/Manual.pm b/Koha/REST/V1/ERM/EHoldings/Titles/Manual.pm new file mode 100644 index 0000000000..4564d2d976 --- /dev/null +++ b/Koha/REST/V1/ERM/EHoldings/Titles/Manual.pm @@ -0,0 +1,241 @@ +package Koha::REST::V1::ERM::EHoldings::Titles::Manual; + +# 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 . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::ERM::EHoldings::Titles; + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + my $titles_set = Koha::ERM::EHoldings::Titles->new; + my $titles = $c->objects->search( $titles_set ); + return $c->render( status => 200, openapi => $titles ); + } + catch { + $c->unhandled_exception($_); + }; + +} + +=head3 get + +Controller function that handles retrieving a single Koha::ERM::EHoldings::Title object + +=cut + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my $title_id = $c->validation->param('title_id'); + my $title = $c->objects->find( Koha::ERM::EHoldings::Titles->search, $title_id ); + + unless ($title ) { + return $c->render( + status => 404, + openapi => { error => "eHolding title not found" } + ); + } + + return $c->render( + status => 200, + openapi => $title, + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 add + +Controller function that handles adding a new Koha::ERM::EHoldings::Title object + +=cut + +sub add { + my $c = shift->openapi->valid_input or return; + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $resources = delete $body->{resources} // []; + + my $title = Koha::ERM::EHoldings::Title->new_from_api($body)->store; + + $title->resources($resources); + + $c->res->headers->location($c->req->url->to_string . '/' . $title->title_id); + return $c->render( + status => 201, + openapi => $title->to_api + ); + } + ); + } + catch { + + my $to_api_mapping = Koha::ERM::EHoldings::Title->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { + return $c->render( + status => 409, + openapi => { error => $_->error, conflict => $_->duplicate_id } + ); + } + elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + } + + $c->unhandled_exception($_); + }; +} + +=head3 update + +Controller function that handles updating a Koha::ERM::EHoldings::Title object + +=cut + +sub update { + my $c = shift->openapi->valid_input or return; + + my $title_id = $c->validation->param('title_id'); + my $title = Koha::ERM::EHoldings::Titles->find( $title_id ); + + unless ($title) { + return $c->render( + status => 404, + openapi => { error => "eHolding title not found" } + ); + } + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $resources = delete $body->{resources} // []; + + $title->set_from_api($body)->store; + + $title->resources($resources); + + $c->res->headers->location($c->req->url->to_string . '/' . $title->title_id); + return $c->render( + status => 200, + openapi => $title->to_api + ); + } + ); + } + catch { + my $to_api_mapping = Koha::ERM::EHoldings::Title->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + } + + $c->unhandled_exception($_); + }; +}; + +=head3 delete + +=cut + +sub delete { + my $c = shift->openapi->valid_input or return; + + my $title = Koha::ERM::EHoldings::Titles->find( $c->validation->param('title_id') ); + unless ($title) { + return $c->render( + status => 404, + openapi => { error => "eHolding title not found" } + ); + } + + return try { + $title->delete; + return $c->render( + status => 204, + openapi => q{} + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/api/v1/swagger/definitions/erm_eholdings_package.yaml b/api/v1/swagger/definitions/erm_eholdings_package.yaml index 356de545cb..b2e055cd1e 100644 --- a/api/v1/swagger/definitions/erm_eholdings_package.yaml +++ b/api/v1/swagger/definitions/erm_eholdings_package.yaml @@ -2,7 +2,7 @@ type: object properties: package_id: - type: integer + type: string description: internally assigned package identifier readOnly: true vendor_id: @@ -47,6 +47,14 @@ properties: type: - object - "null" + is_selected: + type: + - boolean + - "null" + resources_count: + type: + - integer + - "null" additionalProperties: false required: diff --git a/api/v1/swagger/definitions/erm_eholdings_resource.yaml b/api/v1/swagger/definitions/erm_eholdings_resource.yaml index f5b1ec7469..8c8df19372 100644 --- a/api/v1/swagger/definitions/erm_eholdings_resource.yaml +++ b/api/v1/swagger/definitions/erm_eholdings_resource.yaml @@ -2,7 +2,7 @@ type: object properties: resource_id: - type: integer + type: string description: internally assigned identifier readOnly: true title_id: @@ -12,6 +12,11 @@ properties: - "null" package_id: description: foreign key to the package + type: + - string + - "null" + vendor_id: + description: foreign key to aqbooksellers type: - integer - "null" @@ -30,6 +35,25 @@ properties: type: - string - "null" + is_selected: + type: + - boolean + - "null" + title: + description: Information about the title + type: + - object + - "null" + package: + description: Information about the package + type: + - object + - "null" + vendor: + description: Information about the vendor + type: + - object + - "null" additionalProperties: false required: diff --git a/api/v1/swagger/definitions/erm_eholdings_title.yaml b/api/v1/swagger/definitions/erm_eholdings_title.yaml index e60a1fb0f9..3d80db95e8 100644 --- a/api/v1/swagger/definitions/erm_eholdings_title.yaml +++ b/api/v1/swagger/definitions/erm_eholdings_title.yaml @@ -11,11 +11,6 @@ properties: - "null" description: internally assigned identifier for the linked biblio readOnly: true - vendor_id: - description: foreign key to aqbooksellers - type: - - integer - - "null" publication_title: description: publication_title of the title type: string diff --git a/api/v1/swagger/paths/erm_agreements.yaml b/api/v1/swagger/paths/erm_agreements.yaml index 9a5efa0b7f..d244dcea94 100644 --- a/api/v1/swagger/paths/erm_agreements.yaml +++ b/api/v1/swagger/paths/erm_agreements.yaml @@ -68,6 +68,10 @@ items: $ref: "../swagger.yaml#/definitions/erm_agreement" type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" 403: description: Access forbidden schema: diff --git a/api/v1/swagger/paths/erm_eholdings_packages.yaml b/api/v1/swagger/paths/erm_eholdings_packages.yaml index 28bd479e6d..71078f4dac 100644 --- a/api/v1/swagger/paths/erm_eholdings_packages.yaml +++ b/api/v1/swagger/paths/erm_eholdings_packages.yaml @@ -13,7 +13,7 @@ in: query name: package_id required: false - type: integer + type: string - description: Case insensitive search on package vendor_id in: query name: vendor_id @@ -58,6 +58,10 @@ items: $ref: "../swagger.yaml#/definitions/erm_eholdings_package" type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" 403: description: Access forbidden schema: @@ -75,6 +79,9 @@ x-koha-authorization: permissions: erm: 1 + x-koha-embed: + - vendors + - resources+count post: x-mojo-to: ERM::EHoldings::Packages#add operationId: addErmEHoldingsPackages diff --git a/api/v1/swagger/paths/erm_eholdings_packages_resources.yaml b/api/v1/swagger/paths/erm_eholdings_packages_resources.yaml new file mode 100644 index 0000000000..f9483887ce --- /dev/null +++ b/api/v1/swagger/paths/erm_eholdings_packages_resources.yaml @@ -0,0 +1,69 @@ +--- +/erm/eholdings/packages/{package_id}/resources: + get: + x-mojo-to: ERM::EHoldings::Resources#list + operationId: listErmEHoldingsPackagesResources + tags: + - eholdings + summary: List eholdings resources + produces: + - application/json + parameters: + - description: Case insensitive search on resource_id + in: query + name: resource_id + required: false + type: string + - description: Case insensitive search on started_on + in: query + name: started_on + required: false + type: string + - description: Case insensitive search on ended_on + in: query + name: ended_on + required: false + type: string + - description: Case insensitive search on proxy + in: query + name: proxy + required: false + type: string + - $ref: "../swagger.yaml#/parameters/eholdings_package_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/q_header" + responses: + 200: + description: A list of eHoldings resources + schema: + items: + $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" + type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 + x-koha-embed: + - title.publication_title diff --git a/api/v1/swagger/paths/erm_eholdings_resources.yaml b/api/v1/swagger/paths/erm_eholdings_resources.yaml index ed8f8617de..3d8ac9a91c 100644 --- a/api/v1/swagger/paths/erm_eholdings_resources.yaml +++ b/api/v1/swagger/paths/erm_eholdings_resources.yaml @@ -13,11 +13,16 @@ in: query name: resource_id required: false - type: integer + type: string - description: Case insensitive search on package_id in: query name: package_id required: false + type: string + - description: Case insensitive search on title vendor_id + in: query + name: vendor_id + required: false type: integer - description: Case insensitive search on started_on in: query @@ -48,66 +53,14 @@ items: $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" type: array - 403: - description: Access forbidden - schema: - $ref: "../swagger.yaml#/definitions/error" - 500: - description: |- - Internal server error. Possible `error_code` attribute values: - * `internal_server_error` - schema: - $ref: "../swagger.yaml#/definitions/error" - 503: - description: Under maintenance - schema: - $ref: "../swagger.yaml#/definitions/error" - x-koha-authorization: - permissions: - erm: 1 - post: - x-mojo-to: ERM::EHoldings::Resources#add - operationId: addErmEHoldingsResources - tags: - - eholdings - summary: Add eholding - consumes: - - application/json - produces: - - application/json - parameters: - - description: A JSON object containing information about the new resource - in: body - name: body - required: true - schema: - $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" - responses: - 201: - description: A successfully created resource - schema: - items: - $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" 400: - description: Bad parameter - schema: - $ref: "../swagger.yaml#/definitions/error" - 401: - description: Authentication required + description: Bad request schema: $ref: "../swagger.yaml#/definitions/error" 403: description: Access forbidden schema: $ref: "../swagger.yaml#/definitions/error" - 404: - description: Ressource not found - schema: - $ref: "../swagger.yaml#/definitions/error" - 409: - description: Conflict in creating resource - schema: - $ref: "../swagger.yaml#/definitions/error" 500: description: |- Internal server error. Possible `error_code` attribute values: @@ -166,105 +119,3 @@ x-koha-embed: - resources - resources.package - put: - x-mojo-to: ERM::EHoldings::Resources#update - operationId: updateErmEHoldingsResources - tags: - - eholdings - summary: Update resources - consumes: - - application/json - produces: - - application/json - parameters: - - $ref: "../swagger.yaml#/parameters/eholdings_resource_id_pp" - - name: body - in: body - description: A JSON object containing new information about existing resource - required: true - schema: - $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" - responses: - 200: - description: A successfully updated resource - schema: - items: - $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" - 400: - description: Bad parameter - schema: - $ref: "../swagger.yaml#/definitions/error" - 403: - description: Access forbidden - schema: - $ref: "../swagger.yaml#/definitions/error" - 404: - description: Ressource not found - schema: - $ref: "../swagger.yaml#/definitions/error" - 409: - description: Conflict in updating resource - schema: - $ref: "../swagger.yaml#/definitions/error" - 500: - description: |- - Internal server error. Possible `error_code` attribute values: - * `internal_server_error` - schema: - $ref: "../swagger.yaml#/definitions/error" - 503: - description: Under maintenance - schema: - $ref: "../swagger.yaml#/definitions/error" - x-koha-authorization: - permissions: - erm: 1 - x-koha-embed: - - resources - - resources.package - delete: - x-mojo-to: ERM::EHoldings::Resources#delete - operationId: deleteErmEHoldingsResources - tags: - - eholdings - summary: Delete eHolding resource - produces: - - application/json - parameters: - - $ref: "../swagger.yaml#/parameters/eholdings_resource_id_pp" - responses: - 204: - description: resource deleted - 400: - description: resource deletion failed - schema: - $ref: "../swagger.yaml#/definitions/error" - 401: - description: Authentication required - schema: - $ref: "../swagger.yaml#/definitions/error" - 403: - description: Access forbidden - schema: - $ref: "../swagger.yaml#/definitions/error" - 404: - description: Ressource not found - schema: - $ref: "../swagger.yaml#/definitions/error" - 409: - description: Conflict in deleting resource - schema: - $ref: "../swagger.yaml#/definitions/error" - 500: - description: |- - Internal server error. Possible `error_code` attribute values: - * `internal_server_error` - schema: - $ref: "../swagger.yaml#/definitions/error" - 503: - description: Under maintenance - schema: - $ref: "../swagger.yaml#/definitions/error" - x-koha-authorization: - permissions: - erm: 1 diff --git a/api/v1/swagger/paths/erm_eholdings_titles.yaml b/api/v1/swagger/paths/erm_eholdings_titles.yaml index cae8ed0f13..a5df76c3e7 100644 --- a/api/v1/swagger/paths/erm_eholdings_titles.yaml +++ b/api/v1/swagger/paths/erm_eholdings_titles.yaml @@ -14,11 +14,6 @@ name: title_id required: false type: integer - - description: Case insensitive search on title vendor_id - in: query - name: vendor_id - required: false - type: integer - description: Case insensitive search on title publication_title in: query name: publication_title @@ -158,6 +153,10 @@ items: $ref: "../swagger.yaml#/definitions/erm_eholdings_title" type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" 403: description: Access forbidden schema: diff --git a/api/v1/swagger/paths/erm_eholdings_titles_resources.yaml b/api/v1/swagger/paths/erm_eholdings_titles_resources.yaml new file mode 100644 index 0000000000..645dd5275c --- /dev/null +++ b/api/v1/swagger/paths/erm_eholdings_titles_resources.yaml @@ -0,0 +1,69 @@ +--- +/erm/eholdings/titles/{title_id}/resources: + get: + x-mojo-to: ERM::EHoldings::Resources#list + operationId: listErmEHoldingsTitlesResources + tags: + - eholdings + summary: List eholdings resources + produces: + - application/json + parameters: + - description: Case insensitive search on resource_id + in: query + name: resource_id + required: false + type: string + - description: Case insensitive search on started_on + in: query + name: started_on + required: false + type: string + - description: Case insensitive search on ended_on + in: query + name: ended_on + required: false + type: string + - description: Case insensitive search on proxy + in: query + name: proxy + required: false + type: string + - $ref: "../swagger.yaml#/parameters/eholdings_title_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/q_header" + responses: + 200: + description: A list of eHoldings resources + schema: + items: + $ref: "../swagger.yaml#/definitions/erm_eholdings_resource" + type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + erm: 1 + x-koha-embed: + - title.publication_title diff --git a/api/v1/swagger/paths/erm_licenses.yaml b/api/v1/swagger/paths/erm_licenses.yaml index d04df9aaad..74b88975d3 100644 --- a/api/v1/swagger/paths/erm_licenses.yaml +++ b/api/v1/swagger/paths/erm_licenses.yaml @@ -53,6 +53,10 @@ items: $ref: "../swagger.yaml#/definitions/erm_license" type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" 403: description: Access forbidden schema: diff --git a/api/v1/swagger/paths/erm_users.yaml b/api/v1/swagger/paths/erm_users.yaml index 9f696b66d3..17e9cc13ca 100644 --- a/api/v1/swagger/paths/erm_users.yaml +++ b/api/v1/swagger/paths/erm_users.yaml @@ -18,24 +18,28 @@ produces: - application/json responses: - "200": + 200: description: A list of ERM' users schema: type: array items: $ref: "../swagger.yaml#/definitions/patron" - "403": + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: description: Access forbidden schema: $ref: "../swagger.yaml#/definitions/error" - "500": + 500: description: | Internal server error. Possible `error_code` attribute values: * `internal_server_error` schema: $ref: "../swagger.yaml#/definitions/error" - "503": + 503: description: Under maintenance schema: $ref: "../swagger.yaml#/definitions/error" diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index e201838497..9aae93ab0d 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -175,6 +175,8 @@ paths: $ref: ./paths/erm_eholdings_titles.yaml#/~1erm~1eholdings~1titles "/erm/eholdings/titles/{title_id}": $ref: "./paths/erm_eholdings_titles.yaml#/~1erm~1eholdings~1titles~1{title_id}" + "/erm/eholdings/titles/{title_id}/resources": + $ref: "./paths/erm_eholdings_titles_resources.yaml#/~1erm~1eholdings~1titles~1{title_id}~1resources" /erm/eholdings/packages: $ref: ./paths/erm_eholdings_packages.yaml#/~1erm~1eholdings~1packages /erm/eholdings/resources: @@ -183,6 +185,8 @@ paths: $ref: "./paths/erm_eholdings_resources.yaml#/~1erm~1eholdings~1resources~1{resource_id}" "/erm/eholdings/packages/{package_id}": $ref: "./paths/erm_eholdings_packages.yaml#/~1erm~1eholdings~1packages~1{package_id}" + "/erm/eholdings/packages/{package_id}/resources": + $ref: "./paths/erm_eholdings_packages_resources.yaml#/~1erm~1eholdings~1packages~1{package_id}~1resources" /erm/licenses: $ref: ./paths/erm_licenses.yaml#/~1erm~1licenses "/erm/licenses/{license_id}": @@ -367,13 +371,13 @@ parameters: in: path name: package_id required: true - type: integer + type: string eholdings_resource_id_pp: description: Resource internal identifier in: path name: resource_id required: true - type: integer + type: string fund_id_pp: description: Fund id in: path diff --git a/installer/data/mysql/atomicupdate/erm.pl b/installer/data/mysql/atomicupdate/erm.pl index d34e57f502..7363647269 100755 --- a/installer/data/mysql/atomicupdate/erm.pl +++ b/installer/data/mysql/atomicupdate/erm.pl @@ -216,7 +216,6 @@ return { CREATE TABLE `erm_eholdings_titles` ( `title_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', `biblio_id` INT(11) DEFAULT NULL, - `vendor_id` INT(11) DEFAULT NULL, `publication_title` VARCHAR(255) DEFAULT NULL, `external_id` VARCHAR(255) DEFAULT NULL, `print_identifier` VARCHAR(255) DEFAULT NULL, @@ -233,7 +232,7 @@ return { `coverage_depth` VARCHAR(255) DEFAULT NULL, `notes` VARCHAR(255) DEFAULT NULL, `publisher_name` VARCHAR(255) DEFAULT NULL, - `publication_type` VARCHAR(255) DEFAULT NULL, + `publication_type` VARCHAR(80) DEFAULT NULL, `date_monograph_published_print` VARCHAR(255) DEFAULT NULL, `date_monograph_published_online` VARCHAR(255) DEFAULT NULL, `monograph_volume` VARCHAR(255) DEFAULT NULL, @@ -242,7 +241,6 @@ return { `parent_publication_title_id` VARCHAR(255) DEFAULT NULL, `preceeding_publication_title_id` VARCHAR(255) DEFAULT NULL, `access_type` VARCHAR(255) DEFAULT NULL, - CONSTRAINT `erm_eholdings_titles_ibfk_1` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `erm_eholdings_titles_ibfk_2` FOREIGN KEY (`biblio_id`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY(`title_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -254,11 +252,13 @@ return { `resource_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', `title_id` INT(11) NOT NULL, `package_id` INT(11) NOT NULL, + `vendor_id` INT(11) DEFAULT NULL, `started_on` DATE, `ended_on` DATE, `proxy` VARCHAR(80) DEFAULT NULL, CONSTRAINT `erm_eholdings_resources_ibfk_1` FOREIGN KEY (`title_id`) REFERENCES `erm_eholdings_titles` (`title_id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `erm_eholdings_resources_ibfk_2` FOREIGN KEY (`package_id`) REFERENCES `erm_eholdings_packages` (`package_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `erm_eholdings_resources_ibfk_3` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY(`resource_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; }); @@ -276,7 +276,8 @@ return { INSERT IGNORE INTO authorised_value_categories (category_name, is_system) VALUES ('ERM_PACKAGE_TYPE', 1), - ('ERM_PACKAGE_CONTENT_TYPE', 1) + ('ERM_PACKAGE_CONTENT_TYPE', 1), + ('ERM_TITLE_PUBLICATION_TYPE', 1) }); $dbh->do(q{ @@ -284,15 +285,30 @@ return { VALUES ('ERM_PACKAGE_TYPE', 'local', 'Local'), ('ERM_PACKAGE_TYPE', 'complete', 'Complete'), - ('ERM_PACKAGE_CONTENT_TYPE', 'mixed_content', 'Aggregated full'), - ('ERM_PACKAGE_CONTENT_TYPE', 'mixed_content', 'Abstract and index'), - ('ERM_PACKAGE_CONTENT_TYPE', 'e_book', 'E-book'), - ('ERM_PACKAGE_CONTENT_TYPE', 'mixed_content', 'Mixed content'), - ('ERM_PACKAGE_CONTENT_TYPE', 'e_journal', 'E-journal'), - ('ERM_PACKAGE_CONTENT_TYPE', 'online_reference', 'Online reference'), - ('ERM_PACKAGE_CONTENT_TYPE', 'print', 'Print'), - ('ERM_PACKAGE_CONTENT_TYPE', 'streaming_media', 'Streaming media'), - ('ERM_PACKAGE_CONTENT_TYPE', 'unknown', 'Unknown') + ('ERM_PACKAGE_CONTENT_TYPE', 'AggregatedFullText', 'Aggregated full'), + ('ERM_PACKAGE_CONTENT_TYPE', 'AbstractAndIndex', 'Abstract and index'), + ('ERM_PACKAGE_CONTENT_TYPE', 'EBook', 'E-book'), + ('ERM_PACKAGE_CONTENT_TYPE', 'MixedContent', 'Mixed content'), + ('ERM_PACKAGE_CONTENT_TYPE', 'EJournal', 'E-journal'), + ('ERM_PACKAGE_CONTENT_TYPE', 'OnlineReference', 'Online reference'), + ('ERM_PACKAGE_CONTENT_TYPE', 'Print', 'Print'), + ('ERM_PACKAGE_CONTENT_TYPE', 'StreamingMedia', 'Streaming media'), + ('ERM_PACKAGE_CONTENT_TYPE', 'Unknown', 'Unknown'), + ('ERM_TITLE_PUBLICATION_TYPE', 'journal', 'Journal'), + ('ERM_TITLE_PUBLICATION_TYPE', 'newsletter', 'Newsletter'), + ('ERM_TITLE_PUBLICATION_TYPE', 'report', 'Report'), + ('ERM_TITLE_PUBLICATION_TYPE', 'proceedings', 'Proceedings'), + ('ERM_TITLE_PUBLICATION_TYPE', 'website', 'Website'), + ('ERM_TITLE_PUBLICATION_TYPE', 'newspaper', 'Newspaper'), + ('ERM_TITLE_PUBLICATION_TYPE', 'unspecified', 'Unspecified'), + ('ERM_TITLE_PUBLICATION_TYPE', 'book', 'Book'), + ('ERM_TITLE_PUBLICATION_TYPE', 'ebook', 'E-book'), + ('ERM_TITLE_PUBLICATION_TYPE', 'bookseries', 'Bookseries'), + ('ERM_TITLE_PUBLICATION_TYPE', 'database', 'Database'), + ('ERM_TITLE_PUBLICATION_TYPE', 'thesisdissertation', 'Thesis/Dissertation'), + ('ERM_TITLE_PUBLICATION_TYPE', 'streamingaudio', 'Streaming audio'), + ('ERM_TITLE_PUBLICATION_TYPE', 'streamingvideo', 'Streaming video'), + ('ERM_TITLE_PUBLICATION_TYPE', 'audiobook', 'AudioBook'); }); $dbh->do(q{ diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 09101b7ca1..8138f2e3a2 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -2929,7 +2929,6 @@ DROP TABLE IF EXISTS `erm_eholdings_titles`; CREATE TABLE `erm_eholdings_titles` ( `title_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', `biblio_id` INT(11) DEFAULT NULL, - `vendor_id` INT(11) DEFAULT NULL, `publication_title` VARCHAR(255) DEFAULT NULL, `external_id` VARCHAR(255) DEFAULT NULL, `print_identifier` VARCHAR(255) DEFAULT NULL, @@ -2946,7 +2945,7 @@ CREATE TABLE `erm_eholdings_titles` ( `coverage_depth` VARCHAR(255) DEFAULT NULL, `notes` VARCHAR(255) DEFAULT NULL, `publisher_name` VARCHAR(255) DEFAULT NULL, - `publication_type` VARCHAR(255) DEFAULT NULL, + `publication_type` VARCHAR(80) DEFAULT NULL, `date_monograph_published_print` VARCHAR(255) DEFAULT NULL, `date_monograph_published_online` VARCHAR(255) DEFAULT NULL, `monograph_volume` VARCHAR(255) DEFAULT NULL, @@ -2955,7 +2954,6 @@ CREATE TABLE `erm_eholdings_titles` ( `parent_publication_title_id` VARCHAR(255) DEFAULT NULL, `preceeding_publication_title_id` VARCHAR(255) DEFAULT NULL, `access_type` VARCHAR(255) DEFAULT NULL, - CONSTRAINT `erm_eholdings_titles_ibfk_1` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `erm_eholdings_titles_ibfk_2` FOREIGN KEY (`biblio_id`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY(`title_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -2969,11 +2967,13 @@ CREATE TABLE `erm_eholdings_resources` ( `resource_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', `title_id` INT(11) NOT NULL, `package_id` INT(11) NOT NULL, + `vendor_id` INT(11) DEFAULT NULL, `started_on` DATE, `ended_on` DATE, `proxy` VARCHAR(80) DEFAULT NULL, CONSTRAINT `erm_eholdings_resources_ibfk_1` FOREIGN KEY (`title_id`) REFERENCES `erm_eholdings_titles` (`title_id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `erm_eholdings_resources_ibfk_2` FOREIGN KEY (`package_id`) REFERENCES `erm_eholdings_packages` (`package_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `erm_eholdings_resources_ibfk_3` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY(`resource_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/installer/data/mysql/mandatory/auth_val_cat.sql b/installer/data/mysql/mandatory/auth_val_cat.sql index ddf21f9027..533b84a389 100644 --- a/installer/data/mysql/mandatory/auth_val_cat.sql +++ b/installer/data/mysql/mandatory/auth_val_cat.sql @@ -85,7 +85,8 @@ VALUES ('ERM_AGREEMENT_LICENSE_STATUS', 1), ('ERM_AGREEMENT_LICENSE_LOCATION', 1), ('ERM_PACKAGE_TYPE', 1), - ('ERM_PACKAGE_CONTENT_TYPE', 1); + ('ERM_PACKAGE_CONTENT_TYPE', 1), + ('ERM_TITLE_PUBLICATION_TYPE', 1); INSERT IGNORE INTO authorised_values (category, authorised_value, lib) VALUES @@ -115,13 +116,27 @@ VALUES ('ERM_AGREEMENT_LICENSE_LOCATION', 'cupboard', 'Cupboard'), ('ERM_PACKAGE_TYPE', 'local', 'Local'), ('ERM_PACKAGE_TYPE', 'complete', 'Complete'), - ('ERM_PACKAGE_CONTENT_TYPE', 'mixed_content', 'Aggregated full'), - ('ERM_PACKAGE_CONTENT_TYPE', 'mixed_content', 'Abstract and index'), - ('ERM_PACKAGE_CONTENT_TYPE', 'e_book', 'E-book'), - ('ERM_PACKAGE_CONTENT_TYPE', 'mixed_content', 'Mixed content'), - ('ERM_PACKAGE_CONTENT_TYPE', 'e_journal', 'E-journal'), - ('ERM_PACKAGE_CONTENT_TYPE', 'online_reference', 'Online reference'), - ('ERM_PACKAGE_CONTENT_TYPE', 'print', 'Print'), - ('ERM_PACKAGE_CONTENT_TYPE', 'streaming_media', 'Streaming media'), - ('ERM_PACKAGE_CONTENT_TYPE', 'unknown', 'Unknown'); - + ('ERM_PACKAGE_CONTENT_TYPE', 'AggregatedFullText', 'Aggregated full'), + ('ERM_PACKAGE_CONTENT_TYPE', 'AbstractAndIndex', 'Abstract and index'), + ('ERM_PACKAGE_CONTENT_TYPE', 'EBook', 'E-book'), + ('ERM_PACKAGE_CONTENT_TYPE', 'MixedContent', 'Mixed content'), + ('ERM_PACKAGE_CONTENT_TYPE', 'EJournal', 'E-journal'), + ('ERM_PACKAGE_CONTENT_TYPE', 'OnlineReference', 'Online reference'), + ('ERM_PACKAGE_CONTENT_TYPE', 'Print', 'Print'), + ('ERM_PACKAGE_CONTENT_TYPE', 'StreamingMedia', 'Streaming media'), + ('ERM_PACKAGE_CONTENT_TYPE', 'Unknown', 'Unknown'), + ('ERM_TITLE_PUBLICATION_TYPE', 'journal', 'Journal'), + ('ERM_TITLE_PUBLICATION_TYPE', 'newsletter', 'Newsletter'), + ('ERM_TITLE_PUBLICATION_TYPE', 'report', 'Report'), + ('ERM_TITLE_PUBLICATION_TYPE', 'proceedings', 'Proceedings'), + ('ERM_TITLE_PUBLICATION_TYPE', 'website', 'Website'), + ('ERM_TITLE_PUBLICATION_TYPE', 'newspaper', 'Newspaper'), + ('ERM_TITLE_PUBLICATION_TYPE', 'unspecified', 'Unspecified'), + ('ERM_TITLE_PUBLICATION_TYPE', 'book', 'Book'), + ('ERM_TITLE_PUBLICATION_TYPE', 'ebook', 'E-book'), + ('ERM_TITLE_PUBLICATION_TYPE', 'bookseries', 'Bookseries'), + ('ERM_TITLE_PUBLICATION_TYPE', 'database', 'Database'), + ('ERM_TITLE_PUBLICATION_TYPE', 'thesisdissertation', 'Thesis/Dissertation'), + ('ERM_TITLE_PUBLICATION_TYPE', 'streamingaudio', 'Streaming audio'), + ('ERM_TITLE_PUBLICATION_TYPE', 'streamingvideo', 'Streaming video'), + ('ERM_TITLE_PUBLICATION_TYPE', 'audiobook', 'AudioBook'); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/erm/erm.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/erm/erm.tt index fcef81f6b5..432bd5ac44 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/erm/erm.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/erm/erm.tt @@ -42,11 +42,15 @@ const package_types = [% To.json(AuthorisedValues.Get('ERM_PACKAGE_TYPE')) | $raw %]; const package_content_types = [% To.json(AuthorisedValues.Get('ERM_PACKAGE_CONTENT_TYPE')) | $raw %]; + const title_publication_types = [% To.json(AuthorisedValues.Get('ERM_TITLE_PUBLICATION_TYPE')) | $raw %]; + const agreement_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'agreements', 'agreements', 'json' ) | $raw %]; const license_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'licenses', 'licenses', 'json' ) | $raw %]; const eholdings_packages_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'eholdings', 'packages', 'json' ) | $raw %]; const eholdings_titles_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'eholdings', 'titles', 'json' ) | $raw %]; + const erm_provider = "[% Koha.Preference('ERMProvider') | html %]"; + [% Asset.js("js/vue/dist/main.js") | $raw %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue index 33a3b1eb90..0eea2a4904 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue @@ -224,8 +224,6 @@ diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackageTitlesList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackageTitlesList.vue new file mode 100644 index 0000000000..39a60a93da --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackageTitlesList.vue @@ -0,0 +1,205 @@ + + + + + \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesFormAdd.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesFormAdd.vue index c5d1fe7560..20e2545408 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesFormAdd.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesFormAdd.vue @@ -176,6 +176,7 @@ export default { delete erm_package.package_id delete erm_package.resources delete erm_package.vendor + delete erm_package.resources_count erm_package.package_agreements = erm_package.package_agreements.map(({ package_id, agreement, ...keepAttrs }) => keepAttrs) diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesList.vue index 87f5b83df2..c221cb54ec 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesList.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesList.vue @@ -1,10 +1,53 @@ @@ -19,22 +62,30 @@ import { fetchPackages } from "../../fetch" export default { setup() { - const vendorStore = useVendorStore() + const vendorStore = useVendorStore() // FIXME We only need that for 'manual' const { vendors } = storeToRefs(vendorStore) const AVStore = useAVStore() const { av_package_types, av_package_content_types } = storeToRefs(AVStore) + const { get_lib_from_av } = AVStore return { vendors, av_package_types, av_package_content_types, + get_lib_from_av, } }, + inject: ['erm_provider'], data: function () { return { packages: [], initialized: false, + filters: { + package_name: this.$route.query.q || "", + content_type: "", + selection_type: "", + }, } }, beforeRouteEnter(to, from, next) { @@ -44,8 +95,10 @@ export default { }, methods: { async getPackages() { - const packages = await fetchPackages() - this.packages = packages + if (erm_provider == 'manual') { + const packages = await fetchPackages() + this.packages = packages + } this.initialized = true }, show_package: function (package_id) { @@ -57,113 +110,119 @@ export default { delete_package: function (package_id) { this.$router.push("/cgi-bin/koha/erm/eholdings/packages/delete/" + package_id) }, + filter_table: function () { + $("#package_list_result").show() + $("#package_list").DataTable().draw() + } }, updated() { let show_package = this.show_package let edit_package = this.edit_package let delete_package = this.delete_package - let default_search = this.$route.query.q + let get_lib_from_av = this.get_lib_from_av + let filters = this.filters window['vendors'] = this.vendors.map(e => { e['_id'] = e['id'] e['_str'] = e['name'] return e }) - let vendors_map = this.vendors.reduce((map, e) => { - map[e.id] = e - return map - }, {}) window['av_package_types'] = this.av_package_types.map(e => { e['_id'] = e['authorised_value'] e['_str'] = e['lib'] return e }) - let av_package_types_map = this.av_package_types.reduce((map, e) => { - map[e.authorised_value] = e - return map - }, {}) window['av_package_content_types'] = this.av_package_content_types.map(e => { e['_id'] = e['authorised_value'] e['_str'] = e['lib'] return e }) - let av_package_content_types_map = this.av_package_content_types.reduce((map, e) => { - map[e.authorised_value] = e - return map - }, {}) + + let additional_filters = {} + if (erm_provider != 'manual') { + additional_filters = { + name: function () { + return filters.package_name || "" + }, + content_type: function () { + return filters.content_type || "" + }, + selection_type: function () { + return filters.selection_type || "" + }, + } + } $('#package_list').kohaTable({ "ajax": { "url": "/api/v1/erm/eholdings/packages", }, - "order": [[0, "asc"]], - "search": { search: default_search }, - "columnDefs": [{ - "targets": [0], - "render": function (data, type, row, meta) { - if (type == 'display') { - return escape_str(data) - } - return data - } - }], + "embed": ['resources+count', 'vendor.name'], + ...(erm_provider == 'manual' ? { order: [[0, "asc"]] } : {}), + ...(erm_provider != 'manual' ? { ordering: false } : {}), + ...(erm_provider == 'manual' ? { search: { search: filters.package_name } } : {}), + ...(erm_provider != 'manual' ? { dom: '<"top pager"<"table_entries"ilp>>tr<"bottom pager"ip>' } : {}), + ...(erm_provider != 'manual' ? { lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]] } : {}), + ...(erm_provider != 'manual' ? { deferLoading: true } : {}), + autoWidth: false, "columns": [ { "title": __("Name"), "data": "me.package_id:me.name", - "searchable": true, - "orderable": true, + "searchable": (erm_provider == 'manual'), + "orderable": (erm_provider == 'manul'), "render": function (data, type, row, meta) { // Rendering done in drawCallback - return ""; + return "" } }, { "title": __("Vendor"), "data": "vendor_id", - "searchable": true, - "orderable": true, + "searchable": (erm_provider == 'manual'), + "orderable": (erm_provider == 'manul'), "render": function (data, type, row, meta) { - return row.vendor_id != undefined ? escape_str(vendors_map[row.vendor_id].name) : "" - } + return row.vendor ? escape_str(row.vendor.name) : "" + }, }, { "title": __("Type"), "data": "package_type", - "searchable": true, - "orderable": true, + "searchable": (erm_provider == 'manual'), + "orderable": (erm_provider == 'manul'), "render": function (data, type, row, meta) { - return row.package_type != undefined && row.package_type != "" ? escape_str(av_package_types_map[row.package_type].lib) : "" + return escape_str(get_lib_from_av("av_package_types", row.package_type)) } - }, - { - "title": __("Content type"), - "data": "package_type", - "searchable": true, - "orderable": true, - "render": function (data, type, row, meta) { - return row.content_type != undefined && row.content_type != "" ? escape_str(av_package_content_types_map[row.content_type].lib) : "" - } - }, - { - "title": __("Created on"), - "data": "created_on", + }, { + "searchable": (erm_provider == 'manual'), + "orderable": (erm_provider == 'manul'), "searchable": true, "orderable": true, "render": function (data, type, row, meta) { - return $date(row.created_on) + return escape_str(get_lib_from_av("av_package_content_types", row.content_type)) } }, - { - "title": __("Actions"), - "data": function (row, type, val, meta) { - return '
' - }, - "className": "actions noExport", - "searchable": false, - "orderable": false - } - ], + erm_provider == 'manual' ? + { + "title": __("Created on"), + "data": "created_on", + "searchable": true, + "orderable": true, + "render": function (data, type, row, meta) { + return $date(row.created_on) + } + } : null, + erm_provider == 'manual' ? + { + "title": __("Actions"), + "data": function (row, type, val, meta) { + return '
' + }, + "className": "actions noExport", + "searchable": false, + "orderable": false + } : null, + ].filter(Boolean), drawCallback: function (settings) { var api = new $.fn.dataTable.Api(settings) @@ -193,23 +252,37 @@ export default { if (!row) return // Happen if the table is empty let n = createVNode("a", { role: "button", - onClick: () => { + href: "/cgi-bin/koha/erm/eholdings/packages/" + row.package_id, + onClick: (e) => { + e.preventDefault() show_package(row.package_id) } }, - `${row.name} (#${row.package_id})` + `${row.name} (#${row.package_id})` ) + if (row.is_selected) { + n = createVNode('span', {}, [n, " ", createVNode("i", { class: "fa fa-check-square-o", style: { color: "green" }, title: __("Is selected") })]) + } render(n, e) }) }, - preDrawCallback: function (settings) { - var table_id = settings.nTable.id - $("#" + table_id).find("thead th").eq(1).attr('data-filter', 'vendors') - $("#" + table_id).find("thead th").eq(2).attr('data-filter', 'av_package_types') - $("#" + table_id).find("thead th").eq(3).attr('data-filter', 'av_package_content_types') - } + ...(erm_provider == 'manual' ? { + preDrawCallback: function (settings) { + var table_id = settings.nTable.id + if (erm_provider == 'manual') { + $("#" + table_id).find("thead th").eq(1).attr('data-filter', 'vendors') + } + $("#" + table_id).find("thead th").eq(2).attr('data-filter', 'av_package_types') + $("#" + table_id).find("thead th").eq(3).attr('data-filter', 'av_package_content_types') + } + } : {}), + }, eholdings_packages_table_settings, erm_provider == 'manual' ? 1 : 0, additional_filters) - }, eholdings_packages_table_settings, 1) + if (erm_provider != 'manual') { + if (filters.package_name.length) { + this.filter_table() + } + } }, beforeUnmount() { $('#package_list') @@ -219,4 +292,4 @@ export default { components: { Toolbar }, name: "EHoldingsPackagesList", } - + \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesShow.vue index ac0c3c7e4c..6a8263aa43 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesShow.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesShow.vue @@ -1,9 +1,9 @@ @@ -160,4 +155,7 @@ export default { padding-left: 0.2em; font-size: 11px; } +fieldset.rows label { + width: 25rem; +} diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsResourcesShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsResourcesShow.vue index d5960b65d3..4a43c81f88 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsResourcesShow.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsResourcesShow.vue @@ -1,6 +1,6 @@