From d2acdd4d53071f9e0f9718e14532cb009cda1a85 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 16 Sep 2014 06:41:00 -0700 Subject: [PATCH] convert prospects to customers via quotations, RT#20688 --- FS/FS/prospect_main.pm | 53 +++++++++++++++++++++++++- FS/FS/quotation.pm | 73 ++++++++++++++++++++++++++++++++++++ httemplate/edit/prospect_main.html | 6 +++ httemplate/search/prospect_main.html | 2 + httemplate/view/prospect_main.html | 22 ++++++++++- 5 files changed, 152 insertions(+), 4 deletions(-) diff --git a/FS/FS/prospect_main.pm b/FS/FS/prospect_main.pm index 55b12f241..51481437d 100644 --- a/FS/FS/prospect_main.pm +++ b/FS/FS/prospect_main.pm @@ -6,6 +6,7 @@ use vars qw( $DEBUG @location_fields ); use Scalar::Util qw( blessed ); use FS::Record qw( dbh qsearch ); # qsearchs ); use FS::cust_location; +use FS::cust_main; $DEBUG = 0; @@ -78,7 +79,11 @@ primary key =item agentnum -Agent +Agent (see L) + +=item refnum + +Referral (see L) =item company @@ -237,7 +242,8 @@ sub check { my $error = $self->ut_numbern('prospectnum') - || $self->ut_foreign_key('agentnum', 'agent', 'agentnum' ) + || $self->ut_foreign_key( 'agentnum', 'agent', 'agentnum' ) + || $self->ut_foreign_key( 'refnum', 'part_referral', 'refnum' ) || $self->ut_textn('company') ; return $error if $error; @@ -292,6 +298,49 @@ Returns the qualifications (see L) associated with this prospect. Returns the agent (see L) for this customer. +=item convert_cust_main + +Converts this prospect to a customer. + +If there is an error, returns an error message, otherwise, returns the +newly-created FS::cust_main object. + +=cut + +sub convert_cust_main { + my $self = shift; + + my @cust_location = $self->cust_location; + #the interface only allows one, so we're just gonna go with that for now + + my @contact = $self->contact; + + #XXX define one contact type as "billing", then we could pick just that one + my @invoicing_list = map $_->emailaddress, map $_->contact_email, @contact; + + #XXX i'm not compatible with cust_main-require_phone (which is kind of a + # pre-contact thing anyway) + + my $cust_main = new FS::cust_main { + 'bill_location' => $cust_location[0], + 'ship_location' => $cust_location[0], + ( map { $_ => $self->$_ } qw( agentnum refnum company ) ), + }; + + #XXX again, arbitrary, if one contact was "billing", that would be better + if ( $contact[0] ) { + $cust_main->set($_, $contact[0]->get($_)) foreach qw( first last ); + } else { + $cust_main->set('first', 'Unknown'); + $cust_main->set('last', 'Unknown'); + } + + $cust_main->insert( {}, \@invoicing_list, + 'prospectnum' => $self->prospectnum, + ) + or $cust_main; +} + =item search HASHREF (Class method) diff --git a/FS/FS/quotation.pm b/FS/FS/quotation.pm index cf6652f95..9d4785780 100644 --- a/FS/FS/quotation.pm +++ b/FS/FS/quotation.pm @@ -3,7 +3,11 @@ use base qw( FS::Template_Mixin FS::cust_main_Mixin FS::otaker_Mixin FS::Record ); use strict; +use Tie::RefHash; use FS::CurrentUser; +use FS::UID qw( dbh ); +use FS::cust_main; +use FS::cust_pkg; =head1 NAME @@ -194,6 +198,75 @@ sub _items_total { sub enable_previous { 0 } +=item convert_cust_main + +If this quotation already belongs to a customer, then returns that customer, as +an FS::cust_main object. + +Otherwise, creates a new customer (FS::cust_main object and record, and +associated) based on this quotation's prospect, then orders this quotation's +packages as real packages for the customer. + +If there is an error, returns an error message, otherwise, returns the +newly-created FS::cust_main object. + +=cut + +sub convert_cust_main { + my $self = shift; + + my $cust_main = $self->cust_main; + return $cust_main if $cust_main; #already converted, don't again + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + $cust_main = $self->prospect_main->convert_cust_main; + unless ( ref($cust_main) ) { # eq 'FS::cust_main' ) { + $dbh->rollback if $oldAutoCommit; + return $cust_main; + } + + $self->prospectnum(''); + $self->custnum( $cust_main->custnum ); + my $error = $self->replace || $self->order; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + $cust_main; + +} + +=item order + +This method is for use with quotations which are already associated with a customer. + +Orders this quotation's packages as real packages for the customer. + +If there is an error, returns an error message, otherwise returns false. + +=cut + +sub order { + my $self = shift; + + tie my %cust_pkg, 'Tie::RefHash', + map { FS::cust_pkg->new({ pkgpart => $_->pkgpart, + quantity => $_->quantity, + }) + => [] #services + } + $self->quotation_pkg ; + + $self->cust_main->order_pkgs( \%cust_pkg ); + +} + =back =head1 CLASS METHODS diff --git a/httemplate/edit/prospect_main.html b/httemplate/edit/prospect_main.html index d3985410b..da5c6ce37 100644 --- a/httemplate/edit/prospect_main.html +++ b/httemplate/edit/prospect_main.html @@ -3,6 +3,7 @@ 'table' => 'prospect_main', 'labels' => { 'prospectnum' => 'Prospect', 'agentnum' => 'Agent', + 'refnum' => 'Advertising source', 'company' => 'Company', 'contactnum' => 'Contact', 'locationnum' => ' ', @@ -13,6 +14,11 @@ 'empty_label' => 'Select agent', 'colspan' => 6, }, + { 'field' => 'refnum', + 'type' => 'select-part_referral', + 'empty_label' => 'Select advertising source', + 'colspan' => 6, + }, { 'field' => 'residential_commercial', 'type' => 'radio', 'options' => [ 'Residential', 'Commercial', ], diff --git a/httemplate/search/prospect_main.html b/httemplate/search/prospect_main.html index ab37b9089..4798f58f2 100644 --- a/httemplate/search/prospect_main.html +++ b/httemplate/search/prospect_main.html @@ -23,6 +23,8 @@ '', #link to contact edit??? ], 'agent_virt' => 1, + 'disableable' => 1, + 'disabled_statuspos' => 2, &> <%init> diff --git a/httemplate/view/prospect_main.html b/httemplate/view/prospect_main.html index 6c4595dbe..689b422a4 100644 --- a/httemplate/view/prospect_main.html +++ b/httemplate/view/prospect_main.html @@ -11,7 +11,11 @@ Prospect # - <% $prospectnum %> + <% $prospectnum %> +% if ( $prospect_main->disabled ) { + (DISABLED) +% } + %unless ( scalar(@agentnums) == 1 @@ -19,7 +23,15 @@ % my $agent = qsearchs('agent',{ 'agentnum' => $prospect_main->agentnum } ); Agent - <% $agent->agentnum %>: <% $agent->agent %> + <% $agent->agentnum %>: <% $agent->agent |h %> + +%} + +%unless ( ! $prospect_main->refnum ) { # || scalar(@part_referral) == 1 ) { +% my $part_referral = qsearchs('part_referral',{ 'refnum' => $prospect_main->refnum } ); + + Advertising source + <% $part_referral->referral |h %> %} @@ -76,6 +88,9 @@ # <% mt('Date') |h %> + <% mt('Setup') |h %> + <% mt('Recurring') |h %> + % foreach my $quotation (@quotations) { % if ( $bgcolor eq $bgcolor1 ) { @@ -88,6 +103,9 @@ <% $a %><% $quotation->quotationnum %> <% $a %><% time2str($date_format, $quotation->_date) |h %> + <% $a %><% $quotation->total_setup |h %> + <% $a %><% $quotation->total_recur |h %> + Convert to customer % } -- 2.11.0