View | Details | Raw Unified | Return to bug 40932
Collapse All | Expand All

(-)a/C4/Circulation.pm (+34 lines)
Lines 98-103 use Algorithm::CheckDigits qw( CheckDigits ); Link Here
98
98
99
use Data::Dumper qw( Dumper );
99
use Data::Dumper qw( Dumper );
100
use Koha::Account;
100
use Koha::Account;
101
use Koha::Acquisition::OrderItems;
101
use Koha::AuthorisedValues;
102
use Koha::AuthorisedValues;
102
use Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue;
103
use Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue;
103
use Koha::Biblioitems;
104
use Koha::Biblioitems;
Lines 2784-2789 sub AddReturn { Link Here
2784
    my $indexer = Koha::SearchEngine::Indexer->new( { index => $Koha::SearchEngine::BIBLIOS_INDEX } );
2785
    my $indexer = Koha::SearchEngine::Indexer->new( { index => $Koha::SearchEngine::BIBLIOS_INDEX } );
2785
    $indexer->index_records( $item->biblionumber, "specialUpdate", "biblioserver" );
2786
    $indexer->index_records( $item->biblionumber, "specialUpdate", "biblioserver" );
2786
2787
2788
    # Record physical receipt for acquisitions items on successful return
2789
    _record_physical_receipt( $item->itemnumber ) if $doreturn;
2790
2787
    if ( $doreturn and $issue ) {
2791
    if ( $doreturn and $issue ) {
2788
        my $checkin = Koha::Old::Checkouts->find( $issue->id );
2792
        my $checkin = Koha::Old::Checkouts->find( $issue->id );
2789
2793
Lines 5061-5066 sub _CanBookBeAutoRenewed { Link Here
5061
    return "ok";
5065
    return "ok";
5062
}
5066
}
5063
5067
5068
=head2 _record_physical_receipt
5069
5070
    _record_physical_receipt($itemnumber);
5071
5072
Called on circulation check-in. If the item is linked to an acquisitions order
5073
on an open invoice, stamps aqorders_items.received with the current datetime
5074
(first check-in only). Then attempts to auto-close the invoice if the
5075
AutoCloseInvoicesOnCheckin preference is enabled.
5076
5077
=cut
5078
5079
sub _record_physical_receipt {
5080
    my ($itemnumber) = @_;
5081
5082
    my $order_item = Koha::Acquisition::OrderItems->find( { itemnumber => $itemnumber } );
5083
    return unless $order_item;
5084
5085
    my $order = $order_item->order;
5086
    return unless $order && $order->orderstatus ne 'cancelled';
5087
5088
    my $invoice = $order->invoice;
5089
    return unless $invoice;
5090
5091
    # Stamp received if not already set (first check-in only)
5092
    $order_item->update( { received => \'NOW()' } ) unless $order_item->received;
5093
5094
    # Attempt auto-close if preference is enabled
5095
    $invoice->check_and_close if C4::Context->preference('AutoCloseInvoicesOnCheckin');
5096
}
5097
5064
1;
5098
1;
5065
5099
5066
__END__
5100
__END__
(-)a/C4/UsageStats.pm (-1 / +3 lines)
Lines 121-128 sub _shared_preferences { Link Here
121
121
122
    my @preferences = qw/
122
    my @preferences = qw/
123
        AcqCreateItem
123
        AcqCreateItem
124
        AcqWarnOnDuplicateInvoice
125
        AcqViewBaskets
124
        AcqViewBaskets
125
        AcqWarnOnDuplicateInvoice
126
        AutoCloseInvoiceAlertDays
127
        AutoCloseInvoicesOnCheckin
126
        BasketConfirmations
128
        BasketConfirmations
127
        OrderPdfFormat
129
        OrderPdfFormat
128
        casAuthentication
130
        casAuthentication
(-)a/Koha/Acquisition/Invoice.pm (-1 / +47 lines)
Lines 17-23 package Koha::Acquisition::Invoice; Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Koha::Database;
20
use Koha::Acquisition::OrderItems;
21
use Koha::Acquisition::Orders;
22
use Koha::DateUtils qw( dt_from_string );
21
23
22
use base qw(Koha::Object Koha::Object::Mixin::AdditionalFields);
24
use base qw(Koha::Object Koha::Object::Mixin::AdditionalFields);
23
25
Lines 73-78 sub to_api_mapping { Link Here
73
    };
75
    };
74
}
76
}
75
77
78
=head3 orders
79
80
    my $orders = $invoice->orders;
