%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) %# %# %# LICENSE: %# %# This work is made available to you under the terms of Version 2 of %# the GNU General Public License. A copy of that license should have %# been provided with this software, but in any event can be snarfed %# from www.gnu.org. %# %# This work is distributed in the hope that it will be useful, but %# WITHOUT ANY WARRANTY; without even the implied warranty of %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %# General Public License for more details. %# %# You should have received a copy of the GNU General Public License %# along with this program; if not, write to the Free Software %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA %# 02110-1301 or visit their web page on the internet at %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. %# %# %# CONTRIBUTION SUBMISSION POLICY: %# %# (The following paragraph is not intended to limit the rights granted %# to you to modify and distribute this software under the terms of %# the GNU General Public License and is only of importance to you if %# you choose to contribute your changes and enhancements to the %# community by submitting them to Best Practical Solutions, LLC.) %# %# By intentionally submitting any modifications, corrections or %# derivatives to this work, or any other work intended for use with %# Request Tracker, to Best Practical Solutions, LLC, you confirm that %# you are the copyright holder for those contributions and you grant %# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, %# royalty-free, perpetual, license to use, copy, create derivative %# works based on those contributions, and sublicense and distribute %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => $title &> <& /Elements/Tabs &> <& /Elements/ListActions, actions => \@results &> % foreach my $var (qw(Query Format OrderBy Order Rows Page SavedChartSearchId)) { %} <& /Elements/CollectionList, Collection => $Assets, Query => $Query, DisplayFormat => $Format, Format => $ARGS{'Format'}, Verbatim => 1, AllowSorting => 1, OrderBy => $OrderBy, Order => $Order, Rows => $Rows, Page => $Page, BaseURL => RT->Config->Get('WebPath')."/AssetTracker/Search/Grid.html?", Class => 'RTx::AssetTracker::Assets' &> % $m->callback(CallbackName => 'AfterAssetList', ARGSRef => \%ARGS);

<& /Elements/Submit, Label => loc('Update'), CheckboxNameRegex => '/^UpdateAsset\d+$/', CheckAll => 1, ClearAll => 1 &> <%INIT> unless ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'BulkUpdate')) { Abort(loc("No permission to perform bulk updates of assets.")); } unless ( defined $Rows ) { $Rows = $RowsPerPage; $ARGS{Rows} = $RowsPerPage; } my $title = loc("Grid asset update"); # Iterate through the ARGS hash and remove anything with a null value. map ( $ARGS{$_} =~ /^$/ && ( delete $ARGS{$_} ), keys %ARGS ); my (@results); $Page ||= 1; $Format ||= RT->Config->Get('DefaultAssetSearchResultFormat'); # Process the updates my @UpdateIDs; foreach my $arg (keys %ARGS) { if ($arg =~ /^UpdateAsset(\d+)$/) { push @UpdateIDs, $1; delete $ARGS{$arg}; } } foreach my $id (@UpdateIDs) { my $Asset = RTx::AssetTracker::Asset->new( $session{CurrentUser} ); my ($rv, $msg) = $Asset->Load($id); unless ($Asset->Id) { push @results, "Unable to load asset: $msg"; next; } # update the Asset basics my %basics; $basics{id} = $id; foreach my $arg (keys %ARGS) { next unless $arg =~ /^Asset-$id-(.*)$/; $basics{$1} = $ARGS{$arg}; #delete $ARGS{$arg}; } push @results, ProcessAssetBasics( AssetObj => $Asset, ARGSRef => \%basics); # update watchers? push @results, ProcessAssetWatchers(AssetObj => $Asset, ARGSRef => \%ARGS); # update the Assets custom fields my %cfs; $cfs{id} = $id; foreach my $arg (keys %ARGS) { next unless $arg =~ /Asset-$id-CustomField-/; $cfs{$arg} = $ARGS{$arg}; delete $ARGS{$arg}; } push @results, ProcessObjectCustomFieldUpdates( AssetObj => $Asset, ARGSRef => \%cfs); } my $Assets = RTx::AssetTracker::Assets->new($session{'CurrentUser'}); $Assets->FromSQL($Query); if ( $OrderBy =~ /\|/ ) { # Multiple Sorts my @OrderBy = split /\|/, $OrderBy; my @Order = split /\|/, $Order; $Assets->OrderByCols( map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } ( 0 .. $#OrderBy ) ); } else { $Assets->OrderBy( FIELD => $OrderBy, ORDER => $Order ); } $Assets->RowsPerPage($Rows) if ($Rows); $Assets->GotoPage( $Page - 1 ); # SB uses page 0 as the first page Abort( loc("No search to operate on.") ) unless ($Assets); # build up a list of all custom fields for assets that we're displaying, so # we can display sane edit widgets. while ( my $asset = $Assets->Next ) { next if $m->notes->{seen_types}{ $asset->Type }++; my $custom_fields = $asset->CustomFields; while ( my $field = $custom_fields->Next ) { next if $m->notes->{fields}{ $asset->Type }{ $field->Name }++; } } #Iterate through each asset we've been handed $Assets->RedoSearch(); while (my $Asset = $Assets->Next) { $RT::Logger->debug( "Checking Asset ".$Asset->Id ."\n"); next unless ($ARGS{"UpdateAsset".$Asset->Id}); $RT::Logger->debug ("Matched\n"); my @updateresults; #Update the basics. my @basicresults = ProcessAssetBasics(AssetObj => $Asset, ARGSRef => \%ARGS); my @cfresults = ProcessBulkCustomFieldUpdates(Object => $Asset, ARGSRef => \%ARGS); #Update the watchers $RT::Logger->debug( "About to update watchers"); my @watchresults = ProcessAssetWatchers(AssetObj => $Asset, ARGSRef => \%ARGS); push @results, @watchresults; $ARGS{'id'} = $Asset; my @tempresults = ( @basicresults, @cfresults, @updateresults); @tempresults = map { loc("Asset #[_1] [_2]: [_3]",$Asset->Id,$Asset->Name,$_) } @tempresults; push @results, @tempresults; } <%ARGS> $Format => undef $Page => 1 $Rows => undef $RowsPerPage => undef $Order => 'ASC' $OrderBy => 'id' $Query => undef $SavedSearchId => undef