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

(-)a/Koha/REST/V1/Reserve.pm (-49 / +71 lines)
Lines 44-114 sub add { Link Here
44
44
45
    my $body = $c->req->json;
45
    my $body = $c->req->json;
46
46
47
    my $borrowernumber = $body->{borrowernumber};
47
    my $onlyfirst = $body->{onlyfirst};
48
    my $biblionumber = $body->{biblionumber};
48
    my $reserve_group_id;
49
    my $itemnumber = $body->{itemnumber};
49
    if ($onlyfirst) {
50
    my $branchcode = $body->{branchcode};
50
        $reserve_group_id = AddReserveGroup();
51
    my $expirationdate = $body->{expirationdate};
52
    my $borrower = Koha::Patrons->find($borrowernumber);
53
    unless ($borrower) {
54
        return $c->$cb({error => "Borrower not found"}, 404);
55
    }
51
    }
56
52
57
    unless ($biblionumber or $itemnumber) {
53
    my @possible_reserves;
58
        return $c->$cb({
54
    foreach my $reserve (@{ $body->{reserves} }) {
59
            error => "At least one of biblionumber, itemnumber should be given"
55
        my $borrowernumber = $reserve->{borrowernumber};
60
        }, 400);
56
        my $biblionumber = $reserve->{biblionumber};
61
    }
57
        my $itemnumber = $reserve->{itemnumber};
62
    unless ($branchcode) {
58
        my $branchcode = $reserve->{branchcode};
63
        return $c->$cb({
59
        my $expirationdate = $reserve->{expirationdate};
64
            error => "Branchcode is required"
60
65
        }, 400);
61
        my $borrower = Koha::Patrons->find($borrowernumber);
66
    }
62
        unless ($borrower) {
63
            return $c->$cb({error => "Borrower not found"}, 404);
64
        }
67
65
68
    if ($itemnumber) {
66
        unless ($biblionumber or $itemnumber) {
69
        my $item_biblionumber = C4::Biblio::GetBiblionumberFromItemnumber($itemnumber);
70
        if ($biblionumber and $biblionumber != $item_biblionumber) {
71
            return $c->$cb({
67
            return $c->$cb({
72
                error => "Item $itemnumber doesn't belong to biblio $biblionumber"
68
                error => "At least one of biblionumber, itemnumber should be given"
73
            }, 400);
69
            }, 400);
74
        }
70
        }
75
        $biblionumber ||= $item_biblionumber;
71
        unless ($branchcode) {
76
    }
72
            return $c->$cb({
73
                error => "Branchcode is required"
74
            }, 400);
75
        }
76
77
        if ($itemnumber) {
78
            my $item_biblionumber = C4::Biblio::GetBiblionumberFromItemnumber($itemnumber);
79
            if ($biblionumber and $biblionumber != $item_biblionumber) {
80
                return $c->$cb({
81
                    error => "Item $itemnumber doesn't belong to biblio $biblionumber"
82
                }, 400);
83
            }
84
            $biblionumber ||= $item_biblionumber;
85
        }
86
87
        my $biblio = C4::Biblio::GetBiblio($biblionumber);
77
88
78
    my $biblio = C4::Biblio::GetBiblio($biblionumber);
89
        my $can_reserve =
90
          $itemnumber
91
          ? CanItemBeReserved( $borrowernumber, $itemnumber )
92
          : CanBookBeReserved( $borrowernumber, $biblionumber );
79
93
80
    my $can_reserve =
94
        unless ($can_reserve eq 'OK') {
81
      $itemnumber
95
            return $c->$cb({
82
      ? CanItemBeReserved( $borrowernumber, $itemnumber )
96
                error => "Reserve cannot be placed. Reason: $can_reserve"
83
      : CanBookBeReserved( $borrowernumber, $biblionumber );
97
            }, 403);
98
        }
84
99
85
    unless ($can_reserve eq 'OK') {
100
        $reserve->{title} = $biblio->{title};
86
        return $c->$cb({
101
        push @possible_reserves, $reserve;
87
            error => "Reserve cannot be placed. Reason: $can_reserve"
88
        }, 403);
89
    }
102
    }
90
103
91
    my $priority = C4::Reserves::CalculatePriority($biblionumber);
104
    my @reserves;
92
    $itemnumber ||= undef;
105
    foreach my $reserve (@possible_reserves) {
106
        my $borrowernumber = $reserve->{borrowernumber};
107
        my $biblionumber = $reserve->{biblionumber};
108
        my $itemnumber = $reserve->{itemnumber};
109
        my $branchcode = $reserve->{branchcode};
110
        my $expirationdate = $reserve->{expirationdate};
93
111
94
    # AddReserve expects date to be in syspref format
112
        my $priority = C4::Reserves::CalculatePriority($biblionumber);
95
    if ($expirationdate) {
113
        $itemnumber ||= undef;
96
        $expirationdate = output_pref(dt_from_string($expirationdate, 'iso'));
114
97
    }
115
        # AddReserve expects date to be in syspref format
116
        if ($expirationdate) {
117
            $expirationdate = output_pref(dt_from_string($expirationdate, 'iso'));
118
        }
98
119
99
    my $reserve_id = C4::Reserves::AddReserve($branchcode, $borrowernumber,
120
        my $reserve_id = C4::Reserves::AddReserve($branchcode, $borrowernumber,
100
        $biblionumber, undef, $priority, undef, $expirationdate, undef,
121
            $biblionumber, undef, $priority, undef, $expirationdate, undef,
101
        $biblio->{title}, $itemnumber);
122
            $reserve->{title}, $itemnumber, undef, $reserve_group_id);
102
123
103
    unless ($reserve_id) {
124
        unless ($reserve_id) {
104
        return $c->$cb({
125
            return $c->$cb({
105
            error => "Error while placing reserve. See Koha logs for details."
126
                error => "Error while placing reserve. See Koha logs for details."
106
        }, 500);
127
            }, 500);
107
    }
128
        }
108
129
109
    my $reserve = C4::Reserves::GetReserve($reserve_id);
130
        push @reserves, C4::Reserves::GetReserve($reserve_id);
131
    }
110
132
111
    return $c->$cb($reserve, 201);
133
    return $c->$cb(\@reserves, 201);
112
}
134
}
113
135
114
sub edit {
136
sub edit {
(-)a/api/v1/definitions/reserve.json (+4 lines)
Lines 58-63 Link Here
58
        },
58
        },
