From 85ea9e94aab26a83396900fb55e50f48974d5bd6 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Wed, 10 Nov 2021 16:07:00 +0000 Subject: [PATCH] Bug 29453: Add endpoints for fetching patron credits & debits This patch adds two new API endpoints for fetching a patrons credits and a patrons debits. --- Koha/Account.pm | 39 ++++++++++ Koha/Account/Credit.pm | 64 +++++++++++++++ Koha/Account/Credits.pm | 56 ++++++++++++++ Koha/Account/Debit.pm | 65 ++++++++++++++++ Koha/Account/Debits.pm | 56 ++++++++++++++ Koha/REST/V1/Patrons/Account.pm | 52 +++++++++++++ api/v1/swagger/definitions/credit.yaml | 91 ++++++++++++++++++++++ api/v1/swagger/definitions/debit.yaml | 94 +++++++++++++++++++++++ api/v1/swagger/paths/patrons_account.yaml | 87 +++++++++++++++++++++ api/v1/swagger/swagger.yaml | 6 ++ 10 files changed, 610 insertions(+) create mode 100644 Koha/Account/Credit.pm create mode 100644 Koha/Account/Credits.pm create mode 100644 Koha/Account/Debit.pm create mode 100644 Koha/Account/Debits.pm create mode 100644 api/v1/swagger/definitions/credit.yaml create mode 100644 api/v1/swagger/definitions/debit.yaml diff --git a/Koha/Account.pm b/Koha/Account.pm index e37e6465969..c1ee298426e 100644 --- a/Koha/Account.pm +++ b/Koha/Account.pm @@ -30,6 +30,8 @@ use C4::Stats qw( UpdateStats ); use C4::Overdues qw(GetFine); use Koha::Patrons; +use Koha::Account::Credits; +use Koha::Account::Debits; use Koha::Account::Lines; use Koha::Account::Offsets; use Koha::Account::DebitTypes; @@ -749,6 +751,43 @@ sub lines { ); } + +=head3 credits + + my $credits = $self->credits; + +Return all credits for the user + +=cut + +sub credits { + my ($self) = @_; + + return Koha::Account::Credits->search( + { + borrowernumber => $self->{patron_id} + } + ); +} + +=head3 debits + + my $debits = $self->debits; + +Return all debits for the user + +=cut + +sub debits { + my ($self) = @_; + + return Koha::Account::Debits->search( + { + borrowernumber => $self->{patron_id}, + } + ); +} + =head3 reconcile_balance $account->reconcile_balance(); diff --git a/Koha/Account/Credit.pm b/Koha/Account/Credit.pm new file mode 100644 index 00000000000..30b1e9af481 --- /dev/null +++ b/Koha/Account/Credit.pm @@ -0,0 +1,64 @@ +package Koha::Account::Credit; + +# Copyright PTFS Europe 2021 +# +# 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 . + +use Modern::Perl; + +use base qw(Koha::Account::Line); + +=head1 NAME + +Koha::Credit - Koha Credit object class + +This object represents a credit account line + +=head1 API + +=head2 Class Methods + +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::Account::Credit object +on the API. + +=cut + +sub to_api_mapping { + return { + accountlines_id => 'account_line_id', + credit_number => undef, + credit_type_code => 'credit_type', + debit_type_code => undef, + amountoutstanding => 'amount_outstanding', + borrowernumber => 'patron_id', + branchcode => 'library_id', + issue_id => 'checkout_id', + itemnumber => 'item_id', + manager_id => 'user_id', + note => 'internal_note', + register_id => 'cash_register_id', + }; +} + +=head1 AUTHOR + +Martin Renvoize + +=cut + +1; diff --git a/Koha/Account/Credits.pm b/Koha/Account/Credits.pm new file mode 100644 index 00000000000..75ee4497d34 --- /dev/null +++ b/Koha/Account/Credits.pm @@ -0,0 +1,56 @@ +package Koha::Account::Credits; + +# 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 . + +use Modern::Perl; + +use Koha::Database; +use Koha::Account::Credit; + +use base qw(Koha::Account::Lines); + +=head1 NAME + +Koha::Account::Credits - Koha Cash Register Action Object set class + +=head1 API + +=head2 Class methods + +=head3 search + + my $credits = Koha::Account::Credits->search( $where, $attr ); + +Returns a list of credit lines. + +=cut + +sub search { + my ( $self, $where, $attr ) = @_; + + my $rs = $self->SUPER::search({ debit_type_code => undef }); + return $rs->SUPER::search( $where, $attr ); +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::Account::Credit'; +} + +1; diff --git a/Koha/Account/Debit.pm b/Koha/Account/Debit.pm new file mode 100644 index 00000000000..0f7158e5b6c --- /dev/null +++ b/Koha/Account/Debit.pm @@ -0,0 +1,65 @@ +package Koha::Account::Debit; + +# Copyright PTFS Europe 2021 +# +# 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 . + +use Modern::Perl; + +use base qw(Koha::Account::Line); + +=head1 NAME + +Koha::Debit - Koha Debit object class + +This object represents a debit account line + +=head1 API + +=head2 Class Methods + +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::Account::Debit object +on the API. + +=cut + +sub to_api_mapping { + return { + accountlines_id => 'account_line_id', + credit_number => undef, + credit_type_code => undef, + debit_type_code => 'debit_type', + amountoutstanding => 'amount_outstanding', + borrowernumber => 'patron_id', + branchcode => 'library_id', + issue_id => 'checkout_id', + itemnumber => 'item_id', + manager_id => 'user_id', + note => 'internal_note', + register_id => 'cash_register_id', + payment_type => undef + }; +} + +=head1 AUTHOR + +Martin Renvoize + +=cut + +1; diff --git a/Koha/Account/Debits.pm b/Koha/Account/Debits.pm new file mode 100644 index 00000000000..c6a39a1f9e4 --- /dev/null +++ b/Koha/Account/Debits.pm @@ -0,0 +1,56 @@ +package Koha::Account::Debits; + +# 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 . + +use Modern::Perl; + +use Koha::Database; +use Koha::Account::Debit; + +use base qw(Koha::Account::Lines); + +=head1 NAME + +Koha::Account::Debits - Koha Cash Register Action Object set class + +=head1 API + +=head2 Class methods + +=head3 search + + my $debits = Koha::Account::Debits->search( $where, $attr ); + +Returns a list of debit lines. + +=cut + +sub search { + my ( $self, $where, $attr ) = @_; + + my $rs = $self->SUPER::search({ credit_type_code => undef }); + return $rs->SUPER::search( $where, $attr ); +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::Account::Debit'; +} + +1; diff --git a/Koha/REST/V1/Patrons/Account.pm b/Koha/REST/V1/Patrons/Account.pm index cf9bc9a4166..2238ffc0757 100644 --- a/Koha/REST/V1/Patrons/Account.pm +++ b/Koha/REST/V1/Patrons/Account.pm @@ -74,6 +74,32 @@ sub get { }; } +=head3 list_credits + +=cut + +sub list_credits { + my $c = shift->openapi->valid_input or return; + + my $patron_id = $c->validation->param('patron_id'); + my $patron = Koha::Patrons->find($patron_id); + + unless ($patron) { + return $c->render( status => 404, openapi => { error => "Patron not found." } ); + } + + return try { + my $account = $patron->account; + + my $credits_set = $account->credits; + my $credits = $c->objects->search( $credits_set ); + return $c->render( status => 200, openapi => $credits ); + } + catch { + $c->unhandled_exception($_); + }; +} + =head3 add_credit Controller function that handles adding a credit to a patron's account @@ -153,4 +179,30 @@ sub add_credit { }; } +=head3 list_debits + +=cut + +sub list_debits { + my $c = shift->openapi->valid_input or return; + + my $patron_id = $c->validation->param('patron_id'); + my $patron = Koha::Patrons->find($patron_id); + + unless ($patron) { + return $c->render( status => 404, openapi => { error => "Patron not found." } ); + } + + return try { + my $account = $patron->account; + + my $debits_set = $account->debits; + my $debits = $c->objects->search( $debits_set ); + return $c->render( status => 200, openapi => $debits ); + } + catch { + $c->unhandled_exception($_); + }; +} + 1; diff --git a/api/v1/swagger/definitions/credit.yaml b/api/v1/swagger/definitions/credit.yaml new file mode 100644 index 00000000000..3b1db9d02f0 --- /dev/null +++ b/api/v1/swagger/definitions/credit.yaml @@ -0,0 +1,91 @@ +--- +type: object +properties: + account_line_id: + type: + - integer + - "null" + readOnly: true + description: Internal account line identifier + amount: + type: number + minimum: 0 + description: Credit amount + amount_outstanding: + type: number + readOnly: true + description: Outstanding amount + cash_register_id: + type: + - integer + - "null" + description: Internal identifier for the cash register used for the payment (if any) + checkout_id: + type: + - integer + - "null" + description: Internal identifier for the checkout the account line is related to + credit_type: + type: + - string + - "null" + description: Account line credit type + date: + type: string + format: date-time + readOnly: true + description: Date the account line was created + description: + type: + - string + - "null" + readOnly: true + description: Account line description + interface: + type: + - string + - "null" + description: 'Interface in which the account line was generated (values can be: api, cron, commandline, intranet, opac and sip)' + internal_note: + type: + - string + - "null" + description: Internal note + item_id: + type: + - integer + - "null" + description: Internal identifier for the item the account line is related to + library_id: + type: + - string + - "null" + description: Internal identifier for the library in which the transaction took place + patron_id: + type: integer + readOnly: true + description: Internal identifier for the patron the account line belongs to + payment_type: + type: + - string + - "null" + description: Payment type + status: + type: + - string + - "null" + readOnly: true + description: The credit/debit status + timestamp: + type: string + format: date-time + readOnly: true + description: Timestamp for the latest line update + user_id: + type: + - integer + - "null" + description: Internal patron identifier for the staff member that introduced the account line +required: + - amount +additionalProperties: false diff --git a/api/v1/swagger/definitions/debit.yaml b/api/v1/swagger/definitions/debit.yaml new file mode 100644 index 00000000000..4ffe2b8f4a4 --- /dev/null +++ b/api/v1/swagger/definitions/debit.yaml @@ -0,0 +1,94 @@ +type: object +properties: + account_line_id: + type: + - integer + - "null" + readOnly: true + description: Internal account line identifier + checkout_id: + type: + - integer + - "null" + description: Internal identifier for the checkout the account line is related to + patron_id: + type: integer + readOnly: true + description: Internal identifier for the patron the account line belongs to + item_id: + type: + - integer + - "null" + description: Internal identifier for the item the account line is related to + date: + type: string + format: date-time + readOnly: true + description: Date the account line was created + amount: + type: number + description: Account line amount + description: + type: + - string + - "null" + readOnly: true + description: Account line description + account_type: + type: + - string + - "null" + description: Account line type + debit_type: + type: + - string + - "null" + description: Account line debit type + payout_type: + type: + - string + - "null" + description: Payout type + amount_outstanding: + type: number + readOnly: true + description: Outstanding amount + timestamp: + type: string + format: date-time + readOnly: true + description: Timestamp for the latest line update + internal_note: + type: + - string + - "null" + description: Internal note + user_id: + type: + - integer + - "null" + description: Internal patron identifier for the staff member that introduced the account line + library_id: + type: + - string + - "null" + description: Internal identifier for the library in which the transaction took place + interface: + type: + - string + - "null" + description: 'Interface in which the account line was generated (values can be: api, cron, commandline, intranet, opac and sip)' + status: + type: + - string + - "null" + readOnly: true + description: The credit/debit status + cash_register_id: + type: + - integer + - "null" + description: Internal identifier for the cash register used for the payment (if any) +required: + - amount +additionalProperties: false diff --git a/api/v1/swagger/paths/patrons_account.yaml b/api/v1/swagger/paths/patrons_account.yaml index 3f763a7aa41..7c4e033826e 100644 --- a/api/v1/swagger/paths/patrons_account.yaml +++ b/api/v1/swagger/paths/patrons_account.yaml @@ -43,6 +43,47 @@ borrowers: edit_borrowers updatecharges: remaining_permissions "/patrons/{patron_id}/account/credits": + get: + x-mojo-to: Patrons::Account#list_credits + operationId: listPatronCredits + tags: + - patrons + - credits + summary: List patron credits + produces: + - application/json + parameters: + - $ref: "../swagger.yaml#/parameters/patron_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/q_header" + responses: + "200": + description: A list of credits + schema: + type: array + items: + $ref: "../swagger.yaml#/definitions/credit" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: Internal error + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + borrowers: edit_borrowers + updatecharges: remaining_permissions post: x-mojo-to: Patrons::Account#add_credit operationId: addPatronCredit @@ -90,3 +131,49 @@ x-koha-authorization: permissions: updatecharges: remaining_permissions +"/patrons/{patron_id}/account/debits": + get: + x-mojo-to: Patrons::Account#list_debits + operationId: listPatronDebits + tags: + - patrons + - debits + summary: List patron debits + produces: + - application/json + parameters: + - $ref: "../swagger.yaml#/parameters/patron_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/q_header" + responses: + "200": + description: A list of debits + schema: + type: array + items: + $ref: "../swagger.yaml#/definitions/debit" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Patron not found + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: Internal error + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + borrowers: edit_borrowers + updatecharges: remaining_permissions diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 696a73be8b4..0d970762529 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -26,6 +26,10 @@ definitions: $ref: ./definitions/circ-rule-kind.yaml city: $ref: ./definitions/city.yaml + credit: + $ref: ./definitions/credit.yaml + debit: + $ref: ./definitions/debit.yaml erm_agreement: $ref: ./definitions/erm_agreement.yaml erm_eholdings_title: @@ -261,6 +265,8 @@ paths: $ref: "./paths/patrons_account.yaml#/~1patrons~1{patron_id}~1account" "/patrons/{patron_id}/account/credits": $ref: "./paths/patrons_account.yaml#/~1patrons~1{patron_id}~1account~1credits" + "/patrons/{patron_id}/account/debits": + $ref: "./paths/patrons_account.yaml#/~1patrons~1{patron_id}~1account~1debits" "/patrons/{patron_id}/extended_attributes": $ref: "./paths/patrons_extended_attributes.yaml#/~1patrons~1{patron_id}~1extended_attributes" "/patrons/{patron_id}/extended_attributes/{extended_attribute_id}": -- 2.39.0