[freeside-commits] branch master updated. 6870babd1be7976dc8823c46a66254ee977c8cd1

Mark Wells mark at 420.am
Thu Dec 10 01:04:07 PST 2015


The branch, master has been updated
       via  6870babd1be7976dc8823c46a66254ee977c8cd1 (commit)
       via  41dcb76c7a2cd0f020e4eb360944b99dae10c2a4 (commit)
       via  e26b8e8e8036556000defb99879a7ae074b09c60 (commit)
       via  548b94eafa4bc90680e13f015445b6833b065c73 (commit)
      from  a55f3abbb39ddc30d7e8f0a5a573bbf7b691b510 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6870babd1be7976dc8823c46a66254ee977c8cd1
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Dec 10 01:01:21 2015 -0800

    fix some problems with creation of subtask tickets, #34061

diff --git a/rt/lib/RT/Condition/CustomFieldEquals.pm b/rt/lib/RT/Condition/CustomFieldEquals.pm
index 69dedcb..8ebf94b 100644
--- a/rt/lib/RT/Condition/CustomFieldEquals.pm
+++ b/rt/lib/RT/Condition/CustomFieldEquals.pm
@@ -28,9 +28,10 @@ sub IsApplicable {
     if ($trans->Type eq 'CustomField') {
         my $cf = RT::CustomField->new($self->CurrentUser);
         $cf->Load($field);
-        return $trans->Field == $cf->Id
-               and ($trans->NewValue eq $value)
-               and ($trans->OldValue ne $value)
+        return (   $trans->Field == $cf->Id
+               and $trans->NewValue eq $value
+               and $trans->OldValue ne $value
+               );
     }
     return undef;
 }
diff --git a/rt/share/html/Admin/Queues/Tasks.html b/rt/share/html/Admin/Queues/Tasks.html
index 30ec12b..94df549 100755
--- a/rt/share/html/Admin/Queues/Tasks.html
+++ b/rt/share/html/Admin/Queues/Tasks.html
@@ -92,7 +92,7 @@ my $title = loc("Set up subtasks for queue [_1]", $QueueObj->Name);
 
 my $TEMPLATE_NAME = '[Subtask]';
 my $SCRIPCONDITION_NAME = '[Subtask] Queue='.$Queue;
-my $SUBJECT_PREFIX = q({ $Tickets{'TOP'}->Subject }-);
+my $SUBJECT_PREFIX = q({ $TOP->Subject }-);
 
 my ($Scrip, $ScripCondition, $Template, $CustomField);
 
@@ -112,7 +112,7 @@ $Scrip = RT::Scrip->new($RT::SystemUser);
 {
   my $Scrips = RT::Scrips->new($RT::SystemUser);
   $Scrips->LimitToQueue($Queue);
-  $Scrips->Limit( FIELD => 'Template', VALUE => $TEMPLATE_NAME );
+  $Scrips->Limit( FIELD => 'Template', VALUE => $Template->Id );
   if ( $Scrips->Count > 0 ) {
     $Scrip = $Scrips->First;
   }
@@ -138,12 +138,13 @@ if ( $ARGS{task_id} ) { # actually contains numeric indices
     my %task_opts = map { $_ => $ARGS{$_} }
                     grep /^$task_id-/, keys(%ARGS);
     my $task_content = "===Create-Ticket: $task_id
+CF-$cfname:" . q[
 Depended-On-By: TOP
-CF-$cfname: 
-";
-    # any other static content can go here, but we always want the child
-    # ticket relationship, and we want to force the ConditionCF to be empty
-    # to avoid recursion.
+Owner: { $TOP->Owner }
+{ join("\n", map { "Requestor: $_" }
+  $TOP->Requestors->MemberEmailAddresses) }
+];
+    # any other attributes to put on subtask tickets should go here also.
 
     my $has_content = 0;
 
@@ -171,7 +172,6 @@ CF-$cfname:
       $new_content .= $task_content;
     }
   }