59
        "suspend_until": {
59
        "suspend_until": {
60
            "description": ""
60
            "description": ""
61
        },
62
        "reserve_group_id": {
63
            "description": "Identifier of the group the reserve belongs to",
64
            "type": ["string", "null"]
61
        }
65
        }
62
    }
66
    }
63
}
67
}
(-)a/api/v1/swagger.json (-20 / +36 lines)
Lines 111-136 Link Here
111
            "schema": {
111
            "schema": {
112
              "type": "object",
112
              "type": "object",
113
              "properties": {
113
              "properties": {
114
                "borrowernumber": {
114
                "reserves": {
115
                  "description": "Borrower internal identifier",
115
                  "description": "Reserves informations",
116
                  "type": "integer"
116
                  "type": "array",
117
                  "items": {
118
                    "type": "object",
119
                    "properties": {
120
                      "borrowernumber": {
121
                        "description": "Borrower internal identifier",
122
                        "type": "integer"
123
                      },
124
                      "biblionumber": {
125
                        "description": "Biblio internal identifier",
126
                        "type": "integer"
127
                      },
128
                      "itemnumber": {
129
                        "description": "Item internal identifier",
130
                        "type": "integer"
131
                      },
132
                      "branchcode": {
133
                        "description": "Pickup location",
134
                        "type": "string"
135
                      },
136
                      "expirationdate": {
137
                        "description": "Reserve end date",
138
                        "type": "string",
139
                        "format": "date"
140
                      }
141
                    }
142
                  }
117
                },
143
                },
118
                "biblionumber": {
144
                "onlyfirst": {
119
                  "description": "Biblio internal identifier",
145
                  "description": "Reserve only first available item",
120
                  "type": "integer"
146
                  "type": "boolean"
121
                },
122
                "itemnumber": {
123
                  "description": "Item internal identifier",
124
                  "type": "integer"
125
                },
126
                "branchcode": {
127
                  "description": "Pickup location",
128
                  "type": "string"
129
                },
130
                "expirationdate": {
131
                  "description": "Reserve end date",
132
                  "type": "string",
133
                  "format": "date"
134
                }
147
                }
135
              }
148
              }
136
            }
149
            }
