Bug 8007: Discharge management

This patch is the main patch. It adds new package and files for the new
pages (opac-discharge, members/discharge and members/discharges).

At the intranet, it is now possible to generate a discharge for a patron.
At the opac, a patron can request a discharge and a discharge if it has
been validated by a librarian.

Requirements:
    The perl module PDF::FromHTML

New sysprefs:
 - useDischarge: Allows librarians to discharge borrowers and borrowers
   to request a discharge

New letter with a letter_code DISCHARGE.

Test plan:
- Switch on the syspref useDischarge.
- Verify a new tab appears in the patron page (intranet and opac).
- Verify the discharge cannot be generated if the patron has issues.
- Verify the patron can request a discharge from it's opac area.
- The request appears on the main page (intranet).
- Generate the discharge from the intranet.
- Try to download it (from the opac and the intranet).

Signed-off-by: Lucie <lucie.rousseaux@dracenie.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
This commit is contained in:
Yohann Dufour 2014-08-04 16:09:42 +02:00 committed by Tomas Cohen Arazi
parent 45975f4087
commit 9ad589189e
7 changed files with 532 additions and 0 deletions

135
Koha/Borrower/Discharge.pm Normal file
View File

@ -0,0 +1,135 @@
package Koha::Borrower::Discharge;
use Modern::Perl;
use CGI;
use File::Temp qw( :POSIX );
use HTML::HTMLDoc;
use C4::Members qw( GetPendingIssues );
use C4::Reserves qw( GetReservesFromBorrowernumber CancelReserve );
use Koha::Database;
use Koha::DateUtils qw( dt_from_string output_pref );
my $rs = Koha::Database->new->schema->resultset('Discharge');
sub count {
my ($params) = @_;
my $values = {};
if( $params->{borrowernumber} ) {
$values->{borrower} = $params->{borrowernumber};
}
if( $params->{pending} ) {
$values->{needed} = { '!=', undef };
$values->{validated} = undef;
}
elsif( $params->{validated} ) {
$values->{validated} = { '!=', undef };
}
return $rs->search( $values )->count;
}
sub can_be_discharged {
my ($params) = @_;
return unless $params->{borrowernumber};
my $issues = GetPendingIssues( $params->{borrowernumber} );
if( @$issues ) {
return 0;
}
else {
return 1;
}
}
sub request {
my ($params) = @_;
my $borrowernumber = $params->{borrowernumber};
return unless $borrowernumber;
return unless can_be_discharged({ borrowernumber => $borrowernumber });
return if count($params);
return $rs->create({
borrower => $borrowernumber,
needed => dt_from_string,
});
}
sub discharge {
my ($params) = @_;
my $borrowernumber = $params->{borrowernumber};
return unless $borrowernumber and can_be_discharged( { borrowernumber => $borrowernumber } );
# Cancel reserves
my @reserves = GetReservesFromBorrowernumber($borrowernumber);
for my $reserve (@reserves) {
CancelReserve( { reserve_id => $reserve->{reserve_id} } );
}
# Debar the member
Koha::Borrower::Debarments::AddDebarment({
borrowernumber => $borrowernumber,
type => 'DISCHARGE',
});
# Generate the discharge
my $discharge = $rs->search({ borrower => $borrowernumber });
if( $discharge->count > 0 ) {
$discharge->update({ validated => dt_from_string });
}
else {
$rs->create({
borrower => $borrowernumber,
validated => dt_from_string,
});
}
}
sub generate_as_pdf {
my ($params) = @_;
return unless $params->{borrowernumber};
my $letter = C4::Letters::GetPreparedLetter(
module => 'members',
letter_code => 'DISCHARGE',
tables => { borrowers => $params->{borrowernumber}, },
);
my $today = output_pref( dt_from_string() );
$letter->{'title'} =~ s/<<today>>/$today/g;
$letter->{'content'} =~ s/<<today>>/$today/g;
my $tmpl = C4::Templates::gettemplate('batch/print-notices.tt', 'intranet', new CGI);
$tmpl->param(
stylesheet => C4::Context->preference("NoticeCSS"),
today => $today,
messages => [$letter],
);
my $pdf_path = tmpnam();
my $htmldoc = new HTML::HTMLDoc();
$htmldoc->set_html_content($tmpl->output);
$htmldoc->generate_pdf()->to_file($pdf_path);
return $pdf_path;
}
sub get_pendings {
my ($params) = @_;
my $branchcode = $params->{branchcode};
my $borrowernumber = $params->{borrowernumber};
my $cond = {
'me.needed' => { '!=', undef },
'me.validated' => undef,
( defined $borrowernumber ? ( 'me.borrower' => $borrowernumber ) : () ),
( defined $branchcode ? ( 'borrower.branchcode' => $branchcode ) : () ),
};
my @rs = $rs->search( $cond, { join => 'borrower' } );
return \@rs;
}
1;

View File

