From a0124aabb98267adfad660ee86164ae84554620c Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Fri, 23 Apr 2021 14:48:11 -0300
Subject: [PATCH] Bug 17314: Implement /suggestions routes

This patch introduces routes to handle purchase suggestions, from the
staff POV.

Tests are added as well.

To test:
1. Apply this patches
2. Run:
   $ kshell
  k$ prove t/db_dependent/api/v1/suggestions.t
=> SUCCESS: Tests pass! And they are meaningful!
3. Play with your favourite REST tool (Postman?)
4. Sign off :-D
---
 Koha/REST/V1/Suggestions.pm         | 180 ++++++++++++++++++++++++++++
 Koha/Suggestion.pm                  |  46 +++++++
 t/db_dependent/api/v1/suggestions.t |   2 -
 3 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 Koha/REST/V1/Suggestions.pm

diff --git a/Koha/REST/V1/Suggestions.pm b/Koha/REST/V1/Suggestions.pm
new file mode 100644
index 0000000000..1c0532cc61
--- /dev/null
+++ b/Koha/REST/V1/Suggestions.pm
@@ -0,0 +1,180 @@
+package Koha::REST::V1::Suggestions;
+
+# 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, see <http:°www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Mojo::Base 'Mojolicious::Controller';
+
+use Koha::Suggestions;
+
+use Try::Tiny;
+
+=head1 NAME
+
+Koha::REST::V1::Suggestion
+
+=head1 API
+
+=head2 Methods
+
+=head3 list
+
+Controller method that handles listing Koha::Suggestion objects
+
+=cut
+
+sub list {
+    my $c = shift->openapi->valid_input or return;
+
+    return try {
+
+        my $suggestions = $c->objects->search( Koha::Suggestions->new );
+
+        return $c->render(
+            status  => 200,
+            openapi => $suggestions
+        );
+    }
+    catch {
+        $c->unhandled_exception($_);
+    };
+}
+
+=head3 get
+
+Controller method that handles retrieving a single Koha::Suggestion object
+
+=cut
+
+sub get {
+    my $c = shift->openapi->valid_input or return;
+
+    return try {
+        my $suggestion_id = $c->validation->param('suggestion_id');
+        my $suggestion = $c->objects->find( Koha::Suggestions->new, $suggestion_id );
+
+        unless ($suggestion) {
+            return $c->render(
+                status  => 404,
+                openapi => { error => "Suggestion not found." }
+            );
+        }
+
+        return $c->render(
+            status  => 200,
+            openapi => $suggestion
+        );
+    }
+    catch {
+        $c->unhandled_exception($_);
+    };
+}
+
+=head3 add
+
+Controller method that handles adding a new Koha::Suggestion object
+
+=cut
+
+sub add {
+    my $c = shift->openapi->valid_input or return;
+
+    my $body = $c->validation->param('body');
+
+    # FIXME: This should be handled in Koha::Suggestion->store
+    $body->{'status'} = 'ASKED'
+        unless defined $body->{'status'};
+
+    return try {
+        my $suggestion = Koha::Suggestion->new_from_api( $body )->store;
+        $suggestion->discard_changes;
+        $c->res->headers->location( $c->req->url->to_string . '/' . $suggestion->suggestionid );
+
+        return $c->render(
+            status  => 201,
+            openapi => $suggestion->to_api
+        );
+    }
+    catch {
+        $c->unhandled_exception($_);
+    };
+}
+
+=head3 update
+
+Controller method that handles modifying Koha::Suggestion object
+
+=cut
+
+sub update {
+    my $c = shift->openapi->valid_input or return;
+
+    my $suggestion_id = $c->validation->param('suggestion_id');
+    my $suggestion = Koha::Suggestions->find( $suggestion_id );
+
+    return $c->render(
+        status  => 404,
+        openapi => { error => 'Suggestion not found.' }
+    ) unless $suggestion;
+
+    return try {
+
+        my $body = $c->validation->param('body');
+
+        $suggestion->set_from_api( $body )->store;
+        $suggestion->discard_changes;
+
+        return $c->render(
+            status  => 200,
+            openapi => $suggestion->to_api
+        );
+    }
+    catch {
+        $c->unhandled_exception($_);
+    };
+
+}
+
+=head3 delete
+
+Controller method that handles removing a Koha::Suggestion object
+
+=cut
+
+sub delete {
+    my $c = shift->openapi->valid_input or return;
+
+    my $suggestion_id = $c->validation->param('suggestion_id');
+    my $suggestion = Koha::Suggestions->find( $suggestion_id );
+
+    return $c->render(
+        status  => 404,
+        openapi => { error => 'Suggestion not found.' }
+    ) unless $suggestion;
+
+    return try {
+        $suggestion->delete;
+        return $c->render(
+            status  => 204,
+            openapi => q{}
+        );
+    }
+    catch {
+        $c->unhandled_exception($_);
+    };
+}
+
+1;
diff --git a/Koha/Suggestion.pm b/Koha/Suggestion.pm
index 5542963d45..433fe7f1f1 100644
--- a/Koha/Suggestion.pm
+++ b/Koha/Suggestion.pm
@@ -138,6 +138,52 @@ sub _type {
     return 'Suggestion';
 }
 
+=head3 to_api_mapping
+
+This method returns the mapping for representing a Koha::Patron object
+on the API.
+
+=cut
+
+sub to_api_mapping {
+    return {
+        suggestionid         => 'suggestion_id',
+        suggestedby          => 'suggested_by',
+        suggesteddate        => 'suggestion_date',
+        managedby            => 'managed_by',
+        manageddate          => 'managed_date',
+        acceptedby           => 'accepted_by',
+        accepteddate         => 'accepted_date',
+        rejectedby           => 'rejected_by',
+        rejecteddate         => 'rejected_date',
+        lastmodificationdate => 'last_status_change_date',
+        lastmodificationby   => 'last_status_change_by',
+        STATUS               => 'status',
+        note                 => 'note',
+        author               => 'author',
+        title                => 'title',
+        copyrightdate        => 'copyright_date',
+        publishercode        => 'publisher_code',
+        date                 => 'timestamp',
+        volumedesc           => 'volume_desc',
+        publicationyear      => 'publication_year',
+        place                => 'publication_place',
+        isbn                 => 'isbn',
+        biblionumber         => 'biblio_id',
+        reason               => 'reason',
+        patronreason         => 'patron_reason',
+        budgetid             => 'budget_id',
+        branchcode           => 'library_id',
+        collectiontitle      => 'collection_title',
+        itemtype             => 'item_type',
+        quantity             => 'quantity',
+        currency             => 'currency',
+        price                => 'item_price',
+        total                => 'total_price',
+        archived             => 'archived',
+    };
+}
+
 =head1 AUTHOR
 
 Kyle M Hall <kyle@bywatersolutions.com>
diff --git a/t/db_dependent/api/v1/suggestions.t b/t/db_dependent/api/v1/suggestions.t
index ff9ee79fd2..6ec1010003 100755
--- a/t/db_dependent/api/v1/suggestions.t
+++ b/t/db_dependent/api/v1/suggestions.t
@@ -26,8 +26,6 @@ use t::lib::Mocks;
 use Koha::Suggestions;
 use Koha::Database;
 
-use Data::Printer colored => 1;
-
 my $schema  = Koha::Database->new->schema;
 my $builder = t::lib::TestBuilder->new;
 
-- 
2.30.2