Bug 38122: Add the ability to group holdings by status

This is a quite ugly solution, but that may answer end-user needs.

It add the option the group items by status on the bibliographic record
detail page.

However it will have VERY bad impact on performances for record with a
lot of items, as we are going to determine the status of each items of
the record.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Jonathan Druart 2025-07-04 12:07:35 +02:00 committed by Pedro Amorim
parent 89da78b3b9
commit fe876c795d
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
3 changed files with 53 additions and 3 deletions

View File

@ -256,6 +256,9 @@ sub get_items {
# Deletion of parameter to avoid filtering on the items table in the case of bookings on 'itemtype'
$c->req->params->remove('bookable');
my $group_by_status = $c->param('group_by_status');
$c->req->params->remove('group_by_status');
return $c->render_resource_not_found("Bibliographic record")
unless $biblio;
@ -267,6 +270,22 @@ sub get_items {
my $items_rs = $biblio->items( { host_items => 1 } )->search_ordered( {}, { join => 'biblioitem' } );
$items_rs = $items_rs->filter_by_bookable if $bookable_only;
if ($group_by_status) {
my @item_ids;
for my $status (
qw( available checked_out local_use in_transit lost withdrawn damaged not_for_loan on_hold recalled in_bundle restricted )
)
{
push @item_ids, $items_rs->search( { _status => $status } )->get_column('itemnumber');
}
$items_rs = $items_rs->search(
{},
{
order_by => [ \[ sprintf( "field(me.itemnumber, %s)", join( ', ', map { qq{'$_'} } @item_ids ) ) ] ]
}
);
}
# FIXME We need to order_by serial.publisheddate if we have _order_by=+me.serial_issue_number
my $items = $c->objects->search($items_rs);

View File

@ -504,6 +504,11 @@
description: Limit to items that are bookable
required: false
type: boolean
- name: group_by_status
in: query
description: Return the items grouped by status
required: false
type: boolean
consumes:
- application/json
produces:

View File

@ -61,6 +61,7 @@
</span>
<button class="btn btn-link SelectAll" data-tab="[% tab | html %]"><i class="fa fa-check"></i> Select all</button>
<button class="btn btn-link ClearAll" data-tab="[% tab | html %]"><i class="fa fa-times"></i> Clear all</button>
<button class="btn btn-link GroupByStatus" data-tab="[% tab | html %]"><i class="fa fa-object-group"></i> Group by status</button>
<span class="itemselection_actions">
| Actions:
[% IF CAN_user_tools_items_batchdel %]
@ -303,7 +304,6 @@
// FIXME The X-Base-Total-Count will be the number of items of the biblios
// In case or SeparateHoldings we may need to display the number of biblios in each tab
// Do we need separate/new endpoints or do we hack the somewhere client-side?
let item_table_url = `/api/v1/biblios/${biblionumber}/items?`;
let embed = ["+strings,_status,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"];
if (Koha.prefs.LocalCoverImages) {
embed.push("cover_image_ids");
@ -334,7 +334,26 @@
embed.push("analytics_count");
}
let user_colvis = { holdings: {}, otherholdings: {} };
let group_by_status_values = {
holdings: false,
otherholdings: false,
};
$(".GroupByStatus").on("click",function(e){
e.preventDefault();
let tab_id = $(this).data("tab");
let was_grouped = group_by_status_values[tab_id];
group_by_status_values[tab_id] = !was_grouped;
build_items_table(tab_id, true, { destroy: true }, build_items_table_drawncallback );
if ( was_grouped ) {
$(this).html('<i class="fa fa-object-group"></i>' + _("Group by status") + '</button>');
} else {
$(this).html('<i class="fa fa-object-ungroup"></i>' + _("Ungroup by status") + '</button>');
}
});
let user_colvis = {holdings: {}, otherholdings: {}};
function build_items_table(tab_id, add_filters, dt_options, drawcallback) {
let table_dt;
if (dt_options && dt_options.hasOwnProperty("destroy")) {
@ -369,6 +388,13 @@
return $("#" + tab_id + "_status select").val();
};
let group_by_status = function(){
if ( group_by_status_values[tab_id] ) {
return 'group_by_status=1';
}
return '';
}
var columns = [
{
data: "me.item_id",
@ -921,7 +947,7 @@
];
var items_table = $("#" + tab_id + "_table").kohaTable(
{
ajax: { url: item_table_url },
ajax: { url: "/api/v1/biblios/[% biblio.biblionumber | uri %]/items?" + group_by_status() },
order: [],
embed,
autoWidth: false,