Bugzilla – Attachment 13276 Details for
Bug 9016
Multi transport types for notices
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 9016: Multi transport types for notices
Bug-9016-Multi-transport-types-for-notices.patch (text/plain), 69.28 KB, created by
Jonathan Druart
on 2012-11-07 08:51:29 UTC
(
hide
)
Description:
Bug 9016: Multi transport types for notices
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2012-11-07 08:51:29 UTC
Size:
69.28 KB
patch
obsolete
>From fab7f668cee86a0c85c0a86d296e143117c7e795 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@biblibre.com> >Date: Mon, 5 Nov 2012 13:58:59 +0100 >Subject: [PATCH] Bug 9016: Multi transport types for notices > >The goal of the patch: >This patch allows to choose one (or more) message transport type for one >overdue. Currently it is just possible to choose a letter. >To prevent too many letters, we create an association table between >overduerules and message_transport_types and change the primary key for >the letter table. >Like this, we are able to have an unique letter code for several >transport types. >The idea of this patch is to have a sms driver to send messages with a >transport type defined as "sms". > >This patch: >- adds a new jquery plugin : insertatcaret >- adds datatable on the tools/letter.pl page >- adds a new column letter.message_transport_type >- adds a new table overduerules_transport_types : association table > between overduerules and message_transport_types. >- modifies the primary key for the letter table (become module, code, > branchcode, message_transport_type) >- rewrites a big part of the tools/overduerules.tt code > >The migration problem: >A new updatedatabase entry changes the DB structures changes and set all >the letter.message_transport_type to 'email'. The email type is the >default type everywhere in the code. > >To test: >1/ Check that all your previous overdue rules are preserved >2/ Check that the tables on the tools/overduerules.pl page are filled with the >email transport type (default type). >3/ On the tools/letters.pl check that your previous letters still exist. >4/ Now check the features :) The patch allows you to sent letters to the >queue with an email or sms format. >So try to create letters with 1 or both of these transport types and >check the corresponding checkbox on the overdues management page. >Play with the script misc/cronjobs/overdue_notices.pl in order to see >yours notices in the message_queue table. >--- > C4/Letters.pm | 60 ++-- > C4/Overdues.pm | 24 ++ > installer/data/mysql/updatedatabase.pl | 56 ++++ > .../en/lib/jquery/plugins/jquery.insertatcaret.js | 46 +++ > .../intranet-tmpl/prog/en/modules/tools/letter.tt | 329 ++++++++++---------- > .../prog/en/modules/tools/overduerules.tt | 202 +++++------- > misc/cronjobs/overdue_notices.pl | 132 ++++---- > tools/letter.pl | 165 ++++++---- > tools/overduerules.pl | 126 ++++++-- > 9 files changed, 698 insertions(+), 442 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.insertatcaret.js > >diff --git a/C4/Letters.pm b/C4/Letters.pm >index f646241..4cf1f75 100644 >--- a/C4/Letters.pm >+++ b/C4/Letters.pm >@@ -42,7 +42,7 @@ BEGIN { > $VERSION = 3.07.00.049; > @ISA = qw(Exporter); > @EXPORT = qw( >- &GetLetters &GetPreparedLetter &GetWrappedLetter &addalert &getalert &delalert &findrelatedto &SendAlerts &GetPrintMessages >+ &GetLetters &GetPreparedLetter &GetWrappedLetter &addalert &getalert &delalert &findrelatedto &SendAlerts &GetPrintMessages &GetMessageTransportTypes > ); > } > >@@ -97,20 +97,19 @@ $template->param(LETTERLOOP => \@letterloop); > sub GetLetters { > > # returns a reference to a hash of references to ALL letters... >- my $cat = shift; >+ my ( $cat, $message_transport_type ) = @_; >+ $message_transport_type ||= 'email'; > my %letters; > my $dbh = C4::Context->dbh; > my $sth; >- if (defined $cat) { >- my $query = "SELECT * FROM letter WHERE module = ? ORDER BY name"; >- $sth = $dbh->prepare($query); >- $sth->execute($cat); >- } >- else { >- my $query = "SELECT * FROM letter ORDER BY name"; >- $sth = $dbh->prepare($query); >- $sth->execute; >- } >+ my $query = qq{ >+ SELECT * FROM letter WHERE >+ }; >+ $query .= qq{ module = ? AND } if defined $cat; >+ $query .= qq{ message_transport_type = ? ORDER BY name}; >+ $sth = $dbh->prepare($query); >+ $sth->execute((defined $cat ? $cat : ()), $message_transport_type); >+ > while ( my $letter = $sth->fetchrow_hashref ) { > $letters{ $letter->{'code'} } = $letter->{'name'}; > } >@@ -146,7 +145,8 @@ sub GetLetter { > > my %letter; > sub getletter { >- my ( $module, $code, $branchcode ) = @_; >+ my ( $module, $code, $branchcode, $message_transport_type ) = @_; >+ $message_transport_type ||= 'email'; > > $branchcode ||= ''; > >@@ -157,17 +157,22 @@ sub getletter { > $branchcode = C4::Context->userenv->{'branch'}; > } > >- if ( my $l = $letter{$module}{$code}{$branchcode} ) { >+ if ( my $l = $letter{$module}{$code}{$branchcode}{$message_transport_type} ) { > return { %$l }; # deep copy > } > > my $dbh = C4::Context->dbh; >- my $sth = $dbh->prepare("select * from letter where module=? and code=? and (branchcode = ? or branchcode = '') order by branchcode desc limit 1"); >- $sth->execute( $module, $code, $branchcode ); >+ my $sth = $dbh->prepare(qq{ >+ SELECT * >+ FROM letter >+ WHERE module=? AND code=? AND (branchcode = ? OR branchcode = '') AND message_transport_type = ? >+ ORDER BY branchcode DESC LIMIT 1 >+ }); >+ $sth->execute( $module, $code, $branchcode, $message_transport_type ); > my $line = $sth->fetchrow_hashref > or return; > $line->{'content-type'} = 'text/html; charset="UTF-8"' if $line->{is_html}; >- $letter{$module}{$code}{$branchcode} = $line; >+ $letter{$module}{$code}{$branchcode}{$message_transport_type} = $line; > return { %$line }; > } > >@@ -473,7 +478,7 @@ sub GetPreparedLetter { > my $substitute = $params{substitute}; > my $repeat = $params{repeat}; > >- my $letter = getletter( $module, $letter_code, $branchcode ) >+ my $letter = getletter( $module, $letter_code, $branchcode, $params{message_transport_type} ) > or warn( "No $module $letter_code letter"), > return; > >@@ -916,6 +921,25 @@ ENDSQL > return $sth->fetchall_arrayref({}); > } > >+=head2 GetMessageTransportTypes >+ >+ my @mtt = GetMessageTransportTypes(); >+ >+ returns a list of hashes >+ >+=cut >+ >+sub GetMessageTransportTypes { >+ my $dbh = C4::Context->dbh(); >+ my $sth = $dbh->prepare(" >+ SELECT message_transport_type >+ FROM message_transport_types >+ ORDER BY message_transport_type >+ "); >+ $sth->execute; >+ return $sth->fetchall_arrayref({}); >+} >+ > =head2 _add_attachements > > named parameters: >diff --git a/C4/Overdues.pm b/C4/Overdues.pm >index ac66c36..5fe74df 100644 >--- a/C4/Overdues.pm >+++ b/C4/Overdues.pm >@@ -60,6 +60,7 @@ BEGIN { > &GetOverduesForBranch > &RemoveNotifyLine > &AddNotifyLine >+ &GetOverdueMessageTransportTypes > ); > # subs to remove > push @EXPORT, qw( >@@ -1331,6 +1332,29 @@ sub RemoveNotifyLine { > return 1; > } > >+=head2 GetOverdueMessageTransportTypes >+ >+ my $message_transport_types = GetOverdueMessageTransportTypes( $branchcode, $categorycode, $letternumber); >+ >+ return a arrayref with message_transport_type for given branchcode, categorycode and letternumber(1,2 or 3) >+ >+=cut >+ >+sub GetOverdueMessageTransportTypes { >+ my ( $branchcode, $categorycode, $letternumber ) = @_; >+ my $dbh = C4::Context->dbh; >+ my $sth = $dbh->prepare(" >+ SELECT message_transport_type FROM overduerules_transport_types >+ WHERE branchcode = ? AND categorycode = ? AND letternumber = ? >+ "); >+ $sth->execute( $branchcode, $categorycode, $letternumber ); >+ my @mtts; >+ while ( my $mtt = $sth->fetchrow ) { >+ push @mtts, $mtt; >+ } >+ return \@mtts; >+} >+ > 1; > __END__ > >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 7ab48ee..dc7d77f 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -6020,6 +6020,62 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { > SetVersion ($DBversion); > } > >+ >+ >+ >+ >+$DBversion = "3.09.00.XXX"; >+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { >+ >+ $dbh->do( qq{ >+ ALTER TABLE letter ADD COLUMN message_transport_type VARCHAR(20) NOT NULL DEFAULT 'email' >+ } ); >+ >+ $dbh->do( qq{ >+ ALTER TABLE letter ADD CONSTRAINT message_transport_type_fk FOREIGN KEY (message_transport_type) REFERENCES message_transport_types(message_transport_type); >+ } ); >+ >+ $dbh->do( qq{ >+ ALTER TABLE letter DROP PRIMARY KEY, ADD PRIMARY KEY (`module`,`code`,`branchcode`, message_transport_type); >+ } ); >+ >+ $dbh->do( qq{ >+ CREATE TABLE overduerules_transport_types( >+ id INT(11) NOT NULL AUTO_INCREMENT, >+ branchcode varchar(10) NOT NULL DEFAULT '', >+ categorycode VARCHAR(10) NOT NULL DEFAULT '', >+ letternumber INT(1) NOT NULL DEFAULT 1, >+ message_transport_type VARCHAR(20) NOT NULL DEFAULT 'email', >+ PRIMARY KEY (id), >+ CONSTRAINT overduerules_fk FOREIGN KEY (branchcode, categorycode) REFERENCES overduerules (branchcode, categorycode) ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT mtt_fk FOREIGN KEY (message_transport_type) REFERENCES message_transport_types (message_transport_type) ON DELETE CASCADE ON UPDATE CASCADE >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8; >+ } ); >+ >+ my $sth = $dbh->prepare( qq{ >+ SELECT * FROM overduerules; >+ } ); >+ >+ $sth->execute; >+ my $sth_insert_mtt = $dbh->prepare( qq{ >+ INSERT INTO overduerules_transport_types (branchcode, categorycode, letternumber, message_transport_type) VALUES ( ?, ?, ?, ? ) >+ } ); >+ while ( my $row = $sth->fetchrow_hashref ) { >+ my $branchcode = $row->{branchcode}; >+ my $categorycode = $row->{categorycode}; >+ for my $letternumber ( 1..3 ) { >+ next unless $row->{"letter$letternumber"}; >+ $sth_insert_mtt->execute( >+ $branchcode, $categorycode, $letternumber, 'email' >+ ); >+ } >+ } >+ >+ print "Upgrade done (Adds tables and/or fields between letters and messages_transport_types)\n"; >+ SetVersion($DBversion); >+} >+ >+ > =head1 FUNCTIONS > > =head2 TableExists($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.insertatcaret.js b/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.insertatcaret.js >new file mode 100644 >index 0000000..408eb5d >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.insertatcaret.js >@@ -0,0 +1,46 @@ >+/*! >+ * jQuery insertAtCaret >+ * Allows inserting text where the caret is in a textarea >+ * Copyright (c) 2003-2010 phpMyAdmin devel team >+ * Version: 1.0 >+ * Developed by the phpMyAdmin devel team. Modified by Alex King and variaas >+ * http://alexking.org/blog/2003/06/02/inserting-at-the-cursor-using-javascript >+ * http://www.mail-archive.com/jquery-en@googlegroups.com/msg08708.html >+ * Licensed under the GPL license: >+ * http://www.gnu.org/licenses/gpl.html >+ */ >+;(function($) { >+ >+$.fn.insertAtCaret = function (myValue) { >+ >+ return this.each(function() { >+ >+ //IE support >+ if (document.selection) { >+ >+ this.focus(); >+ sel = document.selection.createRange(); >+ sel.text = myValue; >+ this.focus(); >+ >+ } else if (this.selectionStart || this.selectionStart == '0') { >+ >+ //MOZILLA / NETSCAPE support >+ var startPos = this.selectionStart; >+ var endPos = this.selectionEnd; >+ var scrollTop = this.scrollTop; >+ this.value = this.value.substring(0, startPos)+ myValue+ this.value.substring(endPos,this.value.length); >+ this.focus(); >+ this.selectionStart = startPos + myValue.length; >+ this.selectionEnd = startPos + myValue.length; >+ this.scrollTop = scrollTop; >+ >+ } else { >+ >+ this.value += myValue; >+ this.focus(); >+ } >+ }); >+}; >+ >+})(jQuery); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt >index c156e01..23f777e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt >@@ -1,15 +1,29 @@ > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Tools › Notices[% IF ( add_form ) %][% IF ( modify ) %] › Modify notice[% ELSE %] › Add notice[% END %][% END %][% IF ( add_validate ) %] › Notice added[% END %][% IF ( delete_confirm ) %] › Confirm deletion[% END %]</title> >+<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> > [% INCLUDE 'doc-head-close.inc' %] >-<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script> >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.insertatcaret.js"></script> >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> >+[% INCLUDE 'datatables-strings.inc' %] >+<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> > <script type="text/javascript"> > //<![CDATA[ > $(document).ready(function() { >- $("#lettert:has(tbody tr)").tablesorter({ >- widgets : ['zebra'], >- sortList: [[0,0]], >- headers: { 4: {sorter:false},5: { sorter: false },6: { sorter: false }} >- }); >+ var table = $("table#lettert").dataTable($.extend(true, {}, dataTablesDefaults, { >+ 'bPaginate': false, >+ 'bFilter': false, >+ 'bInfo': false, >+ "bAutoWidth": false, >+ 'aoColumns': [ >+ null, >+ null, >+ null, >+ null, >+ {'bSortable': false }, >+ {'bSortable': false }, >+ null, >+ ], >+ } ) ); > > $('#branch').change(function() { > $('#op').val(""); >@@ -19,6 +33,23 @@ $(document).ready(function() { > $('#op').val("add_form"); > return true; > }); >+ >+ $("#submit").click( function(event) { >+ $("fieldset.mtt").each( function(){ >+ var title = $(this).find('input[name="title"]').val(); >+ var content = $(this).find('textarea[name="content"]').val(); >+ if ( >+ ( title.length == 0 && content.length > 0 ) >+ || ( title.length > 0 && content.length == 0 ) >+ ) { >+ var mtt = $(this).find('input[name="message_transport_type"]').val(); >+ alert("You must specify a title and a content for " + mtt); >+ event.preventDefault(); >+ } >+ } ); >+ return true; >+ }); >+ > }); > [% IF ( add_form ) %] > >@@ -59,60 +90,25 @@ $(document).ready(function() { > } > } > >- function Check(f) { >- var ok=1; >- var _alertString=""; >- var alertString2; >-/* if (!(isNotNull(window.document.Aform.code))) { >- _alertString += "\n- " + _("Code missing"); >- }*/ >-/* if (!(isNotNull(window.document.Aform.name))) { >- _alertString += "\n- " + _("Name missing"); >- }*/ >- if (_alertString.length==0) { >- document.Aform.submit(); >- } else { >- alertString2 = _("Form not submitted because of the following problem(s)"); >- alertString2 += "\n------------------------------------------------------------------------------------\n"; >- alertString2 += _alertString; >- alert(alertString2); >- } >- } >- // GPL code coming from PhpMyAdmin >- function insertValueQuery() { >- var myQuery = document.Aform.content; >- var myListBox = document.Aform.SQLfieldname; >- >- if(myListBox.options.length > 0) { >- var chaineAj = ""; >- var NbSelect = 0; >- for(var i=0; i<myListBox.options.length; i++) { >- if (myListBox.options[i].selected){ >- NbSelect++; >- if (NbSelect > 1) >- chaineAj += ", "; >- chaineAj += myListBox.options[i].value; >- } >- } >- >- //IE support >- if (document.selection) { >- myQuery.focus(); >- sel = document.selection.createRange(); >- sel.text = chaineAj; >- document.Aform.insert.focus(); >- } >- //MOZILLA/NETSCAPE support >- else if (document.Aform.content.selectionStart || document.Aform.content.selectionStart == "0") { >- var startPos = document.Aform.content.selectionStart; >- var endPos = document.Aform.content.selectionEnd; >- var chaineSql = document.Aform.content.value; >- myQuery.value = chaineSql.substring(0, startPos) +'<<'+ chaineAj+'>>' + chaineSql.substring(endPos, chaineSql.length); >- } else { >- myQuery.value += chaineAj; >- } >- } >- } >+ function insertValueQuery(mtt_id) { >+ var fieldset = $("#" + mtt_id); >+ var myQuery = $(fieldset).find('textarea[name="content"]'); >+ var myListBox = $(fieldset).find('select[name="SQLfieldname"]'); >+ >+ if($(myListBox).find('option').length > 0) { >+ var chaineAj = ""; >+ var NbSelect = 0; >+ $(myListBox).find('option').each( function (){ >+ if ( $(this).attr('selected') ) { >+ NbSelect++; >+ if (NbSelect > 1) >+ chaineAj += ", "; >+ chaineAj += $(this).val(); >+ } >+ } ); >+ $(myQuery).insertAtCaret(chaineAj); >+ } >+ } > [% END %] > //]]> > </script> >@@ -162,64 +158,66 @@ $(document).ready(function() { > </select> > [% END %] > [% END %] >- <table id="lettert"> >- <thead><tr> >- <th>Library</th> >- <th>Module</th> >- <th>Code</th> >- <th>Name</th> >- <th>Copy notice</th> >- <th> </th> >- <th> </th> >- </tr></thead> >- <tbody> >- [% FOREACH lette IN letter %] >- [% can_edit = lette.branchcode || !independant_branch %] >- [% UNLESS ( loop.odd ) %] >- <tr class="highlight"> >- [% ELSE %] >- <tr> >- [% END %] >- <td>[% lette.branchname || "(All libraries)" %]</td> >- <td>[% lette.module %]</td> >- <td>[% lette.code %]</td> >- <td>[% lette.name %]</td> >- <td> >- [% IF !independant_branch || !lette.branchcode %] >- <form method="post" action="/cgi-bin/koha/tools/letter.pl"> >+ [% IF letter %] >+ <table id="lettert"> >+ <thead> >+ <tr> >+ <th>Library</th> >+ <th>Module</th> >+ <th>Code</th> >+ <th>Name</th> >+ <th>Copy notice</th> >+ <th> </th> >+ <th> </th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH lette IN letter %] >+ [% can_edit = lette.branchcode || !independant_branch %] >+ <tr> >+ <td>[% lette.branchname || "(All libraries)" %]</td> >+ <td>[% lette.module %]</td> >+ <td>[% lette.code %]</td> >+ <td>[% lette.name %]</td> >+ <td> >+ [% IF !independant_branch || !lette.branchcode %] >+ <form method="post" action="/cgi-bin/koha/tools/letter.pl"> > <input type="hidden" name="op" value="copy" /> >- <input type="hidden" name="oldbranchcode" value="[% lette.branchcode %]" /> >+ <input type="hidden" name="oldbranchcode" value="[% lette.branchcode %]" /> > <input type="hidden" name="module" value="[% lette.module %]" /> > <input type="hidden" name="code" value="[% lette.code %]" /> >- [% IF independant_branch %] >- <input type="hidden" name="branchcode" value="[% independant_branch %]" /> >- [% ELSE %] >- [% select_for_copy %] >- [% END %] >+ [% IF independant_branch %] >+ <input type="hidden" name="branchcode" value="[% independant_branch %]" /> >+ [% ELSE %] >+ [% select_for_copy %] >+ [% END %] > <input type="submit" value="Copy" /> >- </form> >- [% END %] >- </td> >- <td> >- [% IF can_edit %] >- <a href="/cgi-bin/koha/tools/letter.pl?op=add_form&branchcode=[% lette.branchcode %]&module=[% lette.module %]&code=[% lette.code %]">Edit</a> >- [% END %] >- </td> >- <td> >- [% IF !lette.protected && can_edit %] >- <a href="/cgi-bin/koha/tools/letter.pl?op=delete_confirm&branchcode=[%lette.branchcode %]&module=[% lette.module %]&code=[% lette.code %]">Delete</a> >+ </form> >+ [% END %] >+ </td> >+ <td> >+ [% IF can_edit %] >+ <a href="/cgi-bin/koha/tools/letter.pl?op=add_form&branchcode=[% lette.branchcode %]&module=[% lette.module %]&code=[% lette.code %]">Edit</a> >+ [% END %] >+ </td> >+ <td> >+ [% IF !lette.protected && can_edit %] >+ <a href="/cgi-bin/koha/tools/letter.pl?op=delete_confirm&branchcode=[%lette.branchcode %]&module=[% lette.module %]&code=[% lette.code %]">Delete</a> >+ [% END %] >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ [% ELSE %] >+ There are no notice or slip for this library. > [% END %] >- </td> >- </tr> >- [% END %] >- </tbody> >- </table> > [% END %] > > > [% IF ( add_form ) %] > <h1>[% IF ( modify ) %]Modify notice[% ELSE %]Add notice[% END %]</h1> >- <form action="?" name="Aform" method="post"> >+ <form name="Aform" method="post" enctype="multipart/form-data"> > <input type="hidden" name="op" id="op" value="add_validate" /> > <input type="hidden" name="checked" value="0" /> > [% IF ( modify ) %] >@@ -247,45 +245,45 @@ $(document).ready(function() { > <label for="module">Koha module:</label> > <input type="hidden" name="oldmodule" value="[% module %]" /> > [% IF ( modify ) %]<select name="module" id="module">[% END %] [% IF ( adding ) %] <select name="module" id="module" onchange="javascript:window.location.href = unescape(window.location.pathname)+'?op=add_form&module='+this.value+'&content='+window.document.forms['Aform'].elements['content'].value;">[% END %] >- [% IF ( catalogue ) %] >- <option value="catalogue" selected="selected">Catalog</option> >+ [% IF ( module == "catalogue" ) %] >+ <option value="catalogue" selected="selected">Catalog</option> > [% ELSE %] >- <option value="catalogue" >Catalog</option> >+ <option value="catalogue" >Catalog</option> > [% END %] >- [% IF ( circulation ) %] >- <option value="circulation" selected="selected">Circulation</option> >+ [% IF ( module == "circulation" ) %] >+ <option value="circulation" selected="selected">Circulation</option> > [% ELSE %] >- <option value="circulation">Circulation</option> >+ <option value="circulation">Circulation</option> > [% END %] >- [% IF ( claimacquisition ) %] >- <option value="claimacquisition" selected="selected">Claim acquisition</option> >+ [% IF ( module == "claimacquisition" ) %] >+ <option value="claimacquisition" selected="selected">Claim acquisition</option> > [% ELSE %] >- <option value="claimacquisition">Claim acquisition</option> >+ <option value="claimacquisition">Claim acquisition</option> > [% END %] >- [% IF ( claimissues ) %] >- <option value="claimissues" selected="selected">Claim serial issue</option> >+ [% IF ( module == "claimissues" ) %] >+ <option value="claimissues" selected="selected">Claim serial issue</option> > [% ELSE %] >- <option value="claimissues">Claim serial issue</option> >+ <option value="claimissues">Claim serial issue</option> > [% END %] >- [% IF ( reserves ) %] >- <option value="reserves" selected="selected">Holds</option> >+ [% IF ( module == "reserves" ) %] >+ <option value="reserves" selected="selected">Holds</option> > [% ELSE %] >- <option value="reserves">Holds</option> >+ <option value="reserves">Holds</option> > [% END %] >- [% IF ( members ) %] >- <option value="members" selected="selected">Members</option> >+ [% IF ( module == "members" ) %] >+ <option value="members" selected="selected">Members</option> > [% ELSE %] >- <option value="members">Members</option> >+ <option value="members">Members</option> > [% END %] >- [% IF ( serial ) %] >- <option value="serial" selected="selected">Serials (routing list)</option> >+ [% IF ( module == "serial" ) %] >+ <option value="serial" selected="selected">Serials (routing list)</option> > [% ELSE %] >- <option value="serial">Serials (routing list)</option> >+ <option value="serial">Serials (routing list)</option> > [% END %] >- [% IF ( suggestions ) %] >- <option value="suggestions" selected="selected">Suggestions</option> >+ [% IF ( module == "suggestions" ) %] >+ <option value="suggestions" selected="selected">Suggestions</option> > [% ELSE %] >- <option value="suggestions">Suggestions</option> >+ <option value="suggestions">Suggestions</option> > [% END %] > </select> > </li> >@@ -295,33 +293,49 @@ $(document).ready(function() { > <li> > <label for="name">Name:</label><input type="text" id="name" name="name" size="60" value="[% name %]" /> > </li> >- <li> >- <label for="is_html">HTML message:</label> >- [% IF is_html %] >- <input type="checkbox" id="is_html" name="is_html" value="1" checked /> >- [% ELSE %] >- <input type="checkbox" id="is_html" name="is_html" value="1" /> >- [% END %] >- </li> >- <li> >- <label for="title">Message subject:</label><input type="text" id="title" name="title" size="60" value="[% title %]" /> >- </li> >- <li> >- <label for="SQLfieldname">Message body:</label> >- </li> >- <li> >- <table> >- <tr><td><select name="SQLfieldname" id="SQLfieldname" size="9"> >- [% FOREACH SQLfieldnam IN SQLfieldname %] >- <option value="[% SQLfieldnam.value %]">[% SQLfieldnam.text %]</option> >- [% END %] >- </select></td><td><input type="button" name="insert" value=">>" onclick="insertValueQuery()" title="Insert" /></td><td><textarea name="content" cols="80" rows="15">[% content %]</textarea></td></tr></table> > >- </li> >- </ol> >- [% IF code.search('DGST') %] <span class="overdue">Warning, this is a template for a Digest, as such, any references to branch data ( e.g. branches.branchname ) will refer to the borrower's home branch.</span> [% END %] >+ [% FOREACH letter IN letters %] >+ <li> >+ <fieldset class="rows mtt" id="[% letter.message_transport_type %]"> >+ <legend>[% letter.message_transport_type %]</legend> >+ <ol> >+ <li> >+ <input type="hidden" name="message_transport_type" value="[% letter.message_transport_type %]" /> >+ <label for="is_html_[% letter.message_transport_type %]">HTML message:</label> >+ [% IF letter.is_html %] >+ <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" checked="checked" /> >+ [% ELSE %] >+ <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" /> >+ [% END %] >+ </li> >+ <li> >+ <label for="title">Message subject:</label><input type="text" id="title" name="title" size="60" value="[% letter.title %]" /> >+ </li> >+ <li> >+ <label for="SQLfieldname">Message body:</label> >+ <table> >+ <tr> >+ <td> >+ <select name="SQLfieldname" multiple="multiple" size="9"> >+ [% FOREACH SQLfieldnam IN SQLfieldname %] >+ <option value="[% SQLfieldnam.value %]">[% SQLfieldnam.text %]</option> >+ [% END %] >+ </select> >+ </td> >+ <td><input type="button" name="insert" value=">>" onclick="insertValueQuery('[% letter.message_transport_type %]')" title="Insert" /></td> >+ <td><textarea name="content" cols="80" rows="15">[% letter.content %]</textarea></td> >+ </tr> >+ </table> >+ </li> >+ </ol> >+ </fieldset> >+ </li> >+ [% END %] >+ </ol> >+ >+ [% IF code.search('DGST') %] <span class="overdue">Warning, this is a template for a Digest, as such, any references to branch data ( e.g. branches.branchname ) will refer to the borrower's home branch.</span> [% END %] > </fieldset> >- <fieldset class="action"><input type="button" value="Submit" onclick="Check(this.form)" class="button" /> <a class="cancel" href="/cgi-bin/koha/tools/letter.pl">Cancel</a></fieldset> >+ <fieldset class="action"><input type="submit" id="submit" value="Submit" class="button" /> <a class="cancel" href="/cgi-bin/koha/tools/letter.pl">Cancel</a></fieldset> > <input type="hidden" name="searchfield" value="[% searchfield %]" /> > </form> > [% END %] >@@ -356,6 +370,7 @@ $(document).ready(function() { > <input type="hidden" name="branchcode" value="[% branchcode %]" /> > <input type="hidden" name="code" value="[% code %]" /> > <input type="hidden" name="module" value="[% module %]" /> >+ <input type="hidden" name="message_transport_type" value="*" /> > <input type="submit" value="Yes, delete" class="approve" /> > </form> > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/overduerules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/overduerules.tt >index 12b53c3..22597de 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/overduerules.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/overduerules.tt >@@ -4,12 +4,17 @@ > > <script type="text/javascript"> > //<![CDATA[ >+var tab_map = { "1" : _("First"), "2" : _("Second"), "3" : _("Third")}; > $(document).ready(function() { >- $('#selectlibrary').find("input:submit").hide(); >- $('#branch').change(function() { >- $('#selectlibrary').submit(); >- }); >- $('#rulestabs').tabs(); >+ $('#selectlibrary').find("input:submit").hide(); >+ $('#branch').change(function() { >+ $('#selectlibrary').submit(); >+ }); >+ $("li>a.tab").each( function(){ >+ var id = $(this).attr("data-number"); >+ $(this).html(tab_map[id]); >+ } ); >+ $('#rulestabs').tabs(); > }); > //]]> > </script> >@@ -72,131 +77,72 @@ $(document).ready(function() { > [% IF ( datasaved ) %]<div class="dialog message">INPUT SAVED</div> [% END %] > > <div id="rulestabs" class="toptabs"> >- <ul class="ui-tabs-nav"> >- <li><a href="#first">First</a></li> >- <li><a href="#second">Second</a></li> >- <li><a href="#third">Third</a></li> >- </ul> >+ <ul class="ui-tabs-nav"> >+ [% FOR tab IN tabs %] >+ <li><a href="#[% tab.id %]" class="tab [% tab.id %]" data-number="[% tab.number %]"></a></li> >+ [% END %] >+ </ul> >+ [% FOR tab IN tabs %] >+ <div id="[% tab.id %]"> >+ <table> >+ <thead> >+ <tr> >+ <th> </th> >+ <th scope="col">Delay</th> >+ <th scope="col">Letter</th> >+ <th scope="col">Restrict</th> >+ [% FOREACH mtt IN message_transport_types %] >+ <th scpre="col">[% mtt.message_transport_type %]</th> >+ [% END %] >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH value IN tab.values %] >+ <tr> >+ <th scope="row">[% value.line %]</th> >+ <td> >+ <input type="text" name="delay[% tab.number %]-[% value.overduename %]" size="5" value="[% value.delay %]" /> >+ </td> >+ <td> >+ [% IF ( value.noletter ) %] >+ <input type="text" name="letter[% tab.number %]-[% value.overduename %]" value="[% value.letter %]" /> >+ [% ELSE %] >+ <select name="letter[% tab.number %]-[% value.overduename %]"> >+ <option value="">No notice</option> >+ [% FOREACH letterloop IN value.letterloop %] >+ [% IF ( letterloop.selected ) %] >+ <option value="[% letterloop.value %]" selected="selected">[% letterloop.lettername %]</option> >+ [% ELSE %] >+ <option value="[% letterloop.value %]">[% letterloop.lettername %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ [% END %] >+ </td> >+ <td> >+ [% IF ( value.debarred ) %] >+ <input type="checkbox" name="debarred[% tab.number %]-[% value.overduename %]" checked="checked" value="1" /> >+ [% ELSE %] >+ <input type="checkbox" name="debarred[% tab.number %]-[% value.overduename %]" value="1" /> >+ [% END %] >+ </td> >+ [% FOREACH mtt IN value.message_transport_types %] >+ <td> >+ [% IF mtt.selected %] >+ <input type="checkbox" name="mtt[% tab.number %]-[% value.overduename %]" value="[% mtt.value %]" checked="checked" /> >+ [% ELSE %] >+ <input type="checkbox" name="mtt[% tab.number %]-[% value.overduename %]" value="[% mtt.value %]" /> >+ [% END %] >+ </td> >+ [% END %] >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ </div> >+ [% END %] > >-<div id="first"><table> >- <tr><th> </th><th scope="col">Delay</th><th scope="col">First letter</th><th scope="col">Restrict</th></tr> >- [% FOREACH tabl IN table %] >- [% UNLESS ( loop.odd ) %] >- <tr class="highlight"> >- [% ELSE %] >- <tr> >- [% END %] >- <th scope="row">[% tabl.line %]</th> >-<td> >- <input type="text" name="delay1-[% tabl.overduename %]" size="5" value="[% tabl.delay1 %]" /> >- </td> >-<td> >- [% IF ( tabl.noletter ) %] >- <input type="text" name="letter1-[% tabl.overduename %]" value="[% tabl.letter1 %]" /> >- [% ELSE %] >- <select name="letter1-[% tabl.overduename %]"> >- <option value="">No notice</option> >- [% FOREACH letterloop IN tabl.letterloop1 %] >- [% IF ( letterloop.selected ) %] >- <option value="[% letterloop.value %]" selected="selected">[% letterloop.lettername %]</option> >- [% ELSE %] >- <option value="[% letterloop.value %]">[% letterloop.lettername %]</option> >- [% END %] >- [% END %] >- </select> >- [% END %] >- </td> >-<td> >- [% IF ( tabl.debarred1 ) %] >- <input type="checkbox" name="debarred1-[% tabl.overduename %]" checked="checked" value="1" /> >- [% ELSE %] >- <input type="checkbox" name="debarred1-[% tabl.overduename %]" value="1" /> >- [% END %] >- </td> >- </tr> >- [% END %] >- </table> >-</div> > >-<div id="second"><table> >- <tr><th> </th><th scope="col">Delay</th><th scope="col">Second letter</th><th scope="col">Restrict</th></tr> >- [% FOREACH tabl IN table %] >- [% UNLESS ( loop.odd ) %] >- <tr class="highlight"> >- [% ELSE %] >- <tr> >- [% END %] >- <th scope="row">[% tabl.line %]</th> >-<td> >- <input type="text" name="delay2-[% tabl.overduename %]" size="5" value="[% tabl.delay2 %]" /> >- </td> >-<td> >- [% IF ( tabl.noletter ) %] >- <input type="text" name="letter2-[% tabl.overduename %]" value="[% tabl.letter2 %]" /> >- [% ELSE %] >- <select name="letter2-[% tabl.overduename %]"> >- <option value="">No notice</option> >- [% FOREACH letterloop IN tabl.letterloop2 %] >- [% IF ( letterloop.selected ) %] >- <option value="[% letterloop.value %]" selected="selected">[% letterloop.lettername %]</option> >- [% ELSE %] >- <option value="[% letterloop.value %]">[% letterloop.lettername %]</option> >- [% END %] >- [% END %] >- </select> >- [% END %] >- </td> >-<td> >- [% IF ( tabl.debarred2 ) %] >- <input type="checkbox" name="debarred2-[% tabl.overduename %]" checked="checked" value="1" /> >- [% ELSE %] >- <input type="checkbox" name="debarred2-[% tabl.overduename %]" value="1" /> >- [% END %] >- </td> >- </tr> >- [% END %] >- </table> >-</div> >- >-<div id="third"><table> >- <tr><th> </th><th scope="col">Delay</th><th scope="col">Third letter</th><th scope="col">Restrict</th></tr> >- [% FOREACH tabl IN table %] >- [% UNLESS ( loop.odd ) %] >- <tr class="highlight"> >- [% ELSE %] >- <tr> >- [% END %] >- <th scope="row">[% tabl.line %]</th> >-<td> >- <input type="text" name="delay3-[% tabl.overduename %]" size="5" value="[% tabl.delay3 %]" /> >- </td> >-<td> >- [% IF ( tabl.noletter ) %] >- <input type="text" name="letter3-[% tabl.overduename %]" value="[% tabl.letter3 %]" /> >- [% ELSE %] >- <select name="letter3-[% tabl.overduename %]"> >- <option value="">No notice</option> >- [% FOREACH letterloop IN tabl.letterloop3 %] >- [% IF ( letterloop.selected ) %] >- <option value="[% letterloop.value %]" selected="selected">[% letterloop.lettername %]</option> >- [% ELSE %] >- <option value="[% letterloop.value %]">[% letterloop.lettername %]</option> >- [% END %] >- [% END %] >- </select> >- [% END %] >- </td> >-<td> >- [% IF ( tabl.debarred3 ) %] >- <input type="checkbox" name="debarred3-[% tabl.overduename %]" checked="checked" value="1" /> >- [% ELSE %] >- <input type="checkbox" name="debarred3-[% tabl.overduename %]" value="1" /> >- [% END %] >- </td> >- </tr> >- [% END %] >- </table> >-</div> > </div> > > <fieldset class="action"><input type="submit" value="Save changes" /></fieldset> >diff --git a/misc/cronjobs/overdue_notices.pl b/misc/cronjobs/overdue_notices.pl >index e83bd39..62f4d39 100755 >--- a/misc/cronjobs/overdue_notices.pl >+++ b/misc/cronjobs/overdue_notices.pl >@@ -39,7 +39,7 @@ use C4::Context; > use C4::Dates qw/format_date/; > use C4::Debug; > use C4::Letters; >-use C4::Overdues qw(GetFine); >+use C4::Overdues qw(GetFine GetOverdueMessageTransportTypes); > > =head1 NAME > >@@ -417,7 +417,7 @@ END_SQL > > # my $outfile = 'overdues_' . ( $mybranch || $branchcode || 'default' ); > while ( my $overdue_rules = $rqoverduerules->fetchrow_hashref ) { >- PERIOD: foreach my $i ( 1 .. 3 ) { >+ PERIOD: foreach my $i ( 1..3 ) { > > $verbose and warn "branch '$branchcode', pass $i\n"; > my $mindays = $overdue_rules->{"delay$i"}; # the notice will be sent after mindays days (grace period) >@@ -507,68 +507,45 @@ END_SQL > } > $sth2->finish; > >- my $letter = parse_letter( >- { letter_code => $overdue_rules->{"letter$i"}, >- letter => $letter_template, >- borrowernumber => $borrowernumber, >- branchcode => $branchcode, >- items => \@items, >- substitute => { # this appears to be a hack to overcome incomplete features in this code. >- bib => $branch_details->{'branchname'}, # maybe 'bib' is a typo for 'lib<rary>'? >- 'items.content' => $titles, >- 'count' => $itemcount, >- } >+ my @message_transport_types = @{ GetOverdueMessageTransportTypes( $branchcode, $overdue_rules->{categorycode}, $i) }; >+ >+ for my $mtt ( @message_transport_types ) { >+ >+ my $letter = parse_letter( >+ { letter_code => $overdue_rules->{"letter$i"}, >+ letter => $letter_template, >+ borrowernumber => $borrowernumber, >+ branchcode => $branchcode, >+ items => \@items, >+ substitute => { # this appears to be a hack to overcome incomplete features in this code. >+ bib => $branch_details->{'branchname'}, # maybe 'bib' is a typo for 'lib<rary>'? >+ 'items.content' => $titles, >+ 'count' => $itemcount, >+ }, >+ message_transport_type => $mtt, >+ } >+ ); >+ unless ($letter) { >+ $verbose and warn "Message '$overdue_rules->{letter$i}' content not found"; >+ >+ # might as well skip while PERIOD, no other borrowers are going to work. >+ # FIXME : Does this mean a letter must be defined in order to trigger a debar ? >+ next PERIOD; > } >- ); >- unless ($letter) { >- $verbose and warn "Message '$overdue_rules->{letter$i}' content not found"; > >- # might as well skip while PERIOD, no other borrowers are going to work. >- # FIXME : Does this mean a letter must be defined in order to trigger a debar ? >- next PERIOD; >- } >- >- if ( $exceededPrintNoticesMaxLines ) { >- $letter->{'content'} .= "List too long for form; please check your account online for a complete list of your overdue items."; >- } >+ if ( $exceededPrintNoticesMaxLines ) { >+ $letter->{'content'} .= "List too long for form; please check your account online for a complete list of your overdue items."; >+ } >+ >+ my @misses = grep { /./ } map { /^([^>]*)[>]+/; ( $1 || '' ); } split /\</, $letter->{'content'}; >+ if (@misses) { >+ $verbose and warn "The following terms were not matched and replaced: \n\t" . join "\n\t", @misses; >+ } >+ $letter->{'content'} =~ s/\<[^<>]*?\>//g; # Now that we've warned about them, remove them. >+ $letter->{'content'} =~ s/\<[^<>]*?\>//g; # 2nd pass for the double nesting. >+ >+ if ($nomail) { > >- my @misses = grep { /./ } map { /^([^>]*)[>]+/; ( $1 || '' ); } split /\</, $letter->{'content'}; >- if (@misses) { >- $verbose and warn "The following terms were not matched and replaced: \n\t" . join "\n\t", @misses; >- } >- $letter->{'content'} =~ s/\<[^<>]*?\>//g; # Now that we've warned about them, remove them. >- $letter->{'content'} =~ s/\<[^<>]*?\>//g; # 2nd pass for the double nesting. >- >- if ($nomail) { >- >- push @output_chunks, >- prepare_letter_for_printing( >- { letter => $letter, >- borrowernumber => $borrowernumber, >- firstname => $firstname, >- lastname => $lastname, >- address1 => $address1, >- address2 => $address2, >- city => $city, >- postcode => $postcode, >- email => $email, >- itemcount => $itemcount, >- titles => $titles, >- outputformat => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : '', >- } >- ); >- } else { >- if ($email) { >- C4::Letters::EnqueueLetter( >- { letter => $letter, >- borrowernumber => $borrowernumber, >- message_transport_type => 'email', >- from_address => $admin_email_address, >- } >- ); >- } else { >- >- # If we don't have an email address for this patron, send it to the admin to deal with. > push @output_chunks, > prepare_letter_for_printing( > { letter => $letter, >@@ -585,6 +562,36 @@ END_SQL > outputformat => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : '', > } > ); >+ } else { >+ if ( ( $email and $mtt eq 'email' ) >+ or $mtt eq 'sms' ) { >+ C4::Letters::EnqueueLetter( >+ { letter => $letter, >+ borrowernumber => $borrowernumber, >+ message_transport_type => $mtt, >+ from_address => $admin_email_address, >+ } >+ ); >+ } else { >+ >+ # If we don't have an email address for this patron, send it to the admin to deal with. >+ push @output_chunks, >+ prepare_letter_for_printing( >+ { letter => $letter, >+ borrowernumber => $borrowernumber, >+ firstname => $firstname, >+ lastname => $lastname, >+ address1 => $address1, >+ address2 => $address2, >+ city => $city, >+ postcode => $postcode, >+ email => $email, >+ itemcount => $itemcount, >+ titles => $titles, >+ outputformat => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : '', >+ } >+ ); >+ } > } > } > } >@@ -711,7 +718,8 @@ sub parse_letter { > branchcode => $params->{'branchcode'}, > tables => \%tables, > substitute => $substitute, >- repeat => { item => \@item_tables } >+ repeat => { item => \@item_tables }, >+ message_transport_type => $params->{message_transport_type}, > ); > } > >diff --git a/tools/letter.pl b/tools/letter.pl >index 317ea83..ddbe706 100755 >--- a/tools/letter.pl >+++ b/tools/letter.pl >@@ -47,14 +47,16 @@ use C4::Auth; > use C4::Context; > use C4::Output; > use C4::Branch; # GetBranches >+use C4::Letters; > use C4::Members::Attributes; > >-# _letter_from_where($branchcode,$module, $code) >+# _letter_from_where($branchcode,$module, $code, $mtt) > # - return FROM WHERE clause and bind args for a letter > sub _letter_from_where { >- my ($branchcode, $module, $code) = @_; >+ my ($branchcode, $module, $code, $mtt) = @_; > my $sql = q{FROM letter WHERE branchcode = ? AND module = ? AND code = ?}; >- my @args = ($branchcode || '', $module, $code); >+ $sql .= q{ AND message_transport_type = ?} if $mtt ne '*'; >+ my @args = ( $branchcode || '', $module, $code, ($mtt ne '*' ? $mtt : ()) ); > # Mysql is retarded. cause branchcode is part of the primary key it cannot be null. How does that > # work with foreign key constraint I wonder... > >@@ -68,12 +70,12 @@ sub _letter_from_where { > return ($sql, \@args); > } > >-# letter_exists($branchcode,$module, $code) >-# - return true if a letter with the given $branchcode, $module and $code exists >-sub letter_exists { >+# get_letters($branchcode,$module, $code, $mtt) >+# - return letters with the given $branchcode, $module, $code and $mtt exists >+sub get_letters { > my ($sql, $args) = _letter_from_where(@_); > my $dbh = C4::Context->dbh; >- my $letter = $dbh->selectrow_hashref("SELECT * $sql", undef, @$args); >+ my $letter = $dbh->selectall_hashref("SELECT * $sql", 'message_transport_type', undef, @$args); > return $letter; > } > >@@ -90,7 +92,7 @@ my $searchfield = $input->param('searchfield'); > my $script_name = '/cgi-bin/koha/tools/letter.pl'; > our $branchcode = $input->param('branchcode'); > my $code = $input->param('code'); >-my $module = $input->param('module'); >+my $module = $input->param('module') || ''; > my $content = $input->param('content'); > my $op = $input->param('op') || ''; > my $dbh = C4::Context->dbh; >@@ -134,7 +136,8 @@ elsif ( $op eq 'delete_confirm' ) { > delete_confirm($branchcode, $module, $code); > } > elsif ( $op eq 'delete_confirmed' ) { >- delete_confirmed($branchcode, $module, $code); >+ my $mtt = $input->param('message_transport_type'); >+ delete_confirmed($branchcode, $module, $code, $mtt); > $op = q{}; # next operation is to return to default screen > } > else { >@@ -151,25 +154,56 @@ if ($op) { > output_html_with_http_headers $input, $cookie, $template->output; > > sub add_form { >- my ($branchcode,$module, $code ) = @_; >+ my ( $branchcode,$module, $code ) = @_; > >- my $letter; >+ my $letters; > # if code has been passed we can identify letter and its an update action > if ($code) { >- $letter = letter_exists($branchcode,$module, $code); >+ $letters = get_letters($branchcode,$module, $code, '*'); > } >- if ($letter) { >- $template->param( modify => 1 ); >- $template->param( code => $letter->{code} ); >+ >+ my $message_transport_types = GetMessageTransportTypes(); >+ my @letter_loop; >+ if ($letters) { >+ my $first_flag = 1; >+ for my $mtt ( @$message_transport_types ) { >+ $mtt = $mtt->{message_transport_type}; >+ if ( $first_flag ) { >+ $template->param( >+ modify => 1, >+ code => $code, >+ branchcode => $branchcode, >+ name => $letters->{$mtt}{name}, >+ ); >+ $first_flag = 0; >+ } >+ >+ push @letter_loop, { >+ message_transport_type => $mtt, >+ is_html => $letters->{$mtt}{is_html}, >+ title => $letters->{$mtt}{title}, >+ content => $letters->{$mtt}{content}, >+ }; >+ } > } > else { # initialize the new fields >- $letter = { >+ for my $mtt ( @$message_transport_types ) { >+ $mtt = $mtt->{message_transport_type}; >+ push @letter_loop, { >+ message_transport_type => $mtt, >+ } >+ } >+ $template->param( > branchcode => $branchcode, > module => $module, >- }; >+ ); > $template->param( adding => 1 ); > } > >+ $template->param( >+ letters => \@letter_loop, >+ ); >+ > my $field_selection; > push @{$field_selection}, add_fields('branches'); > if ($module eq 'reserves') { >@@ -210,13 +244,7 @@ sub add_form { > } > > $template->param( >- branchcode => $letter->{branchcode}, >- name => $letter->{name}, >- is_html => $letter->{is_html}, >- title => $letter->{title}, >- content => $letter->{content}, > module => $module, >- $module => 1, > branchloop => _branchloop($branchcode), > SQLfieldname => $field_selection, > ); >@@ -231,22 +259,36 @@ sub add_validate { > my $oldmodule = $input->param('oldmodule'); > my $code = $input->param('code'); > my $name = $input->param('name'); >- my $is_html = $input->param('is_html'); >- my $title = $input->param('title'); >- my $content = $input->param('content'); >- if (letter_exists($oldbranchcode,$oldmodule, $code)) { >- $dbh->do( >- q{UPDATE letter SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ? WHERE branchcode = ? AND module = ? AND code = ?}, >- undef, >- $branchcode, $module, $name, $is_html || 0, $title, $content, >- $oldbranchcode, $oldmodule, $code >- ); >- } else { >- $dbh->do( >- q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content) VALUES (?,?,?,?,?,?,?)}, >- undef, >- $branchcode, $module, $code, $name, $is_html || 0, $title, $content >- ); >+ my @mtt = $input->param('message_transport_type'); >+ my @title = $input->param('title'); >+ my @content = $input->param('content'); >+ for my $mtt ( @mtt ) { >+ my $is_html = $input->param("is_html_$mtt"); >+ my $title = shift @title; >+ my $content = shift @content; >+ my $letter = get_letters($oldbranchcode,$oldmodule, $code, $mtt); >+ unless ( $title and $content ) { >+ delete_confirmed( $oldbranchcode, $oldmodule, $code, $mtt ); >+ next; >+ } >+ if ( exists $letter->{$mtt} ) { >+ $dbh->do( >+ q{ >+ UPDATE letter >+ SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ? >+ WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ? >+ }, >+ undef, >+ $branchcode, $module, $name, $is_html || 0, $title, $content, >+ $oldbranchcode, $oldmodule, $code, $mtt >+ ); >+ } else { >+ $dbh->do( >+ q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)}, >+ undef, >+ $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt >+ ); >+ } > } > # set up default display > default_display($branchcode); >@@ -259,31 +301,42 @@ sub add_copy { > my $module = $input->param('module'); > my $code = $input->param('code'); > >- return if letter_exists($branchcode,$module, $code); >+ return if keys %{ get_letters($branchcode,$module, $code, '*') }; > >- my $old_letter = letter_exists($oldbranchcode,$module, $code); >+ my $old_letters = get_letters($oldbranchcode,$module, $code, '*'); > >- $dbh->do( >- q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content) VALUES (?,?,?,?,?,?,?)}, >- undef, >- $branchcode, $module, $code, $old_letter->{name}, $old_letter->{is_html}, $old_letter->{title}, $old_letter->{content} >- ); >+ my $message_transport_types = GetMessageTransportTypes(); >+ for my $mtt ( @$message_transport_types ) { >+ my $mtt = $mtt->{message_transport_type}; >+ next unless exists $old_letters->{$mtt}; >+ my $old_letter = $old_letters->{$mtt}; >+ >+ $dbh->do( >+ q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)}, >+ undef, >+ $branchcode, $module, $code, $old_letter->{name}, $old_letter->{is_html}, $old_letter->{title}, $old_letter->{content}, $mtt >+ ); >+ } > } > > sub delete_confirm { > my ($branchcode, $module, $code) = @_; > my $dbh = C4::Context->dbh; >- my $letter = letter_exists($branchcode, $module, $code); >- $template->param( branchcode => $branchcode, branchname => GetBranchName($branchcode) ); >- $template->param( code => $code ); >- $template->param( module => $module); >- $template->param( name => $letter->{name}); >+ my $letter = get_letters($branchcode, $module, $code, '*'); >+ my @values = values %$letter; >+ $template->param( >+ branchcode => $branchcode, >+ branchname => GetBranchName($branchcode), >+ code => $code, >+ module => $module, >+ name => $values[0]->{name}, >+ ); > return; > } > > sub delete_confirmed { >- my ($branchcode, $module, $code) = @_; >- my ($sql, $args) = _letter_from_where($branchcode, $module, $code); >+ my ($branchcode, $module, $code, $mtt) = @_; >+ my ($sql, $args) = _letter_from_where($branchcode, $module, $code, $mtt); > my $dbh = C4::Context->dbh; > $dbh->do("DELETE $sql", undef, @$args); > # setup default display for screen >@@ -300,7 +353,8 @@ sub retrieve_letters { > my ($sql, @where, @args); > $sql = "SELECT branchcode, module, code, name, branchname > FROM letter >- LEFT OUTER JOIN branches USING (branchcode)"; >+ LEFT OUTER JOIN branches USING (branchcode) >+ "; > if ($searchstring && $searchstring=~m/(\S+)/) { > $searchstring = $1 . q{%}; > push @where, 'code LIKE ?'; >@@ -316,8 +370,9 @@ sub retrieve_letters { > } > > $sql .= " WHERE ".join(" AND ", @where) if @where; >+ $sql .= " GROUP BY branchcode,module,code"; > $sql .= " ORDER BY module, code, branchcode"; >-# use Data::Dumper; die Dumper($sql, \@args); >+ > return $dbh->selectall_arrayref($sql, { Slice => {} }, @args); > } > >diff --git a/tools/overduerules.pl b/tools/overduerules.pl >index cc90d0b..c1ce466 100755 >--- a/tools/overduerules.pl >+++ b/tools/overduerules.pl >@@ -27,6 +27,7 @@ use C4::Koha; > use C4::Branch; > use C4::Letters; > use C4::Members; >+use C4::Overdues; > > our $input = new CGI; > my $dbh = C4::Context->dbh; >@@ -44,11 +45,11 @@ sub blank_row { > for my $rp (@rule_params) { > for my $n (1 .. 3) { > my $key = "${rp}${n}-$category_code"; >- >+ > if (utf8::is_utf8($key)) { > utf8::encode($key); > } >- >+ > my $value = $input->param($key); > if ($value) { > return 0; >@@ -84,6 +85,18 @@ if ($op eq 'save') { > my $sth_insert = $dbh->prepare("INSERT INTO overduerules (branchcode,categorycode, delay1,letter1,debarred1, delay2,letter2,debarred2, delay3,letter3,debarred3) VALUES (?,?,?,?,?,?,?,?,?,?,?)"); > my $sth_update=$dbh->prepare("UPDATE overduerules SET delay1=?, letter1=?, debarred1=?, delay2=?, letter2=?, debarred2=?, delay3=?, letter3=?, debarred3=? WHERE branchcode=? AND categorycode=?"); > my $sth_delete=$dbh->prepare("DELETE FROM overduerules WHERE branchcode=? AND categorycode=?"); >+ my $sth_insert_mtt = $dbh->prepare(" >+ INSERT INTO overduerules_transport_types( >+ branchcode, categorycode, letternumber, message_transport_type >+ ) VALUES ( >+ ?, ?, ?, ? >+ ) >+ "); >+ my $sth_delete_mtt = $dbh->prepare(" >+ DELETE FROM overduerules_transport_types >+ WHERE branchcode = ? AND categorycode = ? >+ "); >+ > foreach my $key (@names){ > # ISSUES > if ($key =~ /(delay|letter|debarred)([1-3])-(.*)/) { >@@ -166,6 +179,15 @@ if ($op eq 'save') { > ($temphash{$bor}->{"debarred3"}?$temphash{$bor}->{"debarred3"}:0) > ); > } >+ >+ $sth_delete_mtt->execute( $branch, $bor ); >+ for my $letternumber ( 1..3 ) { >+ my @mtt = $input->param( "mtt${letternumber}-$bor" ); >+ next unless @mtt; >+ for my $mtt ( @mtt ) { >+ $sth_insert_mtt->execute( $branch, $bor, $letternumber, $mtt); >+ } >+ } > } > } > } >@@ -185,19 +207,21 @@ my $countletters = keys %{$letters}; > > my @line_loop; > >+my $message_transport_types = GetMessageTransportTypes(); >+my ( @first, @second, @third ); > for my $data (@categories) { >- my %row = ( >- overduename => $data->{'categorycode'}, >- line => $data->{'description'} >- ); > if (%temphash and not $input_saved){ > # if we managed to save the form submission, don't > # reuse %temphash, but take the values from the > # database - this makes it easier to identify > # bugs where the form submission was not correctly saved >- for (my $i=1;$i<=3;$i++){ >- $row{"delay$i"}=$temphash{$data->{'categorycode'}}->{"delay$i"}; >- $row{"debarred$i"}=$temphash{$data->{'categorycode'}}->{"debarred$i"}; >+ for my $i ( 1..3 ){ >+ my %row = ( >+ overduename => $data->{'categorycode'}, >+ line => $data->{'description'} >+ ); >+ $row{delay}=$temphash{$data->{'categorycode'}}->{"delay$i"}; >+ $row{debarred}=$temphash{$data->{'categorycode'}}->{"debarred$i"}; > if ($countletters){ > my @letterloop; > foreach my $thisletter (sort { $letters->{$a} cmp $letters->{$b} } keys %$letters) { >@@ -212,10 +236,26 @@ for my $data (@categories) { > ); > push @letterloop, \%letterrow; > } >- $row{"letterloop$i"}=\@letterloop; >+ $row{letterloop}=\@letterloop; > } else { >- $row{"noletter"}=1; >- $row{"letter$i"}=$temphash{$data->{'categorycode'}}->{"letter$i"}; >+ $row{noletter}=1; >+ $row{letter}=$temphash{$data->{'categorycode'}}->{"letter$i"}; >+ } >+ my @selected_mtts = @{ GetOverdueMessageTransportTypes( $branch, $data->{'categorycode'}, $i) }; >+ my @mtts; >+ for my $mtt ( @$message_transport_types ) { >+ push @mtts, { >+ value => $mtt->{message_transport_type}, >+ selected => ( grep {$mtt->{message_transport_type} eq $_} @selected_mtts ) ? 1 : 0 , >+ } >+ } >+ $row{message_transport_types} = \@mtts; >+ if ( $i == 1 ) { >+ push @first, \%row; >+ } elsif ( $i == 2 ) { >+ push @second, \%row; >+ } else { >+ push @third, \%row; > } > } > } else { >@@ -223,7 +263,11 @@ for my $data (@categories) { > my $sth2=$dbh->prepare("SELECT * from overduerules WHERE branchcode=? AND categorycode=?"); > $sth2->execute($branch,$data->{'categorycode'}); > my $dat=$sth2->fetchrow_hashref; >- for (my $i=1;$i<=3;$i++){ >+ for my $i ( 1..3 ){ >+ my %row = ( >+ overduename => $data->{'categorycode'}, >+ line => $data->{'description'} >+ ); > if ($countletters){ > my @letterloop; > foreach my $thisletter (sort { $letters->{$a} cmp $letters->{$b} } keys %$letters) { >@@ -237,19 +281,57 @@ for my $data (@categories) { > ); > push @letterloop, \%letterrow; > } >- $row{"letterloop$i"}=\@letterloop; >+ $row{letterloop}=\@letterloop; > } else { >- $row{"noletter"}=1; >- if ($dat->{"letter$i"}){$row{"letter$i"}=$dat->{"letter$i"};} >+ $row{noletter}=1; >+ if ($dat->{"letter$i"}){$row{letter}=$dat->{"letter$i"};} >+ } >+ if ($dat->{"delay$i"}){$row{delay}=$dat->{"delay$i"};} >+ if ($dat->{"debarred$i"}){$row{debarred}=$dat->{"debarred$i"};} >+ my @selected_mtts = @{ GetOverdueMessageTransportTypes( $branch, $data->{'categorycode'}, $i) }; >+ my @mtts; >+ for my $mtt ( @$message_transport_types ) { >+ push @mtts, { >+ value => $mtt->{message_transport_type}, >+ selected => ( grep {$mtt->{message_transport_type} eq $_} @selected_mtts ) ? 1 : 0 , >+ } > } >- if ($dat->{"delay$i"}){$row{"delay$i"}=$dat->{"delay$i"};} >- if ($dat->{"debarred$i"}){$row{"debarred$i"}=$dat->{"debarred$i"};} >+ $row{message_transport_types} = \@mtts; >+ if ( $i == 1 ) { >+ push @first, \%row; >+ } elsif ( $i == 2 ) { >+ push @second, \%row; >+ } else { >+ push @third, \%row; >+ } >+ > } > } >- push @line_loop,\%row; > } > >-$template->param(table=> \@line_loop, >- branchloop => $branchloop, >- branch => $branch); >+my @tabs = ( >+ { >+ id => 'first', >+ number => 1, >+ values => \@first, >+ }, >+ { >+ id => 'second', >+ number => 2, >+ values => \@second, >+ }, >+ { >+ id => 'third', >+ number => 3, >+ values => \@third, >+ }, >+); >+ >+$template->param( >+ table => ( @first or @second or @third ? 1 : 0 ), >+ branchloop => $branchloop, >+ branch => $branch, >+ tabs => \@tabs, >+ message_transport_types => $message_transport_types, >+); > output_html_with_http_headers $input, $cookie, $template->output; >-- >1.7.10.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 9016
:
13276
|
20814
|
20815
|
20816
|
20916
|
21164
|
21165
|
21166
|
21167
|
21636
|
21637
|
21638
|
21639
|
22814
|
23272
|
23273
|
23289
|
23290
|
23291
|
23292
|
23293
|
23562
|
23955
|
23956
|
23957
|
23958
|
23959
|
23960
|
24571
|
24572
|
24573
|
24574
|
24575
|
24576
|
25006
|
25123
|
25124
|
25125
|
25126
|
25127
|
25128
|
25129
|
25130
|
25415
|
25416
|
25417
|
25418
|
25419
|
25420
|
25421
|
25422
|
25606
|
25899
|
26182
|
26209
|
26210
|
26211
|
26216
|
26226
|
26233
|
26648
|
26649
|
26650
|
26656
|
26657
|
26658
|
26659
|
26660
|
26661
|
26662
|
26663
|
26664
|
26665
|
26666
|
26667
|
26668
|
26670
|
26672
|
26673
|
27794
|
27795
|
27796
|
27797
|
27798
|
27799
|
27800
|
27801
|
27802
|
27803
|
27804
|
27805
|
27806
|
27807
|
27808
|
27809