From 96a99b2a5ce10d5e9e14d0c99d6ce4d7de3f645f Mon Sep 17 00:00:00 2001 From: Katrin Fischer Date: Tue, 16 Jun 2015 00:44:44 +0200 Subject: [PATCH] Bug 5260 - Add option to send an order by e-mail to the acquisition module With this patch it will be possible to send order information to the vendor by e-mail. For now this feature can be triggered manually with a button before closing the basket. The order e-mail is based on the acquisition claim feature, but uses a new notice template. Test plan: 1) Vendors A new checkbox "Contact when ordering?" was added to the vendor page. - Add a vendor and/or edit an existing vendor - Verify the new option is saved correctly - Verify the new option displays on the vendor summary page after saving 2) Notices The feature works with a new notice template: ACQORDER It works with the same formatting/fields etc. as the acq claim notice. - Add a new notice template ACQORDER in module 'Claim/order aquisition' - Make sure to use fields from the various offered tables in your notice - Verify it is saved correctly 3) Basket - Turn on LetterLog system preference - Create multiple order lines - Click the 'Send order' button in the toolbar - Verify error or success message - Verify you received the e-mail - Verify there is a new entry with about the sent notice in your action_logs table 4) Regression testing... - Verify order claims still work - Verify serial claims still work - Verify new serial issue notices still work ... (I can provide additional test plans if needed) Signed-off-by: Martin Renvoize Signed-off-by: Jonathan Druart --- C4/Bookseller/Contact.pm | 13 ++- C4/Letters.pm | 104 +++++++++++++++------ acqui/basket.pl | 27 +++++- acqui/lateorders.pl | 4 +- acqui/updatesupplier.pl | 4 +- .../atomicupdate/bug_5260_acq_email_orders.sql | 1 + installer/data/mysql/kohastructure.sql | 1 + .../intranet-tmpl/prog/en/modules/acqui/basket.tt | 20 +++- .../prog/en/modules/acqui/supplier.tt | 15 ++- .../intranet-tmpl/prog/en/modules/tools/letter.tt | 5 + tools/letter.pl | 4 +- 11 files changed, 157 insertions(+), 41 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_5260_acq_email_orders.sql diff --git a/C4/Bookseller/Contact.pm b/C4/Bookseller/Contact.pm index 8816897..a91ecda 100644 --- a/C4/Bookseller/Contact.pm +++ b/C4/Bookseller/Contact.pm @@ -63,6 +63,10 @@ Contact's e-mail address. Notes about contact. +=item orderacquisition + +Whether the contact should receive acquisitions orders. + =item claimacquisition Whether the contact should receive acquisitions claims. @@ -92,7 +96,7 @@ use C4::Context; use base qw(Class::Accessor); -__PACKAGE__->mk_accessors(qw(id name position phone altphone fax email notes claimacquisition claimissues acqprimary serialsprimary bookseller)); +__PACKAGE__->mk_accessors(qw(id name position phone altphone fax email notes orderacquisition claimacquisition claimissues acqprimary serialsprimary bookseller)); =head1 METHODS @@ -168,14 +172,15 @@ sub save { $self->phone, $self->altphone, $self->fax, $self->email, $self->notes, $self->acqprimary ? 1 : 0, - $self->serialsprimary ? 1 : 0, $self->claimacquisition ? 1 : 0, + $self->serialsprimary ? 1 : 0, + $self->orderacquisition ? 1 : 0, $self->claimacquisition ? 1 : 0, $self->claimissues ? 1 : 0, $self->bookseller ); if ($self->id) { - $query = 'UPDATE aqcontacts SET name = ?, position = ?, phone = ?, altphone = ?, fax = ?, email = ?, notes = ?, acqprimary = ?, serialsprimary = ?, claimacquisition = ?, claimissues = ?, booksellerid = ? WHERE id = ?;'; + $query = 'UPDATE aqcontacts SET name = ?, position = ?, phone = ?, altphone = ?, fax = ?, email = ?, notes = ?, acqprimary = ?, serialsprimary = ?, orderacquisition = ?, claimacquisition = ?, claimissues = ?, booksellerid = ? WHERE id = ?;'; push @params, $self->id; } else { - $query = 'INSERT INTO aqcontacts (name, position, phone, altphone, fax, email, notes, acqprimary, serialsprimary, claimacquisition, claimissues, booksellerid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'; + $query = 'INSERT INTO aqcontacts (name, position, phone, altphone, fax, email, notes, acqprimary, serialsprimary, orderacquisition, claimacquisition, claimissues, booksellerid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'; } my $dbh = C4::Context->dbh; my $sth = $dbh->prepare($query); diff --git a/C4/Letters.pm b/C4/Letters.pm index fffaa0d..5f24740 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -17,8 +17,7 @@ package C4::Letters; # You should have received a copy of the GNU General Public License # along with Koha; if not, see . -use strict; -use warnings; +use Modern::Perl; use MIME::Lite; use Mail::Sendmail; @@ -364,12 +363,20 @@ sub findrelatedto { =head2 SendAlerts - parameters : - - $type : the type of alert - - $externalid : the id of the "object" to query - - $letter_code : the letter to send. + my $err = &SendAlerts($type, $externalid, $letter_code); - send an alert to all borrowers having put an alert on a given subject. +Parameters: + - $type : the type of alert + - $externalid : the id of the "object" to query + - $letter_code : the notice template to use + +C<&SendAlerts> sends an email notice directly to a patron or a vendor. +Currently it supports ($type): +- claim serial issues (claimissues) +- claim acquisition orders (claimacquisition) +- send acquisition orders to the vendor (orderacquisition) +- notify patrons about newly received serial issues (issue) +- notify patrons when their account is created (members) Returns undef or { error => 'message } on failure. Returns true on success. @@ -449,20 +456,36 @@ sub SendAlerts { } } } - elsif ( $type eq 'claimacquisition' or $type eq 'claimissues' ) { + elsif ( $type eq 'claimacquisition' or $type eq 'claimissues' or $type eq 'orderacquisition' ) { # prepare the letter... - # search the biblionumber - my $strsth = $type eq 'claimacquisition' - ? qq{ + my $strsth; + my $sthorders; + my $dataorders; + my $action; + if ( $type eq 'claimacquisition') { + $strsth = qq{ SELECT aqorders.*,aqbasket.*,biblio.*,biblioitems.* FROM aqorders LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber LEFT JOIN biblioitems ON aqorders.biblionumber=biblioitems.biblionumber WHERE aqorders.ordernumber IN ( + }; + + if (!@$externalid){ + carp "No order selected"; + return { error => "no_order_selected" }; } - : qq{ + $strsth .= join( ",", @$externalid ) . ")"; + $action = "ACQUISITION CLAIM"; + $sthorders = $dbh->prepare($strsth); + $sthorders->execute; + $dataorders = $sthorders->fetchall_arrayref( {} ); + } + + if ($type eq 'claimissues') { + $strsth = qq{ SELECT serial.*,subscription.*, biblio.*, aqbooksellers.*, aqbooksellers.id AS booksellerid FROM serial @@ -472,21 +495,46 @@ sub SendAlerts { WHERE serial.serialid IN ( }; - if (!@$externalid){ - carp "No Order selected"; - return { error => "no_order_selected" }; + if (!@$externalid){ + carp "No Order selected"; + return { error => "no_order_selected" }; + } + + $strsth .= join( ",", @$externalid ) . ")"; + $action = "CLAIM ISSUE"; + $sthorders = $dbh->prepare($strsth); + $sthorders->execute; + $dataorders = $sthorders->fetchall_arrayref( {} ); } - $strsth .= join( ",", @$externalid ) . ")"; - my $sthorders = $dbh->prepare($strsth); - $sthorders->execute; - my $dataorders = $sthorders->fetchall_arrayref( {} ); + if ( $type eq 'orderacquisition') { + $strsth = qq{ + SELECT aqorders.*,aqbasket.*,biblio.*,biblioitems.* + FROM aqorders + LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno + LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber + LEFT JOIN biblioitems ON aqorders.biblionumber=biblioitems.biblionumber + WHERE aqbasket.basketno = ? + AND orderstatus IN ('new','ordered') + }; + + if (!$externalid){ + carp "No basketnumber given"; + return { error => "no_basketno" }; + } + $action = "ACQUISITION ORDER"; + $sthorders = $dbh->prepare($strsth); + $sthorders->execute($externalid); + $dataorders = $sthorders->fetchall_arrayref( {} ); + } my $sthbookseller = $dbh->prepare("select * from aqbooksellers where id=?"); $sthbookseller->execute( $dataorders->[0]->{booksellerid} ); my $databookseller = $sthbookseller->fetchrow_hashref; - my $addressee = $type eq 'claimacquisition' ? 'acqprimary' : 'serialsprimary'; + + my $addressee = $type eq 'claimacquisition' || $type eq 'orderacquisition' ? 'acqprimary' : 'serialsprimary'; + my $sthcontact = $dbh->prepare("SELECT * FROM aqcontacts WHERE booksellerid=? AND $type=1 ORDER BY $addressee DESC"); $sthcontact->execute( $dataorders->[0]->{booksellerid} ); @@ -537,12 +585,14 @@ sub SendAlerts { : 'text/plain; charset="utf-8"', ); - $mail{'Reply-to'} = C4::Context->preference('ReplytoDefault') - if C4::Context->preference('ReplytoDefault'); - $mail{'Sender'} = C4::Context->preference('ReturnpathDefault') - if C4::Context->preference('ReturnpathDefault'); - $mail{'Bcc'} = $userenv->{emailaddress} - if C4::Context->preference("ClaimsBccCopy"); + if ($type eq 'claimacquisition' || $type eq 'claimissues' ) { + $mail{'Reply-to'} = C4::Context->preference('ReplytoDefault') + if C4::Context->preference('ReplytoDefault'); + $mail{'Sender'} = C4::Context->preference('ReturnpathDefault') + if C4::Context->preference('ReturnpathDefault'); + $mail{'Bcc'} = $userenv->{emailaddress} + if C4::Context->preference("ClaimsBccCopy"); + } unless ( sendmail(%mail) ) { carp $Mail::Sendmail::error; @@ -551,7 +601,7 @@ sub SendAlerts { logaction( "ACQUISITION", - $type eq 'claimissues' ? "CLAIM ISSUE" : "ACQUISITION CLAIM", + $action, undef, "To=" . join( ',', @email ) diff --git a/acqui/basket.pl b/acqui/basket.pl index ecc8f59..b8caba5 100755 --- a/acqui/basket.pl +++ b/acqui/basket.pl @@ -20,8 +20,7 @@ # You should have received a copy of the GNU General Public License # along with Koha; if not, see . -use strict; -use warnings; +use Modern::Perl; use C4::Auth; use C4::Koha; use C4::Output; @@ -35,6 +34,7 @@ use C4::Members qw/GetMember/; #needed for permissions checking for changing ba use C4::Items; use C4::Suggestions; use Koha::Libraries; +use C4::Letters qw/SendAlerts/; use Date::Calc qw/Add_Delta_Days/; use Koha::Database; use Koha::EDI qw( create_edi_order get_edifact_ean ); @@ -116,6 +116,10 @@ if (!defined $op) { my $confirm_pref= C4::Context->preference("BasketConfirmations") || '1'; $template->param( skip_confirm_reopen => 1) if $confirm_pref eq '2'; +$template->param( email_ok => 1 ) if defined $query->param('email_ok'); +$template->param( email_error => $query->param('email_error') ) if defined $query->param('email_error'); + + if ( $op eq 'delete_confirm' ) { my $basketno = $query->param('basketno'); my $delbiblio = $query->param('delbiblio'); @@ -165,6 +169,25 @@ if ( $op eq 'delete_confirm' ) { ); print GetBasketAsCSV($query->param('basketno'), $query); exit; +} elsif ($op eq 'email') { + my $redirect_url = '/cgi-bin/koha/acqui/basket.pl?basketno='.$basket->{'basketno'}; + my $err; + + eval { + $err = SendAlerts( 'orderacquisition', $query->param('basketno'), 'ACQORDER' ); + }; + if ( $@ ) { + $redirect_url .= '&email_error='.$@; + } elsif ( ref $err and exists $err->{error} and $err->{error} eq "no_email" ) { + $redirect_url .= '&email_error=no_email'; + } elsif ( ref $err and exists $err->{error} and $err->{error} eq "no_basketno" ) { + $redirect_url .= '&email_error=no_basketno'; + } else { + $redirect_url .= '&email_ok=1'; + } + + print $query->redirect($redirect_url) + } elsif ($op eq 'close') { my $confirm = $query->param('confirm') || $confirm_pref eq '2'; if ($confirm) { diff --git a/acqui/lateorders.pl b/acqui/lateorders.pl index d372064..fe1acc3 100755 --- a/acqui/lateorders.pl +++ b/acqui/lateorders.pl @@ -102,10 +102,10 @@ if ( $delay and not $delay =~ /^\d{1,3}$/ ) { } if ($op and $op eq "send_alert"){ - my @ordernums = $input->multi_param("ordernumber");# FIXME: Fallback values? + my @ordernums = $input->multi_param("ordernumber"); my $err; eval { - $err = SendAlerts( 'claimacquisition', \@ordernums, $input->param("letter_code") ); # FIXME: Fallback value? + $err = SendAlerts( 'claimacquisition', \@ordernums, $input->param("letter_code") ); if ( not ref $err or not exists $err->{error} ) { AddClaim ( $_ ) for @ordernums; } diff --git a/acqui/updatesupplier.pl b/acqui/updatesupplier.pl index c064f76..962217c 100755 --- a/acqui/updatesupplier.pl +++ b/acqui/updatesupplier.pl @@ -97,14 +97,14 @@ $data{'active'}=$input->param('status'); my @contacts; my %contact_info; -foreach (qw(id name position phone altphone fax email notes claimacquisition claimissues acqprimary serialsprimary)) { +foreach (qw(id name position phone altphone fax email notes orderacquisition claimacquisition claimissues acqprimary serialsprimary)) { $contact_info{$_} = [ $input->param('contact_' . $_) ]; } for my $cnt (0..scalar(@{$contact_info{'id'}})) { my %contact; my $real_contact; - foreach (qw(id name position phone altphone fax email notes claimacquisition claimissues acqprimary serialsprimary)) { + foreach (qw(id name position phone altphone fax email notes orderacquisition claimacquisition claimissues acqprimary serialsprimary)) { $contact{$_} = $contact_info{$_}->[$cnt]; $real_contact = 1 if $contact{$_}; } diff --git a/installer/data/mysql/atomicupdate/bug_5260_acq_email_orders.sql b/installer/data/mysql/atomicupdate/bug_5260_acq_email_orders.sql new file mode 100644 index 0000000..5d6aafe --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_5260_acq_email_orders.sql @@ -0,0 +1 @@ +ALTER TABLE `aqcontacts` ADD `orderacquisition` BOOLEAN NOT NULL DEFAULT 0 AFTER `notes`; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 2142657..e77e4f3 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -2913,6 +2913,7 @@ CREATE TABLE aqcontacts ( fax varchar(100) default NULL, -- contact's fax number email varchar(100) default NULL, -- contact's email address notes mediumtext, -- notes related to the contact + orderacquisition BOOLEAN NOT NULL DEFAULT 0, -- should this contact receive acquisition orders claimacquisition BOOLEAN NOT NULL DEFAULT 0, -- should this contact receive acquisitions claims claimissues BOOLEAN NOT NULL DEFAULT 0, -- should this contact receive serial claims acqprimary BOOLEAN NOT NULL DEFAULT 0, -- is this the primary contact for acquisitions messages diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index d43a959..f94fbf4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -201,6 +201,9 @@ [% IF ediaccount %] [% END %] + [% IF ( active && books_loop ) %] + + [% END %]