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

(-)a/Koha/Item.pm (+14 lines)
Lines 1699-1704 sub itemtype { Link Here
1699
    return Koha::ItemTypes->find( $self->effective_itemtype );
1699
    return Koha::ItemTypes->find( $self->effective_itemtype );
1700
}
1700
}
1701
1701
1702
=head3 effective_bookable
1703
1704
  my $bookable = $item->effective_bookable;
1705
1706
Returns the effective bookability of the current item, be that item or itemtype level
1707
1708
=cut
1709
1710
sub effective_bookable {
1711
    my ($self) = @_;
1712
1713
    return defined( $self->bookable ) ? $self->bookable : $self->itemtype->bookable;
1714
}
1715
1702
=head3 orders
1716
=head3 orders
1703
1717
1704
  my $orders = $item->orders();
1718
  my $orders = $item->orders();
(-)a/Koha/Items.pm (-5 / +10 lines)
Lines 169-180 Returns a new resultset, containing only those items that are allowed to be book Link Here
169
sub filter_by_bookable {
169
sub filter_by_bookable {
170
    my ($self) = @_;
170
    my ($self) = @_;
171
171
172
    my $params =
172
    my @bookable_itemtypes = Koha::ItemTypes->search( { bookable => 1 } )->get_column('itemtype');
173
        C4::Context->preference('item-level_booking') == 1
174
        ? { bookable => 1 }
175
        : { itype    => { -in => \'SELECT itemtype FROM itemtypes WHERE bookable = 1' } };
176
173
177
    return $self->search($params);
174
    my ( $where, $attr );
175
    if ( C4::Context->preference("item-level_itypes") ) {
176
        $where = [ { bookable => 1 }, { bookable => undef, itype => { -in => \@bookable_itemtypes } } ];
177
    } else {
178
        $where = [ { bookable => 1 }, { bookable => undef, 'biblioitem.itemtype' => { -in => \@bookable_itemtypes } } ];
179
        $attr  = { join => 'biblioitem' };
180
    }
181
182
    return $self->search( $where, $attr );
178
}
183
}
179
184
180
=head3 move_to_biblio
185
=head3 move_to_biblio
(-)a/api/v1/swagger/definitions/item.yaml (-3 / +11 lines)
Lines 25-30 properties: Link Here
25
      - "null"
25
      - "null"
26
    description: Information about the acquisition source (it is not really a vendor id)
26
    description: Information about the acquisition source (it is not really a vendor id)
27
  bookable:
27
  bookable:
28
    type:
29
      - boolean
30
      - "null"
31
    description: Item level bookability override.
32
  effective_bookable:
28
    type: boolean
33
    type: boolean
29
    description: Allow bookings on this item.
34
    description: Allow bookings on this item.
30
  home_library_id:
35
  home_library_id:
Lines 91-97 properties: Link Here
91
      - string
96
      - string
92
      - "null"
97
      - "null"
93
    format: date-time
98
    format: date-time
94
    description: The date and time an item was last marked as withdrawn, NULL if not
99
    description:
100
      The date and time an item was last marked as withdrawn, NULL if not
95
      withdrawn
101
      withdrawn
96
  callnumber:
102
  callnumber:
97
    type:
103
    type:
Lines 151-164 properties: Link Here
151
    type:
157
    type:
152
      - string
158
      - string
153
      - "null"
159
      - "null"
154
    description: Linked to the CART and PROC temporary locations feature, stores the
160
    description:
161
      Linked to the CART and PROC temporary locations feature, stores the
155
      permanent shelving location
162
      permanent shelving location
156
  checked_out_date:
163
  checked_out_date:
157
    type:
164
    type:
158
      - string
165
      - string
159
      - "null"
166
      - "null"
160
    format: date
167
    format: date
161
    description: Defines if item is checked out (NULL for not checked out, and checkout
168
    description:
169
      Defines if item is checked out (NULL for not checked out, and checkout
162
      date for checked out)
170
      date for checked out)
163
  call_number_source:
171
  call_number_source:
164
    type:
172
    type:
(-)a/api/v1/swagger/paths/biblios.yaml (-2 / +4 lines)
Lines 372-378 Link Here
372
        collectionFormat: csv
372
        collectionFormat: csv
373
      - name: checked_in
373
      - name: checked_in
374
        in: query
374
        in: query
375
        description: By default, current checkouts are returned, when this is true then
375
        description:
376
          By default, current checkouts are returned, when this is true then
376
          checked in checkouts are returned as result.
377
          checked in checkouts are returned as result.
377
        type: boolean
378
        type: boolean
