[rt-devel] Problems with order of Scrips, Transactions and etc.

Ruslan U. Zakirov cubic at acronis.ru
Tue Dec 30 04:36:11 EST 2003


		Hello.

Attached file is ScripAction that tries automap Priority field to any 
CustomField.

Direct mapping is ok(changes of CF -> changes of Priority), but revers 
mapping is in troubles.

For example:
We use 'Basics' to change Priority, but there is also CF edit forms. 
ScripAction do job for SetPriority transaction and change CF(Severity), 
in the next few steps RT continue to parse user form data and there is 
old CF value that was changed(bt scrip action), then RT update it to old 
value.

Please suggest me workaround for this problem.
I have got ideas, but they leads to RT core changes.
		Best regards. Ruslan.
-------------- next part --------------

package RT::Action::PriorityAutoMap;
require RT::Action::Generic;

use strict;
use vars qw/@ISA/;
@ISA=qw(RT::Action::Generic);

sub Describe  {
	my $self = shift;
	return (ref $self . " will try map ticket's priority with custom field.");
}

sub FieldObj
{
	my $self = shift;
	return($self->{'FieldObj'});
}

sub Map
{
	my $self = shift;
	return($self->{'Map'});
}

sub ReversMap
{
	my $self = shift;
	return($self->{'ReversMap'});
}

sub Prepare
{
	my $self = shift;
	my $arg = $self->Argument;
	unless($arg) {
		$RT::Logger->error('No argument');
		return undef;
	}
	
	my ($FieldName, $MapStr) = ($arg =~ /^(.*?):(.*)$/);
	unless($FieldName) {
		$RT::Logger->error('No Field');
		return undef;
	}
	
	my $Map = eval "$MapStr" ;
	if ($@) {
		$RT::Logger->error($@);
		return undef;
	}
	unless (ref($Map)) {
		$RT::Logger->error('Wrong map format');
		return undef;
	}
	$self->{'Map'} = $Map;
	my $ReversMap = {};
	$ReversMap->{$Map->{$_}} = $_ foreach (keys %$Map);
	$self->{'ReversMap'} = $ReversMap;

	my $cf = RT::CustomField->new($RT::SystemUser);
	$cf->LoadByNameAndQueue(Name => $FieldName, Queue => $self->TicketObj->Queue);
	unless ($cf->Id) {
		$RT::Logger->error('No CF with Name(Id): ' . $FieldName);
		return undef;
	}
	$self->{'FieldObj'} = $cf;
	return 1;
}

sub Commit
{
	my $self = shift;
	if ($self->TransactionObj->Type eq 'Create') {
		if ($self->TicketObj->Priority) {
			$self->SetFieldByPriority;
		} else {
			$self->SetPriorityByField;
		}
		return 1;
	}
	
	if ($self->TransactionObj->Type eq 'Set' and $self->TransactionObj->Field eq 'Priority') {
		$self->SetFieldByPriority;
		return 1;
	}
	
	if ($self->TransactionObj->Type =~ /^(?:Keyword|CustomField)$/ and $self->TransactionObj->Field == $self->FieldObj->Id) {
		$self->SetPriorityByField;
		return 1;
	}
	return 1;
}

sub SetPriorityByField
{
	my $self = shift;
	my $cfv = $self->TicketObj->FirstCustomFieldValue($self->FieldObj->Id);
	return unless(defined $cfv);
	unless ( exists $self->Map->{$cfv} ) {
		$RT::Logger->error($cfv . 'not defined in map');
		return;
	}
	
	$self->TicketObj->_Set(Field => 'Priority', Value => $self->Map->{$cfv}, RecordTransaction => 0);
}

sub SetFieldByPriority
{
	my $self = shift;
	my $priority = $self->TicketObj->Priority;
	my $nearest;
	foreach my $p (keys %{$self->ReversMap}) {
		$nearest = $p unless(defined $nearest);
		$nearest = $p if (abs($priority - $p) < abs($priority - $nearest));
	}
	$RT::Logger->debug('Nearest: ' . $nearest . ', Value: ' . $self->TicketObj->FirstCustomFieldValue($self->FieldObj->Id));

	return if ($self->TicketObj->FirstCustomFieldValue($self->FieldObj->Id) eq $self->ReversMap->{$nearest});
	if ($self->TicketObj->CustomFieldValues($self->FieldObj->Id)->First) {
		$self->TicketObj->CustomFieldValues($self->FieldObj->Id)->First->SetContent( $self->ReversMap->{$nearest} );
	} else {
		$self->TicketObj->_AddCustomFieldValue( Field => $self->FieldObj->Id,
				Value => $self->ReversMap->{$nearest},
				RecordTransaction => 0);
	}

	return ;
}


More information about the Rt-devel mailing list