Lines 141-147 Link Here
141
        "responses": {
154
        "responses": {
142
          "201": {
155
          "201": {
143
            "description": "Created reserve",
156
            "description": "Created reserve",
144
            "schema": { "$ref": "#/definitions/reserve" }
157
            "schema": {
158
              "type": "array",
159
              "items": { "$ref": "#/definitions/reserve" }
160
            }
145
          },
161
          },
146
          "400": {
162
          "400": {
147
            "description": "Missing or wrong parameters",
163
            "description": "Missing or wrong parameters",
(-)a/t/db_dependent/api/v1/reserves.t (-9 / +45 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 30;
20
use Test::More tests => 37;
21
use Test::Mojo;
21
use Test::Mojo;
22
22
23
use DateTime;
23
use DateTime;
Lines 103-119 $dbh->do(q{ Link Here
103
103
104
my $expirationdate = DateTime->now->add(days => 10)->ymd;
104
my $expirationdate = DateTime->now->add(days => 10)->ymd;
105
my $post_data = {
105
my $post_data = {
106
    borrowernumber => int($borrowernumber),
106
    reserves => [
107
    biblionumber => int($biblionumber),
107
        {
108
    itemnumber => int($itemnumber),
108
            borrowernumber => int($borrowernumber),
109
    branchcode => $branchcode,
109
            biblionumber => int($biblionumber),
110
    expirationdate => $expirationdate,
110
            itemnumber => int($itemnumber),
111
            branchcode => $branchcode,
112
            expirationdate => $expirationdate,
113
        },
114
    ],
111
};
115
};
112
$t->post_ok("/api/v1/reserves" => json => $post_data)
116
$t->post_ok("/api/v1/reserves" => json => $post_data)
113
  ->status_is(201)
117
  ->status_is(201)
114
  ->json_has('/reserve_id');
118
  ->json_has('/0/reserve_id');
115
119
116
$reserve_id = $t->tx->res->json->{reserve_id};
120
$reserve_id = $t->tx->res->json->[0]->{reserve_id};
117
121
118
$t->get_ok("/api/v1/reserves?borrowernumber=$borrowernumber")
122
$t->get_ok("/api/v1/reserves?borrowernumber=$borrowernumber")
119
  ->status_is(200)
123
  ->status_is(200)
Lines 125-130 $t->post_ok("/api/v1/reserves" => json => $post_data) Link Here
125
  ->status_is(403)
129
  ->status_is(403)
126
  ->json_like('/error', qr/tooManyReserves/);
130
  ->json_like('/error', qr/tooManyReserves/);
127
131
132
$t->delete_ok("/api/v1/reserves/$reserve_id")
133
  ->status_is(200);
134
135
my $biblionumber2 = create_biblio('RESTful Web APIs 2');
136
my $itemnumber2 = create_item($biblionumber2, 'TEST000002');
137
138
$post_data = {
139
    onlyfirst => \1,
140
    reserves => [
141
        {
142
            borrowernumber => int($borrowernumber),
143
            biblionumber => int($biblionumber),
144
            itemnumber => int($itemnumber),
145
            branchcode => $branchcode,
146
            expirationdate => $expirationdate,
147
        },
148
        {
149
            borrowernumber => int($borrowernumber),
150
            biblionumber => int($biblionumber2),
151
            itemnumber => int($itemnumber2),
152
            branchcode => $branchcode,
153
            expirationdate => $expirationdate,
154
        },
155
    ],
156
};
157
$t->post_ok("/api/v1/reserves" => json => $post_data)
158
  ->status_is(201);
159
160
$t->get_ok("/api/v1/reserves?borrowernumber=$borrowernumber")
161
  ->status_is(200);
162
163
my $json = $t->tx->res->json;
164
is($json->[0]->{reserve_group_id}, $json->[1]->{reserve_group_id}, "Both reserves belong to the same reserve group");
128
165
129
$dbh->rollback;
166
$dbh->rollback;
130
167
131
- 

Return to bug 15566