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

(-)a/Koha/REST/V1/Borrowers/Issues.pm (+60 lines)
Line 0 Link Here
1
package Koha::REST::V1::Borrowers::Issues;
2
3
use Modern::Perl;
4
5
use Mojo::Base 'Mojolicious::Controller';
6
7
use C4::Circulation;
8
9
sub list_borrower_issues {
10
    my ($c, $args, $cb) = @_;
11
12
    my $issues = C4::Circulation::GetIssues({
13
        borrowernumber => $args->{borrowernumber}
14
    });
15
16
    $c->$cb($issues, 200);
17
}
18
19
sub get_borrower_issue {
20
    my ($c, $args, $cb) = @_;
21
22
    my $borrowernumber = $args->{borrowernumber};
23
    my $itemnumber = $args->{itemnumber};
24
25
    my ($issue) = @{ C4::Circulation::GetIssues({ itemnumber => $itemnumber }) };
26
    if (!$issue or $borrowernumber != $issue->{borrowernumber}) {
27
        return $c->$cb({
28
            error => "Item $itemnumber is not issued to borrower $borrowernumber"
29
        }, 404);
30
    }
31
32
    return $c->$cb($issue, 200);
33
}
34
35
sub renew_borrower_issue {
36
    my ($c, $args, $cb) = @_;
37
38
    my $borrowernumber = $args->{borrowernumber};
39
    my $itemnumber = $args->{itemnumber};
40
41
    my ($issue) = @{ C4::Circulation::GetIssues({ itemnumber => $itemnumber }) };
42
    if (!$issue or $borrowernumber != $issue->{borrowernumber}) {
43
        return $c->$cb({
44
            error => "Item $itemnumber is not issued to borrower $borrowernumber"
45
        }, 404);
46
    }
47
48
    my ($can_renew, $error) = C4::Circulation::CanBookBeRenewed($borrowernumber,
49
        $itemnumber);
50
    if (!$can_renew) {
51
        return $c->$cb({error => "Renewal not authorized ($error)"}, 403);
52
    }
53
54
    AddRenewal($borrowernumber, $itemnumber, $issue->{branchcode});
55
    ($issue) = @{ C4::Circulation::GetIssues({ itemnumber => $itemnumber }) };
56
57
    return $c->$cb($issue, 200);
58
}
59
60
1;
(-)a/api/v1/swagger.json (+138 lines)
Lines 77-82 Link Here
77
          { "multi_key_auth": [] }
77
          { "multi_key_auth": [] }
78
        ]
78
        ]
79
      }
79
      }
80
    },
81
    "/borrowers/{borrowernumber}/issues": {
82
      "get": {
83
        "x-mojo-controller": "Koha::REST::V1::Borrowers::Issues",
84
        "operationId": "listBorrowerIssues",
85
        "tags": ["borrowers", "issues"],
86
        "parameters": [
87
          {
88
            "$ref": "#/parameters/borrowernumberPathParam"
89
          }
90
        ],
91
        "produces": [
92
          "application/json"
93
        ],
94
        "responses": {
95
          "200": {
96
            "description": "A list of issues",
97
            "schema": {
98
              "$ref": "#/definitions/issues"
99
            }
100
          },
101
          "404": {
102
            "description": "Borrower not found",
103
            "schema": {
104
              "$ref": "#/definitions/error"
105
            }
106
          }
107
        }
108
      }
109
    },
110
    "/borrowers/{borrowernumber}/issues/{itemnumber}": {
111
      "get": {
112
        "x-mojo-controller": "Koha::REST::V1::Borrowers::Issues",
113
        "operationId": "getBorrowerIssue",
114
        "tags": ["borrowers", "issues"],
115
        "parameters": [
116
          { "$ref": "#/parameters/borrowernumberPathParam" },
117
          { "$ref": "#/parameters/itemnumberPathParam" }
118
        ],
119
        "produces": ["application/json"],
120
        "responses": {
121
          "200": {
122
            "description": "Updated borrower's issue",
123
            "schema": { "$ref": "#/definitions/issue" }
124
          },
125
          "404": {
126
            "description": "Issue not found",
127
            "schema": { "$ref": "#/definitions/error" }
128
          }
129
        }
130
      },
131
      "put": {
132
        "x-mojo-controller": "Koha::REST::V1::Borrowers::Issues",
133
        "operationId": "renewBorrowerIssue",
134
        "tags": ["borrowers", "issues"],
135
        "parameters": [
136
          { "$ref": "#/parameters/borrowernumberPathParam" },
137
          { "$ref": "#/parameters/itemnumberPathParam" }
138
        ],
139
        "produces": ["application/json"],
140
        "responses": {
141
          "200": {
142
            "description": "Updated borrower's issue",
143
            "schema": { "$ref": "#/definitions/issue" }
144
          },
145
          "403": {
146
            "description": "Cannot renew issue",
147
            "schema": { "$ref": "#/definitions/error" }
148
          },
149
          "404": {
150
            "description": "Issue not found",
151
            "schema": { "$ref": "#/definitions/error" }
152
          }
153
        }
154
      }
80
    }
