5 use Support::TestSetup;
9 use SL::DB::Buchungsgruppe;
14 use SL::DATEV qw(:CONSTANTS);
18 my ($i, $customer, $vendor, $currency_id, @parts, $buchungsgruppe, $buchungsgruppe7, $unit, $employee, $ar_tax_19, $ar_tax_7,$ar_tax_0, $taxzone);
19 my ($ar_chart,$bank,$ar_amount_chart);
21 $config->{numberformat} = '1.000,00';
26 $params{$_} ||= {} for qw(buchungsgruppe vendor customer ar_tax_19 ar_tax_7 ar_tax_0 );
30 $employee = SL::DB::Manager::Employee->current || croak "No employee";
31 $taxzone = SL::DB::Manager::TaxZone->find_by( description => 'Inland') || croak "No taxzone"; # only needed for setting customer/vendor
32 $ar_tax_19 = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19, %{ $params{ar_tax_19} }) || croak "No 19% tax";
33 $ar_tax_7 = SL::DB::Manager::Tax->find_by(taxkey => 2, rate => 0.07, %{ $params{ar_tax_7} }) || croak "No 7% tax";
34 $ar_tax_0 = SL::DB::Manager::Tax->find_by(taxkey => 0, rate => 0.00, %{ $params{ar_tax_0} }) || croak "No 0% tax";
35 $currency_id = $::instance_conf->get_currency_id;
37 $customer = SL::DB::Customer->new(
38 name => 'Test Customer foo',
39 currency_id => $currency_id,
40 taxzone_id => $taxzone->id,
43 $ar_chart = SL::DB::Manager::Chart->find_by( accno => '1400' ); # Forderungen
44 $bank = SL::DB::Manager::Chart->find_by( accno => '1200' ); # Bank
45 $ar_amount_chart = SL::DB::Manager::Chart->find_by( accno => '8590' ); # verrechn., eigentlich Anzahlungen
53 my $amount = $params{amount};
54 my $customer = $params{customer};
55 my $date = $params{date} || DateTime->today;
56 my $with_payment = $params{with_payment} || 0;
58 # SL::DB::Invoice has a _before_save_set_invnumber hook, so we don't need to pass invnumber
59 my $invoice = SL::DB::Invoice->new(
65 customer_id => $customer->id,
66 taxzone_id => $customer->taxzone_id,
67 currency_id => $customer->currency_id,
68 globalproject_id => $params{project},
69 notes => $params{notes},
73 my $db = $invoice->db;
75 $db->with_transaction( sub {
77 my $tax = SL::DB::Manager::Tax->find_by(taxkey => 0, rate => 0);
79 $invoice->add_ar_amount_row(
80 amount => $amount / 2,
81 chart => $ar_amount_chart,
84 $invoice->add_ar_amount_row(
85 amount => $amount / 2,
86 chart => $ar_amount_chart,
90 $invoice->create_ar_row( chart => $ar_chart );
92 _save_and_pay_and_check(invoice => $invoice, bank => $bank, pay => 1, check => 1);
96 }) || die "something went wrong: " . $db->error;
97 return $invoice->invnumber;
103 my $amount = $params{amount};
104 my $customer = $params{customer};
105 my $date = $params{date} || DateTime->today;
106 my $with_payment = $params{with_payment} || 0;
108 my $invoice = SL::DB::Invoice->new(
111 netamount => $amount,
114 customer_id => $customer->id,
115 taxzone_id => $customer->taxzone_id,
116 currency_id => $customer->currency_id,
117 globalproject_id => $params{project},
118 notes => $params{notes},
122 my $db = $invoice->db;
124 $db->with_transaction( sub {
126 # TODO: check for currency and exchange rate
128 my $tax = SL::DB::Manager::Tax->find_by(taxkey => 3, rate => 0.19 );
129 my $tax_id = $tax->id or die "can't find tax";
131 $invoice->add_ar_amount_row(
132 amount => $amount / 2,
133 chart => $ar_amount_chart,
136 $invoice->add_ar_amount_row(
137 amount => $amount / 2,
138 chart => $ar_amount_chart,
142 $invoice->create_ar_row( chart => $ar_chart );
143 _save_and_pay_and_check(invoice => $invoice, bank => $bank, pay => 1, check => 1);
146 }) || die "something went wrong: " . $db->error;
147 return $invoice->invnumber;
150 Support::TestSetup::login();
154 # check ar without tax
155 my $invnumber = ar(customer => $customer, amount => 100, with_payment => 0 , notes => 'ar without tax');
156 my $inv = SL::DB::Manager::Invoice->find_by(invnumber => $invnumber);
157 my $number_of_acc_trans = scalar @{ $inv->transactions };
158 is($::form->round_amount($inv->amount), 100, "invoice_amount = 100");
159 is($number_of_acc_trans, 5, "number of transactions");
160 is($inv->datepaid->to_kivitendo, DateTime->today->to_kivitendo, "datepaid");
161 is($inv->amount - $inv->paid, 0 , "paid = amount ");
164 my $invnumber2 = ar_with_tax(customer => $customer, amount => 200, with_payment => 0, notes => 'ar with taxincluded');
165 my $inv_with_tax = SL::DB::Manager::Invoice->find_by(invnumber => $invnumber2);
166 die unless $inv_with_tax;
167 is(scalar @{ $inv_with_tax->transactions } , 7, "number of transactions for inv_with_tax");
170 is(SL::DB::Manager::Invoice->get_all_count(), 2, "total number of invoices created is 2");
178 SL::DB::Manager::AccTransaction->delete_all(all => 1);
179 SL::DB::Manager::Invoice->delete_all( all => 1);
180 SL::DB::Manager::Customer->delete_all( all => 1);
183 sub _save_and_pay_and_check {
185 my $invoice = $params{invoice};
188 my $return = $invoice->save;
190 $invoice->pay_invoice(chart_id => $params{bank}->id,
191 amount => $invoice->amount,
192 transdate => $invoice->transdate->to_kivitendo,
193 payment_type => 'without_skonto', # default if not specified
197 my $datev = SL::DATEV->new(
198 exporttype => DATEV_ET_BUCHUNGEN,
199 format => DATEV_FORMAT_KNE,
200 dbh => $invoice->db->dbh,
201 trans_id => $invoice->id,
205 if ($datev->errors) {
206 $invoice->db->dbh->rollback;
207 die join "\n", $::locale->text('DATEV check returned errors:'), $datev->errors;