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

(-)a/Koha/REST/V1/Biblios.pm (-1 / +49 lines)
Lines 154-160 sub delete { Link Here
154
154
155
=head3 populate_empty_callnumbers
155
=head3 populate_empty_callnumbers
156
156
157
Controller function that handles deleting a biblio object
157
Controller function that populates the item callnumbers of any items
158
for the record that currently have no callnumber. The generated callnumbers
159
will be based on the 'itemcallnumber' system preference.
158
160
159
=cut
161
=cut
160
162
Lines 237-242 sub populate_empty_callnumbers { Link Here
237
    };
239
    };
238
}
240
}
239
241
242
=head3 default_item_callnumber
243
244
Return the callnumber generated for the given record based on the "itemcallnumber" system preference.
245
=cut
246
247
sub default_item_callnumber {
248
    my $c = shift->openapi->valid_input or return;
249
250
    my $biblio = Koha::Biblios->find( $c->param('biblio_id') );
251
252
    if ( not defined $biblio ) {
253
        return $c->render(
254
            status  => 404,
255
            openapi => { error => "Biblio not found" }
256
        );
257
    }
258
259
    my $cn_fields = C4::Context->preference('itemcallnumber');
260
    return $c->render(
261
        status  => 404,
262
        openapi => { error => "Callnumber fields not found" }
263
    ) unless $cn_fields;
264
265
    my $record = $biblio->record;
266
    my $callnumber;
267
268
    foreach my $callnumber_marc_field ( split( /,/, $cn_fields ) ) {
269
        my $callnumber_tag       = substr( $callnumber_marc_field, 0, 3 );
270
        my $callnumber_subfields = substr( $callnumber_marc_field, 3 );
271
272
        next unless $callnumber_tag && $callnumber_subfields;
273
274
        my $field = $record->field($callnumber_tag);
275
276
        next unless $field;
277
278
        $callnumber = $field->as_string( $callnumber_subfields, ' ' );
279
        last if $callnumber;
280
    }
281
282
    return $c->render(
283
        status  => 200,
284
        openapi => { callnumber => $callnumber },
285
    );
286
}
287
240
=head3 get_public
288
=head3 get_public
241
289
242
Controller function that handles retrieving a single biblio object
290
Controller function that handles retrieving a single biblio object
(-)a/api/v1/swagger/paths/biblios.yaml (+46 lines)
Lines 950-952 Link Here
950
        description: Under maintenance
950
        description: Under maintenance
951
        schema:
951
        schema:
952
          $ref: "../swagger.yaml#/definitions/error"
952
          $ref: "../swagger.yaml#/definitions/error"
953
"/biblios/{biblio_id}/default_item_callnumber":
954
  get:
955
    x-mojo-to: Biblios#default_item_callnumber
956
    operationId: getBiblioDefaultItemCallnumber
957
    tags:
958
      - biblios
959
    summary: Get default item callnumber for a biblio
960
    parameters:
961
      - $ref: "../swagger.yaml#/parameters/biblio_id_pp"
962
    produces:
963
      - application/json
964
    responses:
965
      "200":
966
        description: Generated call number
967
        schema:
968
          type: object
969
          properties:
970
            callnumber:
971
              description: Item call number benerated for biblio
972
              type: string
973
      "401":
974
        description: Authentication required
975
        schema:
976
          $ref: "../swagger.yaml#/definitions/error"
977
      "403":
978
        description: Access forbidden
979
        schema:
980
          $ref: "../swagger.yaml#/definitions/error"
981
      "404":
982
        description: Biblio not found
983
        schema:
984
          $ref: "../swagger.yaml#/definitions/error"
985
      "500":
986
        description: |
987
          Internal server error. Possible `error_code` attribute values:
988
989
          * `internal_server_error`
990
        schema:
991
          $ref: "../swagger.yaml#/definitions/error"
992
      "503":
993
        description: Under maintenance
994
        schema:
995
          $ref: "../swagger.yaml#/definitions/error"
996
    x-koha-authorization:
997
      permissions:
998
        catalogue: "1"
