fix check# search
[freeside.git] / httemplate / search / cust_pay.cgi
1 <% include( 'elements/search.html',
2                  'title'       => $title,
3                  'name'        => 'payments',
4                  'query'       => $sql_query,
5                  'count_query' => $count_query,
6                  'count_addl'  => [ '$%.2f total paid', ],
7                  'header'      => [ 'Payment',
8                                     'Amount',
9                                     'Date',
10                                     FS::UI::Web::cust_header(),
11                                   ],
12                  'fields'      => [
13                    sub {
14                      my $cust_pay = shift;
15                      if ( $cust_pay->payby eq 'CARD' ) {
16                        'Card #'. $cust_pay->paymask;
17                      } elsif ( $cust_pay->payby eq 'CHEK' ) {
18                        'E-check acct#'. $cust_pay->payinfo;
19                      } elsif ( $cust_pay->payby eq 'BILL' ) {
20                        'Check #'. $cust_pay->payinfo;
21                      } elsif ( $cust_pay->payby eq 'PREP' ) {
22                        'Prepaid card #'. $cust_pay->payinfo;
23                      } elsif ( $cust_pay->payby eq 'CASH' ) {
24                        'Cash '. $cust_pay->payinfo;
25                      } elsif ( $cust_pay->payby eq 'WEST' ) {
26                        'Western Union'; #. $cust_pay->payinfo;
27                      } elsif ( $cust_pay->payby eq 'MCRD' ) {
28                        'Manual credit card'; #. $cust_pay->payinfo;
29                      } else {
30                        $cust_pay->payby. ' '. $cust_pay->payinfo;
31                      }
32                    },
33                    sub { sprintf('$%.2f', shift->paid ) },
34                    sub { time2str('%b %d %Y', shift->_date ) },
35                    \&FS::UI::Web::cust_fields,
36                  ],
37                  #'align' => 'lrrrll',
38                  'align' => 'rrr'.FS::UI::Web::cust_aligns(),
39                  'links' => [
40                    '',
41                    '',
42                    '',
43                    ( map { $_ ne 'Cust. Status' ? $link : '' }
44                          FS::UI::Web::cust_header()
45                    ),
46                  ],
47                  'color' => [ 
48                               '',
49                               '',
50                               '',
51                               FS::UI::Web::cust_colors(),
52                             ],
53                  'style' => [ 
54                               '',
55                               '',
56                               '',
57                               FS::UI::Web::cust_styles(),
58                             ],
59       )
60 %>
61 <%init>
62
63 die "access denied"
64   unless $FS::CurrentUser::CurrentUser->access_right('Financial reports');
65
66 my $title = 'Payment Search Results';
67 my( $count_query, $sql_query );
68 if ( $cgi->param('magic') ) {
69
70   my @search = ();
71   my $orderby;
72   if ( $cgi->param('magic') eq '_date' ) {
73
74
75     if ( $cgi->param('agentnum') && $cgi->param('agentnum') =~ /^(\d+)$/ ) {
76       push @search, "agentnum = $1"; # $search{'agentnum'} = $1;
77       my $agent = qsearchs('agent', { 'agentnum' => $1 } );
78       die "unknown agentnum $1" unless $agent;
79       $title = $agent->agent. " $title";
80     }
81   
82     if ( $cgi->param('payby') ) {
83       $cgi->param('payby') =~
84         /^(CARD|CHEK|BILL|PREP|CASH|WEST|MCRD)(-(VisaMC|Amex|Discover|Maestro))?$/
85           or die "illegal payby ". $cgi->param('payby');
86       push @search, "cust_pay.payby = '$1'";
87       if ( $3 ) {
88
89         my $cardtype = $3;
90
91         my $search;
92         if ( $cardtype eq 'VisaMC' ) {
93           #avoid posix regexes for portability
94           $search =
95             " ( (     substring(cust_pay.payinfo from 1 for 1) = '4'     ".
96             "     AND substring(cust_pay.payinfo from 1 for 4) != '4936' ".
97             "     AND substring(cust_pay.payinfo from 1 for 6)           ".
98             "         NOT SIMILAR TO '49030[2-9]'                        ".
99             "     AND substring(cust_pay.payinfo from 1 for 6)           ".
100             "         NOT SIMILAR TO '49033[5-9]'                        ".
101             "     AND substring(cust_pay.payinfo from 1 for 6)           ".
102             "         NOT SIMILAR TO '49110[1-2]'                        ".
103             "     AND substring(cust_pay.payinfo from 1 for 6)           ".
104             "         NOT SIMILAR TO '49117[4-9]'                        ".
105             "     AND substring(cust_pay.payinfo from 1 for 6)           ".
106             "         NOT SIMILAR TO '49118[1-2]'                        ".
107             "   )".
108             "   OR substring(cust_pay.payinfo from 1 for 2) = '51' ".
109             "   OR substring(cust_pay.payinfo from 1 for 2) = '52' ".
110             "   OR substring(cust_pay.payinfo from 1 for 2) = '53' ".
111             "   OR substring(cust_pay.payinfo from 1 for 2) = '54' ".
112             "   OR substring(cust_pay.payinfo from 1 for 2) = '54' ".
113             "   OR substring(cust_pay.payinfo from 1 for 2) = '55' ".
114             "   OR substring(cust_pay.payinfo from 1 for 2) = '36' ". #Diner's int'l processed as Visa/MC inside US
115             " ) ";
116         } elsif ( $cardtype eq 'Amex' ) {
117           $search =
118             " (    substring(cust_pay.payinfo from 1 for 2 ) = '34' ".
119             "   OR substring(cust_pay.payinfo from 1 for 2 ) = '37' ".
120             " ) ";
121         } elsif ( $cardtype eq 'Discover' ) {
122           $search =
123             " (    substring(cust_pay.payinfo from 1 for 4 ) = '6011'  ".
124             "   OR substring(cust_pay.payinfo from 1 for 2 ) = '65'    ".
125             "   OR substring(cust_pay.payinfo from 1 for 3 ) = '622'   ". #China Union Pay processed as Discover outside CN
126             " ) ";
127         } elsif ( $cardtype eq 'Maestro' ) { 
128           $search =
129             " (    substring(cust_pay.payinfo from 1 for 2 ) = '63'     ".
130             "   OR substring(cust_pay.payinfo from 1 for 2 ) = '67'     ".
131             "   OR substring(cust_pay.payinfo from 1 for 6 ) = '564182' ".
132             "   OR substring(cust_pay.payinfo from 1 for 4 ) = '4936'   ".
133             "   OR substring(cust_pay.payinfo from 1 for 6 )            ".
134             "      SIMILAR TO '49030[2-9]'                             ".
135             "   OR substring(cust_pay.payinfo from 1 for 6 )            ".
136             "      SIMILAR TO '49033[5-9]'                             ".
137             "   OR substring(cust_pay.payinfo from 1 for 6 )            ".
138             "      SIMILAR TO '49110[1-2]'                             ".
139             "   OR substring(cust_pay.payinfo from 1 for 6 )            ".
140             "      SIMILAR TO '49117[4-9]'                             ".
141             "   OR substring(cust_pay.payinfo from 1 for 6 )            ".
142             "      SIMILAR TO '49118[1-2]'                             ".
143             " ) ";
144         } else {
145           die "unknown card type $cardtype";
146         }
147
148         my $masksearch = $search;
149         $masksearch =~ s/cust_pay\.payinfo/cust_pay.paymask/gi;
150
151         push @search,
152           "( $search OR ( cust_pay.paymask IS NOT NULL AND $masksearch ) )";
153
154       }
155     }
156
157     if ( $cgi->param('payinfo') ) {
158       $cgi->param('payinfo') =~ /^\s*(\d+)\s*$/
159         or die "illegal payinfo ". $cgi->param('payinfo');
160       push @search, "cust_pay.payinfo = '$1'";
161     }
162
163     my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
164     push @search, "_date >= $beginning ",
165                   "_date <= $ending";
166
167     push @search, FS::UI::Web::parse_lt_gt($cgi, 'paid' );
168
169     $orderby = '_date';
170
171   } elsif ( $cgi->param('magic') eq 'paybatch' ) {
172
173     $cgi->param('paybatch') =~ /^([\w\/\:\-\.]+)$/
174       or die "illegal paybatch: ". $cgi->param('paybatch');
175
176     push @search, "paybatch = '$1'";
177
178     $orderby = "LOWER(company || ' ' || last || ' ' || first )";
179
180   } else {
181     die "unknown search magic: ". $cgi->param('magic');
182   }
183
184   #here is the agent virtualization
185   push @search, $FS::CurrentUser::CurrentUser->agentnums_sql;
186
187   my $search = ' WHERE '. join(' AND ', @search);
188
189   $count_query = "SELECT COUNT(*), SUM(paid) ".
190                  "FROM cust_pay LEFT JOIN cust_main USING ( custnum )".
191                  $search;
192
193   $sql_query = {
194     'table'     => 'cust_pay',
195     'select'    => join(', ',
196                      'cust_pay.*',
197                      'cust_main.custnum as cust_main_custnum',
198                      FS::UI::Web::cust_sql_fields(),
199                    ),
200     'hashref'   => {},
201     'extra_sql' => "$search ORDER BY $orderby",
202     'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
203   };
204
205 } else {
206
207   #hmm... is this still used?
208
209   $cgi->param('payinfo') =~ /^\s*(\d+)\s*$/ or die "illegal payinfo";
210   my $payinfo = $1;
211
212   $cgi->param('payby') =~ /^(\w+)$/ or die "illegal payby";
213   my $payby = $1;
214
215   $count_query = "SELECT COUNT(*), SUM(paid) FROM cust_pay".
216                  "  WHERE payinfo = '$payinfo' AND payby = '$payby'".
217                  "  AND ". $FS::CurrentUser::CurrentUser->agentnums_sql;
218
219   $sql_query = {
220     'table'     => 'cust_pay',
221     'hashref'   => { 'payinfo' => $payinfo,
222                      'payby'   => $payby    },
223     'extra_sql' => $FS::CurrentUser::CurrentUser->agentnums_sql.
224                    " ORDER BY _date",
225   };
226
227 }
228
229 my $link = sub {
230   my $cust_pay = shift;
231   $cust_pay->cust_main_custnum
232     ? [ "${p}view/cust_main.cgi?", 'custnum' ] 
233     : '';
234 };
235
236 </%init>