Bug 32030: Proxy with HoldingsIQ
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Mon, 20 Jun 2022 12:57:01 +0000 (14:57 +0200)
committerTomas Cohen Arazi <tomascohen@theke.io>
Tue, 8 Nov 2022 12:44:07 +0000 (09:44 -0300)
Signed-off-by: Jonathan Field <jonathan.field@ptfs-europe.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
43 files changed:
Koha/ERM/EHoldings/Resource.pm
Koha/ERM/Providers/EBSCO.pm [new file with mode: 0644]
Koha/REST/Plugin/Pagination.pm
Koha/REST/V1/ERM/EHoldings/Packages.pm
Koha/REST/V1/ERM/EHoldings/Packages/EBSCO.pm [new file with mode: 0644]
Koha/REST/V1/ERM/EHoldings/Packages/Manual.pm [new file with mode: 0644]
Koha/REST/V1/ERM/EHoldings/Resources.pm
Koha/REST/V1/ERM/EHoldings/Resources/EBSCO.pm [new file with mode: 0644]
Koha/REST/V1/ERM/EHoldings/Resources/Manual.pm [new file with mode: 0644]
Koha/REST/V1/ERM/EHoldings/Titles.pm
Koha/REST/V1/ERM/EHoldings/Titles/EBSCO.pm [new file with mode: 0644]
Koha/REST/V1/ERM/EHoldings/Titles/Manual.pm [new file with mode: 0644]
api/v1/swagger/definitions/erm_eholdings_package.yaml
api/v1/swagger/definitions/erm_eholdings_resource.yaml
api/v1/swagger/definitions/erm_eholdings_title.yaml
api/v1/swagger/paths/erm_agreements.yaml
api/v1/swagger/paths/erm_eholdings_packages.yaml
api/v1/swagger/paths/erm_eholdings_packages_resources.yaml [new file with mode: 0644]
api/v1/swagger/paths/erm_eholdings_resources.yaml
api/v1/swagger/paths/erm_eholdings_titles.yaml
api/v1/swagger/paths/erm_eholdings_titles_resources.yaml [new file with mode: 0644]
api/v1/swagger/paths/erm_licenses.yaml
api/v1/swagger/paths/erm_users.yaml
api/v1/swagger/swagger.yaml
installer/data/mysql/atomicupdate/erm.pl
installer/data/mysql/kohastructure.sql
installer/data/mysql/mandatory/auth_val_cat.sql
koha-tmpl/intranet-tmpl/prog/en/modules/erm/erm.tt
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackageTitlesList.vue [new file with mode: 0644]
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesFormAdd.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesList.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsPackagesShow.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsResourcesShow.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlePackagesList.vue [new file with mode: 0644]
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlesFormAdd.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlesFormAddResources.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlesList.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlesShow.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/ERMMain.vue
koha-tmpl/intranet-tmpl/prog/js/vue/fetch.js
koha-tmpl/intranet-tmpl/prog/js/vue/stores/authorised_values.js
koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js

index a7badbb..fa776cf 100644 (file)
@@ -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 (file)
index 0000000..7326184
--- /dev/null
@@ -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;
index 1176c83..9873a7a 100644 (file)
@@ -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;
         }
     );
index e354a19..fa974fc 100644 (file)
@@ -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 (file)
index 0000000..ddb93b4
--- /dev/null
@@ -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 <http://www.gnu.org/licenses>.
+
+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 (file)
index 0000000..27731ae
--- /dev/null
@@ -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;
index 9c45005..e752a21 100644 (file)
@@ -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 (file)
index 0000000..555a6e3
--- /dev/null
@@ -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 <http://www.gnu.org/licenses>.
+
+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 (file)
index 0000000..537e345
--- /dev/null
@@ -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 <http://www.gnu.org/licenses>.
+
+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;
index 82cbe9b..6b2975f 100644 (file)
@@ -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 (file)
index 0000000..3537a8b
--- /dev/null
@@ -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 <http://www.gnu.org/licenses>.
+
+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 (file)
index 0000000..4564d2d
--- /dev/null
@@ -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 <http://www.gnu.org/licenses>.
+
+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;
index 356de54..b2e055c 100644 (file)
@@ -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:
index f5b1ec7..8c8df19 100644 (file)
@@ -2,7 +2,7 @@
 type: object
 properties:
   resource_id:
-    type: integer
+    type: string
     description: internally assigned identifier
     readOnly: true
   title_id:
@@ -13,6 +13,11 @@ properties:
   package_id:
     description: foreign key to the package
     type:
+      - string
+      - "null"
+  vendor_id:
+    description: foreign key to aqbooksellers
+    type:
       - integer
       - "null"
   started_on:
@@ -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:
index e60a1fb..3d80db9 100644 (file)
@@ -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
index 9a5efa0..d244dce 100644 (file)
           items:
             $ref: "../swagger.yaml#/definitions/erm_agreement"
           type: array
+      400:
+        description: Bad request
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
       403:
         description: Access forbidden
         schema:
index 28bd479..71078f4 100644 (file)
@@ -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
           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 (file)
index 0000000..f948388
--- /dev/null
@@ -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
index ed8f861..3d8ac9a 100644 (file)
         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
           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:
     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
index cae8ed0..a5df76c 100644 (file)
         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
           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 (file)
index 0000000..645dd52
--- /dev/null
@@ -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
index d04df9a..74b8897 100644 (file)
           items:
             $ref: "../swagger.yaml#/definitions/erm_license"
           type: array
+      400:
+        description: Bad request
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
       403:
         description: Access forbidden
         schema:
index 9f696b6..17e9cc1 100644 (file)
     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"
index e201838..9aae93a 100644 (file)
@@ -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
index d34e57f..7363647 100755 (executable)
@@ -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{
index 09101b7..8138f2e 100644 (file)
@@ -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;
 
index ddf21f9..533b84a 100644 (file)
@@ -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');
index fcef81f..432bd5a 100644 (file)
         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 %]";
