better error message
[freeside.git] / httemplate / edit / cust_main.cgi
1 <& /elements/header.html,
2       $title,
3       '',
4       ' onUnload="myclose()"' #hmm, in billing.html
5 &>
6
7 <& /elements/error.html &>
8
9 <FORM NAME   = "CustomerForm"
10       METHOD = "POST"
11       ACTION = "<% popurl(1) %>process/cust_main.cgi"
12 >
13
14 <INPUT TYPE="hidden" NAME="custnum"     VALUE="<% $custnum %>">
15 <INPUT TYPE="hidden" NAME="prospectnum" VALUE="<% $prospectnum %>">
16
17 % if ( $custnum ) { 
18   <% mt('Customer #') |h %><B><% $cust_main->display_custnum %></B> - 
19   <B><FONT COLOR="#<% $cust_main->statuscolor %>">
20     <% ucfirst($cust_main->status) %>
21   </FONT></B>
22   <BR><BR>
23 % } 
24
25 %# agent, agent_custid, refnum (advertising source), referral_custnum
26 %# better section title for this?
27 <FONT CLASS="fsinnerbox-title"><% mt('Basics') |h %></FONT>
28 <& cust_main/top_misc.html, $cust_main, 'custnum' => $custnum  &>
29
30 %# birthdate
31 % if (    $conf->config('national_id-country')
32 %      || $conf->exists('cust_main-enable_birthdate')
33 %      || $conf->exists('cust_main-enable_spouse_birthdate')
34 %      || $conf->exists('cust_main-enable_anniversary_date')
35 %    )
36 % {
37   <BR>
38   <& cust_main/birthdate.html, $cust_main &>
39 % }
40 % my $has_ship_address = '';
41 % if ( $cgi->param('error') ) {
42 %   $has_ship_address = !$same;
43 % } elsif ( $cust_main->custnum ) {
44 %   $has_ship_address = $cust_main->has_ship_address;
45 % }
46 <BR>
47 <TABLE> <TR>
48   <TD STYLE="width:650px">
49 %#; padding-right:2px; vertical-align:top">
50     <FONT CLASS="fsinnerbox-title"><% mt('Billing address') |h %></FONT>
51     <TABLE CLASS="fsinnerbox">
52     <& cust_main/before_bill_location.html, $cust_main &>
53     <& /elements/location.html,
54         object => $cust_main->bill_location,
55         prefix => 'bill_',
56         enable_coords => 1,
57     &>
58     <& cust_main/after_bill_location.html, $cust_main &>
59     </TABLE>
60   </TD>
61 </TR>
62 <TR><TD STYLE="height:40px"></TD></TR>
63 <TR>
64   <TD STYLE="width:650px">
65 %#; padding-left:2px; vertical-align:top">
66     <FONT CLASS="fsinnerbox-title"><% mt('Service address') |h %></FONT>
67     <INPUT TYPE="checkbox" 
68            NAME="same"
69            ID="same"
70            onclick="samechanged(this)"
71            onkeyup="samechanged(this)"
72            VALUE="Y"
73            <% $has_ship_address ? '' : 'CHECKED' %>
74     ><% mt('same as billing address') |h %>
75     <TABLE CLASS="fsinnerbox" ID="table_ship_location">
76     <& /elements/location.html,
77         object => $cust_main->ship_location,
78         prefix => 'ship_',
79         enable_censustract => 1,
80         enable_district => 1,
81         enable_coords => 1,
82     &>
83     </TABLE>
84     <TABLE CLASS="fsinnerbox" ID="table_ship_location_blank"
85     STYLE="display:none">
86     <TR><TD></TD></TR>
87     </TABLE>
88   </TD>
89 </TR></TABLE>
90
91 <SCRIPT>
92 function samechanged(what) {
93 %# not display = 'none', because we still want it to take up space
94 %#  document.getElementById('table_ship_location').style.visibility = 
95 %#    what.checked ? 'hidden' : 'visible';
96   var t1 = document.getElementById('table_ship_location');
97   var t2 = document.getElementById('table_ship_location_blank');
98   if ( what.checked ) {
99     t2.style.width  = t1.clientWidth  + 'px';
100     t2.style.height = t1.clientHeight + 'px';
101     t1.style.display = 'none';
102     t2.style.display = '';
103   }
104   else {
105     t2.style.display = 'none';
106     t1.style.display = '';
107   }
108 }
109 samechanged(document.getElementById('same'));
110 </SCRIPT>
111
112 <BR>
113
114 <& cust_main/contacts_new.html,
115              'cust_main' => $cust_main,
116 &>
117
118 %# billing info
119 <& cust_main/billing.html, $cust_main,
120                'payinfo'        => $payinfo,
121                'invoicing_list' => \@invoicing_list,
122 &>
123 <BR>
124
125 % my $ro_comments = $conf->exists('cust_main-use_comments')?'':'readonly';
126 % if (!$ro_comments || $cust_main->comments) {
127
128     <BR>
129     <FONT CLASS="fsinnerbox-title"><% mt('Comments') |h %></FONT>
130     <TABLE CLASS="fsinnerbox">
131       <TR>
132         <TD>
133           <TEXTAREA NAME = "comments"
134                     COLS = 80
135                     ROWS = 5
136                     WRAP = "HARD"
137                     <% $ro_comments %>
138           ><% $cust_main->comments %></TEXTAREA>
139         </TD>
140       </TR>
141     </TABLE>
142
143 % }
144
145 % unless ( $custnum ) {
146
147     <& cust_main/first_pkg.html, $cust_main,
148                  'pkgpart_svcpart' => $pkgpart_svcpart,
149                  'disable_empty'   =>
150                    scalar( $cgi->param('lock_pkgpart') =~ /^(\d+)$/ ),
151                  'username'        => $username,
152                  'password'        => $password,
153                  'popnum'          => $popnum,
154                  'saved_domsvc'    => $saved_domsvc,
155                  %svc_phone,
156                  %svc_dsl,
157     &>
158
159 % }
160
161 <INPUT TYPE="hidden" NAME="locationnum" VALUE="<% $locationnum %>">
162
163 <INPUT TYPE="hidden" NAME="usernum" VALUE="<% $cust_main->usernum %>">
164
165 %# cust_main/bottomfixup.js
166 % foreach my $hidden (
167 %    'payauto', 'billday',
168 %    'payinfo', 'payinfo1', 'payinfo2', 'payinfo3', 'paytype',
169 %    'payname', 'paystate', 'exp_month', 'exp_year', 'paycvv',
170 %    'paystart_month', 'paystart_year', 'payissue',
171 %    'payip',
172 %    'paid',
173 % ) {
174     <INPUT TYPE="hidden" NAME="<% $hidden %>" VALUE="">
175 % } 
176
177 <& cust_main/bottomfixup.html, 'custnum' => $custnum &>
178
179 <BR>
180 <INPUT TYPE    = "button"
181        NAME    = "submitButton"
182        ID      = "submitButton"
183        VALUE   = "<% $custnum ?  emt("Apply changes") : emt("Add Customer") %>"
184        onClick = "this.disabled=true; bottomfixup(this.form);"
185 >
186 <BR><BR>
187 </FORM>
188
189 <& /elements/footer.html &>
190
191 <%init>
192
193 my $curuser = $FS::CurrentUser::CurrentUser;
194
195 #probably redundant given the checks below...
196 die "access denied"
197   unless $curuser->access_right('New customer')
198      ||  $curuser->access_right('Edit customer');
199
200 my $conf = new FS::Conf;
201
202 #get record
203
204 my($custnum, $cust_main, $ss, $stateid, $payinfo, @invoicing_list);
205 my $pkgpart_svcpart = ''; #first_pkg
206 my($username, $password, $popnum, $saved_domsvc) = ( '', '', 0, 0 ); #svc_acct
207 my %svc_phone = ();
208 my %svc_dsl = ();
209 my $prospectnum = '';
210 my $locationnum = '';
211 my $same = '';
212
213
214 if ( $cgi->param('error') ) {
215
216   $same = ($cgi->param('same') || '') eq 'Y';
217   # false laziness w/ edit/process/cust_main.cgi
218   my %locations;
219   for my $pre (qw(bill ship)) {
220     my %hash;
221     foreach ( FS::cust_main->location_fields ) {
222       $hash{$_} = scalar($cgi->param($pre.'_'.$_));
223     }
224     $hash{'custnum'} = $cgi->param('custnum');
225     $locations{$pre} = qsearchs('cust_location', \%hash)
226                        || FS::cust_location->new( \%hash );
227   }
228   if ( $same ) {
229     $locations{ship} = $locations{bill};
230   }
231
232   $cust_main = new FS::cust_main ( {
233     map { ( $_, scalar($cgi->param($_)) ) } (fields('cust_main')),
234     map { ( "ship_$_", '' ) } (FS::cust_main->location_fields)
235   } );
236
237   for my $pre (qw(bill ship)) {
238     $cust_main->set($pre.'_location', $locations{$pre});
239     $cust_main->set($pre.'_locationnum', $locations{$pre}->locationnum);
240   }
241
242   $custnum = $cust_main->custnum;
243
244   die "access denied"
245     unless $curuser->access_right($custnum ? 'Edit customer' : 'New customer');
246
247   @invoicing_list = split( /\s*,\s*/, $cgi->param('invoicing_list') );
248   $cust_main->setfield('paid' => $cgi->param('paid')) if $cgi->param('paid');
249   $ss = $cust_main->ss;           # don't mask an entered value on errors
250   $stateid = $cust_main->stateid; # don't mask an entered value on errors
251   $payinfo = $cust_main->payinfo; # don't mask an entered value on errors
252
253   $cust_main->national_id( $cgi->param('national_id1') || $cgi->param('national_id2') );
254
255   $prospectnum = $cgi->param('prospectnum') || '';
256
257   $pkgpart_svcpart = $cgi->param('pkgpart_svcpart') || '';
258
259   $locationnum = $cgi->param('locationnum') || '';
260
261   #svc_acct
262   $username = $cgi->param('username');
263   $password = $cgi->param('_password');
264   $popnum = $cgi->param('popnum');
265   $saved_domsvc = $cgi->param('domsvc') || '';
266   if ( $saved_domsvc =~ /^(\d+)$/ ) {
267     $saved_domsvc = $1;
268   } else {
269     $saved_domsvc = '';
270   }
271
272   #svc_phone
273   $svc_phone{$_} = $cgi->param($_)
274     foreach qw( countrycode phonenum sip_password pin phone_name );
275
276   #svc_dsl (phonenum came in with svc_phone)
277   $svc_phone{$_} = $cgi->param($_)
278     foreach qw( password isp_chg isp_prev vendor_qual_id );
279
280 } elsif ( $cgi->keywords ) { #editing
281
282   die "access denied"
283     unless $curuser->access_right('Edit customer');
284
285   my( $query ) = $cgi->keywords;
286   $query =~ /^(\d+)$/;
287   $custnum=$1;
288   $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
289     or die "custnum $custnum not found";
290   if ( $cust_main->dbdef_table->column('paycvv')
291        && length($cust_main->paycvv)             ) {
292     my $paycvv = $cust_main->paycvv;
293     $paycvv =~ s/./*/g;
294     $cust_main->paycvv($paycvv);
295   }
296   @invoicing_list = $cust_main->invoicing_list;
297   $ss = $conf->exists('unmask_ss') ? $cust_main->ss : $cust_main->masked('ss');
298   $stateid = $cust_main->masked('stateid');
299   $payinfo = $cust_main->paymask;
300
301 } else { #new customer
302
303   die "access denied"
304     unless $curuser->access_right('New customer');
305
306   $custnum='';
307   $cust_main = new FS::cust_main ( {} );
308   $cust_main->agentnum( $conf->config('default_agentnum') )
309     if $conf->exists('default_agentnum');
310   $cust_main->otaker( &getotaker );
311   $cust_main->referral_custnum( $cgi->param('referral_custnum') );
312   @invoicing_list = ();
313   push @invoicing_list, 'POST'
314     unless $conf->exists('disablepostalinvoicedefault');
315   $ss = '';
316   $stateid = '';
317   $payinfo = '';
318
319   $cgi->param('tagnum', FS::part_tag->default_tags);
320
321   if ( $cgi->param('qualnum') =~ /^(\d+)$/ ) {
322     my $qualnum = $1;
323     my $qual = qsearchs('qual', { 'qualnum' => $qualnum } )
324       or die "unknown qualnum $qualnum";
325
326     my $prospect_main = $qual->cust_or_prospect;
327     $prospectnum = $prospect_main->prospectnum
328       or die "qualification not on a prospect";
329
330     $cust_main->agentnum( $prospect_main->agentnum );
331     $cust_main->company(  $prospect_main->company  );
332
333     #first contact? -> name
334     my @contacts = $prospect_main->contact;
335     my $contact = $contacts[0];
336     $cust_main->first( $contact->first );
337     $cust_main->set( 'last', $contact->get('last') );
338     #contact phone numbers?
339
340     #location -> address  (all prospect quals have location, right?)
341     my $cust_location = $qual->cust_location;
342     $cust_location->dealternize;
343     $cust_main->$_( $cust_location->$_ )
344       foreach qw( address1 address2 city county state zip country latitude longitude coord_auto geocode );
345
346     #locationnum -> package order
347     $locationnum = $qual->locationnum;
348
349     #pkgpart handled by lock_pkgpart below
350
351     #service telephone & vendor_qual_id -> svc_dsl
352     $svc_dsl{$_} = $qual->$_
353       foreach qw( phonenum vendor_qual_id );
354   }
355   else {
356     my $countrydefault = $conf->config('countrydefault') || 'US';
357     my $statedefault = $conf->config('statedefault') || 'CA';
358     $cust_main->set('bill_location', 
359       FS::cust_location->new( {
360           country => $countrydefault,
361           state => $statedefault,
362           coord_auto => 'Y',
363       } )
364     );
365     $cust_main->set('ship_location',
366       FS::cust_location->new( {
367           country => $countrydefault,
368           state => $statedefault,
369           coord_auto => 'Y',
370       } )
371     );
372   }
373
374   if ( $cgi->param('lock_pkgpart') =~ /^(\d+)$/ ) {
375     my $pkgpart = $1;
376     my $part_pkg = qsearchs('part_pkg', { 'pkgpart' => $pkgpart } )
377       or die "unknown pkgpart $pkgpart";
378     my $svcpart = $part_pkg->svcpart;
379     $pkgpart_svcpart = $pkgpart.'_'.$svcpart;
380   }
381
382 }
383
384 my %keep = map { $_=>1 } qw( error tagnum lock_agentnum lock_pkgpart );
385 $cgi->delete( grep { !$keep{$_} && $_ !~ /^tax_/ } $cgi->param );
386
387 my $title = $custnum ? 'Edit Customer' : 'Add Customer';
388 $title = mt($title);
389 $title .= ": ". $cust_main->name if $custnum;
390
391 my $r = qq!<font color="#ff0000">*</font>&nbsp;!;
392
393 </%init>