Bug 32030: ERM - Users

Signed-off-by: Jonathan Field <jonathan.field@ptfs-europe.com>

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Jonathan Druart 2022-03-08 12:03:14 +01:00 committed by Tomas Cohen Arazi
parent b5465a2b88
commit b8e7788167
Signed by: tomascohen
GPG key ID: 0A272EA1B2F3C15F
9 changed files with 385 additions and 13 deletions

View file

@ -22,6 +22,7 @@ use Koha::Database;
use base qw(Koha::Object);
use Koha::ERM::Agreement::Periods;
use Koha::ERM::Agreement::UserRoles;
=head1 NAME
@ -46,6 +47,19 @@ sub periods {
return Koha::ERM::Agreement::Periods->_new_from_dbic($periods_rs);
}
=head3 user_roles
Returns the user roles for this agreement
=cut
sub user_roles {
my ( $self ) = @_;
my $user_roles_rs = $self->_result->erm_agreement_user_roles;
return Koha::ERM::Agreement::UserRoles->_new_from_dbic($user_roles_rs);
}
=head2 Internal methods
=head3 _type

View file

@ -0,0 +1,58 @@
package Koha::ERM::Agreement::UserRole;
# 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 <http://www.gnu.org/licenses>.
use Modern::Perl;
use Koha::Database;
use Koha::Patrons;
use base qw(Koha::Object);
=head1 NAME
Koha::ERM::Agreement::UserRole - Koha Agreement UserRole Object class
=head1 API
=head2 Class Methods
=cut
=head3 patron
Return the patron linked to this user role
=cut
sub patron {
my ( $self ) = @_;
my $patron_rs = $self->_result->user;
return Koha::Patron->_new_from_dbic($patron_rs);
}
=head2 Internal methods
=head3 _type
=cut
sub _type {
return 'ErmAgreementUserRole';
}
1;

View file

@ -0,0 +1,53 @@
package Koha::ERM::Agreement::UserRoles;
# 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 <http://www.gnu.org/licenses>.
use Modern::Perl;
use Koha::Database;
use Koha::ERM::Agreement::UserRole;
use base qw(Koha::Objects);
=head1 NAME
Koha::ERM::Agreement::UserRoles- Koha Agreement UserRole Object set class
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ErmAgreementUserRole';
}
=head3 object_class
=cut
sub object_class {
return 'Koha::ERM::Agreement::UserRole';
}
1;

58
Koha/REST/V1/ERM.pm Normal file
View file

@ -0,0 +1,58 @@
package Koha::REST::V1::ERM;
# 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 <http://www.gnu.org/licenses>.
use Modern::Perl;
use Mojo::Base 'Mojolicious::Controller';
use Koha::Patrons;
use Try::Tiny qw( catch try );
=head1 NAME
Koha::REST::V1::Acquisitions::Funds
=head1 API
=head2 Class methods
=head3 list_users
Return the list of possible ERM' users
=cut
sub list_users {
my $c = shift->openapi->valid_input or return;
return try {
my $patrons_rs = Koha::Patrons->search->filter_by_have_permission('erm');
my $patrons = $c->objects->search( $patrons_rs );
return $c->render(
status => 200,
openapi => $patrons
);
}
catch {
$c->unhandled_exception($_);
};
}
1;

View file

@ -0,0 +1,47 @@
---
/erm/users:
get:
x-mojo-to: ERM#list_users
operationId: listERMUsers
description: This resource returns a list of patron allowed to be users of the ERM module
summary: List possibe users for ERM
tags:
- ERM
parameters:
- $ref: ../parameters.yaml#/match
- $ref: ../parameters.yaml#/order_by
- $ref: ../parameters.yaml#/page
- $ref: ../parameters.yaml#/per_page
- $ref: ../parameters.yaml#/q_param
- $ref: ../parameters.yaml#/q_body
- $ref: ../parameters.yaml#/q_header
produces:
- application/json
responses:
"200":
description: A list of ERM' users
schema:
type: array
items:
$ref: ../definitions.yaml#/patron
"403":
description: Access forbidden
schema:
$ref: ../definitions.yaml#/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../definitions.yaml#/error
"503":
description: Under maintenance
schema:
$ref: ../definitions.yaml#/error
x-koha-authorization:
permissions:
erm: 1
x-koha-embed:
- extended_attributes

View file

@ -157,6 +157,10 @@ paths:
$ref: ./paths/config_smtp_servers.yaml#/~1config~1smtp_servers
"/config/smtp_servers/{smtp_server_id}":
$ref: "./paths/config_smtp_servers.yaml#/~1config~1smtp_servers~1{smtp_server_id}"
/erm/agreements:
$ref: ./paths/erm_agreements.yaml#/~1erm~1agreements
/erm/users:
$ref: ./paths/erm_users.yaml#/~1erm~1users
/holds:
$ref: ./paths/holds.yaml#/~1holds
"/holds/{hold_id}":

View file

@ -107,6 +107,7 @@ elsif ( $op eq 'add_validate' ) {
if ( $stored ) {
if ( $agreement_id ) {
$agreement->periods->delete;
$agreement->user_roles->delete;
}
for my $unique_id ( $input->multi_param('period_unique_id') ) {
my $started_on = $input->param( 'started_on_' . $unique_id );
@ -129,6 +130,20 @@ elsif ( $op eq 'add_validate' ) {
}
)->store;
}
for my $unique_id ( $input->multi_param('user_unique_id') ) {
my $user_id = $input->param('user_id_' . $unique_id);
next unless $user_id;
my $role = $input->param('user_role_' . $unique_id);
Koha::ERM::Agreement::UserRole->new(
{
agreement_id => $agreement->agreement_id,
user_id => $user_id,
role => $role,
}
)->store;
}
}
});
$op = 'list';

View file

@ -103,7 +103,7 @@
[%# - Browse by last name %]
[%# - The table %]
[%# Get the following parameters: %]
[%# - filter: can be 'suggestions_managers', 'orders_managers', 'funds_owners' or 'funds_users' to filter patrons on their permissions %]
[%# - filter: can be 'suggestions_managers', 'orders_managers', 'funds_owners', 'funds_users' or 'erm_users' to filter patrons on their permissions %]
[%# - table_id: the ID of the table %]
[%# open_on_row_click: See patron_search_js %]
[%# columns: See patron_search_js %]
@ -115,6 +115,8 @@
<div class="hint">Only staff with superlibrarian or acquisitions permissions (or order_manage permission if granular permissions are enabled) are returned in the search results</div>
[% ELSIF filter == 'funds_owners' OR filter == 'funds_users' %]
<div class="hint">Only staff with superlibrarian or acquisitions permissions (or budget_modify permission if granular permissions are enabled) are returned in the search results</div>
[% ELSIF filter == 'erm_users' %]
<div class="hint">Only staff with superlibrarian or ERM permissions are returned in the search results</div>
[% END %]
<div class="browse">
@ -269,6 +271,8 @@
let patron_search_url = '/api/v1/acquisitions/funds/owners';
[% CASE 'funds_users' %]
let patron_search_url = '/api/v1/acquisitions/funds/users';
[% CASE 'erm_users' %]
let patron_search_url = '/api/v1/erm/users';
[% CASE %]
let patron_search_url = '/api/v1/patrons';
[% END %]

View file

@ -218,7 +218,53 @@
[% ELSE %]
[% PROCESS agreement_period id => 1 %]
[% END %]
<button class="add_new_period" type="button" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i>Add new period</button>
<button class="add_new_period" type="button" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i> Add new period</button>
</fieldset>
[% BLOCK agreement_user %]
<fieldset class="agreement_user">
<legend>
User <span class="user_count">[% id | html %]</span>
<a href="#" class="remove_user"><i class="fa fa-trash"></i> Remove this user</a>
</legend>
<input type="hidden" name="user_unique_id" value="[% id | html %]" />
<ol>
<li>
<label for="user" class="required">User: </label>
<span class="user">
[% IF u %]
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% u.user_id| uri %]">
[% INCLUDE 'patron-title.inc' patron = u.patron %]
</a>
<input type="hidden" class="user_id" name="user_id_[% id | html %]" value="[% u.user_id %]" />
[% END %]
</span>
(<a href="#" class="pick_user" class="btn btn-default">Select user</a>)
</li>
<li>
<label>Role: </label>
<select class="user_role" name="user_role_[% id | html %]">
<option value=""></option>
[% PROCESS options_for_authorised_values authorised_values => AuthorisedValues.GetAuthValueDropbox( 'ERM_AGREEMENT_USER_ROLES' ), selected_av => u.role %]
</select>
</li>
</ol>
</fieldset>
[% END %]
<fieldset class="rows">
<legend>Users</legend>
[% IF agreement.user_roles.count %]
[% FOR u IN agreement.user_roles %]
[% PROCESS agreement_user user => u, id => loop.count %]
[% END %]
[% ELSE %]
[% PROCESS agreement_user, id => 1 %]
[% END %]
<button class="add_new_user_block" type="button" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i> Add new user</button>
</fieldset>
<fieldset class="action">
@ -321,6 +367,7 @@
[% INCLUDE 'calendar.inc' %]
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'columns_settings.inc' %]
[% INCLUDE 'js-patron-format.inc' %]
<script>
const agreement_statuses = [% To.json(AuthorisedValues.Get('ERM_AGREEMENT_STATUS')) | $raw %];
@ -340,7 +387,7 @@
}, {});
let current_user_node;
var columns_settings = [% TablesSettings.GetColumns( 'erm', 'agreements', 'table_agreements', 'json' ) | $raw %];
$(document).ready(function() {
var agreements_table_url = '/api/v1/erm/agreements?';
@ -428,28 +475,77 @@
$(".add_new_period").on("click", function(e){
e.preventDefault();
let new_period_block = $("fieldset.agreement_period:first").clone(1);
new_period_block.find("input").val("");
$(new_period_block).insertBefore(this);
let first_period_block = $("fieldset.agreement_period:first");
if ( first_period_block.is(":visible") ) {
let new_period_block = first_period_block.clone(1);
new_period_block.find("input").val("");
$(new_period_block).insertBefore(this);
} else {
first_period_block.show();
}
update_period_count();
});
$(".remove_period").on("click", function(e){
e.preventDefault();
$(this).parent().parent().remove();
let fieldset = $(this).parent().parent();
if ( $("fieldset.agreement_period").length == 1 ) {
clear_block(fieldset);
fieldset.hide();
} else {
fieldset.remove();
}
update_period_count();
});
$(".add_new_user_block").on("click",function(e){
e.preventDefault();
let first_user_block = $("fieldset.agreement_user:first");
if ( first_user_block.is(":visible") ) {
let new_user_block = $("fieldset.agreement_user:first").clone(1);
new_user_block.find("span.user").empty();
clear_block(new_user_block);
$(new_user_block).insertBefore(this);
} else {
first_user_block.show();
}
update_user_count();
});
$(".remove_user").on("click", function(e){
e.preventDefault();
let fieldset = $(this).parent().parent();
if ( $("fieldset.agreement_user").length == 1 ) {
fieldset.find("span.user").empty();
clear_block(fieldset);
fieldset.hide();
} else {
fieldset.remove();
}
update_user_count();
});
$(".pick_user").on("click", function(e){
e.preventDefault();
current_user_node = $(this).closest("fieldset");
window.open("/cgi-bin/koha/members/search.pl?columns=cardnumber,name,category,branch,action&selection_type=select&filter=erm_users",
'PatronPopup',
'width=740,height=450,location=yes,toolbar=no,'
+ 'scrollbars=yes,resize=yes'
);
});
update_period_count();
update_user_count();
});
function clear_block(block){
$(block).find('input').val("");
$(block).find("select option:first-child").attr("selected", "selected");
}
function update_period_count(){
$("fieldset.agreement_period").each(function(i, period){
let id = i + 1;
let remove_period_link = $(this).find(".remove_period");
if ( id == 1 ) {
$(remove_period_link).hide();
} else {
$(remove_period_link).show();
}
$(period).find(".period_count").text(id);
$(period).find("input[name='period_unique_id']").val(id);
@ -468,9 +564,32 @@
$(cancellation_deadline_input).flatpickr();
$(period).find(".notes").attr("name", "notes_" + id);
$(period).attr('id', 'agreement_period_' + id);
});
}
function update_user_count(){
$("fieldset.agreement_user").each(function(i, user){
let id = i + 1;
let remove_user_link = $(this).find(".remove_user");
$(user).find(".user_count").text(id);
$(user).find("input[name='user_unique_id']").val(id);
$(user).find(".user_id").attr("name", "user_id_" + id);
$(user).find(".user_role").attr("name", "user_role_" + id);
});
}
function select_user(borrowernumber, patron) {
patron['patron_id'] = borrowernumber;
let unique_id = $(current_user_node).find("input[name='user_unique_id']").val();
let a = '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber='
+ borrowernumber + '">' + $patron_to_html(patron) + '</a> '
+ '<input type="hidden" class="user_id" name="user_id_' + unique_id + '" value="' + borrowernumber + '" />';
$(current_user_node).find("span.user").html(a);
}
</script>
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]