+
     </script>
 
     [% Asset.js("js/vue/dist/main.js") | $raw %]
index 33a3b1e..0eea2a4 100644 (file)
 </template>
 
 <script>
-import AgreementPeriods from './AgreementPeriods.vue'
-import AgreementUserRoles from './AgreementUserRoles.vue'
 import { useVendorStore } from "../../stores/vendors"
 import { useAVStore } from "../../stores/authorised_values"
 import { fetchAgreement } from "../../fetch"
@@ -283,10 +281,6 @@ export default {
             this.initialized = true
         },
     },
-    components: {
-        AgreementPeriods,
-        AgreementUserRoles
-    },
     name: "AgreementsShow",
 }
 </script>
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 (file)
index 0000000..39a60a9
--- /dev/null
@@ -0,0 +1,205 @@
+<template>
+    <div id="title_list_result">
+        <div id="filters" v-if="erm_provider != 'manual'">
+            <a href="#" @click.prevent="toggle_filters($event)"
+                ><i class="fa fa-search"></i>
+                {{ display_filters ? $t("Hide filters") : $t("Show filters") }}
+            </a>
+            <fieldset v-if="display_filters">
+                <ol>
+                    <li>
+                        <label>{{ $t("Title") }}:</label>
+                        <input
+                            type="text"
+                            id="publication_title_filter"
+                            @keyup.enter="filter_table"
+                        />
+                    </li>
+                    <li>
+                        <label>{{ $t("Publication type") }}:</label>
+                        <select id="publication_type_filter">
+                            <option value="">{{ $t("All") }}</option>
+                            <option
+                                v-for="type in av_title_publication_types"
+                                :key="type.authorised_values"
+                                :value="type.authorised_value"
+                            >
+                                {{ type.lib }}
+                            </option>
+                        </select>
+                    </li>
+                    <li>
+                        <label>{{ $t("Selection status") }}:</label>
+                        <select id="selection_type_filter">
+                            <option value="0">{{ $t("All") }}</option>
+                            <option value="1">{{ $t("Selected") }}</option>
+                            <option value="2">{{ $t("Not selected") }}</option>
+                        </select>
+                    </li>
+                </ol>
+
+                <input
+                    @click="filter_table"
+                    id="filter_table"
+                    type="button"
+                    :value="$t('Filter')"
+                />
+            </fieldset>
+        </div>
+        <table id="title_list"></table>
+    </div>
+</template>
+
+<script>
+
+import { createVNode, render } from 'vue'
+import { useAVStore } from "../../stores/authorised_values"
+import { storeToRefs } from "pinia"
+
+export default {
+    setup() {
+        const AVStore = useAVStore()
+        const { av_title_publication_types } = storeToRefs(AVStore)
+        const { get_lib_from_av } = AVStore
+
+        return {
+            av_title_publication_types,
+            get_lib_from_av,
+        }
+    },
+    data() {
+        return {
+            display_filters: false,
+        }
+    },
+    inject: ['erm_provider'],
+    methods: {
+        show_resource: function (resource_id) {
+            this.$router.push("/cgi-bin/koha/erm/eholdings/resources/" + resource_id)
+        },
+        filter_table: function () {
+            $("#title_list").DataTable().draw()
+        },
+        toggle_filters: function (e) {
+            this.display_filters = !this.display_filters
+        },
+    },
+    mounted() {
+        let show_resource = this.show_resource
+        let package_id = this.package_id
+        let get_lib_from_av = this.get_lib_from_av
+
+        window['av_title_publication_types'] = this.av_title_publication_types.map(e => {
+            e['_id'] = e['authorised_value']
+            e['_str'] = e['lib']
+            return e
+        })
+
+        let additional_filters = {}
+        if (erm_provider != 'manual') {
+            additional_filters = {
+                publication_title: function () {
+                    let publication_title_search = $("#publication_title_filter").val()
+                    if (!publication_title_search) return ""
+                    return publication_title_search
+                },
+                publication_type: function () {
+                    let content_type_search = $("#publication_type_filter").val()
+                    if (!content_type_search) return ""
+                    return content_type_search
+                },
+                selection_type: function () {
+                    let selection_type_search = $("#selection_type_filter").val()
+                    if (!selection_type_search) return ""
+                    return selection_type_search
+                },
+            }
+        }
+
+        $('#title_list').kohaTable({
+            "ajax": {
+                "url": "/api/v1/erm/eholdings/packages/" + package_id + "/resources",
+            },
+            ...(erm_provider != 'manual' ? { ordering: false } : {}),
+            ...(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]] } : {}),
+            "embed": ['title.publication_title'],
+            autoWidth: false,
+            "columns": [
+                {
+                    "title": __("Name"),
+                    "data": "title.publication_title",
+                    "searchable": (erm_provider == 'manual') ? 1 : 0,
+                    "orderable": (erm_provider == 'manul') ? 1 : 0,
+                    "render": function (data, type, row, meta) {
+                        // Rendering done in drawCallback
+                        return ""
+                    }
+                },
+                {
+                    "title": __("Publication type"),
+                    "data": "title.publication_type",
+                    "searchable": (erm_provider == 'manual') ? 1 : 0,
+                    "orderable": (erm_provider == 'manul') ? 1 : 0,
+                    "render": function (data, type, row, meta) {
+                        return escape_str(get_lib_from_av("av_title_publication_types", row.title.publication_type))
+                    }
+                },
+            ],
+            drawCallback: function (settings) {
+
+                var api = new $.fn.dataTable.Api(settings)
+
+                $.each($(this).find("tbody tr td:first-child"), function (index, e) {
+                    let row = api.row(index).data()
+                    if (!row) return // Happen if the table is empty
+                    let n = createVNode("a", {
+                        role: "button",
+                        href: "/cgi-bin/koha/erm/eholdings/resources/" + row.resource_id,
+                        onClick: (e) => {
+                            e.preventDefault()
+                            show_resource(row.resource_id)
+                        }
+                    },
+                        `${row.title.publication_title}`
+                    )
+                    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)
+                })
+            },
+            ...(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', 'av_title_publication_types')
+                    }
+                }
+            } : {}),
+        }, null, erm_provider == 'manual' ? 1 : 0, additional_filters)
+    },
+    beforeUnmount() {
+        $('#title_list')
+            .DataTable()
+            .destroy(true)
+    },
+    props: {
+        package_id: String,
+    },
+    name: 'EHoldingsPackageTitlesList',
+}
+</script>
+
+<style scoped>
+#title_list_result {
+    width: 50%;
+    padding-left: 10rem;
+}
+#title_list {
+    display: table;
+}
+#filters {
+    margin: 0;
+}
+</style>
\ No newline at end of file
index c5d1fe7..20e2545 100644 (file)
@@ -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)
 
