Compare commits

...

12 Commits

Author SHA1 Message Date
Tomás Cohen Arazi 65542edbe0 Bug 27839: (follow-up) Update docs for koha-worker 3 years ago
Tomás Cohen Arazi 90291914f9 Bug 27839: Add tab-completion in bash for koha-worker 3 years ago
Kyle Hall 14d843f5f4 Bug 24695: (QA follow-up) Fix POD 3 years ago
Jonathan Druart 48ac552699 Bug 24695: Move to Koha::Report->is_sql_valid 4 years ago
Pasi Kallinen ba5be802e0 Bug 24695: Improve SQL report validation 4 years ago
Kyle Hall 925eecd6bd Bug 27049: (QA follow-up) Add short params, replace warn with say 3 years ago
Martin Renvoize ac7f878959 Bug 27049: Add /misc/cronjobs/writeoff_debts.pl 3 years ago
Martin Renvoize 58ec862da2 Bug 26734: Ratify account slip printing 4 years ago
Séverine QUEUNE 3c6e7ec55d Bug 28121: Correct the place of the question mark 3 years ago
Jonathan Druart a10d45ea18 Bug 27726: DBIC schema changes 3 years ago
Jonathan Druart 611d3aa483 Bug 27726: DBRev 20.12.00.029 3 years ago
Martin Renvoize 7c854a87d2 Bug 27726: Increase 'content' field size 3 years ago
  1. 8
      C4/Reports/Guided.pm
  2. 2
      Koha.pm
  3. 29
      Koha/Report.pm
  4. 10
      Koha/Schema/Result/ProblemReport.pm
  5. 82
      debian/docs/koha-worker.xml
  6. 38
      debian/koha-common.bash-completion
  7. 1
      debian/scripts/koha-worker
  8. 2
      installer/data/mysql/kohastructure.sql
  9. 7
      installer/data/mysql/updatedatabase.pl
  10. 2
      koha-tmpl/intranet-tmpl/prog/en/modules/admin/desks.tt
  11. 6
      koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt
  12. 100
      members/printfeercpt.pl
  13. 78
      members/printinvoice.pl
  14. 208
      misc/cronjobs/writeoff_debts.pl
  15. 25
      pos/printreceipt.pl
  16. 16
      reports/guided_reports.pl
  17. 41
      t/db_dependent/Koha/Reports.t

8
C4/Reports/Guided.pm