81
82
Returns a I<Koha::Acquisition::Orders> resultset for the orders associated
83
to this invoice.
84
85
=cut
86
87
sub orders {
88
    my ($self) = @_;
89
    my $orders_rs = $self->_result->aqorders;
90
    return Koha::Acquisition::Orders->_new_from_dbic($orders_rs);
91
}
92
93
=head3 check_and_close
94
95
    my $closed = $invoice->check_and_close;
96
97
Closes the invoice if all items on non-cancelled order lines have been
98
physically received (aqorders_items.received IS NOT NULL).
99
100
Returns 1 if the invoice was closed, 0 otherwise.
101
Does nothing if the invoice is already closed or has no linked items.
102
103
=cut
104
105
sub check_and_close {
106
    my ($self) = @_;
107
108
    return 0 if $self->closedate;
109
110
    my @active_order_numbers =
111
        $self->orders->search( { orderstatus => { '!=' => 'cancelled' } } )->get_column('ordernumber');
112
113
    my $order_items = Koha::Acquisition::OrderItems->search( { ordernumber => \@active_order_numbers } );
114
115
    return 0 unless $order_items->count;
116
    return 0 if $order_items->search( { received => undef } )->count;
117
118
    $self->update( { closedate => dt_from_string()->ymd } );
119
    return 1;
120
}
121
76
=head2 Internal methods
122
=head2 Internal methods
77
123
78
=head3 _type
124
=head3 _type
(-)a/Koha/Acquisition/OrderItem.pm (+57 lines)
Line 0 Link Here
1
package Koha::Acquisition::OrderItem;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Koha::Acquisition::Orders;
21
22
use base qw(Koha::Object);
23
24
=head1 NAME
25
26
Koha::Acquisition::OrderItem - Koha OrderItem Object class
27
28
=head1 API
29
30
=head2 Class methods
31
32
=head3 order
33
34
    my $order = $order_item->order;
35
36
Returns the I<Koha::Acquisition::Order> object for the order associated to this item.
37
38
=cut
39
40
sub order {
41
    my ($self) = @_;
42
    my $order_rs = $self->_result->ordernumber;
43
    return unless $order_rs;
44
    return Koha::Acquisition::Order->_new_from_dbic($order_rs);
45
}
46
47
=head2 Internal methods
48
49
=head3 _type
50
51
=cut
52
53
sub _type {
54
    return 'AqordersItem';
55
}
56
57
1;
(-)a/Koha/Acquisition/OrderItems.pm (+48 lines)
Line 0 Link Here
1
package Koha::Acquisition::OrderItems;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Koha::Acquisition::OrderItem;
21
22
use base qw(Koha::Objects);
23
24
=head1 NAME
25
26
Koha::Acquisition::OrderItems - Koha OrderItem Object set class
27
28
=head1 API
29
30
=head2 Internal methods
31
32
=head3 _type
33
34
=cut
35
36
sub _type {
37
    return 'AqordersItem';
38
}
39
40
=head3 object_class
41
42
=cut
43
44
sub object_class {
45
    return 'Koha::Acquisition::OrderItem';
46
}
47
48
1;
(-)a/acqui/close-completed-invoices.pl (+54 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <https://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use CGI        qw( -utf8 );
21
use C4::Auth   qw( get_template_and_user );
22
use C4::Output qw( output_html_with_http_headers );
23
24
use Koha::Acquisition::Invoices;
25
26
my $input = CGI->new;
27
my $op    = $input->param('op') // q{};
28
29
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
30
    {
31
        template_name => 'acqui/close-completed-invoices.tt',
32
        query         => $input,
33
        type          => 'intranet',
34
        flagsrequired => { acquisition => 'order_manage' },
35
    }
36
);
37
38
my @results;
39
40
if ( $op eq 'cud-run' ) {
41
    my $open_invoices = Koha::Acquisition::Invoices->search( { closedate => undef } );
42
43
    while ( my $invoice = $open_invoices->next ) {
44
        my $closed = $invoice->check_and_close;
45
        push @results, {
46
            invoiceid     => $invoice->invoiceid,
47
            invoicenumber => $invoice->invoicenumber,
48
            closed        => $closed,
49
        };
50
    }
51
    $template->param( results => \@results, ran => 1 );
52
}
53
54
output_html_with_http_headers( $input, $cookie, $template->output );
(-)a/acqui/invoice.pl (+12 lines)
Lines 243-248 if ( $op && $op eq 'cud-close' ) { Link Here
243
            }
243
            }
244
        }
244
        }
245
    }
