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

(-)a/Koha/Patron/Quota/Usage.pm (+25 lines)
Lines 39-44 sub quota { Link Here
39
    return Koha::Patron::Quota->_new_from_dbic($rs);
39
    return Koha::Patron::Quota->_new_from_dbic($rs);
40
}
40
}
41
41
42
=head3 checkout
43
44
    my $checkout = $usage->checkout;
45
46
=cut
47
48
sub checkout {
49
    my ($self) = @_;
50
51
    my $checkout_rs = $self->_result->checkout;
52
    return unless $checkout_rs;
53
    return Koha::Checkout->_new_from_dbic($checkout_rs);
54
}
55
42
=head3 store
56
=head3 store
43
57
44
Overloaded I<store> method to set implement issue_id foreign key in code
58
Overloaded I<store> method to set implement issue_id foreign key in code
Lines 62-67 sub store { Link Here
62
    return $self->SUPER::store();
76
    return $self->SUPER::store();
63
}
77
}
64
78
79
=head3 to_api_mapping
80
81
This method returns the mapping for representing a Koha::Patron::Quota::Usage
82
object on the API.
83
84
=cut
85
86
sub to_api_mapping {
87
    return { issue_id => 'checkout_id' };
88
}
89
65
=head2 Internal methods
90
=head2 Internal methods
66
91
67
=head3 _type
92
=head3 _type
(-)a/Koha/REST/V1/Patrons/Quotas.pm (-20 / +38 lines)
Lines 21-27 sub list { Link Here
21
    my $c = shift->openapi->valid_input or return;
21
    my $c = shift->openapi->valid_input or return;
22
22
23
    return try {
23
    return try {
24
        my $patron_id = $c->param('patron_id');
24
        my $patron_id   = $c->param('patron_id');
25
        my $only_active = $c->param('only_active');
25
        my $only_active = $c->param('only_active');
26
26
27
        # Remove params we've handled
27
        # Remove params we've handled
Lines 30-36 sub list { Link Here
30
        my $quotas_set = Koha::Patron::Quotas->new;
30
        my $quotas_set = Koha::Patron::Quotas->new;
31
31
32
        if ($patron_id) {
32
        if ($patron_id) {
33
            $quotas_set = $quotas_set->search({ patron_id => $patron_id });
33
            $quotas_set = $quotas_set->search( { patron_id => $patron_id } );
34
        }
34
        }
35
35
36
        if ($only_active) {
36
        if ($only_active) {
Lines 38-48 sub list { Link Here
38
        }
38
        }
39
39
40
        return $c->render(
40
        return $c->render(
41
            status => 200,
41
            status  => 200,
42
            openapi => $c->objects->search($quotas_set)
42
            openapi => $c->objects->search($quotas_set)
43
        );
43
        );
44
    }
44
    } catch {
45
    catch {
46
        $c->unhandled_exception($_);
45
        $c->unhandled_exception($_);
47
    };
46
    };
48
}
47
}
Lines 62-69 sub get { Link Here
62
        return $c->render_resource_not_found("Quota") unless $quota;
61
        return $c->render_resource_not_found("Quota") unless $quota;
63
62
64
        return $c->render( status => 200, openapi => $c->objects->to_api($quota) );
63
        return $c->render( status => 200, openapi => $c->objects->to_api($quota) );
65
    }
64
    } catch {
66
    catch {
67
        $c->unhandled_exception($_);
65
        $c->unhandled_exception($_);
68
    };
66
    };
69
}
67
}
Lines 84-97 sub add { Link Here
84
        my $quota = Koha::Patron::Quota->new_from_api($body);
82
        my $quota = Koha::Patron::Quota->new_from_api($body);
85
        $quota->store;
83
        $quota->store;
86
84
87
        $c->res->headers->location($c->req->url->to_string . '/' . $quota->id);
85
        $c->res->headers->location( $c->req->url->to_string . '/' . $quota->id );
88
        return $c->render(
86
        return $c->render(
89
            status  => 201,
87
            status  => 201,
90
            openapi => $c->objects->to_api($quota)
88
            openapi => $c->objects->to_api($quota)
91
        );
89
        );
92
    }
