Редактирование трудозатрат

Только для готовых решений! Пожалуйста, не используйте для вопросов и обсуждений!

Модератор: ykolesnikov

Ответить
alex.t
OTRS Новобранец
Сообщения: 30
Зарегистрирован: 29 апр 2018, 09:26
Благодарил (а): 1 раз
Поблагодарили: 9 раз

Редактирование трудозатрат

Сообщение alex.t » 02 янв 2020, 18:32

Добрый день!
При работе агенты могут не верно внести трудозатраты по тикету или забыть внести их например за предыдущий день.
Модуль позволяет редактировать агенту трудозатраты, причем только свои)
Работает на OTRS 5.

1. Создаем файл AccountingTimeEdit.xml, закидываем в папку otrs/Kernel/Config/Files:

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

<?xml version="1.0" encoding="iso-8859-1"?>
<otrs_config version="1.0" init="Application">
    <ConfigItem Name="Ticket::Frontend::MenuModule###AccountingTimeEdit" Required="0" Valid="1">
        <Description Translatable="1">Edit accounting time.</Description>
        <Group>AccountingTimeEdit</Group>
        <SubGroup>Frontend::Agent::Ticket::MenuModule</SubGroup>
        <Setting>
            <Hash>
                <Item Key="Module">Kernel::Output::HTML::TicketMenu::Generic</Item>
                <Item Key="Name" Translatable="0">Accounting Time Edit</Item>
                <Item Key="Description" Translatable="0">Accounting Time Edit</Item>
                <Item Key="Action"></Item>
                <Item Key="Link">Action=TicketAccountingTimeEdit;TicketID=[% Data.TicketID | html %];</Item>
                <Item Key="LinkParam"></Item>
                <Item Key="Target"></Item>
                <Item Key="PopupType">TicketAction</Item>
            </Hash>
        </Setting>
    </ConfigItem>

    <ConfigItem Name="Frontend::Module###TicketAccountingTimeEdit" Required="1" Valid="1">
        <Description Translatable="1">Module edit accounting time.</Description>
        <Group>Ticket</Group>
        <SubGroup>Core::Ticket</SubGroup>
        <Setting>
            <Hash>
                <Item Key="Module">Kernel::Modules::TicketAccountingTimeEdit</Item>
            </Hash>
        </Setting>
    </ConfigItem>
</otrs_config>
2. Создаем файл TicketAccountingTimeEdit.pm, закидываем в папку otrs/Custom/Kernel/Modules:

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

package Kernel::Modules::TicketAccountingTimeEdit;

