optimize employee commission report, RT#13390
[freeside.git] / httemplate / search / part_pkg.html
1 <% include( 'elements/search.html',
2               'title'       => $title,
3               'name'        => $name,
4               'header'      => \@header,
5               'query'       => { 'select'    => $select,
6                                  'table'     => 'part_pkg',
7                                  'addl_from' => $addl_from,
8                                  'hashref'   => {},
9                                  'extra_sql' => $extra_sql,
10                                  'order_by'  => "ORDER BY $order_by",
11                                },
12               'count_query' => $count_query,
13               'fields'      => \@fields,
14               'links'       => \@links,
15               'align'       => $align,
16           )
17 %>
18 <%init>
19
20 #this is about reports about packages definitions (starting w/commission ones)
21 # while browse/part_pkg.cgi is config->package definitions
22
23 my $curuser = $FS::CurrentUser::CurrentUser;
24 die "access denied"
25   unless $curuser->access_right('Financial reports');
26
27 my $conf = new FS::Conf;
28 my $money_char = $conf->config('money_char') || '$';
29
30 my $title = 'Package definition report';
31 my $name = 'package definition';
32
33 my $select = '';
34 my $addl_from = '';
35 my @where = ();
36 my @order_by = ();
37 my @header = ();
38 my @fields = ();
39 my @links  = ();
40 my $align  = '';
41 my $group_by = '';
42 my $match = '';
43
44 if (1) { #commission reports
45
46   if (1) { #employee commission reports 
47
48     $group_by = join(', ', ( map "access_user.$_", qw( usernum username    ) ),
49                            ( map "part_pkg.$_",    qw( pkgpart pkg comment ) ),
50                     );
51
52     $select = $group_by;
53
54     $addl_from .= ' CROSS JOIN access_user ';
55
56     $match = 'cust_pkg.usernum = access_user.usernum';
57
58     if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
59
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";
63
64       $title = $access_user->name;
65
66     } else {
67
68       push @header, 'Employee';
69       push @fields, sub { shift->get('username'); }; #access_user->name
70       push @links, ''; #link to employee edit w/ACL?
71       $align .= 'c';
72
73       push @order_by, 'usernum'; #join to username?  we're mostly interested in grouping rather than order
74
75       $title = 'Employee';
76
77     }
78
79   } elsif (0) { #agent commission reports
80
81     $match = 'cust_main.agentnum = agent.agentnum'; #XXX need to join to this
82
83     if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
84
85       #agent virt
86       my $agent = qsearchs('agent', { 'agentnum' => $1 })
87         or die "unknown agentnum";
88
89       $title = $agent->agent;
90
91       push @header, 'Agent';
92       push @fields, sub { 'XXXagent' };
93       push @links, ''; #link to agent edit w/ACL?
94       $align .= 'c';
95
96       push @order_by, 'agentnum'; #join to agent?  we're mostly interested in grouping rather than order
97
98     } else {
99       $title = 'Agent';
100     }
101
102   }
103
104   $addl_from .= "
105     LEFT JOIN cust_pkg ON ( part_pkg.pkgpart = cust_pkg.pkgpart
106                               AND $match )
107     LEFT JOIN cust_bill_pkg USING ( pkgnum )
108     LEFT JOIN cust_bill USING ( invnum )
109   ";
110
111   $title .= ' commission report';
112   $name = "commissionable $name";
113
114
115 }
116
117 push @header, 'Package definition';
118 push @fields, 'pkg_comment';
119 push @links, ''; #link to pkg definition edit w/ACL?
120 $align .= 'l';
121
122 if (1) { #commission reports
123
124   my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
125
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";
131
132   push @header, '#'; # of sales';
133   push @links, ''; #link to detail report
134   $align .= 'r';
135   push @fields, 'num_cust_pkg';
136   $select .= ", COUNT(DISTINCT cust_pkg.pkgnum) AS num_cust_pkg";
137
138   push @header, 'Sales';
139   push @links, ''; #link to detail report
140   $align .= 'r';
141 #  push @fields, sub { $money_char. sprintf('%.2f', shift->get('pkg_sales')); };
142 #  $select .=
143 #    ", SUM( SELECT setup+recur $from_cust_bill_pkg_where ) AS pkg_sales";
144   push @fields, sub {
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 ";
148               " FROM cust_bill_pkg
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';
158     }
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] );
162   };
163
164   push @header, 'Commission';
165   push @links, ''; #link to detail report
166   $align .= 'r';
167   #push @fields, sub { $money_char. sprintf('%.2f', shift->get('pkg_commission')); };
168   push @fields, sub {
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'
177                                  )
178                    AND cust_credit._date >= $beginning
179                    AND cust_credit._date <= $ending         
180                    AND pkgpart = ?
181                    AND cust_credit.custnum = ?
182               ";
183     my @arg = ($part_pkg->pkgpart);
184     if (1) { #employee commission reports 
185
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";
189
190       return 0 unless $access_user->user_custnum;
191       push @arg, $access_user->user_custnum;
192
193     } elsif (0) { #agent commission reports
194       push @arg, 'XXXagent_custnum'; #$agent->agent_custnum
195     }
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] );
199      
200   };
201
202 }
203
204 push @order_by, 'pkgpart'; #pkg?
205
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);
210
211 my $count_query = "SELECT COUNT(*) FROM part_pkg $addl_from $extra_sql";
212
213 </%init>