]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 389835: Various issues when changing several bugs at once - Patch by Frédéric...
authorlpsolit%gmail.com <>
Sat, 28 Jul 2007 05:54:36 +0000 (05:54 +0000)
committerlpsolit%gmail.com <>
Sat, 28 Jul 2007 05:54:36 +0000 (05:54 +0000)
Bugzilla/Bug.pm
Bugzilla/Status.pm
buglist.cgi
process_bug.cgi
template/en/default/global/user-error.html.tmpl
template/en/default/list/edit-multiple.html.tmpl

index de1884b7f8bbc38fc2ae8bdfab92e58f8265f5ac..4793c87da3a926811b24ca6e45308a6e9dc47f09 100755 (executable)
@@ -1899,30 +1899,13 @@ sub bug_alias_to_id {
 # Workflow Control routines
 #####################################################################
 
-# Make sure that the new status is valid for ALL bugs.
+# Make sure that the new status is allowed by the status workflow.
 sub check_status_transition {
-    my ($self, $new_status, $bug_ids) = @_;
-    my $dbh = Bugzilla->dbh;
+    my ($self, $new_status) = @_;
 
-    check_field('bug_status', $new_status);
-    trick_taint($new_status);
-
-    my $illegal_statuses =
-      $dbh->selectcol_arrayref('SELECT DISTINCT bug_status.value
-                                  FROM bug_status
-                            INNER JOIN bugs
-                                    ON bugs.bug_status = bug_status.value
-                                 WHERE bug_id IN (' . join (',', @$bug_ids). ')
-                                   AND bug_status.id NOT IN (SELECT old_status
-                                                               FROM status_workflow
-                                                         INNER JOIN bug_status b_s
-                                                                 ON b_s.id = status_workflow.new_status
-                                                              WHERE b_s.value = ?)',
-                                 undef, $new_status);
-
-    if (scalar(@$illegal_statuses)) {
-        ThrowUserError('illegal_bug_status_transition', {old => $illegal_statuses,
-                                                         new => $new_status})
+    if (!grep { $_->name eq $self->bug_status } @{$new_status->can_change_from}) {
+        ThrowUserError('illegal_bug_status_transition', {old => $self->bug_status,
+                                                         new => $new_status->name})
     }
 }
 
index cf8f98efae628f5c098679e5ebc4c9723123bd0a..9af0f043cbb714638ff5746c1aa9888b8d60b10f 100644 (file)
@@ -93,6 +93,28 @@ sub can_change_to {
     return $self->{'can_change_to'};
 }
 
+sub can_change_from {
+    my $self = shift;
+    my $dbh = Bugzilla->dbh;
+
+    if (!defined $self->{'can_change_from'}) {
+        my $old_status_ids = $dbh->selectcol_arrayref('SELECT old_status
+                                                         FROM status_workflow
+                                                   INNER JOIN bug_status
+                                                           ON id = old_status
+                                                        WHERE isactive = 1
+                                                          AND new_status = ?
+                                                          AND old_status IS NOT NULL',
+                                                        undef, $self->id);
+
+        # Allow the bug status to remain unchanged.
+        push(@$old_status_ids, $self->id);
+        $self->{'can_change_from'} = Bugzilla::Status->new_from_list($old_status_ids);
+    }
+
+    return $self->{'can_change_from'};
+}
+
 sub add_missing_bug_status_transitions {
     my $bug_status = shift || Bugzilla->params->{'duplicate_or_move_bug_status'};
     my $dbh = Bugzilla->dbh;
@@ -161,7 +183,20 @@ below.
 =item C<can_change_to>
 
  Description: Returns the list of active statuses a bug can be changed to
-              given the current bug status.
+              given the current bug status. If this method is called as a
+              class method, then it returns all bug statuses available on
+              bug creation.
+
+ Params:      none.
+
+ Returns:     A list of Bugzilla::Status objects.
+
+=item C<can_change_from>
+
+ Description: Returns the list of active statuses a bug can be changed from
+              given the new bug status. If the bug status is available on
+              bug creation, this method doesn't return this information.
+              You have to call C<can_change_to> instead.
 
  Params:      none.
 
index f9c9875c4c9f8f7704eddbf56ebc309dbcb77013..8aa9249dfadae91b15d57cfcd5d6cbd0e7f2e56f 100755 (executable)
@@ -1099,9 +1099,8 @@ $vars->{'buglist_joined'} = join(',', @bugidlist);
 $vars->{'columns'} = $columns;
 $vars->{'displaycolumns'} = \@displaycolumns;
 
-my @openstates = BUG_STATE_OPEN;
-$vars->{'openstates'} = \@openstates;
-$vars->{'closedstates'} = ['CLOSED', 'VERIFIED', 'RESOLVED'];
+$vars->{'openstates'} = [BUG_STATE_OPEN];
+$vars->{'closedstates'} = [map {$_->name} Bugzilla::Status::closed_bug_statuses()];
 
 # The list of query fields in URL query string format, used when creating
 # URLs to the same query results page with different parameters (such as
index f8b5201b3a13f99ff042ec02804d19aef81c4755..14d6c4ce7c9e916e7e129a1d33b2064e7b21cb6a 100755 (executable)
@@ -814,8 +814,11 @@ my $knob = scalar $cgi->param('knob');
 # Special actions (duplicate, change_resolution and clearresolution) are outside
 # the workflow.
 if (!grep { $knob eq $_ } SPECIAL_STATUS_WORKFLOW_ACTIONS) {
-    Bugzilla::Bug->check_status_transition($knob, \@idlist);
+    # Make sure the bug status exists and is active.
+    check_field('bug_status', $knob);
     my $bug_status = new Bugzilla::Status({name => $knob});
+    $_->check_status_transition($bug_status) foreach @bug_objects;
+
     # Fill the resolution field with the correct value (e.g. in case the
     # workflow allows several open -> closed transitions).
     if ($bug_status->is_open) {
index f7fe1d652c8686dbfbbf0cbbc1b95a84814c46b6..f92399f00baf79d89a4262c2ca9904d8ed100245 100644 (file)
   [% ELSIF error == "illegal_bug_status_transition" %]
     [% title = "Illegal $terms.Bug Status Change" %]
     You are not allowed to change the [% terms.bug %] status from
-    [%+ old.join(", ") FILTER html %] to [%+ new FILTER html %].
+    [%+ old FILTER html %] to [% new FILTER html %].
 
   [% ELSIF error == "illegal_change" %]
     [% title = "Not allowed" %]
index 28e513e7bea0bb5d141eba5187640e05d8e63ca6..0fd2067976780df43b5cc1117d5a2b31a36b3299 100644 (file)
 
 [% END %]
 
-
+[% all_open_bugs = !current_bug_statuses.containsany(closedstates) %]
+[% all_closed_bugs = !current_bug_statuses.containsany(openstates) %]
+[% display_warning = 0 %]
 
 <input id="knob-none" type="radio" name="knob" value="none" checked="checked">
 <label for="knob-none">Do nothing else</label><br>
     <label for="knob_[% bug_status.id FILTER html %]">
       Change status to <b>[% get_status(bug_status.name) FILTER html %]</b>
     </label>
-    [% IF !bug_status.is_open %]
-      and set the resolution to [% PROCESS select_resolution field = "knob_${bug_status.id}" %]
+    [%# Closed bugs cannot have their resolution changed this way. %]
+    [% IF !bug_status.is_open && !all_closed_bugs %]
+      and set the resolution to [% PROCESS select_resolution id = bug_status.id %]
+      [%+ "(*)" UNLESS all_open_bugs %]
+      [% display_warning = 1 UNLESS all_open_bugs %]
     [% END %]
     <br>
 [% END %]
 
 [%# If all the bugs being changed are open, allow the user to clear their resolution. %]
-[% IF !current_bug_statuses.containsany(closedstates) %]
+[% IF all_open_bugs %]
   <input id="knob-clearresolution" type="radio" name="knob" value="clearresolution">
   <label for="knob-clearresolution">Clear the resolution</label><br>
 [% END %]
 
+[%# If all the bugs being changed are closed, allow the user to change their resolution. %]
+[% IF all_closed_bugs %]
+  <input type="radio" id="knob_change_resolution" name="knob" value="change_resolution">
+  <label for="knob_change_resolution">Change resolution to</label>
+  [%+ PROCESS select_resolution id = "change_resolution" %]<br>
+[% END %]
+
+[% IF display_warning %]
+  <p class="box">
+    (*) Note that the resolution will only be applied to open [% terms.bugs %].
+    Already closed [% terms.bugs %] will keep their resolution unchanged.
+  </p>
+[% END %]
+
 <input type="submit" id="commit" value="Commit">
 
 [% IF Param('move-enabled') && user.is_mover %]
 [% END %]
 
 [% BLOCK select_resolution %]
-  <select name="resolution"
-          onchange="document.forms['changeform'].[% field FILTER html %].checked=true">
+  <select id="resolution_knob_[% id FILTER html %]" name="resolution_knob_[% id FILTER html %]"
+          onchange="document.forms['changeform'].[% "knob_$id" FILTER html %].checked=true">
     [% FOREACH r = resolutions %]
       [% NEXT IF !r %]
       <option value="[% r FILTER html %]">[% get_resolution(r) FILTER html %]</option>