90
    } catch {
93
    catch {
91
        if ( ref($_) eq 'Koha::Exceptions::Quota::Clash' ) {
94
        if (ref($_) eq 'Koha::Exceptions::Quota::Clash') {
95
            return $c->render(
92
            return $c->render(
96
                status  => 409,
93
                status  => 409,
97
                openapi => { error => "Quota period overlaps with existing quota" }
94
                openapi => { error => "Quota period overlaps with existing quota" }
Lines 110-126 Controller method for updating a quota Link Here
110
sub update {
107
sub update {
111
    my $c = shift->openapi->valid_input or return;
108
    my $c = shift->openapi->valid_input or return;
112
109
113
    my $quota = Koha::Patron::Quotas->find($c->param('quota_id'));
110
    my $quota = Koha::Patron::Quotas->find( $c->param('quota_id') );
114
111
115
    return $c->render_resource_not_found("Quota") unless $quota;
112
    return $c->render_resource_not_found("Quota") unless $quota;
116
113
117
    return try {
114
    return try {
118
        $quota->set_from_api($c->req->json);
115
        $quota->set_from_api( $c->req->json );
119
        $quota->store;
116
        $quota->store;
120
        return $c->render(status => 200, openapi => $c->objects->to_api($quota));
117
        return $c->render( status => 200, openapi => $c->objects->to_api($quota) );
121
    }
118
    } catch {
122
    catch {
119
        if ( ref($_) eq 'Koha::Exceptions::Quota::Clash' ) {
123
        if (ref($_) eq 'Koha::Exceptions::Quota::Clash') {
124
            return $c->render(
120
            return $c->render(
125
                status  => 409,
121
                status  => 409,
126
                openapi => { error => "Quota period overlaps with existing quota" }
122
                openapi => { error => "Quota period overlaps with existing quota" }
Lines 139-153 Controller method for deleting a quota Link Here
139
sub delete {
135
sub delete {
140
    my $c = shift->openapi->valid_input or return;
136
    my $c = shift->openapi->valid_input or return;
141
137
142
    my $quota = Koha::Patron::Quotas->find($c->param('quota_id'));
138
    my $quota = Koha::Patron::Quotas->find( $c->param('quota_id') );
143
139
144
    return $c->render_resource_not_found("Quota") unless $quota;
140
    return $c->render_resource_not_found("Quota") unless $quota;
145
141
146
    return try {
142
    return try {
147
        $quota->delete;
143
        $quota->delete;
148
        return $c->render_resource_deleted;
144
        return $c->render_resource_deleted;
149
    }
145
    } catch {
150
    catch {
146
        $c->unhandled_exception($_);
147
    };
148
}
149
150
=head3 get_usage
151
152
Controller method for getting usage for a quota
153
154
=cut
155
156
sub get_usage {
157
    my $c = shift->openapi->valid_input or return;
158
159
    my $quota = Koha::Patron::Quotas->find( $c->param('quota_id') );
160
    return $c->render_resource_not_found("Quota") unless $quota;
161
162
    return try {
163
        my $usage_set = $quota->usages;
164
        return $c->render(
165
            status  => 200,
166
            openapi => $c->objects->search($usage_set)
167
        );
168
    } catch {
151
        $c->unhandled_exception($_);
169
        $c->unhandled_exception($_);
152
    };
170
    };
153
}
171
}
(-)a/Koha/Schema/Result/PatronQuotaUsage.pm (-4 / +4 lines)
Lines 145-151 __PACKAGE__->belongs_to( Link Here
145
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-08-21 16:54:49
145
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-08-21 16:54:49
146
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:x+OvLQNInT0DkfPmiZwZzg
146
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:x+OvLQNInT0DkfPmiZwZzg
147
147
148
=head2 issue
148
=head2 checkout
149
149
150
Type: belongs_to
150
Type: belongs_to
151
151
Lines 154-165 Related object: L<Koha::Schema::Result::Issue> Link Here
154
=cut
154
=cut
155
155
156
__PACKAGE__->belongs_to(
156
__PACKAGE__->belongs_to(
157
    issue => 'Koha::Schema::Result::Issue',
157
    checkout => 'Koha::Schema::Result::Issue',
158
    'issue_id',
158
    'issue_id',
159
    { join_type => 'left' }
159
    { join_type => 'left' }
160
);
160
);
161
161
162
=head2 old_issue
162
=head2 old_checkout
163
163
164
Type: belongs_to
164
Type: belongs_to
165
165
Lines 168-174 Related object: L<Koha::Schema::Result::OldIssue> Link Here
168
=cut
168
=cut
169
169
170
__PACKAGE__->belongs_to(
170
__PACKAGE__->belongs_to(
171
    old_issue => 'Koha::Schema::Result::OldIssue',
171
    old_checkout => 'Koha::Schema::Result::OldIssue',
172
    'issue_id',
172
    'issue_id',
173
    { join_type => 'left' }
173
    { join_type => 'left' }
174
);
174
);
(-)a/api/v1/swagger/definitions/quota_usage.yaml (+36 lines)
Line 0 Link Here
1
---
2
type: object
3
properties:
4
  id:
5
    type: integer
6
    description: Internal quota identifier
7
    readOnly: true
8
  patron_quota_id:
9
    type: integer
10
    description: Link to quota
11
  patron_id:
12
    type: integer
13
    description: Link to patron
14
  patron:
15
    type: object
16
  checkout_id:
17
    type:
18
      - integer
19
      - "null"
20
    description: Link to issue
21
  checkout:
22
    type:
23
      - object
24
      - "null"
25
  creation_date:
26
    type: string
27
    format: date-time
28
    description: Date of increment
29
  type:
30
    type: string
31
    enum:
32
      - 'ISSUE'
33
      - 'RENEW'
34
additionalProperties: false
35
required:
36
  - id
(-)a/api/v1/swagger/paths/patrons_quotas.yaml (+65 lines)
Lines 197-199 Link Here
197
    x-koha-authorization:
197
    x-koha-authorization:
198
      permissions:
198
      permissions:
199
        borrowers: manage_borrower_quotas
199
        borrowers: manage_borrower_quotas
200
/patrons/{patron_id}/quotas/{quota_id}/usages:
201
  get:
202
    x-mojo-to: Patrons::Quotas#get_usage
203
    operationId: getPatronQuotaUsage
204
    tags:
205
      - quotas
206
    summary: Get quota usage details
207
    parameters:
208
      - $ref: "../swagger.yaml#/parameters/patron_id_pp"
209
      - name: quota_id
210
        in: path
211
        description: Internal quota identifier
212
        required: true
213
        type: string
214
      - $ref: "../swagger.yaml#/parameters/page"
215
      - $ref: "../swagger.yaml#/parameters/per_page"
216
      - $ref: "../swagger.yaml#/parameters/match"
217
      - $ref: "../swagger.yaml#/parameters/order_by"
218
      - $ref: "../swagger.yaml#/parameters/q_param"
219
      - $ref: "../swagger.yaml#/parameters/q_body"
220
      - $ref: "../swagger.yaml#/parameters/request_id_header"
221
      - name: x-koha-embed
222
        in: header
223
        required: false
224
        description: Embed list sent as a request header
225
        type: array
226
        items:
227
          type: string
228
          enum:
229
            - checkout
230
            - checkout.item
231
            - checkout.item.biblio
232
            - patron
233
        collectionFormat: csv
234
    produces:
235
      - application/json
236
    responses:
237
      "200":
238
        description: A quota usage
239
        schema:
240
          type: array
241
          items:
242
            $ref: "../swagger.yaml#/definitions/quota_usage"
243
      "400":
244
        description: |
245
          Bad request. Possible `error_code` attribute values:
246
            * `bad_request`
247
            * `invalid_query`
248
        schema:
249
          $ref: "../swagger.yaml#/definitions/error"
250
      "403":
251
        description: Access forbidden
252
        schema:
253
          $ref: "../swagger.yaml#/definitions/error"
254
      "404":
255
        description: Quota not found
256
        schema:
257
          $ref: "../swagger.yaml#/definitions/error"
258
      "500":
259
        description: Internal server error
260
        schema:
261
          $ref: "../swagger.yaml#/definitions/error"
262
    x-koha-authorization:
263
      permissions:
264
        borrowers: view_borrower_quotas
(-)a/api/v1/swagger/swagger.yaml (-1 / +5 lines)
Lines 164-169 definitions: Link Here
164
    $ref: ./definitions/quote.yaml
164
    $ref: ./definitions/quote.yaml
165
  quota:
165
  quota:
166
    $ref: ./definitions/quota.yaml
166
    $ref: ./definitions/quota.yaml
167
  quota_usage:
168
    $ref: ./definitions/quota_usage.yaml
167
  recall:
169
  recall:
168
    $ref: ./definitions/recall.yaml
170
    $ref: ./definitions/recall.yaml
169
  recalls:
171
  recalls:
Lines 495-500 paths: Link Here
495
    $ref: "./paths/patrons_quotas.yaml#/~1patrons~1{patron_id}~1quotas"
497
    $ref: "./paths/patrons_quotas.yaml#/~1patrons~1{patron_id}~1quotas"
496
  "/patrons/{patron_id}/quotas/{quota_id}":
498
  "/patrons/{patron_id}/quotas/{quota_id}":
497
    $ref: "./paths/patrons_quotas.yaml#/~1patrons~1{patron_id}~1quotas~1{quota_id}"
499
    $ref: "./paths/patrons_quotas.yaml#/~1patrons~1{patron_id}~1quotas~1{quota_id}"
500
  "/patrons/{patron_id}/quotas/{quota_id}/usages":
501
    $ref: "./paths/patrons_quotas.yaml#/~1patrons~1{patron_id}~1quotas~1{quota_id}~1usages"
502
498
  "/patrons/{patron_id}/recalls":
503
  "/patrons/{patron_id}/recalls":
499
    $ref: "./paths/patrons_recalls.yaml#/~1patrons~1{patron_id}~1recalls"
504
    $ref: "./paths/patrons_recalls.yaml#/~1patrons~1{patron_id}~1recalls"
500
  "/patrons/{patron_id}/ill/requests":
505
  "/patrons/{patron_id}/ill/requests":
501
- 

Return to bug 38924