From cc6eeab313f3f08352e1498df4c74a2a293bbd6a Mon Sep 17 00:00:00 2001
From: Pedro Amorim <pedro.amorim@ptfs-europe.com>
Date: Mon, 11 Dec 2023 17:30:37 +0000
Subject: [PATCH] Bug 26297: API specs

Test plan, k-t-d:
1) Access /api/v1/patron_categories
2) Verify the patron categories are correctly listed

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>

Bug 26297: (QA follow-up) Move to REST::V1::Patrons::Categories

Bug 26297: (QA follow-up) Use search_with_library_limits

JD amended-patch: squashed + tidy
---
 Koha/REST/V1/Patrons/Categories.pm            |  54 +++++++++
 .../swagger/definitions/patron_category.yaml  | 106 ++++++++++++++++++
 api/v1/swagger/paths/patron_categories.yaml   |  40 +++++++
 api/v1/swagger/swagger.yaml                   |   4 +
 4 files changed, 204 insertions(+)
 create mode 100644 Koha/REST/V1/Patrons/Categories.pm
 create mode 100644 api/v1/swagger/definitions/patron_category.yaml
 create mode 100644 api/v1/swagger/paths/patron_categories.yaml

diff --git a/Koha/REST/V1/Patrons/Categories.pm b/Koha/REST/V1/Patrons/Categories.pm
new file mode 100644
index 00000000000..be5d6d2b049
--- /dev/null
+++ b/Koha/REST/V1/Patrons/Categories.pm
@@ -0,0 +1,54 @@
+package Koha::REST::V1::Patrons::Categories;
+
+# 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 Try::Tiny qw( catch try );
+
+=head1 NAME
+
+Koha::REST::V1::Patrons::Categories;
+
+=head1 API
+
+=head2 Methods
+
+=head3 list
+
+Controller function that handles listing Koha::Patron::Category objects
+
+=cut
+
+sub list {
+    my $c = shift->openapi->valid_input or return;
+
+    return try {
+        my $patron_categories_rs = Koha::Patron::Categories->search_with_library_limits;
+        my $categories           = $c->objects->search($patron_categories_rs);
+
+        return $c->render(
+            status  => 200,
+            openapi => $categories
+        );
+    } catch {
+        $c->unhandled_exception($_);
+    };
+}
+
+1;
diff --git a/api/v1/swagger/definitions/patron_category.yaml b/api/v1/swagger/definitions/patron_category.yaml
new file mode 100644
index 00000000000..647a6c5d57f
--- /dev/null
+++ b/api/v1/swagger/definitions/patron_category.yaml
@@ -0,0 +1,106 @@
+---
+type: object
+properties:
+  patron_category_id:
+    type: string
+    description: Internal patron category identifier
+  name:
+    type:
+      - string
+      - "null"
+    description: Name of the patron category
+  enrolment_period:
+    type:
+      - number
+      - "null"
+    description: Number of months the patron is enrolled for
+  enrolment_period_date:
+    type:
+      - string
+      - "null"
+    format: date
+    description: Date the patron is enrolled until
+  password_expiry_days:
+    type:
+      - number
+      - "null"
+    description: Number of days after which the patron must reset their password
+    description: Date the patron is enrolled until
+  upper_age_limit:
+    type:
+      - number
+      - "null"
+    description: Age limit for the patron
+  date_of_birth_required:
+    type:
+      - boolean
+      - "null"
+    description: The minimum age required for the patron category
+  enrolment_fee:
+    type:
+      - number
+      - "null"
+    description: Enrollment fee for the patron
+  overdue_notice_required:
+    type:
+      - boolean
+      - "null"
+    description: Are overdue notices sent to this patron category (1 for yes, 0 for no)
+  reserve_fee:
+    type:
+      - number
+      - "null"
+    description: Cost to place holds
+  hide_lost_items:
+    type: boolean
+    description: Are lost items shown to this category (1 for yes, 0 for no)
+  category_type:
+    type: string
+    description: Type of Koha patron (Adult, Child, Professional, Organizational, Statistical, Staff)
+  block_expired_patron_opac_actions:
+    type: number
+    description: Whether or not a patron of this category can renew books or place holds once their card has expired. 0 means they can, 1 means they cannot, -1 means use syspref BlockExpiredPatronOpacActions
+  default_privacy:
+    type: string
+    enum:
+      - default
+      - never
+      - forever
+    description: Default privacy setting for this patron category
+  check_prev_checkout:
+    type: string
+    description: Produce a warning for this patron category if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to syspref setting if ''inherit''.'
+  can_place_ill_in_opac:
+    type: boolean
+    description: Can this patron category place interlibrary loan requests
+  can_be_guarantee:
+    type: boolean
+    description: If patrons of this category can be guarantees
+  reset_password:
+    type:
+      - boolean
+      - "null"
+    description: If patrons of this category can do the password reset flow
+  change_password:
+    type:
+      - boolean
+      - "null"
+    description: If patrons of this category can change their passwords in the OPAC
+  min_password_length:
+    type:
+      - number
+      - "null"
+    description: Set minimum password length for patrons in this category
+  require_strong_password:
+    type:
+      - boolean
+      - "null"
+    description: Set required password strength for patrons in this category
+  exclude_from_local_holds_priority:
+    type:
+      - boolean
+      - "null"
+    description: Exclude patrons of this category from local holds priority
+additionalProperties: false
+required:
+  - patron_category_id
diff --git a/api/v1/swagger/paths/patron_categories.yaml b/api/v1/swagger/paths/patron_categories.yaml
new file mode 100644
index 00000000000..b07fbcce818
--- /dev/null
+++ b/api/v1/swagger/paths/patron_categories.yaml
@@ -0,0 +1,40 @@
+---
+/patron_categories:
+  get:
+    x-mojo-to: Patrons::Categories#list
+    operationId: listPatronCategories
+    tags:
+      - patron_categories
+    summary: List patron categories
+    produces:
+      - application/json
+    parameters: []
+    responses:
+      "200":
+        description: A list of patron categories
+        schema:
+          type: array
+          items:
+            $ref: "../swagger.yaml#/definitions/patron_category"
+      "401":
+        description: Authentication required
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "403":
+        description: Access forbidden
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "500":
+        description: |
+          Internal server error. Possible `error_code` attribute values:
+
+          * `internal_server_error`
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "503":
+        description: Under maintenance
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+    x-koha-authorization:
+      permissions:
+        catalogue: "1"
diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml
index 227921d7957..b0944b445e3 100644
--- a/api/v1/swagger/swagger.yaml
+++ b/api/v1/swagger/swagger.yaml
@@ -128,6 +128,8 @@ definitions:
     $ref: ./definitions/patron_account_credit.yaml
   patron_balance:
     $ref: ./definitions/patron_balance.yaml
+  patron_category:
+    $ref: ./definitions/patron_category.yaml
   patron_extended_attribute:
     $ref: ./definitions/patron_extended_attribute.yaml
   preservation_config:
@@ -427,6 +429,8 @@ paths:
     $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password"
   "/patrons/{patron_id}/password/expiration_date":
     $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password~1expiration_date"
+  /patron_categories:
+    $ref: ./paths/patron_categories.yaml#/~1patron_categories
   /preservation/config:
     $ref: ./paths/preservation_config.yaml#/~1preservation~1config
   /preservation/trains:
-- 
2.34.1