<%doc>
Asset tasks
</%doc>

<%attr>
title   => 'Assets'
section => "Management"
</%attr>
%
%
<%args>
$user               => $ui->get_current_user($r)
$submit             => undef
$date_purchased     => undef
@import_fields      => undef
$asset_rows         => undef
$view               => 'search'
$show_tasks         => undef
$showheader         => 1
$search             => undef
$search_type        => 'all'  # installed, not installed, all
</%args>


<%init>
my $DEBUG = 0;
print '%ARGS is  <pre>', Dumper(%ARGS), $m->dhandler_arg,'</pre><br>' if $DEBUG;
my $manager = $ui->get_permission_manager($r);

$show_tasks = $show_tasks || $user->getAttribute("SHOW_TASKS");
if ( $show_tasks eq "" ) {
    $user->setAttribute($r, "SHOW_TASKS", "show");
    $show_tasks = "show";
}
*print_showtaskslink = $m->comp('SELF:.sub_print_showtaskslink'); 
my $hideheader = 'style="display:none"' if ( !$showheader );
my @list;
</%init>

<div id="sectiontools" <% $hideheader %>>
  <div class="container">
    <div class="containerheadleft">
        Asset Tasks
    </div>
    <div class="containerheadright">
%   if ( $view eq 'search' ){ 
%       if ( $manager && $manager->can($user, 'access_admin_section', 'asset_tasks:import') ){
	    <a href="asset_tasks.html?view=import">[import]</a>
%       }
%   }elsif ( $view eq 'import' ){
        <a href="asset_tasks.html?view=search">[search]</a>
%   }
%       print_showtaskslink($show_tasks);
    </div>
    <div class="containerbody" id="tasks" style="display:<% ($show_tasks eq "show"?"block":"none") %>">
        <table><tr><td>
%    if ( $view eq 'import' ){
          <fieldset class="large">
            <legend>Bulk Import</legend>
            <p>This form allows you to import multiple hardware assets. For example, you can use a bar code scanner to scan the information from vendor boxes as you receive your equipment. Create a text file composed of part number, serial number, and optionally other fields. The part number must match the value from an existing product in Netdot. The order of fields in each line must match the list of fields in the select menu.
            <p>
            <form name="asset_entry" method='POST'>
             <p>
             <label>Purchase Date:</label>
             <input type="text" size="10" id="date_purchased" name="date_purchased"> <img src="../img/calendar.gif" onclick="showChooser(this, 'date_purchased', 'chooserSpan', 1990, 2050, 'Y-m-d', false);"/><div id="chooserSpan" class="dateChooser select-free" style="display: none; visibility: hidden; width: 160px;"></div>
             </p>
             <p>
             <label>Fields for import:</label>
             <select name="import_fields" id="import_fields" multiple>
               <option value='part_number' SELECTED >Part Number</option>
               <option value='serial_number' SELECTED >S/N</option>
%              my @a_cols = qw(physaddr po_number);
%              foreach my $mc ( @a_cols ){
%                  my $tag = Asset->meta_data->get_column($mc)->tag;
                   <option value='<% $mc %>'><% $tag %></option> 
%              }
             </select>
             </p>
             <p>
             <label>Comma-separated Data:</label> 
             <textarea name="asset_rows" rows="7" cols="80"></textarea>
             </p>
             <p>
             <input type="submit" name="submit" class="btn" value="Import">
             </p>
            </form>     
          </fieldset>

%       }elsif ( $view eq 'search' ){
        <fieldset class="medium">
             <legend>Search</legend>
             <form action="asset_tasks.html" method="POST">
                <p>
                <label for="Find">Keywords:</label>
                <input type="text" name="search" class="txt" value="<% $search %>"> 
		<select name="search_type">
%		foreach my $type ( 'installed', 'not installed', 'all' ){
%                   if ( $search_type eq $type ){
		        <option value="<% $type %>" SELECTED><% $type %></option>
%                   }else{
		        <option value="<% $type %>"><% $type %></option>
%                   }
%	        }   
		</select>
                <input name="submit" value="Search" class="btn" type="submit">
                </p>
            </form>
        </fieldset>
%       }
        </td></tr></table>
    </div>
  </div>
</div>


