Tickets unlock even if there is no new message

When an agent has replied to a client with an e-mail message the ticket becomes locked. We have set an unlock timeout of 480 minutes (8 hours) so that when a customer replies to a ticket that is locked it becomes unlocked. The strange thing is that the ticket gets unlocked even if the client has not replied, i.e. there is no new message with this ticket. After the agent has written and sent his reply the ticket will be unlocked after 480 minutes unconditionally. This does not seem right. Is this a configuration option? Regards, Jurgen de Wijs

Hmm it does exactly what it's supposed to do. After inactivity of 480 minutes it gets unlocked. Why do you want to unlock a ticket when a client sends another e-mail? Maybe you are looking for pending status? To close a ticket if a client did not respond within 8 hours? Regards, Richard Jurgen de Wijs wrote:
When an agent has replied to a client with an e-mail message the ticket becomes locked.
We have set an unlock timeout of 480 minutes (8 hours) so that when a customer replies to a ticket that is locked it becomes unlocked.
The strange thing is that the ticket gets unlocked even if the client has not replied, i.e. there is no new message with this ticket. After the agent has written and sent his reply the ticket will be unlocked after 480 minutes unconditionally. This does not seem right.

Richard Hinkamp - BeSite schreef:
Hmm it does exactly what it's supposed to do. After inactivity of 480 minutes it gets unlocked. Why do you want to unlock a ticket when a client sends another e-mail? Maybe you are looking for pending status? To close a ticket if a client did not respond within 8 hours? I am looking for this situation:
* ticket is openened * agent sends a reply to ticket and herewith locks the ticket * client replies only after 5 days or so * agent with ticket locked shall receive notification * If agent is on holiday or on business trip the ticket shall be unlocked 1 day after receipt of the client reply * Message moved back in queue and message is sent to all team members indicating that something must be done. I though ticket unlock was the solution for this but appearantly it is not. Should i try to do this with a generic agent or is there another possibility? Best regards, Jurgen de Wijs

Hi Jurgen,
I am looking for this situation:
* ticket is openened * agent sends a reply to ticket and herewith locks the ticket * client replies only after 5 days or so * agent with ticket locked shall receive notification * If agent is on holiday or on business trip the ticket shall be unlocked 1 day after receipt of the client reply * Message moved back in queue and message is sent to all team members indicating that something must be done.
I though ticket unlock was the solution for this but appearantly it is not. Should i try to do this with a generic agent or is there another possibility?
Ticket unlock count does not start on a new message, but when the lock starts, so it's not what you're looking for. I don't know if there's a way to accomplish this, never tried. Generic Agent may be the correct approach. Regards, Richard

Hi Juergen, Richard Hinkamp - BeSite schrieb:
Hi Jurgen,
I am looking for this situation:
* ticket is openened * agent sends a reply to ticket and herewith locks the ticket * client replies only after 5 days or so * agent with ticket locked shall receive notification * If agent is on holiday or on business trip the ticket shall be unlocked 1 day after receipt of the client reply * Message moved back in queue and message is sent to all team members indicating that something must be done.
I though ticket unlock was the solution for this but appearantly it is not. Should i try to do this with a generic agent or is there another possibility?
Ticket unlock count does not start on a new message, but when the lock starts, so it's not what you're looking for.
Richard is right.
I don't know if there's a way to accomplish this, never tried. Generic Agent may be the correct approach.
This approach should work fine: * tickets should get a new state after an incoming and not yet processed customer follow-up. * if a agent acts upon an follow-up, the state must change (e.g. to open) * create a generic agent job that searches for all locked tickets with that specific state * parse these tickets to your own written generic agent module. This module checks the age of the customer-followup and unlocks the ticket if it is older than 1 day. Very-very-small instructions for writing such a module: * make a copy of ~/Kernel/System/GenericAgent/AutoPriorityIncrease.pm * edit this copy to not increase the priority but to do the unlocks if necessary It's not really much work if you know where to do it. Bye, Alex

Alexander Scholler schreef:
Hi Juergen,
This approach should work fine: * tickets should get a new state after an incoming and not yet processed customer follow-up. Is this something you can configure in OTRS or is that where I have to write my own module for? * if a agent acts upon an follow-up, the state must change (e.g. to open) I think that this is standard functionality. Am I right? * create a generic agent job that searches for all locked tickets with that specific state Search for tickets with new state that are locked. Am I right? * parse these tickets to your own written generic agent module.
This module should process all these tickets, unlock tickets that are longer than 1 day in new state and send an unlock notification to all agents that are subscribed to the queue where the ticket is in.
This module checks the age of the customer-followup and unlocks the ticket if it is older than 1 day.
Very-very-small instructions for writing such a module: * make a copy of ~/Kernel/System/GenericAgent/AutoPriorityIncrease.pm * edit this copy to not increase the priority but to do the unlocks if necessary
It's not really much work if you know where to do it. I guess not. I am not so much of a Perl expert myself. I will have a look at the pointers you gave me. Many thanks. May I contact you directly for some more detailed questions?
Regards, Jurgen de Wijs

