%# BEGIN BPS TAGGED BLOCK {{{
%#
%# COPYRIGHT:
%#
%# This software is Copyright (c) 1996-2025 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 => loc("Assets") &>
<& /Elements/Tabs &>

% $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Assets => $assets, Actions => \@results);

<& /Elements/ListActions, actions => \@results &>

<form method="post" action="<% RT->Config->Get('WebPath') %>/Asset/Search/Bulk.html" enctype="multipart/form-data" name="BulkUpdate" id="BulkUpdate">
% foreach my $var ( @{$search{'PassArguments'}} )  {
<input type="hidden" class="hidden" name="<% $var %>" value="<% $ARGS{$var} || '' %>" />
% }
<& /Elements/CollectionList,
    %search,
    Collection      => $assets,
    AllowSorting    => 1,
    DisplayFormat   => $DisplayFormat,
    &>
% if (not $assets->Count) {
<em><&|/l&>No assets matching search criteria found.</&></em>
% }

<& /Elements/Submit,
    Name => 'Update',
    Label => loc('Update'),
    CheckboxNameRegex => '/^UpdateAsset(All)?$/',
    CheckAll => 1, ClearAll => 1,
&>
<div class="submit">
  <div class="buttons">
  <span class="caption"></span>
  <input type="submit" id="bulk-update-create-linked-ticket" name="CreateLinkedTicket"  value="Create Linked Ticket" class="button" alt="Create a ticket with checked assets linked" />
  </div>
</div>

<&| /Widgets/TitleBox, title => loc("Basics"), class => "asset-basics asset-bulk-basics", title_class => "inverse" &>
<table class="core-fields">
  <tr class="asset-catalog">
    <td class="label"><label for="UpdateCatalog"><&|/l&>Catalog</&></label></td>
    <td><& /Asset/Elements/SelectCatalog, Name => 'UpdateCatalog', Default => $catalog_obj->id, UpdateSession => 0, &></td>
  </tr>
  <tr class="asset-name">
    <td class="label"><label for="UpdateName"><&|/l&>Name</&></label></td>
    <td><input name="UpdateName" value="<% $ARGS{'Name'}||'' %>" size="40"></td>
  </tr>
  <tr class="asset-description">
    <td class="label"><label for="UpdateDescription"><&|/l&>Description</&></label></td>
    <td><input name="UpdateDescription" value="<% $ARGS{'Description'}||'' %>" size="40"></td>
  </tr>
  <tr class="asset-status">
    <td class="label"><label for="UpdateStatus"><&|/l&>Status</&></label></td>
    <td><& /Asset/Elements/SelectStatus, Name => 'UpdateStatus', DefaultValue => 1, Catalogs => { $catalog_obj->id => $catalog_obj } &></td>
  </tr>
</table>
%   my $cfs = $catalog_obj->AssetCustomFields;
%   $cfs->LimitToGrouping( 'RT::Asset' => 'Basics');
%   if ( $cfs->Count ) {
<& /Elements/BulkCustomFields, CustomFields => $cfs, &>
%   }
</&>

<&| /Widgets/TitleBox, title => loc("People"), class => "asset-people asset-bulk-people", title_class => "inverse" &>
<table class="core-fields">
% for my $rname ( $asset->Roles( ACLOnly => 0 ) ) {
% my $role = $asset->Role( $rname );
% if ( $role->{'Single'} ) {
% my $input = "SetRoleMember-$rname";
<tr class="full-width">
<td class="label"><label for="<% $input %>"><% loc($rname) %></label></td>
<td><input type="text" value="<% $ARGS{ $input } || '' %>" name="<% $input %>" id="<% $input %>" data-autocomplete="Users" data-autocomplete-return="Name" /></td>
</tr>
% } else {
<tr>
% my $input = "AddRoleMember-$rname";
<td class="label"><label for="<% $input %>"><% loc("Add [_1]", loc($rname)) %></label></td>
<td><input type="text" value="<% $ARGS{ $input } || '' %>" name="<% $input %>" id="<% $input %>" data-autocomplete="Users" data-autocomplete-return="Name" /></td>
</tr>

<tr>
% $input = "RemoveRoleMember-$rname";
<td class="label"><label for="<% $input %>"><% loc("Remove [_1]", loc($rname)) %></label></td>
<td>
  <input type="text" value="<% $ARGS{ $input } || '' %>" name="<% $input %>" id="<% $input %>" data-autocomplete="Users" data-autocomplete-return="Name" />
  <label>
    <input type="checkbox" name="RemoveAllRoleMembers-<% $rname %>" value="1"/>
    <em><&|/l&>(Check to delete all values)</&></em>
  </label>
</td>
</tr>
% }
% }
%   my $cfs = $catalog_obj->AssetCustomFields;
%   $cfs->LimitToGrouping( 'RT::Asset' => 'People');
%   if ( $cfs->Count ) {
<& /Elements/BulkCustomFields, CustomFields => $cfs, &>
%   }
</table>
</&>

