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

(-)a/Koha/Acquisition/Basket.pm (+1 lines)
Lines 286-291 sub to_api_mapping { Link Here
286
    return {
286
    return {
287
        basketno                => 'basket_id',
287
        basketno                => 'basket_id',
288
        basketname              => 'name',
288
        basketname              => 'name',
289
        note                    => 'internal_note',
289
        booksellernote          => 'vendor_note',
290
        booksellernote          => 'vendor_note',
290
        contractnumber          => 'contract_id',
291
        contractnumber          => 'contract_id',
291
        creationdate            => 'creation_date',
292
        creationdate            => 'creation_date',
(-)a/Koha/REST/V1/Acquisitions/Baskets.pm (+26 lines)
Lines 78-81 sub list { Link Here
78
    };
78
    };
79
}
79
}
80
80
81
=head3 add
82
83
Controller function that handles adding a new Koha::Acquisition::Basket object
84
85
=cut
86
87
sub add {
88
    my $c = shift->openapi->valid_input or return;
89
90
    return try {
91
        my $basket = Koha::Acquisition::Basket->new_from_api( $c->validation->param('body') );
92
        $basket->store->discard_changes;
93
94
        $c->res->headers->location(
95
            $c->req->url->to_string . '/' . $basket->basketno
96
        );
97
98
        return $c->render(
99
            status  => 201,
100
            openapi => $basket->to_api
101
        );
102
    } catch {
103
        $c->unhandled_exception($_);
104
    };
105
}
106
81
1;
107
1;
(-)a/api/v1/swagger/definitions/basket.yaml (-10 / +9 lines)
Lines 5-11 properties: Link Here
5
    type: integer
5
    type: integer
6
    description: Internal identifier for the basket
6
    description: Internal identifier for the basket
7
  name:
7
  name:
8
    type: string
8
    type:
9
      - string
10
      - "null"
9
    description: Basket name
11
    description: Basket name
10
  internal_note:
12
  internal_note:
11
    type:
13
    type:
Lines 34-39 properties: Link Here
34
      - "null"
36
      - "null"
35
    format: date
37
    format: date
36
    description: The date the basket was closed
38
    description: The date the basket was closed
39
  closed:
40
    type: boolean
41
    description: Is the basket closed ?
37
  vendor_id:
42
  vendor_id:
38
    type: integer
43
    type: integer
39
    description: Internal identifier for the vendor
44
    description: Internal identifier for the vendor
Lines 65-78 properties: Link Here
65
  standing:
70
  standing:
66
    type: boolean
71
    type: boolean
67
    description: If the orders in this basket are standing
72
    description: If the orders in this basket are standing
68
  closed:
69
    type: boolean
70
    description: Is the basket closed
71
  note:
72
    type:
73
      - string
74
      - "null"
75
    description: basket notes
76
  create_items:
73
  create_items:
77
    type:
74
    type:
78
      - string
75
      - string
Lines 84-87 properties: Link Here
84
      - null
81
      - null
85
    description: "When items should be created for orders in this basket (Options:
82
    description: "When items should be created for orders in this basket (Options:
86
      'ordering', 'receiving', 'cataloguing'. Null means system wide config)"
83
      'ordering', 'receiving', 'cataloguing'. Null means system wide config)"
87
additionalProperties: false
84
additionalProperties: false
85
required:
86
  - vendor_id
(-)a/api/v1/swagger/paths.yaml (+145 lines)
Line 0 Link Here
1
---
2
/oauth/token:
3
  $ref: paths/oauth.yaml#/~1oauth~1token
4
"/acquisitions/baskets":
5
  $ref: paths/acquisitions_baskets.yaml#/~1acquisitions~1baskets
6
/acquisitions/orders:
7
  $ref: paths/acquisitions_orders.yaml#/~1acquisitions~1orders
8
"/acquisitions/orders/{order_id}":
9
  $ref: paths/acquisitions_orders.yaml#/~1acquisitions~1orders~1{order_id}
10
/acquisitions/vendors:
11
  $ref: paths/acquisitions_vendors.yaml#/~1acquisitions~1vendors
12
"/acquisitions/vendors/{vendor_id}":
13
  $ref: paths/acquisitions_vendors.yaml#/~1acquisitions~1vendors~1{vendor_id}
14
/acquisitions/funds:
15
  $ref: paths/acquisitions_funds.yaml#/~1acquisitions~1funds