155
    }
81
  },
156
  },
82
  "definitions": {
157
  "definitions": {
Lines 97-105 Link Here
97
        }
172
        }
98
      }
173
      }
99
    },
174
    },
175
    "issues": {
176
      "type": "array",
177
      "items": {
178
        "$ref": "#/definitions/issue"
179
      }
180
    },
181
    "issue": {
182
      "type": "object",
183
      "properties": {
184
        "borrowernumber": {
185
          "$ref": "#/definitions/borrowernumber"
186
        },
187
        "itemnumber": {
188
          "$ref": "#/definitions/itemnumber"
189
        },
190
        "date_due": {
191
          "description": "Due date"
192
        },
193
        "branchcode": {
194
          "$ref": "#/definitions/branchcode"
195
        },
196
        "issuingbranch": {
197
          "description": "Code of the branch where issue was made"
198
        },
199
        "returndate": {
200
          "description": "Date the item was returned"
201
        },
202
        "lastreneweddate": {
203
          "description": "Date the item was last renewed"
204
        },
205
        "return": {
206
          "description": "?"
207
        },
208
        "renewals": {
209
          "description": "Number of renewals"
210
        },
211
        "auto_renew": {
212
          "description": "Auto renewal"
213
        },
214
        "timestamp": {
215
          "description": "Last update time"
216
        },
217
        "issuedate": {
218
          "description": "Date the item was issued"
219
        },
220
        "onsite_checkout": {
221
          "description": "On site checkout"
222
        }
223
      }
224
    },
100
    "borrowernumber": {
225
    "borrowernumber": {
101
      "description": "Borrower internal identifier"
226
      "description": "Borrower internal identifier"
102
    },
227
    },
228
    "branchcode": {
229
      "description": "Branch code"
230
    },
231
    "itemnumber": {
232
      "description": "Item internal identifier"
233
    },
103
    "error": {
234
    "error": {
104
      "type": "object",
235
      "type": "object",
105
      "properties": {
236
      "properties": {
Lines 117-122 Link Here
117
      "description": "Internal borrower identifier",
248
      "description": "Internal borrower identifier",
118
      "required": "true",
249
      "required": "true",
119
      "type": "integer"
250
      "type": "integer"
251
    },
252
    "itemnumberPathParam": {
253
      "name": "itemnumber",
254
      "in": "path",
255
      "description": "Internal item identifier",
256
      "required": "true",
257
      "type": "integer"
120
    }
258
    }
121
  },
259
  },