(-)a/api/v1/swagger/swagger.yaml (+2 lines)
Lines 231-236 paths: Link Here
231
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1checkouts"
231
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1checkouts"
232
  "/biblios/{biblio_id}/items":
232
  "/biblios/{biblio_id}/items":
233
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1items"
233
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1items"
234
  "/biblios/{biblio_id}/default_item_callnumber":
235
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1default_item_callnumber"
234
  "/biblios/{biblio_id}/items/populate_empty_callnumbers":
236
  "/biblios/{biblio_id}/items/populate_empty_callnumbers":
235
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1items~1populate_empty_callnumbers"
237
    $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1items~1populate_empty_callnumbers"
236
  "/biblios/{biblio_id}/items/{item_id}/populate_empty_callnumbers":
238
  "/biblios/{biblio_id}/items/{item_id}/populate_empty_callnumbers":
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc (-8 / +4 lines)
Lines 43-48 Link Here
43
            <li><a id="modifybiblio" href="/cgi-bin/koha/tools/batch_record_modification.pl?recordtype=biblio&op=list&recordnumber_list=[% biblionumber | html %]">Modify record using template</a></li>
43
            <li><a id="modifybiblio" href="/cgi-bin/koha/tools/batch_record_modification.pl?recordtype=biblio&op=list&recordnumber_list=[% biblionumber | html %]">Modify record using template</a></li>
44
            [% END %]
44
            [% END %]
45
45
46
            [% IF Koha.Preference('EnablePopulateCallnumbers') && ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items || CAN_user_tools_items_batchmod || CAN_user_tools_items_batchdel ) or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %]
47
                <li><a id="populate-callnumbers-biblio" href="#" data-biblionumber="[% biblionumber | html %]" data-toggle="tooltip" data-placement="left" title="Populate callnumbers for items with no call number.">Populate call numbers</a></li>
48
            [% END %]
49
46
            [% IF CAN_user_editcatalogue_edit_items or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %]
50
            [% IF CAN_user_editcatalogue_edit_items or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %]
47
            <li><a id="edititems" href="/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblionumber | html %]">Edit items</a></li>
51
            <li><a id="edititems" href="/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblionumber | html %]">Edit items</a></li>
48
            [% END %]
52
            [% END %]
Lines 211-224 Link Here
211
    [% END %]
215
    [% END %]
212
[% END %]
216
[% END %]
213
217
214
[% IF Koha.Preference('EnablePopulateCallnumbers') %]
215
[% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items || CAN_user_tools_items_batchmod || CAN_user_tools_items_batchdel ) or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %]
216
    <div class="btn-group">
217
        <button id="populate-callnumbers-biblio" class="btn btn-default" href="#" data-biblionumber="[% biblionumber | html %]" data-toggle="tooltip" data-placement="top" title="Populate callnumbers for items with no callnumber."><i class="fa fa-bars"></i> Populate callnumbers</button>
218
    </div>
219
[% END %]
220
[% END %]
221
222
[% FOREACH p IN plugins %]
218
[% FOREACH p IN plugins %]
223
    [% p.intranet_catalog_biblio_enhancements_toolbar_button | $raw %]
219
    [% p.intranet_catalog_biblio_enhancements_toolbar_button | $raw %]
224
[% END %]
220
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-5 / +9 lines)
Lines 642-660 Link Here
642
                [% IF CAN_user_editcatalogue_edit_items %]
642
                [% IF CAN_user_editcatalogue_edit_items %]
643
                    <td class="actions">
643
                    <td class="actions">
644
                        [% IF item.can_be_edited %]
644
                        [% IF item.can_be_edited %]
645
                            [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %]
645
                            [% SET show_itemcallnumber_link = !item.itemcallnumber && Koha.Preference('EnablePopulateCallnumbers') %]
646
                            [% SET show_local_covers_link = Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %]
647
                            [% IF show_itemcallnumber_link || show_itemcallnumber_link %]
646
                                <div class="btn-group">
648
                                <div class="btn-group">
647
                                    <a  class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber | html %]&itemnumber=[% item.itemnumber | html %]#edititem"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a><a class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
649
                                    <a  class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber | html %]&itemnumber=[% item.itemnumber | html %]#edititem"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a><a class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