16
"/article_requests/{article_request_id}":
17
  $ref: paths/article_requests.yaml#/~1article_requests~1{article_request_id}
18
"/biblios/{biblio_id}":
19
  $ref: paths/biblios.yaml#/~1biblios~1{biblio_id}
20
"/biblios/{biblio_id}/checkouts":
21
  $ref: paths/biblios.yaml#/~1biblios~1{biblio_id}~1checkouts
22
"/biblios/{biblio_id}/items":
23
  $ref: paths/biblios.yaml#/~1biblios~1{biblio_id}~1items
24
"/biblios/{biblio_id}/pickup_locations":
25
  $ref: paths/biblios.yaml#/~1biblios~1{biblio_id}~1pickup_locations
26
"/cash_registers/{cash_register_id}/cashups":
27
  $ref: paths/cash_registers.yaml#/~1cash_registers~1{cash_register_id}~1cashups
28
"/cashups/{cashup_id}":
29
  $ref: paths/cash_registers.yaml#/~1cashups~1{cashup_id}
30
/checkouts:
31
  $ref: paths/checkouts.yaml#/~1checkouts
32
"/checkouts/{checkout_id}":
33
  $ref: paths/checkouts.yaml#/~1checkouts~1{checkout_id}
34
"/checkouts/{checkout_id}/renewal":
35
  $ref: paths/checkouts.yaml#/~1checkouts~1{checkout_id}~1renewal
36
/circulation-rules/kinds:
37
  $ref: paths/circulation-rules.yaml#/~1circulation-rules~1kinds
38
/cities:
39
  $ref: paths/cities.yaml#/~1cities
40
"/cities/{city_id}":
41
  $ref: paths/cities.yaml#/~1cities~1{city_id}
42
"/clubs/{club_id}/holds":
43
  $ref: paths/clubs.yaml#/~1clubs~1{club_id}~1holds
44
/config/smtp_servers:
45
  $ref: paths/config_smtp_servers.yaml#/~1config~1smtp_servers
46
"/config/smtp_servers/{smtp_server_id}":
47
  $ref: paths/config_smtp_servers.yaml#/~1config~1smtp_servers~1{smtp_server_id}
48
/holds:
49
  $ref: paths/holds.yaml#/~1holds
50
"/holds/{hold_id}":
51
  $ref: paths/holds.yaml#/~1holds~1{hold_id}
52
"/holds/{hold_id}/priority":
53
  $ref: paths/holds.yaml#/~1holds~1{hold_id}~1priority
54
"/holds/{hold_id}/suspension":
55
  $ref: paths/holds.yaml#/~1holds~1{hold_id}~1suspension
56
"/holds/{hold_id}/pickup_locations":
57
  $ref: paths/holds.yaml#/~1holds~1{hold_id}~1pickup_locations
58
"/holds/{hold_id}/pickup_location":
59
  $ref: paths/holds.yaml#/~1holds~1{hold_id}~1pickup_location
60
/items:
61
  $ref: paths/items.yaml#/~1items
62
"/items/{item_id}":
63
  $ref: paths/items.yaml#/~1items~1{item_id}
64
"/items/{item_id}/pickup_locations":
65
  $ref: paths/items.yaml#/~1items~1{item_id}~1pickup_locations
66
/libraries:
67
  $ref: paths/libraries.yaml#/~1libraries
68
"/libraries/{library_id}":
69
  $ref: paths/libraries.yaml#/~1libraries~1{library_id}
70
/transfer_limits:
71
  $ref: paths/transfer_limits.yaml#/~1transfer_limits
72
"/transfer_limits/{limit_id}":
73
  $ref: paths/transfer_limits.yaml#/~1transfer_limits~1{limit_id}
74
/transfer_limits/batch:
75
  $ref: paths/transfer_limits.yaml#/~1transfer_limits~1batch
76
"/checkouts/{checkout_id}/allows_renewal":
77
  $ref: paths/checkouts.yaml#/~1checkouts~1{checkout_id}~1allows_renewal
78
/advanced_editor/macros:
79
  $ref: paths/advancededitormacros.yaml#/~1advanced_editor~1macros
80
"/advanced_editor/macros/{advancededitormacro_id}":
81
  $ref: paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1{advancededitormacro_id}
82
/advanced_editor/macros/shared:
83
  $ref: paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared
84
"/advanced_editor/macros/shared/{advancededitormacro_id}":
85
  $ref: paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared~1{advancededitormacro_id}