122
  "securityDefinitions": {
260
  "securityDefinitions": {
(-)a/t/db_dependent/api/v1/borrowers/issues.t (-1 / +131 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
5
use Test::More tests => 33;
6
use Test::MockModule;
7
use Test::Mojo;
8
9
use DateTime;
10
use MARC::Record;
11
12
use C4::Context;
13
use C4::Biblio;
14
use C4::Circulation;
15
use C4::Items;
16
17
use Koha::Database;
18
use Koha::Borrower;
19
20
my $dbh = C4::Context->dbh;
21
$dbh->{AutoCommit} = 0;
22
$dbh->{RaiseError} = 1;
23
24
my $c4_context = new Test::MockModule('C4::Context');
25
$c4_context->mock('userenv', \&Mock_userenv);
26
27
my $t = Test::Mojo->new('Koha::REST::V1');
28
29
my $schema = Koha::Database->new->schema;
30
my $categorycode = $schema->resultset('Category')->first->categorycode;
31
my $branchcode = $schema->resultset('Branch')->first->branchcode;
32
33
my $borrower = Koha::Borrower->new;
34
$borrower->categorycode( $categorycode );
35
$borrower->branchcode( $branchcode );
36
$borrower->surname("Test Surname");
37
$borrower->store;
38
my $borrowernumber = $borrower->borrowernumber;
39
40
$t->get_ok("/v1/borrowers/$borrowernumber/issues")
41
  ->status_is(200)
42
  ->json_is([]);
43
44
my $notexisting_borrowernumber = $borrowernumber + 1;
45
$t->get_ok("/v1/borrowers/$notexisting_borrowernumber/issues")
46
  ->status_is(200)
47
  ->json_is([]);
48
49
my $biblionumber = create_biblio('RESTful Web APIs');
50
my $itemnumber1 = create_item($biblionumber, 'TEST000001');
51
my $itemnumber2 = create_item($biblionumber, 'TEST000002');
52
53
my $date_due = DateTime->now->add(weeks => 2);
54
my $issue1 = C4::Circulation::AddIssue($borrower->unblessed, 'TEST000001', $date_due);
55
my $date_due1 = Koha::DateUtils::dt_from_string( $issue1->date_due );
56
my $issue2 = C4::Circulation::AddIssue($borrower->unblessed, 'TEST000002', $date_due);
57
my $date_due2 = Koha::DateUtils::dt_from_string( $issue2->date_due );
58
59
$t->get_ok("/v1/borrowers/$borrowernumber/issues")
60
  ->status_is(200)
61
  ->json_is('/0/borrowernumber' => $borrowernumber)
62
  ->json_is('/0/itemnumber' => $itemnumber1)
63
  ->json_is('/0/date_due' => $date_due1->ymd . ' ' . $date_due1->hms)
64
  ->json_is('/1/borrowernumber' => $borrowernumber)
65
  ->json_is('/1/itemnumber' => $itemnumber2)
66
  ->json_is('/1/date_due' => $date_due2->ymd . ' ' . $date_due2->hms)
67
  ->json_hasnt('/2');
68
69
$t->get_ok("/v1/borrowers/$borrowernumber/issues/$itemnumber1")
70
  ->status_is(200)
71
  ->json_is('/date_due' => $date_due1->ymd . ' ' . $date_due1->hms);
72
73
$t->get_ok("/v1/borrowers/$borrowernumber/issues/$itemnumber2")
74
  ->status_is(200)
75
  ->json_is('/date_due' => $date_due2->ymd . ' ' . $date_due2->hms);
76
77
78
$dbh->do('DELETE FROM issuingrules');
79
$dbh->do(q{
80
    INSERT INTO issuingrules (categorycode, branchcode, itemtype, issuelength, renewalsallowed)
81
    VALUES (?, ?, ?, ?, ?)
82
}, {}, '*', '*', '*', 7, 1);
83
84
my $expected_datedue = DateTime->now->add(days => 7)->set(hour => 23, minute => 59, second => 0);
85
$t->put_ok("/v1/borrowers/$borrowernumber/issues/$itemnumber1")
86
  ->status_is(200)
87
  ->json_is('/date_due' => $expected_datedue->ymd . ' ' . $expected_datedue->hms);
88
89
$t->put_ok("/v1/borrowers/$borrowernumber/issues/$itemnumber1")
90
  ->status_is(403)
91
  ->json_is({ error => 'Renewal not authorized (too_many)' });
92
93
$t->put_ok("/v1/borrowers/$notexisting_borrowernumber/issues/$itemnumber1")
94
  ->status_is(404)
95
  ->json_is({ error => "Item $itemnumber1 is not issued to borrower $notexisting_borrowernumber" });
96
97
my $notexisting_itemnumber = $itemnumber2 + 1;
98
$t->put_ok("/v1/borrowers/$borrowernumber/issues/$notexisting_itemnumber")
99
  ->status_is(404)
100
  ->json_is({ error => "Item $notexisting_itemnumber is not issued to borrower $borrowernumber" });
101
102
$dbh->rollback;
103
104
sub create_biblio {
105
    my ($title) = @_;
106
107
    my $record = new MARC::Record;
108
    $record->append_fields(
109
        new MARC::Field('200', ' ', ' ', a => $title),
110
    );
111
112
    my ($biblionumber) = C4::Biblio::AddBiblio($record, '');
113
114
    return $biblionumber;
115
}
116
117
sub create_item {
118
    my ($biblionumber, $barcode) = @_;
119
120
    my $item = {
121
        barcode => $barcode,
122
    };
123
124
    my $itemnumber = C4::Items::AddItem($item, $biblionumber);
125
126
    return $itemnumber;
127
}
128
129
sub Mock_userenv {
130
    return { branch => $branchcode };
131
}

Return to bug 13895