index 87f5b83..c221cb5 100644 (file)
@@ -1,10 +1,53 @@
 <template>
-    <div v-if="!this.initialized">{{ $t("Loading") }}</div>
-    <div v-else-if="this.packages" id="packages_list">
-        <Toolbar />
-        <table v-if="this.packages.length" id="package_list"></table>
-        <div v-else-if="this.initialized" class="dialog message">
-            {{ $t("There are no packages defined") }}
+    <div v-if="erm_provider == 'manual'">
+        <div v-if="!this.initialized">{{ $t("Loading") }}</div>
+        <div v-else-if="this.packages" id="packages_list">
+            <Toolbar />
+            <table v-if="this.packages.length" id="package_list"></table>
+            <div v-else-if="this.initialized" class="dialog message">
+                {{ $t("There are no packages defined") }}
+            </div>
+        </div>
+
+        <div id="package_list_result">
+            <table id="package_list"></table>
+        </div>
+    </div>
+    <div v-else>
+        <fieldset>
+            {{ $t("Package name") }}:
+            <input
+                type="text"
+                id="package_name_filter"
+                v-model="filters.package_name"
+                @keyup.enter="filter_table"
+            />
+            {{ $t("Content type") }}:
+            <select id="content_type_filter" v-model="filters.content_type">
+                <option value="">{{ $t("All") }}</option>
+                <option
+                    v-for="type in av_package_content_types"
+                    :key="type.authorised_values"
+                    :value="type.authorised_value"
+                >
+                    {{ type.lib }}
+                </option>
+            </select>
+            {{ $t("Selection status") }}:
+            <select id="selection_type_filter" v-model="filters.selection_type">
+                <option value="0">{{ $t("All") }}</option>
+                <option value="1">{{ $t("Selected") }}</option>
+                <option value="2">{{ $t("Not selected") }}</option>
+            </select>
+            <input
+                @click="filter_table"
+                id="filter_table"
+                type="button"
+                :value="$t('Submit')"
+            />
+        </fieldset>
+        <div id="package_list_result" style="display: none">
+            <table id="package_list"></table>
         </div>
     </div>
 </template>
@@ -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 '<div class="actions"></div>'
-                    },
-                    "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 '<div class="actions"></div>'
+                        },
+                        "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",
 }
-</script>
+</script>
\ No newline at end of file
index ac0c3c7..6a8263a 100644 (file)
@@ -1,9 +1,9 @@
 <template>
-    <div v-if="!this.initialized">{{ $t("Loading") }}</div>
-    <div v-else id="packages_show">
+    <div v-if="!initialized">{{ $t("Loading") }}</div>
+    <div v-else-if="erm_package" id="packages_show">
         <h2>
             {{ $t("Package .id", { id: erm_package.package_id }) }}
-            <span class="action_links">
+            <span v-if="erm_provider == 'manual'" class="action_links">
                 <router-link
                     :to="`/cgi-bin/koha/erm/eholdings/packages/edit/${erm_package.package_id}`"
                     :title="$t('Edit')"
                             {{ erm_package.name }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="erm_package.vendor">
                         <label>{{ $t("Vendor") }}:</label>
-                        <span v-if="erm_package.vendor"
-                            ><a :href="`/cgi-bin/koha/acqui/booksellers.pl?booksellerid=${erm_package.vendor_id}`">{{ erm_package.vendor.name }}</a>
+                        <span v-if="erm_provider == 'manual'">
+                            <a
+                                :href="`/cgi-bin/koha/acqui/booksellers.pl?booksellerid=${erm_package.vendor_id}`"
+                                >{{ erm_package.vendor.name }}</a
+                            >
                         </span>
+                        <span v-else>{{ erm_package.vendor.name }}</span>
                     </li>
                     <li v-if="erm_package.external_id">
                         <label>{{ $t("External ID") }}:</label>
                             )
                         }}</span>
                     </li>
-                    <li>
+                    <li v-if="erm_package.created_on">
                         <label>{{ $t("Created on") }}:</label>
                         <span>{{ format_date(erm_package.created_on) }}</span>
                     </li>
 
-                    <li v-if="erm_package.resources.length">
-                        <label>{{ $t("Titles") }}</label>
-                        <table>
-                            <thead>
-                                <tr>
-                                    <th>Name</th>
-                                </tr>
-                            </thead>
-                            <tbody>
-                                <tr
-                                    v-for="(
-                                        r, counter
-                                    ) in erm_package.resources"
-                                    v-bind:key="counter"
-                                >
-                                    <td>
-                                        <router-link
-                                            :to="`/cgi-bin/koha/erm/eholdings/resources/${r.resource_id}`"
-                                            :title="$t('Show resource')"
-                                        >
-                                            {{ r.title.publication_title }}
-                                        </router-link>
-                                    </td>
-                                </tr>
-                            </tbody>
-                        </table>
+                    <li>
+                        <label
+                            >Titles ({{ erm_package.resources_count }})</label
+                        >
+                        <div v-if="erm_package.resources_count">
+                            <EHoldingsPackageTitlesList
+                                :package_id="erm_package.package_id.toString()"
+                            />
+                        </div>
                     </li>