648
                                    <ul class="dropdown-menu pull-right">
650
                                    <ul class="dropdown-menu pull-right">
649
                                        <li><a href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=[% item.itemnumber | uri %]&amp;filetype=image"><i class="fa fa-upload"></i> Upload image</a></li>
651
                                        [% IF show_local_covers_link %]
652
                                            <li><a href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=[% item.itemnumber | uri %]&amp;filetype=image"><i class="fa fa-upload"></i> Upload image</a></li>
653
                                        [% END %]
654
                                        [% IF show_itemcallnumber_link %]
655
                                            <li><a class="populate-callnumber-item" href="#" data-itemnumber="[% item.itemnumber | html %]" data-biblionumber="[% item.biblionumber | html %]" data-toggle="tooltip" data-placement="left" title="Populate callnumber for this item."><i class="fa fa-bars"></i> Populate callnumber</a></li>
656
                                        [% END %]
650
                                    </ul>
657
                                    </ul>
651
                                </div>
658
                                </div>
652
                            [% ELSE %]
659
                            [% ELSE %]
653
                                <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber | html %]&itemnumber=[% item.itemnumber | html %]#edititem"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a>
660
                                <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=[% item.biblionumber | html %]&itemnumber=[% item.itemnumber | html %]#edititem"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a>
654
                            [% END %]
661
                            [% END %]
655
                            [% IF !item.itemcallnumber && Koha.Preference('EnablePopulateCallnumbers') %]
656
                                <button class="populate-callnumber-item" class="btn btn-default" href="#" data-itemnumber="[% item.itemnumber | html %]" data-biblionumber="[% item.biblionumber | html %]" data-toggle="tooltip" data-placement="top" title="Populate callnumber for this item."><i class="fa fa-bars"></i> Populate callnumber</button>
657
                            [% END %]
658
                        [% END %]
662
                        [% END %]
659
                        [% IF bundlesEnabled %]
663
                        [% IF bundlesEnabled %]
660
                            <button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> Manage bundle ([% item.bundled | html %]|[% item.bundled_lost | html %])</button>
664
                            <button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> Manage bundle ([% item.bundled | html %]|[% item.bundled_lost | html %])</button>