@ -551,11 +551,9 @@ sub execute_query {
$offset = 0 unless $offset;
$limit = 999999 unless $limit;
$debug and print STDERR "execute_query($sql, $offset, $limit)\n";
if ($sql =~ /;?\W?(UPDATE|DELETE|DROP|INSERT|SHOW|CREATE)\W/i) {
return (undef, { sqlerr => $1} );
} elsif ($sql !~ /^\s*SELECT\b\s*/i) {
return (undef, { queryerr => 'Missing SELECT'} );
}
my ( $is_sql_valid, $errors ) = Koha::Report->new({ savedsql => $sql })->is_sql_valid;
return (undef, @{$errors}[0]) unless $is_sql_valid;
foreach my $sql_param ( @$sql_params ){
if ( $sql_param =~ m/\n/ ){

2
Koha.pm

@ -29,7 +29,7 @@ use vars qw{ $VERSION };
# - #4 : the developer version. The 4th number is the database subversion.
# used by developers when the database changes. updatedatabase take care of the changes itself
# and is automatically called by Auth.pm when needed.
$VERSION = "20.12.00.028";
$VERSION = "20.12.00.029";
sub version {
return $VERSION;

29
Koha/Report.pm

@ -25,6 +25,10 @@ use Koha::Reports;
use Koha::DateUtils qw( dt_from_string output_pref );
use base qw(Koha::Object);
#
# FIXME We could only return an error code instead of the arrayref
# Only 1 error is returned
# TODO Koha::Report->store should check this before saving
=head1 NAME
@ -34,8 +38,33 @@ Koha::Report - Koha Report Object class
=head2 Class Methods
=head3 is_sql_valid
my ( $is_sql_valid, $errors ) = $report->is_sql_valid;
$errors is a arrayref of hashrefs, keys can be sqlerr or queryerr.
Validate SQL query string so it only contains a select,
not any of the harmful queries.
=cut
sub is_sql_valid {
my ($self) = @_;
my $sql = $self->savedsql;
$sql //= '';
my @errors = ();
if ($sql =~ /;?\W?(UPDATE|DELETE|DROP|INSERT|SHOW|CREATE)\W/i) {
push @errors, { sqlerr => $1 };
} elsif ($sql !~ /^\s*SELECT\b\s*/i) {
push @errors, { queryerr => 'Missing SELECT' };
}
return ( @errors ? 0 : 1, \@errors );
}
=head3 get_search_info
Return search info

10
Koha/Schema/Result/ProblemReport.pm

@ -42,10 +42,8 @@ report subject line
=head2 content
data_type: 'varchar'
default_value: (empty string)
data_type: 'text'
is_nullable: 0
size: 255
report message content
@ -118,7 +116,7 @@ __PACKAGE__->add_columns(
"title",
{ data_type => "varchar", default_value => "", is_nullable => 0, size => 40 },
"content",
{ data_type => "varchar", default_value => "", is_nullable => 0, size => 255 },
{ data_type => "text", is_nullable => 0 },
"borrowernumber",
{
data_type => "integer",
@ -201,8 +199,8 @@ __PACKAGE__->belongs_to(
);
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-01-21 13:39:29
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ETzDxg5r4N476ZWkK2wviQ
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2021-04-12 13:27:06
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:YdCX1Hak6UwiJo1iBJqqzg
# You can replace this text with custom code or comments, and it will be preserved on regeneration

82
debian/docs/koha-worker.xml

@ -0,0 +1,82 @@
<article xmlns='http://docbook.org/ns/docbook'>
<title>koha-worker</title>
<info>
<productname>Koha</productname> is the first free software library automation package.
<author>
<orgname>The Koha Community</orgname>
<uri>https://koha-community.org/</uri>
</author>
</info>
<refentry xml:id="koha-worker">
<refmeta>
<refentrytitle>koha-worker</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>koha-worker</refname>
<refpurpose>Handle worker daemon for named Koha instances.</refpurpose>
<refclass>UNIX/Linux</refclass>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>koha-worker</command>
<arg><option>--start</option>|<option>--stop</option>|<option>--restart</option></arg>
<arg><option>--status</option></arg>
<arg><option>--quiet</option>|<option>-q</option></arg>
<arg><option>-h</option>|<option>--help</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Options</title>
<para>All option switches are mutually exclusive</para>
<variablelist>
<varlistentry>
<term><option>--start</option></term>
<listitem>
<para>Start worker daemon for named Koha instances.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--stop</option></term>
<listitem>
<para>Stop worker daemon for named Koha instances.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--restart</option></term>
<listitem>
<para>Restart worker daemon for named Koha instances.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--status</option></term>
<listitem>
<para>Show status information about worker daemon for named Koha instances.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option>|<option>--verbose</option></term>
<listitem>
<para>Enable verbose output.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-h</option>|<option>--help</option></term>
<listitem>
<para>This help.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Description</title>
<para>This script handles worker daemons for Koha instances.</para>
</refsect1>
</refentry>
</article>

38
debian/koha-common.bash-completion

@ -295,6 +295,44 @@ _koha-zebra()
}
complete -F _koha-zebra koha-zebra
_koha-worker()
{
local cur opts substract
COMPREPLY=()
_get_comp_words_by_ref cur
opts="--start --stop --restart --status --quiet -q --help -h"
# Build a list of the already used option switches
for (( i=0; i < ${#COMP_WORDS[@]}-1; i++ )); do
if [[ ${COMP_WORDS[i]} == -* ]]; then
case ${COMP_WORDS[i]} in
--start) _koha_list_cmd ; return 0 ;;
--stop) _koha_list_cmd ; return 0 ;;
--restart) _koha_list_cmd ; return 0 ;;
--status) _koha_list_cmd ; return 0 ;;
--help) COMPREPLY=() ; return 0 ;; # no more completions
-h) COMPREPLY=() ; return 0 ;; # no more completions
--quiet) # filter the other quiet switches and go on
substract="$substract -e -q"; ;;
-q) # filter the other quiet switches and go on
substract="$substract -e --quiet"; ;;
esac
substract="$substract -e ${COMP_WORDS[i]}"
fi
done
if [[ "$substract" != "" ]]; then
opts=$( echo $opts | sed -e 's/ /\n/g' | grep -v -x $substract )
fi
COMPREPLY=( $(compgen -W "$opts" -- $cur ) )
return 0
}
complete -F _koha-worker koha-worker
_koha-sip()
{
local cur opts substract

1
debian/scripts/koha-worker

@ -41,6 +41,7 @@ This script lets you manage the worker daemon for your Koha instances.
Usage:
$scriptname [--start|--stop|--restart] [--quiet|-q] instancename1 [instancename2...]
$scriptname --status instancename1 [instancename2...]
$scriptname -h|--help
--start Start the worker daemon for the specified instances

2
installer/data/mysql/kohastructure.sql

@ -4134,7 +4134,7 @@ DROP TABLE IF EXISTS `problem_reports`;
CREATE TABLE `problem_reports` (
`reportid` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique identifier assigned by Koha',
`title` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'report subject line',
`content` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'report message content',
`content` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'report message content',
`borrowernumber` int(11) NOT NULL DEFAULT 0 COMMENT 'the user who created the problem report',
`branchcode` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'borrower''s branch',
`username` varchar(75) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'OPAC username',

7
installer/data/mysql/updatedatabase.pl

@ -23790,6 +23790,13 @@ if ( CheckVersion($DBversion) ) {
NewVersion( $DBversion, 14233, "Add id field to letter table" );
}
$DBversion = '20.12.00.029';
if( CheckVersion( $DBversion ) ) {
$dbh->do("ALTER TABLE problem_reports MODIFY content TEXT NOT NULL");
NewVersion( $DBversion, 27726, "Increase field size for problem_reports.content");
}
# SEE bug 13068
# if there is anything in the atomicupdate, read and execute it.
my $update_dir = C4::Context->config('intranetdir') . '/installer/data/mysql/atomicupdate/';

2
koha-tmpl/intranet-tmpl/prog/en/modules/admin/desks.tt

@ -128,7 +128,7 @@
[% IF op == 'delete_confirm' %]
<div class="dialog alert">
<h3>Delete desk "[% desk.desk_name | html %]?"</h3>
<h3>Delete desk "[% desk.desk_name | html %]"?</h3>
<table>
<tr><th>Desk ID</th>
<td>[% desk.desk_id | html %]</td>

6
koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt

@ -103,9 +103,9 @@
[% IF account.amountoutstanding <= 0 %]<td class="credit" style="text-align: right;">[% ELSE %]<td class="debit" style="text-align: right;">[% END %][% account.amountoutstanding | $Price %]</td>
<td class="actions">
[% IF ( account.is_credit ) %]
<a target="_blank" href="printfeercpt.pl?action=print&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs"><i class="fa fa-print"></i> Print</a>
<a target="_blank" href="printfeercpt.pl?action=print&amp;accountlines_id=[% account.accountlines_id | uri %]" class="btn btn-default btn-xs"><i class="fa fa-print"></i> Print</a>
[% ELSE %]
<a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id | uri %]&amp;borrowernumber=[% account.borrowernumber | uri %]" class="btn btn-default btn-xs"><i class="fa fa-print"></i> Print</a>
<a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id | uri %]" class="btn btn-default btn-xs"><i class="fa fa-print"></i> Print</a>
[% END %]
<a href="accountline-details.pl?accountlines_id=[% account.accountlines_id | uri %]" class="btn btn-default btn-xs"><i class="fa fa-list"></i> Details</a>
[% IF account.is_debit && account.amountoutstanding > 0 %]
@ -343,7 +343,7 @@
<script>
$(document).ready(function() {
[% IF payment_id && Koha.Preference('FinePaymentAutoPopup') %]
window.open('/cgi-bin/koha/members/printfeercpt.pl?action=print&change_given=[% change_given | html %]&accountlines_id=[% payment_id | html %]&borrowernumber=[% patron.borrowernumber | html %]', '_blank');
window.open('/cgi-bin/koha/members/printfeercpt.pl?action=print&change_given=[% change_given | html %]&accountlines_id=[% payment_id | html %]', '_blank');
[% END %]
var txtActivefilter = _("Filter paid transactions");

100
members/printfeercpt.pl

@ -1,11 +1,7 @@
#!/usr/bin/perl
#written 3rd May 2010 by kmkale@anantcorp.com adapted from boraccount.pl by chris@katipo.oc.nz
#script to print fee receipts
# Copyright Koustubha Kale
# Copyright Koustubha Kale 2010
# Copyright PTFS Europe 2020
#
# This file is part of Koha.
#
@ -27,73 +23,47 @@ use Modern::Perl;
use C4::Auth;
use C4::Output;
use CGI qw ( -utf8 );
use C4::Members;
use C4::Accounts;
use C4::Letters;
use Koha::Account::Lines;
use Koha::DateUtils;
use Koha::Patrons;
use Koha::Patron::Categories;
my $input=CGI->new;
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "members/printfeercpt.tt",
query => $input,
type => "intranet",
flagsrequired => {borrowers => 'edit_borrowers', updatecharges => 'remaining_permissions'},
debug => 1,
});
my $borrowernumber=$input->param('borrowernumber');
my $action = $input->param('action') || '';
my $accountlines_id = $input->param('accountlines_id');
my $change_given = $input->param('change_given');
my $logged_in_user = Koha::Patrons->find( $loggedinuser );
my $patron = Koha::Patrons->find( $borrowernumber );
output_and_exit_if_error( $input, $cookie, $template, { module => 'members', logged_in_user => $logged_in_user, current_patron => $patron } );
#get account details
my $total = $patron->account->balance;
# FIXME This whole stuff is ugly and should be rewritten
# FIXME We should pass the $accts iterator to the template and do this formatting part there
my $accountline_object = Koha::Account::Lines->find($accountlines_id);
my $accountline = $accountline_object->unblessed;
my $totalcredit;
if($total <= 0){
$totalcredit = 1;
}
$accountline->{'amount'} += 0.00;
if ( $accountline->{'amount'} <= 0 ) {
$accountline->{'amountcredit'} = 1;
$accountline->{'amount'} *= -1.00;
}
$accountline->{'amountoutstanding'} += 0.00;
if ( $accountline->{'amountoutstanding'} <= 0 ) {
$accountline->{'amountoutstandingcredit'} = 1;
}
my $input = CGI->new;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "members/printfeercpt.tt",
query => $input,
type => "intranet",
flagsrequired => {
borrowers => 'edit_borrowers',
updatecharges => 'remaining_permissions'
}
}
);
my $letter = C4::Letters::getletter( 'circulation', 'ACCOUNT_CREDIT', C4::Context::mybranch, 'print', $patron->lang );
my $credit_id = $input->param('accountlines_id');
my $credit = Koha::Account::Lines->find($credit_id);
my $patron = $credit->patron;
my $logged_in_user = Koha::Patrons->find($loggedinuser) or die "Not logged in";
output_and_exit_if_error(
$input, $cookie,
$template,
{
module => 'members',
logged_in_user => $logged_in_user,
current_patron => $patron
}
);
my @account_offsets = Koha::Account::Offsets->search( { credit_id => $accountline_object->id } );
my $letter = C4::Letters::getletter( 'circulation', 'ACCOUNT_CREDIT',
C4::Context::mybranch, 'print', $patron->lang );
$template->param(
letter => $letter,
patron => $patron,
library => C4::Context::mybranch,
offsets => \@account_offsets,
credit => $accountline_object,
finesview => 1,
total => $total,
totalcredit => $totalcredit,
accounts => [$accountline], # FIXME There is always only 1 row!
letter => $letter,
credit => $credit,
change_given => $change_given,
tendered => scalar $input->param('tendered'),
change => scalar $input->param('change')
);
output_html_with_http_headers $input, $cookie, $template->output;