-  warn "NEW CONTENT:\n$new_content\n\n"; # XXX
 
   if ( ! $Template->Id ) {
     my ( $val, $msg ) = $Template->Create(
@@ -252,12 +252,10 @@ my $Action = $action_class->new(
   CurrentUser    => $session{'CurrentUser'},
 );
 # this will populate $Action with the 'create_tickets' hash
-warn $Template->Content;
 $Action->Parse(
   Content         => $Template->Content,
   _ActiveContent  => 0,
 );
-warn Dumper \$Action;
 my @task_ids;
 @task_ids = @{ $Action->{create_tickets} } if exists $Action->{create_tickets};
 

commit 41dcb76c7a2cd0f020e4eb360944b99dae10c2a4
Merge: e26b8e8 a55f3ab
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Dec 10 01:02:00 2015 -0800

    Merge branch 'master' of git.freeside.biz:/home/git/freeside


commit e26b8e8e8036556000defb99879a7ae074b09c60
Author: Mark Wells <mark at freeside.biz>
Date:   Wed Dec 9 17:23:46 2015 -0800

    fix strange behavior after inserting a substitution, #38803, fallout from #24331

diff --git a/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js b/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js
index e4ef391..96c0f42 100644
--- a/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js
+++ b/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js
@@ -133,7 +133,20 @@
                             } // span function
                           } // elements
                         });
-                }
+
+                        editor.on( 'afterInsertHtml', function( evt ) {
+                          // if this leaves an open SPAN, move the cursor
+                          // to after it
+                          var range = editor.getSelection().getRanges()[0];
+                          var ec = range.endContainer;
+                          if ( ec.hasClass('cke_blockprotect') ) {
+                            range.setEndAfter(ec);
+                            range.collapse();
+                            editor.getSelection().selectRanges([ range ]);
+                          }
+                        });
+
+                } // afterInit
         }); // plugins.add
 }) ();
 
diff --git a/httemplate/elements/htmlarea.html b/httemplate/elements/htmlarea.html
index d8b2512..4f9b721 100644
--- a/httemplate/elements/htmlarea.html
+++ b/httemplate/elements/htmlarea.html
@@ -20,7 +20,8 @@ Example:
 
 <SCRIPT TYPE="text/javascript">
 
