X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FTemplate_Mixin.pm;h=8734a78b4a1038fdc1e777f3e638128a51ab3199;hb=01f9e027252b87d21c76b8dad737a761e61bb1f7;hp=76cadc3961d7603b4240956c9a444ad5c2d79f38;hpb=213d2aee192d0aa9ccf5d2caa6bdb09611686901;p=freeside.git diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index 76cadc396..8734a78b4 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -10,6 +10,7 @@ use vars qw( $invoice_lines @buf ); #yuck use List::Util qw(sum); #can't import first, it conflicts with cust_main.first use Date::Format; use Date::Language; +use Time::Local qw( timelocal ); use Text::Template 1.20; use File::Temp 0.14; use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); @@ -147,6 +148,10 @@ sub print_latex { $template ||= $self->_agent_template if $self->can('_agent_template'); + #the new way + $self->set('mode', $params{mode}) + if $params{mode}; + my $pkey = $self->primary_key; my $tmp_template = $self->table. '.'. $self->$pkey. '.XXXXXXXX'; @@ -1059,7 +1064,7 @@ sub print_generic { # start setting up summary subtotals my @summary_subtotals; my $method = $conf->config('summary_subtotals_method'); - if ( $method and $method ne $conf->config($tc.'sections_method') ) { + if ( ( ref($self) ne 'FS::quotation' ) and $method and $method ne $conf->config($tc.'sections_method') ) { # then re-section them by the correct method my %section_method = ( by_category => 1 ); if ( $conf->config('summary_subtotals_method') eq 'location' ) { @@ -1666,6 +1671,13 @@ sub print_generic { } else { # this is where we actually create the invoice + if ( $params{no_addresses} ) { + delete $invoice_data{$_} foreach qw( + payname company address1 address2 city state zip country + ); + $invoice_data{returnaddress} = '~'; + } + warn "filling in template for invoice ". $self->invnum. "\n" if $DEBUG; warn join("\n", map " $_ => ". $invoice_data{$_}, keys %invoice_data). "\n" @@ -1908,6 +1920,12 @@ sub due_date { my $duedate = ''; if ( $self->terms =~ /^\s*Net\s*(\d+)\s*$/ ) { $duedate = $self->_date() + ( $1 * 86400 ); + } elsif ( $self->terms =~ /^End of Month$/ ) { + my ($mon,$year) = (localtime($self->_date) )[4,5]; + $mon++; + until ( $mon < 12 ) { $mon -= 12; $year++; } + my $nextmonth_first = timelocal(0,0,0,1,$mon,$year); + $duedate = $nextmonth_first - 86400; } $duedate; } @@ -1936,7 +1954,8 @@ sub balance_due_msg { # (yes, or if invoice_sections is enabled; this is just for compatibility) if ( $self->due_date ) { $msg .= ' - ' . $self->mt('Please pay by'). ' '. - $self->due_date2str('short'); + $self->due_date2str('short') + unless $self->conf->config_bool('invoice_omit_due_date',$self->agentnum); } elsif ( $self->terms ) { $msg .= ' - '. $self->mt($self->terms); } @@ -2345,6 +2364,108 @@ sub mimebuild_pdf { ); } +=item postal_mail_fsinc + +Sends this invoice to the Freeside Internet Services, Inc. print and mail +service. + +=cut + +use CAM::PDF; +use IO::Socket::SSL; +use LWP::UserAgent; +use HTTP::Request::Common qw( POST ); +use JSON::XS; +use MIME::Base64; +sub postal_mail_fsinc { + my ( $self, %opt ) = @_; + + my $url = 'https://ws.freeside.biz/print'; + + my $cust_main = $self->cust_main; + my $agentnum = $cust_main->agentnum; + my $bill_location = $cust_main->bill_location; + + die "Extra charges for international mailing; contact support\@freeside.biz to enable\n" + if $bill_location->country ne 'US'; + + my $conf = new FS::Conf; + + my @company_address = $conf->config('company_address', $agentnum); + my ( $company_address1, $company_address2, $company_city, $company_state, $company_zip ); + if ( $company_address[2] =~ /^\s*(\S.*\S)\s*[\s,](\w\w),?\s*(\d{5}(-\d{4})?)\s*$/ ) { + $company_address1 = $company_address[0]; + $company_address2 = $company_address[1]; + $company_city = $1; + $company_state = $2; + $company_zip = $3; + } elsif ( $company_address[1] =~ /^\s*(\S.*\S)\s*[\s,](\w\w),?\s*(\d{5}(-\d{4})?)\s*$/ ) { + $company_address1 = $company_address[0]; + $company_address2 = ''; + $company_city = $1; + $company_state = $2; + $company_zip = $3; + } else { + die "Unparsable company_address; contact support\@freeside.biz\n"; + } + $company_city =~ s/,$//; + + my $file = $self->print_pdf(%opt, 'no_addresses' => 1); + my $pages = CAM::PDF->new($file)->numPages; + + my $ua = LWP::UserAgent->new( + 'ssl_opts' => { + verify_hostname => 0, + SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, + } + ); + my $response = $ua->request( POST $url, [ + 'support-key' => scalar($conf->config('support-key')), + 'file' => encode_base64($file), + 'pages' => $pages, + + #from: + 'company_name' => scalar( $conf->config('company_name', $agentnum) ), + 'company_address1' => $company_address1, + 'company_address2' => $company_address2, + 'company_city' => $company_city, + 'company_state' => $company_state, + 'company_zip' => $company_zip, + 'company_country' => 'US', + 'company_phonenum' => scalar($conf->config('company_phonenum', $agentnum)), + 'company_email' => scalar($conf->config('invoice_from', $agentnum)), + + #to: + 'name' => ( $cust_main->payname + && $cust_main->payby !~ /^(CARD|DCRD|CHEK|DCHK)$/ + ? $cust_main->payname + : $cust_main->contact_firstlast + ), + 'company' => $cust_main->company, + 'address1' => $bill_location->address1, + 'address2' => $bill_location->address2, + 'city' => $bill_location->city, + 'state' => $bill_location->state, + 'zip' => $bill_location->zip, + 'country' => $bill_location->country, + ]); + + die "Print connection error: ". $response->message. "\n" + unless $response->is_success; + + local $@; + my $content = eval { decode_json($response->content) }; + die "Print JSON error : $@\n" if $@; + + die $content->{error}."\n" + if $content->{error}; + + #TODO: store this so we can query for a status later + warn "Invoice printed, ID ". $content->{id}. "\n"; + + $content->{id}; +} + =item _items_sections OPTIONS Generate section information for all items appearing on this invoice. @@ -3064,7 +3185,9 @@ sub _items_cust_bill_pkg { # for location labels: use default location on the invoice date my $default_locationnum; - if ( $self->custnum ) { + if ( $conf->exists('invoice-all_pkg_addresses') ) { + $default_locationnum = 0; # treat them all as non-default + } elsif ( $self->custnum ) { my $h_cust_main; my @h_search = FS::h_cust_main->sql_h_search($self->_date); $h_cust_main = qsearchs({ @@ -3172,7 +3295,7 @@ sub _items_cust_bill_pkg { my @details = $cust_bill_pkg->details; # and I guess they're never bundled either? - if ( $cust_bill_pkg->setup != 0 ) { + if (( $cust_bill_pkg->setup != 0 ) || ( $cust_bill_pkg->setup_show_zero )) { my $description = $desc; $description .= ' Setup' if $cust_bill_pkg->recur != 0 @@ -3193,7 +3316,7 @@ sub _items_cust_bill_pkg { ), }; } - if ( $cust_bill_pkg->recur != 0 ) { + if (( $cust_bill_pkg->recur != 0 ) || ( $cust_bill_pkg->recur_show_zero )) { #push @b, { $r = { 'pkgnum' => $cust_bill_pkg->pkgpart, #so it displays in Ref @@ -3243,6 +3366,7 @@ sub _items_cust_bill_pkg { # append the word 'Setup' to the setup line if there's going to be # a recur line for the same package (i.e. not a one-time charge) + # XXX localization my $description = $desc; $description .= ' Setup' if $cust_bill_pkg->recur != 0 @@ -3263,8 +3387,11 @@ sub _items_cust_bill_pkg { # always pass the svc_label through to the template, even if # not displaying it as an ext_description my @svc_labels = map &{$escape_function}($_), - $cust_pkg->h_labels_short($self->_date, undef, 'I'); - + $cust_pkg->h_labels_short($self->_date, + undef, + 'I', + $self->conf->{locale}, + ); $svc_label = $svc_labels[0]; unless ( $cust_pkg->part_pkg->hide_svc_detail @@ -3354,7 +3481,9 @@ sub _items_cust_bill_pkg { push @dates, undef if !$prev; my @svc_labels = map &{$escape_function}($_), - $cust_pkg->h_labels_short(@dates, 'I'); + $cust_pkg->h_labels_short(@dates, + 'I', + $self->conf->{locale}); $svc_label = $svc_labels[0]; # show service labels, unless...