1 <% include( 'elements/search.html',
3 'name_singular' => $name,
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,
21 #this is about reports about packages definitions (starting w/commission ones)
22 # while browse/part_pkg.cgi is config->package definitions
24 my $curuser = $FS::CurrentUser::CurrentUser;
26 unless $curuser->access_right('Financial reports');
28 my $conf = new FS::Conf;
29 my $money_char = $conf->config('money_char') || '$';
31 my $title = 'Package definition report';
32 my $name = 'package definition';
46 if (1) { #commission reports
48 if (1) { #employee commission reports
50 $group_by = join(', ',
51 ( map "access_user.$_", qw( usernum username ) ),
52 ( map "part_pkg.$_", qw( pkgpart pkg comment plan ) ),
57 $addl_from .= ' CROSS JOIN access_user ';
59 $match = 'cust_pkg.usernum = access_user.usernum';
61 if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
63 #XXX in this context, agent virt for employees, not package defs
64 my $access_user = qsearchs('access_user', { 'usernum' => $1, })
65 or die "unknown usernum";
67 $title = $access_user->name;
69 push @top_where, 'access_user.usernum = '. $access_user->usernum;
73 push @header, 'Employee';
74 push @fields, sub { shift->get('username'); }; #access_user->name
75 push @links, ''; #link to employee edit w/ACL?
78 push @order_by, 'usernum'; #join to username? we're mostly interested in grouping rather than order
84 } elsif (0) { #agent commission reports
86 $match = 'cust_main.agentnum = agent.agentnum'; #XXX need to join to this
88 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
91 my $agent = qsearchs('agent', { 'agentnum' => $1 })
92 or die "unknown agentnum";
94 $title = $agent->agent;
96 push @header, 'Agent';
97 push @fields, sub { 'XXXagent' };
98 push @links, ''; #link to agent edit w/ACL?
101 push @order_by, 'agentnum'; #join to agent? we're mostly interested in grouping rather than order
110 LEFT JOIN cust_pkg ON ( part_pkg.pkgpart = cust_pkg.pkgpart
112 LEFT JOIN cust_bill_pkg USING ( pkgnum )
113 LEFT JOIN cust_bill USING ( invnum )
116 $title .= ' commission report';
117 $name = "commissionable $name";
122 push @header, 'Package definition';
123 push @fields, 'pkg_comment';
124 push @links, ''; #link to pkg definition edit w/ACL?
127 if (1) { #commission reports
129 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
131 push @where, " cust_bill_pkg.pkgnum > 0 ",
132 " cust_bill._date >= $beginning ",
133 " cust_bill._date <= $ending ";
135 push @header, '#'; # of sales';
136 push @links, ''; #link to detail report
138 push @fields, 'num_cust_pkg';
139 $select .= ", COUNT(DISTINCT cust_pkg.pkgnum) AS num_cust_pkg";
141 push @header, 'Sales';
142 push @links, ''; #link to detail report
144 # push @fields, sub { $money_char. sprintf('%.2f', shift->get('pkg_sales')); };
146 # ", SUM( SELECT setup+recur $from_cust_bill_pkg_where ) AS pkg_sales";
148 my $part_pkg = shift;
149 my $sql = "SELECT SUM(cust_bill_pkg.setup+cust_bill_pkg.recur)".
150 # " FROM cust_bill_pkg $addl_from $where AND pkgpart = ? AND ";
152 LEFT JOIN cust_pkg USING ( pkgnum )
153 LEFT JOIN cust_bill USING ( invnum )
154 WHERE ". join(' AND ', @where).
155 " AND pkgpart = ? AND ";
156 my @arg = ($part_pkg->pkgpart);
157 if (1) { #employee commission reports
158 $sql .= 'usernum = ?';
159 push @arg, $part_pkg->get('usernum');
160 } elsif (0) { #agent commission reports
161 $match = 'cust_main.agentnum = agent.agentnum';
163 my $sth = dbh->prepare($sql) or die dbh->errstr;
164 $sth->execute(@arg) or die $sth->errstr;
165 $money_char. sprintf('%.2f', $sth->fetchrow_arrayref->[0] );
168 push @header, 'Commission';
169 push @links, ''; #link to detail report
171 #push @fields, sub { $money_char. sprintf('%.2f', shift->get('pkg_commission')); };
173 my $part_pkg = shift;
174 my $sql = "SELECT SUM(amount) FROM cust_credit
175 LEFT JOIN cust_event USING ( eventnum )
176 LEFT JOIN part_event USING ( eventpart )
177 LEFT JOIN cust_pkg ON ( cust_event.tablenum = cust_pkg.pkgnum )
178 WHERE eventnum IS NOT NULL
179 AND action IN ( 'pkg_employee_credit',
180 'pkg_employee_credit_pkg'
182 AND cust_credit._date >= $beginning
183 AND cust_credit._date <= $ending
185 AND cust_credit.custnum = ?
187 my @arg = ($part_pkg->pkgpart);
188 if (1) { #employee commission reports
190 #XXX in this context, agent virt for employees, not package defs
191 my $access_user = qsearchs('access_user', { 'usernum' => $part_pkg->get('usernum'), })
192 or die "unknown usernum";
194 return $money_char.'0.00' unless $access_user->user_custnum;
195 push @arg, $access_user->user_custnum;
197 } elsif (0) { #agent commission reports
198 push @arg, 'XXXagent_custnum'; #$agent->agent_custnum
201 #warn join(',', @arg);
202 my $sth = dbh->prepare($sql) or die dbh->errstr;
203 $sth->execute(@arg) or die $sth->errstr;
204 $money_char. sprintf('%.2f', $sth->fetchrow_arrayref->[0] );
210 push @order_by, 'pkgpart'; #pkg?
212 $select ||= 'part_pkg.*';
213 push @top_where, @where;
214 my $extra_sql = scalar(@top_where) ? 'WHERE ' . join(' AND ', @top_where) : '';
215 $extra_sql .= "GROUP BY $group_by" if $group_by;
216 my $order_by = join(', ', @order_by);
219 #my $count_query = "SELECT COUNT(*) FROM ( SELECT 1 FROM part_pkg $addl_from $extra_sql ) AS num";
221 my $count_query = "SELECT COUNT(*) FROM ( SELECT DISTINCT part_pkg.pkgpart FROM part_pkg $addl_from $extra_sql ) AS num";