1 <% include( 'elements/search.html',
5 'query' => { 'select' => $select,
7 'addl_from' => $addl_from,
9 'extra_sql' => $extra_sql,
10 'order_by' => "ORDER BY $order_by",
12 'count_query' => $count_query,
20 #this is about reports about packages definitions (starting w/commission ones)
21 # while browse/part_pkg.cgi is config->package definitions
23 my $curuser = $FS::CurrentUser::CurrentUser;
25 unless $curuser->access_right('Financial reports');
27 my $conf = new FS::Conf;
28 my $money_char = $conf->config('money_char') || '$';
30 my $title = 'Package definition report';
31 my $name = 'package definition';
44 if (1) { #commission reports
46 if (1) { #employee commission reports
48 $group_by = join(', ', ( map "access_user.$_", qw( usernum username ) ),
49 ( map "part_pkg.$_", qw( pkgpart pkg comment ) ),
54 $addl_from .= ' CROSS JOIN access_user ';
56 $match = 'cust_pkg.usernum = access_user.usernum';
58 if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
60 #XXX in this context, agent virt for employees, not package defs
61 my $access_user = qsearchs('access_user', { 'usernum' => $1, })
62 or die "unknown usernum";
64 $title = $access_user->name;
68 push @header, 'Employee';
69 push @fields, sub { shift->get('username'); }; #access_user->name
70 push @links, ''; #link to employee edit w/ACL?
73 push @order_by, 'usernum'; #join to username? we're mostly interested in grouping rather than order
79 } elsif (0) { #agent commission reports
81 $match = 'cust_main.agentnum = agent.agentnum'; #XXX need to join to this
83 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
86 my $agent = qsearchs('agent', { 'agentnum' => $1 })
87 or die "unknown agentnum";
89 $title = $agent->agent;
91 push @header, 'Agent';
92 push @fields, sub { 'XXXagent' };
93 push @links, ''; #link to agent edit w/ACL?
96 push @order_by, 'agentnum'; #join to agent? we're mostly interested in grouping rather than order
105 LEFT JOIN cust_pkg ON ( part_pkg.pkgpart = cust_pkg.pkgpart
107 LEFT JOIN cust_bill_pkg USING ( pkgnum )
108 LEFT JOIN cust_bill USING ( invnum )
111 $title .= ' commission report';
112 $name = "commissionable $name";
117 push @header, 'Package definition';
118 push @fields, 'pkg_comment';
119 push @links, ''; #link to pkg definition edit w/ACL?
122 if (1) { #commission reports
124 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
126 my $where = "WHERE cust_bill_pkg.pkgnum > 0
127 AND cust_bill._date >= $beginning
128 AND cust_bill._date <= $ending ";
129 my $and = " AND $match
130 AND cust_pkg.pkgpart = part_pkg.pkgpart";
132 push @header, '#'; # of sales';
133 push @links, ''; #link to detail report
135 push @fields, 'num_cust_pkg';
136 $select .= ", COUNT(DISTINCT cust_pkg.pkgnum) AS num_cust_pkg";
138 push @header, 'Sales';
139 push @links, ''; #link to detail report
141 # push @fields, sub { $money_char. sprintf('%.2f', shift->get('pkg_sales')); };
143 # ", SUM( SELECT setup+recur $from_cust_bill_pkg_where ) AS pkg_sales";
145 my $part_pkg = shift;
146 my $sql = "SELECT SUM(cust_bill_pkg.setup+cust_bill_pkg.recur)".
147 # " FROM cust_bill_pkg $addl_from $where AND pkgpart = ? AND ";
149 LEFT JOIN cust_pkg USING ( pkgnum )
150 LEFT JOIN cust_bill USING ( invnum )
151 $where AND pkgpart = ? AND ";
152 my @arg = ($part_pkg->pkgpart);
153 if (1) { #employee commission reports
154 $sql .= 'usernum = ?';
155 push @arg, $part_pkg->get('usernum');
156 } elsif (0) { #agent commission reports
157 $match = 'cust_main.agentnum = agent.agentnum';
159 my $sth = dbh->prepare($sql) or die dbh->errstr;
160 $sth->execute(@arg) or die $sth->errstr;
161 $money_char. sprintf('%.2f', $sth->fetchrow_arrayref->[0] );
164 push @header, 'Commission';
165 push @links, ''; #link to detail report
167 #push @fields, sub { $money_char. sprintf('%.2f', shift->get('pkg_commission')); };
169 my $part_pkg = shift;
170 my $sql = "SELECT SUM(amount) FROM cust_credit
171 LEFT JOIN cust_event USING ( eventnum )
172 LEFT JOIN part_event USING ( eventpart )
173 LEFT JOIN cust_pkg ON ( cust_event.tablenum = cust_pkg.pkgnum )
174 WHERE eventnum IS NOT NULL
175 AND action IN ( 'pkg_employee_credit',
176 'pkg_employee_credit_pkg'
178 AND cust_credit._date >= $beginning
179 AND cust_credit._date <= $ending
181 AND cust_credit.custnum = ?
183 my @arg = ($part_pkg->pkgpart);
184 if (1) { #employee commission reports
186 #XXX in this context, agent virt for employees, not package defs
187 my $access_user = qsearchs('access_user', { 'usernum' => $part_pkg->get('usernum'), })
188 or die "unknown usernum";
190 return 0 unless $access_user->user_custnum;
191 push @arg, $access_user->user_custnum;
193 } elsif (0) { #agent commission reports
194 push @arg, 'XXXagent_custnum'; #$agent->agent_custnum
196 my $sth = dbh->prepare($sql) or die dbh->errstr;
197 $sth->execute(@arg) or die $sth->errstr;
198 $money_char. sprintf('%.2f', $sth->fetchrow_arrayref->[0] );
204 push @order_by, 'pkgpart'; #pkg?
206 $select ||= 'part_pkg.*';
207 my $extra_sql = scalar(@where) ? 'WHERE ' . join(' AND ', @where) : '';
208 $extra_sql .= "GROUP BY $group_by" if $group_by;
209 my $order_by = join(', ', @order_by);
211 my $count_query = "SELECT COUNT(*) FROM part_pkg $addl_from $extra_sql";