245
    }
246
} elsif ( $op && $op eq 'cud-check-and-close' ) {
247
248
    output_and_exit( $input, $cookie, $template, 'insufficient_permission' )
249
        unless $logged_in_patron->has_permission( { acquisition => 'edit_invoices' } );
250
251
    if ($invoiceid) {
252
        my $invoice = Koha::Acquisition::Invoices->find($invoiceid);
253
        if ($invoice) {
254
            my $closed = $invoice->check_and_close;
255
            $template->param( check_close_result => $closed ? 'closed' : 'not_ready' );
256
        }
257
    }
246
}
258
}
247
259
248
my $active_currency = Koha::Acquisition::Currencies->get_active,
260
my $active_currency = Koha::Acquisition::Currencies->get_active,
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/close-completed-invoices.tt (+102 lines)
Line 0 Link Here
1
[% USE raw %]
2
[% USE Koha %]
3
[% PROCESS 'i18n.inc' %]
4
[% INCLUDE 'doc-head-open.inc' %]
5
<title
6
    >[% FILTER collapse %]
7
        [% t("Close completed invoices") | html %]
8
        &rsaquo; [% t("Acquisitions") | html %] &rsaquo; [% t("Koha") | html %]
9
    [% END %]</title
10
>
11
[% INCLUDE 'doc-head-close.inc' %]
12
</head>
13
14
<body id="acq_close_completed_invoices" class="acq">
15
[% WRAPPER 'header.inc' %]
16
    [% INCLUDE 'acquisitions-search.inc' %]
17
[% END %]
18
19
[% WRAPPER 'sub-header.inc' %]
20
    [% WRAPPER breadcrumbs %]
21
        [% WRAPPER breadcrumb_item %]
22
            <a href="/cgi-bin/koha/acqui/acqui-home.pl">Acquisitions</a>
23
        [% END %]
24
        [% WRAPPER breadcrumb_item bc_active= 1 %]
25
            <span>Close completed invoices</span>
26
        [% END %]
