From 2f5e8bcab8fc21748d0239964a314c08cb875543 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Tue, 28 Feb 2017 09:00:07 -0300 Subject: [PATCH] Bug 18120: REST api | Add a 'vendors' endpoint This patch introduces an /acquisitions/vendors endpoint. To test: - Apply the patch - Run: $ sudo koha-shell kohadev k$ prove t/db_dependent/api/v1/acquisitions_vendors.t => SUCCESS: Tests pass - Sign off :-D Sponsored-by: ByWater Solutions --- Koha/REST/V1/Acquisitions/Vendors.pm | 173 ++++++++++++++++++++ Koha/Schema/Result/Aqbookseller.pm | 7 + api/v1/swagger/definitions.json | 3 + api/v1/swagger/definitions/vendor.json | 149 +++++++++++++++++ api/v1/swagger/parameters.json | 3 + api/v1/swagger/parameters/vendor.json | 9 + api/v1/swagger/paths.json | 6 + api/v1/swagger/paths/acquisitions_vendors.json | 218 +++++++++++++++++++++++++ api/v1/swagger/x-primitives.json | 5 + 9 files changed, 573 insertions(+) create mode 100644 Koha/REST/V1/Acquisitions/Vendors.pm create mode 100644 api/v1/swagger/definitions/vendor.json create mode 100644 api/v1/swagger/parameters/vendor.json create mode 100644 api/v1/swagger/paths/acquisitions_vendors.json diff --git a/Koha/REST/V1/Acquisitions/Vendors.pm b/Koha/REST/V1/Acquisitions/Vendors.pm new file mode 100644 index 0000000000..18b4fd0138 --- /dev/null +++ b/Koha/REST/V1/Acquisitions/Vendors.pm @@ -0,0 +1,173 @@ +package Koha::REST::V1::Acquisitions::Vendors; + +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::Acquisition::Bookseller; +use Koha::Acquisition::Booksellers; + +use Try::Tiny; + +sub list { + my ( $c, $args, $cb ) = @_; + + my @vendors; + + return try { + @vendors = map { _to_api($_) } Koha::Acquisition::Booksellers->search(); + return $c->$cb( \@vendors, 200 ); + } + catch { + if ( $_->isa('DBIx::Class::Exception') ) { + return $c->$cb( { error => $_->{msg} }, 500 ); + } + else { + return $c->$cb( { error => "Something went wrong, check the logs." }, 500 ); + } + }; +} + +sub get { + my ( $c, $args, $cb ) = @_; + + my $vendor = Koha::Acquisition::Booksellers->find( $args->{vendor_id} ); + unless ($vendor) { + return $c->$cb( { error => "Vendor not found" }, 404 ); + } + + return $c->$cb( _to_api($vendor), 200 ); +} + +sub add { + my ( $c, $args, $cb ) = @_; + + my $vendor = Koha::Acquisition::Bookseller->new( _to_model( $args->{body} ) ); + + return try { + $vendor->store; + return $c->$cb( _to_api($vendor), 200 ); + } + catch { + if ( $_->isa('DBIx::Class::Exception') ) { + return $c->$cb( { error => $_->msg }, 500 ); + } + else { + return $c->$cb( { error => "Something went wrong, check the logs." }, 500 ); + } + }; +} + +sub update { + my ( $c, $args, $cb ) = @_; + + my $vendor; + + return try { + $vendor = Koha::Acquisition::Booksellers->find( $args->{vendor_id} ); + $vendor->set( _to_model( $args->{body} ) ); + $vendor->store(); + return $c->$cb( _to_api($vendor), 200 ); + } + catch { + if ( not defined $vendor ) { + return $c->$cb( { error => "Object not found" }, 404 ); + } + elsif ( $_->isa('Koha::Exceptions::Object') ) { + return $c->$cb( { error => $_->message }, 500 ); + } + else { + return $c->$cb( { error => "Something went wrong, check the logs." }, 500 ); + } + }; + +} + +sub delete { + my ( $c, $args, $cb ) = @_; + + my $vendor; + + return try { + $vendor = Koha::Acquisition::Booksellers->find( $args->{vendor_id} ); + $vendor->delete; + return $c->$cb( q{}, 200 ); + } + catch { + if ( not defined $vendor ) { + return $c->$cb( { error => "Object not found" }, 404 ); + } + elsif ( $_->isa('DBIx::Class::Exception') ) { + return $c->$cb( { error => $_->msg }, 500 ); + } + else { + return $c->$cb( { error => "Something went wrong, check the logs." }, 500 ); + } + }; + +} + +sub _to_api { + + my $vendor_param = shift; + + my $vendor = $vendor_param->TO_JSON; + + # Delete unused fields + delete $vendor->{booksellerfax}; + delete $vendor->{bookselleremail}; + delete $vendor->{booksellerurl}; + delete $vendor->{currency}; + delete $vendor->{othersupplier}; + + # Rename changed fields + $vendor->{list_currency} = $vendor->{listprice}; + delete $vendor->{listprice}; + $vendor->{invoice_currency} = $vendor->{invoiceprice}; + delete $vendor->{invoiceprice}; + $vendor->{gst} = $vendor->{gstreg}; + delete $vendor->{gstreg}; + $vendor->{list_includes_gst} = $vendor->{listincgst}; + delete $vendor->{listincgst}; + $vendor->{invoice_includes_gst} = $vendor->{invoiceincgst}; + delete $vendor->{invoiceincgst}; + + return $vendor; +} + +sub _to_model { + my $vendor_param = shift; + + my $vendor = $vendor_param; + + # Rename back + $vendor->{listprice} = $vendor->{list_currency}; + delete $vendor->{list_currency}; + $vendor->{invoiceprice} = $vendor->{invoice_currency}; + delete $vendor->{invoice_currency}; + $vendor->{gstreg} = $vendor->{gst}; + delete $vendor->{gst}; + $vendor->{listincgst} = $vendor->{list_includes_gst}; + delete $vendor->{list_includes_gst}; + $vendor->{invoiceincgst} = $vendor->{invoice_includes_gst}; + delete $vendor->{invoice_includes_gst}; + + return $vendor; +} + +1; diff --git a/Koha/Schema/Result/Aqbookseller.pm b/Koha/Schema/Result/Aqbookseller.pm index e9c2656940..e59b7057e8 100644 --- a/Koha/Schema/Result/Aqbookseller.pm +++ b/Koha/Schema/Result/Aqbookseller.pm @@ -385,6 +385,13 @@ __PACKAGE__->has_many( # Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-09-09 13:43:30 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:b3aUNZsdvNzEuKScGD7ZPQ +__PACKAGE__->add_columns( + '+active' => { is_boolean => 1 }, + '+gstreg' => { is_boolean => 1 }, + '+listincgst' => { is_boolean => 1 }, + '+invoiceincgst' => { is_boolean => 1 }, +); + # You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/api/v1/swagger/definitions.json b/api/v1/swagger/definitions.json index d27167b924..c49f0e9f57 100644 --- a/api/v1/swagger/definitions.json +++ b/api/v1/swagger/definitions.json @@ -13,5 +13,8 @@ }, "error": { "$ref": "definitions/error.json" + }, + "vendor": { + "$ref": "definitions/vendor.json" } } diff --git a/api/v1/swagger/definitions/vendor.json b/api/v1/swagger/definitions/vendor.json new file mode 100644 index 0000000000..f24bdde414 --- /dev/null +++ b/api/v1/swagger/definitions/vendor.json @@ -0,0 +1,149 @@ +{ + "type": "object", + "properties": { + "id": { + "$ref": "../x-primitives.json#/vendor_id" + }, + "name": { + "type": [ + "string" + ], + "description": "Vendor name" + }, + "address1": { + "type": [ + "string", + "null" + ], + "description": "Vendor physical address (line 1)" + }, + "address2": { + "type": [ + "string", + "null" + ], + "description": "Vendor physical address (line 2)" + }, + "address3": { + "type": [ + "string", + "null" + ], + "description": "Vendor physical address (line 3)" + }, + "address4": { + "type": [ + "string", + "null" + ], + "description": "Vendor physical address (line 4)" + }, + "phone": { + "type": [ + "string", + "null" + ], + "description": "Vendor phone number" + }, + "fax": { + "type": [ + "string", + "null" + ], + "description": "Vendor fax number" + }, + "accountnumber": { + "type": [ + "string", + "null" + ], + "description": "Vendor account number" + }, + "notes": { + "type": [ + "string", + "null" + ], + "description": "Vendor notes" + }, + "postal": { + "type": [ + "string", + "null" + ], + "description": "Vendor postal address" + }, + "url": { + "type": [ + "string", + "null" + ], + "description": "Vendor web address" + }, + "active": { + "type": [ + "boolean", + "null" + ], + "description": "Is this vendor active" + }, + "list_currency": { + "type": [ + "string", + "null" + ], + "description": "List prices currency" + }, + "invoice_currency": { + "type": [ + "string", + "null" + ], + "description": "Invoice prices currency" + }, + "gst": { + "type": [ + "boolean", + "null" + ], + "description": "Is the library taxed when buying to this vendor" + }, + "list_includes_gst": { + "type": [ + "boolean", + "null" + ], + "description": "List prices include taxes" + }, + "invoice_includes_gst": { + "type": [ + "boolean", + "null" + ], + "description": "Invoice prices include taxes" + }, + "tax_rate": { + "type": [ + "number", + "null" + ], + "description": "Tax rate" + }, + "discount": { + "type": [ + "number", + "null" + ], + "description": "Discount offered on all items ordered from this vendor" + }, + "deliverytime": { + "type": [ + "integer", + "null" + ], + "description": "Vendor expected delivery time (in days)" + } + }, + "additionalProperties": false, + "required": ["name"] +} diff --git a/api/v1/swagger/parameters.json b/api/v1/swagger/parameters.json index eeb156a7b8..b8835d22d1 100644 --- a/api/v1/swagger/parameters.json +++ b/api/v1/swagger/parameters.json @@ -10,5 +10,8 @@ }, "holdIdPathParam": { "$ref": "parameters/hold.json#/holdIdPathParam" + }, + "vendoridPathParam": { + "$ref": "parameters/vendor.json#/vendoridPathParam" } } diff --git a/api/v1/swagger/parameters/vendor.json b/api/v1/swagger/parameters/vendor.json new file mode 100644 index 0000000000..64dbea0f53 --- /dev/null +++ b/api/v1/swagger/parameters/vendor.json @@ -0,0 +1,9 @@ +{ + "vendoridPathParam": { + "name": "vendor_id", + "in": "path", + "description": "Vendor id", + "required": true, + "type": "integer" + } +} diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json index b1fcf40f5e..147e985386 100644 --- a/api/v1/swagger/paths.json +++ b/api/v1/swagger/paths.json @@ -1,4 +1,10 @@ { + "/acquisitions/vendors": { + "$ref": "paths/acquisitions_vendors.json#/~1acquisitions~1vendors" + }, + "/acquisitions/vendors/{vendor_id}": { + "$ref": "paths/acquisitions_vendors.json#/~1acquisitions~1vendors~1{vendor_id}" + }, "/cities": { "$ref": "paths/cities.json#/~1cities" }, diff --git a/api/v1/swagger/paths/acquisitions_vendors.json b/api/v1/swagger/paths/acquisitions_vendors.json new file mode 100644 index 0000000000..08f90f9d94 --- /dev/null +++ b/api/v1/swagger/paths/acquisitions_vendors.json @@ -0,0 +1,218 @@ +{ + "/acquisitions/vendors": { + "get": { + "x-mojo-controller": "Koha::REST::V1::Acquisitions::Vendors", + "operationId": "list", + "tags": ["acquisitions","vendors"], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "A list of vendors", + "schema": { + "type": "array", + "items": { + "$ref": "../definitions.json#/vendor" + } + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal error", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "acquisition": "1" + } + } + }, + "post": { + "x-mojo-controller": "Koha::REST::V1::Acquisitions::Vendors", + "operationId": "add", + "tags": ["acquisitions","vendors"], + "parameters": [{ + "name": "body", + "in": "body", + "description": "A JSON object representing a vendor", + "required": true, + "schema": { + "$ref": "../definitions.json#/vendor" + } + }], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Vendor added", + "schema": { + "$ref": "../definitions.json#/vendor" + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal error", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "acquisition": "vendors_manage" + } + } + } + }, + "/acquisitions/vendors/{vendor_id}": { + "get": { + "x-mojo-controller": "Koha::REST::V1::Acquisitions::Vendors", + "operationId": "get", + "tags": ["acquisitions","vendors"], + "parameters": [{ + "$ref": "../parameters.json#/vendoridPathParam" + }], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "A vendor", + "schema": { + "$ref": "../definitions.json#/vendor" + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Vendor not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal error", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "acquisition": "1" + } + } + }, + "put": { + "x-mojo-controller": "Koha::REST::V1::Acquisitions::Vendors", + "operationId": "update", + "tags": ["acquisitions","vendors"], + "parameters": [{ + "$ref": "../parameters.json#/vendoridPathParam" + }, { + "name": "body", + "in": "body", + "description": "A JSON object representing a vendor", + "required": true, + "schema": { + "$ref": "../definitions.json#/vendor" + } + }], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "A vendor", + "schema": { + "$ref": "../definitions.json#/vendor" + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Vendor not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal error", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "acquisition": "1" + } + } + }, + "delete": { + "x-mojo-controller": "Koha::REST::V1::Acquisitions::Vendors", + "operationId": "delete", + "tags": ["acquisitions","vendors"], + "parameters": [{ + "$ref": "../parameters.json#/vendoridPathParam" + }], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Vendor deleted", + "schema": { + "type": "string" + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Vendor not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal error", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "acquisition": "1" + } + } + } + } +} diff --git a/api/v1/swagger/x-primitives.json b/api/v1/swagger/x-primitives.json index ae4e7395f6..12e5e9de39 100644 --- a/api/v1/swagger/x-primitives.json +++ b/api/v1/swagger/x-primitives.json @@ -39,5 +39,10 @@ "surname": { "type": "string", "description": "patron's last name" + }, + "vendor_id": { + "type": "integer", + "description": "internally assigned vendor identifier", + "readOnly": true } } -- 2.12.0