From 663b89d06a2c97fb0e7915ba409310fbefefea98 Mon Sep 17 00:00:00 2001 From: levinse Date: Mon, 6 Dec 2010 06:36:02 +0000 Subject: [PATCH] -tr-select-cust_location.html and elements/location.html: optionally support alternate address format and optional address -nearly finished qualifications, RT7111 --- FS/FS/part_export/ikano.pm | 27 +++++- FS/FS/qual.pm | 25 ++++- httemplate/edit/process/qual.cgi | 115 +++++++++++++++++++++++ httemplate/elements/location.html | 66 ++++++++++--- httemplate/elements/tr-select-cust_location.html | 36 ++++--- httemplate/misc/qual.html | 81 ++++++++++++++++ httemplate/view/cust_main/packages.html | 5 + httemplate/view/cust_main/qual_link.html | 16 ++++ httemplate/view/qual.cgi | 65 +++++++++++++ 9 files changed, 409 insertions(+), 27 deletions(-) create mode 100644 httemplate/edit/process/qual.cgi create mode 100644 httemplate/misc/qual.html create mode 100644 httemplate/view/cust_main/qual_link.html create mode 100644 httemplate/view/qual.cgi diff --git a/FS/FS/part_export/ikano.pm b/FS/FS/part_export/ikano.pm index bae683a12..d3715829b 100644 --- a/FS/FS/part_export/ikano.pm +++ b/FS/FS/part_export/ikano.pm @@ -278,6 +278,7 @@ sub qual { RequestClientIP => '127.0.0.1', CheckNetworks => $self->option('check_networks'), } ); + return $result unless ref($result); # error case return 'Invalid prequal response' unless defined $result->{'PrequalId'}; my $qoptions = {}; @@ -293,7 +294,7 @@ sub qual { foreach my $productgroup ( @productgroups ) { my $prefix = "ikano_Network_$netcount"."_ProductGroup_$pgcount"."_"; $qoptions->{$prefix."TermsId"} = $productgroup->{'TermsId'}; - my $products = $network->{'Product'}; + my $products = $productgroup->{'Product'}; my @products = defined $products ? @$products : (); my $prodcount = 0; foreach my $product ( @products ) { @@ -312,7 +313,29 @@ sub qual { } sub qual_html { - ''; + my($self,$qual) = (shift,shift); + + my %qual_options = $qual->options; + my @externalids = (); + my( $optionname, $optionvalue ); + while (($optionname, $optionvalue) = each %qual_options) { + push @externalids, $optionvalue + if ( $optionname =~ /^ikano_Network_(\d+)_ProductGroup_(\d+)_Product_(\d+)_ProductCustomId$/ + && $optionvalue ne '' ); + } + + my $list = "Qualifying Packages:"; + $list; } sub notes_html { diff --git a/FS/FS/qual.pm b/FS/FS/qual.pm index 553de136a..4859b7734 100644 --- a/FS/FS/qual.pm +++ b/FS/FS/qual.pm @@ -143,8 +143,31 @@ sub location { ''; } +sub cust_or_prospect { + my $self = shift; + if ( $self->locationnum ) { + my $l = qsearchs( 'cust_location', + { 'locationnum' => $self->locationnum }); + return qsearchs('cust_main',{ 'custnum' => $l->custnum }) + if $l->custnum; + return qsearchs('prospect_main',{ 'prospectnum' => $l->prospectnum }) + if $l->prospectnum; + } + return qsearchs('cust_main', { 'custnum' => $self->custnum }) + if $self->custnum; + return qsearchs('prospect_main', { 'prospectnum' => $self->prospectnum }) + if $self->prospectnum; +} + sub status_long { - + my $self = shift; + my $s = { + 'Q' => 'Qualified', + 'D' => 'Does not Qualify', + 'N' => 'New', + }; + return $s->{$self->status} if defined $s->{$self->status}; + return 'Unknown'; } =back diff --git a/httemplate/edit/process/qual.cgi b/httemplate/edit/process/qual.cgi new file mode 100644 index 000000000..78e877009 --- /dev/null +++ b/httemplate/edit/process/qual.cgi @@ -0,0 +1,115 @@ +%if ($error) { +% $cgi->param('error', $error); +% $dbh->rollback if $oldAutoCommit; +<% $cgi->redirect(popurl(3). 'misc/qual.html?'. $cgi->query_string ) %> +%} else { +% $dbh->commit or die $dbh->errstr if $oldAutoCommit; +<% header('Qualification entered') %> + + + +%} +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Order customer package'); # XXX: fix me + +$cgi->param('custnum') =~ /^(\d+)$/ + or die 'illegal custnum '. $cgi->param('custnum'); +my $custnum = $1; +my $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $custnum }, + 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, +}); +die 'unknown custnum' unless $cust_main; + +$cgi->param('exportnum') =~ /^(\d+)$/ or die 'illegal exportnum'; +my $exportnum = $1; + +$cgi->param('phonenum') =~ /^(\d*)$/ or die 'illegal phonenum'; +my $phonenum = $1; + +$cgi->param('locationnum') =~ /^(\-?\d*)$/ + or die 'illegal locationnum '. $cgi->param('locationnum'); +my $locationnum = $1; + +my $oldAutoCommit = $FS::UID::AutoCommit; +local $FS::UID::AutoCommit = 0; +my $dbh = dbh; +my $error = ''; +my $cust_location; +if ( $locationnum == -1 ) { # adding a new one + my %location_hash = map { $_ => scalar($cgi->param($_)) } + qw( custnum address1 address2 city county state zip country geocode ); + $location_hash{location_type} = $cgi->param('location_type') + if $cgi->param('location_type'); + $location_hash{location_number} = $cgi->param('location_number') + if $cgi->param('location_number'); + $location_hash{location_kind} = $cgi->param('location_kind') + if $cgi->param('location_kind'); + $cust_location = new FS::cust_location ( { %location_hash } ); + $error = $cust_location->insert; + die "Unable to insert cust_location: $error" if $error; +} +elsif ( $locationnum eq '' ) { # default service location + $cust_location = new FS::cust_location ( { + $cust_main->location_hash, + custnum => $custnum, + } ); +} +elsif ( $locationnum != -2 ) { # -2 = address not required for qual + $cust_location = qsearchs('cust_location', { 'locationnum' => $locationnum }) + or die 'Invalid locationnum'; +} + +my $export; +if ( $exportnum > 0 ) { + $export = qsearchs( 'part_export', { 'exportnum' => $exportnum } ) + or die 'Invalid exportnum'; +} + +die "Nothing to qualify - neither TN nor address specified" + unless ( defined $cust_location || $phonenum ne '' ); + +my $qual; +if ( $locationnum != -2 && $cust_location->locationnum > 0 ) { + $qual = new FS::qual( { locationnum => $cust_location->locationnum } ); +} +else { # a cust_main default service address *OR* address not required + $qual = new FS::qual( { custnum => $custnum } ); +} +$qual->phonenum($phonenum) if $phonenum ne ''; +$qual->status('N'); + +if ( $export ) { + $qual->exportnum($export->exportnum); + my $qres = $export->qual($qual); + $error = "Qualification error: $qres" unless ref($qres); + unless ( $error ) { + $qual->status($qres->{'status'}) if $qres->{'status'}; + $qual->vendor_qual_id($qres->{'vendor_qual_id'}) + if $qres->{'vendor_qual_id'}; + $error = $qual->insert($qres->{'options'}) if ref($qres->{'options'}); + } +} + +unless ( $error || $qual->qualnum ) { + $error = $qual->insert; +} + +my $qualnum; +unless ( $error ) { + if($qual->qualnum) { + $qualnum = $qual->qualnum; + } + else { + $error = "Unable to save qualification"; + } +} + + diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html index 0d2fa38c3..b5f76409b 100644 --- a/httemplate/elements/location.html +++ b/httemplate/elements/location.html @@ -31,21 +31,60 @@ Example: > + + >* >Unit # + + + <% $style %> + > + + + +% if ( $opt{'alt_format'} ) { - >* >Unit # - - - <% $style %> - > - + <<%$th%> ALIGN="right">Location Type> + + <% $style %> + > + + + <<%$th%> ALIGN="right">Number> + + <% $style %> + > + + <<%$th%> ALIGN="right">Kind> + + <% include('/elements/select.html', + 'cgi' => $cgi, + 'field' => 'location_kind', + 'disabled' => $disabled, + 'style' => $style, + 'options' => \@location_kind_options, + 'labels' => $location_kind_labels, + 'curr_value' => $cgi->param('location_kind'), + ) + %> + +% } <<%$th%> ALIGN="right"><%$r%>City> @@ -155,4 +194,7 @@ my %select_hash = ( my $th = $opt{'no_bold'} ? 'TD' : 'TH'; +my @location_kind_options = ( '', 'R', 'B' ); +my $location_kind_labels = { '' => '', 'R' => 'Residential', 'B' => 'Business' }; + diff --git a/httemplate/elements/tr-select-cust_location.html b/httemplate/elements/tr-select-cust_location.html index f2b267a8b..78252ba1d 100644 --- a/httemplate/elements/tr-select-cust_location.html +++ b/httemplate/elements/tr-select-cust_location.html @@ -25,18 +25,26 @@ Example: function locationnum_changed(what) { var locationnum = what.options[what.selectedIndex].value; + if ( locationnum == -2 ) { +% for (@location_fields, 'city_select') { + what.form.<%$_%>.disabled = true; + var ftype = what.form.<%$_%>.tagName; + if( ftype == 'SELECT') changeSelect(what.form.<%$_%>, ''); + else what.form.<%$_%>.value = ''; + what.form.<%$_%>.style.backgroundColor = '#dddddd'; +% } + return; + } + if ( locationnum == -1 ) { % for (@location_fields, 'city_select') { what.form.<%$_%>.disabled = false; what.form.<%$_%>.style.backgroundColor = '#ffffff'; + var ftype = what.form.<%$_%>.tagName; + if( ftype == 'INPUT' ) what.form.<%$_%>.value = ''; % } - what.form.address1.value = ''; - what.form.address2.value = ''; - what.form.city.value = ''; - what.form.zip.value = ''; - changeSelect(what.form.country, <% $countrydefault |js_string %>); country_changed( what.form.country, @@ -147,6 +155,9 @@ Example: + +<% ntable("#cccccc", 2) %> + +<% include('/elements/tr-td-label.html', + 'cgi' => $cgi, + 'label' => 'Qualify using', + 'cell_style' => 'font-weight: bold', + 'id' => 'exportnum', + ) +%> + +<% include('/elements/select.html', + 'cgi' => $cgi, + 'field' => 'exportnum', + 'options' => \@export_options, + 'labels' => $export_labels, + 'curr_value' => $cgi->param('exportnum'), + ) +%> + + + +<% include('/elements/tr-input-text.html', + 'cgi' => $cgi, + 'label' => 'Service Telephone Number', + 'field' => 'phonenum', + 'size' => '12', + 'value' => $cgi->param('phonenum'), + ) +%> + +<% include('/elements/tr-select-cust_location.html', + 'cgi' => $cgi, + 'cust_main' => $cust_main, + 'alt_format' => 1, # XXX: use a config option + 'is_optional' => 1, + 'no_bold' => 1, + ) +%> + + +
+ + + + + +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; + +die "access denied" + unless $curuser->access_right('Order customer package'); # XXX: fix this + +my $conf = new FS::Conf; +my $date_format = $conf->config('date_format') || '%m/%d/%Y'; + +$cgi->param('custnum') =~ /^(\d+)$/ or die "no custnum"; +my $custnum = $1; +my $cust_main = qsearchs({ + 'table' => 'cust_main', + 'hashref' => { 'custnum' => $custnum }, + 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql, +}); + +my @exports = grep { $_->can('qual') } qsearch( 'part_export', {} ); +my @export_options = ( 0 ); +my $export_labels = { '0' => '(manual)' }; +foreach my $export ( @exports ) { + push @export_options, $export->exportnum; + $export_labels->{$export->exportnum} = $export->exportname; +} + + diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html index 660d0ef86..04c47aa3e 100755 --- a/httemplate/view/cust_main/packages.html +++ b/httemplate/view/cust_main/packages.html @@ -1,4 +1,9 @@ % my $s = 0; + +% # XXX: add qual access right + <% $s++ ? ' | ' : '' %> + <% include('qual_link.html', $cust_main) %> + % if ( $curuser->access_right('Order customer package') ) { <% $s++ ? ' | ' : '' %> <% include('order_pkg_link.html', $cust_main) %> diff --git a/httemplate/view/cust_main/qual_link.html b/httemplate/view/cust_main/qual_link.html new file mode 100644 index 000000000..077142c0a --- /dev/null +++ b/httemplate/view/cust_main/qual_link.html @@ -0,0 +1,16 @@ +<% include( '/elements/popup_link-cust_main.html', + 'action' => $p. 'misc/qual.html', + 'label' => 'Service Qualification', + 'actionlabel' => 'Service Qualification', + 'color' => '#333399', + 'cust_main' => $cust_main, + 'closetext' => 'Close', + 'width' => 763, + 'height' => 436, + ) +%> +<%init> + +my($cust_main) = @_; + + diff --git a/httemplate/view/qual.cgi b/httemplate/view/qual.cgi new file mode 100644 index 000000000..f96726995 --- /dev/null +++ b/httemplate/view/qual.cgi @@ -0,0 +1,65 @@ +<% include("/elements/header.html","View Qualification") %> + +% if ( $cust_or_prospect->custnum ) { + + <% include( '/elements/small_custview.html', $cust_or_prospect->custnum, '', 1, + "${p}view/cust_main.cgi") %> +
+ +% } + +Qualification #<% $qual->qualnum %> +<% ntable("#cccccc", 2) %> +<% include('elements/tr.html', label => 'Status', value => $qual->status_long ) %> +<% include('elements/tr.html', label => 'Service Telephone Number', value => $qual->phonenum ) %> +<% include('elements/tr.html', label => 'Address', value => $location_line ) %> +% if ( $location_kind ) { +<% include('elements/tr.html', label => 'Location Kind', value => $location_kind ) %> +% } if ( $export ) { +<% include('elements/tr.html', label => 'Qualified using', value => $export->exportname ) %> +<% include('elements/tr.html', label => 'Vendor Qualification #', value => $qual->vendor_qual_id ) %> +% } + +

