summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
authorivan <ivan>2009-12-28 19:20:25 +0000
committerivan <ivan>2009-12-28 19:20:25 +0000
commit03ceab71dad1e5eb366865d304e5e459cc905ce4 (patch)
tree18b4532289a0237ae694b1ad5c033b25f448bd7c /httemplate
parent5950a980cef4968ac59ca8041d2204e6d98e7a3d (diff)
beginning of prospect/CRM/contact work
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/edit/elements/edit.html7
-rw-r--r--httemplate/edit/process/elements/process.html28
-rw-r--r--httemplate/edit/process/prospect_main.html34
-rw-r--r--httemplate/edit/prospect_main.html83
-rw-r--r--httemplate/elements/city.html4
-rw-r--r--httemplate/elements/contact.html72
-rw-r--r--httemplate/elements/header.html49
-rw-r--r--httemplate/elements/menu.html2
-rw-r--r--httemplate/elements/tr-contact.html24
-rw-r--r--httemplate/elements/tr-select-cust_location.html79
-rw-r--r--httemplate/misc/location.cgi15
-rw-r--r--httemplate/search/prospect_main.html74
-rw-r--r--httemplate/search/report_prospect_main.html32
-rw-r--r--httemplate/view/cust_main/packages/location.html6
-rw-r--r--httemplate/view/prospect_main.html92
15 files changed, 561 insertions, 40 deletions
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index fd73e031e..4935ddc1a 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -409,7 +409,7 @@ Example:
% $label[0] = '/elements/tr-td-label.html';
<% include( @label ) %>
- <TD>
+ <TD COLSPAN="<% $f->{'colspan'} || 1 %>">
<% include( @existing ) %>
</TD>
@@ -465,7 +465,7 @@ Example:
% $label[0] = '/elements/tr-td-label.html';
<% include( @label ) %>
- <TD>
+ <TD COLSPAN="<% $f->{'colspan'} || 1 %>">
<% include( @include ) %>
</TD>
@@ -503,7 +503,7 @@ Example:
// only spawn if we're the last element... return if not
- var field_regex = /(\d+)$/;
+ var field_regex = /(\d+)(_[a-z]+)?$/;
var match = field_regex.exec(what.name);
if ( !match ) {
alert(what.name + " didn't match?!");
@@ -574,6 +574,7 @@ Example:
widget_cell.style.borderTop = "1px solid black";
widget_cell.style.paddingTop = "3px";
+ widget_cell.colSpan = "<% $f->{'colspan'} || 1 %>"
widget_cell.innerHTML = newrow;
diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html
index 5befdd337..e24f3f681 100644
--- a/httemplate/edit/process/elements/process.html
+++ b/httemplate/edit/process/elements/process.html
@@ -56,13 +56,17 @@ Example:
},
+ 'process_o2m' => { 'table' => table_name',
+ 'num_col' => 'column', #if column name is different in
+ #link_table than source_table
+ },
#checks CGI params and whatever else before much else runs
#return an error string or empty for no error
'precheck_callback' => sub { my( $cgi ) = @_; },
#supplies arguments to insert() and replace()
- # for use with tables that are FS::option_Common
+ # for use with tables that are FS::option_Common (among other things)
'args_callback' => sub { my( $cgi, $object ) = @_; },
'debug' => 1, #turns on debugging output
@@ -255,6 +259,28 @@ if ( !$error && $opt{'process_m2name'} ) {
}
+if ( !$error && $opt{'process_o2m'} ) {
+
+ my @process_o2m = ref($opt{'process_o2m'}) eq 'ARRAY'
+ ? @{ $opt{'process_o2m'} }
+ : ( $opt{'process_o2m'} );
+
+
+ foreach my $process_o2m (@process_o2m) {
+
+ if ( $opt{'debug'} ) {
+ warn "$me processing o2m:\n". Dumper( %{ $process_o2m },
+ 'params' => scalar($cgi->Vars),
+ );
+ }
+
+ $error = $new->process_o2m( %{ $process_o2m },
+ 'params' => scalar($cgi->Vars),
+ );
+ }
+
+}
+
if ( $error ) {
$cgi->param('error', $error);
diff --git a/httemplate/edit/process/prospect_main.html b/httemplate/edit/process/prospect_main.html
new file mode 100644
index 000000000..34d26421b
--- /dev/null
+++ b/httemplate/edit/process/prospect_main.html
@@ -0,0 +1,34 @@
+<% include('elements/process.html',
+ 'table' => 'prospect_main',
+ 'args_callback' => $args_callback,
+ 'agent_virt' => 1,
+ 'process_o2m' => {
+ 'table' => 'contact',
+ 'fields' => [qw( first last title comment )],
+ },
+ 'redirect' => popurl(3). 'view/prospect_main.html?',
+ )
+%>
+<%init>
+
+my $args_callback = sub {
+ my( $cgi, $object ) = @_;
+
+ $cgi->param('locationnum') =~ /^(\-?\d*)$/
+ or die 'illegal locationnum '. $cgi->param('locationnum');
+ my $locationnum = $1;
+
+ return ( 'cust_location' => '' ) unless $locationnum;
+
+ my $cust_location = new FS::cust_location {
+ map { $_ => scalar($cgi->param($_)) }
+ qw( address1 address2 city county state zip country )
+ };
+
+ $cust_location->locationnum($locationnum) unless $locationnum == -1;
+
+ ( 'cust_location' => $cust_location );
+
+};
+
+</%init>
diff --git a/httemplate/edit/prospect_main.html b/httemplate/edit/prospect_main.html
new file mode 100644
index 000000000..c4123a078
--- /dev/null
+++ b/httemplate/edit/prospect_main.html
@@ -0,0 +1,83 @@
+<% include('elements/edit.html',
+ 'name_singular' => 'prospect',
+ 'table' => 'prospect_main',
+ 'labels' => { 'prospectnum' => 'Prospect',
+ 'agentnum' => 'Agent',
+ 'company' => 'Company',
+ 'contactnum' => 'Contact',
+ },
+ 'fields' => [
+ { 'field' => 'agentnum',
+ 'type' => 'select-agent',
+ 'empty_label' => 'Select agent',
+ },
+ { 'field' => 'company',
+ 'type' => 'text',
+ 'size' => 50,
+ },
+ { 'field' => 'contactnum',
+ 'type' => 'contact',
+ 'colspan' => 6,
+ #actually o2m, but this seems to be working for edit so far
+ 'm2name_table' => 'contact',
+ 'm2name_namecol' => 'contactnum',
+ 'm2_label' => 'Contact',
+ 'm2_error_callback' => sub { my($cgi, $object) = @_; (); }, #XXX
+ },
+ { 'field' => 'locationnum',
+ 'type' => 'select-cust_location',
+ 'empty_label' => 'No address',
+ },
+ ],
+ 'edit_callback' => $edit_callback,
+ 'error_callbacck' => $error_callback,
+ 'agent_virt' => 1,
+ )
+%>
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+my $prospectnum;
+if ( $cgi->param('error') ) {
+ $prospectnum = scalar($cgi->param('prospectnum'));
+
+ die "access denied"
+ unless $curuser->access_right(($prospectnum ? 'Edit' : 'New'). ' prospect');
+
+} elsif ( $cgi->keywords ) { #editing
+
+ die "access denied"
+ unless $curuser->access_right('Edit prospect');
+
+} else { #new prospect
+
+ die "access denied"
+ unless $curuser->access_right('New prospect');
+
+}
+
+my $edit_callback = sub {
+ #my( $cgi, $prospect_main, $fields_listref, $opt_hashref ) = @_;
+ my( $cgi, $prospect_main ) = @_;
+ my @cust_location =
+ qsearch('cust_location', { 'prospectnum' => $prospect_main->prospectnum } );
+ die 'multiple locations for prospect '. $prospect_main->prospectnum
+ if scalar(@cust_location) > 1;
+ $prospect_main->set('locationnum', $cust_location[0]->locationnum)
+ if scalar(@cust_location);
+ #warn 'prospect_main.locationnum '.$prospect_main->get('locationnum');
+};
+
+my $error_callback = sub {
+ #my( $cgi, $prospect_main, $fields_listref, $opt_hashref ) = @_;
+ my( $cgi, $prospect_main ) = @_;
+ $cgi->param('locationnum') =~ /^(\-?\d*)$/
+ or die 'illegal locationnum '. $cgi->param('locationnum');
+ my $locationnum = $1;
+ $prospect_main->set('locationnum', $locationnum);
+};
+
+my @agentnums = $FS::CurrentUser::CurrentUser->agentnums;
+
+</%init>
diff --git a/httemplate/elements/city.html b/httemplate/elements/city.html
index 47e5c37c2..61d057889 100644
--- a/httemplate/elements/city.html
+++ b/httemplate/elements/city.html
@@ -34,7 +34,7 @@ Example:
what.options[length] = optionName;
}
- var saved_<%$pre%>city= '';
+ var saved_<%$pre%>city= '<% $saved_city |h %>';
function <% $pre %>county_changed(what, callback) {
@@ -124,10 +124,12 @@ my $text_style = $opt{'style'} ? [ @{ $opt{'style'} } ] : [];
my $select_style = $opt{'style'} ? [ @{ $opt{'style'} } ] : [];
my @cities = cities( $opt{'county'}, $opt{'state'}, $opt{'country'} );
+my $saved_city = '';
if ( scalar(@cities) > 1 || $cities[0] ) {
push @$text_style, 'display:none';
} else {
push @$select_style, 'display:none';
+ $saved_city = $opt{'city'};
}
$text_style =
diff --git a/httemplate/elements/contact.html b/httemplate/elements/contact.html
new file mode 100644
index 000000000..38703bfef
--- /dev/null
+++ b/httemplate/elements/contact.html
@@ -0,0 +1,72 @@
+% unless ( $opt{'js_only'} ) {
+
+ <INPUT TYPE="hidden" NAME="<%$name%>" ID="<%$id%>" VALUE="<% $curr_value %>">
+
+ <TABLE>
+ <TR>
+ <TD>
+ <INPUT TYPE = "text"
+ NAME = "<%$name%>_first"
+ ID = "<%$id%>_id"
+ VALUE = "<% $contact->first |h %>"
+ <% $onchange %>
+ ><BR>
+ <FONT SIZE="-2">First name</FONT>
+ </TD>
+ <TD>
+ <INPUT TYPE = "text"
+ NAME = "<%$name%>_last"
+ ID = "<%$id%>_id"
+ VALUE = "<% $contact->get('last') |h %>"
+ <% $onchange %>
+ ><BR>
+ <FONT SIZE="-2">Last name</FONT>
+ </TD>
+ <TD>
+ <INPUT TYPE = "text"
+ NAME = "<%$name%>_title"
+ ID = "<%$id%>_id"
+ VALUE = "<% $contact->title |h %>"
+ <% $onchange %>
+ ><BR>
+ <FONT SIZE="-2">Title/Position</FONT>
+ </TD>
+ <TD>
+ <INPUT TYPE = "text"
+ NAME = "<%$name%>_comment"
+ ID = "<%$id%>_id"
+ VALUE = "<% $contact->comment |h %>"
+ <% $onchange %>
+ ><BR>
+ <FONT SIZE="-2">Comment</FONT>
+ </TD>
+ </TR>
+ </TABLE>
+
+% }
+<%init>
+
+my( %opt ) = @_;
+
+my $name = $opt{'element_name'} || $opt{'field'} || 'contactnum';
+my $id = $opt{'id'} || 'contactnum';
+
+my $curr_value = $opt{'curr_value'} || $opt{'value'};
+
+my $onchange = '';
+if ( $opt{'onchange'} ) {
+ $onchange = $opt{'onchange'};
+ $onchange .= '(this)' unless $onchange =~ /\(\w*\);?$/;
+ $onchange =~ s/\(what\);/\(this\);/g; #ugh, terrible hack. all onchange
+ #callbacks should act the same
+ $onchange = 'onChange="'. $onchange. '"';
+}
+
+my $contact;
+if ( $curr_value ) {
+ $contact = qsearchs('contact', { 'contactnum' => $curr_value } );
+} else {
+ $contact = new FS::contact {};
+}
+
+</%init>
diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html
index 22e872eca..495923c4d 100644
--- a/httemplate/elements/header.html
+++ b/httemplate/elements/header.html
@@ -39,6 +39,12 @@ Example:
<% include('init_overlib.html') |n %>
<SCRIPT TYPE="text/javascript">
+
+ function clearhint_search_prospect (what) {
+ if ( what.value == '<% $prospect_label |n %>' )
+ what.value = '';
+ }
+
function clearhint_search_cust (what) {
if ( what.value == '<% $cust_label |n %>' )
what.value = '';
@@ -63,6 +69,7 @@ Example:
if ( what.value == '<% $ticketing_label |n %>' )
what.value = '';
}
+
</SCRIPT>
<% $head |n %>
@@ -140,6 +147,7 @@ input.fstext {
vertical-align:bottom;
text-align:right;
font-family: Arial,Verdana,Helvetica,sans-serif;
+ font-size: 13px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
@@ -154,14 +162,14 @@ input.fstext {
<TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=0>
<TR>
- <TD COLSPAN=6 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
+ <TD COLSPAN="7" WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
</TR>
% if ( $menu_position eq 'top' ) {
<TR>
- <TD COLSPAN="4" WIDTH="100%" STYLE="padding:0" BGCOLOR="#000000">
+ <TD COLSPAN="5" WIDTH="100%" STYLE="padding:0" BGCOLOR="#000000">
<SCRIPT TYPE="text/javascript">
document.write(myBar);
</SCRIPT>
@@ -180,12 +188,12 @@ input.fstext {
</TR>
<TR>
- <TD COLSPAN="6" WIDTH="100%" HEIGHT="2px" STYLE="padding:0" BGCOLOR="#000000">
+ <TD COLSPAN="7" WIDTH="100%" HEIGHT="2px" STYLE="padding:0" BGCOLOR="#000000">
</TD>
</TR>
<TR>
- <TD COLSPAN="6" WIDTH="100%" HEIGHT="4px" STYLE="padding:0" BGCOLOR="#000000">
+ <TD COLSPAN="7" WIDTH="100%" HEIGHT="4px" STYLE="padding:0" BGCOLOR="#000000">
</TD>
</TR>
@@ -193,7 +201,17 @@ input.fstext {
<TR>
- <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-left:2px">
+% if ( $curuser->access_right('List prospects') ) {
+ <FORM ACTION="<%$fsurl%>search/prospect_main.html" METHOD="GET" STYLE="margin:0">
+ <INPUT NAME="search_prospect" TYPE="text" VALUE="<% $prospect_label |n %>" STYLE="width:155px" onFocus="clearhint_search_prospect(this);" onClick="clearhint_search_prospect(this);" CLASS="fstext"><BR>
+ <A HREF="<%$fsurl%>search/report_prospect_main.html" STYLE="color: #ffffff; font-size: 11px">Adv</A>
+ <INPUT TYPE="submit" VALUE="Search prospects" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px;padding-left:1px;padding-right:1px"">
+ </FORM>
+% }
+ </TD>
+
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-left:2px">
% if ( $curuser->access_right('List customers') ) {
<FORM ACTION="<%$fsurl%>search/cust_main.cgi" METHOD="GET" STYLE="margin:0">
<INPUT NAME="search_cust" TYPE="text" VALUE="<% $cust_label |n %>" STYLE="width:<%$cust_width%>px" onFocus="clearhint_search_cust(this);" onClick="clearhint_search_cust(this);" CLASS="fstext"><BR>
@@ -209,7 +227,7 @@ input.fstext {
<INPUT TYPE="hidden" NAME="address2_on" VALUE="1">
<INPUT NAME="address2_text" TYPE="text" VALUE="<% $address2_label |n %>" STYLE="width:67px" onFocus="clearhint_search_address2(this);" onClick="clearhint_search_address2(this);" CLASS="fstext">
<BR>
- <INPUT TYPE="submit" VALUE="Search units" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px;padding-left:2px;padding-right:2px">
+ <INPUT TYPE="submit" VALUE="Search units" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px;padding-left:1px;padding-right:1px;margin-top:3px">
</FORM>
% }
</TD>
@@ -217,30 +235,29 @@ input.fstext {
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
% if ( $curuser->access_right('View invoices') ) {
<FORM ACTION="<%$fsurl%>search/cust_bill.html" METHOD="GET" STYLE="margin:0;display:inline">
- <INPUT NAME="invnum" TYPE="text" VALUE="<% $inv_label |n %>" STYLE="width:64px" onFocus="clearhint_search_invoice(this);" onClick="clearhint_search_invoice(this);" CLASS="fstext">
+ <INPUT NAME="invnum" TYPE="text" VALUE="<% $inv_label |n %>" STYLE="width:56px" onFocus="clearhint_search_invoice(this);" onClick="clearhint_search_invoice(this);" CLASS="fstext">
% if ( $curuser->access_right('List invoices') ) {
<A HREF="<%$fsurl%>search/report_cust_bill.html" STYLE="color: #ffffff; font-size: 11px">Adv</A>\
% }
-<BR>
- <INPUT TYPE="submit" VALUE="Search invoices" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px;padding-left:2px;padding-right:2px">
+<BR><INPUT TYPE="submit" VALUE="Search invoices" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px;padding-left:1px;padding-right:1px;margin-top:3px">
</FORM>
% }
</TD>
- <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-left:2px">
% if ( $curuser->access_right('View customer services') ) {
<FORM ACTION="<%$fsurl%>search/cust_svc.html" METHOD="GET" STYLE="margin:0">
- <INPUT NAME="search_svc" TYPE="text" VALUE="<% $svc_label |n %>" STYLE="width:324px" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" CLASS="fstext"><BR>
+ <INPUT NAME="search_svc" TYPE="text" VALUE="<% $svc_label |n %>" STYLE="width:271px" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" CLASS="fstext"><BR>
<A NOTYET="<%$fsurl%>search/svc_Smarter.html" STYLE="color: #000000; font-size:11px">Advanced</A>
<INPUT TYPE="submit" VALUE="Search services" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px">
</FORM>
% }
</TD>
- <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-left:4px;padding-right:4px">
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right" STYLE="padding-left:2px;padding-right:2px">
% if ( $conf->config("ticket_system") ) {
<FORM ACTION="<% FS::TicketSystem->baseurl %>index.html" METHOD="GET" STYLE="margin:0">
- <INPUT NAME="q" TYPE="text" VALUE="<% $ticketing_label |n %>" STYLE="width:256px" onFocus="clearhint_search_ticket(this);" onClick="clearhint_search_ticket(this);" CLASS="fstext"><BR>
+ <INPUT NAME="q" TYPE="text" VALUE="<% $ticketing_label |n %>" STYLE="width:223px" onFocus="clearhint_search_ticket(this);" onClick="clearhint_search_ticket(this);" CLASS="fstext"><BR>
<A HREF="<% FS::TicketSystem->baseurl %>Search/Build.html" STYLE="color: #ffffff; font-size:11px">Advanced</A>
<INPUT TYPE="submit" VALUE="Search tickets" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:11px">
</FORM>
@@ -334,11 +351,13 @@ if ( scalar(@agentnums) == 1 ) {
$company_name = $conf->config('company_name');
}
-my $cust_width = 288; #251 #ok for IE, slightly bigger for windows firefox
+my $prospect_label = '(name, company or phone)';
+
+my $cust_width = 246;
my $cust_label = '(cust #, name, company';
if ( $conf->exists('address1-search') ) {
$cust_label .= ', address';
- $cust_width += 64;
+ $cust_width += 56;
}
$cust_label .= ' or contact phone)';
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index caf227409..ce0278f13 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -476,6 +476,8 @@ if ( $conf->config('ticket_system') ) {
'Ticketing start page',
],
}
+$menu{'New prospect'} = [ $fsurl.'edit/prospect_main.html', 'Add a new prospect' ]
+ if $curuser->access_right('New prospect');
$menu{'New customer'} = [ $fsurl.'edit/cust_main.cgi', 'Add a new customer' ]
if $curuser->access_right('New customer');
$menu{'Reports'} = [ \%report_menu, 'Lists, reporting and graphing' ]
diff --git a/httemplate/elements/tr-contact.html b/httemplate/elements/tr-contact.html
new file mode 100644
index 000000000..ee0e6e824
--- /dev/null
+++ b/httemplate/elements/tr-contact.html
@@ -0,0 +1,24 @@
+% unless ( $opt{'js_only'} ) {
+
+ <% include('tr-td-label.html', %opt) %>
+ <TD <% $cell_style %>>
+
+% }
+%
+ <% include( '/elements/contact.html', %opt ) %>
+%
+% unless ( $opt{'js_only'} ) {
+
+ </TD>
+ </TR>
+
+% }
+<%init>
+
+my( %opt ) = @_;
+
+my $cell_style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+$opt{'label'} ||= 'Contact';
+
+</%init>
diff --git a/httemplate/elements/tr-select-cust_location.html b/httemplate/elements/tr-select-cust_location.html
index ab043ee7e..5e938b53a 100644
--- a/httemplate/elements/tr-select-cust_location.html
+++ b/httemplate/elements/tr-select-cust_location.html
@@ -4,7 +4,13 @@ Example:
include('/elements/tr-select-cust_location.html',
'cgi' => $cgi,
- 'cust_main' => $cust_main,
+
+ 'cust_main' => $cust_main,
+ #or
+ 'prospect_main' => $prospect_main,
+
+ #optional
+ 'empty_label' => '(default service address)',
)
</%doc>
@@ -42,6 +48,7 @@ Example:
} else {
if ( locationnum == 0 ) {
+% if ( $cust_main ) {
what.form.address1.value = <% $cust_main->get($prefix.'address1') |js_string %>;
what.form.address2.value = <% $cust_main->get($prefix.'address2') |js_string %>;
what.form.city.value = <% $cust_main->get($prefix.'city') |js_string %>;
@@ -54,16 +61,33 @@ Example:
<% $cust_main->get($prefix.'county') | js_string %>
)
);
+% }
} else {
get_location( locationnum, update_location );
}
+% if ( $editable ) {
+ if ( locationnum == 0 ) {
+% }
+
%#sleep/wait until dropdowns are updated?
-% for (@location_fields, 'city_select') {
- what.form.<%$_%>.disabled = true;
- what.form.<%$_%>.style.backgroundColor = '#dddddd';
-% }
+% for (@location_fields, 'city_select') {
+ what.form.<%$_%>.disabled = true;
+ what.form.<%$_%>.style.backgroundColor = '#dddddd';
+% }
+
+% if ( $editable ) {
+ } else {
+
+%#sleep/wait until dropdowns are updated?
+% for (@location_fields, 'city_select') {
+ what.form.<%$_%>.disabled = false;
+ what.form.<%$_%>.style.backgroundColor = '#ffffff';
+% }
+
+ }
+% }
}
}
@@ -122,15 +146,20 @@ Example:
<TH ALIGN="right">Service&nbsp;location</TH>
<TD COLSPAN=7>
<SELECT NAME="locationnum" onChange="locationnum_changed(this);">
- <OPTION VALUE="">(default service address)
-% foreach my $loc ( $cust_main->cust_location ) {
+ <OPTION VALUE=""><% $opt{'empty_label'} || '(default service address)' |h %>
+% my @locations = $cust_main ? $cust_main->cust_location : ();
+% push @locations, $cust_location
+% if !$cust_main && $cust_location && $cust_location->locationnum>0;
+% foreach my $loc ( @locations ) {
<OPTION VALUE="<% $loc->locationnum %>"
<% $locationnum == $loc->locationnum ? 'SELECTED' : '' %>
><% $loc->line |h %>
% }
- <OPTION VALUE="-1"
- <% $locationnum == -1 ? 'SELECTED' : '' %>
- >Add new location
+% if ( $addnew ) {
+ <OPTION VALUE="-1"
+ <% $locationnum == -1 ? 'SELECTED' : '' %>
+ >Add new location
+% }
</SELECT>
</TD>
</TR>
@@ -138,7 +167,7 @@ Example:
<% include('/elements/location.html',
'object' => $cust_location,
#'onchange' ? probably not
- 'disabled' => ( $locationnum == -1 ? '' : 'DISABLED' ),
+ 'disabled' => $disabled,
'no_asterisks' => 1,
)
%>
@@ -156,13 +185,25 @@ my $statedefault = $conf->config('statedefault')
|| ($countrydefault eq 'US' ? 'CA' : '');
my %opt = @_;
-my $cgi = $opt{'cgi'};
-my $cust_main = $opt{'cust_main'};
+my $cgi = $opt{'cgi'};
+my $cust_main = $opt{'cust_main'};
+my $prospect_main = $opt{'prospect_main'};
+
+my $prefix = ($cust_main && length($cust_main->ship_last)) ? 'ship_' : '';
-my $prefix = length($cust_main->ship_last) ? 'ship_' : '';
+my $locationnum;
+if ( length($opt{'curr_value'}) ) {
+ $locationnum = $opt{'curr_value'};
+} else {
+ $cgi->param('locationnum') =~ /^(\-?\d*)$/ or die "illegal locationnum";
+ $locationnum = $1;
+}
+
+#probably could use explicit controls
+# (cust_main locations not editable for tax reasons)
+my $editable = $cust_main ? 0 : 1; #could use explicit control
+my $addnew = $cust_main ? 1 : ( $locationnum>0 ? 0 : 1 );
-$cgi->param('locationnum') =~ /^(\-?\d*)$/ or die "illegal locationnum";
-my $locationnum = $1;
my $cust_location;
if ( $locationnum && $locationnum != -1 ) {
$cust_location = qsearchs('cust_location', { 'locationnum' => $locationnum } )
@@ -171,9 +212,13 @@ if ( $locationnum && $locationnum != -1 ) {
$cust_location = new FS::cust_location;
if ( $locationnum == -1 ) {
$cust_location->$_( $cgi->param($_) ) foreach @location_fields;
- } else {
+ } elsif ( $cust_main ) {
$cust_location->$_( $cust_main->get($prefix.$_) ) foreach @location_fields;
}
}
+my $disabled = ( $locationnum == -1 || ($editable && $locationnum) )
+ ? ''
+ : 'DISABLED';
+
</%init>
diff --git a/httemplate/misc/location.cgi b/httemplate/misc/location.cgi
index 419c59f2e..82ad636c4 100644
--- a/httemplate/misc/location.cgi
+++ b/httemplate/misc/location.cgi
@@ -3,12 +3,23 @@
my $locationnum = $cgi->param('arg');
+my $curuser = $FS::CurrentUser::CurrentUser;
+
my $cust_location = qsearchs({
'select' => 'cust_location.*',
'table' => 'cust_location',
'hashref' => { 'locationnum' => $locationnum },
- 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
- 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+ 'addl_from' => ' LEFT JOIN cust_main USING ( custnum ) ',
+ ' LEFT JOIN prospect_main USING ( prospectnum ) ',
+ 'extra_sql' => ' AND ( '.
+ ' ( custnum IS NOT NULL AND '.
+ $curuser->agentnums_sql( table=>'cust_main' ).
+ ' ) '.
+ ' OR '.
+ ' ( prospectnum IS NOT NULL AND '.
+ $curuser->agentnums_sql( table=>'prospect_main' ).
+ ' ) '.
+ ' )',
});
my %hash = ();
diff --git a/httemplate/search/prospect_main.html b/httemplate/search/prospect_main.html
new file mode 100644
index 000000000..12e3e1812
--- /dev/null
+++ b/httemplate/search/prospect_main.html
@@ -0,0 +1,74 @@
+<% include('elements/search.html',
+ 'title' => 'Prospect Search Results',
+ 'name_singular' => 'prospect',
+ 'query' => $query,
+ 'count_query' => $count_query,
+ 'header' => [ '#',
+ 'Prospect',
+ 'Contact(s)',
+ ],
+ 'fields' => [ 'prospectnum',
+ 'company',
+ sub {
+ my $pm = shift;
+ [ map {
+ [ { 'data' => $_->line, }, ];
+ }
+ $pm->contact
+ ];
+ },
+ ],
+ 'links' => [ '',
+ $link,
+ '', #link to contact edit???
+ ],
+ 'agent_virt' => 1,
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('List prospects');
+
+my %search_hash = ();
+
+#$search_hash{'query'} = $cgi->keywords;
+
+#scalars
+my @scalars = qw (
+ agentnum
+);
+
+for my $param ( @scalars ) {
+ $search_hash{$param} = scalar( $cgi->param($param) )
+ if $cgi->param($param);
+}
+
+#lists
+#for my $param () {
+# $search_hash{$param} = [ $cgi->param($param) ];
+#}
+
+# parse dates
+#foreach my $field (qw( signupdate )) {
+#
+# my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi, $field);
+#
+# next if $beginning == 0 && $ending == 4294967295;
+# #or $disable{$cgi->param('status')}->{$field};
+#
+# $search_hash{$field} = [ $beginning, $ending ];
+#
+#}
+
+my $query = FS::prospect_main->search(\%search_hash);
+my $count_query = delete($query->{'count_query'});
+#my @extra_headers = @{ delete($query->{'extra_headers'}) };
+#my @extra_fields = @{ delete($query->{'extra_fields'}) };
+
+my $link = sub {
+ my $prospect_main = shift;
+ [ "${p}view/prospect_main.html?", 'prospectnum' ];
+};
+
+</%init>
diff --git a/httemplate/search/report_prospect_main.html b/httemplate/search/report_prospect_main.html
new file mode 100644
index 000000000..5e3834346
--- /dev/null
+++ b/httemplate/search/report_prospect_main.html
@@ -0,0 +1,32 @@
+<% include('/elements/header.html', 'Prospect Report' ) %>
+
+<FORM ACTION="prospect_main.html" METHOD="GET">
+
+ <TABLE BGCOLOR="#cccccc" CELLSPACING=0>
+
+ <TR>
+ <TH BGCOLOR="#e8e8e8" COLSPAN=2 ALIGN="left"><FONT SIZE="+1">Search options</FONT></TH>
+ </TR>
+
+ <% include( '/elements/tr-select-agent.html',
+ 'curr_value' => scalar($cgi->param('agentnum')),
+ 'disable_empty' => 0,
+ )
+ %>
+
+ </TABLE>
+
+<BR>
+<INPUT TYPE="submit" VALUE="Get Report">
+
+</FORM>
+
+<% include('/elements/footer.html') %>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('List prospects');
+
+my $conf = new FS::Conf;
+
+</%init>
diff --git a/httemplate/view/cust_main/packages/location.html b/httemplate/view/cust_main/packages/location.html
index 9f348e5d3..41155cbae 100644
--- a/httemplate/view/cust_main/packages/location.html
+++ b/httemplate/view/cust_main/packages/location.html
@@ -4,12 +4,16 @@
<I><FONT SIZE=-1>(default service address)</FONT><BR>
% }
- <% $loc->location_label( 'join_string' => '<BR>',
+ <% $loc->location_label( 'join_string' => '<BR>',
+ 'double_space' => ' &nbsp; ',
'escape_function' => \&encode_entities,
+ 'countrydefault' => $countrydefault,
)
%>
+% unless ( $cust_pkg->locationnum ) {
</I>
+% }
% if ( ! $cust_pkg->get('cancel')
% && $FS::CurrentUser::CurrentUser->access_right('Change customer package')
diff --git a/httemplate/view/prospect_main.html b/httemplate/view/prospect_main.html
new file mode 100644
index 000000000..de446a9fb
--- /dev/null
+++ b/httemplate/view/prospect_main.html
@@ -0,0 +1,92 @@
+<% include('/elements/header.html',
+ 'Prospect View: '. $prospect_main->company
+ )
+%>
+
+% if ( $curuser->access_right('Edit prospect') ) {
+ <A HREF="<% $p %>edit/prospect_main.html?<% $prospectnum %>">Edit this prospect</A>
+% }
+
+<% ntable("#cccccc",2) %>
+
+<TR>
+ <TD ALIGN="right">Prospect #</TD>
+ <TD BGCOLOR="#FFFFFF"><B><% $prospectnum %></B></TD>
+</TR>
+
+%unless ( scalar(@agentnums) == 1 ) {
+% my $agent = qsearchs('agent',{ 'agentnum' => $prospect_main->agentnum } );
+ <TR>
+ <TD ALIGN="right">Agent</TD>
+ <TD BGCOLOR="#ffffff"><% $agent->agentnum %>: <% $agent->agent %></TD>
+ </TR>
+%}
+
+<TR>
+ <TD ALIGN="right">Company</TD>
+ <TD BGCOLOR="#FFFFFF"><B><% $prospect_main->company |h %></B></TD>
+</TR>
+
+% foreach my $contact ( $prospect_main->contact ) {
+ <TR>
+ <TD ALIGN="right">Contact</TD>
+ <TD BGCOLOR="#FFFFFF"><% $contact->line %></TD>
+ </TR>
+%}
+
+% my @cust_location =
+% qsearch('cust_location', { 'prospectnum' => $prospectnum } );
+% #but only one, for now
+% foreach my $cust_location (@cust_location) {
+ <TR>
+ <TD ALIGN="right">Address</TD>
+ <TD BGCOLOR="#FFFFFF">
+ <% $cust_location->location_label(
+ 'join_string' => '<BR>',
+ 'double_space' => ' &nbsp; ',
+ 'escape_function' => \&encode_entities,
+ )
+ %>
+ </TD>
+ </TR>
+% }
+
+</TABLE>
+
+<BR>
+
+<% ntable("#cccccc") %>
+
+<TR>
+ <TH BGCOLOR="#e8e8e8" COLSPAN=2 ALIGN="left"><FONT SIZE="+1">Tickets</FONT></TH>
+</TR>
+
+</TABLE>
+
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+ unless $curuser->access_right('View prospect');
+
+my $prospectnum;
+if ( $cgi->param('prospectnum') =~ /^(\d+)$/ ) {
+ $prospectnum = $1;
+} else {
+ die "No prospect specified (bad URL)!" unless $cgi->keywords;
+ my($query) = $cgi->keywords; # needs parens with my, ->keywords returns array
+ $query =~ /^(\d+)$/;
+ $prospectnum = $1;
+}
+
+my $prospect_main = qsearchs( {
+ 'table' => 'prospect_main',
+ 'hashref' => { 'prospectnum' => $prospectnum },
+ 'extra_sql' => ' AND '. $curuser->agentnums_sql,
+});
+die "Prospect not found!" unless $prospect_main;
+
+my @agentnums = $curuser->agentnums;
+
+</%init>