Bug 37334: Restore filtering holdings per status

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi>

Bug 37334: Fix column offset

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Jonathan Druart 2024-10-02 14:52:18 +02:00 committed by Katrin Fischer
parent e8129f5aea
commit a61d0178c6
No known key found for this signature in database
GPG Key ID: 0EF6E2C03357A834
3 changed files with 146 additions and 12 deletions

View File

@ -1446,11 +1446,7 @@ sub _status {
push @statuses, "local_use";
}
} elsif ( my $transfer = $self->transfer ) {
if ( $transfer->datesent ) {
push @statuses, "in_transit";
} else {
push @statuses, "transit_pending";
}
push @statuses, "in_transit";
}
if ( $self->itemlost ) {
push @statuses, 'lost';

View File

@ -225,6 +225,90 @@ sub filter_by_bookable {
);
}
sub filter_by_checked_out {
my ( $self, $params ) = @_;
$params //= {};
my $checkouts = Koha::Checkouts->search(
{ %$params, 'me.itemnumber' => [ $self->get_column('itemnumber') ], },
{
columns => ['itemnumber'],
distinct => 1
}
)->_resultset->as_query;
return $self->search( { 'me.itemnumber' => { '-in' => $checkouts } } );
}
sub filter_by_in_transit {
my ( $self, $params ) = @_;
$params //= {};
my $transfers = Koha::Item::Transfers->search(
{ %$params, 'me.itemnumber' => [ $self->get_column('itemnumber') ], },
{
columns => ['itemnumber'],
distinct => 1
}
)->_resultset->as_query;
return $self->search( { 'me.itemnumber' => { '-in' => $transfers } } );
}
sub filter_by_for_loan {
}
sub filter_by_has_holds {
my ( $self, $params ) = @_;
$params //= {};
my $holds = Koha::Holds->search(
{ %$params, 'me.itemnumber' => [ $self->get_column('itemnumber') ], },
{
columns => ['itemnumber'],
distinct => 1
}
)->_resultset->as_query;
return $self->search( { 'me.itemnumber' => { '-in' => $holds } } );
}
sub filter_by_has_recalls {
my ( $self, $params ) = @_;
$params //= {};
my $recalls = Koha::Recalls->search(
{ %$params, 'me.itemnumber' => [ $self->get_column('itemnumber') ], },
{
columns => ['itemnumber'],
distinct => 1
}
)->_resultset->as_query;
return $self->search( { 'me.itemnumber' => { '-in' => $recalls } } );
}
sub filter_by_available {
my ($self) = @_;
my @all_itemnumbers = $self->get_column('itemnumber');
my @item_types_notforloan = Koha::ItemTypes->search( { notforloan => { '!=' => 0 } } )->get_column('itemtype');
my @not_available_itemnumbers;
push @not_available_itemnumbers, $self->filter_by_checked_out->get_column('itemnumber');
push @not_available_itemnumbers, $self->filter_by_in_transit->get_column('itemnumber');
push @not_available_itemnumbers, $self->search(
{
itemlost => 0, withdrawn => 0, damaged => 0, notforloan => 0,
itype => { -not_in => \@item_types_notforloan }, restricted => 0,
}
)->get_column('itemnumber');
push @not_available_itemnumbers, $self->filter_by_has_holds->get_column('itemnumber');
push @not_available_itemnumbers, $self->filter_by_has_recalls->get_column('itemnumber');
return Koha::Items->search( { 'me.itemnumber' => [ array_minus @all_itemnumbers, @not_available_itemnumbers ] } );
}
=head3 move_to_biblio
$items->move_to_biblio($to_biblio);
@ -498,6 +582,52 @@ sub apply_regex {
return $value;
}
sub search {
my ( $self, $params, $attributes ) = @_;
my $status = ( $params && ref($params) eq 'HASH' ) ? delete $params->{_status} : undef;
if ($status) {
if ( $status eq 'checked_out' ) {
$self = $self->filter_by_checked_out( { onsite_checkout => 0 } );
}
if ( $status eq 'local_use' ) {
$self = $self->filter_by_checked_out( { onsite_checkout => 1 } );
}
if ( $status eq 'in_transit' ) {
$self = $self->filter_by_in_transit;
}
if ( $status eq 'lost' ) {
$self = $self->search( { itemlost => { '!=' => 0 } } );
}
if ( $status eq 'withdrawn' ) {
$self = $self->search( { withdrawn => { '!=' => 0 } } );
}
if ( $status eq 'damaged' ) {
$self = $self->search( { damaged => { '!=' => 0 } } );
}
if ( $status eq 'not_for_loan' ) {
my @item_types_notforloan =
Koha::ItemTypes->search( { notforloan => { '!=' => 0 } } )->get_column('itemtype');
$self = $self->search( [ { notforloan => { '!=' => 0 } }, { 'me.itype' => \@item_types_notforloan } ] );
}
if ( $status eq 'on_hold' ) {
$self = $self->filter_by_has_holds;
}
if ( $status eq 'recalled' ) {
$self = $self->filter_by_has_recalls;
}
if ( $status eq 'available' ) {
$self = $self->filter_by_available;
}
if ( $status eq 'restricted' ) {
$self = $self->search( { restricted => { '!=' => 0 } } );
}
}
return $self->SUPER::search( $params, $attributes );
}
=head3 search_ordered
$items->search_ordered;

View File

@ -220,6 +220,9 @@
});
const item_types_notforloan = new Map(all_item_types.map( it => [it.itemtype, it.notforloan] ));
const statuses = {checked_out: _("Checked out"), local_use: _("On-site checkout"), in_transit: _("In transit"), lost: _("Lost"), withdrawn: _("Withdrawn"), damaged:_("Damaged"), not_for_loan: _("Not for loan"), on_hold: _("On hold"), recalled: _("Recalled"), available: _("Available"), restricted: _("Restricted")};
const all_statuses = Object.keys(statuses).map(k => {return {_id: k, _str: statuses[k]}});
const can_edit_items_from = [% To.json(can_edit_items_from || []) | $raw %];
const item_type_image_locations = [% To.json(item_type_image_locations) | $raw %];
const av_loc = new Map([% To.json(AuthorisedValues.Get('LOC')) | $raw %].map( av => [av.authorised_value, av.lib]));
@ -319,12 +322,17 @@
items_selection[tab_id] = [];
}
default_filters._status = function(){
return $("#" + tab_id + "_status select").val();
};
let offset = 2;
[% UNLESS Koha.Preference('LocalCoverImages') %]offset--;[% END %]
let filters_options = {
[offset] : () => all_item_types,
[offset+1] : () => all_libraries,
[offset+2] : () => all_libraries,
[offset+7] : () => all_statuses,
};
var items_table = $("#" + tab_id + '_table').kohaTable({
@ -497,9 +505,9 @@
}
},
{
data: "me._status",
data: "",
className: "status",
searchable: false, // FIXME We are losing the ability to search on the status
searchable: false,
orderable: false,
render: function (data, type, row, meta) {
let nodes = "";
@ -523,11 +531,11 @@
}
if ( status == 'in_transit' ) {
nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent)));
}
if ( status == 'transit_pending' ) {
nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested)));
if ( row.transfer.datesent ) {
nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent)));
} else {
nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested)));
}
}
if ( status == 'lost' ) {