Bugzilla – Attachment 160100 Details for
Bug 35560
Use the REST API for holds history
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 35560: [POC] Make the holds list use the REST API
Bug-35560-POC-Make-the-holds-list-use-the-REST-API.patch (text/plain), 18.93 KB, created by
Jonathan Druart
on 2023-12-20 10:27:32 UTC
(
hide
)
Description:
Bug 35560: [POC] Make the holds list use the REST API
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2023-12-20 10:27:32 UTC
Size:
18.93 KB
patch
obsolete
>From 6461915a1053e0195ac0cc3163b1a968f7f37672 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Wed, 13 Dec 2023 16:00:16 +0100 >Subject: [PATCH] Bug 35560: [POC] Make the holds list use the REST API > >--- > Koha/Hold.pm | 12 +- > Koha/Old/Hold.pm | 26 +++ > Koha/REST/V1/Holds.pm | 11 +- > Koha/REST/V1/Patrons.pm | 3 + > Koha/REST/V1/Patrons/Holds.pm | 18 +- > api/v1/swagger/definitions/hold.yaml | 15 ++ > api/v1/swagger/paths/holds.yaml | 7 + > api/v1/swagger/paths/patrons_holds.yaml | 11 +- > .../prog/en/modules/members/holdshistory.tt | 196 +++++++++++++----- > members/holdshistory.pl | 45 +--- > 10 files changed, 248 insertions(+), 96 deletions(-) > >diff --git a/Koha/Hold.pm b/Koha/Hold.pm >index 0224d019b76..369e562428b 100644 >--- a/Koha/Hold.pm >+++ b/Koha/Hold.pm >@@ -579,8 +579,18 @@ Returns the related Koha::Library object for this Hold > =cut > > sub branch { >+ return shift->pickup_library(@_); >+} >+ >+=head3 pickup_library >+ >+Returns the related Koha::Biblio object for this hold >+ >+=cut >+ >+sub pickup_library { > my ($self) = @_; >- my $rs = $self->_result->branchcode; >+ my $rs = $self->_result->pickup_library; > return Koha::Library->_new_from_dbic($rs); > } > >diff --git a/Koha/Old/Hold.pm b/Koha/Old/Hold.pm >index 91f2adb39c6..8f97163c6eb 100644 >--- a/Koha/Old/Hold.pm >+++ b/Koha/Old/Hold.pm >@@ -47,6 +47,32 @@ sub biblio { > return Koha::Biblio->_new_from_dbic($rs); > } > >+=head3 item >+ >+Returns the related Koha::Item object for this old Hold >+ >+=cut >+ >+sub item { >+ my ($self) = @_; >+ my $rs = $self->_result->itemnumber; >+ return unless $rs; >+ return Koha::Item->_new_from_dbic($rs); >+} >+ >+=head3 pickup_library >+ >+Returns the related Koha::Biblio object for this old hold >+ >+=cut >+ >+sub pickup_library { >+ my ($self) = @_; >+ my $rs = $self->_result->pickup_library; >+ return unless $rs; >+ return Koha::Library->_new_from_dbic($rs); >+} >+ > =head3 anonymize > > $old_hold->anonymize(); >diff --git a/Koha/REST/V1/Holds.pm b/Koha/REST/V1/Holds.pm >index ff162cd9453..c52f6a0c7e6 100644 >--- a/Koha/REST/V1/Holds.pm >+++ b/Koha/REST/V1/Holds.pm >@@ -26,6 +26,7 @@ use C4::Reserves; > use Koha::Items; > use Koha::Patrons; > use Koha::Holds; >+use Koha::Old::Holds; > use Koha::DateUtils qw( dt_from_string ); > > use List::MoreUtils qw( any ); >@@ -44,8 +45,16 @@ Method that handles listing Koha::Hold objects > sub list { > my $c = shift->openapi->valid_input or return; > >+ my $old = $c->param('old'); >+ $c->req->params->remove('old'); >+ > return try { >- my $holds = $c->objects->search( Koha::Holds->new ); >+ my $holds_set = >+ $old >+ ? Koha::Old::Holds->new >+ : Koha::Holds->new; >+ >+ my $holds = $c->objects->search( $holds_set ); > return $c->render( status => 200, openapi => $holds ); > } > catch { >diff --git a/Koha/REST/V1/Patrons.pm b/Koha/REST/V1/Patrons.pm >index 24aba7fa9f8..292d420edda 100644 >--- a/Koha/REST/V1/Patrons.pm >+++ b/Koha/REST/V1/Patrons.pm >@@ -44,6 +44,9 @@ Controller function that handles listing Koha::Patron objects > > sub list { > my $c = shift->openapi->valid_input or return; >+ use Data::Printer colored => 1; warn p $c->req->headers; >+ use Data::Printer colored => 1; warn p $c->stash('koha.embed'); >+ > > return try { > >diff --git a/Koha/REST/V1/Patrons/Holds.pm b/Koha/REST/V1/Patrons/Holds.pm >index 88eea15b537..d54cc271e0a 100644 >--- a/Koha/REST/V1/Patrons/Holds.pm >+++ b/Koha/REST/V1/Patrons/Holds.pm >@@ -49,16 +49,18 @@ sub list { > ); > } > >- return try { >+ my $old = $c->param('old'); >+ $c->req->params->remove('old'); > >- my $holds = $c->objects->search( $patron->holds ); >+ return try { >+ my $holds_set = >+ $old >+ ? Koha::Old::Holds->new >+ : Koha::Holds->new; > >- return $c->render( >- status => 200, >- openapi => $holds >- ); >- } >- catch { >+ my $holds = $c->objects->search( $holds_set ); >+ return $c->render( status => 200, openapi => $holds ); >+ } catch { > $c->unhandled_exception($_); > }; > } >diff --git a/api/v1/swagger/definitions/hold.yaml b/api/v1/swagger/definitions/hold.yaml >index f97c3e216b8..ae2c055a309 100644 >--- a/api/v1/swagger/definitions/hold.yaml >+++ b/api/v1/swagger/definitions/hold.yaml >@@ -108,5 +108,20 @@ properties: > - boolean > - "null" > description: Cancellation requests count for the hold (x-koha-embed) >+ biblio: >+ type: >+ - object >+ - "null" >+ description: Bibliographic record >+ item: >+ type: >+ - object >+ - "null" >+ description: The item >+ pickup_library: >+ type: >+ - object >+ - "null" >+ description: Pickup library > > additionalProperties: false >diff --git a/api/v1/swagger/paths/holds.yaml b/api/v1/swagger/paths/holds.yaml >index 7a1055e3915..6458ff72ef3 100644 >--- a/api/v1/swagger/paths/holds.yaml >+++ b/api/v1/swagger/paths/holds.yaml >@@ -88,6 +88,11 @@ > - $ref: "../swagger.yaml#/parameters/q_param" > - $ref: "../swagger.yaml#/parameters/q_body" > - $ref: "../swagger.yaml#/parameters/request_id_header" >+ - name: old >+ in: query >+ description: By default, current holds are returned, when this is true then >+ old holds are returned as result. >+ type: boolean > - name: x-koha-embed > in: header > required: false >@@ -97,6 +102,8 @@ > type: string > enum: > - cancellation_requested >+ - biblio >+ - pickup_library > collectionFormat: csv > produces: > - application/json >diff --git a/api/v1/swagger/paths/patrons_holds.yaml b/api/v1/swagger/paths/patrons_holds.yaml >index e8e1335a87d..c8a4750b917 100644 >--- a/api/v1/swagger/paths/patrons_holds.yaml >+++ b/api/v1/swagger/paths/patrons_holds.yaml >@@ -15,6 +15,11 @@ > - $ref: "../swagger.yaml#/parameters/q_param" > - $ref: "../swagger.yaml#/parameters/q_body" > - $ref: "../swagger.yaml#/parameters/request_id_header" >+ - name: old >+ in: query >+ description: By default, current holds are returned, when this is true then >+ old holds are returned as result. >+ type: boolean > - name: x-koha-embed > in: header > required: false >@@ -24,7 +29,11 @@ > type: string > enum: > - cancellation_requested >- collectionFormat: csv >+ - biblio >+ - item >+ - pickup_library >+ - pickup_library.branchname >+ collectionFormat: csv > produces: > - application/json > responses: >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt >index 92a7e1d7584..3264539aed0 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/holdshistory.tt >@@ -48,10 +48,9 @@ > <div class="dialog alert">Staff members are not allowed to access patron's holds history</div> > [% ELSIF is_anonymous %] > <div class="dialog alert">This is the anonymous patron, so no holds history is displayed.</div> >-[% ELSIF ( !holds ) %] >- <div class="dialog message">This patron has no holds history.</div> > [% ELSE %] > >+<!-- FIXME <div class="dialog message">This patron has no holds history.</div> --> > [% SET show_itemtype_column = Koha.Preference('AllowHoldItemTypeSelection') %] > > <div id="holdshistory" class="page-section"> >@@ -72,54 +71,26 @@ > <th>Status</th> > </tr> > </thead> >- <tbody> >- [% FOREACH hold IN holds %] >+ </table> >+ <table id="table_oldholdshistory"> >+ <thead> > <tr> >- <td>[% INCLUDE 'biblio-title.inc' biblio=hold.biblio link = 1 %]</td> >- <td>[% hold.biblio.author | html %]</td> >- <td>[% hold.item.barcode | html %]</td> >- <td>[% Branches.GetName( hold.branchcode ) | html %]</td> >- <td data-order="[% hold.reservedate | html %]">[% hold.reservedate | $KohaDates %]</td> >- <td data-order="[% hold.expirationdate | html %]"> >- [% hold.expirationdate | $KohaDates %] >- </td> >- <td data-order="[% hold.waitingdate | html %]"> >- [% hold.waitingdate | $KohaDates %] >- </td> >- <td data-order="[% hold.cancellationdate | html %]"> >- [% hold.cancellationdate | $KohaDates %] >- </td> >- [% IF show_itemtype_column %] >- <td> >- [% IF hold.itemtype %] >- [% ItemTypes.GetDescription( hold.itemtype ) | html %] >- [% ELSE %] >- <span>Any item type</span> >- [% END %] >- </td> >- [% END %] >- <td> >- [% IF hold.found == 'F' %] >- <span>Fulfilled</span> >- [% ELSIF hold.cancellationdate %] >- <span>Cancelled</span> >- [% IF hold.cancellation_reason %] >- ([% AuthorisedValues.GetByCode('HOLD_CANCELLATION', hold.cancellation_reason) | html %]) >- [% END %] >- [% ELSIF hold.found == 'W' %] >- <span>Waiting</span> >- [% ELSIF hold.found == 'P' %] >- <span>Processing</span> >- [% ELSIF hold.found == 'T' %] >- <span>In transit</span> >- [% ELSE %] >- <span>Pending</span> >- [% END %] >- </td> >+ <th class="anti-the">Title</th> >+ <th>Author</th> >+ <th>Barcode</th> >+ <th>Library</th> >+ <th>Hold date</th> >+ <th>Expiration date</th> >+ <th>Waiting date</th> >+ <th>Cancellation date</th> >+ [% IF show_itemtype_column %] >+ <th>Requested item type</th> >+ [% END %] >+ <th>Status</th> > </tr> >- [% END %] >- </tbody> >+ </thead> > </table> >+ > </div> > > [% END %] >@@ -139,6 +110,7 @@ > [% INCLUDE 'columns_settings.inc' %] > [% INCLUDE 'str/members-menu.inc' %] > [% Asset.js("js/members-menu.js") | $raw %] >+ [% INCLUDE 'js-biblio-format.inc' %] > <script> > $(document).ready(function() { > var table_settings = [% TablesSettings.GetTableSettings('members', 'holdshistory', 'holdshistory-table', 'json') | $raw %]; >@@ -146,10 +118,132 @@ > //Remove item type column settings > table_settings['columns'] = table_settings['columns'].filter(function(c){return c['columnname'] != 'itemtype';}); > [% END %] >- var table = KohaTable("table_holdshistory", { >- "sPaginationType": "full", >- "aaSorting": [[4, 'desc']] >- }, table_settings); >+ build_holds_table("#table_holdshistory"); >+ build_holds_table("#table_oldholdshistory", 1); >+ function build_holds_table(table_id, old){ >+ let table_url = '/api/v1/patrons/[% patron.borrowernumber | uri %]/holds'; >+ if (old){table_url += '?old=1'} >+ $(table_id).kohaTable({ >+ ajax: { >+ url: table_url, >+ //dataSrc: function ( json ) { >+ // json.data.forEach((el, i) => el.item ??= { external_id: '' }); >+ // console.log(json.data); >+ // return json.data; >+ //}, >+ }, >+ order: [], >+ embed: ['biblio', 'item', 'pickup_library', 'pickup_library.branchname'], >+ columns: [ >+ { >+ data: "biblio.title:biblio.subtitle:biblio.medium", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $biblio_to_html(row.biblio, { link: 1 }); >+ } >+ }, >+ { >+ data: "biblio.author", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return row.biblio.author; >+ } >+ }, >+ { >+ data: "item.external_id", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return row.item ? row.item.external_id : ""; >+ } >+ }, >+ { >+ data: "pickup_library_id:pickup_library.branchname", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return row.pickup_library.name; >+ } >+ }, >+ { >+ data: "hold_date", >+ type: "date", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $date(row.hold_date); >+ } >+ }, >+ { >+ data: "expiration_date", >+ type: "date", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $date(row.expiration_date) >+ } >+ }, >+ { >+ data: "waiting_date", >+ type: "date", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $date(row.waiting_date) >+ } >+ }, >+ { >+ data: "cancellation_date", >+ type: "date", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $date(row.cancellation_date) >+ } >+ }, >+ [% IF show_itemtype_column %] >+ { >+ data: "item_type.item_type", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ if ( row.item_type ) { >+ return row.item_type.item_type; >+ } else { >+ return _("Any item type"); >+ } >+ } >+ }, >+ [% END %] >+ { >+ data: "found", // FIXME filter with dropdown list >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ if ( row.status == 'F' ) { >+ return _("Fulfilled"); >+ } else if (row.cancellation_date) { >+ let r = _("Cancelled"); >+ if (row.cancellation_reason){ >+ r += "(%s)".format("FIXME"); //FIXME Add HOLD_CANCELLATION description >+ } >+ return r; >+ } else if (row.status == 'W') { >+ return _("Waiting"); >+ } else if (row.status == 'P') { >+ return _("Processing"); >+ } else if (row.status == 'T') { >+ return _("In transit"); >+ } >+ >+ return _("Pending"); >+ } >+ }, >+ ], >+ }, table_settings); >+ } > }); > </script> > [% END %] >diff --git a/members/holdshistory.pl b/members/holdshistory.pl >index 8564c09a699..c77501ab3d8 100755 >--- a/members/holdshistory.pl >+++ b/members/holdshistory.pl >@@ -26,56 +26,33 @@ use Koha::Patrons; > > my $input = CGI->new; > >-my $borrowernumber; >-my $cardnumber; >-my @all_holds; >- >-my ($template, $loggedinuser, $cookie)= get_template_and_user({template_name => "members/holdshistory.tt", >- query => $input, >- type => "intranet", >- flagsrequired => {borrowers => 'edit_borrowers'}, >- }); >- >-my $patron; >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { >+ template_name => "members/holdshistory.tt", >+ query => $input, >+ type => "intranet", >+ flagsrequired => { borrowers => 'edit_borrowers' }, >+ } >+); > >-if ($input->param('cardnumber')) { >- $cardnumber = $input->param('cardnumber'); >- $patron = Koha::Patrons->find( { cardnumber => $cardnumber } ); >-} >-if ($input->param('borrowernumber')) { >- $borrowernumber = $input->param('borrowernumber'); >- $patron = Koha::Patrons->find( $borrowernumber ); >-} >+my $cardnumber = $input->param('cardnumber'); >+my $borrowernumber = $input->param('borrowernumber'); >+my $patron = Koha::Patrons->find( $cardnumber ? { cardnumber => $cardnumber } : $borrowernumber ); > > unless ( $patron ) { > print $input->redirect("/cgi-bin/koha/circ/circulation.pl?borrowernumber=$borrowernumber"); > exit; > } > >-my $holds; >-my $old_holds; >- > if ( $borrowernumber eq C4::Context->preference('AnonymousPatron') ){ > # use of 'eq' in the above comparison is intentional -- the > # system preference value could be blank > $template->param( is_anonymous => 1 ); >-} else { >- $holds = $patron->holds; >- $old_holds = $patron->old_holds; >- >- while (my $hold = $holds->next) { >- push @all_holds, $hold; >- } >- >- while (my $hold = $old_holds->next) { >- push @all_holds, $hold; >- } > } > > $template->param( > holdshistoryview => 1, > patron => $patron, >- holds => \@all_holds, > ); > > output_html_with_http_headers $input, $cookie, $template->output; >-- >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 35560
:
160100
|
160101
|
163831
|
163832
|
164093
|
165231
|
165232
|
165233
|
177161
|
177162
|
177163
|
177200
|
177201
|
177202
|
177203