(-)a/koha-tmpl/intranet-tmpl/prog/js/catalog.js (-30 / +37 lines)
Lines 126-166 $(document).ready(function() { Link Here
126
126
127
    $("#populate-callnumbers-biblio")
127
    $("#populate-callnumbers-biblio")
128
        .on('click', function() {
128
        .on('click', function() {
129
            if ( confirm(__('Are you sure you want to populate callnumbers for all items without a callnumber on this record?')) ) {
129
            $.getJSON( `/api/v1/biblios/${biblionumber}/default_item_callnumber`, function( cn ) {
130
                const biblionumber = $(this).data('biblionumber');
130
                const callnumber = cn.callnumber;
131
                $.post( `/api/v1/biblios/${biblionumber}/items/populate_empty_callnumbers`, function( data ) {
131
                if ( confirm(__(`Are you sure you want to populate callnumbers for all items without a callnumber on this record to the following value: ${callnumber}`)) ) {
132
                    const items_updated = data.items_updated;
132
                    const biblionumber = $(this).data('biblionumber');
133
                    const callnumber = data.callnumber;
133
                    $.post( `/api/v1/biblios/${biblionumber}/items/populate_empty_callnumbers`, function( data ) {
134
                    let msg = __('Items populated with the callnumber "%s": %s').format(callnumber, items_updated);
134
                        const items_updated = data.items_updated;
135
135
                        const callnumber = data.callnumber;
136
                    if ( items_updated ) {
136
                        let msg = __('Items populated with the callnumber "%s": %s').format(callnumber, items_updated);
137
                        msg += __('\nReload the page?');
137
138
                        if( confirm(msg) ) {
138
                        if ( items_updated ) {
139
                            location.reload(true);
139
                            msg += " " + __('Reload the page?');
140
                            if( confirm(msg) ) {
141
                                location.reload(true);
142
                            }
143
                        } else {
144
                            alert(msg);
140
                        }
145
                        }
141
                    } else {
146
                    });
142
                        alert(msg);
147
                }
143
                    }
148
            });
144
                });
145
            }
146
        }).tooltip();
149
        }).tooltip();
147
150
148
    $(".populate-callnumber-item")
151
    $(".populate-callnumber-item")
149
        .on('click', function() {
152
        .on('click', function() {
150
            if ( confirm(__('Are you sure you want to populate the callnumber for this item?')) ) {
153
            $.getJSON( `/api/v1/biblios/${biblionumber}/default_item_callnumber`, function( cn ) {
151
                const biblionumber = $(this).data('biblionumber');
154
                const callnumber = cn.callnumber;
152
                const itemnumber  = $(this).data('itemnumber');
155
                if ( confirm(__(`Are you sure you want to populate the callnumber for this item to the following value: ${callnumber}`)) ) {
153
                const button = $(this);
156
                    const biblionumber = $(this).data('biblionumber');
154
                $.post( `/api/v1/biblios/${biblionumber}/items/${itemnumber}/populate_empty_callnumbers`, function( data ) {
157
                    const itemnumber  = $(this).data('itemnumber');
155
                    const callnumber = data.callnumber;
158
                    const button = $(this);
156
                    let msg = __('Item populated with the callnumber "%s"\nReload the page?').format(callnumber);
159
                    $.post( `/api/v1/biblios/${biblionumber}/items/${itemnumber}/populate_empty_callnumbers`, function( data ) {
157
                    if( confirm(msg) ) {
160
                        const callnumber = data.callnumber;
158
                        location.reload(true);
161
                        let msg = __('Item populated with the callnumber "%s"').format(callnumber);
159
                    } else {
162
                        msg += " " + __('Reload the page?');
160
                        button.hide();
163
                        if( confirm(msg) ) {
161
                    }
164
                            location.reload(true);
162
                });
165
                        } else {
163
            }
166
                            button.hide();
167
                        }
168
                    });
169
                }
170
            });
164
        }).tooltip();
171
        }).tooltip();
165
172
166
    $(".addtolist").on("click", function (e) {
173
    $(".addtolist").on("click", function (e) {
(-)a/t/db_dependent/api/v1/biblios.t (-3 / +5 lines)
Lines 1813-1819 subtest 'update_item() tests' => sub { Link Here
1813
};
1813
};
1814
1814
1815
subtest 'populate_empty_callnumbers() tests' => sub {
1815
subtest 'populate_empty_callnumbers() tests' => sub {
1816
    plan tests => 23;
1816
    plan tests => 26;
1817
1817
1818
    t::lib::Mocks::mock_preference( 'itemcallnumber', '245a' );
1818
    t::lib::Mocks::mock_preference( 'itemcallnumber', '245a' );
1819
1819
Lines 1824-1830 subtest 'populate_empty_callnumbers() tests' => sub { Link Here
1824
    my $patron = $builder->build_object(
1824
    my $patron = $builder->build_object(
1825
        {
1825
        {
1826
            class => 'Koha::Patrons',
1826
            class => 'Koha::Patrons',
1827
            value => { flags => 0 }
1827
            value => { flags => 2**2 }
1828
        }
1828
        }
1829
    );
1829
    );
1830
    my $password = 'thePassword123';
1830
    my $password = 'thePassword123';
Lines 1885-1890 subtest 'populate_empty_callnumbers() tests' => sub { Link Here
1885
    $t->post_ok( "//$userid:$password@/api/v1/biblios/0/items/$item1_id/populate_empty_callnumbers" => json => {} )
1885
    $t->post_ok( "//$userid:$password@/api/v1/biblios/0/items/$item1_id/populate_empty_callnumbers" => json => {} )
1886
        ->status_is( 404, 'Record not found' );
1886
        ->status_is( 404, 'Record not found' );
1887
1887
1888
    $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/default_item_callnumber" => json => {} )
1889
        ->status_is( 200, 'Items updated' )->json_is( '/callnumber', 'Some boring read' );
1890
1888
    $schema->storage->txn_rollback;
1891
    $schema->storage->txn_rollback;
1889
1892
1890
};
1893
};
1891
- 

Return to bug 34784