use HTTP::Request;
use LWP::UserAgent;
-use JSON qw( from_json decode_json );
+use JSON qw( from_json decode_json encode_json );
use List::Util qw( first );
use Koha::Exceptions;
}
sub request {
- my ( $self, $method, $url, $params ) = @_;
+ my ( $self, $method, $url, $params, $payload ) = @_;
$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);
+ my $request = HTTP::Request->new(
+ $method => $base_url . $url,
+ undef, ( $payload ? encode_json($payload) : undef )
+ );
$request->header( 'x-api-key' => $config->{api_key} );
my $ua = LWP::UserAgent->new;
my $response = $ua->simple_request($request);
die sprintf "ERROR requesting EBSCO API\n%s\ncode %s: %s\n", $url, $response->code,
$message;
}
+ } elsif ( $response->code == 204 ) { # No content
+ return
}
+
return decode_json( $response->decoded_content );
}
}
}
+=head3 edit
+
+Controller function that handles editing a single Koha::ERM::EHoldings::Resource object
+
+=cut
+
+sub edit {
+ my $c = shift->openapi->valid_input or return;
+
+ my $provider = $c->validation->param('provider');
+ if ( $provider eq 'ebsco' ) {
+ return Koha::REST::V1::ERM::EHoldings::Resources::EBSCO::edit($c);
+ } else {
+ die "invalid action";
+ }
+}
+
1;
};
}
+=head3 edit
+
+=cut
+
+sub edit {
+ my $c = shift->openapi->valid_input or return;
+
+ return try {
+ my $body = $c->validation->param('body');
+ my $is_selected = $body->{is_selected};
+ my ( $vendor_id, $package_id, $resource_id ) = split '-',
+ $c->validation->param('resource_id');
+
+ my $ebsco = Koha::ERM::Providers::EBSCO->new;
+ my $t = try {
+ return $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" }
+ );
+ }
+
+ $ebsco->request(
+ PUT => '/vendors/'
+ . $vendor_id
+ . '/packages/'
+ . $package_id
+ . '/titles/'
+ . $resource_id,
+ undef,
+ {
+ isSelected => $is_selected,
+ titleName => $t->{titleName},
+ pubType => $t->{pubType}
+ }
+ );
+
+ return $c->render(
+ status => 200,
+ openapi => { is_selected => $is_selected } # We don't want to refetch the resource to make sure it has been updated
+ );
+ }
+ catch {
+ $c->unhandled_exception($_);
+ };
+
+}
+
1;
x-koha-embed:
- resources
- resources.package
+ patch:
+ x-mojo-to: ERM::EHoldings::Resources#edit
+ operationId: editErmEHoldingsResources
+ tags:
+ - eholdings
+ summary: Edit a resource
+ produces:
+ - application/json
+ parameters:
+ - description: Provider name
+ in: path
+ name: provider
+ required: true
+ type: string
+ - description: A JSON object containing the fields to edit
+ in: body
+ name: body
+ required: true
+ schema:
+ type: object
+ properties:
+ is_selected:
+ description: Add or remove this resource from remote holdings
+ type: boolean
+ additionalProperties: false
+ - $ref: "../swagger.yaml#/parameters/eholdings_resource_id_pp"
+ responses:
+ 200:
+ description: What has been modified
+ schema:
+ type: object
+ properties:
+ is_selected:
+ description: Add or remove this resource from remote holdings
+ type: boolean
+ additionalProperties: false
+ 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"
+ 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
<div v-else-if="resource" id="eholdings_resources_show">
<h2>
{{ $t("Resource .id", { id: resource.resource_id }) }}
+ <span v-if="!updating_is_selected">
+ <a
+ v-if="!resource.is_selected"
+ class="btn btn-default btn-xs"
+ role="button"
+ @click="add_to_holdings"
+ ><font-awesome-icon icon="plus" /> Add to holdings</a
+ >
+ <a
+ v-else
+ class="btn btn-default btn-xs"
+ role="button"
+ id="remove-from-holdings"
+ @click="remove_from_holdings"
+ ><font-awesome-icon icon="minus" /> Remove from holdings</a
+ > </span
+ ><span v-else><font-awesome-icon icon="spinner" /></span>
</h2>
<div>
<fieldset class="rows">
import { fetchEBSCOResource } from "../../fetch"
import { useVendorStore } from "../../stores/vendors"
import { storeToRefs } from "pinia"
+import { checkError } from '../../fetch.js'
+
export default {
setup() {
const format_date = $date
package: {},
},
initialized: false,
+ updating_is_selected: false,
}
},
const resource = await fetchEBSCOResource(resource_id)
this.resource = resource
this.initialized = true
+ this.updating_is_selected = false
+ },
+ edit_selected(is_selected) {
+ this.updating_is_selected = true
+ fetch('/api/v1/erm/eholdings/ebsco/resources/' + this.resource.resource_id, {
+ method: "PATCH",
+ body: JSON.stringify({ is_selected }),
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ })
+ .then(checkError)
+ .then(
+ (result) => {
+ // Refresh the page. We should not need that actually.
+ this.getResource(this.resource.resource_id)
+ },
+ ).catch(
+ (error) => {
+ setError(error)
+ }
+ )
+ },
+ add_to_holdings() {
+ this.edit_selected(true)
+ },
+ remove_from_holdings() {
+ this.edit_selected(false)
},
},
name: "EHoldingsEBSCOResourcesShow",
import { createPinia } from "pinia";
import { library } from "@fortawesome/fontawesome-svg-core";
-import { faPlus, faPencil, faTrash } from "@fortawesome/free-solid-svg-icons";
+import {
+ faPlus,
+ faMinus,
+ faPencil,
+ faTrash,
+ faSpinner,
+} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import vSelect from "vue-select";
-library.add(faPlus, faPencil, faTrash);
+library.add(faPlus, faMinus, faPencil, faTrash, faSpinner);
import App from "./components/ERM/ERMMain.vue";