+
+                    <li></li>
                 </ol>
             </fieldset>
             <fieldset class="action">
 </template>
 
 <script>
+import EHoldingsPackageTitlesList from "./EHoldingsPackageTitlesList.vue"
 import { useAVStore } from "../../stores/authorised_values"
 import { fetchPackage } from "../../fetch"
 
@@ -123,6 +113,7 @@ export default {
             get_lib_from_av,
         }
     },
+    inject: ['erm_provider'],
     data() {
         return {
             erm_package: {
@@ -133,6 +124,7 @@ export default {
                 package_type: '',
                 content_type: '',
                 created_on: null,
+                resources: null,
             },
             initialized: false,
         }
@@ -152,6 +144,9 @@ export default {
             this.initialized = true
         },
     },
+    components: {
+        EHoldingsPackageTitlesList,
+    },
     name: "EHoldingsPackagesShow",
 }
 </script>
@@ -160,4 +155,7 @@ export default {
     padding-left: 0.2em;
     font-size: 11px;
 }
+fieldset.rows label {
+    width: 25rem;
+}
 </style>
index d5960b6..4a43c81 100644 (file)
@@ -1,6 +1,6 @@
 <template>
     <div v-if="!initialized">{{ $t("Loading") }}</div>
-    <div v-else id="eholdings_resources_show">
+    <div v-else-if="resource" id="eholdings_resources_show">
         <h2>
             {{ $t("Resource .id", { id: resource.resource_id }) }}
         </h2>
                         >
                     </li>
                     <li>
-                        <label>{{ $t("First author") }}:</label>
-                        <span>
-                            {{ resource.title.first_author }}
-                        </span>
-                    </li>
-                    <li>
                         <label>{{ $t("Publisher name") }}:</label>
                         <span>
                             {{ resource.title.publisher_name }}
 
                     <li>
                         <label>{{ $t("Vendor") }}:</label>
-                        <span v-if="resource.vendor_id">
-                            {{
-                                vendors.find((e) => e.id == resource.vendor_id)
-                                    .name
-                            }}
+                        <span v-if="resource.vendor">
+                            {{ resource.vendor.name }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="resource.package.content_type">
                         <label>{{ $t("Package content type") }}:</label>
                         <span>{{ resource.package.content_type }}</span>
                     </li>
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlePackagesList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsTitlePackagesList.vue
new file mode 100644 (file)
index 0000000..f1c8b72
--- /dev/null
@@ -0,0 +1,157 @@
+<template>
+    <div id="package_list_result">
+        <div id="filters" v-if="erm_provider != 'manual'">
+            <a href="#" @click.prevent="toggle_filters($event)"
+                ><i class="fa fa-search"></i>
+                {{ display_filters ? $t("Hide filters") : $t("Show filters") }}
+            </a>
+            <fieldset v-if="display_filters" id="filters">
+                <ol>
+                    <li>
+                        <label>{{ $t("Package name") }}:</label>
+                        <input
+                            type="text"
+                            id="package_name_filter"
+                            @keyup.enter="filter_table"
+                        />
+                    </li>
+                    <li>
+                        <label>{{ $t("Selection status") }}:</label>
+                        <select id="selection_type_filter">
+                            <option value="0">{{ $t("All") }}</option>
+                            <option value="1">{{ $t("Selected") }}</option>
+                            <option value="2">{{ $t("Not selected") }}</option>
+                        </select>
+                    </li>
+                </ol>
+                <input
+                    @click="filter_table"
+                    id="filter_table"
+                    type="button"
+                    :value="$t('Filter')"
+                />
+            </fieldset>
+        </div>
+        <table id="package_list"></table>
+    </div>
+</template>
+
+<script>
+
+import { createVNode, render } from 'vue'
+
+export default {
+    setup() {
+        return {
+        }
+    },
+    data() {
+        return {
+            display_filters: false,
+        }
+    },
+    inject: ['erm_provider'],
+    methods: {
+        show_resource: function (resource_id) {
+            this.$router.push("/cgi-bin/koha/erm/eholdings/resources/" + resource_id)
+        },
+        toggle_filters: function (e) {
+            this.display_filters = !this.display_filters
+        },
+        filter_table: function () {
+            $("#package_list").DataTable().draw()
+        },
+    },
+    mounted() {
+        let show_resource = this.show_resource
+        let resources = this.resources
+
+        let additional_filters = {}
+        if (erm_provider != 'manual') {
+            additional_filters = {
+                name: function () {
+                    let package_name_search = $("#package_name_filter").val()
+                    if (!package_name_search) return ""
+                    return package_name_search
+                },
+                selection_type: function () {
+                    let selection_type_search = $("#selection_type_filter").val()
+                    if (!selection_type_search) return ""
+                    return selection_type_search
+                },
+            }
+        }
+
+        $('#package_list').dataTable($.extend(true, {}, dataTablesDefaults, {
+            data: resources,
+            ...(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]] } : {}),
+            "embed": ['package.name'],
+            "columnDefs": [{ "width": "20%", "targets": 0 }
+            ],
+            autoWidth: false,
+            "columns": [
+                {
+                    "title": __("Name"),
+                    "data": "package_name",
+                    "searchable": true,
+                    "orderable": true,
+                    "render": function (data, type, row, meta) {
+                        // Rendering done in drawCallback
+                        return ""
+                    },
+                    width: '100%',
+                },
+            ],
+            drawCallback: function (settings) {
+
+                var api = new $.fn.dataTable.Api(settings)
+
+                $.each($(this).find("tbody tr td:first-child"), function (index, e) {
+                    let row = api.row(index).data()
+                    if (!row) return // Happen if the table is empty
+                    let n = createVNode("a", {
+                        role: "button",
+                        href: "/cgi-bin/koha/erm/eholdings/resources/" + row.resource_id,
+                        onClick: (e) => {
+                            e.preventDefault()
+                            show_resource(row.resource_id)
+                        }
+                    },
+                        `${row.package.name}`
+                    )
+                    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)
+                })
+            },
+        }))
+
+        $('#package_list_result').css('display', 'block')
+        $("#package_list").DataTable().columns.adjust().draw()
+    },
+    beforeUnmount() {
+        $('#package_list')
+            .DataTable()
+            .destroy(true)
+    },
+    props: {
+        resources: Array,
+    },
+    name: 'EHoldingsTitlePackagesList',
+}
+</script>
+
+<style scoped>
+#package_list_result {
+    width: 50%;
+    padding-left: 26rem;
+}
+#package_list {
+    display: table;
+}
+#filters fieldset {
+    margin: 0;
+}
+</style>
\ No newline at end of file
index 7de8ea1..17d4a8f 100644 (file)
                         </li>
 
                         <li>
