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

(-)a/Koha/REST/V1/Accountline.pm (+83 lines)
Lines 20-26 use Modern::Perl; Link Here
20
use Mojo::Base 'Mojolicious::Controller';
20
use Mojo::Base 'Mojolicious::Controller';
21
21
22
use C4::Auth qw( haspermission );
22
use C4::Auth qw( haspermission );
23
use C4::Accounts qw( makepayment makepartialpayment recordpayment );
24
use C4::Members qw( GetMember );
23
use Koha::Accountlines;
25
use Koha::Accountlines;
26
use Scalar::Util qw( looks_like_number );
24
27
25
sub list {
28
sub list {
26
    my ($c, $args, $cb) = @_;
29
    my ($c, $args, $cb) = @_;
Lines 58-61 sub edit { Link Here
58
    return $c->$cb($accountline->unblessed(), 200);
61
    return $c->$cb($accountline->unblessed(), 200);
59
}
62
}
60
63
64
65
sub pay {
66
    my ($c, $args, $cb) = @_;
67
68
    my $user = $c->stash('koha.user');
69
    unless ($user && haspermission($user->userid, {updatecharges => 1})) {
70
        return $c->$cb({error => "You don't have the required permission"}, 403);
71
    }
72
73
    my $accountline = Koha::Accountlines->find($args->{accountlines_id});
74
    unless ($accountline) {
75
        return $c->$cb({error => "Accountline not found"}, 404);
76
    }
77
78
    makepayment($accountline->accountlines_id,
79
                $accountline->borrowernumber,
80
                $accountline->accountno,
81
                $accountline->amount);
82
83
    $accountline = Koha::Accountlines->find($args->{accountlines_id});
84
    return $c->$cb($accountline->unblessed(), 200);
85
}
86
87
sub partialpay {
88
    my ($c, $args, $cb) = @_;
89
90
    my $user = $c->stash('koha.user');
91
    unless ($user && haspermission($user->userid, {updatecharges => 1})) {
92
        return $c->$cb({error => "You don't have the required permission"}, 403);
93
    }
94
95
    my $accountline = Koha::Accountlines->find($args->{accountlines_id});
96
    unless ($accountline) {
97
        return $c->$cb({error => "Accountline not found"}, 404);
98
    }
99
100
    my $body = $c->req->json;
101
    my $amount = $body->{amount};
102
    my $note = $body->{note} || '';
103
104
    unless ($amount && looks_like_number($amount)) {
105
        return $c->$cb({error => "Invalid amount"}, 400);
106
    }
107
108
    makepartialpayment($accountline->accountlines_id,
109
                       $accountline->borrowernumber,
110
                       $accountline->accountno,
111
                       $amount, '', '', $note);
112
113
    $accountline = Koha::Accountlines->find($args->{accountlines_id});
114
    return $c->$cb($accountline->unblessed(), 200);
115
}
116
117
118
sub payamount   {
119
    my ($c, $args, $cb) = @_;
120
121
    my $user = $c->stash('koha.user');
122
    unless ($user && haspermission($user->userid, {updatecharges => 1})) {
123
        return $c->$cb({error => "You don't have the required permission"}, 403);
124
    }
125
126
    my $borrower = GetMember(borrowernumber => $args->{borrowernumber});
127
    unless ($borrower) {
128
        return $c->$cb({error => "Borrower not found"}, 404);
129
    }
130
131
    my $body = $c->req->json;
132
    my $amount = $body->{amount};
133
    my $note = $body->{note} || '';
134
135
    unless ($amount && looks_like_number($amount)) {
136
        return $c->$cb({error => "Invalid amount"}, 400);
137
    }
138
139
    recordpayment($borrower->{borrowernumber}, $amount, '', $note);
140
141
    return $c->$cb({amount => $amount}, 200);
142
}
143
61
1;
144
1;
(-)a/api/v1/definitions/amountpaid.json (+9 lines)
Line 0 Link Here
1
{
2
  "type": "object",
3
  "properties": {
4
    "amount": {
5
      "type": "number",
6
      "description": "Amount paid"
7
    }
8
  }
9
}
(-)a/api/v1/definitions/index.json (+2 lines)
Lines 1-6 Link Here
1
{
1
{
2
    "amountpaid": { "$ref": "amountpaid.json" },
2
    "accountline": { "$ref": "accountline.json" },
3
    "accountline": { "$ref": "accountline.json" },
3
    "editAccountlineBody": { "$ref": "editAccountlineBody.json" },
4
    "editAccountlineBody": { "$ref": "editAccountlineBody.json" },
5
    "partialpayAccountlineBody": { "$ref": "partialpayAccountlineBody.json" },
4
    "patron": { "$ref": "patron.json" },
6
    "patron": { "$ref": "patron.json" },
5
    "holds": { "$ref": "holds.json" },
7
    "holds": { "$ref": "holds.json" },
6
    "hold": { "$ref": "hold.json" },
8
    "hold": { "$ref": "hold.json" },
(-)a/api/v1/definitions/partialpayAccountlineBody.json (+11 lines)
Line 0 Link Here
1
{
2
    "type": "object",
3
        "properties": {
4
            "amount": {
5
                "description": "Amount to pay"
6
            },
7
            "note": {
8
                "description": "Payment note"
9
            }
10
      }
11
}
(-)a/api/v1/swagger.json (+115 lines)
Lines 298-303 Link Here
298
          }
298
          }
299
        }
