Bug 31028: Add ability to report concerns from the staff interface

This patch brings the CatalogConcerns feature to the staff client
allowing non-cataloguers to report issues with catalog records from the
record details page.

Test plan
1) Enable the new `CatalogConcerns` system preference
2) Confirm that without the `edit_catalogue` permission your user can
   submit a catalog concern via `New -> New catalog concern` from the
   toolbar on a records detail display.
3) Confirm that the right user was recorded as the reporter on the
   catalog concern management page (You must have logged in again as a
   user with the `edit_catalogue` permission to see this page.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Helen Oliver <HOliver@tavi-port.ac.uk>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Martin Renvoize 2022-10-25 15:33:04 +01:00 committed by Tomas Cohen Arazi
parent 255a8645a7
commit 2c8f13fee2
18 changed files with 206 additions and 9 deletions

View file

@ -125,5 +125,13 @@ return {
}
);
say $out "Added new notice 'TICKET_NOTIFY'";
$dbh->do(
q{
INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
('CatalogConcerns', '0', NULL, 'Allow users to report catalog concerns', 'YesNo')
}
);
say $out "`CatalogConcerns` preference added";
}
}

View file

@ -131,6 +131,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('casLogout','0','','Does a logout from Koha should also log the user out of CAS?','YesNo'),
('casServerUrl','https://localhost:8443/cas','','URL of the cas server','Free'),
('casServerVersion','2', '2|3','Version of the CAS server Koha will connect to.','Choice'),
('CatalogConcerns', '0', NULL, 'Allow users to report catalog concerns', 'YesNo'),
('CatalogerEmails', '', '', 'Notify these catalogers by email when a catalog concern is submitted', 'free'),
('CatalogModuleRelink','0',NULL,'If OFF the linker will never replace the authids that are set in the cataloging module.','YesNo'),
('CataloguingLog','1',NULL,'If ON, log edit/create/delete actions on bibliographic data. WARNING: this feature is very resource consuming.','YesNo'),

View file

@ -29,7 +29,7 @@
</ul>
[% END %]
[% IF ( CAN_user_tools_inventory || ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) ) %]
[% IF ( CAN_user_tools_inventory || ( ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) ) %]
<h5>Reports</h5>
<ul>
[% IF ( CAN_user_tools_inventory ) %]
@ -37,7 +37,7 @@
<a href="/cgi-bin/koha/tools/inventory.pl">Inventory</a>
</li>
[% END %]
[% IF Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue %]
[% IF ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue %]
<li>
<a href="/cgi-bin/koha/cataloguing/concerns.pl">Catalog concerns</a>
</li>

View file

@ -2,7 +2,7 @@
[% INCLUDE 'blocking_errors.inc' %]
<div id="toolbar" class="btn-toolbar">
[% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items || CAN_user_serials_create_subscription ) %]
[% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items || CAN_user_serials_create_subscription || Koha.Preference('CatalogConcerns') ) %]
<div class="btn-group">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus"></i> New <span class="caret"></span></button>
<ul class="dropdown-menu">
@ -23,6 +23,9 @@
[% IF CAN_user_editcatalogue_edit_catalogue && ! EasyAnalyticalRecords %]
<li><a href="/cgi-bin/koha/cataloguing/addbiblio.pl?parentbiblionumber=[% biblionumber | uri %]">New child record</a></li>
[% END %]
[% IF Koha.Preference('CatalogConcerns') %]
<li><a id="newconcern" role="button" href="#" data-toggle="modal" data-target="#addConcernModal">New catalog concern</a></li>
[% END %]
</ul>
</div>
[% END %]

View file

