move account search (httemplate/search/svc_acct.cgi) to new template, cust-fields...
[freeside.git] / FS / FS / UI / Web.pm
1 package FS::UI::Web;
2
3 use FS::Conf;
4 use FS::Record qw(dbdef);
5
6 #use vars qw(@ISA);
7 #use FS::UI
8 #@ISA = qw( FS::UI );
9
10 use Date::Parse;
11 sub parse_beginning_ending {
12   my($cgi) = @_;
13
14   $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/;
15   my $beginning = str2time($1) || 0;
16
17   #need an option to turn off the + 86399 ???
18   $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/;
19   my $ending =  ( $1 ? str2time($1) : 4294880896 ) + 86399;
20
21   ( $beginning, $ending );
22 }
23
24 ###
25 # cust_main report methods
26 ###
27
28 =item cust_header
29
30 Returns an array of customer information headers according to the
31 B<cust-fields> configuration setting.
32
33 =cut
34
35 use vars qw( @cust_fields );
36
37 sub cust_sql_fields {
38   my @fields = qw( last first company );
39   push @fields, map "ship_$_", @fields
40     if dbdef->table('cust_main')->column('ship_last');
41   map "cust_main.$_", @fields;
42 }
43
44 sub cust_header {
45
46   warn "FS::svc_Common::cust_header called"
47     if $DEBUG;
48
49   my $conf = new FS::Conf;
50
51   my %header2method = (
52     'Customer'           => 'name',
53     'Cust#'              => 'custnum',
54     'Name'               => 'contact',
55     'Company'            => 'company',
56     '(bill) Customer'    => 'name',
57     '(service) Customer' => 'ship_name',
58     '(bill) Name'        => 'contact',
59     '(service) Name'     => 'ship_contact',
60     '(bill) Company'     => 'company',
61     '(service) Company'  => 'ship_company',
62   );
63
64   my @cust_header;
65   if (    $conf->exists('cust-fields')
66        && $conf->config('cust-fields') =~ /^([\w \|\#\(\)]+):/
67      )
68   {
69     warn "  found cust-fields configuration value"
70       if $DEBUG;
71
72     my $cust_fields = $1;
73      @cust_header = split(/ \| /, $cust_fields);
74      @cust_fields = map { $header2method{$_} } @cust_header;
75   } else { 
76     warn "  no cust-fields configuration value found; using default 'Customer'"
77       if $DEBUG;
78     @cust_header = ( 'Customer' );
79     @cust_fields = ( 'cust_name' );
80   }
81
82   #my $svc_x = shift;
83   @cust_header;
84 }
85
86 =item cust_fields
87
88 Given a svc_ object that contains fields from cust_main (say, from a
89 JOINed search.  See httemplate/search/svc_* for examples), returns an array
90 of customer information according to the <B>cust-fields</B> configuration
91 setting, or "(unlinked)" if this service is not linked to a customer.
92
93 =cut
94
95 sub cust_fields {
96   my $svc_x = shift;
97   warn "FS::svc_Common::cust_fields called for $svc_x ".
98        "(cust_fields: @cust_fields)"
99     if $DEBUG > 1;
100
101   cust_header() unless @cust_fields;
102
103   my $seen_unlinked = 0;
104   map { 
105     if ( $svc_x->custnum ) {
106       warn "  $svc_x -> $_"
107         if $DEBUG > 1;
108       $svc_x->$_(@_);
109     } else {
110       warn "  ($svc_x unlinked)"
111         if $DEBUG > 1;
112       $seen_unlinked++ ? '' : '(unlinked)';
113     }
114   } @cust_fields;
115 }
116
117 ###
118 # begin JSRPC code...
119 ###
120
121 package FS::UI::Web::JSRPC;
122
123 use strict;
124 use vars qw(@ISA $DEBUG);
125 use Storable qw(nfreeze);
126 use MIME::Base64;
127 use JavaScript::RPC::Server::CGI;
128 use FS::UID;
129 use FS::Record qw(qsearchs);
130 use FS::queue;
131
132 @ISA = qw( JavaScript::RPC::Server::CGI );
133 $DEBUG = 0;
134
135 sub new {
136         my $class = shift;
137         my $self  = {
138                 env => {},
139                 job => shift,
140         };
141
142         bless $self, $class;
143
144         return $self;
145 }
146
147 sub start_job {
148   my $self = shift;
149
150   warn "FS::UI::Web::start_job: ". join(', ', @_) if $DEBUG;
151 #  my %param = @_;
152   my %param = ();
153   while ( @_ ) {
154     my( $field, $value ) = splice(@_, 0, 2);
155     unless ( exists( $param{$field} ) ) {
156       $param{$field} = $value;
157     } elsif ( ! ref($param{$field}) ) {
158       $param{$field} = [ $param{$field}, $value ];
159     } else {
160       push @{$param{$field}}, $value;
161     }
162   }
163   warn "FS::UI::Web::start_job\n".
164        join('', map {
165                       if ( ref($param{$_}) ) {
166                         "  $_ => [ ". join(', ', @{$param{$_}}). " ]\n";
167                       } else {
168                         "  $_ => $param{$_}\n";
169                       }
170                     } keys %param )
171     if $DEBUG;
172
173   #first get the CGI params shipped off to a job ASAP so an id can be returned
174   #to the caller
175   
176   my $job = new FS::queue { 'job' => $self->{'job'} };
177   
178   #too slow to insert all the cgi params as individual args..,?
179   #my $error = $queue->insert('_JOB', $cgi->Vars);
180   
181   #warn 'froze string of size '. length(nfreeze(\%param)). " for job args\n"
182   #  if $DEBUG;
183
184   my $error = $job->insert( '_JOB', encode_base64(nfreeze(\%param)) );
185
186   if ( $error ) {
187     $error;
188   } else {
189     $job->jobnum;
190   }
191   
192 }
193
194 sub job_status {
195   my( $self, $jobnum ) = @_; #$url ???
196
197   sleep 5; #could use something better...
198
199   my $job;
200   if ( $jobnum =~ /^(\d+)$/ ) {
201     $job = qsearchs('queue', { 'jobnum' => $jobnum } );
202   } else {
203     die "FS::UI::Web::job_status: illegal jobnum $jobnum\n";
204   }
205
206   my @return;
207   if ( $job && $job->status ne 'failed' ) {
208     @return = ( 'progress', $job->statustext );
209   } elsif ( !$job ) { #handle job gone case : job sucessful
210                       # so close popup, redirect parent window...
211     @return = ( 'complete' );
212   } else {
213     @return = ( 'error', $job ? $job->statustext : $jobnum );
214   }
215
216   join("\n",@return);
217
218 }
219
220 sub get_new_query {
221   FS::UID::cgi();
222 }
223
224 1;
225