299
        }
300
      }
300
      }
301
    },
302
    "/accountlines/{accountlines_id}/payment": {
303
      "put": {
304
        "operationId": "payAccountlines",
305
        "tags": ["accountlines"],
306
        "produces": [
307
          "application/json"
308
        ],
309
        "parameters": [
310
          { "$ref": "#/parameters/accountlinesIdPathParam" }
311
        ],
312
        "produces": ["application/json"],
313
        "responses": {
314
          "200": {
315
            "description": "Paid accountline",
316
            "schema": { "$ref": "#/definitions/accountline" }
317
          },
318
          "400": {
319
            "description": "Missing or wrong parameters",
320
            "schema": { "$ref": "#/definitions/error" }
321
          },
322
          "403": {
323
            "description": "Access forbidden",
324
            "schema": {
325
              "$ref": "#/definitions/error"
326
            }
327
          },
328
          "404": {
329
            "description": "Accountline not found",
330
            "schema": { "$ref": "#/definitions/error" }
331
          }
332
        }
333
      }
334
    },
335
    "/accountlines/{accountlines_id}/partialpayment": {
336
      "put": {
337
        "operationId": "partialpayAccountlines",
338
        "tags": ["accountlines"],
339
        "produces": [
340
          "application/json"
341
        ],
342
        "parameters": [
343
          { "$ref": "#/parameters/accountlinesIdPathParam" },
344
          {
345
            "name": "body",
346
            "in": "body",
347
            "description": "A JSON object containing fields to modify",
348
            "required": true,
349
            "schema": { "$ref": "#/definitions/partialpayAccountlineBody" }
350
          }
351
        ],
352
        "consumes": ["application/json"],
353
        "produces": ["application/json"],
354
        "responses": {
355
          "200": {
356
            "description": "Paid accountline",
357
            "schema": { "$ref": "#/definitions/accountline" }
358
          },
359
          "400": {
360
            "description": "Missing or wrong parameters",
361
            "schema": { "$ref": "#/definitions/error" }
362
          },
363
          "403": {
364
            "description": "Access forbidden",
365
            "schema": {
366
              "$ref": "#/definitions/error"
367
            }
368
          },
369
          "404": {
370
            "description": "Accountline not found",
371
            "schema": { "$ref": "#/definitions/error" }
372
          }
373
        }
374
      }
375
    },
