RT tool & RecordTransaction => 0

Hi,

Is there an equivalent way of making the transactions silent via the RT
tool?

Within a normal scrip using RecordTransaction => 0, is there a similar way
for making an edit via the RT tool silent?

– Bart

Hi,

Is there an equivalent way of making the transactions silent via the RT
tool?

No.

Within a normal scrip using RecordTransaction => 0, is there a similar way
for making an edit via the RT tool silent?

– Bart


RT Training Sessions (http://bestpractical.com/services/training.html)

  • Boston — March 5 & 6, 2012

Best regards, Ruslan.

Hmm, I might need to rethink my script then…

Have this script in cron:

#!/bin/bash

datum=date "+%d%m%y"
tijd=date "+%H%M"

if [ $tijd -ge 0830 -a $datum -ne 261211 -a $datum -ne 090412 -a $datum -ne
300412 -a $datum -ne 170512 -a $datum -ne 180512 -a $datum -ne 280512 -a
$datum -ne 251212 -a $datum -ne 261212 ]
then
for i in /opt/rt4/bin/rt ls -t ticket "Status!='resolved' and Status!='rejected' and Status!='spam' and Status!='deleted'" -f status | grep ^[0-9] | cut -f 1; do
case /opt/rt4/bin/rt ls -t ticket "id=$i" -f status | grep ^[0-9] | cut -f 2 in
new) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_new’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_new' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
open) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_open’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_open' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
stalled) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_stalled’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_stalled' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
Bij_Leverancier) /opt/rt4/bin/rt edit ticket/$i set
CF-‘aantal_minuten_Bij_Leverancier’=$(( /opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_Bij_Leverancier' | grep ^[0-9] | cut -f 2 +
5 ))&
;;
Bij_Aanvrager) /opt/rt4/bin/rt edit ticket/$i set
CF-‘aantal_minuten_Bij_Aanvrager’=$(( /opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_Bij_Aanvrager' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
Intern) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_Intern’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_Intern' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
*) ;;
esac
done
fi

It runs every 5 minutes during business hours, rough translation would be
that it runs 114 times a day. During each run it increases the value of a
custom field by 5, this will give us the amount of time in minutes a ticket
stood at a certain active status. (in the above you’ll see a few default
statuses along with a few custom ones)

I kinda overlooked that it writes an entry in the ticket history where it
shows the change of the CF value… 114 times a day for each ticket, where
an average ticket might be open a few days (changes or problems even
longer). . .

Users however won’t see these changes unless they hit the history tab, but
I the ticket view will be slowed down when the history gets bigger and
bigger (we use RT::Extension::HistoryFilter, but even with it RT will first
load the entire history)…

Any suggestions on how to achieve the above without writing stuff in the
ticket history?

– Bart

Op 7 december 2011 22:44 schreef Ruslan Zakirov ruz@bestpractical.com het
volgende:> On Wed, Dec 7, 2011 at 7:23 PM, Bart bart@pleh.info wrote:

Hi,

Is there an equivalent way of making the transactions silent via the RT
tool?

No.

Within a normal scrip using RecordTransaction => 0, is there a similar
way
for making an edit via the RT tool silent?

– Bart