78
members/printinvoice.pl

@ -1,9 +1,7 @@
#!/usr/bin/perl
#written 3rd May 2010 by kmkale@anantcorp.com adapted from boraccount.pl by chris@katipo.oc.nz
#script to print fee receipts
# Copyright Koustubha Kale
# Copyright Koustubha Kale 2010
# Copyright PTFS Europe 2020
#
# This file is part of Koha.
#
@ -24,70 +22,46 @@ use Modern::Perl;
use C4::Auth;
use C4::Output;
use Koha::DateUtils;
use CGI qw ( -utf8 );
use C4::Members;
use C4::Accounts;
use C4::Letters;
use Koha::Account::Lines;
use Koha::Patrons;
use Koha::Patron::Categories;
my $input = CGI->new;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{ template_name => "members/printinvoice.tt",
{
template_name => "members/printinvoice.tt",
query => $input,
type => "intranet",
flagsrequired => { borrowers => 'edit_borrowers', updatecharges => 'remaining_permissions' },
debug => 1,
flagsrequired => {
borrowers => 'edit_borrowers',
updatecharges => 'remaining_permissions'
}
}
);
my $borrowernumber = $input->param('borrowernumber');
my $action = $input->param('action') || '';
my $accountlines_id = $input->param('accountlines_id');
my $logged_in_user = Koha::Patrons->find( $loggedinuser );
my $patron = Koha::Patrons->find( $borrowernumber );
output_and_exit_if_error( $input, $cookie, $template, { module => 'members', logged_in_user => $logged_in_user, current_patron => $patron } );
#get account details
my $total = $patron->account->balance;
my $accountline_object = Koha::Account::Lines->find($accountlines_id);
my $accountline = $accountline_object->unblessed;
my $totalcredit;
if ( $total <= 0 ) {
$totalcredit = 1;
}
$accountline->{'amount'} += 0.00;
if ( $accountline->{'amount'} <= 0 ) {
$accountline->{'amountcredit'} = 1;
$accountline->{'amount'} *= -1.00;
}
$accountline->{'amountoutstanding'} += 0.00;
if ( $accountline->{'amountoutstanding'} <= 0 ) {
$accountline->{'amountoutstandingcredit'} = 1;
}
my @account_offsets = Koha::Account::Offsets->search( { debit_id => $accountline_object->id } );
my $debit_id = $input->param('accountlines_id');
my $debit = Koha::Account::Lines->find($debit_id);
my $patron = $debit->patron;
my $logged_in_user = Koha::Patrons->find($loggedinuser) or die "Not logged in";
output_and_exit_if_error(
$input, $cookie,
$template,
{
module => 'members',
logged_in_user => $logged_in_user,
current_patron => $patron
}
);
my $letter = C4::Letters::getletter( 'circulation', 'ACCOUNT_DEBIT', C4::Context::mybranch, 'print', $patron->lang );
my $letter = C4::Letters::getletter( 'circulation', 'ACCOUNT_DEBIT',
C4::Context::mybranch, 'print', $patron->lang );
$template->param(
letter => $letter,
patron => $patron,
library => C4::Context::mybranch,
offsets => \@account_offsets,
debit => $accountline_object,
debit => $debit
finesview => 1,
total => sprintf( "%.2f", $total ),
totalcredit => $totalcredit,
accounts => [$accountline], # FIXME There is always only 1 row!
);
output_html_with_http_headers $input, $cookie, $template->output;