376
    "/accountlines/{borrowernumber}/amountpayment": {
377
      "put": {
378
        "operationId": "payamountAccountlines",
379
        "tags": ["accountlines"],
380
        "produces": [
381
          "application/json"
382
        ],
383
        "parameters": [
384
          { "$ref": "#/parameters/borrowernumberPathParam" },
385
          {
386
            "name": "body",
387
            "in": "body",
388
            "description": "A JSON object containing fields to modify",
389
            "required": true,
390
            "schema": { "$ref": "#/definitions/partialpayAccountlineBody" }
391
          }
392
        ],
393
        "consumes": ["application/json"],
394
        "produces": ["application/json"],
395
        "responses": {
396
          "200": {
397
            "description": "Amount paid",
398
            "schema": { "$ref": "#/definitions/amountpaid" }
399
          },
400
          "400": {
401
            "description": "Missing or wrong parameters",
402
            "schema": { "$ref": "#/definitions/error" }
403
          },
404
          "403": {
405
            "description": "Access forbidden",
406
            "schema": {
407
              "$ref": "#/definitions/error"
408
            }
409
          },
410
          "404": {
411
            "description": "Borrower not found",
412
            "schema": { "$ref": "#/definitions/error" }
413
          }
414
        }
415
      }
301
    }
416
    }
302
  },
417
  },