-                            <label for="title_vendor_id"
-                                >{{ $t("Vendor") }}:</label
-                            >
-                            <select
-                                id="title_vendor_id"
-                                v-model="title.vendor_id"
-                            >
-                                <option value=""></option>
-                                <option
-                                    v-for="vendor in vendors"
-                                    :key="vendor.vendor_id"
-                                    :value="vendor.id"
-                                    :selected="
-                                        vendor.id == title.vendor_id
-                                            ? true
-                                            : false
-                                    "
-                                >
-                                    {{ vendor.name }}
-                                </option>
-                            </select>
-                        </li>
-
-                        <li>
                             <label for="title_print_identifier"
                                 >{{ $t("Print-format identifier") }}:</label
                             >
                             <label for="title_publication_type"
                                 >{{ $t("Publication type") }}:</label
                             >
-                            <input
+                            <select
                                 id="title_publication_type"
                                 v-model="title.publication_type"
-                                :placeholder="$t('Publication type')"
-                            />
+                            >
+                                <option value=""></option>
+                                <option
+                                    v-for="type in av_title_publication_types"
+                                    :key="type.authorised_values"
+                                    :value="type.authorised_value"
+                                    :selected="
+                                        type.authorised_value ==
+                                        title.publication_type
+                                            ? true
+                                            : false
+                                    "
+                                >
+                                    {{ type.lib }}
+                                </option>
+                            </select>
                         </li>
 
                         <li>
 
 <script>
 import { useVendorStore } from "../../stores/vendors"
+import { useAVStore } from "../../stores/authorised_values"
 import EHoldingsTitlesFormAddResources from "./EHoldingsTitlesFormAddResources.vue"
 import { setMessage, setError } from "../../messages"
 import { fetchTitle } from '../../fetch'
