Hi All,
We are looking to develop a feature whereby we can display for support staff, a list of products that a customer has, what type of support plan they are on, etc. So that when the staff pull up a ticket it can influence what kind of support to give them.
What I need to figure out is: How can I take custom field values that I store in an RT user, and display those when rendering either the ticket display or update pages.
Or more specifically right now, I am struggling to figure out how to access the TicketObj or TransactionObj from the Ticket/Update.html/BeforeMessageBox callback.
We already have a mechanism whereby each customer is a user in RT, and we can store customer-wide data in there. And we already have a mechanism whereby there is a “Customer” custom field on ticket transactions that link the ticket to the relevant customer user. I am just not sure how to go about using that relationship to display info on the pages.
I think that using a Callback is my preferred approach, but I’ve tried using them and I’m not sure how to get started to access a user object via a callback.
Another approach idea I had was to simply add a read-only custom field to the ticket, and use a scrip to find the related customer, pull the info, and populate it in the field on ticket creation/update. And just rely on these read-only fields. But that seems overly clunky, and I’d really like to leverage callbacks so I can do custom formatting of the fields, add colour, etc.
Thanks!
Rhys.
OK I have a proof of concept mostly happening based on docs and examples I’ve found, but I have two major issues:
-
When there is a bug in the code the page goes blank, and I get no errors in the web server logs like I would with scrips. My RT logging and web server logs are set to debug verbosity. Where can I find these errors to debug properly?
-
Trying to use $RT::Logger
seems to be breaking the callback code entirely. How can I add logging to my callback without breaking things?
Here’s what I have so far. I wasn’t able to figure out how to access the ticket object, only the ticket ID. So I loaded the ticket object again, and went from there.
%# We are displaying a message box if the timeWorked for a customer is near or at their limit
%# See example: https://wiki.gentoo.org/wiki/Request_Tracker/Password_Reset
%# See example: https://rt-wiki.bestpractical.com/wiki/ShowPerQueueInstructions
%# See example: https://rt-wiki.bestpractical.com/wiki/ToggleCFs
<div class="error" style="text-align: left;">
<div class="titlebox error">
<div class="titlebox-title">
<span class="left">Billable Time Alert</span>
<span class="right-empty"> </span>
</div>
<div class="titlebox-content">
<% $msg %>
<hr class="clear" />
</div>
</div>
</div>
<%INIT>
# This is the name of the Ticket Customer custom field
my $cf_customer_name = "Customer";
# This is the name of the User Billable custom field
my $cf_customer_billable = "Billable";
my $msg = "";
my $ticket = LoadTicket($ARGS{'id'});
# Pull the customer name from the ticket
my $customer_name = $ticket->FirstCustomFieldValue($cf_customer_name);
if ($customer_name eq undef)
{
$customer_name = "";
}
# Based on that, find the relevant customer user
my $users = RT::Users->new($RT::SystemUser);
$users->LimitToPrivileged();
# Try and find matching RT User object
my $customer_user = undef;
while (my $user = $users->Next)
{
if ($user->RealName() eq $customer_name)
{
$customer_user = $user;
last;
}
}
# No user found
if ($customer_user eq undef)
{
#$RT::Logger->info($scrip . "Unable to find RT user for " . $customer_name);
return;
}
# Then pull the billable CF from the user.
my $billable = "";
my $cf_billable_value = $customer_user->FirstCustomFieldValue($cf_customer_billable);
if ($cf_billable_value ne 'Yes')
{
$billable = "No";
}
else
{
$billable = "Yes";
}
$msg = "This customer (".$customer_name.") has reached their maximum billable time for the month. Billable: ".$billable;
</%INIT>
<%args>
$CustomFields => undef
$ARGS => undef
$Object => undef
</%args>
You don’t need the dollar in front of the RT::Logger->info
call. Try removing that and then see what output you get.
Yes! Thank you, my callback no longer breaks with the logging statements. But I still don’t get any logs. I realised I am not seeing my scrips in the logs either.
I think that the logs are no longer working how I remember - so that’s for me to figure out. BUT - in your experience, should the call back logging be found in the same location as the scrip logs are?
We are using nginx with perl-fcgi and I just realised I don’t remember where it logs RT stuff to. I’m just hoping if I can find the scrip log entries, that the callback logs will be there.
Ah fantastic, just found the log entries - can confirm that scrip and callback logging is in the same spot. In my case, syslog.
root@rt4:/opt/rt4# grep -r "BillableTimeAlert#" /var/log/*
/var/log/syslog:Apr 14 19:13:27 rt4 RT: [19970] BillableTimeAlert#54214: Unable to find RT user for XX
One more question: How can I pass info around between multiple callbacks? I know some callbacks pass this in via arguments, but what about the ones that don’t, like “BeforeMessageBox”?
For example, in my current code that I’ve pasted here, I could only figure out how to access the ticket ID and so reloaded the entire ticket object. Surely there must be a way to execute logic via a callback and store a variable “globally” on the page so other callbacks can then access it? Or is this the only way to do it?
If I have multiple callbacks on a page it doesn’t make sense to have to re-load the same objects multiple times.
Thanks all!