303
  "definitions": {
418
  "definitions": {
(-)a/t/db_dependent/api/v1/accountlines.t (-6 / +109 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 18;
20
use Test::More tests => 46;
21
use Test::Mojo;
21
use Test::Mojo;
22
use t::lib::TestBuilder;
22
use t::lib::TestBuilder;
23
23
Lines 44-49 $t->get_ok('/api/v1/accountlines') Link Here
44
$t->put_ok("/api/v1/accountlines/11224409" => json => {'amount' => -5})
44
$t->put_ok("/api/v1/accountlines/11224409" => json => {'amount' => -5})
45
    ->status_is(403);
45
    ->status_is(403);
46
46
47
$t->put_ok("/api/v1/accountlines/11224408/payment")
48
    ->status_is(403);
49
50
$t->put_ok("/api/v1/accountlines/11224407/partialpayment" => json => {'amount' => 8})
51
    ->status_is(403);
52
47
my $loggedinuser = $builder->build({
53
my $loggedinuser = $builder->build({
48
    source => 'Borrower',
54
    source => 'Borrower',
49
    value => {
55
    value => {
Lines 73-80 my $borrowernumber2 = $borrower2->{borrowernumber}; Link Here
73
79
74
$dbh->do(q| DELETE FROM accountlines |);
80
$dbh->do(q| DELETE FROM accountlines |);
75
$dbh->do(q|
81
$dbh->do(q|
76
    INSERT INTO accountlines (borrowernumber, amount, accounttype)
82
    INSERT INTO accountlines (borrowernumber, amount, accounttype, amountoutstanding)
77
    VALUES (?, 20, 'A'), (?, 40, 'F'), (?, 80, 'F'), (?, 10, 'F')
83
    VALUES (?, 20, 'A', 20), (?, 40, 'F', 40), (?, 80, 'F', 80), (?, 10, 'F', 10)
78
    |, undef, $borrowernumber, $borrowernumber, $borrowernumber, $borrowernumber2);
84
    |, undef, $borrowernumber, $borrowernumber, $borrowernumber, $borrowernumber2);
79
85
80
my $session = C4::Auth::get_session('');
86
my $session = C4::Auth::get_session('');
Lines 113-119 my $put_data = { Link Here
113
119
114
$tx = $t->ua->build_tx(
120
$tx = $t->ua->build_tx(
115
    PUT => "/api/v1/accountlines/11224409"
121
    PUT => "/api/v1/accountlines/11224409"
116
        => {Accept => '*/*'}
117
        => json => $put_data);
122
        => json => $put_data);
118
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
123
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
119
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
124
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
Lines 124-130 my $accountline_to_edit = Koha::Accountlines->search({'borrowernumber' => $borro Link Here
124
129
125
$tx = $t->ua->build_tx(
130
$tx = $t->ua->build_tx(
126
    PUT => "/api/v1/accountlines/$accountline_to_edit->{accountlines_id}"
131
    PUT => "/api/v1/accountlines/$accountline_to_edit->{accountlines_id}"
127
        => {Accept => '*/*'}
128
        => json => $put_data);
132
        => json => $put_data);
129
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
133
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
130
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
134
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
Lines 138-142 is($accountline_edited->{amountoutstanding}, '-19.000000'); Link Here
138
142
139
143
140
# Payment tests
144
# Payment tests
145
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/4562765765/payment");
146
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
147
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
148
$t->request_ok($tx)
149
  ->status_is(404);
150
151
my $accountline_to_pay = Koha::Accountlines->search({'borrowernumber' => $borrowernumber, 'amount' => 20})->unblessed()->[0];
152
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/$accountline_to_pay->{accountlines_id}/payment");
153
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
154
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
155
$t->request_ok($tx)
156
  ->status_is(200);
157
158
my $accountline_paid = Koha::Accountlines->search({'borrowernumber' => $borrowernumber, 'amount' => -20})->unblessed()->[0];
159
ok($accountline_paid);
160
161
# Partial payment tests
162
$put_data = {
163
    'amount' => 17,
164
    'note' => 'Partial payment'
165
};
166
167
$tx = $t->ua->build_tx(
168
    PUT => "/api/v1/accountlines/11224419/partialpayment"
169
        => json => $put_data);
170
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
171
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
172
$t->request_ok($tx)
173
    ->status_is(404);
174
175
my $accountline_to_partiallypay = Koha::Accountlines->search({'borrowernumber' => $borrowernumber, 'amount' => 80})->unblessed()->[0];
176
177
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/$accountline_to_partiallypay->{accountlines_id}/partialpayment" => json => {amount => 'foo'});
178
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
179
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
180
$t->request_ok($tx)
181
  ->status_is(400);
182
183
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/$accountline_to_partiallypay->{accountlines_id}/partialpayment" => json => $put_data);
184
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
185
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
186
$t->request_ok($tx)
187
  ->status_is(200);
188
189
$accountline_to_partiallypay = Koha::Accountlines->search({'borrowernumber' => $borrowernumber, 'amount' => 80})->unblessed()->[0];
190
is($accountline_to_partiallypay->{amountoutstanding}, '63.000000');
191
192
my $accountline_partiallypaid = Koha::Accountlines->search({'borrowernumber' => $borrowernumber, 'amount' => 17})->unblessed()->[0];
193
ok($accountline_partiallypaid);
194
195
# Pay amount tests
196
my $borrower3 = $builder->build({
197
    source => 'Borrower',
198
    value => {
199
        branchcode   => $branchcode,
200
        categorycode => $categorycode,
201
    }
202
});
203
my $borrowernumber3 = $borrower3->{borrowernumber};
204
205
$dbh->do(q|
206
    INSERT INTO accountlines (borrowernumber, amount, accounttype, amountoutstanding)
207
    VALUES (?, 26, 'A', 26)
208
    |, undef, $borrowernumber3);
209
210
$t->put_ok("/api/v1/accountlines/$borrowernumber3/amountpayment" => json => {'amount' => 8})
211
    ->status_is(403);
212
213
my $put_data2 = {
214
    'amount' => 24,
215
    'note' => 'Partial payment'
216
};
217
218
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/8789798797/amountpayment" => json => $put_data2);
219
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
220
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
221
$t->request_ok($tx)
222
  ->status_is(404);
223
224
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/$borrowernumber3/amountpayment" => json => {amount => 0});
225
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
226
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
227
$t->request_ok($tx)
228
  ->status_is(400);
229
230
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/$borrowernumber3/amountpayment" => json => {amount => 'foo'});
231
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
232
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
233
$t->request_ok($tx)
234
  ->status_is(400);
235
236
$tx = $t->ua->build_tx(PUT => "/api/v1/accountlines/$borrowernumber3/amountpayment" => json => $put_data2);
237
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
238
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
239
$t->request_ok($tx)
240
  ->status_is(200);
241
242
$accountline_partiallypaid = Koha::Accountlines->search({'borrowernumber' => $borrowernumber3, 'amount' => 26})->unblessed()->[0];
243
244
is($accountline_partiallypaid->{amountoutstanding}, '2.000000');
141
245
142
$dbh->rollback;
246
$dbh->rollback;
143
- 

Return to bug 15165