From b76142477521bda348f0e033ece26e3dea640077 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Tue, 25 Oct 2022 14:03:11 +0100 Subject: [PATCH] Bug 31028: Add catalog concern management page to staff This patch adds a catalog concern management page to the staff client accessible via the cataloging home page and a new 'Pending catalog concerns' link on the front page. This includes added the requisit ticket_updates api endpoints and notice triggers and templates for notifying patrons of changes to their reported concerns. Test plan 1) Enable the `OpacCatalogConcerns` system preference 2) Catalog concern management is tied to your users ability to edit the catalog, `editcatalogue`. 3) Confirm that you can see 'Catalog concerns' listed on the cataloging home page if you have the `editcatalogue` permission and not if you do not. 4) Add a new concern as an opac user. 5) Confirm that once a concern is present in the system you see a count of 'catalog concerns pending' on the intranet main page if you have the `editcatalogue` permission. 6) Click through either the cataloging home page or pending concerns link on the main page to view the new concerns management page. 7) Confirm the table displays as one would expect. 8) Confirm clicking on details or the concern title exposes a 'details' modal with the option to add an update or resolve the concern. 9) Verify that if selecting 'notify' when updateing or resolving a concern triggers a notice to be sent to the opac user who first reported the issue. Signed-off-by: David Nind Signed-off-by: Helen Oliver --- C4/Letters.pm | 7 + Koha/REST/V1/Tickets.pm | 98 ++++++ Koha/Ticket/Update.pm | 11 + admin/columns_settings.yml | 17 + api/v1/swagger/definitions/ticket.yaml | 5 + api/v1/swagger/definitions/ticket_update.yaml | 30 ++ api/v1/swagger/paths/tickets.yaml | 103 ++++++ api/v1/swagger/swagger.yaml | 4 + cataloguing/concerns.pl | 37 +++ .../data/mysql/atomicupdate/bug_31028.pl | 16 + .../mysql/en/mandatory/sample_notices.yml | 36 +++ .../prog/css/src/staff-global.scss | 4 + .../prog/en/includes/cat-menu.inc | 7 +- .../en/modules/cataloguing/cataloging-home.tt | 8 +- .../prog/en/modules/cataloguing/concerns.tt | 306 ++++++++++++++++++ .../prog/en/modules/intranet-main.tt | 9 +- koha-tmpl/intranet-tmpl/prog/js/datatables.js | 16 +- mainpage.pl | 12 + 18 files changed, 718 insertions(+), 8 deletions(-) create mode 100644 api/v1/swagger/definitions/ticket_update.yaml create mode 100755 cataloguing/concerns.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/concerns.tt diff --git a/C4/Letters.pm b/C4/Letters.pm index 2899370c476..1506bb009f6 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -739,6 +739,7 @@ sub _parseletter_sth { ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : ($table eq 'tickets' ) ? "SELECT * FROM $table WHERE id = ?" : + ($table eq 'ticket_updates' ) ? "SELECT * FROM $table WHERE id = ?" : ($table eq 'credits' ) ? "SELECT * FROM accountlines WHERE accountlines_id = ?" : ($table eq 'debits' ) ? "SELECT * FROM accountlines WHERE accountlines_id = ?" : ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : @@ -1736,6 +1737,12 @@ sub _get_tt_params { plural => 'tickets', pk => 'id', }, + ticket_updates => { + module => 'Koha::Ticket::Updates', + singular => 'ticket_update', + plural => 'ticket_updates', + pk => 'id', + }, issues => { module => 'Koha::Checkouts', singular => 'checkout', diff --git a/Koha/REST/V1/Tickets.pm b/Koha/REST/V1/Tickets.pm index 2e5a418b633..c3f9ad3ee2a 100644 --- a/Koha/REST/V1/Tickets.pm +++ b/Koha/REST/V1/Tickets.pm @@ -147,4 +147,102 @@ sub delete { }; } +=head3 list_updates + +=cut + +sub list_updates { + my $c = shift->openapi->valid_input or return; + + return try { + my $ticket = Koha::Tickets->find( $c->validation->param('ticket_id') ); + unless ($ticket) { + return $c->render( + status => 404, + openapi => { error => "Ticket not found" } + ); + } + + my $updates_set = $ticket->updates; + my $updates = $c->objects->search($updates_set); + return $c->render( status => 200, openapi => $updates ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 add_update + +=cut + +sub add_update { + my $c = shift->openapi->valid_input or return; + + my $ticket_id_param = $c->validation->param('ticket_id'); + my $ticket_update = $c->validation->param('body'); + $ticket_update->{ticket_id} //= $ticket_id_param; + + if ( $ticket_update->{ticket_id} != $ticket_id_param ) { + return $c->render( + status => 400, + openapi => { error => "Ticket Mismatch" } + ); + } + + return try { + my $state = delete $ticket_update->{state}; + + # Store update + my $update = Koha::Ticket::Update->new_from_api($ticket_update)->store; + $update->discard_changes; + + # Update ticket state if needed + if ( defined($state) && $state eq 'resolved' ) { + my $ticket = $update->ticket; + $ticket->set( + { + resolver_id => $update->user_id, + resolved_date => $update->date + } + )->store; + } + + # Optionally add to message_queue here to notify reporter + if ( $update->public ) { + my $notice = + ( defined($state) && $state eq 'resolved' ) + ? 'TICKET_RESOLVE' + : 'TICKET_UPDATE'; + my $letter = C4::Letters::GetPreparedLetter( + module => 'catalog', + letter_code => $notice, + branchcode => $update->user->branchcode, + tables => { ticket_updates => $update->id } + ); + + if ($letter) { + my $message_id = C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $update->ticket->reporter_id, + message_transport_type => 'email', + } + ); + } + } + + # Return + $c->res->headers->location( + $c->req->url->to_string . '/' . $update->id ); + return $c->render( + status => 201, + openapi => $update->to_api + ); + } + catch { + $c->unhandled_exception($_); + }; +} + 1; diff --git a/Koha/Ticket/Update.pm b/Koha/Ticket/Update.pm index b954d59f03d..f275a32df6f 100644 --- a/Koha/Ticket/Update.pm +++ b/Koha/Ticket/Update.pm @@ -57,6 +57,17 @@ sub user { =head2 Internal methods +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::Ticket::Update object +on the API. + +=cut + +sub to_api_mapping { + return { id => 'update_id', }; +} + =head3 _type =cut diff --git a/admin/columns_settings.yml b/admin/columns_settings.yml index 5a73bec4145..96e03a335c2 100644 --- a/admin/columns_settings.yml +++ b/admin/columns_settings.yml @@ -633,6 +633,23 @@ modules: - columnname: stocknumber + concerns: + table_concerns: + default_sort_order: 0 + columns: + - + columnname: reported + - + columnname: details + - + columnname: title + - + columnname: status + - + columnname: actions + cannot_be_toggled: 1 + cannot_be_modified: 1 + z3950_search: resultst: default_sort_order: 1 diff --git a/api/v1/swagger/definitions/ticket.yaml b/api/v1/swagger/definitions/ticket.yaml index d3439e04439..25c770d0fc7 100644 --- a/api/v1/swagger/definitions/ticket.yaml +++ b/api/v1/swagger/definitions/ticket.yaml @@ -48,4 +48,9 @@ properties: - "null" format: date-time description: Date the ticket was resolved_date + updates_count: + type: + - integer + - "null" + description: Number of updates additionalProperties: false diff --git a/api/v1/swagger/definitions/ticket_update.yaml b/api/v1/swagger/definitions/ticket_update.yaml new file mode 100644 index 00000000000..bb03aa65cfe --- /dev/null +++ b/api/v1/swagger/definitions/ticket_update.yaml @@ -0,0 +1,30 @@ +--- +type: object +properties: + update_id: + type: integer + description: Internal ticket update identifier + ticket_id: + type: integer + description: Internal ticket identifier + user: + type: + - object + - "null" + description: The object representing the patron who added the update + user_id: + type: integer + description: Internal identifier for the patron who added the update + date: + type: + - string + - "null" + format: date-time + description: Date the ticket update was reported + message: + type: string + description: Ticket update details + public: + type: boolean + description: Is this update intended to be sent to the patron +additionalProperties: true diff --git a/api/v1/swagger/paths/tickets.yaml b/api/v1/swagger/paths/tickets.yaml index ad652a0d784..1516e1cc913 100644 --- a/api/v1/swagger/paths/tickets.yaml +++ b/api/v1/swagger/paths/tickets.yaml @@ -28,6 +28,7 @@ - reporter - resolver - biblio + - updates+count collectionFormat: csv responses: "200": @@ -210,6 +211,108 @@ x-koha-authorization: permissions: editcatalogue: edit_catalogue +"/tickets/{ticket_id}/updates": + get: + x-mojo-to: Tickets#list_updates + operationId: listTicketUpdates + tags: + - tickets + summary: List ticket updates + produces: + - application/json + parameters: + - $ref: "../swagger.yaml#/parameters/ticket_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/q_header" + - $ref: "../swagger.yaml#/parameters/request_id_header" + - name: x-koha-embed + in: header + required: false + description: Embed list sent as a request header + type: array + items: + type: string + enum: + - user + collectionFormat: csv + responses: + "200": + description: A list of ticket updates + schema: + type: array + items: + $ref: "../swagger.yaml#/definitions/ticket_update" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Ticket not found + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: | + Internal server error. Possible `error_code` attribute values: + + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + catalogue: "1" + post: + x-mojo-to: Tickets#add_update + operationId: addTicketUpdate + tags: + - tickets + summary: Add an update to the ticket + parameters: + - $ref: "../swagger.yaml#/parameters/ticket_id_pp" + - name: body + in: body + description: A ticket update object + required: true + schema: + $ref: "../swagger.yaml#/definitions/ticket_update" + produces: + - application/json + responses: + "201": + description: Ticket added + schema: + $ref: "../swagger.yaml#/definitions/ticket_update" + "401": + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Ticket not found + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: Internal error + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + editcatalogue: edit_catalogue /public/tickets: post: x-mojo-to: Tickets#add diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 9c763bd21d0..5b7828fd86b 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -90,6 +90,8 @@ definitions: $ref: ./definitions/suggestion.yaml ticket: $ref: ./definitions/ticket.yaml + ticket_update: + $ref: ./definitions/ticket_update.yaml transfer_limit: $ref: ./definitions/transfer_limit.yaml vendor: @@ -319,6 +321,8 @@ paths: $ref: "./paths/tickets.yaml#/~1tickets" "/tickets/{ticket_id}": $ref: "./paths/tickets.yaml#/~1tickets~1{ticket_id}" + "/tickets/{ticket_id}/updates": + $ref: "./paths/tickets.yaml#/~1tickets~1{ticket_id}~1updates" /transfer_limits: $ref: ./paths/transfer_limits.yaml#/~1transfer_limits /transfer_limits/batch: diff --git a/cataloguing/concerns.pl b/cataloguing/concerns.pl new file mode 100755 index 00000000000..4e3d1ff55e8 --- /dev/null +++ b/cataloguing/concerns.pl @@ -0,0 +1,37 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use CGI qw ( -utf8 ); +use C4::Context; +use C4::Auth qw( get_template_and_user ); +use C4::Output qw( output_html_with_http_headers ); + +my $query = CGI->new; +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "cataloguing/concerns.tt", + query => $query, + type => "intranet", + flagsrequired => { cataloguing => '*' }, + } +); + +output_html_with_http_headers $query, $cookie, $template->output; + +1; diff --git a/installer/data/mysql/atomicupdate/bug_31028.pl b/installer/data/mysql/atomicupdate/bug_31028.pl index c54db652ee3..169f26806f2 100644 --- a/installer/data/mysql/atomicupdate/bug_31028.pl +++ b/installer/data/mysql/atomicupdate/bug_31028.pl @@ -93,5 +93,21 @@ return { } ); say $out "Added new notice 'TICKET_ACKNOWLEDGEMENT'"; + + $dbh->do( + q{ + INSERT IGNORE INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'catalog', 'TICKET_UPDATE', '', 'Concern updated', '1', 'Catalog concern updated', "Dear [% INCLUDE 'patron-title.inc' patron => ticket_update.ticket.reporter %],\r\n\r\nThe library has added an update to the concern you reported against [% INCLUDE 'biblio-title.inc' biblio=ticket_update.ticket.biblio link = 0 %].\r\n\r\nThe following comment was left: \r\n[% ticket_update.message %]\r\n\r\nThankyou", 'email' ); + } + ); + say $out "Added new notice 'TICKET_UPDATE'"; + + $dbh->do( + q{ + INSERT IGNORE INTO letter(module,code,branchcode,name,is_html,title,content,message_transport_type) + VALUES ( 'catalog', 'TICKET_RESOLVE', '', 'Concern resolved', '1', 'Catalog concern resolved', "Dear [% INCLUDE 'patron-title.inc' patron => ticket_update.ticket.reporter %],\r\n\r\nThe library has now marked your concern with [% INCLUDE 'biblio-title.inc' biblio=ticket_update.ticket.biblio link = 0 %] as resolved.\r\n\r\nThe following comment was left: \r\n[% ticket_update.message %]\r\n\r\nThankyou", 'email' ); + } + ); + say $out "Added new notice 'TICKET_RESOLVE'"; } } diff --git a/installer/data/mysql/en/mandatory/sample_notices.yml b/installer/data/mysql/en/mandatory/sample_notices.yml index c6d1edf2271..7648361715b 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.yml +++ b/installer/data/mysql/en/mandatory/sample_notices.yml @@ -61,6 +61,42 @@ tables: - "" - "Thankyou" + - module: catalog + code: TICKET_RESOLVE + branchcode: "" + name: "Concern resolved" + is_html: 1 + title: "Catalog concern resolved" + message_transport_type: email + lang: default + content: + - "Dear [% INCLUDE 'patron-title.inc' patron => ticket_update.ticket.reporter %]," + - "" + - "The library has now marked your concern with [% INCLUDE 'biblio-title.inc' biblio=ticket_update.ticket.biblio link = 0 %] as resolved." + - "" + - "The following comment was left: " + - "[% ticket_update.message %]" + - "" + - "Thankyou" + + - module: catalog + code: TICKET_UPDATE + branchcode: "" + name: "Concern updated" + is_html: 1 + title: "Catalog concern updated" + message_transport_type: email + lang: default + content: + - "Dear [% INCLUDE 'patron-title.inc' patron => ticket_update.ticket.reporter %]," + - "" + - "The library has added an update to the concern you reported against [% INCLUDE 'biblio-title.inc' biblio=ticket_update.ticket.biblio link = 0 %]." + - "" + - "The following comment was left: " + - "[% ticket_update.message %]" + - "" + - "Thankyou" + - module: circulation code: ACCOUNT_CREDIT branchcode: "" diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss index 31404446409..57826a39151 100644 --- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss +++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss @@ -3290,6 +3290,10 @@ label { white-space: pre-wrap; } +.wrapfix { + white-space: pre-wrap; +} + pre { background-color: transparent; border: 0; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-menu.inc index 2bd37f8fc97..024b0c47e9e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-menu.inc @@ -29,7 +29,7 @@ [% END %] - [% IF ( CAN_user_tools_inventory ) %] + [% IF ( CAN_user_tools_inventory || ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) ) %]
Reports
    [% IF ( CAN_user_tools_inventory ) %] @@ -37,6 +37,11 @@ Inventory [% END %] + [% IF Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue %] +
  • + Catalog concerns +
  • + [% END %]
[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/cataloging-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/cataloging-home.tt index 70c1a822144..dddb7264568 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/cataloging-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/cataloging-home.tt @@ -91,7 +91,7 @@ [% END %] - [% IF ( CAN_user_tools_inventory ) %] + [% IF ( CAN_user_tools_inventory || ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) ) %]

Reports

    [% IF ( CAN_user_tools_inventory ) %] @@ -99,6 +99,12 @@ Inventory [% END %] + + [% IF ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) %] +
  • + Catalog concerns +
  • + [% END %]
[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/concerns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/concerns.tt new file mode 100644 index 00000000000..42e8f8c0a18 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/concerns.tt @@ -0,0 +1,306 @@ +[% USE raw %] +[% USE Asset %] +[% SET footerjs = 1 %] +[% USE TablesSettings %] +[% INCLUDE 'doc-head-open.inc' %] + + Catalog concerns › Tools › Koha + +[% INCLUDE 'doc-head-close.inc' %] + + + + [% INCLUDE 'header.inc' %] + [% INCLUDE 'cataloging-search.inc' %] + + + +
+
+
+
+

Concerns

+ +
+
+ Hide resolved + | Show all +
+ + + + + + + + + + + +
ReportedDetailsTitleStatusActions
+
+
+
+ +
+ +
+
+ + + + +[% MACRO jsinclude BLOCK %] + [% INCLUDE 'datatables.inc' %] + [% INCLUDE 'columns_settings.inc' %] + [% INCLUDE 'js-date-format.inc' %] + [% INCLUDE 'js-patron-format.inc' %] + [% INCLUDE 'js-biblio-format.inc' %] + +[% END %] +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt index 1b96d1a8a52..6e7ccac6798 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt @@ -177,7 +177,7 @@
[%# Following statement must be in one line for translatability %] - [% IF ( CAN_user_tools_moderate_comments && pendingcomments ) || ( CAN_user_tools_moderate_tags && pendingtags ) || ( CAN_user_borrowers_edit_borrowers && pending_borrower_modifications ) || ( CAN_user_suggestions_suggestions_manage && ( pendingsuggestions || all_pendingsuggestions )) || ( CAN_user_borrowers_edit_borrowers && pending_discharge_requests ) || pending_article_requests || ( Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes.count ) || ( Koha.Preference('OPACReportProblem') && CAN_user_problem_reports && pending_problem_reports.count ) || already_ran_jobs || new_curbside_pickups.count %] + [% IF ( CAN_user_tools_moderate_comments && pendingcomments ) || ( CAN_user_tools_moderate_tags && pendingtags ) || ( CAN_user_borrowers_edit_borrowers && pending_borrower_modifications ) || ( CAN_user_suggestions_suggestions_manage && ( pendingsuggestions || all_pendingsuggestions )) || ( CAN_user_borrowers_edit_borrowers && pending_discharge_requests ) || pending_article_requests || ( Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes.count ) || ( Koha.preference('OpacCatalogConcerns') && pending_biblio_tickets && CAN_user_editcatalogue_edit_catalogue ) || ( Koha.Preference('OPACReportProblem') && CAN_user_problem_reports && pending_problem_reports.count ) || already_ran_jobs || new_curbside_pickups.count %]
[% IF pending_article_requests %]
@@ -232,6 +232,13 @@
[% END %] + [% IF ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) %] +
+ Catalog concerns pending: + [% pending_biblio_tickets | html %] +
+ [% END %] + [% IF Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes.count %]
Checkout notes pending: diff --git a/koha-tmpl/intranet-tmpl/prog/js/datatables.js b/koha-tmpl/intranet-tmpl/prog/js/datatables.js index 0fbb9b625cb..1265cab6ba3 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/datatables.js +++ b/koha-tmpl/intranet-tmpl/prog/js/datatables.js @@ -590,12 +590,18 @@ jQuery.fn.dataTable.ext.errMode = function(settings, note, message) { var part = {}; var attr = attributes[i]; let criteria = options.criteria; - if ( value.match(/^\^(.*)\$$/) ) { - value = value.replace(/^\^/, '').replace(/\$$/, ''); + if ( value === 'special:undefined' ) { + value = null; criteria = "exact"; - } else { - // escape SQL LIKE special characters % and _ - value = value.replace(/(\%|\\)/g, "\\$1"); + } + if ( value !== null ) { + if ( value.match(/^\^(.*)\$$/) ) { + value = value.replace(/^\^/, '').replace(/\$$/, ''); + criteria = "exact"; + } else { + // escape SQL LIKE special characters % + value = value.replace(/(\%|\\)/g, "\\$1"); + } } part[!attr.includes('.')?'me.'+attr:attr] = criteria === 'exact' ? value diff --git a/mainpage.pl b/mainpage.pl index f5872e65bbb..a1bc19d4d5f 100755 --- a/mainpage.pl +++ b/mainpage.pl @@ -35,6 +35,7 @@ use Koha::Quotes; use Koha::Suggestions; use Koha::BackgroundJobs; use Koha::CurbsidePickups; +use Koha::Tickets; my $query = CGI->new; @@ -103,6 +104,17 @@ my $pending_article_requests = Koha::ArticleRequests->search_limited( )->count; my $pending_problem_reports = Koha::ProblemReports->search({ status => 'New' }); +if ( C4::Context->preference('OpacCatalogConcerns') ) { + my $pending_biblio_tickets = Koha::Tickets->search( + { + resolved_date => undef, + biblio_id => { '!=' => undef } + } + ); + $template->param( + pending_biblio_tickets => $pending_biblio_tickets->count ); +} + unless ( $logged_in_user->has_permission( { parameters => 'manage_background_jobs' } ) ) { my $already_ran_jobs = Koha::BackgroundJobs->search( { borrowernumber => $logged_in_user->borrowernumber } )->count ? 1 : 0; -- 2.39.0