1package App::Netdisco::Web::Plugin::Report::ModuleInventory; 2 3use Dancer ':syntax'; 4use Dancer::Plugin::DBIC; 5use Dancer::Plugin::Auth::Extensible; 6use App::Netdisco::Util::ExpandParams 'expand_hash'; 7 8use App::Netdisco::Web::Plugin; 9use List::MoreUtils (); 10 11register_report( 12 { category => 'Device', 13 tag => 'moduleinventory', 14 label => 'Module Inventory', 15 provides_csv => 1, 16 } 17); 18 19hook 'before_template' => sub { 20 my $tokens = shift; 21 22 return 23 unless ( 24 request->path eq uri_for('/report/moduleinventory')->path 25 or index( request->path, 26 uri_for('/ajax/content/report/moduleinventory')->path ) == 0 27 ); 28 29 # used in the search sidebar template to set selected items 30 foreach my $opt (qw/class/) { 31 my $p = ( 32 ref [] eq ref param($opt) 33 ? param($opt) 34 : ( param($opt) ? [ param($opt) ] : [] ) 35 ); 36 $tokens->{"${opt}_lkp"} = { map { $_ => 1 } @$p }; 37 } 38}; 39 40get '/ajax/content/report/moduleinventory/data' => require_login sub { 41 send_error( 'Missing parameter', 400 ) 42 unless ( param('draw') && param('draw') =~ /\d+/ ); 43 44 my $rs = schema('netdisco')->resultset('DeviceModule'); 45 $rs = $rs->search( { -bool => 'fru' } ) if param('fruonly'); 46 47 if ( param('device') ) { 48 my @ips = schema('netdisco')->resultset('Device') 49 ->search_fuzzy( param('device') )->get_column('ip')->all; 50 51 params->{'ips'} = \@ips; 52 } 53 54 $rs = $rs->search_by_field( scalar params )->columns( 55 [ 'ip', 'description', 'name', 'class', 56 'type', 'serial', 'hw_ver', 'fw_ver', 57 'sw_ver', 'model' 58 ] 59 )->search( 60 {}, 61 { '+columns' => [qw/ device.dns device.name /], 62 join => 'device', 63 collapse => 1, 64 } 65 ); 66 67 my $exp_params = expand_hash( scalar params ); 68 69 my $recordsTotal = $rs->count; 70 71 my @data = $rs->get_datatables_data($exp_params)->hri->all; 72 73 my $recordsFiltered = $rs->get_datatables_filtered_count($exp_params); 74 75 content_type 'application/json'; 76 return to_json( 77 { draw => int( param('draw') ), 78 recordsTotal => int($recordsTotal), 79 recordsFiltered => int($recordsFiltered), 80 data => \@data, 81 } 82 ); 83}; 84 85get '/ajax/content/report/moduleinventory' => require_login sub { 86 87 my $has_opt = List::MoreUtils::any { param($_) } 88 qw/device description name type model serial class/; 89 90 my $rs = schema('netdisco')->resultset('DeviceModule'); 91 $rs = $rs->search( { -bool => 'fru' } ) if param('fruonly'); 92 my @results; 93 94 if ( $has_opt && !request->is_ajax ) { 95 96 if ( param('device') ) { 97 my @ips = schema('netdisco')->resultset('Device') 98 ->search_fuzzy( param('device') )->get_column('ip')->all; 99 100 params->{'ips'} = \@ips; 101 } 102 103 @results = $rs->search_by_field( scalar params )->columns( 104 [ 'ip', 'description', 'name', 'class', 105 'type', 'serial', 'hw_ver', 'fw_ver', 106 'sw_ver', 'model' 107 ] 108 )->search( 109 {}, 110 { '+columns' => [qw/ device.dns device.name /], 111 join => 'device', 112 collapse => 1, 113 } 114 )->hri->all; 115 116 return unless scalar @results; 117 } 118 elsif ( !$has_opt ) { 119 @results = $rs->search( 120 { class => { '!=', undef } }, 121 { select => [ 'class', { count => 'class' } ], 122 as => [qw/ class count /], 123 group_by => [qw/ class /] 124 } 125 )->order_by( { -desc => 'count' } )->hri->all; 126 127 return unless scalar @results; 128 } 129 130 if ( request->is_ajax ) { 131 my $json = to_json( \@results ); 132 template 'ajax/report/moduleinventory.tt', 133 { results => $json, opt => $has_opt }, 134 { layout => undef }; 135 } 136 else { 137 header( 'Content-Type' => 'text/comma-separated-values' ); 138 template 'ajax/report/moduleinventory_csv.tt', 139 { results => \@results, opt => $has_opt }, 140 { layout => undef }; 141 } 142}; 143 1441; 145