208
misc/cronjobs/writeoff_debts.pl

@ -0,0 +1,208 @@
#!/usr/bin/perl
use Modern::Perl;
use feature 'say';
use Getopt::Long;
use Pod::Usage;
use Koha::Account::Lines;
use Koha::DateUtils;
use Koha::Script -cron;
my ( $help, $verbose, @type, $added, $file, $confirm );
GetOptions(
'h|help' => \$help,
'v|verbose+' => \$verbose,
't|type:s' => \@type,
'ab|added_before:s' => \$added,
'f|file:s' => \$file,
'c|confirm' => \$confirm,
);
@type = split( /,/, join( ',', @type ) );
pod2usage(1) if ( $help || !$confirm && !$verbose || !$file && !@type && !$added );
my $where = { 'amountoutstanding' => { '>' => 0 } };
my $attr = {};
if ($file) {
my @accounts_from_file;
open( my $fh, '<:encoding(UTF-8)', $file )
or die "Could not open file '$file' $!";
while ( my $line = <$fh> ) {
chomp($line);
push @accounts_from_file, $line;
}
close($fh);
$where->{accountlines_id} = { '-in' => \@accounts_from_file };
}
if (@type) {
$where->{debit_type_code} = \@type;
}
if ($added) {
my $added_before = dt_from_string( $added, 'iso' );
my $dtf = Koha::Database->new->schema->storage->datetime_parser;
$where->{date} = { '<' => $dtf->format_datetime($added_before) };
}
my $lines = Koha::Account::Lines->search( $where, $attr );
if ( $verbose ) {
print "Attempting to write off " . $lines->count . " debts";
print " of type " . join(',',@type) if @type;
print " added before " . $added if $added;
print " from the passed list" if $file;
print "\n";
}
while ( my $line = $lines->next ) {
say "Skipping " . $line->accountlines_id . "; Not a debt" and next
if $line->is_credit && $verbose > 1;
say "Skipping " . $line->accountlines_id . "; Is a PAYOUT" and next
if $line->debit_type_code eq 'PAYOUT' && $verbose > 1;
if ($confirm) {
$line->_result->result_source->schema->txn_do(
sub {
# A 'writeoff' is a 'credit'
my $writeoff = Koha::Account::Line->new(
{
date => \'NOW()',
amount => 0 - $line->amount,
credit_type_code => 'WRITEOFF',
status => 'ADDED',
amountoutstanding => 0 - $line->amount,
manager_id => undef,
borrowernumber => $line->borrowernumber,
interface => 'intranet',
branchcode => undef,
}
)->store();
my $writeoff_offset = Koha::Account::Offset->new(
{
credit_id => $writeoff->accountlines_id,
type => 'WRITEOFF',
amount => $line->amount
}
)->store();
# Link writeoff to charge
$writeoff->apply(
{
debits => [$line],
offset_type => 'WRITEOFF'
}
);
$writeoff->status('APPLIED')->store();
# Update status of original debit
$line->status('FORGIVEN')->store;
}
);
}
if ($verbose) {
if ($confirm) {
say "Accountline " . $line->accountlines_id . " written off";
}
else {
say "Accountline " . $line->accountlines_id . " will be written off";
}
}
}
exit(0);
__END__
=head1 NAME
writeoff_debts.pl
=head1 SYNOPSIS
./writeoff_debts.pl --added_before DATE --type OVERDUE --file REPORT --confirm
This script batch waives debts.
The options to select the debt records to writeoff are cumulative. For
example, supplying both --added_before and --type specifies that the
accountline must meet both conditions to be selected for writeoff.
You must pass at least one of the filtering options for the script to run.
This is to prevent an accidental 'writeoff all' operation.
=head1 OPTIONS
=over
=item B<-h|--help>
Prints this help message
=item B<--added_before>
Writeoff debts added before the date passed.
Dates should be in ISO format, e.g., 2013-07-19, and can be generated
with `date -d '-3 month' --iso-8601`.
=item B<--type>
Writeoff debts of the passed type. Accepts a list of CREDIT_TYPE_CODEs.
=item B<--file>
Writeoff debts passed as one accountlines_id per line in this file. If other
criteria are defined it will only writeoff those in the file that match those
criteria.
=item B<-v|--verbose>
This flag set the script to output logging for the actions it will perform.
=item B<-c|--confirm>
This flag must be provided in order for the script to actually
writeoff debts. If it is not supplied, the script will
only report on the accountline records it would have been written off.
=back
=head1 AUTHOR
Martin Renvoize <martin.renvoize@ptfs-europe.com>
=head1 COPYRIGHT
Copyright 2020 PTFS Europe
=head1 LICENSE
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>.
=head1 DISCLAIMER OF WARRANTY
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.
=cut

