'message_noemail', 'char', 'NULL', 1, '', '',
'bill_locationnum', 'int', 'NULL', '', '', '',
'ship_locationnum', 'int', 'NULL', '', '', '',
- 'taxstatusnum', 'char', 'NULL', 32, '', '',
+ 'taxstatusnum', 'int', 'NULL', '', '', '',
'complimentary', 'char', 'NULL', 1, '', '',
'po_number', 'varchar', 'NULL', $char_d, '', '',
'invoice_attn', 'varchar', 'NULL', $char_d, '', '',
'disabled', 'char', 'NULL', 1, '', '',
'custnum', 'int', 'NULL', '', '', '',
'refnum', 'int', 'NULL', '', '', '',
+ 'taxstatusnum', 'int', 'NULL', '', '', '',
],
'primary_key' => 'prospectnum',
'unique' => [],
'quotationtaxnum', 'serial', '', '', '', '',
'quotationpkgnum', 'int', '', '', '', '',
'itemdesc', 'varchar', '', $char_d, '', '',
- 'taxnum', 'int', '', '', '', '',
- 'taxtype', 'varchar', '', $char_d, '', '',
'setup_amount', @money_type, '', '',
'recur_amount', @money_type, '', '',
],
- 'primary_key' => 'quotationtaxnum',,
+ 'primary_key' => 'quotationtaxnum',
'unique' => [],
'index' => [ [ 'quotationpkgnum' ] ],
'foreign_keys' => [
table => 'quotation_pkg',
},
],
-},
+ },
'cust_location' => { #'location' now that its prospects too, but...
'columns' => [
use JSON;
use Geo::StreetAddress::US;
-our $DEBUG = 2;
+our $DEBUG = 0;
our $json = JSON->new->pretty(1);
our $conf;
#}
# Avalara address standardization would be nice but isn't necessary
-# XXX this is just here to avoid reworking the framework right now. By the
-# 4.0 release, ALL tax calculations should be done after the invoice has
-# been inserted into the database.
-
# nothing to do here
sub add_sale {}
};
push @lines, $line;
}
+ # don't make the request unless there are some eligible line items
+ return '' if !@lines;
# assemble address records for any cust_locations we used here, plus
# the company address
# create the top level object
my $date = DateTime->from_epoch(epoch => $self->{invoice_time});
+ my $doctype = $self->{estimate} ? 'SalesOrder' : 'SalesInvoice';
return {
'CustomerCode' => $cust_main->custnum,
'DocDate' => $date->strftime('%Y-%m-%d'),
'DocCode' => $cust_bill->invnum,
'DetailLevel' => 'Tax',
'Commit' => 'false',
- 'DocType' => 'SalesInvoice', # ???
+ 'DocType' => $doctype,
'CustomerUsageType' => $cust_main->taxstatus,
# ExemptionNo, Discount, TaxOverride, PurchaseOrderNo,
'Addresses' => \@addrs,
# assemble the request hash
my $request = $self->build_request;
+ if (!$request) {
+ warn "no tax-eligible items on this invoice\n" if $DEBUG;
+ return [];
+ }
warn "sending Avalara tax request\n" if $DEBUG;
my $request_json = $json->encode($request);
my $error = $tax_rate->find_or_insert;
return "error inserting tax_rate record for '$taxname': $error\n"
if $error;
+ $tax_rate = $tax_rate->replace_old; # get its taxnum if there wasn't one
# create a tax_rate_location record
my $tax_rate_location = FS::tax_rate_location->new({
# create a link record
my $tax_link = FS::cust_bill_pkg_tax_rate_location->new({
- cust_bill_pkg => $tax_item,
+ tax_cust_bill_pkg => $tax_item,
taxtype => 'FS::tax_rate',
taxnum => $tax_rate->taxnum,
taxratelocationnum => $tax_rate_location->taxratelocationnum,
use vars qw( $DEBUG @location_fields );
use Scalar::Util qw( blessed );
use FS::Conf;
-use FS::Record qw( dbh qsearch ); # qsearchs );
+use FS::Record qw( dbh qsearch qsearchs );
use FS::cust_location;
use FS::cust_main;
|| $self->ut_foreign_key( 'agentnum', 'agent', 'agentnum' )
|| $self->ut_foreign_keyn( 'refnum', 'part_referral', 'refnum' )
|| $self->ut_textn('company')
+ || $self->ut_foreign_keyn( 'taxstatusnum', 'tax_status', 'taxstatusnum' )
;
return $error if $error;
Returns the agent (see L<FS::agent>) for this customer.
+=item tax_status
+
+Returns the external tax status, as an FS::tax_status object, or the empty
+string if there is no tax status.
+
+=cut
+
+sub tax_status {
+ my $self = shift;
+ if ( $self->taxstatusnum ) {
+ qsearchs('tax_status', { 'taxstatusnum' => $self->taxstatusnum } );
+ } else {
+ return '';
+ }
+}
+
+=item taxstatus
+
+Returns the tax status code if there is one.
+
+=cut
+
+sub taxstatus {
+ my $self = shift;
+ my $tax_status = $self->tax_status;
+ $tax_status
+ ? $tax_status->taxstatus
+ : '';
+}
+
=item convert_cust_main
Converts this prospect to a customer.
my $cust_main = new FS::cust_main {
'bill_location' => $cust_location[0],
'ship_location' => $cust_location[0],
- ( map { $_ => $self->$_ } qw( agentnum refnum company ) ),
+ ( map { $_ => $self->$_ } qw( agentnum refnum company taxstatusnum ) ),
};
$cust_main->refnum( FS::Conf->new->config('referraldefault') || 1 )
return;
}
+# XXX should have real localization here eventually
+sub locale {
+ FS::Conf->new->config('locale');
+}
+
=back
=head1 BUGS
'company' => 'Company',
'contactnum' => 'Contact',
'locationnum' => ' ',
+ 'taxstatusnum'=> 'Tax status',
},
'fields' => [
{ 'field' => 'agentnum',
'prospect_main' => shift
},
},
+ { 'field' => 'taxstatusnum',
+ 'type' => 'select-tax_status',
+ 'empty_label' => ' ',
+ },
],
'new_callback' => $new_callback,
'edit_callback' => $edit_callback,
&>
% }
% }
+% if ( my $tax_status = $prospect_main->tax_status ) {
+ <TR>
+ <TD ALIGN="right">Tax status</TD>
+ <TD BGCOLOR="#FFFFFF">
+ <B><% $tax_status->taxstatus %>:</B> <% $tax_status->description %>
+ </TD>
+ </TR>
+% }
</TABLE>