1%# BEGIN BPS TAGGED BLOCK {{{
2%#
3%# COPYRIGHT:
4%#
5%# This software is Copyright (c) 1996-2021 Best Practical Solutions, LLC
6%#                                          <sales@bestpractical.com>
7%#
8%# (Except where explicitly superseded by other copyright notices)
9%#
10%#
11%# LICENSE:
12%#
13%# This work is made available to you under the terms of Version 2 of
14%# the GNU General Public License. A copy of that license should have
15%# been provided with this software, but in any event can be snarfed
16%# from www.gnu.org.
17%#
18%# This work is distributed in the hope that it will be useful, but
19%# WITHOUT ANY WARRANTY; without even the implied warranty of
20%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21%# General Public License for more details.
22%#
23%# You should have received a copy of the GNU General Public License
24%# along with this program; if not, write to the Free Software
25%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26%# 02110-1301 or visit their web page on the internet at
27%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28%#
29%#
30%# CONTRIBUTION SUBMISSION POLICY:
31%#
32%# (The following paragraph is not intended to limit the rights granted
33%# to you to modify and distribute this software under the terms of
34%# the GNU General Public License and is only of importance to you if
35%# you choose to contribute your changes and enhancements to the
36%# community by submitting them to Best Practical Solutions, LLC.)
37%#
38%# By intentionally submitting any modifications, corrections or
39%# derivatives to this work, or any other work intended for use with
40%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41%# you are the copyright holder for those contributions and you grant
42%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43%# royalty-free, perpetual, license to use, copy, create derivative
44%# works based on those contributions, and sublicense and distribute
45%# those contributions and any derivatives thereof.
46%#
47%# END BPS TAGGED BLOCK }}}
48<%init>
49$m->abort unless RT->Config->Get('SimplifiedRecipients', $session{'CurrentUser'});
50
51my $TicketObj = RT::Ticket->new($session{CurrentUser});
52$TicketObj->Load($ARGS{id});
53$m->abort unless $TicketObj->id && $ARGS{UpdateType};
54
55if ( $ARGS{UpdateType} eq 'private' ) {
56    $m->abort
57      unless $TicketObj->CurrentUserHasRight( 'CommentOnTicket' ) || $TicketObj->CurrentUserHasRight( 'ModifyTicket' );
58}
59else {
60    $m->abort
61      unless $TicketObj->CurrentUserHasRight( 'ReplyToTicket' ) || $TicketObj->CurrentUserHasRight( 'ModifyTicket' );
62}
63
64my @dryrun = $TicketObj->DryRun(
65    sub {
66        local $ARGS{UpdateContent} ||= "Content";
67        ProcessUpdateMessage(ARGSRef  => \%ARGS, TicketObj => $TicketObj );
68        ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj => $TicketObj );
69        ProcessTicketBasics(  ARGSRef => \%ARGS, TicketObj => $TicketObj );
70        ProcessTicketLinks(   ARGSRef => \%ARGS, TicketObj => $TicketObj );
71        ProcessTicketDates(   ARGSRef => \%ARGS, TicketObj => $TicketObj );
72        ProcessObjectCustomFieldUpdates(ARGSRef => \%ARGS, Object => $TicketObj );
73        ProcessTicketReminders( ARGSRef => \%ARGS, TicketObj => $TicketObj );
74    }
75);
76$m->abort unless @dryrun;
77
78my %headers = (To => {}, Cc => {}, Bcc => {});
79my %no_squelch = (To => {}, Cc => {}, Bcc => {});
80my @scrips = map {@{$_->Scrips->Prepared}} @dryrun;
81if (@scrips) {
82    for my $scrip (grep $_->ActionObj->Action->isa('RT::Action::SendEmail'), @scrips) {
83        my $action = $scrip->ActionObj->Action;
84        for my $type (qw(To Cc Bcc)) {
85            for my $addr ($action->$type()) {
86                if (grep {$addr->address eq $_} @{$action->{NoSquelch}{$type} || []}) {
87                    $no_squelch{$type}{$addr->address} = $addr;
88                } else {
89                    $headers{$type}{$addr->address} = $addr;
90                }
91            }
92        }
93    }
94}
95my %recips;
96my %squelched = ProcessTransactionSquelching( \%ARGS );
97my $squelched_config = !( RT->Config->Get('SquelchedRecipients', $session{'CurrentUser'}) );
98my %submitted;
99$submitted{$_} = 1 for split /,/, $ARGS{TxnRecipients};
100</%init>
101%   if ( scalar(map { keys %{$headers{$_}} } qw(To Cc Bcc)) ) {
102
103<div class="custom-control custom-checkbox">
104  <input class="custom-control-input" type="checkbox" id="TxnSendMailToAll-Simplified" name="TxnSendMailToAll" value="1">
105  <label class="custom-control-label" for="TxnSendMailToAll-Simplified"><b><% loc('All recipients') %></b></label>
106</div>
107% }
108% for my $type (qw(To Cc Bcc)) {
109%     next unless keys %{$headers{$type}} or keys %{$no_squelch{$type}};
110<ul class="list-group list-group-compact">
111  <li class="list-group-item">
112    <div class="form-row">
113      <div class="col-auto">
114        <% $type %>:
115      </div>
116      <div class="col-auto">
117%     for my $addr (sort {$a->address cmp $b->address} values %{$headers{$type}}) {
118%         my $checked = $submitted{$addr->address} ? not $squelched{$addr->address} : $squelched_config;
119%         $m->callback(CallbackName => 'BeforeAddress', Ticket => $TicketObj, Address => $addr, Type => $type, Checked => \$checked);
120%         $recips{$addr->address}++;
121        <div class="custom-control custom-checkbox">
122          <input type="checkbox" name="TxnSendMailTo" <% $checked ? 'checked="checked"' : '' |n%> value="<%$addr->address%>" id="TxnSendMailTo-<% $addr->address %>-<% $recips{$addr->address} %>" class="custom-control-input" />
123          <label class="custom-control-label" for="TxnSendMailTo-<% $addr->address %>-<% $recips{$addr->address} %>"><& /Elements/ShowUser, Address => $addr &></label>
124        </div>
125%         $m->callback(CallbackName => 'AfterAddress', Ticket => $TicketObj, Address => $addr, Type => $type);
126%     }
127%     for my $addr (sort {$a->address cmp $b->address} values %{$no_squelch{$type}}) {
128<div class="col-auto">
129<label><& /Elements/ShowUser, Address => $addr &></label>
130%         if ( $type eq 'Cc' ) {
131(<&|/l&>explicit one-time Cc</&>)
132%         } else {
133(<&|/l&>explicit one-time Bcc</&>)
134%         }
135</div>
136%     }
137      </div>
138    </li>
139  </ul>
140% }
141% $m->callback( CallbackName => 'AfterRecipients', TicketObj => $TicketObj );
142<p>
143<&|/l, RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$TicketObj->Id,
144&>Uncheck boxes to disable notifications to the listed recipients <b>for this transaction only</b>; persistent squelching is managed on the <a href="[_1]">People page</a>.</&>
145</p>
146
147% if (!$TicketObj->CurrentUserHasRight('ShowOutgoingEmail') || $ARGS{'RenderTxnRecipientsInput'}) {
148    <input type="hidden" name="TxnRecipients" value="<% join ",",sort keys %recips %>" />
149% }
150% $m->abort();
151