use SL::DB::Helper::ALL; # since we work on meta data, we need everything
use SL::DB::Helper::Mappings;
use SL::Locale::String qw(t8);
+use SL::Version;
use Rose::Object::MakeMethods::Generic (
scalar => [ qw(from to writer company location) ],
amount => { type => 'Rose::DB::Object::Metadata::Column::Numeric', text => t8('Amount'), },
credit_accname => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Credit Account Name'), },
credit_accno => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Credit Account'), },
+ credit_amount => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Credit Amount'), },
+ credit_tax => { type => 'Rose::DB::Object::Metadata::Column::Numeric', text => t8('Credit Tax (lit)'), },
debit_accname => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Debit Account Name'), },
debit_accno => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Debit Account'), },
+ debit_amount => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Debit Amount'), },
+ debit_tax => { type => 'Rose::DB::Object::Metadata::Column::Numeric', text => t8('Debit Tax (lit)'), },
invnumber => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Reference'), },
name => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Name'), },
notes => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Notes'), },
taxkey => { type => 'Rose::DB::Object::Metadata::Column::Integer', text => t8('Taxkey'), },
tax_accname => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Tax Account Name'), },
tax_accno => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Tax Account'), },
- transdate => { type => 'Rose::DB::Object::Metadata::Column::Date', text => t8('Invoice Date'), },
+ transdate => { type => 'Rose::DB::Object::Metadata::Column::Date', text => t8('Transdate'), },
vcnumber => { type => 'Rose::DB::Object::Metadata::Column::Text', text => t8('Customer/Vendor Number'), },
customer_id => { type => 'Rose::DB::Object::Metadata::Column::Integer', text => t8('Customer (database ID)'), },
vendor_id => { type => 'Rose::DB::Object::Metadata::Column::Integer', text => t8('Vendor (database ID)'), },
itime => { type => 'Rose::DB::Object::Metadata::Column::Date', text => t8('Create Date'), },
+ gldate => { type => 'Rose::DB::Object::Metadata::Column::Date', text => t8('Gldate'), },
);
my @datev_columns = qw(
customer_id vendor_id
name vcnumber
transdate invnumber amount
- debit_accno debit_accname
- credit_accno credit_accname
+ debit_accno debit_accname debit_amount debit_tax
+ credit_accno credit_accname credit_amount credit_tax
taxdescription tax
tax_accno tax_accname taxkey
- notes itime
+ notes itime gldate
);
# rows in this listing are tiers.
my $datev = SL::DATEV->new(from => $self->from, to => $self->to);
- $datev->_get_transactions(from_to => $datev->fromto);
+ $datev->generate_datev_data(from_to => $datev->fromto);
+
+ if ($datev->errors) {
+ die [ $datev->errors ];
+ }
for my $transaction (@{ $datev->{DATEV} }) {
for my $entry (@{ $transaction }) {
my $is_payment = any { $_->{link} =~ m{A[PR]_paid} } @{ $transaction };
my ($soll, $haben) = map { $transaction->[$_] } ($transaction->[0]->{amount} > 0 ? (1, 0) : (0, 1));
- my $tax = defined($soll->{tax_amount}) ? $soll : defined($haben->{tax_amount}) ? $haben : {};
+ my $tax = defined($soll->{tax_accno}) ? $soll : defined($haben->{tax_accno}) ? $haben : {};
my $amount = defined($soll->{net_amount}) ? $soll : $haben;
$haben->{notes} = ($haben->{memo} || $soll->{memo}) if $haben->{memo} || $soll->{memo};
$haben->{notes} //= '';
$haben->{notes} = SL::HTML::Util->strip($haben->{notes});
+ my $tax_amount = defined $amount->{net_amount} ? abs($amount->{amount}) - abs($amount->{net_amount}) : 0;
+
+ $tax = {} if abs($tax_amount) < 0.001;
+
my %row = (
amount => $::form->format_amount($myconfig, abs($amount->{amount}),5),
debit_accno => $soll->{accno},
debit_accname => $soll->{accname},
+ debit_amount => $::form->format_amount($myconfig, abs(-$soll->{amount}),5),
+ debit_tax => $soll->{tax_accno} ? $::form->format_amount($myconfig, $tax_amount, 5) : 0,
credit_accno => $haben->{accno},
credit_accname => $haben->{accname},
- tax => defined $amount->{net_amount} ? $::form->format_amount($myconfig, abs($amount->{amount}) - abs($amount->{net_amount}), 5) : 0,
+ credit_amount => $::form->format_amount($myconfig, abs($haben->{amount}),5),,
+ credit_tax => $haben->{tax_accno} ? $::form->format_amount($myconfig, $tax_amount, 5) : 0,
+ tax => $::form->format_amount($myconfig, $tax_amount, 5),
notes => $haben->{notes},
(map { ($_ => $tax->{$_}) } qw(taxkey tax_accname tax_accno taxdescription)),
- (map { ($_ => ($haben->{$_} // $soll->{$_})) } qw(trans_id invnumber name vcnumber transdate itime customer_id vendor_id)),
+ (map { ($_ => ($haben->{$_} // $soll->{$_})) } qw(trans_id invnumber name vcnumber transdate gldate itime customer_id vendor_id)),
);
+# if ($row{debit_amount} + $row{debit_tax} - ($row{credit_amount} + $row{credit_tax}) > 0.005) {
+# $::lxdebug->dump(0, "broken taxes", [ $transaction, \%row, $row{debit_amount} + $row{debit_tax}, $row{credit_amount} + $row{credit_tax} ]);
+# }
+
_normalize_cell($_) for values %row; # see CAVEATS
$csv->print($fh, [ map { $row{$_} } @datev_columns ]);
my $query = "SELECT " . join(', ', @select_tokens) . " FROM $table $where_clause";
my $sth = $::form->get_standard_dbh->prepare($query);
- $sth->execute(@values) or die "error executing query $query: " . $sth->errstr;
+ $sth->execute(@values) or $::form->dberror($query);
while (my $row = $sth->fetch) {
for my $keep_col (@{ $known_tables{$table}{keep} || [] }) {
sub make_comment {
my $gobd_version = API_VERSION();
- my $kivi_version = $::form->read_version;
+ my $kivi_version = SL::Version->get_version;
my $person = $::myconfig{name};
my $contact = join ', ',
(t8("Email") . ": $::myconfig{email}" ) x!! $::myconfig{email},