1package App::Netdisco::Web::Plugin::Report::NodeVendor; 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; 9 10register_report( 11 { category => 'Node', 12 tag => 'nodevendor', 13 label => 'Node Vendor Inventory', 14 provides_csv => 1, 15 } 16); 17 18hook 'before_template' => sub { 19 my $tokens = shift; 20 21 return 22 unless ( 23 request->path eq uri_for('/report/nodevendor')->path 24 or index( request->path, 25 uri_for('/ajax/content/report/nodevendor')->path ) == 0 26 ); 27 28 # used in the search sidebar template to set selected items 29 foreach my $opt (qw/vendor/) { 30 my $p = ( 31 ref [] eq ref param($opt) 32 ? param($opt) 33 : ( param($opt) ? [ param($opt) ] : [] ) 34 ); 35 $tokens->{"${opt}_lkp"} = { map { $_ => 1 } @$p }; 36 } 37}; 38 39get '/ajax/content/report/nodevendor/data' => require_login sub { 40 send_error( 'Missing parameter', 400 ) 41 unless ( param('draw') && param('draw') =~ /\d+/ ); 42 43 my $vendor = param('vendor'); 44 45 my $rs = schema('netdisco')->resultset('Node'); 46 47 my $match = $vendor eq 'blank' ? undef : $vendor; 48 49 $rs = $rs->search( { 'oui.abbrev' => $match }, 50 { '+columns' => [qw/ device.dns device.name oui.abbrev oui.company /], 51 join => [qw/ oui device /], 52 collapse => 1, 53 }); 54 55 unless ( param('archived') ) { 56 $rs = $rs->search( { -bool => 'me.active' } ); 57 } 58 59 my $exp_params = expand_hash( scalar params ); 60 61 my $recordsTotal = $rs->count; 62 63 my @data = $rs->get_datatables_data($exp_params)->hri->all; 64 65 my $recordsFiltered = $rs->get_datatables_filtered_count($exp_params); 66 67 content_type 'application/json'; 68 return to_json( 69 { draw => int( param('draw') ), 70 recordsTotal => int($recordsTotal), 71 recordsFiltered => int($recordsFiltered), 72 data => \@data, 73 } 74 ); 75}; 76 77get '/ajax/content/report/nodevendor' => require_login sub { 78 79 my $vendor = param('vendor'); 80 81 my $rs = schema('netdisco')->resultset('Node'); 82 my @results; 83 84 if ( defined $vendor && !request->is_ajax ) { 85 86 my $match = $vendor eq 'blank' ? undef : $vendor; 87 88 $rs = $rs->search( { 'oui.abbrev' => $match }, 89 { '+columns' => [qw/ device.dns device.name oui.abbrev oui.company /], 90 join => [qw/ oui device /], 91 collapse => 1, 92 }); 93 94 unless ( param('archived') ) { 95 $rs = $rs->search( { -bool => 'me.active' } ); 96 } 97 98 @results = $rs->hri->all; 99 return unless scalar @results; 100 } 101 elsif ( !defined $vendor ) { 102 $rs = $rs->search( 103 { }, 104 { join => 'oui', 105 select => [ 'oui.abbrev', 'oui.company', { count => {distinct => 'me.mac'}} ], 106 as => [qw/ abbrev vendor count /], 107 group_by => [qw/ oui.abbrev oui.company /] 108 } 109 )->order_by( { -desc => 'count' } ); 110 111 unless ( param('archived') ) { 112 $rs = $rs->search( { -bool => 'me.active' } ); 113 } 114 115 @results = $rs->hri->all; 116 return unless scalar @results; 117 } 118 119 if ( request->is_ajax ) { 120 my $json = to_json( \@results ); 121 template 'ajax/report/nodevendor.tt', 122 { results => $json, opt => $vendor }, 123 { layout => undef }; 124 } 125 else { 126 header( 'Content-Type' => 'text/comma-separated-values' ); 127 template 'ajax/report/nodevendor_csv.tt', 128 { results => \@results, opt => $vendor }, 129 { layout => undef }; 130 } 131}; 132 1331; 134