use strict;
use warnings;

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

    my $Self = {%Param};
    bless( $Self, $Type );

    return $Self;
}

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

    my $LayoutObject  = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
    my $ParamObject   = $Kernel::OM->Get('Kernel::System::Web::Request');
    my $UserObject    = $Kernel::OM->Get('Kernel::System::User');
    my $DBO           = $Kernel::OM->Get('Kernel::System::DB');

    my %GetParam;

    $GetParam{ TicketID } = $ParamObject->GetParam( Param => 'TicketID' );     

    if ( $Self->{Subaction} eq 'Change' ) {

        my @ParamNames = $ParamObject->GetParamNames();
        
        foreach my $ArticleID ( grep /^ArticleID/, @ParamNames ) {

            if ( $ArticleID =~ /^ArticleID(\d+)/ ) {

                my $AccountingTime = $ParamObject->GetParam( Param => 'Time'.$1 );
                my $CreateByID     = $ParamObject->GetParam( Param => 'CreateByID'.$1 );
                my $ArticleID      = $1;

                if ( $ArticleID ) {

                    my $Check = $Self->Check( $ArticleID );

                    if ( $Check ) { 
                        $DBO->Do( SQL => "UPDATE time_accounting SET TIME_UNIT = '$AccountingTime' WHERE article_id = $ArticleID" );
                    }
                    else {
                        $DBO->Do(
                            SQL => "INSERT INTO time_accounting ( ticket_id, article_id, time_unit, create_time, create_by, change_time, change_by ) 
                                    VALUES ( ?, ?, ?, current_timestamp, ?, current_timestamp, ? )",
                            Bind => [ \$GetParam{ TicketID }, \$ArticleID, \$AccountingTime, \$CreateByID, \$CreateByID ],
                        );                        
                    }
                } 
            }
        }   
        return $LayoutObject->PopupClose( Reload => 1 );   
    }

    $DBO->Prepare(
        SQL => "SELECT a.ID, at.ID, at.TIME_UNIT, a.CREATE_BY, a.CREATE_TIME  
                FROM article a
                LEFT JOIN time_accounting at ON at.ARTICLE_ID = a.ID
                WHERE a.TICKET_ID = $GetParam{ TicketID }
                AND a.ARTICLE_SENDER_TYPE_ID = 1
                AND a.CREATE_BY <> 1",
        Limit => 1000,
    );

    my %UserTimeUnit;
    while ( my @Row = $DBO->FetchrowArray() ) {       

        my %User = $UserObject->GetUserData( UserID => $Row[3] );

        $UserTimeUnit{ "$User{ UserFirstname } $User{ UserLastname }" } += int $Row[2];

        $LayoutObject->Block(
            Name => 'OverviewResultRow',
            Data => {
                ArticleID       => $Row[0],
                ID              => $Row[1],
                AccountingTime  => int $Row[2],
                CreateBy        => $User{ UserFirstname }. ' ' . $User{ UserLastname },
                CreateByID      => $Row[3],
                CreateTime      => $Self->FormatDataTime( $Row[4] ),
                TicketID        => $GetParam{ TicketID },
                lock            => ( $Row[3] == $LayoutObject->{ UserID } ) ? '' : 'readonly',
            },
        );
    }    

    for ( sort keys %UserTimeUnit ) {
        $LayoutObject->Block(
            Name => 'OverviewUserTime',
            Data => {
                User     => $_,
                TimeUnit => $UserTimeUnit{ $_ },
            },
        );        
    }

    my $Output = $LayoutObject->Header( Type => 'Small' );

    $Output .= $LayoutObject->Output(
        TemplateFile => 'TicketAccountingTimeEdit',
        Data         => \%GetParam,
    );

    $Output .= $LayoutObject->Footer( Type => 'Small' );

    return $Output;
}

sub Check {
    my ( $Self, $ArticleID ) = @_;

    my $DBO = $Kernel::OM->Get('Kernel::System::DB');
 
    $DBO->Prepare(
        SQL => "SELECT ID FROM time_accounting WHERE ARTICLE_ID = $ArticleID",
        LIMIT => 1,
    );      

    my $Check;
    while ( my @Row = $DBO->FetchrowArray() ) { 
        $Check = $Row[0];
    }  

    return $Check;
}

sub FormatDataTime {
    my ( $Self, $Time ) = @_;

    my $TimeObject = $Kernel::OM->Get('Kernel::System::Time');

    my $SystemTime = $TimeObject->TimeStamp2SystemTime(
        String => $Time,
    );    

    my ($Sec, $Min, $Hour, $Day, $Month, $Year, $WeekDay) = $TimeObject->SystemTime2Date(
        SystemTime => $SystemTime,
    );

    my $TimeStamp = "$Day.$Month.$Year $Hour:$Min";

    return $TimeStamp;
}

1;
Последний раз редактировалось alex.t 02 янв 2020, 18:37, всего редактировалось 1 раз.

alex.t
OTRS Новобранец
Сообщения: 30
Зарегистрирован: 29 апр 2018, 09:26
Благодарил (а): 1 раз
Поблагодарили: 9 раз

Re: Редактирование трудозатрат

Сообщение alex.t » 02 янв 2020, 18:37