378
    produces:
379
    produces:
Lines 422-427 Link Here
422
          type: string
423
          type: string
423
          enum:
424
          enum:
424
            - +strings
425
            - +strings
426
            - effective_bookable
425
        collectionFormat: csv
427
        collectionFormat: csv
426
      - $ref: "../swagger.yaml#/parameters/match"
428
      - $ref: "../swagger.yaml#/parameters/match"
427
      - $ref: "../swagger.yaml#/parameters/order_by"
429
      - $ref: "../swagger.yaml#/parameters/order_by"
Lines 786-792 Link Here
786
                - integer
788
                - integer
787
                - "null"
789
                - "null"
788
          required:
790
          required:
789
              - rating
791
            - rating
790
          additionalProperties: false
792
          additionalProperties: false
791
    produces:
793
    produces:
792
      - application/json
794
      - application/json
(-)a/api/v1/swagger/paths/items.yaml (-1 / +3 lines)
Lines 22-27 Link Here
22
          enum:
22
          enum:
23
            - +strings
23
            - +strings
24
            - biblio
24
            - biblio
25
            - effective_bookable
25
        collectionFormat: csv
26
        collectionFormat: csv
26
      - $ref: "../swagger.yaml#/parameters/match"
27
      - $ref: "../swagger.yaml#/parameters/match"
27
      - $ref: "../swagger.yaml#/parameters/order_by"
28
      - $ref: "../swagger.yaml#/parameters/order_by"
Lines 81-86 Link Here
81
          type: string
82
          type: string
82
          enum:
83
          enum:
83
            - +strings
84
            - +strings
85
            - effective_bookable
84
        collectionFormat: csv
86
        collectionFormat: csv
85
    consumes:
87
    consumes:
86
      - application/json
88
      - application/json
Lines 150-156 Link Here
150
            * linked_analytics: The item has linked analytic records
152
            * linked_analytics: The item has linked analytic records
151
            * not_same_branch: The item is blocked by independent branches
153
            * not_same_branch: The item is blocked by independent branches
152
        schema:
154
        schema:
153
              $ref: "../swagger.yaml#/definitions/error"
155
          $ref: "../swagger.yaml#/definitions/error"
154
      "500":
156
      "500":
155
        description: |
157
        description: |
156
          Internal server error. Possible `error_code` attribute values:
158
          Internal server error. Possible `error_code` attribute values:
(-)a/catalogue/updateitem.pl (-1 / +2 lines)
Lines 39-45 my $itemnotes_nonpublic=$cgi->param('itemnotes_nonpublic'); Link Here
39
my $withdrawn=$cgi->param('withdrawn');
39
my $withdrawn=$cgi->param('withdrawn');
40
my $damaged=$cgi->param('damaged');
40
my $damaged=$cgi->param('damaged');
41
my $exclude_from_local_holds_priority = $cgi->param('exclude_from_local_holds_priority');
41
my $exclude_from_local_holds_priority = $cgi->param('exclude_from_local_holds_priority');
42
my $bookable = $cgi->param('bookable');
42
my $bookable = $cgi->param('bookable') // q{};
43
43
44
my $confirm=$cgi->param('confirm');
44
my $confirm=$cgi->param('confirm');
45
my $dbh = C4::Context->dbh;
45
my $dbh = C4::Context->dbh;
Lines 77-82 elsif ( $op eq "set_public_note" ) { # i.e., itemnotes parameter passed from for Link Here
77
    $item->exclude_from_local_holds_priority($exclude_from_local_holds_priority);
77
    $item->exclude_from_local_holds_priority($exclude_from_local_holds_priority);
78
    $messages = "updated_exclude_from_local_holds_priority=$exclude_from_local_holds_priority&";
78
    $messages = "updated_exclude_from_local_holds_priority=$exclude_from_local_holds_priority&";
79
} elsif ( $op eq "set_bookable" && $bookable ne $item_data_hashref->{'bookable'} ) {
79
} elsif ( $op eq "set_bookable" && $bookable ne $item_data_hashref->{'bookable'} ) {
80
    undef($bookable) if $bookable eq "";
80
    $item->bookable($bookable);
81
    $item->bookable($bookable);
81
} elsif ( $op eq "set_damaged" && $damaged ne $item_data_hashref->{'damaged'}) {
82
} elsif ( $op eq "set_damaged" && $damaged ne $item_data_hashref->{'damaged'}) {
82
    $item->damaged($damaged);
83
    $item->damaged($damaged);
(-)a/installer/data/mysql/atomicupdate/Bug_35906_add-column-bookable-itemtype.pl (-7 / +21 lines)
Lines 7-21 return { Link Here
7
        my ($args) = @_;
7
        my ($args) = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
9
10
        $dbh->do(q{
10
        $dbh->do(
11
            INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES  ('item-level_booking', 1, '', 'enables item type level for future booking', 'YesNo');
11
            q{
12
        });
13
14
        $dbh->do(q{
15
            ALTER TABLE itemtypes ADD IF NOT EXISTS bookable INT(1) DEFAULT 0
12
            ALTER TABLE itemtypes ADD IF NOT EXISTS bookable INT(1) DEFAULT 0
16
        });
13
        }
14
        );
17
15
18
        say $out "Added new system preference 'item-level_booking'";
19
        say $out "Added column 'itemtypes.bookable'";
16
        say $out "Added column 'itemtypes.bookable'";
17
18
        $dbh->do(
19
            q{
20
            ALTER TABLE items MODIFY COLUMN bookable tinyint(1) DEFAULT NULL COMMENT 'nullable boolean value defining whether this this item is available for bookings or not'
21
        }
22
        );
23
24
        say $out "Updated column 'items.bookable' allow nullable";
25
26
        $dbh->do(
27
            q{
28
            ALTER TABLE deleteditems MODIFY COLUMN bookable tinyint(1) DEFAULT NULL COMMENT 'nullable boolean value defining whether this this item is available for bookings or not'
29
        }
30
        );
31
32
        say $out "Updated column 'deleteditems.bookable' allow nullable";
33
20
    },
34
    },
