From aa8d61ce0841ee8402ecb7082e984c469a7e5087 Mon Sep 17 00:00:00 2001 From: Yohann Dufour Date: Mon, 4 Aug 2014 16:09:42 +0200 Subject: [PATCH] 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 HTML::HTMLDoc 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). --- Koha/Borrower/Discharge.pm | 135 +++++++++++++++++++++ .../prog/en/modules/members/discharge.tt | 41 +++++++ .../prog/en/modules/members/discharges.tt | 41 +++++++ .../bootstrap/en/modules/opac-discharge.tt | 47 +++++++ members/discharge.pl | 120 ++++++++++++++++++ members/discharges.pl | 58 +++++++++ opac/opac-discharge.pl | 90 ++++++++++++++ 7 files changed, 532 insertions(+) create mode 100644 Koha/Borrower/Discharge.pm create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/discharge.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/discharges.tt create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-discharge.tt create mode 100755 members/discharge.pl create mode 100755 members/discharges.pl create mode 100755 opac/opac-discharge.pl diff --git a/Koha/Borrower/Discharge.pm b/Koha/Borrower/Discharge.pm new file mode 100644 index 0000000..6027e7e --- /dev/null +++ b/Koha/Borrower/Discharge.pm @@ -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/g; + $letter->{'content'} =~ s/<>/$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; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/discharge.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/discharge.tt new file mode 100644 index 0000000..c487506 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/discharge.tt @@ -0,0 +1,41 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Patrons › [% IF (unknowuser) %]Patron does not exist[% ELSE %]Discharge for [% firstname %] [% surname %] ([% cardnumber %])[% END %] +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'patron-search.inc' %] + + + +
+
+
+
+
+

Discharge

+[% UNLESS can_be_discharged %] +

Cannot edit discharge: borrower has issues.

+[% ELSE %] + [% IF has_reserves %] +

Borrower has reserves: they will be canceled if the discharge is generated.

+ [% END %] +
+ + +
+[% END %] +
+ + +
+
+
+[% INCLUDE 'circ-menu.inc' %] +
+
+[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/discharges.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/discharges.tt new file mode 100644 index 0000000..ae08aeb --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/discharges.tt @@ -0,0 +1,41 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Patrons › Pending discharge requests +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'patron-search.inc' %] + + + +
+
+
+ [% IF pending_discharges %] +

Pending discharge requests

+
+ + + + + + + + + [% FOR d IN pending_discharges %] + + + + + [% END %] + +
PatronAllow
[% d.borrower.surname %], [% d.borrower.firstname %]Allow
+
+ [% ELSE %] +
+

There are no pending discharge requests.

+
+ [% END %] +
+
+[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-discharge.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-discharge.tt new file mode 100644 index 0000000..c775336 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-discharge.tt @@ -0,0 +1,47 @@ +[% USE Koha %] +[% INCLUDE 'doc-head-open.inc' %] +[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Discharge +[% INCLUDE 'doc-head-close.inc' %] +[% BLOCK cssinclude %][% END %] + + +[% INCLUDE 'masthead.inc' %] + +
+ + +
+
+
+ +
+
+
+

Discharge

+ [% IF success %] +

Your discharge request has been sent. Your discharge will be available on this page within a few days.

+ [% ELSIF available %] + Get your discharge + [% ELSIF pending %] +

Your discharge will be available on this page within a few days.

+ [% ELSIF has_issues %] +

You cannot be discharged, you have issues. Please return items before asking for a discharge.

+ [% ELSE %] +

What is a discharge?

+

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.

+

Warning: 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.

+ Ask for a discharge + [% END %] +
+
+
+
+
+ +[% INCLUDE 'opac-bottom.inc' %] +[% BLOCK jsinclude %][% END %] diff --git a/members/discharge.pl b/members/discharge.pl new file mode 100755 index 0000000..54a9f46 --- /dev/null +++ b/members/discharge.pl @@ -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 . + +=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; diff --git a/members/discharges.pl b/members/discharges.pl new file mode 100755 index 0000000..d318e00 --- /dev/null +++ b/members/discharges.pl @@ -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 . + +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; diff --git a/opac/opac-discharge.pl b/opac/opac-discharge.pl new file mode 100755 index 0000000..8338d05 --- /dev/null +++ b/opac/opac-discharge.pl @@ -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 . + +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; -- 2.1.0