%   my $cfs = $catalog_obj->AssetCustomFields;
%   $cfs->LimitToGrouping( 'RT::Asset' => 'Dates');
%   if ( $cfs->Count ) {
<&| /Widgets/TitleBox, title => loc("Dates"), class => "asset-dates asset-bulk-dates", title_class => "inverse" &>
<& /Elements/BulkCustomFields, CustomFields => $cfs, &>
</&>
%   }

% for my $group ( RT::CustomField->CustomGroupings( 'RT::Asset' ), '' ) {
%   my $cfs = $catalog_obj->AssetCustomFields;
%   $cfs->LimitToGrouping( 'RT::Asset' => $group);
%   if ( $cfs->Count ) {
<&| /Widgets/TitleBox, class=>'asset-bulk-grouping asset-info-cfs asset-bulk-cfs', title => loc('Edit [_1]', ($group? loc($group) : loc('Custom Fields')) ), title_class => "inverse" &>
<& /Elements/BulkCustomFields, CustomFields => $cfs, &>
</&>
%   }
% }

<&|/Widgets/TitleBox, title => loc('Edit Links'), class => "asset-links asset-bulk-links", title_class => "inverse" &>
<& /Elements/BulkLinks, Collection => $assets, %ARGS &>
%   my $cfs = $catalog_obj->AssetCustomFields;
%   $cfs->LimitToGrouping( 'RT::Asset' => 'Links');
%   if ( $cfs->Count ) {
<& /Elements/BulkCustomFields, CustomFields => $cfs, &>
%   }
</&>

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

<%INIT>
my @results;
$m->callback(ARGSRef => \%ARGS, Results => \@results, CallbackName => 'Initial');

my $catalog_obj = LoadDefaultCatalog($ARGS{'Catalog'} || '');
$ARGS{'Catalog'} = $catalog_obj->Id;

my $assets = RT::Assets->new($session{CurrentUser});
my %search = ProcessAssetsSearchArguments(
    Assets => $assets, Catalog => $catalog_obj, ARGSRef => \%ARGS,
);

my $DisplayFormat = "'__CheckBox.{UpdateAsset}__',". $search{'Format'};
$DisplayFormat =~ s/\s*,\s*('?__NEWLINE__'?)/,$1,''/gi;

my $asset = RT::Asset->new( $session{'CurrentUser'} );

delete $ARGS{$_} foreach grep { $ARGS{$_} =~ /^$/ } keys %ARGS;

$DECODED_ARGS->{'UpdateAssetAll'} = 1 unless @UpdateAsset;

if ( $ARGS{'CreateLinkedTicket'} ){
    my $url = RT->Config->Get('WebURL') . "Asset/CreateLinkedTicket.html";
    $url .= '?'. $m->comp( '/Elements/QueryString', 'Assets' => \@UpdateAsset );
    RT::Interface::Web::Redirect($url);
}
elsif ( $ARGS{Update} ) {
    my @attributes  = $asset->WritableAttributes;
    @attributes = grep exists $ARGS{ 'Update'. $_ }, @attributes;
    my %basics = map { $_ => $ARGS{ 'Update'. $_ } } @attributes;

    foreach my $aid ( @UpdateAsset ) {
        my $asset = LoadAsset($aid);

        my @tmp_res;
        push @tmp_res, UpdateRecordObject(
            Object          => $asset,
            AttributesRef   => \@attributes,
            ARGSRef         => \%basics,
        );
        push @tmp_res, ProcessAssetRoleMembers( $asset => %ARGS );
        push @tmp_res, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
        push @tmp_res, ProcessRecordLinks( RecordObj => $asset, RecordId => 'Asset', ARGSRef => \%ARGS );
        push @tmp_res, ProcessRecordBulkCustomFields( RecordObj => $asset, ARGSRef => \%ARGS );
        push @results, map { loc( "Asset #[_1]: [_2]", $asset->id, $_ ) } @tmp_res;
    }

    MaybeRedirectForResults(
        Actions     => \@results,
        Arguments   => { map { $_ => $ARGS{$_} } grep { defined $ARGS{$_} } @{$search{'PassArguments'}} },
    );
}
</%INIT>
<%ARGS>
@UpdateAsset => ()
</%ARGS>
