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 <lucas@bywatersolutions.com>

Signed-off-by: Agustin Moyano <agustinmoyano@theke.io>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Martin Renvoize 2021-11-10 16:07:00 +00:00 committed by Tomas Cohen Arazi
parent 020f710e31
commit f4c6a5dfd5
No known key found for this signature in database
GPG Key ID: 0A272EA1B2F3C15F
12 changed files with 688 additions and 80 deletions

View File

@ -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();

64
Koha/Account/Credit.pm Normal file
View File

@ -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 <http://www.gnu.org/licenses>.
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 => undef,
itemnumber => undef,
manager_id => 'user_id',
note => 'internal_note',
register_id => 'cash_register_id',
};
}
=head1 AUTHOR
Martin Renvoize <martin.renvoize@ptfs-europe.com>
=cut
1;

56
Koha/Account/Credits.pm Normal file
View File

@ -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 <http://www.gnu.org/licenses>.
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;

65
Koha/Account/Debit.pm Normal file
View File

@ -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 <http://www.gnu.org/licenses>.
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 <martin.renvoize@ptfs-europe.com>
=cut
1;

56
Koha/Account/Debits.pm Normal file
View File

@ -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 <http://www.gnu.org/licenses>.
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;

View File

@ -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',

View File

@ -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;

View File

@ -2,95 +2,106 @@
type: object
properties:
account_line_id:
type: integer
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
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
description: Date the account line was created
amount:
type: number
description: Account line amount
description:
type:
- string
- "null"
description: Account line description
account_type:
type:
- string
- "null"
description: Account line type
debit_type:
type:
- string
- "null"
description: Account line debit type
credit_type:
type:
- string
- "null"
description: Account line credit type
payment_type:
type:
- string
- "null"
description: Payment type
amount_outstanding:
type: number
readOnly: true
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
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"
description: The credit/debit status
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_number:
type:
- string
- "null"
readOnly: true
description: Internally generated identifier for credits
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
debit_type:
type:
- string
- "null"
description: Account line debit type
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
payment_type:
type:
- string
- "null"
description: Payment type
payout_type:
type:
- string
- "null"
description: Payout 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

View File

@ -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

View File

@ -0,0 +1,85 @@
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
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
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
description: Internal identifier for the patron the account line belongs to
payout_type:
type:
- string
- "null"
description: Payout type
status:
type:
- string
- "null"
description: The debit status
timestamp:
type: string
format: date-time
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

View File

@ -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

View File

@ -30,6 +30,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:
@ -285,6 +289,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}":