@ -0,0 +1,41 @@
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Patrons &rsaquo; [% IF (unknowuser) %]Patron does not exist[% ELSE %]Discharge for [% firstname %] [% surname %] ([% cardnumber %])[% END %]</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>
<body>
[% INCLUDE 'header.inc' %]
[% INCLUDE 'patron-search.inc' %]
<div id="breadcrumbs">
<a href="/cgi-bin/koha/mainpage.pl">Home</a>
&rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>
&rsaquo; [% IF (unknowuser) %]Patron does not exist[% ELSE %]Discharge for [% firstname %] [% surname %] ([% cardnumber %])[% END %]
</div>
<div id="doc3" class="yui-t1">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<div class="yui-g">
<h3>Discharge</h3>
[% UNLESS can_be_discharged %]
<p>Cannot edit discharge: borrower has issues.</p>
[% ELSE %]
[% IF has_reserves %]
<p>Borrower has reserves: they will be canceled if the discharge is generated.</p>
[% END %]
<form method="post">
<input type="submit" value="Generate discharge" name="discharge" />
<input type="hidden" value="[% borrowernumber %]" name="borrowernumber" />
</form>
[% END %]
</div>
</div>
</div>
<div class="yui-b">
[% INCLUDE 'circ-menu.inc' %]
</div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]

View File

@ -0,0 +1,41 @@
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Patrons &rsaquo; Pending discharge requests</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>
<body id="pat_discharges" class="pat">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'patron-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> &rsaquo; Pending discharge requests</div>
<div id="doc2" class="yui-t7">
<div id="bd">
<div id="yui-main">
[% IF pending_discharges %]
<h2>Pending discharge requests</h2>
<div id="pending_updates">
<table>
<thead>
<tr>
<th>Patron</th>
<th>Allow</th>
</tr>
</thead>
<tbody>
[% FOR d IN pending_discharges %]
<tr>
<td><a href="/cgi-bin/koha/members/discharge.pl?borrowernumber=[% d.borrower.borrowernumber %]">[% d.borrower.surname %], [% d.borrower.firstname %]</a></td>
<td><a href="/cgi-bin/koha/members/discharges.pl?op=allow&borrowernumber=[% d.borrower.borrowernumber %]">Allow</a></td>
</tr>
[% END %]
</tbody>
</table>
</div>
[% ELSE %]
<div class="dialog message">
<p>There are no pending discharge requests.</p>
</div>
[% END %]
</div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]

View File

