%# BEGIN BPS TAGGED BLOCK {{{
%#
%# COPYRIGHT:
%#
%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
%#                                          <sales@bestpractical.com>
%#
%# (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 &>
<form method="post" action="<% RT->Config->Get('WebPath') %>/AssetTracker/Search/Bulk.html" enctype="multipart/form-data" name="BulkUpdate" id="BulkUpdate">
% foreach my $var (qw(Query Format OrderBy Order Rows Page SavedChartSearchId)) {
<input type="hidden" class="hidden" name="<%$var%>" value="<%$ARGS{$var} || ''%>" />
%}
<& /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/Bulk.html?",
    Class => 'RTx::AssetTracker::Assets'
   &>

% $m->callback(CallbackName => 'AfterAssetList', ARGSRef => \%ARGS);

<hr />

<& /Elements/Submit, Label => loc('Update'), CheckboxNameRegex => '/^UpdateAsset\d+$/', CheckAll => 1, ClearAll => 1 &>
<br />
<&|/Widgets/TitleBox, title => $title &>
<table>
<tr>
<td valign="top">
<table>
% for my $role ( RTx::AssetTracker::Type->RoleGroupTypes() ) {
<tr><td class="label"> <&|/l&>Add <% $role %></&>: </td>
<td class="value"> <input name="Add<% $role %>" size="20" value="<% $ARGS{"Add$role"} || '' %>" /> </td></tr>
<tr><td class="label"> <&|/l&>Remove <% $role %></&>: </td>
<td class="value"> <input name="Delete<% $role %>" size="20" value="<% $ARGS{"Delete$role"} || '' %>" /> </td></tr>
% }
<tr><td class=label colspan=2> <i>(Username or Email separated by spaces)</i></td>
</table>
</td>
<td valign="top">
<table>
<tr><td class="label"> <&|/l&>Make Description</&>: </td>
<td class="value"> <input name="Description" size="50" value="<% $ARGS{Description} || '' %>" /> </td></tr>
<tr><td class="label"> <&|/l&>Make Type</&>: </td>
<td class="value"> <& /AssetTracker/Elements/SelectType, Name => "Type", Default => $ARGS{Type} &> </td></tr>
<tr><td class="label"> <&|/l&>Make Status</&>: </td>
<td class="value"> <& /AssetTracker/Elements/SelectStatus, Name => "Status", Default => $ARGS{Status}, Types => $seen_types &> </td></tr>
</table>

</td>
</tr>
</table>
</&>

<%perl>
my $cfs = RT::CustomFields->new($session{'CurrentUser'});
$cfs->LimitToGlobalAsset();
$cfs->LimitToAssetType($_) for keys %$seen_types;
</%perl>

% if ($cfs->Count) {
<&|/Widgets/TitleBox, title => loc('Edit Custom Fields'), color => "#336633"&>
<table>
<tr>
<th><&|/l&>Name</&></th>
<th><&|/l&>Add values</&></th>
<th><&|/l&>Delete values</&></th>
</tr>
% while (my $cf = $cfs->Next()) {
<tr>
<td class="label"><% loc($cf->Name) %><br />
<em>(<%$cf->FriendlyType%>)</em></td>
% my $rows = 5;
% my $cf_id = $cf->id;
% my @add = (NamePrefix => 'Bulk-Add-CustomField-', CustomField => $cf, Rows => $rows,
%   Multiple => ($cf->MaxValues ==1 ? 0 : 1) , Cols => 25, 
%   Default => $ARGS{"Bulk-Add-CustomField-$cf_id-Values"} || $ARGS{"Bulk-Add-CustomField-$cf_id-Value"}, );
% my @del = (NamePrefix => 'Bulk-Delete-CustomField-', CustomField => $cf,
%   Rows => $rows, Multiple => 1, Cols => 25,
%   Default => $ARGS{"Bulk-Delete-CustomField-$cf_id-Values"} || $ARGS{"Bulk-Delete-CustomField-$cf_id-Value"}, );
% if ($cf->Type eq 'Select') {
<td><& /Elements/EditCustomFieldSelect, @add &></td>
<td><& /Elements/EditCustomFieldSelect, @del &></td>
% } elsif ($cf->Type eq 'Combobox') {
<td><& /Elements/EditCustomFieldCombobox, @add &></td>
<td><& /Elements/EditCustomFieldCombobox, @del &></td>
% } elsif ($cf->Type eq 'Freeform') {
<td><& /Elements/EditCustomFieldFreeform, @add &></td>
<td><& /Elements/EditCustomFieldFreeform, @del &></td>
% } elsif ($cf->Type eq 'Text') {
<td><& /Elements/EditCustomFieldText, @add &></td>
<td>&nbsp;</td>
% } else {
%   $RT::Logger->crit("Unknown CustomField type: " . $cf->Type);
% }
</tr>
% }
</table>
</&>
% }

<&|/Widgets/TitleBox, title => loc('Edit Links'), color => "#336633"&>
<& /AssetTracker/Asset/Elements/BulkLinks, Assets => $Assets &>
</&>