21
};
35
};
(-)a/installer/data/mysql/kohastructure.sql (-2 / +2 lines)
Lines 2738-2744 CREATE TABLE `deleteditems` ( Link Here
2738
  `biblionumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from biblio table used to link this item to the right bib record',
2738
  `biblionumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from biblio table used to link this item to the right bib record',
2739
  `biblioitemnumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from the biblioitems table to link to item to additional information',
2739
  `biblioitemnumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from the biblioitems table to link to item to additional information',
2740
  `barcode` varchar(20) DEFAULT NULL COMMENT 'item barcode (MARC21 952$p)',
2740
  `barcode` varchar(20) DEFAULT NULL COMMENT 'item barcode (MARC21 952$p)',
2741
  `bookable` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'boolean value defining whether this this item is available for bookings or not',
2741
  `bookable` tinyint(1) DEFAULT NULL COMMENT 'nullable boolean value defining whether this this item is available for bookings or not',
2742
  `dateaccessioned` date DEFAULT NULL COMMENT 'date the item was acquired or added to Koha (MARC21 952$d)',
2742
  `dateaccessioned` date DEFAULT NULL COMMENT 'date the item was acquired or added to Koha (MARC21 952$d)',
2743
  `booksellerid` longtext DEFAULT NULL COMMENT 'where the item was purchased (MARC21 952$e)',
2743
  `booksellerid` longtext DEFAULT NULL COMMENT 'where the item was purchased (MARC21 952$e)',
2744
  `homebranch` varchar(10) DEFAULT NULL COMMENT 'foreign key from the branches table for the library that owns this item (MARC21 952$a)',
2744
  `homebranch` varchar(10) DEFAULT NULL COMMENT 'foreign key from the branches table for the library that owns this item (MARC21 952$a)',
Lines 3995-4001 CREATE TABLE `items` ( Link Here
3995
  `biblionumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from biblio table used to link this item to the right bib record',
3995
  `biblionumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from biblio table used to link this item to the right bib record',
3996
  `biblioitemnumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from the biblioitems table to link to item to additional information',
3996
  `biblioitemnumber` int(11) NOT NULL DEFAULT 0 COMMENT 'foreign key from the biblioitems table to link to item to additional information',
3997
  `barcode` varchar(20) DEFAULT NULL COMMENT 'item barcode (MARC21 952$p)',
3997
  `barcode` varchar(20) DEFAULT NULL COMMENT 'item barcode (MARC21 952$p)',
3998
  `bookable` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'boolean value defining whether this this item is available for bookings or not',
3998
  `bookable` tinyint(1) DEFAULT NULL COMMENT 'nullable boolean value defining whether this this item is available for bookings or not',
3999
  `dateaccessioned` date DEFAULT NULL COMMENT 'date the item was acquired or added to Koha (MARC21 952$d)',
3999
  `dateaccessioned` date DEFAULT NULL COMMENT 'date the item was acquired or added to Koha (MARC21 952$d)',
4000
  `booksellerid` longtext DEFAULT NULL COMMENT 'where the item was purchased (MARC21 952$e)',
4000
  `booksellerid` longtext DEFAULT NULL COMMENT 'where the item was purchased (MARC21 952$e)',
4001
  `homebranch` varchar(10) DEFAULT NULL COMMENT 'foreign key from the branches table for the library that owns this item (MARC21 952$a)',
4001
  `homebranch` varchar(10) DEFAULT NULL COMMENT 'foreign key from the branches table for the library that owns this item (MARC21 952$a)',
(-)a/installer/data/mysql/mandatory/sysprefs.sql (-1 lines)
Lines 345-351 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
345
('IssueLostItem','alert','Defines what should be done when an attempt is made to issue an item that has been marked as lost.','alert|confirm|nothing','Choice'),
345
('IssueLostItem','alert','Defines what should be done when an attempt is made to issue an item that has been marked as lost.','alert|confirm|nothing','Choice'),
346
('IssuingInProcess','0',NULL,'If ON, disables fines if the patron is issuing item that accumulate debt','YesNo'),
346
('IssuingInProcess','0',NULL,'If ON, disables fines if the patron is issuing item that accumulate debt','YesNo'),
347
('item-level_itypes','1','','If ON, enables Item-level Itemtype / Issuing Rules','YesNo'),
347
('item-level_itypes','1','','If ON, enables Item-level Itemtype / Issuing Rules','YesNo'),
348
('item-level_booking','1','','If ON, enables Item-level for future booking feature','YesNo'),
349
('itemBarcodeFallbackSearch','0',NULL,'If set, uses scanned item barcodes as a catalogue search if not found as barcodes','YesNo'),
348
('itemBarcodeFallbackSearch','0',NULL,'If set, uses scanned item barcodes as a catalogue search if not found as barcodes','YesNo'),
350
('itemBarcodeInputFilter','','whitespace|T-prefix|cuecat|libsuite8|EAN13','If set, allows specification of a item barcode input filter','Choice'),
349
('itemBarcodeInputFilter','','whitespace|T-prefix|cuecat|libsuite8|EAN13','If set, allows specification of a item barcode input filter','Choice'),
351
('itemcallnumber','',NULL,'The MARC field/subfield that is used to calculate the itemcallnumber (Dewey would be 082ab or 092ab; LOC would be 050ab or 090ab) could be 852hi from an item record','free'),
350
('itemcallnumber','',NULL,'The MARC field/subfield that is used to calculate the itemcallnumber (Dewey would be 082ab or 092ab; LOC would be 050ab or 090ab) could be 852hi from an item record','free'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt (-11 / +9 lines)
Lines 257-273 Link Here
257
                        [% END %]
257
                        [% END %]
258
                        <span class="hint">If checked, items will be automatically checked in once they've reached their due date. This feature requires the <code>misc/cronjobs/automatic_checkin.pl</code> cronjob. Ask your system administrator to schedule it.</span>
258
                        <span class="hint">If checked, items will be automatically checked in once they've reached their due date. This feature requires the <code>misc/cronjobs/automatic_checkin.pl</code> cronjob. Ask your system administrator to schedule it.</span>
259
                </li>
259
                </li>
260
                [% IF Koha.Preference('item-level_booking') == 0 %]
260
                <li>
261
                    <li>
261
                    <label for="bookable">Bookable: </label>
262
                        <label for="bookable">Bookable: </label>
262
                        [% IF itemtype.bookable %]
263
                            [% IF itemtype.bookable %]
263
                            <input type="checkbox" id="bookable" name="bookable" checked="checked" value="1" />
264
                                <input type="checkbox" id="bookable" name="bookable" checked="checked" value="1" />
264
                        [% ELSE %]
265
                            [% ELSE %]
265
                            <input type="checkbox" id="bookable" name="bookable" value="1" />
266
                                <input type="checkbox" id="bookable" name="bookable" value="1" />
266
                        [% END %]
267
                            [% END %]
267
                        <span class="hint">If checked, all items of this type will be enabled for future bookings unless overridden at the item level.</span>
268
                            <span class="hint">If checked, all items of this type will be enabled for future bookings.</span>
268
                </li>
269
                    </li>
270
                [% END %]
271
                <li>
269
                <li>
272
                    <label for="rentalcharge">Rental charge: </label>
270
                    <label for="rentalcharge">Rental charge: </label>
273
                    <input type="text" id="rentalcharge" name="rentalcharge" size="10" value="[% itemtype.rentalcharge | $Price on_editing => 1 %]" min="0" />
271
                    <input type="text" id="rentalcharge" name="rentalcharge" size="10" value="[% itemtype.rentalcharge | $Price on_editing => 1 %]" min="0" />
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-7 lines)
Lines 1008-1020 Circulation: Link Here
1008
                  0: "Don't allow"
1008
                  0: "Don't allow"
1009
            - holds to be automatically filled after being automatically checked in.
1009
            - holds to be automatically filled after being automatically checked in.
1010
            - '<br><strong>NOTE:</strong> This system preference requires the <code>misc/cronjobs/automatic_checkin.pl</code> cronjob. Ask your system administrator to schedule it.'
1010
            - '<br><strong>NOTE:</strong> This system preference requires the <code>misc/cronjobs/automatic_checkin.pl</code> cronjob. Ask your system administrator to schedule it.'
1011
        -
1012
            - Use the type of the
1013
            - pref: item-level_booking
1014
              choices:
1015
                  1: item
1016
                  0: itemtype
1017
            - level to defined witch items can be bookable in future.
1018
    Patron restrictions:
1011
    Patron restrictions:
1019
        -
1012
        -
1020
            - pref: PatronRestrictionTypes
1013
            - pref: PatronRestrictionTypes
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt (-6 / +12 lines)
Lines 355-375 Link Here
355
                                                    <input type="hidden" name="biblionumber" value="[% ITEM_DAT.biblionumber | html %]" />
355
                                                    <input type="hidden" name="biblionumber" value="[% ITEM_DAT.biblionumber | html %]" />
356
                                                    <input type="hidden" name="biblioitemnumber" value="[% ITEM_DAT.biblioitemnumber | html %]" />
356
                                                    <input type="hidden" name="biblioitemnumber" value="[% ITEM_DAT.biblioitemnumber | html %]" />
357
                                                    <input type="hidden" name="itemnumber" value="[% ITEM_DAT.itemnumber | html %]" />
357
                                                    <input type="hidden" name="itemnumber" value="[% ITEM_DAT.itemnumber | html %]" />
358
                                                    <select name="bookable" [% IF ITEM_DAT.effective_itemtype.bookable == 1 && Koha.Preference('item-level_booking') == 0 %]disabled[% END %]>
358
                                                    <select name="bookable">
359
                                                    [% IF ITEM_DAT.bookable == 1 || ITEM_DAT.effective_itemtype.bookable == 1 %]
359
                                                    [% IF ITEM_DAT.bookable == 1 %]
360
                                                        <option value="">Follow item type</option>
360
                                                        <option value="1" selected="selected">Yes</option>
361
                                                        <option value="1" selected="selected">Yes</option>
361
                                                        <option value="0">No</option>
362
                                                        <option value="0">No</option>
362
                                                        [% ELSE %]
363
                                                    [% ELSIF ITEM_DAT.bookable == 0 %]
364
                                                        <option value="">Follow item type</option>
363
                                                        <option value="1">Yes</option>
365
                                                        <option value="1">Yes</option>
364
                                                        <option value="0" selected="selected">No</option>
366
                                                        <option value="0" selected="selected">No</option>
365
                                                        [% END %]
367
                                                    [% ELSE %]
368
                                                        <option value="" selected="selected">Follow item type</option>
369
                                                        <option value="1">Yes</option>
370
                                                        <option value="0">No</option>
371
                                                    [% END %]
366
                                                    </select>
372
                                                    </select>
367
                                                    <input type="hidden" name="op" value="set_bookable" />
373
                                                    <input type="hidden" name="op" value="set_bookable" />
368
                                                    <input type="submit" name="submit" class="btn btn-primary btn-xs" value="Update" />
374
                                                    <input type="submit" name="submit" class="btn btn-primary btn-xs" value="Update" />
369
                                                </form>
375
                                                </form>
370
                                            [% ELSE %]
376
                                            [% ELSE %]
371
                                                [% IF ITEM_DAT.bookable == 1 %] Yes [% ELSE %] No [% END %]
377
                                                [% IF ITEM_DAT.bookable == 1 %] Yes [% ELSIF ITEM_DAT.bookable == 0 %] No [% ELSE %] Follow item type [% END %]
372
                                            [% END %]
378
                                            [% END %]
379
                                            <span class="hint"> Item type bookable: [% IF ITEM_DAT.effective_itemtype.bookable == 1 %]Yes[% ELSE %]No[% END %]</span>
373
                                        </li>
380
                                        </li>
374
381
375
                                    </ol> <!-- /.bibliodetails -->
382
                                    </ol> <!-- /.bibliodetails -->
376
- 

Return to bug 35906