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
Signed-off-by: Matthias Meusburger <matthias.meusburger@biblibre.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
--- /dev/null
+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::Booksellers;
+
+use Try::Tiny;
+
+sub list_vendors {
+ my $c = shift->openapi->valid_input or return;
+
+ my $args = _to_model($c->req->params->to_hash);
+ my $filter;
+
+ for my $filter_param ( keys %$args ) {
+ $filter->{$filter_param} = { LIKE => $args->{$filter_param} . "%" }
+ if $args->{$filter_param};
+ }
+
+ my @vendors;
+
+ return try {
+ @vendors = Koha::Acquisition::Booksellers->search($filter);
+ @vendors = map { _to_api($_->TO_JSON) } @vendors;
+ return $c->render( status => 200,
+ openapi => \@vendors );
+ }
+ catch {
+ if ( $_->isa('DBIx::Class::Exception') ) {
+ return $c->render( status => 500,
+ openapi => { error => $_->{msg} } );
+ }
+ else {
+ return $c->render( status => 500,
+ openapi => { error => "Something went wrong, check the logs." } );
+ }
+ };
+}
+
+sub get_vendor {
+ my $c = shift->openapi->valid_input or return;
+
+ my $vendor = Koha::Acquisition::Booksellers->find( $c->validation->param('vendor_id') );
+ unless ($vendor) {
+ return $c->render( status => 404,
+ openapi => { error => "Vendor not found" } );
+ }
+
+ return $c->render( status => 200,
+ openapi => _to_api($vendor->TO_JSON) );
+}
+
+sub add_vendor {
+ my $c = shift->openapi->valid_input or return;
+
+ my $vendor = Koha::Acquisition::Bookseller->new( _to_model( $c->validation->param('body') ) );
+
+ return try {
+ $vendor->store;
+ return $c->render( status => 200,
+ openapi => _to_api($vendor->TO_JSON) );
+ }
+ catch {
+ if ( $_->isa('DBIx::Class::Exception') ) {
+ return $c->render( status => 500,
+ openapi => { error => $_->msg } );
+ }
+ else {
+ return $c->render( status => 500,
+ openapi => { error => "Something went wrong, check the logs." } );
+ }
+ };
+}
+
+sub update_vendor {
+ my $c = shift->openapi->valid_input or return;
+
+ my $vendor;
+
+ return try {
+ $vendor = Koha::Acquisition::Booksellers->find( $c->validation->param('vendor_id') );
+ $vendor->set( _to_model( $c->validation->param('body') ) );
+ $vendor->store();
+ return $c->render( status => 200,
+ openapi => _to_api($vendor->TO_JSON) );
+ }
+ catch {
+ if ( not defined $vendor ) {
+ return $c->render( status => 404,
+ openapi => { error => "Object not found" } );
+ }
+ elsif ( $_->isa('Koha::Exceptions::Object') ) {
+ return $c->render( status => 500,
+ openapi => { error => $_->message } );
+ }
+ else {
+ return $c->render( status => 500,
+ openapi => { error => "Something went wrong, check the logs." } );
+ }
+ };
+
+}
+
+sub delete_vendor {
+ my $c = shift->openapi->valid_input or return;
+
+ my $vendor;
+
+ return try {
+ $vendor = Koha::Acquisition::Booksellers->find( $c->validation->param('vendor_id') );
+ $vendor->delete;
+ return $c->render( status => 200,
+ openapi => q{} );
+ }
+ catch {
+ if ( not defined $vendor ) {
+ return $c->render( status => 404,
+ openapi => { error => "Object not found" } );
+ }
+ elsif ( $_->isa('DBIx::Class::Exception') ) {
+ return $c->render( status => 500,
+ openapi => { error => $_->msg } );
+ }
+ else {
+ return $c->render( status => 500,
+ openapi => { error => "Something went wrong, check the logs." } );
+ }
+ };
+
+}
+
+sub _to_api {
+
+ my $vendor = 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;
# 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;
},
"patron": {
"$ref": "definitions/patron.json"
+ },
+ "error": {
+ "$ref": "definitions/error.json"
+ },
+ "vendor": {
+ "$ref": "definitions/vendor.json"
}
}
--- /dev/null
+{
+ "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"]
+}
},
"holdIdPathParam": {
"$ref": "parameters/hold.json#/holdIdPathParam"
+ },
+ "vendoridPathParam": {
+ "$ref": "parameters/vendor.json#/vendoridPathParam"
}
}
--- /dev/null
+{
+ "vendoridPathParam": {
+ "name": "vendor_id",
+ "in": "path",
+ "description": "Vendor id",
+ "required": true,
+ "type": "integer"
+ }
+}
{
+ "/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"
},
--- /dev/null
+{
+ "/acquisitions/vendors": {
+ "get": {
+ "x-mojo-to": "Acquisitions::Vendors#list_vendors",
+ "operationId": "listVendors",
+ "tags": ["acquisitions","vendors"],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [{
+ "name": "name",
+ "in": "query",
+ "description": "Case insensitive search on vendor name",
+ "required": false,
+ "type": "string"
+ }, {
+ "name": "accountnumber",
+ "in": "query",
+ "description": "Case insensitive search on vendor's account number",
+ "required": false,
+ "type": "string"
+ }],
+ "responses": {
+ "200": {
+ "description": "A list of vendors",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "../definitions.json#/vendor"
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication required",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "403": {
+ "description": "Access forbidden",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "404": {
+ "description": "Vendor not found",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "503": {
+ "description": "Under maintenance",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ }
+ },
+ "x-koha-authorization": {
+ "permissions": {
+ "acquisition": "1"
+ }
+ }
+ },
+ "post": {
+ "x-mojo-to": "Acquisitions::Vendors#add_vendor",
+ "operationId": "addVendor",
+ "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"
+ }
+ },
+ "401": {
+ "description": "Authentication required",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "403": {
+ "description": "Access forbidden",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "404": {
+ "description": "Vendor not found",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "503": {
+ "description": "Under maintenance",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ }
+ },
+ "x-koha-authorization": {
+ "permissions": {
+ "acquisition": "vendors_manage"
+ }
+ }
+ }
+ },
+ "/acquisitions/vendors/{vendor_id}": {
+ "get": {
+ "x-mojo-to": "Acquisitions::Vendors#get_vendor",
+ "operationId": "getVendor",
+ "tags": ["acquisitions","vendors"],
+ "parameters": [{
+ "$ref": "../parameters.json#/vendoridPathParam"
+ }],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "A vendor",
+ "schema": {
+ "$ref": "../definitions.json#/vendor"
+ }
+ },
+ "401": {
+ "description": "Authentication required",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "403": {
+ "description": "Access forbidden",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "404": {
+ "description": "Vendor not found",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "503": {
+ "description": "Under maintenance",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ }
+ },
+ "x-koha-authorization": {
+ "permissions": {
+ "acquisition": "1"
+ }
+ }
+ },
+ "put": {
+ "x-mojo-to": "Acquisitions::Vendors#update_vendor",
+ "operationId": "updateVendor",
+ "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"
+ }
+ },
+ "401": {
+ "description": "Authentication required",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "403": {
+ "description": "Access forbidden",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "404": {
+ "description": "Vendor not found",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "503": {
+ "description": "Under maintenance",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ }
+ },
+ "x-koha-authorization": {
+ "permissions": {
+ "acquisition": "1"
+ }
+ }
+ },
+ "delete": {
+ "x-mojo-to": "Acquisitions::Vendors#delete_vendor",
+ "operationId": "deleteVendor",
+ "tags": ["acquisitions","vendors"],
+ "parameters": [{
+ "$ref": "../parameters.json#/vendoridPathParam"
+ }],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "Vendor deleted",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "401": {
+ "description": "Authentication required",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "403": {
+ "description": "Access forbidden",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "404": {
+ "description": "Vendor not found",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ },
+ "503": {
+ "description": "Under maintenance",
+ "schema": {
+ "$ref": "../definitions.json#/error"
+ }
+ }
+ },
+ "x-koha-authorization": {
+ "permissions": {
+ "acquisition": "1"
+ }
+ }
+ }
+ }
+}
"surname": {
"type": "string",
"description": "patron's last name"
+ },
+ "vendor_id": {
+ "type": "integer",
+ "description": "internally assigned vendor identifier",
+ "readOnly": true
}
}