RT Training Sessions (http://bestpractical.com/services/training.html)

  • Boston — March 5 & 6, 2012


Best regards, Ruslan.

Small update

Since I want a simple solution I’m now looking into doing this inside SQL
instead of trying to make a clever script.

Few SQL queries that should give you an idea to where I’m heading.

Get all tickets along with their status, though I’ll probably make a
separate query for each status (to keep things simple)

select id,Status from Tickets where Status != “deleted” AND Status !=
“resolved” AND Status != “spam” AND Status != “rejected”;

Show the CustomField value of ticket 2222 (specific CF, selected by ID),
disabled 0 means it’s the active value:

select * from ObjectCustomFieldValues where ObjectId = “2222” AND Disabled
= “0” AND CustomField = “12”;

Update the CustomField value for ticket 2222 and increase the value by 5:

update ObjectCustomFieldValues set Content = Content + 5 where CustomField
= “12” AND Disabled = “0” AND ObjectId = “2222”;

The only problem I’m now looking at is that if a CF never had a value
(empty) then it won’t have an entry in the DB. So in addition to the SQL
queries I’m going to make sure that these specific CF’s always have a value
(set during ticket creation + set once manually for all tickets).

The CustomField values will be set to 0 + during ticket creation I’ll make
sure that the transaction isn’t recorded.

When you update a CF that’s already been recorded in the ticket history
you’ll update the value shown in the ticket history for that entry.

One thing that I want to do to make things a little “nicer” is to also
update the “LastUpdated” field for that entry.

Overall I think this will be the better solution for us, will post the
results once I’m done.

– BartOp 8 december 2011 07:34 schreef Bart bart@pleh.info het volgende:

Hmm, I might need to rethink my script then…

Have this script in cron:

#!/bin/bash

datum=date "+%d%m%y"
tijd=date "+%H%M"

if [ $tijd -ge 0830 -a $datum -ne 261211 -a $datum -ne 090412 -a $datum
-ne 300412 -a $datum -ne 170512 -a $datum -ne 180512 -a $datum -ne 280512
-a $datum -ne 251212 -a $datum -ne 261212 ]
then
for i in /opt/rt4/bin/rt ls -t ticket "Status!='resolved' and Status!='rejected' and Status!='spam' and Status!='deleted'" -f status | grep ^[0-9] | cut -f 1; do
case /opt/rt4/bin/rt ls -t ticket "id=$i" -f status | grep ^[0-9] | cut -f 2 in
new) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_new’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_new' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
open) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_open’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_open' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
stalled) /opt/rt4/bin/rt edit ticket/$i set
CF-‘aantal_minuten_stalled’=$(( /opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_stalled' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
Bij_Leverancier) /opt/rt4/bin/rt edit ticket/$i set
CF-‘aantal_minuten_Bij_Leverancier’=$(( /opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_Bij_Leverancier' | grep ^[0-9] | cut -f 2 +
5 ))&
;;
Bij_Aanvrager) /opt/rt4/bin/rt edit ticket/$i set
CF-‘aantal_minuten_Bij_Aanvrager’=$(( /opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_Bij_Aanvrager' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
Intern) /opt/rt4/bin/rt edit ticket/$i set CF-‘aantal_minuten_Intern’=$((
/opt/rt4/bin/rt ls -t ticket "id=$i" -f CF-'aantal_minuten_Intern' | grep ^[0-9] | cut -f 2 + 5 ))&
;;
*) ;;
esac
done
fi

It runs every 5 minutes during business hours, rough translation would be
that it runs 114 times a day. During each run it increases the value of a
custom field by 5, this will give us the amount of time in minutes a ticket
stood at a certain active status. (in the above you’ll see a few default
statuses along with a few custom ones)

I kinda overlooked that it writes an entry in the ticket history where it
shows the change of the CF value… 114 times a day for each ticket, where
an average ticket might be open a few days (changes or problems even
longer). . .

Users however won’t see these changes unless they hit the history tab, but
I the ticket view will be slowed down when the history gets bigger and
bigger (we use RT::Extension::HistoryFilter, but even with it RT will first
load the entire history)…

Any suggestions on how to achieve the above without writing stuff in the
ticket history?

– Bart

Op 7 december 2011 22:44 schreef Ruslan Zakirov ruz@bestpractical.comhet volgende:

On Wed, Dec 7, 2011 at 7:23 PM, Bart bart@pleh.info wrote:

Hi,

Is there an equivalent way of making the transactions silent via the RT
tool?

No.

Within a normal scrip using RecordTransaction => 0, is there a similar
way
for making an edit via the RT tool silent?

– Bart