@@ -414,15 +405,20 @@ export default {
         const vendorStore = useVendorStore()
         const { vendors } = storeToRefs(vendorStore)
 
+        const AVStore = useAVStore()
+        const { av_title_publication_types } = storeToRefs(AVStore)
+        const { get_lib_from_av } = AVStore
+
         return {
             vendors,
+            av_title_publication_types,
+            get_lib_from_av,
         }
     },
     data() {
         return {
             title: {
                 title_id: null,
-                vendor_id: null,
                 publication_title: '',
                 external_id: '',
                 print_identifier: '',
index 59a041f..4620228 100644 (file)
                     <span class="required">{{ $t("Required") }}</span>
                 </li>
                 <li>
+                    <label for="title_vendor_id">{{ $t("Vendor") }}:</label>
+                    <select id="title_vendor_id" v-model="resource.vendor_id">
+                        <option value=""></option>
+                        <option
+                            v-for="vendor in vendors"
+                            :key="vendor.vendor_id"
+                            :value="vendor.id"
+                            :selected="
+                                vendor.id == resource.vendor_id ? true : false
+                            "
+                        >
+                            {{ vendor.name }}
+                        </option>
+                    </select>
+                </li>
+
+                <li>
                     <label :for="`started_on_${counter}`"
                         >{{ $t("Start date") }}:
                     </label>
 
 <script>
 import flatPickr from 'vue-flatpickr-component'
+import { useVendorStore } from "../../stores/vendors"
+import { storeToRefs } from "pinia"
 import { fetchPackages } from "../../fetch"
 
 export default {
+    setup() {
+        const vendorStore = useVendorStore() // FIXME We only need that for 'manual'
+        const { vendors } = storeToRefs(vendorStore)
+        return { vendors }
+    },
     data() {
         return {
             packages: [],
@@ -104,6 +128,7 @@ export default {
         addPackage() {
             this.resources.push({
                 package_id: null,
+                vendor_id: null,
                 started_on: null,
                 ended_on: null,
                 proxy: '',
index 5ff6afd..dffb5ad 100644 (file)
@@ -1,10 +1,58 @@
 <template>
-    <div v-if="!this.initialized">{{ $t("Loading") }}</div>
-    <div v-else-if="this.titles" id="titles_list">
-        <Toolbar />
-        <table v-if="this.titles.length" id="title_list"></table>
-        <div v-else-if="this.initialized" class="dialog message">
-            {{ $t("There are no titles defined") }}
+    <div v-if="erm_provider == 'manual'">
+        <div v-if="!this.initialized">{{ $t("Loading") }}</div>
+        <div v-else-if="this.titles" id="titles_list">
+            <Toolbar />
+            <table v-if="this.titles.length" id="title_list"></table>
+            <div v-else-if="this.initialized" class="dialog message">
+                {{ $t("There are no titles defined") }}
+            </div>
+        </div>
+        <div id="title_list_result">
+            <table id="title_list"></table>
+        </div>
+    </div>
+    <div v-else>
+        <fieldset>
+            {{ $t("Publication title") }}:
+            <input
+                type="text"
+                id="publication_title_filter"
+                v-model="filters.publication_title"
+                @keyup.enter="filter_table"
+            />
+            {{ $t("Publication type") }}:
+            <select
+                id="publication_type_filter"
+                v-model="filters.publication_type"
+            >
+                <option value="">{{ $t("All") }}</option>
+                <option
+                    v-for="type in av_title_publication_types"
+                    :key="type.authorised_values"
+                    :value="type.authorised_value"
+                >
+                    {{ type.lib }}
+                </option>
+            </select>
+            {{ $t("Selection status") }}:
+            <select id="selection_type_filter" v-model="filters.selection_type">
+                <option value="0">{{ $t("All") }}</option>
+                <option value="1">{{ $t("Selected") }}</option>
+                <option value="2">{{ $t("Not selected") }}</option>
+            </select>
+            <input
+                @click="filter_table"
+                id="filter_table"
+                type="button"
+                :value="$t('Submit')"
+            />
+            <span v-if="cannot_search">{{
+                $t("Please enter a search term")
+            }}</span>
+        </fieldset>
+        <div id="title_list_result" style="display: none">
+            <table id="title_list"></table>
         </div>
     </div>
 </template>
@@ -13,6 +61,7 @@
 import Toolbar from "./EHoldingsTitlesToolbar.vue"
 import { createVNode, render } from 'vue'
 import { useVendorStore } from "../../stores/vendors"
+import { useAVStore } from "../../stores/authorised_values"
 import { storeToRefs } from "pinia"
 import { fetchTitles } from "../../fetch"
 
@@ -21,14 +70,26 @@ export default {
         const vendorStore = useVendorStore()
         const { vendors } = storeToRefs(vendorStore)
 
+        const AVStore = useAVStore()
+        const { av_title_publication_types } = storeToRefs(AVStore)
+        const { get_lib_from_av } = AVStore
+
         return {
             vendors,
+            av_title_publication_types,
+            get_lib_from_av,
         }
     },
     data: function () {
         return {
             titles: [],
             initialized: false,
+            filters: {
+                publication_title: this.$route.query.q || "",
+                publication_type: "",
+                selection_type: "",
+            },
+            cannot_search: false,
         }
     },
     beforeRouteEnter(to, from, next) {
@@ -36,10 +97,13 @@ export default {
             vm.getTitles()
         })
     },
+    inject: ['erm_provider'],
     methods: {
         async getTitles() {
-            const titles = await fetchTitles()
-            this.titles = titles
+            if (erm_provider == 'manual') {
+                const titles = await fetchTitles()
+                this.titles = titles
+            }
             this.initialized = true
         },
         show_title: function (title_id) {
@@ -51,12 +115,22 @@ export default {
         delete_title: function (title_id) {
             this.$router.push("/cgi-bin/koha/erm/eholdings/titles/delete/" + title_id)
         },
+        filter_table: function () {
+            if (this.filters.publication_title.length) {
+                this.cannot_search = false
+                $("#title_list_result").show()
+                $("#title_list").DataTable().draw()
+            } else {
+                this.cannot_search = true
+            }
+        }
     },
     updated() {
-        let show_title= this.show_title
-        let edit_title= this.edit_title
-        let delete_title= this.delete_title
-        let default_search = this.$route.query.q
+        let show_title = this.show_title
+        let edit_title = this.edit_title
+        let delete_title = this.delete_title
+        let get_lib_from_av = this.get_lib_from_av
+        let filters = this.filters
 
         window['vendors'] = this.vendors.map(e => {
             e['_id'] = e['id']
@@ -67,38 +141,54 @@ export default {
             map[e.id] = e
             return map
         }, {})
+        window['av_title_publication_types'] = this.av_title_publication_types.map(e => {
+            e['_id'] = e['authorised_value']
+            e['_str'] = e['lib']
+            return e
+        })
 
+        let additional_filters = {}
+        if (erm_provider != 'manual') {
+            additional_filters = {
+                publication_title: function () {
+                    return filters.publication_title || ""
+                },
+                publication_type: function () {
+                    return filters.content_type_search || ""
+                },
+                selection_type: function () {
+                    return filters.selection_type || ""
+                },
+            }
+        }
         $('#title_list').kohaTable({
             "ajax": {
                 "url": "/api/v1/erm/eholdings/titles",
             },
-            "order": [[0, "asc"]],
-            "search": { search: default_search },
-            "columnDefs": [{
-                "targets": [1],
-                "render": function (data, type, row, meta) {
-                    if (type == 'display') {
-                        return escape_str(data)
-                    }
-                    return data
-                }
-            }],
+            embed: ["resources.package"],
+            ...(erm_provider == 'manual' ? { order: [[0, "asc"]] } : {}),
+            ...(erm_provider != 'manual' ? { ordering: false } : {}),
+            ...(erm_provider == 'manual' ? { search: { search: filters.publication_title } } : {}),
+            ...(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": __("Title"),
-                    "data": "me.title_id:me.publication_title",
-                    "searchable": true,
-                    "orderable": true,
+                    "data": "me.publication_title",
+                    "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) : ""
                     }
@@ -106,14 +196,17 @@ export default {
                 {
                     "title": __("Publication type"),
                     "data": "publication_type",
-                    "searchable": true,
-                    "orderable": true,
+                    "searchable": (erm_provider == 'manual'),
+                    "orderable": (erm_provider == 'manul'),
+                    "render": function (data, type, row, meta) {
+                        return escape_str(get_lib_from_av("av_title_publication_types", row.publication_type))
+                    }
                 },
                 {
                     "title": __("Identifier"),
                     "data": "print_identifier:online_identifier",
-                    "searchable": true,
-                    "orderable": true,
+                    "searchable": (erm_provider == 'manual'),
+                    "orderable": (erm_provider == 'manul'),
                     "render": function (data, type, row, meta) {
                         let print_identifier = row.print_identifier
                         let online_identifier = row.online_identifier
@@ -121,7 +214,7 @@ export default {
                             (online_identifier ? escape_str(_("ISBN (Online): %s").format(online_identifier)) : "")
                     }
                 },
-                {
+                erm_provider == 'manual' ? {
                     "title": __("Actions"),
                     "data": function (row, type, val, meta) {
                         return '<div class="actions"></div>'
@@ -129,8 +222,8 @@ export default {
                     "className": "actions noExport",
                     "searchable": false,
                     "orderable": false
-                }
-            ],
+                } : null,
+            ].filter(Boolean),
             drawCallback: function (settings) {
 
                 var api = new $.fn.dataTable.Api(settings)
@@ -160,20 +253,33 @@ export default {
                     if (!row) return // Happen if the table is empty
                     let n = createVNode("a", {
                         role: "button",
-                        onClick: () => {
+                        onClick: (e) => {
+                            e.preventDefault()
                             show_title(row.title_id)
                         }
                     },
                         `${row.publication_title} (#${row.title_id})`
                     )
+                    // TODO? We don't have is_selected at title level
+                    //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')
+            ...(erm_provider == 'manual' ? {
+                preDrawCallback: function (settings) {
+                    var table_id = settings.nTable.id
+                    $("#" + table_id).find("thead th").eq(1).attr('data-filter', 'vendors')
+                }
+            } : {}),
+        }, eholdings_titles_table_settings, erm_provider == 'manual' ? 1 : 0, additional_filters)
+
+        if (erm_provider != 'manual') {
+            if (filters.publication_title.length) {
+                this.filter_table()
             }
-        }, eholdings_titles_table_settings, 1)
+        }
     },
     beforeUnmount() {
         $('#title_list')
@@ -183,4 +289,4 @@ export default {
     components: { Toolbar },
     name: "EHoldingsTitlesList",
 }
-</script>
+</script>
\ No newline at end of file
index 9ee2cca..24fadec 100644 (file)
@@ -1,9 +1,9 @@
 <template>
     <div v-if="!initialized">{{ $t("Loading") }}</div>
-    <div v-else id="eholdings_title_show">
+    <div v-else-if="title" id="eholdings_title_show">
         <h2>
             {{ $t("Title .id", { id: title.title_id }) }}
-            <span class="action_links">
+            <span v-if="erm_provider == 'manual'" class="action_links">
                 <router-link
                     :to="`/cgi-bin/koha/erm/eholdings/titles/edit/${title.title_id}`"
                     :title="$t('Edit')"
                             </a>
                         </span>
                     </li>
-                    <li v-if="title.external_id">
-                        <label>{{ $t("External ID") }}:</label>
-                        <span>
-                            {{ title.external_id }}
-                        </span>
-                    </li>
-                    <li>
-                        <label>{{ $t("Vendor") }}:</label>
-                        <span v-if="title.vendor_id">
-                            {{
-                                vendors.find((e) => e.id == title.vendor_id)
-                                    .name
-                            }}
-                        </span>
-                    </li>
-                    <li>
+                    <li v-if="title.print_identifier">
                         <label>{{ $t("Print-format identifier") }}:</label>
                         <span>
                             {{ title.print_identifier }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.online_identifier">
                         <label>{{ $t("Online-format identifier") }}:</label>
                         <span>
                             {{ title.online_identifier }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.date_first_issue_online">
                         <label
                             >{{
                                 $t(
@@ -77,7 +62,7 @@
                             {{ title.date_first_issue_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.num_first_vol_online">
                         <label
                             >{{
                                 $t("Number of first volume available online")
@@ -87,7 +72,7 @@
                             {{ title.num_first_vol_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.num_first_issue_online">
                         <label
                             >{{
                                 $t("Number of first issue available online")
@@ -97,7 +82,7 @@
                             {{ title.num_first_issue_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.date_last_issue_online">
                         <label
                             >{{
                                 $t("Date of last issue available online")
                             {{ title.date_last_issue_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.num_last_vol_online">
                         <label
                             >{{
                                 $t("Number of last volume available online")
                             {{ title.num_last_vol_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.num_last_issue_online">
                         <label
                             >{{
                                 $t("Number of last issue available online")
                             {{ title.num_last_issue_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.title_url">
                         <label>{{ $t("Title-level URL") }}:</label>
                         <span>
                             {{ title.title_url }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.first_author">
                         <label>{{ $t("First author") }}:</label>
                         <span>
                             {{ title.first_author }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.embargo_info">
                         <label>{{ $t("Embargo information") }}:</label>
                         <span>
                             {{ title.embargo_info }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.coverage_depth">
                         <label>{{ $t("Coverage depth") }}:</label>
                         <span>
                             {{ title.coverage_depth }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.notes">
                         <label>{{ $t("Notes") }}:</label>
                         <span>
                             {{ title.notes }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.publisher_name">
                         <label>{{ $t("Publisher name") }}:</label>
                         <span>
                             {{ title.publisher_name }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.publication_type">
                         <label>{{ $t("Publication type") }}:</label>
-                        <span>
-                            {{ title.publication_type }}
+                        <span
+                            >{{
+                                get_lib_from_av(
+                                    "av_title_publication_types",
+                                    title.publication_type
+                                )
+                            }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.date_monograph_published_print">
                         <label
                             >{{
                                 $t(
                             {{ title.date_monograph_published_print }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.date_monograph_published_online">
                         <label
                             >{{
                                 $t(
                             {{ title.date_monograph_published_online }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.monograph_volume">
                         <label
                             >{{ $t("Number of volume for monograph") }}:</label
                         >
                             {{ title.monograph_volume }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.monograph_edition">
                         <label>{{ $t("Edition of the monograph") }}:</label>
                         <span>
                             {{ title.monograph_edition }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.first_editor">
                         <label>{{ $t("First editor") }}:</label>
                         <span>
                             {{ title.first_editor }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.parent_publication_title_id">
                         <label
                             >{{
                                 $t(
                             {{ title.parent_publication_title_id }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.preceeding_publication_title_id">
                         <label
                             >{{
                                 $t(
                             {{ title.preceeding_publication_title_id }}
                         </span>
                     </li>
-                    <li>
+                    <li v-if="title.access_type">
                         <label>{{ $t("Acces type") }}:</label>
                         <span>
                             {{ title.access_type }}
                         </span>
                     </li>
-
-                    <li v-if="title.resources.length">
-                        <label>{{ $t("Packages") }}</label>
-                        <table>
-                            <thead>
-                                <tr>
-                                    <th>Name</th>
-                                </tr>
-                            </thead>
-                            <tbody>
-                                <tr
-                                    v-for="(r, counter) in title.resources"
-                                    v-bind:key="counter"
-                                >
-                                    <td>
-                                        <router-link
-                                            :to="`/cgi-bin/koha/erm/eholdings/resources/${r.resource_id}`"
-                                            :title="$t('Show resource')"
-                                        >
-                                            {{ r.package.name }}
-                                        </router-link>
-                                    </td>
-                                </tr>
-                            </tbody>
-                        </table>
+                    <li>
+                        <label>Packages ({{ title.resources.length }})</label>
+                        <div v-if="title.resources.length">
+                            <EHoldingsTitlePackagesList
+                                :resources="title.resources"
+                            />
+                        </div>
                     </li>
                 </ol>
             </fieldset>
 </template>
 
 <script>
+import EHoldingsTitlePackagesList from "./EHoldingsTitlePackagesList.vue"
 import { fetchTitle } from "../../fetch"
-import { useVendorStore } from "../../stores/vendors"
-import { storeToRefs } from "pinia"
+import { useAVStore } from "../../stores/authorised_values"
 export default {
     setup() {
-        const vendorStore = useVendorStore()
-        const { vendors } = storeToRefs(vendorStore)
+        const AVStore = useAVStore()
+        const { get_lib_from_av } = AVStore
 
         return {
-            vendors,
+            get_lib_from_av,
         }
     },
     data() {
         return {
             title: {
                 title_id: null,
-                vendor_id: null,
                 publication_title: '',
                 external_id: '',
                 print_identifier: '',
@@ -331,7 +302,7 @@ export default {
             initialized: false,
         }
     },
-
+    inject: ['erm_provider'],
     beforeRouteEnter(to, from, next) {
         next(vm => {
             vm.getTitle(to.params.title_id)
@@ -347,6 +318,9 @@ export default {
             this.initialized = true
         },
     },
+    components: {
+        EHoldingsTitlePackagesList,
+    },
     name: "EHoldingsTitlesShow",
 }
 </script>
index 8d38890..149524b 100644 (file)
@@ -93,11 +93,15 @@ export default {
         AVStore.av_agreement_license_location = agreement_license_location
         AVStore.av_package_types = package_types
         AVStore.av_package_content_types = package_content_types
+        AVStore.av_title_publication_types = title_publication_types
 
         return {
             vendorStore,
         }
     },
+    provide: {
+        erm_provider
+    },
     data() {
         return {
             component: "agreement",
@@ -117,4 +121,4 @@ export default {
 a.router-link-active {
     font-weight: 700;
 }
-</style>
\ No newline at end of file
+</style>
index 616c4db..4ad4dc6 100644 (file)
@@ -110,7 +110,8 @@ export const fetchPackage = async function (package_id) {
     let erm_package;
     await fetch(apiUrl, {
         headers: {
-            "x-koha-embed": "package_agreements,package_agreements.agreement,resources,resources.title,vendor",
+            "x-koha-embed":
+                "package_agreements,package_agreements.agreement,resources+count,vendor",
         },
     })
         .then(checkError)
@@ -128,7 +129,11 @@ export const fetchPackage = async function (package_id) {
 export const fetchPackages = async function () {
     const apiUrl = "/api/v1/erm/eholdings/packages";
     let packages;
-    await fetch(apiUrl)
+    await fetch(apiUrl, {
+        headers: {
+            "x-koha-embed": "resources+count,vendor.name",
+        },
+    })
         .then(checkError)
         .then(
             (result) => {
@@ -184,7 +189,7 @@ export const fetchResource = async function (resource_id) {
     let resource;
     await fetch(apiUrl, {
         headers: {
-            "x-koha-embed": "title,package",
+            "x-koha-embed": "title,package,vendor",
         },
     })
         .then(checkError)
@@ -199,7 +204,7 @@ export const fetchResource = async function (resource_id) {
     return resource;
 };
 
-export const fetchresources = async function () {
+export const fetchResources = async function () {
     const apiUrl = "/api/v1/erm/eholdings/resources";
     let resources;
     await fetch(apiUrl)
@@ -215,6 +220,27 @@ export const fetchresources = async function () {
     return resources;
 };
 
+export const fetchPackageResources = async function (package_id) {
+    const apiUrl =
+        "/api/v1/erm/eholdings/packages/" + package_id + "/resources";
+    let resources;
+    await fetch(apiUrl, {
+        headers: {
+            "x-koha-embed": "title.publication_title",
+        },
+    })
+        .then(checkError)
+        .then(
+            (result) => {
+                resources = result;
+            },
+            (error) => {
+                setError(error);
+            }
+        );
+    return resources;
+};
+
 function checkError(response) {
     if (response.status >= 200 && response.status <= 299) {
         return response.json();
index d6e6693..ca10ac3 100644 (file)
@@ -35,6 +35,7 @@ export const useAVStore = defineStore("authorised_values", {
         ],
         av_package_types: [],
         av_package_content_types: [],
+        av_title_publication_types: [],
     }),
     actions: {
         get_lib_from_av(arr_name, av) {
@@ -47,7 +48,7 @@ export const useAVStore = defineStore("authorised_values", {
                 return;
             }
             let o = this[arr_name].find((e) => e.authorised_value == av);
-            return o ? o.lib : "";
+            return o ? o.lib : av;
         },
     },
 });
index f21d957..9e66ce8 100644 (file)
@@ -12,12 +12,12 @@ export const useMainStore = defineStore("main", {
         setMessage(message) {
             this.error = null;
             this.message = message;
-            this.displayed_already = false;
+            this.displayed_already = false; /* Will be displayed on the next view */
         },
         setError(error) {
             this.error = error;
             this.message = null;
-            this.displayed_already = false;
+            this.displayed_already = true; /* Is displayed on the current view */
         },
         removeMessages() {
             if (this.displayed_already) {