Skip to content

Commit 17bf15b

Browse files
committed
Merge branch '5.0/transaction-search-status' into 5.0-trunk
2 parents cb794e6 + 706015b commit 17bf15b

File tree

5 files changed

+153
-9
lines changed

5 files changed

+153
-9
lines changed

lib/RT/Transaction.pm

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ sub _FormatPrincipal {
970970
sub _FormatUser {
971971
my $self = shift;
972972
my $user = shift;
973+
return '' unless $user->id;
973974
return [
974975
\'<span class="user" data-replace="user" data-user-id="', $user->id, \'">',
975976
$user->Format,
@@ -1350,30 +1351,34 @@ sub _CanonicalizeRoleName {
13501351
my $New = RT::User->new( $self->CurrentUser );
13511352
$New->Load( $self->NewValue );
13521353

1353-
if ( $Old->id == RT->Nobody->id ) {
1354-
if ( $New->id == $self->Creator ) {
1354+
my $old_id = $Old->id // 0;
1355+
my $new_id = $New->id // 0;
1356+
1357+
if ( $old_id == RT->Nobody->id ) {
1358+
if ( $new_id == $self->Creator ) {
13551359
return ("Taken"); #loc()
13561360
}
13571361
else {
1358-
return ( "Given to [_1]", $self->_FormatUser($New) ); #loc()
1362+
return ( "Given to [_1]", $new_id ? $self->_FormatUser($New) : $self->NewValue ); #loc()
13591363
}
13601364
}
13611365
else {
1362-
if ( $New->id == $self->Creator ) {
1363-
return ("Stolen from [_1]", $self->_FormatUser($Old) ); #loc()
1366+
if ( $new_id == $self->Creator ) {
1367+
return ("Stolen from [_1]", $old_id ? $self->_FormatUser($Old) : $self->OldValue ); #loc()
13641368
}
1365-
elsif ( $Old->id == $self->Creator ) {
1366-
if ( $New->id == RT->Nobody->id ) {
1369+
elsif ( $old_id == $self->Creator ) {
1370+
if ( $new_id == RT->Nobody->id ) {
13671371
return ("Untaken"); #loc()
13681372
}
13691373
else {
1370-
return ( "Given to [_1]", $self->_FormatUser($New) ); #loc()
1374+
return ( "Given to [_1]", $new_id ? $self->_FormatUser($New) : $self->NewValue ); #loc()
13711375
}
13721376
}
13731377
else {
13741378
return (
13751379
"Owner forcibly changed from [_1] to [_2]",
1376-
map { $self->_FormatUser($_) } $Old, $New
1380+
( $old_id ? $self->_FormatUser($Old) : $self->OldValue ),
1381+
( $new_id ? $self->_FormatUser($New) : $self->NewValue )
13771382
); #loc()
13781383
}
13791384
}

lib/RT/Transactions.pm

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,48 @@ sub _TicketLimit {
876876
}
877877
}
878878

879+
# Handle date fields specially for = operator with date-only values
880+
if ( $field =~ /^(?:Created|Started|Resolved|Told|LastUpdated|Starts|Due)$/ ) {
881+
my $date = RT::Date->new( $self->CurrentUser );
882+
$date->Set( Format => 'unknown', Value => $value );
883+
884+
if ( $op eq '=' && $date->IsSet ) {
885+
# For = operator, convert date-only values to a range query
886+
# to match all records from that day (midnight to midnight)
887+
$date->SetToMidnight( Timezone => 'user' );
888+
my $daystart = $date->ISO;
889+
$date->AddDay;
890+
my $dayend = $date->ISO;
891+
892+
$self->_OpenParen;
893+
894+
$self->Limit(
895+
%rest,
896+
ALIAS => $self->_JoinTickets,
897+
FIELD => $field,
898+
OPERATOR => '>=',
899+
VALUE => $daystart,
900+
CASESENSITIVE => 0,
901+
);
902+
903+
$self->Limit(
904+
%rest,
905+
ALIAS => $self->_JoinTickets,
906+
FIELD => $field,
907+
OPERATOR => '<',
908+
VALUE => $dayend,
909+
CASESENSITIVE => 0,
910+
ENTRYAGGREGATOR => 'AND',
911+
);
912+
913+
$self->_CloseParen;
914+
return;
915+
}
916+
elsif ( $date->IsSet ) {
917+
$value = $date->ISO;
918+
}
919+
}
920+
879921
$self->Limit(
880922
%rest,
881923
ALIAS => $self->_JoinTickets,

share/html/Elements/RT__Transaction/ColumnMap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ my $COLUMN_MAP = {
134134
title => 'Ticket Queue', # loc
135135
value => $get_ticket_value->( @_, sub { $_[0]->Object->QueueObj->Name } ),
136136
},
137+
TicketStatus => {
138+
title => 'Ticket Status', # loc
139+
value => $get_ticket_value->( @_, sub { $_[0]->Object->Status } ),
140+
},
137141
TicketOwner => {
138142
title => 'Ticket Owner', # loc
139143
value => $get_ticket_value->( @_, sub { $_[0]->Object->OwnerObj->Name } ),

t/transaction/search.t

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,86 @@ is( $txns->Count, 1, 'Found the txn with id limit' );
136136
$txns->FromSQL("id > 10000");
137137
is( $txns->Count, 0, 'No txns with big ids yet' );
138138

139+
diag 'Test TicketResolved date search';
140+
{
141+
# Create tickets with different resolved dates
142+
my $ticket1 = RT::Ticket->new( RT->SystemUser );
143+
my ($id1) = $ticket1->Create(
144+
Queue => 'General',
145+
Subject => 'Resolved yesterday',
146+
Status => 'resolved',
147+
);
148+
ok( $id1, 'Created ticket 1' );
149+
150+
my $ticket2 = RT::Ticket->new( RT->SystemUser );
151+
my ($id2) = $ticket2->Create(
152+
Queue => 'General',
153+
Subject => 'Resolved 5 days ago',
154+
Status => 'resolved',
155+
);
156+
ok( $id2, 'Created ticket 2' );
157+
158+
my $ticket3 = RT::Ticket->new( RT->SystemUser );
159+
my ($id3) = $ticket3->Create(
160+
Queue => 'General',
161+
Subject => 'Resolved 10 days ago',
162+
Status => 'resolved',
163+
);
164+
ok( $id3, 'Created ticket 3' );
165+
166+
# Set different resolved dates using _Set to bypass normal date handling
167+
# Set to noon on each day to ensure they have a time component
168+
my $yesterday = RT::Date->new( RT->SystemUser );
169+
$yesterday->SetToNow;
170+
$yesterday->AddDays(-1);
171+
$yesterday->SetToMidnight( Timezone => 'UTC' );
172+
$yesterday->AddSeconds( 12 * 60 * 60 ); # noon
173+
174+
my $five_days_ago = RT::Date->new( RT->SystemUser );
175+
$five_days_ago->SetToNow;
176+
$five_days_ago->AddDays(-5);
177+
$five_days_ago->SetToMidnight( Timezone => 'UTC' );
178+
$five_days_ago->AddSeconds( 12 * 60 * 60 ); # noon
179+
180+
my $ten_days_ago = RT::Date->new( RT->SystemUser );
181+
$ten_days_ago->SetToNow;
182+
$ten_days_ago->AddDays(-10);
183+
$ten_days_ago->SetToMidnight( Timezone => 'UTC' );
184+
$ten_days_ago->AddSeconds( 12 * 60 * 60 ); # noon
185+
186+
# Update resolved dates directly
187+
$ticket1->_Set( Field => 'Resolved', Value => $yesterday->ISO );
188+
$ticket2->_Set( Field => 'Resolved', Value => $five_days_ago->ISO );
189+
$ticket3->_Set( Field => 'Resolved', Value => $ten_days_ago->ISO );
190+
191+
# Test searching with just a date (no time) using = operator
192+
my $yesterday_date = $yesterday->Date; # Just YYYY-MM-DD
193+
$txns = RT::Transactions->new( RT->SystemUser );
194+
$txns->FromSQL(qq{ObjectType = 'RT::Ticket' AND Type = 'Create' AND TicketId = $id1 AND TicketResolved = '$yesterday_date'});
195+
is( $txns->Count, 1, "TicketResolved = '$yesterday_date' (date only) finds ticket resolved on that day" );
196+
197+
# Also test with 5 days ago date
198+
my $five_days_date = $five_days_ago->Date;
199+
$txns->FromSQL(qq{ObjectType = 'RT::Ticket' AND Type = 'Create' AND TicketId = $id2 AND TicketResolved = '$five_days_date'});
200+
is( $txns->Count, 1, "TicketResolved = '$five_days_date' (date only) finds ticket resolved on that day" );
201+
202+
# Test searching with full datetime using = operator
203+
my $yesterday_datetime = $yesterday->ISO; # YYYY-MM-DD HH:MM:SS
204+
$txns->FromSQL(qq{ObjectType = 'RT::Ticket' AND Type = 'Create' AND TicketId = $id1 AND TicketResolved = '$yesterday_datetime'});
205+
is( $txns->Count, 1, "TicketResolved = '$yesterday_datetime' (datetime) finds ticket with exact match" );
206+
207+
my $five_days_datetime = $five_days_ago->ISO;
208+
$txns->FromSQL(qq{ObjectType = 'RT::Ticket' AND Type = 'Create' AND TicketId = $id2 AND TicketResolved = '$five_days_datetime'});
209+
is( $txns->Count, 1, "TicketResolved = '$five_days_datetime' (datetime) finds ticket with exact match" );
210+
211+
# Test that > and < operators still work with dates
212+
$txns->FromSQL(qq{ObjectType = 'RT::Ticket' AND Type = 'Create' AND TicketId = $id1 AND TicketResolved > '$five_days_date'});
213+
is( $txns->Count, 1, "TicketResolved > '$five_days_date' finds ticket resolved after that date" );
214+
215+
$txns->FromSQL(qq{ObjectType = 'RT::Ticket' AND Type = 'Create' AND TicketId = $id3 AND TicketResolved < '$five_days_date'});
216+
is( $txns->Count, 1, "TicketResolved < '$five_days_date' finds ticket resolved before that date" );
217+
}
218+
139219
diag 'Test HTML::Mason::Commands::PreprocessTransactionSearchQuery';
140220

141221
my %processed = (

t/web/search_txns.t

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,17 @@ diag "Saved searches";
108108
);
109109
}
110110

111+
diag "TicketStatus in Format";
112+
{
113+
# TicketStatus is supported in the query but should also work in Format
114+
$m->get_ok(
115+
"/Search/Results.html?Class=RT::Transactions"
116+
. "&Query=TicketId=" . $ticket->id . "+AND+Type='Create'"
117+
. "&Format='__id__','__TicketSubject__','__TicketStatus__'"
118+
);
119+
$m->title_is('Found 1 transaction');
120+
$m->text_contains('Test ticket', 'TicketSubject is displayed');
121+
$m->text_contains('open', 'TicketStatus is displayed');
122+
}
123+
111124
done_testing;

0 commit comments

Comments
 (0)