+ +% if ( $export ) { +<% $export->qual_html($qual) %> +% } + +<%init> + +# XXX: add access right for quals? + +my $qualnum; +if ( $cgi->param('qualnum') ) { + $cgi->param('qualnum') =~ /^(\d+)$/ or die "unparsable qualnum"; + $qualnum = $1; +} else { + my($query) = $cgi->keywords; + $query =~ /^(\d+)$/ or die "no qualnum"; + $qualnum = $1; +} + +my $qual = qsearchs('qual', { qualnum => $qualnum }) or die "invalid qualnum"; +my $location_line = ''; +my %location_hash = $qual->location; +my $cust_location; +if ( %location_hash ) { + $cust_location = new FS::cust_location(\%location_hash); + $location_line = $cust_location->location_label; +} +# XXX: geocode_Mixin location_label doesn't currently have the new cust_location fields - add them + +my $location_kind; +$location_kind = "Residential" if $cust_location->location_kind eq 'R'; +$location_kind = "Business" if $cust_location->location_kind eq 'B'; + +my $cust_or_prospect = $qual->cust_or_prospect; + +my $export; +if ( $qual->exportnum ) { + $export = qsearchs('part_export', { exportnum => $qual->exportnum } ) + or die 'invalid exportnum'; +} + + -- 2.11.0