Skip to content

Commit

Permalink
Merge pull request #4 from ricofreak/main
Browse files Browse the repository at this point in the history
RT 112195
  • Loading branch information
ricofreak authored Dec 18, 2024
2 parents ace6e26 + 000702e commit 962424f
Show file tree
Hide file tree
Showing 5 changed files with 548 additions and 3 deletions.
221 changes: 221 additions & 0 deletions Koha/Plugin/Com/ByWaterSolutions/ItemMessages.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use C4::Context;
use Koha::AuthorisedValues;
use Koha::DateUtils qw(dt_from_string);
use Koha::Schema;
use C4::Circulation qw( barcodedecode );

use Module::Metadata;
use Mojo::JSON qw(decode_json to_json);
Expand Down Expand Up @@ -122,6 +123,226 @@ sub configure {
}
}

sub tool {
my ( $self, $args ) = @_;

my $cgi = $self->{'cgi'};
if ( $cgi->param('update') || $cgi->param('delete') ) {
$self->tool_step3();
}
elsif ( $cgi->param('submitted') ) {
$self->tool_step2();
} else {
$self->tool_step1();
}

}

sub tool_step1 {
my ( $self, $args ) = @_;
my $cgi = $self->{'cgi'};

my $template = $self->get_template({ file => 'tool-step1.tt' });

$self->output_html( $template->output() );
}

sub tool_step2 {
my ( $self, $args ) = @_;
my $cgi = $self->{'cgi'};

my $template = $self->get_template({ file => 'tool-step2.tt' });

my $uploadbarcodes = $cgi->upload('uploadbarcodes');
my @barcodes;
my @uploadedbarcodes;

if ( $uploadbarcodes && length($uploadbarcodes) > 0 ) {
binmode($uploadbarcodes, ":encoding(UTF-8)");
my $split_chars = C4::Context->preference('BarcodeSeparators');
while (my $barcode=<$uploadbarcodes>) {
chomp $barcode;
push @uploadedbarcodes, grep { /\S/ } split( /[$split_chars]/, $barcode );
}
} else {
warn 'NO UPLOADED BARCODES';
}

for my $barcode (@uploadedbarcodes) {
next unless $barcode;

$barcode = barcodedecode($barcode);

push @barcodes,$barcode;
}

my @items_rs = Koha::Items->search(
{ barcode => { -in => \@barcodes } },
{
join => 'biblio',
prefetch => 'biblio',
}
)->as_list;

my %items_data; # Hash to store item and biblio information

foreach my $item (@items_rs) {
my $biblio = $item->biblio; # Access the prefetched biblio relation
$items_data{$item->itemnumber} = {
itemnumber => $item->itemnumber,
barcode => $item->barcode,
title => $biblio->title,
messages => [], # Placeholder for item_messages.message
type => '', # Placeholder for item_messages.type
};
}

if (%items_data) {
my @itemnumbers = keys %items_data;
my $dbh = C4::Context->dbh;
my $placeholders = join(',', ('?') x @itemnumbers);
my $query = qq{
SELECT itemnumber, message, type, item_message_id
FROM item_messages
WHERE itemnumber IN ($placeholders)
};

my $sth = $dbh->prepare($query);
$sth->execute(@itemnumbers);

while (my $row = $sth->fetchrow_hashref) {
my $itemnumber = $row->{itemnumber};
if (exists $items_data{$itemnumber}) {
push @{$items_data{$itemnumber}->{messages}}, {
item_message_id => $row->{item_message_id},
message => $row->{message},
type => $row->{type},
};
}
}
}

my @scanned_items = values %items_data;

$template->param(
scanned_items => \@scanned_items,
);

$self->output_html( $template->output() );
}