Hi Jurgen, Jurgen de Wijs schrieb:
Alexander Scholler schreef:
Hi Juergen,
This approach should work fine: * tickets should get a new state after an incoming and not yet processed customer follow-up. Is this something you can configure in OTRS or is that where I have to write my own module for? It can be configured => PostmasterFollowUpState I set it to "new - extended", a new state of type "new" I added to OTRS with "System > States"-setup.
* if a agent acts upon an follow-up, the state must change (e.g. to open) I think that this is standard functionality. Am I right?
When an agent replies to a follow-up by sending e.g. a mail-answer, he has to select a new state which is a state unequal to state-type new. So on my installation, the state is changed.
* create a generic agent job that searches for all locked tickets with that specific state Search for tickets with new state that are locked. Am I right?
Right.
* parse these tickets to your own written generic agent module.
This module should process all these tickets, unlock tickets that are longer than 1 day in new state and send an unlock notification to all agents that are subscribed to the queue where the ticket is in.
This module checks the age of the customer-followup and unlocks the ticket if it is older than 1 day.
Very-very-small instructions for writing such a module: * make a copy of ~/Kernel/System/GenericAgent/AutoPriorityIncrease.pm * edit this copy to not increase the priority but to do the unlocks if necessary
It's not really much work if you know where to do it. I guess not. I am not so much of a Perl expert myself. I will have a look at the pointers you gave me. Many thanks. May I contact you directly for some more detailed questions?
You can contact me directly, but remember that many of the things discussed between you and me could be interested for the community.
Regards, Jurgen de Wijs
Bye, Alex

Dear Alexander Alexander Scholler schreef:
It can be configured => PostmasterFollowUpState I set it to "new - extended", a new state of type "new" I added to OTRS with "System > States"-setup.
I have configured an additional state "new followup" and when a followup is received for an existing ticket it gets this state.
* create a generic agent job that searches for all locked tickets with that specific state Search for tickets with new state that are locked. Am I right?
Right.
I have created a GenericAgent job that does just that. When you modify it it will give you a list of the tickets affected. That works fine.
Very-very-small instructions for writing such a module: * make a copy of ~/Kernel/System/GenericAgent/AutoPriorityIncrease.pm * edit this copy to not increase the priority but to do the unlocks if necessary
I have modified the module as you suggested. I have attached the module to this message. It unlocks tickets that are locked and in state "new followup" for a configurable duration. It takes working time into account. This all works fine. I have only one problem left. I have also copied a piece of code from the NotifyAgentGroupofCustomQueue module to send a "followup" notification to all agents that are subscribed to the queue the unlocked ticket is in. When I run the generic agent I get the following error message in the web-browser window: Software error: Can't call method "GetUserData" on an undefined value at ../..//Kernel/System/GenericAgent/UnlockAfterFollowup.pm line 110. I am not sure what is going wrong here. Can you give me a tip? Many thanks for your help so far. Regards, Jurgen # -- # Kernel/System/GenericAgent/UnlockAfterFollowup.pm # -- package Kernel::System::GenericAgent::UnlockAfterFollowup; use strict; use vars qw(@ISA $VERSION); $VERSION = '$Revision: 1.0 $'; $VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/; # -- sub new { my $Type = shift; my %Param = @_; # allocate new hash for object my $Self = {}; bless ($Self, $Type); # check needed objects foreach (qw(DBObject ConfigObject LogObject TicketObject TimeObject)) { $Self->{$_} = $Param{$_} || die "Got no $_!"; } # 0=off; 1=on; $Self->{Debug} = $Param{Debug} || 0; return $Self; } # -- sub Run { my $Self = shift; my %Param = @_; my $Update = 0; my $LatestUpdate = 0; my $CountedTime; # check needed param if (!$Param{New}->{"TimeInterval"}) { $Self->{LogObject}->Log( Priority => 'error', Message => "Need TimeInterval param for GenericAgent module!", ); return; } else { $Param{New}->{"TimeInterval"} = $Param{New}->{"TimeInterval"} * 60; } # get ticket data my %Ticket = $Self->{TicketObject}->TicketGet(%Param); # find latest change date in ticket $LatestUpdate = $Ticket{Changed}; # Convert latest change date into System time format $LatestUpdate = $Self->{TimeObject}->TimeStamp2SystemTime( String => $LatestUpdate, ); # Calculate the duration since last change in working time only $CountedTime = $Self->{TimeObject}->WorkingTime( StartTime => $LatestUpdate, StopTime => $Self->{TimeObject}->SystemTime(), ); $Self->{LogObject}->Log( Priority => 'debug', Message => "CountedTime = $CountedTime", ); # If duration exceeds maximum lock duration then ticket must be unlocked if ($CountedTime > $Param{New}->{"TimeInterval"}) { $Update = 1; } # check if ticket needs to be unlocked if (!$Update) { # do nothing if ($Self->{Debug}) { $Self->{LogObject}->Log( Priority => 'debug', Message => "Nothing to do on (Ticket=$Ticket{TicketNumber}/TicketID=$Ticket{TicketID})!", ); } return 1; } else { # unlock ticket $Self->{TicketObject}->LockSet( Lock => 'Unlock', TicketID => "$Ticket{TicketID}", UserID => "$Ticket{UserID}", ); # log message $Self->{LogObject}->Log( Priority => 'notice', Message => "Ticket=$Ticket{TicketNumber}/TicketID=$Ticket{TicketID} unlocked due to agent inactivity!", ); # get agentss who are sucscribed the ticket queue to the custom queues my @UserIDs = $Self->{TicketObject}->GetSubscribedUserIDsByQueueID( QueueID => $Ticket{QueueID}, ); # send each agent the unlock notification foreach (@UserIDs) { $Self->{LogObject}->Log( Priority => 'notice', Message => "UserID = $_", ); my %User = $Self->{UserObject}->GetUserData(UserID => $_); # send agent notification $Self->{TicketObject}->SendAgentNotification( Type => 'FollowUp', UserData => \%User, CustomerMessageParams => \%Param, TicketID => $Ticket{TicketID}, UserID => 1, ); }; return 1; } } # -- 1;

