Bugzilla – Attachment 70302 Details for
Bug 17981
Add the ability to preview generated notice templates
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 17981: Add a preview mode for notice templates
Bug-17981-Add-a-preview-mode-for-notice-templates.patch (text/plain), 24.69 KB, created by
Jonathan Druart
on 2018-01-05 16:03:46 UTC
(
hide
)
Description:
Bug 17981: Add a preview mode for notice templates
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2018-01-05 16:03:46 UTC
Size:
24.69 KB
patch
obsolete
>From ef3e8a47271fbcee08cb38fc26cece27acdc6fbf Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Tue, 24 Jan 2017 13:31:30 +0100 >Subject: [PATCH] Bug 17981: Add a preview mode for notice templates > >This patch is a first step to provide a preview mode for notice >templates. > >CHECKIN, CHECKOUT and HOLD_SLIP are supported so far. >Maybe more, but I have not tested yet and the interface will not allow >you to generate the preview. > >The idea is to provide an idea of how will render the messages generated >from a notice template. > >A new "Preview" button is added close to each textarea on the editing >notice templates view. >For each notice template code (letter_code), we will need some input >data to produce the preview. > >For instance, for CHECKIN we need an barcode. From the barcode we >can guess all the other data. >For CHECKOUT we will need the borrowernumber and the barcode. >Note that the way to enter the data for the preview is not really >user-friendly, for CHECKOUT you will have to fill >'borrowernumber|barcode', but the placeholder will help you to know how >and what to fill. >In the modal window, you will see 4 blocks: >1/ the content of the letter (with the placeholds << >>) >2/ the generated message (with the data filled) >3/ if the letter contained historical syntax markers, the screen will >try to generate a notice template using the TT syntax >4/ the generated message from this TT syntax >=> You will be able to compare the 2 generated messages. > >What is the goal of this first patchset: >- Show this first POC and get feedback from other developpers >- Add a way to easily visualise the differences between the 2 syntaxes >- Confort users with the TT syntax and the migration step from the >historical syntax. > >I'd like to get opinions before going further. > >The possibilities: >- Mock data to get fully working generated messages for any notice >templates. For instance, for CHECKIN and CHECKOUT, the item is not >checked in/out yet. So we cannot access the issue's information. >(I have no idea how to do that) >- Browse the data to get the ones we want to use for the preview (big). > >Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> >--- > C4/Letters.pm | 2 +- > .../intranet-tmpl/prog/en/modules/tools/letter.tt | 101 ++++++++- > .../prog/en/modules/tools/preview_letter.tt | 52 +++++ > svc/letters/preview | 248 +++++++++++++++++++++ > tools/letter.pl | 4 + > 5 files changed, 400 insertions(+), 7 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/preview_letter.tt > create mode 100644 svc/letters/preview > >diff --git a/C4/Letters.pm b/C4/Letters.pm >index 355f7b5f8c..b90fba9724 100644 >--- a/C4/Letters.pm >+++ b/C4/Letters.pm >@@ -881,7 +881,7 @@ sub _parseletter { > my $values = $values_in ? { %$values_in } : {}; > > if ( $table eq 'borrowers' && $values->{'dateexpiry'} ){ >- $values->{'dateexpiry'} = format_sqldatetime( $values->{'dateexpiry'} ); >+ $values->{'dateexpiry'} = output_pref({ str => $values->{dateexpiry}, dateonly => 1 }); > } > > if ( $table eq 'reserves' && $values->{'waitingdate'} ) { >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 65aeeded35..70781b61ec 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt >@@ -13,6 +13,24 @@ > > <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › [% IF ( add_form or copy_form) %][% IF ( modify ) %]<a href="/cgi-bin/koha/tools/letter.pl">Notices & Slips</a> › Modify notice[% ELSE %] <a href="/cgi-bin/koha/tools/letter.pl">Notices & Slips</a> › Add notice[% END %][% ELSE %][% IF ( add_validate or copy_validate) %] <a href="/cgi-bin/koha/tools/letter.pl">Notices & Slips</a> › Notice added[% ELSE %][% IF ( delete_confirm ) %] <a href="/cgi-bin/koha/tools/letter.pl">Notices & Slips</a> › Confirm deletion[% ELSE %]Notices & Slips[% END %][% END %][% END %]</div> > >+<div id="preview_template" class="modal in" tabindex="-1" role="dialog" aria-labelledby="preview_template_label" aria-hidden="true"> >+ <div class="modal-dialog modal-lg"> >+ <div class="modal-content"> >+ <div class="modal-header"> >+ <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >+ <h3 id="preview_template_label">Preview notice template</h3> >+ </div> >+ <div class="modal-body"> >+ <div id="loading"> <img src="[% interface %]/[% theme %]/img/spinner-small.gif" alt="" /> Loading </div> >+ </div> >+ <div class="modal-footer"> >+ <!-- TODO <a href="#" class="btn btn-default" id="preview_template_button" role="button" data-toggle="modal">Convert using the Template Toolkit syntax</a>--> >+ <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button> >+ </div> >+ </div> >+ </div> >+</div> >+ > [% IF add_form or copy_form %]<div id="doc" class="yui-t7">[% ELSE %]<div id="doc3" class="yui-t2">[% END %] > > <div id="bd"> >@@ -240,6 +258,21 @@ > <input type="text" id="name" name="name" size="60" value="[% letter_name %]" required="required" /> > <span class="required">Required</span> > </li> >+ [% IF code and preview_is_available%] >+ <li> >+ <label for="name">Data for preview:</label> >+ [% SWITCH code %] >+ [% CASE 'CHECKIN' %] >+ <input type="text" id="data_preview" name="data_preview" value="" placeholder="barcode" /> >+ [% CASE 'CHECKOUT' %] >+ <input type="text" id="data_preview" name="data_preview" value="" placeholder="barcode|borrowernumber" /> >+ [% CASE 'HOLD_SLIP' %] >+ <input type="text" id="data_preview" name="data_preview" value="" placeholder="biblionumber|borrowernumber" /> >+ [% CASE %] >+ Not supported yet. >+ [% END %] >+ </li> >+ [% END %] > </ol> > </fieldset> > [% IF Koha.Preference('TranslateNotices') %] >@@ -295,23 +328,23 @@ > <input type="hidden" name="lang" value="[% lang %]" /> > <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" /> >+ <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]_[% lang %]" value="1" checked="checked" /> > [% ELSE %] >- <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]" value="1" /> >+ <input type="checkbox" name="is_html_[% letter.message_transport_type %]" id="is_html_[% letter.message_transport_type %]_[% lang %]" value="1" /> > [% END %] > </li> > <li> >- <label for="title_[% letter.message_transport_type %]">Message subject:</label><input type="text" id="title_[% letter.message_transport_type %]" name="title" size="60" value="[% letter.title %]" /> >+ <label for="title_[% letter.message_transport_type %]_[% lang %]">Message subject:</label><input type="text" id="title_[% letter.message_transport_type %]_[% lang %]" name="title" size="60" value="[% letter.title %]" /> > </li> > <li> >- <label for="SQLfieldname_[% letter.message_transport_type %]">Message body:</label> >+ <label for="SQLfieldname_[% letter.message_transport_type %]_[% lang %]">Message body:</label> > [% IF letter.message_transport_type == 'sms' %] > <span id="sms_counter">[% IF letter.content && letter.content.length > 0 %][% letter.content.length %][% ELSE %]0[% END %]/160 characters</span> > [% END %] > <table> > <tr> > <td> >- <select name="SQLfieldname" id="SQLfieldname_[% letter.message_transport_type %]" multiple="multiple" size="9"> >+ <select name="SQLfieldname" id="SQLfieldname_[% letter.message_transport_type %]_[% lang %]" multiple="multiple" size="9"> > [% FOREACH SQLfieldname IN SQLfieldnames %] > <option value="[% SQLfieldname.value %]">[% SQLfieldname.text %]</option> > [% END %] >@@ -320,10 +353,15 @@ > <td class="actions"> > <button type="button" data-containerid="[% letter.message_transport_type %]_[% lang %]" class="btn btn-default btn-sm insert">Insert <i class="fa fa-long-arrow-right"></i></button> > </td> >- <td><textarea name="content" id="content_[% letter.message_transport_type %]" cols="80" rows="15">[% letter.content %]</textarea></td> >+ <td><textarea name="content" id="content_[% letter.message_transport_type %]_[% lang %]" cols="80" rows="15">[% letter.content %]</textarea></td> > </tr> > </table> > </li> >+ [% IF preview_is_available %] >+ <li> >+ <a href="/cgi-bin/koha/svc/letters/preview" class="preview_template btn btn-default btn-xs" title="Preview this notice template" data-mtt="[% letter.message_transport_type %]" data-lang="[% lang %]"><i class="fa fa-eye"></i> Preview</a> >+ </li> >+ [% END %] > </ol> > </fieldset> > [% END %] >@@ -517,6 +555,57 @@ > $("#submit_form").click(); > }); > >+ $("body").on("click", ".preview_template", function(e){ >+ e.preventDefault(); >+ var mtt = $(this).data("mtt"); >+ var lang = $(this).data("lang"); >+ >+ var code = $("#code").val(); >+ var content = $("#content_"+mtt+"_"+lang).val(); >+ var title = $("#title_"+mtt+"_"+lang).val(); >+ >+ var is_html = $("#is_html_"+mtt+"_"+lang).val(); >+ var page = $(this).attr("href"); >+ var data_preview = $("#data_preview").val(); >+ page += '?code='+encodeURIComponent(code); >+ page += '&title='+encodeURIComponent(title); >+ page += '&content='+encodeURIComponent(content); >+ page += '&data_preview='+encodeURIComponent(data_preview); >+ page += '&is_html='+encodeURIComponent(is_html); >+ $("#preview_template .modal-body").load(page + " div"); >+ $('#preview_template').modal('show'); >+ $("#preview_template_button").attr("href", "/cgi-bin/koha/svc/letters/convert?module="+module+"&code="+code+"&mtt="+mtt+"&lang="+lang); >+ }); >+ $("#preview_template").on("hidden", function(){ >+ $("#preview_template_label").html(""); >+ $("#preview_template .modal-body").html("<div id=\"loading\"><img src=\"[% interface %]/[% theme %]/img/spinner-small.gif\" alt=\"\" /> "+_("Loading")+"</div>"); >+ }); >+ $("body").on("click", "#convert_template", function(e){ >+ e.preventDefault(); >+ var mtt = $(this).data("mtt"); >+ var lang = $(this).data("lang"); >+ >+ var code = $("#code").val(); >+ var content = $("#content_"+mtt+"_"+lang).val(); >+ var title = $("#title_"+mtt+"_"+lang).val(); >+ >+ var is_html = $("#is_html_"+mtt+"_"+lang).val(); >+ var page = $(this).attr("href"); >+ var data_preview = $("#data_preview").val(); >+ page += '?code='+encodeURIComponent(code); >+ page += '&title='+encodeURIComponent(title); >+ page += '&content='+encodeURIComponent(content); >+ page += '&data_preview='+encodeURIComponent(data_preview); >+ page += '&is_html='+encodeURIComponent(is_html); >+ $("#preview_template .modal-body").load(page + " div"); >+ $('#preview_template').modal('show'); >+ $("#preview_template_button").attr("href", "/cgi-bin/koha/svc/letters/convert?module="+module+"&code="+code+"&branchcode="+branchcode+"&mtt="+mtt+"&lang="+lang); >+ }); >+ $("#convert_template").on("hidden", function(){ >+ $("#convert_template_label").html(""); >+ $("#convert_template .modal-body").html("<div id=\"loading\"><img src=\"[% interface %]/[% theme %]/img/spinner-small.gif\" alt=\"\" /> "+_("Loading")+"</div>"); >+ }); >+ > }); > [% IF add_form or copy_form %] > function cancel(f) { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/preview_letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/preview_letter.tt >new file mode 100644 >index 0000000000..f7aea70676 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/preview_letter.tt >@@ -0,0 +1,52 @@ >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Tools › Preview notice template</title> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> >+ </head> >+ <body id="preview_letter" class="catalog"> >+ <div id="main"> >+ [% FOR m IN messages %] >+ [%# FIXME The message block does not appear at the top of the modal! %] >+ <div class="dialog [% m.type %]"> >+ [% SWITCH m.code %] >+ [% CASE 'no_data_for_preview' %]You did not specify data for preview. >+ [% CASE 'preview_not_available' %]Preview is not available for letters '[% m.letter_code %]'. >+ [% CASE 'not_checked_in_yet' %]Do not forget that the issue has not been checked in yet. >+ [% CASE 'not_checked_out_yet' %]Do not forget that the issue has not been checked out yet. >+ [% CASE %][% m.code %] >+ [% END %] >+ </div> >+ [% END %] >+ [% IF rendered_message %] >+ <fieldset class="brief"> >+ <legend>Original version</legend> >+ <pre>[% original_content | html %]</pre> >+ </fieldset> >+ >+ <fieldset class="brief"> >+ <legend>Rendered message:</legend> >+ <pre>[% rendered_message.content | html %]</pre> >+ </fieldset> >+ [% END %] >+ >+ [% IF tt_content %] >+ <fieldset class="brief"> >+ <legend>Converted version</legend> >+ <pre>[% tt_content | html %]</pre> >+ </fieldset> >+ >+ <fieldset class="brief"> >+ <legend>Rendered message:</legend> >+ <pre>[% rendered_tt_message.content | html %]</pre> >+ </fieldset> >+ [% END %] >+ </div> >+ >+ [% IF tt_content %] >+ [% IF messages_are_similar %] >+ <div class="dialog message">The generated notices are exactly the same!</div> >+ [% ELSE %] >+ <div class="dialog alert">The generated notices are different!</div> >+ [% END %] >+ [% END %] >+ </body> >+</html> >diff --git a/svc/letters/preview b/svc/letters/preview >new file mode 100644 >index 0000000000..d517398bfb >--- /dev/null >+++ b/svc/letters/preview >@@ -0,0 +1,248 @@ >+#!/usr/bin/perl >+ >+# Copyright 2016 Koha Development Team >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw( -utf8 ); >+use C4::Auth; >+use C4::Context; >+use C4::Output; >+use C4::Circulation; >+use C4::Letters; >+use Koha::Checkouts; >+use Koha::Items; >+use Koha::Patrons; >+ >+my $input = new CGI; >+ >+my ( $template, $borrowernumber, $cookie ) = get_template_and_user( >+ { >+ template_name => "tools/preview_letter.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { tools => 'edit_notices' }, >+ debug => 1, >+ } >+); >+ >+my @messages; >+my $code = $input->param('code'); >+my $content = $input->param('content'); >+my $title = $input->param('title'); >+my $is_html = $input->param('is_html'); >+my $data_preview = $input->param('data_preview'); >+ >+unless ( $data_preview ) { >+ $template->param( messages => [{ code => 'no_data_for_preview', type => 'error' }]); >+ output_html_with_http_headers $input, $cookie, $template->output; >+ exit; >+} >+ >+my $fake_letter = { content => $content, title => $title, is_html => $is_html }; >+ >+my ( $tt_content, $fake_tt_letter ); >+if ( $content =~ m/[^\n]*<<.*>>[^\n]*/so ) { >+ $tt_content = $content; >+ >+ my $table_mapping = { >+ biblio => 'biblio', >+ borrowers => 'borrower', >+ branches => 'branch', >+ items => 'item', >+ opac_news => 'news', >+ aqorders => 'orders', >+ reserves => 'hold', >+ serial => 'serial', >+ subscription => 'subscription', >+ suggestions => 'suggestion', >+ issues => 'checkout', >+ old_issues => 'old_checkout', >+ overdues => 'overdue', >+ borrower_modifications => 'patron_modification', >+ }; >+ >+ # Today >+ $tt_content =~ s#<<today>>#[% today| \$KohaDates with_hours => 1 %]#sg; >+ >+ >+ for my $date_field ( qw( >+ borrowers.dateofbirth >+ borrowers.dateenrolled >+ borrowers.dateexpiry >+ borrowers.debarred >+ items.dateaccessioned >+ items.datelastborrowed >+ items.datelastseen >+ items.onloan >+ serials.planneddate >+ serials.publisheddate >+ serials.claimdate >+ reserves.reservedate >+ reserves.waitingdate >+ reserves.expirationdate >+ suggestions.suggesteddate >+ suggestions.manageddate >+ suggestions.accepteddate >+ suggestions.rejecteddate >+ aqorders.entrydate >+ aqorders.datereceived >+ aqorders.datecancellationprinted >+ aqorders.budgetdate >+ aqorders.claimed_date >+ ) ) { >+ my ( $table, $field ) = split '\.', $date_field; >+ my $new_field = >+ exists $table_mapping->{$table} >+ ? $table_mapping->{$table} . ".$field" >+ : "$table.$field"; >+ $tt_content =~ s#<<$table\.$field>>#[% $new_field | \$KohaDates %]#sg; >+ $tt_content =~ s#<<$table\.$field\s*|\s*dateonly>>#[% $new_field | \$KohaDates %]#sg; >+ } >+ >+ for my $datetime_field ( qw( >+ items.itemlost_on >+ items.withdrawn_on >+ issues.date_due >+ issues.returndate >+ issues.lastreneweddate >+ issues.issuedate >+ reserves.suspend_until >+ ) ) { >+ my ( $table, $field ) = split '\.', $datetime_field; >+ my $new_field = >+ exists $table_mapping->{$table} >+ ? $table_mapping->{$table} . ".$field" >+ : "$table.$field"; >+ $tt_content =~ s#<<$table\.$field>>#[% $new_field | \$KohaDates with_hours => 1 %]#sg; >+ $tt_content =~ s#<<$table\.$field\s*|\s*dateonly>>#[% $new_field | \$KohaDates %]#sg; >+ } >+ >+ >+ >+ while ( my ( $key, $value ) = each %$table_mapping ) { >+ $tt_content =~ s|<<$key\.|<<$value.|sg; >+ } >+ >+ $tt_content =~ s|<<|[% |sg; >+ $tt_content =~ s|>>| %]|sg; >+ $fake_tt_letter = >+ { content => $tt_content, title => $title, is_html => $is_html }; >+} >+ >+my ( $rendered_message, $rendered_tt_message ) = (q||) x 2; >+my $messages_are_similar; >+my $letter_params = {}; >+if ( $code eq 'CHECKIN' ) { >+ my $item = Koha::Items->find( { barcode => $data_preview } ); >+ my $checkout = Koha::Checkouts->find( { itemnumber => $item->itemnumber } ); >+ if ($checkout) { >+ my $patron = Koha::Patrons->find( $checkout->borrowernumber ); >+ my $branchcode = >+ C4::Circulation::_GetCircControlBranch( $item->unblessed, >+ $patron->unblessed ); >+ $letter_params = { >+ tables => { >+ issues => $item->itemnumber, >+ items => $item->itemnumber, >+ biblio => $item->biblionumber, >+ biblioitems => $item->biblionumber, >+ issues => $patron->borrowernumber, >+ branches => $branchcode, >+ } >+ }; >+ push @messages, { code => 'not_checked_in_yet', type => 'message' }; >+ } >+ else { >+ warn "No checkout"; >+ } >+} >+elsif ( $code eq 'CHECKOUT' ) { >+ my ( $barcode, $borrowernumber ) = split '\|', $data_preview; >+ my $item = Koha::Items->find( { barcode => $barcode } ); >+ my $patron = Koha::Patrons->find( $borrowernumber ); >+ if ($item and $patron) { >+ my $branchcode = >+ C4::Circulation::_GetCircControlBranch( $item->unblessed, >+ $patron->unblessed ); >+ $letter_params = { >+ tables => { >+ issues => $item->itemnumber, >+ items => $item->itemnumber, >+ biblio => $item->biblionumber, >+ biblioitems => $item->biblionumber, >+ issues => $patron->borrowernumber, >+ branches => $branchcode, >+ } >+ }; >+ push @messages, { code => 'not_checked_out_yet', type => 'message' }; >+ } >+ else { >+ warn "No item or no patron"; >+ } >+} >+elsif ( $code eq 'HOLD_SLIP' ) { >+ my ( $biblionumber, $borrowernumber ) = split '\|', $data_preview; >+ my $hold = Koha::Holds->find( { borrowernumber => $borrowernumber, biblionumber => $biblionumber } ); >+ if ($hold) { >+ $letter_params = { >+ tables => { >+ reserves => $hold->unblessed, >+ branches => $hold->branchcode, >+ borrowers => $hold->borrowernumber, >+ biblio => $hold->biblionumber, >+ biblioitems => $hold->biblionumber, >+ items => $hold->itemnumber, >+ } >+ }; >+ } >+ else { >+ warn "No hold placed by this patron on this bibliographic record."; >+ } >+} >+else { >+ warn "Preview for letter code $code is not available"; >+ push @messages, { type => 'alert', code => 'preview_not_available', letter_code => $code, }; >+} >+ >+if ( %$letter_params ) { >+ # FIXME Be case here GetPreparedLetter modify $fake_letter >+ $rendered_message = C4::Letters::GetPreparedLetter( >+ letter => $fake_letter, >+ %$letter_params, >+ ); >+ if ($tt_content) { >+ $rendered_tt_message = C4::Letters::GetPreparedLetter( >+ letter => $fake_tt_letter, >+ %$letter_params, >+ ); >+ } >+ $messages_are_similar = >+ $rendered_message->{content} eq $rendered_tt_message->{content}; >+} >+ >+$template->param( >+ original_content => $content, >+ rendered_message => $rendered_message, >+ tt_content => $tt_content, >+ rendered_tt_message => $rendered_tt_message, >+ messages_are_similar => $messages_are_similar, >+ messages => \@messages, >+); >+ >+output_html_with_http_headers $input, $cookie, $template->output; >diff --git a/tools/letter.pl b/tools/letter.pl >index 922207958a..04f98e6f90 100755 >--- a/tools/letter.pl >+++ b/tools/letter.pl >@@ -268,10 +268,14 @@ sub add_form { > } > } > >+ my $preview_is_available = grep {/^$code$/} qw( >+ CHECKIN CHECKOUT HOLD_SLIP >+ ); > $template->param( > module => $module, > SQLfieldnames => $field_selection, > branchcode => $branchcode, >+ preview_is_available => $preview_is_available, > ); > return; > } >-- >2.11.0
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 17981
:
59508
|
59509
|
59510
|
59514
|
59524
|
63978
|
63979
|
63980
|
63981
|
63982
|
65688
|
65689
|
65690
|
65701
|
65702
|
65703
|
65704
|
65705
|
67144
|
67145
|
67146
|
67147
|
67148
|
67152
|
70300
|
70301
|
70302
|
70303
|
70304
|
70305
|
73201
|
73202
|
73203
|
73204
|
73205
|
73206
|
73949
|
73950
|
73951
|
73952
|
74025
|
74027
|
74028
|
74029
|
74030
|
74031
|
74032
|
74033
|
74034