<%perl>
if ( $submit ){
    if ( $submit eq 'Import' ){
        unless ( $manager && $manager->can($user, 'access_admin_section', 'asset_tasks:submit_import') ){
	    $m->comp('/generic/error.mhtml', error=>"You do not have permission to do this");
	}

	$m->comp('/generic/error.mhtml', error=>"Please select fields for import")
	    unless @import_fields;

	$m->comp('/generic/error.mhtml', 
		 error=>"Please provide a comma-separated list of asset data")
	    unless $asset_rows;
	
	my @rows = split(/[\n\r]+/, $asset_rows);

	# Cache products by part number
	my %products;

	# for dup detection
	my %assets; 
	for ( Asset->retrieve_all() ){ $assets{$_->serial_number}  = 1 }
	my %macs;
	for ( PhysAddr->retrieve_all() ){ $macs{$_->address}  = 1 }
	my %dups;

	my @new_assets;
	eval {
	    Netdot::Model->do_transaction(sub{ 
		foreach my $line ( @rows ){
		    next if $line eq "";
		    # Remove leading and trailing spaces
		    $line = $ui->rem_lt_sp($line);
		    my @data = split /,/, $line;
		    if ( scalar(@import_fields) != scalar(@data) ){
			Netdot->throw_user("Number of import fields does not match number of data columns");
		    }
		    my %d; my $i = 0;
		    for ( @import_fields ){ $d{$_} = $data[$i]; $i++; }
		    
		    unless ( $d{serial_number} && $d{part_number} ){
			Netdot->throw_user("Part Number and S/N are required");
		    }
		    
		    # Check for dups
		    if ( exists($assets{$d{serial_number}}) ){
			$dups{serial}{$d{serial_number}} = 1;
			next;
		    }
		    $assets{$d{serial_number}} = 1;

		    # fill up data for insert
		    my %args;

		    # MAC
		    if ( $d{physaddr} ){
			my $mac = PhysAddr->validate($d{physaddr});
			Netdot->throw_user("Invalid MAC: $d{physaddr}")
			    unless $mac;
			if ( exists($macs{$mac}) ){
			    $dups{macs}{$mac} = 1;
			    next;
			}
			$macs{$mac} = 1;
			$args{physaddr} = PhysAddr->insert({address=>$mac})->id;
		    }
		    
		    $args{date_purchased} = $date_purchased if $date_purchased;
		    $args{serial_number}  = $d{serial_number};

		    # Product
		    my $product_id;
		    unless ( $product_id = $products{$d{part_number}} ){
			my $product = Product->search(part_number=>$d{part_number})->first ||
			    Netdot->throw_user("Product with part number $d{part_number} not found in DB");
			$products{$d{part_number}} = $product->id;
			$product_id = $product->id;
		    }
		    $args{product_id} = $product_id;

		    $args{po_number} = $d{po_number} if $d{po_number};
		    push @new_assets, Asset->insert(\%args);
		}
					  });
	};
	if ( my $e = $@ ){
	    $m->comp('/generic/error.mhtml', error=>"$e");
	}
	my $msg = '<p>'.scalar(@new_assets).' assets inserted</p>';

	if ( $dups{serial} ){
	    $msg .= "<p>Note: The following serial numbers were duplicated or already existed in the DB: <br>";
	    $msg .=  join (' ', keys %{$dups{serial}});
	    $msg .= "</p>";
	}
	if ( $dups{macs} ){
	    $msg .= "<p>Note: The following MAC addresses were duplicated or already existed in the DB: <br>";
	    $msg .=  join (' ', keys %{$dups{macs}});
	    $msg .= "</p>";
	}
	$m->comp('.show_message', title=>"Action Message", msg=>$msg);

	print '<div class="containerhead"><b>New Assets</b></div>';
	print '<div class="containerbody">';
	$m->comp('/generic/sortresults.mhtml', object=>\@new_assets);
	print '</div>';
	print '</div>';
	print '</div>';
	

    }elsif ( $submit eq 'Search' ){
	
	my $installed = Asset->get_installed_hash() 
	    unless $search_type eq 'all';

	my @assets;
	if ( $search ){
	    # Search for labels in Asset table and foreign objects recursively
	    my $r1 = $ui->select_query(table=>'Asset', terms=>[$search]);
	    @assets = values %$r1;

	    # Search for other fields in Asset table
	    my @where;
	    foreach my $field ( qw/custom_serial inventory_number reserved_for 
                               description info po_number/ ){
		push @where, { $field => { '-like' => '%'.$search.'%' } };
	    }
	    push @assets, Asset->search_where(\@where);
	}else{
	    # No criteria given. Get all.
	    @assets = Asset->retrieve_all();
	}
	my %res;
	for ( @assets ) {
	    if ( $search_type eq 'all' || 
		 ($search_type eq 'installed' && $installed->{$_->id}) ||
		 ($search_type eq 'not installed' && !exists $installed->{$_->id}) ){
		$res{$_->id} = $_;
	    }
	}
	@list = values %res;
	if ( @list ){
	    $m->comp('/generic/show_search_results.mhtml', search=>$search, list=>\@list, dowindow=>1 );
	}else{
	    $m->comp('/generic/no_search_results.html', search=>$search);
	}
    }
}
</%perl>


<%def .show_message>
<%args>
$title => undef
$msg   => undef
</%args>
<div class="container">
    <div class="containerhead">
       <strong><% $title %></strong>   
    </div>
    <div class="containerbody">
       <% $msg %><br>
    </div>
</div>
</%def>

