X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_main.pm;h=4fb4f520a4ab3c48053796529e200aaef50a0687;hp=2d6d4590730405933df7e65cbc13cbcaaf66a111;hb=11a4787e386291574aca2357421b586e365252d9;hpb=2b2dd969f3c18751afc583ad1e836ab8e6f73b5d diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 2d6d45907..4fb4f520a 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -28,7 +28,6 @@ use Date::Format; #use Date::Manip; use File::Temp; #qw( tempfile ); use Business::CreditCard 0.28; -use Locale::Country; use FS::UID qw( dbh driver_name ); use FS::Record qw( qsearchs qsearch dbdef regexp_sql ); use FS::Cursor; @@ -325,14 +324,7 @@ a better explanation of this, but until then, here's an example: ); $cust_main->insert( \%hash ); -INVOICING_LIST_ARYREF: If you pass an arrarref to the insert method, it will -be set as the invoicing list (see L<"invoicing_list">). Errors return as -expected and rollback the entire transaction; it is not necessary to call -check_invoicing_list first. The invoicing_list is set after the records in the -CUST_PKG_HASHREF above are inserted, so it is now possible to set an -invoicing_list destination to the newly-created svc_acct. Here's an example: - - $cust_main->insert( {}, [ $email, 'POST' ] ); +INVOICING_LIST_ARYREF: No longer supported. Currently available options are: I, I, I, I, I and I. @@ -352,8 +344,8 @@ created and inserted. If I is set, moves contacts and locations from that prospect. -If I is set to an arrayref of FS::contact objects, inserts those -new contacts with this new customer. +If I is set to an arrayref of FS::contact objects, those will be +inserted. If I is set to a hashref of CGI parameters (and I is unset), inserts those new contacts with this new customer. Handles CGI @@ -368,7 +360,11 @@ for an "m2" multiple entry field as passed by edit/cust_main.cgi sub insert { my $self = shift; my $cust_pkgs = @_ ? shift : {}; - my $invoicing_list = @_ ? shift : ''; + my $invoicing_list; + if ( $_[0] and ref($_[0]) eq 'ARRAY' ) { + warn "cust_main::insert using deprecated invoicing list argument"; + $invoicing_list = shift; + } my %options = @_; warn "$me insert called with options ". join(', ', map { "$_: $options{$_}" } keys %options ). "\n" @@ -495,19 +491,6 @@ sub insert { } } - warn " setting invoicing list\n" - if $DEBUG > 1; - - if ( $invoicing_list ) { - $error = $self->check_invoicing_list( $invoicing_list ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - #return "checking invoicing_list (transaction rolled back): $error"; - return $error; - } - $self->invoicing_list( $invoicing_list ); - } - warn " setting customer tags\n" if $DEBUG > 1; @@ -572,6 +555,25 @@ sub insert { warn " setting contacts\n" if $DEBUG > 1; + $invoicing_list ||= $options{'invoicing_list'}; + if ( $invoicing_list ) { + + $invoicing_list = join(',', @$invoicing_list) if ref $invoicing_list; + my $contact = FS::contact->new({ + 'custnum' => $self->get('custnum'), + 'last' => $self->get('last'), + 'first' => $self->get('first'), + 'emailaddress' => $invoicing_list, + 'invoice_dest' => 'Y', + }); + my $error = $contact->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + if ( my $contact = delete $options{'contact'} ) { foreach my $c ( @$contact ) { @@ -599,7 +601,18 @@ sub insert { warn " setting cust_payby\n" if $DEBUG > 1; - if ( my $cust_payby_params = delete $options{'cust_payby_params'} ) { + if ( $options{cust_payby} ) { + + foreach my $cust_payby ( @{ $options{cust_payby} } ) { + $cust_payby->custnum($self->custnum); + my $error = $cust_payby->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + } elsif ( my $cust_payby_params = delete $options{'cust_payby_params'} ) { my $error = $self->process_o2m( 'table' => 'cust_payby', @@ -1263,19 +1276,25 @@ To change the customer's address, set the pseudo-fields C and C. The address will still only change if at least one of the address fields differs from the existing values. -INVOICING_LIST_ARYREF: If you pass an arrarref to the insert method, it will -be set as the invoicing list (see L<"invoicing_list">). Errors return as -expected and rollback the entire transaction; it is not necessary to call -check_invoicing_list first. Here's an example: - - $new_cust_main->replace( $old_cust_main, [ $email, 'POST' ] ); +INVOICING_LIST_ARYREF: If you pass an arrayref to this method, it will be +set as the contact email address for a default contact with the same name as +the customer. -Currently available options are: I. +Currently available options are: I, I, +I, I. The I option can be set to an arrayref of tax names or a hashref of tax names and exemption numbers. FS::cust_main_exemption records will be deleted and inserted as appropriate. +I and I can be hashrefs of named parameter +groups (describing the customer's payment methods and contacts, respectively) +in the style supported by L. See L +and L for the fields these can contain. + +I is a synonym for the INVOICING_LIST_ARYREF parameter, and +should be used instead if possible. + =cut sub replace { @@ -1336,6 +1355,54 @@ sub replace { $self->set($l.'num', $new_loc->locationnum); } #for $l + my $invoicing_list; + if ( @param && ref($param[0]) eq 'ARRAY' ) { # INVOICING_LIST_ARYREF + warn "cust_main::replace: using deprecated invoicing list argument"; + $invoicing_list = shift @param; + } + + my %options = @param; + + $invoicing_list ||= $options{invoicing_list}; + + if ( $invoicing_list ) { + my $email = ''; + foreach (@$invoicing_list) { + if ($_ eq 'POST') { + $self->set('postal_invoice', 'Y'); + } else { + $email .= ',' if length($email); + $email .= $_; + } + } + my @contacts = map { $_->contact } $self->cust_contact; + # if possible, use a contact that matches the customer's name + my ($contact) = grep { $_->first eq $old->get('first') and + $_->last eq $old->get('last') } + @contacts; + $contact ||= FS::contact->new({ + 'custnum' => $self->custnum, + 'locationnum' => $self->get('bill_locationnum'), + }); + $contact->set('last', $self->get('last')); + $contact->set('first', $self->get('first')); + $contact->set('emailaddress', $email); + $contact->set('invoice_dest', 'Y'); + + my $error; + if ( $contact->contactnum ) { + $error = $contact->replace; + } elsif ( length($email) ) { # don't create a new contact if email is empty + $error = $contact->insert; + } + + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + # replace the customer record my $error = $self->SUPER::replace($old); @@ -1365,16 +1432,6 @@ sub replace { } } - if ( @param && ref($param[0]) eq 'ARRAY' ) { # INVOICING_LIST_ARYREF - my $invoicing_list = shift @param; - $error = $self->check_invoicing_list( $invoicing_list ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } - $self->invoicing_list( $invoicing_list ); - } - if ( $self->exists('tagnum') ) { #so we don't delete these on edit by accident #this could be more efficient than deleting and re-inserting, if it matters @@ -1397,8 +1454,6 @@ sub replace { } - my %options = @param; - my $tax_exemption = delete $options{'tax_exemption'}; if ( $tax_exemption ) { @@ -1456,6 +1511,24 @@ sub replace { } + if ( my $contact_params = delete $options{'contact_params'} ) { + + # this can potentially replace contacts that were created by the + # invoicing list argument, but the UI shouldn't allow both of them + # to be specified + + my $error = $self->process_o2m( + 'table' => 'contact', + 'fields' => FS::contact->cgi_contact_fields, + 'params' => $contact_params, + ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + unless ( $import || $skip_fuzzyfiles ) { $error = $self->queue_fuzzyfiles_update; if ( $error ) { @@ -1594,6 +1667,7 @@ sub check { || $self->ut_alphan('po_number') || $self->ut_enum('complimentary', [ '', 'Y' ]) || $self->ut_flag('invoice_ship_address') + || $self->ut_flag('invoice_dest') ; foreach (qw(company ship_company)) { @@ -2803,18 +2877,10 @@ sub tax_exemption { =item cust_main_exemption -=item invoicing_list [ ARRAYREF ] - -If an arguement is given, sets these email addresses as invoice recipients -(see L). Errors are not fatal and are not reported -(except as warnings), so use check_invoicing_list first. - -Returns a list of email addresses (with svcnum entries expanded). - -Note: You can clear the invoicing list by passing an empty ARRAYREF. You can -check it without disturbing anything by passing nothing. +=item invoicing_list -This interface may change in the future. +Returns a list of email addresses (with svcnum entries expanded), and the word +'POST' if the customer receives postal invoices. =cut @@ -2822,47 +2888,13 @@ sub invoicing_list { my( $self, $arrayref ) = @_; if ( $arrayref ) { - my @cust_main_invoice; - if ( $self->custnum ) { - @cust_main_invoice = - qsearch( 'cust_main_invoice', { 'custnum' => $self->custnum } ); - } else { - @cust_main_invoice = (); - } - foreach my $cust_main_invoice ( @cust_main_invoice ) { - #warn $cust_main_invoice->destnum; - unless ( grep { $cust_main_invoice->address eq $_ } @{$arrayref} ) { - #warn $cust_main_invoice->destnum; - my $error = $cust_main_invoice->delete; - warn $error if $error; - } - } - if ( $self->custnum ) { - @cust_main_invoice = - qsearch( 'cust_main_invoice', { 'custnum' => $self->custnum } ); - } else { - @cust_main_invoice = (); - } - my %seen = map { $_->address => 1 } @cust_main_invoice; - foreach my $address ( @{$arrayref} ) { - next if exists $seen{$address} && $seen{$address}; - $seen{$address} = 1; - my $cust_main_invoice = new FS::cust_main_invoice ( { - 'custnum' => $self->custnum, - 'dest' => $address, - } ); - my $error = $cust_main_invoice->insert; - warn $error if $error; - } + warn "FS::cust_main::invoicing_list(ARRAY) is no longer supported."; } - if ( $self->custnum ) { - map { $_->address } - qsearch( 'cust_main_invoice', { 'custnum' => $self->custnum } ); - } else { - (); - } + my @emails = $self->invoicing_list_emailonly; + push @emails, 'POST' if $self->get('postal_invoice'); + @emails; } =item check_invoicing_list ARRAYREF @@ -2900,18 +2932,6 @@ sub check_invoicing_list { ''; } -=item set_default_invoicing_list - -Sets the invoicing list to all accounts associated with this customer, -overwriting any previous invoicing list. - -=cut - -sub set_default_invoicing_list { - my $self = shift; - $self->invoicing_list($self->all_emails); -} - =item all_emails Returns the email addresses of all accounts provisioned for this customer. @@ -2941,10 +2961,11 @@ to receive postal invoices, does nothing. sub invoicing_list_addpost { my $self = shift; - return if grep { $_ eq 'POST' } $self->invoicing_list; - my @invoicing_list = $self->invoicing_list; - push @invoicing_list, 'POST'; - $self->invoicing_list(\@invoicing_list); + if ( $self->get('postal_invoice') eq '' ) { + $self->set('postal_invoice', 'Y'); + my $error = $self->replace; + warn $error if $error; # should fail harder, but this is traditional + } } =item invoicing_list_emailonly @@ -2958,7 +2979,16 @@ sub invoicing_list_emailonly { my $self = shift; warn "$me invoicing_list_emailonly called" if $DEBUG; - grep { $_ !~ /^([A-Z]+)$/ } $self->invoicing_list; + return () if !$self->custnum; # not yet inserted + return map { $_->emailaddress } + qsearch({ + table => 'cust_contact', + select => 'emailaddress', + addl_from => ' JOIN contact USING (contactnum) '. + ' JOIN contact_email USING (contactnum)', + hashref => { 'custnum' => $self->custnum, }, + extra_sql => q( AND invoice_dest = 'Y'), + }); } =item invoicing_list_emailonly_scalar @@ -3838,26 +3868,14 @@ sub ship_contact_firstlast { $contact->get('first') . ' '. $contact->get('last'); } -#XXX this doesn't work in 3.x+ -#=item country_full -# -#Returns this customer's full country name -# -#=cut -# -#sub country_full { -# my $self = shift; -# code2country($self->country); -#} - sub bill_country_full { my $self = shift; - code2country($self->bill_location->country); + $self->bill_location->country_full; } sub ship_country_full { my $self = shift; - code2country($self->ship_location->country); + $self->ship_location->country_full; } =item county_state_county [ PREFIX ]