25
pos/printreceipt.pl

@ -36,31 +36,30 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
}
);
my $action = $input->param('action') || '';
my $payment_id = $input->param('accountlines_id');
my $payment = Koha::Account::Lines->find($payment_id);
my $patron = $payment->patron;
my $logged_in_user = Koha::Patrons->find($loggedinuser) or die "Not logged in";
output_and_exit_if_error(
$input, $cookie,
$template,
{
module => 'pos',
module => 'members',
logged_in_user => $logged_in_user,
current_patron => $patron
}
);
my $payment = Koha::Account::Lines->find($payment_id);
my @offsets = Koha::Account::Offsets->search( { credit_id => $payment_id } );
) if $patron; # Payment could have been anonymous
my $letter =
C4::Letters::getletter( 'pos', 'RECEIPT', C4::Context::mybranch, 'print' );
my $letter = C4::Letters::getletter( 'pos', 'RECEIPT',
C4::Context::mybranch, 'print', $patron->lang );
$template->param(
letter => $letter,
payment => $payment,
offsets => \@offsets,
collected => scalar $input->param('collected'),
change => scalar $input->param('change')
letter => $letter,
payment => $payment,
tendered => scalar $input->param('tendered'),
change => scalar $input->param('change')
);
output_html_with_http_headers $input, $cookie, $template->output;