-  CKEDITOR.replace('<% $opt{'field'} %>',
+  var <% $opt{'field'} %>_editor =
+    CKEDITOR.replace('<% $opt{'field'} %>',
                    <% encode_json($config) %>
   );
 

commit 548b94eafa4bc90680e13f015445b6833b065c73
Author: Mark Wells <mark at freeside.biz>
Date:   Wed Dec 9 16:00:14 2015 -0800

    automatic creation of subtask tickets, #34061

diff --git a/rt/lib/RT/Condition/CustomFieldEquals.pm b/rt/lib/RT/Condition/CustomFieldEquals.pm
new file mode 100644
index 0000000..69dedcb
--- /dev/null
+++ b/rt/lib/RT/Condition/CustomFieldEquals.pm
@@ -0,0 +1,39 @@
+package RT::Condition::CustomFieldEquals;
+use base 'RT::Condition';
+use strict;
+
+=head2 IsApplicable
+
+If a custom field has a value equal to some specified value.
+
+=cut
+
+# Based on Chuck Boeheim's code posted on the RT Wiki 3/13/06
+# Simplified to avoid carrying old schema around. The new mechanics are that
+# the ScripCondition's "Argument" is the custom field name = value. If the 
+# transaction initially sets the CF value to a the specified value, or 
+# changes it from not equaling to equaling the specified value, the condition
+# returns true.
+# Don't use this on custom fields that allow multiple values.
+
+sub IsApplicable {
+    my $self = shift;
+    my $trans = $self->TransactionObj;
+    my $scrip = $self->ScripObj;
+    my ($field, $value) = split('=', $self->Argument, 2);
+
+    if ($trans->Type eq 'Create') {
+        return ($trans->TicketObj->FirstCustomFieldValue($field) eq $value);
+    }
+    if ($trans->Type eq 'CustomField') {
+        my $cf = RT::CustomField->new($self->CurrentUser);
+        $cf->Load($field);
+        return $trans->Field == $cf->Id
+               and ($trans->NewValue eq $value)
+               and ($trans->OldValue ne $value)
+    }
+    return undef;
+}
+
+1;
+
diff --git a/rt/share/html/Admin/Queues/Tasks.html b/rt/share/html/Admin/Queues/Tasks.html
new file mode 100755
index 0000000..30ec12b
--- /dev/null
+++ b/rt/share/html/Admin/Queues/Tasks.html
@@ -0,0 +1,269 @@
+<& /Admin/Elements/Header, Title => $title &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="Tasks.html" method="post">
+<input type="hidden" name="Queue" value="<% $Queue %>" />
+<h2>
+  <label for="ConditionCF"><&|/l&>Enabled if</&>:</label>
+% if ( $PossibleCustomFields->Count > 0 ) {
+  <select name="ConditionCF">
+%   while ( my $thiscf = $PossibleCustomFields->Next ) {
+    <option value="<% $thiscf->Id %>" <% $thiscf->Id == $cfid ? 'selected' : '' %>><% $thiscf->Name %></option>
+%   }
+  </select>
+  <label for="ConditionValue"><&|/l&>equals</&></label>
+  <input name="ConditionValue" value="<% $cfvalue %>" />
+% } else {
+  <select name="no_cfs" disabled>
+    <option value="1">(no custom fields defined)</option>
+  </select>
+% }
+</h2>
+<table>
+% my (@links, @postponed); # not really used here
+% my $idx = 1;
+% foreach my $task_id (@task_ids, 'new') {
+%   # simulate creating the tickets, but don't evaluate any perl inclusions
+%   # in the content (_ActiveContent => 0 earlier)
+%   my ($ticket, $ticketargs);
+%   if ( $task_id eq 'new' ) {
+%     $ticket = RT::Ticket->new($session{'CurrentUser'});
+%     $ticketargs = {
+%       Queue => $Queue,
+%       # any other defaults make sense here?
+%     };
+%   } else {
+%     ($ticket, $ticketargs) =
+%       $Action->ParseLines($task_id, \@links, \@postponed);
+%   }
+%   my $subject = $ticketargs->{Subject};
+%   my $subjectprefix = 0;
+%   if ( $subject =~ s/^\Q$SUBJECT_PREFIX\E// ) {
+%     $subjectprefix = 1;
+%   }
+
+  <tr>
+    <td colspan="2">
+      <h2>
+      <label for="task_id"><&|/l&>Task #</&><% $idx %>
+% # each time these are edited, replace all task IDs with sequential numbers.
+% # no point in letting them be anything else, at least yet.
+      <input type="hidden" name="task_id" value="<% $idx %>">
+      </h2>
+    </td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Subject</&>:</td>
+    <td class="value">
+      <input name="<% $idx %>-Subject" value="<% $subject |h %>" />
+      <input type="checkbox" name="<% $idx %>-SubjectPrefix" <% $subjectprefix ? 'checked' : '' %> /> <&|/l&>Prefix with main subject</&>
+    </td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>In queue</&>:</td>
+    <td class="value"><& /Elements/SelectQueue,
+      Name => "$idx-Queue",
+      ShowNullOption => 0,
+      Default => ($ticketargs->{Queue} || $Queue),
+    &></td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Content</&>:</td>
+    <td class="value"><textarea name="<% $idx %>-Content" rows="10" cols="80" wrap="soft"><%
+    ( $ticketargs->{MIMEObj} ? $ticketargs->{MIMEObj}->body_as_string : '' )
+    %></textarea>
+    </td>
+  </tr>
+
+%   $idx++;
+% }
+</table>
+<& /Elements/Submit, Label => 'Save Changes' &>
+</form>
+<%init>
+my @results;
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+Abort(loc("Queue [_1] not found",$Queue)) unless $QueueObj->Id;
+
+my $title = loc("Set up subtasks for queue [_1]", $QueueObj->Name);
+
+my $TEMPLATE_NAME = '[Subtask]';
+my $SCRIPCONDITION_NAME = '[Subtask] Queue='.$Queue;
+my $SUBJECT_PREFIX = q({ $Tickets{'TOP'}->Subject }-);
+
+my ($Scrip, $ScripCondition, $Template, $CustomField);
+
+# SystemUser for the scrip so that the user doesn't need ACLs to edit scrips
+# as such.  all the scrip parameters are hardcoded anyway...
+
+$ScripCondition = RT::ScripCondition->new($RT::SystemUser);
+$ScripCondition->LoadByCol('Name', $SCRIPCONDITION_NAME);
+
+$Template = RT::Template->new($session{'CurrentUser'});
+$Template->LoadByName(
+  Name  => $TEMPLATE_NAME,
+  Queue => $Queue,
+);
+
+$Scrip = RT::Scrip->new($RT::SystemUser);
+{
+  my $Scrips = RT::Scrips->new($RT::SystemUser);
+  $Scrips->LimitToQueue($Queue);
+  $Scrips->Limit( FIELD => 'Template', VALUE => $TEMPLATE_NAME );
+  if ( $Scrips->Count > 0 ) {
+    $Scrip = $Scrips->First;
+  }
+}
+
+# The CF name to test, and the value it must have to trigger the scrip.
+my $cfid = $ARGS{ConditionCF};
+my $cfvalue = $ARGS{ConditionValue};
+$CustomField = RT::CustomField->new($session{'CurrentUser'});
+if ( $cfid ) {
+  $CustomField->Load($cfid);
+}
+my $cfname = $CustomField->Name;
+
+# if there's input from the form, process it into a new template content
+my $new_content = '';
+
+if ( $ARGS{task_id} ) { # actually contains numeric indices
+  my @task_ids = $ARGS{task_id};
+  @task_ids = @{ $task_ids[0] } if ref($task_ids[0]);
+  foreach my $task_id (@task_ids) {
+    # find the inputs for this task_id
+    my %task_opts = map { $_ => $ARGS{$_} }
+                    grep /^$task_id-/, keys(%ARGS);
+    my $task_content = "===Create-Ticket: $task_id
+Depended-On-By: TOP
+CF-$cfname: 
+";
+    # any other static content can go here, but we always want the child
+    # ticket relationship, and we want to force the ConditionCF to be empty
+    # to avoid recursion.
+
+    my $has_content = 0;
+
+    # special case: automate prefixing the main ticket subject
+    if ( $task_opts{"$task_id-SubjectPrefix"} ) {
+      $task_opts{"$task_id-Subject"} =
+        $SUBJECT_PREFIX . $task_opts{"$task_id-Subject"};
+    }
+    
+    foreach my $key (sort keys %task_opts) {
+      $key =~ /^$task_id-(.*)/;
+      my $tag = $1;
+      my $value = $task_opts{$key};
+      $value =~ s/^\s*//;
+      $value =~ s/\s*$//;
+      $value =~ s/\r//g;
+      $task_content .= "$tag: $value\n";
+      # only create a task if the ticket has non-whitespace content
+      if ( lc($tag) eq 'content' and length($value) > 0 ) {
+        $task_content .= "ENDOFCONTENT\n";
+        $has_content = 1;
+      }
+    }
+    if ( $has_content ) {
+      $new_content .= $task_content;
+    }
+  }
+  warn "NEW CONTENT:\n$new_content\n\n"; # XXX
+
+  if ( ! $Template->Id ) {
+    my ( $val, $msg ) = $Template->Create(
+      Queue           => $Queue,
+      Name            => $TEMPLATE_NAME,
+      Description     => 'Subtask tickets',
+      Type            => 'Perl',
+      Content         => $new_content,
+    );
+    if (!$val) {
+      push @results, loc("Could not create template: [_1]", $msg);
+    } else {
+      push @results, loc("Template created");
+    }
+  } elsif ( $Template->Content ne $new_content ) { # template needs updating
+    my ( $val, $msg ) = $Template->SetContent($new_content);
+    if (!$val) {
+      push @results, loc("Could not update template: [_1]", $msg);
+    } else {
+      push @results, loc("Template updated");
+    }
+  }
+
+  # Set up ScripCondition
+  if ( !$cfname ) {
+    push @results, loc("No custom field selected");
+  } elsif ( length($cfvalue) == 0 ) {
+    push @results, loc("Custom field value is required");
+  } elsif ( ! $ScripCondition->Id ) {
+    my ( $val, $msg ) = $ScripCondition->Create(
+      Name            => $SCRIPCONDITION_NAME,
+      Description     => "When CF.[$cfname] equals '$cfvalue'",
+      ExecModule      => 'CustomFieldEquals',
+      Argument        => "$cfname=$cfvalue",
+      ApplicableTransTypes => 'Any',
+    );
+    if (!$val) {
+      push @results, loc("Could not create custom field condition: [_1]", $msg);
+    } else {
+      push @results, loc("Custom field condition created");
+    }
+  } elsif ( $ScripCondition->Argument ne "$cfname=$cfvalue" ) {
+    my ( $val, $msg ) = $ScripCondition->SetArgument("$cfname=$cfvalue");
+    if (!$val) {
+      push @results, loc("Could not set custom field condition: [_1]", $msg);
+    } else {
+      push @results, loc("Custom field condition set");
+    }
+  }
+
+  # Set up Scrip
+  if ( $Template->Id and ! $Scrip->Id ) {
+    my ($val, $msg) = $Scrip->Create(
+      Queue           => $Queue,
+      Template        => $Template->Id,
+      Description     => 'Create subtasks for ' . $QueueObj->Name,
+      ScripCondition  => $ScripCondition->Id,
+      ScripAction     => 'Create Tickets',
+    );
+    if (!$val) {
+      push @results, loc("Could not create scrip: [_1]", $msg);
+    } else {
+      push @results, loc("Scrip created");
+    }
+  } # else don't need to create the scrip
+
+  # even if $new_content is empty, there's no harm in letting the scrip and
+  # template exist with empty content. they just won't do anything.
+}
+
+# CHANGES HAVE BEEN SAVED.
+# Now prepare to (re-)display the form.
+
+# ask RT::Action::CreateTickets how it will parse the template
+my $action_class = 'RT::Action::CreateTickets';
+$action_class->require;
+my $Action = $action_class->new(
+  CurrentUser    => $session{'CurrentUser'},
+);
+# this will populate $Action with the 'create_tickets' hash
+warn $Template->Content;
+$Action->Parse(
+  Content         => $Template->Content,
+  _ActiveContent  => 0,
+);
+warn Dumper \$Action;
+my @task_ids;
+ at task_ids = @{ $Action->{create_tickets} } if exists $Action->{create_tickets};
+
+my $PossibleCustomFields = $QueueObj->TicketCustomFields;
+
+</%init>
+<%ARGS>
+$Queue => undef         #queue id
+</%ARGS>
diff --git a/rt/share/html/Elements/Tabs b/rt/share/html/Elements/Tabs
index 46d2bd8..920a3a0 100755
--- a/rt/share/html/Elements/Tabs
+++ b/rt/share/html/Elements/Tabs
@@ -305,6 +305,8 @@ my $build_admin_menu = sub {
                 my $txn_cfs = $cfs->child( 'transactions' => title => loc('Transactions'),
                     path => '/Admin/Queues/CustomFields.html?SubType=RT::Ticket-RT::Transaction&id='.$id );
 
+                $queue->child( 'tasks' => title => loc('Subtasks'), path => "Admin/Queues/Tasks.html?Queue=".$id );
+
                 $queue->child( 'group-rights' => title => loc('Group Rights'), path => "/Admin/Queues/GroupRights.html?id=".$id );
                 $queue->child( 'user-rights' => title => loc('User Rights'), path => "/Admin/Queues/UserRights.html?id=" . $id );
                 $queue->child( 'history' => title => loc('History'), path => "/Admin/Queues/History.html?id=" . $id );

-----------------------------------------------------------------------

Summary of changes:
 .../ckeditor/plugins/blockprotect/plugin.js        |   15 +-
 httemplate/elements/htmlarea.html                  |    3 +-
 rt/lib/RT/Condition/CustomFieldEquals.pm           |   40 +++
 rt/share/html/Admin/Queues/Tasks.html              |  267 ++++++++++++++++++++
 rt/share/html/Elements/Tabs                        |    2 +
 5 files changed, 325 insertions(+), 2 deletions(-)
 create mode 100644 rt/lib/RT/Condition/CustomFieldEquals.pm
 create mode 100755 rt/share/html/Admin/Queues/Tasks.html




More information about the freeside-commits mailing list