View | Details | Raw Unified | Return to bug 41592
Collapse All | Expand All

(-)a/Koha/Account/Credit.pm (-1 / +1 lines)
Lines 41-47 on the API. Link Here
41
sub to_api_mapping {
41
sub to_api_mapping {
42
    return {
42
    return {
43
        accountlines_id   => 'account_line_id',
43
        accountlines_id   => 'account_line_id',
44
        credit_number     => undef,
44
        credit_number     => 'credit_number',
45
        credit_type_code  => 'type',
45
        credit_type_code  => 'type',
46
        debit_type_code   => undef,
46
        debit_type_code   => undef,
47
        amountoutstanding => 'amount_outstanding',
47
        amountoutstanding => 'amount_outstanding',
(-)a/Koha/Account/Line.pm (-2 / +2 lines)
Lines 200-206 sub credits { Link Here
200
    my $cond_m = { map { "credit." . $_ => $cond->{$_} } keys %{$cond} };
200
    my $cond_m = { map { "credit." . $_ => $cond->{$_} } keys %{$cond} };
201
    my $rs     = $self->_result->search_related('account_offsets_debits')->search_related( 'credit', $cond_m, $attr );
201
    my $rs     = $self->_result->search_related('account_offsets_debits')->search_related( 'credit', $cond_m, $attr );
202
    return unless $rs;
202
    return unless $rs;
203
    return Koha::Account::Lines->_new_from_dbic($rs);
203
    return Koha::Account::Credits->_new_from_dbic($rs);
204
}
204
}
205
205
206
=head3 debits
206
=head3 debits
Lines 224-230 sub debits { Link Here
224
    my $cond_m = { map { "debit." . $_ => $cond->{$_} } keys %{$cond} };
224
    my $cond_m = { map { "debit." . $_ => $cond->{$_} } keys %{$cond} };
225
    my $rs     = $self->_result->search_related('account_offsets_credits')->search_related( 'debit', $cond_m, $attr );
225
    my $rs     = $self->_result->search_related('account_offsets_credits')->search_related( 'debit', $cond_m, $attr );
226
    return unless $rs;
226
    return unless $rs;
227
    return Koha::Account::Lines->_new_from_dbic($rs);
227
    return Koha::Account::Debits->_new_from_dbic($rs);
228
}
228
}
229
229
230
=head3 void
230
=head3 void
(-)a/Koha/REST/V1/Account.pm (+81 lines)
Line 0 Link Here
1
package Koha::REST::V1::Account;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Controller';
21
22
use Koha::Account::Credits;
23
use Koha::Account::Debits;
24
25
use Try::Tiny qw( catch try );
26
27
=head1 NAME
28
29
Koha::REST::V1::Account - Global account line endpoints (not patron-specific)
30
31
=head1 API
32
33
=head2 Methods
34
35
=head3 list_credits
36
37
Controller function that handles listing credits globally (not patron-specific).
38
Used for searching credits across all patrons by credit_number or accountlines_id.
39
40
=cut
41
42
sub list_credits {
43
    my $c = shift->openapi->valid_input or return;
44
45
    return try {
46
        my $credits_rs = Koha::Account::Credits->new;
47
        my $credits    = $c->objects->search($credits_rs);
48
49
        return $c->render(
50
            status  => 200,
51
            openapi => $credits
52
        );
53
    } catch {
54
        $c->unhandled_exception($_);
55
    };
56
}
57
58
=head3 list_debits
59
60
Controller function that handles listing debits globally (not patron-specific).
61
Used for searching debits across all patrons.
62
63
=cut
64
65
sub list_debits {
66
    my $c = shift->openapi->valid_input or return;
67
68
    return try {
69
        my $debits_rs = Koha::Account::Debits->new;
70
        my $debits    = $c->objects->search($debits_rs);
71
72
        return $c->render(
73
            status  => 200,
74
            openapi => $debits
75
        );
76
    } catch {
77
        $c->unhandled_exception($_);
78
    };
79
}
80
81
1;
(-)a/api/v1/swagger/definitions/credit.yaml (-1 / +7 lines)
Lines 53-59 properties: Link Here
53
      - "null"
53
      - "null"
54
    description: Internal identifier for the library in which the transaction took place
54
    description: Internal identifier for the library in which the transaction took place
55
  patron_id:
55
  patron_id:
56
    type: integer
56
    type:
57
      - integer
58
      - "null"
57
    readOnly: true
59
    readOnly: true
58
    description: Internal identifier for the patron the account line belongs to
60
    description: Internal identifier for the patron the account line belongs to
59
  payment_type:
61
  payment_type:
Lines 82-87 properties: Link Here
82
      - integer
84
      - integer
83
      - "null"
85
      - "null"
84
    description: Internal patron identifier for the staff member that introduced the account line
86
    description: Internal patron identifier for the staff member that introduced the account line
87
  debits:
88
    type: array
89
    items:
90
      $ref: "debit.yaml"
85
required:
91
required:
86
  - amount
92
  - amount
87
additionalProperties: false
93
additionalProperties: false
(-)a/api/v1/swagger/definitions/debit.yaml (-1 / +3 lines)
Lines 58-64 properties: Link Here
58
      - "null"
58
      - "null"
59
    description: Internal identifier for the library in which the transaction took place
59
    description: Internal identifier for the library in which the transaction took place
60
  patron_id:
60
  patron_id:
61
    type: integer
61
    type:
62
      - integer
63
      - "null"
62
    description: Internal identifier for the patron the account line belongs to
64
    description: Internal identifier for the patron the account line belongs to
63
  payout_type:
65
  payout_type:
64
    type:
66
    type:
(-)a/api/v1/swagger/paths/account.yaml (+115 lines)
Line 0 Link Here
1
---
2
/account/credits:
3
  get:
4
    x-mojo-to: Account#list_credits
5
    operationId: listAccountCredits
6
    tags:
7
      - account
8
    summary: List account credits (global search, not patron-specific)
9
    produces:
10
      - application/json
11
    parameters:
12
      - $ref: "../swagger.yaml#/parameters/match"
13
      - $ref: "../swagger.yaml#/parameters/order_by"
14
      - $ref: "../swagger.yaml#/parameters/page"
15
      - $ref: "../swagger.yaml#/parameters/per_page"
16
      - $ref: "../swagger.yaml#/parameters/q_param"
17
      - $ref: "../swagger.yaml#/parameters/q_body"
18
      - $ref: "../swagger.yaml#/parameters/request_id_header"
19
      - name: x-koha-embed
20
        in: header
21
        required: false
22
        description: Embed list sent as a request header
23
        type: array
24
        items:
25
          type: string
26
          enum:
27
            - debits
28
            - register
29
        collectionFormat: csv
30
    responses:
31
      "200":
32
        description: A list of credits
33
        schema:
34
          type: array
35
          items:
36
            $ref: "../swagger.yaml#/definitions/credit"
37
      "400":
38
        description: |
39
          Bad request. Possible `error_code` attribute values:
40
41
            * `invalid_query`
42
        schema:
43
          $ref: "../swagger.yaml#/definitions/error"
44
      "403":
45
        description: Access forbidden
46
        schema:
47
          $ref: "../swagger.yaml#/definitions/error"
48
      "500":
49
        description: Internal error
50
        schema:
51
          $ref: "../swagger.yaml#/definitions/error"
52
      "503":
53
        description: Under maintenance
54
        schema:
55
          $ref: "../swagger.yaml#/definitions/error"
56
    x-koha-authorization:
57
      permissions:
58
        cash_management: anonymous_refund
59
/account/debits:
60
  get:
61
    x-mojo-to: Account#list_debits
62
    operationId: listAccountDebits
63
    tags:
64
      - account
65
    summary: List account debits (global search, not patron-specific)
66
    produces:
67
      - application/json
68
    parameters:
69
      - $ref: "../swagger.yaml#/parameters/match"
70
      - $ref: "../swagger.yaml#/parameters/order_by"
71
      - $ref: "../swagger.yaml#/parameters/page"
72
      - $ref: "../swagger.yaml#/parameters/per_page"
73
      - $ref: "../swagger.yaml#/parameters/q_param"
74
      - $ref: "../swagger.yaml#/parameters/q_body"
75
      - $ref: "../swagger.yaml#/parameters/request_id_header"
76
      - name: x-koha-embed
77
        in: header
78
        required: false
79
        description: Embed list sent as a request header
80
        type: array
81
        items:
82
          type: string
83
          enum:
84
            - credit
85
            - register
86
        collectionFormat: csv
87
    responses:
88
      "200":
89
        description: A list of debits
90
        schema:
91
          type: array
92
          items:
93
            $ref: "../swagger.yaml#/definitions/debit"
94
      "400":
95
        description: |
96
          Bad request. Possible `error_code` attribute values:
97
98
            * `invalid_query`
99
        schema:
100
          $ref: "../swagger.yaml#/definitions/error"
101
      "403":
102
        description: Access forbidden
103
        schema:
104
          $ref: "../swagger.yaml#/definitions/error"
105
      "500":
106
        description: Internal error
107
        schema:
108
          $ref: "../swagger.yaml#/definitions/error"
109
      "503":
110
        description: Under maintenance
111
        schema:
112
          $ref: "../swagger.yaml#/definitions/error"
113
    x-koha-authorization:
114
      permissions:
115
        cash_management: anonymous_refund
(-)a/api/v1/swagger/swagger.yaml (+4 lines)
Lines 233-238 paths: Link Here
233
    $ref: "./paths/acquisitions_vendors.yaml#/~1acquisitions~1vendors~1{vendor_id}"
233
    $ref: "./paths/acquisitions_vendors.yaml#/~1acquisitions~1vendors~1{vendor_id}"
234
  "/acquisitions/vendors/{vendor_id}/issues":
234
  "/acquisitions/vendors/{vendor_id}/issues":
235
    $ref: "./paths/acquisitions_vendor_issues.yaml#/~1acquisitions~1vendors~1{vendor_id}~1issues"
235
    $ref: "./paths/acquisitions_vendor_issues.yaml#/~1acquisitions~1vendors~1{vendor_id}~1issues"
236
  /account/credits:
237
    $ref: ./paths/account.yaml#/~1account~1credits
238
  /account/debits:
239
    $ref: ./paths/account.yaml#/~1account~1debits
236
  /advanced_editor/macros:
240
  /advanced_editor/macros:
237
    $ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros
241
    $ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros
238
  /advanced_editor/macros/shared:
242
  /advanced_editor/macros/shared:
(-)a/t/db_dependent/Koha/Account/Line.t (-4 / +7 lines)
Lines 787-793 subtest 'checkout() tests' => sub { Link Here
787
};
787
};
788
788
789
subtest 'credits() and debits() tests' => sub {
789
subtest 'credits() and debits() tests' => sub {
790
    plan tests => 12;
790
    plan tests => 15;
791
791
792
    $schema->storage->txn_begin;
792
    $schema->storage->txn_begin;
793
793
Lines 827-833 subtest 'credits() and debits() tests' => sub { Link Here
827
    $credit2->apply( { debits => [ $debit1, $debit2 ] } );
827
    $credit2->apply( { debits => [ $debit1, $debit2 ] } );
828
828
829
    my $credits = $debit1->credits;
829
    my $credits = $debit1->credits;
830
    is( $credits->count, 2, '2 Credits applied to debit 1' );
830
    is( ref($credits),   'Koha::Account::Credits', 'credits() returns a Koha::Account::Credits object' );
831
    is( $credits->count, 2,                        '2 Credits applied to debit 1' );
831
    my $credit = $credits->next;
832
    my $credit = $credits->next;
832
    is( $credit->amount + 0, -5, 'Correct first credit' );
833
    is( $credit->amount + 0, -5, 'Correct first credit' );
833
    $credit = $credits->next;
834
    $credit = $credits->next;
Lines 839-850 subtest 'credits() and debits() tests' => sub { Link Here
839
    is( $credit->amount + 0, -10, 'Correct first credit' );
840
    is( $credit->amount + 0, -10, 'Correct first credit' );
840
841
841
    my $debits = $credit1->debits;
842
    my $debits = $credit1->debits;
842
    is( $debits->count, 1, 'Credit 1 applied to 1 debit' );
843
    is( ref($debits),   'Koha::Account::Debits', 'debits() returns a Koha::Account::Debits object' );
844
    is( $debits->count, 1,                       'Credit 1 applied to 1 debit' );
843
    my $debit = $debits->next;
845
    my $debit = $debits->next;
844
    is( $debit->amount + 0, 8, 'Correct first debit' );
846
    is( $debit->amount + 0, 8, 'Correct first debit' );
845
847
846
    $debits = $credit2->debits;
848
    $debits = $credit2->debits;
847
    is( $debits->count, 2, 'Credit 2 applied to 2 debits' );
849
    is( ref($debits),   'Koha::Account::Debits', 'debits() returns a Koha::Account::Debits object' );
850
    is( $debits->count, 2,                       'Credit 2 applied to 2 debits' );
848
    $debit = $debits->next;
851
    $debit = $debits->next;
849
    is( $debit->amount + 0, 8, 'Correct first debit' );
852
    is( $debit->amount + 0, 8, 'Correct first debit' );
850
    $debit = $debits->next;
853
    $debit = $debits->next;
(-)a/t/db_dependent/api/v1/account.t (-1 / +343 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 4;
21
use Test::NoWarnings;
22
23
use Test::Mojo;
24
25
use t::lib::TestBuilder;
26
use t::lib::Mocks;
27
28
use Koha::Account::Lines;
29
use Koha::Account::CreditTypes;
30
use Koha::Cash::Registers;
31
32
my $schema  = Koha::Database->new->schema;
33
my $builder = t::lib::TestBuilder->new;
34
35
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
36
37
my $t = Test::Mojo->new('Koha::REST::V1');
38
39
subtest 'list_credits() tests' => sub {
40
41
    plan tests => 23;
42
43
    $schema->storage->txn_begin;
44
45
    # Create test patron with anonymous_refund permission
46
    my $librarian = $builder->build_object(
47
        {
48
            class => 'Koha::Patrons',
49
            value => { flags => 0 }
50
        }
51
    );
52
    my $password = 'thePassword123';
53
    $librarian->set_password( { password => $password, skip_validation => 1 } );
54
    $builder->build(
55
        {
56
            source => 'UserPermission',
57
            value  => {
58
                borrowernumber => $librarian->borrowernumber,
59
                module_bit     => 25,                           # cash_management
60
                code           => 'anonymous_refund',
61
            },
62
        }
63
    );
64
    my $userid = $librarian->userid;
65
66
    # Create test patron without permission
67
    my $patron = $builder->build_object(
68
        {
69
            class => 'Koha::Patrons',
70
            value => { flags => 0 }
71
        }
72
    );
73
    my $password2 = 'thePassword321';
74
    $patron->set_password( { password => $password2, skip_validation => 1 } );
75
    my $unauth_userid = $patron->userid;
76
77
    # Create test library
78
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
79
80
    # Mock userenv for creating account lines
81
    t::lib::Mocks::mock_userenv( { patron => $librarian, branchcode => $library->branchcode } );
82
83
    # Create test patrons for account lines
84
    my $patron_1 = $builder->build_object( { class => 'Koha::Patrons' } );
85
    my $patron_2 = $builder->build_object( { class => 'Koha::Patrons' } );
86
87
    # Enable credit numbers for PAYMENT type
88
    my $credit_type = Koha::Account::CreditTypes->find('PAYMENT');
89
    $credit_type->credit_number_enabled(1)->store;
90
91
    # Add credits with credit numbers
92
    t::lib::Mocks::mock_preference( 'AutoCreditNumber', 'incremental' );
93
    my $credit_1 = $patron_1->account->add_credit(
94
        {
95
            amount     => 5.00,
96
            user_id    => $librarian->borrowernumber,
97
            library_id => $library->branchcode,
98
            interface  => 'test',
99
            type       => 'PAYMENT',
100
        }
101
    );
102
    $credit_1->discard_changes;
103
104
    my $credit_2 = $patron_2->account->add_credit(
105
        {
106
            amount     => 10.00,
107
            user_id    => $librarian->borrowernumber,
108
            library_id => $library->branchcode,
109
            interface  => 'test',
110
            type       => 'PAYMENT',
111
        }
112
    );
113
    $credit_2->discard_changes;
114
115
    my $credit_3 = $patron_1->account->add_credit(
116
        {
117
            amount     => 7.50,
118
            user_id    => $librarian->borrowernumber,
119
            library_id => $library->branchcode,
120
            interface  => 'test',
121
            type       => 'PAYMENT',
122
        }
123
    );
124
    $credit_3->discard_changes;
125
126
    # TEST: Unauthorized access (no permission)
127
    $t->get_ok("//$unauth_userid:$password2@/api/v1/account/credits")->status_is(403);
128
129
    # TEST: Authorized access - list all credits
130
    $t->get_ok("//$userid:$password@/api/v1/account/credits")->status_is(200)
131
        ->json_is( '/0/account_line_id', $credit_1->accountlines_id )
132
        ->json_is( '/1/account_line_id', $credit_2->accountlines_id )
133
        ->json_is( '/2/account_line_id', $credit_3->accountlines_id );
134
135
    # TEST: Search by credit_number using query parameter
136
    my $credit_number = $credit_1->credit_number;
137
    $t->get_ok( "//$userid:$password@/api/v1/account/credits" . "?q=" . '{"credit_number":"' . $credit_number . '"}' )
138
        ->status_is(200)->json_is( '/0/account_line_id', $credit_1->accountlines_id )
139
        ->json_is( '/0/credit_number', $credit_number );
140
141
    # TEST: Search by accountlines_id
142
    $t->get_ok( "//$userid:$password@/api/v1/account/credits" . "?q="
143
            . '{"account_line_id":'
144
            . $credit_2->accountlines_id
145
            . '}' )->status_is(200)->json_is( '/0/account_line_id', $credit_2->accountlines_id );
146
147
    # TEST: Pagination
148
    $t->get_ok("//$userid:$password@/api/v1/account/credits?_per_page=1")->status_is(200)
149
        ->json_is( '/0/account_line_id', $credit_1->accountlines_id )->header_is( 'X-Total-Count', 3 );
150
151
    # TEST: Ordering
152
    $t->get_ok("//$userid:$password@/api/v1/account/credits?_order_by=-account_line_id")->status_is(200)
153
        ->json_is( '/0/account_line_id', $credit_3->accountlines_id )
154
        ->json_is( '/1/account_line_id', $credit_2->accountlines_id )
155
        ->json_is( '/2/account_line_id', $credit_1->accountlines_id );
156
157
    $schema->storage->txn_rollback;
158
};
159
160
subtest 'list_credits() with embed tests' => sub {
161
162
    plan tests => 8;
163
164
    $schema->storage->txn_begin;
165
166
    # Create test patron with anonymous_refund permission
167
    my $librarian = $builder->build_object(
168
        {
169
            class => 'Koha::Patrons',
170
            value => { flags => 0 }
171
        }
172
    );
173
    my $password = 'thePassword123';
174
    $librarian->set_password( { password => $password, skip_validation => 1 } );
175
    $builder->build(
176
        {
177
            source => 'UserPermission',
178
            value  => {
179
                borrowernumber => $librarian->borrowernumber,
180
                module_bit     => 25,                           # cash_management
181
                code           => 'anonymous_refund',
182
            },
183
        }
184
    );
185
    my $userid = $librarian->userid;
186
187
    # Create test library
188
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
189
190
    # Mock userenv for creating account lines
191
    t::lib::Mocks::mock_userenv( { patron => $librarian, branchcode => $library->branchcode } );
192
193
    # Create test patron
194
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
195
196
    # Add debit
197
    my $debit = $patron->account->add_debit(
198
        {
199
            amount     => 10.00,
200
            type       => 'OVERDUE',
201
            interface  => 'test',
202
            user_id    => $librarian->borrowernumber,
203
            library_id => $library->branchcode,
204
        }
205
    );
206
207
    # Add credit and apply to debit
208
    my $credit = $patron->account->add_credit(
209
        {
210
            amount     => 10.00,
211
            user_id    => $librarian->borrowernumber,
212
            library_id => $library->branchcode,
213
            interface  => 'test',
214
            type       => 'PAYMENT',
215
        }
216
    );
217
    $credit->apply( { debits => [$debit] } );
218
219
    # TEST: Embed debits
220
    $t->get_ok( "//$userid:$password@/api/v1/account/credits" . "?q="
221
            . '{"account_line_id":'
222
            . $credit->accountlines_id
223
            . '}' => { 'x-koha-embed' => 'debits' } )->status_is(200)
224
        ->json_is( '/0/account_line_id',          $credit->accountlines_id )->json_has('/0/debits')
225
        ->json_is( '/0/debits/0/account_line_id', $debit->accountlines_id );
226
227
    # TEST: Without embed, debits should not be present
228
    $t->get_ok(
229
        "//$userid:$password@/api/v1/account/credits" . "?q=" . '{"account_line_id":' . $credit->accountlines_id . '}' )
230
        ->status_is(200)->json_hasnt('/0/debits');
231
232
    $schema->storage->txn_rollback;
233
};
234
235
subtest 'list_debits() tests' => sub {
236
237
    plan tests => 22;
238
239
    $schema->storage->txn_begin;
240
241
    # Create test patron with anonymous_refund permission
242
    my $librarian = $builder->build_object(
243
        {
244
            class => 'Koha::Patrons',
245
            value => { flags => 0 }
246
        }
247
    );
248
    my $password = 'thePassword123';
249
    $librarian->set_password( { password => $password, skip_validation => 1 } );
250
    $builder->build(
251
        {
252
            source => 'UserPermission',
253
            value  => {
254
                borrowernumber => $librarian->borrowernumber,
255
                module_bit     => 25,                           # cash_management
256
                code           => 'anonymous_refund',
257
            },
258
        }
259
    );
260
    my $userid = $librarian->userid;
261
262
    # Create test patron without permission
263
    my $patron = $builder->build_object(
264
        {
265
            class => 'Koha::Patrons',
266
            value => { flags => 0 }
267
        }
268
    );
269
    my $password2 = 'thePassword321';
270
    $patron->set_password( { password => $password2, skip_validation => 1 } );
271
    my $unauth_userid = $patron->userid;
272
273
    # Create test library
274
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
275
276
    # Mock userenv for creating account lines
277
    t::lib::Mocks::mock_userenv( { patron => $librarian, branchcode => $library->branchcode } );
278
279
    # Create test patrons for account lines
280
    my $patron_1 = $builder->build_object( { class => 'Koha::Patrons' } );
281
    my $patron_2 = $builder->build_object( { class => 'Koha::Patrons' } );
282
283
    # Add debits
284
    my $debit_1 = $patron_1->account->add_debit(
285
        {
286
            amount     => 5.00,
287
            type       => 'OVERDUE',
288
            interface  => 'test',
289
            user_id    => $librarian->borrowernumber,
290
            library_id => $library->branchcode,
291
        }
292
    );
293
294
    my $debit_2 = $patron_2->account->add_debit(
295
        {
296
            amount     => 10.00,
297
            type       => 'LOST',
298
            interface  => 'test',
299
            user_id    => $librarian->borrowernumber,
300
            library_id => $library->branchcode,
301
        }
302
    );
303
304
    my $debit_3 = $patron_1->account->add_debit(
305
        {
306
            amount     => 7.50,
307
            type       => 'OVERDUE',
308
            interface  => 'test',
309
            user_id    => $librarian->borrowernumber,
310
            library_id => $library->branchcode,
311
        }
312
    );
313
314
    # TEST: Unauthorized access (no permission)
315
    $t->get_ok("//$unauth_userid:$password2@/api/v1/account/debits")->status_is(403);
316
317
    # TEST: Authorized access - list all debits
318
    $t->get_ok("//$userid:$password@/api/v1/account/debits")->status_is(200)
319
        ->json_is( '/0/account_line_id', $debit_1->accountlines_id )
320
        ->json_is( '/1/account_line_id', $debit_2->accountlines_id )
321
        ->json_is( '/2/account_line_id', $debit_3->accountlines_id );
322
323
    # TEST: Search by accountlines_id
324
    $t->get_ok(
325
        "//$userid:$password@/api/v1/account/debits" . "?q=" . '{"account_line_id":' . $debit_2->accountlines_id . '}' )
326
        ->status_is(200)->json_is( '/0/account_line_id', $debit_2->accountlines_id );
327
328
    # TEST: Search by type
329
    $t->get_ok( "//$userid:$password@/api/v1/account/debits" . "?q=" . '{"type":"LOST"}' )->status_is(200)
330
        ->json_is( '/0/account_line_id', $debit_2->accountlines_id );
331
332
    # TEST: Pagination
333
    $t->get_ok("//$userid:$password@/api/v1/account/debits?_per_page=1")->status_is(200)
334
        ->json_is( '/0/account_line_id', $debit_1->accountlines_id )->header_is( 'X-Total-Count', 3 );
335
336
    # TEST: Ordering
337
    $t->get_ok("//$userid:$password@/api/v1/account/debits?_order_by=-account_line_id")->status_is(200)
338
        ->json_is( '/0/account_line_id', $debit_3->accountlines_id )
339
        ->json_is( '/1/account_line_id', $debit_2->accountlines_id )
340
        ->json_is( '/2/account_line_id', $debit_1->accountlines_id );
341
342
    $schema->storage->txn_rollback;
343
};

Return to bug 41592