3. Создаем файл TicketAccountingTimeEdit.tt, закидываем в папку otrs/Custom/Kernel/Output/HTML/Templates/Standard:

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

<div class="MainBox">	
	<h1>Изменить трудозатраты</h1>

	<h4><label>[% "Суммарные трудозатраты по тикету" | html %]</label></h4>
	<table class="DataTable">
	    <thead>
	        <tr>
	            <th>[% 'Агент' | html %]</th>
	            <th>[% 'Трудозатраты (минут)' | html %]</th>
	        </tr>
	    </thead>
	    <tbody>
	[% RenderBlockStart("OverviewUserTime") %]
	        <tr>
	            <td>[% Data.User %]</td>
	            <td>[% Data.TimeUnit %]</td>
	        </tr>
	[% RenderBlockEnd("OverviewUserTime") %]
	    </tbody>
	</table>
	</br>

	<h4><label>[% "Редактирование трудозатрат по тикету" | html %]</label></h4>
    <form action="[% Env("CGIHandle") %]" method="post" class="Validate">
        <input type="hidden" name="Action" value="[% Env("Action") %]"/>
        <input type="hidden" name="Subaction" value="Change"/>
        <input type="hidden" name="TicketID" value="[% Data.TicketID | html %]"/>
		<table class="DataTable">
		    <thead>
		        <tr>
		            <th>[% 'Агент' | html %]</th>
		            <th>[% 'Трудозатраты (минут)' | html %]</th>
		            <th>[% 'Дата записи трудозатрат' | html %]</th>
		        </tr>
		    </thead>
		    <tbody>
		[% RenderBlockStart("OverviewResultRow") %]
		        <tr>
		            <td>[% Data.CreateBy %]</td>
		            <td><input type="text" [% Data.lock %] name="Time[% Data.ArticleID %]" id="Time[% Data.ArticleID %]" value="[% Data.AccountingTime | html %]" class="W50px Validate_Number"/></td>
		            <td>[% Data.CreateTime %]</td>
		            <input type="hidden" readonly name="ArticleID[% Data.ArticleID %]" id="ArticleID[% Data.ArticleID %]" value="[% Data.ArticleID | html %]" class="W10px"/>
		            <input type="hidden" readonly name="CreateByID[% Data.ArticleID %]" id="CreateByID[% Data.ArticleID %]" value="[% Data.CreateByID | html %]" class="W50px"/>
		        </tr>
		[% RenderBlockEnd("OverviewResultRow") %]
		    </tbody>
		</table>		
		</br>
	    <button class="Primary CallForAction" id="AccountingTimeSave" type="submit" value="[% Translate("Save") | html %]"><span>[% Translate("Save") | html %]</span></button>
    </form>
</div>
На панели в тикете появится кнопка "Accounting Time Edit" при нажатии откроется окно пример:
Изображение

wss
OTRS Новобранец
Сообщения: 113
Зарегистрирован: 11 июл 2018, 10:06
Благодарил (а): 9 раз
Поблагодарили: 2 раза

Re: Редактирование трудозатрат

Сообщение wss » 14 янв 2021, 18:45

Не подскажете, новую заявку через свой action в 6-й отрс как создать?

alex.t
OTRS Новобранец
Сообщения: 30
Зарегистрирован: 29 апр 2018, 09:26
Благодарил (а): 1 раз
Поблагодарили: 9 раз

Re: Редактирование трудозатрат

Сообщение alex.t » 26 янв 2021, 08:57

Нужно что при нажатии на кнопку открывалась форма новой заявки?
Или нужно из каких то собранных данных автоматом создать заявку?

wss
OTRS Новобранец
Сообщения: 113
Зарегистрирован: 11 июл 2018, 10:06
Благодарил (а): 9 раз
Поблагодарили: 2 раза

Re: Редактирование трудозатрат

Сообщение wss » 11 мар 2021, 13:50

Нужна новая форма заявки. Спасибо.

Ответить