27
    [% END #/ WRAPPER breadcrumbs %]
28
[% END #/ WRAPPER sub-header.inc %]
29
30
<div class="main container-fluid">
31
    <div class="row">
32
        <div class="col-md-10 order-md-2 order-sm-2">
33
            <main>
34
                [% INCLUDE 'messages.inc' %]
35
36
                <h1>Close completed invoices</h1>
37
38
                <p> This tool checks all open invoices and closes any where every item has been physically received (checked in at circulation). Items on cancelled order lines are excluded from the check. </p>
39
40
                [% IF ran %]
41
                    [% SET closed_count = 0 %]
42
                    [% FOREACH r IN results %][% IF r.closed %][% SET closed_count = closed_count + 1 %][% END %][% END %]
43
44
                    [% IF closed_count %]
45
                        <div class="dialog message"> [% closed_count | html %] invoice[% IF closed_count != 1 %]s[% END %] closed successfully. </div>
46
                    [% ELSE %]
47
                        <div class="dialog alert"> No invoices were closed. Either all open invoices still have outstanding items, or there are no open invoices with items. </div>
48
                    [% END %]
49
50
                    [% IF results.size %]
51
                        <table class="table table-bordered table-striped">
52
                            <thead>
53
                                <tr>
54
                                    <th>Invoice ID</th>
55
                                    <th>Invoice number</th>
56
                                    <th>Result</th>
57
                                </tr>
58
                            </thead>
59
                            <tbody>
60
                                [% FOREACH r IN results %]
61
                                    <tr>
62
                                        <td>
63
                                            <a href="/cgi-bin/koha/acqui/invoice.pl?invoiceid=[% r.invoiceid | uri %]"> [% r.invoiceid | html %] </a>
64
                                        </td>
65
                                        <td>[% r.invoicenumber | html %]</td>
66
                                        <td>
67
                                            [% IF r.closed %]
68
                                                <span class="text-success">Closed</span>
69
                                            [% ELSE %]
70
                                                <span class="text-muted">Still open (items outstanding)</span>
71
                                            [% END %]
72
                                        </td>
73
                                    </tr>
74
                                [% END %]
75
                            </tbody>
76
                        </table>
77
                    [% END %]
78
79
                    <p><a href="/cgi-bin/koha/acqui/close-completed-invoices.pl" class="btn btn-default">Run again</a></p>
80
                [% ELSE %]
81
                    <form method="post" action="/cgi-bin/koha/acqui/close-completed-invoices.pl">
82
                        [% INCLUDE 'csrf-token.inc' %]
83
                        <input type="hidden" name="op" value="cud-run" />
84
                        <fieldset class="action">
85
                            <button type="submit" class="btn btn-primary">
86
                                <i class="fa fa-check-circle"></i>
87
                                Close all completed invoices
88
                            </button>
89
                            <a href="/cgi-bin/koha/acqui/acqui-home.pl" class="cancel">Cancel</a>
90
                        </fieldset>
91
                    </form>
92
                [% END %]
93
            </main>
94
        </div>
95
96
        <div class="col-md-2 order-md-2 order-sm-1">
97
            <aside> [% INCLUDE 'acquisitions-menu.inc' %] </aside>
98
        </div>
99
    </div>
100
</div>
101
102
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt (+20 lines)
Lines 156-161 Link Here
156
                        </li>
156
                        </li>
157
                    [% END %]
157
                    [% END %]
158
                [% END # /IF ( invoiceclosedate ) %]
158
                [% END # /IF ( invoiceclosedate ) %]
159
                [% IF !invoiceclosedate && CAN_user_acquisition_edit_invoices && !readonly %]
160
                    <li>
161
                        <span class="label">&nbsp;</span>
162
                        <form method="post" action="/cgi-bin/koha/acqui/invoice.pl" style="display:inline">
163
                            [% INCLUDE 'csrf-token.inc' %]
164
                            <input type="hidden" name="op" value="cud-check-and-close" />
165
                            <input type="hidden" name="invoiceid" value="[% invoiceid | html %]" />
166
                            <button type="submit" class="btn btn-default btn-sm">
167
                                <i class="fa fa-check-circle"></i>
168
                                Check &amp; close if all items received
169
                            </button>
170
                        </form>
171
                    </li>
172
                    [% IF check_close_result == 'not_ready' %]
173
                        <li>
174
                            <span class="label">&nbsp;</span>
175
                            <div class="dialog alert"> Not all items on this invoice have been checked in yet. The invoice remains open. </div>
176
                        </li>
177
                    [% END %]
178
                [% END %]
159
            </ol>
179
            </ol>
160
180
161
            [% IF available_additional_fields.count %]
181
            [% IF available_additional_fields.count %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref (+13 lines)
Lines 146-151 Acquisitions: Link Here
146
                1: Enable
146
                1: Enable
147
                0:  Disable
147
                0:  Disable
148
            - automatic order line creation from MARC records.
148
            - automatic order line creation from MARC records.
149
    Invoice automation:
150
        -
151
            - pref: AutoCloseInvoicesOnCheckin
152
              default: no
153
              choices:
154
                1: Enable
155
                0: Disable
156
            - automatically closing invoices when all their items have been physically checked in at circulation.
157
        -
158
            - Show a staff client alert for open invoices with items not yet checked in for more than
159
            - pref: AutoCloseInvoiceAlertDays
160
              class: integer
161
            - "days (set to 0 to disable)."
149
    Printing:
162
    Printing:
150
        -
163
        -
151
            - Use the
164
            - Use the
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt (-1 / +11 lines)
Lines 186-192 Link Here
186
            <div class="row">
186
            <div class="row">
187
                <div class="col-sm-12">
187
                <div class="col-sm-12">
188
                    [%# Following statement must be in one line for translatability %]
188
                    [%# Following statement must be in one line for translatability %]
189
                    [% IF ( CAN_user_tools_moderate_comments  && pendingcomments ) || ( CAN_user_tools_moderate_tags && pendingtags ) || ( CAN_user_borrowers_edit_borrowers && pending_borrower_modifications ) || ( CAN_user_suggestions_suggestions_manage && ( pendingsuggestions || all_pendingsuggestions )) || ( CAN_user_borrowers_edit_borrowers && pending_discharge_requests ) || pending_article_requests || ( Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes.count ) || ( ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && pending_biblio_tickets && CAN_user_editcatalogue_edit_catalogue ) || ( Koha.Preference('OPACReportProblem') && CAN_user_problem_reports && pending_problem_reports.count ) || already_ran_jobs || new_curbside_pickups.count || ( holds_with_cancellation_requests && CAN_user_circulate_circulate_remaining_permissions ) || ( CAN_user_borrowers_edit_borrowers && self_registered_count ) || ( CAN_user_borrowers_list_borrowers && self_registered_count ) %]
189
                    [% IF ( CAN_user_tools_moderate_comments  && pendingcomments ) || ( CAN_user_tools_moderate_tags && pendingtags ) || ( CAN_user_borrowers_edit_borrowers && pending_borrower_modifications ) || ( CAN_user_suggestions_suggestions_manage && ( pendingsuggestions || all_pendingsuggestions )) || ( CAN_user_borrowers_edit_borrowers && pending_discharge_requests ) || pending_article_requests || ( Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes.count ) || ( ( Koha.Preference('OpacCatalogConcerns') || Koha.Preference('CatalogConcerns') ) && pending_biblio_tickets && CAN_user_editcatalogue_edit_catalogue ) || ( Koha.Preference('OPACReportProblem') && CAN_user_problem_reports && pending_problem_reports.count ) || already_ran_jobs || new_curbside_pickups.count || ( holds_with_cancellation_requests && CAN_user_circulate_circulate_remaining_permissions ) || ( CAN_user_borrowers_edit_borrowers && self_registered_count ) || ( CAN_user_borrowers_list_borrowers && self_registered_count ) || ( CAN_user_acquisition_order_manage && overdue_invoice_count ) %]
190
                        <div id="area-pending" class="page-section">
190
                        <div id="area-pending" class="page-section">
191
                            [% IF pending_article_requests %]
191
                            [% IF pending_article_requests %]
192
                                <div class="pending-info" id="article_requests_pending">
192
                                <div class="pending-info" id="article_requests_pending">
Lines 279-284 Link Here
279
                                </div>
279
                                </div>
280
                            [% END %]
280
                            [% END %]
281
281
282
                            [% IF CAN_user_acquisition_order_manage && overdue_invoice_count %]
283
                                <div class="pending-info" id="overdue_invoices_pending">
284
                                    <a href="/cgi-bin/koha/acqui/invoices.pl?closedate_is=open">
285
                                        [% overdue_invoice_count | html %] invoice[% IF overdue_invoice_count != 1 %]s[% END %]
286
                                        [% IF overdue_invoice_count == 1 %]has[% ELSE %]have[% END %]
287
                                        items outstanding for more than [% Koha.Preference('AutoCloseInvoiceAlertDays') | html %] days
288
                                    </a>
289
                                </div>
290
                            [% END %]
291
282
                            [% IF (CAN_user_borrowers_edit_borrowers) || (CAN_user_borrowers_list_borrowers) %]
292
                            [% IF (CAN_user_borrowers_edit_borrowers) || (CAN_user_borrowers_list_borrowers) %]
283
                                [% IF self_registered_count %]
293
                                [% IF self_registered_count %]
284
                                    <div class="pending-info" id="self_registered_patrons_info">
294
                                    <div class="pending-info" id="self_registered_patrons_info">
(-)a/mainpage.pl (-1 / +24 lines)
Lines 34-39 use Koha::BiblioFrameworks; Link Here
34
use Koha::ProblemReports;
34
use Koha::ProblemReports;
35
use Koha::Quotes;
35
use Koha::Quotes;
36
use Koha::Suggestions;
36
use Koha::Suggestions;
37
use Koha::Acquisition::Invoices;
37
use Koha::BackgroundJobs;
38
use Koha::BackgroundJobs;
38
use Koha::CurbsidePickups;
39
use Koha::CurbsidePickups;
39
use Koha::Tickets;
40
use Koha::Tickets;
Lines 162-165 $template->param( Link Here
162
    pending_problem_reports        => $pending_problem_reports,
163
    pending_problem_reports        => $pending_problem_reports,
163
);
164
);
164
165
166
if (   $flags
167
    && $flags->{acquisition}
168
    && C4::Context->preference('AutoCloseInvoiceAlertDays') )
169
{
170
    my $threshold = C4::Context->preference('AutoCloseInvoiceAlertDays');
171
172
    my $overdue_invoice_count = Koha::Acquisition::Invoices->search(
173
        {
174
            'me.closedate'            => undef,
175
            'aqorders.orderstatus'    => { '!=' => 'cancelled' },
176
            'aqorders_items.received' => undef,
177
            'me.shipmentdate'         => { '<' => \[ 'DATE_SUB(NOW(), INTERVAL ? DAY)', $threshold ] },
178
        },
179
        {
180
            join     => { aqorders => 'aqorders_items' },
181
            distinct => 1,
182
        }
183
    )->count;
184
185
    $template->param( overdue_invoice_count => $overdue_invoice_count )
186
        if $overdue_invoice_count;
187
}
188
165
output_html_with_http_headers $query, $cookie, $template->output;
189
output_html_with_http_headers $query, $cookie, $template->output;
166
- 

Return to bug 40932