Hi Jurgen, great that you managed to write your of generic agent module. After knowing how it works, you are able to customize OTRS to your very special needs, never thought before of being able to realize this. I think OTRS is really great.
I have only one problem left. I have also copied a piece of code from the NotifyAgentGroupofCustomQueue module to send a "followup" notification to all agents that are subscribed to the queue the unlocked ticket is in.
When I run the generic agent I get the following error message in the web-browser window:
Software error: Can't call method "GetUserData" on an undefined value at ../..//Kernel/System/GenericAgent/UnlockAfterFollowup.pm line 110.
Why line 110 - this is an empty line?
I am not sure what is going wrong here. Can you give me a tip?
I don't know perl quite well, but let me try: The problem can only be in # send each agent the unlock notification foreach (@UserIDs) { ## I think it works, but I would prefer ## foreach $UserID (@UserIDs) ## and use $UserID instead of $_ in the following lines $Self->{LogObject}->Log( Priority => 'notice', Message => "UserID = $_", ); ## does the logging give you the correct data ## I think UserObject is not initialized ## ====> you have to add it in qw(...) in line 23 my %User = $Self->{UserObject}->GetUserData(UserID => $_); # send agent notification $Self->{TicketObject}->SendAgentNotification( Type => 'FollowUp', UserData => \%User, ## I don't know what has to be set on CustomerMessageParams ## Is it really \%Param? CustomerMessageParams => \%Param, TicketID => $Ticket{TicketID}, UserID => 1, ); };
Many thanks for your help so far.
Regards, Jurgen
Let me know when you generate further modules for OTRS. Bye, Alex

Hi Alexander Alexander Scholler schreef:
Hi Jurgen,
great that you managed to write your of generic agent module. After knowing how it works, you are able to customize OTRS to your very special needs, never thought before of being able to realize this. I think OTRS is really great.
I must admit that this OTRS can do more than I had imagined. Also the way you can customize using the GenenericAgent is elegant and powerfull.
I don't know perl quite well, but let me try:
## I think UserObject is not initialized ## ====> you have to add it in qw(...) in line 23 my %User = $Self->{UserObject}->GetUserData(UserID => $_);
I cracked it. I forgot to initialize the UserObject. My module works now!
Let me know when you generate further modules for OTRS.
I have no plans to develop further modules. But you wil never know :) Many thanks for your help. Cheers, Jurgen

Jurgen de Wijs wrote:
When an agent has replied to a client with an e-mail message the ticket becomes locked.
We have set an unlock timeout of 480 minutes (8 hours) so that when a customer replies to a ticket that is locked it becomes unlocked.
The strange thing is that the ticket gets unlocked even if the client has not replied, i.e. there is no new message with this ticket. After the agent has written and sent his reply the ticket will be unlocked after 480 minutes unconditionally. This does not seem right.
It does seem right to me. The documentation seems to agree: http:// doc.otrs.org/2.0/en/html/x1362.html Nils Breunese.

Jurgen de Wijs wrote:
When an agent has replied to a client with an e-mail message the ticket becomes locked.
We have set an unlock timeout of 480 minutes (8 hours) so that when a customer replies to a ticket that is locked it becomes unlocked.
The strange thing is that the ticket gets unlocked even if the client has not replied, i.e. there is no new message with this ticket. After the agent has written and sent his reply the ticket will be unlocked after 480 minutes unconditionally. This does not seem right.
It does seem right to me. The documentation seems to agree: http:// doc.otrs.org/2.0/en/html/x1362.html Nils Breunese.
participants (4)
-
Alexander Scholler
-
Jurgen de Wijs
-
Nils Breunese
-
Richard Hinkamp - BeSite