}
sub round_amount {
- $main::lxdebug->enter_sub(2);
-
my ($self, $amount, $places) = @_;
- my $round_amount;
# Rounding like "Kaufmannsrunden" (see http://de.wikipedia.org/wiki/Rundung )
# Round amounts to eight places before rounding to the requested
# number of places. This gets rid of errors due to internal floating
# point representation.
- $amount = $self->round_amount($amount, 8) if $places < 8;
- $amount = $amount * (10**($places));
- $round_amount = int($amount + .5 * ($amount <=> 0)) / (10**($places));
+ $amount = $self->round_amount($amount, 8) if $places < 8;
- $main::lxdebug->leave_sub(2);
+ # Remember the amount's sign but calculate in positive values only.
+ my $sign = $amount <=> 0;
+ $amount = abs $amount;
+
+ # Shift the amount left by $places+1 decimal places and truncate it
+ # to integer. Then to the integer equivalent of rounding to the next
+ # multiple of 10: first add half of it (5). Then truncate it back to
+ # the lower multiple of 10 by subtracting $amount modulo 10.
+ my $shift = 10 ** ($places + 1);
+ $amount = int($amount * $shift) + 5;
+ $amount -= $amount % 10;
- return $round_amount;
+ # Lastly shift the amount back right by $places+1 decimal places and
+ # restore its sign. Then we're done.
+ $amount = ($amount / $shift) * $sign;
+ return $amount;
}
sub parse_template {
my ($self, $dbh, $key) = @_;
$key = "all_taxzones" unless ($key);
+ my $tzfilter = "";
+ $tzfilter = "WHERE obsolete is FALSE" if $key eq 'ALL_ACTIVE_TAXZONES';
- my $query = qq|SELECT * FROM tax_zones ORDER BY id|;
+ my $query = qq|SELECT * FROM tax_zones $tzfilter ORDER BY sortkey|;
$self->{$key} = selectall_hashref_query($self, $dbh, $query);
my $dbh = $self->get_standard_dbh(\%main::myconfig);
my ($sth, $query, $ref);
- my $vc = $self->{"vc"} eq "customer" ? "customer" : "vendor";
- my $vc_id = $self->{"${vc}_id"};
+ my ($vc, $vc_id);
+ if ($params{contacts} || $params{shipto}) {
+ $vc = 'customer' if $self->{"vc"} eq "customer";
+ $vc = 'vendor' if $self->{"vc"} eq "vendor";
+ die "invalid use of get_lists, need 'vc'";
+ $vc_id = $self->{"${vc}_id"};
+ }
if ($params{"contacts"}) {
$self->_get_contacts($dbh, $vc_id, $params{"contacts"});
$self->{"employee_${_}"} = $defaults->$_ for qw(address businessnumber co_ustid company duns sepa_creditor_id taxnumber);
}
- # set shipto from billto unless set
- my $has_shipto = any { $self->{"shipto$_"} } qw(name street zipcode city country contact);
- if (!$has_shipto && ($self->{type} =~ m/^(?:purchase_order|request_quotation)$/)) {
- $self->{shiptoname} = $defaults->company;
- $self->{shiptostreet} = $defaults->address;
+ # Load shipping address from database if shipto_id is set.
+ if ($self->{shipto_id}) {
+ my $shipto = SL::DB::Shipto->new(shipto_id => $self->{shipto_id})->load;
+ $self->{$_} = $shipto->$_ for grep { m{^shipto} } map { $_->name } @{ $shipto->meta->columns };
}
my $language = $self->{language} ? '_' . $self->{language} : '';