<&|/Widgets/TitleBox, title => 'Change Comment', color=> "#999900", width => "100%" &>
<& /AssetTracker/Asset/Elements/ChangeComment, Name => "GlobalComment" &>
</&>

<& /Elements/Submit, Label => loc('Update') &>


</form>


<%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("Update multiple assets");

# 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');

# inject _CHECKBOX to the first field.
$Format =~ s/'?([^']+)'?,/'___CHECKBOX__$1',/;

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.

my $fields      = {};
my $seen_types = {};
while ( my $asset = $Assets->Next ) {
    next if $seen_types->{ $asset->Type }++;

    my $custom_fields = $asset->CustomFields;
    while ( my $field = $custom_fields->Next ) {
        $fields->{ $field->id } = $field;
    }
}

#Iterate through each asset we've been handed
my @linkresults;

$Assets->RedoSearch();

# pull out the labels for any custom fields we want to update

my $cf_del_keys;
@$cf_del_keys = grep { /^Bulk-Delete-CustomField/ } keys %ARGS;
my $cf_add_keys;
@$cf_add_keys = grep { /^Bulk-Add-CustomField/ } keys %ARGS;

while ( my $Asset = $Assets->Next ) {
    next unless ( $ARGS{ "UpdateAsset" . $Asset->Id } );

    #Update the links
    $ARGS{'id'} = $Asset->id;

    #Update the basics.
    my @basicresults =
        ProcessAssetBasics( AssetObj => $Asset, ARGSRef => \%ARGS );

    #Update the watchers
    my @watchresults =
        ProcessAssetWatchers( AssetObj => $Asset, ARGSRef => \%ARGS );

    foreach my $type ( keys %{ RTx::AssetTracker::Asset::LINKDIRMAP() } ) {
        $ARGS{ $Asset->id . "-" . $type } = $ARGS{"Asset-$type"};
        $ARGS{ $type . "-" . $Asset->id } = $ARGS{"$type-Asset"};
    }
    @linkresults =
        ProcessAssetLinks( AssetObj => $Asset, ARGSRef => \%ARGS );
    foreach my $type ( keys %{ RTx::AssetTracker::Asset::LINKDIRMAP() } ) {
        delete $ARGS{ $type . "-" . $Asset->id };
        delete $ARGS{ $Asset->id . "-" . $type };
    }

    my @cfresults;

    foreach my $list ( $cf_add_keys, $cf_del_keys ) {
        next unless $list->[0];

        my $op;
        if ( $list->[0] =~ /Add/ ) {
            $op = 'add';
        }
        elsif ( $list->[0] =~ /Del/ ) {
            $op = 'del';
        }
        else {
            $RT::Logger->crit(
                "Got an op that was neither add nor delete. can never happen"
                    . $list->[0] );
            last;
        }

        foreach my $key (@$list) {
            my ( $cfid, $cf );
            next if $key =~ /CustomField-(\d+)-Category$/;
            if ( $key =~ /CustomField-(\d+)-/ ) {
                $cfid = $1;
                $cf   = RT::CustomField->new( $session{'CurrentUser'} );
                $cf->Load($cfid);
            }
            else {next}
            my @values =
                ref( $ARGS{$key} ) eq 'ARRAY'
                ? @{ $ARGS{$key} }
                : ( $ARGS{$key} );
            map { s/(\r\n|\r)/\n/g; } @values;    # fix the newlines
            # now break the multiline values into multivalues
            @values = map { split( /\n/, $_ ) } @values
                unless ( $cf->SingleValue );

            my $current_values = $Asset->CustomFieldValues($cfid);
            foreach my $value (@values) {
                if ( $op eq 'del' && $current_values->HasEntry($value) ) {
                    my ( $id, $msg ) = $Asset->DeleteCustomFieldValue(
                        Field => $cfid,
                        Value => $value
                    );
                    push @cfresults, $msg;
                }

                elsif ( $op eq 'add' && !$current_values->HasEntry($value) ) {
                    my ( $id, $msg ) = $Asset->AddCustomFieldValue(
                        Field => $cfid,
                        Value => $value
                    );
                    push @cfresults, $msg;
                }
            }
        }
    }
    my @tempresults = (
        @watchresults,  @basicresults, @linkresults,  @cfresults
    );

    @tempresults =
        map { loc( "Asset #[_1] [_2]: [_3]", $Asset->Id, $Asset->Name, $_ ) } @tempresults;

    @results = ( @results, @tempresults );
}

#my $TxnCFs = RT::CustomFields->new( $session{CurrentUser} );
#$TxnCFs->LimitToLookupType( "RTx::AssetTracker::Type-RTx::AssetTracker::Asset-RT::Transaction" );
#$TxnCFs->LimitToGlobalOrObjectId( sort keys %seen_types );

</%INIT>
<%args>
$Format => undef
$Page => 1
$Rows => undef
$RowsPerPage => undef
$Order => 'ASC'
$OrderBy => 'id'
$Query => undef
$SavedSearchId => undef
$SavedChartSearchId => undef
</%args>