@ -0,0 +1,50 @@
[% USE raw %]
[% USE AdditionalContents %]
[% SET CatalogConcernHelp = AdditionalContents.get( location => "CatalogConcernHelp", lang => lang, library => logged_in_user.branchcode ) %]
[% SET CatalogConcernTemplate = AdditionalContents.get( location => "CatalogConcernTemplate", lang => lang, library => logged_in_user.branchcode ) %]
<!-- Add concern modal -->
<div class="modal" id="addConcernModal" tabindex="-1" role="dialog" aria-labelledby="addConcernModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content modal-lg">
<div class="modal-header">
<button type="button" class="closebtn" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="addConcernModalLabel">Add concern</h4>
</div>
<div class="modal-body">
<fieldset id="concern_fieldset">
<ol>
<li class="form-group row">
<label for="concern_title" class="col-sm-1 col-form-label">Title: </label>
<div class="col-sm-11">
<input type="text" name="concern_title" id="concern_title" class="form-control" required="required"/>
</div>
</li>
<li class="form-group">
<label class="required" for="concern_body">Please describe your concern: </label>
<textarea class="form-control" id="concern_body" name="concern_body" required="required" rows="15"></textarea>
[%- IF CatalogConcernHelp && CatalogConcernHelp.content && CatalogConcernHelp.content.count > 0 -%]
[%- FOREACH help IN CatalogConcernHelp.content -%]
<p id="helpBlock" class="help-block">[%- help.content | $raw -%]</p>
[%- END -%]
[%- END -%]
<div class="hidden" id="concern_template">
[%- IF CatalogConcernTemplate && CatalogConcernTemplate.content && CatalogConcernTemplate.content.count > 0 -%]
[%- FOREACH template IN CatalogConcernTemplate.content -%]
[%- template.content | $raw -%]
[%- END -%]
[%- END -%]
</div>
</li>
</ol>
</fieldset>
</div> <!-- /.modal-body -->
<div class="modal-footer">
<input type="hidden" id="concern_biblio" name="biblio_id" value="[% biblionumber | html %]">
<button type="submit" class="btn btn-primary" id="addConfirm">Submit <i id="concern-submit-spinner" class="fa fa-spinner fa-pulse fa-fw" style="display:none"></i></button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div> <!-- /.modal-footer -->
</div> <!-- /.modal-content -->
</div> <!-- /.modal-dialog -->
</div> <!-- /#addConcernModal -->

View file

@ -42,6 +42,14 @@ Cataloging:
1: "Allow"
0: "Don't allow"
- authorized values to be created within the cataloguing module. Librarian will need the manage_auth_values subpermission.
-
- pref: CatalogConcerns
default: 0
choices:
0: "Don't allow"
1: Allow
- "staff to report concerns about catalog records."
- '<p><strong>Note:</strong> You can also enable `<a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=OpacCatalogConcerns">OpacCatalogConcerns</a>` to allow OPAC users the same option.</p>'
-
- "Use "
- pref: CatalogerEmails

View file

@ -342,6 +342,7 @@ OPAC:
0: "Don't allow"
1: Allow
- "OPAC users to report concerns about catalog records."
- '<p><strong>Note:</strong> Enabling `<a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=CatalogConcerns">CatalogConcerns</a>` will allow concern submissions from the staff client.</p>'
-
- pref: OPACReportProblem
choices:

View file

@ -84,10 +84,21 @@
</div> <!-- /.col-sm-2.col-sm-pull-10 -->
</div> <!-- /.row -->
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'catalog-strings.inc' %]
[% Asset.js("js/catalog.js") | $raw %]
[% Asset.js("js/browser.js") | $raw %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
var browser = KOHA.browser('[% searchid | html %]', parseInt('[% biblionumber | html %]', 10));
browser.show();

View file

@ -209,11 +209,21 @@
[% END %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'catalog-strings.inc' %]
[% Asset.js("js/catalog.js") | $raw %]
[% Asset.js("js/browser.js") | $raw %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
var browser = KOHA.browser('[% searchid | html %]', parseInt('[% biblionumber | html %]', 10));
browser.show();

View file

@ -1306,12 +1306,23 @@ Note that permanent location is a code, and location may be an authval.
</div>
[% END %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'catalog-strings.inc' %]
[% Asset.js("js/catalog.js") | $raw %]
[% Asset.js("js/recalls.js") | $raw %]
[% Asset.js("js/coce.js") | $raw %]
[% Asset.js("lib/Chocolat/js/chocolat.js") | $raw %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
var interface = "[% interface | html %]";
var theme = "[% theme | html %]";

View file

@ -133,9 +133,20 @@
</div> <!-- /.col-sm-2.col-sm-pull-10 -->
</div> <!-- /.row -->
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'catalog-strings.inc' %]
[% Asset.js("js/catalog.js") | $raw %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
var interface = "[% interface | html %]";
var theme = "[% theme | html %]";

View file

@ -98,10 +98,21 @@
</div> <!-- /.row -->
[% END %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'catalog-strings.inc' %]
[% Asset.js("js/catalog.js") | $raw %]
[% Asset.js("js/browser.js") | $raw %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
//<![CDATA[
var browser = KOHA.browser('[% searchid | html %]', parseInt('[% biblionumber | html %]', 10));

View file

@ -472,6 +472,10 @@
</div> <!-- /.col-sm-2.col-sm-pull-10 -->
</div> <!-- /.row -->
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'catalog-strings.inc' %]
[% INCLUDE 'modals/checkout_renewals.inc' %]
@ -480,6 +484,13 @@
[% Asset.js("js/catalog.js") | $raw %]
[% Asset.js("js/browser.js") | $raw %]
[% Asset.js("js/checkout_renewals_modal.js") | $raw %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
var browser = KOHA.browser('[% searchid | html %]', parseInt('[% biblionumber | html %]', 10));
browser.show();

View file

@ -91,7 +91,7 @@
</ul>
[% END %]
[% IF ( CAN_user_tools_inventory || ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) ) %]
[% IF ( CAN_user_tools_inventory || ( ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) ) %]
<h3>Reports</h3>
<ul class="buttons-list">
[% IF ( CAN_user_tools_inventory ) %]
@ -100,7 +100,7 @@
</li>
[% END %]
[% IF ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) %]
[% IF ( ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
<li>
<a class="circ-button" href="/cgi-bin/koha/cataloguing/concerns.pl"><i class="fa fa-list-ul"></i> Catalog concerns</a>
</li>

View file

@ -1366,6 +1366,10 @@
</div> <!-- /#bundleMissingModal -->
[% END %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
[% INCLUDE 'modals/add_catalog_concern.inc' %]
[% END %]
[% MACRO jsinclude BLOCK %]
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'columns_settings.inc' %]
@ -1378,7 +1382,13 @@
</script>
[% Asset.js("js/resolve_claim_modal.js") | $raw %]
[% END %]
[% IF ( Koha.Preference('CatalogConcerns') ) %]
<script>
/* Set a variable needed by add_catalog_concern.js */
var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
</script>
[% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
[% END %]
<script>
function Dopop(link) {
var newin = window.open(link, 'popup', 'width=600,height=400,resizable=1,toolbar=0,scrollbars=1,top');

View file

@ -172,7 +172,7 @@
<div class="row">
<div class="col-sm-12">
[%# 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('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 ( 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') || Koha.Preference('CatalogConcerns') ) && 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 %]
<div id="area-pending" class="page-section">
[% IF pending_article_requests %]
<div class="pending-info" id="article_requests_pending">
@ -227,7 +227,7 @@
</div>
[% END %]
[% IF ( Koha.Preference('OpacCatalogConcerns') && CAN_user_editcatalogue_edit_catalogue ) %]
[% IF ( ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
<div class="pending-info" id="catalog_concerns_pending">
<a href="/cgi-bin/koha/cataloguing/concerns.pl">Catalog concerns pending</a>:
<span class="pending-number-link">[% pending_biblio_tickets | html %]</span>

View file

@ -0,0 +1,51 @@
$(document).ready(function() {
// Pre-populate empty message with template
$('#addConcernModal').on('show.bs.modal', function (e) {
$('#addConfirm').prop('disabled', false);
let concern_body = $('#concern_body');
if ( concern_body.val() === "" ) {
let template = $('#concern_template').text();
concern_body.val(template);
}
});
$('#addConcernModal').on('click', '#addConfirm', function(e) {
let concern_title = $('#concern_title').val();
let concern_body = $('#concern_body').val();
let biblio_id = $('#concern_biblio').val();
let reporter_id = $('#concern_reporter').val();
let params = {
title: concern_title,
body: concern_body,
biblio_id: biblio_id,
reporter_id: logged_in_user_borrowernumber,
};
$('#concern-submit-spinner').show();
$('#addConfirm').prop('disabled', true);
$.ajax({
url: '/api/v1/tickets',
type: 'POST',
data: JSON.stringify(params),
success: function(data) {
$('#concern-submit-spinner').hide();
$('#addConcernModal').modal('hide');
$('#concern_body').val('');
$('#concern_title').val('');
$('#toolbar').before('<div class="alert alert-success">Your concern was sucessfully submitted.</div>');
if ($.fn.dataTable.isDataTable("#table_concerns")) {
$("#table_concerns").DataTable().ajax.reload();
}
},
error: function(data) {
$('#concern-submit-spinner').hide();
$('#addConcernModal').modal('hide');
$('#toolbar').before('<div class="alert alert-error">There was an error when submitting your concern, please contact a librarian.</div>');
},
contentType: "json"
});
});
});

View file

@ -104,7 +104,7 @@ my $pending_article_requests = Koha::ArticleRequests->search_limited(
)->count;
my $pending_problem_reports = Koha::ProblemReports->search({ status => 'New' });
if ( C4::Context->preference('OpacCatalogConcerns') ) {
if ( C4::Context->preference('OpacCatalogConcerns') || C4::Context->preference('CatalogConcerns') ) {
my $pending_biblio_tickets = Koha::Tickets->search(
{
resolved_date => undef,