16
reports/guided_reports.pl

@ -239,12 +239,8 @@ elsif ( $phase eq 'Update SQL'){
create_non_existing_group_and_subgroup($input, $group, $subgroup);
if ($sql =~ /;?\W?(UPDATE|DELETE|DROP|INSERT|SHOW|CREATE)\W/i) {
push @errors, {sqlerr => $1};
}
elsif ($sql !~ /^(SELECT)/i) {
push @errors, {queryerr => "No SELECT"};
}
my ( $is_sql_valid, $validation_errors ) = Koha::Report->new({ savedsql => $sql })->is_sql_valid;
push(@errors, @$validation_errors) unless $is_sql_valid;
if (@errors) {
$template->param(
@ -600,12 +596,8 @@ elsif ( $phase eq 'Save Report' ) {
create_non_existing_group_and_subgroup($input, $group, $subgroup);
## FIXME this is AFTER entering a name to save the report under
if ($sql =~ /;?\W?(UPDATE|DELETE|DROP|INSERT|SHOW|CREATE)\W/i) {
push @errors, {sqlerr => $1};
}
elsif ($sql !~ /^(SELECT)/i) {
push @errors, {queryerr => "No SELECT"};
}
my ( $is_sql_valid, $validation_errors ) = Koha::Report->new({ savedsql => $sql })->is_sql_valid;
push(@errors, @$validation_errors) unless $is_sql_valid;
if (@errors) {
$template->param(

41
t/db_dependent/Koha/Reports.t

@ -17,7 +17,7 @@
use Modern::Perl;
use Test::More tests => 5;
use Test::More tests => 6;
use Koha::Report;
use Koha::Reports;
@ -70,3 +70,42 @@ subtest 'prep_report' => sub {
};
$schema->storage->txn_rollback;
subtest 'is_sql_valid' => sub {
plan tests => 3 + 6 * 2;
my @badwords = ( 'UPDATE', 'DELETE', 'DROP', 'INSERT', 'SHOW', 'CREATE' );
is_deeply(
[ Koha::Report->new( { savedsql => '' } )->is_sql_valid ],
[ 0, [ { queryerr => 'Missing SELECT' } ] ],
'Empty sql is missing SELECT'
);
is_deeply(
[ Koha::Report->new( { savedsql => 'FOO' } )->is_sql_valid ],
[ 0, [ { queryerr => 'Missing SELECT' } ] ],
'Nonsense sql is missing SELECT'
);
is_deeply(
[ Koha::Report->new( { savedsql => 'select FOO' } )->is_sql_valid ],
[ 1, [] ],
'select FOO is good'
);
foreach my $word (@badwords) {
is_deeply(
[
Koha::Report->new(
{ savedsql => 'select FOO;' . $word . ' BAR' }
)->is_sql_valid
],
[ 0, [ { sqlerr => $word } ] ],
'select FOO with ' . $word . ' BAR'
);
is_deeply(
[
Koha::Report->new( { savedsql => $word . ' qux' } )
->is_sql_valid
],
[ 0, [ { sqlerr => $word } ] ],
$word . ' qux'
);
}
}

Loading…
Cancel
Save