@ -0,0 +1,47 @@
[% USE Koha %]
[% INCLUDE 'doc-head-open.inc' %]
[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Discharge
[% INCLUDE 'doc-head-close.inc' %]
[% BLOCK cssinclude %][% END %]
</head>
<body id="opac-discharge" class="scrollto">
[% INCLUDE 'masthead.inc' %]
<div class="main">
<ul class="breadcrumb">
<li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
<li><a href="#">Discharge</a></li>
</ul>
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<div id="navigation">
[% INCLUDE 'navigation.inc' IsPatronPage=1 %]
</div>
</div>
<div class="span10">
<div id="discharge" class="maincontainer">
<h1>Discharge</h1>
[% IF success %]
<p>Your discharge request has been sent. Your discharge will be available on this page within a few days.</p>
[% ELSIF available %]
<a href="/cgi-bin/koha/opac-discharge.pl?op=get">Get your discharge</a></li>
[% ELSIF pending %]
<p>Your discharge will be available on this page within a few days.</p>
[% ELSIF has_issues %]
<p>You cannot be discharged, you have issues. Please return items before asking for a discharge.</p>
[% ELSE %]
<h2>What is a discharge?</h2>
<p>This document certifies that you have returned all borrowed items. It is sometimes asked during a file transfer from a school to another. The discharge is sent by us to your school. You will also find it available on your reader account.</p>
<p><strong>Warning</strong>: This request is only valid if you are in good standing with the library. Once the application is made, you can not borrow library materials.</p>
<a href="/cgi-bin/koha/opac-discharge.pl?op=request">Ask for a discharge</a>
[% END %]
</div> <!-- / #discharge -->
</div> <!-- / .span10 -->
</div> <!-- / .row-fluid -->
</div> <!-- / .container-fluid -->
</div> <!-- / .main -->
[% INCLUDE 'opac-bottom.inc' %]
[% BLOCK jsinclude %][% END %]

120
members/discharge.pl Executable file
View File

@ -0,0 +1,120 @@
#!/usr/bin/perl
# This file is part of Koha.
#
# Copyright 2013 BibLibre
#
# 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 NAME
discharges.pl
=head1 DESCRIPTION
Allows librarian to edit and/or manage borrowers' discharges
=cut
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use C4::Members;
use C4::Reserves;
use C4::Letters;
use Koha::Borrower::Discharge;
use Koha::DateUtils;
my $input = new CGI;
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user({
template_name => 'members/discharge.tt',
query => $input,
type => 'intranet',
authnotrequired => 0,
flagsrequired => { 'borrowers' => '*' },
});
my $borrowernumber;
my $data;
if ( $input->param('borrowernumber') ) {
$borrowernumber = $input->param('borrowernumber');
# Getting member data
$data = GetMember( borrowernumber => $borrowernumber );
my $can_be_discharged = Koha::Borrower::Discharge::can_be_discharged({
borrowernumber => $borrowernumber
});
# Getting reserves
my @reserves = GetReservesFromBorrowernumber($borrowernumber);
my $has_reserves = scalar(@reserves);
# Generating discharge if needed
if ( $input->param('discharge') and $can_be_discharged ) {
my $is_discharged = Koha::Borrower::Discharge::count({
borrowernumber => $borrowernumber,
validated => 1,
});
unless ($is_discharged) {
Koha::Borrower::Discharge::discharge({
borrowernumber => $borrowernumber
});
}
my $pdf_path = Koha::Borrower::Discharge::generate_as_pdf(
{ borrowernumber => $borrowernumber, } );
print $input->header(
-type => 'application/pdf',
-charset => 'utf-8',
-attachment => "discharge_$borrowernumber.pdf",
);
open my $fh, '<', $pdf_path;
my @lines = <$fh>;
close $fh;
print @lines;
exit;
}
$template->param(
borrowernumber => $borrowernumber,
biblionumber => $data->{'biblionumber'},
title => $data->{'title'},
initials => $data->{'initials'},
surname => $data->{'surname'},
borrowernumber => $borrowernumber,
firstname => $data->{'firstname'},
cardnumber => $data->{'cardnumber'},
categorycode => $data->{'categorycode'},
category_type => $data->{'category_type'},
categoryname => $data->{'description'},
address => $data->{'address'},
address2 => $data->{'address2'},
city => $data->{'city'},
zipcode => $data->{'zipcode'},
country => $data->{'country'},
phone => $data->{'phone'},
email => $data->{'email'},
branchcode => $data->{'branchcode'},
has_reserves => $has_reserves,
can_be_discharged => $can_be_discharged,
);
}
$template->param( dischargeview => 1, );
output_html_with_http_headers $input, $cookie, $template->output;

58
members/discharges.pl Executable file
View File

@ -0,0 +1,58 @@
#!/usr/bin/perl
# This file is part of Koha.
#
# Copyright 2013 BibLibre
#
# 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 CGI;
use C4::Auth;
use C4::Output;
use C4::Context;
use Koha::Borrower::Discharge;
my $input = new CGI;
my $op = $input->param('op') // 'list';
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user({
template_name => "members/discharges.tt",
query => $input,
type => "intranet",
authnotrequired => 0,
flagsrequired => { borrowers => 1 },
});
my $branchcode =
( C4::Context->preference("IndependentBranches")
and not C4::Context->IsSuperLibrarian() )
? C4::Context->userenv()->{'branch'}
: undef;
if( $op eq 'allow' ) {
my $borrowernumber = $input->param('borrowernumber');
Koha::Borrower::Discharge::discharge({
borrowernumber => $borrowernumber
}) if $borrowernumber;
}
my $pending_discharges = Koha::Borrower::Discharge::get_pendings({
branchcode => $branchcode
});
$template->param( pending_discharges => $pending_discharges );
output_html_with_http_headers $input, $cookie, $template->output;

90
opac/opac-discharge.pl Executable file
View File

@ -0,0 +1,90 @@
#!/usr/bin/perl
# This file is part of Koha.
#
# Copyright 2013 BibLibre
#
# 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 C4::Auth qw(:DEFAULT get_session);
use CGI;
use C4::Context;
use C4::Output;
use C4::Log;
use C4::Debug;
use C4::Branch;
use C4::Members;
use Koha::Borrower::Discharge;
use Koha::DateUtils;
my $input = new CGI;
my $op = $input->param("op");
# Getting the template and auth
my ( $template, $loggedinuser, $cookie ) = get_template_and_user({
template_name => "opac-discharge.tt",
query => $input,
type => "opac",
debug => 1,
});
if ( $op eq 'request' ) {
my $success = Koha::Borrower::Discharge::request({
borrowernumber => $loggedinuser,
});
if ($success) {
$template->param( success => 1 );
}
else {
$template->param( has_issues => 1 );
}
}
elsif ( $op eq 'get' ) {
my $pdf_path = Koha::Borrower::Discharge::generate_as_pdf({
borrowernumber => $loggedinuser
});
print $input->header(
-type => 'application/pdf',
-charset => 'utf-8',
-attachment => "discharge_$loggedinuser.pdf",
);
open my $fh, '<', $pdf_path;
my @lines = <$fh>;
close $fh;
print @lines;
exit;
}
else {
my $pending = Koha::Borrower::Discharge::count({
borrowernumber => $loggedinuser,
pending => 1,
});
my $available = Koha::Borrower::Discharge::count({
borrowernumber => $loggedinuser,
validated => 1,
});
$template->param(
available => $available,
pending => $pending,
);
}
$template->param( dischargeview => 1 );
output_html_with_http_headers $input, $cookie, $template->output;