86
/patrons:
87
  $ref: paths/patrons.yaml#/~1patrons
88
"/patrons/{patron_id}":
89
  $ref: paths/patrons.yaml#/~1patrons~1{patron_id}
90
"/patrons/{patron_id}/account":
91
  $ref: paths/patrons_account.yaml#/~1patrons~1{patron_id}~1account
92
"/patrons/{patron_id}/account/credits":
93
  $ref: paths/patrons_account.yaml#/~1patrons~1{patron_id}~1account~1credits
94
"/patrons/{patron_id}/extended_attributes":
95
  $ref: paths/patrons_extended_attributes.yaml#/~1patrons~1{patron_id}~1extended_attributes
96
"/patrons/{patron_id}/extended_attributes/{extended_attribute_id}":
97
  $ref: paths/patrons_extended_attributes.yaml#/~1patrons~1{patron_id}~1extended_attributes~1{extended_attribute_id}
98
"/patrons/{patron_id}/holds":
99
  $ref: paths/patrons_holds.yaml#/~1patrons~1{patron_id}~1holds
100
"/patrons/{patron_id}/password":
101
  $ref: paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password
102
/ill_backends:
103
  $ref: paths/ill_backends.yaml#/~1ill_backends
104
"/ill_backends/{ill_backend_id}":
105
  $ref: paths/ill_backends.yaml#/~1ill_backends~1{ill_backend_id}
106
/illrequests:
107
  $ref: paths/illrequests.yaml#/~1illrequests
108
/import_batch_profiles:
109
  $ref: paths/import_batch_profiles.yaml#/~1import_batch_profiles
110
"/import_batch_profiles/{import_batch_profile_id}":
111
  $ref: paths/import_batch_profiles.yaml#/~1import_batch_profiles~1{import_batch_profile_id}
112
"/rotas/{rota_id}/stages/{stage_id}/position":
113
  $ref: paths/rotas.yaml#/~1rotas~1{rota_id}~1stages~1{stage_id}~1position
114
"/public/biblios/{biblio_id}":
115
  $ref: paths/biblios.yaml#/~1public~1biblios~1{biblio_id}
116
"/public/biblios/{biblio_id}/items":
117
  $ref: paths/biblios.yaml#/~1public~1biblios~1{biblio_id}~1items
118
/public/libraries:
119
  $ref: paths/libraries.yaml#/~1public~1libraries
120
"/public/libraries/{library_id}":
121
  $ref: paths/libraries.yaml#/~1public~1libraries~1{library_id}
122
"/public/patrons/{patron_id}/article_requests/{article_request_id}":
123
  $ref: paths/article_requests.yaml#/~1public~1patrons~1{patron_id}~1article_requests~1{article_request_id}
124
"/public/patrons/{patron_id}/password":
125
  $ref: paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1password
126
"/public/patrons/{patron_id}/guarantors/can_see_charges":
127
  $ref: paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_charges
128
"/public/patrons/{patron_id}/guarantors/can_see_checkouts":
129
  $ref: paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_checkouts
130
/quotes:
131
  $ref: paths/quotes.yaml#/~1quotes
132
"/quotes/{quote_id}":
133
  $ref: paths/quotes.yaml#/~1quotes~1{quote_id}
134
/return_claims:
135
  $ref: paths/return_claims.yaml#/~1return_claims
136
"/return_claims/{claim_id}/notes":
137
  $ref: paths/return_claims.yaml#/~1return_claims~1{claim_id}~1notes
138
"/return_claims/{claim_id}/resolve":
139
  $ref: paths/return_claims.yaml#/~1return_claims~1{claim_id}~1resolve
140
"/return_claims/{claim_id}":
141
  $ref: paths/return_claims.yaml#/~1return_claims~1{claim_id}
142
/suggestions:
143
  $ref: paths/suggestions.yaml#/~1suggestions
144
"/suggestions/{suggestion_id}":
145
  $ref: paths/suggestions.yaml#/~1suggestions~1{suggestion_id}
(-)a/api/v1/swagger/paths/acquisitions_baskets.yaml (-1 / +60 lines)
Lines 48-53 Link Here
48
    x-koha-authorization:
48
    x-koha-authorization:
49
      permissions:
49
      permissions:
50
        acquisition: order_manage
50
        acquisition: order_manage
51
  post:
52
    x-mojo-to: Acquisitions::Baskets#add
53
    operationId: addBasket
54
    tags:
55
      - baskets
56
    summary: Add basket
57
    consumes:
58
      - application/json
59
    produces:
60
      - application/json
61
    parameters:
62
      -
63
        name: body
64
        in: body
65
        description: A basket
66
        required: true
67
        schema:
68
          $ref: "../swagger.yaml#/definitions/basket"
69
    responses:
70
      "201":
71
        description: A successfully created basket
72
        schema:
73
          items:
74
            $ref: "../swagger.yaml#/definitions/basket"
75
      "400":
76
        description: Bad request
77
        schema:
78
          $ref: "../swagger.yaml#/definitions/error"
79
      "401":
80
        description: Authentication required
81
        schema:
82
          $ref: "../swagger.yaml#/definitions/error"
83
      "403":
84
        description: Access forbidden
85
        schema:
86
          $ref: "../swagger.yaml#/definitions/error"
87
      "404":
88
        description: Resource not found
89
        schema:
90
          $ref: "../swagger.yaml#/definitions/error"
91
      "409":
92
        description: Conflict in creating resource
93
        schema:
94
          $ref: "../swagger.yaml#/definitions/error"
95
      "500":
96
        description: |
97
          Internal server error. Possible `error_code` attribute values:
98
99
          * `internal_server_error`
100
        schema:
101
          $ref: "../swagger.yaml#/definitions/error"
102
      "503":
103
        description: Under maintenance
104
        schema:
105
          $ref: "../swagger.yaml#/definitions/error"
106
    x-koha-authorization:
107
      permissions:
108
        acquisition:
109
          - order_manage
51
/acquisitions/baskets/managers:
110
/acquisitions/baskets/managers:
52
  get:
111
  get:
53
    x-mojo-to: Acquisitions::Baskets#list_managers
112
    x-mojo-to: Acquisitions::Baskets#list_managers
Lines 107-110 Link Here
107
          $ref: "../swagger.yaml#/definitions/error"
166
          $ref: "../swagger.yaml#/definitions/error"
108
    x-koha-authorization:
167
    x-koha-authorization:
109
      permissions:
168
      permissions:
110
        acquisition: order_manage
169
        acquisition: order_manage
(-)a/t/db_dependent/api/v1/acquisitions_baskets/post.t (-1 / +68 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
5
use Test::More tests => 14;
6
use Test::Mojo;
7
8
use t::lib::Mocks;
9
use t::lib::TestBuilder;
10
11
my $schema  = Koha::Database->new->schema;
12
my $builder = t::lib::TestBuilder->new;
13
14
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
15
16
my $t = Test::Mojo->new('Koha::REST::V1');
17
18
$schema->storage->txn_begin;
19
20
my $bookseller = $builder->build_object(
21
    {
22
        class => 'Koha::Acquisition::Booksellers',
23
    }
24
);
25
my $patron = $builder->build_object(
26
    {
27
        class => 'Koha::Patrons',
28
        value => { flags => 0 }
29
    }
30
);
31
my $password = 'thePassword123';
32
$patron->set_password( { password => $password, skip_validation => 1 } );
33
my $userid = $patron->userid;
34
35
my $url = "//$userid:$password@/api/v1/acquisitions/baskets";
36
37
$t->post_ok($url, json => {})
38
  ->status_is(403);
39
40
$schema->resultset('UserPermission')->create(
41
    {
42
        borrowernumber => $patron->borrowernumber,
43
        module_bit => 11,
44
        code => 'order_manage',
45
    }
46
);
47
48
$t->post_ok($url, json => {})
49
  ->status_is(400);
50
51
$t->post_ok($url, json => { vendor_id => $bookseller->id })
52
  ->status_is(201)
53
  ->json_has('/basket_id')
54
  ->json_is('/vendor_id', $bookseller->id);
55
56
my $basket = {
57
    vendor_id => $bookseller->id,
58
    name => 'Basket #1',
59
    vendor_note => 'Vendor note',
60
};
61
$t->post_ok($url, json => $basket)
62
  ->status_is(201)
63
  ->json_has('/basket_id')
64
  ->json_is('/vendor_id', $basket->{vendor_id})
65
  ->json_is('/name', $basket->{name})
66
  ->json_is('/vendor_note', $basket->{vendor_note});
67
68
$schema->storage->txn_rollback;

Return to bug 29668