Bugzilla – Attachment 176023 Details for
Bug 37334
Cannot filter holdings table by status
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 37334: Allow embed _status for GET /biblio/{biblio_id}/items
0001-Bug-37334-Allow-embed-_status-for-GET-biblio-biblio_.patch (text/plain), 15.92 KB, created by
Emmi Takkinen
on 2024-12-31 08:06:52 UTC
(
hide
)
Description:
Bug 37334: Allow embed _status for GET /biblio/{biblio_id}/items
Filename:
MIME Type:
Creator:
Emmi Takkinen
Created:
2024-12-31 08:06:52 UTC
Size:
15.92 KB
patch
obsolete
>From ad5454f982025631589554d08565d202727de6f6 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Wed, 2 Oct 2024 11:02:13 +0200 >Subject: [PATCH 01/13] Bug 37334: Allow embed _status for GET > /biblio/{biblio_id}/items > >Signed-off-by: Lucas Gass <lucas@bywatersolutions.com> >Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi> >--- > Koha/Item.pm | 50 +++++++ > api/v1/swagger/definitions/item.yaml | 5 + > api/v1/swagger/paths/biblios.yaml | 1 + > .../tables/items/catalogue_detail.inc | 132 +++++++++--------- > 4 files changed, 123 insertions(+), 65 deletions(-) > >diff --git a/Koha/Item.pm b/Koha/Item.pm >index 07fc6ad5c8..f6bc0f6951 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -1443,6 +1443,56 @@ sub columns_to_str { > return $values; > } > >+sub _status { >+ my ($self) = @_; >+ >+ my @statuses; >+ if ( my $checkout = $self->checkout ) { >+ unless ( $checkout->onsite_checkout ) { >+ push @statuses, "checked_out"; >+ } else { >+ push @statuses, "local_use"; >+ } >+ } elsif ( my $transfer = $self->transfer ) { >+ if ( $transfer->datesent ) { >+ push @statuses, "in_transit"; >+ } else { >+ push @statuses, "transit_pending"; >+ } >+ } >+ if ( $self->itemlost ) { >+ push @statuses, 'lost'; >+ } >+ if ( $self->withdrawn ) { >+ push @statuses, 'withdrawn'; >+ } >+ if ( $self->damaged ) { >+ push @statuses, 'damaged'; >+ } >+ if ( $self->notforloan || $self->item_type->notforloan ) { >+ # TODO on a big Koha::Items loop we are going to join with item_type too often, use a cache >+ push @statuses, 'not_for_loan'; >+ } >+ if ( $self->first_hold ) { >+ push @statuses, 'on_hold'; >+ } >+ if ( C4::Context->preference('UseRecalls') && $self->recall ) { >+ push @statuses, 'recalled'; >+ } >+ >+ unless (@statuses ){ >+ push @statuses, 'available'; >+ } >+ >+ if ( $self->restricted ) { >+ push @statuses, 'restricted'; >+ } >+ >+ # TODO in_bundle? >+ >+ return join ',', @statuses; >+} >+ > =head3 additional_attributes > > my $attributes = $item->additional_attributes; >diff --git a/api/v1/swagger/definitions/item.yaml b/api/v1/swagger/definitions/item.yaml >index b254eb2dc3..cf57ec5f67 100644 >--- a/api/v1/swagger/definitions/item.yaml >+++ b/api/v1/swagger/definitions/item.yaml >@@ -322,4 +322,9 @@ properties: > - object > - "null" > description: A return claims object if one exists that's unresolved >+ _status: >+ type: >+ - string >+ - "null" >+ description: The status of the item > additionalProperties: false >diff --git a/api/v1/swagger/paths/biblios.yaml b/api/v1/swagger/paths/biblios.yaml >index 6502a4f67d..f3538547cc 100644 >--- a/api/v1/swagger/paths/biblios.yaml >+++ b/api/v1/swagger/paths/biblios.yaml >@@ -455,6 +455,7 @@ > type: string > enum: > - +strings >+ - _status > - home_library > - holding_library > - biblio.title >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 83559a159e..2783165883 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 >@@ -232,7 +232,7 @@ > [%# 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/[% biblio.biblionumber | uri %]/items?"; >- let embed = ["+strings,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"]; >+ 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.Preference('LocalCoverImages') %] > embed.push('cover_image_ids'); > [% END %] >@@ -467,82 +467,84 @@ > } > }, > { >- data: "me.lost_status", >+ data: "me._status", > className: "status", > searchable: false, // FIXME We are losing the ability to search on the status > orderable: false, > render: function (data, type, row, meta) { > let nodes = ""; >- if ( row.checkout ) { >- [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >- row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) }; >+ row._status.split(",").forEach( status => { >+ if ( status == 'checked_out' || status == 'local_use') { >+ nodes += '<span>'; > >- nodes += '<span>'; >- if ( row.checkout.onsite_checkout ) { >+ [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >+ row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) }; > let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name }); >- nodes += _("Currently in local use by %s").format(patron_to_html); >- } else { >- nodes += '<span class="datedue">'; >- let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name }); >- nodes += _("Checked out to %s").format(patron_to_html); >+ >+ if ( status == 'local_use' ) { >+ nodes += _("Currently in local use by %s").format(patron_to_html); >+ } else { >+ nodes += '<span class="datedue">'; >+ nodes += _("Checked out to %s").format(patron_to_html); >+ } >+ nodes += ': '; >+ nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true })); >+ nodes += "</span>" >+ > } >- nodes += ': '; >- nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true })); >- nodes += "</span>" >- } else if ( row.transfer ) { >- if ( row.transfer.datesent ) { >+ 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))); >- } else { >+ } >+ >+ 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.lost_status ) { >- let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing"); >- nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib)); >- [% IF Koha.Preference('ClaimReturnedLostValue') %] >- const hasReturnClaims = row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false >+ if ( status == 'lost' ) { >+ let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing"); >+ nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib)); >+ >+ const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false > if(hasReturnClaims) { > nodes += '<span class="claimed_returned">' + _("(Claimed returned)") + '</span>'; > } >- [% END %] >- } >+ } > >- if ( row.withdrawn ) { >- let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn"); >- nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib)); >- } >+ if ( status == 'withdrawn' ) { >+ let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn"); >+ nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib)); >+ } > >- if ( row.damaged_status ) { >- let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged"); >- nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib)); >- } >+ if ( status == 'damaged' ) { >+ let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged"); >+ nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib)); >+ } > >- if ( row.not_for_loan_status || item_types_notforloan.get(row.item_type_id) ) { >- let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString()); >- nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : '' ) + '</span>'; >- } >+ if ( status == 'not_for_loan' ) { >+ let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString()); >+ nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : '' ) + '</span>'; >+ } > >- if ( row.first_hold ) { >- if ( row.first_hold.waiting_date ) { >- if ( row.first_hold.desk ) { >- nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s, %s since %s.").format(row.first_hold._strings.pickup_library_id.str, row.first_hold.desk.desk_name, $date(row.first_hold.waiting_date))); >+ if ( status == 'on_hold') { >+ if ( row.first_hold.waiting_date ) { >+ if ( row.first_hold.desk ) { >+ nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s, %s since %s.".format(row.first_hold._strings.pickup_library_id.str, row.first_hold.desk.desk_name, $date(row.first_hold.waiting_date)))); >+ } else { >+ nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date)))); >+ } >+ [% IF Koha.Preference('canreservefromotherbranches') %] >+ if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) { >+ [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >+ row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) }; >+ >+ let patron_to_html = $patron_to_html(row.first_hold.patron, { url: true, display_cardnumber: true, hide_patron_name }); >+ nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html)); >+ } >+ [% END %] > } else { >- nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.").format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date))); >+ nodes += ' <span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority)); > } >- [% IF Koha.Preference('canreservefromotherbranches') %] >- if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) { >- [%# Hacky for patron_to_html in case we simply want to display the patron's library name %] >- row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) }; >- >- let patron_to_html = $patron_to_html(row.first_hold.patron, { url: true, display_cardnumber: true, hide_patron_name }); >- nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html)); >- } >- [% END %] >- } else { >- nodes += ' <span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority)); > } >- } > > [% IF Koha.Preference('UseRecalls') %] > if ( row.recall && ( row.item_id === row.recall.item_id ) ) { >@@ -557,18 +559,18 @@ > } > } > [% END %] >+ if ( status == 'available' ) { >+ nodes += ' <span>%s</span>'.format(_("Available")) >+ } > >- if ( ! ( row.not_for_loan_status || item_types_notforloan.get(row.item_type_id) || row.checked_out_date || row.lost_status || row.withdrawn || row.damaged_status || row.transfer || row.first_hold || ( row.recall && ( row.item_id === row.recall.item_id ) ) )) { >- nodes += ' <span>%s</span>'.format(_("Available")) >- } >- >- if ( row.restricted_status ) { >- nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString()))); >- } >+ if ( status == 'restricted') { >+ nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString()))); >+ } > >- if ( row.in_bundle ) { >- nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true }))); >- } >+ if ( status == 'restricted') { >+ nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true }))); >+ } >+ }); > return nodes; > } > }, >-- >2.34.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 37334
:
172300
|
172301
|
172302
|
173499
|
173500
|
173501
|
173949
|
173950
|
173951
|
173982
|
174310
|
174798
|
174799
|
174800
|
174801
|
174802
|
174803
|
174804
|
174813
|
174814
|
174901
|
174902
|
174903
|
174955
|
175859
|
175860
|
175861
|
175862
|
175863
|
175864
|
175865
|
175866
|
175867
|
175868
|
175869
|
175870
|
175871
|
175999
|
176000
|
176001
|
176002
|
176003
|
176004
|
176005
|
176006
|
176007
|
176008
|
176009
|
176010
|
176011
|
176023
|
176024
|
176025
|
176026
|
176027
|
176028
|
176029
|
176030
|
176031
|
176032
|
176033
|
176034
|
176035
|
176475
|
176477
|
176480
|
176481
|
177321
|
177415
|
177416
|
177417
|
177418
|
177419
|
177420
|
177421
|
177422
|
177423
|
177424
|
177425
|
177426
|
177427
|
177428
|
177429
|
177430
|
177431
|
177432