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

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

Модератор: ykolesnikov

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

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

Сообщение 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 Новобранец
Сообщения: 19
Зарегистрирован: 29 апр 2018, 09:26
Поблагодарили: 3 раза

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" при нажатии откроется окно пример:
Изображение

Ответить