Подтверждение решения заявки

Обсуждение вопросов и решений

Модератор: ykolesnikov

Ответить
dalfos
OTRS Новобранец
Сообщения: 8
Зарегистрирован: 11 ноя 2011, 15:36

Подтверждение решения заявки

Сообщение dalfos » 12 фев 2012, 10:49

Подскажите, пожалуйста, как лучше реализовать следующие, в каждой очереди должен быть руководитель и только он может принимать окончательное решение о том, выполнены ли работы по заявке в полном объеме?

yuri0001
OTRS Бывалый
Сообщения: 492
Зарегистрирован: 11 фев 2011, 20:25
Откуда: Череповец

Re: Подтверждение решения заявки

Сообщение yuri0001 » 12 фев 2012, 12:18

В http://doc.otrs.org/3.0/ru/html/acl.html есть Пример 18.2. Списки прав доступа (ACL) делают невозможным закрытие заявок в очереди raw и скрывают кнопку "закрыть". Можно взять за образец и попытаться изобразить свою идею, например к каждой из очередей сделать подочередь - "На закрытие" и только там иметь кнопку "Закрыть" для заявок. Права в ней должен иметь только тот, кому дано право закрывать, остальные только читать и перемещать в неё заявки. По окончании работы агент пересылает заявку в эту очередь с заметкой об окончании работы, а руководитель принимает решение и закрывает или отправляет обратно на доработку. Это как вариант.
Еще один вариант, но его надо проверять состоит в том, чтобы по аналогии с параметром SysConfig in Ticket -> Frontend::Agent::Ticket::MenuModule Ticket::Frontend::MenuModule###460-Delete внести в параметр Ticket::Frontend::MenuModule###450-Close атрибут Group и задать там имена групп агентов имеющих право закрывать заявку (предварительно, ее надо создать). Тогда по идее кнопка "Закрыть" будет только у этих агентов в меню заявки. Но это идея, не пробовал. Чтобы это сделать, надо кликнуть по "+" под табличкой параметров - появится новая строка и создать пару Group в колонке Ключ и что-то типа rw:Ticket-Manager;rw:admin (здесь Ticket-Manager и admin - имена групп) в колонке Содержание - это описано в комментарии к параметру Ticket::Frontend::MenuModule###460-Delete.
Попробуйте. Если получится и нам сообщите. ;)
С уважением
Ю. Колесников
OTRS 3.3.1, ITSM 3.3.1, SUSE 12, MySQL5

dalfos
OTRS Новобранец
Сообщения: 8
Зарегистрирован: 11 ноя 2011, 15:36

Re: Подтверждение решения заявки

Сообщение dalfos » 03 окт 2012, 16:35

проблему решил следующим образом:
у меня есть статусы Решена удачно, Решена неудачно и т.д. и соответствующие им Закрыта удачно, Закрыта неудачно. Все эти статусы имеют тип "Закрыта",
то есть заявки не отображаются в очереди.
Статусы "Решена *" могут выставлять любые агенты.
Статусы "Закрыты *" могут выставлены только модератором очереди. Модераторы очереди находят заявки, решение которых нужно подтвердить, через шаблон поиска.
Ограничил доступ к статусам "Закрыта *" с помощью написанного мной модуля Kernel::System::Ticket::Acl::TicketClose,
который определяет является ли текущий агент модератором очереди.

vetedie
OTRS Новобранец
Сообщения: 17
Зарегистрирован: 09 сен 2012, 19:09

Re: Подтверждение решения заявки

Сообщение vetedie » 10 окт 2012, 17:07

Уважаемый Dalfos - не могли бы поделиться кодом данного модуля, потому что такая же проблема актуальна и у меня.

dalfos
OTRS Новобранец
Сообщения: 8
Зарегистрирован: 11 ноя 2011, 15:36

Re: Подтверждение решения заявки

Сообщение dalfos » 11 окт 2012, 09:37

Вот для примера. У меня на каждую очередь свой начальник и прописан он в коде модуля, возможно в коде прописывать не лучший вариант, но другого решения не нашел. И в принципе это редкий случай изменение начальника очереди.
Еще у меня реализована такая функция, если начальник очереди (Agent1) отсутствует, т.е. он в личном кабинете поставил галочку отсутствия офиса, то в выбранное им время его отсутствие его права на статусы "Закрыта" переходят его заместителю (Agent2).

Код: Выделить всё

# --
# Kernel/System/Ticket/Acl/TicketClose.pm - acl module
# --

package Kernel::System::Ticket::Acl::TicketClose;

use strict;
use warnings;
use utf8;


use vars qw($VERSION);
$VERSION = qw($Revision: 1.0 $) [1];

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {};
    bless( $Self, $Type );

    # get needed objects
    for (
        qw(ConfigObject DBObject TicketObject LogObject UserObject CustomerUserObject MainObject TimeObject EncodeObject)
        )
    {
        $Self->{$_} = $Param{$_} || die "Got no $_!";
    }

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;

    # check needed stuff
    for (qw(Config Acl)) {
        if ( !$Param{$_} ) {
            $Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" );
            return;
        }
    }
    
    return 1 if !$Param{TicketID} || !$Param{UserID};
    
    my %Ticket = $Self->{TicketObject}->TicketGet(
        TicketID => $Param{TicketID},
        UserID   => $Param{UserID},
        DynamicFields => 0,
    );
    return if !%Ticket;
    

    #Начало обработки статусов "Закрыта *"
    my $valid = 0; #по-умолчанию 0 - для всех агентов статусы недоступны
    my $Agent1    =   $Self->{UserObject}->UserLookup(UserLogin => 'Agent1');
    my $Agent2   =   $Self->{UserObject}->UserLookup(UserLogin => 'Agent2');

    if ($Ticket{State} =~ m/^Решена/)
    {
        #"Инцидент"
        if ($Ticket{Type} eq 'Инцидент')
        {
            if ($Ticket{Queue} eq 'Дежурная смена')
            {
                my %User = $Self->{UserObject}->GetUserData( UserID => $Agent1 );
                $Agent1 =  $Agent2 if ($User{OutOfOffice} && $User{OutOfOfficeMessage});
                $valid = 1 if ($Param{UserID} == $Agent1);
            }
        }

        #"Проблема" и "Запрос на изменение"
        if (($Ticket{Type} eq 'Проблема')||($Ticket{Type} eq 'Запрос на изменение'))
        {
            if ($Ticket{Queue} eq 'Отдел эксплуатации')
            {
                my %User = $Self->{UserObject}->GetUserData( UserID => $Agent1 );
                $Agent1 =  $Agent2 if ($User{OutOfOffice} && $User{OutOfOfficeMessage});
                $valid = 1 if ($Param{UserID} == $Agent1);
            }
        }
    }
    
    
    if (!$valid)
    {
        $Param{Acl}->{TicketClose} = {
            # match properties
            Properties => {
                User => {
                    UserID => [ $Param{UserID} ],
                },
                # current ticket match properties
                Ticket => {
                    TicketID => [ $Param{TicketID} ],
                },
                
            },
            # return possible options (black list)
            PossibleNot => {
                # possible ticket options (black list)
                Ticket => {
                    State => ['[RegExp]^Закрыта'],
                },
            },
        };
    }

    #$Self->{LogObject}->Log( Priority => 'notice', Message => "Hello World! $Ticket{Queue}" );
    return 1;
}

1;

Ответить