From 16d86969013ea92bb2039faa6ccfc24e90efb56f Mon Sep 17 00:00:00 2001 From: Ayoub Glizi-Vicioso Date: Wed, 11 Feb 2026 16:35:56 -0500 Subject: [PATCH] Bug 38122: (follow-up) Correct item regrouping behavior --- Koha/REST/V1/Biblios.pm | 24 ++-- .../tables/items/catalogue_detail.inc | 108 ++++++++++++++++-- 2 files changed, 116 insertions(+), 16 deletions(-) diff --git a/Koha/REST/V1/Biblios.pm b/Koha/REST/V1/Biblios.pm index d9e689850b..89d0629cdd 100644 --- a/Koha/REST/V1/Biblios.pm +++ b/Koha/REST/V1/Biblios.pm @@ -271,17 +271,25 @@ sub get_items { if ($group_by_status) { $c->req->params->remove('_order_by'); - 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 ) ) ] ] + order_by => [ + \[ "CASE + WHEN (withdrawn != 0) THEN '10_Withdrawn' + WHEN (itemlost != 0) THEN '09_Lost' + WHEN (damaged != 0) THEN '08_Damaged' + WHEN (notforloan = 3) THEN '07_In bundle' + WHEN (notforloan != 0) THEN '06_Not for loan' + WHEN EXISTS (SELECT 1 FROM issues WHERE itemnumber = me.itemnumber AND onsite_checkout = 1) THEN '05_Local use' + WHEN (onloan IS NOT NULL) THEN '04_Checked out' + WHEN (SELECT COUNT(*) FROM branchtransfers WHERE itemnumber = me.itemnumber AND datearrived IS NULL) > 0 THEN '03_In transit' + WHEN (SELECT COUNT(*) FROM reserves WHERE itemnumber = me.itemnumber AND (found IS NULL OR found = 'W')) > 0 THEN '02_On hold' + ELSE '01_Available' + END ASC" ], + { -asc => 'me.itemlost' }, + { -asc => 'me.notforloan' }, + ] } ); } diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc index a9ac561d15..908165866a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc @@ -301,19 +301,111 @@ holdings: false, otherholdings: false, }; - $(".GroupByStatus").on("click",function(e){ + + function get_display_status(row, forSort = false) { + let status = ""; + let priority = ""; + + if (!row._status) row._status = []; + + if (row.withdrawn != 0) { + status = _("Withdrawn"); + priority = "10"; + } else if (row.lost_status != 0) { + let lost_text = av_lost.get(row.lost_status.toString()) || _("Lost"); + status = lost_text; + if (forSort) { + if (lost_text.toLowerCase().includes("paid")) priority = "09c"; + else if (lost_text.toLowerCase().includes("overdue")) priority = "09b"; + else priority = "09a"; + } else { + priority = "09"; + } + } + else if (row.damaged_status != 0) { + status = _("Damaged"); + priority = "08"; + } + else if (row.not_for_loan_status == 3) { + status = _("In bundle"); + priority = "07"; + } else if (row.not_for_loan_status != 0) { + status = _("Not for loan"); + priority = "06"; + } + else if (row._status.includes('local_use')) { + status = _("Local use"); + priority = "05"; + } + else if (row._status.includes('checked_out')) { + status = _("Checked out"); + priority = "04"; + } + else if (row._status.includes('in_transit')) { + status = _("In transit"); + priority = "03"; + } + else if (row._status.includes('on_hold') || row._status.includes('waiting')) { + status = _("On hold"); + priority = "02"; + } + else if (row._status.includes('available') || (row.lost_status == 0 && row.withdrawn == 0)) { + status = _("Available"); + priority = "01"; + } + else { + status = _("Undefined"); + priority = "99"; + } + + status = status.trim(); + + if (forSort) { + if (priority.startsWith("09")) { + return "09_" + _("Lost"); + } + return priority + "_" + status; + } + + return status; + } + + $(".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; + group_by_status_values[tab_id] = !group_by_status_values[tab_id]; + let is_grouping = group_by_status_values[tab_id]; + + var dt_options = { + "destroy": true, + }; + + if (is_grouping) { + dt_options["rowGroup"] = { + "dataSrc": function(row) { + return get_display_status(row, true); + }, + "startRender": function (rows, group) { + let displayTitle = group.indexOf('_') !== -1 ? group.split('_')[1] : group; + + let groupColor = "#007bff"; - build_items_table(tab_id, true, { destroy: true }, build_items_table_drawncallback ); + if (group.startsWith("01")) { + groupColor = "#28a745"; + } else if (group.startsWith("08") || group.startsWith("09") || group.startsWith("10")) { + groupColor = "#dc3545"; + } + + return $('' + + displayTitle + ' (' + rows.count() + ')'); + } + }; - if ( was_grouped ) { - $(this).html(' ' + _("Group by status") + ''); + $(this).html(' ' + _("Ungroup by status") + ''); } else { - $(this).html(' '+ _("Ungroup by status") + ''); + $(this).html(' '+ _("Group by status") + ''); } + build_items_table(tab_id, true, dt_options, build_items_table_drawncallback, { group_by_status: is_grouping ? 1 : 0 }); }); function build_items_table (tab_id, add_filters, dt_options, drawcallback) { @@ -570,7 +662,7 @@ } if ( status == 'lost' ) { - let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing"); + let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing)"); nodes += '%s'.format(escape_str(lost_lib)); const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false -- 2.52.0