Browse Source
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>17.11.x
9 changed files with 685 additions and 0 deletions
@ -0,0 +1,197 @@ |
|||
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; |
@ -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"] |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"vendoridPathParam": { |
|||
"name": "vendor_id", |
|||
"in": "path", |
|||
"description": "Vendor id", |
|||
"required": true, |
|||
"type": "integer" |
|||
} |
|||
} |
@ -0,0 +1,303 @@ |
|||
{ |
|||
"/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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue