Bug 17387: (follow-up) take library groups in to account for permissions check
Signed-off-by: Michaela <michaela.sieber@kit.edu> Sponsored-by: ByWater Solutions Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
parent
b1df5271f3
commit
c07639777d
|
|
@ -154,18 +154,32 @@ sub to_api_mapping {
|
|||
=head3 restore
|
||||
|
||||
my $biblio = $deleted_biblio->restore;
|
||||
my $biblio = $deleted_biblio->restore({
|
||||
patron => $patron,
|
||||
item_ids => \@item_ids,
|
||||
restore_all => 0
|
||||
});
|
||||
|
||||
Restores the deleted biblio record back to the biblio table along with
|
||||
its biblioitems and metadata. This removes the record from the deleted tables
|
||||
and re-inserts it into the active tables. The biblio record will be reindexed
|
||||
after restoration.
|
||||
|
||||
Optional parameters:
|
||||
patron - Koha::Patron object. If provided, only items the patron can edit will be restored.
|
||||
item_ids - Arrayref of item IDs to restore. If not provided and restore_all is false,
|
||||
no items will be restored.
|
||||
restore_all - Boolean. If true and no item_ids provided, restore all items the patron
|
||||
has permission to edit.
|
||||
|
||||
Returns the newly restored Koha::Biblio object.
|
||||
|
||||
=cut
|
||||
|
||||
sub restore {
|
||||
my ($self) = @_;
|
||||
my ( $self, $params ) = @_;
|
||||
|
||||
$params //= {};
|
||||
|
||||
my $biblio_data = $self->unblessed;
|
||||
my $biblioitem = $self->biblioitem;
|
||||
|
|
@ -187,13 +201,43 @@ sub restore {
|
|||
$biblioitem->delete;
|
||||
$self->delete;
|
||||
|
||||
my $patron = $params->{patron};
|
||||
my $item_ids = $params->{item_ids};
|
||||
my $restore_all = $params->{restore_all} // 0;
|
||||
|
||||
my @restored_items;
|
||||
my @skipped_items;
|
||||
|
||||
if ( $restore_all || $item_ids ) {
|
||||
my $deleted_items = $self->items;
|
||||
while ( my $deleted_item = $deleted_items->next ) {
|
||||
my $should_restore = 0;
|
||||
|
||||
if ($item_ids) {
|
||||
$should_restore = grep { $_ == $deleted_item->itemnumber } @$item_ids;
|
||||
} elsif ($restore_all) {
|
||||
$should_restore = 1;
|
||||
}
|
||||
|
||||
if ($should_restore) {
|
||||
if ( $patron && !$patron->can_edit_items_from( $deleted_item->homebranch ) ) {
|
||||
push @skipped_items, $deleted_item->itemnumber;
|
||||
next;
|
||||
}
|
||||
|
||||
$deleted_item->restore;
|
||||
push @restored_items, $deleted_item->itemnumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $indexer = Koha::SearchEngine::Indexer->new( { index => $Koha::SearchEngine::BIBLIOS_INDEX } );
|
||||
$indexer->index_records( $new_biblio->biblionumber, "specialUpdate", "biblioserver" );
|
||||
|
||||
logaction( "CATALOGUING", "RESTORE", $new_biblio->biblionumber, "biblio", undef, $new_biblio )
|
||||
if C4::Context->preference("CataloguingLog");
|
||||
|
||||
return $new_biblio;
|
||||
return wantarray ? ( $new_biblio, \@restored_items, \@skipped_items ) : $new_biblio;
|
||||
}
|
||||
|
||||
=head2 Internal methods
|
||||
|
|
|
|||
|
|
@ -180,12 +180,31 @@ sub restore {
|
|||
return $c->render_resource_not_found("Bibliographic record")
|
||||
unless $deleted_biblio;
|
||||
|
||||
my $body = $c->req->json;
|
||||
my $item_ids = $body->{item_ids};
|
||||
my $restore_all = $body->{restore_all} // 0;
|
||||
|
||||
return try {
|
||||
my $biblio = $deleted_biblio->restore;
|
||||
my $patron = $c->stash('koha.user');
|
||||
|
||||
my ( $biblio, $restored_items, $skipped_items ) = $deleted_biblio->restore(
|
||||
{
|
||||
patron => $patron,
|
||||
item_ids => $item_ids,
|
||||
restore_all => $restore_all
|
||||
}
|
||||
);
|
||||
|
||||
my $response = { biblio_id => $biblio->biblionumber };
|
||||
|
||||
if ( $item_ids || $restore_all ) {
|
||||
$response->{restored_items} = $restored_items if @$restored_items;
|
||||
$response->{skipped_items} = $skipped_items if @$skipped_items;
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => { biblio_id => $biblio->biblionumber }
|
||||
openapi => $response
|
||||
);
|
||||
} catch {
|
||||
$c->unhandled_exception($_);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,15 @@ sub restore {
|
|||
unless $deleted_item;
|
||||
|
||||
return try {
|
||||
my $patron = $c->stash('koha.user');
|
||||
|
||||
unless ( $patron->can_edit_items_from( $deleted_item->homebranch ) ) {
|
||||
return $c->render(
|
||||
status => 403,
|
||||
openapi => { error => "You do not have permission to restore items from this library." }
|
||||
);
|
||||
}
|
||||
|
||||
my $item = $deleted_item->restore;
|
||||
|
||||
return $c->render(
|
||||
|
|
|
|||
|
|
@ -135,6 +135,24 @@
|
|||
summary: Restore deleted biblio
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/biblio_id_pp"
|
||||
- name: body
|
||||
in: body
|
||||
description: Restore options for items
|
||||
required: false
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
item_ids:
|
||||
type: array
|
||||
description: Array of item IDs to restore with the biblio
|
||||
items:
|
||||
type: integer
|
||||
restore_all:
|
||||
type: boolean
|
||||
description: Restore all items the user has permission to edit
|
||||
additionalProperties: false
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
|
@ -142,6 +160,23 @@
|
|||
description: Biblio restored successfully
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
biblio_id:
|
||||
type: integer
|
||||
description: The ID of the restored biblio
|
||||
restored_items:
|
||||
type: array
|
||||
description: List of item IDs that were successfully restored
|
||||
items:
|
||||
type: integer
|
||||
skipped_items:
|
||||
type: array
|
||||
description: List of item IDs that were skipped during restoration due to insufficient permissions
|
||||
items:
|
||||
type: integer
|
||||
required:
|
||||
- biblio_id
|
||||
additionalProperties: false
|
||||
"400":
|
||||
description: Bad request
|
||||
schema:
|
||||
|
|
|
|||
|
|
@ -190,6 +190,16 @@
|
|||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
var librariesWhereCanEdit = [% libraries_where_can_edit_json | $raw %];
|
||||
var canEditAnyLibrary = librariesWhereCanEdit.length === 0;
|
||||
|
||||
function canEditItem(homebranch) {
|
||||
if (canEditAnyLibrary) {
|
||||
return true;
|
||||
}
|
||||
return librariesWhereCanEdit.includes(homebranch);
|
||||
}
|
||||
|
||||
var oneYearAgo = new Date();
|
||||
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||
var today = new Date();
|
||||
|
|
@ -365,17 +375,22 @@
|
|||
{
|
||||
data: function (row, type) {
|
||||
if (type === "display") {
|
||||
return (
|
||||
'<button class="btn btn-sm btn-default restore-item" data-item-id="' +
|
||||
var canEdit = canEditItem(row.home_library_id);
|
||||
var disabled = canEdit ? '' : ' disabled';
|
||||
var button = '<button class="btn btn-sm btn-default restore-item" data-item-id="' +
|
||||
row.item_id +
|
||||
'" data-barcode="' +
|
||||
$("<div/>")
|
||||
.text(row.external_id || row.item_id)
|
||||
.html() +
|
||||
'"><i class="fa fa-undo" aria-hidden="true"></i> ' +
|
||||
'"' + disabled + '><i class="fa fa-undo" aria-hidden="true"></i> ' +
|
||||
_("Restore") +
|
||||
"</button>"
|
||||
);
|
||||
"</button>";
|
||||
|
||||
if (!canEdit) {
|
||||
return '<span title="' + _("You do not have permission to restore items from this library") + '" style="cursor: not-allowed;">' + button + '</span>';
|
||||
}
|
||||
return button;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
|
@ -422,7 +437,14 @@
|
|||
{
|
||||
data: function (row, type) {
|
||||
if (type === "display") {
|
||||
return '<input type="checkbox" class="item-checkbox" data-item-id="' + row.item_id + '">';
|
||||
var canEdit = canEditItem(row.home_library_id);
|
||||
var disabled = canEdit ? '' : ' disabled';
|
||||
var checkbox = '<input type="checkbox" class="item-checkbox" data-item-id="' + row.item_id + '"' + disabled + '>';
|
||||
|
||||
if (!canEdit) {
|
||||
return '<span title="' + _("You do not have permission to restore items from this library") + '">' + checkbox + '</span>';
|
||||
}
|
||||
return checkbox;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
|
@ -462,7 +484,12 @@
|
|||
orderable: true,
|
||||
render: function (data, type, row) {
|
||||
if (type === "display") {
|
||||
return data ? $("<div/>").text(data).html() : "";
|
||||
var text = data ? $("<div/>").text(data).html() : "";
|
||||
var canEdit = canEditItem(data);
|
||||
if (!canEdit) {
|
||||
text += ' <span class="badge bg-warning text-dark">' + _("No permission") + '</span>';
|
||||
}
|
||||
return text;
|
||||
}
|
||||
return data || "";
|
||||
},
|
||||
|
|
@ -570,7 +597,7 @@
|
|||
// Select all items checkbox
|
||||
$("#select-all-items").on("change", function () {
|
||||
var checked = $(this).prop("checked");
|
||||
$(".item-checkbox").prop("checked", checked);
|
||||
$(".item-checkbox:not(:disabled)").prop("checked", checked);
|
||||
});
|
||||
|
||||
// Restore biblio with items
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@
|
|||
|
||||
use Modern::Perl;
|
||||
|
||||
use CGI qw ( -utf8 );
|
||||
use CGI qw ( -utf8 );
|
||||
use JSON qw( encode_json );
|
||||
|
||||
use C4::Auth qw( get_template_and_user );
|
||||
use C4::Output qw( output_html_with_http_headers );
|
||||
use Koha::Patrons;
|
||||
|
||||
my $input = CGI->new;
|
||||
|
||||
|
|
@ -33,4 +35,11 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
|
|||
}
|
||||
);
|
||||
|
||||
my $patron = Koha::Patrons->find($loggedinuser);
|
||||
my @libraries_where_can_edit = $patron->libraries_where_can_edit_items;
|
||||
|
||||
$template->param(
|
||||
libraries_where_can_edit_json => encode_json( \@libraries_where_can_edit ),
|
||||
);
|
||||
|
||||
output_html_with_http_headers $input, $cookie, $template->output;
|
||||
|
|
|
|||
Loading…
Reference in New Issue