sub tool_step3 {
my ( $self, $args ) = @_;
my $cgi = $self->{'cgi'};

my $template = $self->get_template({ file => 'tool-step3.tt' });

my @itemnumbers = $cgi->param('itemnumber');
my $action = $cgi->param('action');
my $type = $cgi->param('type');
my $dbh = C4::Context->dbh;
my @updated_items;

if ( $action eq 'update' ) {
my $new_message = $cgi->param('new_message');

unless ($type) {
warn "No type provided!";
return;
}

my $placeholders = join(',', ('?') x scalar(@itemnumbers));
my $query = qq{
UPDATE item_messages
SET message = ?
WHERE type = ?
AND item_message_id IN ( $placeholders )
};

my $sth = $dbh->prepare($query);
$sth->execute($new_message, $type, @itemnumbers);

my $select_query = qq{
SELECT im.item_message_id, im.itemnumber, im.message AS message, im.type,
i.barcode, b.title
FROM item_messages im
JOIN items i ON im.itemnumber = i.itemnumber
LEFT JOIN biblio b ON i.biblionumber = b.biblionumber
WHERE im.type = ?
AND im.item_message_id IN ($placeholders)
};

my $select_sth = $dbh->prepare($select_query);
$select_sth->execute($type, @itemnumbers);

while (my $row = $select_sth->fetchrow_hashref) {
next unless $row;
push @updated_items, {
item_message_id => $row->{item_message_id},
itemnumber => $row->{itemnumber},
barcode => $row->{barcode},
title => $row->{title},
message => $row->{message},
type => $row->{type},
};
}

$select_sth->finish;

} elsif ( $action eq 'delete' ) {
unless (@itemnumbers) {
warn "No itemnumbers provided!";
return;
}

my $placeholders = join(',', ('?') x scalar(@itemnumbers));

my $select_query = qq{
SELECT im.item_message_id, im.itemnumber, im.message AS old_message, im.type,
i.barcode, b.title
FROM item_messages im
JOIN items i ON im.itemnumber = i.itemnumber
LEFT JOIN biblio b ON i.biblionumber = b.biblionumber
WHERE im.type = ?
AND im.item_message_id IN ($placeholders)
};
my $select_sth = $dbh->prepare($select_query);
$select_sth->execute($type, @itemnumbers);

while (my $row = $select_sth->fetchrow_hashref) {
next unless $row;

push @updated_items, {
item_message_id => $row->{item_message_id},
itemnumber => $row->{itemnumber},
barcode => $row->{barcode},
title => $row->{title},
message => $row->{message},
type => $row->{type},
};
}
$select_sth->finish;

my $query = qq{
DELETE FROM item_messages
WHERE type = ?
AND item_message_id IN ( $placeholders )
};

my $sth = $dbh->prepare($query);
$sth->execute($type, @itemnumbers);
}

my $count = scalar @updated_items;
$template->param(
action => $action,
updated_count => $count,
updated_items => \@updated_items,
);

$self->output_html( $template->output() );
}

## API methods
# If your plugin implements API routes, then the 'api_routes' method needs
# to be implemented, returning valid OpenAPI 2.0 paths serialized as a hashref.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,14 @@ class ItemMessageCreator extends React.Component {
let pulldown_or_text;
if (lib_opac) {
pulldown_or_text = html `
<span style=${{margin: ".5em"}}
<select style=${{margin: ".5em"}}
className="input-xlarge"
value=${this.state.message}
onChange=${this.handleContentChange}
style=${{width: "15em", margin: ".5em"}}
>
${ av_options.map( (av) => html`<span key=${av}>${av}</span>` ) }
</span>`;
${ av_options.map( (av) => html`<option key=${av} value=${av}>${av}</option>` ) }
</select>`;
} else {
pulldown_or_text = html `<input style=${{width: "15em", margin: ".5em"}} className="input-xlarge" type="text" value=${this.state.message} onChange=${this.handleContentChange} />`;
}
Expand Down
65 changes: 65 additions & 0 deletions Koha/Plugin/Com/ByWaterSolutions/ItemMessages/tool-step1.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
[% USE raw %]
[% USE HtmlTags %]
[% USE Koha %]
[% USE Asset %]
[% USE KohaDates %]
[% PROCESS 'i18n.inc' %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]

<title>[% FILTER collapse %]
[% t("Item Messages Configuration") | html %] &rsaquo;
[% t("Koha") | html %]
[% END %]</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>

<body id="plugins_item_message" class="plugins">
[% INCLUDE 'header.inc' %]
[% PROCESS 'about-team.inc' %]
[% WRAPPER 'sub-header.inc' %]
[% WRAPPER breadcrumbs %]
[% IF blocking_error %]
[% WRAPPER breadcrumb_item bc_active= 1 %]
<span>Plugins</span>
[% END %]
[% ELSE %]
[% WRAPPER breadcrumb_item %]
<a href="/cgi-bin/koha/plugins/plugins-home.pl">Plugins</a>
[% END %]
[% WRAPPER breadcrumb_item bc_active= 1 %]
<span>Item messages configuration</span>
[% END %]
[% END %]
[% END #/ WRAPPER breadcrumbs %]
[% END #/ WRAPPER sub-header.inc %]

<div id="doc3">
<h1>Bulk update item messages</h1>
<form id="barcode_form" method="post" enctype="multipart/form-data">
[% INCLUDE 'csrf-token.inc' %]
<input type="hidden" name="class" value="[% CLASS %]"/>
<input type="hidden" name="method" value="[% METHOD %]"/>

<br/>

<fieldset class="rows">
<legend>Use a barcode file</legend>
<ol>
<li>
<label for="uploadbarcodes">Barcode file: </label>
<input type="file" id="uploadbarcodes" name="uploadbarcodes">
<input type="button" id="resetuploadbarcodes" name="resetuploadbarcodes" value="Reset">
</li>
</ol>
</fieldset>

<fieldset class="action">
<input type="submit" name="submitted" class="btn btn-primary" value="Submit">
</fieldset>
</form>
</div>
<br/>


[% INCLUDE 'intranet-bottom.inc' %]
Loading

0 comments on commit 962424f

Please sign in to comment.