From 9a5bfd2aae58273eda80d0a674fb617cfe7fefb5 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. Signed-off-by: Lucas Gass --- 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/Account/Line.pm | 1 - Koha/REST/V1/Patrons/Account.pm | 52 +++++++++++ api/v1/swagger/definitions/account_line.yaml | 93 +++++++++++--------- api/v1/swagger/definitions/credit.yaml | 88 ++++++++++++++++++ api/v1/swagger/definitions/debit.yaml | 91 +++++++++++++++++++ api/v1/swagger/paths/patrons_account.yaml | 87 ++++++++++++++++++ api/v1/swagger/swagger.yaml | 6 ++ 12 files changed, 654 insertions(+), 44 deletions(-) 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 e37e646596..c1ee298426 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 0000000000..48fdce0012 --- /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 => '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 0000000000..75ee4497d3 --- /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 0000000000..e48cd2bffa --- /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 => '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 => 'payout_type', + }; +} + +=head1 AUTHOR + +Martin Renvoize + +=cut + +1; diff --git a/Koha/Account/Debits.pm b/Koha/Account/Debits.pm new file mode 100644 index 0000000000..c6a39a1f9e --- /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/Account/Line.pm b/Koha/Account/Line.pm index 6ab6120a1a..cab0a3cae3 100644 --- a/Koha/Account/Line.pm +++ b/Koha/Account/Line.pm @@ -955,7 +955,6 @@ on the API. sub to_api_mapping { return { accountlines_id => 'account_line_id', - credit_number => undef, credit_type_code => 'credit_type', debit_type_code => 'debit_type', amountoutstanding => 'amount_outstanding', diff --git a/Koha/REST/V1/Patrons/Account.pm b/Koha/REST/V1/Patrons/Account.pm index cf9bc9a416..2238ffc075 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/account_line.yaml b/api/v1/swagger/definitions/account_line.yaml index f517350f89..626a384a80 100644 --- a/api/v1/swagger/definitions/account_line.yaml +++ b/api/v1/swagger/definitions/account_line.yaml @@ -2,95 +2,102 @@ type: object properties: account_line_id: - type: integer + type: + - integer + - "null" + readOnly: true description: Internal account line identifier - checkout_id: + amount: + type: number + minimum: 0 + description: Account line amount + amount_outstanding: + type: number + readOnly: true + description: Outstanding amount + cash_register_id: type: - integer - "null" - description: Internal identifier for the checkout the account line is related to - patron_id: - type: integer - description: Internal identifier for the patron the account line belongs to - item_id: + description: Internal identifier for the cash register used for the payment (if any) + checkout_id: type: - integer - "null" - description: Internal identifier for the item the account line is related to - date: - type: string - format: date-time - description: Date the account line was created - amount: - type: number - description: Account line amount - description: + description: Internal identifier for the checkout the account line is related to + credit_number: type: - string - "null" - description: Account line description - account_type: + readOnly: true + description: Internally generated identifier for credits + credit_type: type: - string - "null" - description: Account line type + description: Account line credit type + date: + type: string + format: date-time + readOnly: true + description: Date the account line was created debit_type: type: - string - "null" description: Account line debit type - credit_type: + description: type: - string - "null" - description: Account line credit type - payment_type: + readOnly: true + description: Account line description + interface: type: - string - "null" - description: Payment type - amount_outstanding: - type: number - description: Outstanding amount - last_increment: - type: - - number - - "null" - description: The amount the line was increased last time - timestamp: - type: string - format: date-time - description: Timestamp for the latest line update + readOnly: true + 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 - user_id: + item_id: type: - integer - "null" - description: Internal patron identifier for the staff member that introduced the - account line + 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 - interface: + patron_id: + type: integer + readOnly: true + description: Internal identifier for the patron the account line belongs to + payment_type: type: - string - "null" - description: "Interface in which the account line was generated (values can be: api, - cron, commandline, intranet, opac and sip)" + description: Payment type status: type: - string - "null" + readOnly: true description: The credit/debit status - cash_register_id: + timestamp: + type: string + format: date-time + readOnly: true + description: Timestamp for the latest line update + user_id: type: - integer - "null" - description: Internal identifier for the cash register used for the payment (if any) + description: Internal patron identifier for the staff member that introduced the account line +required: + - amount additionalProperties: false diff --git a/api/v1/swagger/definitions/credit.yaml b/api/v1/swagger/definitions/credit.yaml new file mode 100644 index 0000000000..df76473308 --- /dev/null +++ b/api/v1/swagger/definitions/credit.yaml @@ -0,0 +1,88 @@ +--- +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) + credit_number: + type: + - string + - "null" + readOnly: true + description: Internally generated identifier for credits + 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" + readOnly: true + 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 + 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 status + timestamp: + type: string + format: date-time + readOnly: true + description: Timestamp for the latest line update + type: + type: + - string + - "null" + description: Account credit type + 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 0000000000..841f972d85 --- /dev/null +++ b/api/v1/swagger/definitions/debit.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: Debit 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 payout (if any) + checkout_id: + type: + - integer + - "null" + description: Internal identifier for the checkout the account line is related to + 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" + readOnly: true + 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 + payout_type: + type: + - string + - "null" + description: Payout type + status: + type: + - string + - "null" + readOnly: true + description: The debit status + timestamp: + type: string + format: date-time + readOnly: true + description: Timestamp for the latest line update + type: + type: + - string + - "null" + description: Account debit type + 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/paths/patrons_account.yaml b/api/v1/swagger/paths/patrons_account.yaml index 3f763a7aa4..7c4e033826 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 479c4d710b..5f31d4e881 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: @@ -263,6 +267,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.2