[freeside-commits] branch FREESIDE_4_BRANCH updated. bae965143e7933331a608eb8f2a56bba0a844a3c

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


The branch, FREESIDE_4_BRANCH has been updated
       via  bae965143e7933331a608eb8f2a56bba0a844a3c (commit)
       via  93606bc1854625bfffb8316630bbd4d987d161ec (commit)
       via  0414f671da0bb49fd2af12c9adc641fda3478bb1 (commit)
       via  e9f17b33c350027f713b88dc3a1c67837a8fd7d6 (commit)
      from  8fd0a2a920cf5e46c36da85f3346f933727e5dc8 (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 bae965143e7933331a608eb8f2a56bba0a844a3c
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 93606bc1854625bfffb8316630bbd4d987d161ec
Merge: 0414f67 8fd0a2a
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Dec 10 01:03:17 2015 -0800

    Merge branch 'FREESIDE_4_BRANCH' of git.freeside.biz:/home/git/freeside into 4.x


commit 0414f671da0bb49fd2af12c9adc641fda3478bb1
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 e9f17b33c350027f713b88dc3a1c67837a8fd7d6
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