RT Training Sessions (http://bestpractical.com/services/training.html)

  • Boston — March 5 & 6, 2012


Best regards, Ruslan.

Any suggestions on how to achieve the above without writing stuff in the
ticket history?

With a silent flag that only available through API. rt-crontool +
custom scrip action is your friend.

Best regards, Ruslan.

I find the rt-crontool to be a bit confusing. I can search with it, set a
CF based on search results etc.

But the trick would be to do something like CF-‘some cf’=“Old CF Value” + 5.

Can the rt-crontool launch an internal RT scrip (e.g. a global scrip or
something like that) as action instead of the actions that I come across at
the examples?

– Bart

Op 8 december 2011 10:50 schreef Ruslan Zakirov ruz@bestpractical.com het
volgende:> On Thu, Dec 8, 2011 at 10:34, Bart bart@pleh.info wrote:

Any suggestions on how to achieve the above without writing stuff in the
ticket history?

With a silent flag that only available through API. rt-crontool +
custom scrip action is your friend.


Best regards, Ruslan.

Looking into this atm, might be a more “clean” way of doing this:

http://requesttracker.wikia.com/wiki/WriteCustomAction

– BartOp 8 december 2011 11:01 schreef Bart bart@pleh.info het volgende:

I find the rt-crontool to be a bit confusing. I can search with it, set a
CF based on search results etc.

But the trick would be to do something like CF-‘some cf’=“Old CF Value” +
5.

Can the rt-crontool launch an internal RT scrip (e.g. a global scrip or
something like that) as action instead of the actions that I come across at
the examples?

– Bart

Op 8 december 2011 10:50 schreef Ruslan Zakirov ruz@bestpractical.comhet volgende:

On Thu, Dec 8, 2011 at 10:34, Bart bart@pleh.info wrote:

Any suggestions on how to achieve the above without writing stuff in the
ticket history?

With a silent flag that only available through API. rt-crontool +
custom scrip action is your friend.


Best regards, Ruslan.

Can the rt-crontool launch an internal RT scrip (e.g. a global scrip or
something like that) as action instead of the actions that I come across at
the examples?

It’s exactly what it does - replays custom condition, scrip and
template combination on every ticket returned by a custom search.

You need RT::Action::IncreaseCustomField module and there do something like:

my ($status, $msg) = $ticket->AddCustomFieldValue(
Field => “CF”,
Value => $ticket->FirstCustomFieldValue(“CF”) + 5,
);

Best regards, Ruslan.

Damn, this really is kinda cool :slight_smile: (learn something new every day)

To recap what I did.

Go to the place where all the actions are located

cd /opt/rt4/lib/RT/Action

Copy EscalatePriority to TEST.pm, I needed an example :wink:

cp EscalatePriority.pm TEST.pm

Edit TEST.pm to look like this (full content)

=head1 NAME

RT::Action::TEST

=head1 DESCRIPTION

Some test script, will increase the value of a CF by 5.

CF = CF +  5

=cut

package RT::Action::TEST;
use base ‘RT::Action’;

use strict;

sub Describe {
my $self = shift;
return (ref $self . " will increase the value of a CF by 5..");
}

sub Prepare {
my $self = shift;
my $new_value = $self->TicketObj-> FirstCustomFieldValue( ‘Teller New’
) + 5;
$self->TicketObj->AddCustomFieldValue(Field => ‘Teller New’, Value =>
$new_value, RecordTransaction => 0 );
return 1;
}

sub Commit {
# ---- I’ll see if I can add some error logging here ----
}

---- Is this one needed? ----

RT::Base->_ImportOverlays();

1;

Then launch rt-crontool like this as a test for all new tickets: (it

should edit roughly 6000 tickets in my test environment)

/opt/rt4/bin/rt-crontool --search RT::Search::FromSQL --search-arg “status
= ‘new’” --action RT::Action::TEST

The last bit takes a while to complete but I find that understandable (it’s
a slow test server, it’s swapping memory like crazy and CPU load is rather
high, production has more memory and more CPU’s / stronger CPU’s so it
shouldn’t be much of a problem there ^_~)

One last question though, this custom action is only loaded when I
explicitly call for it? (I assume yes, but want to be sure if it)

Other then that this is allot “cleaner” then hacking the SQL database. (and
it’s silent ^_^)

– Bart

Op 8 december 2011 11:17 schreef Ruslan Zakirov ruz@bestpractical.com het
volgende:> On Thu, Dec 8, 2011 at 14:01, Bart bart@pleh.info wrote:

Can the rt-crontool launch an internal RT scrip (e.g. a global scrip or
something like that) as action instead of the actions that I come across
at
the examples?

It’s exactly what it does - replays custom condition, scrip and
template combination on every ticket returned by a custom search.

You need RT::Action::IncreaseCustomField module and there do something
like:

my ($status, $msg) = $ticket->AddCustomFieldValue(
Field => “CF”,
Value => $ticket->FirstCustomFieldValue(“CF”) + 5,
);


Best regards, Ruslan.

One last question though, this custom action is only loaded when I
explicitly call for it? (I assume yes, but want to be sure if it)

Yes. You can register it in database and use in scrips. You can also
use Argument value to control the action.

Check other actions for examples.

Best regards, Ruslan.

sub Prepare {
my $self = shift;
my $new_value = $self->TicketObj-> FirstCustomFieldValue( ‘Teller New’ )

  • 5;
    $self->TicketObj->AddCustomFieldValue(Field => ‘Teller New’, Value =>
    $new_value, RecordTransaction => 0 );
    return 1;
    }

You should move all this code into Commit. Don’t change objects during prepare.

Best regards, Ruslan.

Ok,

Will do a little more adjusting, thanks for the help.

– Bart

Op 8 december 2011 12:28 schreef Ruslan Zakirov ruz@bestpractical.com het
volgende:> On Thu, Dec 8, 2011 at 14:46, Bart bart@pleh.info wrote:

sub Prepare {
my $self = shift;
my $new_value = $self->TicketObj-> FirstCustomFieldValue( ‘Teller
New’ )

  • 5;
    $self->TicketObj->AddCustomFieldValue(Field => ‘Teller New’, Value =>
    $new_value, RecordTransaction => 0 );
    return 1;
    }

You should move all this code into Commit. Don’t change objects during
prepare.


Best regards, Ruslan.

I think I’ve finished it, only have some issues with the $RT::Logger->error
thing. The scrip won’t launch when I have that part enabled, when disabled
it runs just fine O_o

package RT::Action::TEST;
use base ‘RT::Action’;
use strict;
use warnings;

sub Prepare {
return 1;
}

sub Commit {
my $self = shift;
my $tstatus = $self->TicketObj->Status;
if ($tstatus eq ‘new’) { my ($val, $msg) =
$self->TicketObj->AddCustomFieldValue(Field => ‘Teller New’, Value =>
$self->TicketObj->FirstCustomFieldValue( ‘Teller New’ ) + 5,
RecordTransaction => 0 ); }
if ($tstatus eq ‘open’) { my ($val, $msg) =
$self->TicketObj->AddCustomFieldValue(Field => ‘Teller New’, Value =>
$self->TicketObj->FirstCustomFieldValue( ‘Teller New’ ) + 5,
RecordTransaction => 0 ); }
# — Insert more if statements to match more ticket statusses. —

    # --- the part below doesn't seem to work, no idea why. ---
    #unless ( $val ) {
    #       $RT::Logger->error("Coudln't change Custom Field: $msg");
    #       return 0;
    #}
    return 1;

}

1;

– BartOp 8 december 2011 12:31 schreef Bart bart@pleh.info het volgende:

Ok,

Will do a little more adjusting, thanks for the help.

– Bart

Op 8 december 2011 12:28 schreef Ruslan Zakirov ruz@bestpractical.comhet volgende:

On Thu, Dec 8, 2011 at 14:46, Bart bart@pleh.info wrote:

sub Prepare {
my $self = shift;
my $new_value = $self->TicketObj-> FirstCustomFieldValue( ‘Teller
New’ )

  • 5;
    $self->TicketObj->AddCustomFieldValue(Field => ‘Teller New’, Value
    =>
    $new_value, RecordTransaction => 0 );
    return 1;
    }

You should move all this code into Commit. Don’t change objects during
prepare.


Best regards, Ruslan.

I think I’ve finished it, only have some issues with the $RT::Logger->error
thing. The scrip won’t launch when I have that part enabled, when disabled
it runs just fine O_o

$val is inside if {} block and lexically scoped, so it’s not available outside.

Use my ($val, $msg); if { ($val, $msg) = … }

Best regards, Ruslan.

So this if statement would be more accurate: (to have the ability to have a
little more specific error log message)

    if ($tstatus eq 'new') {
            my ($status, $msg) =

$self->TicketObj->AddCustomFieldValue(Field => ‘aantal_minuten_new’, Value
=> $self->TicketObj->FirstCustomFieldValue( ‘aantal_minuten_new’ ) + 5,
RecordTransaction => 0 );
unless ( $status ) {
$RT::Logger->error("Coudln’t change Custom Field:
". $msg);
return 0;
}
}

(test run seems to work this way)

– Bart

Op 8 december 2011 15:44 schreef Ruslan Zakirov ruz@bestpractical.com het
volgende:> On Thu, Dec 8, 2011 at 17:00, Bart bart@pleh.info wrote:

I think I’ve finished it, only have some issues with the
$RT::Logger->error
thing. The scrip won’t launch when I have that part enabled, when
disabled
it runs just fine O_o

$val is inside if {} block and lexically scoped, so it’s not available
outside.

Use my ($val, $msg); if { ($val, $msg) = … }


Best regards, Ruslan.