improve mandatory fields, #9260
[freeside.git] / rt / lib / RT / Interface / Web_Vendor.pm
1 # Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
2 # Copyright (c) 2008 Freeside Internet Services, Inc.
3 #
4 # This work is made available to you under the terms of Version 2 of
5 # the GNU General Public License. A copy of that license should have
6 # been provided with this software, but in any event can be snarfed
7 # from www.gnu.org.
8
9 # This work is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # General Public License for more details.
13
14 =head1 NAME
15
16 RT::Interface::Web_Vendor
17
18 =head1 SYNOPSIS
19
20 =head1 DESCRIPTION
21
22 Freeside vendor overlay for RT::Interface::Web.
23
24 =begin testing
25
26 use_ok(RT::Interface::Web_Vendor);
27
28 =end testing
29
30 =cut
31
32 #package RT::Interface::Web;
33 #use strict;
34
35 package HTML::Mason::Commands;
36 use strict;
37 no warnings qw(redefine);
38
39 =head2 ProcessTicketCustomers 
40
41 =cut
42
43 sub ProcessTicketCustomers {
44     my %args = (
45         TicketObj => undef,
46         ARGSRef   => undef,
47         Debug     => 0,
48         @_
49     );
50     my @results = ();
51
52     my $Ticket  = $args{'TicketObj'};
53     my $ARGSRef = $args{'ARGSRef'};
54     my $Debug   = $args{'Debug'};
55     my $me = 'ProcessTicketCustomers';
56
57     ### false laziness w/RT::Interface::Web::ProcessTicketLinks
58     # Delete links that are gone gone gone.
59     foreach my $arg ( keys %$ARGSRef ) {
60         if ( $arg =~ /DeleteLink-(.*?)-(DependsOn|MemberOf|RefersTo)-(.*)$/ ) {
61             my $base   = $1;
62             my $type   = $2;
63             my $target = $3;
64
65             push @results,
66               "Trying to delete: Base: $base Target: $target  Type $type";
67             my ( $val, $msg ) = $Ticket->DeleteLink( Base   => $base,
68                                                      Type   => $type,
69                                                      Target => $target );
70
71             push @results, $msg;
72
73         }
74
75     }
76     ###
77
78     ###
79     #find new customers
80     ###
81
82     my @custnums = map  { /^Ticket-AddCustomer-(\d+)$/; $1 }
83                    grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} }
84                    keys %$ARGSRef;
85
86     #my @delete_custnums =
87     #  map  { /^Ticket-AddCustomer-(\d+)$/; $1 }
88     #  grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} }
89     #  keys %$ARGSRef;
90
91     ###
92     #figure out if we're going to auto-link requestors, and find them if so
93     ###
94
95     my $num_cur_cust = $Ticket->Customers->Count;
96     my $num_new_cust = scalar(@custnums);
97     warn "$me: $num_cur_cust current customers / $num_new_cust new customers\n"
98       if $Debug;
99
100     #if we're linking the first ticket to one customer
101     my $link_requestors = ( $num_cur_cust == 0 && $num_new_cust == 1 );
102     warn "$me: adding a single customer to a previously customerless".
103          " ticket, so linking customers to requestor too\n"
104       if $Debug && $link_requestors;
105
106     my @Requestors = ();
107     if ( $link_requestors ) {
108
109       #find any requestors without customers
110       @Requestors =
111         grep { ! $_->Customers->Count }
112              @{ $Ticket->Requestors->UserMembersObj->ItemsArrayRef };
113
114       warn "$me: found ". scalar(@Requestors). " requestors without".
115            " customers; linking them\n"
116         if $Debug;
117
118     }
119
120     ###
121     #link ticket (and requestors) to customers
122     ###
123
124     foreach my $custnum ( @custnums ) {
125
126       my @link = ( 'Type'   => 'MemberOf',
127                    'Target' => "freeside://freeside/cust_main/$custnum",
128                  );
129
130       my( $val, $msg ) = $Ticket->AddLink(@link);
131       push @results, $msg;
132
133       #add customer links to requestors
134       foreach my $Requestor ( @Requestors ) {
135         my( $val, $msg ) = $Requestor->AddLink(@link);
136         push @results, $msg;
137         warn "$me: linking requestor to custnum $custnum: $msg\n"
138           if $Debug > 1;
139       }
140
141     }
142
143     return @results;
144
145 }
146
147 #false laziness w/above... eventually it should go away in favor of this
148 sub ProcessObjectCustomers {
149     my %args = (
150         Object => undef,
151         ARGSRef   => undef,
152         @_
153     );
154     my @results = ();
155
156     my $Object  = $args{'Object'};
157     my $ARGSRef = $args{'ARGSRef'};
158
159     ### false laziness w/RT::Interface::Web::ProcessTicketLinks
160     # Delete links that are gone gone gone.
161     foreach my $arg ( keys %$ARGSRef ) {
162         if ( $arg =~ /DeleteLink-(.*?)-(DependsOn|MemberOf|RefersTo)-(.*)$/ ) {
163             my $base   = $1;
164             my $type   = $2;
165             my $target = $3;
166
167             push @results,
168               "Trying to delete: Base: $base Target: $target  Type $type";
169             my ( $val, $msg ) = $Object->DeleteLink( Base   => $base,
170                                                      Type   => $type,
171                                                      Target => $target );
172
173             push @results, $msg;
174
175         }
176
177     }
178     ###
179
180     #my @delete_custnums =
181     #  map  { /^Object-AddCustomer-(\d+)$/; $1 }
182     #  grep { /^Object-AddCustomer-(\d+)$/ && $ARGSRef->{$_} }
183     #  keys %$ARGSRef;
184
185     my @custnums = map  { /^Object-AddCustomer-(\d+)$/; $1 }
186                    grep { /^Object-AddCustomer-(\d+)$/ && $ARGSRef->{$_} }
187                    keys %$ARGSRef;
188
189     foreach my $custnum ( @custnums ) {
190       my( $val, $msg ) =
191         $Object->AddLink( 'Type'   => 'MemberOf',
192                           'Target' => "freeside://freeside/cust_main/$custnum",
193                         );
194       push @results, $msg;
195     }
196
197     return @results;
198
199 }
200
201 =head2 ProcessTicketBasics ( TicketObj => $Ticket, ARGSRef => \%ARGS );
202
203 Updates all core ticket fields except Status, and returns an array of results
204 messages.
205
206 =cut
207
208 sub ProcessTicketBasics {
209
210     my %args = (
211         TicketObj => undef,
212         ARGSRef   => undef,
213         @_
214     );
215
216     my $TicketObj = $args{'TicketObj'};
217     my $ARGSRef   = $args{'ARGSRef'};
218
219     # {{{ Set basic fields
220     my @attribs = qw(
221         Subject
222         FinalPriority
223         Priority
224         TimeEstimated
225         TimeWorked
226         TimeLeft
227         Type
228         Queue
229     );
230
231     if ( $ARGSRef->{'Queue'} and ( $ARGSRef->{'Queue'} !~ /^(\d+)$/ ) ) {
232         my $tempqueue = RT::Queue->new($RT::SystemUser);
233         $tempqueue->Load( $ARGSRef->{'Queue'} );
234         if ( $tempqueue->id ) {
235             $ARGSRef->{'Queue'} = $tempqueue->id;
236         }
237     }
238
239     my @results = UpdateRecordObject(
240         AttributesRef => \@attribs,
241         Object        => $TicketObj,
242         ARGSRef       => $ARGSRef,
243     );
244
245     # We special case owner changing, so we can use ForceOwnerChange
246     if ( $ARGSRef->{'Owner'} && ( $TicketObj->Owner != $ARGSRef->{'Owner'} ) ) {
247         my ($ChownType);
248         if ( $ARGSRef->{'ForceOwnerChange'} ) {
249             $ChownType = "Force";
250         } else {
251             $ChownType = "Give";
252         }
253
254         my ( $val, $msg ) = $TicketObj->SetOwner( $ARGSRef->{'Owner'}, $ChownType );
255         push( @results, $msg );
256     }
257
258     # }}}
259
260     return (@results);
261 }
262
263 =head2 ProcessTicketStatus (TicketObj => RT::Ticket, ARGSRef => {})
264
265 Process updates to the 'Status' field of the ticket.  If the new value 
266 of Status is 'resolved', this will check required custom fields before 
267 allowing the update.
268
269 =cut
270
271 sub ProcessTicketStatus {
272     my %args = (
273         TicketObj => undef,
274         ARGSRef   => undef,
275         @_
276     );
277
278     my $TicketObj = $args{'TicketObj'};
279     my $ARGSRef   = $args{'ARGSRef'};
280     my @results;
281
282     return () if !$ARGSRef->{'Status'};
283
284     if ( lc( $ARGSRef->{'Status'} ) eq 'resolved' ) {
285         foreach my $field ( $TicketObj->MissingRequiredFields ) {
286             push @results, loc('Missing required field: [_1]', $field->Name);
287         }
288     }
289     if ( @results ) {
290         $m->notes('RedirectToBasics' => 1);
291         return @results;
292     }
293
294     return UpdateRecordObject(
295         AttributesRef => [ 'Status' ],
296         Object        => $TicketObj,
297         ARGSRef       => $ARGSRef,
298     );
299 }
300
301 1;
302