=cut
sub num_avail {
- shift->num_sql('( svcnum IS NULL OR svcnum = 0 )');
+ my( $self, $sql ) = @_;
+ $sql .= ' AND ' if length($sql);
+ $sql .= '( svcnum IS NULL OR svcnum = 0 )';
+ $self->num_sql($sql);
}
sub num_sql {
=cut
sub num_used {
- shift->num_sql("svcnum IS NOT NULL AND svcnum > 0 ");
+ my( $self, $sql ) = @_;
+ $sql .= ' AND ' if length($sql);
+ $sql .= 'svcnum IS NOT NULL AND svcnum > 0 ';
+ $self->num_sql($sql);
}
=item num_total
=cut
sub num_total {
- shift->num_sql('');
+ my( $self, $sql ) = @_;
+ $self->num_sql($sql);
+}
+
+=back
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item searchcell_factory
+
+=cut
+
+sub countcell_factory {
+ my($class, %opt) = @_;
+
+ my $p = $opt{p};
+
+ my $sql = $opt{'agentnum'} ? 'agentnum = '.$opt{'agentnum'} : '';
+
+ use Tie::IxHash;
+ tie my %labels, 'Tie::IxHash',
+ 'num_avail' => 'Available', # <FONT SIZE="-1"><A HREF="eventually">(upload batch)</A></FONT>',
+ 'num_used' => 'In use', #'Used', #'Allocated',
+ 'num_total' => 'Total',
+ ;
+
+ my %link = (
+ 'num_avail' => ';avail=1',
+ 'num_used' => ';used=1',
+ 'num_total' => '',
+ );
+
+ my %inv_action_link = (
+ 'num_avail' => [ 'upload batch',
+ $p.'misc/inventory_item-import.html?classnum=',
+ 'classnum'
+ ],
+ );
+
+ sub {
+ my $inventory_class = shift;
+
+ my $link =
+ $p. 'search/inventory_item.html?'.
+ 'classnum='. $inventory_class->classnum;
+ $link .= ';agentnum='.$opt{'agentnum'} if $opt{'agentnum'};
+
+ my %actioncol = ();
+ foreach ( keys %inv_action_link ) {
+ my($label, $baseurl, $method) =
+ @{ $inv_action_link{$_} };
+ my $url = $baseurl. $inventory_class->$method();
+ $actioncol{$_} =
+ '<FONT SIZE="-1">'.
+ '('.
+ '<A HREF="'.$url.'">'.
+ $label.
+ '</A>'.
+ ')'.
+ '</FONT>';
+ }
+
+ my %num = map {
+ $_ => $inventory_class->$_($sql);
+ } keys %labels;
+
+ [ map {
+ [
+ {
+ 'data' => '<B>'. $num{$_}. '</B>',
+ 'align' => 'right',
+ },
+ {
+ 'data' => $labels{$_},
+ 'align' => 'left',
+ 'link' => ( $num{$_}
+ ? $link.$link{$_}
+ : ''
+ ),
+ },
+ { 'data' => $actioncol{$_},
+ 'align' => 'left',
+ },
+ ]
+ } keys %labels
+ ];
+ };
}
=back
'header' => [ '#', 'Inventory class', 'Inventory' ],
'fields' => [ 'classnum',
'classname',
- sub {
- #my $inventory_class = shift;
- my $i_c = shift;
-
- my $link =
- $p. 'search/inventory_item.html?'.
- 'classnum='. $i_c->classnum;
-
- my %actioncol = ();
- foreach ( keys %inv_action_link ) {
- my($label, $baseurl, $method) =
- @{ $inv_action_link{$_} };
- my $url = $baseurl. $i_c->$method();
- $actioncol{$_} =
- '<FONT SIZE="-1">'.
- '('.
- '<A HREF="'.$url.'">'.
- $label.
- '</A>'.
- ')'.
- '</FONT>';
- }
-
- my %num = map {
- $_ => $i_c->$_();
- } keys %labels;
-
- [ map {
- [
- {
- 'data' => '<B>'. $num{$_}. '</B>',
- 'align' => 'right',
- },
- {
- 'data' => $labels{$_},
- 'align' => 'left',
- 'link' => ( $num{$_}
- ? $link.$link{$_}
- : ''
- ),
- },
- { 'data' => $actioncol{$_},
- 'align' => 'left',
- },
- ]
- } keys %labels
- ];
- },
+ FS::inventory_class->countcell_factory(
+ 'p'=>$p,
+ ),
],
'links' => [ $link,
$link,
|| $curuser->access_right('Edit global inventory')
|| $curuser->access_right('Configuration');
-tie my %labels, 'Tie::IxHash',
- 'num_avail' => 'Available', # <FONT SIZE="-1"><A HREF="eventually">(upload batch)</A></FONT>',
- 'num_used' => 'In use', #'Used', #'Allocated',
- 'num_total' => 'Total',
-;
-
-my %link = (
- 'num_avail' => ';avail=1',
- 'num_used' => ';used=1',
- 'num_total' => '',
-);
-
-my %inv_action_link = (
- 'num_avail' => [ 'upload batch',
- $p.'misc/inventory_item-import.html?classnum=',
- 'classnum'
- ],
-);
-
my $menubar = $curuser->access_right('Configuration')
? [ 'Add a new inventory class' =>
$p.'edit/inventory_class.html',
if $conf->exists('cust_main-require_censustract');
$report_packages{'Advanced package reports'} = [ $fsurl.'search/report_cust_pkg.html', 'by agent, date range, status, package definition' ];
+tie my %report_inventory, 'Tie::IxHash',
+ 'Inventory by agent' => [ $fsurl.'search/report_agent_inventory.html', '' ],
+ #'Inventory activity' => [ $fsurl.'search/report_h_inventory_item.html', '' ],
+;
+
tie my %report_rating, 'Tie::IxHash',
'RADIUS sessions' => [ $fsurl.'search/sqlradius.html', '' ],
'Call Detail Records (CDRs)' => [ $fsurl.'search/report_cdr.html', '' ],
if $curuser->access_right('List packages');
$report_menu{'Services'} = [ \%report_services, 'Services reports' ]
if $curuser->access_right('List services');
+$report_menu{'Inventory'} = [ \%report_inventory, 'Inventory reports' ]
+ if $curuser->access_right('Configuration'); #XXX List inventory?
$report_menu{'Usage'} = [ \%report_rating, 'Usage reports' ]
if $curuser->access_right('List rating data');
$report_menu{'Tickets'} = [ \%report_ticketing, 'Ticket reports' ]
--- /dev/null
+<% include('elements/search.html',
+ 'title' => 'Inventory summary per agent',
+ 'name_singular' => 'agent',
+ 'query' => { 'table' => 'agent',
+ 'hashref' => { 'disabled' => '' },
+ 'extra_sql' => "AND $agentnums_sql",
+ },
+ 'count_query' => "SELECT COUNT(*) FROM agent".
+ " WHERE disabled = '' OR disabled IS NULL".
+ " AND $agentnums_sql",
+ 'header' => \@header,
+ 'fields' => \@fields,
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+#XXX List inventory
+
+my $agentnums_sql = $FS::CurrentUser::CurrentUser->agentnums_sql;
+
+my @header = ('Agent');
+my @fields = ('agent');
+
+ #{ 'disabled' => '' }
+foreach my $inventory_class ( qsearch('inventory_class', {}) ) {
+ push @header, $inventory_class->classname;
+ push @fields, sub {
+ my $agent = shift;
+ my $sub = FS::inventory_class->countcell_factory(
+ 'p' => $p, 'agentnum' => $agent->agentnum,
+ );
+ &{$sub}($inventory_class);
+ };
+}
+
+#XXX show global inventory too
+
+</%init>
my $title = $inventory_class->classname. ' Inventory';
+if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
+ $extra_sql .= " AND inventory_item.agentnum = $1 ";
+ my $agent = qsearchs('agent', { 'agentnum' => $1 }) or die "unknown agentnum";
+ $title = $agent->agent. " $title";
+}
+
#little false laziness with SQL fragments in inventory_class.pm
if ( $cgi->param('avail') ) {
$extra_sql .= ' AND ( svcnum IS NULL OR svcnum = 0 )';
--- /dev/null
+<% include('/elements/header.html', 'Inventory summary per agent' ) %>
+
+<FORM ACTION="agent_inventory.html" METHOD="GET">
+
+<TABLE BGCOLOR="#cccccc" CELLSPACING=0>
+
+%# select agents
+
+%# select inventory classes
+
+</TABLE>
+
+<BR>
+<INPUT TYPE="submit" VALUE="Search">
+
+</FORM>
+
+<% include('/elements/footer.html') %>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+#XXX List inventory
+
+</%init>
+