Страница 1 из 1

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

Добавлено: 02 янв 2020, 18:32
alex.t
Добрый день!
При работе агенты могут не верно внести трудозатраты по тикету или забыть внести их например за предыдущий день.
Модуль позволяет редактировать агенту трудозатраты, причем только свои)
Работает на 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;

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

Добавлено: 02 янв 2020, 18:37
alex.t
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" при нажатии откроется окно пример:
Изображение

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

Добавлено: 14 янв 2021, 18:45
wss
Не подскажете, новую заявку через свой action в 6-й отрс как создать?

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

Добавлено: 26 янв 2021, 08:57
alex.t
Нужно что при нажатии на кнопку открывалась форма новой заявки?
Или нужно из каких то собранных данных автоматом создать заявку?

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

Добавлено: 11 мар 2021, 13:50
wss
Нужна новая форма заявки. Спасибо.