Browse Source
This patch adds a new route to the REST api: /api/v1/acquisitions/funds/ Signed-off-by: David Bourgault <david.bourgault@inlibro.com> Signed-off-by: Josef Moravec <josef.moravec@gmail.com> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Signed-off-by: Nick Clemens <nick@bywatersolutions.com>19.05.x
9 changed files with 352 additions and 1 deletions
@ -0,0 +1,105 @@ |
|||
package Koha::REST::V1::Acquisitions::Funds; |
|||
|
|||
# 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 C4::Budgets; |
|||
use JSON qw(to_json); |
|||
|
|||
use Try::Tiny; |
|||
|
|||
=head1 NAME |
|||
|
|||
Koha::REST::V1::Acquisitions::Funds |
|||
|
|||
=head1 API |
|||
|
|||
=head2 Methods |
|||
|
|||
=head3 list_funds |
|||
|
|||
Controller function that handles listing Funds |
|||
|
|||
=cut |
|||
|
|||
sub list_funds { |
|||
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}; |
|||
} |
|||
|
|||
return try { |
|||
my $funds = GetBudgets($filter); |
|||
my @fundsArray = map { _to_api($_) } @$funds; |
|||
return $c->render( status => 200, |
|||
openapi => \@fundsArray); |
|||
} |
|||
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. $_ $filter" } ); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
=head3 _to_api |
|||
|
|||
Helper function that maps a Fund into |
|||
the attribute names the exposed REST api spec. |
|||
|
|||
=cut |
|||
|
|||
sub _to_api { |
|||
my $fund = shift; |
|||
my $returnfund; |
|||
$returnfund->{id} = delete $fund->{budget_id}; |
|||
$returnfund->{code} = delete $fund->{budget_code}; |
|||
$returnfund->{name} = delete $fund->{budget_name}; |
|||
|
|||
return $returnfund; |
|||
} |
|||
|
|||
=head3 _to_model |
|||
|
|||
Helper function that maps REST api objects into Fund |
|||
attribute names. |
|||
|
|||
=cut |
|||
|
|||
sub _to_model { |
|||
my $fund = shift; |
|||
|
|||
# Rename back |
|||
$fund->{budget_id} = delete $fund->{id}; |
|||
$fund->{budget_code} = delete $fund->{code}; |
|||
$fund->{budget_name} = delete $fund->{name}; |
|||
|
|||
return $fund; |
|||
} |
|||
|
|||
1; |
@ -0,0 +1,24 @@ |
|||
{ |
|||
"type": "object", |
|||
"properties": { |
|||
"id": { |
|||
"$ref": "../x-primitives.json#/fund_id" |
|||
}, |
|||
"code": { |
|||
"type": [ |
|||
"string", |
|||
"null" |
|||
], |
|||
"description": "Fund code" |
|||
}, |
|||
"name": { |
|||
"type": [ |
|||
"string", |
|||
"null" |
|||
], |
|||
"description": "Fund name" |
|||
} |
|||
}, |
|||
"additionalProperties": false, |
|||
"required": ["name"] |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"fundidPathParam": { |
|||
"name": "fund_id", |
|||
"in": "path", |
|||
"description": "Fund id", |
|||
"required": true, |
|||
"type": "integer" |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
{ |
|||
"/acquisitions/funds": { |
|||
"get": { |
|||
"x-mojo-to": "Acquisitions::Funds#list_funds", |
|||
"operationId": "listFunds", |
|||
"tags": ["acquisitions","funds"], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"parameters": [{ |
|||
"name": "name", |
|||
"in": "query", |
|||
"description": "Case insensitive search on fund name", |
|||
"required": false, |
|||
"type": "string" |
|||
}, |
|||
{ |
|||
"name": "budget_owner_id", |
|||
"in": "query", |
|||
"description": "Display only the funds that belongs to the given borrowernumber", |
|||
"required": false, |
|||
"type": "integer" |
|||
} |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "A list of funds", |
|||
"schema": { |
|||
"type": "array", |
|||
"items": { |
|||
"$ref": "../definitions.json#/fund" |
|||
} |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "Fund 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": "budget_manage_all" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,125 @@ |
|||
#!/usr/bin/env perl |
|||
|
|||
# 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 Test::More tests => 14; |
|||
use Test::Mojo; |
|||
use t::lib::TestBuilder; |
|||
use t::lib::Mocks; |
|||
|
|||
use C4::Auth; |
|||
use C4::Context; |
|||
use C4::Budgets; |
|||
|
|||
use Koha::Database; |
|||
use Koha::Patron; |
|||
|
|||
my $schema = Koha::Database->new->schema; |
|||
my $builder = t::lib::TestBuilder->new(); |
|||
|
|||
$schema->storage->txn_begin; |
|||
|
|||
# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling |
|||
# this affects the other REST api tests |
|||
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); |
|||
|
|||
$ENV{REMOTE_ADDR} = '127.0.0.1'; |
|||
my $t = Test::Mojo->new('Koha::REST::V1'); |
|||
|
|||
my $fund1 = { |
|||
budget_code => 'ABCD', |
|||
budget_amount => '123.132000', |
|||
budget_name => 'Periodiques', |
|||
budget_notes => 'This is a note', |
|||
}; |
|||
my $budget_id = AddBudget($fund1); |
|||
isnt( $budget_id, undef, 'AddBudget does not returns undef' ); |
|||
|
|||
$t->get_ok('/api/v1/acquisitions/funds') |
|||
->status_is(401); |
|||
|
|||
$t->get_ok('/api/v1/acquisitions/funds/?name=testFund') |
|||
->status_is(401); |
|||
|
|||
my ( $borrowernumber, $session_id ) |
|||
#= create_user_and_session( { authorized => 1 } ); |
|||
= create_user_and_session( ); |
|||
|
|||
my $tx = $t->ua->build_tx(GET => '/api/v1/acquisitions/funds'); |
|||
$tx->req->cookies({name => 'CGISESSID', value => $session_id}); |
|||
$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); |
|||
$t->request_ok($tx) |
|||
->status_is(403); |
|||
|
|||
$tx = $t->ua->build_tx(GET => "/api/v1/acquisitions/funds/?name=" . $fund1->{ budget_name }); |
|||
$tx->req->cookies({name => 'CGISESSID', value => $session_id}); |
|||
$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); |
|||
$t->request_ok($tx) |
|||
->status_is(403); |
|||
|
|||
( $borrowernumber, $session_id ) |
|||
= create_user_and_session( { authorized => 1 } ); |
|||
|
|||
$tx = $t->ua->build_tx(GET => '/api/v1/acquisitions/funds'); |
|||
$tx->req->cookies({name => 'CGISESSID', value => $session_id}); |
|||
$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); |
|||
$t->request_ok($tx) |
|||
->status_is(200); |
|||
|
|||
$tx = $t->ua->build_tx(GET => "/api/v1/acquisitions/funds/?name=" . $fund1->{ budget_name }); |
|||
$tx->req->cookies({name => 'CGISESSID', value => $session_id}); |
|||
$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); |
|||
$t->request_ok($tx) |
|||
->status_is(200) |
|||
->json_like('/0/name' => qr/$fund1->{ budget_name }/); |
|||
|
|||
$schema->storage->txn_rollback; |
|||
|
|||
sub create_user_and_session { |
|||
|
|||
my $args = shift; |
|||
my $flags = ( $args->{authorized} ) ? 2052 : 0; |
|||
|
|||
# my $flags = ( $args->{authorized} ) ? $args->{authorized} : 0; |
|||
my $dbh = C4::Context->dbh; |
|||
|
|||
my $user = $builder->build( |
|||
{ source => 'Borrower', |
|||
value => { flags => $flags } |
|||
} |
|||
); |
|||
|
|||
# Create a session for the authorized user |
|||
my $session = C4::Auth::get_session(''); |
|||
$session->param( 'number', $user->{borrowernumber} ); |
|||
$session->param( 'id', $user->{userid} ); |
|||
$session->param( 'ip', '127.0.0.1' ); |
|||
$session->param( 'lasttime', time() ); |
|||
$session->flush; |
|||
|
|||
if ( $args->{authorized} ) { |
|||
$dbh->do( |
|||
q{ |
|||
INSERT INTO user_permissions (borrowernumber,module_bit,code) |
|||
VALUES (?,11,'budget_manage_all')}, |
|||
undef, $user->{borrowernumber} |
|||
); |
|||
} |
|||
|
|||
return ( $user->{borrowernumber}, $session->id ); |
|||
} |
Loading…
Reference in new issue